Chromium Code Reviews| Index: chrome/renderer/extensions/extension_dispatcher.cc |
| diff --git a/chrome/renderer/extensions/extension_dispatcher.cc b/chrome/renderer/extensions/extension_dispatcher.cc |
| index 458e7d403d49f08145323148fb775ab1fa3b14dd..13eb0e0ef26a976b01f2d5645afb550bcee51721 100644 |
| --- a/chrome/renderer/extensions/extension_dispatcher.cc |
| +++ b/chrome/renderer/extensions/extension_dispatcher.cc |
| @@ -4,7 +4,10 @@ |
| #include "chrome/renderer/extensions/extension_dispatcher.h" |
| +#include "base/callback.h" |
| #include "base/command_line.h" |
| +#include "base/memory/scoped_ptr.h" |
| +#include "base/string_piece.h" |
| #include "chrome/common/child_process_logging.h" |
| #include "chrome/common/chrome_switches.h" |
| #include "chrome/common/extensions/extension.h" |
| @@ -22,6 +25,8 @@ |
| #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 "content/public/renderer/render_thread.h" |
| #include "grit/renderer_resources.h" |
| #include "third_party/WebKit/Source/WebKit/chromium/public/WebDataSource.h" |
| @@ -34,6 +39,19 @@ |
| #include "ui/base/resource/resource_bundle.h" |
| #include "v8/include/v8.h" |
| +#include "chrome/renderer/extensions/chrome_private_custom_bindings.h" |
| +#include "chrome/renderer/extensions/context_menus_custom_bindings.h" |
| +#include "chrome/renderer/extensions/experimental.socket_custom_bindings.h" |
| +#include "chrome/renderer/extensions/extension_custom_bindings.h" |
| +#include "chrome/renderer/extensions/file_browser_handler_custom_bindings.h" |
| +#include "chrome/renderer/extensions/file_browser_private_custom_bindings.h" |
| +#include "chrome/renderer/extensions/i18n_custom_bindings.h" |
| +#include "chrome/renderer/extensions/page_actions_custom_bindings.h" |
| +#include "chrome/renderer/extensions/page_capture_custom_bindings.h" |
| +#include "chrome/renderer/extensions/tabs_custom_bindings.h" |
| +#include "chrome/renderer/extensions/tts_custom_bindings.h" |
| +#include "chrome/renderer/extensions/web_request_custom_bindings.h" |
| + |
| namespace { |
| static const int64 kInitialExtensionIdleHandlerDelayMs = 5*1000; |
| @@ -110,25 +128,6 @@ void ExtensionDispatcher::WebKitInitialized() { |
| RenderThread::Get(), &RenderThread::IdleHandler); |
| } |
| - RegisterExtension(new AppBindings(this), false); |
| - RegisterExtension(new WebstoreBindings(this), false); |
| - |
| - // Add v8 extensions related to chrome extensions. |
| - RegisterExtension(new ChromeV8Extension( |
| - "extensions/json_schema.js", IDR_JSON_SCHEMA_JS, NULL), true); |
| - RegisterExtension(EventBindings::Get(this), true); |
| - RegisterExtension(MiscellaneousBindings::Get(this), true); |
| - RegisterExtension(SchemaGeneratedBindings::Get(this), true); |
| - RegisterExtension(new ChromeV8Extension( |
| - "extensions/apitest.js", IDR_EXTENSION_APITEST_JS, NULL), true); |
| - |
| - std::vector<v8::Extension*> custom_bindings = |
| - custom_bindings_util::GetAll(this); |
| - for (std::vector<v8::Extension*>::iterator it = custom_bindings.begin(); |
| - it != custom_bindings.end(); ++it) { |
| - RegisterExtension(*it, true); |
| - } |
| - |
| // Initialize host permissions for any extensions that were activated before |
| // WebKit was initialized. |
| for (std::set<std::string>::iterator iter = active_extension_ids_.begin(); |
| @@ -349,6 +348,170 @@ bool ExtensionDispatcher::AllowScriptExtension( |
| return false; |
| } |
| +base::StringPiece GetResource(int resource_id) { |
| + return ResourceBundle::GetSharedInstance().GetRawDataResource(resource_id); |
| +} |
| + |
| +std::map<std::string, base::StringPiece>* GetOrCreateSourceMap() { |
| + static std::map<std::string, base::StringPiece>* source_map = NULL; |
|
Aaron Boodman
2012/02/28 02:42:59
Sadly, we do not static non-pod types in Chrome. Y
koz (OOO until 15th September)
2012/03/01 03:41:56
I've made it an instance member.
|
| + if (source_map == NULL) { |
| + source_map = new std::map<std::string, base::StringPiece>(); |
| + (*source_map)["app"] = GetResource(IDR_APP_BINDINGS_JS); |
| + (*source_map)["webstore"] = GetResource(IDR_WEBSTORE_BINDINGS_JS); |
| + (*source_map)["event_bindings"] = GetResource(IDR_EVENT_BINDINGS_JS); |
| + (*source_map)["miscellaneous_bindings"] = |
| + GetResource(IDR_MISCELLANEOUS_BINDINGS_JS); |
| + (*source_map)["schema_generated_bindings"] = |
| + GetResource(IDR_SCHEMA_GENERATED_BINDINGS_JS); |
| + (*source_map)["json_schema"] = GetResource(IDR_JSON_SCHEMA_JS); |
| + (*source_map)["apitest"] = GetResource(IDR_EXTENSION_APITEST_JS); |
| + (*source_map)["setup_bindings"] = GetResource(IDR_SETUP_BINDINGS_JS); |
| + |
| + // Custom bindings. |
| + (*source_map)["browserAction"] = |
| + GetResource(IDR_BROWSER_ACTION_CUSTOM_BINDINGS_JS); |
| + (*source_map)["chromePrivate"] = |
| + GetResource(IDR_CHROME_PRIVATE_CUSTOM_BINDINGS_JS); |
| + (*source_map)["contentSettings"] = |
| + GetResource(IDR_CONTENT_SETTINGS_CUSTOM_BINDINGS_JS); |
| + (*source_map)["contextMenus"] = |
| + GetResource(IDR_CONTEXT_MENUS_CUSTOM_BINDINGS_JS); |
| + (*source_map)["devtools"] = GetResource(IDR_DEVTOOLS_CUSTOM_BINDINGS_JS); |
| + (*source_map)["experimental.declarative"] = |
| + GetResource(IDR_EXPERIMENTAL_DECLARATIVE_CUSTOM_BINDINGS_JS); |
| + (*source_map)["experimental.socket"] = |
| + GetResource(IDR_EXPERIMENTAL_SOCKET_CUSTOM_BINDINGS_JS); |
| + (*source_map)["extension"] = GetResource(IDR_EXTENSION_CUSTOM_BINDINGS_JS); |
| + (*source_map)["fileBrowserHandler"] = |
| + GetResource(IDR_FILE_BROWSER_HANDLER_CUSTOM_BINDINGS_JS); |
| + (*source_map)["fileBrowserPrivate"] = |
| + GetResource(IDR_FILE_BROWSER_PRIVATE_CUSTOM_BINDINGS_JS); |
| + (*source_map)["i18n"] = GetResource(IDR_I18N_CUSTOM_BINDINGS_JS); |
| + (*source_map)["input.ime"] = GetResource(IDR_INPUT_IME_CUSTOM_BINDINGS_JS); |
| + (*source_map)["omnibox"] = GetResource(IDR_OMNIBOX_CUSTOM_BINDINGS_JS); |
| + (*source_map)["pageActions"] = |
| + GetResource(IDR_PAGE_ACTIONS_CUSTOM_BINDINGS_JS); |
| + (*source_map)["pageAction"] = |
| + GetResource(IDR_PAGE_ACTION_CUSTOM_BINDINGS_JS); |
| + (*source_map)["pageCapture"] = |
| + GetResource(IDR_PAGE_CAPTURE_CUSTOM_BINDINGS_JS); |
| + (*source_map)["storage"] = GetResource(IDR_STORAGE_CUSTOM_BINDINGS_JS); |
| + (*source_map)["tabs"] = GetResource(IDR_TABS_CUSTOM_BINDINGS_JS); |
| + (*source_map)["tts"] = GetResource(IDR_TTS_CUSTOM_BINDINGS_JS); |
| + (*source_map)["ttsEngine"] = |
| + GetResource(IDR_TTS_ENGINE_CUSTOM_BINDINGS_JS); |
| + (*source_map)["types"] = GetResource(IDR_TYPES_CUSTOM_BINDINGS_JS); |
| + (*source_map)["webRequest"] = |
| + GetResource(IDR_WEB_REQUEST_CUSTOM_BINDINGS_JS); |
| + (*source_map)["windows"] = GetResource(IDR_WINDOWS_CUSTOM_BINDINGS_JS); |
| + } |
| + |
| + return source_map; |
| +} |
| + |
| +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(bool is_bindings_allowed) |
| + : is_bindings_allowed_(is_bindings_allowed) { |
| + RouteFunction("IsBindingsAllowed", |
| + base::Bind(&ContextInfoNativeHandler::IsBindingsAllowed, |
| + base::Unretained(this))); |
| + } |
| + |
| + v8::Handle<v8::Value> IsBindingsAllowed(const v8::Arguments& args) { |
| + return v8::Boolean::New(is_bindings_allowed_); |
| + } |
| + |
| + private: |
| + bool is_bindings_allowed_; |
| +}; |
| + |
| +void ExtensionDispatcher::RegisterNativeHandlers(ModuleSystem* module_system, |
| + ChromeV8Context* context, |
| + bool is_bindings_allowed) { |
| + module_system->RegisterNativeHandler("app", |
| + scoped_ptr<NativeHandler>(new AppBindings(this, context))); |
|
Matt Perry
2012/02/28 20:34:20
+2 indent
Matt Perry
2012/02/28 20:34:20
fyi: make_scoped_ptr(new X) looks nicer
koz (OOO until 15th September)
2012/03/01 03:41:56
Done.
koz (OOO until 15th September)
2012/03/01 03:41:56
I think it doesn't work here because we need to up
|
| + module_system->RegisterNativeHandler("webstore", |
| + scoped_ptr<NativeHandler>(new WebstoreBindings(this, context))); |
| + module_system->RegisterNativeHandler("event_bindings", |
| + scoped_ptr<NativeHandler>(EventBindings::Get(this))); |
|
Matt Perry
2012/02/28 20:34:20
+2 indent
koz (OOO until 15th September)
2012/03/01 03:41:56
Done.
|
| + 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())); |
| + |
| + module_system->RegisterNativeHandler("chrome_hidden", |
| + scoped_ptr<NativeHandler>(new ChromeHiddenNativeHandler())); |
| + module_system->RegisterNativeHandler("print", |
| + scoped_ptr<NativeHandler>(new PrintNativeHandler())); |
| + module_system->RegisterNativeHandler("context_info", |
| + scoped_ptr<NativeHandler>(new ContextInfoNativeHandler( |
| + is_bindings_allowed))); |
| +} |
| + |
| void ExtensionDispatcher::DidCreateScriptContext( |
| WebFrame* frame, v8::Handle<v8::Context> v8_context, int world_id) { |
| ChromeV8Context* context = |
| @@ -360,11 +523,25 @@ void ExtensionDispatcher::DidCreateScriptContext( |
| hack_DidCreateScriptContext_extension_group)); |
| v8_context_set_.Add(context); |
| + bool is_bindings_allowed = |
| + context->context_type() == ChromeV8Context::CONTENT_SCRIPT || |
| + extensions_.ExtensionBindingsAllowed(ExtensionURLInfo( |
| + frame->document().securityOrigin(), |
| + UserScriptSlave::GetDataSourceURLForFrame(frame))); |
| + |
| + ModuleSystem* module_system = new ModuleSystem(GetOrCreateSourceMap()); |
| + RegisterNativeHandlers(module_system, context, is_bindings_allowed); |
| + |
| + context->set_module_system(scoped_ptr<ModuleSystem>(module_system)); |
|
Matt Perry
2012/02/28 20:34:20
Why is there one module system per context, rather
koz (OOO until 15th September)
2012/03/01 03:41:56
ModuleSystem injects JS into a particular context
|
| + |
| + |
| const Extension* extension = extensions_.GetByID(context->extension_id()); |
| int manifest_version = 1; |
| if (extension) |
| manifest_version = extension->manifest_version(); |
| + module_system->Require("setup_bindings"); |
| + |
| context->DispatchOnLoadEvent( |
| is_extension_process_, |
| ChromeRenderProcessObserver::is_incognito_process(), |
| @@ -395,12 +572,6 @@ void ExtensionDispatcher::WillReleaseScriptContext( |
| context->DispatchOnUnloadEvent(); |
| - ChromeV8Extension::InstanceSet extensions = ChromeV8Extension::GetAll(); |
| - for (ChromeV8Extension::InstanceSet::const_iterator iter = extensions.begin(); |
| - iter != extensions.end(); ++iter) { |
| - (*iter)->ContextWillBeReleased(context); |
| - } |
| - |
| v8_context_set_.Remove(context); |
| VLOG(1) << "Num tracked contexts: " << v8_context_set_.size(); |
| } |