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
@@ -11,16 +11,32 @@
#include "mozilla/dom/EventTarget.h"
#include "nsContentUtils.h"
#include "nsIDOMEvent.h"
namespace mozilla {
using namespace dom;
+static DispatcherTrait*
+GetDispatcher(AsyncEventDispatcher* dispatcher)
+{
+ if (nsCOMPtr<nsIGlobalObject> global = dispatcher->mTarget->GetOwnerGlobal()) {
+ return global;
+ }
+
+ // Sometimes GetOwnerGlobal returns null because it uses
+ // GetScriptHandlingObject rather than GetScopeObject.
+ if (nsCOMPtr<nsINode> node = do_QueryInterface(dispatcher->mTarget)) {
+ return node->OwnerDoc();
+ }
+
+ return nullptr;
+}
+
/******************************************************************************
* mozilla::AsyncEventDispatcher
******************************************************************************/
AsyncEventDispatcher::AsyncEventDispatcher(EventTarget* aTarget,
WidgetEvent& aEvent)
: mTarget(aTarget)
{
@@ -61,16 +77,21 @@ AsyncEventDispatcher::Cancel()
mCanceled = true;
return NS_OK;
}
nsresult
AsyncEventDispatcher::PostDOMEvent()
{
RefPtr<AsyncEventDispatcher> ensureDeletionWhenFailing = this;
+ if (NS_IsMainThread()) {
+ if (DispatcherTrait* dispatcher = GetDispatcher(this)) {
+ return dispatcher->Dispatch("AsyncEvent", TaskCategory::Other, ensureDeletionWhenFailing.forget());
+ }
+ }
return NS_DispatchToCurrentThread(this);
}
void
AsyncEventDispatcher::RunDOMEventWhenSafe()
{
RefPtr<AsyncEventDispatcher> ensureDeletionWhenFailing = this;
nsContentUtils::AddScriptRunner(this);