Title: [230664] trunk
Revision
230664
Author
cdu...@apple.com
Date
2018-04-15 18:01:18 -0700 (Sun, 15 Apr 2018)

Log Message

Change Event's returnValue so it doesn't expose a new primitive
https://bugs.webkit.org/show_bug.cgi?id=184415

Reviewed by Darin Adler.

LayoutTests/imported/w3c:

Import test coverage from https://github.com/w3c/web-platform-tests/pull/10258.

* web-platform-tests/dom/events/AddEventListenerOptions-passive-expected.txt:
* web-platform-tests/dom/events/AddEventListenerOptions-passive.html:
* web-platform-tests/dom/events/Event-constructors.html:
* web-platform-tests/dom/events/Event-defaultPrevented-after-dispatch-expected.txt:
* web-platform-tests/dom/events/Event-defaultPrevented-after-dispatch.html:
* web-platform-tests/dom/events/Event-defaultPrevented-expected.txt:
* web-platform-tests/dom/events/Event-defaultPrevented.html:
* web-platform-tests/dom/events/Event-dispatch-click.html:
* web-platform-tests/dom/events/Event-dispatch-detached-click.html:
* web-platform-tests/dom/events/Event-dispatch-other-document.html:
* web-platform-tests/dom/events/Event-initEvent.html:
* web-platform-tests/dom/events/Event-returnValue-expected.txt: Added.
* web-platform-tests/dom/events/Event-returnValue.html: Added.
* web-platform-tests/dom/events/EventListener-handleEvent.html:
* web-platform-tests/dom/events/EventTarget-dispatchEvent-returnvalue-expected.txt:
* web-platform-tests/dom/events/EventTarget-dispatchEvent-returnvalue.html:
* web-platform-tests/dom/events/w3c-import.log:
* web-platform-tests/dom/interfaces-expected.txt:
* web-platform-tests/interfaces/dom.idl:

Source/WebCore:

Update Event.returnValue setter to match the latest DOM specification after:
- https://github.com/whatwg/dom/pull/626

In particular, the returnValue setter is now a no-op if the new flag value
is true. If the input flag value is false, it only sets the 'canceled' flag
if the event is cancelable and the event’s in passive listener flag is unset.

Test: imported/w3c/web-platform-tests/dom/events/Event-returnValue.html

* dom/Event.cpp:
(WebCore::Event::setLegacyReturnValue):
(WebCore::Event::setCanceledFlagIfPossible):
(WebCore::Event::preventDefault):
* dom/Event.h:

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/imported/w3c/ChangeLog (230663 => 230664)


--- trunk/LayoutTests/imported/w3c/ChangeLog	2018-04-15 21:21:51 UTC (rev 230663)
+++ trunk/LayoutTests/imported/w3c/ChangeLog	2018-04-16 01:01:18 UTC (rev 230664)
@@ -1,3 +1,32 @@
+2018-04-15  Chris Dumez  <cdu...@apple.com>
+
+        Change Event's returnValue so it doesn't expose a new primitive
+        https://bugs.webkit.org/show_bug.cgi?id=184415
+
+        Reviewed by Darin Adler.
+
+        Import test coverage from https://github.com/w3c/web-platform-tests/pull/10258.
+
+        * web-platform-tests/dom/events/AddEventListenerOptions-passive-expected.txt:
+        * web-platform-tests/dom/events/AddEventListenerOptions-passive.html:
+        * web-platform-tests/dom/events/Event-constructors.html:
+        * web-platform-tests/dom/events/Event-defaultPrevented-after-dispatch-expected.txt:
+        * web-platform-tests/dom/events/Event-defaultPrevented-after-dispatch.html:
+        * web-platform-tests/dom/events/Event-defaultPrevented-expected.txt:
+        * web-platform-tests/dom/events/Event-defaultPrevented.html:
+        * web-platform-tests/dom/events/Event-dispatch-click.html:
+        * web-platform-tests/dom/events/Event-dispatch-detached-click.html:
+        * web-platform-tests/dom/events/Event-dispatch-other-document.html:
+        * web-platform-tests/dom/events/Event-initEvent.html:
+        * web-platform-tests/dom/events/Event-returnValue-expected.txt: Added.
+        * web-platform-tests/dom/events/Event-returnValue.html: Added.
+        * web-platform-tests/dom/events/EventListener-handleEvent.html:
+        * web-platform-tests/dom/events/EventTarget-dispatchEvent-returnvalue-expected.txt:
+        * web-platform-tests/dom/events/EventTarget-dispatchEvent-returnvalue.html:
+        * web-platform-tests/dom/events/w3c-import.log:
+        * web-platform-tests/dom/interfaces-expected.txt:
+        * web-platform-tests/interfaces/dom.idl:
+
 2018-04-12  Antoine Quint  <grao...@apple.com>
 
         [Web Animations] Turn CSS Animations and CSS Transitions as Web Animations on by default

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/IndexedDB/interfaces.any.worker-expected.txt (230663 => 230664)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/IndexedDB/interfaces.any.worker-expected.txt	2018-04-15 21:21:51 UTC (rev 230663)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/IndexedDB/interfaces.any.worker-expected.txt	2018-04-16 01:01:18 UTC (rev 230664)
@@ -20,6 +20,8 @@
 PASS CDATASection interface: existence and properties of interface object 
 PASS ProcessingInstruction interface: existence and properties of interface object 
 PASS Comment interface: existence and properties of interface object 
+PASS AbstractRange interface: existence and properties of interface object 
+PASS StaticRange interface: existence and properties of interface object 
 PASS Range interface: existence and properties of interface object 
 PASS NodeIterator interface: existence and properties of interface object 
 PASS TreeWalker interface: existence and properties of interface object 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/AddEventListenerOptions-passive-expected.txt (230663 => 230664)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/AddEventListenerOptions-passive-expected.txt	2018-04-15 21:21:51 UTC (rev 230663)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/AddEventListenerOptions-passive-expected.txt	2018-04-16 01:01:18 UTC (rev 230664)
@@ -1,6 +1,7 @@
 
 PASS Supports passive option on addEventListener only 
 PASS preventDefault should be ignored if-and-only-if the passive option is true 
-PASS passive behavior of one listener should be unaffeted by the presence of other listeners 
+PASS returnValue should be ignored if-and-only-if the passive option is true 
+PASS passive behavior of one listener should be unaffected by the presence of other listeners 
 PASS Equivalence of option values 
 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/AddEventListenerOptions-passive.html (230663 => 230664)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/AddEventListenerOptions-passive.html	2018-04-15 21:21:51 UTC (rev 230663)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/AddEventListenerOptions-passive.html	2018-04-16 01:01:18 UTC (rev 230664)
@@ -55,6 +55,32 @@
   testPassiveValue({passive: 1}, false);
 }, "preventDefault should be ignored if-and-only-if the passive option is true");
 
+function testPassiveValueOnReturnValue(test, optionsValue, expectedDefaultPrevented) {
+  var defaultPrevented = undefined;
+  var handler = test.step_func(e => {
+    assert_false(e.defaultPrevented, "Event prematurely marked defaultPrevented");
+    e.returnValue = false;
+    defaultPrevented = e.defaultPrevented;
+  });
+  document.addEventListener('test', handler, optionsValue);
+  var uncanceled = document.body.dispatchEvent(new Event('test', {bubbles: true, cancelable: true}));
+
+  assert_equals(defaultPrevented, expectedDefaultPrevented, "Incorrect defaultPrevented for options: " + JSON.stringify(optionsValue));
+  assert_equals(uncanceled, !expectedDefaultPrevented, "Incorrect return value from dispatchEvent");
+
+  document.removeEventListener('test', handler, optionsValue);
+}
+
+async_test(t => {
+  testPassiveValueOnReturnValue(t, undefined, true);
+  testPassiveValueOnReturnValue(t, {}, true);
+  testPassiveValueOnReturnValue(t, {passive: false}, true);
+  testPassiveValueOnReturnValue(t, {passive: true}, false);
+  testPassiveValueOnReturnValue(t, {passive: 0}, true);
+  testPassiveValueOnReturnValue(t, {passive: 1}, false);
+  t.done();
+}, "returnValue should be ignored if-and-only-if the passive option is true");
+
 function testPassiveWithOtherHandlers(optionsValue, expectedDefaultPrevented) {
   var handlerInvoked1 = false;
   var dummyHandler1 = function() {
@@ -81,7 +107,7 @@
   testPassiveWithOtherHandlers({}, true);
   testPassiveWithOtherHandlers({passive: false}, true);
   testPassiveWithOtherHandlers({passive: true}, false);
-}, "passive behavior of one listener should be unaffeted by the presence of other listeners");
+}, "passive behavior of one listener should be unaffected by the presence of other listeners");
 
 function testOptionEquivalence(optionValue1, optionValue2, expectedEquality) {
   var invocationCount = 0;

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-constructors.html (230663 => 230664)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-constructors.html	2018-04-15 21:21:51 UTC (rev 230663)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-constructors.html	2018-04-16 01:01:18 UTC (rev 230664)
@@ -19,11 +19,13 @@
   var ev = new Event("")
   assert_equals(ev.type, "")
   assert_equals(ev.target, null)
+  assert_equals(ev.srcElement, null)
   assert_equals(ev.currentTarget, null)
   assert_equals(ev.eventPhase, Event.NONE)
   assert_equals(ev.bubbles, false)
   assert_equals(ev.cancelable, false)
   assert_equals(ev.defaultPrevented, false)
+  assert_equals(ev.returnValue, true)
   assert_equals(ev.isTrusted, false)
   assert_true(ev.timeStamp > 0)
   assert_true("initEvent" in ev)
@@ -32,11 +34,13 @@
   var ev = new Event("test")
   assert_equals(ev.type, "test")
   assert_equals(ev.target, null)
+  assert_equals(ev.srcElement, null)
   assert_equals(ev.currentTarget, null)
   assert_equals(ev.eventPhase, Event.NONE)
   assert_equals(ev.bubbles, false)
   assert_equals(ev.cancelable, false)
   assert_equals(ev.defaultPrevented, false)
+  assert_equals(ev.returnValue, true)
   assert_equals(ev.isTrusted, false)
   assert_true(ev.timeStamp > 0)
   assert_true("initEvent" in ev)

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-defaultPrevented-after-dispatch-expected.txt (230663 => 230664)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-defaultPrevented-after-dispatch-expected.txt	2018-04-15 21:21:51 UTC (rev 230663)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-defaultPrevented-after-dispatch-expected.txt	2018-04-16 01:01:18 UTC (rev 230664)
@@ -1,3 +1,4 @@
 
-PASS Event.defaultPrevented is not reset after dipatchEvent() 
+PASS Default prevention via preventDefault 
+PASS Default prevention via returnValue 
 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-defaultPrevented-after-dispatch.html (230663 => 230664)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-defaultPrevented-after-dispatch.html	2018-04-15 21:21:51 UTC (rev 230663)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-defaultPrevented-after-dispatch.html	2018-04-16 01:01:18 UTC (rev 230664)
@@ -1,6 +1,6 @@
 <!DOCTYPE html>
 <meta charset=utf-8>
-<title>Event.defaultPrevented is not reset after dipatchEvent()</title>
+<title>Event.defaultPrevented is not reset after dispatchEvent()</title>
 <script src=""
 <script src=""
 </head>
@@ -22,5 +22,23 @@
 
     assert_true(evt.defaultPrevented, "after dispatch");
     assert_equals(evt.target, TARGET);
-});
+    assert_equals(evt.srcElement, TARGET);
+}, "Default prevention via preventDefault");
+
+test(function() {
+    var EVENT = "foo";
+    var TARGET = document.getElementById("target");
+    var evt = document.createEvent("Event");
+    evt.initEvent(EVENT, true, true);
+
+    TARGET.addEventListener(EVENT, this.step_func(function(e) {
+        e.returnValue = false;
+        assert_true(e.defaultPrevented, "during dispatch");
+    }), true);
+    TARGET.dispatchEvent(evt);
+
+    assert_true(evt.defaultPrevented, "after dispatch");
+    assert_equals(evt.target, TARGET);
+    assert_equals(evt.srcElement, TARGET);
+}, "Default prevention via returnValue");
 </script>

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-defaultPrevented-expected.txt (230663 => 230664)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-defaultPrevented-expected.txt	2018-04-15 21:21:51 UTC (rev 230663)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-defaultPrevented-expected.txt	2018-04-16 01:01:18 UTC (rev 230664)
@@ -2,7 +2,9 @@
 PASS When an event is created, defaultPrevented should be initialized to false. 
 PASS initEvent should work correctly (not cancelable). 
 PASS preventDefault() should not change defaultPrevented if cancelable is false. 
+PASS returnValue should not change defaultPrevented if cancelable is false. 
 PASS initEvent should work correctly (cancelable). 
 PASS preventDefault() should change defaultPrevented if cancelable is true. 
+PASS returnValue should change defaultPrevented if cancelable is true. 
 PASS initEvent should unset defaultPrevented. 
 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-defaultPrevented.html (230663 => 230664)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-defaultPrevented.html	2018-04-15 21:21:51 UTC (rev 230663)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-defaultPrevented.html	2018-04-16 01:01:18 UTC (rev 230664)
@@ -22,6 +22,12 @@
   assert_equals(ev.defaultPrevented, false, "defaultPrevented");
 }, "preventDefault() should not change defaultPrevented if cancelable is false.");
 test(function() {
+  assert_equals(ev.cancelable, false, "cancelable (before)");
+  ev.returnValue = false;
+  assert_equals(ev.cancelable, false, "cancelable (after)");
+  assert_equals(ev.defaultPrevented, false, "defaultPrevented");
+}, "returnValue should not change defaultPrevented if cancelable is false.");
+test(function() {
   ev.initEvent("foo", true, true);
   assert_equals(ev.bubbles, true, "bubbles");
   assert_equals(ev.cancelable, true, "cancelable");
@@ -34,6 +40,12 @@
   assert_equals(ev.defaultPrevented, true, "defaultPrevented");
 }, "preventDefault() should change defaultPrevented if cancelable is true.");
 test(function() {
+  assert_equals(ev.cancelable, true, "cancelable (before)");
+  ev.returnValue = false;
+  assert_equals(ev.cancelable, true, "cancelable (after)");
+  assert_equals(ev.defaultPrevented, true, "defaultPrevented");
+}, "returnValue should change defaultPrevented if cancelable is true.");
+test(function() {
   ev.initEvent("foo", true, true);
   assert_equals(ev.bubbles, true, "bubbles");
   assert_equals(ev.cancelable, true, "cancelable");

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-dispatch-click.html (230663 => 230664)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-dispatch-click.html	2018-04-15 21:21:51 UTC (rev 230663)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-dispatch-click.html	2018-04-16 01:01:18 UTC (rev 230664)
@@ -94,9 +94,11 @@
   var clickEvent = new MouseEvent("click")
   input._onchange_ = t.step_func_done(function() {
     assert_false(clickEvent.defaultPrevented)
+    assert_true(clickEvent.returnValue)
     assert_equals(clickEvent.eventPhase, 0)
     assert_equals(clickEvent.currentTarget, null)
     assert_equals(clickEvent.target, input)
+    assert_equals(clickEvent.srcElement, input)
     assert_equals(clickEvent.composedPath().length, 0)
   })
   input.dispatchEvent(clickEvent)
@@ -110,6 +112,7 @@
   var finalTarget = document.createElement("doesnotmatter")
   finalTarget._onclick_ = t.step_func_done(function() {
     assert_equals(clickEvent.target, finalTarget)
+    assert_equals(clickEvent.srcElement, finalTarget)
   })
   input._onchange_ = t.step_func(function() {
     finalTarget.dispatchEvent(clickEvent)

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-dispatch-detached-click.html (230663 => 230664)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-dispatch-detached-click.html	2018-04-15 21:21:51 UTC (rev 230663)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-dispatch-detached-click.html	2018-04-16 01:01:18 UTC (rev 230664)
@@ -10,6 +10,7 @@
   var t = async_test("Click event can be dispatched to an element that is not in the document.")
   TARGET.addEventListener(EVENT, t.step_func(function(evt) {
     assert_equals(evt.target, TARGET);
+    assert_equals(evt.srcElement, TARGET);
     t.done();
   }), true);
   var e = document.createEvent("Event");

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-dispatch-other-document.html (230663 => 230664)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-dispatch-other-document.html	2018-04-15 21:21:51 UTC (rev 230663)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-dispatch-other-document.html	2018-04-16 01:01:18 UTC (rev 230664)
@@ -12,6 +12,7 @@
     assert_false(called);
     called = true;
     assert_equals(ev.target, element);
+    assert_equals(ev.srcElement, element);
   }));
   doc.body.appendChild(element);
 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-initEvent.html (230663 => 230664)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-initEvent.html	2018-04-15 21:21:51 UTC (rev 230663)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-initEvent.html	2018-04-16 01:01:18 UTC (rev 230664)
@@ -12,18 +12,20 @@
       var e = document.createEvent("Event")
       e.initEvent("type", bubbles, cancelable)
 
-      // Step 3.
+      // Step 2.
       // Stop (immediate) propagation flag is tested later
       assert_equals(e.defaultPrevented, false, "defaultPrevented")
+      assert_equals(e.returnValue, true, "returnValue")
+      // Step 3.
+      assert_equals(e.isTrusted, false, "isTrusted")
       // Step 4.
-      assert_equals(e.isTrusted, false, "isTrusted")
+      assert_equals(e.target, null, "target")
+      assert_equals(e.srcElement, null, "srcElement")
       // Step 5.
-      assert_equals(e.target, null, "target")
+      assert_equals(e.type, "type", "type")
       // Step 6.
-      assert_equals(e.type, "type", "type")
+      assert_equals(e.bubbles, bubbles, "bubbles")
       // Step 7.
-      assert_equals(e.bubbles, bubbles, "bubbles")
-      // Step 8.
       assert_equals(e.cancelable, cancelable, "cancelable")
     }, "Properties of initEvent(type, " + bubbles + ", " + cancelable + ")")
   })

Added: trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-returnValue-expected.txt (0 => 230664)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-returnValue-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-returnValue-expected.txt	2018-04-16 01:01:18 UTC (rev 230664)
@@ -0,0 +1,9 @@
+
+PASS When an event is created, returnValue should be initialized to true. 
+PASS preventDefault() should not change returnValue if cancelable is false. 
+PASS returnValue=false should have no effect if cancelable is false. 
+PASS preventDefault() should change returnValue if cancelable is true. 
+PASS returnValue should change returnValue if cancelable is true. 
+PASS initEvent should unset returnValue. 
+FAIL returnValue=true should have no effect once the canceled flag was set. assert_true: expected true got false
+

Added: trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-returnValue.html (0 => 230664)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-returnValue.html	                        (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-returnValue.html	2018-04-16 01:01:18 UTC (rev 230664)
@@ -0,0 +1,64 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Event.returnValue</title>
+  <link rel="author" title="Chris Rebert" href=""
+  <link rel="help" href=""
+  <meta name="flags" content="dom">
+  <script src=""
+  <script src=""
+</head>
+<body>
+  <div id="log"></div>
+  <script>
+test(function() {
+  var ev = new Event("foo");
+  assert_true(ev.returnValue, "returnValue");
+}, "When an event is created, returnValue should be initialized to true.");
+test(function() {
+  var ev = new Event("foo", {"cancelable": false});
+  assert_false(ev.cancelable, "cancelable (before)");
+  ev.preventDefault();
+  assert_false(ev.cancelable, "cancelable (after)");
+  assert_true(ev.returnValue, "returnValue");
+}, "preventDefault() should not change returnValue if cancelable is false.");
+test(function() {
+  var ev = new Event("foo", {"cancelable": false});
+  assert_false(ev.cancelable, "cancelable (before)");
+  ev.returnValue = false;
+  assert_false(ev.cancelable, "cancelable (after)");
+  assert_true(ev.returnValue, "returnValue");
+}, "returnValue=false should have no effect if cancelable is false.");
+test(function() {
+  var ev = new Event("foo", {"cancelable": true});
+  assert_true(ev.cancelable, "cancelable (before)");
+  ev.preventDefault();
+  assert_true(ev.cancelable, "cancelable (after)");
+  assert_false(ev.returnValue, "returnValue");
+}, "preventDefault() should change returnValue if cancelable is true.");
+test(function() {
+  var ev = new Event("foo", {"cancelable": true});
+  assert_true(ev.cancelable, "cancelable (before)");
+  ev.returnValue = false;
+  assert_true(ev.cancelable, "cancelable (after)");
+  assert_false(ev.returnValue, "returnValue");
+}, "returnValue should change returnValue if cancelable is true.");
+test(function() {
+  var ev = document.createEvent("Event");
+  ev.returnValue = false;
+  ev.initEvent("foo", true, true);
+  assert_true(ev.bubbles, "bubbles");
+  assert_true(ev.cancelable, "cancelable");
+  assert_true(ev.returnValue, "returnValue");
+}, "initEvent should unset returnValue.");
+test(function() {
+  var ev = new Event("foo");
+  ev.preventDefault();
+  ev.returnValue = true;// no-op
+  assert_true(ev.defaultPrevented);
+  assert_false(ev.returnValue);
+}, "returnValue=true should have no effect once the canceled flag was set.");
+  </script>
+</body>
+</html>

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/EventListener-handleEvent.html (230663 => 230664)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/EventListener-handleEvent.html	2018-04-15 21:21:51 UTC (rev 230663)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/EventListener-handleEvent.html	2018-04-16 01:01:18 UTC (rev 230664)
@@ -27,6 +27,7 @@
             t.step(function() {
                 assert_equals(evt.type, event);
                 assert_equals(evt.target, target);
+                assert_equals(evt.srcElement, target);
                 assert_equals(that, event_listener);
             });
         }

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/EventTarget-dispatchEvent-returnvalue-expected.txt (230663 => 230664)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/EventTarget-dispatchEvent-returnvalue-expected.txt	2018-04-15 21:21:51 UTC (rev 230663)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/EventTarget-dispatchEvent-returnvalue-expected.txt	2018-04-16 01:01:18 UTC (rev 230664)
@@ -1,3 +1,4 @@
 
-PASS Return value of EventTarget.dispatchEvent. 
+PASS Return value of EventTarget.dispatchEvent() affected by preventDefault(). 
+PASS Return value of EventTarget.dispatchEvent() affected by returnValue. 
 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/EventTarget-dispatchEvent-returnvalue.html (230663 => 230664)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/EventTarget-dispatchEvent-returnvalue.html	2018-04-15 21:21:51 UTC (rev 230663)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/EventTarget-dispatchEvent-returnvalue.html	2018-04-16 01:01:18 UTC (rev 230664)
@@ -3,6 +3,7 @@
 <title>EventTarget.dispatchEvent: return value</title>
 <link rel="help" href=""
 <link rel="help" href=""
+<link rel="help" href=""
 <link rel="help" href=""
 <script src=""
 <script src=""
@@ -25,11 +26,13 @@
     var target = document.getElementById("target");
     var parent = document.getElementById("parent");
     var default_prevented;
+    var return_value;
 
     parent.addEventListener(event_type, function(e) {}, true);
     target.addEventListener(event_type, function(e) {
         evt.preventDefault();
         default_prevented = evt.defaultPrevented;
+        return_value = evt.returnValue;
     }, true);
     target.addEventListener(event_type, function(e) {}, true);
 
@@ -39,5 +42,30 @@
     assert_true(parent.dispatchEvent(evt));
     assert_false(target.dispatchEvent(evt));
     assert_true(default_prevented);
-}, "Return value of EventTarget.dispatchEvent.");
+    assert_false(return_value);
+}, "Return value of EventTarget.dispatchEvent() affected by preventDefault().");
+
+test(function() {
+    var event_type = "foo";
+    var target = document.getElementById("target");
+    var parent = document.getElementById("parent");
+    var default_prevented;
+    var return_value;
+
+    parent.addEventListener(event_type, function(e) {}, true);
+    target.addEventListener(event_type, function(e) {
+        evt.returnValue = false;
+        default_prevented = evt.defaultPrevented;
+        return_value = evt.returnValue;
+    }, true);
+    target.addEventListener(event_type, function(e) {}, true);
+
+    var evt = document.createEvent("Event");
+    evt.initEvent(event_type, true, true);
+
+    assert_true(parent.dispatchEvent(evt));
+    assert_false(target.dispatchEvent(evt));
+    assert_true(default_prevented);
+    assert_false(return_value);
+}, "Return value of EventTarget.dispatchEvent() affected by returnValue.");
 </script>

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/w3c-import.log (230663 => 230664)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/w3c-import.log	2018-04-15 21:21:51 UTC (rev 230663)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/w3c-import.log	2018-04-16 01:01:18 UTC (rev 230664)
@@ -42,6 +42,7 @@
 /LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-init-while-dispatching.html
 /LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-initEvent.html
 /LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-propagation.html
+/LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-returnValue.html
 /LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-subclasses-constructors.html
 /LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-timestamp-high-resolution.html
 /LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-timestamp-safe-resolution.html

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/dom/interfaces-expected.txt (230663 => 230664)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/dom/interfaces-expected.txt	2018-04-15 21:21:51 UTC (rev 230663)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/dom/interfaces-expected.txt	2018-04-16 01:01:18 UTC (rev 230664)
@@ -24,6 +24,8 @@
 PASS Unscopable handled correctly for type property on Event 
 PASS Event interface: attribute target 
 PASS Unscopable handled correctly for target property on Event 
+PASS Event interface: attribute srcElement 
+PASS Unscopable handled correctly for srcElement property on Event 
 PASS Event interface: attribute currentTarget 
 PASS Unscopable handled correctly for currentTarget property on Event 
 PASS Event interface: constant NONE on interface object 
@@ -44,6 +46,8 @@
 PASS Unscopable handled correctly for bubbles property on Event 
 PASS Event interface: attribute cancelable 
 PASS Unscopable handled correctly for cancelable property on Event 
+PASS Event interface: attribute returnValue 
+PASS Unscopable handled correctly for returnValue property on Event 
 PASS Event interface: operation preventDefault() 
 PASS Unscopable handled correctly for preventDefault() on Event 
 PASS Event interface: attribute defaultPrevented 
@@ -56,6 +60,7 @@
 PASS Stringification of document.createEvent("Event") 
 PASS Event interface: document.createEvent("Event") must inherit property "type" with the proper type 
 PASS Event interface: document.createEvent("Event") must inherit property "target" with the proper type 
+PASS Event interface: document.createEvent("Event") must inherit property "srcElement" with the proper type 
 PASS Event interface: document.createEvent("Event") must inherit property "currentTarget" with the proper type 
 PASS Event interface: document.createEvent("Event") must inherit property "NONE" with the proper type 
 PASS Event interface: document.createEvent("Event") must inherit property "CAPTURING_PHASE" with the proper type 
@@ -66,6 +71,7 @@
 PASS Event interface: document.createEvent("Event") must inherit property "stopImmediatePropagation()" with the proper type 
 PASS Event interface: document.createEvent("Event") must inherit property "bubbles" with the proper type 
 PASS Event interface: document.createEvent("Event") must inherit property "cancelable" with the proper type 
+PASS Event interface: document.createEvent("Event") must inherit property "returnValue" with the proper type 
 PASS Event interface: document.createEvent("Event") must inherit property "preventDefault()" with the proper type 
 PASS Event interface: document.createEvent("Event") must inherit property "defaultPrevented" with the proper type 
 PASS Event interface: document.createEvent("Event") must have own property "isTrusted" 
@@ -76,6 +82,7 @@
 PASS Stringification of new Event("foo") 
 PASS Event interface: new Event("foo") must inherit property "type" with the proper type 
 PASS Event interface: new Event("foo") must inherit property "target" with the proper type 
+PASS Event interface: new Event("foo") must inherit property "srcElement" with the proper type 
 PASS Event interface: new Event("foo") must inherit property "currentTarget" with the proper type 
 PASS Event interface: new Event("foo") must inherit property "NONE" with the proper type 
 PASS Event interface: new Event("foo") must inherit property "CAPTURING_PHASE" with the proper type 
@@ -86,6 +93,7 @@
 PASS Event interface: new Event("foo") must inherit property "stopImmediatePropagation()" with the proper type 
 PASS Event interface: new Event("foo") must inherit property "bubbles" with the proper type 
 PASS Event interface: new Event("foo") must inherit property "cancelable" with the proper type 
+PASS Event interface: new Event("foo") must inherit property "returnValue" with the proper type 
 PASS Event interface: new Event("foo") must inherit property "preventDefault()" with the proper type 
 PASS Event interface: new Event("foo") must inherit property "defaultPrevented" with the proper type 
 PASS Event interface: new Event("foo") must have own property "isTrusted" 
@@ -109,6 +117,7 @@
 PASS CustomEvent interface: calling initCustomEvent(DOMString, boolean, boolean, any) on new CustomEvent("foo") with too few arguments must throw TypeError 
 PASS Event interface: new CustomEvent("foo") must inherit property "type" with the proper type 
 PASS Event interface: new CustomEvent("foo") must inherit property "target" with the proper type 
+PASS Event interface: new CustomEvent("foo") must inherit property "srcElement" with the proper type 
 PASS Event interface: new CustomEvent("foo") must inherit property "currentTarget" with the proper type 
 PASS Event interface: new CustomEvent("foo") must inherit property "NONE" with the proper type 
 PASS Event interface: new CustomEvent("foo") must inherit property "CAPTURING_PHASE" with the proper type 
@@ -119,6 +128,7 @@
 PASS Event interface: new CustomEvent("foo") must inherit property "stopImmediatePropagation()" with the proper type 
 PASS Event interface: new CustomEvent("foo") must inherit property "bubbles" with the proper type 
 PASS Event interface: new CustomEvent("foo") must inherit property "cancelable" with the proper type 
+PASS Event interface: new CustomEvent("foo") must inherit property "returnValue" with the proper type 
 PASS Event interface: new CustomEvent("foo") must inherit property "preventDefault()" with the proper type 
 PASS Event interface: new CustomEvent("foo") must inherit property "defaultPrevented" with the proper type 
 PASS Event interface: new CustomEvent("foo") must have own property "isTrusted" 
@@ -1637,22 +1647,34 @@
 PASS EventTarget interface: calling removeEventListener(DOMString, EventListener, [object Object],[object Object]) on document.createComment("abc") with too few arguments must throw TypeError 
 PASS EventTarget interface: document.createComment("abc") must inherit property "dispatchEvent(Event)" with the proper type 
 PASS EventTarget interface: calling dispatchEvent(Event) on document.createComment("abc") with too few arguments must throw TypeError 
-PASS Range interface: existence and properties of interface object 
+FAIL AbstractRange interface: existence and properties of interface object assert_own_property: self does not have own property "AbstractRange" expected property "AbstractRange" missing
+FAIL AbstractRange interface object length assert_own_property: self does not have own property "AbstractRange" expected property "AbstractRange" missing
+FAIL AbstractRange interface object name assert_own_property: self does not have own property "AbstractRange" expected property "AbstractRange" missing
+FAIL AbstractRange interface: existence and properties of interface prototype object assert_own_property: self does not have own property "AbstractRange" expected property "AbstractRange" missing
+FAIL AbstractRange interface: existence and properties of interface prototype object's "constructor" property assert_own_property: self does not have own property "AbstractRange" expected property "AbstractRange" missing
+FAIL AbstractRange interface: existence and properties of interface prototype object's @@unscopables property assert_own_property: self does not have own property "AbstractRange" expected property "AbstractRange" missing
+FAIL AbstractRange interface: attribute startContainer assert_own_property: self does not have own property "AbstractRange" expected property "AbstractRange" missing
+PASS Unscopable handled correctly for startContainer property on AbstractRange 
+FAIL AbstractRange interface: attribute startOffset assert_own_property: self does not have own property "AbstractRange" expected property "AbstractRange" missing
+PASS Unscopable handled correctly for startOffset property on AbstractRange 
+FAIL AbstractRange interface: attribute endContainer assert_own_property: self does not have own property "AbstractRange" expected property "AbstractRange" missing
+PASS Unscopable handled correctly for endContainer property on AbstractRange 
+FAIL AbstractRange interface: attribute endOffset assert_own_property: self does not have own property "AbstractRange" expected property "AbstractRange" missing
+PASS Unscopable handled correctly for endOffset property on AbstractRange 
+FAIL AbstractRange interface: attribute collapsed assert_own_property: self does not have own property "AbstractRange" expected property "AbstractRange" missing
+PASS Unscopable handled correctly for collapsed property on AbstractRange 
+FAIL StaticRange interface: existence and properties of interface object assert_own_property: should inherit from AbstractRange, but self has no such property expected property "AbstractRange" missing
+PASS StaticRange interface object length 
+PASS StaticRange interface object name 
+FAIL StaticRange interface: existence and properties of interface prototype object assert_own_property: should inherit from AbstractRange, but self has no such property expected property "AbstractRange" missing
+PASS StaticRange interface: existence and properties of interface prototype object's "constructor" property 
+PASS StaticRange interface: existence and properties of interface prototype object's @@unscopables property 
+FAIL Range interface: existence and properties of interface object assert_own_property: should inherit from AbstractRange, but self has no such property expected property "AbstractRange" missing
 PASS Range interface object length 
 PASS Range interface object name 
-PASS Range interface: existence and properties of interface prototype object 
+FAIL Range interface: existence and properties of interface prototype object assert_own_property: should inherit from AbstractRange, but self has no such property expected property "AbstractRange" missing
 PASS Range interface: existence and properties of interface prototype object's "constructor" property 
 PASS Range interface: existence and properties of interface prototype object's @@unscopables property 
-PASS Range interface: attribute startContainer 
-PASS Unscopable handled correctly for startContainer property on Range 
-PASS Range interface: attribute startOffset 
-PASS Unscopable handled correctly for startOffset property on Range 
-PASS Range interface: attribute endContainer 
-PASS Unscopable handled correctly for endContainer property on Range 
-PASS Range interface: attribute endOffset 
-PASS Unscopable handled correctly for endOffset property on Range 
-PASS Range interface: attribute collapsed 
-PASS Unscopable handled correctly for collapsed property on Range 
 PASS Range interface: attribute commonAncestorContainer 
 PASS Unscopable handled correctly for commonAncestorContainer property on Range 
 PASS Range interface: operation setStart(Node, unsigned long) 
@@ -1706,11 +1728,6 @@
 PASS Range interface: stringifier 
 PASS Range must be primary interface of document.createRange() 
 PASS Stringification of document.createRange() 
-PASS Range interface: document.createRange() must inherit property "startContainer" with the proper type 
-PASS Range interface: document.createRange() must inherit property "startOffset" with the proper type 
-PASS Range interface: document.createRange() must inherit property "endContainer" with the proper type 
-PASS Range interface: document.createRange() must inherit property "endOffset" with the proper type 
-PASS Range interface: document.createRange() must inherit property "collapsed" with the proper type 
 PASS Range interface: document.createRange() must inherit property "commonAncestorContainer" with the proper type 
 PASS Range interface: document.createRange() must inherit property "setStart(Node, unsigned long)" with the proper type 
 PASS Range interface: calling setStart(Node, unsigned long) on document.createRange() with too few arguments must throw TypeError 
@@ -1751,13 +1768,13 @@
 PASS Range interface: calling comparePoint(Node, unsigned long) on document.createRange() with too few arguments must throw TypeError 
 PASS Range interface: document.createRange() must inherit property "intersectsNode(Node)" with the proper type 
 PASS Range interface: calling intersectsNode(Node) on document.createRange() with too few arguments must throw TypeError 
+PASS AbstractRange interface: document.createRange() must inherit property "startContainer" with the proper type 
+PASS AbstractRange interface: document.createRange() must inherit property "startOffset" with the proper type 
+PASS AbstractRange interface: document.createRange() must inherit property "endContainer" with the proper type 
+PASS AbstractRange interface: document.createRange() must inherit property "endOffset" with the proper type 
+PASS AbstractRange interface: document.createRange() must inherit property "collapsed" with the proper type 
 PASS Range must be primary interface of detachedRange 
 PASS Stringification of detachedRange 
-PASS Range interface: detachedRange must inherit property "startContainer" with the proper type 
-PASS Range interface: detachedRange must inherit property "startOffset" with the proper type 
-PASS Range interface: detachedRange must inherit property "endContainer" with the proper type 
-PASS Range interface: detachedRange must inherit property "endOffset" with the proper type 
-PASS Range interface: detachedRange must inherit property "collapsed" with the proper type 
 PASS Range interface: detachedRange must inherit property "commonAncestorContainer" with the proper type 
 PASS Range interface: detachedRange must inherit property "setStart(Node, unsigned long)" with the proper type 
 PASS Range interface: calling setStart(Node, unsigned long) on detachedRange with too few arguments must throw TypeError 
@@ -1798,6 +1815,11 @@
 PASS Range interface: calling comparePoint(Node, unsigned long) on detachedRange with too few arguments must throw TypeError 
 PASS Range interface: detachedRange must inherit property "intersectsNode(Node)" with the proper type 
 PASS Range interface: calling intersectsNode(Node) on detachedRange with too few arguments must throw TypeError 
+PASS AbstractRange interface: detachedRange must inherit property "startContainer" with the proper type 
+PASS AbstractRange interface: detachedRange must inherit property "startOffset" with the proper type 
+PASS AbstractRange interface: detachedRange must inherit property "endContainer" with the proper type 
+PASS AbstractRange interface: detachedRange must inherit property "endOffset" with the proper type 
+PASS AbstractRange interface: detachedRange must inherit property "collapsed" with the proper type 
 PASS NodeIterator interface: existence and properties of interface object 
 PASS NodeIterator interface object length 
 PASS NodeIterator interface object name 

Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/interfaces/dom.idl (230663 => 230664)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/interfaces/dom.idl	2018-04-15 21:21:51 UTC (rev 230663)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/interfaces/dom.idl	2018-04-16 01:01:18 UTC (rev 230664)
@@ -3,6 +3,7 @@
 interface Event {
   readonly attribute DOMString type;
   readonly attribute EventTarget? target;
+  readonly attribute EventTarget? srcElement;
   readonly attribute EventTarget? currentTarget;
 
   const unsigned short NONE = 0;
@@ -16,6 +17,7 @@
 
   readonly attribute boolean bubbles;
   readonly attribute boolean cancelable;
+           attribute boolean returnValue;
   void preventDefault();
   readonly attribute boolean defaultPrevented;
 
@@ -440,14 +442,22 @@
 };
 
 
-[Constructor,
- Exposed=Window]
-interface Range {
+[Exposed=Window]
+interface AbstractRange {
   readonly attribute Node startContainer;
   readonly attribute unsigned long startOffset;
   readonly attribute Node endContainer;
   readonly attribute unsigned long endOffset;
   readonly attribute boolean collapsed;
+};
+
+[Exposed=Window]
+interface StaticRange : AbstractRange {
+};
+
+[Constructor,
+ Exposed=Window]
+interface Range : AbstractRange {
   readonly attribute Node commonAncestorContainer;
 
   void setStart(Node node, unsigned long offset);

Modified: trunk/Source/WebCore/ChangeLog (230663 => 230664)


--- trunk/Source/WebCore/ChangeLog	2018-04-15 21:21:51 UTC (rev 230663)
+++ trunk/Source/WebCore/ChangeLog	2018-04-16 01:01:18 UTC (rev 230664)
@@ -1,3 +1,25 @@
+2018-04-15  Chris Dumez  <cdu...@apple.com>
+
+        Change Event's returnValue so it doesn't expose a new primitive
+        https://bugs.webkit.org/show_bug.cgi?id=184415
+
+        Reviewed by Darin Adler.
+
+        Update Event.returnValue setter to match the latest DOM specification after:
+        - https://github.com/whatwg/dom/pull/626
+
+        In particular, the returnValue setter is now a no-op if the new flag value
+        is true. If the input flag value is false, it only sets the 'canceled' flag
+        if the event is cancelable and the event’s in passive listener flag is unset.
+
+        Test: imported/w3c/web-platform-tests/dom/events/Event-returnValue.html
+
+        * dom/Event.cpp:
+        (WebCore::Event::setLegacyReturnValue):
+        (WebCore::Event::setCanceledFlagIfPossible):
+        (WebCore::Event::preventDefault):
+        * dom/Event.h:
+
 2018-04-14  Thibault Saunier  <tsaun...@igalia.com>
 
         [GStreamer] Expose a method to retrieve the GstStream from a TrackPrivateBaseGStreamer

Modified: trunk/Source/WebCore/dom/Event.h (230663 => 230664)


--- trunk/Source/WebCore/dom/Event.h	2018-04-15 21:21:51 UTC (rev 230663)
+++ trunk/Source/WebCore/dom/Event.h	2018-04-16 01:01:18 UTC (rev 230664)
@@ -96,7 +96,7 @@
     void setUntrusted() { m_isTrusted = false; }
 
     bool legacyReturnValue() const { return !m_wasCanceled; }
-    void setLegacyReturnValue(bool returnValue) { m_wasCanceled = !returnValue; }
+    void setLegacyReturnValue(bool);
 
     virtual EventInterface eventInterface() const { return EventInterfaceType; }
 
@@ -153,6 +153,8 @@
 private:
     AtomicString m_type;
 
+    void setCanceledFlagIfPossible();
+
     bool m_isInitialized { false };
     bool m_canBubble { false };
     bool m_cancelable { false };
@@ -176,6 +178,18 @@
 
 inline void Event::preventDefault()
 {
+    setCanceledFlagIfPossible();
+}
+
+inline void Event::setLegacyReturnValue(bool returnValue)
+{
+    if (!returnValue)
+        setCanceledFlagIfPossible();
+}
+
+// https://dom.spec.whatwg.org/#set-the-canceled-flag
+inline void Event::setCanceledFlagIfPossible()
+{
     if (m_cancelable && !m_isExecutingPassiveEventListener)
         m_wasCanceled = true;
     // FIXME: Specification suggests we log something to the console when preventDefault is called but
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to