summaryrefslogtreecommitdiffstats
path: root/chrome/renderer
diff options
context:
space:
mode:
authorkoz@chromium.org <koz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-09 04:36:01 +0000
committerkoz@chromium.org <koz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-09 04:36:01 +0000
commit7b0c3f536f8ef4c248d03084a7e4ef9747cfc8c0 (patch)
treecb4afa76ecae3987687d70062aa136801ba93318 /chrome/renderer
parent1b9ab79cf95ef6956b56c06ba3466f4f14ee3b39 (diff)
downloadchromium_src-7b0c3f536f8ef4c248d03084a7e4ef9747cfc8c0.zip
chromium_src-7b0c3f536f8ef4c248d03084a7e4ef9747cfc8c0.tar.gz
chromium_src-7b0c3f536f8ef4c248d03084a7e4ef9747cfc8c0.tar.bz2
Implement a module system for the extension bindings JS.
BUG=104100 TEST=existing browser tests Committed: http://src.chromium.org/viewvc/chrome?view=rev&revision=125132 Review URL: http://codereview.chromium.org/9386001 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@125801 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/renderer')
-rw-r--r--chrome/renderer/extensions/app_bindings.cc108
-rw-r--r--chrome/renderer/extensions/app_bindings.h27
-rw-r--r--chrome/renderer/extensions/chrome_private_custom_bindings.cc19
-rw-r--r--chrome/renderer/extensions/chrome_private_custom_bindings.h7
-rw-r--r--chrome/renderer/extensions/chrome_v8_context.h8
-rw-r--r--chrome/renderer/extensions/chrome_v8_extension.cc101
-rw-r--r--chrome/renderer/extensions/chrome_v8_extension.h41
-rw-r--r--chrome/renderer/extensions/chrome_v8_extension_handler.h5
-rw-r--r--chrome/renderer/extensions/context_menus_custom_bindings.cc25
-rw-r--r--chrome/renderer/extensions/context_menus_custom_bindings.h5
-rw-r--r--chrome/renderer/extensions/custom_bindings_util.cc77
-rw-r--r--chrome/renderer/extensions/custom_bindings_util.h3
-rw-r--r--chrome/renderer/extensions/event_bindings.cc43
-rw-r--r--chrome/renderer/extensions/event_bindings.h5
-rw-r--r--chrome/renderer/extensions/experimental.socket_custom_bindings.cc26
-rw-r--r--chrome/renderer/extensions/experimental.socket_custom_bindings.h6
-rw-r--r--chrome/renderer/extensions/extension_custom_bindings.cc24
-rw-r--r--chrome/renderer/extensions/extension_custom_bindings.h8
-rw-r--r--chrome/renderer/extensions/extension_dispatcher.cc309
-rw-r--r--chrome/renderer/extensions/extension_dispatcher.h16
-rw-r--r--chrome/renderer/extensions/file_browser_handler_custom_bindings.cc28
-rw-r--r--chrome/renderer/extensions/file_browser_handler_custom_bindings.h6
-rw-r--r--chrome/renderer/extensions/file_browser_private_custom_bindings.cc23
-rw-r--r--chrome/renderer/extensions/file_browser_private_custom_bindings.h6
-rw-r--r--chrome/renderer/extensions/i18n_custom_bindings.cc18
-rw-r--r--chrome/renderer/extensions/i18n_custom_bindings.h5
-rw-r--r--chrome/renderer/extensions/json_schema_unittest.cc17
-rw-r--r--chrome/renderer/extensions/miscellaneous_bindings.cc30
-rw-r--r--chrome/renderer/extensions/miscellaneous_bindings.h5
-rw-r--r--chrome/renderer/extensions/page_actions_custom_bindings.cc22
-rw-r--r--chrome/renderer/extensions/page_actions_custom_bindings.h8
-rw-r--r--chrome/renderer/extensions/page_capture_custom_bindings.cc32
-rw-r--r--chrome/renderer/extensions/page_capture_custom_bindings.h7
-rw-r--r--chrome/renderer/extensions/schema_generated_bindings.cc43
-rw-r--r--chrome/renderer/extensions/schema_generated_bindings.h5
-rw-r--r--chrome/renderer/extensions/tabs_custom_bindings.cc20
-rw-r--r--chrome/renderer/extensions/tabs_custom_bindings.h5
-rw-r--r--chrome/renderer/extensions/tts_custom_bindings.cc26
-rw-r--r--chrome/renderer/extensions/tts_custom_bindings.h6
-rw-r--r--chrome/renderer/extensions/web_request_custom_bindings.cc25
-rw-r--r--chrome/renderer/extensions/web_request_custom_bindings.h6
-rw-r--r--chrome/renderer/extensions/webstore_bindings.cc73
-rw-r--r--chrome/renderer/extensions/webstore_bindings.h26
-rw-r--r--chrome/renderer/module_system.cc54
-rw-r--r--chrome/renderer/module_system.h47
-rw-r--r--chrome/renderer/module_system_unittest.cc101
-rw-r--r--chrome/renderer/native_handler.cc9
-rw-r--r--chrome/renderer/native_handler.h10
-rw-r--r--chrome/renderer/renderer_resources.grd1
-rw-r--r--chrome/renderer/resource_bundle_source_map.cc40
-rw-r--r--chrome/renderer/resource_bundle_source_map.h40
-rw-r--r--chrome/renderer/resources/extensions/apitest.js5
-rw-r--r--chrome/renderer/resources/extensions/app.js19
-rw-r--r--chrome/renderer/resources/extensions/browser_action_custom_bindings.js8
-rw-r--r--chrome/renderer/resources/extensions/chrome_private_custom_bindings.js10
-rw-r--r--chrome/renderer/resources/extensions/content_settings_custom_bindings.js8
-rw-r--r--chrome/renderer/resources/extensions/context_menus_custom_bindings.js10
-rw-r--r--chrome/renderer/resources/extensions/devtools_custom_bindings.js8
-rw-r--r--chrome/renderer/resources/extensions/event.js13
-rw-r--r--chrome/renderer/resources/extensions/experimental.declarative_custom_bindings.js8
-rw-r--r--chrome/renderer/resources/extensions/experimental.socket_custom_bindings.js9
-rw-r--r--chrome/renderer/resources/extensions/extension_custom_bindings.js12
-rw-r--r--chrome/renderer/resources/extensions/file_browser_handler_custom_bindings.js9
-rw-r--r--chrome/renderer/resources/extensions/file_browser_private_custom_bindings.js10
-rw-r--r--chrome/renderer/resources/extensions/i18n_custom_bindings.js10
-rw-r--r--chrome/renderer/resources/extensions/input.ime_custom_bindings.js8
-rw-r--r--chrome/renderer/resources/extensions/json_schema.js6
-rw-r--r--chrome/renderer/resources/extensions/miscellaneous_bindings.js20
-rw-r--r--chrome/renderer/resources/extensions/omnibox_custom_bindings.js8
-rw-r--r--chrome/renderer/resources/extensions/page_action_custom_bindings.js8
-rw-r--r--chrome/renderer/resources/extensions/page_actions_custom_bindings.js12
-rw-r--r--chrome/renderer/resources/extensions/page_capture_custom_bindings.js12
-rw-r--r--chrome/renderer/resources/extensions/schema_generated_bindings.js17
-rw-r--r--chrome/renderer/resources/extensions/setup_bindings.js21
-rw-r--r--chrome/renderer/resources/extensions/storage_custom_bindings.js8
-rw-r--r--chrome/renderer/resources/extensions/tabs_custom_bindings.js10
-rw-r--r--chrome/renderer/resources/extensions/tts_custom_bindings.js10
-rw-r--r--chrome/renderer/resources/extensions/tts_engine_custom_bindings.js8
-rw-r--r--chrome/renderer/resources/extensions/types_custom_bindings.js8
-rw-r--r--chrome/renderer/resources/extensions/web_request_custom_bindings.js10
-rw-r--r--chrome/renderer/resources/extensions/webstore.js9
-rw-r--r--chrome/renderer/resources/require.js15
82 files changed, 861 insertions, 1075 deletions
diff --git a/chrome/renderer/extensions/app_bindings.cc b/chrome/renderer/extensions/app_bindings.cc
index 21ee438..34c8047 100644
--- a/chrome/renderer/extensions/app_bindings.cc
+++ b/chrome/renderer/extensions/app_bindings.cc
@@ -53,93 +53,41 @@ const char* kMissingClientIdError = "Missing clientId parameter";
const char* kInvalidClientIdError = "Invalid clientId";
const char* kInvalidCallbackIdError = "Invalid callbackId";
-
-class AppBindingsHandler : public ChromeV8ExtensionHandler {
- public:
- AppBindingsHandler(ExtensionDispatcher* dispatcher, ChromeV8Context* context);
-
- // ChromeV8ExtensionHandler
- virtual v8::Handle<v8::Value> HandleNativeFunction(
- const std::string& name,
- const v8::Arguments& arguments) OVERRIDE;
-
- // IPC::Channel::Listener
- virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
-
- private:
- v8::Handle<v8::Value> GetIsInstalled(const v8::Arguments& args);
- v8::Handle<v8::Value> Install(const v8::Arguments& args);
- v8::Handle<v8::Value> GetDetails(const v8::Arguments& args);
- v8::Handle<v8::Value> GetDetailsForFrame(const v8::Arguments& args);
- v8::Handle<v8::Value> GetAppNotifyChannel(const v8::Arguments& args);
-
- v8::Handle<v8::Value> GetDetailsForFrameImpl(WebKit::WebFrame* frame);
-
- void OnGetAppNotifyChannelResponse(const std::string& channel_id,
- const std::string& error,
- int callback_id);
-
- ExtensionDispatcher* dispatcher_;
- DISALLOW_COPY_AND_ASSIGN(AppBindingsHandler);
-};
-
} // namespace
-AppBindings::AppBindings(ExtensionDispatcher* dispatcher)
- : ChromeV8Extension("extensions/app.js", IDR_APP_BINDINGS_JS,
- dispatcher) {
-}
-
-ChromeV8ExtensionHandler* AppBindings::CreateHandler(
- ChromeV8Context* context) {
- return new AppBindingsHandler(extension_dispatcher(), context);
-}
-
-
-
-AppBindingsHandler::AppBindingsHandler(ExtensionDispatcher* dispatcher,
- ChromeV8Context* context)
- : ChromeV8ExtensionHandler(context),
- dispatcher_(dispatcher) {
+AppBindings::AppBindings(ExtensionDispatcher* dispatcher,
+ ChromeV8Context* context)
+ : ChromeV8Extension(dispatcher),
+ ChromeV8ExtensionHandler(context) {
+ RouteFunction("GetIsInstalled",
+ base::Bind(&AppBindings::GetIsInstalled, base::Unretained(this)));
+ RouteFunction("Install",
+ base::Bind(&AppBindings::Install, base::Unretained(this)));
+ RouteFunction("GetDetails",
+ base::Bind(&AppBindings::GetDetails, base::Unretained(this)));
+ RouteFunction("GetDetailsForFrame",
+ base::Bind(&AppBindings::GetDetailsForFrame, base::Unretained(this)));
+ RouteFunction("GetAppNotifyChannel",
+ base::Bind(&AppBindings::GetAppNotifyChannel, base::Unretained(this)));
}
-v8::Handle<v8::Value> AppBindingsHandler::HandleNativeFunction(
- const std::string& name, const v8::Arguments& args) {
- // TODO(aa): Create a helper map of callback that can be used in either
- // extensions or handlers.
- if (name == "GetIsInstalled") {
- return GetIsInstalled(args);
- } else if (name == "Install") {
- return Install(args);
- } else if (name == "GetDetails") {
- return GetDetails(args);
- } else if (name == "GetDetailsForFrame") {
- return GetDetailsForFrame(args);
- } else if (name == "GetAppNotifyChannel") {
- return GetAppNotifyChannel(args);
- } else {
- CHECK(false) << "Unknown native function: " << name;
- }
-
- return v8::Undefined();
-}
-v8::Handle<v8::Value> AppBindingsHandler::GetIsInstalled(
+v8::Handle<v8::Value> AppBindings::GetIsInstalled(
const v8::Arguments& args) {
// TODO(aa): Hm, maybe ExtensionBindingsContext should have GetExtension()
// afterall?
const ::Extension* extension =
- dispatcher_->extensions()->GetByID(context_->extension_id());
+ extension_dispatcher_->extensions()->GetByID(context_->extension_id());
// TODO(aa): Why only hosted app?
// TODO(aa): GARRR - why is there IsExtensionActive and IsApplicationActive!?
bool result = extension && extension->is_hosted_app() &&
- dispatcher_->IsApplicationActive(extension->id());
+ extension_dispatcher_->IsApplicationActive(extension->id());
return v8::Boolean::New(result);
}
-v8::Handle<v8::Value> AppBindingsHandler::Install(const v8::Arguments& args) {
+v8::Handle<v8::Value> AppBindings::Install(const v8::Arguments& args) {
content::RenderView* render_view = context_->GetRenderView();
CHECK(render_view);
@@ -153,13 +101,13 @@ v8::Handle<v8::Value> AppBindingsHandler::Install(const v8::Arguments& args) {
return v8::Undefined();
}
-v8::Handle<v8::Value> AppBindingsHandler::GetDetails(
+v8::Handle<v8::Value> AppBindings::GetDetails(
const v8::Arguments& args) {
CHECK(context_->web_frame());
return GetDetailsForFrameImpl(context_->web_frame());
}
-v8::Handle<v8::Value> AppBindingsHandler::GetDetailsForFrame(
+v8::Handle<v8::Value> AppBindings::GetDetailsForFrame(
const v8::Arguments& args) {
CHECK(context_->web_frame());
if (!CheckAccessToAppDetails(context_->web_frame()))
@@ -186,12 +134,12 @@ v8::Handle<v8::Value> AppBindingsHandler::GetDetailsForFrame(
return GetDetailsForFrameImpl(target_frame);
}
-v8::Handle<v8::Value> AppBindingsHandler::GetDetailsForFrameImpl(
+v8::Handle<v8::Value> AppBindings::GetDetailsForFrameImpl(
WebFrame* frame) {
const ::Extension* extension =
- dispatcher_->extensions()->GetExtensionOrAppByURL(ExtensionURLInfo(
- frame->document().securityOrigin(),
- frame->document().url()));
+ extension_dispatcher_->extensions()->GetExtensionOrAppByURL(
+ ExtensionURLInfo(frame->document().securityOrigin(),
+ frame->document().url()));
if (!extension)
return v8::Null();
@@ -203,7 +151,7 @@ v8::Handle<v8::Value> AppBindingsHandler::GetDetailsForFrameImpl(
frame->mainWorldScriptContext());
}
-v8::Handle<v8::Value> AppBindingsHandler::GetAppNotifyChannel(
+v8::Handle<v8::Value> AppBindings::GetAppNotifyChannel(
const v8::Arguments& args) {
// Read the required 'clientId' value out of the object at args[0].
std::string client_id;
@@ -242,8 +190,8 @@ v8::Handle<v8::Value> AppBindingsHandler::GetAppNotifyChannel(
return v8::Undefined();
}
-bool AppBindingsHandler::OnMessageReceived(const IPC::Message& message) {
- IPC_BEGIN_MESSAGE_MAP(AppBindingsHandler, message)
+bool AppBindings::OnMessageReceived(const IPC::Message& message) {
+ IPC_BEGIN_MESSAGE_MAP(AppBindings, message)
IPC_MESSAGE_HANDLER(ExtensionMsg_GetAppNotifyChannelResponse,
OnGetAppNotifyChannelResponse)
IPC_MESSAGE_UNHANDLED(CHECK(false) << "Unhandled IPC message")
@@ -251,7 +199,7 @@ bool AppBindingsHandler::OnMessageReceived(const IPC::Message& message) {
return true;
}
-void AppBindingsHandler::OnGetAppNotifyChannelResponse(
+void AppBindings::OnGetAppNotifyChannelResponse(
const std::string& channel_id, const std::string& error, int callback_id) {
v8::HandleScope handle_scope;
v8::Context::Scope context_scope(context_->v8_context());
diff --git a/chrome/renderer/extensions/app_bindings.h b/chrome/renderer/extensions/app_bindings.h
index 9455ba2..e27c770 100644
--- a/chrome/renderer/extensions/app_bindings.h
+++ b/chrome/renderer/extensions/app_bindings.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -14,21 +14,34 @@
#include "base/compiler_specific.h"
#include "chrome/renderer/extensions/chrome_v8_extension.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
class ChromeV8Context;
// Implements the chrome.app JavaScript object.
//
// TODO(aa): Add unit testing for this class.
-class AppBindings : public ChromeV8Extension {
+class AppBindings : public ChromeV8Extension, public ChromeV8ExtensionHandler {
public:
- explicit AppBindings(ExtensionDispatcher* dispatcher);
-
- protected:
- virtual ChromeV8ExtensionHandler* CreateHandler(
- ChromeV8Context* context) OVERRIDE;
+ explicit AppBindings(ExtensionDispatcher* dispatcher,
+ ChromeV8Context* context);
private:
+ // IPC::Channel::Listener
+ virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
+
+ v8::Handle<v8::Value> GetIsInstalled(const v8::Arguments& args);
+ v8::Handle<v8::Value> Install(const v8::Arguments& args);
+ v8::Handle<v8::Value> GetDetails(const v8::Arguments& args);
+ v8::Handle<v8::Value> GetDetailsForFrame(const v8::Arguments& args);
+ v8::Handle<v8::Value> GetAppNotifyChannel(const v8::Arguments& args);
+
+ v8::Handle<v8::Value> GetDetailsForFrameImpl(WebKit::WebFrame* frame);
+
+ void OnGetAppNotifyChannelResponse(const std::string& channel_id,
+ const std::string& error,
+ int callback_id);
+
DISALLOW_COPY_AND_ASSIGN(AppBindings);
};
diff --git a/chrome/renderer/extensions/chrome_private_custom_bindings.cc b/chrome/renderer/extensions/chrome_private_custom_bindings.cc
index a1e4fbb..2e8aa86 100644
--- a/chrome/renderer/extensions/chrome_private_custom_bindings.cc
+++ b/chrome/renderer/extensions/chrome_private_custom_bindings.cc
@@ -18,15 +18,10 @@
namespace extensions {
ChromePrivateCustomBindings::ChromePrivateCustomBindings(
- int dependency_count,
- const char** dependencies,
ExtensionDispatcher* extension_dispatcher)
- : ChromeV8Extension(
- "extensions/chrome_private_custom_bindings.js",
- IDR_CHROME_PRIVATE_CUSTOM_BINDINGS_JS,
- dependency_count,
- dependencies,
- extension_dispatcher) {}
+ : ChromeV8Extension(extension_dispatcher) {
+ RouteStaticFunction("DecodeJPEG", &DecodeJPEG);
+}
// static
v8::Handle<v8::Value> ChromePrivateCustomBindings::DecodeJPEG(
@@ -87,12 +82,4 @@ v8::Handle<v8::Value> ChromePrivateCustomBindings::DecodeJPEG(
return bitmap_array;
}
-v8::Handle<v8::FunctionTemplate> ChromePrivateCustomBindings::GetNativeFunction(
- v8::Handle<v8::String> name) {
- if (name->Equals(v8::String::New("DecodeJPEG")))
- return v8::FunctionTemplate::New(DecodeJPEG, v8::External::New(this));
-
- return ChromeV8Extension::GetNativeFunction(name);
-}
-
} // namespace extensions
diff --git a/chrome/renderer/extensions/chrome_private_custom_bindings.h b/chrome/renderer/extensions/chrome_private_custom_bindings.h
index d1bfdb9..0d6fd5e 100644
--- a/chrome/renderer/extensions/chrome_private_custom_bindings.h
+++ b/chrome/renderer/extensions/chrome_private_custom_bindings.h
@@ -15,14 +15,9 @@ namespace extensions {
// Implements custom bindings for the chromePrivate API.
class ChromePrivateCustomBindings : public ChromeV8Extension {
public:
- ChromePrivateCustomBindings(
- int dependency_count,
- const char** dependencies,
+ explicit ChromePrivateCustomBindings(
ExtensionDispatcher* extension_dispatcher);
- virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction(
- v8::Handle<v8::String> name) OVERRIDE;
-
private:
// Decodes supplied JPEG byte array to image pixel array.
static v8::Handle<v8::Value> DecodeJPEG(const v8::Arguments& args);
diff --git a/chrome/renderer/extensions/chrome_v8_context.h b/chrome/renderer/extensions/chrome_v8_context.h
index 11a4a87..3faf9d2 100644
--- a/chrome/renderer/extensions/chrome_v8_context.h
+++ b/chrome/renderer/extensions/chrome_v8_context.h
@@ -9,6 +9,7 @@
#include <string>
#include "base/basictypes.h"
+#include "chrome/renderer/module_system.h"
#include "v8/include/v8.h"
namespace WebKit {
@@ -60,6 +61,10 @@ class ChromeV8Context {
return context_type_;
}
+ void set_module_system(scoped_ptr<ModuleSystem> module_system) {
+ module_system_ = module_system.Pass();
+ }
+
// 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
@@ -113,6 +118,9 @@ class ChromeV8Context {
// The type of context.
ContextType context_type_;
+ // Owns and structures the JS that is injected to set up extension bindings.
+ scoped_ptr<ModuleSystem> module_system_;
+
DISALLOW_COPY_AND_ASSIGN(ChromeV8Context);
};
diff --git a/chrome/renderer/extensions/chrome_v8_extension.cc b/chrome/renderer/extensions/chrome_v8_extension.cc
index 35b5153..791b1f5 100644
--- a/chrome/renderer/extensions/chrome_v8_extension.cc
+++ b/chrome/renderer/extensions/chrome_v8_extension.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -33,11 +33,6 @@ static base::LazyInstance<ChromeV8Extension::InstanceSet> g_instances =
// static
-base::StringPiece ChromeV8Extension::GetStringResource(int resource_id) {
- return ResourceBundle::GetSharedInstance().GetRawDataResource(resource_id);
-}
-
-// static
content::RenderView* ChromeV8Extension::GetCurrentRenderView() {
WebFrame* webframe = WebFrame::frameForCurrentContext();
DCHECK(webframe) << "RetrieveCurrentFrame called when not in a V8 context.";
@@ -53,27 +48,8 @@ content::RenderView* ChromeV8Extension::GetCurrentRenderView() {
return renderview;
}
-ChromeV8Extension::ChromeV8Extension(const char* name, int resource_id,
- ExtensionDispatcher* extension_dispatcher)
- : v8::Extension(name,
- GetStringResource(resource_id).data(),
- 0, // num dependencies
- NULL, // dependencies array
- GetStringResource(resource_id).size()), // source length
- extension_dispatcher_(extension_dispatcher) {
- g_instances.Get().insert(this);
-}
-
-ChromeV8Extension::ChromeV8Extension(const char* name, int resource_id,
- int dependency_count,
- const char** dependencies,
- ExtensionDispatcher* extension_dispatcher)
- : v8::Extension(name,
- GetStringResource(resource_id).data(),
- dependency_count,
- dependencies,
- GetStringResource(resource_id).size()),
- extension_dispatcher_(extension_dispatcher) {
+ChromeV8Extension::ChromeV8Extension(ExtensionDispatcher* extension_dispatcher)
+ : extension_dispatcher_(extension_dispatcher) {
g_instances.Get().insert(this);
}
@@ -86,19 +62,6 @@ const ChromeV8Extension::InstanceSet& ChromeV8Extension::GetAll() {
return g_instances.Get();
}
-void ChromeV8Extension::ContextWillBeReleased(ChromeV8Context* context) {
- handlers_.erase(context);
-}
-
-ChromeV8ExtensionHandler* ChromeV8Extension::GetHandler(
- ChromeV8Context* context) const {
- HandlerMap::const_iterator iter = handlers_.find(context);
- if (iter == handlers_.end())
- return NULL;
- else
- return iter->second.get();
-}
-
const Extension* ChromeV8Extension::GetExtensionForCurrentRenderView() const {
content::RenderView* renderview = GetCurrentRenderView();
if (!renderview)
@@ -152,61 +115,3 @@ bool ChromeV8Extension::CheckCurrentContextAccessToExtensionAPI(
return true;
}
-
-v8::Handle<v8::FunctionTemplate>
- ChromeV8Extension::GetNativeFunction(v8::Handle<v8::String> name) {
- if (name->Equals(v8::String::New("GetChromeHidden"))) {
- return v8::FunctionTemplate::New(GetChromeHidden);
- }
-
- if (name->Equals(v8::String::New("Print"))) {
- return v8::FunctionTemplate::New(Print);
- }
-
- return v8::FunctionTemplate::New(HandleNativeFunction,
- v8::External::New(this));
-}
-
-// static
-v8::Handle<v8::Value> ChromeV8Extension::HandleNativeFunction(
- const v8::Arguments& arguments) {
- ChromeV8Extension* self = GetFromArguments<ChromeV8Extension>(arguments);
- ChromeV8Context* context =
- self->extension_dispatcher()->v8_context_set().GetCurrent();
- CHECK(context) << "Unknown V8 context. Maybe a native function is getting "
- << "called during parse of a v8 extension, before the context "
- << "has been registered.";
-
- ChromeV8ExtensionHandler* handler = self->GetHandler(context);
- if (!handler) {
- handler = self->CreateHandler(context);
- if (handler)
- self->handlers_[context] = linked_ptr<ChromeV8ExtensionHandler>(handler);
- }
- CHECK(handler) << "No handler for v8 extension: " << self->name();
-
- std::string name = *v8::String::AsciiValue(arguments.Callee()->GetName());
- return handler->HandleNativeFunction(name, arguments);
-}
-
-ChromeV8ExtensionHandler* ChromeV8Extension::CreateHandler(
- ChromeV8Context* context) {
- return NULL;
-}
-
-v8::Handle<v8::Value> ChromeV8Extension::GetChromeHidden(
- const v8::Arguments& args) {
- return ChromeV8Context::GetOrCreateChromeHidden(v8::Context::GetCurrent());
-}
-
-v8::Handle<v8::Value> ChromeV8Extension::Print(const v8::Arguments& args) {
- if (args.Length() < 1)
- return v8::Undefined();
-
- std::vector<std::string> components;
- for (int i = 0; i < args.Length(); ++i)
- components.push_back(*v8::String::Utf8Value(args[i]->ToString()));
-
- LOG(ERROR) << JoinString(components, ',');
- return v8::Undefined();
-}
diff --git a/chrome/renderer/extensions/chrome_v8_extension.h b/chrome/renderer/extensions/chrome_v8_extension.h
index 511273f..7e4b8e8 100644
--- a/chrome/renderer/extensions/chrome_v8_extension.h
+++ b/chrome/renderer/extensions/chrome_v8_extension.h
@@ -10,6 +10,7 @@
#include "base/memory/linked_ptr.h"
#include "base/string_piece.h"
#include "chrome/renderer/extensions/chrome_v8_extension_handler.h"
+#include "chrome/renderer/native_handler.h"
#include "v8/include/v8.h"
#include <map>
@@ -26,31 +27,17 @@ class RenderView;
// This is a base class for chrome extension bindings. Common features that
// are shared by different modules go here.
-class ChromeV8Extension : public v8::Extension {
+// TODO(koz): Rename this to ExtensionNativeModule.
+class ChromeV8Extension : public NativeHandler {
public:
typedef std::set<ChromeV8Extension*> InstanceSet;
static const InstanceSet& GetAll();
- ChromeV8Extension(const char* name,
- int resource_id,
- ExtensionDispatcher* extension_dispatcher);
- ChromeV8Extension(const char* name,
- int resource_id,
- int dependency_count,
- const char** dependencies,
- ExtensionDispatcher* extension_dispatcher);
+ explicit ChromeV8Extension(ExtensionDispatcher* extension_dispatcher);
virtual ~ChromeV8Extension();
ExtensionDispatcher* extension_dispatcher() { return extension_dispatcher_; }
- void ContextWillBeReleased(ChromeV8Context* context);
-
- // Derived classes should call this at the end of their implementation in
- // order to expose common native functions, like GetChromeHidden, to the
- // v8 extension.
- virtual v8::Handle<v8::FunctionTemplate>
- GetNativeFunction(v8::Handle<v8::String> name) OVERRIDE;
-
protected:
template<class T>
static T* GetFromArguments(const v8::Arguments& args) {
@@ -73,32 +60,12 @@ class ChromeV8Extension : public v8::Extension {
bool CheckCurrentContextAccessToExtensionAPI(
const std::string& function_name) const;
- // Create a handler for |context|. If a subclass of ChromeV8Extension wishes
- // to support handlers, it should override this.
- virtual ChromeV8ExtensionHandler* CreateHandler(ChromeV8Context* context);
-
// Returns the chromeHidden object for the current context.
static v8::Handle<v8::Value> GetChromeHidden(const v8::Arguments& args);
ExtensionDispatcher* extension_dispatcher_;
private:
- static base::StringPiece GetStringResource(int resource_id);
-
- // Helper to print from bindings javascript.
- static v8::Handle<v8::Value> Print(const v8::Arguments& args);
-
- // Handle a native function call from JavaScript.
- static v8::Handle<v8::Value> HandleNativeFunction(const v8::Arguments& args);
-
- // Get the handler instance for |context|, or NULL if no such context exists.
- ChromeV8ExtensionHandler* GetHandler(ChromeV8Context* context) const;
-
- // Map of all current handlers.
- typedef std::map<ChromeV8Context*,
- linked_ptr<ChromeV8ExtensionHandler> > HandlerMap;
- HandlerMap handlers_;
-
DISALLOW_COPY_AND_ASSIGN(ChromeV8Extension);
};
diff --git a/chrome/renderer/extensions/chrome_v8_extension_handler.h b/chrome/renderer/extensions/chrome_v8_extension_handler.h
index f933fc9..301b9f6 100644
--- a/chrome/renderer/extensions/chrome_v8_extension_handler.h
+++ b/chrome/renderer/extensions/chrome_v8_extension_handler.h
@@ -15,11 +15,10 @@
class ChromeV8Context;
// Base class for context-scoped handlers used with ChromeV8Extension.
+// TODO(koz): Rename/refactor this somehow. Maybe just pull it into
+// ChromeV8Extension.
class ChromeV8ExtensionHandler : public IPC::Channel::Listener {
public:
- virtual v8::Handle<v8::Value> HandleNativeFunction(
- const std::string& name,
- const v8::Arguments& arguments) = 0;
virtual ~ChromeV8ExtensionHandler();
// IPC::Channel::Listener
diff --git a/chrome/renderer/extensions/context_menus_custom_bindings.cc b/chrome/renderer/extensions/context_menus_custom_bindings.cc
index bfb6114..db3b3d9 100644
--- a/chrome/renderer/extensions/context_menus_custom_bindings.cc
+++ b/chrome/renderer/extensions/context_menus_custom_bindings.cc
@@ -7,19 +7,9 @@
#include "grit/renderer_resources.h"
#include "v8/include/v8.h"
-namespace extensions {
+namespace {
-ContextMenusCustomBindings::ContextMenusCustomBindings(
- int dependency_count,
- const char** dependencies)
- : ChromeV8Extension(
- "extensions/context_menus_custom_bindings.js",
- IDR_CONTEXT_MENUS_CUSTOM_BINDINGS_JS,
- dependency_count,
- dependencies,
- NULL) {}
-
-static v8::Handle<v8::Value> GetNextContextMenuId(const v8::Arguments& args) {
+v8::Handle<v8::Value> GetNextContextMenuId(const v8::Arguments& args) {
// Note: this works because contextMenus.create() only works in the
// extension process. If that API is opened up to content scripts, this
// will need to change. See crbug.com/77023
@@ -27,12 +17,13 @@ static v8::Handle<v8::Value> GetNextContextMenuId(const v8::Arguments& args) {
return v8::Integer::New(next_context_menu_id++);
}
-v8::Handle<v8::FunctionTemplate> ContextMenusCustomBindings::GetNativeFunction(
- v8::Handle<v8::String> name) {
- if (name->Equals(v8::String::New("GetNextContextMenuId")))
- return v8::FunctionTemplate::New(GetNextContextMenuId);
+} // namespace
+
+namespace extensions {
- return ChromeV8Extension::GetNativeFunction(name);
+ContextMenusCustomBindings::ContextMenusCustomBindings()
+ : ChromeV8Extension(NULL) {
+ RouteStaticFunction("GetNextContextMenuId", &GetNextContextMenuId);
}
} // extensions
diff --git a/chrome/renderer/extensions/context_menus_custom_bindings.h b/chrome/renderer/extensions/context_menus_custom_bindings.h
index 1b31e50..18d3b38 100644
--- a/chrome/renderer/extensions/context_menus_custom_bindings.h
+++ b/chrome/renderer/extensions/context_menus_custom_bindings.h
@@ -13,10 +13,7 @@ namespace extensions {
// Implements custom bindings for the contextMenus API.
class ContextMenusCustomBindings : public ChromeV8Extension {
public:
- ContextMenusCustomBindings(int dependency_count, const char** dependencies);
-
- virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction(
- v8::Handle<v8::String> name) OVERRIDE;
+ ContextMenusCustomBindings();
};
} // extensions
diff --git a/chrome/renderer/extensions/custom_bindings_util.cc b/chrome/renderer/extensions/custom_bindings_util.cc
index b9dfa84..5de0470b 100644
--- a/chrome/renderer/extensions/custom_bindings_util.cc
+++ b/chrome/renderer/extensions/custom_bindings_util.cc
@@ -31,83 +31,6 @@ namespace extensions {
namespace custom_bindings_util {
-std::vector<v8::Extension*> GetAll(ExtensionDispatcher* extension_dispatcher) {
- // Must match kResourceIDs.
- static const char* kJavascriptFiles[] = {
- "extensions/browser_action_custom_bindings.js",
- "extensions/content_settings_custom_bindings.js",
- "extensions/experimental.declarative_custom_bindings.js",
- "extensions/devtools_custom_bindings.js",
- "extensions/input.ime_custom_bindings.js",
- "extensions/omnibox_custom_bindings.js",
- "extensions/page_action_custom_bindings.js",
- "extensions/storage_custom_bindings.js",
- "extensions/tts_engine_custom_bindings.js",
- "extensions/types_custom_bindings.js",
- };
- static const size_t kJavascriptFilesSize = arraysize(kJavascriptFiles);
-
- // Must match kJavascriptFiles.
- static const int kResourceIDs[] = {
- IDR_BROWSER_ACTION_CUSTOM_BINDINGS_JS,
- IDR_CONTENT_SETTINGS_CUSTOM_BINDINGS_JS,
- IDR_EXPERIMENTAL_DECLARATIVE_CUSTOM_BINDINGS_JS,
- IDR_DEVTOOLS_CUSTOM_BINDINGS_JS,
- IDR_INPUT_IME_CUSTOM_BINDINGS_JS,
- IDR_OMNIBOX_CUSTOM_BINDINGS_JS,
- IDR_PAGE_ACTION_CUSTOM_BINDINGS_JS,
- IDR_STORAGE_CUSTOM_BINDINGS_JS,
- IDR_TTS_ENGINE_CUSTOM_BINDINGS_JS,
- IDR_TYPES_CUSTOM_BINDINGS_JS,
- };
- static const size_t kResourceIDsSize = arraysize(kResourceIDs);
-
- static const char* kDependencies[] = {
- "extensions/schema_generated_bindings.js",
- };
- static const size_t kDependencyCount = arraysize(kDependencies);
-
- std::vector<v8::Extension*> result;
-
- // Custom bindings that have native code parts.
- result.push_back(new ChromePrivateCustomBindings(
- kDependencyCount, kDependencies, extension_dispatcher));
- result.push_back(new ContextMenusCustomBindings(
- kDependencyCount, kDependencies));
- result.push_back(new ExtensionCustomBindings(
- kDependencyCount, kDependencies, extension_dispatcher));
- result.push_back(new ExperimentalSocketCustomBindings(
- kDependencyCount, kDependencies));
- result.push_back(new FileBrowserHandlerCustomBindings(
- kDependencyCount, kDependencies));
- result.push_back(new FileBrowserPrivateCustomBindings(
- kDependencyCount, kDependencies));
- result.push_back(new I18NCustomBindings(
- kDependencyCount, kDependencies));
- result.push_back(new PageActionsCustomBindings(
- kDependencyCount, kDependencies, extension_dispatcher));
- result.push_back(new PageCaptureCustomBindings(
- kDependencyCount, kDependencies));
- result.push_back(new TabsCustomBindings(
- kDependencyCount, kDependencies));
- result.push_back(new TTSCustomBindings(
- kDependencyCount, kDependencies));
- result.push_back(new WebRequestCustomBindings(
- kDependencyCount, kDependencies));
-
- // Pure JavaScript custom bindings.
- CHECK_EQ(kJavascriptFilesSize, kResourceIDsSize);
- for (size_t i = 0; i < kJavascriptFilesSize; ++i) {
- result.push_back(new ChromeV8Extension(
- kJavascriptFiles[i],
- kResourceIDs[i],
- kDependencyCount, kDependencies,
- NULL));
- }
-
- return result;
-}
-
// Extracts the name of an API from the name of the V8 extension which contains
// custom bindings for it (see kCustomBindingNames).
std::string GetAPIName(const std::string& v8_extension_name) {
diff --git a/chrome/renderer/extensions/custom_bindings_util.h b/chrome/renderer/extensions/custom_bindings_util.h
index f4d6fe3..73d026d 100644
--- a/chrome/renderer/extensions/custom_bindings_util.h
+++ b/chrome/renderer/extensions/custom_bindings_util.h
@@ -24,9 +24,6 @@ namespace extensions {
// bindings.
namespace custom_bindings_util {
-// Creates V8 extensions for all custom bindings.
-std::vector<v8::Extension*> GetAll(ExtensionDispatcher* extension_dispatcher);
-
// Extracts the name of an API from the name of the V8 extension which contains
// custom bindings for it.
// Returns an empty string if the extension is not for a custom binding.
diff --git a/chrome/renderer/extensions/event_bindings.cc b/chrome/renderer/extensions/event_bindings.cc
index 9bab21a..f187f27 100644
--- a/chrome/renderer/extensions/event_bindings.cc
+++ b/chrome/renderer/extensions/event_bindings.cc
@@ -39,25 +39,26 @@ using content::RenderThread;
namespace {
+// A map of event names to the number of contexts listening to that event.
+// We notify the browser about event listeners when we transition between 0
+// and 1.
+typedef std::map<std::string, int> EventListenerCounts;
+
+// A map of extension IDs to listener counts for that extension.
+base::LazyInstance<std::map<std::string, EventListenerCounts> >
+ g_listener_counts = LAZY_INSTANCE_INITIALIZER;
+
+// TODO(koz): Merge this into EventBindings.
class ExtensionImpl : public ChromeV8Extension {
public:
+
explicit ExtensionImpl(ExtensionDispatcher* dispatcher)
- : ChromeV8Extension("extensions/event.js",
- IDR_EVENT_BINDINGS_JS,
- dispatcher) {
+ : ChromeV8Extension(dispatcher) {
+ RouteStaticFunction("AttachEvent", &AttachEvent);
+ RouteStaticFunction("DetachEvent", &DetachEvent);
}
~ExtensionImpl() {}
- virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction(
- v8::Handle<v8::String> name) {
- if (name->Equals(v8::String::New("AttachEvent"))) {
- return v8::FunctionTemplate::New(AttachEvent, v8::External::New(this));
- } else if (name->Equals(v8::String::New("DetachEvent"))) {
- return v8::FunctionTemplate::New(DetachEvent, v8::External::New(this));
- }
- return ChromeV8Extension::GetNativeFunction(name);
- }
-
// Attach an event name to an object.
static v8::Handle<v8::Value> AttachEvent(const v8::Arguments& args) {
DCHECK(args.Length() == 1);
@@ -76,7 +77,7 @@ class ExtensionImpl : public ChromeV8Extension {
return v8::Undefined();
EventListenerCounts& listener_counts =
- self->listener_counts_[context->extension_id()];
+ g_listener_counts.Get()[context->extension_id()];
if (++listener_counts[event_name] == 1) {
content::RenderThread::Get()->Send(
new ExtensionHostMsg_AddListener(context->extension_id(),
@@ -110,7 +111,7 @@ class ExtensionImpl : public ChromeV8Extension {
return v8::Undefined();
EventListenerCounts& listener_counts =
- self->listener_counts_[context->extension_id()];
+ g_listener_counts.Get()[context->extension_id()];
std::string event_name(*v8::String::AsciiValue(args[0]));
bool is_manual = args[1]->BooleanValue();
@@ -135,10 +136,6 @@ class ExtensionImpl : public ChromeV8Extension {
}
private:
- // A map of event names to the number of contexts listening to that event.
- // We notify the browser about event listeners when we transition between 0
- // and 1.
- typedef std::map<std::string, int> EventListenerCounts;
bool IsLazyBackgroundPage(const std::string& extension_id) {
content::RenderView* render_view = GetCurrentRenderView();
@@ -151,14 +148,10 @@ class ExtensionImpl : public ChromeV8Extension {
return (extension && !extension->background_page_persists() &&
helper->view_type() == chrome::VIEW_TYPE_EXTENSION_BACKGROUND_PAGE);
}
-
- // A map of extension IDs to listener counts for that extension.
- std::map<std::string, EventListenerCounts> listener_counts_;
};
} // namespace
-v8::Extension* EventBindings::Get(ExtensionDispatcher* dispatcher) {
- static v8::Extension* extension = new ExtensionImpl(dispatcher);
- return extension;
+ChromeV8Extension* EventBindings::Get(ExtensionDispatcher* dispatcher) {
+ return new ExtensionImpl(dispatcher);
}
diff --git a/chrome/renderer/extensions/event_bindings.h b/chrome/renderer/extensions/event_bindings.h
index 64ada22..baa2004 100644
--- a/chrome/renderer/extensions/event_bindings.h
+++ b/chrome/renderer/extensions/event_bindings.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -6,6 +6,7 @@
#define CHROME_RENDERER_EXTENSIONS_EVENT_BINDINGS_H_
#pragma once
+class ChromeV8Extension;
class ExtensionDispatcher;
namespace v8 {
@@ -15,7 +16,7 @@ class Extension;
// This class deals with the javascript bindings related to Event objects.
class EventBindings {
public:
- static v8::Extension* Get(ExtensionDispatcher* dispatcher);
+ static ChromeV8Extension* Get(ExtensionDispatcher* dispatcher);
};
#endif // CHROME_RENDERER_EXTENSIONS_EVENT_BINDINGS_H_
diff --git a/chrome/renderer/extensions/experimental.socket_custom_bindings.cc b/chrome/renderer/extensions/experimental.socket_custom_bindings.cc
index 11d34bb..8dd096b 100644
--- a/chrome/renderer/extensions/experimental.socket_custom_bindings.cc
+++ b/chrome/renderer/extensions/experimental.socket_custom_bindings.cc
@@ -11,32 +11,22 @@
#include "grit/renderer_resources.h"
#include "v8/include/v8.h"
-namespace extensions {
+namespace {
-ExperimentalSocketCustomBindings::ExperimentalSocketCustomBindings(
- int dependency_count,
- const char** dependencies)
- : ChromeV8Extension(
- "extensions/experimental.socket_custom_bindings.js",
- IDR_EXPERIMENTAL_SOCKET_CUSTOM_BINDINGS_JS,
- dependency_count,
- dependencies,
- NULL) {}
-
-static v8::Handle<v8::Value> GetNextSocketEventId(const v8::Arguments& args) {
+v8::Handle<v8::Value> GetNextSocketEventId(const v8::Arguments& args) {
// Note: this works because the socket API only works in the extension
// process, not content scripts.
static int next_event_id = 1;
return v8::Integer::New(next_event_id++);
}
-v8::Handle<v8::FunctionTemplate>
-ExperimentalSocketCustomBindings::GetNativeFunction(
- v8::Handle<v8::String> name) {
- if (name->Equals(v8::String::New("GetNextSocketEventId")))
- return v8::FunctionTemplate::New(GetNextSocketEventId);
+} // namespace
+
+namespace extensions {
- return ChromeV8Extension::GetNativeFunction(name);
+ExperimentalSocketCustomBindings::ExperimentalSocketCustomBindings()
+ : ChromeV8Extension(NULL) {
+ RouteStaticFunction("GetNextSocketEventId", &GetNextSocketEventId);
}
} // extensions
diff --git a/chrome/renderer/extensions/experimental.socket_custom_bindings.h b/chrome/renderer/extensions/experimental.socket_custom_bindings.h
index a444fa1..32a7f7d 100644
--- a/chrome/renderer/extensions/experimental.socket_custom_bindings.h
+++ b/chrome/renderer/extensions/experimental.socket_custom_bindings.h
@@ -13,11 +13,7 @@ namespace extensions {
// Implements custom bindings for the experimental.socket API.
class ExperimentalSocketCustomBindings : public ChromeV8Extension {
public:
- ExperimentalSocketCustomBindings(
- int dependency_count, const char** dependencies);
-
- virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction(
- v8::Handle<v8::String> name) OVERRIDE;
+ ExperimentalSocketCustomBindings();
};
} // extensions
diff --git a/chrome/renderer/extensions/extension_custom_bindings.cc b/chrome/renderer/extensions/extension_custom_bindings.cc
index 6c9947c..c4895cd 100644
--- a/chrome/renderer/extensions/extension_custom_bindings.cc
+++ b/chrome/renderer/extensions/extension_custom_bindings.cc
@@ -111,15 +111,11 @@ class ExtensionViewAccumulator : public content::RenderViewVisitor {
} // namespace
ExtensionCustomBindings::ExtensionCustomBindings(
- int dependency_count,
- const char** dependencies,
ExtensionDispatcher* extension_dispatcher)
- : ChromeV8Extension(
- "extensions/extension_custom_bindings.js",
- IDR_EXTENSION_CUSTOM_BINDINGS_JS,
- dependency_count,
- dependencies,
- extension_dispatcher) {}
+ : ChromeV8Extension(extension_dispatcher) {
+ RouteStaticFunction("GetExtensionViews", &GetExtensionViews);
+ RouteStaticFunction("OpenChannelToExtension", &OpenChannelToExtension);
+}
// static
v8::Handle<v8::Value> ExtensionCustomBindings::GetExtensionViews(
@@ -172,18 +168,6 @@ v8::Handle<v8::Value> ExtensionCustomBindings::GetExtensionViews(
return accumulator.views();
}
-v8::Handle<v8::FunctionTemplate> ExtensionCustomBindings::GetNativeFunction(
- v8::Handle<v8::String> name) {
- if (name->Equals(v8::String::New("GetExtensionViews"))) {
- return v8::FunctionTemplate::New(GetExtensionViews,
- v8::External::New(this));
- } else if (name->Equals(v8::String::New("OpenChannelToExtension"))) {
- return v8::FunctionTemplate::New(OpenChannelToExtension);
- }
-
- return ChromeV8Extension::GetNativeFunction(name);
-}
-
// static
v8::Handle<v8::Value> ExtensionCustomBindings::OpenChannelToExtension(
const v8::Arguments& args) {
diff --git a/chrome/renderer/extensions/extension_custom_bindings.h b/chrome/renderer/extensions/extension_custom_bindings.h
index d8ac77c..59cf77a 100644
--- a/chrome/renderer/extensions/extension_custom_bindings.h
+++ b/chrome/renderer/extensions/extension_custom_bindings.h
@@ -15,13 +15,7 @@ namespace extensions {
// Implements custom bindings for the extension API.
class ExtensionCustomBindings : public ChromeV8Extension {
public:
- ExtensionCustomBindings(
- int dependency_count,
- const char** dependencies,
- ExtensionDispatcher* extension_dispatcher);
-
- virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction(
- v8::Handle<v8::String> name) OVERRIDE;
+ explicit ExtensionCustomBindings(ExtensionDispatcher* extension_dispatcher);
private:
static v8::Handle<v8::Value> GetExtensionViews(const v8::Arguments& args);
diff --git a/chrome/renderer/extensions/extension_dispatcher.cc b/chrome/renderer/extensions/extension_dispatcher.cc
index 841ca21..0d12b18 100644
--- a/chrome/renderer/extensions/extension_dispatcher.cc
+++ b/chrome/renderer/extensions/extension_dispatcher.cc
@@ -4,7 +4,10 @@
#include "chrome/renderer/extensions/extension_dispatcher.h"
+#include "base/callback.h"
#include "base/command_line.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/string_piece.h"
#include "chrome/common/child_process_logging.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/extension.h"
@@ -22,6 +25,9 @@
#include "chrome/renderer/extensions/schema_generated_bindings.h"
#include "chrome/renderer/extensions/user_script_slave.h"
#include "chrome/renderer/extensions/webstore_bindings.h"
+#include "chrome/renderer/module_system.h"
+#include "chrome/renderer/native_handler.h"
+#include "chrome/renderer/resource_bundle_source_map.h"
#include "content/public/renderer/render_thread.h"
#include "grit/renderer_resources.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebDataSource.h"
@@ -35,6 +41,19 @@
#include "ui/base/resource/resource_bundle.h"
#include "v8/include/v8.h"
+#include "chrome/renderer/extensions/chrome_private_custom_bindings.h"
+#include "chrome/renderer/extensions/context_menus_custom_bindings.h"
+#include "chrome/renderer/extensions/experimental.socket_custom_bindings.h"
+#include "chrome/renderer/extensions/extension_custom_bindings.h"
+#include "chrome/renderer/extensions/file_browser_handler_custom_bindings.h"
+#include "chrome/renderer/extensions/file_browser_private_custom_bindings.h"
+#include "chrome/renderer/extensions/i18n_custom_bindings.h"
+#include "chrome/renderer/extensions/page_actions_custom_bindings.h"
+#include "chrome/renderer/extensions/page_capture_custom_bindings.h"
+#include "chrome/renderer/extensions/tabs_custom_bindings.h"
+#include "chrome/renderer/extensions/tts_custom_bindings.h"
+#include "chrome/renderer/extensions/web_request_custom_bindings.h"
+
namespace {
static const int64 kInitialExtensionIdleHandlerDelayMs = 5*1000;
@@ -46,6 +65,75 @@ ChromeV8Context::ContextType ExtensionGroupToContextType(int extension_group) {
return ChromeV8Context::OTHER;
}
+class ChromeHiddenNativeHandler : public NativeHandler {
+ public:
+ ChromeHiddenNativeHandler() {
+ RouteFunction("GetChromeHidden",
+ base::Bind(&ChromeHiddenNativeHandler::GetChromeHidden,
+ base::Unretained(this)));
+ }
+
+ v8::Handle<v8::Value> GetChromeHidden(const v8::Arguments& args) {
+ return ChromeV8Context::GetOrCreateChromeHidden(v8::Context::GetCurrent());
+ }
+};
+
+class PrintNativeHandler : public NativeHandler {
+ public:
+ PrintNativeHandler() {
+ RouteFunction("Print",
+ base::Bind(&PrintNativeHandler::Print,
+ base::Unretained(this)));
+ }
+
+ v8::Handle<v8::Value> Print(const v8::Arguments& args) {
+ if (args.Length() < 1)
+ return v8::Undefined();
+
+ std::vector<std::string> components;
+ for (int i = 0; i < args.Length(); ++i)
+ components.push_back(*v8::String::Utf8Value(args[i]->ToString()));
+
+ LOG(ERROR) << JoinString(components, ',');
+ return v8::Undefined();
+ }
+};
+
+class ContextInfoNativeHandler : public NativeHandler {
+ public:
+ explicit ContextInfoNativeHandler(ExtensionDispatcher* extension_dispatcher,
+ bool is_bindings_allowed,
+ WebKit::WebFrame* frame,
+ int world_id)
+ : extension_dispatcher_(extension_dispatcher),
+ is_bindings_allowed_(is_bindings_allowed),
+ frame_(frame),
+ world_id_(world_id) {
+ RouteFunction("IsBindingsAllowed",
+ base::Bind(&ContextInfoNativeHandler::IsBindingsAllowed,
+ base::Unretained(this)));
+ RouteFunction("IsAPIAllowed",
+ base::Bind(&ContextInfoNativeHandler::IsAPIAllowed,
+ base::Unretained(this)));
+ }
+
+ v8::Handle<v8::Value> IsBindingsAllowed(const v8::Arguments& args) {
+ return v8::Boolean::New(is_bindings_allowed_);
+ }
+
+ v8::Handle<v8::Value> IsAPIAllowed(const v8::Arguments& args) {
+ std::string custom_api_name = *v8::String::AsciiValue(args[0]->ToString());
+ return v8::Boolean::New(extension_dispatcher_->AllowCustomAPI(
+ frame_, custom_api_name, world_id_));
+ }
+
+ private:
+ ExtensionDispatcher* extension_dispatcher_;
+ bool is_bindings_allowed_;
+ WebKit::WebFrame* frame_;
+ int world_id_;
+};
+
}
using namespace extensions;
@@ -64,7 +152,8 @@ ExtensionDispatcher::ExtensionDispatcher()
: is_webkit_initialized_(false),
webrequest_adblock_(false),
webrequest_adblock_plus_(false),
- webrequest_other_(false) {
+ webrequest_other_(false),
+ source_map_(&ResourceBundle::GetSharedInstance()) {
const CommandLine& command_line = *(CommandLine::ForCurrentProcess());
is_extension_process_ =
command_line.HasSwitch(switches::kExtensionProcess) ||
@@ -76,6 +165,7 @@ ExtensionDispatcher::ExtensionDispatcher()
}
user_script_slave_.reset(new UserScriptSlave(&extensions_));
+ PopulateSourceMap();
}
ExtensionDispatcher::~ExtensionDispatcher() {
@@ -113,25 +203,6 @@ void ExtensionDispatcher::WebKitInitialized() {
RenderThread::Get(), &RenderThread::IdleHandler);
}
- RegisterExtension(new AppBindings(this), false);
- RegisterExtension(new WebstoreBindings(this), false);
-
- // Add v8 extensions related to chrome extensions.
- RegisterExtension(new ChromeV8Extension(
- "extensions/json_schema.js", IDR_JSON_SCHEMA_JS, NULL), true);
- RegisterExtension(EventBindings::Get(this), true);
- RegisterExtension(MiscellaneousBindings::Get(this), true);
- RegisterExtension(SchemaGeneratedBindings::Get(this), true);
- RegisterExtension(new ChromeV8Extension(
- "extensions/apitest.js", IDR_EXTENSION_APITEST_JS, NULL), true);
-
- std::vector<v8::Extension*> custom_bindings =
- custom_bindings_util::GetAll(this);
- for (std::vector<v8::Extension*>::iterator it = custom_bindings.begin();
- it != custom_bindings.end(); ++it) {
- RegisterExtension(*it, true);
- }
-
// Initialize host permissions for any extensions that were activated before
// WebKit was initialized.
for (std::set<std::string>::iterator iter = active_extension_ids_.begin();
@@ -299,55 +370,121 @@ bool ExtensionDispatcher::AllowScriptExtension(
int extension_group,
int world_id) {
g_hack_extension_group = extension_group;
+ return true;
+}
- // NULL in unit tests.
- if (!RenderThread::Get())
- return true;
-
- // If we don't know about it, it was added by WebCore, so we should allow it.
- if (!RenderThread::Get()->IsRegisteredExtension(v8_extension_name))
- return true;
-
- // If the V8 extension is not restricted, allow it to run anywhere.
- if (!restricted_v8_extensions_.count(v8_extension_name))
- return true;
-
- // Extension-only bindings should be restricted to content scripts and
- // extension-blessed URLs.
- ChromeV8Context::ContextType context_type =
- ExtensionGroupToContextType(extension_group);
-
- if (context_type == ChromeV8Context::CONTENT_SCRIPT ||
- extensions_.ExtensionBindingsAllowed(ExtensionURLInfo(
- frame->document().securityOrigin(),
- UserScriptSlave::GetDataSourceURLForFrame(frame)))) {
- // If the extension is a custom API binding, only allow if the extension
- // has permission to use the API.
- std::string custom_binding_api_name =
- custom_bindings_util::GetAPIName(v8_extension_name);
- if (!custom_binding_api_name.empty()) {
- std::string extension_id = GetExtensionID(frame, world_id);
- const Extension* extension = extensions_.GetByID(extension_id);
- if (!extension) {
- // This can happen when a resource is blocked due to CSP; a valid
- // chrome-extension:// URL is navigated to, so it passes the initial
- // checks, but the URL gets changed to "chrome-extension://invalid"
- // afterwards (see chrome_content_renderer_client.cc). An extension
- // page still gets loaded, just for the extension with ID "invalid",
- // which of course isn't found so GetById extension will be NULL.
- //
- // Reference: http://crbug.com/111614.
- CHECK_EQ("invalid", extension_id);
- return false;
- }
- return custom_bindings_util::AllowAPIInjection(
- custom_binding_api_name, *extension, this);
- }
-
+bool ExtensionDispatcher::AllowCustomAPI(
+ WebFrame* frame,
+ const std::string& custom_binding_api_name,
+ int world_id) {
+ std::string extension_id = GetExtensionID(frame, world_id);
+ if (test_extension_id_ == extension_id)
return true;
+ const Extension* extension = extensions_.GetByID(extension_id);
+ if (!extension) {
+ // This can happen when a resource is blocked due to CSP; a valid
+ // chrome-extension:// URL is navigated to, so it passes the initial
+ // checks, but the URL gets changed to "chrome-extension://invalid"
+ // afterwards (see chrome_content_renderer_client.cc). An extension
+ // page still gets loaded, just for the extension with ID "invalid",
+ // which of course isn't found so GetById extension will be NULL.
+ //
+ // Reference: http://crbug.com/111614.
+ CHECK_EQ("invalid", extension_id);
+ return false;
}
-
- return false;
+ return custom_bindings_util::AllowAPIInjection(
+ custom_binding_api_name, *extension, this);
+}
+
+void ExtensionDispatcher::RegisterNativeHandlers(ModuleSystem* module_system,
+ ChromeV8Context* context) {
+ module_system->RegisterNativeHandler("app",
+ scoped_ptr<NativeHandler>(new AppBindings(this, context)));
+ module_system->RegisterNativeHandler("webstore",
+ scoped_ptr<NativeHandler>(new WebstoreBindings(this, context)));
+ module_system->RegisterNativeHandler("event_bindings",
+ scoped_ptr<NativeHandler>(EventBindings::Get(this)));
+ module_system->RegisterNativeHandler("miscellaneous_bindings",
+ scoped_ptr<NativeHandler>(MiscellaneousBindings::Get(this)));
+ module_system->RegisterNativeHandler("schema_generated_bindings",
+ scoped_ptr<NativeHandler>(SchemaGeneratedBindings::Get(this)));
+
+ // Custom bindings.
+ module_system->RegisterNativeHandler("chrome_private",
+ scoped_ptr<NativeHandler>(
+ new ChromePrivateCustomBindings(this)));
+ module_system->RegisterNativeHandler("context_menus",
+ scoped_ptr<NativeHandler>(new ContextMenusCustomBindings()));
+ module_system->RegisterNativeHandler("extension",
+ scoped_ptr<NativeHandler>(
+ new ExtensionCustomBindings(this)));
+ module_system->RegisterNativeHandler("experimental_socket",
+ scoped_ptr<NativeHandler>(new ExperimentalSocketCustomBindings()));
+ module_system->RegisterNativeHandler("file_browser_handler",
+ scoped_ptr<NativeHandler>(new FileBrowserHandlerCustomBindings()));
+ module_system->RegisterNativeHandler("file_browser_private",
+ scoped_ptr<NativeHandler>(new FileBrowserPrivateCustomBindings()));
+ module_system->RegisterNativeHandler("i18n",
+ scoped_ptr<NativeHandler>(new I18NCustomBindings()));
+ module_system->RegisterNativeHandler("page_actions",
+ scoped_ptr<NativeHandler>(
+ new PageActionsCustomBindings(this)));
+ module_system->RegisterNativeHandler("page_capture",
+ scoped_ptr<NativeHandler>(new PageCaptureCustomBindings()));
+ module_system->RegisterNativeHandler("tabs",
+ scoped_ptr<NativeHandler>(new TabsCustomBindings()));
+ module_system->RegisterNativeHandler("tts",
+ scoped_ptr<NativeHandler>(new TTSCustomBindings()));
+ module_system->RegisterNativeHandler("web_request",
+ scoped_ptr<NativeHandler>(new WebRequestCustomBindings()));
+}
+
+void ExtensionDispatcher::PopulateSourceMap() {
+ source_map_.RegisterSource("app", IDR_APP_BINDINGS_JS);
+ source_map_.RegisterSource("webstore", IDR_WEBSTORE_BINDINGS_JS);
+ source_map_.RegisterSource("event_bindings", IDR_EVENT_BINDINGS_JS);
+ source_map_.RegisterSource("miscellaneous_bindings",
+ IDR_MISCELLANEOUS_BINDINGS_JS);
+ source_map_.RegisterSource("schema_generated_bindings",
+ IDR_SCHEMA_GENERATED_BINDINGS_JS);
+ source_map_.RegisterSource("json_schema", IDR_JSON_SCHEMA_JS);
+ source_map_.RegisterSource("apitest", IDR_EXTENSION_APITEST_JS);
+ source_map_.RegisterSource("setup_bindings", IDR_SETUP_BINDINGS_JS);
+
+ // Custom bindings.
+ source_map_.RegisterSource("browserAction",
+ IDR_BROWSER_ACTION_CUSTOM_BINDINGS_JS);
+ source_map_.RegisterSource("chromePrivate",
+ IDR_CHROME_PRIVATE_CUSTOM_BINDINGS_JS);
+ source_map_.RegisterSource("contentSettings",
+ IDR_CONTENT_SETTINGS_CUSTOM_BINDINGS_JS);
+ source_map_.RegisterSource("contextMenus",
+ IDR_CONTEXT_MENUS_CUSTOM_BINDINGS_JS);
+ source_map_.RegisterSource("devtools", IDR_DEVTOOLS_CUSTOM_BINDINGS_JS);
+ source_map_.RegisterSource("experimental.declarative",
+ IDR_EXPERIMENTAL_DECLARATIVE_CUSTOM_BINDINGS_JS);
+ source_map_.RegisterSource("experimental.socket",
+ IDR_EXPERIMENTAL_SOCKET_CUSTOM_BINDINGS_JS);
+ source_map_.RegisterSource("extension", IDR_EXTENSION_CUSTOM_BINDINGS_JS);
+ source_map_.RegisterSource("fileBrowserHandler",
+ IDR_FILE_BROWSER_HANDLER_CUSTOM_BINDINGS_JS);
+ source_map_.RegisterSource("fileBrowserPrivate",
+ IDR_FILE_BROWSER_PRIVATE_CUSTOM_BINDINGS_JS);
+ source_map_.RegisterSource("i18n", IDR_I18N_CUSTOM_BINDINGS_JS);
+ source_map_.RegisterSource("input.ime", IDR_INPUT_IME_CUSTOM_BINDINGS_JS);
+ source_map_.RegisterSource("omnibox", IDR_OMNIBOX_CUSTOM_BINDINGS_JS);
+ source_map_.RegisterSource("pageActions",
+ IDR_PAGE_ACTIONS_CUSTOM_BINDINGS_JS);
+ source_map_.RegisterSource("pageAction", IDR_PAGE_ACTION_CUSTOM_BINDINGS_JS);
+ source_map_.RegisterSource("pageCapture",
+ IDR_PAGE_CAPTURE_CUSTOM_BINDINGS_JS);
+ source_map_.RegisterSource("storage", IDR_STORAGE_CUSTOM_BINDINGS_JS);
+ source_map_.RegisterSource("tabs", IDR_TABS_CUSTOM_BINDINGS_JS);
+ source_map_.RegisterSource("tts", IDR_TTS_CUSTOM_BINDINGS_JS);
+ source_map_.RegisterSource("ttsEngine", IDR_TTS_ENGINE_CUSTOM_BINDINGS_JS);
+ source_map_.RegisterSource("types", IDR_TYPES_CUSTOM_BINDINGS_JS);
+ source_map_.RegisterSource("webRequest", IDR_WEB_REQUEST_CUSTOM_BINDINGS_JS);
}
void ExtensionDispatcher::DidCreateScriptContext(
@@ -356,19 +493,49 @@ void ExtensionDispatcher::DidCreateScriptContext(
// TODO(koz): If the caller didn't pass extension_group, use the last value.
if (extension_group == -1)
extension_group = g_hack_extension_group;
+
+ std::string extension_id = GetExtensionID(frame, world_id);
ChromeV8Context* context =
new ChromeV8Context(
v8_context,
frame,
- GetExtensionID(frame, world_id),
+ extension_id,
ExtensionGroupToContextType(extension_group));
v8_context_set_.Add(context);
+ scoped_ptr<ModuleSystem> module_system(new ModuleSystem(&source_map_));
+ RegisterNativeHandlers(module_system.get(), context);
+
+ bool is_bindings_allowed =
+ IsTestExtensionId(extension_id) ||
+ context->context_type() == ChromeV8Context::CONTENT_SCRIPT ||
+ extensions_.ExtensionBindingsAllowed(ExtensionURLInfo(
+ frame->document().securityOrigin(),
+ UserScriptSlave::GetDataSourceURLForFrame(frame)));
+
+ module_system->RegisterNativeHandler("chrome_hidden",
+ scoped_ptr<NativeHandler>(new ChromeHiddenNativeHandler()));
+ module_system->RegisterNativeHandler("context_info",
+ scoped_ptr<NativeHandler>(new ContextInfoNativeHandler(
+ this,
+ is_bindings_allowed,
+ frame,
+ world_id)));
+ module_system->RegisterNativeHandler("print",
+ scoped_ptr<NativeHandler>(new PrintNativeHandler()));
+
const Extension* extension = extensions_.GetByID(context->extension_id());
int manifest_version = 1;
if (extension)
manifest_version = extension->manifest_version();
+ module_system->RunString("var chrome; chrome = chrome || {};",
+ "setup-chrome-object");
+ module_system->Require("setup_bindings");
+ module_system->set_natives_enabled(false);
+
+ context->set_module_system(module_system.Pass());
+
context->DispatchOnLoadEvent(
is_extension_process_,
ChromeRenderProcessObserver::is_incognito_process(),
@@ -399,12 +566,6 @@ void ExtensionDispatcher::WillReleaseScriptContext(
context->DispatchOnUnloadEvent();
- ChromeV8Extension::InstanceSet extensions = ChromeV8Extension::GetAll();
- for (ChromeV8Extension::InstanceSet::const_iterator iter = extensions.begin();
- iter != extensions.end(); ++iter) {
- (*iter)->ContextWillBeReleased(context);
- }
-
v8_context_set_.Remove(context);
VLOG(1) << "Num tracked contexts: " << v8_context_set_.size();
}
@@ -414,7 +575,7 @@ void ExtensionDispatcher::SetTestExtensionId(const std::string& id) {
}
bool ExtensionDispatcher::IsTestExtensionId(const std::string& id) {
- return id == test_extension_id_;
+ return !test_extension_id_.empty() && id == test_extension_id_;
}
void ExtensionDispatcher::OnActivateApplication(
diff --git a/chrome/renderer/extensions/extension_dispatcher.h b/chrome/renderer/extensions/extension_dispatcher.h
index e72c269..b1dfb40 100644
--- a/chrome/renderer/extensions/extension_dispatcher.h
+++ b/chrome/renderer/extensions/extension_dispatcher.h
@@ -15,8 +15,10 @@
#include "content/public/renderer/render_process_observer.h"
#include "chrome/common/extensions/extension_set.h"
#include "chrome/renderer/extensions/chrome_v8_context_set.h"
+#include "chrome/renderer/resource_bundle_source_map.h"
#include "v8/include/v8.h"
+class ModuleSystem;
class GURL;
class URLPattern;
class UserScriptSlave;
@@ -55,12 +57,18 @@ class ExtensionDispatcher : public content::RenderProcessObserver {
bool IsApplicationActive(const std::string& extension_id) const;
bool IsExtensionActive(const std::string& extension_id) const;
+ // Whether or not we should set up custom bindings for this api.
+ bool AllowCustomAPI(WebKit::WebFrame* frame,
+ const std::string& custom_binding_api_name,
+ int world_id);
+
// See WebKit::WebPermissionClient::allowScriptExtension
// TODO(koz): Remove once WebKit no longer calls this.
bool AllowScriptExtension(WebKit::WebFrame* frame,
const std::string& v8_extension_name,
int extension_group);
+ // TODO(koz): Remove once WebKit no longer calls this.
bool AllowScriptExtension(WebKit::WebFrame* frame,
const std::string& v8_extension_name,
int extension_group,
@@ -137,6 +145,12 @@ class ExtensionDispatcher : public content::RenderProcessObserver {
const Extension* extension,
const URLPatternSet& origins);
+ void RegisterNativeHandlers(ModuleSystem* module_system,
+ ChromeV8Context* context);
+
+ // Inserts static source code into |source_map_|.
+ void PopulateSourceMap();
+
// Finds the extension ID for the current context. This is determined from
// |world_id| if it's non-zero, or the URL in |frame| if it is.
std::string GetExtensionID(WebKit::WebFrame* frame, int world_id);
@@ -182,6 +196,8 @@ class ExtensionDispatcher : public content::RenderProcessObserver {
bool webrequest_adblock_plus_;
bool webrequest_other_;
+ ResourceBundleSourceMap source_map_;
+
DISALLOW_COPY_AND_ASSIGN(ExtensionDispatcher);
};
diff --git a/chrome/renderer/extensions/file_browser_handler_custom_bindings.cc b/chrome/renderer/extensions/file_browser_handler_custom_bindings.cc
index 0688839..015d0b5 100644
--- a/chrome/renderer/extensions/file_browser_handler_custom_bindings.cc
+++ b/chrome/renderer/extensions/file_browser_handler_custom_bindings.cc
@@ -13,18 +13,9 @@
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h"
-namespace extensions {
-
-FileBrowserHandlerCustomBindings::FileBrowserHandlerCustomBindings(
- int dependency_count,
- const char** dependencies)
- : ChromeV8Extension("extensions/file_browser_handler_custom_bindings.js",
- IDR_FILE_BROWSER_HANDLER_CUSTOM_BINDINGS_JS,
- dependency_count,
- dependencies,
- NULL) {}
+namespace {
-static v8::Handle<v8::Value> GetExternalFileEntry(const v8::Arguments& args) {
+v8::Handle<v8::Value> GetExternalFileEntry(const v8::Arguments& args) {
// TODO(zelidrag): Make this magic work on other platforms when file browser
// matures enough on ChromeOS.
#if defined(OS_CHROMEOS)
@@ -54,13 +45,14 @@ static v8::Handle<v8::Value> GetExternalFileEntry(const v8::Arguments& args) {
#endif
}
-v8::Handle<v8::FunctionTemplate>
-FileBrowserHandlerCustomBindings::GetNativeFunction(
- v8::Handle<v8::String> name) {
- if (name->Equals(v8::String::New("GetExternalFileEntry")))
- return v8::FunctionTemplate::New(GetExternalFileEntry);
- else
- return ChromeV8Extension::GetNativeFunction(name);
+} // namespace
+
+namespace extensions {
+
+FileBrowserHandlerCustomBindings::FileBrowserHandlerCustomBindings()
+ : ChromeV8Extension(NULL) {
+ RouteStaticFunction("GetExternalFileEntry", &GetExternalFileEntry);
}
+
} // namespace extensions
diff --git a/chrome/renderer/extensions/file_browser_handler_custom_bindings.h b/chrome/renderer/extensions/file_browser_handler_custom_bindings.h
index 23ec5a8..354686b 100644
--- a/chrome/renderer/extensions/file_browser_handler_custom_bindings.h
+++ b/chrome/renderer/extensions/file_browser_handler_custom_bindings.h
@@ -14,13 +14,9 @@ namespace extensions {
// Custom bindings for the fileBrowserHandler API.
class FileBrowserHandlerCustomBindings : public ChromeV8Extension {
public:
- FileBrowserHandlerCustomBindings(
- int dependency_count, const char** dependencies);
+ FileBrowserHandlerCustomBindings();
private:
- virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction(
- v8::Handle<v8::String> name) OVERRIDE;
-
DISALLOW_COPY_AND_ASSIGN(FileBrowserHandlerCustomBindings);
};
diff --git a/chrome/renderer/extensions/file_browser_private_custom_bindings.cc b/chrome/renderer/extensions/file_browser_private_custom_bindings.cc
index a36e606..1731552 100644
--- a/chrome/renderer/extensions/file_browser_private_custom_bindings.cc
+++ b/chrome/renderer/extensions/file_browser_private_custom_bindings.cc
@@ -13,16 +13,7 @@
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h"
-namespace extensions {
-
-FileBrowserPrivateCustomBindings::FileBrowserPrivateCustomBindings(
- int dependency_count,
- const char** dependencies)
- : ChromeV8Extension("extensions/file_browser_private_custom_bindings.js",
- IDR_FILE_BROWSER_PRIVATE_CUSTOM_BINDINGS_JS,
- dependency_count,
- dependencies,
- NULL) {}
+namespace {
static v8::Handle<v8::Value> GetLocalFileSystem(
const v8::Arguments& args) {
@@ -40,13 +31,13 @@ static v8::Handle<v8::Value> GetLocalFileSystem(
WebKit::WebString::fromUTF8(path.c_str()));
}
-v8::Handle<v8::FunctionTemplate>
-FileBrowserPrivateCustomBindings::GetNativeFunction(
- v8::Handle<v8::String> name) {
- if (name->Equals(v8::String::New("GetLocalFileSystem")))
- return v8::FunctionTemplate::New(GetLocalFileSystem);
+} // namespace
+
+namespace extensions {
- return ChromeV8Extension::GetNativeFunction(name);
+FileBrowserPrivateCustomBindings::FileBrowserPrivateCustomBindings()
+ : ChromeV8Extension(NULL) {
+ RouteStaticFunction("GetLocalFileSystem", &GetLocalFileSystem);
}
} // namespace extensions
diff --git a/chrome/renderer/extensions/file_browser_private_custom_bindings.h b/chrome/renderer/extensions/file_browser_private_custom_bindings.h
index d987a06..191c0dd 100644
--- a/chrome/renderer/extensions/file_browser_private_custom_bindings.h
+++ b/chrome/renderer/extensions/file_browser_private_custom_bindings.h
@@ -14,13 +14,9 @@ namespace extensions {
// Custom bindings for the fileBrowserPrivate API.
class FileBrowserPrivateCustomBindings : public ChromeV8Extension {
public:
- FileBrowserPrivateCustomBindings(
- int dependency_count, const char** dependencies);
+ FileBrowserPrivateCustomBindings();
private:
- virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction(
- v8::Handle<v8::String> name) OVERRIDE;
-
DISALLOW_COPY_AND_ASSIGN(FileBrowserPrivateCustomBindings);
};
diff --git a/chrome/renderer/extensions/i18n_custom_bindings.cc b/chrome/renderer/extensions/i18n_custom_bindings.cc
index 982acbf..afd4be7 100644
--- a/chrome/renderer/extensions/i18n_custom_bindings.cc
+++ b/chrome/renderer/extensions/i18n_custom_bindings.cc
@@ -12,21 +12,9 @@
namespace extensions {
-I18NCustomBindings::I18NCustomBindings(
- int dependency_count, const char** dependencies)
- : ChromeV8Extension(
- "extensions/i18n_custom_bindings.js",
- IDR_I18N_CUSTOM_BINDINGS_JS,
- dependency_count,
- dependencies,
- NULL) {}
-
-v8::Handle<v8::FunctionTemplate> I18NCustomBindings::GetNativeFunction(
- v8::Handle<v8::String> name) {
- if (name->Equals(v8::String::New("GetL10nMessage")))
- return v8::FunctionTemplate::New(GetL10nMessage);
-
- return ChromeV8Extension::GetNativeFunction(name);
+I18NCustomBindings::I18NCustomBindings()
+ : ChromeV8Extension(NULL) {
+ RouteStaticFunction("GetL10nMessage", &GetL10nMessage);
}
// static
diff --git a/chrome/renderer/extensions/i18n_custom_bindings.h b/chrome/renderer/extensions/i18n_custom_bindings.h
index 1cc8743..e0ca0df 100644
--- a/chrome/renderer/extensions/i18n_custom_bindings.h
+++ b/chrome/renderer/extensions/i18n_custom_bindings.h
@@ -13,10 +13,7 @@ namespace extensions {
// Implements custom bindings for the i18n API.
class I18NCustomBindings : public ChromeV8Extension {
public:
- I18NCustomBindings(int dependency_count, const char** dependencies);
-
- virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction(
- v8::Handle<v8::String> name) OVERRIDE;
+ I18NCustomBindings();
private:
static v8::Handle<v8::Value> GetL10nMessage(const v8::Arguments& args);
diff --git a/chrome/renderer/extensions/json_schema_unittest.cc b/chrome/renderer/extensions/json_schema_unittest.cc
index 1e76b41..c4b0614 100644
--- a/chrome/renderer/extensions/json_schema_unittest.cc
+++ b/chrome/renderer/extensions/json_schema_unittest.cc
@@ -25,15 +25,14 @@ class JsonSchemaTest : public V8UnitTest {
std::string code = ResourceBundle::GetSharedInstance().GetRawDataResource(
IDR_JSON_SCHEMA_JS).as_string();
- // This is a nasty hack, but it is easier to test the code if we don't use
- // it as a v8 extension. So replace the only bit that relies on that with a
- // more easily testable implementation.
- ReplaceFirstSubstringAfterOffset(&code, 0,
- "native function GetChromeHidden();",
- "function GetChromeHidden() {\n"
- " if (!this.chromeHidden) this.chromeHidden = {};\n"
- " return this.chromeHidden;\n"
- "}");
+ // json_schema.js expects to have requireNative() defined.
+ ExecuteScriptInContext(
+ "function requireNative(id) {"
+ " return {"
+ " GetChromeHidden: function() { return {}; },"
+ " };"
+ "}",
+ "test-code");
ExecuteScriptInContext(code, kJsonSchema);
// Add the test functions to the context.
diff --git a/chrome/renderer/extensions/miscellaneous_bindings.cc b/chrome/renderer/extensions/miscellaneous_bindings.cc
index 31a8923..25fc895 100644
--- a/chrome/renderer/extensions/miscellaneous_bindings.cc
+++ b/chrome/renderer/extensions/miscellaneous_bindings.cc
@@ -62,31 +62,18 @@ static void ClearPortData(int port_id) {
}
const char kPortClosedError[] = "Attempting to use a disconnected port object";
-const char* kExtensionDeps[] = { "extensions/event.js" };
class ExtensionImpl : public ChromeV8Extension {
public:
explicit ExtensionImpl(ExtensionDispatcher* dispatcher)
- : ChromeV8Extension("extensions/miscellaneous_bindings.js",
- IDR_MISCELLANEOUS_BINDINGS_JS,
- arraysize(kExtensionDeps), kExtensionDeps,
- dispatcher) {
+ : ChromeV8Extension(dispatcher) {
+ RouteStaticFunction("CloseChannel", &CloseChannel);
+ RouteStaticFunction("PortAddRef", &PortAddRef);
+ RouteStaticFunction("PortRelease", &PortRelease);
+ RouteStaticFunction("PostMessage", &PostMessage);
}
- ~ExtensionImpl() {}
- virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction(
- v8::Handle<v8::String> name) {
- if (name->Equals(v8::String::New("PostMessage"))) {
- return v8::FunctionTemplate::New(PostMessage);
- } else if (name->Equals(v8::String::New("CloseChannel"))) {
- return v8::FunctionTemplate::New(CloseChannel);
- } else if (name->Equals(v8::String::New("PortAddRef"))) {
- return v8::FunctionTemplate::New(PortAddRef);
- } else if (name->Equals(v8::String::New("PortRelease"))) {
- return v8::FunctionTemplate::New(PortRelease);
- }
- return ChromeV8Extension::GetNativeFunction(name);
- }
+ ~ExtensionImpl() {}
// Sends a message along the given channel.
static v8::Handle<v8::Value> PostMessage(const v8::Arguments& args) {
@@ -155,9 +142,8 @@ class ExtensionImpl : public ChromeV8Extension {
namespace extensions {
-v8::Extension* MiscellaneousBindings::Get(ExtensionDispatcher* dispatcher) {
- static v8::Extension* extension = new ExtensionImpl(dispatcher);
- return extension;
+ChromeV8Extension* MiscellaneousBindings::Get(ExtensionDispatcher* dispatcher) {
+ return new ExtensionImpl(dispatcher);
}
void MiscellaneousBindings::DeliverMessage(
diff --git a/chrome/renderer/extensions/miscellaneous_bindings.h b/chrome/renderer/extensions/miscellaneous_bindings.h
index 1db641b..0df26fa 100644
--- a/chrome/renderer/extensions/miscellaneous_bindings.h
+++ b/chrome/renderer/extensions/miscellaneous_bindings.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -10,6 +10,7 @@
#include "chrome/renderer/extensions/chrome_v8_context_set.h"
+class ChromeV8Extension;
class ExtensionDispatcher;
namespace content {
@@ -30,7 +31,7 @@ namespace extensions {
class MiscellaneousBindings {
public:
// Creates an instance of the extension.
- static v8::Extension* Get(ExtensionDispatcher* dispatcher);
+ static ChromeV8Extension* Get(ExtensionDispatcher* dispatcher);
// Delivers a message sent using content script messaging to some of the
// contexts in |bindings_context_set|. If |restrict_to_render_view| is
diff --git a/chrome/renderer/extensions/page_actions_custom_bindings.cc b/chrome/renderer/extensions/page_actions_custom_bindings.cc
index 0d9d61a..b6e86ee 100644
--- a/chrome/renderer/extensions/page_actions_custom_bindings.cc
+++ b/chrome/renderer/extensions/page_actions_custom_bindings.cc
@@ -14,15 +14,10 @@
namespace extensions {
PageActionsCustomBindings::PageActionsCustomBindings(
- int dependency_count,
- const char** dependencies,
ExtensionDispatcher* extension_dispatcher)
- : ChromeV8Extension(
- "extensions/page_actions_custom_bindings.js",
- IDR_PAGE_ACTIONS_CUSTOM_BINDINGS_JS,
- dependency_count,
- dependencies,
- extension_dispatcher) {}
+ : ChromeV8Extension(extension_dispatcher) {
+ RouteStaticFunction("GetCurrentPageActions", &GetCurrentPageActions);
+}
// static
v8::Handle<v8::Value> PageActionsCustomBindings::GetCurrentPageActions(
@@ -45,15 +40,4 @@ v8::Handle<v8::Value> PageActionsCustomBindings::GetCurrentPageActions(
return page_action_vector;
}
-
-v8::Handle<v8::FunctionTemplate> PageActionsCustomBindings::GetNativeFunction(
- v8::Handle<v8::String> name) {
- if (name->Equals(v8::String::New("GetCurrentPageActions"))) {
- return v8::FunctionTemplate::New(GetCurrentPageActions,
- v8::External::New(this));
- }
-
- return ChromeV8Extension::GetNativeFunction(name);
-}
-
} // extensions
diff --git a/chrome/renderer/extensions/page_actions_custom_bindings.h b/chrome/renderer/extensions/page_actions_custom_bindings.h
index 09e68d9..1faad35 100644
--- a/chrome/renderer/extensions/page_actions_custom_bindings.h
+++ b/chrome/renderer/extensions/page_actions_custom_bindings.h
@@ -15,13 +15,7 @@ namespace extensions {
// Implements custom bindings for the pageActions API.
class PageActionsCustomBindings : public ChromeV8Extension {
public:
- PageActionsCustomBindings(
- int dependency_count,
- const char** dependencies,
- ExtensionDispatcher* extension_dispatcher);
-
- virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction(
- v8::Handle<v8::String> name) OVERRIDE;
+ explicit PageActionsCustomBindings(ExtensionDispatcher* extension_dispatcher);
private:
static v8::Handle<v8::Value> GetCurrentPageActions(const v8::Arguments& args);
diff --git a/chrome/renderer/extensions/page_capture_custom_bindings.cc b/chrome/renderer/extensions/page_capture_custom_bindings.cc
index e37cdab..c7e41ea 100644
--- a/chrome/renderer/extensions/page_capture_custom_bindings.cc
+++ b/chrome/renderer/extensions/page_capture_custom_bindings.cc
@@ -13,18 +13,15 @@
namespace extensions {
-PageCaptureCustomBindings::PageCaptureCustomBindings(
- int dependency_count,
- const char** dependencies)
- : ChromeV8Extension(
- "extensions/page_capture_custom_bindings.js",
- IDR_PAGE_CAPTURE_CUSTOM_BINDINGS_JS,
- dependency_count,
- dependencies,
- NULL) {}
-
-// Creates a Blob with the content of the specified file.
-static v8::Handle<v8::Value> CreateBlob(const v8::Arguments& args) {
+PageCaptureCustomBindings::PageCaptureCustomBindings()
+ : ChromeV8Extension(NULL) {
+ RouteStaticFunction("CreateBlob", &CreateBlob);
+ RouteStaticFunction("SendResponseAck", &SendResponseAck);
+}
+
+// static
+v8::Handle<v8::Value> PageCaptureCustomBindings::CreateBlob(
+ const v8::Arguments& args) {
CHECK(args.Length() == 2);
CHECK(args[0]->IsString());
CHECK(args[1]->IsInt32());
@@ -48,15 +45,4 @@ v8::Handle<v8::Value> PageCaptureCustomBindings::SendResponseAck(
return v8::Undefined();
}
-v8::Handle<v8::FunctionTemplate> PageCaptureCustomBindings::GetNativeFunction(
- v8::Handle<v8::String> name) {
- if (name->Equals(v8::String::New("CreateBlob"))) {
- return v8::FunctionTemplate::New(CreateBlob, v8::External::New(this));
- } else if (name->Equals(v8::String::New("SendResponseAck"))) {
- return v8::FunctionTemplate::New(SendResponseAck, v8::External::New(this));
- }
-
- return ChromeV8Extension::GetNativeFunction(name);
-}
-
} // namespace extensions
diff --git a/chrome/renderer/extensions/page_capture_custom_bindings.h b/chrome/renderer/extensions/page_capture_custom_bindings.h
index a6ec433..4796e13 100644
--- a/chrome/renderer/extensions/page_capture_custom_bindings.h
+++ b/chrome/renderer/extensions/page_capture_custom_bindings.h
@@ -13,12 +13,11 @@ namespace extensions {
// Implements custom bindings for the pageCapture API.
class PageCaptureCustomBindings : public ChromeV8Extension {
public:
- PageCaptureCustomBindings(int dependency_count, const char** dependencies);
-
- virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction(
- v8::Handle<v8::String> name) OVERRIDE;
+ PageCaptureCustomBindings();
private:
+ // Creates a Blob with the content of the specified file.
+ static v8::Handle<v8::Value> CreateBlob(const v8::Arguments& args);
static v8::Handle<v8::Value> SendResponseAck(const v8::Arguments& args);
};
diff --git a/chrome/renderer/extensions/schema_generated_bindings.cc b/chrome/renderer/extensions/schema_generated_bindings.cc
index c0e0725..eda15d8 100644
--- a/chrome/renderer/extensions/schema_generated_bindings.cc
+++ b/chrome/renderer/extensions/schema_generated_bindings.cc
@@ -51,13 +51,6 @@ using WebKit::WebSecurityOrigin;
namespace {
-const char* kExtensionDeps[] = {
- "extensions/event.js",
- "extensions/json_schema.js",
- "extensions/miscellaneous_bindings.js",
- "extensions/apitest.js"
-};
-
// Contains info relevant to a pending API request.
struct PendingRequest {
public :
@@ -77,11 +70,12 @@ base::LazyInstance<PendingRequestMap> g_pending_requests =
class ExtensionImpl : public ChromeV8Extension {
public:
explicit ExtensionImpl(ExtensionDispatcher* extension_dispatcher)
- : ChromeV8Extension("extensions/schema_generated_bindings.js",
- IDR_SCHEMA_GENERATED_BINDINGS_JS,
- arraysize(kExtensionDeps),
- kExtensionDeps,
- extension_dispatcher) {
+ : ChromeV8Extension(extension_dispatcher) {
+ RouteStaticFunction("GetExtensionAPIDefinition",
+ &GetExtensionAPIDefinition);
+ RouteStaticFunction("GetNextRequestId", &GetNextRequestId);
+ RouteStaticFunction("StartRequest", &StartRequest);
+ RouteStaticFunction("SetIconCommon", &SetIconCommon);
}
~ExtensionImpl() {
@@ -94,24 +88,6 @@ class ExtensionImpl : public ChromeV8Extension {
}
}
- virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction(
- v8::Handle<v8::String> name) OVERRIDE {
- if (name->Equals(v8::String::New("GetExtensionAPIDefinition"))) {
- return v8::FunctionTemplate::New(GetExtensionAPIDefinition,
- v8::External::New(this));
- } else if (name->Equals(v8::String::New("GetNextRequestId"))) {
- return v8::FunctionTemplate::New(GetNextRequestId);
- } else if (name->Equals(v8::String::New("StartRequest"))) {
- return v8::FunctionTemplate::New(StartRequest,
- v8::External::New(this));
- } else if (name->Equals(v8::String::New("SetIconCommon"))) {
- return v8::FunctionTemplate::New(SetIconCommon,
- v8::External::New(this));
- }
-
- return ChromeV8Extension::GetNativeFunction(name);
- }
-
private:
static v8::Handle<v8::Value> GetV8SchemaForAPI(
ExtensionImpl* self,
@@ -347,12 +323,9 @@ class ExtensionImpl : public ChromeV8Extension {
namespace extensions {
-v8::Extension* SchemaGeneratedBindings::Get(
+ChromeV8Extension* SchemaGeneratedBindings::Get(
ExtensionDispatcher* extension_dispatcher) {
- static v8::Extension* extension = new ExtensionImpl(extension_dispatcher);
- CHECK_EQ(extension_dispatcher,
- static_cast<ExtensionImpl*>(extension)->extension_dispatcher());
- return extension;
+ return new ExtensionImpl(extension_dispatcher);
}
// static
diff --git a/chrome/renderer/extensions/schema_generated_bindings.h b/chrome/renderer/extensions/schema_generated_bindings.h
index 1785171..e50ed96 100644
--- a/chrome/renderer/extensions/schema_generated_bindings.h
+++ b/chrome/renderer/extensions/schema_generated_bindings.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -10,6 +10,7 @@
class ExtensionDispatcher;
class ChromeV8ContextSet;
+class ChromeV8Extension;
namespace v8 {
class Extension;
@@ -21,7 +22,7 @@ namespace extensions {
// declarations in chrome/common/extensions/api/.
class SchemaGeneratedBindings {
public:
- static v8::Extension* Get(ExtensionDispatcher* extension_dispatcher);
+ static ChromeV8Extension* Get(ExtensionDispatcher* extension_dispatcher);
// Handles a response to an API request. Sets |extension_id|.
static void HandleResponse(const ChromeV8ContextSet& contexts,
diff --git a/chrome/renderer/extensions/tabs_custom_bindings.cc b/chrome/renderer/extensions/tabs_custom_bindings.cc
index abb2262..3d908bb 100644
--- a/chrome/renderer/extensions/tabs_custom_bindings.cc
+++ b/chrome/renderer/extensions/tabs_custom_bindings.cc
@@ -15,14 +15,10 @@
namespace extensions {
-TabsCustomBindings::TabsCustomBindings(
- int dependency_count, const char** dependencies)
- : ChromeV8Extension(
- "extensions/tabs_custom_bindings.js",
- IDR_TABS_CUSTOM_BINDINGS_JS,
- dependency_count,
- dependencies,
- NULL) {}
+TabsCustomBindings::TabsCustomBindings()
+ : ChromeV8Extension(NULL) {
+ RouteStaticFunction("OpenChannelToTab", &OpenChannelToTab);
+}
// static
v8::Handle<v8::Value> TabsCustomBindings::OpenChannelToTab(
@@ -47,12 +43,4 @@ v8::Handle<v8::Value> TabsCustomBindings::OpenChannelToTab(
return v8::Undefined();
}
-v8::Handle<v8::FunctionTemplate> TabsCustomBindings::GetNativeFunction(
- v8::Handle<v8::String> name) {
- if (name->Equals(v8::String::New("OpenChannelToTab")))
- return v8::FunctionTemplate::New(OpenChannelToTab);
-
- return ChromeV8Extension::GetNativeFunction(name);
-}
-
} // extensions
diff --git a/chrome/renderer/extensions/tabs_custom_bindings.h b/chrome/renderer/extensions/tabs_custom_bindings.h
index 0700a43..ec06979 100644
--- a/chrome/renderer/extensions/tabs_custom_bindings.h
+++ b/chrome/renderer/extensions/tabs_custom_bindings.h
@@ -13,10 +13,7 @@ namespace extensions {
// Implements custom bindings for the tabs API.
class TabsCustomBindings : public ChromeV8Extension {
public:
- TabsCustomBindings(int dependency_count, const char** dependencies);
-
- virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction(
- v8::Handle<v8::String> name) OVERRIDE;
+ TabsCustomBindings();
private:
// Creates a new messaging channel to the tab with the given ID.
diff --git a/chrome/renderer/extensions/tts_custom_bindings.cc b/chrome/renderer/extensions/tts_custom_bindings.cc
index dca526a..33e1887 100644
--- a/chrome/renderer/extensions/tts_custom_bindings.cc
+++ b/chrome/renderer/extensions/tts_custom_bindings.cc
@@ -13,30 +13,18 @@
namespace extensions {
-TTSCustomBindings::TTSCustomBindings(
- int dependency_count,
- const char** dependencies)
- : ChromeV8Extension(
- "extensions/tts_custom_bindings.js",
- IDR_TTS_CUSTOM_BINDINGS_JS,
- dependency_count,
- dependencies,
- NULL) {}
+TTSCustomBindings::TTSCustomBindings()
+ : ChromeV8Extension(NULL) {
+ RouteStaticFunction("GetNextTTSEventId", &GetNextTTSEventId);
+}
-static v8::Handle<v8::Value> GetNextTTSEventId(const v8::Arguments& args) {
+// static
+v8::Handle<v8::Value> TTSCustomBindings::GetNextTTSEventId(
+ const v8::Arguments& args) {
// Note: this works because the TTS API only works in the
// extension process, not content scripts.
static int next_tts_event_id = 1;
return v8::Integer::New(next_tts_event_id++);
}
-v8::Handle<v8::FunctionTemplate>
-TTSCustomBindings::GetNativeFunction(
- v8::Handle<v8::String> name) {
- if (name->Equals(v8::String::New("GetNextTTSEventId")))
- return v8::FunctionTemplate::New(GetNextTTSEventId);
-
- return ChromeV8Extension::GetNativeFunction(name);
-}
-
} // extensions
diff --git a/chrome/renderer/extensions/tts_custom_bindings.h b/chrome/renderer/extensions/tts_custom_bindings.h
index c7598eb..c99a03a 100644
--- a/chrome/renderer/extensions/tts_custom_bindings.h
+++ b/chrome/renderer/extensions/tts_custom_bindings.h
@@ -13,10 +13,10 @@ namespace extensions {
// Implements custom bindings for the tts API.
class TTSCustomBindings : public ChromeV8Extension {
public:
- TTSCustomBindings(int dependency_count, const char** dependencies);
+ TTSCustomBindings();
- virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction(
- v8::Handle<v8::String> name) OVERRIDE;
+ private:
+ static v8::Handle<v8::Value> GetNextTTSEventId(const v8::Arguments& args);
};
} // extensions
diff --git a/chrome/renderer/extensions/web_request_custom_bindings.cc b/chrome/renderer/extensions/web_request_custom_bindings.cc
index 3246926..83f716c 100644
--- a/chrome/renderer/extensions/web_request_custom_bindings.cc
+++ b/chrome/renderer/extensions/web_request_custom_bindings.cc
@@ -12,18 +12,15 @@
namespace extensions {
-WebRequestCustomBindings::WebRequestCustomBindings(
- int dependency_count,
- const char** dependencies)
- : ChromeV8Extension(
- "extensions/web_request_custom_bindings.js",
- IDR_WEB_REQUEST_CUSTOM_BINDINGS_JS,
- dependency_count,
- dependencies,
- NULL) {}
+WebRequestCustomBindings::WebRequestCustomBindings()
+ : ChromeV8Extension(NULL) {
+ RouteStaticFunction("GetUniqueSubEventName", &GetUniqueSubEventName);
+}
// Attach an event name to an object.
-static v8::Handle<v8::Value> GetUniqueSubEventName(const v8::Arguments& args) {
+// static
+v8::Handle<v8::Value> WebRequestCustomBindings::GetUniqueSubEventName(
+ const v8::Arguments& args) {
static int next_event_id = 0;
DCHECK(args.Length() == 1);
DCHECK(args[0]->IsString());
@@ -33,13 +30,5 @@ static v8::Handle<v8::Value> GetUniqueSubEventName(const v8::Arguments& args) {
return v8::String::New(unique_event_name.c_str());
}
-v8::Handle<v8::FunctionTemplate> WebRequestCustomBindings::GetNativeFunction(
- v8::Handle<v8::String> name) {
- if (name->Equals(v8::String::New("GetUniqueSubEventName")))
- return v8::FunctionTemplate::New(GetUniqueSubEventName);
-
- return ChromeV8Extension::GetNativeFunction(name);
-}
-
} // extensions
diff --git a/chrome/renderer/extensions/web_request_custom_bindings.h b/chrome/renderer/extensions/web_request_custom_bindings.h
index 285ae88..028c37d 100644
--- a/chrome/renderer/extensions/web_request_custom_bindings.h
+++ b/chrome/renderer/extensions/web_request_custom_bindings.h
@@ -13,10 +13,10 @@ namespace extensions {
// Implements custom bindings for the webRequest API.
class WebRequestCustomBindings : public ChromeV8Extension {
public:
- WebRequestCustomBindings(int dependency_count, const char** dependencies);
+ WebRequestCustomBindings();
- virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction(
- v8::Handle<v8::String> name) OVERRIDE;
+ private:
+ static v8::Handle<v8::Value> GetUniqueSubEventName(const v8::Arguments& args);
};
} // extensions
diff --git a/chrome/renderer/extensions/webstore_bindings.cc b/chrome/renderer/extensions/webstore_bindings.cc
index 5991e6a..7214db9 100644
--- a/chrome/renderer/extensions/webstore_bindings.cc
+++ b/chrome/renderer/extensions/webstore_bindings.cc
@@ -13,7 +13,6 @@
#include "grit/renderer_resources.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebNode.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebNodeList.h"
#include "v8/include/v8.h"
@@ -48,69 +47,17 @@ const char kInvalidWebstoreItemUrlError[] =
// (successful or not) via OnInlineWebstoreInstallResponse.
int g_next_install_id = 0;
-class WebstoreBindingsHandler : public ChromeV8ExtensionHandler {
- public:
- WebstoreBindingsHandler(
- ExtensionDispatcher* dispatcher, ChromeV8Context* context);
-
- // ChromeV8ExtensionHandler
- virtual v8::Handle<v8::Value> HandleNativeFunction(
- const std::string& name,
- const v8::Arguments& arguments) OVERRIDE;
-
- // IPC::Channel::Listener
- virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
-
- private:
- v8::Handle<v8::Value> Install(const v8::Arguments& args);
-
- void OnInlineWebstoreInstallResponse(
- int install_id, bool success, const std::string& error);
-
- // Extracts a Web Store item ID from a <link rel="chrome-webstore-item"
- // href="https://chrome.google.com/webstore/detail/id"> node found in the
- // frame. On success, true will be returned and the |webstore_item_id|
- // parameter will be populated with the ID. On failure, false will be returned
- // and |error| will be populated with the error.
- static bool GetWebstoreItemIdFromFrame(
- WebFrame* frame, const std::string& preferred_store_link_url,
- std::string* webstore_item_id, std::string* error);
-
- ExtensionDispatcher* dispatcher_;
- DISALLOW_COPY_AND_ASSIGN(WebstoreBindingsHandler);
-};
-
} // anonymous namespace
-WebstoreBindings::WebstoreBindings(ExtensionDispatcher* dispatcher)
- : ChromeV8Extension("extensions/webstore.js", IDR_WEBSTORE_BINDINGS_JS,
- dispatcher) {
-}
-
-ChromeV8ExtensionHandler* WebstoreBindings::CreateHandler(
- ChromeV8Context* context) {
- return new WebstoreBindingsHandler(extension_dispatcher(), context);
-}
-
-WebstoreBindingsHandler::WebstoreBindingsHandler(
- ExtensionDispatcher* dispatcher,
+WebstoreBindings::WebstoreBindings(ExtensionDispatcher* dispatcher,
ChromeV8Context* context)
- : ChromeV8ExtensionHandler(context),
- dispatcher_(dispatcher) {
-}
-
-v8::Handle<v8::Value> WebstoreBindingsHandler::HandleNativeFunction(
- const std::string& name, const v8::Arguments& args) {
- if (name == "Install") {
- return Install(args);
- } else {
- CHECK(false) << "Unknown native function: " << name;
- }
-
- return v8::Undefined();
+ : ChromeV8Extension(dispatcher),
+ ChromeV8ExtensionHandler(context) {
+ RouteFunction("Install",
+ base::Bind(&WebstoreBindings::Install, base::Unretained(this)));
}
-v8::Handle<v8::Value> WebstoreBindingsHandler::Install(
+v8::Handle<v8::Value> WebstoreBindings::Install(
const v8::Arguments& args) {
WebFrame* frame = WebFrame::frameForCurrentContext();
if (!frame || !frame->view())
@@ -161,7 +108,7 @@ v8::Handle<v8::Value> WebstoreBindingsHandler::Install(
}
// static
-bool WebstoreBindingsHandler::GetWebstoreItemIdFromFrame(
+bool WebstoreBindings::GetWebstoreItemIdFromFrame(
WebFrame* frame, const std::string& preferred_store_link_url,
std::string* webstore_item_id, std::string* error) {
if (frame != frame->top()) {
@@ -247,8 +194,8 @@ bool WebstoreBindingsHandler::GetWebstoreItemIdFromFrame(
return false;
}
-bool WebstoreBindingsHandler::OnMessageReceived(const IPC::Message& message) {
- IPC_BEGIN_MESSAGE_MAP(WebstoreBindingsHandler, message)
+bool WebstoreBindings::OnMessageReceived(const IPC::Message& message) {
+ IPC_BEGIN_MESSAGE_MAP(WebstoreBindings, message)
IPC_MESSAGE_HANDLER(ExtensionMsg_InlineWebstoreInstallResponse,
OnInlineWebstoreInstallResponse)
IPC_MESSAGE_UNHANDLED(CHECK(false) << "Unhandled IPC message")
@@ -256,7 +203,7 @@ bool WebstoreBindingsHandler::OnMessageReceived(const IPC::Message& message) {
return true;
}
-void WebstoreBindingsHandler::OnInlineWebstoreInstallResponse(
+void WebstoreBindings::OnInlineWebstoreInstallResponse(
int install_id,
bool success,
const std::string& error) {
diff --git a/chrome/renderer/extensions/webstore_bindings.h b/chrome/renderer/extensions/webstore_bindings.h
index 098f888..33ac48e 100644
--- a/chrome/renderer/extensions/webstore_bindings.h
+++ b/chrome/renderer/extensions/webstore_bindings.h
@@ -8,21 +8,37 @@
#include "base/compiler_specific.h"
#include "chrome/renderer/extensions/chrome_v8_extension.h"
+#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
class ChromeV8Context;
// A V8 extension that creates an object at window.chrome.webstore. This object
// allows JavaScript to initiate inline installs of apps that are listed in the
// Chrome Web Store (CWS).
-class WebstoreBindings : public ChromeV8Extension {
+class WebstoreBindings : public ChromeV8Extension,
+ public ChromeV8ExtensionHandler {
public:
- explicit WebstoreBindings(ExtensionDispatcher* dispatcher);
+ explicit WebstoreBindings(ExtensionDispatcher* dispatcher,
+ ChromeV8Context* context);
- protected:
- virtual ChromeV8ExtensionHandler* CreateHandler(
- ChromeV8Context* context) OVERRIDE;
+ // IPC::Channel::Listener
+ virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE;
private:
+ v8::Handle<v8::Value> Install(const v8::Arguments& args);
+
+ void OnInlineWebstoreInstallResponse(
+ int install_id, bool success, const std::string& error);
+
+ // Extracts a Web Store item ID from a <link rel="chrome-webstore-item"
+ // href="https://chrome.google.com/webstore/detail/id"> node found in the
+ // frame. On success, true will be returned and the |webstore_item_id|
+ // parameter will be populated with the ID. On failure, false will be returned
+ // and |error| will be populated with the error.
+ static bool GetWebstoreItemIdFromFrame(
+ WebKit::WebFrame* frame, const std::string& preferred_store_link_url,
+ std::string* webstore_item_id, std::string* error);
+
DISALLOW_COPY_AND_ASSIGN(WebstoreBindings);
};
diff --git a/chrome/renderer/module_system.cc b/chrome/renderer/module_system.cc
index 6c685f3..30f5906 100644
--- a/chrome/renderer/module_system.cc
+++ b/chrome/renderer/module_system.cc
@@ -11,18 +11,11 @@
namespace {
-v8::Handle<v8::String> GetResource(int resourceId) {
- const ResourceBundle& resource_bundle = ResourceBundle::GetSharedInstance();
- return v8::String::NewExternal(new StaticV8ExternalAsciiStringResource(
- resource_bundle.GetRawDataResource(resourceId)));
-}
-
} // namespace
-ModuleSystem::ModuleSystem(const std::map<std::string, std::string>* source_map)
- : source_map_(source_map) {
- RouteFunction("Run",
- base::Bind(&ModuleSystem::Run, base::Unretained(this)));
+ModuleSystem::ModuleSystem(SourceMap* source_map)
+ : source_map_(source_map),
+ natives_enabled_(true) {
RouteFunction("GetSource",
base::Bind(&ModuleSystem::GetSource, base::Unretained(this)));
RouteFunction("GetNative",
@@ -47,12 +40,21 @@ void ModuleSystem::RegisterNativeHandler(const std::string& name,
linked_ptr<NativeHandler>(native_handler.release());
}
+void ModuleSystem::RunString(const std::string& code, const std::string& name) {
+ v8::HandleScope handle_scope;
+ RunString(v8::String::New(code.c_str()), v8::String::New(name.c_str()));
+}
+
void ModuleSystem::EnsureRequireLoaded() {
v8::HandleScope handle_scope;
if (!require_.IsEmpty())
return;
v8::Handle<v8::Object> bootstrap = NewInstance();
- v8::Handle<v8::Value> result = RunString(GetResource(IDR_REQUIRE_JS));
+ // NOTE v8 takes ownership of the StaticV8ExternalAsciiStringResource.
+ v8::Handle<v8::String> source = v8::String::NewExternal(
+ new StaticV8ExternalAsciiStringResource(GetResource(IDR_REQUIRE_JS)));
+ v8::Handle<v8::Value> result = RunString(source,
+ v8::String::New("require.js"));
v8::Handle<v8::Function> require_factory =
v8::Handle<v8::Function>::Cast(result);
CHECK(!require_factory.IsEmpty())
@@ -67,32 +69,38 @@ void ModuleSystem::EnsureRequireLoaded() {
v8::Handle<v8::Function>::Cast(require));
}
-v8::Handle<v8::Value> ModuleSystem::RunString(v8::Handle<v8::String> code) {
+v8::Handle<v8::Value> ModuleSystem::RunString(v8::Handle<v8::String> code,
+ v8::Handle<v8::String> name) {
v8::HandleScope handle_scope;
- return handle_scope.Close(v8::Script::New(code)->Run());
-}
-
-v8::Handle<v8::Value> ModuleSystem::Run(const v8::Arguments& args) {
- CHECK_EQ(1, args.Length());
- v8::HandleScope handle_scope;
- return handle_scope.Close(v8::Script::New(args[0]->ToString())->Run());
+ return handle_scope.Close(v8::Script::New(code, name)->Run());
}
v8::Handle<v8::Value> ModuleSystem::GetSource(const v8::Arguments& args) {
CHECK_EQ(1, args.Length());
+
+ v8::HandleScope handle_scope;
std::string module_name = *v8::String::AsciiValue(args[0]->ToString());
- std::map<std::string, std::string>::const_iterator p =
- source_map_->find(module_name);
- if (p == source_map_->end())
+ if (!source_map_->Contains(module_name))
return v8::Undefined();
- return v8::String::New(p->second.c_str());
+ return handle_scope.Close(source_map_->GetSource(module_name));
}
v8::Handle<v8::Value> ModuleSystem::GetNative(const v8::Arguments& args) {
CHECK_EQ(1, args.Length());
+ if (!natives_enabled_)
+ return ThrowException("Natives disabled");
std::string native_name = *v8::String::AsciiValue(args[0]->ToString());
NativeHandlerMap::iterator i = native_handler_map_.find(native_name);
if (i == native_handler_map_.end())
return v8::Undefined();
return i->second->NewInstance();
}
+
+base::StringPiece ModuleSystem::GetResource(int resourceId) {
+ const ResourceBundle& resource_bundle = ResourceBundle::GetSharedInstance();
+ return resource_bundle.GetRawDataResource(resourceId);
+}
+
+v8::Handle<v8::Value> ModuleSystem::ThrowException(const std::string& message) {
+ return v8::ThrowException(v8::String::New(message.c_str()));
+}
diff --git a/chrome/renderer/module_system.h b/chrome/renderer/module_system.h
index b29d8d6..da93423 100644
--- a/chrome/renderer/module_system.h
+++ b/chrome/renderer/module_system.h
@@ -9,12 +9,15 @@
#include "base/compiler_specific.h"
#include "base/memory/linked_ptr.h"
#include "base/memory/scoped_ptr.h"
+#include "base/string_piece.h"
#include "chrome/renderer/native_handler.h"
#include "v8/include/v8.h"
#include <map>
#include <string>
+class SourceMap;
+
// A module system for JS similar to node.js' require() function.
// Each module has three variables in the global scope:
// - exports, an object returned to dependencies who require() this
@@ -27,10 +30,20 @@
//
// Each module in a ModuleSystem is executed at most once and its exports
// object cached.
+//
+// Note that a ModuleSystem must be used only in conjunction with a single
+// v8::Context.
+// TODO(koz): Rename this to JavaScriptModuleSystem.
class ModuleSystem : public NativeHandler {
public:
+ class SourceMap {
+ public:
+ virtual v8::Handle<v8::Value> GetSource(const std::string& name) = 0;
+ virtual bool Contains(const std::string& name) = 0;
+ };
+
// |source_map| is a weak pointer.
- explicit ModuleSystem(const std::map<std::string, std::string>* source_map);
+ explicit ModuleSystem(SourceMap* source_map);
virtual ~ModuleSystem();
// Require the specified module. This is the equivalent of calling
@@ -41,18 +54,27 @@ class ModuleSystem : public NativeHandler {
// calls to requireNative(|name|) from JS will return a new object created by
// |native_handler|.
void RegisterNativeHandler(const std::string& name,
- scoped_ptr<NativeHandler> native_handler);
+ scoped_ptr<NativeHandler> native_handler);
+
+ // Executes |code| in the current context with |name| as the filename.
+ void RunString(const std::string& code, const std::string& name);
+
+ // When false |natives_enabled_| causes calls to GetNative() (the basis of
+ // requireNative() in JS) to throw an exception.
+ void set_natives_enabled(bool natives_enabled) {
+ natives_enabled_ = natives_enabled;
+ }
private:
+ typedef std::map<std::string, linked_ptr<NativeHandler> > NativeHandlerMap;
+
// Ensure that require_ has been evaluated from require.js.
void EnsureRequireLoaded();
- // Run |code| in the current context.
- v8::Handle<v8::Value> RunString(v8::Handle<v8::String> code);
-
- // Run the given code in the current context.
- // |args[0]| - the code to execute.
- v8::Handle<v8::Value> Run(const v8::Arguments& args);
+ // Run |code| in the current context with the name |name| used for stack
+ // traces.
+ v8::Handle<v8::Value> RunString(v8::Handle<v8::String> code,
+ v8::Handle<v8::String> name);
// Return the named source file stored in the source map.
// |args[0]| - the name of a source file in source_map_.
@@ -63,12 +85,17 @@ class ModuleSystem : public NativeHandler {
// |args[0]| - the name of a native handler object.
v8::Handle<v8::Value> GetNative(const v8::Arguments& args);
+ base::StringPiece GetResource(int resource_id);
+
+ // Throws an exception in the calling JS context.
+ v8::Handle<v8::Value> ThrowException(const std::string& message);
+
// A map from module names to the JS source for that module. GetSource()
// performs a lookup on this map.
- const std::map<std::string, std::string>* source_map_;
- typedef std::map<std::string, linked_ptr<NativeHandler> > NativeHandlerMap;
+ SourceMap* source_map_;
NativeHandlerMap native_handler_map_;
v8::Handle<v8::Function> require_;
+ bool natives_enabled_;
};
#endif // CHROME_RENDERER_MODULE_SYSTEM_H_
diff --git a/chrome/renderer/module_system_unittest.cc b/chrome/renderer/module_system_unittest.cc
index bed8a27..47584a3 100644
--- a/chrome/renderer/module_system_unittest.cc
+++ b/chrome/renderer/module_system_unittest.cc
@@ -4,12 +4,14 @@
#include "base/callback.h"
#include "base/memory/scoped_ptr.h"
+#include "base/string_piece.h"
#include "chrome/renderer/module_system.h"
#include "testing/gtest/include/gtest/gtest.h"
#include <map>
#include <string>
+// Native JS functions for doing asserts.
class AssertNatives : public NativeHandler {
public:
AssertNatives()
@@ -33,22 +35,69 @@ class AssertNatives : public NativeHandler {
bool failed_;
};
+class StringSourceMap : public ModuleSystem::SourceMap {
+ public:
+ StringSourceMap() {}
+
+ v8::Handle<v8::Value> GetSource(const std::string& name) OVERRIDE {
+ if (source_map_.count(name) == 0)
+ return v8::Undefined();
+ return v8::String::New(source_map_[name].c_str());
+ }
+
+ bool Contains(const std::string& name) OVERRIDE {
+ return source_map_.count(name);
+ }
+
+ void RegisterModule(const std::string& name, const std::string& source) {
+ source_map_[name] = source;
+ }
+
+ private:
+ std::map<std::string, std::string> source_map_;
+};
+
+// Native JS functions for disabling injection in ModuleSystem.
+class DisableNativesHandler : public NativeHandler {
+ public:
+ explicit DisableNativesHandler(ModuleSystem* module_system)
+ : module_system_(module_system) {
+ RouteFunction("DisableNatives",
+ base::Bind(&DisableNativesHandler::DisableNatives,
+ base::Unretained(this)));
+ }
+
+ v8::Handle<v8::Value> DisableNatives(const v8::Arguments& args) {
+ module_system_->set_natives_enabled(false);
+ return v8::Undefined();
+ }
+
+ private:
+ ModuleSystem* module_system_;
+};
+
class ModuleSystemTest : public testing::Test {
public:
ModuleSystemTest()
: context_(v8::Context::New()),
- assert_natives_(new AssertNatives()) {
+ handle_scope_(),
+ assert_natives_(new AssertNatives()),
+ source_map_(new StringSourceMap()),
+ module_system_(new ModuleSystem(source_map_)) {
context_->Enter();
- source_map_["add"] = "exports.Add = function(x, y) { return x + y; };";
- module_system_.reset(new ModuleSystem(&source_map_));
module_system_->RegisterNativeHandler("assert", scoped_ptr<NativeHandler>(
assert_natives_));
+ RegisterModule("add", "exports.Add = function(x, y) { return x + y; };");
}
~ModuleSystemTest() {
context_.Dispose();
}
+ void RegisterModule(const std::string& name, const std::string& code) {
+ source_map_->RegisterModule(name, code);
+ }
+
virtual void TearDown() {
// All tests must call a native function at least once.
ASSERT_TRUE(assert_natives_->native_function_called());
@@ -56,45 +105,63 @@ class ModuleSystemTest : public testing::Test {
ASSERT_FALSE(try_catch_.HasCaught());
}
+ v8::Persistent<v8::Context> context_;
v8::HandleScope handle_scope_;
v8::TryCatch try_catch_;
- v8::Persistent<v8::Context> context_;
AssertNatives* assert_natives_;
- std::map<std::string, std::string> source_map_;
+ StringSourceMap* source_map_;
scoped_ptr<ModuleSystem> module_system_;
};
TEST_F(ModuleSystemTest, TestRequire) {
- source_map_["test"] =
+ RegisterModule("test",
"var Add = require('add').Add;"
- "requireNative('assert').AssertTrue(Add(3, 5) == 8);";
+ "requireNative('assert').AssertTrue(Add(3, 5) == 8);");
module_system_->Require("test");
}
TEST_F(ModuleSystemTest, TestNestedRequire) {
- source_map_["double"] =
+ RegisterModule("double",
"var Add = require('add').Add;"
- "exports.Double = function(x) { return Add(x, x); };";
- source_map_["test"] =
+ "exports.Double = function(x) { return Add(x, x); };");
+ RegisterModule("test",
"var Double = require('double').Double;"
- "requireNative('assert').AssertTrue(Double(3) == 6);";
+ "requireNative('assert').AssertTrue(Double(3) == 6);");
module_system_->Require("test");
}
TEST_F(ModuleSystemTest, TestModuleInsulation) {
- source_map_["x"] =
+ RegisterModule("x",
"var x = 10;"
- "exports.X = function() { return x; };";
- source_map_["y"] =
+ "exports.X = function() { return x; };");
+ RegisterModule("y",
"var x = 15;"
"require('x');"
- "exports.Y = function() { return x; };";
- source_map_["test"] =
+ "exports.Y = function() { return x; };");
+ RegisterModule("test",
"var Y = require('y').Y;"
"var X = require('x').X;"
"var assert = requireNative('assert');"
"assert.AssertTrue(!this.hasOwnProperty('x'));"
"assert.AssertTrue(Y() == 15);"
- "assert.AssertTrue(X() == 10);";
+ "assert.AssertTrue(X() == 10);");
+ module_system_->Require("test");
+}
+
+TEST_F(ModuleSystemTest, TestDisableNativesPreventsNativeModulesBeingLoaded) {
+ module_system_->RegisterNativeHandler("disable",
+ scoped_ptr<NativeHandler>(
+ new DisableNativesHandler(module_system_.get())));
+ RegisterModule("test",
+ "var assert = requireNative('assert');"
+ "var disable = requireNative('disable');"
+ "disable.DisableNatives();"
+ "var caught = false;"
+ "try {"
+ " requireNative('assert');"
+ "} catch (e) {"
+ " caught = true;"
+ "}"
+ "assert.AssertTrue(caught);");
module_system_->Require("test");
}
diff --git a/chrome/renderer/native_handler.cc b/chrome/renderer/native_handler.cc
index 614df08..afa21ff 100644
--- a/chrome/renderer/native_handler.cc
+++ b/chrome/renderer/native_handler.cc
@@ -28,9 +28,18 @@ v8::Handle<v8::Value> NativeHandler::Router(const v8::Arguments& args) {
void NativeHandler::RouteFunction(const std::string& name,
const HandlerFunction& handler_function) {
linked_ptr<HandlerFunction> function(new HandlerFunction(handler_function));
+ // TODO(koz): Investigate using v8's MakeWeak() function instead of holding
+ // on to these pointers here.
handler_functions_.push_back(function);
v8::Handle<v8::FunctionTemplate> function_template =
v8::FunctionTemplate::New(Router,
v8::External::New(function.get()));
object_template_->Set(name.c_str(), function_template);
}
+
+void NativeHandler::RouteStaticFunction(const std::string& name,
+ const HandlerFunc handler_func) {
+ v8::Handle<v8::FunctionTemplate> function_template =
+ v8::FunctionTemplate::New(handler_func, v8::External::New(this));
+ object_template_->Set(name.c_str(), function_template);
+}
diff --git a/chrome/renderer/native_handler.h b/chrome/renderer/native_handler.h
index b4d3078..f595a0d 100644
--- a/chrome/renderer/native_handler.h
+++ b/chrome/renderer/native_handler.h
@@ -16,6 +16,12 @@
// A NativeHandler is a factory for JS objects with functions on them that map
// to native C++ functions. Subclasses should call RouteFunction() in their
// constructor to define functions on the created JS objects.
+//
+// NativeHandlers are intended to be used with a ModuleSystem. The ModuleSystem
+// will assume ownership of the NativeHandler, and as a ModuleSystem is tied to
+// a single v8::Context, this implies that NativeHandlers will also be tied to
+// a single v8::context.
+// TODO(koz): Rename this to NativeJavaScriptModule.
class NativeHandler {
public:
explicit NativeHandler();
@@ -26,6 +32,7 @@ class NativeHandler {
v8::Handle<v8::Object> NewInstance();
protected:
+ typedef v8::Handle<v8::Value> (*HandlerFunc)(const v8::Arguments&);
typedef base::Callback<v8::Handle<v8::Value>(const v8::Arguments&)>
HandlerFunction;
@@ -35,6 +42,9 @@ class NativeHandler {
void RouteFunction(const std::string& name,
const HandlerFunction& handler_function);
+ void RouteStaticFunction(const std::string& name,
+ const HandlerFunc handler_func);
+
private:
static v8::Handle<v8::Value> Router(const v8::Arguments& args);
diff --git a/chrome/renderer/renderer_resources.grd b/chrome/renderer/renderer_resources.grd
index 82ecee7..99cd777 100644
--- a/chrome/renderer/renderer_resources.grd
+++ b/chrome/renderer/renderer_resources.grd
@@ -26,6 +26,7 @@ without changes to the corresponding grd file. fb9 -->
<include name="IDR_REQUIRE_JS" file="resources\require.js" type="BINDATA" />
<include name="IDR_SAD_PLUGIN" file="resources\sadplugin.png" type="BINDATA" />
<include name="IDR_SCHEMA_GENERATED_BINDINGS_JS" file="resources\extensions\schema_generated_bindings.js" type="BINDATA" />
+ <include name="IDR_SETUP_BINDINGS_JS" file="resources\extensions\setup_bindings.js" type="BINDATA" />
<include name="IDR_WEBSTORE_BINDINGS_JS" file="resources\extensions\webstore.js" type="BINDATA" />
<!-- Custom bindings for extension APIs. -->
diff --git a/chrome/renderer/resource_bundle_source_map.cc b/chrome/renderer/resource_bundle_source_map.cc
new file mode 100644
index 0000000..2c06b7b
--- /dev/null
+++ b/chrome/renderer/resource_bundle_source_map.cc
@@ -0,0 +1,40 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/renderer/resource_bundle_source_map.h"
+
+#include "ui/base/resource/resource_bundle.h"
+
+ResourceBundleSourceMap::ResourceBundleSourceMap(
+ const ui::ResourceBundle* resource_bundle)
+ : resource_bundle_(resource_bundle) {
+}
+
+ResourceBundleSourceMap::~ResourceBundleSourceMap() {
+}
+
+void ResourceBundleSourceMap::RegisterSource(const std::string& name,
+ int resource_id) {
+ resource_id_map_[name] = resource_id;
+}
+
+v8::Handle<v8::Value> ResourceBundleSourceMap::GetSource(
+ const std::string& name) {
+ if (!Contains(name))
+ return v8::Undefined();
+ int resource_id = resource_id_map_[name];
+ return ConvertString(resource_bundle_->GetRawDataResource(resource_id));
+}
+
+bool ResourceBundleSourceMap::Contains(const std::string& name) {
+ return resource_id_map_.count(name) > 0;
+}
+
+v8::Handle<v8::String> ResourceBundleSourceMap::ConvertString(
+ const base::StringPiece& string) {
+ // v8 takes ownership of the StaticV8ExternalAsciiStringResource (see
+ // v8::String::NewExternal()).
+ return v8::String::NewExternal(
+ new StaticV8ExternalAsciiStringResource(string));
+}
diff --git a/chrome/renderer/resource_bundle_source_map.h b/chrome/renderer/resource_bundle_source_map.h
new file mode 100644
index 0000000..142930c
--- /dev/null
+++ b/chrome/renderer/resource_bundle_source_map.h
@@ -0,0 +1,40 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_RENDERER_RESOURCE_BUNDLE_SOURCE_MAP_H_
+#define CHROME_RENDERER_RESOURCE_BUNDLE_SOURCE_MAP_H_
+#pragma once
+
+#include "base/compiler_specific.h"
+#include "base/memory/linked_ptr.h"
+#include "base/string_piece.h"
+#include "chrome/renderer/module_system.h"
+#include "chrome/renderer/static_v8_external_string_resource.h"
+#include "v8/include/v8.h"
+
+#include <map>
+#include <string>
+
+namespace ui {
+ class ResourceBundle;
+}
+
+class ResourceBundleSourceMap : public ModuleSystem::SourceMap {
+ public:
+ explicit ResourceBundleSourceMap(const ui::ResourceBundle* resource_bundle);
+ ~ResourceBundleSourceMap();
+
+ virtual v8::Handle<v8::Value> GetSource(const std::string& name) OVERRIDE;
+ virtual bool Contains(const std::string& name) OVERRIDE;
+
+ void RegisterSource(const std::string& name, int resource_id);
+
+ private:
+ v8::Handle<v8::String> ConvertString(const base::StringPiece& string);
+
+ const ui::ResourceBundle* resource_bundle_;
+ std::map<std::string, int> resource_id_map_;
+};
+
+#endif // CHROME_RENDERER_RESOURCE_BUNDLE_SOURCE_MAP_H_
diff --git a/chrome/renderer/resources/extensions/apitest.js b/chrome/renderer/resources/extensions/apitest.js
index 7e7e62f..6f015ef 100644
--- a/chrome/renderer/resources/extensions/apitest.js
+++ b/chrome/renderer/resources/extensions/apitest.js
@@ -1,12 +1,10 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// extension_apitest.js
// mini-framework for ExtensionApiTest browser tests
-var chrome = chrome || {};
-(function() {
chrome.test = chrome.test || {};
chrome.test.tests = chrome.test.tests || [];
@@ -275,4 +273,3 @@ var chrome = chrome || {};
chrome.test.tests = tests;
chrome.test.runNextTest();
};
-})();
diff --git a/chrome/renderer/resources/extensions/app.js b/chrome/renderer/resources/extensions/app.js
index 8fbce65..7337d86 100644
--- a/chrome/renderer/resources/extensions/app.js
+++ b/chrome/renderer/resources/extensions/app.js
@@ -1,17 +1,15 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-var chrome = chrome || {};
-(function() {
- native function GetChromeHidden();
- native function GetIsInstalled();
- native function Install();
- native function GetDetails();
- native function GetDetailsForFrame();
- native function GetAppNotifyChannel();
+ var natives = requireNative('app');
+ var GetIsInstalled = natives.GetIsInstalled;
+ var Install = natives.Install;
+ var GetDetails = natives.GetDetails;
+ var GetDetailsForFrame = natives.GetDetailsForFrame;
+ var GetAppNotifyChannel = natives.GetAppNotifyChannel;
- var chromeHidden = GetChromeHidden();
+ var chromeHidden = requireNative('chrome_hidden').GetChromeHidden();
var callbacks = {};
var nextCallbackId = 1;
@@ -41,4 +39,3 @@ var chrome = chrome || {};
delete callbacks[callbackId];
}
};
-})();
diff --git a/chrome/renderer/resources/extensions/browser_action_custom_bindings.js b/chrome/renderer/resources/extensions/browser_action_custom_bindings.js
index 8b791a7..137da5b 100644
--- a/chrome/renderer/resources/extensions/browser_action_custom_bindings.js
+++ b/chrome/renderer/resources/extensions/browser_action_custom_bindings.js
@@ -4,11 +4,9 @@
// Custom bindings for the browserAction API.
-(function() {
+var chromeHidden = requireNative('chrome_hidden').GetChromeHidden();
-native function GetChromeHidden();
-
-GetChromeHidden().registerCustomHook('browserAction', function(bindingsAPI) {
+chromeHidden.registerCustomHook('browserAction', function(bindingsAPI) {
var apiFunctions = bindingsAPI.apiFunctions;
var setIcon = bindingsAPI.setIcon;
@@ -16,5 +14,3 @@ GetChromeHidden().registerCustomHook('browserAction', function(bindingsAPI) {
setIcon(details, this.name, this.definition.parameters, 'browser action');
});
});
-
-})();
diff --git a/chrome/renderer/resources/extensions/chrome_private_custom_bindings.js b/chrome/renderer/resources/extensions/chrome_private_custom_bindings.js
index c3f712b..b50bbee 100644
--- a/chrome/renderer/resources/extensions/chrome_private_custom_bindings.js
+++ b/chrome/renderer/resources/extensions/chrome_private_custom_bindings.js
@@ -4,17 +4,15 @@
// Custom bindings for the chromePrivate API.
-(function() {
+var chromePrivate = requireNative('chrome_private');
+var DecodeJPEG = chromePrivate.DecodeJPEG;
-native function GetChromeHidden();
-native function DecodeJPEG(jpegImage);
+var chromeHidden = requireNative('chrome_hidden').GetChromeHidden();
-GetChromeHidden().registerCustomHook('chromePrivate', function(bindingsAPI) {
+chromeHidden.registerCustomHook('chromePrivate', function(bindingsAPI) {
var apiFunctions = bindingsAPI.apiFunctions;
apiFunctions.setHandleRequest('decodeJPEG', function(jpeg_image) {
return DecodeJPEG(jpeg_image);
});
});
-
-})();
diff --git a/chrome/renderer/resources/extensions/content_settings_custom_bindings.js b/chrome/renderer/resources/extensions/content_settings_custom_bindings.js
index 14bc91c..bc98a90 100644
--- a/chrome/renderer/resources/extensions/content_settings_custom_bindings.js
+++ b/chrome/renderer/resources/extensions/content_settings_custom_bindings.js
@@ -4,11 +4,7 @@
// Custom bindings for the contentSettings API.
-(function() {
-
-native function GetChromeHidden();
-
-var chromeHidden = GetChromeHidden();
+var chromeHidden = requireNative('chrome_hidden').GetChromeHidden();
chromeHidden.registerCustomType('ContentSetting', function(typesAPI) {
var sendRequest = typesAPI.sendRequest;
@@ -54,5 +50,3 @@ chromeHidden.registerCustomType('ContentSetting', function(typesAPI) {
return ContentSetting;
});
-
-})();
diff --git a/chrome/renderer/resources/extensions/context_menus_custom_bindings.js b/chrome/renderer/resources/extensions/context_menus_custom_bindings.js
index e4983e6..546140b 100644
--- a/chrome/renderer/resources/extensions/context_menus_custom_bindings.js
+++ b/chrome/renderer/resources/extensions/context_menus_custom_bindings.js
@@ -4,12 +4,10 @@
// Custom bindings for the contextMenus API.
-(function() {
+var contextMenus = requireNative('context_menus');
+var GetNextContextMenuId = contextMenus.GetNextContextMenuId;
-native function GetChromeHidden();
-native function GetNextContextMenuId();
-
-var chromeHidden = GetChromeHidden();
+var chromeHidden = requireNative('chrome_hidden').GetChromeHidden();
chromeHidden.registerCustomHook('contextMenus', function(bindingsAPI) {
var apiFunctions = bindingsAPI.apiFunctions;
@@ -87,5 +85,3 @@ chromeHidden.registerCustomHook('contextMenus', function(bindingsAPI) {
chromeHidden.contextMenus.handlers = {};
});
});
-
-})();
diff --git a/chrome/renderer/resources/extensions/devtools_custom_bindings.js b/chrome/renderer/resources/extensions/devtools_custom_bindings.js
index d1ad34c..9d1d8eb 100644
--- a/chrome/renderer/resources/extensions/devtools_custom_bindings.js
+++ b/chrome/renderer/resources/extensions/devtools_custom_bindings.js
@@ -4,11 +4,9 @@
// Custom bindings for the devtools API.
-(function() {
+var chromeHidden = requireNative('chrome_hidden').GetChromeHidden();
-native function GetChromeHidden();
-
-GetChromeHidden().registerCustomHook('devtools', function(bindingsAPI) {
+chromeHidden.registerCustomHook('devtools', function(bindingsAPI) {
var apiFunctions = bindingsAPI.apiFunctions;
apiFunctions.setHandleRequest('getTabEvents', function(tabId) {
@@ -23,5 +21,3 @@ GetChromeHidden().registerCustomHook('devtools', function(bindingsAPI) {
return tabIdProxy;
});
});
-
-})();
diff --git a/chrome/renderer/resources/extensions/event.js b/chrome/renderer/resources/extensions/event.js
index 2cf78a8..c8a05cf 100644
--- a/chrome/renderer/resources/extensions/event.js
+++ b/chrome/renderer/resources/extensions/event.js
@@ -2,14 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-var chrome = chrome || {};
-(function () {
- native function GetChromeHidden();
- native function AttachEvent(eventName);
- native function DetachEvent(eventName, manual);
- native function Print();
+ var eventBindingsNatives = requireNative('event_bindings');
+ var AttachEvent = eventBindingsNatives.AttachEvent;
+ var DetachEvent = eventBindingsNatives.DetachEvent;
+ var Print = eventBindingsNatives.Print;
- var chromeHidden = GetChromeHidden();
+ var chromeHidden = requireNative('chrome_hidden').GetChromeHidden();
// Local implementation of JSON.parse & JSON.stringify that protect us
// from being clobbered by an extension.
@@ -311,4 +309,3 @@ var chrome = chrome || {};
chromeHidden.dispatchError = function(msg) {
console.error(msg);
};
-})();
diff --git a/chrome/renderer/resources/extensions/experimental.declarative_custom_bindings.js b/chrome/renderer/resources/extensions/experimental.declarative_custom_bindings.js
index de47b6c..73d4642 100644
--- a/chrome/renderer/resources/extensions/experimental.declarative_custom_bindings.js
+++ b/chrome/renderer/resources/extensions/experimental.declarative_custom_bindings.js
@@ -4,11 +4,7 @@
// Custom bindings for the declarative API.
-(function() {
-
-native function GetChromeHidden();
-
-var chromeHidden = GetChromeHidden();
+var chromeHidden = requireNative('chrome_hidden').GetChromeHidden();
chromeHidden.registerCustomHook('experimental.declarative',
function(bindingsAPI) {
@@ -78,5 +74,3 @@ chromeHidden.registerCustomHook('experimental.declarative',
this.definition.parameters);
});
});
-
-})();
diff --git a/chrome/renderer/resources/extensions/experimental.socket_custom_bindings.js b/chrome/renderer/resources/extensions/experimental.socket_custom_bindings.js
index 52a8659..a5b2568 100644
--- a/chrome/renderer/resources/extensions/experimental.socket_custom_bindings.js
+++ b/chrome/renderer/resources/extensions/experimental.socket_custom_bindings.js
@@ -4,11 +4,10 @@
// Custom bindings for the experimental.socket API.
-(function() {
- native function GetChromeHidden();
- native function GetNextSocketEventId();
+ var experimentalSocketNatives = requireNative('experimental_socket');
+ var GetNextSocketEventId = experimentalSocketNatives.GetNextSocketEventId;
- var chromeHidden = GetChromeHidden();
+ var chromeHidden = requireNative('chrome_hidden').GetChromeHidden();
chromeHidden.registerCustomHook('experimental.socket', function(api) {
var apiFunctions = api.apiFunctions;
@@ -56,5 +55,3 @@
}
});
});
-
-})();
diff --git a/chrome/renderer/resources/extensions/extension_custom_bindings.js b/chrome/renderer/resources/extensions/extension_custom_bindings.js
index f746e2a..970e11f 100644
--- a/chrome/renderer/resources/extensions/extension_custom_bindings.js
+++ b/chrome/renderer/resources/extensions/extension_custom_bindings.js
@@ -4,13 +4,11 @@
// Custom bindings for the extension API.
-(function() {
+var extensionNatives = requireNative('extension');
+var GetExtensionViews = extensionNatives.GetExtensionViews;
+var OpenChannelToExtension = extensionNatives.OpenChannelToExtension;
-native function GetChromeHidden();
-native function GetExtensionViews();
-native function OpenChannelToExtension(sourceId, targetId, name);
-
-var chromeHidden = GetChromeHidden();
+var chromeHidden = requireNative('chrome_hidden').GetChromeHidden();
// This should match chrome.windows.WINDOW_ID_NONE.
//
@@ -144,5 +142,3 @@ chromeHidden.registerCustomHook('extension',
throw new Error('Error connecting to extension ' + targetId);
});
});
-
-})();
diff --git a/chrome/renderer/resources/extensions/file_browser_handler_custom_bindings.js b/chrome/renderer/resources/extensions/file_browser_handler_custom_bindings.js
index 9fb152c..44d1539 100644
--- a/chrome/renderer/resources/extensions/file_browser_handler_custom_bindings.js
+++ b/chrome/renderer/resources/extensions/file_browser_handler_custom_bindings.js
@@ -4,12 +4,11 @@
// Custom bindings for the fileBrowserHandler API.
-(function() {
+var fileBrowserNatives = requireNative('file_browser_handler');
+var GetExternalFileEntry = fileBrowserNatives.GetExternalFileEntry;
-native function GetChromeHidden();
-native function GetExternalFileEntry();
+var chromeHidden = requireNative('chrome_hidden').GetChromeHidden();
-var chromeHidden = GetChromeHidden();
chromeHidden.Event.registerArgumentMassager('fileBrowserHandler.onExecute',
function(args) {
if (args.length < 2)
@@ -23,5 +22,3 @@ chromeHidden.Event.registerArgumentMassager('fileBrowserHandler.onExecute',
for (var i = 0; i < fileList.length; i++)
fileList[i] = GetExternalFileEntry(fileList[i]);
});
-
-})();
diff --git a/chrome/renderer/resources/extensions/file_browser_private_custom_bindings.js b/chrome/renderer/resources/extensions/file_browser_private_custom_bindings.js
index 7b483b5..2423cfb 100644
--- a/chrome/renderer/resources/extensions/file_browser_private_custom_bindings.js
+++ b/chrome/renderer/resources/extensions/file_browser_private_custom_bindings.js
@@ -4,12 +4,10 @@
// Custom bindings for the fileBrowserPrivate API.
-(function() {
+var fileBrowserPrivateNatives = requireNative('file_browser_private');
+var GetLocalFileSystem = fileBrowserPrivateNatives.GetLocalFileSystem;
-native function GetChromeHidden();
-native function GetLocalFileSystem(name, path);
-
-var chromeHidden = GetChromeHidden();
+var chromeHidden = requireNative('chrome_hidden').GetChromeHidden();
chromeHidden.registerCustomHook('fileBrowserPrivate', function(bindingsAPI) {
var apiFunctions = bindingsAPI.apiFunctions;
@@ -25,5 +23,3 @@ chromeHidden.registerCustomHook('fileBrowserPrivate', function(bindingsAPI) {
request.callback = null;
});
});
-
-})();
diff --git a/chrome/renderer/resources/extensions/i18n_custom_bindings.js b/chrome/renderer/resources/extensions/i18n_custom_bindings.js
index 8f9ca30..a9fa5a2 100644
--- a/chrome/renderer/resources/extensions/i18n_custom_bindings.js
+++ b/chrome/renderer/resources/extensions/i18n_custom_bindings.js
@@ -4,12 +4,12 @@
// Custom bindings for the i18n API.
-(function() {
+var i18nNatives = requireNative('i18n');
+var GetL10nMessage = i18nNatives.GetL10nMessage;
-native function GetChromeHidden();
-native function GetL10nMessage();
+var chromeHidden = requireNative('chrome_hidden').GetChromeHidden();
-GetChromeHidden().registerCustomHook('i18n',
+chromeHidden.registerCustomHook('i18n',
function(bindingsAPI, extensionId) {
var apiFunctions = bindingsAPI.apiFunctions;
@@ -18,5 +18,3 @@ GetChromeHidden().registerCustomHook('i18n',
return GetL10nMessage(messageName, substitutions, extensionId);
});
});
-
-})();
diff --git a/chrome/renderer/resources/extensions/input.ime_custom_bindings.js b/chrome/renderer/resources/extensions/input.ime_custom_bindings.js
index c6bbbfc..8f400c7 100644
--- a/chrome/renderer/resources/extensions/input.ime_custom_bindings.js
+++ b/chrome/renderer/resources/extensions/input.ime_custom_bindings.js
@@ -5,11 +5,9 @@
// Custom bindings for the input ime API. Only injected into the
// v8 contexts for extensions which have permission for the API.
-(function() {
+var chromeHidden = requireNative('chrome_hidden').GetChromeHidden();
-native function GetChromeHidden();
-
-GetChromeHidden().registerCustomHook('input.ime', function() {
+chromeHidden.registerCustomHook('input.ime', function() {
chrome.input.ime.onKeyEvent.dispatch = function(engineID, keyData) {
var args = Array.prototype.slice.call(arguments);
if (this.validate_) {
@@ -36,5 +34,3 @@ GetChromeHidden().registerCustomHook('input.ime', function() {
}
};
});
-
-})();
diff --git a/chrome/renderer/resources/extensions/json_schema.js b/chrome/renderer/resources/extensions/json_schema.js
index f1fdf9e..bc51d97 100644
--- a/chrome/renderer/resources/extensions/json_schema.js
+++ b/chrome/renderer/resources/extensions/json_schema.js
@@ -38,9 +38,7 @@
// additional properties will be validated.
//==============================================================================
-(function() {
-native function GetChromeHidden();
-var chromeHidden = GetChromeHidden();
+var chromeHidden = requireNative('chrome_hidden').GetChromeHidden();
function isInstanceOfClass(instance, className) {
if (!instance)
@@ -498,5 +496,3 @@ chromeHidden.JSONSchemaValidator.prototype.addError =
chromeHidden.JSONSchemaValidator.prototype.resetErrors = function() {
this.errors = [];
};
-
-})();
diff --git a/chrome/renderer/resources/extensions/miscellaneous_bindings.js b/chrome/renderer/resources/extensions/miscellaneous_bindings.js
index 6bcfc11..a2d284d 100644
--- a/chrome/renderer/resources/extensions/miscellaneous_bindings.js
+++ b/chrome/renderer/resources/extensions/miscellaneous_bindings.js
@@ -7,16 +7,15 @@
// scripts or background pages.
// See user_script_slave.cc for script that is loaded by content scripts only.
-var chrome = chrome || {};
-(function () {
- native function CloseChannel(portId, notifyBrowser);
- native function PortAddRef(portId);
- native function PortRelease(portId);
- native function PostMessage(portId, msg);
- native function GetChromeHidden();
- native function Print();
-
- var chromeHidden = GetChromeHidden();
+ require('json_schema');
+ require('event_bindings');
+ var miscNatives = requireNative('miscellaneous_bindings');
+ var CloseChannel = miscNatives.CloseChannel;
+ var PortAddRef = miscNatives.PortAddRef;
+ var PortRelease = miscNatives.PortRelease;
+ var PostMessage = miscNatives.PostMessage;
+
+ var chromeHidden = requireNative('chrome_hidden').GetChromeHidden();
var manifestVersion;
var extensionId;
@@ -210,4 +209,3 @@ var chrome = chrome || {};
chrome.extension.inIncognitoContext = inIncognitoContext;
});
-})();
diff --git a/chrome/renderer/resources/extensions/omnibox_custom_bindings.js b/chrome/renderer/resources/extensions/omnibox_custom_bindings.js
index 13a3c61..37f8d92 100644
--- a/chrome/renderer/resources/extensions/omnibox_custom_bindings.js
+++ b/chrome/renderer/resources/extensions/omnibox_custom_bindings.js
@@ -5,9 +5,7 @@
// Custom bindings for the omnibox API. Only injected into the v8 contexts
// for extensions which have permission for the omnibox API.
-(function() {
-
-native function GetChromeHidden();
+var chromeHidden = requireNative('chrome_hidden').GetChromeHidden();
// Remove invalid characters from |text| so that it is suitable to use
// for |AutocompleteMatch::contents|.
@@ -79,7 +77,7 @@ function parseOmniboxDescription(input) {
return result;
}
-GetChromeHidden().registerCustomHook('omnibox', function(bindingsAPI) {
+chromeHidden.registerCustomHook('omnibox', function(bindingsAPI) {
var apiFunctions = bindingsAPI.apiFunctions;
var sendRequest = bindingsAPI.sendRequest;
@@ -108,5 +106,3 @@ GetChromeHidden().registerCustomHook('omnibox', function(bindingsAPI) {
chrome.Event.prototype.dispatch.apply(this, [text, suggestCallback]);
};
});
-
-})();
diff --git a/chrome/renderer/resources/extensions/page_action_custom_bindings.js b/chrome/renderer/resources/extensions/page_action_custom_bindings.js
index 722a57b..13336b1d 100644
--- a/chrome/renderer/resources/extensions/page_action_custom_bindings.js
+++ b/chrome/renderer/resources/extensions/page_action_custom_bindings.js
@@ -4,11 +4,9 @@
// Custom bindings for the pageAction API.
-(function() {
+var chromeHidden = requireNative('chrome_hidden').GetChromeHidden();
-native function GetChromeHidden();
-
-GetChromeHidden().registerCustomHook('pageAction', function(bindingsAPI) {
+chromeHidden.registerCustomHook('pageAction', function(bindingsAPI) {
var apiFunctions = bindingsAPI.apiFunctions;
var setIcon = bindingsAPI.setIcon;
@@ -16,5 +14,3 @@ GetChromeHidden().registerCustomHook('pageAction', function(bindingsAPI) {
setIcon(details, this.name, this.definition.parameters, 'page action');
});
});
-
-})();
diff --git a/chrome/renderer/resources/extensions/page_actions_custom_bindings.js b/chrome/renderer/resources/extensions/page_actions_custom_bindings.js
index 2a7a2de..d5ec888 100644
--- a/chrome/renderer/resources/extensions/page_actions_custom_bindings.js
+++ b/chrome/renderer/resources/extensions/page_actions_custom_bindings.js
@@ -4,13 +4,13 @@
// Custom bindings for the pageActions API.
-(function() {
+var pageActionsNatives = requireNative('page_actions');
+var GetCurrentPageActions = pageActionsNatives.GetCurrentPageActions;
-native function GetChromeHidden();
-native function GetCurrentPageActions();
+var chromeHidden = requireNative('chrome_hidden').GetChromeHidden();
-GetChromeHidden().registerCustomHook('pageActions',
- function(bindingsAPI, extensionId) {
+chromeHidden.registerCustomHook('pageActions',
+ function(bindingsAPI, extensionId) {
var pageActions = GetCurrentPageActions(extensionId);
var oldStyleEventName = 'pageActions';
for (var i = 0; i < pageActions.length; ++i) {
@@ -18,5 +18,3 @@ GetChromeHidden().registerCustomHook('pageActions',
chrome.pageActions[pageActions[i]] = new chrome.Event(oldStyleEventName);
}
});
-
-})();
diff --git a/chrome/renderer/resources/extensions/page_capture_custom_bindings.js b/chrome/renderer/resources/extensions/page_capture_custom_bindings.js
index e8a7af4..0bcbb0b 100644
--- a/chrome/renderer/resources/extensions/page_capture_custom_bindings.js
+++ b/chrome/renderer/resources/extensions/page_capture_custom_bindings.js
@@ -4,13 +4,11 @@
// Custom bindings for the pageCapture API.
-(function() {
+var pageCaptureNatives = requireNative('page_capture');
+var CreateBlob = pageCaptureNatives.CreateBlob;
+var SendResponseAck = pageCaptureNatives.SendResponseAck;
-native function GetChromeHidden();
-native function CreateBlob(filePath);
-native function SendResponseAck(requestId);
-
-var chromeHidden = GetChromeHidden();
+var chromeHidden = requireNative('chrome_hidden').GetChromeHidden();
chromeHidden.registerCustomHook('pageCapture', function(bindingsAPI) {
var apiFunctions = bindingsAPI.apiFunctions;
@@ -30,5 +28,3 @@ chromeHidden.registerCustomHook('pageCapture', function(bindingsAPI) {
SendResponseAck(request.id);
});
});
-
-})();
diff --git a/chrome/renderer/resources/extensions/schema_generated_bindings.js b/chrome/renderer/resources/extensions/schema_generated_bindings.js
index bc057d2..ab11923 100644
--- a/chrome/renderer/resources/extensions/schema_generated_bindings.js
+++ b/chrome/renderer/resources/extensions/schema_generated_bindings.js
@@ -5,15 +5,15 @@
// This script contains privileged chrome extension related javascript APIs.
// It is loaded by pages whose URL has the chrome-extension protocol.
-var chrome = chrome || {};
-(function() {
- native function GetChromeHidden();
- native function GetExtensionAPIDefinition();
- native function GetNextRequestId();
- native function StartRequest();
- native function SetIconCommon();
+ require('json_schema');
+ require('event_bindings');
+ var natives = requireNative('schema_generated_bindings');
+ var GetExtensionAPIDefinition = natives.GetExtensionAPIDefinition;
+ var GetNextRequestId = natives.GetNextRequestId;
+ var StartRequest = natives.StartRequest;
+ var SetIconCommon = natives.SetIconCommon;
- var chromeHidden = GetChromeHidden();
+ var chromeHidden = requireNative('chrome_hidden').GetChromeHidden();
// The object to generate the bindings for "internal" APIs in, so that
// extensions can't directly call them (without access to chromeHidden),
@@ -753,4 +753,3 @@ var chrome = chrome || {};
if (chrome.test)
chrome.test.getApiDefinitions = GetExtensionAPIDefinition;
});
-})();
diff --git a/chrome/renderer/resources/extensions/setup_bindings.js b/chrome/renderer/resources/extensions/setup_bindings.js
new file mode 100644
index 0000000..86b0cd5
--- /dev/null
+++ b/chrome/renderer/resources/extensions/setup_bindings.js
@@ -0,0 +1,21 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+var contextInfo = requireNative('context_info');
+var sgb = requireNative('schema_generated_bindings');
+
+require('app');
+require('webstore');
+
+if (contextInfo.IsBindingsAllowed()) {
+ require('miscellaneous_bindings');
+ require('schema_generated_bindings');
+ require('apitest');
+
+ // Load the custom bindings for each API.
+ sgb.GetExtensionAPIDefinition().forEach(function(apiDef) {
+ if (contextInfo.IsAPIAllowed(apiDef.namespace))
+ require(apiDef.namespace);
+ });
+}
diff --git a/chrome/renderer/resources/extensions/storage_custom_bindings.js b/chrome/renderer/resources/extensions/storage_custom_bindings.js
index 1d358c2..a3c8a54 100644
--- a/chrome/renderer/resources/extensions/storage_custom_bindings.js
+++ b/chrome/renderer/resources/extensions/storage_custom_bindings.js
@@ -4,11 +4,7 @@
// Custom bindings for the storage API.
-(function() {
-
-native function GetChromeHidden();
-
-var chromeHidden = GetChromeHidden();
+var chromeHidden = requireNative('chrome_hidden').GetChromeHidden();
chromeHidden.registerCustomType('StorageArea', function(typesAPI) {
var sendRequest = typesAPI.sendRequest;
@@ -43,5 +39,3 @@ chromeHidden.registerCustomType('StorageArea', function(typesAPI) {
return StorageArea;
});
-
-})();
diff --git a/chrome/renderer/resources/extensions/tabs_custom_bindings.js b/chrome/renderer/resources/extensions/tabs_custom_bindings.js
index dd66481..e0cc59c 100644
--- a/chrome/renderer/resources/extensions/tabs_custom_bindings.js
+++ b/chrome/renderer/resources/extensions/tabs_custom_bindings.js
@@ -4,12 +4,10 @@
// Custom bindings for the tabs API.
-(function() {
+var tabsNatives = requireNative('tabs');
+var OpenChannelToTab = tabsNatives.OpenChannelToTab;
-native function GetChromeHidden();
-native function OpenChannelToTab();
-
-var chromeHidden = GetChromeHidden();
+var chromeHidden = requireNative('chrome_hidden').GetChromeHidden();
chromeHidden.registerCustomHook('tabs', function(bindingsAPI, extensionId) {
var apiFunctions = bindingsAPI.apiFunctions;
@@ -44,5 +42,3 @@ chromeHidden.registerCustomHook('tabs', function(bindingsAPI, extensionId) {
});
});
});
-
-})();
diff --git a/chrome/renderer/resources/extensions/tts_custom_bindings.js b/chrome/renderer/resources/extensions/tts_custom_bindings.js
index ef8011a..dee01d3 100644
--- a/chrome/renderer/resources/extensions/tts_custom_bindings.js
+++ b/chrome/renderer/resources/extensions/tts_custom_bindings.js
@@ -4,12 +4,10 @@
// Custom bindings for the tts API.
-(function() {
+var ttsNatives = requireNative('tts');
+var GetNextTTSEventId = ttsNatives.GetNextTTSEventId;
-native function GetChromeHidden();
-native function GetNextTTSEventId();
-
-var chromeHidden = GetChromeHidden();
+var chromeHidden = requireNative('chrome_hidden').GetChromeHidden();
chromeHidden.registerCustomHook('tts', function(api) {
var apiFunctions = api.apiFunctions;
@@ -42,5 +40,3 @@ chromeHidden.registerCustomHook('tts', function(api) {
return id;
});
});
-
-})();
diff --git a/chrome/renderer/resources/extensions/tts_engine_custom_bindings.js b/chrome/renderer/resources/extensions/tts_engine_custom_bindings.js
index 85e36b0..7c0067b 100644
--- a/chrome/renderer/resources/extensions/tts_engine_custom_bindings.js
+++ b/chrome/renderer/resources/extensions/tts_engine_custom_bindings.js
@@ -4,11 +4,9 @@
// Custom bindings for the ttsEngine API.
-(function() {
+var chromeHidden = requireNative('chrome_hidden').GetChromeHidden();
-native function GetChromeHidden();
-
-GetChromeHidden().registerCustomHook('ttsEngine', function() {
+chromeHidden.registerCustomHook('ttsEngine', function() {
chrome.ttsEngine.onSpeak.dispatch = function(text, options, requestId) {
var sendTtsEvent = function(event) {
chrome.ttsEngine.sendTtsEvent(requestId, event);
@@ -17,5 +15,3 @@ GetChromeHidden().registerCustomHook('ttsEngine', function() {
this, [text, options, sendTtsEvent]);
};
});
-
-})();
diff --git a/chrome/renderer/resources/extensions/types_custom_bindings.js b/chrome/renderer/resources/extensions/types_custom_bindings.js
index 62dbe0a..48eba8a 100644
--- a/chrome/renderer/resources/extensions/types_custom_bindings.js
+++ b/chrome/renderer/resources/extensions/types_custom_bindings.js
@@ -4,11 +4,7 @@
// Custom bindings for the types API.
-(function() {
-
-native function GetChromeHidden();
-
-var chromeHidden = GetChromeHidden();
+var chromeHidden = requireNative('chrome_hidden').GetChromeHidden();
chromeHidden.registerCustomType('ChromeSetting', function(typesAPI) {
var sendRequest = typesAPI.sendRequest;
@@ -48,5 +44,3 @@ chromeHidden.registerCustomType('ChromeSetting', function(typesAPI) {
return ChromeSetting;
});
-
-})();
diff --git a/chrome/renderer/resources/extensions/web_request_custom_bindings.js b/chrome/renderer/resources/extensions/web_request_custom_bindings.js
index 564251e..392f66c 100644
--- a/chrome/renderer/resources/extensions/web_request_custom_bindings.js
+++ b/chrome/renderer/resources/extensions/web_request_custom_bindings.js
@@ -4,12 +4,10 @@
// Custom bindings for the webRequest API.
-(function() {
+var webRequestNatives = requireNative('web_request');
+var GetUniqueSubEventName = webRequestNatives.GetUniqueSubEventName;
-native function GetChromeHidden();
-native function GetUniqueSubEventName(eventName);
-
-var chromeHidden = GetChromeHidden();
+var chromeHidden = requireNative('chrome_hidden').GetChromeHidden();
// WebRequestEvent object. This is used for special webRequest events with
// extra parameters. Each invocation of addListener creates a new named
@@ -172,5 +170,3 @@ chromeHidden.registerCustomHook('webRequest', function(api) {
{forIOThread: true});
});
});
-
-})();
diff --git a/chrome/renderer/resources/extensions/webstore.js b/chrome/renderer/resources/extensions/webstore.js
index b387c46..14bacc5 100644
--- a/chrome/renderer/resources/extensions/webstore.js
+++ b/chrome/renderer/resources/extensions/webstore.js
@@ -2,12 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-var chrome = chrome || {};
-(function() {
- native function GetChromeHidden();
- native function Install(preferredStoreUrl, onSuccess, onFailure);
+ var webstoreNatives = requireNative('webstore');
+ var Install = webstoreNatives.Install;
- var chromeHidden = GetChromeHidden();
+ var chromeHidden = requireNative('chrome_hidden').GetChromeHidden();
var pendingInstalls = {};
chrome.webstore = new function() {
this.install = function(
@@ -41,4 +39,3 @@ var chrome = chrome || {};
delete pendingInstall[installId];
}
}
-})();
diff --git a/chrome/renderer/resources/require.js b/chrome/renderer/resources/require.js
index 34f3543..7108616 100644
--- a/chrome/renderer/resources/require.js
+++ b/chrome/renderer/resources/require.js
@@ -15,15 +15,9 @@
//
// |bootstrap| contains the following fields:
// - GetSource(module): returns the source code for |module|
-// - Run(source): runs the string os JS |source|
// - GetNative(nativeName): returns the named native object
(function(bootstrap) {
-function wrap(source) {
- return "(function(require, requireNative, exports) {" + source +
- "\n})";
-}
-
function ModuleLoader() {
this.cache_ = {};
};
@@ -33,9 +27,8 @@ ModuleLoader.prototype.run = function(id) {
if (!source) {
return null;
}
- var wrappedSource = wrap(source);
- var f = bootstrap.Run(wrappedSource);
var exports = {};
+ var f = new Function("require", "requireNative", "exports", source);
f(require, requireNative, exports);
return exports;
};
@@ -53,7 +46,11 @@ ModuleLoader.prototype.load = function(id) {
var moduleLoader = new ModuleLoader();
function requireNative(nativeName) {
- return bootstrap.GetNative(nativeName);
+ var result = bootstrap.GetNative(nativeName);
+ if (!result) {
+ throw "No such native object: '" + nativeName + "'";
+ }
+ return result;
}
function require(moduleId) {