Index: chrome_frame/np_event_listener.h |
=================================================================== |
--- chrome_frame/np_event_listener.h (revision 0) |
+++ chrome_frame/np_event_listener.h (revision 0) |
@@ -0,0 +1,187 @@ |
+// Copyright (c) 2009 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#ifndef CHROME_FRAME_NP_EVENT_LISTENER_H_ |
+#define CHROME_FRAME_NP_EVENT_LISTENER_H_ |
+ |
+#include "base/logging.h" |
+ |
+#include "chrome_frame/utils.h" |
+#include "chrome_frame/np_browser_functions.h" |
+ |
+// Avoid conflicts with basictypes and the gecko sdk. |
+// (different definitions of uint32). |
+#define NO_NSPR_10_SUPPORT |
+#include "third_party/xulrunner-sdk/win/include/dom/nsIDOMEventListener.h" |
+ |
+ |
+class nsIDOMElement; |
+ |
+class NpEventDelegate { |
+ public: |
+ virtual void OnEvent(const char* event_name) = 0; |
+}; |
+ |
+class NpEventListener { |
+ public: |
+ NS_IMETHOD_(nsrefcnt) AddRef() = 0; |
+ NS_IMETHOD_(nsrefcnt) Release() = 0; |
+ virtual bool Subscribe(NPP instance, |
+ const char* event_names[], |
+ int event_name_count) = 0; |
+ virtual bool Unsubscribe(NPP instance, |
+ const char* event_names[], |
+ int event_name_count) = 0; |
+}; |
+ |
+// A little helper class to implement simple ref counting |
+// and assert on single threadedness. |
+template <class T> |
+class NpEventListenerBase : public NpEventListener { |
+ public: |
+ NpEventListenerBase(NpEventDelegate* delegate) |
+ : ref_count_(0), delegate_(delegate) { |
+ DCHECK(delegate_); |
+ thread_id_ = ::GetCurrentThreadId(); |
+ } |
+ |
+ ~NpEventListenerBase() { |
+ DCHECK(thread_id_ == ::GetCurrentThreadId()); |
+ } |
+ |
+ NS_IMETHOD_(nsrefcnt) AddRef() { |
+ DCHECK(thread_id_ == ::GetCurrentThreadId()); |
+ ref_count_++; |
+ return ref_count_; |
+ } |
+ |
+ NS_IMETHOD_(nsrefcnt) Release() { |
+ DCHECK(thread_id_ == ::GetCurrentThreadId()); |
+ ref_count_--; |
+ |
+ if (!ref_count_) { |
+ T* me = static_cast<T*>(this); |
+ delete me; |
+ return 0; |
+ } |
+ |
+ return ref_count_; |
+ } |
+ |
+ protected: |
+ nsrefcnt ref_count_; |
+ NpEventDelegate* delegate_; |
+ AddRefModule module_ref_; |
+ // used to DCHECK on expected single-threaded usage |
+ unsigned long thread_id_; |
+}; |
+ |
+// Implements nsIDOMEventListener in order to receive events from DOM |
+// elements inside an HTML page. |
+class DomEventListener |
+ : public nsIDOMEventListener, |
+ public NpEventListenerBase<DomEventListener> { |
+ public: |
+ DomEventListener(NpEventDelegate* delegate); |
+ ~DomEventListener(); |
+ |
+ // Implementation of NpEventListener |
+ virtual bool Subscribe(NPP instance, |
+ const char* event_names[], |
+ int event_name_count); |
+ virtual bool Unsubscribe(NPP instance, |
+ const char* event_names[], |
+ int event_name_count); |
+ protected: |
+ // We implement QueryInterface etc ourselves in order to avoid |
+ // extra dependencies brought on by the NS_IMPL_* macros. |
+ NS_IMETHOD QueryInterface(REFNSIID iid, void** ptr); |
+ NS_IMETHOD_(nsrefcnt) AddRef() { |
+ return NpEventListenerBase<DomEventListener>::AddRef(); |
+ } |
+ |
+ NS_IMETHOD_(nsrefcnt) Release() { |
+ return NpEventListenerBase<DomEventListener>::Release(); |
+ } |
+ |
+ // Implementation of nsIDOMEventListener |
+ NS_IMETHOD HandleEvent(nsIDOMEvent *event); |
+ |
+ private: |
+ static bool GetObjectElement(NPP instance, nsIDOMElement** element); |
+ |
+ private: |
+ DISALLOW_COPY_AND_ASSIGN(DomEventListener); |
+}; |
+ |
+class NPObjectEventListener |
+ : public NpEventListenerBase<NPObjectEventListener> { |
+ public: |
+ NPObjectEventListener(NpEventDelegate* delegate); |
+ ~NPObjectEventListener(); |
+ |
+ // Implementation of NpEventListener |
+ virtual bool Subscribe(NPP instance, |
+ const char* event_names[], |
+ int event_name_count); |
+ virtual bool Unsubscribe(NPP instance, |
+ const char* event_names[], |
+ int event_name_count); |
+ |
+ protected: |
+ // NPObject structure which is exposed by NPObjectEventListener. |
+ class Npo : public NPObject { |
+ public: |
+ Npo(NPP npp) : npp_(npp), listener_(NULL) { |
+ } |
+ |
+ void Initialize(NPObjectEventListener* listener) { |
+ listener_ = listener; |
+ } |
+ |
+ inline NPObjectEventListener* listener() const { |
+ return listener_; |
+ } |
+ |
+ inline NPP npp() const { |
+ return npp_; |
+ } |
+ |
+ protected: |
+ NPP npp_; |
+ NPObjectEventListener* listener_; |
+ AddRefModule module_ref_; |
+ }; |
+ |
+ static NPClass* PluginClass(); |
+ |
+ static bool HasMethod(Npo* npo, NPIdentifier name); |
+ static bool Invoke(Npo* npo, NPIdentifier name, const NPVariant* args, |
+ uint32_t arg_count, NPVariant* result); |
+ static NPObject* AllocateObject(NPP instance, NPClass* class_name); |
+ static void DeallocateObject(Npo* npo); |
+ |
+ typedef enum { |
+ HANDLE_EVENT, |
+ TYPE, |
+ ADD_EVENT_LISTENER, |
+ REMOVE_EVENT_LISTENER, |
+ TAG_NAME, |
+ PARENT_ELEMENT, |
+ IDENTIFIER_COUNT, |
+ } CachedStringIdentifiers; |
+ |
+ static NPIdentifier* GetCachedStringIds(); |
+ |
+ void HandleEvent(Npo* npo, NPObject* event); |
+ static NPObject* GetObjectElement(NPP instance); |
+ |
+ private: |
+ // Our NPObject. |
+ ScopedNpObject<Npo> npo_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(NPObjectEventListener); |
+}; |
+ |
+#endif // CHROME_FRAME_NP_EVENT_LISTENER_H_ |