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_extensions_ExtensionEventManager_h
8 #define mozilla_extensions_ExtensionEventManager_h
9 
10 #include "js/GCHashTable.h"  // for JS::GCHashMap
11 #include "js/TypeDecls.h"    // for JS::Handle, JSContext, JSObject, ...
12 #include "mozilla/Attributes.h"
13 #include "mozilla/dom/BindingDeclarations.h"
14 #include "mozilla/ErrorResult.h"
15 #include "nsCycleCollectionParticipant.h"
16 #include "nsCOMPtr.h"
17 #include "nsISupports.h"
18 #include "nsPointerHashKeys.h"
19 #include "nsRefPtrHashtable.h"
20 #include "nsWrapperCache.h"
21 
22 #include "ExtensionAPIBase.h"
23 
24 class nsIGlobalObject;
25 
26 namespace mozilla {
27 
28 namespace dom {
29 class Function;
30 }  // namespace dom
31 
32 namespace extensions {
33 
34 class ExtensionBrowser;
35 class ExtensionEventListener;
36 
37 class ExtensionEventManager final : public nsISupports,
38                                     public nsWrapperCache,
39                                     public ExtensionAPIBase {
40   nsCOMPtr<nsIGlobalObject> mGlobal;
41   RefPtr<ExtensionBrowser> mExtensionBrowser;
42   nsString mAPINamespace;
43   nsString mEventName;
44   nsString mAPIObjectType;
45   nsString mAPIObjectId;
46 
47   using ListenerWrappersMap =
48       JS::GCHashMap<JS::Heap<JSObject*>, RefPtr<ExtensionEventListener>,
49                     js::MovableCellHasher<JS::Heap<JSObject*>>,
50                     js::SystemAllocPolicy>;
51 
52   ListenerWrappersMap mListeners;
53 
54   ~ExtensionEventManager();
55 
56   void ReleaseListeners();
57 
58  protected:
59   // ExtensionAPIBase methods
GetGlobalObject()60   nsIGlobalObject* GetGlobalObject() const override { return mGlobal; }
GetExtensionBrowser()61   ExtensionBrowser* GetExtensionBrowser() const override {
62     return mExtensionBrowser;
63   }
64 
GetAPINamespace()65   nsString GetAPINamespace() const override { return mAPINamespace; }
66 
GetAPIObjectType()67   nsString GetAPIObjectType() const override { return mAPIObjectType; }
68 
GetAPIObjectId()69   nsString GetAPIObjectId() const override { return mAPIObjectId; }
70 
71  public:
72   ExtensionEventManager(nsIGlobalObject* aGlobal,
73                         ExtensionBrowser* aExtensionBrowser,
74                         const nsAString& aNamespace,
75                         const nsAString& aEventName,
76                         const nsAString& aObjectType = VoidString(),
77                         const nsAString& aObjectId = VoidString());
78 
79   // nsWrapperCache interface methods
80   JSObject* WrapObject(JSContext* aCx,
81                        JS::Handle<JSObject*> aGivenProto) override;
82   nsIGlobalObject* GetParentObject() const;
83 
84   bool HasListener(dom::Function& aCallback, ErrorResult& aRv) const;
85   bool HasListeners(ErrorResult& aRv) const;
86 
87   void AddListener(JSContext* aCx, dom::Function& aCallback,
88                    const dom::Optional<JS::Handle<JSObject*>>& aOptions,
89                    ErrorResult& aRv);
90   void RemoveListener(dom::Function& aCallback, ErrorResult& aRv);
91 
92   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
93   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(ExtensionEventManager)
94 };
95 
96 }  // namespace extensions
97 }  // namespace mozilla
98 
99 #endif  // mozilla_extensions_ExtensionEventManager_h
100