Bug 684208 - make dispatchEvent()'s return value to follow the spec, r=masayuki
authorOlli Pettay <Olli.Pettay@helsinki.fi>
Thu, 07 Apr 2016 15:49:12 +0300
changeset 315994 83d398b9419ae8727df9b07607403a8b15718282
parent 315993 6271ce7ff2aaaee6376cb0673a4999f5058bf89e
child 315995 de1873c4d8b893eed815c566da877cca4af6f14b
push id9480
push userjlund@mozilla.com
push dateMon, 25 Apr 2016 17:12:58 +0000
treeherdermozilla-aurora@0d6a91c76a9e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmasayuki
bugs684208
milestone48.0a1
Bug 684208 - make dispatchEvent()'s return value to follow the spec, r=masayuki
dom/base/nsINode.cpp
dom/bindings/Bindings.conf
dom/events/EventTarget.cpp
dom/events/EventTarget.h
dom/events/test/mochitest.ini
dom/events/test/test_bug517851.html
dom/events/test/test_bug684208.html
--- a/dom/base/nsINode.cpp
+++ b/dom/base/nsINode.cpp
@@ -2810,25 +2810,16 @@ nsDOMAttributeMap*
 nsINode::GetAttributes()
 {
   if (!IsElement()) {
     return nullptr;
   }
   return AsElement()->Attributes();
 }
 
-bool
-EventTarget::DispatchEvent(Event& aEvent,
-                           ErrorResult& aRv)
-{
-  bool result = false;
-  aRv = DispatchEvent(&aEvent, &result);
-  return result;
-}
-
 Element*
 nsINode::GetParentElementCrossingShadowRoot() const
 {
   if (!mParent) {
     return nullptr;
   }
 
   if (mParent->IsElement()) {
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -466,17 +466,18 @@ DOMInterfaces = {
 'EventTarget': {
     # When we get rid of hasXPConnectImpls, we can get rid of the
     # couldBeDOMBinding stuff in GetOrCreateDOMReflector.
     #
     # We can also get rid of the UnwrapArg bits in
     # the dom QueryInterface (in BindingUtils.cpp) at that point.
     'hasXPConnectImpls': True,
     'concrete': False,
-    'jsImplParent': 'mozilla::DOMEventTargetHelper'
+    'jsImplParent': 'mozilla::DOMEventTargetHelper',
+    'implicitJSContext': [ 'dispatchEvent' ]
 },
 
 'Exception': {
     'headerFile': 'mozilla/dom/DOMException.h',
     'binaryNames': {
         'message': 'messageMoz',
     },
     'implicitJSContext': [ '__stringifier', 'filename', 'lineNumber', 'stack' ],
--- a/dom/events/EventTarget.cpp
+++ b/dom/events/EventTarget.cpp
@@ -58,10 +58,20 @@ EventTarget::SetEventHandler(nsIAtom* aT
 
 bool
 EventTarget::HasApzAwareListeners() const
 {
   EventListenerManager* elm = GetExistingListenerManager();
   return elm && elm->HasApzAwareListeners();
 }
 
+bool
+EventTarget::DispatchEvent(JSContext* aCx,
+                           Event& aEvent,
+                           ErrorResult& aRv)
+{
+  bool result = false;
+  aRv = DispatchEvent(&aEvent, &result);
+  return !aEvent.DefaultPrevented(aCx);
+}
+
 } // namespace dom
 } // namespace mozilla
--- a/dom/events/EventTarget.h
+++ b/dom/events/EventTarget.h
@@ -45,17 +45,17 @@ public:
                                 EventListener* aCallback,
                                 bool aCapture,
                                 const Nullable<bool>& aWantsUntrusted,
                                 ErrorResult& aRv) = 0;
   virtual void RemoveEventListener(const nsAString& aType,
                                    EventListener* aCallback,
                                    bool aCapture,
                                    ErrorResult& aRv);
-  bool DispatchEvent(Event& aEvent, ErrorResult& aRv);
+  bool DispatchEvent(JSContext* aCx, Event& aEvent, ErrorResult& aRv);
 
   // Note, this takes the type in onfoo form!
   EventHandlerNonNull* GetEventHandler(const nsAString& aType)
   {
     nsCOMPtr<nsIAtom> type = NS_Atomize(aType);
     return GetEventHandler(type, EmptyString());
   }
 
--- a/dom/events/test/mochitest.ini
+++ b/dom/events/test/mochitest.ini
@@ -115,16 +115,17 @@ skip-if = buildapp == 'b2g' # b2g(1 fail
 [test_bug659350.html]
 skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM
 [test_bug662678.html]
 skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM
 [test_bug667612.html]
 skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM
 [test_bug667919-1.html]
 skip-if = buildapp == 'b2g' || toolkit == 'android' #CRASH_DUMP, RANDOM # b2g(bug 900969, 5 tests) b2g-debug(bug 900969, 5 tests) b2g-desktop(bug 900969, 5 tests)
+[test_bug684208.html]
 [test_bug689564.html]
 skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM
 [test_bug698929.html]
 skip-if = toolkit == 'android' #CRASH_DUMP, RANDOM
 [test_bug704423.html]
 [test_bug741666.html]
 [test_bug742376.html]
 [test_bug812744.html]
--- a/dom/events/test/test_bug517851.html
+++ b/dom/events/test/test_bug517851.html
@@ -58,19 +58,27 @@ e.initEvent("beforeunload", true, true);
 window.testReturnValue = true;
 is(target.dispatchEvent(e), true,
    "beforeunload event on random element should not be prevented!");
 is(handledCount, 4, "Wrong event count; handler should not have run!");
 is(target2.dispatchEvent(e), false,
    "beforeunload event should be prevented!");
 is(handledCount, 5, "Wrong event count!");
 window.testReturnValue = false;
+is(target.dispatchEvent(e), false,
+   "beforeunload event on random element should be prevented because the event was already cancelled!");
+is(handledCount, 5, "Wrong event count; handler should not have run! (2)");
+
+e = document.createEvent("BeforeUnloadEvent");
+e.initEvent("beforeunload", true, true);
+window.testReturnValue = false;
 is(target.dispatchEvent(e), true,
    "beforeunload event on random element should not be prevented (2)!");
 is(handledCount, 5, "Wrong event count; handler should not have run! (2)");
+
 is(target2.dispatchEvent(e), false,
    "beforeunload event should be prevented (2)!");
 is(handledCount, 6, "Wrong event count!");
 
 // Create normal event for beforeunload.
 e = document.createEvent("Event");
 e.initEvent("beforeunload", true, true);
 window.testReturnValue = true;
new file mode 100644
--- /dev/null
+++ b/dom/events/test/test_bug684208.html
@@ -0,0 +1,80 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=684208
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 684208</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+  <script type="application/javascript">
+
+  /** Test for Bug 684208 **/
+
+  function checkDispatchReturnValue(targetOrUndefined) {
+    var target = targetOrUndefined ? targetOrUndefined : self;
+    function createEvent() {
+      if ("MouseEvent" in this) {
+        return new MouseEvent("click", {cancelable: true});
+      }
+      return new Event("dummy", {cancelable: true});
+    }
+
+    function postSelfMessage(msg) {
+      try {
+        self.postMessage(msg);
+      } catch(ex) {
+        self.postMessage(msg, "*");
+      }
+    }
+
+    function passiveListener(e) {
+      e.target.removeEventListener(e.type, passiveListener);
+    }
+    var event = createEvent();
+    target.addEventListener(event.type, passiveListener);
+    postSelfMessage(target.dispatchEvent(event) == true);
+
+    function cancellingListener(e) {
+      e.target.removeEventListener(e.type, cancellingListener);
+      e.preventDefault();
+    }
+    event = createEvent();
+    target.addEventListener(event.type, cancellingListener);
+    postSelfMessage(target.dispatchEvent(event) == false);
+  }
+
+  function test() {
+    var expectedEvents = 6;
+    function messageHandler(e) {
+      ok(e.data, "All the dispatchEvent calls should pass.");
+      --expectedEvents;
+      if (!expectedEvents) {
+        window.onmessage = null;
+        window.worker.onmessage = null;
+        SimpleTest.finish();
+      }
+    }
+    window.onmessage = messageHandler;
+    checkDispatchReturnValue();
+    checkDispatchReturnValue(document.getElementById("link"));
+    window.worker =
+      new Worker(URL.createObjectURL(new Blob(["(" + checkDispatchReturnValue.toString() + ")();"])));
+    window.worker.onmessage = messageHandler;
+  }
+
+  SimpleTest.waitForExplicitFinish();
+
+  </script>
+</head>
+<body onload="test();">
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=684208">Mozilla Bug 684208</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+<a id="link" href="#foo">foo</a>
+</div>
+<pre id="test">
+</pre>
+</body>
+</html>