tor-browser

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

EventTarget.h (20301B)


      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 #ifndef mozilla_dom_EventTarget_h_
      8 #define mozilla_dom_EventTarget_h_
      9 
     10 #include "mozilla/dom/Nullable.h"
     11 #include "nsAtom.h"
     12 #include "nsISupports.h"
     13 #include "nsWrapperCache.h"
     14 
     15 class nsIDOMEventListener;
     16 class nsIGlobalObject;
     17 class nsINode;
     18 class nsPIDOMWindowInner;
     19 class nsPIDOMWindowOuter;
     20 class nsPIWindowRoot;
     21 class nsScreen;
     22 
     23 namespace mozilla {
     24 
     25 class AsyncEventDispatcher;
     26 class ErrorResult;
     27 class EventChainPostVisitor;
     28 class EventChainPreVisitor;
     29 class EventChainVisitor;
     30 class EventListenerManager;
     31 
     32 namespace dom {
     33 
     34 class AddEventListenerOptionsOrBoolean;
     35 class Event;
     36 class EventListener;
     37 class EventListenerOptionsOrBoolean;
     38 class EventHandlerNonNull;
     39 class GlobalObject;
     40 class Navigation;
     41 class WindowProxyHolder;
     42 enum class CallerType : uint32_t;
     43 enum class EventCallbackDebuggerNotificationType : uint8_t;
     44 
     45 // IID for the dom::EventTarget interface
     46 #define NS_EVENTTARGET_IID \
     47  {0xde651c36, 0x0053, 0x4c67, {0xb1, 0x3d, 0x67, 0xb9, 0x40, 0xfc, 0x82, 0xe4}}
     48 
     49 class EventTarget : public nsISupports, public nsWrapperCache {
     50 public:
     51  NS_INLINE_DECL_STATIC_IID(NS_EVENTTARGET_IID)
     52 
     53  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
     54 
     55  void SetIsOnMainThread() {
     56    MOZ_ASSERT(NS_IsMainThread());
     57    mRefCnt.SetIsOnMainThread();
     58  }
     59 
     60 #ifndef NS_BUILD_REFCNT_LOGGING
     61  MozExternalRefCountType NonVirtualAddRef();
     62  MozExternalRefCountType NonVirtualRelease();
     63 #endif
     64 
     65  // WebIDL API
     66  static already_AddRefed<EventTarget> Constructor(const GlobalObject& aGlobal,
     67                                                   ErrorResult& aRv);
     68  void AddEventListener(const nsAString& aType, EventListener* aCallback,
     69                        const AddEventListenerOptionsOrBoolean& aOptions,
     70                        const Nullable<bool>& aWantsUntrusted);
     71  void RemoveEventListener(const nsAString& aType, EventListener* aCallback,
     72                           const EventListenerOptionsOrBoolean& aOptions);
     73 
     74 protected:
     75  /**
     76   * This method allows addition of event listeners represented by
     77   * nsIDOMEventListener, with almost the same semantics as the
     78   * standard AddEventListener.  The one difference is that it just
     79   * has a "use capture" boolean, not an EventListenerOptions.
     80   */
     81  nsresult AddEventListener(const nsAString& aType,
     82                            nsIDOMEventListener* aListener, bool aUseCapture,
     83                            const Nullable<bool>& aWantsUntrusted);
     84 
     85 public:
     86  /**
     87   * Helper methods to make the nsIDOMEventListener version of
     88   * AddEventListener simpler to call for consumers.
     89   */
     90  nsresult AddEventListener(const nsAString& aType,
     91                            nsIDOMEventListener* aListener, bool aUseCapture) {
     92    return AddEventListener(aType, aListener, aUseCapture, Nullable<bool>());
     93  }
     94  nsresult AddEventListener(const nsAString& aType,
     95                            nsIDOMEventListener* aListener, bool aUseCapture,
     96                            bool aWantsUntrusted) {
     97    return AddEventListener(aType, aListener, aUseCapture,
     98                            Nullable<bool>(aWantsUntrusted));
     99  }
    100 
    101  /**
    102   * This method allows the removal of event listeners represented by
    103   * nsIDOMEventListener from the event target, with the same semantics as the
    104   * standard RemoveEventListener.
    105   */
    106  void RemoveEventListener(const nsAString& aType,
    107                           nsIDOMEventListener* aListener, bool aUseCapture);
    108  /**
    109   * RemoveSystemEventListener() should be used if you have used
    110   * AddSystemEventListener().
    111   */
    112  void RemoveSystemEventListener(const nsAString& aType,
    113                                 nsIDOMEventListener* aListener,
    114                                 bool aUseCapture);
    115 
    116  /**
    117   * Add a system event listener with the default wantsUntrusted value.
    118   */
    119  nsresult AddSystemEventListener(const nsAString& aType,
    120                                  nsIDOMEventListener* aListener,
    121                                  bool aUseCapture) {
    122    return AddSystemEventListener(aType, aListener, aUseCapture,
    123                                  Nullable<bool>());
    124  }
    125 
    126  /**
    127   * Add a system event listener with the given wantsUntrusted value.
    128   */
    129  nsresult AddSystemEventListener(const nsAString& aType,
    130                                  nsIDOMEventListener* aListener,
    131                                  bool aUseCapture, bool aWantsUntrusted) {
    132    return AddSystemEventListener(aType, aListener, aUseCapture,
    133                                  Nullable<bool>(aWantsUntrusted));
    134  }
    135 
    136  virtual bool IsNode() const { return false; }
    137  inline nsINode* GetAsNode();
    138  inline const nsINode* GetAsNode() const;
    139  inline nsINode* AsNode();
    140  inline const nsINode* AsNode() const;
    141 
    142  virtual bool IsNavigation() const { return false; }
    143  inline Navigation* GetAsNavigation();
    144  inline const Navigation* GetAsNavigation() const;
    145  inline Navigation* AsNavigation();
    146  inline const Navigation* AsNavigation() const;
    147 
    148  virtual bool IsScreen() const { return false; }
    149  inline nsScreen* GetAsScreen();
    150  inline const nsScreen* GetAsScreen() const;
    151  inline nsScreen* AsScreen();
    152  inline const nsScreen* AsScreen() const;
    153 
    154  virtual bool IsInnerWindow() const { return false; }
    155  virtual bool IsOuterWindow() const { return false; }
    156  virtual bool IsRootWindow() const { return false; }
    157  nsPIDOMWindowInner* GetAsInnerWindow();
    158  const nsPIDOMWindowInner* GetAsInnerWindow() const;
    159  nsPIDOMWindowOuter* GetAsOuterWindow();
    160  const nsPIDOMWindowOuter* GetAsOuterWindow() const;
    161  inline nsPIWindowRoot* GetAsWindowRoot();
    162  inline const nsPIWindowRoot* GetAsWindowRoot() const;
    163  nsPIDOMWindowInner* AsInnerWindow();
    164  const nsPIDOMWindowInner* AsInnerWindow() const;
    165  nsPIDOMWindowOuter* AsOuterWindow();
    166  const nsPIDOMWindowOuter* AsOuterWindow() const;
    167  inline nsPIWindowRoot* AsWindowRoot();
    168  inline const nsPIWindowRoot* AsWindowRoot() const;
    169 
    170  /**
    171   * Returns the EventTarget object which should be used as the target
    172   * of DOMEvents.
    173   * Usually |this| is returned, but for example Window (inner windw) returns
    174   * the WindowProxy (outer window).
    175   */
    176  virtual EventTarget* GetTargetForDOMEvent() { return this; };
    177 
    178  /**
    179   * Returns the EventTarget object which should be used as the target
    180   * of the event and when constructing event target chain.
    181   * Usually |this| is returned, but for example WindowProxy (outer window)
    182   * returns the Window (inner window).
    183   */
    184  virtual EventTarget* GetTargetForEventTargetChain() { return this; }
    185 
    186  /**
    187   * The most general DispatchEvent method.  This is the one the bindings call.
    188   */
    189  // TODO: Convert this to MOZ_CAN_RUN_SCRIPT (bug 1415230)
    190  MOZ_CAN_RUN_SCRIPT_BOUNDARY virtual bool DispatchEvent(Event& aEvent,
    191                                                         CallerType aCallerType,
    192                                                         ErrorResult& aRv) = 0;
    193 
    194  /**
    195   * A version of DispatchEvent you can use if you really don't care whether it
    196   * succeeds or not and whether default is prevented or not.
    197   */
    198  // TODO: Convert this to MOZ_CAN_RUN_SCRIPT (bug 1415230)
    199  MOZ_CAN_RUN_SCRIPT_BOUNDARY void DispatchEvent(Event& aEvent);
    200 
    201  /**
    202   * A version of DispatchEvent you can use if you really don't care whether
    203   * default is prevented or not.
    204   */
    205  // TODO: Convert this to MOZ_CAN_RUN_SCRIPT (bug 1415230)
    206  MOZ_CAN_RUN_SCRIPT_BOUNDARY void DispatchEvent(Event& aEvent,
    207                                                 ErrorResult& aRv);
    208 
    209  nsIGlobalObject* GetParentObject() const { return GetOwnerGlobal(); }
    210 
    211  // Note, this takes the type in onfoo form!
    212  EventHandlerNonNull* GetEventHandler(const nsAString& aType) {
    213    RefPtr<nsAtom> type = NS_Atomize(aType);
    214    return GetEventHandler(type);
    215  }
    216 
    217  // Note, this takes the type in onfoo form!
    218  void SetEventHandler(const nsAString& aType, EventHandlerNonNull* aHandler,
    219                       ErrorResult& rv);
    220 
    221  // For an event 'foo' aType will be 'onfoo'.
    222  virtual void EventListenerAdded(nsAtom* aType) {}
    223 
    224  // For an event 'foo' aType will be 'onfoo'.
    225  virtual void EventListenerRemoved(nsAtom* aType) {}
    226 
    227  // Returns an outer window that corresponds to the inner window this event
    228  // target is associated with.  Will return null if the inner window is not the
    229  // current inner or if there is no window around at all.
    230  Nullable<WindowProxyHolder> GetOwnerGlobalForBindings();
    231  virtual nsPIDOMWindowOuter* GetOwnerGlobalForBindingsInternal() = 0;
    232 
    233  // The global object this event target is associated with, if any.
    234  // This may be an inner window or some other global object.  This
    235  // will never be an outer window.
    236  virtual nsIGlobalObject* GetOwnerGlobal() const = 0;
    237 
    238  /**
    239   * Get the event listener manager, creating it if it does not already exist.
    240   */
    241  virtual EventListenerManager* GetOrCreateListenerManager() = 0;
    242 
    243  /**
    244   * Get the event listener manager, returning null if it does not already
    245   * exist.
    246   */
    247  virtual EventListenerManager* GetExistingListenerManager() const = 0;
    248 
    249  virtual Maybe<EventCallbackDebuggerNotificationType>
    250  GetDebuggerNotificationType() const {
    251    return Nothing();
    252  }
    253 
    254  // Called from AsyncEventDispatcher to notify it is running.
    255  virtual void AsyncEventRunning(AsyncEventDispatcher* aEvent) {}
    256 
    257  // Used by APZ to determine whether this event target has non-chrome event
    258  // listeners for untrusted key events.
    259  bool HasNonSystemGroupListenersForUntrustedKeyEvents() const;
    260 
    261  // Used by APZ to determine whether this event target has non-chrome and
    262  // non-passive event listeners for untrusted key events.
    263  bool HasNonPassiveNonSystemGroupListenersForUntrustedKeyEvents() const;
    264 
    265  virtual bool IsApzAware() const;
    266 
    267  /**
    268   * Called before the capture phase of the event flow.
    269   * This is used to create the event target chain and implementations
    270   * should set the necessary members of EventChainPreVisitor.
    271   * At least aVisitor.mCanHandle must be set,
    272   * usually also aVisitor.mParentTarget if mCanHandle is true.
    273   * mCanHandle says that this object can handle the aVisitor.mEvent event and
    274   * the mParentTarget is the possible parent object for the event target chain.
    275   * @see EventDispatcher.h for more documentation about aVisitor.
    276   *
    277   * @param aVisitor the visitor object which is used to create the
    278   *                 event target chain for event dispatching.
    279   *
    280   * @note Only EventDispatcher should call this method.
    281   */
    282  virtual void GetEventTargetParent(EventChainPreVisitor& aVisitor) = 0;
    283 
    284  /**
    285   * Called on the activation target during dispatch of activation events.
    286   * https://dom.spec.whatwg.org/#eventtarget-legacy-pre-activation-behavior
    287   */
    288  virtual void LegacyPreActivationBehavior(EventChainVisitor& aVisitor) {}
    289 
    290  /**
    291   * Called on the activation target during dispatch of activation events.
    292   * https://dom.spec.whatwg.org/#eventtarget-activation-behavior
    293   */
    294  MOZ_CAN_RUN_SCRIPT
    295  virtual void ActivationBehavior(EventChainPostVisitor& aVisitor) {}
    296 
    297  /**
    298   * Called on the activation target during dispatch of activation events.
    299   * https://dom.spec.whatwg.org/#eventtarget-legacy-canceled-activation-behavior
    300   */
    301  virtual void LegacyCanceledActivationBehavior(
    302      EventChainPostVisitor& aVisitor) {}
    303 
    304  /**
    305   * Called before the capture phase of the event flow and after event target
    306   * chain creation. This is used to handle things that must be executed before
    307   * dispatching the event to DOM.
    308   */
    309  virtual nsresult PreHandleEvent(EventChainVisitor& aVisitor) { return NS_OK; }
    310 
    311  /**
    312   * If EventChainPreVisitor.mWantsWillHandleEvent is set true,
    313   * called just before possible event handlers on this object will be called.
    314   */
    315  virtual void WillHandleEvent(EventChainPostVisitor& aVisitor) {}
    316 
    317  /**
    318   * Called after the bubble phase of the system event group.
    319   * The default handling of the event should happen here.
    320   * @param aVisitor the visitor object which is used during post handling.
    321   *
    322   * @see EventDispatcher.h for documentation about aVisitor.
    323   * @note Only EventDispatcher should call this method.
    324   */
    325  MOZ_CAN_RUN_SCRIPT
    326  virtual nsresult PostHandleEvent(EventChainPostVisitor& aVisitor) = 0;
    327 
    328 protected:
    329  EventHandlerNonNull* GetEventHandler(nsAtom* aType);
    330  void SetEventHandler(nsAtom* aType, EventHandlerNonNull* aHandler);
    331 
    332  /**
    333   * Hook for AddEventListener that allows it to compute the right
    334   * wantsUntrusted boolean when one is not provided.  If this returns failure,
    335   * the listener will not be added.
    336   *
    337   * This hook will NOT be called unless aWantsUntrusted is null in
    338   * AddEventListener.  If you need to take action when event listeners are
    339   * added, use EventListenerAdded.  Especially because not all event listener
    340   * additions go through AddEventListener!
    341   */
    342  virtual bool ComputeDefaultWantsUntrusted(ErrorResult& aRv) = 0;
    343 
    344  /**
    345   * A method to compute the right wantsUntrusted value for AddEventListener.
    346   * This will call the above hook as needed.
    347   *
    348   * If aOptions is non-null, and it contains a value for mWantUntrusted, that
    349   * value takes precedence over aWantsUntrusted.
    350   */
    351  bool ComputeWantsUntrusted(const Nullable<bool>& aWantsUntrusted,
    352                             const AddEventListenerOptionsOrBoolean* aOptions,
    353                             ErrorResult& aRv);
    354 
    355  /**
    356   * addSystemEventListener() adds an event listener of aType to the system
    357   * group.  Typically, core code should use the system group for listening to
    358   * content (i.e., non-chrome) element's events.  If core code uses
    359   * EventTarget::AddEventListener for a content node, it means
    360   * that the listener cannot listen to the event when web content calls
    361   * stopPropagation() of the event.
    362   *
    363   * @param aType            An event name you're going to handle.
    364   * @param aListener        An event listener.
    365   * @param aUseCapture      true if you want to listen the event in capturing
    366   *                         phase.  Otherwise, false.
    367   * @param aWantsUntrusted  true if you want to handle untrusted events.
    368   *                         false if not.
    369   *                         Null if you want the default behavior.
    370   */
    371  nsresult AddSystemEventListener(const nsAString& aType,
    372                                  nsIDOMEventListener* aListener,
    373                                  bool aUseCapture,
    374                                  const Nullable<bool>& aWantsUntrusted);
    375 };
    376 
    377 #define NS_IMPL_FROMEVENTTARGET_GENERIC(_class, _check, _const)             \
    378  template <typename T>                                                     \
    379  static auto FromEventTarget(_const T& aEventTarget)                       \
    380      -> decltype(static_cast<_const _class*>(&aEventTarget)) {             \
    381    return aEventTarget._check ? static_cast<_const _class*>(&aEventTarget) \
    382                               : nullptr;                                   \
    383  }                                                                         \
    384  template <typename T>                                                     \
    385  static _const _class* FromEventTarget(_const T* aEventTarget) {           \
    386    MOZ_DIAGNOSTIC_ASSERT(aEventTarget);                                    \
    387    return FromEventTarget(*aEventTarget);                                  \
    388  }                                                                         \
    389  template <typename T>                                                     \
    390  static _const _class* FromEventTargetOrNull(_const T* aEventTarget) {     \
    391    return aEventTarget ? FromEventTarget(*aEventTarget) : nullptr;         \
    392  }
    393 
    394 #define NS_IMPL_FROMEVENTTARGET_HELPER(_class, _check)                         \
    395  NS_IMPL_FROMEVENTTARGET_GENERIC(_class, _check, )                            \
    396  NS_IMPL_FROMEVENTTARGET_GENERIC(_class, _check, const)                       \
    397  template <typename T>                                                        \
    398  static _class* FromEventTarget(T&& aEventTarget) {                           \
    399    MOZ_DIAGNOSTIC_ASSERT(!!aEventTarget);                                     \
    400    /* We need the double-cast in case aEventTarget is a smartptr.  Those */   \
    401    /* can cast to superclasses of the type they're templated on, */           \
    402    /* but not directly to subclasses.  */                                     \
    403    return aEventTarget->_check                                                \
    404               ? static_cast<_class*>(static_cast<EventTarget*>(aEventTarget)) \
    405               : nullptr;                                                      \
    406  }                                                                            \
    407  template <typename T>                                                        \
    408  static _class* FromEventTargetOrNull(T&& aEventTarget) {                     \
    409    return aEventTarget ? FromEventTarget(aEventTarget) : nullptr;             \
    410  }
    411 
    412 // Unfortunately, nsPIDOMWindowInner and nsPIDOMWindowOuter do not inherit
    413 // EventTarget directly, but they are public interfaces which should have
    414 // these helper methods.  Therefore, we cannot cast from EventTarget to
    415 // the interfaces in their header file.  That's the reason why we cannot use
    416 // the zero cost casts nor decltype for the template methods which take a
    417 // reference.
    418 #define NS_IMPL_FROMEVENTTARGET_GENERIC_WITH_GETTER(_class, _getter, _const) \
    419  static _const _class* FromEventTarget(                                     \
    420      _const mozilla::dom::EventTarget& aEventTarget) {                      \
    421    return aEventTarget._getter;                                             \
    422  }                                                                          \
    423  template <typename T>                                                      \
    424  static _const _class* FromEventTarget(_const T* aEventTarget) {            \
    425    return aEventTarget->_getter;                                            \
    426  }                                                                          \
    427  template <typename T>                                                      \
    428  static _const _class* FromEventTargetOrNull(_const T* aEventTarget) {      \
    429    return aEventTarget ? aEventTarget->_getter : nullptr;                   \
    430  }
    431 
    432 #define NS_IMPL_FROMEVENTTARGET_HELPER_WITH_GETTER_INNER(_class, _getter) \
    433  template <typename T>                                                   \
    434  static _class* FromEventTarget(T&& aEventTarget) {                      \
    435    return aEventTarget->_getter;                                         \
    436  }                                                                       \
    437  template <typename T>                                                   \
    438  static _class* FromEventTargetOrNull(T&& aEventTarget) {                \
    439    return aEventTarget ? aEventTarget->_getter : nullptr;                \
    440  }
    441 
    442 #define NS_IMPL_FROMEVENTTARGET_HELPER_WITH_GETTER(_class, _getter)   \
    443  NS_IMPL_FROMEVENTTARGET_GENERIC_WITH_GETTER(_class, _getter, )      \
    444  NS_IMPL_FROMEVENTTARGET_GENERIC_WITH_GETTER(_class, _getter, const) \
    445  NS_IMPL_FROMEVENTTARGET_HELPER_WITH_GETTER_INNER(_class, _getter)
    446 
    447 }  // namespace dom
    448 }  // namespace mozilla
    449 
    450 #ifdef NS_BUILD_REFCNT_LOGGING
    451 #  define NON_VIRTUAL_ADDREF_RELEASE(class_) /* Nothing */
    452 #else
    453 #  define NON_VIRTUAL_ADDREF_RELEASE(class_)                                 \
    454    namespace mozilla {                                                      \
    455    template <>                                                              \
    456    class RefPtrTraits<class_> {                                             \
    457     public:                                                                 \
    458      static void Release(class_* aObject) { aObject->NonVirtualRelease(); } \
    459      static void AddRef(class_* aObject) { aObject->NonVirtualAddRef(); }   \
    460    };                                                                       \
    461    }
    462 
    463 #endif
    464 
    465 NON_VIRTUAL_ADDREF_RELEASE(mozilla::dom::EventTarget)
    466 
    467 #endif  // mozilla_dom_EventTarget_h_