diff options
author | mpcomplete@chromium.org <mpcomplete@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-09 18:13:27 +0000 |
---|---|---|
committer | mpcomplete@chromium.org <mpcomplete@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-09 18:13:27 +0000 |
commit | ea4d0790da2db4aae00e07af25feffd7e3857377 (patch) | |
tree | 44af49f6bd1432124069d2bba095ac49f9fc2af3 /chrome/renderer | |
parent | 76624fdeda4c8409a6bfd8a5f48de00dbceb0760 (diff) | |
download | chromium_src-ea4d0790da2db4aae00e07af25feffd7e3857377.zip chromium_src-ea4d0790da2db4aae00e07af25feffd7e3857377.tar.gz chromium_src-ea4d0790da2db4aae00e07af25feffd7e3857377.tar.bz2 |
Implement chrome.extension.connectExternal and fix various API inconsistencies.
BUG=23583
BUG=17910
TEST=no
Review URL: http://codereview.chromium.org/262016
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@28565 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/renderer')
-rw-r--r-- | chrome/renderer/extensions/bindings_utils.h | 5 | ||||
-rw-r--r-- | chrome/renderer/extensions/renderer_extension_bindings.cc | 11 | ||||
-rw-r--r-- | chrome/renderer/mock_render_thread.cc | 3 | ||||
-rw-r--r-- | chrome/renderer/mock_render_thread.h | 3 | ||||
-rw-r--r-- | chrome/renderer/resources/event_bindings.js | 10 | ||||
-rw-r--r-- | chrome/renderer/resources/extension_process_bindings.js | 13 | ||||
-rw-r--r-- | chrome/renderer/resources/renderer_extension_bindings.js | 91 | ||||
-rw-r--r-- | chrome/renderer/user_script_slave.cc | 8 |
8 files changed, 79 insertions, 65 deletions
diff --git a/chrome/renderer/extensions/bindings_utils.h b/chrome/renderer/extensions/bindings_utils.h index b0b3f08..471023c 100644 --- a/chrome/renderer/extensions/bindings_utils.h +++ b/chrome/renderer/extensions/bindings_utils.h @@ -28,6 +28,11 @@ class ExtensionBase : public v8::Extension { const char** deps) : v8::Extension(name, source, dep_count, deps) {} + // Note: do not call this function before or during the chromeHidden.onLoad + // event dispatch. The URL might not have been committed yet and might not + // be an extension URL. + static std::string ExtensionIdForCurrentContext(); + // Derived classes should call this at the end of their implementation in // order to expose common native functions, like GetChromeHidden, to the // v8 extension. diff --git a/chrome/renderer/extensions/renderer_extension_bindings.cc b/chrome/renderer/extensions/renderer_extension_bindings.cc index 374e673..de958d1 100644 --- a/chrome/renderer/extensions/renderer_extension_bindings.cc +++ b/chrome/renderer/extensions/renderer_extension_bindings.cc @@ -77,12 +77,15 @@ class ExtensionImpl : public ExtensionBase { if (!renderview) return v8::Undefined(); - if (args.Length() >= 2 && args[0]->IsString() && args[1]->IsString()) { - std::string id = *v8::String::Utf8Value(args[0]->ToString()); - std::string channel_name = *v8::String::Utf8Value(args[1]->ToString()); + if (args.Length() >= 3 && args[0]->IsString() && args[1]->IsString() && + args[2]->IsString()) { + std::string source_id = *v8::String::Utf8Value(args[0]->ToString()); + std::string target_id = *v8::String::Utf8Value(args[1]->ToString()); + std::string channel_name = *v8::String::Utf8Value(args[2]->ToString()); int port_id = -1; renderview->Send(new ViewHostMsg_OpenChannelToExtension( - renderview->routing_id(), id, channel_name, &port_id)); + renderview->routing_id(), source_id, target_id, + channel_name, &port_id)); return v8::Integer::New(port_id); } return v8::Undefined(); diff --git a/chrome/renderer/mock_render_thread.cc b/chrome/renderer/mock_render_thread.cc index e99c618..6445dce 100644 --- a/chrome/renderer/mock_render_thread.cc +++ b/chrome/renderer/mock_render_thread.cc @@ -97,7 +97,8 @@ void MockRenderThread::OnMsgCreateWidget(int opener_id, } void MockRenderThread::OnMsgOpenChannelToExtension( - int routing_id, const std::string& extension_id, + int routing_id, const std::string& source_extension_id, + const std::string& target_extension_id, const std::string& channel_name, int* port_id) { *port_id = 0; } diff --git a/chrome/renderer/mock_render_thread.h b/chrome/renderer/mock_render_thread.h index 69a5186..eb1a458 100644 --- a/chrome/renderer/mock_render_thread.h +++ b/chrome/renderer/mock_render_thread.h @@ -84,7 +84,8 @@ class MockRenderThread : public RenderThreadBase { // The callee expects to be returned a valid channel_id. void OnMsgOpenChannelToExtension( int routing_id, const std::string& extension_id, - const std::string& channel_name, int* port_id); + const std::string& source_extension_id, + const std::string& target_extension_id, int* port_id); void OnDuplicateSection(base::SharedMemoryHandle renderer_handle, base::SharedMemoryHandle* browser_handle); diff --git a/chrome/renderer/resources/event_bindings.js b/chrome/renderer/resources/event_bindings.js index 3def161..dc69268 100644 --- a/chrome/renderer/resources/event_bindings.js +++ b/chrome/renderer/resources/event_bindings.js @@ -2,11 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// ----------------------------------------------------------------------------- -// NOTE: If you change this file you need to touch renderer_resources.grd to -// have your change take effect. -// ----------------------------------------------------------------------------- - var chrome = chrome || {}; (function () { native function GetChromeHidden(); @@ -105,6 +100,11 @@ var chrome = chrome || {}; return this.findListeners_(cb) > -1; }; + // Test if any callbacks are registered for this event. + chrome.Event.prototype.hasListeners = function(cb) { + return this.listeners_.length > 0; + }; + // Returns the index of the given callback if registered, or -1 if not // found. chrome.Event.prototype.findListener_ = function(cb) { diff --git a/chrome/renderer/resources/extension_process_bindings.js b/chrome/renderer/resources/extension_process_bindings.js index 6dfa25a..0ac0be4 100644 --- a/chrome/renderer/resources/extension_process_bindings.js +++ b/chrome/renderer/resources/extension_process_bindings.js @@ -2,11 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// ----------------------------------------------------------------------------- -// NOTE: If you change this file you need to touch renderer_resources.grd to -// have your change take effect. -// ----------------------------------------------------------------------------- - // This script contains privileged chrome extension related javascript APIs. // It is loaded by pages whose URL has the chrome-extension protocol. @@ -221,11 +216,7 @@ var chrome = chrome || {}; } chromeHidden.onLoad.addListener(function (extensionId) { - chrome.extension = new chrome.Extension(extensionId); - - // TODO(mpcomplete): chrome.self is deprecated. Remove it at 1.0. - // http://code.google.com/p/chromium/issues/detail?id=16356 - chrome.self = chrome.extension; + chrome.initExtension(extensionId); // |apiFunctions| is a hash of name -> object that stores the // name & definition of the apiFunction. Custom handling of api functions @@ -297,7 +288,7 @@ var chrome = chrome || {}; name = connectInfo.name || name; } var portId = OpenChannelToTab( - tabId, chrome.extension.id_, name); + tabId, chromeHidden.extensionId, name); return chromeHidden.Port.createPort(portId, name); } diff --git a/chrome/renderer/resources/renderer_extension_bindings.js b/chrome/renderer/resources/renderer_extension_bindings.js index 6e9b387..09021540 100644 --- a/chrome/renderer/resources/renderer_extension_bindings.js +++ b/chrome/renderer/resources/renderer_extension_bindings.js @@ -2,11 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// ----------------------------------------------------------------------------- -// NOTE: If you change this file you need to touch renderer_resources.grd to -// have your change take effect. -// ----------------------------------------------------------------------------- - // This script contains unprivileged javascript APIs related to chrome // extensions. It is loaded by any extension-related context, such as content // scripts or toolstrips. @@ -16,7 +11,7 @@ var chrome = chrome || {}; (function () { - native function OpenChannelToExtension(id, name); + native function OpenChannelToExtension(sourceId, targetId, name); native function CloseChannel(portId); native function PortAddRef(portId); native function PortRelease(portId); @@ -56,19 +51,28 @@ var chrome = chrome || {}; // Called by native code when a channel has been opened to this context. chromeHidden.Port.dispatchOnConnect = function(portId, channelName, tab, - extensionId) { + sourceExtensionId, + targetExtensionId) { // Only create a new Port if someone is actually listening for a connection. // In addition to being an optimization, this also fixes a bug where if 2 // channels were opened to and from the same process, closing one would // close both. - var connectEvent = "channel-connect:" + extensionId; - if (chromeHidden.Event.hasListener(connectEvent)) { + if (targetExtensionId != chromeHidden.extensionId) + return; // not for us + + // Determine whether this is coming from another extension, and use the + // right event. + var connectEvent = (sourceExtensionId == chromeHidden.extensionId ? + chrome.extension.onConnect : chrome.extension.onConnectExternal); + if (connectEvent.hasListeners()) { var port = chromeHidden.Port.createPort(portId, channelName); if (tab) { tab = JSON.parse(tab); } - port.tab = tab; - chromeHidden.Event.dispatch(connectEvent, [port]); + port.sender = {tab: tab, id: sourceExtensionId}; + // TODO(EXTENSIONS_DEPRECATED): port.tab is obsolete. + port.tab = port.sender.tab; + connectEvent.dispatch(port); } }; @@ -107,30 +111,43 @@ var chrome = chrome || {}; CloseChannel(this.portId_); } - // Extension object. - chrome.Extension = function(id) { - this.id_ = id; - this.onConnect = new chrome.Event('channel-connect:' + id); - }; - - // Opens a message channel to the extension. Returns a Port for - // message passing. - chrome.Extension.prototype.connect = function(connectInfo) { - var name = ""; - if (connectInfo) { - name = connectInfo.name || name; - } - var portId = OpenChannelToExtension(this.id_, name); - if (portId == -1) - throw new Error("No such extension: '" + this.id_ + "'"); - return chromeHidden.Port.createPort(portId, name); - }; - - // Returns a resource URL that can be used to fetch a resource from this - // extension. - chrome.Extension.prototype.getURL = function(path) { - return "chrome-extension://" + this.id_ + "/" + path; - }; - - chrome.self = chrome.self || {}; + // This function is called on context initialization for both content scripts + // and extension contexts. + chrome.initExtension = function(extensionId) { + delete chrome.initExtension; + chromeHidden.extensionId = extensionId; + + chrome.extension = chrome.extension || {}; + + // TODO(EXTENSIONS_DEPRECATED): chrome.self is obsolete. + // http://code.google.com/p/chromium/issues/detail?id=16356 + chrome.self = chrome.extension; + + // Events for when a message channel is opened to our extension. + chrome.extension.onConnect = new chrome.Event(); + chrome.extension.onConnectExternal = new chrome.Event(); + + // Opens a message channel to the given target extension, or the current one + // if unspecified. Returns a Port for message passing. + chrome.extension.connect = function(targetId_opt, connectInfo_opt) { + var name = ""; + var targetId = extensionId; + var nextArg = 0; + if (typeof(arguments[nextArg]) == "string") + targetId = arguments[nextArg++]; + if (typeof(arguments[nextArg]) == "object") + name = arguments[nextArg++].name || name; + + var portId = OpenChannelToExtension(extensionId, targetId, name); + if (portId >= 0) + return chromeHidden.Port.createPort(portId, name); + throw new Error("Error connecting to extension '" + targetId + "'"); + }; + + // Returns a resource URL that can be used to fetch a resource from this + // extension. + chrome.extension.getURL = function(path) { + return "chrome-extension://" + extensionId + "/" + path; + }; + } })(); diff --git a/chrome/renderer/user_script_slave.cc b/chrome/renderer/user_script_slave.cc index 86fcc1a..f3df33c 100644 --- a/chrome/renderer/user_script_slave.cc +++ b/chrome/renderer/user_script_slave.cc @@ -25,12 +25,8 @@ using WebKit::WebString; static const char kUserScriptHead[] = "(function (unsafeWindow) {\n"; static const char kUserScriptTail[] = "\n})(window);"; -// Creates a convenient reference to a content script's parent extension. -// TODO(mpcomplete): self.onConnect is deprecated. Remove it at 1.0. -// http://code.google.com/p/chromium/issues/detail?id=16356 -static const char kInitExtension[] = - "chrome.extension = new chrome.Extension('%s');" - "chrome.self.onConnect = chrome.extension.onConnect;"; +// Sets up the chrome.extension module. +static const char kInitExtension[] = "chrome.initExtension('%s');"; int UserScriptSlave::GetIsolatedWorldId(const std::string& extension_id) { typedef std::map<std::string, int> IsolatedWorldMap; |