DOMEventTargetHelper.h (5424B)
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 "mozilla/Attributes.h" 11 #include "mozilla/GlobalTeardownObserver.h" 12 #include "mozilla/RefPtr.h" 13 #include "mozilla/dom/EventTarget.h" 14 #include "nsAtom.h" 15 #include "nsCOMPtr.h" 16 #include "nsCycleCollectionParticipant.h" 17 #include "nsDebug.h" 18 #include "nsGkAtoms.h" 19 #include "nsID.h" 20 #include "nsIGlobalObject.h" 21 #include "nsISupports.h" 22 #include "nsPIDOMWindow.h" 23 #include "nsStringFwd.h" 24 #include "nsTArray.h" 25 26 class nsCycleCollectionTraversalCallback; 27 28 namespace mozilla { 29 30 class ErrorResult; 31 class EventChainPostVisitor; 32 class EventChainPreVisitor; 33 class EventListenerManager; 34 35 namespace dom { 36 class Document; 37 class Event; 38 enum class CallerType : uint32_t; 39 } // namespace dom 40 41 #define NS_DOMEVENTTARGETHELPER_IID \ 42 {0xa28385c6, 0x9451, 0x4d7e, {0xa3, 0xdd, 0xf4, 0xb6, 0x87, 0x2f, 0xa4, 0x76}} 43 44 class DOMEventTargetHelper : public dom::EventTarget, 45 public GlobalTeardownObserver { 46 public: 47 DOMEventTargetHelper(); 48 explicit DOMEventTargetHelper(nsPIDOMWindowInner* aWindow); 49 explicit DOMEventTargetHelper(nsIGlobalObject* aGlobalObject); 50 explicit DOMEventTargetHelper(DOMEventTargetHelper* aOther); 51 52 NS_DECL_ISUPPORTS_INHERITED 53 NS_IMETHOD_(void) DeleteCycleCollectable() override; 54 NS_DECL_CYCLE_COLLECTION_SKIPPABLE_WRAPPERCACHE_CLASS_AMBIGUOUS( 55 DOMEventTargetHelper, dom::EventTarget) 56 57 EventListenerManager* GetExistingListenerManager() const override; 58 EventListenerManager* GetOrCreateListenerManager() override; 59 60 bool ComputeDefaultWantsUntrusted(ErrorResult& aRv) override; 61 62 using EventTarget::DispatchEvent; 63 // TODO: Convert this to MOZ_CAN_RUN_SCRIPT (bug 1415230) 64 MOZ_CAN_RUN_SCRIPT_BOUNDARY bool DispatchEvent(dom::Event& aEvent, 65 dom::CallerType aCallerType, 66 ErrorResult& aRv) override; 67 68 void GetEventTargetParent(EventChainPreVisitor& aVisitor) override; 69 70 nsresult PostHandleEvent(EventChainPostVisitor& aVisitor) override; 71 72 NS_INLINE_DECL_STATIC_IID(NS_DOMEVENTTARGETHELPER_IID) 73 74 nsIGlobalObject* GetOwnerGlobal() const override { 75 return GlobalTeardownObserver::GetOwnerGlobal(); 76 } 77 78 static DOMEventTargetHelper* FromSupports(nsISupports* aSupports) { 79 dom::EventTarget* target = static_cast<dom::EventTarget*>(aSupports); 80 #ifdef DEBUG 81 { 82 nsCOMPtr<dom::EventTarget> target_qi = do_QueryInterface(aSupports); 83 84 // If this assertion fires the QI implementation for the object in 85 // question doesn't use the EventTarget pointer as the 86 // nsISupports pointer. That must be fixed, or we'll crash... 87 NS_ASSERTION(target_qi == target, "Uh, fix QI!"); 88 } 89 #endif 90 91 return static_cast<DOMEventTargetHelper*>(target); 92 } 93 94 bool HasListenersFor(const nsAString& aType) const; 95 96 bool HasListenersFor(nsAtom* aTypeWithOn) const; 97 98 nsPIDOMWindowOuter* GetOwnerGlobalForBindingsInternal() override; 99 100 // Like GetOwner, but only returns non-null if the window being returned is 101 // current (in the "current document" sense of the HTML spec). 102 nsPIDOMWindowInner* GetWindowIfCurrent() const; 103 // Returns the document associated with this event target, if that document is 104 // the current document of its browsing context. Will return null otherwise. 105 mozilla::dom::Document* GetDocumentIfCurrent() const; 106 107 void DisconnectFromOwner() override; 108 using EventTarget::GetParentObject; 109 110 void EventListenerAdded(nsAtom* aType) override; 111 112 void EventListenerRemoved(nsAtom* aType) override; 113 114 // Dispatch a trusted, non-cancellable and non-bubbling event to |this|. 115 nsresult DispatchTrustedEvent(const nsAString& aEventName); 116 117 protected: 118 virtual ~DOMEventTargetHelper(); 119 120 nsresult WantsUntrusted(bool* aRetVal); 121 122 void MaybeUpdateKeepAlive(); 123 void MaybeDontKeepAlive(); 124 125 // If this method returns true your object is kept alive until it returns 126 // false. You can use this method instead using 127 // NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN macro. 128 virtual bool IsCertainlyAliveForCC() const { return mIsKeptAlive; } 129 130 RefPtr<EventListenerManager> mListenerManager; 131 // Make |event| trusted and dispatch |aEvent| to |this|. 132 nsresult DispatchTrustedEvent(dom::Event* aEvent); 133 134 virtual void LastRelease() {} 135 136 void KeepAliveIfHasListenersFor(nsAtom* aType); 137 138 void IgnoreKeepAliveIfHasListenersFor(nsAtom* aType); 139 140 private: 141 nsTArray<RefPtr<nsAtom>> mKeepingAliveTypes; 142 143 bool mIsKeptAlive = false; 144 }; 145 146 } // namespace mozilla 147 148 // WebIDL event handlers 149 #define IMPL_EVENT_HANDLER(_event) \ 150 inline mozilla::dom::EventHandlerNonNull* GetOn##_event() { \ 151 return GetEventHandler(nsGkAtoms::on##_event); \ 152 } \ 153 inline void SetOn##_event(mozilla::dom::EventHandlerNonNull* aCallback) { \ 154 SetEventHandler(nsGkAtoms::on##_event, aCallback); \ 155 } 156 157 #endif // mozilla_DOMEventTargetHelper_h_