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(); |
} |