diff options
author | mpcomplete@chromium.org <mpcomplete@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-15 01:19:26 +0000 |
---|---|---|
committer | mpcomplete@chromium.org <mpcomplete@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-15 01:19:26 +0000 |
commit | c41fe6697e38057138cbe33332d9882e0d7d9b4b (patch) | |
tree | 1b7791940ff36d4a2fd3f43065b857fdaa14b4b4 /chrome/renderer | |
parent | a9846c8d20c3658aadacee6127fc734dc3488b25 (diff) | |
download | chromium_src-c41fe6697e38057138cbe33332d9882e0d7d9b4b.zip chromium_src-c41fe6697e38057138cbe33332d9882e0d7d9b4b.tar.gz chromium_src-c41fe6697e38057138cbe33332d9882e0d7d9b4b.tar.bz2 |
Retrying r74887: Add plumbing to webRequest API to support event filtering.
This introduces a new kind of event (WebRequestEvent) to handle the extra parameters to addListener. Behind the scenes, adding a listener creates a unique sub-event associated with that set of filter+extraInfo parameters. When we dispatch the event, we dispatch only those sub-events that match the required filters.
Original CL: http://codereview.chromium.org/6250152/
This time I fixed the linux compile.
BUG=60101
TEST=no
Review URL: http://codereview.chromium.org/6528005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@74902 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/renderer')
-rw-r--r-- | chrome/renderer/extensions/extension_process_bindings.cc | 15 | ||||
-rw-r--r-- | chrome/renderer/resources/extension_process_bindings.js | 68 |
2 files changed, 81 insertions, 2 deletions
diff --git a/chrome/renderer/extensions/extension_process_bindings.cc b/chrome/renderer/extensions/extension_process_bindings.cc index 923ddf6..e2e8fb3 100644 --- a/chrome/renderer/extensions/extension_process_bindings.cc +++ b/chrome/renderer/extensions/extension_process_bindings.cc @@ -13,6 +13,7 @@ #include "base/json/json_reader.h" #include "base/lazy_instance.h" #include "base/scoped_ptr.h" +#include "base/string_number_conversions.h" #include "base/string_util.h" #include "chrome/common/extensions/extension.h" #include "chrome/common/extensions/extension_constants.h" @@ -231,6 +232,8 @@ class ExtensionImpl : public ExtensionBase { return v8::FunctionTemplate::New(IsExtensionProcess); } else if (name->Equals(v8::String::New("IsIncognitoProcess"))) { return v8::FunctionTemplate::New(IsIncognitoProcess); + } else if (name->Equals(v8::String::New("GetUniqueSubEventName"))) { + return v8::FunctionTemplate::New(GetUniqueSubEventName); } return ExtensionBase::GetNativeFunction(name); @@ -286,6 +289,18 @@ class ExtensionImpl : public ExtensionBase { return v8::Integer::New(next_request_id++); } + // Attach an event name to an object. + static v8::Handle<v8::Value> GetUniqueSubEventName( + const v8::Arguments& args) { + static int next_event_id = 0; + DCHECK(args.Length() == 1); + DCHECK(args[0]->IsString()); + std::string event_name(*v8::String::AsciiValue(args[0])); + std::string unique_event_name = + event_name + "/" + base::IntToString(++next_event_id); + return v8::String::New(unique_event_name.c_str()); + } + // Creates a new messaging channel to the tab with the given ID. static v8::Handle<v8::Value> OpenChannelToTab(const v8::Arguments& args) { // Get the current RenderView so that we can send a routed IPC message from diff --git a/chrome/renderer/resources/extension_process_bindings.js b/chrome/renderer/resources/extension_process_bindings.js index f09b40a..d6e08fe 100644 --- a/chrome/renderer/resources/extension_process_bindings.js +++ b/chrome/renderer/resources/extension_process_bindings.js @@ -18,6 +18,7 @@ var chrome = chrome || {}; native function SetIconCommon(); native function IsExtensionProcess(); native function IsIncognitoProcess(); + native function GetUniqueSubEventName(eventName); var chromeHidden = GetChromeHidden(); @@ -234,6 +235,63 @@ var chrome = chrome || {}; // --- Setup additional api's not currently handled in common/extensions/api + // WebRequestEvent object. This is used for special webRequest events with + // extra parameters. Each invocation of addListener creates a new named + // sub-event. That sub-event is associated with the extra parameters in the + // browser process, so that only it is dispatched when the main event occurs + // matching the extra parameters. + // + // Example: + // chrome.webRequest.onBeforeRequest.addListener( + // callback, {urls: "http://*.google.com/*"}); + // ^ callback will only be called for onBeforeRequests matching the filter. + chrome.WebRequestEvent = function(eventName, opt_argSchemas) { + if (typeof eventName != "string") + throw new Error("chrome.WebRequestEvent requires an event name."); + + this.eventName_ = eventName; + this.argSchemas_ = opt_argSchemas; + this.subEvents_ = []; + }; + + // Registers a callback to be called when this event is dispatched. If + // opt_filter is specified, then the callback is only called for events that + // match the given filters. If opt_extraInfo is specified, the given optional + // info is sent to the callback. + chrome.WebRequestEvent.prototype.addListener = + function(cb, opt_filter, opt_extraInfo) { + var subEventName = GetUniqueSubEventName(this.eventName_); + // Note: this could fail to validate, in which case we would not add the + // subEvent listener. + chrome.experimental.webRequest.addEventListener( + cb, opt_filter, opt_extraInfo, this.eventName_, subEventName); + + var subEvent = new chrome.Event(subEventName, this.argSchemas_); + this.subEvents_.push(subEvent); + subEvent.addListener(cb); + }; + + // Unregisters a callback. + chrome.WebRequestEvent.prototype.removeListener = function(cb) { + var idx = this.findListener_(cb); + if (idx >= -1) { + return; + } + + this.subEvents_[idx].removeListener(cb); + if (!this.subEvents_[idx].hasListeners()) + this.subEvents_.splice(idx, 1); + }; + + chrome.WebRequestEvent.prototype.findListener_ = function(cb) { + for (var i = 0; i < this.subEvents_.length; i++) { + if (this.subEvents_[i].findListener_(cb) > -1) + return i; + } + + return -1; + }; + // Page action events send (pageActionId, {tabId, tabUrl}). function setupPageActionEvents(extensionId) { var pageActions = GetCurrentPageActions(extensionId); @@ -442,8 +500,14 @@ var chrome = chrome || {}; return; var eventName = apiDef.namespace + "." + eventDef.name; - module[eventDef.name] = new chrome.Event(eventName, - eventDef.parameters); + if (apiDef.namespace == "experimental.webRequest") { + // WebRequest events have a special structure. + module[eventDef.name] = new chrome.WebRequestEvent(eventName, + eventDef.parameters); + } else { + module[eventDef.name] = new chrome.Event(eventName, + eventDef.parameters); + } }); } |