Commit 54bce518 authored by aa@chromium.org's avatar aa@chromium.org

Only create chromeHidden object when needed.

This was less useful than I thought it would be because we
are purposely creating chromeHidden for web pages now, due
to the chrome.app API.

Also, move GetChromeHidden() to ChromeV8Context just because
it makes more sense to me there.

BUG=106014

Review URL: http://codereview.chromium.org/8761020

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@112540 0039d316-1c4b-4281-b951-d872f2087c98
parent 2db58cf9
......@@ -14,6 +14,17 @@
#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
#include "v8/include/v8.h"
namespace {
const char kChromeHidden[] = "chromeHidden";
#ifndef NDEBUG
const char kValidateCallbacks[] = "validateCallbacks";
#endif
} // namespace
ChromeV8Context::ChromeV8Context(v8::Handle<v8::Context> v8_context,
WebKit::WebFrame* web_frame,
const std::string& extension_id)
......@@ -31,6 +42,34 @@ ChromeV8Context::~ChromeV8Context() {
v8_context_.Dispose();
}
// static
v8::Handle<v8::Value> ChromeV8Context::GetOrCreateChromeHidden(
v8::Handle<v8::Context> context) {
v8::Local<v8::Object> global = context->Global();
v8::Local<v8::Value> hidden = global->GetHiddenValue(
v8::String::New(kChromeHidden));
if (hidden.IsEmpty() || hidden->IsUndefined()) {
hidden = v8::Object::New();
global->SetHiddenValue(v8::String::New(kChromeHidden), hidden);
#ifndef NDEBUG
// Tell schema_generated_bindings.js to validate callbacks and events
// against their schema definitions in api/extension_api.json.
v8::Local<v8::Object>::Cast(hidden)
->Set(v8::String::New(kValidateCallbacks), v8::True());
#endif
}
DCHECK(hidden->IsObject());
return v8::Local<v8::Object>::Cast(hidden);
}
v8::Handle<v8::Value> ChromeV8Context::GetChromeHidden() const {
v8::Local<v8::Object> global = v8_context_->Global();
return global->GetHiddenValue(v8::String::New(kChromeHidden));
}
content::RenderView* ChromeV8Context::GetRenderView() const {
if (web_frame_ && web_frame_->view())
return content::RenderView::FromWebView(web_frame_->view());
......@@ -48,8 +87,10 @@ bool ChromeV8Context::CallChromeHiddenMethod(
// Look up the function name, which may be a sub-property like
// "Port.dispatchOnMessage" in the hidden global variable.
v8::Local<v8::Value> value = v8::Local<v8::Value>::New(
ChromeV8Extension::GetChromeHidden(v8_context_));
v8::Local<v8::Value> value = v8::Local<v8::Value>::New(GetChromeHidden());
if (value.IsEmpty())
return false;
std::vector<std::string> components;
base::SplitStringDontTrim(function_name, '.', &components);
for (size_t i = 0; i < components.size(); ++i) {
......
......@@ -46,6 +46,18 @@ class ChromeV8Context {
web_frame_ = NULL;
}
// Returns a special Chrome-specific hidden object that is associated with a
// context, but not reachable from the JavaScript in that context. This is
// used by our v8::Extension implementations as a way to share code and as a
// bridge between C++ and JavaScript.
static v8::Handle<v8::Value> GetOrCreateChromeHidden(
v8::Handle<v8::Context> context);
// Return the chromeHidden object associated with this context, or an empty
// handle if no chrome hidden has been created (by GetOrCreateChromeHidden)
// yet for this context.
v8::Handle<v8::Value> GetChromeHidden() const;
// Returns the RenderView associated with this context. Can return NULL if the
// context is in the process of being destroyed.
content::RenderView* GetRenderView() const;
......
......@@ -25,12 +25,6 @@ using WebKit::WebView;
namespace {
const char kChromeHidden[] = "chromeHidden";
#ifndef NDEBUG
const char kValidateCallbacks[] = "validateCallbacks";
#endif
static base::LazyInstance<ChromeV8Extension::InstanceSet> g_instances =
LAZY_INSTANCE_INITIALIZER;
......@@ -198,29 +192,7 @@ ChromeV8ExtensionHandler* ChromeV8Extension::CreateHandler(
v8::Handle<v8::Value> ChromeV8Extension::GetChromeHidden(
const v8::Arguments& args) {
return GetChromeHidden(v8::Context::GetCurrent());
}
v8::Handle<v8::Value> ChromeV8Extension::GetChromeHidden(
const v8::Handle<v8::Context>& context) {
v8::Local<v8::Object> global = context->Global();
v8::Local<v8::Value> hidden = global->GetHiddenValue(
v8::String::New(kChromeHidden));
if (hidden.IsEmpty() || hidden->IsUndefined()) {
hidden = v8::Object::New();
global->SetHiddenValue(v8::String::New(kChromeHidden), hidden);
#ifndef NDEBUG
// Tell schema_generated_bindings.js to validate callbacks and events
// against their schema definitions in api/extension_api.json.
v8::Local<v8::Object>::Cast(hidden)
->Set(v8::String::New(kValidateCallbacks), v8::True());
#endif
}
DCHECK(hidden->IsObject());
return v8::Local<v8::Object>::Cast(hidden);
return ChromeV8Context::GetOrCreateChromeHidden(v8::Context::GetCurrent());
}
v8::Handle<v8::Value> ChromeV8Extension::Print(const v8::Arguments& args) {
......
......@@ -25,12 +25,6 @@ class RenderView;
// This is a base class for chrome extension bindings. Common features that
// are shared by different modules go here.
//
// TODO(aa): Remove the extension-system specific bits of this and move to
// renderer/, or even to renderer/bindings and use DEPS to enforce separation
// from extension system.
//
// TODO(aa): Add unit testing for this class.
class ChromeV8Extension : public v8::Extension {
public:
typedef std::set<ChromeV8Extension*> InstanceSet;
......@@ -48,11 +42,6 @@ class ChromeV8Extension : public v8::Extension {
ExtensionDispatcher* extension_dispatcher() { return extension_dispatcher_; }
// Returns a hidden variable for use by the bindings in the specified context
// that is unreachable by the page for the current context.
static v8::Handle<v8::Value> GetChromeHidden(
const v8::Handle<v8::Context>& context);
void ContextWillBeReleased(ChromeV8Context* context);
// Derived classes should call this at the end of their implementation in
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment