summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/renderer/extensions/extension_process_bindings.cc84
-rw-r--r--chrome/renderer/extensions/extension_process_bindings.h1
-rw-r--r--chrome/renderer/render_view.cc6
-rw-r--r--chrome/renderer/renderer_resources.grd2
-rw-r--r--chrome/renderer/resources/extension_process_bindings.js17
-rwxr-xr-xchrome/test/data/extensions/samples/getviews/bg.html9
-rwxr-xr-xchrome/test/data/extensions/samples/getviews/common.css10
-rwxr-xr-xchrome/test/data/extensions/samples/getviews/common.js15
-rwxr-xr-xchrome/test/data/extensions/samples/getviews/manifest.json7
-rwxr-xr-xchrome/test/data/extensions/samples/getviews/ts1.html9
-rwxr-xr-xchrome/test/data/extensions/samples/getviews/ts2.html9
11 files changed, 167 insertions, 2 deletions
diff --git a/chrome/renderer/extensions/extension_process_bindings.cc b/chrome/renderer/extensions/extension_process_bindings.cc
index dccc32a..96f0256 100644
--- a/chrome/renderer/extensions/extension_process_bindings.cc
+++ b/chrome/renderer/extensions/extension_process_bindings.cc
@@ -6,6 +6,7 @@
#include "base/singleton.h"
#include "chrome/common/render_messages.h"
+#include "chrome/common/url_constants.h"
#include "chrome/renderer/extensions/bindings_utils.h"
#include "chrome/renderer/extensions/event_bindings.h"
#include "chrome/renderer/extensions/renderer_extension_bindings.h"
@@ -29,6 +30,14 @@ const char* kExtensionDeps[] = {
RendererExtensionBindings::kName,
};
+// Types for storage of per-renderer-singleton data structure that maps
+// |extension_id| -> <List of v8 Contexts for the "views" of that extension>
+typedef std::list< v8::Persistent<v8::Context> > ContextList;
+typedef std::map<std::string, ContextList> ExtensionIdContextsMap;
+struct ExtensionViewContexts {
+ ExtensionIdContextsMap contexts;
+};
+
class ExtensionImpl : public v8::Extension {
public:
ExtensionImpl() : v8::Extension(
@@ -48,6 +57,12 @@ class ExtensionImpl : public v8::Extension {
if (name->Equals(v8::String::New("GetNextRequestId")))
return v8::FunctionTemplate::New(GetNextRequestId);
+ else if (name->Equals(v8::String::New("RegisterExtension")))
+ return v8::FunctionTemplate::New(RegisterExtension);
+ else if (name->Equals(v8::String::New("UnregisterExtension")))
+ return v8::FunctionTemplate::New(UnregisterExtension);
+ else if (name->Equals(v8::String::New("GetViews")))
+ return v8::FunctionTemplate::New(GetViews);
else if (names->find(*v8::String::AsciiValue(name)) != names->end())
return v8::FunctionTemplate::New(StartRequest, name);
@@ -63,6 +78,70 @@ class ExtensionImpl : public v8::Extension {
return &Singleton<SingletonData>()->function_names_;
}
+ static ContextList& GetRegisteredContexts(std::string extension_id) {
+ return Singleton<ExtensionViewContexts>::get()->contexts[extension_id];
+ }
+
+ static v8::Handle<v8::Value> RegisterExtension(const v8::Arguments& args) {
+ RenderView* renderview = GetRenderViewForCurrentContext();
+ DCHECK(renderview);
+ GURL url = renderview->webview()->GetMainFrame()->GetURL();
+ DCHECK(url.scheme() == chrome::kExtensionScheme);
+
+ v8::Persistent<v8::Context> current_context =
+ v8::Persistent<v8::Context>::New(v8::Context::GetCurrent());
+ DCHECK(!current_context.IsEmpty());
+
+ std::string extension_id = url.host();
+ GetRegisteredContexts(extension_id).push_back(current_context);
+ return v8::String::New(extension_id.c_str());
+ }
+
+ static v8::Handle<v8::Value> UnregisterExtension(const v8::Arguments& args) {
+ DCHECK_EQ(args.Length(), 1);
+ DCHECK(args[0]->IsString());
+
+ std::string extension_id(*v8::String::Utf8Value(args[0]));
+ ContextList& contexts = GetRegisteredContexts(extension_id);
+ v8::Local<v8::Context> current_context = v8::Context::GetCurrent();
+ DCHECK(!current_context.IsEmpty());
+
+ ContextList::iterator it = std::find(contexts.begin(), contexts.end(),
+ current_context);
+ if (it == contexts.end()) {
+ NOTREACHED();
+ return v8::Undefined();
+ }
+
+ it->Dispose();
+ it->Clear();
+ contexts.erase(it);
+
+ return v8::Undefined();
+ }
+
+ static v8::Handle<v8::Value> GetViews(const v8::Arguments& args) {
+ RenderView* renderview = GetRenderViewForCurrentContext();
+ DCHECK(renderview);
+ GURL url = renderview->webview()->GetMainFrame()->GetURL();
+ std::string extension_id = url.host();
+
+ ContextList& contexts = GetRegisteredContexts(extension_id);
+ DCHECK(contexts.size() > 0);
+
+ v8::Local<v8::Array> views = v8::Array::New(contexts.size());
+ int index = 0;
+ ContextList::const_iterator it = contexts.begin();
+ for (; it != contexts.end(); ++it) {
+ v8::Local<v8::Value> window = (*it)->Global()->Get(
+ v8::String::New("window"));
+ DCHECK(!window.IsEmpty());
+ views->Set(v8::Integer::New(index), window);
+ index++;
+ }
+ return views;
+ }
+
static v8::Handle<v8::Value> GetNextRequestId(const v8::Arguments& args) {
static int next_request_id = 0;
return v8::Integer::New(next_request_id++);
@@ -103,6 +182,11 @@ void ExtensionProcessBindings::SetFunctionNames(
ExtensionImpl::SetFunctionNames(names);
}
+void ExtensionProcessBindings::RegisterExtensionContext(WebFrame* frame) {
+ frame->ExecuteScript(WebScriptSource(WebString::fromUTF8(
+ "chrome.self.register_();")));
+}
+
void ExtensionProcessBindings::ExecuteResponseInFrame(
CallContext *call, int request_id, bool success,
const std::string& response,
diff --git a/chrome/renderer/extensions/extension_process_bindings.h b/chrome/renderer/extensions/extension_process_bindings.h
index a24e4e5..d5798cd 100644
--- a/chrome/renderer/extensions/extension_process_bindings.h
+++ b/chrome/renderer/extensions/extension_process_bindings.h
@@ -27,6 +27,7 @@ class ExtensionProcessBindings {
static void SetFunctionNames(const std::vector<std::string>& names);
static v8::Extension* Get();
+ static void RegisterExtensionContext(WebFrame* frame);
static void ExecuteResponseInFrame(CallContext *call, int request_id,
bool success,
const std::string& response,
diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc
index 210fd7f..d09b195 100644
--- a/chrome/renderer/render_view.cc
+++ b/chrome/renderer/render_view.cc
@@ -1532,6 +1532,12 @@ void RenderView::DocumentElementAvailable(WebFrame* frame) {
if (frame->GetURL().SchemeIs(chrome::kExtensionScheme))
frame->GrantUniversalAccess();
+ // Tell extensions to self-register their js contexts.
+ // TODO:(rafaelw): This is kind of gross. We need a way to call through
+ // the glue layer to retrieve the current v8::Context.
+ if (frame->GetURL().SchemeIs(chrome::kExtensionScheme))
+ ExtensionProcessBindings::RegisterExtensionContext(frame);
+
if (RenderThread::current()) // Will be NULL during unit tests.
RenderThread::current()->user_script_slave()->InjectScripts(
frame, UserScript::DOCUMENT_START);
diff --git a/chrome/renderer/renderer_resources.grd b/chrome/renderer/renderer_resources.grd
index c59e98c..cda253b 100644
--- a/chrome/renderer/renderer_resources.grd
+++ b/chrome/renderer/renderer_resources.grd
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- This comment is only here because changes to resources are not picked up
-without changes to the corresponding grd file. -->
+without changes to the corresponding grd file. -->
<grit latest_public_release="0" current_release="1">
<outputs>
<output filename="grit/renderer_resources.h" type="rc_header">
diff --git a/chrome/renderer/resources/extension_process_bindings.js b/chrome/renderer/resources/extension_process_bindings.js
index 9bd0aca3..5a9fcf1 100644
--- a/chrome/renderer/resources/extension_process_bindings.js
+++ b/chrome/renderer/resources/extension_process_bindings.js
@@ -10,6 +10,9 @@
var chrome;
(function() {
native function GetNextRequestId();
+ native function RegisterExtension();
+ native function UnregisterExtension();
+ native function GetViews();
native function GetWindow();
native function GetCurrentWindow();
native function GetLastFocusedWindow();
@@ -499,7 +502,19 @@ var chrome;
//----------------------------------------------------------------------------
// Self.
- chrome.self = {};
+ chrome.self = chrome.self || {};
chrome.self.onConnect = new chrome.Event("channel-connect");
+
+ // Register
+ chrome.self.register_ = function() {
+ var extensionId = RegisterExtension();
+ window.addEventListener('unload', function() {
+ UnregisterExtension(extensionId); }, false);
+ delete chrome.self.register_;
+ }
+
+ chrome.self.getViews = function() {
+ return GetViews();
+ }
})();
diff --git a/chrome/test/data/extensions/samples/getviews/bg.html b/chrome/test/data/extensions/samples/getviews/bg.html
new file mode 100755
index 0000000..cdfbf58
--- /dev/null
+++ b/chrome/test/data/extensions/samples/getviews/bg.html
@@ -0,0 +1,9 @@
+<html>
+ <head>
+ <link rel="stylesheet" type="text/css" href="common.css">
+ <script src="common.js" type="text/javascript"></script>
+ </head>
+ <body>
+ <div span id="me" onclick="claim();">Background Page</div>
+ </body>
+</html> \ No newline at end of file
diff --git a/chrome/test/data/extensions/samples/getviews/common.css b/chrome/test/data/extensions/samples/getviews/common.css
new file mode 100755
index 0000000..99d72a0
--- /dev/null
+++ b/chrome/test/data/extensions/samples/getviews/common.css
@@ -0,0 +1,10 @@
+body {
+ font-size: 18px;
+}
+
+.strong {
+ background-color: red;
+}
+.weak {
+ color: pink;
+} \ No newline at end of file
diff --git a/chrome/test/data/extensions/samples/getviews/common.js b/chrome/test/data/extensions/samples/getviews/common.js
new file mode 100755
index 0000000..e567088
--- /dev/null
+++ b/chrome/test/data/extensions/samples/getviews/common.js
@@ -0,0 +1,15 @@
+function claim() {
+ var views = chrome.self.getViews();
+ for (var i = 0; i < views.length; i++) {
+ views[i].respond(document.getElementById("me").innerHTML);
+ }
+}
+
+function respond(val) {
+ var me = document.getElementById("me");
+ if (val == me.innerHTML) {
+ me.className = "strong";
+ } else {
+ me.className = "weak";
+ }
+} \ No newline at end of file
diff --git a/chrome/test/data/extensions/samples/getviews/manifest.json b/chrome/test/data/extensions/samples/getviews/manifest.json
new file mode 100755
index 0000000..84e18b1
--- /dev/null
+++ b/chrome/test/data/extensions/samples/getviews/manifest.json
@@ -0,0 +1,7 @@
+{
+ "name": "ViewTest",
+ "description": "Clicking on any toolstrip or background page should 'claim' the 'strong' typeface from the others by calling claim() directly on their window objects",
+ "version": "0.1",
+ "toolstrips": ["ts1.html", "ts2.html"],
+ "background_page": "bg.html"
+}
diff --git a/chrome/test/data/extensions/samples/getviews/ts1.html b/chrome/test/data/extensions/samples/getviews/ts1.html
new file mode 100755
index 0000000..df2b006
--- /dev/null
+++ b/chrome/test/data/extensions/samples/getviews/ts1.html
@@ -0,0 +1,9 @@
+<html>
+ <head>
+ <link rel="stylesheet" type="text/css" href="common.css">
+ <script src="common.js" type="text/javascript"></script>
+ </head>
+ <body>
+ <div span id="me" onclick="claim();">Toolstrip 1</div>
+ </body>
+</html> \ No newline at end of file
diff --git a/chrome/test/data/extensions/samples/getviews/ts2.html b/chrome/test/data/extensions/samples/getviews/ts2.html
new file mode 100755
index 0000000..f5ee37e
--- /dev/null
+++ b/chrome/test/data/extensions/samples/getviews/ts2.html
@@ -0,0 +1,9 @@
+<html>
+ <head>
+ <link rel="stylesheet" type="text/css" href="common.css">
+ <script src="common.js" type="text/javascript"></script>
+ </head>
+ <body>
+ <div span id="me" onclick="claim();">Toolstrip 2</div>
+ </body>
+</html> \ No newline at end of file