tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

EventTarget.cpp (8822B)


      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/dom/EventTarget.h"
      8 
      9 #include "mozilla/EventListenerManager.h"
     10 #include "mozilla/dom/ConstructibleEventTarget.h"
     11 #include "mozilla/dom/EventTargetBinding.h"
     12 #include "mozilla/dom/Nullable.h"
     13 #include "mozilla/dom/WindowProxyHolder.h"
     14 #include "nsGlobalWindowInner.h"
     15 #include "nsGlobalWindowOuter.h"
     16 #include "nsIGlobalObject.h"
     17 #include "nsPIDOMWindow.h"
     18 #include "nsThreadUtils.h"
     19 
     20 namespace mozilla::dom {
     21 
     22 #ifndef NS_BUILD_REFCNT_LOGGING
     23 MozExternalRefCountType EventTarget::NonVirtualAddRef() {
     24  return mRefCnt.incr(this);
     25 }
     26 
     27 MozExternalRefCountType EventTarget::NonVirtualRelease() {
     28  if (mRefCnt.get() == 1) {
     29    return Release();
     30  }
     31  return mRefCnt.decr(this);
     32 }
     33 #endif
     34 
     35 NS_IMETHODIMP_(MozExternalRefCountType) EventTarget::AddRef() {
     36  MOZ_ASSERT_UNREACHABLE("EventTarget::AddRef should not be called");
     37  return 0;
     38 }
     39 
     40 NS_IMETHODIMP_(MozExternalRefCountType) EventTarget::Release() {
     41  MOZ_ASSERT_UNREACHABLE("EventTarget::Release should not be called");
     42  return 0;
     43 }
     44 
     45 NS_IMETHODIMP EventTarget::QueryInterface(REFNSIID aIID, void** aInstancePtr) {
     46  MOZ_ASSERT_UNREACHABLE("EventTarget::QueryInterface should not be called");
     47  *aInstancePtr = nullptr;
     48  return NS_ERROR_FAILURE;
     49 }
     50 
     51 NS_IMETHODIMP_(void) EventTarget::DeleteCycleCollectable() {
     52  MOZ_ASSERT_UNREACHABLE(
     53      "EventTarget::DeleteCycleCollectable should not be called");
     54 }
     55 
     56 /* static */
     57 already_AddRefed<EventTarget> EventTarget::Constructor(
     58    const GlobalObject& aGlobal, ErrorResult& aRv) {
     59  nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(aGlobal.GetAsSupports());
     60  if (!global) {
     61    aRv.Throw(NS_ERROR_UNEXPECTED);
     62    return nullptr;
     63  }
     64  RefPtr<EventTarget> target = new ConstructibleEventTarget(global);
     65  return target.forget();
     66 }
     67 
     68 bool EventTarget::ComputeWantsUntrusted(
     69    const Nullable<bool>& aWantsUntrusted,
     70    const AddEventListenerOptionsOrBoolean* aOptions, ErrorResult& aRv) {
     71  if (aOptions && aOptions->IsAddEventListenerOptions()) {
     72    const auto& options = aOptions->GetAsAddEventListenerOptions();
     73    if (options.mWantUntrusted.WasPassed()) {
     74      return options.mWantUntrusted.Value();
     75    }
     76  }
     77 
     78  if (!aWantsUntrusted.IsNull()) {
     79    return aWantsUntrusted.Value();
     80  }
     81 
     82  bool defaultWantsUntrusted = ComputeDefaultWantsUntrusted(aRv);
     83  if (aRv.Failed()) {
     84    return false;
     85  }
     86 
     87  return defaultWantsUntrusted;
     88 }
     89 
     90 void EventTarget::AddEventListener(
     91    const nsAString& aType, EventListener* aCallback,
     92    const AddEventListenerOptionsOrBoolean& aOptions,
     93    const Nullable<bool>& aWantsUntrusted) {
     94  IgnoredErrorResult rv;
     95  bool wantsUntrusted = ComputeWantsUntrusted(aWantsUntrusted, &aOptions, rv);
     96  if (NS_WARN_IF(rv.Failed())) {
     97    return;
     98  }
     99 
    100  EventListenerManager* elm = GetOrCreateListenerManager();
    101  if (!elm) {
    102    return;
    103  }
    104 
    105  elm->AddEventListener(aType, aCallback, aOptions, wantsUntrusted);
    106 }
    107 
    108 nsresult EventTarget::AddEventListener(const nsAString& aType,
    109                                       nsIDOMEventListener* aListener,
    110                                       bool aUseCapture,
    111                                       const Nullable<bool>& aWantsUntrusted) {
    112  ErrorResult rv;
    113  bool wantsUntrusted = ComputeWantsUntrusted(aWantsUntrusted, nullptr, rv);
    114  if (rv.Failed()) {
    115    return rv.StealNSResult();
    116  }
    117 
    118  EventListenerManager* elm = GetOrCreateListenerManager();
    119  NS_ENSURE_STATE(elm);
    120  elm->AddEventListener(aType, aListener, aUseCapture, wantsUntrusted);
    121  return NS_OK;
    122 }
    123 
    124 void EventTarget::RemoveEventListener(
    125    const nsAString& aType, EventListener* aListener,
    126    const EventListenerOptionsOrBoolean& aOptions) {
    127  EventListenerManager* elm = GetExistingListenerManager();
    128  if (elm) {
    129    elm->RemoveEventListener(aType, aListener, aOptions);
    130  }
    131 }
    132 
    133 void EventTarget::RemoveEventListener(const nsAString& aType,
    134                                      nsIDOMEventListener* aListener,
    135                                      bool aUseCapture) {
    136  EventListenerManager* elm = GetExistingListenerManager();
    137  if (elm) {
    138    elm->RemoveEventListener(aType, aListener, aUseCapture);
    139  }
    140 }
    141 
    142 nsresult EventTarget::AddSystemEventListener(
    143    const nsAString& aType, nsIDOMEventListener* aListener, bool aUseCapture,
    144    const Nullable<bool>& aWantsUntrusted) {
    145  ErrorResult rv;
    146  bool wantsUntrusted = ComputeWantsUntrusted(aWantsUntrusted, nullptr, rv);
    147  if (rv.Failed()) {
    148    return rv.StealNSResult();
    149  }
    150 
    151  EventListenerManager* elm = GetOrCreateListenerManager();
    152  NS_ENSURE_STATE(elm);
    153 
    154  EventListenerFlags flags;
    155  flags.mInSystemGroup = true;
    156  flags.mCapture = aUseCapture;
    157  flags.mAllowUntrustedEvents = wantsUntrusted;
    158  elm->AddEventListenerByType(aListener, aType, flags);
    159  return NS_OK;
    160 }
    161 
    162 void EventTarget::RemoveSystemEventListener(const nsAString& aType,
    163                                            nsIDOMEventListener* aListener,
    164                                            bool aUseCapture) {
    165  EventListenerManager* elm = GetExistingListenerManager();
    166  if (elm) {
    167    EventListenerFlags flags;
    168    flags.mInSystemGroup = true;
    169    flags.mCapture = aUseCapture;
    170    elm->RemoveEventListenerByType(aListener, aType, flags);
    171  }
    172 }
    173 
    174 EventHandlerNonNull* EventTarget::GetEventHandler(nsAtom* aType) {
    175  EventListenerManager* elm = GetExistingListenerManager();
    176  return elm ? elm->GetEventHandler(aType) : nullptr;
    177 }
    178 
    179 void EventTarget::SetEventHandler(const nsAString& aType,
    180                                  EventHandlerNonNull* aHandler,
    181                                  ErrorResult& aRv) {
    182  if (!StringBeginsWith(aType, u"on"_ns)) {
    183    aRv.Throw(NS_ERROR_INVALID_ARG);
    184    return;
    185  }
    186  RefPtr<nsAtom> type = NS_Atomize(aType);
    187  SetEventHandler(type, aHandler);
    188 }
    189 
    190 void EventTarget::SetEventHandler(nsAtom* aType,
    191                                  EventHandlerNonNull* aHandler) {
    192  GetOrCreateListenerManager()->SetEventHandler(aType, aHandler);
    193 }
    194 
    195 bool EventTarget::HasNonSystemGroupListenersForUntrustedKeyEvents() const {
    196  EventListenerManager* elm = GetExistingListenerManager();
    197  return elm && elm->HasNonSystemGroupListenersForUntrustedKeyEvents();
    198 }
    199 
    200 bool EventTarget::HasNonPassiveNonSystemGroupListenersForUntrustedKeyEvents()
    201    const {
    202  EventListenerManager* elm = GetExistingListenerManager();
    203  return elm &&
    204         elm->HasNonPassiveNonSystemGroupListenersForUntrustedKeyEvents();
    205 }
    206 
    207 bool EventTarget::IsApzAware() const {
    208  EventListenerManager* elm = GetExistingListenerManager();
    209  return elm && elm->HasApzAwareListeners();
    210 }
    211 
    212 void EventTarget::DispatchEvent(Event& aEvent) {
    213  // The caller type doesn't really matter if we don't care about the
    214  // return value, but let's be safe and pass NonSystem.
    215  (void)DispatchEvent(aEvent, CallerType::NonSystem, IgnoreErrors());
    216 }
    217 
    218 void EventTarget::DispatchEvent(Event& aEvent, ErrorResult& aRv) {
    219  // The caller type doesn't really matter if we don't care about the
    220  // return value, but let's be safe and pass NonSystem.
    221  (void)DispatchEvent(aEvent, CallerType::NonSystem, IgnoreErrors());
    222 }
    223 
    224 Nullable<WindowProxyHolder> EventTarget::GetOwnerGlobalForBindings() {
    225  nsPIDOMWindowOuter* win = GetOwnerGlobalForBindingsInternal();
    226  if (!win) {
    227    return nullptr;
    228  }
    229 
    230  return WindowProxyHolder(win->GetBrowsingContext());
    231 }
    232 
    233 nsPIDOMWindowInner* EventTarget::GetAsInnerWindow() {
    234  return IsInnerWindow() ? static_cast<nsGlobalWindowInner*>(this) : nullptr;
    235 }
    236 
    237 const nsPIDOMWindowInner* EventTarget::GetAsInnerWindow() const {
    238  return IsInnerWindow() ? static_cast<const nsGlobalWindowInner*>(this)
    239                         : nullptr;
    240 }
    241 
    242 nsPIDOMWindowOuter* EventTarget::GetAsOuterWindow() {
    243  return IsOuterWindow() ? static_cast<nsGlobalWindowOuter*>(this) : nullptr;
    244 }
    245 
    246 const nsPIDOMWindowOuter* EventTarget::GetAsOuterWindow() const {
    247  return IsOuterWindow() ? static_cast<const nsGlobalWindowOuter*>(this)
    248                         : nullptr;
    249 }
    250 
    251 nsPIDOMWindowInner* EventTarget::AsInnerWindow() {
    252  MOZ_DIAGNOSTIC_ASSERT(IsInnerWindow());
    253  return static_cast<nsGlobalWindowInner*>(this);
    254 }
    255 
    256 const nsPIDOMWindowInner* EventTarget::AsInnerWindow() const {
    257  MOZ_DIAGNOSTIC_ASSERT(IsInnerWindow());
    258  return static_cast<const nsGlobalWindowInner*>(this);
    259 }
    260 
    261 nsPIDOMWindowOuter* EventTarget::AsOuterWindow() {
    262  MOZ_DIAGNOSTIC_ASSERT(IsOuterWindow());
    263  return static_cast<nsGlobalWindowOuter*>(this);
    264 }
    265 
    266 const nsPIDOMWindowOuter* EventTarget::AsOuterWindow() const {
    267  MOZ_DIAGNOSTIC_ASSERT(IsOuterWindow());
    268  return static_cast<const nsGlobalWindowOuter*>(this);
    269 }
    270 
    271 }  // namespace mozilla::dom