Backed out changeset 2450366cf7ca (bug 1891629) for causing win msix mochitest failures
[gecko.git] / dom / events / AsyncEventDispatcher.cpp
blob297a03d7cb5ded6426557b1c1068b11f90080efd
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "mozilla/AsyncEventDispatcher.h"
8 #include "mozilla/BasicEvents.h"
9 #include "mozilla/EventDispatcher.h"
10 #include "mozilla/dom/DocumentInlines.h"
11 #include "mozilla/dom/Event.h"
12 #include "mozilla/dom/EventTarget.h"
13 #include "nsContentUtils.h"
15 namespace mozilla {
17 using namespace dom;
19 /******************************************************************************
20 * mozilla::AsyncEventDispatcher
21 ******************************************************************************/
23 AsyncEventDispatcher::AsyncEventDispatcher(EventTarget* aTarget,
24 WidgetEvent& aEvent)
25 : CancelableRunnable("AsyncEventDispatcher"),
26 mTarget(aTarget),
27 mEventMessage(eUnidentifiedEvent) {
28 MOZ_ASSERT(mTarget);
29 RefPtr<Event> event =
30 EventDispatcher::CreateEvent(aTarget, nullptr, &aEvent, u""_ns);
31 mEvent = std::move(event);
32 mEventType.SetIsVoid(true);
33 NS_ASSERTION(mEvent, "Should never fail to create an event");
34 mEvent->DuplicatePrivateData();
35 mEvent->SetTrusted(aEvent.IsTrusted());
38 NS_IMETHODIMP
39 AsyncEventDispatcher::Run() {
40 if (mCanceled) {
41 return NS_OK;
43 nsINode* node = nsINode::FromEventTargetOrNull(mTarget);
44 if (mCheckStillInDoc) {
45 MOZ_ASSERT(node);
46 if (!node->IsInComposedDoc()) {
47 return NS_OK;
50 mTarget->AsyncEventRunning(this);
51 if (mEventMessage != eUnidentifiedEvent) {
52 MOZ_ASSERT(mComposed == Composed::eDefault);
53 return nsContentUtils::DispatchTrustedEvent<WidgetEvent>(
54 node->OwnerDoc(), mTarget, mEventMessage, mCanBubble, Cancelable::eNo,
55 nullptr /* aDefaultAction */, mOnlyChromeDispatch);
57 // MOZ_KnownLives because this instance shouldn't be touched while running.
58 if (mEvent) {
59 DispatchEventOnTarget(MOZ_KnownLive(mTarget), MOZ_KnownLive(mEvent),
60 mOnlyChromeDispatch, mComposed);
61 } else {
62 DispatchEventOnTarget(MOZ_KnownLive(mTarget), mEventType, mCanBubble,
63 mOnlyChromeDispatch, mComposed);
65 return NS_OK;
68 // static
69 void AsyncEventDispatcher::DispatchEventOnTarget(
70 EventTarget* aTarget, const nsAString& aEventType, CanBubble aCanBubble,
71 ChromeOnlyDispatch aOnlyChromeDispatch, Composed aComposed) {
72 RefPtr<Event> event = NS_NewDOMEvent(aTarget, nullptr, nullptr);
73 event->InitEvent(aEventType, aCanBubble, Cancelable::eNo);
74 event->SetTrusted(true);
75 DispatchEventOnTarget(aTarget, event, aOnlyChromeDispatch, aComposed);
78 // static
79 void AsyncEventDispatcher::DispatchEventOnTarget(
80 EventTarget* aTarget, Event* aEvent, ChromeOnlyDispatch aOnlyChromeDispatch,
81 Composed aComposed) {
82 if (aComposed != Composed::eDefault) {
83 aEvent->WidgetEventPtr()->mFlags.mComposed = aComposed == Composed::eYes;
85 if (aOnlyChromeDispatch == ChromeOnlyDispatch::eYes) {
86 MOZ_ASSERT(aEvent->IsTrusted());
87 aEvent->WidgetEventPtr()->mFlags.mOnlyChromeDispatch = true;
89 aTarget->DispatchEvent(*aEvent);
92 nsresult AsyncEventDispatcher::Cancel() {
93 mCanceled = true;
94 return NS_OK;
97 nsresult AsyncEventDispatcher::PostDOMEvent() {
98 RefPtr<AsyncEventDispatcher> ensureDeletionWhenFailing = this;
99 return NS_DispatchToCurrentThread(ensureDeletionWhenFailing.forget());
102 void AsyncEventDispatcher::RunDOMEventWhenSafe() {
103 RefPtr<AsyncEventDispatcher> ensureDeletionWhenFailing = this;
104 nsContentUtils::AddScriptRunner(ensureDeletionWhenFailing.forget());
107 // static
108 void AsyncEventDispatcher::RunDOMEventWhenSafe(
109 EventTarget& aTarget, const nsAString& aEventType, CanBubble aCanBubble,
110 ChromeOnlyDispatch aOnlyChromeDispatch /* = ChromeOnlyDispatch::eNo */,
111 Composed aComposed /* = Composed::eDefault */) {
112 if (nsContentUtils::IsSafeToRunScript()) {
113 OwningNonNull<EventTarget> target = aTarget;
114 DispatchEventOnTarget(target, aEventType, aCanBubble, aOnlyChromeDispatch,
115 aComposed);
116 return;
118 (new AsyncEventDispatcher(&aTarget, aEventType, aCanBubble,
119 aOnlyChromeDispatch, aComposed))
120 ->RunDOMEventWhenSafe();
123 void AsyncEventDispatcher::RunDOMEventWhenSafe(
124 EventTarget& aTarget, Event& aEvent,
125 ChromeOnlyDispatch aOnlyChromeDispatch /* = ChromeOnlyDispatch::eNo */) {
126 if (nsContentUtils::IsSafeToRunScript()) {
127 DispatchEventOnTarget(&aTarget, &aEvent, aOnlyChromeDispatch,
128 Composed::eDefault);
129 return;
131 (new AsyncEventDispatcher(&aTarget, do_AddRef(&aEvent), aOnlyChromeDispatch))
132 ->RunDOMEventWhenSafe();
135 // static
136 nsresult AsyncEventDispatcher::RunDOMEventWhenSafe(
137 nsINode& aTarget, WidgetEvent& aEvent,
138 nsEventStatus* aEventStatus /* = nullptr */) {
139 if (nsContentUtils::IsSafeToRunScript()) {
140 // MOZ_KnownLive due to bug 1832202
141 nsPresContext* presContext = aTarget.OwnerDoc()->GetPresContext();
142 return EventDispatcher::Dispatch(MOZ_KnownLive(&aTarget),
143 MOZ_KnownLive(presContext), &aEvent,
144 nullptr, aEventStatus);
146 (new AsyncEventDispatcher(&aTarget, aEvent))->RunDOMEventWhenSafe();
147 return NS_OK;
150 void AsyncEventDispatcher::RequireNodeInDocument() {
151 MOZ_ASSERT(mTarget);
152 MOZ_ASSERT(mTarget->IsNode());
153 mCheckStillInDoc = true;
156 } // namespace mozilla