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