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
--- 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);