Bug 1318506 - Label AsyncEventDispatcher runnables with DocGroup (r=ehsan)
authorBill McCloskey <billm@mozilla.com>
Sun, 13 Nov 2016 10:22:52 -0800
changeset 453588 30b32a2aabb1d18f952492ea41f9465c32ecebe7
parent 453587 32a005fd81f39ec493a735c71d3c3848078bbd44
child 453589 f980cbff80529d0c9d19d257e32f2af416c559b2
push id39711
push userdmitchell@mozilla.com
push dateFri, 23 Dec 2016 21:59:47 +0000
reviewersehsan
bugs1318506
milestone53.0a1
Bug 1318506 - Label AsyncEventDispatcher runnables with DocGroup (r=ehsan) I still don't completely understand why we sometimes need to use the global and sometimes the node. As far as I understand it: - Not all event targets are nodes, so the node code can't always be used. - The nsINode::GetOwnerGlobal implementation uses GetScriptHandlingObject, which returns null in some cases where GetScopeObject doesn't. Here is one: http://searchfox.org/mozilla-central/rev/62db1c9021cfbde9fa5e6e9601de16c21f4c7ce4/dom/base/nsDocument.cpp#4627 MozReview-Commit-ID: DdLWeQJIWZx
dom/events/AsyncEventDispatcher.cpp
--- a/dom/events/AsyncEventDispatcher.cpp
+++ b/dom/events/AsyncEventDispatcher.cpp
@@ -61,16 +61,28 @@ AsyncEventDispatcher::Cancel()
   mCanceled = true;
   return NS_OK;
 }
 
 nsresult
 AsyncEventDispatcher::PostDOMEvent()
 {
   RefPtr<AsyncEventDispatcher> ensureDeletionWhenFailing = this;
+  if (NS_IsMainThread()) {
+    if (nsCOMPtr<nsIGlobalObject> global = mTarget->GetOwnerGlobal()) {
+      return global->Dispatch("AsyncEvent", TaskCategory::Other, ensureDeletionWhenFailing.forget());
+    }
+
+    // Sometimes GetOwnerGlobal returns null because it uses
+    // GetScriptHandlingObject rather than GetScopeObject.
+    if (nsCOMPtr<nsINode> node = do_QueryInterface(mTarget)) {
+      nsCOMPtr<nsIDocument> doc = node->OwnerDoc();
+      return doc->Dispatch("AsyncEvent", TaskCategory::Other, ensureDeletionWhenFailing.forget());
+    }
+  }
   return NS_DispatchToCurrentThread(this);
 }
 
 void
 AsyncEventDispatcher::RunDOMEventWhenSafe()
 {
   RefPtr<AsyncEventDispatcher> ensureDeletionWhenFailing = this;
   nsContentUtils::AddScriptRunner(this);