Bug 1009445 - Support AsyncEventDispatcher on non-node interfaces, r=masayuki

This commit is contained in:
Olli Pettay 2014-05-14 12:48:37 +03:00
parent a1f697372c
commit 2ef3c7ff3d
3 changed files with 36 additions and 19 deletions

View File

@ -426,7 +426,7 @@ protected:
NS_IMETHOD Run() MOZ_OVERRIDE
{
static_cast<HTMLFormElement*>(mEventNode.get())->EventHandled();
static_cast<HTMLFormElement*>(mTarget.get())->EventHandled();
return AsyncEventDispatcher::Run();
}
};

View File

@ -19,13 +19,13 @@ using namespace dom;
* mozilla::AsyncEventDispatcher
******************************************************************************/
AsyncEventDispatcher::AsyncEventDispatcher(nsINode* aEventNode,
AsyncEventDispatcher::AsyncEventDispatcher(EventTarget* aTarget,
WidgetEvent& aEvent)
: mEventNode(aEventNode)
: mTarget(aTarget)
, mDispatchChromeOnly(false)
{
MOZ_ASSERT(mEventNode);
EventDispatcher::CreateEvent(aEventNode, nullptr, &aEvent, EmptyString(),
MOZ_ASSERT(mTarget);
EventDispatcher::CreateEvent(aTarget, nullptr, &aEvent, EmptyString(),
getter_AddRefs(mEvent));
NS_ASSERTION(mEvent, "Should never fail to create an event");
mEvent->DuplicatePrivateData();
@ -39,8 +39,9 @@ AsyncEventDispatcher::Run()
if (mDispatchChromeOnly) {
MOZ_ASSERT(mEvent->InternalDOMEvent()->IsTrusted());
nsCOMPtr<nsIDocument> ownerDoc = mEventNode->OwnerDoc();
nsPIDOMWindow* window = ownerDoc->GetWindow();
nsCOMPtr<nsINode> node = do_QueryInterface(mTarget);
MOZ_ASSERT(node, "ChromeOnly dispatch supported with Node targets only!");
nsPIDOMWindow* window = node->OwnerDoc()->GetWindow();
if (!window) {
return NS_ERROR_INVALID_ARG;
}
@ -52,18 +53,23 @@ AsyncEventDispatcher::Run()
EventDispatcher::DispatchDOMEvent(target, nullptr, mEvent,
nullptr, nullptr);
} else {
nsCOMPtr<EventTarget> target = mEventNode.get();
bool defaultActionEnabled; // This is not used because the caller is async
target->DispatchEvent(mEvent, &defaultActionEnabled);
mTarget->DispatchEvent(mEvent, &defaultActionEnabled);
}
} else {
nsIDocument* doc = mEventNode->OwnerDoc();
if (mDispatchChromeOnly) {
nsContentUtils::DispatchChromeEvent(doc, mEventNode, mEventType,
nsCOMPtr<nsINode> node = do_QueryInterface(mTarget);
MOZ_ASSERT(node, "ChromeOnly dispatch supported with Node targets only!");
nsContentUtils::DispatchChromeEvent(node->OwnerDoc(), node, mEventType,
mBubbles, false);
} else {
nsContentUtils::DispatchTrustedEvent(doc, mEventNode, mEventType,
mBubbles, false);
nsCOMPtr<nsIDOMEvent> event;
NS_NewDOMEvent(getter_AddRefs(event), mTarget, nullptr, nullptr);
nsresult rv = event->InitEvent(mEventType, mBubbles, false);
NS_ENSURE_SUCCESS(rv, rv);
event->SetTrusted(true);
bool dummy;
mTarget->DispatchEvent(event, &dummy);
}
}
@ -73,12 +79,14 @@ AsyncEventDispatcher::Run()
nsresult
AsyncEventDispatcher::PostDOMEvent()
{
nsRefPtr<AsyncEventDispatcher> ensureDeletionWhenFailing = this;
return NS_DispatchToCurrentThread(this);
}
void
AsyncEventDispatcher::RunDOMEventWhenSafe()
{
nsRefPtr<AsyncEventDispatcher> ensureDeletionWhenFailing = this;
nsContentUtils::AddScriptRunner(this);
}

View File

@ -26,29 +26,38 @@ namespace mozilla {
class AsyncEventDispatcher : public nsRunnable
{
public:
AsyncEventDispatcher(nsINode* aEventNode, const nsAString& aEventType,
AsyncEventDispatcher(nsINode* aTarget, const nsAString& aEventType,
bool aBubbles, bool aDispatchChromeOnly)
: mEventNode(aEventNode)
: mTarget(aTarget)
, mEventType(aEventType)
, mBubbles(aBubbles)
, mDispatchChromeOnly(aDispatchChromeOnly)
{
}
AsyncEventDispatcher(nsINode* aEventNode, nsIDOMEvent* aEvent)
: mEventNode(aEventNode)
AsyncEventDispatcher(dom::EventTarget* aTarget, const nsAString& aEventType,
bool aBubbles)
: mTarget(aTarget)
, mEventType(aEventType)
, mBubbles(aBubbles)
, mDispatchChromeOnly(false)
{
}
AsyncEventDispatcher(dom::EventTarget* aTarget, nsIDOMEvent* aEvent)
: mTarget(aTarget)
, mEvent(aEvent)
, mDispatchChromeOnly(false)
{
}
AsyncEventDispatcher(nsINode* aEventNode, WidgetEvent& aEvent);
AsyncEventDispatcher(dom::EventTarget* aTarget, WidgetEvent& aEvent);
NS_IMETHOD Run() MOZ_OVERRIDE;
nsresult PostDOMEvent();
void RunDOMEventWhenSafe();
nsCOMPtr<nsINode> mEventNode;
nsCOMPtr<dom::EventTarget> mTarget;
nsCOMPtr<nsIDOMEvent> mEvent;
nsString mEventType;
bool mBubbles;