Filtered events.
Makes web_navigation events support filters, eg:
chrome.webNavigation.onBeforeCommitted.addListener(callback, {url: [{hostSuffix: 'google.com'}]});
Now callback will only be called when the event has a URL with a host suffix of google.com.
BUG=121479
Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=143872
Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=143874
Committed: http://src.chromium.org/viewvc/chrome?view=rev&revision=143896
Committed: http://src.chromium.org/viewvc/chrome?view=rev&revision=145145
Review URL: https://chromiumcodereview.appspot.com/10514013
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@145484 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/renderer/extensions/event_unittest.cc b/chrome/renderer/extensions/event_unittest.cc
index 947d3e8..4b0619f 100644
--- a/chrome/renderer/extensions/event_unittest.cc
+++ b/chrome/renderer/extensions/event_unittest.cc
@@ -22,13 +22,41 @@
OverrideNativeHandler("event_bindings",
"var assert = requireNative('assert');"
"var attachedListeners = exports.attachedListeners = {};"
+ "var attachedFilteredListeners = "
+ " exports.attachedFilteredListeners = {};"
+ "var nextId = 0;"
+ "var idToName = {};"
+
"exports.AttachEvent = function(eventName) {"
" assert.AssertFalse(!!attachedListeners[eventName]);"
" attachedListeners[eventName] = 1;"
"};"
+
"exports.DetachEvent = function(eventName) {"
" assert.AssertTrue(!!attachedListeners[eventName]);"
" delete attachedListeners[eventName];"
+ "};"
+
+ "exports.IsEventAttached = function(eventName) {"
+ " return !!attachedListeners[eventName];"
+ "};"
+
+ "exports.AttachFilteredEvent = function(name, filters) {"
+ " var id = nextId++;"
+ " idToName[id] = name;"
+ " attachedFilteredListeners[name] ="
+ " attachedFilteredListeners[name] || [];"
+ " attachedFilteredListeners[name][id] = filters;"
+ " return id;"
+ "};"
+
+ "exports.DetachFilteredEvent = function(id, manual) {"
+ " var i = attachedFilteredListeners[idToName[id]].indexOf(id);"
+ " attachedFilteredListeners[idToName[id]].splice(i, 1);"
+ "};"
+
+ "exports.HasFilteredListener = function(name) {"
+ " return attachedFilteredListeners[name].length;"
"};");
OverrideNativeHandler("chrome_hidden",
"var chromeHidden = {};"
@@ -62,6 +90,39 @@
module_system_->Require("test");
}
+TEST_F(EventUnittest, OnUnloadDetachesAllListeners) {
+ ModuleSystem::NativesEnabledScope natives_enabled_scope(module_system_.get());
+ RegisterModule("test",
+ "var assert = requireNative('assert');"
+ "var event = require('event');"
+ "var eventBindings = requireNative('event_bindings');"
+ "var chromeHidden = requireNative('chrome_hidden').GetChromeHidden();"
+ "var myEvent = new event.Event('named-event');"
+ "var cb1 = function() {};"
+ "var cb2 = function() {};"
+ "myEvent.addListener(cb1);"
+ "myEvent.addListener(cb2);"
+ "chromeHidden.dispatchOnUnload();"
+ "assert.AssertFalse(!!eventBindings.attachedListeners['named-event']);");
+ module_system_->Require("test");
+}
+
+TEST_F(EventUnittest, OnUnloadDetachesAllListenersEvenDupes) {
+ ModuleSystem::NativesEnabledScope natives_enabled_scope(module_system_.get());
+ RegisterModule("test",
+ "var assert = requireNative('assert');"
+ "var event = require('event');"
+ "var eventBindings = requireNative('event_bindings');"
+ "var chromeHidden = requireNative('chrome_hidden').GetChromeHidden();"
+ "var myEvent = new event.Event('named-event');"
+ "var cb1 = function() {};"
+ "myEvent.addListener(cb1);"
+ "myEvent.addListener(cb1);"
+ "chromeHidden.dispatchOnUnload();"
+ "assert.AssertFalse(!!eventBindings.attachedListeners['named-event']);");
+ module_system_->Require("test");
+}
+
TEST_F(EventUnittest, EventsThatSupportRulesMustHaveAName) {
ModuleSystem::NativesEnabledScope natives_enabled_scope(module_system_.get());
RegisterModule("test",
@@ -92,4 +153,97 @@
module_system_->Require("test");
}
+TEST_F(EventUnittest, AddListenerWithFiltersThrowsErrorByDefault) {
+ ModuleSystem::NativesEnabledScope natives_enabled_scope(module_system_.get());
+ RegisterModule("test",
+ "var event = require('event');"
+ "var assert = requireNative('assert');"
+ "var e = new event.Event('myevent');"
+ "var filter = [{"
+ " url: {hostSuffix: 'google.com'},"
+ "}];"
+ "var caught = false;"
+ "try {"
+ " e.addListener(function() {}, filter);"
+ "} catch (e) {"
+ " caught = true;"
+ "}"
+ "assert.AssertTrue(caught);");
+ module_system_->Require("test");
+}
+
+TEST_F(EventUnittest, FilteredEventsAttachment) {
+ ModuleSystem::NativesEnabledScope natives_enabled_scope(module_system_.get());
+ RegisterModule("test",
+ "var event = require('event');"
+ "var assert = requireNative('assert');"
+ "var bindings = requireNative('event_bindings');"
+ "var eventOpts = {supportsListeners: true, supportsFilters: true};"
+ "var e = new event.Event('myevent', undefined, eventOpts);"
+ "var cb = function() {};"
+ "var filters = {url: [{hostSuffix: 'google.com'}]};"
+ "e.addListener(cb, filters);"
+ "assert.AssertTrue(bindings.HasFilteredListener('myevent'));"
+ "e.removeListener(cb);"
+ "assert.AssertFalse(bindings.HasFilteredListener('myevent'));");
+ module_system_->Require("test");
+}
+
+TEST_F(EventUnittest, DetachFilteredEvent) {
+ ModuleSystem::NativesEnabledScope natives_enabled_scope(module_system_.get());
+ RegisterModule("test",
+ "var event = require('event');"
+ "var assert = requireNative('assert');"
+ "var bindings = requireNative('event_bindings');"
+ "var eventOpts = {supportsListeners: true, supportsFilters: true};"
+ "var e = new event.Event('myevent', undefined, eventOpts);"
+ "var cb1 = function() {};"
+ "var cb2 = function() {};"
+ "var filters = {url: [{hostSuffix: 'google.com'}]};"
+ "e.addListener(cb1, filters);"
+ "e.addListener(cb2, filters);"
+ "e.detach_();"
+ "assert.AssertFalse(bindings.HasFilteredListener('myevent'));");
+ module_system_->Require("test");
+}
+
+TEST_F(EventUnittest, AttachAndRemoveSameFilteredEventListener) {
+ ModuleSystem::NativesEnabledScope natives_enabled_scope(module_system_.get());
+ RegisterModule("test",
+ "var event = require('event');"
+ "var assert = requireNative('assert');"
+ "var bindings = requireNative('event_bindings');"
+ "var eventOpts = {supportsListeners: true, supportsFilters: true};"
+ "var e = new event.Event('myevent', undefined, eventOpts);"
+ "var cb = function() {};"
+ "var filters = {url: [{hostSuffix: 'google.com'}]};"
+ "e.addListener(cb, filters);"
+ "e.addListener(cb, filters);"
+ "assert.AssertTrue(bindings.HasFilteredListener('myevent'));"
+ "e.removeListener(cb);"
+ "assert.AssertTrue(bindings.HasFilteredListener('myevent'));"
+ "e.removeListener(cb);"
+ "assert.AssertFalse(bindings.HasFilteredListener('myevent'));");
+ module_system_->Require("test");
+}
+
+TEST_F(EventUnittest, AddingFilterWithUrlFieldNotAListThrowsException) {
+ ModuleSystem::NativesEnabledScope natives_enabled_scope(module_system_.get());
+ RegisterModule("test",
+ "var event = require('event');"
+ "var assert = requireNative('assert');"
+ "var eventOpts = {supportsListeners: true, supportsFilters: true};"
+ "var e = new event.Event('myevent', undefined, eventOpts);"
+ "var cb = function() {};"
+ "var filters = {url: {hostSuffix: 'google.com'}};"
+ "var caught = false;"
+ "try {"
+ " e.addListener(cb, filters);"
+ "} catch (e) {"
+ " caught = true;"
+ "}"
+ "assert.AssertTrue(caught);");
+ module_system_->Require("test");
+}
+
} // namespace