Index: extensions/renderer/script_context.cc |
diff --git a/chrome/renderer/extensions/chrome_v8_context.cc b/extensions/renderer/script_context.cc |
similarity index 53% |
copy from chrome/renderer/extensions/chrome_v8_context.cc |
copy to extensions/renderer/script_context.cc |
index 24fad4aacb8d05736f40f6b7aa52ba9794a6edce..2113dbffa0a429a32d4e950db6f5287b9e4aba33 100644 |
--- a/chrome/renderer/extensions/chrome_v8_context.cc |
+++ b/extensions/renderer/script_context.cc |
@@ -2,21 +2,19 @@ |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
-#include "chrome/renderer/extensions/chrome_v8_context.h" |
+#include "extensions/renderer/script_context.h" |
#include "base/logging.h" |
#include "base/memory/scoped_ptr.h" |
#include "base/strings/string_split.h" |
#include "base/values.h" |
-#include "chrome/renderer/extensions/chrome_v8_extension.h" |
-#include "chrome/renderer/extensions/module_system.h" |
-#include "chrome/renderer/extensions/user_script_slave.h" |
#include "content/public/renderer/render_view.h" |
#include "content/public/renderer/v8_value_converter.h" |
#include "extensions/common/extension.h" |
#include "extensions/common/extension_api.h" |
#include "extensions/common/extension_urls.h" |
#include "extensions/common/features/base_feature_provider.h" |
+#include "third_party/WebKit/public/web/WebDataSource.h" |
#include "third_party/WebKit/public/web/WebFrame.h" |
#include "third_party/WebKit/public/web/WebScopedMicrotaskSuppression.h" |
#include "third_party/WebKit/public/web/WebView.h" |
@@ -26,16 +24,15 @@ using content::V8ValueConverter; |
namespace extensions { |
-ChromeV8Context::ChromeV8Context(v8::Handle<v8::Context> v8_context, |
- blink::WebFrame* web_frame, |
- const Extension* extension, |
- Feature::Context context_type) |
+ScriptContext::ScriptContext(v8::Handle<v8::Context> v8_context, |
+ blink::WebFrame* web_frame, |
+ const Extension* extension, |
+ Feature::Context context_type) |
: v8_context_(v8_context), |
web_frame_(web_frame), |
extension_(extension), |
context_type_(context_type), |
safe_builtins_(this), |
- pepper_request_proxy_(this), |
isolate_(v8_context->GetIsolate()) { |
VLOG(1) << "Created context:\n" |
<< " extension id: " << GetExtensionID() << "\n" |
@@ -43,13 +40,13 @@ ChromeV8Context::ChromeV8Context(v8::Handle<v8::Context> v8_context, |
<< " context type: " << GetContextTypeDescription(); |
} |
-ChromeV8Context::~ChromeV8Context() { |
+ScriptContext::~ScriptContext() { |
VLOG(1) << "Destroyed context for extension\n" |
<< " extension id: " << GetExtensionID(); |
Invalidate(); |
} |
-void ChromeV8Context::Invalidate() { |
+void ScriptContext::Invalidate() { |
if (!is_valid()) |
return; |
if (module_system_) |
@@ -58,23 +55,18 @@ void ChromeV8Context::Invalidate() { |
v8_context_.reset(); |
} |
-std::string ChromeV8Context::GetExtensionID() const { |
+std::string ScriptContext::GetExtensionID() const { |
return extension_.get() ? extension_->id() : std::string(); |
} |
-content::RenderView* ChromeV8Context::GetRenderView() const { |
+content::RenderView* ScriptContext::GetRenderView() const { |
if (web_frame_ && web_frame_->view()) |
return content::RenderView::FromWebView(web_frame_->view()); |
else |
return NULL; |
} |
-GURL ChromeV8Context::GetURL() const { |
- return web_frame_ ? |
- UserScriptSlave::GetDataSourceURLForFrame(web_frame_) : GURL(); |
-} |
- |
-v8::Local<v8::Value> ChromeV8Context::CallFunction( |
+v8::Local<v8::Value> ScriptContext::CallFunction( |
v8::Handle<v8::Function> function, |
int argc, |
v8::Handle<v8::Value> argv[]) const { |
@@ -95,15 +87,7 @@ v8::Local<v8::Value> ChromeV8Context::CallFunction( |
function, global, argc, argv))); |
} |
-bool ChromeV8Context::IsAnyFeatureAvailableToContext(const Feature& api) { |
- return ExtensionAPI::GetSharedInstance()->IsAnyFeatureAvailableToContext( |
- api, |
- extension_.get(), |
- context_type_, |
- UserScriptSlave::GetDataSourceURLForFrame(web_frame_)); |
-} |
- |
-Feature::Availability ChromeV8Context::GetAvailability( |
+Feature::Availability ScriptContext::GetAvailability( |
const std::string& api_name) { |
// Hack: Hosted apps should have the availability of messaging APIs based on |
// the URL of the page (which might have access depending on some extension |
@@ -114,14 +98,12 @@ Feature::Availability ChromeV8Context::GetAvailability( |
(api_name == "runtime.connect" || api_name == "runtime.sendMessage")) { |
extension = NULL; |
} |
- return ExtensionAPI::GetSharedInstance()->IsAvailable(api_name, |
- extension, |
- context_type_, |
- GetURL()); |
+ return ExtensionAPI::GetSharedInstance()->IsAvailable( |
+ api_name, extension, context_type_, GetURL()); |
} |
-void ChromeV8Context::DispatchEvent(const char* event_name, |
- v8::Handle<v8::Array> args) const { |
+void ScriptContext::DispatchEvent(const char* event_name, |
+ v8::Handle<v8::Array> args) const { |
v8::HandleScope handle_scope(isolate()); |
v8::Context::Scope context_scope(v8_context()); |
@@ -131,44 +113,73 @@ void ChromeV8Context::DispatchEvent(const char* event_name, |
kEventBindings, "dispatchEvent", arraysize(argv), argv); |
} |
-void ChromeV8Context::DispatchOnUnloadEvent() { |
+void ScriptContext::DispatchOnUnloadEvent() { |
module_system_->CallModuleMethod("unload_event", "dispatch"); |
} |
-std::string ChromeV8Context::GetContextTypeDescription() { |
+std::string ScriptContext::GetContextTypeDescription() { |
switch (context_type_) { |
- case Feature::UNSPECIFIED_CONTEXT: return "UNSPECIFIED"; |
- case Feature::BLESSED_EXTENSION_CONTEXT: return "BLESSED_EXTENSION"; |
- case Feature::UNBLESSED_EXTENSION_CONTEXT: return "UNBLESSED_EXTENSION"; |
- case Feature::CONTENT_SCRIPT_CONTEXT: return "CONTENT_SCRIPT"; |
- case Feature::WEB_PAGE_CONTEXT: return "WEB_PAGE"; |
- case Feature::BLESSED_WEB_PAGE_CONTEXT: return "BLESSED_WEB_PAGE"; |
+ case Feature::UNSPECIFIED_CONTEXT: |
+ return "UNSPECIFIED"; |
+ case Feature::BLESSED_EXTENSION_CONTEXT: |
+ return "BLESSED_EXTENSION"; |
+ case Feature::UNBLESSED_EXTENSION_CONTEXT: |
+ return "UNBLESSED_EXTENSION"; |
+ case Feature::CONTENT_SCRIPT_CONTEXT: |
+ return "CONTENT_SCRIPT"; |
+ case Feature::WEB_PAGE_CONTEXT: |
+ return "WEB_PAGE"; |
+ case Feature::BLESSED_WEB_PAGE_CONTEXT: |
+ return "BLESSED_WEB_PAGE"; |
} |
NOTREACHED(); |
return std::string(); |
} |
-ChromeV8Context* ChromeV8Context::GetContext() { |
- return this; |
+GURL ScriptContext::GetURL() const { |
+ return web_frame() ? GetDataSourceURLForFrame(web_frame()) : GURL(); |
+} |
+ |
+bool ScriptContext::IsAnyFeatureAvailableToContext(const Feature& api) { |
+ return ExtensionAPI::GetSharedInstance()->IsAnyFeatureAvailableToContext( |
+ api, extension(), context_type(), GetDataSourceURLForFrame(web_frame())); |
+} |
+ |
+// static |
+GURL ScriptContext::GetDataSourceURLForFrame(const blink::WebFrame* frame) { |
+ // Normally we would use frame->document().url() to determine the document's |
+ // URL, but to decide whether to inject a content script, we use the URL from |
+ // the data source. This "quirk" helps prevents content scripts from |
+ // inadvertently adding DOM elements to the compose iframe in Gmail because |
+ // the compose iframe's dataSource URL is about:blank, but the document URL |
+ // changes to match the parent document after Gmail document.writes into |
+ // it to create the editor. |
+ // http://code.google.com/p/chromium/issues/detail?id=86742 |
+ blink::WebDataSource* data_source = frame->provisionalDataSource() |
+ ? frame->provisionalDataSource() |
+ : frame->dataSource(); |
+ CHECK(data_source); |
+ return GURL(data_source->request().url()); |
} |
-void ChromeV8Context::OnResponseReceived(const std::string& name, |
- int request_id, |
- bool success, |
- const base::ListValue& response, |
- const std::string& error) { |
+ScriptContext* ScriptContext::GetContext() { return this; } |
+ |
+void ScriptContext::OnResponseReceived(const std::string& name, |
+ int request_id, |
+ bool success, |
+ const base::ListValue& response, |
+ const std::string& error) { |
v8::HandleScope handle_scope(isolate()); |
scoped_ptr<V8ValueConverter> converter(V8ValueConverter::create()); |
v8::Handle<v8::Value> argv[] = { |
- v8::Integer::New(isolate(), request_id), |
- v8::String::NewFromUtf8(isolate(), name.c_str()), |
- v8::Boolean::New(isolate(), success), |
- converter->ToV8Value(&response, v8_context_.NewHandle(isolate())), |
- v8::String::NewFromUtf8(isolate(), error.c_str()) |
- }; |
- |
- v8::Handle<v8::Value> retval = module_system_->CallModuleMethod( |
+ v8::Integer::New(isolate(), request_id), |
+ v8::String::NewFromUtf8(isolate(), name.c_str()), |
+ v8::Boolean::New(isolate(), success), |
+ converter->ToV8Value(&response, v8_context_.NewHandle(isolate())), |
+ v8::String::NewFromUtf8(isolate(), error.c_str())}; |
+ |
+ v8::Handle<v8::Value> retval = module_system()->CallModuleMethod( |
"sendRequest", "handleResponse", arraysize(argv), argv); |
// In debug, the js will validate the callback parameters and return a |