Diff
Modified: trunk/LayoutTests/ChangeLog (201729 => 201730)
--- trunk/LayoutTests/ChangeLog 2016-06-06 21:47:05 UTC (rev 201729)
+++ trunk/LayoutTests/ChangeLog 2016-06-06 22:28:25 UTC (rev 201730)
@@ -1,3 +1,37 @@
+2016-06-06 Chris Dumez <[email protected]>
+
+ Implement EventListenerOptions argument to addEventListener
+ https://bugs.webkit.org/show_bug.cgi?id=149466
+ <rdar://problem/22802031>
+
+ Reviewed by Dean Jackson.
+
+ * fast/events/AddEventListenerOptions-once-expected.txt: Added.
+ * fast/events/AddEventListenerOptions-once-recursive-expected.txt: Added.
+ * fast/events/AddEventListenerOptions-once-recursive.html: Added.
+ * fast/events/AddEventListenerOptions-once.html: Added.
+ * fast/events/AddEventListenerOptions-passive-expected.txt: Added.
+ * fast/events/AddEventListenerOptions-passive.html: Added.
+ * fast/events/removeEventListener-EventListenerOptions-capture-expected.txt: Added.
+ * fast/events/removeEventListener-EventListenerOptions-capture.html: Added.
+
+ Add layout testing coverage for various aspects of the functionality.
+
+ * imported/blink/fast/events/eventlisteneroptions/capture_default-expected.txt: Added.
+ * imported/blink/fast/events/eventlisteneroptions/capture_default.html: Added.
+ * imported/blink/fast/events/eventlisteneroptions/capture_equality-expected.txt: Added.
+ * imported/blink/fast/events/eventlisteneroptions/capture_equality.html: Added.
+ * imported/blink/fast/events/eventlisteneroptions/capture_query-expected.txt: Added.
+ * imported/blink/fast/events/eventlisteneroptions/capture_query.html: Added.
+ * imported/blink/fast/events/eventlisteneroptions/passive_dispatch-expected.txt: Added.
+ * imported/blink/fast/events/eventlisteneroptions/passive_dispatch.html: Added.
+ * imported/blink/fast/events/eventlisteneroptions/passive_inequality-expected.txt: Added.
+ * imported/blink/fast/events/eventlisteneroptions/passive_inequality.html: Added.
+ * imported/blink/fast/events/eventlisteneroptions/passive_query-expected.txt: Added.
+ * imported/blink/fast/events/eventlisteneroptions/passive_query.html: Added.
+
+ Import blink tests for this functionality.
+
2016-06-06 Adam Bergkvist <[email protected]>
WebRTC: Update MediaEndpointPeerConnection::createOffer() to use the transceiver set
Added: trunk/LayoutTests/fast/events/AddEventListenerOptions-once-expected.txt (0 => 201730)
--- trunk/LayoutTests/fast/events/AddEventListenerOptions-once-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/events/AddEventListenerOptions-once-expected.txt 2016-06-06 22:28:25 UTC (rev 201730)
@@ -0,0 +1,15 @@
+Tests support for 'once' member in AddEventListenerOptions.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+document.body.addEventListener('test', listenerFunction, { 'once': true })
+PASS listenerCallCount is 0
+document.body.dispatchEvent(new Event('test'))
+PASS listenerCallCount is 1
+document.body.dispatchEvent(new Event('test'))
+PASS listenerCallCount is 1
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/events/AddEventListenerOptions-once-recursive-expected.txt (0 => 201730)
--- trunk/LayoutTests/fast/events/AddEventListenerOptions-once-recursive-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/events/AddEventListenerOptions-once-recursive-expected.txt 2016-06-06 22:28:25 UTC (rev 201730)
@@ -0,0 +1,15 @@
+Tests support for 'once' member in AddEventListenerOptions.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+document.body.addEventListener('test', listenerFunction, { 'once': true })
+PASS listenerCallCount is 0
+document.body.dispatchEvent(new Event('test'))
+PASS listenerCallCount is 1
+document.body.dispatchEvent(new Event('test'))
+PASS listenerCallCount is 1
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/events/AddEventListenerOptions-once-recursive.html (0 => 201730)
--- trunk/LayoutTests/fast/events/AddEventListenerOptions-once-recursive.html (rev 0)
+++ trunk/LayoutTests/fast/events/AddEventListenerOptions-once-recursive.html 2016-06-06 22:28:25 UTC (rev 201730)
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src=""
+<script>
+description("Tests support for 'once' member in AddEventListenerOptions.");
+
+var listenerCallCount = 0;
+function listenerFunction()
+{
+ ++listenerCallCount;
+
+ if (listenerCallCount == 1)
+ document.body.dispatchEvent(new Event('test'));
+}
+
+evalAndLog("document.body.addEventListener('test', listenerFunction, { 'once': true })");
+shouldBe("listenerCallCount", "0");
+evalAndLog("document.body.dispatchEvent(new Event('test'))");
+shouldBe("listenerCallCount", "1");
+evalAndLog("document.body.dispatchEvent(new Event('test'))");
+shouldBe("listenerCallCount", "1");
+
+</script>
+<script src=""
+</body>
+</html>
Added: trunk/LayoutTests/fast/events/AddEventListenerOptions-once.html (0 => 201730)
--- trunk/LayoutTests/fast/events/AddEventListenerOptions-once.html (rev 0)
+++ trunk/LayoutTests/fast/events/AddEventListenerOptions-once.html 2016-06-06 22:28:25 UTC (rev 201730)
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src=""
+<script>
+description("Tests support for 'once' member in AddEventListenerOptions.");
+
+var listenerCallCount = 0;
+function listenerFunction()
+{
+ ++listenerCallCount;
+}
+
+evalAndLog("document.body.addEventListener('test', listenerFunction, { 'once': true })");
+shouldBe("listenerCallCount", "0");
+evalAndLog("document.body.dispatchEvent(new Event('test'))");
+shouldBe("listenerCallCount", "1");
+evalAndLog("document.body.dispatchEvent(new Event('test'))");
+shouldBe("listenerCallCount", "1");
+
+</script>
+<script src=""
+</body>
+</html>
Added: trunk/LayoutTests/fast/events/AddEventListenerOptions-passive-expected.txt (0 => 201730)
--- trunk/LayoutTests/fast/events/AddEventListenerOptions-passive-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/events/AddEventListenerOptions-passive-expected.txt 2016-06-06 22:28:25 UTC (rev 201730)
@@ -0,0 +1,23 @@
+Tests support for 'passive' member in AddEventListenerOptions.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+document.body.addEventListener('test', passiveListenerFunction, { 'passive': true })
+document.body.dispatchEvent(testEvent1)
+PASS listenerCallCount is 1
+PASS testEvent1.defaultPrevented is false
+
+document.body.addEventListener('test', activeListenerFunction, { })
+document.body.dispatchEvent(testEvent2)
+PASS listenerCallCount is 2
+PASS testEvent2.defaultPrevented is true
+
+document.body.addEventListener('test', activeListenerFunction, { 'passive': false })
+document.body.dispatchEvent(testEvent2)
+PASS listenerCallCount is 2
+PASS testEvent2.defaultPrevented is true
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/events/AddEventListenerOptions-passive.html (0 => 201730)
--- trunk/LayoutTests/fast/events/AddEventListenerOptions-passive.html (rev 0)
+++ trunk/LayoutTests/fast/events/AddEventListenerOptions-passive.html 2016-06-06 22:28:25 UTC (rev 201730)
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src=""
+<script>
+description("Tests support for 'passive' member in AddEventListenerOptions.");
+
+var listenerCallCount = 0;
+function passiveListenerFunction(ev)
+{
+ ++listenerCallCount;
+ ev.preventDefault();
+}
+
+function activeListenerFunction(ev)
+{
+ ++listenerCallCount;
+ ev.preventDefault();
+}
+
+evalAndLog("document.body.addEventListener('test', passiveListenerFunction, { 'passive': true })");
+var testEvent1 = new Event('test', { 'cancelable': true });
+evalAndLog("document.body.dispatchEvent(testEvent1)");
+shouldBe("listenerCallCount", "1");
+shouldBeFalse("testEvent1.defaultPrevented");
+
+debug("");
+listenerCallCount = 0;
+// 'passive should be false by default.
+evalAndLog("document.body.addEventListener('test', activeListenerFunction, { })");
+var testEvent2 = new Event('test', { 'cancelable': true });
+evalAndLog("document.body.dispatchEvent(testEvent2)");
+shouldBe("listenerCallCount", "2");
+shouldBeTrue("testEvent2.defaultPrevented");
+document.body.removeEventListener('test', activeListenerFunction);
+
+debug("");
+listenerCallCount = 0;
+evalAndLog("document.body.addEventListener('test', activeListenerFunction, { 'passive': false })");
+var testEvent2 = new Event('test', { 'cancelable': true });
+evalAndLog("document.body.dispatchEvent(testEvent2)");
+shouldBe("listenerCallCount", "2");
+shouldBeTrue("testEvent2.defaultPrevented");
+
+</script>
+<script src=""
+</body>
+</html>
Added: trunk/LayoutTests/fast/events/removeEventListener-EventListenerOptions-capture-expected.txt (0 => 201730)
--- trunk/LayoutTests/fast/events/removeEventListener-EventListenerOptions-capture-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/events/removeEventListener-EventListenerOptions-capture-expected.txt 2016-06-06 22:28:25 UTC (rev 201730)
@@ -0,0 +1,50 @@
+Tests support for calling removeEventListener() with an EventListenerOptions dictionary
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS testAddThenRemove(undefined, false) is true
+PASS testAddThenRemove(undefined, { 'capture': false }) is true
+PASS testAddThenRemove(undefined, { }) is true
+PASS testAddThenRemove(undefined, undefined) is true
+PASS testAddThenRemove(undefined, true) is false
+PASS testAddThenRemove(undefined, { 'capture': true }) is false
+
+PASS testAddThenRemove(false, false) is true
+PASS testAddThenRemove(false, { 'capture': false }) is true
+PASS testAddThenRemove(false, { }) is true
+PASS testAddThenRemove(false, undefined) is true
+PASS testAddThenRemove(false, true) is false
+PASS testAddThenRemove(false, { 'capture': true }) is false
+
+PASS testAddThenRemove({ 'capture': false }, false) is true
+PASS testAddThenRemove({ 'capture': false }, { 'capture': false }) is true
+PASS testAddThenRemove({ 'capture': false }, { }) is true
+PASS testAddThenRemove({ 'capture': false }, undefined) is true
+PASS testAddThenRemove({ 'capture': false }, true) is false
+PASS testAddThenRemove({ 'capture': false }, { 'capture': true }) is false
+
+PASS testAddThenRemove({ }, false) is true
+PASS testAddThenRemove({ }, { 'capture': false }) is true
+PASS testAddThenRemove({ }, { }) is true
+PASS testAddThenRemove({ }, undefined) is true
+PASS testAddThenRemove({ }, true) is false
+PASS testAddThenRemove({ }, { 'capture': true }) is false
+
+PASS testAddThenRemove(true, true) is true
+PASS testAddThenRemove(true, { 'capture': true }) is true
+PASS testAddThenRemove(true, { }) is false
+PASS testAddThenRemove(true, undefined) is false
+PASS testAddThenRemove(true, false) is false
+PASS testAddThenRemove(true, { 'capture': false }) is false
+
+PASS testAddThenRemove({ 'capture': true } , true) is true
+PASS testAddThenRemove({ 'capture': true }, { 'capture': true }) is true
+PASS testAddThenRemove({ 'capture': true }, { }) is false
+PASS testAddThenRemove({ 'capture': true }, undefined) is false
+PASS testAddThenRemove({ 'capture': true }, false) is false
+PASS testAddThenRemove({ 'capture': true }, { 'capture': false }) is false
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/events/removeEventListener-EventListenerOptions-capture.html (0 => 201730)
--- trunk/LayoutTests/fast/events/removeEventListener-EventListenerOptions-capture.html (rev 0)
+++ trunk/LayoutTests/fast/events/removeEventListener-EventListenerOptions-capture.html 2016-06-06 22:28:25 UTC (rev 201730)
@@ -0,0 +1,93 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src=""
+<script>
+description("Tests support for calling removeEventListener() with an EventListenerOptions dictionary");
+
+var wasListenerCalled = false;
+function listenerFunction(ev)
+{
+ wasListenerCalled = true;
+}
+
+function isListenerRegistered()
+{
+ document.body.dispatchEvent(new Event('test'));
+ var result = wasListenerCalled;
+ wasListenerCalled = false;
+ return result;
+}
+
+function testAddThenRemove(addOptions, removeOptions)
+{
+ document.body.addEventListener('test', listenerFunction, addOptions);
+ if (!isListenerRegistered())
+ testFailed("Failed to add event listener with given options");
+ document.body.removeEventListener('test', listenerFunction, removeOptions);
+ var result = !isListenerRegistered();
+
+ // clean up.
+ capture = false;
+ if (typeof(addOptions) === "boolean")
+ capture = addOptions;
+ else if (typeof(addOptions) === "object")
+ capture = addOptions.capture;
+ document.body.removeEventListener('test', listenerFunction, capture);
+
+ return result;
+}
+
+testAddThenRemove(undefined, undefined, true);
+
+// capture is false by default.
+shouldBeTrue("testAddThenRemove(undefined, false)");
+shouldBeTrue("testAddThenRemove(undefined, { 'capture': false })");
+shouldBeTrue("testAddThenRemove(undefined, { })");
+shouldBeTrue("testAddThenRemove(undefined, undefined)");
+shouldBeFalse("testAddThenRemove(undefined, true)");
+shouldBeFalse("testAddThenRemove(undefined, { 'capture': true })");
+
+debug("");
+shouldBeTrue("testAddThenRemove(false, false)");
+shouldBeTrue("testAddThenRemove(false, { 'capture': false })");
+shouldBeTrue("testAddThenRemove(false, { })");
+shouldBeTrue("testAddThenRemove(false, undefined)");
+shouldBeFalse("testAddThenRemove(false, true)");
+shouldBeFalse("testAddThenRemove(false, { 'capture': true })");
+
+debug("");
+shouldBeTrue("testAddThenRemove({ 'capture': false }, false)");
+shouldBeTrue("testAddThenRemove({ 'capture': false }, { 'capture': false })");
+shouldBeTrue("testAddThenRemove({ 'capture': false }, { })");
+shouldBeTrue("testAddThenRemove({ 'capture': false }, undefined)");
+shouldBeFalse("testAddThenRemove({ 'capture': false }, true)");
+shouldBeFalse("testAddThenRemove({ 'capture': false }, { 'capture': true })");
+
+debug("");
+shouldBeTrue("testAddThenRemove({ }, false)");
+shouldBeTrue("testAddThenRemove({ }, { 'capture': false })");
+shouldBeTrue("testAddThenRemove({ }, { })");
+shouldBeTrue("testAddThenRemove({ }, undefined)");
+shouldBeFalse("testAddThenRemove({ }, true)");
+shouldBeFalse("testAddThenRemove({ }, { 'capture': true })");
+
+debug("");
+shouldBeTrue("testAddThenRemove(true, true)");
+shouldBeTrue("testAddThenRemove(true, { 'capture': true })");
+shouldBeFalse("testAddThenRemove(true, { })");
+shouldBeFalse("testAddThenRemove(true, undefined)");
+shouldBeFalse("testAddThenRemove(true, false)");
+shouldBeFalse("testAddThenRemove(true, { 'capture': false })");
+
+debug("");
+shouldBeTrue("testAddThenRemove({ 'capture': true } , true)");
+shouldBeTrue("testAddThenRemove({ 'capture': true }, { 'capture': true })");
+shouldBeFalse("testAddThenRemove({ 'capture': true }, { })");
+shouldBeFalse("testAddThenRemove({ 'capture': true }, undefined)");
+shouldBeFalse("testAddThenRemove({ 'capture': true }, false)");
+shouldBeFalse("testAddThenRemove({ 'capture': true }, { 'capture': false })");
+</script>
+<script src=""
+</body>
+</html>
Added: trunk/LayoutTests/imported/blink/fast/events/eventlisteneroptions/capture_default-expected.txt (0 => 201730)
--- trunk/LayoutTests/imported/blink/fast/events/eventlisteneroptions/capture_default-expected.txt (rev 0)
+++ trunk/LayoutTests/imported/blink/fast/events/eventlisteneroptions/capture_default-expected.txt 2016-06-06 22:28:25 UTC (rev 201730)
@@ -0,0 +1,14 @@
+
+PASS True value
+PASS False value
+PASS Empty object
+PASS Null object
+PASS Undefined object
+PASS Positive value
+PASS Negative value
+PASS NaN value
+PASS Postive zero value
+PASS Negative zero value
+PASS Empty string value
+PASS Non empty string value
+
Added: trunk/LayoutTests/imported/blink/fast/events/eventlisteneroptions/capture_default.html (0 => 201730)
--- trunk/LayoutTests/imported/blink/fast/events/eventlisteneroptions/capture_default.html (rev 0)
+++ trunk/LayoutTests/imported/blink/fast/events/eventlisteneroptions/capture_default.html 2016-06-06 22:28:25 UTC (rev 201730)
@@ -0,0 +1,34 @@
+<!DOCTYPE HTML>
+<body/>
+<script src=""
+<script src=""
+
+<script>
+
+function testCaptureValue(captureValue, expectedValue, test) {
+ var handlerPhase = undefined;
+ var handler = function handler(e) {
+ assert_equals(handlerPhase, undefined);
+ handlerPhase = e.eventPhase;
+ }
+ document.addEventListener('test', handler, captureValue);
+ document.body.dispatchEvent(new Event('test', {'bubbles': true}));
+ document.removeEventListener('test', handler, captureValue);
+ document.body.dispatchEvent(new Event('test', {'bubbles': true}));
+ assert_equals(handlerPhase, expectedValue);
+ test.done();
+}
+
+test(function(t) { testCaptureValue(true, Event.CAPTURING_PHASE, t); }, "True value");
+test(function(t) { testCaptureValue(false, Event.BUBBLING_PHASE, t); }, "False value");
+test(function(t) { testCaptureValue({}, Event.BUBBLING_PHASE, t); }, "Empty object");
+test(function(t) { testCaptureValue(null, Event.BUBBLING_PHASE, t); }, "Null object");
+test(function(t) { testCaptureValue(undefined, Event.BUBBLING_PHASE, t); }, "Undefined object");
+test(function(t) { testCaptureValue(2.3, Event.CAPTURING_PHASE, t); }, "Positive value");
+test(function(t) { testCaptureValue(-1000.3, Event.CAPTURING_PHASE, t); }, "Negative value");
+test(function(t) { testCaptureValue(NaN, Event.BUBBLING_PHASE, t); }, "NaN value");
+test(function(t) { testCaptureValue(+0.0, Event.BUBBLING_PHASE, t); }, "Postive zero value");
+test(function(t) { testCaptureValue(-0.0, Event.BUBBLING_PHASE, t); }, "Negative zero value");
+test(function(t) { testCaptureValue("", Event.BUBBLING_PHASE, t); }, "Empty string value");
+test(function(t) { testCaptureValue("AAAA", Event.CAPTURING_PHASE, t); }, "Non empty string value");
+</script>
Added: trunk/LayoutTests/imported/blink/fast/events/eventlisteneroptions/capture_equality-expected.txt (0 => 201730)
--- trunk/LayoutTests/imported/blink/fast/events/eventlisteneroptions/capture_equality-expected.txt (rev 0)
+++ trunk/LayoutTests/imported/blink/fast/events/eventlisteneroptions/capture_equality-expected.txt 2016-06-06 22:28:25 UTC (rev 201730)
@@ -0,0 +1,6 @@
+
+PASS Empty object
+PASS Capture false
+PASS Capture true
+PASS Non-empty object
+
Added: trunk/LayoutTests/imported/blink/fast/events/eventlisteneroptions/capture_equality.html (0 => 201730)
--- trunk/LayoutTests/imported/blink/fast/events/eventlisteneroptions/capture_equality.html (rev 0)
+++ trunk/LayoutTests/imported/blink/fast/events/eventlisteneroptions/capture_equality.html 2016-06-06 22:28:25 UTC (rev 201730)
@@ -0,0 +1,22 @@
+<!DOCTYPE HTML>
+<body/>
+<script src=""
+<script src=""
+
+<script>
+function testOptionEquality(addOptionValue, removeOptionValue, test) {
+ var handler = function handler(e) {
+ assert_unreached("dummy value getter invoked");
+ }
+ document.addEventListener('test', handler, addOptionValue);
+ document.removeEventListener('test', handler, removeOptionValue);
+ document.body.dispatchEvent(new Event('test', {'bubbles': true}));
+ test.done();
+}
+
+test(function(t) { testOptionEquality({}, false, t); }, "Empty object");
+test(function(t) { testOptionEquality({'capture': false}, false, t); }, "Capture false");
+test(function(t) { testOptionEquality({'capture': true}, true, t); }, "Capture true");
+test(function(t) { testOptionEquality({'dummy': true}, false, t); }, "Non-empty object");
+
+</script>
Added: trunk/LayoutTests/imported/blink/fast/events/eventlisteneroptions/capture_query-expected.txt (0 => 201730)
--- trunk/LayoutTests/imported/blink/fast/events/eventlisteneroptions/capture_query-expected.txt (rev 0)
+++ trunk/LayoutTests/imported/blink/fast/events/eventlisteneroptions/capture_query-expected.txt 2016-06-06 22:28:25 UTC (rev 201730)
@@ -0,0 +1,3 @@
+
+PASS Supports Capture
+
Added: trunk/LayoutTests/imported/blink/fast/events/eventlisteneroptions/capture_query.html (0 => 201730)
--- trunk/LayoutTests/imported/blink/fast/events/eventlisteneroptions/capture_query.html (rev 0)
+++ trunk/LayoutTests/imported/blink/fast/events/eventlisteneroptions/capture_query.html 2016-06-06 22:28:25 UTC (rev 201730)
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML>
+<body/>
+<script src=""
+<script src=""
+
+<script>
+test(function(t) {
+ var supportsCapture = false;
+ var query_function = function(e) {};
+ var query_options = {
+ get capture() {
+ supportsCapture = true;
+ return false;
+ },
+ get dummy() {
+ assert_unreached("dummy value getter invoked");
+ return false;
+ }
+ };
+
+ document.addEventListener('test_event', query_function, query_options);
+ assert_true(supportsCapture);
+ supportsCapture = false;
+ document.removeEventListener('test_event', query_function, query_options);
+ assert_true(supportsCapture);
+ t.done();
+}, "Supports Capture");
+</script>
Added: trunk/LayoutTests/imported/blink/fast/events/eventlisteneroptions/passive_dispatch-expected.txt (0 => 201730)
--- trunk/LayoutTests/imported/blink/fast/events/eventlisteneroptions/passive_dispatch-expected.txt (rev 0)
+++ trunk/LayoutTests/imported/blink/fast/events/eventlisteneroptions/passive_dispatch-expected.txt 2016-06-06 22:28:25 UTC (rev 201730)
@@ -0,0 +1,9 @@
+
+PASS Two argument register
+PASS Prevent default capture false
+PASS Prevent default capture true
+PASS Prevent default with empty object
+PASS Prevent default with passive false
+PASS Prevent default with passive true
+PASS Passive and Blocking Registered Handlers
+
Added: trunk/LayoutTests/imported/blink/fast/events/eventlisteneroptions/passive_dispatch.html (0 => 201730)
--- trunk/LayoutTests/imported/blink/fast/events/eventlisteneroptions/passive_dispatch.html (rev 0)
+++ trunk/LayoutTests/imported/blink/fast/events/eventlisteneroptions/passive_dispatch.html 2016-06-06 22:28:25 UTC (rev 201730)
@@ -0,0 +1,62 @@
+<!DOCTYPE HTML>
+<body/>
+<script src=""
+<script src=""
+
+<!-- This test is run with normal layout tests with passiveEventListeners
+ enabled and in virtual/stable with passiveEventListeners disabled -->
+<script>
+
+function testTwoArgumentRegister() {
+ var handler = function handler(e) {
+ e.preventDefault();
+ }
+ document.addEventListener('test', handler);
+ assert_equals(false, document.body.dispatchEvent(new Event('test', {'bubbles': true, 'cancelable': true})));
+ document.removeEventListener('test', handler);
+ assert_equals(true, document.body.dispatchEvent(new Event('test', {'bubbles': true, 'cancelable': true})));
+}
+
+function testPassiveValue(registerValue, expectedValue, test) {
+ var handler = function handler(e) {
+ e.preventDefault();
+ }
+ document.addEventListener('test', handler, registerValue);
+ var event = new Event('test', {'bubbles': true, 'cancelable': true});
+ assert_equals(expectedValue, document.body.dispatchEvent(event));
+ assert_equals(!expectedValue, event.defaultPrevented);
+ document.removeEventListener('test', handler, registerValue);
+ assert_equals(true, document.body.dispatchEvent(new Event('test', {'bubbles': true, 'cancelable': true})));
+ test.done();
+}
+
+function testTwoHandlers() {
+ var passive_called = undefined;
+ var blocking_called = undefined;
+ var passive_handler = function handler(e) {
+ passive_called = true;
+ }
+ var blocking_handler = function handler(e) {
+ blocking_called = true;
+ e.preventDefault();
+ }
+ document.addEventListener('test', passive_handler, {"passive" : true});
+ document.addEventListener('test', blocking_handler, {"passive" : false});
+ var event = new Event('test', {'bubbles': true, 'cancelable': true});
+ document.body.dispatchEvent(event);
+ assert_true(passive_called);
+ assert_true(blocking_called);
+ assert_true(event.defaultPrevented);
+ document.removeEventListener('test', passive_handler, {});
+ document.removeEventListener('test', blocking_handler, {});
+}
+
+test(testTwoArgumentRegister, "Two argument register");
+test(function(t) { testPassiveValue(false, false, t); }, "Prevent default capture false");
+test(function(t) { testPassiveValue(true, false, t); }, "Prevent default capture true");
+test(function(t) { testPassiveValue({}, false, t); }, "Prevent default with empty object");
+test(function(t) { testPassiveValue({passive: false}, false, t); }, "Prevent default with passive false");
+test(function(t) { testPassiveValue({passive: true}, true, t); }, "Prevent default with passive true ");
+test(testTwoHandlers, "Passive and Blocking Registered Handlers");
+
+</script>
Added: trunk/LayoutTests/imported/blink/fast/events/eventlisteneroptions/passive_inequality-expected.txt (0 => 201730)
--- trunk/LayoutTests/imported/blink/fast/events/eventlisteneroptions/passive_inequality-expected.txt (rev 0)
+++ trunk/LayoutTests/imported/blink/fast/events/eventlisteneroptions/passive_inequality-expected.txt 2016-06-06 22:28:25 UTC (rev 201730)
@@ -0,0 +1,5 @@
+
+PASS Passive Handler
+PASS Non Passive Handler
+PASS Passive Handler And Non Passive Capturing
+
Added: trunk/LayoutTests/imported/blink/fast/events/eventlisteneroptions/passive_inequality.html (0 => 201730)
--- trunk/LayoutTests/imported/blink/fast/events/eventlisteneroptions/passive_inequality.html (rev 0)
+++ trunk/LayoutTests/imported/blink/fast/events/eventlisteneroptions/passive_inequality.html 2016-06-06 22:28:25 UTC (rev 201730)
@@ -0,0 +1,43 @@
+<!DOCTYPE HTML>
+<body/>
+<script src=""
+<script src=""
+
+<script>
+
+function passiveHandlerAddNonPassive() {
+ var handler = function handler(e) {
+ e.preventDefault();
+ assert_false(e.defaultPrevented);
+ }
+ document.addEventListener('test', handler, {"passive": true});
+ document.addEventListener('test', handler, {"passive": false});
+ document.body.dispatchEvent(new Event('test', {'bubbles': true, 'cancelable': true}));
+}
+
+function nonPassiveHandlerAddPassive() {
+ var handler = function handler(e) {
+ e.preventDefault();
+ assert_true(e.defaultPrevented);
+ }
+ document.addEventListener('test', handler, {"passive": false});
+ document.addEventListener('test', handler, {"passive": true});
+ document.body.dispatchEvent(new Event('test', {'bubbles': true, 'cancelable': true}));
+}
+
+function passiveHandlerAddNonPassiveCapturing() {
+ var handlersCalled = 0;
+ var handler = function handler(e) {
+ handlersCalled++;
+ }
+ document.addEventListener('test', handler, {"passive": true});
+ document.addEventListener('test', handler, {"passive": false, "capture": true});
+ document.body.dispatchEvent(new Event('test', {'bubbles': true, 'cancelable': true}));
+ assert_equals(handlersCalled, 2, "Handlers called correct number of times");
+}
+
+test(passiveHandlerAddNonPassive, "Passive Handler");
+test(nonPassiveHandlerAddPassive, "Non Passive Handler");
+test(passiveHandlerAddNonPassiveCapturing, "Passive Handler And Non Passive Capturing");
+
+</script>
Added: trunk/LayoutTests/imported/blink/fast/events/eventlisteneroptions/passive_query-expected.txt (0 => 201730)
--- trunk/LayoutTests/imported/blink/fast/events/eventlisteneroptions/passive_query-expected.txt (rev 0)
+++ trunk/LayoutTests/imported/blink/fast/events/eventlisteneroptions/passive_query-expected.txt 2016-06-06 22:28:25 UTC (rev 201730)
@@ -0,0 +1,3 @@
+
+PASS Supports Passive
+
Added: trunk/LayoutTests/imported/blink/fast/events/eventlisteneroptions/passive_query.html (0 => 201730)
--- trunk/LayoutTests/imported/blink/fast/events/eventlisteneroptions/passive_query.html (rev 0)
+++ trunk/LayoutTests/imported/blink/fast/events/eventlisteneroptions/passive_query.html 2016-06-06 22:28:25 UTC (rev 201730)
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML>
+<body/>
+<script src=""
+<script src=""
+
+<!-- This test is run with normal layout tests with passiveEventListeners
+ enabled and in virtual/stable with passiveEventListeners disabled -->
+<script>
+test(function(t) {
+ var supportsPassive = false;
+ var query_function = function(e) {};
+ var query_options = {
+ get passive() {
+ supportsPassive = true;
+ return false;
+ },
+ get dummy() {
+ assert_unreached("dummy value getter invoked");
+ return false;
+ }
+ };
+
+ document.addEventListener('test_event', query_function, query_options);
+ assert_equals(supportsPassive, true);
+ t.done();
+}, "Supports Passive");
+</script>
Modified: trunk/LayoutTests/imported/w3c/ChangeLog (201729 => 201730)
--- trunk/LayoutTests/imported/w3c/ChangeLog 2016-06-06 21:47:05 UTC (rev 201729)
+++ trunk/LayoutTests/imported/w3c/ChangeLog 2016-06-06 22:28:25 UTC (rev 201730)
@@ -1,3 +1,16 @@
+2016-06-06 Chris Dumez <[email protected]>
+
+ Implement EventListenerOptions argument to addEventListener
+ https://bugs.webkit.org/show_bug.cgi?id=149466
+ <rdar://problem/22802031>
+
+ Reviewed by Dean Jackson.
+
+ Import new test from W3C that covers EventListenerOptions.
+
+ * web-platform-tests/dom/events/EventListenerOptions-capture-expected.txt: Added.
+ * web-platform-tests/dom/events/EventListenerOptions-capture.html: Added.
+
2016-06-03 Chris Dumez <[email protected]>
CanvasRenderingContext2D.createPattern() / putImageData() throw wrong exception type
Added: trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/EventListenerOptions-capture-expected.txt (0 => 201730)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/EventListenerOptions-capture-expected.txt (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/EventListenerOptions-capture-expected.txt 2016-06-06 22:28:25 UTC (rev 201730)
@@ -0,0 +1,6 @@
+
+PASS Capture boolean should be honored correctly
+PASS Capture option should be honored correctly
+PASS Supports capture option
+PASS Equivalence of option values
+
Added: trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/EventListenerOptions-capture.html (0 => 201730)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/EventListenerOptions-capture.html (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/EventListenerOptions-capture.html 2016-06-06 22:28:25 UTC (rev 201730)
@@ -0,0 +1,98 @@
+<!DOCTYPE HTML>
+<meta charset="utf-8">
+<title>EventListenerOptions.capture</title>
+<link rel="author" title="Rick Byers" href=""
+<link rel="help" href=""
+<script src=""
+<script src=""
+<div id="log"></div>
+
+<script>
+
+function testCaptureValue(captureValue, expectedValue) {
+ var handlerPhase = undefined;
+ var handler = function handler(e) {
+ assert_equals(handlerPhase, undefined, "Handler invoked after remove");
+ handlerPhase = e.eventPhase;
+ }
+ document.addEventListener('test', handler, captureValue);
+ document.body.dispatchEvent(new Event('test', {'bubbles': true}));
+ document.removeEventListener('test', handler, captureValue);
+ document.body.dispatchEvent(new Event('test', {'bubbles': true}));
+ assert_equals(handlerPhase, expectedValue, "Incorrect event phase for value: " + JSON.stringify(captureValue));
+}
+
+test(function() {
+ testCaptureValue(true, Event.CAPTURING_PHASE);
+ testCaptureValue(false, Event.BUBBLING_PHASE);
+ testCaptureValue(null, Event.BUBBLING_PHASE);
+ testCaptureValue(undefined, Event.BUBBLING_PHASE);
+ testCaptureValue(2.3, Event.CAPTURING_PHASE);
+ testCaptureValue(-1000.3, Event.CAPTURING_PHASE);
+ testCaptureValue(NaN, Event.BUBBLING_PHASE);
+ testCaptureValue(+0.0, Event.BUBBLING_PHASE);
+ testCaptureValue(-0.0, Event.BUBBLING_PHASE);
+ testCaptureValue("", Event.BUBBLING_PHASE);
+ testCaptureValue("AAAA", Event.CAPTURING_PHASE);
+}, "Capture boolean should be honored correctly");
+
+test(function() {
+ testCaptureValue({}, Event.BUBBLING_PHASE);
+ testCaptureValue({capture:true}, Event.CAPTURING_PHASE);
+ testCaptureValue({capture:false}, Event.BUBBLING_PHASE);
+ testCaptureValue({capture:2}, Event.CAPTURING_PHASE);
+ testCaptureValue({capture:0}, Event.BUBBLING_PHASE);
+}, "Capture option should be honored correctly");
+
+test(function() {
+ var supportsCapture = false;
+ var query_options = {
+ get capture() {
+ supportsCapture = true;
+ return false;
+ },
+ get dummy() {
+ assert_unreached("dummy value getter invoked");
+ return false;
+ }
+ };
+
+ document.addEventListener('test_event', null, query_options);
+ assert_true(supportsCapture, "addEventListener doesn't support the capture option");
+ supportsCapture = false;
+ document.removeEventListener('test_event', null, query_options);
+ assert_true(supportsCapture, "removeEventListener doesn't support the capture option");
+}, "Supports capture option");
+
+function testOptionEquality(addOptionValue, removeOptionValue, expectedEquality) {
+ var handlerInvoked = false;
+ var handler = function handler(e) {
+ assert_equals(handlerInvoked, false, "Handler invoked multiple times");
+ handlerInvoked = true;
+ }
+ document.addEventListener('test', handler, addOptionValue);
+ document.removeEventListener('test', handler, removeOptionValue);
+ document.body.dispatchEvent(new Event('test', {'bubbles': true}));
+ assert_equals(!handlerInvoked, expectedEquality, "equivalence of options " +
+ JSON.stringify(addOptionValue) + " and " + JSON.stringify(removeOptionValue));
+ if (handlerInvoked)
+ document.removeEventListener('test', handler, addOptionValue);
+}
+
+test(function() {
+ // Option values that should be treated as equivalent
+ testOptionEquality({}, false, true);
+ testOptionEquality({capture: false}, false, true);
+ testOptionEquality(true, {capture: true}, true);
+ testOptionEquality({capture: null}, undefined, true);
+ testOptionEquality({capture: true}, {dummy: false, capture: 1}, true);
+ testOptionEquality({dummy: true}, false, true);
+
+ // Option values that should be treated as distinct
+ testOptionEquality(true, false, false);
+ testOptionEquality(true, {capture:false}, false);
+ testOptionEquality({}, true, false);
+
+}, "Equivalence of option values");
+
+</script>
Modified: trunk/Source/WebCore/ChangeLog (201729 => 201730)
--- trunk/Source/WebCore/ChangeLog 2016-06-06 21:47:05 UTC (rev 201729)
+++ trunk/Source/WebCore/ChangeLog 2016-06-06 22:28:25 UTC (rev 201730)
@@ -1,3 +1,90 @@
+2016-06-06 Chris Dumez <[email protected]>
+
+ Implement EventListenerOptions argument to addEventListener
+ https://bugs.webkit.org/show_bug.cgi?id=149466
+ <rdar://problem/22802031>
+
+ Reviewed by Dean Jackson.
+
+ Implement AddEventListenerOptions dictionary argument to addEventListener()
+ and EventListenerOptions dictionary argument to removeEventListener(), as
+ per the latest DOM specification:
+ - https://dom.spec.whatwg.org/#interface-eventtarget
+
+ Firefox and Chrome already support this.
+
+ Support for AddEventListenerOptions in this patch is as follows:
+ - 'capture': fully supported.
+ - 'once': fully supported.
+ - 'passive': supported in the sense that preventDefault() will be ignored
+ for passive event listeners. There are however currently no
+ performance benefits from passing this flag. Those optimizations
+ will be implemented in follow-up patches (in particular for
+ Touch and Scroll events).
+
+ Tests: fast/events/AddEventListenerOptions-once-recursive.html
+ fast/events/AddEventListenerOptions-once.html
+ fast/events/AddEventListenerOptions-passive.html
+ fast/events/removeEventListener-EventListenerOptions-capture.html
+ imported/w3c/web-platform-tests/dom/events/EventListenerOptions-capture.html
+
+ * Modules/webaudio/AudioScheduledSourceNode.cpp:
+ (WebCore::AudioScheduledSourceNode::addEventListener):
+ (WebCore::AudioScheduledSourceNode::removeEventListener):
+ * Modules/webaudio/AudioScheduledSourceNode.h:
+ * Modules/webaudio/ScriptProcessorNode.cpp:
+ (WebCore::ScriptProcessorNode::addEventListener):
+ (WebCore::ScriptProcessorNode::removeEventListener):
+ * Modules/webaudio/ScriptProcessorNode.h:
+ * bindings/scripts/CodeGeneratorJS.pm:
+ (GenerateParametersCheckExpression):
+ * dom/Event.h:
+ (WebCore::Event::preventDefault):
+ (WebCore::Event::setInPassiveListener):
+ * dom/EventListenerMap.cpp:
+ (WebCore::addListenerToVector):
+ (WebCore::EventListenerMap::add):
+ * dom/EventListenerMap.h:
+ * dom/EventTarget.cpp:
+ (WebCore::EventTarget::addEventListener):
+ (WebCore::EventTarget::addEventListenerForBindings):
+ (WebCore::EventTarget::removeEventListenerForBindings):
+ (WebCore::EventTarget::removeEventListener):
+ (WebCore::EventTarget::setAttributeEventListener):
+ (WebCore::EventTarget::fireEventListeners):
+ * dom/EventTarget.h:
+ (WebCore::EventTarget::ListenerOptions::ListenerOptions):
+ (WebCore::EventTarget::AddEventListenerOptions::AddEventListenerOptions):
+ (WebCore::EventTarget::addEventListener):
+ (WebCore::EventTarget::addEventListenerForBindings):
+ (WebCore::EventTarget::removeEventListenerForBindings):
+ * dom/EventTarget.idl:
+ * dom/MessagePort.cpp:
+ (WebCore::MessagePort::addEventListener):
+ * dom/MessagePort.h:
+ * dom/Node.cpp:
+ (WebCore::tryAddEventListener):
+ (WebCore::Node::addEventListener):
+ (WebCore::tryRemoveEventListener):
+ (WebCore::Node::removeEventListener):
+ * dom/Node.h:
+ * dom/RegisteredEventListener.h:
+ (WebCore::RegisteredEventListener::Options::Options):
+ (WebCore::RegisteredEventListener::RegisteredEventListener):
+ (WebCore::operator==):
+ * html/HTMLMediaElement.cpp:
+ (WebCore::HTMLMediaElement::addEventListener):
+ (WebCore::HTMLMediaElement::removeEventListener):
+ * html/HTMLMediaElement.h:
+ * page/DOMWindow.cpp:
+ (WebCore::DOMWindow::addEventListener):
+ (WebCore::DOMWindow::removeEventListener):
+ * page/DOMWindow.h:
+ * svg/SVGElement.cpp:
+ (WebCore::SVGElement::addEventListener):
+ (WebCore::SVGElement::removeEventListener):
+ * svg/SVGElement.h:
+
2016-06-06 Jer Noble <[email protected]>
Media elements should only be allowed to control controls manager during a user gesture.
Modified: trunk/Source/WebCore/Modules/webaudio/AudioScheduledSourceNode.cpp (201729 => 201730)
--- trunk/Source/WebCore/Modules/webaudio/AudioScheduledSourceNode.cpp 2016-06-06 21:47:05 UTC (rev 201729)
+++ trunk/Source/WebCore/Modules/webaudio/AudioScheduledSourceNode.cpp 2016-06-06 22:28:25 UTC (rev 201730)
@@ -201,17 +201,17 @@
}
}
-bool AudioScheduledSourceNode::addEventListener(const AtomicString& eventType, Ref<EventListener>&& listener, bool useCapture)
+bool AudioScheduledSourceNode::addEventListener(const AtomicString& eventType, Ref<EventListener>&& listener, const AddEventListenerOptions& options)
{
- bool success = AudioNode::addEventListener(eventType, WTFMove(listener), useCapture);
+ bool success = AudioNode::addEventListener(eventType, WTFMove(listener), options);
if (success && eventType == eventNames().endedEvent)
m_hasEndedListener = hasEventListeners(eventNames().endedEvent);
return success;
}
-bool AudioScheduledSourceNode::removeEventListener(const AtomicString& eventType, EventListener& listener, bool useCapture)
+bool AudioScheduledSourceNode::removeEventListener(const AtomicString& eventType, EventListener& listener, const ListenerOptions& options)
{
- bool success = AudioNode::removeEventListener(eventType, listener, useCapture);
+ bool success = AudioNode::removeEventListener(eventType, listener, options);
if (success && eventType == eventNames().endedEvent)
m_hasEndedListener = hasEventListeners(eventNames().endedEvent);
return success;
Modified: trunk/Source/WebCore/Modules/webaudio/AudioScheduledSourceNode.h (201729 => 201730)
--- trunk/Source/WebCore/Modules/webaudio/AudioScheduledSourceNode.h 2016-06-06 21:47:05 UTC (rev 201729)
+++ trunk/Source/WebCore/Modules/webaudio/AudioScheduledSourceNode.h 2016-06-06 22:28:25 UTC (rev 201730)
@@ -101,8 +101,8 @@
static const double UnknownTime;
private:
- bool addEventListener(const AtomicString& eventType, Ref<EventListener>&&, bool useCapture) override;
- bool removeEventListener(const AtomicString& eventType, EventListener&, bool useCapture) override;
+ bool addEventListener(const AtomicString& eventType, Ref<EventListener>&&, const AddEventListenerOptions&) override;
+ bool removeEventListener(const AtomicString& eventType, EventListener&, const ListenerOptions&) override;
void removeAllEventListeners() override;
};
Modified: trunk/Source/WebCore/Modules/webaudio/ScriptProcessorNode.cpp (201729 => 201730)
--- trunk/Source/WebCore/Modules/webaudio/ScriptProcessorNode.cpp 2016-06-06 21:47:05 UTC (rev 201729)
+++ trunk/Source/WebCore/Modules/webaudio/ScriptProcessorNode.cpp 2016-06-06 22:28:25 UTC (rev 201730)
@@ -273,17 +273,17 @@
return std::numeric_limits<double>::infinity();
}
-bool ScriptProcessorNode::addEventListener(const AtomicString& eventType, Ref<EventListener>&& listener, bool useCapture)
+bool ScriptProcessorNode::addEventListener(const AtomicString& eventType, Ref<EventListener>&& listener, const AddEventListenerOptions& options)
{
- bool success = AudioNode::addEventListener(eventType, WTFMove(listener), useCapture);
+ bool success = AudioNode::addEventListener(eventType, WTFMove(listener), options);
if (success && eventType == eventNames().audioprocessEvent)
m_hasAudioProcessListener = hasEventListeners(eventNames().audioprocessEvent);
return success;
}
-bool ScriptProcessorNode::removeEventListener(const AtomicString& eventType, EventListener& listener, bool useCapture)
+bool ScriptProcessorNode::removeEventListener(const AtomicString& eventType, EventListener& listener, const ListenerOptions& options)
{
- bool success = AudioNode::removeEventListener(eventType, listener, useCapture);
+ bool success = AudioNode::removeEventListener(eventType, listener, options);
if (success && eventType == eventNames().audioprocessEvent)
m_hasAudioProcessListener = hasEventListeners(eventNames().audioprocessEvent);
return success;
Modified: trunk/Source/WebCore/Modules/webaudio/ScriptProcessorNode.h (201729 => 201730)
--- trunk/Source/WebCore/Modules/webaudio/ScriptProcessorNode.h 2016-06-06 21:47:05 UTC (rev 201729)
+++ trunk/Source/WebCore/Modules/webaudio/ScriptProcessorNode.h 2016-06-06 22:28:25 UTC (rev 201730)
@@ -73,8 +73,8 @@
void fireProcessEvent();
- bool addEventListener(const AtomicString& eventType, Ref<EventListener>&&, bool useCapture) override;
- bool removeEventListener(const AtomicString& eventType, EventListener&, bool useCapture) override;
+ bool addEventListener(const AtomicString& eventType, Ref<EventListener>&&, const AddEventListenerOptions&) override;
+ bool removeEventListener(const AtomicString& eventType, EventListener&, const ListenerOptions&) override;
void removeAllEventListeners() override;
// Double buffering
Modified: trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm (201729 => 201730)
--- trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm 2016-06-06 21:47:05 UTC (rev 201729)
+++ trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm 2016-06-06 22:28:25 UTC (rev 201730)
@@ -1678,7 +1678,10 @@
push(@andExpression, "(${value}.isNull() || ${value}.isObject())");
}
$usedArguments{$parameterIndex} = 1;
- } elsif ($codeGenerator->GetArrayOrSequenceType($type) || $codeGenerator->IsTypedArrayType($type) || $codeGenerator->IsWrapperType($type)) {
+ } elsif ($codeGenerator->IsDictionaryType($parameter->type)) {
+ push(@andExpression, "(${value}.isUndefinedOrNull() || ${value}.isObject())");
+ $usedArguments{$parameterIndex} = 1;
+ } elsif (($codeGenerator->GetArrayOrSequenceType($type) || $codeGenerator->IsTypedArrayType($type) || $codeGenerator->IsWrapperType($type)) && $type ne "EventListener") {
my $condition = "";
if ($parameter->isNullable) {
Modified: trunk/Source/WebCore/dom/Event.h (201729 => 201730)
--- trunk/Source/WebCore/dom/Event.h 2016-06-06 21:47:05 UTC (rev 201729)
+++ trunk/Source/WebCore/dom/Event.h 2016-06-06 22:28:25 UTC (rev 201730)
@@ -172,7 +172,7 @@
bool defaultPrevented() const { return m_defaultPrevented; }
void preventDefault()
{
- if (m_cancelable)
+ if (m_cancelable && !m_isExecutingPassiveEventListener)
m_defaultPrevented = true;
}
void setDefaultPrevented(bool defaultPrevented) { m_defaultPrevented = defaultPrevented; }
@@ -180,6 +180,8 @@
bool defaultHandled() const { return m_defaultHandled; }
void setDefaultHandled() { m_defaultHandled = true; }
+ void setInPassiveListener(bool value) { m_isExecutingPassiveEventListener = value; }
+
bool cancelBubble() const { return m_cancelBubble; }
void setCancelBubble(bool cancel) { m_cancelBubble = cancel; }
@@ -217,6 +219,7 @@
bool m_defaultHandled { false };
bool m_cancelBubble { false };
bool m_isTrusted { false };
+ bool m_isExecutingPassiveEventListener { false };
unsigned short m_eventPhase { 0 };
EventTarget* m_currentTarget { nullptr };
Modified: trunk/Source/WebCore/dom/EventListenerMap.cpp (201729 => 201730)
--- trunk/Source/WebCore/dom/EventListenerMap.cpp 2016-06-06 21:47:05 UTC (rev 201729)
+++ trunk/Source/WebCore/dom/EventListenerMap.cpp 2016-06-06 22:28:25 UTC (rev 201730)
@@ -95,9 +95,9 @@
return types;
}
-static bool addListenerToVector(EventListenerVector* vector, Ref<EventListener>&& listener, bool useCapture)
+static bool addListenerToVector(EventListenerVector* vector, Ref<EventListener>&& listener, const RegisteredEventListener::Options& options)
{
- RegisteredEventListener registeredListener(WTFMove(listener), useCapture);
+ RegisteredEventListener registeredListener(WTFMove(listener), options);
if (vector->find(registeredListener) != notFound)
return false; // Duplicate listener.
@@ -106,17 +106,17 @@
return true;
}
-bool EventListenerMap::add(const AtomicString& eventType, Ref<EventListener>&& listener, bool useCapture)
+bool EventListenerMap::add(const AtomicString& eventType, Ref<EventListener>&& listener, const RegisteredEventListener::Options& options)
{
assertNoActiveIterators();
for (auto& entry : m_entries) {
if (entry.first == eventType)
- return addListenerToVector(entry.second.get(), WTFMove(listener), useCapture);
+ return addListenerToVector(entry.second.get(), WTFMove(listener), options);
}
m_entries.append(std::make_pair(eventType, std::make_unique<EventListenerVector>()));
- return addListenerToVector(m_entries.last().second.get(), WTFMove(listener), useCapture);
+ return addListenerToVector(m_entries.last().second.get(), WTFMove(listener), options);
}
static bool removeListenerFromVector(EventListenerVector* listenerVector, EventListener& listener, bool useCapture, size_t& indexOfRemovedListener)
Modified: trunk/Source/WebCore/dom/EventListenerMap.h (201729 => 201730)
--- trunk/Source/WebCore/dom/EventListenerMap.h 2016-06-06 21:47:05 UTC (rev 201729)
+++ trunk/Source/WebCore/dom/EventListenerMap.h 2016-06-06 22:28:25 UTC (rev 201730)
@@ -54,7 +54,8 @@
bool containsCapturing(const AtomicString& eventType) const;
void clear();
- bool add(const AtomicString& eventType, Ref<EventListener>&&, bool useCapture);
+
+ bool add(const AtomicString& eventType, Ref<EventListener>&&, const RegisteredEventListener::Options&);
bool remove(const AtomicString& eventType, EventListener&, bool useCapture, size_t& indexOfRemovedListener);
EventListenerVector* find(const AtomicString& eventType);
Vector<AtomicString> eventTypes() const;
Modified: trunk/Source/WebCore/dom/EventTarget.cpp (201729 => 201730)
--- trunk/Source/WebCore/dom/EventTarget.cpp 2016-06-06 21:47:05 UTC (rev 201729)
+++ trunk/Source/WebCore/dom/EventTarget.cpp 2016-06-06 22:28:25 UTC (rev 201730)
@@ -75,28 +75,26 @@
return false;
}
-bool EventTarget::addEventListener(const AtomicString& eventType, Ref<EventListener>&& listener, bool useCapture)
+bool EventTarget::addEventListener(const AtomicString& eventType, Ref<EventListener>&& listener, const AddEventListenerOptions& options)
{
- return ensureEventTargetData().eventListenerMap.add(eventType, WTFMove(listener), useCapture);
+ return ensureEventTargetData().eventListenerMap.add(eventType, WTFMove(listener), { options.capture, options.passive, options.once });
}
-void EventTarget::addEventListenerForBindings(const AtomicString& eventType, RefPtr<EventListener>&& listener, bool useCapture)
+void EventTarget::addEventListenerForBindings(const AtomicString& eventType, RefPtr<EventListener>&& listener, const AddEventListenerOptions& options)
{
- // FIXME: listener is not supposed to be nullable.
if (!listener)
return;
- addEventListener(eventType, listener.releaseNonNull(), useCapture);
+ addEventListener(eventType, listener.releaseNonNull(), options);
}
-void EventTarget::removeEventListenerForBindings(const AtomicString& eventType, RefPtr<EventListener>&& listener, bool useCapture)
+void EventTarget::removeEventListenerForBindings(const AtomicString& eventType, RefPtr<EventListener>&& listener, const ListenerOptions& options)
{
- // FIXME: listener is not supposed to be nullable.
if (!listener)
return;
- removeEventListener(eventType, *listener, useCapture);
+ removeEventListener(eventType, *listener, options);
}
-bool EventTarget::removeEventListener(const AtomicString& eventType, EventListener& listener, bool useCapture)
+bool EventTarget::removeEventListener(const AtomicString& eventType, EventListener& listener, const ListenerOptions& options)
{
EventTargetData* d = eventTargetData();
if (!d)
@@ -104,7 +102,7 @@
size_t indexOfRemovedListener;
- if (!d->eventListenerMap.remove(eventType, listener, useCapture, indexOfRemovedListener))
+ if (!d->eventListenerMap.remove(eventType, listener, options.capture, indexOfRemovedListener))
return false;
// Notify firing events planning to invoke the listener at 'index' that
@@ -131,7 +129,7 @@
clearAttributeEventListener(eventType);
if (!listener)
return false;
- return addEventListener(eventType, listener.releaseNonNull(), false);
+ return addEventListener(eventType, listener.releaseNonNull());
}
EventListener* EventTarget::getAttributeEventListener(const AtomicString& eventType)
@@ -260,6 +258,10 @@
for (; i < size; ++i) {
RegisteredEventListener& registeredListener = entry[i];
+
+ if (registeredListener.isMarkedForRemoval)
+ continue;
+
if (event.eventPhase() == Event::CAPTURING_PHASE && !registeredListener.useCapture)
continue;
if (event.eventPhase() == Event::BUBBLING_PHASE && registeredListener.useCapture)
@@ -270,12 +272,27 @@
if (event.immediatePropagationStopped())
break;
+ if (registeredListener.isPassive)
+ event.setInPassiveListener(true);
+
+ // Mark listener for removal before executing the listener, in case the listener tries to
+ // dispatch an event that would cause it to get executed again.
+ if (registeredListener.isOnce)
+ registeredListener.isMarkedForRemoval = true;
+
InspectorInstrumentationCookie cookie = InspectorInstrumentation::willHandleEvent(context, event);
// To match Mozilla, the AT_TARGET phase fires both capturing and bubbling
// event listeners, even though that violates some versions of the DOM spec.
registeredListener.listener->handleEvent(context, &event);
InspectorInstrumentation::didHandleEvent(cookie);
+
+ if (registeredListener.isPassive)
+ event.setInPassiveListener(false);
+
+ if (registeredListener.isOnce)
+ removeEventListener(event.type(), *registeredListener.listener, ListenerOptions(registeredListener.useCapture));
}
+
d->firingEventIterators->removeLast();
if (document)
Modified: trunk/Source/WebCore/dom/EventTarget.h (201729 => 201730)
--- trunk/Source/WebCore/dom/EventTarget.h 2016-06-06 21:47:05 UTC (rev 201729)
+++ trunk/Source/WebCore/dom/EventTarget.h 2016-06-06 22:28:25 UTC (rev 201730)
@@ -121,10 +121,31 @@
virtual DOMWindow* toDOMWindow();
virtual bool isMessagePort() const;
+ struct ListenerOptions {
+ ListenerOptions(bool capture = false)
+ : capture(capture)
+ { }
+
+ bool capture;
+ };
+
+ struct AddEventListenerOptions : public ListenerOptions {
+ AddEventListenerOptions(bool capture = false, bool passive = false, bool _once_ = false)
+ : ListenerOptions(capture)
+ , passive(passive)
+ , once(once)
+ { }
+
+ bool passive;
+ bool once;
+ };
+
void addEventListenerForBindings(const AtomicString& eventType, RefPtr<EventListener>&&, bool useCapture);
void removeEventListenerForBindings(const AtomicString& eventType, RefPtr<EventListener>&&, bool useCapture);
- virtual bool addEventListener(const AtomicString& eventType, Ref<EventListener>&&, bool useCapture);
- virtual bool removeEventListener(const AtomicString& eventType, EventListener&, bool useCapture);
+ void addEventListenerForBindings(const AtomicString& eventType, RefPtr<EventListener>&&, const AddEventListenerOptions&);
+ void removeEventListenerForBindings(const AtomicString& eventType, RefPtr<EventListener>&&, const ListenerOptions&);
+ virtual bool addEventListener(const AtomicString& eventType, Ref<EventListener>&&, const AddEventListenerOptions& = { });
+ virtual bool removeEventListener(const AtomicString& eventType, EventListener&, const ListenerOptions&);
virtual void removeAllEventListeners();
virtual bool dispatchEvent(Event&);
@@ -209,6 +230,16 @@
return d->eventListenerMap.containsCapturing(eventType);
}
+inline void EventTarget::addEventListenerForBindings(const AtomicString& eventType, RefPtr<EventListener>&& listener, bool useCapture)
+{
+ addEventListenerForBindings(eventType, WTFMove(listener), AddEventListenerOptions(useCapture));
+}
+
+inline void EventTarget::removeEventListenerForBindings(const AtomicString& eventType, RefPtr<EventListener>&& listener, bool useCapture)
+{
+ removeEventListenerForBindings(eventType, WTFMove(listener), ListenerOptions(useCapture));
+}
+
} // namespace WebCore
#endif // EventTarget_h
Modified: trunk/Source/WebCore/dom/EventTarget.idl (201729 => 201730)
--- trunk/Source/WebCore/dom/EventTarget.idl 2016-06-06 21:47:05 UTC (rev 201729)
+++ trunk/Source/WebCore/dom/EventTarget.idl 2016-06-06 22:28:25 UTC (rev 201730)
@@ -25,6 +25,11 @@
JSCustomToNativeObject,
ObjCProtocol,
] interface EventTarget {
+#if defined(LANGUAGE_JAVASCRIPT) && LANGUAGE_JAVASCRIPT
+ [ImplementedAs=addEventListenerForBindings] void addEventListener([AtomicString] DOMString type, EventListener? listener, optional AddEventListenerOptions options);
+ [ImplementedAs=removeEventListenerForBindings] void removeEventListener([AtomicString] DOMString type, EventListener? listener, optional EventListenerOptions options);
+#endif
+
// FIXME: The 'type' and 'listener' parameters should not be optional.
[ObjCLegacyUnnamedParameters, ImplementedAs=addEventListenerForBindings] void addEventListener([AtomicString] optional DOMString type = "undefined", optional EventListener? listener, optional boolean useCapture = false);
[ObjCLegacyUnnamedParameters, ImplementedAs=removeEventListenerForBindings] void removeEventListener([AtomicString] optional DOMString type = "undefined", optional EventListener? listener, optional boolean useCapture = false);
@@ -32,3 +37,13 @@
// FIXME: event should not be nullable.
[ImplementedAs=dispatchEventForBindings, RaisesException] boolean dispatchEvent(Event? event);
};
+
+dictionary EventListenerOptions {
+ boolean capture = false;
+};
+
+dictionary AddEventListenerOptions {
+ boolean capture = false;
+ boolean passive = false;
+ boolean _once_ = false;
+};
Modified: trunk/Source/WebCore/dom/MessagePort.cpp (201729 => 201730)
--- trunk/Source/WebCore/dom/MessagePort.cpp 2016-06-06 21:47:05 UTC (rev 201729)
+++ trunk/Source/WebCore/dom/MessagePort.cpp 2016-06-06 22:28:25 UTC (rev 201730)
@@ -221,11 +221,11 @@
return portArray;
}
-bool MessagePort::addEventListener(const AtomicString& eventType, Ref<EventListener>&& listener, bool useCapture)
+bool MessagePort::addEventListener(const AtomicString& eventType, Ref<EventListener>&& listener, const AddEventListenerOptions& options)
{
if (listener->isAttribute() && eventType == eventNames().messageEvent)
start();
- return EventTargetWithInlineData::addEventListener(eventType, WTFMove(listener), useCapture);
+ return EventTargetWithInlineData::addEventListener(eventType, WTFMove(listener), options);
}
} // namespace WebCore
Modified: trunk/Source/WebCore/dom/MessagePort.h (201729 => 201730)
--- trunk/Source/WebCore/dom/MessagePort.h 2016-06-06 21:47:05 UTC (rev 201729)
+++ trunk/Source/WebCore/dom/MessagePort.h 2016-06-06 22:28:25 UTC (rev 201730)
@@ -92,7 +92,7 @@
// A port gets neutered when it is transferred to a new owner via postMessage().
bool isNeutered() { return !m_entangledChannel; }
- bool addEventListener(const AtomicString& eventType, Ref<EventListener>&&, bool useCapture) override;
+ bool addEventListener(const AtomicString& eventType, Ref<EventListener>&&, const AddEventListenerOptions&) override;
private:
explicit MessagePort(ScriptExecutionContext&);
Modified: trunk/Source/WebCore/dom/Node.cpp (201729 => 201730)
--- trunk/Source/WebCore/dom/Node.cpp 2016-06-06 21:47:05 UTC (rev 201729)
+++ trunk/Source/WebCore/dom/Node.cpp 2016-06-06 22:28:25 UTC (rev 201730)
@@ -1907,9 +1907,9 @@
}
}
-static inline bool tryAddEventListener(Node* targetNode, const AtomicString& eventType, Ref<EventListener>&& listener, bool useCapture)
+static inline bool tryAddEventListener(Node* targetNode, const AtomicString& eventType, Ref<EventListener>&& listener, const EventTarget::AddEventListenerOptions& options)
{
- if (!targetNode->EventTarget::addEventListener(eventType, listener.copyRef(), useCapture))
+ if (!targetNode->EventTarget::addEventListener(eventType, listener.copyRef(), options))
return false;
targetNode->document().addListenerTypeIfNeeded(eventType);
@@ -1927,7 +1927,7 @@
// This code was added to address <rdar://problem/5846492> Onorientationchange event not working for document.body.
// Forward this call to addEventListener() to the window since these are window-only events.
if (eventType == eventNames().orientationchangeEvent || eventType == eventNames().resizeEvent)
- targetNode->document().domWindow()->addEventListener(eventType, WTFMove(listener), useCapture);
+ targetNode->document().domWindow()->addEventListener(eventType, WTFMove(listener), options);
#if ENABLE(TOUCH_EVENTS)
if (eventNames().isTouchEventType(eventType))
@@ -1943,14 +1943,14 @@
return true;
}
-bool Node::addEventListener(const AtomicString& eventType, Ref<EventListener>&& listener, bool useCapture)
+bool Node::addEventListener(const AtomicString& eventType, Ref<EventListener>&& listener, const AddEventListenerOptions& options)
{
- return tryAddEventListener(this, eventType, WTFMove(listener), useCapture);
+ return tryAddEventListener(this, eventType, WTFMove(listener), options);
}
-static inline bool tryRemoveEventListener(Node* targetNode, const AtomicString& eventType, EventListener& listener, bool useCapture)
+static inline bool tryRemoveEventListener(Node* targetNode, const AtomicString& eventType, EventListener& listener, const EventTarget::ListenerOptions& options)
{
- if (!targetNode->EventTarget::removeEventListener(eventType, listener, useCapture))
+ if (!targetNode->EventTarget::removeEventListener(eventType, listener, options))
return false;
// FIXME: Notify Document that the listener has vanished. We need to keep track of a number of
@@ -1968,7 +1968,7 @@
// This code was added to address <rdar://problem/5846492> Onorientationchange event not working for document.body.
// Forward this call to removeEventListener() to the window since these are window-only events.
if (eventType == eventNames().orientationchangeEvent || eventType == eventNames().resizeEvent)
- targetNode->document().domWindow()->removeEventListener(eventType, listener, useCapture);
+ targetNode->document().domWindow()->removeEventListener(eventType, listener, options);
#if ENABLE(TOUCH_EVENTS)
if (eventNames().isTouchEventType(eventType))
@@ -1984,9 +1984,9 @@
return true;
}
-bool Node::removeEventListener(const AtomicString& eventType, EventListener& listener, bool useCapture)
+bool Node::removeEventListener(const AtomicString& eventType, EventListener& listener, const ListenerOptions& options)
{
- return tryRemoveEventListener(this, eventType, listener, useCapture);
+ return tryRemoveEventListener(this, eventType, listener, options);
}
typedef HashMap<Node*, std::unique_ptr<EventTargetData>> EventTargetDataMap;
Modified: trunk/Source/WebCore/dom/Node.h (201729 => 201730)
--- trunk/Source/WebCore/dom/Node.h 2016-06-06 21:47:05 UTC (rev 201729)
+++ trunk/Source/WebCore/dom/Node.h 2016-06-06 22:28:25 UTC (rev 201730)
@@ -507,8 +507,8 @@
EventTargetInterface eventTargetInterface() const override;
ScriptExecutionContext* scriptExecutionContext() const final; // Implemented in Document.h
- bool addEventListener(const AtomicString& eventType, Ref<EventListener>&&, bool useCapture) override;
- bool removeEventListener(const AtomicString& eventType, EventListener&, bool useCapture) override;
+ bool addEventListener(const AtomicString& eventType, Ref<EventListener>&&, const AddEventListenerOptions&) override;
+ bool removeEventListener(const AtomicString& eventType, EventListener&, const ListenerOptions&) override;
using EventTarget::dispatchEvent;
bool dispatchEvent(Event&) override;
Modified: trunk/Source/WebCore/dom/RegisteredEventListener.h (201729 => 201730)
--- trunk/Source/WebCore/dom/RegisteredEventListener.h 2016-06-06 21:47:05 UTC (rev 201729)
+++ trunk/Source/WebCore/dom/RegisteredEventListener.h 2016-06-06 22:28:25 UTC (rev 201730)
@@ -31,6 +31,26 @@
class RegisteredEventListener {
public:
+ struct Options {
+ Options(bool capture = false, bool passive = false, bool _once_ = false)
+ : capture(capture)
+ , passive(passive)
+ , once(once)
+ { }
+
+ bool capture;
+ bool passive;
+ bool once;
+ };
+
+ RegisteredEventListener(Ref<EventListener>&& listener, const Options& options)
+ : listener(WTFMove(listener))
+ , useCapture(options.capture)
+ , isPassive(options.passive)
+ , isOnce(options.once)
+ {
+ }
+
RegisteredEventListener(Ref<EventListener>&& listener, bool useCapture)
: listener(WTFMove(listener))
, useCapture(useCapture)
@@ -38,11 +58,16 @@
}
RefPtr<EventListener> listener;
- bool useCapture;
+ bool useCapture { false };
+ bool isPassive { false };
+ bool isOnce { false };
+ bool isMarkedForRemoval { false };
};
inline bool operator==(const RegisteredEventListener& a, const RegisteredEventListener& b)
{
+ // Other data members are purposefully not checked. The DOM specification says that upon adding / removing
+ // EventListeners, we should only check the type and the capture flag.
return *a.listener == *b.listener && a.useCapture == b.useCapture;
}
Modified: trunk/Source/WebCore/html/HTMLMediaElement.cpp (201729 => 201730)
--- trunk/Source/WebCore/html/HTMLMediaElement.cpp 2016-06-06 21:47:05 UTC (rev 201729)
+++ trunk/Source/WebCore/html/HTMLMediaElement.cpp 2016-06-06 22:28:25 UTC (rev 201730)
@@ -5228,13 +5228,13 @@
return HTMLElement::dispatchEvent(event);
}
-bool HTMLMediaElement::addEventListener(const AtomicString& eventType, Ref<EventListener>&& listener, bool useCapture)
+bool HTMLMediaElement::addEventListener(const AtomicString& eventType, Ref<EventListener>&& listener, const AddEventListenerOptions& options)
{
if (eventType != eventNames().webkitplaybacktargetavailabilitychangedEvent)
- return Node::addEventListener(eventType, WTFMove(listener), useCapture);
+ return Node::addEventListener(eventType, WTFMove(listener), options);
bool isFirstAvailabilityChangedListener = !hasEventListeners(eventNames().webkitplaybacktargetavailabilitychangedEvent);
- if (!Node::addEventListener(eventType, WTFMove(listener), useCapture))
+ if (!Node::addEventListener(eventType, WTFMove(listener), options))
return false;
if (isFirstAvailabilityChangedListener) {
@@ -5248,12 +5248,12 @@
return true;
}
-bool HTMLMediaElement::removeEventListener(const AtomicString& eventType, EventListener& listener, bool useCapture)
+bool HTMLMediaElement::removeEventListener(const AtomicString& eventType, EventListener& listener, const ListenerOptions& options)
{
if (eventType != eventNames().webkitplaybacktargetavailabilitychangedEvent)
- return Node::removeEventListener(eventType, listener, useCapture);
+ return Node::removeEventListener(eventType, listener, options);
- if (!Node::removeEventListener(eventType, listener, useCapture))
+ if (!Node::removeEventListener(eventType, listener, options))
return false;
bool didRemoveLastAvailabilityChangedListener = !hasEventListeners(eventNames().webkitplaybacktargetavailabilitychangedEvent);
Modified: trunk/Source/WebCore/html/HTMLMediaElement.h (201729 => 201730)
--- trunk/Source/WebCore/html/HTMLMediaElement.h 2016-06-06 21:47:05 UTC (rev 201729)
+++ trunk/Source/WebCore/html/HTMLMediaElement.h 2016-06-06 22:28:25 UTC (rev 201730)
@@ -342,8 +342,8 @@
#if ENABLE(WIRELESS_PLAYBACK_TARGET)
void webkitShowPlaybackTargetPicker();
- bool addEventListener(const AtomicString& eventType, Ref<EventListener>&&, bool useCapture) override;
- bool removeEventListener(const AtomicString& eventType, EventListener&, bool useCapture) override;
+ bool addEventListener(const AtomicString& eventType, Ref<EventListener>&&, const AddEventListenerOptions&) override;
+ bool removeEventListener(const AtomicString& eventType, EventListener&, const ListenerOptions&) override;
void wirelessRoutesAvailableDidChange() override;
bool canPlayToWirelessPlaybackTarget() const override;
Modified: trunk/Source/WebCore/page/DOMWindow.cpp (201729 => 201730)
--- trunk/Source/WebCore/page/DOMWindow.cpp 2016-06-06 21:47:05 UTC (rev 201729)
+++ trunk/Source/WebCore/page/DOMWindow.cpp 2016-06-06 22:28:25 UTC (rev 201730)
@@ -1722,9 +1722,9 @@
return false;
}
-bool DOMWindow::addEventListener(const AtomicString& eventType, Ref<EventListener>&& listener, bool useCapture)
+bool DOMWindow::addEventListener(const AtomicString& eventType, Ref<EventListener>&& listener, const AddEventListenerOptions& options)
{
- if (!EventTarget::addEventListener(eventType, WTFMove(listener), useCapture))
+ if (!EventTarget::addEventListener(eventType, WTFMove(listener), options))
return false;
if (Document* document = this->document()) {
@@ -1825,9 +1825,9 @@
#endif
}
-bool DOMWindow::removeEventListener(const AtomicString& eventType, EventListener& listener, bool useCapture)
+bool DOMWindow::removeEventListener(const AtomicString& eventType, EventListener& listener, const ListenerOptions& options)
{
- if (!EventTarget::removeEventListener(eventType, listener, useCapture))
+ if (!EventTarget::removeEventListener(eventType, listener, options.capture))
return false;
if (Document* document = this->document()) {
Modified: trunk/Source/WebCore/page/DOMWindow.h (201729 => 201730)
--- trunk/Source/WebCore/page/DOMWindow.h 2016-06-06 21:47:05 UTC (rev 201729)
+++ trunk/Source/WebCore/page/DOMWindow.h 2016-06-06 22:28:25 UTC (rev 201730)
@@ -279,8 +279,8 @@
// Events
// EventTarget API
- bool addEventListener(const AtomicString& eventType, Ref<EventListener>&&, bool useCapture) override;
- bool removeEventListener(const AtomicString& eventType, EventListener&, bool useCapture) override;
+ bool addEventListener(const AtomicString& eventType, Ref<EventListener>&&, const AddEventListenerOptions&) override;
+ bool removeEventListener(const AtomicString& eventType, EventListener&, const ListenerOptions&) override;
void removeAllEventListeners() override;
using EventTarget::dispatchEvent;
Modified: trunk/Source/WebCore/svg/SVGElement.cpp (201729 => 201730)
--- trunk/Source/WebCore/svg/SVGElement.cpp 2016-06-06 21:47:05 UTC (rev 201729)
+++ trunk/Source/WebCore/svg/SVGElement.cpp 2016-06-06 22:28:25 UTC (rev 201730)
@@ -528,10 +528,10 @@
return true;
}
-bool SVGElement::addEventListener(const AtomicString& eventType, Ref<EventListener>&& listener, bool useCapture)
+bool SVGElement::addEventListener(const AtomicString& eventType, Ref<EventListener>&& listener, const AddEventListenerOptions& options)
{
// Add event listener to regular DOM element
- if (!Node::addEventListener(eventType, listener.copyRef(), useCapture))
+ if (!Node::addEventListener(eventType, listener.copyRef(), options))
return false;
if (containingShadowRoot())
@@ -541,17 +541,17 @@
ASSERT(!instanceUpdatesBlocked());
for (auto* instance : instances()) {
ASSERT(instance->correspondingElement() == this);
- bool result = instance->Node::addEventListener(eventType, listener.copyRef(), useCapture);
+ bool result = instance->Node::addEventListener(eventType, listener.copyRef(), options);
ASSERT_UNUSED(result, result);
}
return true;
}
-bool SVGElement::removeEventListener(const AtomicString& eventType, EventListener& listener, bool useCapture)
+bool SVGElement::removeEventListener(const AtomicString& eventType, EventListener& listener, const ListenerOptions& options)
{
if (containingShadowRoot())
- return Node::removeEventListener(eventType, listener, useCapture);
+ return Node::removeEventListener(eventType, listener, options);
// EventTarget::removeEventListener creates a PassRefPtr around the given EventListener
// object when creating a temporary RegisteredEventListener object used to look up the
@@ -561,7 +561,7 @@
Ref<EventListener> protector(listener);
// Remove event listener from regular DOM element
- if (!Node::removeEventListener(eventType, listener, useCapture))
+ if (!Node::removeEventListener(eventType, listener, options))
return false;
// Remove event listener from all shadow tree DOM element instances
@@ -569,7 +569,7 @@
for (auto& instance : instances()) {
ASSERT(instance->correspondingElement() == this);
- if (instance->Node::removeEventListener(eventType, listener, useCapture))
+ if (instance->Node::removeEventListener(eventType, listener, options))
continue;
// This case can only be hit for event listeners created from markup
Modified: trunk/Source/WebCore/svg/SVGElement.h (201729 => 201730)
--- trunk/Source/WebCore/svg/SVGElement.h 2016-06-06 21:47:05 UTC (rev 201729)
+++ trunk/Source/WebCore/svg/SVGElement.h 2016-06-06 22:28:25 UTC (rev 201730)
@@ -133,8 +133,8 @@
virtual bool haveLoadedRequiredResources();
- bool addEventListener(const AtomicString& eventType, Ref<EventListener>&&, bool useCapture) override;
- bool removeEventListener(const AtomicString& eventType, EventListener&, bool useCapture) override;
+ bool addEventListener(const AtomicString& eventType, Ref<EventListener>&&, const AddEventListenerOptions&) override;
+ bool removeEventListener(const AtomicString& eventType, EventListener&, const ListenerOptions&) override;
bool hasFocusEventListeners() const;
#if ENABLE(CSS_REGIONS)