diff options
author | akalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-09 07:55:14 +0000 |
---|---|---|
committer | akalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-09 07:55:14 +0000 |
commit | 65f8fbbd988207a470e2a399379baa70f4abb282 (patch) | |
tree | 9f91f7a50a48af285b12cb406f45fc8d00b38127 | |
parent | c7f74e7ca7e2b2428fb7434b0ef0b7a9b4bfbff8 (diff) | |
download | chromium_src-65f8fbbd988207a470e2a399379baa70f4abb282.zip chromium_src-65f8fbbd988207a470e2a399379baa70f4abb282.tar.gz chromium_src-65f8fbbd988207a470e2a399379baa70f4abb282.tar.bz2 |
Revert 125801 - 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
TBR=koz@chromium.org
Review URL: https://chromiumcodereview.appspot.com/9657026
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@125814 0039d316-1c4b-4281-b951-d872f2087c98
84 files changed, 1090 insertions, 864 deletions
diff --git a/chrome/chrome_renderer.gypi b/chrome/chrome_renderer.gypi index dcd2806..668d10b 100644 --- a/chrome/chrome_renderer.gypi +++ b/chrome/chrome_renderer.gypi @@ -127,8 +127,6 @@ 'renderer/net/predictor_queue.h', 'renderer/net/renderer_net_predictor.cc', 'renderer/net/renderer_net_predictor.h', - 'renderer/resource_bundle_source_map.cc', - 'renderer/resource_bundle_source_map.h', 'renderer/resources/extensions/apitest.js', 'renderer/resources/extensions/app.js', 'renderer/resources/extensions/browser_action_custom_bindings.js', @@ -150,7 +148,6 @@ 'renderer/resources/extensions/page_actions_custom_bindings.js', 'renderer/resources/extensions/page_capture_custom_bindings.js', 'renderer/resources/extensions/schema_generated_bindings.js', - 'renderer/resources/extensions/setup_bindings.js', 'renderer/resources/extensions/tts_custom_bindings.js', 'renderer/resources/extensions/tts_engine_custom_bindings.js', 'renderer/resources/extensions/types_custom_bindings.js', diff --git a/chrome/renderer/extensions/app_bindings.cc b/chrome/renderer/extensions/app_bindings.cc index 34c8047..21ee438 100644 --- a/chrome/renderer/extensions/app_bindings.cc +++ b/chrome/renderer/extensions/app_bindings.cc @@ -53,41 +53,93 @@ 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, - 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))); +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) { } +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> AppBindings::GetIsInstalled( +v8::Handle<v8::Value> AppBindingsHandler::GetIsInstalled( const v8::Arguments& args) { // TODO(aa): Hm, maybe ExtensionBindingsContext should have GetExtension() // afterall? const ::Extension* extension = - extension_dispatcher_->extensions()->GetByID(context_->extension_id()); + 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() && - extension_dispatcher_->IsApplicationActive(extension->id()); + dispatcher_->IsApplicationActive(extension->id()); return v8::Boolean::New(result); } -v8::Handle<v8::Value> AppBindings::Install(const v8::Arguments& args) { +v8::Handle<v8::Value> AppBindingsHandler::Install(const v8::Arguments& args) { content::RenderView* render_view = context_->GetRenderView(); CHECK(render_view); @@ -101,13 +153,13 @@ v8::Handle<v8::Value> AppBindings::Install(const v8::Arguments& args) { return v8::Undefined(); } -v8::Handle<v8::Value> AppBindings::GetDetails( +v8::Handle<v8::Value> AppBindingsHandler::GetDetails( const v8::Arguments& args) { CHECK(context_->web_frame()); return GetDetailsForFrameImpl(context_->web_frame()); } -v8::Handle<v8::Value> AppBindings::GetDetailsForFrame( +v8::Handle<v8::Value> AppBindingsHandler::GetDetailsForFrame( const v8::Arguments& args) { CHECK(context_->web_frame()); if (!CheckAccessToAppDetails(context_->web_frame())) @@ -134,12 +186,12 @@ v8::Handle<v8::Value> AppBindings::GetDetailsForFrame( return GetDetailsForFrameImpl(target_frame); } -v8::Handle<v8::Value> AppBindings::GetDetailsForFrameImpl( +v8::Handle<v8::Value> AppBindingsHandler::GetDetailsForFrameImpl( WebFrame* frame) { const ::Extension* extension = - extension_dispatcher_->extensions()->GetExtensionOrAppByURL( - ExtensionURLInfo(frame->document().securityOrigin(), - frame->document().url())); + dispatcher_->extensions()->GetExtensionOrAppByURL(ExtensionURLInfo( + frame->document().securityOrigin(), + frame->document().url())); if (!extension) return v8::Null(); @@ -151,7 +203,7 @@ v8::Handle<v8::Value> AppBindings::GetDetailsForFrameImpl( frame->mainWorldScriptContext()); } -v8::Handle<v8::Value> AppBindings::GetAppNotifyChannel( +v8::Handle<v8::Value> AppBindingsHandler::GetAppNotifyChannel( const v8::Arguments& args) { // Read the required 'clientId' value out of the object at args[0]. std::string client_id; @@ -190,8 +242,8 @@ v8::Handle<v8::Value> AppBindings::GetAppNotifyChannel( return v8::Undefined(); } -bool AppBindings::OnMessageReceived(const IPC::Message& message) { - IPC_BEGIN_MESSAGE_MAP(AppBindings, message) +bool AppBindingsHandler::OnMessageReceived(const IPC::Message& message) { + IPC_BEGIN_MESSAGE_MAP(AppBindingsHandler, message) IPC_MESSAGE_HANDLER(ExtensionMsg_GetAppNotifyChannelResponse, OnGetAppNotifyChannelResponse) IPC_MESSAGE_UNHANDLED(CHECK(false) << "Unhandled IPC message") @@ -199,7 +251,7 @@ bool AppBindings::OnMessageReceived(const IPC::Message& message) { return true; } -void AppBindings::OnGetAppNotifyChannelResponse( +void AppBindingsHandler::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 e27c770..9455ba2 100644 --- a/chrome/renderer/extensions/app_bindings.h +++ b/chrome/renderer/extensions/app_bindings.h @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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,34 +14,21 @@ #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, public ChromeV8ExtensionHandler { +class AppBindings : public ChromeV8Extension { public: - explicit AppBindings(ExtensionDispatcher* dispatcher, - ChromeV8Context* context); + explicit AppBindings(ExtensionDispatcher* dispatcher); - 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); + protected: + virtual ChromeV8ExtensionHandler* CreateHandler( + ChromeV8Context* context) OVERRIDE; + private: 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 2e8aa86..a1e4fbb 100644 --- a/chrome/renderer/extensions/chrome_private_custom_bindings.cc +++ b/chrome/renderer/extensions/chrome_private_custom_bindings.cc @@ -18,10 +18,15 @@ namespace extensions { ChromePrivateCustomBindings::ChromePrivateCustomBindings( + int dependency_count, + const char** dependencies, ExtensionDispatcher* extension_dispatcher) - : ChromeV8Extension(extension_dispatcher) { - RouteStaticFunction("DecodeJPEG", &DecodeJPEG); -} + : ChromeV8Extension( + "extensions/chrome_private_custom_bindings.js", + IDR_CHROME_PRIVATE_CUSTOM_BINDINGS_JS, + dependency_count, + dependencies, + extension_dispatcher) {} // static v8::Handle<v8::Value> ChromePrivateCustomBindings::DecodeJPEG( @@ -82,4 +87,12 @@ 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 0d6fd5e..d1bfdb9 100644 --- a/chrome/renderer/extensions/chrome_private_custom_bindings.h +++ b/chrome/renderer/extensions/chrome_private_custom_bindings.h @@ -15,9 +15,14 @@ namespace extensions { // Implements custom bindings for the chromePrivate API. class ChromePrivateCustomBindings : public ChromeV8Extension { public: - explicit ChromePrivateCustomBindings( + ChromePrivateCustomBindings( + int dependency_count, + const char** dependencies, 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 3faf9d2..11a4a87 100644 --- a/chrome/renderer/extensions/chrome_v8_context.h +++ b/chrome/renderer/extensions/chrome_v8_context.h @@ -9,7 +9,6 @@ #include <string> #include "base/basictypes.h" -#include "chrome/renderer/module_system.h" #include "v8/include/v8.h" namespace WebKit { @@ -61,10 +60,6 @@ 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 @@ -118,9 +113,6 @@ 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 791b1f5..35b5153 100644 --- a/chrome/renderer/extensions/chrome_v8_extension.cc +++ b/chrome/renderer/extensions/chrome_v8_extension.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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,6 +33,11 @@ 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."; @@ -48,8 +53,27 @@ content::RenderView* ChromeV8Extension::GetCurrentRenderView() { return renderview; } -ChromeV8Extension::ChromeV8Extension(ExtensionDispatcher* extension_dispatcher) - : extension_dispatcher_(extension_dispatcher) { +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) { g_instances.Get().insert(this); } @@ -62,6 +86,19 @@ 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) @@ -115,3 +152,61 @@ 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 7e4b8e8..511273f 100644 --- a/chrome/renderer/extensions/chrome_v8_extension.h +++ b/chrome/renderer/extensions/chrome_v8_extension.h @@ -10,7 +10,6 @@ #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> @@ -27,17 +26,31 @@ class RenderView; // This is a base class for chrome extension bindings. Common features that // are shared by different modules go here. -// TODO(koz): Rename this to ExtensionNativeModule. -class ChromeV8Extension : public NativeHandler { +class ChromeV8Extension : public v8::Extension { public: typedef std::set<ChromeV8Extension*> InstanceSet; static const InstanceSet& GetAll(); - explicit ChromeV8Extension(ExtensionDispatcher* extension_dispatcher); + 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); 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) { @@ -60,12 +73,32 @@ class ChromeV8Extension : public NativeHandler { 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 301b9f6..f933fc9 100644 --- a/chrome/renderer/extensions/chrome_v8_extension_handler.h +++ b/chrome/renderer/extensions/chrome_v8_extension_handler.h @@ -15,10 +15,11 @@ 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 db3b3d9..bfb6114 100644 --- a/chrome/renderer/extensions/context_menus_custom_bindings.cc +++ b/chrome/renderer/extensions/context_menus_custom_bindings.cc @@ -7,9 +7,19 @@ #include "grit/renderer_resources.h" #include "v8/include/v8.h" -namespace { +namespace extensions { -v8::Handle<v8::Value> GetNextContextMenuId(const v8::Arguments& args) { +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) { // 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 @@ -17,13 +27,12 @@ v8::Handle<v8::Value> GetNextContextMenuId(const v8::Arguments& args) { return v8::Integer::New(next_context_menu_id++); } -} // namespace - -namespace extensions { +v8::Handle<v8::FunctionTemplate> ContextMenusCustomBindings::GetNativeFunction( + v8::Handle<v8::String> name) { + if (name->Equals(v8::String::New("GetNextContextMenuId"))) + return v8::FunctionTemplate::New(GetNextContextMenuId); -ContextMenusCustomBindings::ContextMenusCustomBindings() - : ChromeV8Extension(NULL) { - RouteStaticFunction("GetNextContextMenuId", &GetNextContextMenuId); + return ChromeV8Extension::GetNativeFunction(name); } } // extensions diff --git a/chrome/renderer/extensions/context_menus_custom_bindings.h b/chrome/renderer/extensions/context_menus_custom_bindings.h index 18d3b38..1b31e50 100644 --- a/chrome/renderer/extensions/context_menus_custom_bindings.h +++ b/chrome/renderer/extensions/context_menus_custom_bindings.h @@ -13,7 +13,10 @@ namespace extensions { // Implements custom bindings for the contextMenus API. class ContextMenusCustomBindings : public ChromeV8Extension { public: - ContextMenusCustomBindings(); + ContextMenusCustomBindings(int dependency_count, const char** dependencies); + + virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction( + v8::Handle<v8::String> name) OVERRIDE; }; } // extensions diff --git a/chrome/renderer/extensions/custom_bindings_util.cc b/chrome/renderer/extensions/custom_bindings_util.cc index 5de0470b..b9dfa84 100644 --- a/chrome/renderer/extensions/custom_bindings_util.cc +++ b/chrome/renderer/extensions/custom_bindings_util.cc @@ -31,6 +31,83 @@ 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 73d026d..f4d6fe3 100644 --- a/chrome/renderer/extensions/custom_bindings_util.h +++ b/chrome/renderer/extensions/custom_bindings_util.h @@ -24,6 +24,9 @@ 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 f187f27..9bab21a 100644 --- a/chrome/renderer/extensions/event_bindings.cc +++ b/chrome/renderer/extensions/event_bindings.cc @@ -39,26 +39,25 @@ 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(dispatcher) { - RouteStaticFunction("AttachEvent", &AttachEvent); - RouteStaticFunction("DetachEvent", &DetachEvent); + : ChromeV8Extension("extensions/event.js", + IDR_EVENT_BINDINGS_JS, + dispatcher) { } ~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); @@ -77,7 +76,7 @@ class ExtensionImpl : public ChromeV8Extension { return v8::Undefined(); EventListenerCounts& listener_counts = - g_listener_counts.Get()[context->extension_id()]; + self->listener_counts_[context->extension_id()]; if (++listener_counts[event_name] == 1) { content::RenderThread::Get()->Send( new ExtensionHostMsg_AddListener(context->extension_id(), @@ -111,7 +110,7 @@ class ExtensionImpl : public ChromeV8Extension { return v8::Undefined(); EventListenerCounts& listener_counts = - g_listener_counts.Get()[context->extension_id()]; + self->listener_counts_[context->extension_id()]; std::string event_name(*v8::String::AsciiValue(args[0])); bool is_manual = args[1]->BooleanValue(); @@ -136,6 +135,10 @@ 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(); @@ -148,10 +151,14 @@ 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 -ChromeV8Extension* EventBindings::Get(ExtensionDispatcher* dispatcher) { - return new ExtensionImpl(dispatcher); +v8::Extension* EventBindings::Get(ExtensionDispatcher* dispatcher) { + static v8::Extension* extension = new ExtensionImpl(dispatcher); + return extension; } diff --git a/chrome/renderer/extensions/event_bindings.h b/chrome/renderer/extensions/event_bindings.h index baa2004..64ada22 100644 --- a/chrome/renderer/extensions/event_bindings.h +++ b/chrome/renderer/extensions/event_bindings.h @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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,7 +6,6 @@ #define CHROME_RENDERER_EXTENSIONS_EVENT_BINDINGS_H_ #pragma once -class ChromeV8Extension; class ExtensionDispatcher; namespace v8 { @@ -16,7 +15,7 @@ class Extension; // This class deals with the javascript bindings related to Event objects. class EventBindings { public: - static ChromeV8Extension* Get(ExtensionDispatcher* dispatcher); + static v8::Extension* 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 8dd096b..11d34bb 100644 --- a/chrome/renderer/extensions/experimental.socket_custom_bindings.cc +++ b/chrome/renderer/extensions/experimental.socket_custom_bindings.cc @@ -11,22 +11,32 @@ #include "grit/renderer_resources.h" #include "v8/include/v8.h" -namespace { +namespace extensions { -v8::Handle<v8::Value> GetNextSocketEventId(const v8::Arguments& args) { +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) { // 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++); } -} // namespace - -namespace extensions { +v8::Handle<v8::FunctionTemplate> +ExperimentalSocketCustomBindings::GetNativeFunction( + v8::Handle<v8::String> name) { + if (name->Equals(v8::String::New("GetNextSocketEventId"))) + return v8::FunctionTemplate::New(GetNextSocketEventId); -ExperimentalSocketCustomBindings::ExperimentalSocketCustomBindings() - : ChromeV8Extension(NULL) { - RouteStaticFunction("GetNextSocketEventId", &GetNextSocketEventId); + return ChromeV8Extension::GetNativeFunction(name); } } // extensions diff --git a/chrome/renderer/extensions/experimental.socket_custom_bindings.h b/chrome/renderer/extensions/experimental.socket_custom_bindings.h index 32a7f7d..a444fa1 100644 --- a/chrome/renderer/extensions/experimental.socket_custom_bindings.h +++ b/chrome/renderer/extensions/experimental.socket_custom_bindings.h @@ -13,7 +13,11 @@ namespace extensions { // Implements custom bindings for the experimental.socket API. class ExperimentalSocketCustomBindings : public ChromeV8Extension { public: - ExperimentalSocketCustomBindings(); + ExperimentalSocketCustomBindings( + int dependency_count, const char** dependencies); + + virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction( + v8::Handle<v8::String> name) OVERRIDE; }; } // extensions diff --git a/chrome/renderer/extensions/extension_custom_bindings.cc b/chrome/renderer/extensions/extension_custom_bindings.cc index c4895cd..6c9947c 100644 --- a/chrome/renderer/extensions/extension_custom_bindings.cc +++ b/chrome/renderer/extensions/extension_custom_bindings.cc @@ -111,11 +111,15 @@ class ExtensionViewAccumulator : public content::RenderViewVisitor { } // namespace ExtensionCustomBindings::ExtensionCustomBindings( + int dependency_count, + const char** dependencies, ExtensionDispatcher* extension_dispatcher) - : ChromeV8Extension(extension_dispatcher) { - RouteStaticFunction("GetExtensionViews", &GetExtensionViews); - RouteStaticFunction("OpenChannelToExtension", &OpenChannelToExtension); -} + : ChromeV8Extension( + "extensions/extension_custom_bindings.js", + IDR_EXTENSION_CUSTOM_BINDINGS_JS, + dependency_count, + dependencies, + extension_dispatcher) {} // static v8::Handle<v8::Value> ExtensionCustomBindings::GetExtensionViews( @@ -168,6 +172,18 @@ 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 59cf77a..d8ac77c 100644 --- a/chrome/renderer/extensions/extension_custom_bindings.h +++ b/chrome/renderer/extensions/extension_custom_bindings.h @@ -15,7 +15,13 @@ namespace extensions { // Implements custom bindings for the extension API. class ExtensionCustomBindings : public ChromeV8Extension { public: - explicit ExtensionCustomBindings(ExtensionDispatcher* extension_dispatcher); + ExtensionCustomBindings( + int dependency_count, + const char** dependencies, + ExtensionDispatcher* extension_dispatcher); + + virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction( + v8::Handle<v8::String> name) OVERRIDE; 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 0d12b18..841ca21 100644 --- a/chrome/renderer/extensions/extension_dispatcher.cc +++ b/chrome/renderer/extensions/extension_dispatcher.cc @@ -4,10 +4,7 @@ #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" @@ -25,9 +22,6 @@ #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" @@ -41,19 +35,6 @@ #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; @@ -65,75 +46,6 @@ 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; @@ -152,8 +64,7 @@ ExtensionDispatcher::ExtensionDispatcher() : is_webkit_initialized_(false), webrequest_adblock_(false), webrequest_adblock_plus_(false), - webrequest_other_(false), - source_map_(&ResourceBundle::GetSharedInstance()) { + webrequest_other_(false) { const CommandLine& command_line = *(CommandLine::ForCurrentProcess()); is_extension_process_ = command_line.HasSwitch(switches::kExtensionProcess) || @@ -165,7 +76,6 @@ ExtensionDispatcher::ExtensionDispatcher() } user_script_slave_.reset(new UserScriptSlave(&extensions_)); - PopulateSourceMap(); } ExtensionDispatcher::~ExtensionDispatcher() { @@ -203,6 +113,25 @@ 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(); @@ -370,121 +299,55 @@ bool ExtensionDispatcher::AllowScriptExtension( int extension_group, int world_id) { g_hack_extension_group = extension_group; - return true; -} -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) + // 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); + } + 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 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); + + return false; } void ExtensionDispatcher::DidCreateScriptContext( @@ -493,49 +356,19 @@ 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, - extension_id, + GetExtensionID(frame, world_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(), @@ -566,6 +399,12 @@ 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(); } @@ -575,7 +414,7 @@ void ExtensionDispatcher::SetTestExtensionId(const std::string& id) { } bool ExtensionDispatcher::IsTestExtensionId(const std::string& id) { - return !test_extension_id_.empty() && id == test_extension_id_; + return id == test_extension_id_; } void ExtensionDispatcher::OnActivateApplication( diff --git a/chrome/renderer/extensions/extension_dispatcher.h b/chrome/renderer/extensions/extension_dispatcher.h index b1dfb40..e72c269 100644 --- a/chrome/renderer/extensions/extension_dispatcher.h +++ b/chrome/renderer/extensions/extension_dispatcher.h @@ -15,10 +15,8 @@ #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; @@ -57,18 +55,12 @@ 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, @@ -145,12 +137,6 @@ 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); @@ -196,8 +182,6 @@ 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 015d0b5..0688839 100644 --- a/chrome/renderer/extensions/file_browser_handler_custom_bindings.cc +++ b/chrome/renderer/extensions/file_browser_handler_custom_bindings.cc @@ -13,9 +13,18 @@ #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h" -namespace { +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) {} -v8::Handle<v8::Value> GetExternalFileEntry(const v8::Arguments& args) { +static 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) @@ -45,14 +54,13 @@ v8::Handle<v8::Value> GetExternalFileEntry(const v8::Arguments& args) { #endif } -} // namespace - -namespace extensions { - -FileBrowserHandlerCustomBindings::FileBrowserHandlerCustomBindings() - : ChromeV8Extension(NULL) { - RouteStaticFunction("GetExternalFileEntry", &GetExternalFileEntry); +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 extensions diff --git a/chrome/renderer/extensions/file_browser_handler_custom_bindings.h b/chrome/renderer/extensions/file_browser_handler_custom_bindings.h index 354686b..23ec5a8 100644 --- a/chrome/renderer/extensions/file_browser_handler_custom_bindings.h +++ b/chrome/renderer/extensions/file_browser_handler_custom_bindings.h @@ -14,9 +14,13 @@ namespace extensions { // Custom bindings for the fileBrowserHandler API. class FileBrowserHandlerCustomBindings : public ChromeV8Extension { public: - FileBrowserHandlerCustomBindings(); + FileBrowserHandlerCustomBindings( + int dependency_count, const char** dependencies); 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 1731552..a36e606 100644 --- a/chrome/renderer/extensions/file_browser_private_custom_bindings.cc +++ b/chrome/renderer/extensions/file_browser_private_custom_bindings.cc @@ -13,7 +13,16 @@ #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h" -namespace { +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) {} static v8::Handle<v8::Value> GetLocalFileSystem( const v8::Arguments& args) { @@ -31,13 +40,13 @@ static v8::Handle<v8::Value> GetLocalFileSystem( WebKit::WebString::fromUTF8(path.c_str())); } -} // namespace - -namespace extensions { +v8::Handle<v8::FunctionTemplate> +FileBrowserPrivateCustomBindings::GetNativeFunction( + v8::Handle<v8::String> name) { + if (name->Equals(v8::String::New("GetLocalFileSystem"))) + return v8::FunctionTemplate::New(GetLocalFileSystem); -FileBrowserPrivateCustomBindings::FileBrowserPrivateCustomBindings() - : ChromeV8Extension(NULL) { - RouteStaticFunction("GetLocalFileSystem", &GetLocalFileSystem); + return ChromeV8Extension::GetNativeFunction(name); } } // 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 191c0dd..d987a06 100644 --- a/chrome/renderer/extensions/file_browser_private_custom_bindings.h +++ b/chrome/renderer/extensions/file_browser_private_custom_bindings.h @@ -14,9 +14,13 @@ namespace extensions { // Custom bindings for the fileBrowserPrivate API. class FileBrowserPrivateCustomBindings : public ChromeV8Extension { public: - FileBrowserPrivateCustomBindings(); + FileBrowserPrivateCustomBindings( + int dependency_count, const char** dependencies); 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 afd4be7..982acbf 100644 --- a/chrome/renderer/extensions/i18n_custom_bindings.cc +++ b/chrome/renderer/extensions/i18n_custom_bindings.cc @@ -12,9 +12,21 @@ namespace extensions { -I18NCustomBindings::I18NCustomBindings() - : ChromeV8Extension(NULL) { - RouteStaticFunction("GetL10nMessage", &GetL10nMessage); +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); } // static diff --git a/chrome/renderer/extensions/i18n_custom_bindings.h b/chrome/renderer/extensions/i18n_custom_bindings.h index e0ca0df..1cc8743 100644 --- a/chrome/renderer/extensions/i18n_custom_bindings.h +++ b/chrome/renderer/extensions/i18n_custom_bindings.h @@ -13,7 +13,10 @@ namespace extensions { // Implements custom bindings for the i18n API. class I18NCustomBindings : public ChromeV8Extension { public: - I18NCustomBindings(); + I18NCustomBindings(int dependency_count, const char** dependencies); + + virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction( + v8::Handle<v8::String> name) OVERRIDE; 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 c4b0614..1e76b41 100644 --- a/chrome/renderer/extensions/json_schema_unittest.cc +++ b/chrome/renderer/extensions/json_schema_unittest.cc @@ -25,14 +25,15 @@ class JsonSchemaTest : public V8UnitTest { std::string code = ResourceBundle::GetSharedInstance().GetRawDataResource( IDR_JSON_SCHEMA_JS).as_string(); - // json_schema.js expects to have requireNative() defined. - ExecuteScriptInContext( - "function requireNative(id) {" - " return {" - " GetChromeHidden: function() { return {}; }," - " };" - "}", - "test-code"); + // 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" + "}"); 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 25fc895..31a8923 100644 --- a/chrome/renderer/extensions/miscellaneous_bindings.cc +++ b/chrome/renderer/extensions/miscellaneous_bindings.cc @@ -62,19 +62,32 @@ 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(dispatcher) { - RouteStaticFunction("CloseChannel", &CloseChannel); - RouteStaticFunction("PortAddRef", &PortAddRef); - RouteStaticFunction("PortRelease", &PortRelease); - RouteStaticFunction("PostMessage", &PostMessage); + : ChromeV8Extension("extensions/miscellaneous_bindings.js", + IDR_MISCELLANEOUS_BINDINGS_JS, + arraysize(kExtensionDeps), kExtensionDeps, + dispatcher) { } - ~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); + } + // Sends a message along the given channel. static v8::Handle<v8::Value> PostMessage(const v8::Arguments& args) { content::RenderView* renderview = GetCurrentRenderView(); @@ -142,8 +155,9 @@ class ExtensionImpl : public ChromeV8Extension { namespace extensions { -ChromeV8Extension* MiscellaneousBindings::Get(ExtensionDispatcher* dispatcher) { - return new ExtensionImpl(dispatcher); +v8::Extension* MiscellaneousBindings::Get(ExtensionDispatcher* dispatcher) { + static v8::Extension* extension = new ExtensionImpl(dispatcher); + return extension; } void MiscellaneousBindings::DeliverMessage( diff --git a/chrome/renderer/extensions/miscellaneous_bindings.h b/chrome/renderer/extensions/miscellaneous_bindings.h index 0df26fa..1db641b 100644 --- a/chrome/renderer/extensions/miscellaneous_bindings.h +++ b/chrome/renderer/extensions/miscellaneous_bindings.h @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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,7 +10,6 @@ #include "chrome/renderer/extensions/chrome_v8_context_set.h" -class ChromeV8Extension; class ExtensionDispatcher; namespace content { @@ -31,7 +30,7 @@ namespace extensions { class MiscellaneousBindings { public: // Creates an instance of the extension. - static ChromeV8Extension* Get(ExtensionDispatcher* dispatcher); + static v8::Extension* 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 b6e86ee..0d9d61a 100644 --- a/chrome/renderer/extensions/page_actions_custom_bindings.cc +++ b/chrome/renderer/extensions/page_actions_custom_bindings.cc @@ -14,10 +14,15 @@ namespace extensions { PageActionsCustomBindings::PageActionsCustomBindings( + int dependency_count, + const char** dependencies, ExtensionDispatcher* extension_dispatcher) - : ChromeV8Extension(extension_dispatcher) { - RouteStaticFunction("GetCurrentPageActions", &GetCurrentPageActions); -} + : ChromeV8Extension( + "extensions/page_actions_custom_bindings.js", + IDR_PAGE_ACTIONS_CUSTOM_BINDINGS_JS, + dependency_count, + dependencies, + extension_dispatcher) {} // static v8::Handle<v8::Value> PageActionsCustomBindings::GetCurrentPageActions( @@ -40,4 +45,15 @@ 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 1faad35..09e68d9 100644 --- a/chrome/renderer/extensions/page_actions_custom_bindings.h +++ b/chrome/renderer/extensions/page_actions_custom_bindings.h @@ -15,7 +15,13 @@ namespace extensions { // Implements custom bindings for the pageActions API. class PageActionsCustomBindings : public ChromeV8Extension { public: - explicit PageActionsCustomBindings(ExtensionDispatcher* extension_dispatcher); + PageActionsCustomBindings( + int dependency_count, + const char** dependencies, + ExtensionDispatcher* extension_dispatcher); + + virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction( + v8::Handle<v8::String> name) OVERRIDE; 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 c7e41ea..e37cdab 100644 --- a/chrome/renderer/extensions/page_capture_custom_bindings.cc +++ b/chrome/renderer/extensions/page_capture_custom_bindings.cc @@ -13,15 +13,18 @@ namespace extensions { -PageCaptureCustomBindings::PageCaptureCustomBindings() - : ChromeV8Extension(NULL) { - RouteStaticFunction("CreateBlob", &CreateBlob); - RouteStaticFunction("SendResponseAck", &SendResponseAck); -} - -// static -v8::Handle<v8::Value> PageCaptureCustomBindings::CreateBlob( - const v8::Arguments& args) { +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) { CHECK(args.Length() == 2); CHECK(args[0]->IsString()); CHECK(args[1]->IsInt32()); @@ -45,4 +48,15 @@ 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 4796e13..a6ec433 100644 --- a/chrome/renderer/extensions/page_capture_custom_bindings.h +++ b/chrome/renderer/extensions/page_capture_custom_bindings.h @@ -13,11 +13,12 @@ namespace extensions { // Implements custom bindings for the pageCapture API. class PageCaptureCustomBindings : public ChromeV8Extension { public: - PageCaptureCustomBindings(); + PageCaptureCustomBindings(int dependency_count, const char** dependencies); + + virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction( + v8::Handle<v8::String> name) OVERRIDE; 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 eda15d8..c0e0725 100644 --- a/chrome/renderer/extensions/schema_generated_bindings.cc +++ b/chrome/renderer/extensions/schema_generated_bindings.cc @@ -51,6 +51,13 @@ 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 : @@ -70,12 +77,11 @@ base::LazyInstance<PendingRequestMap> g_pending_requests = class ExtensionImpl : public ChromeV8Extension { public: explicit ExtensionImpl(ExtensionDispatcher* extension_dispatcher) - : ChromeV8Extension(extension_dispatcher) { - RouteStaticFunction("GetExtensionAPIDefinition", - &GetExtensionAPIDefinition); - RouteStaticFunction("GetNextRequestId", &GetNextRequestId); - RouteStaticFunction("StartRequest", &StartRequest); - RouteStaticFunction("SetIconCommon", &SetIconCommon); + : ChromeV8Extension("extensions/schema_generated_bindings.js", + IDR_SCHEMA_GENERATED_BINDINGS_JS, + arraysize(kExtensionDeps), + kExtensionDeps, + extension_dispatcher) { } ~ExtensionImpl() { @@ -88,6 +94,24 @@ 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, @@ -323,9 +347,12 @@ class ExtensionImpl : public ChromeV8Extension { namespace extensions { -ChromeV8Extension* SchemaGeneratedBindings::Get( +v8::Extension* SchemaGeneratedBindings::Get( ExtensionDispatcher* extension_dispatcher) { - return new ExtensionImpl(extension_dispatcher); + static v8::Extension* extension = new ExtensionImpl(extension_dispatcher); + CHECK_EQ(extension_dispatcher, + static_cast<ExtensionImpl*>(extension)->extension_dispatcher()); + return extension; } // static diff --git a/chrome/renderer/extensions/schema_generated_bindings.h b/chrome/renderer/extensions/schema_generated_bindings.h index e50ed96..1785171 100644 --- a/chrome/renderer/extensions/schema_generated_bindings.h +++ b/chrome/renderer/extensions/schema_generated_bindings.h @@ -1,4 +1,4 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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,7 +10,6 @@ class ExtensionDispatcher; class ChromeV8ContextSet; -class ChromeV8Extension; namespace v8 { class Extension; @@ -22,7 +21,7 @@ namespace extensions { // declarations in chrome/common/extensions/api/. class SchemaGeneratedBindings { public: - static ChromeV8Extension* Get(ExtensionDispatcher* extension_dispatcher); + static v8::Extension* 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 3d908bb..abb2262 100644 --- a/chrome/renderer/extensions/tabs_custom_bindings.cc +++ b/chrome/renderer/extensions/tabs_custom_bindings.cc @@ -15,10 +15,14 @@ namespace extensions { -TabsCustomBindings::TabsCustomBindings() - : ChromeV8Extension(NULL) { - RouteStaticFunction("OpenChannelToTab", &OpenChannelToTab); -} +TabsCustomBindings::TabsCustomBindings( + int dependency_count, const char** dependencies) + : ChromeV8Extension( + "extensions/tabs_custom_bindings.js", + IDR_TABS_CUSTOM_BINDINGS_JS, + dependency_count, + dependencies, + NULL) {} // static v8::Handle<v8::Value> TabsCustomBindings::OpenChannelToTab( @@ -43,4 +47,12 @@ 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 ec06979..0700a43 100644 --- a/chrome/renderer/extensions/tabs_custom_bindings.h +++ b/chrome/renderer/extensions/tabs_custom_bindings.h @@ -13,7 +13,10 @@ namespace extensions { // Implements custom bindings for the tabs API. class TabsCustomBindings : public ChromeV8Extension { public: - TabsCustomBindings(); + TabsCustomBindings(int dependency_count, const char** dependencies); + + virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction( + v8::Handle<v8::String> name) OVERRIDE; 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 33e1887..dca526a 100644 --- a/chrome/renderer/extensions/tts_custom_bindings.cc +++ b/chrome/renderer/extensions/tts_custom_bindings.cc @@ -13,18 +13,30 @@ namespace extensions { -TTSCustomBindings::TTSCustomBindings() - : ChromeV8Extension(NULL) { - RouteStaticFunction("GetNextTTSEventId", &GetNextTTSEventId); -} +TTSCustomBindings::TTSCustomBindings( + int dependency_count, + const char** dependencies) + : ChromeV8Extension( + "extensions/tts_custom_bindings.js", + IDR_TTS_CUSTOM_BINDINGS_JS, + dependency_count, + dependencies, + NULL) {} -// static -v8::Handle<v8::Value> TTSCustomBindings::GetNextTTSEventId( - const v8::Arguments& args) { +static v8::Handle<v8::Value> 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 c99a03a..c7598eb 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(); + TTSCustomBindings(int dependency_count, const char** dependencies); - private: - static v8::Handle<v8::Value> GetNextTTSEventId(const v8::Arguments& args); + virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction( + v8::Handle<v8::String> name) OVERRIDE; }; } // extensions diff --git a/chrome/renderer/extensions/web_request_custom_bindings.cc b/chrome/renderer/extensions/web_request_custom_bindings.cc index 83f716c..3246926 100644 --- a/chrome/renderer/extensions/web_request_custom_bindings.cc +++ b/chrome/renderer/extensions/web_request_custom_bindings.cc @@ -12,15 +12,18 @@ namespace extensions { -WebRequestCustomBindings::WebRequestCustomBindings() - : ChromeV8Extension(NULL) { - RouteStaticFunction("GetUniqueSubEventName", &GetUniqueSubEventName); -} +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) {} // Attach an event name to an object. -// static -v8::Handle<v8::Value> WebRequestCustomBindings::GetUniqueSubEventName( - const v8::Arguments& args) { +static v8::Handle<v8::Value> GetUniqueSubEventName(const v8::Arguments& args) { static int next_event_id = 0; DCHECK(args.Length() == 1); DCHECK(args[0]->IsString()); @@ -30,5 +33,13 @@ v8::Handle<v8::Value> WebRequestCustomBindings::GetUniqueSubEventName( 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 028c37d..285ae88 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(); + WebRequestCustomBindings(int dependency_count, const char** dependencies); - private: - static v8::Handle<v8::Value> GetUniqueSubEventName(const v8::Arguments& args); + virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction( + v8::Handle<v8::String> name) OVERRIDE; }; } // extensions diff --git a/chrome/renderer/extensions/webstore_bindings.cc b/chrome/renderer/extensions/webstore_bindings.cc index 7214db9..5991e6a 100644 --- a/chrome/renderer/extensions/webstore_bindings.cc +++ b/chrome/renderer/extensions/webstore_bindings.cc @@ -13,6 +13,7 @@ #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" @@ -47,17 +48,69 @@ 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, +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, ChromeV8Context* context) - : ChromeV8Extension(dispatcher), - ChromeV8ExtensionHandler(context) { - RouteFunction("Install", - base::Bind(&WebstoreBindings::Install, base::Unretained(this))); + : 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(); } -v8::Handle<v8::Value> WebstoreBindings::Install( +v8::Handle<v8::Value> WebstoreBindingsHandler::Install( const v8::Arguments& args) { WebFrame* frame = WebFrame::frameForCurrentContext(); if (!frame || !frame->view()) @@ -108,7 +161,7 @@ v8::Handle<v8::Value> WebstoreBindings::Install( } // static -bool WebstoreBindings::GetWebstoreItemIdFromFrame( +bool WebstoreBindingsHandler::GetWebstoreItemIdFromFrame( WebFrame* frame, const std::string& preferred_store_link_url, std::string* webstore_item_id, std::string* error) { if (frame != frame->top()) { @@ -194,8 +247,8 @@ bool WebstoreBindings::GetWebstoreItemIdFromFrame( return false; } -bool WebstoreBindings::OnMessageReceived(const IPC::Message& message) { - IPC_BEGIN_MESSAGE_MAP(WebstoreBindings, message) +bool WebstoreBindingsHandler::OnMessageReceived(const IPC::Message& message) { + IPC_BEGIN_MESSAGE_MAP(WebstoreBindingsHandler, message) IPC_MESSAGE_HANDLER(ExtensionMsg_InlineWebstoreInstallResponse, OnInlineWebstoreInstallResponse) IPC_MESSAGE_UNHANDLED(CHECK(false) << "Unhandled IPC message") @@ -203,7 +256,7 @@ bool WebstoreBindings::OnMessageReceived(const IPC::Message& message) { return true; } -void WebstoreBindings::OnInlineWebstoreInstallResponse( +void WebstoreBindingsHandler::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 33ac48e..098f888 100644 --- a/chrome/renderer/extensions/webstore_bindings.h +++ b/chrome/renderer/extensions/webstore_bindings.h @@ -8,37 +8,21 @@ #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, - public ChromeV8ExtensionHandler { +class WebstoreBindings : public ChromeV8Extension { public: - explicit WebstoreBindings(ExtensionDispatcher* dispatcher, - ChromeV8Context* context); + explicit WebstoreBindings(ExtensionDispatcher* dispatcher); - // IPC::Channel::Listener - virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; + protected: + virtual ChromeV8ExtensionHandler* CreateHandler( + ChromeV8Context* context) 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 30f5906..6c685f3 100644 --- a/chrome/renderer/module_system.cc +++ b/chrome/renderer/module_system.cc @@ -11,11 +11,18 @@ 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(SourceMap* source_map) - : source_map_(source_map), - natives_enabled_(true) { +ModuleSystem::ModuleSystem(const std::map<std::string, std::string>* source_map) + : source_map_(source_map) { + RouteFunction("Run", + base::Bind(&ModuleSystem::Run, base::Unretained(this))); RouteFunction("GetSource", base::Bind(&ModuleSystem::GetSource, base::Unretained(this))); RouteFunction("GetNative", @@ -40,21 +47,12 @@ 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(); - // 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::Value> result = RunString(GetResource(IDR_REQUIRE_JS)); v8::Handle<v8::Function> require_factory = v8::Handle<v8::Function>::Cast(result); CHECK(!require_factory.IsEmpty()) @@ -69,38 +67,32 @@ void ModuleSystem::EnsureRequireLoaded() { v8::Handle<v8::Function>::Cast(require)); } -v8::Handle<v8::Value> ModuleSystem::RunString(v8::Handle<v8::String> code, - v8::Handle<v8::String> name) { +v8::Handle<v8::Value> ModuleSystem::RunString(v8::Handle<v8::String> code) { v8::HandleScope handle_scope; - return handle_scope.Close(v8::Script::New(code, name)->Run()); + return handle_scope.Close(v8::Script::New(code)->Run()); } -v8::Handle<v8::Value> ModuleSystem::GetSource(const v8::Arguments& args) { +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()); +} + +v8::Handle<v8::Value> ModuleSystem::GetSource(const v8::Arguments& args) { + CHECK_EQ(1, args.Length()); std::string module_name = *v8::String::AsciiValue(args[0]->ToString()); - if (!source_map_->Contains(module_name)) + std::map<std::string, std::string>::const_iterator p = + source_map_->find(module_name); + if (p == source_map_->end()) return v8::Undefined(); - return handle_scope.Close(source_map_->GetSource(module_name)); + return v8::String::New(p->second.c_str()); } 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 da93423..b29d8d6 100644 --- a/chrome/renderer/module_system.h +++ b/chrome/renderer/module_system.h @@ -9,15 +9,12 @@ #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 @@ -30,20 +27,10 @@ class SourceMap; // // 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(SourceMap* source_map); + explicit ModuleSystem(const std::map<std::string, std::string>* source_map); virtual ~ModuleSystem(); // Require the specified module. This is the equivalent of calling @@ -54,27 +41,18 @@ 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); - - // 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; - } + scoped_ptr<NativeHandler> native_handler); 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 with the name |name| used for stack - // traces. - v8::Handle<v8::Value> RunString(v8::Handle<v8::String> code, - v8::Handle<v8::String> name); + // 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); // Return the named source file stored in the source map. // |args[0]| - the name of a source file in source_map_. @@ -85,17 +63,12 @@ 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. - SourceMap* source_map_; + const std::map<std::string, std::string>* source_map_; + typedef std::map<std::string, linked_ptr<NativeHandler> > NativeHandlerMap; 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 47584a3..bed8a27 100644 --- a/chrome/renderer/module_system_unittest.cc +++ b/chrome/renderer/module_system_unittest.cc @@ -4,14 +4,12 @@ #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() @@ -35,69 +33,22 @@ 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()), - handle_scope_(), - assert_natives_(new AssertNatives()), - source_map_(new StringSourceMap()), - module_system_(new ModuleSystem(source_map_)) { + assert_natives_(new AssertNatives()) { 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()); @@ -105,63 +56,45 @@ 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_; - StringSourceMap* source_map_; + std::map<std::string, std::string> source_map_; scoped_ptr<ModuleSystem> module_system_; }; TEST_F(ModuleSystemTest, TestRequire) { - RegisterModule("test", + source_map_["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) { - RegisterModule("double", + source_map_["double"] = "var Add = require('add').Add;" - "exports.Double = function(x) { return Add(x, x); };"); - RegisterModule("test", + "exports.Double = function(x) { return Add(x, x); };"; + source_map_["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) { - RegisterModule("x", + source_map_["x"] = "var x = 10;" - "exports.X = function() { return x; };"); - RegisterModule("y", + "exports.X = function() { return x; };"; + source_map_["y"] = "var x = 15;" "require('x');" - "exports.Y = function() { return x; };"); - RegisterModule("test", + "exports.Y = function() { return x; };"; + source_map_["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);"); - 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);"); + "assert.AssertTrue(X() == 10);"; module_system_->Require("test"); } diff --git a/chrome/renderer/native_handler.cc b/chrome/renderer/native_handler.cc index afa21ff..614df08 100644 --- a/chrome/renderer/native_handler.cc +++ b/chrome/renderer/native_handler.cc @@ -28,18 +28,9 @@ 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 f595a0d..b4d3078 100644 --- a/chrome/renderer/native_handler.h +++ b/chrome/renderer/native_handler.h @@ -16,12 +16,6 @@ // 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(); @@ -32,7 +26,6 @@ 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; @@ -42,9 +35,6 @@ 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 99cd777..82ecee7 100644 --- a/chrome/renderer/renderer_resources.grd +++ b/chrome/renderer/renderer_resources.grd @@ -26,7 +26,6 @@ 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 deleted file mode 100644 index 2c06b7b..0000000 --- a/chrome/renderer/resource_bundle_source_map.cc +++ /dev/null @@ -1,40 +0,0 @@ -// 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 deleted file mode 100644 index 142930c..0000000 --- a/chrome/renderer/resource_bundle_source_map.h +++ /dev/null @@ -1,40 +0,0 @@ -// 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 6f015ef..7e7e62f 100644 --- a/chrome/renderer/resources/extensions/apitest.js +++ b/chrome/renderer/resources/extensions/apitest.js @@ -1,10 +1,12 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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 || []; @@ -273,3 +275,4 @@ chrome.test.tests = tests; chrome.test.runNextTest(); }; +})(); diff --git a/chrome/renderer/resources/extensions/app.js b/chrome/renderer/resources/extensions/app.js index 7337d86..8fbce65 100644 --- a/chrome/renderer/resources/extensions/app.js +++ b/chrome/renderer/resources/extensions/app.js @@ -1,15 +1,17 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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 natives = requireNative('app'); - var GetIsInstalled = natives.GetIsInstalled; - var Install = natives.Install; - var GetDetails = natives.GetDetails; - var GetDetailsForFrame = natives.GetDetailsForFrame; - var GetAppNotifyChannel = natives.GetAppNotifyChannel; +var chrome = chrome || {}; +(function() { + native function GetChromeHidden(); + native function GetIsInstalled(); + native function Install(); + native function GetDetails(); + native function GetDetailsForFrame(); + native function GetAppNotifyChannel(); - var chromeHidden = requireNative('chrome_hidden').GetChromeHidden(); + var chromeHidden = GetChromeHidden(); var callbacks = {}; var nextCallbackId = 1; @@ -39,3 +41,4 @@ 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 137da5b..8b791a7 100644 --- a/chrome/renderer/resources/extensions/browser_action_custom_bindings.js +++ b/chrome/renderer/resources/extensions/browser_action_custom_bindings.js @@ -4,9 +4,11 @@ // Custom bindings for the browserAction API. -var chromeHidden = requireNative('chrome_hidden').GetChromeHidden(); +(function() { -chromeHidden.registerCustomHook('browserAction', function(bindingsAPI) { +native function GetChromeHidden(); + +GetChromeHidden().registerCustomHook('browserAction', function(bindingsAPI) { var apiFunctions = bindingsAPI.apiFunctions; var setIcon = bindingsAPI.setIcon; @@ -14,3 +16,5 @@ chromeHidden.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 b50bbee..c3f712b 100644 --- a/chrome/renderer/resources/extensions/chrome_private_custom_bindings.js +++ b/chrome/renderer/resources/extensions/chrome_private_custom_bindings.js @@ -4,15 +4,17 @@ // Custom bindings for the chromePrivate API. -var chromePrivate = requireNative('chrome_private'); -var DecodeJPEG = chromePrivate.DecodeJPEG; +(function() { -var chromeHidden = requireNative('chrome_hidden').GetChromeHidden(); +native function GetChromeHidden(); +native function DecodeJPEG(jpegImage); -chromeHidden.registerCustomHook('chromePrivate', function(bindingsAPI) { +GetChromeHidden().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 bc98a90..14bc91c 100644 --- a/chrome/renderer/resources/extensions/content_settings_custom_bindings.js +++ b/chrome/renderer/resources/extensions/content_settings_custom_bindings.js @@ -4,7 +4,11 @@ // Custom bindings for the contentSettings API. -var chromeHidden = requireNative('chrome_hidden').GetChromeHidden(); +(function() { + +native function GetChromeHidden(); + +var chromeHidden = GetChromeHidden(); chromeHidden.registerCustomType('ContentSetting', function(typesAPI) { var sendRequest = typesAPI.sendRequest; @@ -50,3 +54,5 @@ 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 546140b..e4983e6 100644 --- a/chrome/renderer/resources/extensions/context_menus_custom_bindings.js +++ b/chrome/renderer/resources/extensions/context_menus_custom_bindings.js @@ -4,10 +4,12 @@ // Custom bindings for the contextMenus API. -var contextMenus = requireNative('context_menus'); -var GetNextContextMenuId = contextMenus.GetNextContextMenuId; +(function() { -var chromeHidden = requireNative('chrome_hidden').GetChromeHidden(); +native function GetChromeHidden(); +native function GetNextContextMenuId(); + +var chromeHidden = GetChromeHidden(); chromeHidden.registerCustomHook('contextMenus', function(bindingsAPI) { var apiFunctions = bindingsAPI.apiFunctions; @@ -85,3 +87,5 @@ 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 9d1d8eb..d1ad34c 100644 --- a/chrome/renderer/resources/extensions/devtools_custom_bindings.js +++ b/chrome/renderer/resources/extensions/devtools_custom_bindings.js @@ -4,9 +4,11 @@ // Custom bindings for the devtools API. -var chromeHidden = requireNative('chrome_hidden').GetChromeHidden(); +(function() { -chromeHidden.registerCustomHook('devtools', function(bindingsAPI) { +native function GetChromeHidden(); + +GetChromeHidden().registerCustomHook('devtools', function(bindingsAPI) { var apiFunctions = bindingsAPI.apiFunctions; apiFunctions.setHandleRequest('getTabEvents', function(tabId) { @@ -21,3 +23,5 @@ chromeHidden.registerCustomHook('devtools', function(bindingsAPI) { return tabIdProxy; }); }); + +})(); diff --git a/chrome/renderer/resources/extensions/event.js b/chrome/renderer/resources/extensions/event.js index c8a05cf..2cf78a8 100644 --- a/chrome/renderer/resources/extensions/event.js +++ b/chrome/renderer/resources/extensions/event.js @@ -2,12 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. - var eventBindingsNatives = requireNative('event_bindings'); - var AttachEvent = eventBindingsNatives.AttachEvent; - var DetachEvent = eventBindingsNatives.DetachEvent; - var Print = eventBindingsNatives.Print; +var chrome = chrome || {}; +(function () { + native function GetChromeHidden(); + native function AttachEvent(eventName); + native function DetachEvent(eventName, manual); + native function Print(); - var chromeHidden = requireNative('chrome_hidden').GetChromeHidden(); + var chromeHidden = GetChromeHidden(); // Local implementation of JSON.parse & JSON.stringify that protect us // from being clobbered by an extension. @@ -309,3 +311,4 @@ 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 73d4642..de47b6c 100644 --- a/chrome/renderer/resources/extensions/experimental.declarative_custom_bindings.js +++ b/chrome/renderer/resources/extensions/experimental.declarative_custom_bindings.js @@ -4,7 +4,11 @@ // Custom bindings for the declarative API. -var chromeHidden = requireNative('chrome_hidden').GetChromeHidden(); +(function() { + +native function GetChromeHidden(); + +var chromeHidden = GetChromeHidden(); chromeHidden.registerCustomHook('experimental.declarative', function(bindingsAPI) { @@ -74,3 +78,5 @@ 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 a5b2568..52a8659 100644 --- a/chrome/renderer/resources/extensions/experimental.socket_custom_bindings.js +++ b/chrome/renderer/resources/extensions/experimental.socket_custom_bindings.js @@ -4,10 +4,11 @@ // Custom bindings for the experimental.socket API. - var experimentalSocketNatives = requireNative('experimental_socket'); - var GetNextSocketEventId = experimentalSocketNatives.GetNextSocketEventId; +(function() { + native function GetChromeHidden(); + native function GetNextSocketEventId(); - var chromeHidden = requireNative('chrome_hidden').GetChromeHidden(); + var chromeHidden = GetChromeHidden(); chromeHidden.registerCustomHook('experimental.socket', function(api) { var apiFunctions = api.apiFunctions; @@ -55,3 +56,5 @@ } }); }); + +})(); diff --git a/chrome/renderer/resources/extensions/extension_custom_bindings.js b/chrome/renderer/resources/extensions/extension_custom_bindings.js index 970e11f..f746e2a 100644 --- a/chrome/renderer/resources/extensions/extension_custom_bindings.js +++ b/chrome/renderer/resources/extensions/extension_custom_bindings.js @@ -4,11 +4,13 @@ // Custom bindings for the extension API. -var extensionNatives = requireNative('extension'); -var GetExtensionViews = extensionNatives.GetExtensionViews; -var OpenChannelToExtension = extensionNatives.OpenChannelToExtension; +(function() { -var chromeHidden = requireNative('chrome_hidden').GetChromeHidden(); +native function GetChromeHidden(); +native function GetExtensionViews(); +native function OpenChannelToExtension(sourceId, targetId, name); + +var chromeHidden = GetChromeHidden(); // This should match chrome.windows.WINDOW_ID_NONE. // @@ -142,3 +144,5 @@ 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 44d1539..9fb152c 100644 --- a/chrome/renderer/resources/extensions/file_browser_handler_custom_bindings.js +++ b/chrome/renderer/resources/extensions/file_browser_handler_custom_bindings.js @@ -4,11 +4,12 @@ // Custom bindings for the fileBrowserHandler API. -var fileBrowserNatives = requireNative('file_browser_handler'); -var GetExternalFileEntry = fileBrowserNatives.GetExternalFileEntry; +(function() { -var chromeHidden = requireNative('chrome_hidden').GetChromeHidden(); +native function GetChromeHidden(); +native function GetExternalFileEntry(); +var chromeHidden = GetChromeHidden(); chromeHidden.Event.registerArgumentMassager('fileBrowserHandler.onExecute', function(args) { if (args.length < 2) @@ -22,3 +23,5 @@ 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 2423cfb..7b483b5 100644 --- a/chrome/renderer/resources/extensions/file_browser_private_custom_bindings.js +++ b/chrome/renderer/resources/extensions/file_browser_private_custom_bindings.js @@ -4,10 +4,12 @@ // Custom bindings for the fileBrowserPrivate API. -var fileBrowserPrivateNatives = requireNative('file_browser_private'); -var GetLocalFileSystem = fileBrowserPrivateNatives.GetLocalFileSystem; +(function() { -var chromeHidden = requireNative('chrome_hidden').GetChromeHidden(); +native function GetChromeHidden(); +native function GetLocalFileSystem(name, path); + +var chromeHidden = GetChromeHidden(); chromeHidden.registerCustomHook('fileBrowserPrivate', function(bindingsAPI) { var apiFunctions = bindingsAPI.apiFunctions; @@ -23,3 +25,5 @@ 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 a9fa5a2..8f9ca30 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. -var i18nNatives = requireNative('i18n'); -var GetL10nMessage = i18nNatives.GetL10nMessage; +(function() { -var chromeHidden = requireNative('chrome_hidden').GetChromeHidden(); +native function GetChromeHidden(); +native function GetL10nMessage(); -chromeHidden.registerCustomHook('i18n', +GetChromeHidden().registerCustomHook('i18n', function(bindingsAPI, extensionId) { var apiFunctions = bindingsAPI.apiFunctions; @@ -18,3 +18,5 @@ chromeHidden.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 8f400c7..c6bbbfc 100644 --- a/chrome/renderer/resources/extensions/input.ime_custom_bindings.js +++ b/chrome/renderer/resources/extensions/input.ime_custom_bindings.js @@ -5,9 +5,11 @@ // Custom bindings for the input ime API. Only injected into the // v8 contexts for extensions which have permission for the API. -var chromeHidden = requireNative('chrome_hidden').GetChromeHidden(); +(function() { -chromeHidden.registerCustomHook('input.ime', function() { +native function GetChromeHidden(); + +GetChromeHidden().registerCustomHook('input.ime', function() { chrome.input.ime.onKeyEvent.dispatch = function(engineID, keyData) { var args = Array.prototype.slice.call(arguments); if (this.validate_) { @@ -34,3 +36,5 @@ chromeHidden.registerCustomHook('input.ime', function() { } }; }); + +})(); diff --git a/chrome/renderer/resources/extensions/json_schema.js b/chrome/renderer/resources/extensions/json_schema.js index bc51d97..f1fdf9e 100644 --- a/chrome/renderer/resources/extensions/json_schema.js +++ b/chrome/renderer/resources/extensions/json_schema.js @@ -38,7 +38,9 @@ // additional properties will be validated. //============================================================================== -var chromeHidden = requireNative('chrome_hidden').GetChromeHidden(); +(function() { +native function GetChromeHidden(); +var chromeHidden = GetChromeHidden(); function isInstanceOfClass(instance, className) { if (!instance) @@ -496,3 +498,5 @@ 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 a2d284d..6bcfc11 100644 --- a/chrome/renderer/resources/extensions/miscellaneous_bindings.js +++ b/chrome/renderer/resources/extensions/miscellaneous_bindings.js @@ -7,15 +7,16 @@ // scripts or background pages. // See user_script_slave.cc for script that is loaded by content scripts only. - 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 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(); var manifestVersion; var extensionId; @@ -209,3 +210,4 @@ 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 37f8d92..13a3c61 100644 --- a/chrome/renderer/resources/extensions/omnibox_custom_bindings.js +++ b/chrome/renderer/resources/extensions/omnibox_custom_bindings.js @@ -5,7 +5,9 @@ // Custom bindings for the omnibox API. Only injected into the v8 contexts // for extensions which have permission for the omnibox API. -var chromeHidden = requireNative('chrome_hidden').GetChromeHidden(); +(function() { + +native function GetChromeHidden(); // Remove invalid characters from |text| so that it is suitable to use // for |AutocompleteMatch::contents|. @@ -77,7 +79,7 @@ function parseOmniboxDescription(input) { return result; } -chromeHidden.registerCustomHook('omnibox', function(bindingsAPI) { +GetChromeHidden().registerCustomHook('omnibox', function(bindingsAPI) { var apiFunctions = bindingsAPI.apiFunctions; var sendRequest = bindingsAPI.sendRequest; @@ -106,3 +108,5 @@ chromeHidden.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 13336b1d..722a57b 100644 --- a/chrome/renderer/resources/extensions/page_action_custom_bindings.js +++ b/chrome/renderer/resources/extensions/page_action_custom_bindings.js @@ -4,9 +4,11 @@ // Custom bindings for the pageAction API. -var chromeHidden = requireNative('chrome_hidden').GetChromeHidden(); +(function() { -chromeHidden.registerCustomHook('pageAction', function(bindingsAPI) { +native function GetChromeHidden(); + +GetChromeHidden().registerCustomHook('pageAction', function(bindingsAPI) { var apiFunctions = bindingsAPI.apiFunctions; var setIcon = bindingsAPI.setIcon; @@ -14,3 +16,5 @@ chromeHidden.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 d5ec888..2a7a2de 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. -var pageActionsNatives = requireNative('page_actions'); -var GetCurrentPageActions = pageActionsNatives.GetCurrentPageActions; +(function() { -var chromeHidden = requireNative('chrome_hidden').GetChromeHidden(); +native function GetChromeHidden(); +native function GetCurrentPageActions(); -chromeHidden.registerCustomHook('pageActions', - function(bindingsAPI, extensionId) { +GetChromeHidden().registerCustomHook('pageActions', + function(bindingsAPI, extensionId) { var pageActions = GetCurrentPageActions(extensionId); var oldStyleEventName = 'pageActions'; for (var i = 0; i < pageActions.length; ++i) { @@ -18,3 +18,5 @@ chromeHidden.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 0bcbb0b..e8a7af4 100644 --- a/chrome/renderer/resources/extensions/page_capture_custom_bindings.js +++ b/chrome/renderer/resources/extensions/page_capture_custom_bindings.js @@ -4,11 +4,13 @@ // Custom bindings for the pageCapture API. -var pageCaptureNatives = requireNative('page_capture'); -var CreateBlob = pageCaptureNatives.CreateBlob; -var SendResponseAck = pageCaptureNatives.SendResponseAck; +(function() { -var chromeHidden = requireNative('chrome_hidden').GetChromeHidden(); +native function GetChromeHidden(); +native function CreateBlob(filePath); +native function SendResponseAck(requestId); + +var chromeHidden = GetChromeHidden(); chromeHidden.registerCustomHook('pageCapture', function(bindingsAPI) { var apiFunctions = bindingsAPI.apiFunctions; @@ -28,3 +30,5 @@ 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 ab11923..bc057d2 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. - 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 chrome = chrome || {}; +(function() { + native function GetChromeHidden(); + native function GetExtensionAPIDefinition(); + native function GetNextRequestId(); + native function StartRequest(); + native function SetIconCommon(); - var chromeHidden = requireNative('chrome_hidden').GetChromeHidden(); + var chromeHidden = GetChromeHidden(); // The object to generate the bindings for "internal" APIs in, so that // extensions can't directly call them (without access to chromeHidden), @@ -753,3 +753,4 @@ 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 deleted file mode 100644 index 86b0cd5..0000000 --- a/chrome/renderer/resources/extensions/setup_bindings.js +++ /dev/null @@ -1,21 +0,0 @@ -// 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 a3c8a54..1d358c2 100644 --- a/chrome/renderer/resources/extensions/storage_custom_bindings.js +++ b/chrome/renderer/resources/extensions/storage_custom_bindings.js @@ -4,7 +4,11 @@ // Custom bindings for the storage API. -var chromeHidden = requireNative('chrome_hidden').GetChromeHidden(); +(function() { + +native function GetChromeHidden(); + +var chromeHidden = GetChromeHidden(); chromeHidden.registerCustomType('StorageArea', function(typesAPI) { var sendRequest = typesAPI.sendRequest; @@ -39,3 +43,5 @@ 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 e0cc59c..dd66481 100644 --- a/chrome/renderer/resources/extensions/tabs_custom_bindings.js +++ b/chrome/renderer/resources/extensions/tabs_custom_bindings.js @@ -4,10 +4,12 @@ // Custom bindings for the tabs API. -var tabsNatives = requireNative('tabs'); -var OpenChannelToTab = tabsNatives.OpenChannelToTab; +(function() { -var chromeHidden = requireNative('chrome_hidden').GetChromeHidden(); +native function GetChromeHidden(); +native function OpenChannelToTab(); + +var chromeHidden = GetChromeHidden(); chromeHidden.registerCustomHook('tabs', function(bindingsAPI, extensionId) { var apiFunctions = bindingsAPI.apiFunctions; @@ -42,3 +44,5 @@ 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 dee01d3..ef8011a 100644 --- a/chrome/renderer/resources/extensions/tts_custom_bindings.js +++ b/chrome/renderer/resources/extensions/tts_custom_bindings.js @@ -4,10 +4,12 @@ // Custom bindings for the tts API. -var ttsNatives = requireNative('tts'); -var GetNextTTSEventId = ttsNatives.GetNextTTSEventId; +(function() { -var chromeHidden = requireNative('chrome_hidden').GetChromeHidden(); +native function GetChromeHidden(); +native function GetNextTTSEventId(); + +var chromeHidden = GetChromeHidden(); chromeHidden.registerCustomHook('tts', function(api) { var apiFunctions = api.apiFunctions; @@ -40,3 +42,5 @@ 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 7c0067b..85e36b0 100644 --- a/chrome/renderer/resources/extensions/tts_engine_custom_bindings.js +++ b/chrome/renderer/resources/extensions/tts_engine_custom_bindings.js @@ -4,9 +4,11 @@ // Custom bindings for the ttsEngine API. -var chromeHidden = requireNative('chrome_hidden').GetChromeHidden(); +(function() { -chromeHidden.registerCustomHook('ttsEngine', function() { +native function GetChromeHidden(); + +GetChromeHidden().registerCustomHook('ttsEngine', function() { chrome.ttsEngine.onSpeak.dispatch = function(text, options, requestId) { var sendTtsEvent = function(event) { chrome.ttsEngine.sendTtsEvent(requestId, event); @@ -15,3 +17,5 @@ chromeHidden.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 48eba8a..62dbe0a 100644 --- a/chrome/renderer/resources/extensions/types_custom_bindings.js +++ b/chrome/renderer/resources/extensions/types_custom_bindings.js @@ -4,7 +4,11 @@ // Custom bindings for the types API. -var chromeHidden = requireNative('chrome_hidden').GetChromeHidden(); +(function() { + +native function GetChromeHidden(); + +var chromeHidden = GetChromeHidden(); chromeHidden.registerCustomType('ChromeSetting', function(typesAPI) { var sendRequest = typesAPI.sendRequest; @@ -44,3 +48,5 @@ 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 392f66c..564251e 100644 --- a/chrome/renderer/resources/extensions/web_request_custom_bindings.js +++ b/chrome/renderer/resources/extensions/web_request_custom_bindings.js @@ -4,10 +4,12 @@ // Custom bindings for the webRequest API. -var webRequestNatives = requireNative('web_request'); -var GetUniqueSubEventName = webRequestNatives.GetUniqueSubEventName; +(function() { -var chromeHidden = requireNative('chrome_hidden').GetChromeHidden(); +native function GetChromeHidden(); +native function GetUniqueSubEventName(eventName); + +var chromeHidden = GetChromeHidden(); // WebRequestEvent object. This is used for special webRequest events with // extra parameters. Each invocation of addListener creates a new named @@ -170,3 +172,5 @@ chromeHidden.registerCustomHook('webRequest', function(api) { {forIOThread: true}); }); }); + +})(); diff --git a/chrome/renderer/resources/extensions/webstore.js b/chrome/renderer/resources/extensions/webstore.js index 14bacc5..b387c46 100644 --- a/chrome/renderer/resources/extensions/webstore.js +++ b/chrome/renderer/resources/extensions/webstore.js @@ -2,10 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. - var webstoreNatives = requireNative('webstore'); - var Install = webstoreNatives.Install; +var chrome = chrome || {}; +(function() { + native function GetChromeHidden(); + native function Install(preferredStoreUrl, onSuccess, onFailure); - var chromeHidden = requireNative('chrome_hidden').GetChromeHidden(); + var chromeHidden = GetChromeHidden(); var pendingInstalls = {}; chrome.webstore = new function() { this.install = function( @@ -39,3 +41,4 @@ delete pendingInstall[installId]; } } +})(); diff --git a/chrome/renderer/resources/require.js b/chrome/renderer/resources/require.js index 7108616..34f3543 100644 --- a/chrome/renderer/resources/require.js +++ b/chrome/renderer/resources/require.js @@ -15,9 +15,15 @@ // // |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_ = {}; }; @@ -27,8 +33,9 @@ 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; }; @@ -46,11 +53,7 @@ ModuleLoader.prototype.load = function(id) { var moduleLoader = new ModuleLoader(); function requireNative(nativeName) { - var result = bootstrap.GetNative(nativeName); - if (!result) { - throw "No such native object: '" + nativeName + "'"; - } - return result; + return bootstrap.GetNative(nativeName); } function require(moduleId) { diff --git a/chrome/test/base/chrome_render_view_test.cc b/chrome/test/base/chrome_render_view_test.cc index db8d3b8..6f023c4 100644 --- a/chrome/test/base/chrome_render_view_test.cc +++ b/chrome/test/base/chrome_render_view_test.cc @@ -65,6 +65,21 @@ void ChromeRenderViewTest::SetUp() { render_thread_.reset(chrome_render_thread_); content::RenderViewTest::SetUp(); + WebScriptController::registerExtension(new ChromeV8Extension( + "extensions/json_schema.js", IDR_JSON_SCHEMA_JS, NULL)); + WebScriptController::registerExtension(EventBindings::Get( + extension_dispatcher_)); + WebScriptController::registerExtension(MiscellaneousBindings::Get( + extension_dispatcher_)); + WebScriptController::registerExtension(SchemaGeneratedBindings::Get( + extension_dispatcher_)); + WebScriptController::registerExtension(new ChromeV8Extension( + "extensions/apitest.js", IDR_EXTENSION_APITEST_JS, NULL)); + + // HACK: register only the custom bindings that we need for the test. + WebScriptController::registerExtension(new ExtensionCustomBindings( + 0, NULL, extension_dispatcher_)); + // RenderView doesn't expose it's PasswordAutofillManager or // AutofillAgent objects, because it has no need to store them directly // (they're stored as RenderViewObserver*). So just create another set. |