Change Event's returnValue so it doesn't expose a new primitive
authorcdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 16 Apr 2018 01:01:18 +0000 (01:01 +0000)
committercdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 16 Apr 2018 01:01:18 +0000 (01:01 +0000)
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:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@230664 268f45cc-cd09-0410-ab3c-d52691b4dbfc

23 files changed:
LayoutTests/imported/w3c/ChangeLog
LayoutTests/imported/w3c/web-platform-tests/IndexedDB/interfaces.any.worker-expected.txt
LayoutTests/imported/w3c/web-platform-tests/dom/events/AddEventListenerOptions-passive-expected.txt
LayoutTests/imported/w3c/web-platform-tests/dom/events/AddEventListenerOptions-passive.html
LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-constructors.html
LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-defaultPrevented-after-dispatch-expected.txt
LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-defaultPrevented-after-dispatch.html
LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-defaultPrevented-expected.txt
LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-defaultPrevented.html
LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-dispatch-click.html
LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-dispatch-detached-click.html
LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-dispatch-other-document.html
LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-initEvent.html
LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-returnValue-expected.txt [new file with mode: 0644]
LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-returnValue.html [new file with mode: 0644]
LayoutTests/imported/w3c/web-platform-tests/dom/events/EventListener-handleEvent.html
LayoutTests/imported/w3c/web-platform-tests/dom/events/EventTarget-dispatchEvent-returnvalue-expected.txt
LayoutTests/imported/w3c/web-platform-tests/dom/events/EventTarget-dispatchEvent-returnvalue.html
LayoutTests/imported/w3c/web-platform-tests/dom/events/w3c-import.log
LayoutTests/imported/w3c/web-platform-tests/dom/interfaces-expected.txt
LayoutTests/imported/w3c/web-platform-tests/interfaces/dom.idl
Source/WebCore/ChangeLog
Source/WebCore/dom/Event.h

index 9adafd4..2d6811d 100644 (file)
@@ -1,3 +1,32 @@
+2018-04-15  Chris Dumez  <cdumez@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  <graouts@apple.com>
 
         [Web Animations] Turn CSS Animations and CSS Transitions as Web Animations on by default
index 3a37323..5544c15 100644 (file)
@@ -20,6 +20,8 @@ PASS Text interface: existence and properties of interface object
 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 
index 01e03da..853dafe 100644 (file)
@@ -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 
 
index 1f0118e..bf41580 100644 (file)
@@ -55,6 +55,32 @@ test(function() {
   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 @@ test(function() {
   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;
index a3cd3f8..5f1ed15 100644 (file)
@@ -19,11 +19,13 @@ test(function() {
   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 @@ test(function() {
   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)
index decf7e9..8fef005 100644 (file)
@@ -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="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 </head>
@@ -22,5 +22,23 @@ test(function() {
 
     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>
index 01d699d..49a4601 100644 (file)
@@ -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. 
 
index 2a3d171..f023008 100644 (file)
@@ -22,6 +22,12 @@ test(function() {
   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 @@ test(function() {
   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");
index 29b0cae..4aa4bbe 100644 (file)
@@ -94,9 +94,11 @@ async_test(function(t) {
   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 @@ async_test(function(t) {
   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)
index 30e15b8..76ea3d7 100644 (file)
@@ -10,6 +10,7 @@ test(function() {
   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");
index 0252a4f..689b480 100644 (file)
@@ -12,6 +12,7 @@ test(function() {
     assert_false(called);
     called = true;
     assert_equals(ev.target, element);
+    assert_equals(ev.srcElement, element);
   }));
   doc.body.appendChild(element);
 
index c6b8564..34ed32a 100644 (file)
@@ -12,18 +12,20 @@ booleans.forEach(function(bubbles) {
       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")
-      // Step 4.
+      assert_equals(e.returnValue, true, "returnValue")
+      // Step 3.
       assert_equals(e.isTrusted, false, "isTrusted")
-      // Step 5.
+      // Step 4.
       assert_equals(e.target, null, "target")
-      // Step 6.
+      assert_equals(e.srcElement, null, "srcElement")
+      // Step 5.
       assert_equals(e.type, "type", "type")
-      // Step 7.
+      // Step 6.
       assert_equals(e.bubbles, bubbles, "bubbles")
-      // Step 8.
+      // Step 7.
       assert_equals(e.cancelable, cancelable, "cancelable")
     }, "Properties of initEvent(type, " + bubbles + ", " + cancelable + ")")
   })
diff --git a/LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-returnValue-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-returnValue-expected.txt
new file mode 100644 (file)
index 0000000..f002265
--- /dev/null
@@ -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
+
diff --git a/LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-returnValue.html b/LayoutTests/imported/w3c/web-platform-tests/dom/events/Event-returnValue.html
new file mode 100644 (file)
index 0000000..50c2660
--- /dev/null
@@ -0,0 +1,64 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Event.returnValue</title>
+  <link rel="author" title="Chris Rebert" href="http://chrisrebert.com">
+  <link rel="help" href="https://dom.spec.whatwg.org/#dom-event-returnvalue">
+  <meta name="flags" content="dom">
+  <script src="/resources/testharness.js"></script>
+  <script src="/resources/testharnessreport.js"></script>
+</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>
index 3b58c49..b33b030 100644 (file)
@@ -27,6 +27,7 @@ test(function(t) {
             t.step(function() {
                 assert_equals(evt.type, event);
                 assert_equals(evt.target, target);
+                assert_equals(evt.srcElement, target);
                 assert_equals(that, event_listener);
             });
         }
index 8804c38..c4466e0 100644 (file)
@@ -3,6 +3,7 @@
 <title>EventTarget.dispatchEvent: return value</title>
 <link rel="help" href="https://dom.spec.whatwg.org/#concept-event-dispatch">
 <link rel="help" href="https://dom.spec.whatwg.org/#dom-event-preventdefault">
+<link rel="help" href="https://dom.spec.whatwg.org/#dom-event-returnvalue">
 <link rel="help" href="https://dom.spec.whatwg.org/#dom-event-defaultprevented">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
@@ -25,11 +26,13 @@ test(function() {
     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 @@ test(function() {
     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>
index a894b01..8ac29d9 100644 (file)
@@ -42,6 +42,7 @@ List of files:
 /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
index 877554e..44531be 100644 (file)
@@ -24,6 +24,8 @@ PASS Event interface: attribute type
 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 Event interface: attribute bubbles
 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 Event must be primary interface of document.createEvent("Event")
 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 "stopP
 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 Event must be primary interface of new Event("foo")
 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 "stopPropagation()"
 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: new CustomEvent("foo") must inherit property "initCu
 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 "stopPropagat
 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: document.createComment("abc") must inherit property
 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 Unscopable handled correctly for intersectsNode(Node) on Range
 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: document.createRange() must inherit property "comparePoint
 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: detachedRange must inherit property "comparePoint(Node, un
 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 
index ae65018..087fe4d 100644 (file)
@@ -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 @@ interface Event {
 
   readonly attribute boolean bubbles;
   readonly attribute boolean cancelable;
+           attribute boolean returnValue;
   void preventDefault();
   readonly attribute boolean defaultPrevented;
 
@@ -440,14 +442,22 @@ interface Comment : CharacterData {
 };
 
 
-[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);
index 81ce635..12d9ad4 100644 (file)
@@ -1,3 +1,25 @@
+2018-04-15  Chris Dumez  <cdumez@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  <tsaunier@igalia.com>
 
         [GStreamer] Expose a method to retrieve the GstStream from a TrackPrivateBaseGStreamer
index 6bfdafe..5e56ac5 100644 (file)
@@ -96,7 +96,7 @@ public:
     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 @@ protected:
 private:
     AtomicString m_type;
 
+    void setCanceledFlagIfPossible();
+
     bool m_isInitialized { false };
     bool m_canBubble { false };
     bool m_cancelable { false };
@@ -176,6 +178,18 @@ private:
 
 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