/src/mozilla-central/dom/events/AsyncEventDispatcher.cpp
Line | Count | Source (jump to first uncovered line) |
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/. */ |
6 | | |
7 | | #include "mozilla/AsyncEventDispatcher.h" |
8 | | #include "mozilla/BasicEvents.h" |
9 | | #include "mozilla/EventDispatcher.h" |
10 | | #include "mozilla/dom/Event.h" |
11 | | #include "mozilla/dom/EventTarget.h" |
12 | | #include "nsContentUtils.h" |
13 | | |
14 | | namespace mozilla { |
15 | | |
16 | | using namespace dom; |
17 | | |
18 | | /****************************************************************************** |
19 | | * mozilla::AsyncEventDispatcher |
20 | | ******************************************************************************/ |
21 | | |
22 | | AsyncEventDispatcher::AsyncEventDispatcher(EventTarget* aTarget, |
23 | | WidgetEvent& aEvent) |
24 | | : CancelableRunnable("AsyncEventDispatcher") |
25 | | , mTarget(aTarget) |
26 | | , mEventMessage(eUnidentifiedEvent) |
27 | 0 | { |
28 | 0 | MOZ_ASSERT(mTarget); |
29 | 0 | RefPtr<Event> event = |
30 | 0 | EventDispatcher::CreateEvent(aTarget, nullptr, &aEvent, EmptyString()); |
31 | 0 | mEvent = event.forget(); |
32 | 0 | mEventType.SetIsVoid(true); |
33 | 0 | NS_ASSERTION(mEvent, "Should never fail to create an event"); |
34 | 0 | mEvent->DuplicatePrivateData(); |
35 | 0 | mEvent->SetTrusted(aEvent.IsTrusted()); |
36 | 0 | } |
37 | | |
38 | | NS_IMETHODIMP |
39 | | AsyncEventDispatcher::Run() |
40 | 0 | { |
41 | 0 | if (mCanceled) { |
42 | 0 | return NS_OK; |
43 | 0 | } |
44 | 0 | nsCOMPtr<nsINode> node = do_QueryInterface(mTarget); |
45 | 0 | if (mCheckStillInDoc) { |
46 | 0 | MOZ_ASSERT(node); |
47 | 0 | if (!node->IsInComposedDoc()) { |
48 | 0 | return NS_OK; |
49 | 0 | } |
50 | 0 | } |
51 | 0 | mTarget->AsyncEventRunning(this); |
52 | 0 | if (mEventMessage != eUnidentifiedEvent) { |
53 | 0 | MOZ_ASSERT(mComposed == Composed::eDefault); |
54 | 0 | return nsContentUtils::DispatchTrustedEvent<WidgetEvent> |
55 | 0 | (node->OwnerDoc(), mTarget, mEventMessage, mCanBubble, |
56 | 0 | Cancelable::eNo, nullptr /* aDefaultAction */, mOnlyChromeDispatch); |
57 | 0 | } |
58 | 0 | RefPtr<Event> event = mEvent; |
59 | 0 | if (!event) { |
60 | 0 | event = NS_NewDOMEvent(mTarget, nullptr, nullptr); |
61 | 0 | event->InitEvent(mEventType, mCanBubble, Cancelable::eNo); |
62 | 0 | event->SetTrusted(true); |
63 | 0 | } |
64 | 0 | if (mComposed != Composed::eDefault) { |
65 | 0 | event->WidgetEventPtr()->mFlags.mComposed = |
66 | 0 | mComposed == Composed::eYes; |
67 | 0 | } |
68 | 0 | if (mOnlyChromeDispatch == ChromeOnlyDispatch::eYes) { |
69 | 0 | MOZ_ASSERT(event->IsTrusted()); |
70 | 0 | event->WidgetEventPtr()->mFlags.mOnlyChromeDispatch = true; |
71 | 0 | } |
72 | 0 | mTarget->DispatchEvent(*event); |
73 | 0 | return NS_OK; |
74 | 0 | } |
75 | | |
76 | | nsresult |
77 | | AsyncEventDispatcher::Cancel() |
78 | 0 | { |
79 | 0 | mCanceled = true; |
80 | 0 | return NS_OK; |
81 | 0 | } |
82 | | |
83 | | nsresult |
84 | | AsyncEventDispatcher::PostDOMEvent() |
85 | 0 | { |
86 | 0 | RefPtr<AsyncEventDispatcher> ensureDeletionWhenFailing = this; |
87 | 0 | if (NS_IsMainThread()) { |
88 | 0 | if (nsCOMPtr<nsIGlobalObject> global = mTarget->GetOwnerGlobal()) { |
89 | 0 | return global->Dispatch(TaskCategory::Other, ensureDeletionWhenFailing.forget()); |
90 | 0 | } |
91 | 0 | |
92 | 0 | // Sometimes GetOwnerGlobal returns null because it uses |
93 | 0 | // GetScriptHandlingObject rather than GetScopeObject. |
94 | 0 | if (nsCOMPtr<nsINode> node = do_QueryInterface(mTarget)) { |
95 | 0 | nsCOMPtr<nsIDocument> doc = node->OwnerDoc(); |
96 | 0 | return doc->Dispatch(TaskCategory::Other, ensureDeletionWhenFailing.forget()); |
97 | 0 | } |
98 | 0 | } |
99 | 0 | return NS_DispatchToCurrentThread(this); |
100 | 0 | } |
101 | | |
102 | | void |
103 | | AsyncEventDispatcher::RunDOMEventWhenSafe() |
104 | 0 | { |
105 | 0 | RefPtr<AsyncEventDispatcher> ensureDeletionWhenFailing = this; |
106 | 0 | nsContentUtils::AddScriptRunner(this); |
107 | 0 | } |
108 | | |
109 | | void |
110 | | AsyncEventDispatcher::RequireNodeInDocument() |
111 | 0 | { |
112 | | #ifdef DEBUG |
113 | | nsCOMPtr<nsINode> node = do_QueryInterface(mTarget); |
114 | | MOZ_ASSERT(node); |
115 | | #endif |
116 | |
|
117 | 0 | mCheckStillInDoc = true; |
118 | 0 | } |
119 | | |
120 | | /****************************************************************************** |
121 | | * mozilla::LoadBlockingAsyncEventDispatcher |
122 | | ******************************************************************************/ |
123 | | |
124 | | LoadBlockingAsyncEventDispatcher::~LoadBlockingAsyncEventDispatcher() |
125 | 0 | { |
126 | 0 | if (mBlockedDoc) { |
127 | 0 | mBlockedDoc->UnblockOnload(true); |
128 | 0 | } |
129 | 0 | } |
130 | | |
131 | | } // namespace mozilla |