LCOV - code coverage report
Current view: top level - dom/events - JSEventHandler.h (source / functions) Hit Total Coverage
Test: output.info Lines: 65 99 65.7 %
Date: 2017-07-14 16:53:18 Functions: 24 36 66.7 %
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_JSEventHandler_h_
       8             : #define mozilla_JSEventHandler_h_
       9             : 
      10             : #include "mozilla/Attributes.h"
      11             : #include "mozilla/MemoryReporting.h"
      12             : #include "mozilla/dom/EventHandlerBinding.h"
      13             : #include "nsCOMPtr.h"
      14             : #include "nsCycleCollectionParticipant.h"
      15             : #include "nsIAtom.h"
      16             : #include "nsIDOMKeyEvent.h"
      17             : #include "nsIDOMEventListener.h"
      18             : #include "nsIScriptContext.h"
      19             : 
      20             : namespace mozilla {
      21             : 
      22             : class TypedEventHandler
      23             : {
      24             : public:
      25             :   enum HandlerType
      26             :   {
      27             :     eUnset = 0,
      28             :     eNormal = 0x1,
      29             :     eOnError = 0x2,
      30             :     eOnBeforeUnload = 0x3,
      31             :     eTypeBits = 0x3
      32             :   };
      33             : 
      34         554 :   TypedEventHandler()
      35         554 :     : mBits(0)
      36             :   {
      37         554 :   }
      38             : 
      39           8 :   explicit TypedEventHandler(dom::EventHandlerNonNull* aHandler)
      40           8 :     : mBits(0)
      41             :   {
      42           8 :     Assign(aHandler, eNormal);
      43           8 :   }
      44             : 
      45           0 :   explicit TypedEventHandler(dom::OnErrorEventHandlerNonNull* aHandler)
      46           0 :     : mBits(0)
      47             :   {
      48           0 :     Assign(aHandler, eOnError);
      49           0 :   }
      50             : 
      51           0 :   explicit TypedEventHandler(dom::OnBeforeUnloadEventHandlerNonNull* aHandler)
      52           0 :     : mBits(0)
      53             :   {
      54           0 :     Assign(aHandler, eOnBeforeUnload);
      55           0 :   }
      56             : 
      57         557 :   TypedEventHandler(const TypedEventHandler& aOther)
      58         557 :   {
      59         557 :     if (aOther.HasEventHandler()) {
      60             :       // Have to make sure we take our own ref
      61           8 :       Assign(aOther.Ptr(), aOther.Type());
      62             :     } else {
      63         549 :       mBits = 0;
      64             :     }
      65         557 :   }
      66             : 
      67         572 :   ~TypedEventHandler()
      68         572 :   {
      69         572 :     ReleaseHandler();
      70         572 :   }
      71             : 
      72          68 :   HandlerType Type() const
      73             :   {
      74          68 :     return HandlerType(mBits & eTypeBits);
      75             :   }
      76             : 
      77        1143 :   bool HasEventHandler() const
      78             :   {
      79        1143 :     return !!Ptr();
      80             :   }
      81             : 
      82           5 :   void SetHandler(const TypedEventHandler& aHandler)
      83             :   {
      84           5 :     if (aHandler.HasEventHandler()) {
      85           0 :       ReleaseHandler();
      86           0 :       Assign(aHandler.Ptr(), aHandler.Type());
      87             :     } else {
      88           5 :       ForgetHandler();
      89             :     }
      90           5 :   }
      91             : 
      92          15 :   dom::EventHandlerNonNull* NormalEventHandler() const
      93             :   {
      94          15 :     MOZ_ASSERT(Type() == eNormal && Ptr());
      95          15 :     return reinterpret_cast<dom::EventHandlerNonNull*>(Ptr());
      96             :   }
      97             : 
      98           7 :   void SetHandler(dom::EventHandlerNonNull* aHandler)
      99             :   {
     100           7 :     ReleaseHandler();
     101           7 :     Assign(aHandler, eNormal);
     102           7 :   }
     103             : 
     104           0 :   dom::OnBeforeUnloadEventHandlerNonNull* OnBeforeUnloadEventHandler() const
     105             :   {
     106           0 :     MOZ_ASSERT(Type() == eOnBeforeUnload);
     107           0 :     return reinterpret_cast<dom::OnBeforeUnloadEventHandlerNonNull*>(Ptr());
     108             :   }
     109             : 
     110           0 :   void SetHandler(dom::OnBeforeUnloadEventHandlerNonNull* aHandler)
     111             :   {
     112           0 :     ReleaseHandler();
     113           0 :     Assign(aHandler, eOnBeforeUnload);
     114           0 :   }
     115             : 
     116           0 :   dom::OnErrorEventHandlerNonNull* OnErrorEventHandler() const
     117             :   {
     118           0 :     MOZ_ASSERT(Type() == eOnError);
     119           0 :     return reinterpret_cast<dom::OnErrorEventHandlerNonNull*>(Ptr());
     120             :   }
     121             : 
     122           0 :   void SetHandler(dom::OnErrorEventHandlerNonNull* aHandler)
     123             :   {
     124           0 :     ReleaseHandler();
     125           0 :     Assign(aHandler, eOnError);
     126           0 :   }
     127             : 
     128        1803 :   dom::CallbackFunction* Ptr() const
     129             :   {
     130             :     // Have to cast eTypeBits so we don't have to worry about
     131             :     // promotion issues after the bitflip.
     132        1803 :     return reinterpret_cast<dom::CallbackFunction*>(mBits &
     133        1803 :                                                       ~uintptr_t(eTypeBits));
     134             :   }
     135             : 
     136           5 :   void ForgetHandler()
     137             :   {
     138           5 :     ReleaseHandler();
     139           5 :     mBits = 0;
     140           5 :   }
     141             : 
     142           5 :   bool operator==(const TypedEventHandler& aOther) const
     143             :   {
     144             :     return
     145           5 :       Ptr() && aOther.Ptr() &&
     146           5 :       Ptr()->CallbackPreserveColor() == aOther.Ptr()->CallbackPreserveColor();
     147             :   }
     148             : 
     149             : private:
     150             :   void operator=(const TypedEventHandler&) = delete;
     151             : 
     152         584 :   void ReleaseHandler()
     153             :   {
     154         584 :     nsISupports* ptr = Ptr();
     155         584 :     NS_IF_RELEASE(ptr);
     156         584 :   }
     157             : 
     158          23 :   void Assign(nsISupports* aHandler, HandlerType aType)
     159             :   {
     160          23 :     MOZ_ASSERT(aHandler, "Must have handler");
     161          23 :     NS_ADDREF(aHandler);
     162          23 :     mBits = uintptr_t(aHandler) | uintptr_t(aType);
     163          23 :   }
     164             : 
     165             :   uintptr_t mBits;
     166             : };
     167             : 
     168             : /**
     169             :  * Implemented by script event listeners. Used to retrieve the script object
     170             :  * corresponding to the event target and the handler itself.
     171             :  *
     172             :  * Note, mTarget is a raw pointer and the owner of the JSEventHandler object
     173             :  * is expected to call Disconnect()!
     174             :  */
     175             : 
     176             : #define NS_JSEVENTHANDLER_IID \
     177             : { 0x4f486881, 0x1956, 0x4079, \
     178             :   { 0x8c, 0xa0, 0xf3, 0xbd, 0x60, 0x5c, 0xc2, 0x79 } }
     179             : 
     180             : class JSEventHandler : public nsIDOMEventListener
     181             : {
     182             : public:
     183             :   NS_DECLARE_STATIC_IID_ACCESSOR(NS_JSEVENTHANDLER_IID)
     184             : 
     185             :   JSEventHandler(nsISupports* aTarget, nsIAtom* aType,
     186             :                  const TypedEventHandler& aTypedHandler);
     187             : 
     188             :   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
     189             : 
     190             :   // nsIDOMEventListener interface
     191             :   NS_DECL_NSIDOMEVENTLISTENER
     192             : 
     193             :   nsISupports* GetEventTarget() const
     194             :   {
     195             :     return mTarget;
     196             :   }
     197             : 
     198          10 :   void Disconnect()
     199             :   {
     200          10 :     mTarget = nullptr;
     201          10 :   }
     202             : 
     203          45 :   const TypedEventHandler& GetTypedEventHandler() const
     204             :   {
     205          45 :     return mTypedHandler;
     206             :   }
     207             : 
     208             :   void ForgetHandler()
     209             :   {
     210             :     mTypedHandler.ForgetHandler();
     211             :   }
     212             : 
     213          14 :   nsIAtom* EventName() const
     214             :   {
     215          14 :     return mEventName;
     216             :   }
     217             : 
     218             :   // Set a handler for this event listener.  The handler must already
     219             :   // be bound to the right target.
     220           5 :   void SetHandler(const TypedEventHandler& aTypedHandler)
     221             :   {
     222           5 :     mTypedHandler.SetHandler(aTypedHandler);
     223           5 :   }
     224           7 :   void SetHandler(dom::EventHandlerNonNull* aHandler)
     225             :   {
     226           7 :     mTypedHandler.SetHandler(aHandler);
     227           7 :   }
     228           0 :   void SetHandler(dom::OnBeforeUnloadEventHandlerNonNull* aHandler)
     229             :   {
     230           0 :     mTypedHandler.SetHandler(aHandler);
     231           0 :   }
     232           0 :   void SetHandler(dom::OnErrorEventHandlerNonNull* aHandler)
     233             :   {
     234           0 :     mTypedHandler.SetHandler(aHandler);
     235           0 :   }
     236             : 
     237           0 :   size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
     238             :   {
     239           0 :     return 0;
     240             : 
     241             :     // Measurement of the following members may be added later if DMD finds it
     242             :     // is worthwhile:
     243             :     // - mTarget
     244             :     //
     245             :     // The following members are not measured:
     246             :     // - mTypedHandler: may be shared with others
     247             :     // - mEventName: shared with others
     248             :   }
     249             : 
     250           0 :   size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf)
     251             :   {
     252           0 :     return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
     253             :   }
     254             : 
     255        5129 :   NS_DECL_CYCLE_COLLECTION_SKIPPABLE_CLASS(JSEventHandler)
     256             : 
     257             :   bool IsBlackForCC();
     258             : 
     259             : protected:
     260             :   virtual ~JSEventHandler();
     261             : 
     262             :   nsISupports* mTarget;
     263             :   nsCOMPtr<nsIAtom> mEventName;
     264             :   TypedEventHandler mTypedHandler;
     265             : };
     266             : 
     267             : NS_DEFINE_STATIC_IID_ACCESSOR(JSEventHandler, NS_JSEVENTHANDLER_IID)
     268             : 
     269             : } // namespace mozilla
     270             : 
     271             : /**
     272             :  * Factory function.  aHandler must already be bound to aTarget.
     273             :  * aContext is allowed to be null if aHandler is already set up.
     274             :  */
     275             : nsresult NS_NewJSEventHandler(nsISupports* aTarget,
     276             :                               nsIAtom* aType,
     277             :                               const mozilla::TypedEventHandler& aTypedHandler,
     278             :                               mozilla::JSEventHandler** aReturn);
     279             : 
     280             : #endif // mozilla_JSEventHandler_h_
     281             : 

Generated by: LCOV version 1.13