OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #ifndef CHROME_FRAME_NP_EVENT_LISTENER_H_ |
| 6 #define CHROME_FRAME_NP_EVENT_LISTENER_H_ |
| 7 |
| 8 #include "base/logging.h" |
| 9 |
| 10 #include "chrome_frame/utils.h" |
| 11 #include "chrome_frame/np_browser_functions.h" |
| 12 |
| 13 // Avoid conflicts with basictypes and the gecko sdk. |
| 14 // (different definitions of uint32). |
| 15 #define NO_NSPR_10_SUPPORT |
| 16 #include "third_party/xulrunner-sdk/win/include/dom/nsIDOMEventListener.h" |
| 17 |
| 18 |
| 19 class nsIDOMElement; |
| 20 |
| 21 class NpEventDelegate { |
| 22 public: |
| 23 virtual void OnEvent(const char* event_name) = 0; |
| 24 }; |
| 25 |
| 26 class NpEventListener { |
| 27 public: |
| 28 NS_IMETHOD_(nsrefcnt) AddRef() = 0; |
| 29 NS_IMETHOD_(nsrefcnt) Release() = 0; |
| 30 virtual bool Subscribe(NPP instance, |
| 31 const char* event_names[], |
| 32 int event_name_count) = 0; |
| 33 virtual bool Unsubscribe(NPP instance, |
| 34 const char* event_names[], |
| 35 int event_name_count) = 0; |
| 36 }; |
| 37 |
| 38 // A little helper class to implement simple ref counting |
| 39 // and assert on single threadedness. |
| 40 template <class T> |
| 41 class NpEventListenerBase : public NpEventListener { |
| 42 public: |
| 43 NpEventListenerBase(NpEventDelegate* delegate) |
| 44 : ref_count_(0), delegate_(delegate) { |
| 45 DCHECK(delegate_); |
| 46 thread_id_ = ::GetCurrentThreadId(); |
| 47 } |
| 48 |
| 49 ~NpEventListenerBase() { |
| 50 DCHECK(thread_id_ == ::GetCurrentThreadId()); |
| 51 } |
| 52 |
| 53 NS_IMETHOD_(nsrefcnt) AddRef() { |
| 54 DCHECK(thread_id_ == ::GetCurrentThreadId()); |
| 55 ref_count_++; |
| 56 return ref_count_; |
| 57 } |
| 58 |
| 59 NS_IMETHOD_(nsrefcnt) Release() { |
| 60 DCHECK(thread_id_ == ::GetCurrentThreadId()); |
| 61 ref_count_--; |
| 62 |
| 63 if (!ref_count_) { |
| 64 T* me = static_cast<T*>(this); |
| 65 delete me; |
| 66 return 0; |
| 67 } |
| 68 |
| 69 return ref_count_; |
| 70 } |
| 71 |
| 72 protected: |
| 73 nsrefcnt ref_count_; |
| 74 NpEventDelegate* delegate_; |
| 75 AddRefModule module_ref_; |
| 76 // used to DCHECK on expected single-threaded usage |
| 77 unsigned long thread_id_; |
| 78 }; |
| 79 |
| 80 // Implements nsIDOMEventListener in order to receive events from DOM |
| 81 // elements inside an HTML page. |
| 82 class DomEventListener |
| 83 : public nsIDOMEventListener, |
| 84 public NpEventListenerBase<DomEventListener> { |
| 85 public: |
| 86 DomEventListener(NpEventDelegate* delegate); |
| 87 ~DomEventListener(); |
| 88 |
| 89 // Implementation of NpEventListener |
| 90 virtual bool Subscribe(NPP instance, |
| 91 const char* event_names[], |
| 92 int event_name_count); |
| 93 virtual bool Unsubscribe(NPP instance, |
| 94 const char* event_names[], |
| 95 int event_name_count); |
| 96 protected: |
| 97 // We implement QueryInterface etc ourselves in order to avoid |
| 98 // extra dependencies brought on by the NS_IMPL_* macros. |
| 99 NS_IMETHOD QueryInterface(REFNSIID iid, void** ptr); |
| 100 NS_IMETHOD_(nsrefcnt) AddRef() { |
| 101 return NpEventListenerBase<DomEventListener>::AddRef(); |
| 102 } |
| 103 |
| 104 NS_IMETHOD_(nsrefcnt) Release() { |
| 105 return NpEventListenerBase<DomEventListener>::Release(); |
| 106 } |
| 107 |
| 108 // Implementation of nsIDOMEventListener |
| 109 NS_IMETHOD HandleEvent(nsIDOMEvent *event); |
| 110 |
| 111 private: |
| 112 static bool GetObjectElement(NPP instance, nsIDOMElement** element); |
| 113 |
| 114 private: |
| 115 DISALLOW_COPY_AND_ASSIGN(DomEventListener); |
| 116 }; |
| 117 |
| 118 class NPObjectEventListener |
| 119 : public NpEventListenerBase<NPObjectEventListener> { |
| 120 public: |
| 121 NPObjectEventListener(NpEventDelegate* delegate); |
| 122 ~NPObjectEventListener(); |
| 123 |
| 124 // Implementation of NpEventListener |
| 125 virtual bool Subscribe(NPP instance, |
| 126 const char* event_names[], |
| 127 int event_name_count); |
| 128 virtual bool Unsubscribe(NPP instance, |
| 129 const char* event_names[], |
| 130 int event_name_count); |
| 131 |
| 132 protected: |
| 133 // NPObject structure which is exposed by NPObjectEventListener. |
| 134 class Npo : public NPObject { |
| 135 public: |
| 136 Npo(NPP npp) : npp_(npp), listener_(NULL) { |
| 137 } |
| 138 |
| 139 void Initialize(NPObjectEventListener* listener) { |
| 140 listener_ = listener; |
| 141 } |
| 142 |
| 143 inline NPObjectEventListener* listener() const { |
| 144 return listener_; |
| 145 } |
| 146 |
| 147 inline NPP npp() const { |
| 148 return npp_; |
| 149 } |
| 150 |
| 151 protected: |
| 152 NPP npp_; |
| 153 NPObjectEventListener* listener_; |
| 154 AddRefModule module_ref_; |
| 155 }; |
| 156 |
| 157 static NPClass* PluginClass(); |
| 158 |
| 159 static bool HasMethod(Npo* npo, NPIdentifier name); |
| 160 static bool Invoke(Npo* npo, NPIdentifier name, const NPVariant* args, |
| 161 uint32_t arg_count, NPVariant* result); |
| 162 static NPObject* AllocateObject(NPP instance, NPClass* class_name); |
| 163 static void DeallocateObject(Npo* npo); |
| 164 |
| 165 typedef enum { |
| 166 HANDLE_EVENT, |
| 167 TYPE, |
| 168 ADD_EVENT_LISTENER, |
| 169 REMOVE_EVENT_LISTENER, |
| 170 TAG_NAME, |
| 171 PARENT_ELEMENT, |
| 172 IDENTIFIER_COUNT, |
| 173 } CachedStringIdentifiers; |
| 174 |
| 175 static NPIdentifier* GetCachedStringIds(); |
| 176 |
| 177 void HandleEvent(Npo* npo, NPObject* event); |
| 178 static NPObject* GetObjectElement(NPP instance); |
| 179 |
| 180 private: |
| 181 // Our NPObject. |
| 182 ScopedNpObject<Npo> npo_; |
| 183 |
| 184 DISALLOW_COPY_AND_ASSIGN(NPObjectEventListener); |
| 185 }; |
| 186 |
| 187 #endif // CHROME_FRAME_NP_EVENT_LISTENER_H_ |
OLD | NEW |