Coverage Report

Created: 2018-09-25 14:53

/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