LCOV - code coverage report
Current view: top level - dom/events - DOMEventTargetHelper.h (source / functions) Hit Total Coverage
Test: output.info Lines: 20 40 50.0 %
Date: 2018-08-07 16:35:00 Functions: 0 0 -
Legend: Lines: hit not hit

          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             : #ifndef mozilla_DOMEventTargetHelper_h_
       8             : #define mozilla_DOMEventTargetHelper_h_
       9             : 
      10             : #include "nsCOMPtr.h"
      11             : #include "nsGkAtoms.h"
      12             : #include "nsCycleCollectionParticipant.h"
      13             : #include "nsPIDOMWindow.h"
      14             : #include "nsIScriptGlobalObject.h"
      15             : #include "nsIScriptContext.h"
      16             : #include "nsIWeakReferenceUtils.h"
      17             : #include "MainThreadUtils.h"
      18             : #include "mozilla/Attributes.h"
      19             : #include "mozilla/EventListenerManager.h"
      20             : #include "mozilla/LinkedList.h"
      21             : #include "mozilla/dom/EventTarget.h"
      22             : 
      23             : class nsIDocument;
      24             : 
      25             : namespace mozilla {
      26             : 
      27             : class ErrorResult;
      28             : 
      29             : namespace dom {
      30             : class Event;
      31             : } // namespace dom
      32             : 
      33             : #define NS_DOMEVENTTARGETHELPER_IID \
      34             : { 0xa28385c6, 0x9451, 0x4d7e, \
      35             :   { 0xa3, 0xdd, 0xf4, 0xb6, 0x87, 0x2f, 0xa4, 0x76 } }
      36             : 
      37             : class DOMEventTargetHelper : public dom::EventTarget,
      38             :                              public LinkedListElement<DOMEventTargetHelper>
      39             : {
      40             : public:
      41          46 :   DOMEventTargetHelper()
      42           0 :     : mParentObject(nullptr)
      43             :     , mOwnerWindow(nullptr)
      44             :     , mHasOrHasHadOwnerWindow(false)
      45         184 :     , mIsKeptAlive(false)
      46             :   {
      47          46 :   }
      48           0 :   explicit DOMEventTargetHelper(nsPIDOMWindowInner* aWindow)
      49           0 :     : mParentObject(nullptr)
      50             :     , mOwnerWindow(nullptr)
      51             :     , mHasOrHasHadOwnerWindow(false)
      52          88 :     , mIsKeptAlive(false)
      53             :   {
      54             :     // Be careful not to call the virtual BindToOwner() in a
      55             :     // constructor.
      56          22 :     nsIGlobalObject* global = aWindow ? aWindow->AsGlobal() : nullptr;
      57           0 :     BindToOwnerInternal(global);
      58           0 :   }
      59           0 :   explicit DOMEventTargetHelper(nsIGlobalObject* aGlobalObject)
      60           0 :     : mParentObject(nullptr)
      61             :     , mOwnerWindow(nullptr)
      62             :     , mHasOrHasHadOwnerWindow(false)
      63          20 :     , mIsKeptAlive(false)
      64             :   {
      65             :     // Be careful not to call the virtual BindToOwner() in a
      66             :     // constructor.
      67           5 :     BindToOwnerInternal(aGlobalObject);
      68           0 :   }
      69           0 :   explicit DOMEventTargetHelper(DOMEventTargetHelper* aOther)
      70           0 :     : mParentObject(nullptr)
      71             :     , mOwnerWindow(nullptr)
      72             :     , mHasOrHasHadOwnerWindow(false)
      73          72 :     , mIsKeptAlive(false)
      74             :   {
      75             :     // Be careful not to call the virtual BindToOwner() in a
      76             :     // constructor.
      77          18 :     if (!aOther) {
      78           0 :       BindToOwnerInternal(static_cast<nsIGlobalObject*>(nullptr));
      79           0 :       return;
      80             :     }
      81          18 :     BindToOwnerInternal(aOther->GetParentObject());
      82           0 :     mHasOrHasHadOwnerWindow = aOther->HasOrHasHadOwner();
      83             :   }
      84             : 
      85             :   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
      86           0 :   NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS(DOMEventTargetHelper)
      87             : 
      88             :   virtual EventListenerManager* GetExistingListenerManager() const override;
      89             :   virtual EventListenerManager* GetOrCreateListenerManager() override;
      90             : 
      91             :   bool ComputeDefaultWantsUntrusted(ErrorResult& aRv) override;
      92             : 
      93             :   using EventTarget::DispatchEvent;
      94             :   bool DispatchEvent(dom::Event& aEvent, dom::CallerType aCallerType,
      95             :                      ErrorResult& aRv) override;
      96             : 
      97             :   void GetEventTargetParent(EventChainPreVisitor& aVisitor) override;
      98             : 
      99             :   nsresult PostHandleEvent(EventChainPostVisitor& aVisitor) override;
     100             : 
     101             :   NS_DECLARE_STATIC_IID_ACCESSOR(NS_DOMEVENTTARGETHELPER_IID)
     102             : 
     103             :   void GetParentObject(nsIScriptGlobalObject **aParentObject)
     104             :   {
     105             :     if (mParentObject) {
     106             :       CallQueryInterface(mParentObject, aParentObject);
     107             :     } else {
     108             :       *aParentObject = nullptr;
     109             :     }
     110             :   }
     111             : 
     112             :   static DOMEventTargetHelper* FromSupports(nsISupports* aSupports)
     113             :   {
     114             :     dom::EventTarget* target = static_cast<dom::EventTarget*>(aSupports);
     115             : #ifdef DEBUG
     116             :     {
     117             :       nsCOMPtr<dom::EventTarget> target_qi = do_QueryInterface(aSupports);
     118             : 
     119             :       // If this assertion fires the QI implementation for the object in
     120             :       // question doesn't use the EventTarget pointer as the
     121             :       // nsISupports pointer. That must be fixed, or we'll crash...
     122             :       NS_ASSERTION(target_qi == target, "Uh, fix QI!");
     123             :     }
     124             : #endif
     125             : 
     126             :     return static_cast<DOMEventTargetHelper*>(target);
     127             :   }
     128             : 
     129           8 :   bool HasListenersFor(const nsAString& aType) const
     130             :   {
     131          16 :     return mListenerManager && mListenerManager->HasListenersFor(aType);
     132             :   }
     133             : 
     134          59 :   bool HasListenersFor(nsAtom* aTypeWithOn) const
     135             :   {
     136         118 :     return mListenerManager && mListenerManager->HasListenersFor(aTypeWithOn);
     137             :   }
     138             : 
     139           0 :   virtual nsPIDOMWindowOuter* GetOwnerGlobalForBindings() override
     140             :   {
     141           0 :     return nsPIDOMWindowOuter::GetFromCurrentInner(GetOwner());
     142             :   }
     143             : 
     144        1034 :   nsresult CheckInnerWindowCorrectness() const
     145             :   {
     146        1034 :     NS_ENSURE_STATE(!mHasOrHasHadOwnerWindow || mOwnerWindow);
     147           0 :     if (mOwnerWindow && !mOwnerWindow->IsCurrentInnerWindow()) {
     148             :       return NS_ERROR_FAILURE;
     149             :     }
     150        1034 :     return NS_OK;
     151             :   }
     152             : 
     153             :   nsPIDOMWindowInner* GetOwner() const { return mOwnerWindow; }
     154             :   // Like GetOwner, but only returns non-null if the window being returned is
     155             :   // current (in the "current document" sense of the HTML spec).
     156             :   nsPIDOMWindowInner* GetWindowIfCurrent() const;
     157             :   // Returns the document associated with this event target, if that document is
     158             :   // the current document of its browsing context.  Will return null otherwise.
     159             :   nsIDocument* GetDocumentIfCurrent() const;
     160             : 
     161             :   // DETH subclasses may override the BindToOwner(nsIGlobalObject*) method
     162             :   // to take action when dynamically binding to a new global.  This is only
     163             :   // called on rebind since virtual methods cannot be called from the
     164             :   // constructor.  The other BindToOwner() methods will call into this
     165             :   // method.
     166             :   //
     167             :   // NOTE: Any overrides of BindToOwner() *must* invoke
     168             :   //       DOMEventTargetHelper::BindToOwner(aOwner).
     169             :   virtual void BindToOwner(nsIGlobalObject* aOwner);
     170             : 
     171             :   void BindToOwner(nsPIDOMWindowInner* aOwner);
     172             :   void BindToOwner(DOMEventTargetHelper* aOther);
     173             : 
     174             :   virtual void DisconnectFromOwner();
     175             :   using EventTarget::GetParentObject;
     176         547 :   nsIGlobalObject* GetOwnerGlobal() const final
     177             :   {
     178         592 :     return mParentObject;
     179             :   }
     180             :   bool HasOrHasHadOwner() { return mHasOrHasHadOwnerWindow; }
     181             : 
     182             :   virtual void EventListenerAdded(nsAtom* aType) override;
     183             :   virtual void EventListenerAdded(const nsAString& aType) override;
     184             : 
     185             :   virtual void EventListenerRemoved(nsAtom* aType) override;
     186             :   virtual void EventListenerRemoved(const nsAString& aType) override;
     187             : 
     188             :   // Dispatch a trusted, non-cancellable and non-bubbling event to |this|.
     189             :   nsresult DispatchTrustedEvent(const nsAString& aEventName);
     190             : protected:
     191             :   virtual ~DOMEventTargetHelper();
     192             : 
     193             :   nsresult WantsUntrusted(bool* aRetVal);
     194             : 
     195             :   void MaybeUpdateKeepAlive();
     196             :   void MaybeDontKeepAlive();
     197             : 
     198             :   // If this method returns true your object is kept alive until it returns
     199             :   // false. You can use this method instead using
     200             :   // NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN macro.
     201           0 :   virtual bool IsCertainlyAliveForCC() const
     202             :   {
     203           0 :     return mIsKeptAlive;
     204             :   }
     205             : 
     206             :   RefPtr<EventListenerManager> mListenerManager;
     207             :   // Make |event| trusted and dispatch |aEvent| to |this|.
     208             :   nsresult DispatchTrustedEvent(dom::Event* aEvent);
     209             : 
     210           0 :   virtual void LastRelease() {}
     211             : 
     212             :   void KeepAliveIfHasListenersFor(const nsAString& aType);
     213             :   void KeepAliveIfHasListenersFor(nsAtom* aType);
     214             : 
     215             :   void IgnoreKeepAliveIfHasListenersFor(const nsAString& aType);
     216             :   void IgnoreKeepAliveIfHasListenersFor(nsAtom* aType);
     217             : 
     218             :   void BindToOwnerInternal(nsIGlobalObject* aOwner);
     219             : 
     220             : private:
     221             :   // The parent global object.  The global will clear this when
     222             :   // it is destroyed by calling DisconnectFromOwner().
     223             :   nsIGlobalObject* MOZ_NON_OWNING_REF mParentObject;
     224             :   // mParentObject pre QI-ed and cached (inner window)
     225             :   // (it is needed for off main thread access)
     226             :   // It is obtained in BindToOwner and reset in DisconnectFromOwner.
     227             :   nsPIDOMWindowInner* MOZ_NON_OWNING_REF mOwnerWindow;
     228             :   bool                       mHasOrHasHadOwnerWindow;
     229             : 
     230         273 :   struct {
     231             :     nsTArray<nsString> mStrings;
     232             :     nsTArray<RefPtr<nsAtom>> mAtoms;
     233             :   } mKeepingAliveTypes;
     234             : 
     235             :   bool mIsKeptAlive;
     236             : };
     237             : 
     238             : NS_DEFINE_STATIC_IID_ACCESSOR(DOMEventTargetHelper,
     239             :                               NS_DOMEVENTTARGETHELPER_IID)
     240             : 
     241             : } // namespace mozilla
     242             : 
     243             : // WebIDL event handlers
     244             : #define IMPL_EVENT_HANDLER(_event)                                        \
     245             :   inline mozilla::dom::EventHandlerNonNull* GetOn##_event()               \
     246             :   {                                                                       \
     247             :     if (NS_IsMainThread()) {                                              \
     248             :       return GetEventHandler(nsGkAtoms::on##_event, EmptyString());       \
     249             :     }                                                                     \
     250             :     return GetEventHandler(nullptr, NS_LITERAL_STRING(#_event));          \
     251             :   }                                                                       \
     252             :   inline void SetOn##_event(mozilla::dom::EventHandlerNonNull* aCallback) \
     253             :   {                                                                       \
     254             :     if (NS_IsMainThread()) {                                              \
     255             :       SetEventHandler(nsGkAtoms::on##_event, EmptyString(), aCallback);   \
     256             :     } else {                                                              \
     257             :       SetEventHandler(nullptr, NS_LITERAL_STRING(#_event), aCallback);    \
     258             :     }                                                                     \
     259             :   }
     260             : 
     261             : #endif // mozilla_DOMEventTargetHelper_h_

Generated by: LCOV version 1.13-14-ga5dd952