1 // Copyright 2007, Google Inc.
3 // Redistribution and use in source and binary forms, with or without
4 // modification, are permitted provided that the following conditions are met:
6 // 1. Redistributions of source code must retain the above copyright notice,
7 // this list of conditions and the following disclaimer.
8 // 2. Redistributions in binary form must reproduce the above copyright notice,
9 // this list of conditions and the following disclaimer in the documentation
10 // and/or other materials provided with the distribution.
11 // 3. Neither the name of Google Inc. nor the names of its contributors may be
12 // used to endorse or promote products derived from this software without
13 // specific prior written permission.
15 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
16 // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
17 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
18 // EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
19 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
21 // OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22 // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23 // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
24 // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 // This implementation makes use of window.addEventListener() to watch the
27 // event. IE does not support this, but it's not a target for the NPAPI port,
30 #include "gears/base/common/html_event_monitor.h"
34 #include "gears/base/common/dispatcher.h"
35 #include "gears/base/common/string_utils.h"
36 #include "gears/base/npapi/np_utils.h"
37 #include "gears/base/npapi/plugin.h"
38 #include "gears/base/npapi/scoped_npapi_handles.h"
40 DECLARE_DISPATCHER(HtmlEventMonitorHook
);
42 class HtmlEventMonitorHook
: public PluginBase
{
44 HtmlEventMonitorHook(NPP instance
)
45 : PluginBase(instance
), dispatcher_(this) {
46 PluginBase::Init(&dispatcher_
);
49 void Init(HtmlEventMonitor::HtmlEventCallback function
, void *user_param
) {
51 user_param_
= user_param
;
54 void HandleEvent(JsCallContext
*context
) {
55 function_(user_param_
); // invoke user callback
59 HtmlEventMonitor::HtmlEventCallback function_
;
62 Dispatcher
<HtmlEventMonitorHook
> dispatcher_
;
64 DISALLOW_EVIL_CONSTRUCTORS(HtmlEventMonitorHook
);
69 void Dispatcher
<HtmlEventMonitorHook
>::Init() {
70 // Safari treats "handleEvent" as a method, while Firefox treats it as a
71 // property. Go figure.
72 RegisterMethod("handleEvent", &HtmlEventMonitorHook::HandleEvent
);
73 RegisterProperty("handleEvent", &HtmlEventMonitorHook::HandleEvent
, NULL
);
76 HtmlEventMonitorHook
* CreateHtmlEventMonitorHook(JsContextPtr context
) {
77 return static_cast<HtmlEventMonitorHook
*>(
78 NPN_CreateObject(context
, GetNPClass
<HtmlEventMonitorHook
>()));
85 bool HtmlEventMonitor::Start(NPP context
, NPObject
*event_source
) {
87 assert(NPVARIANT_IS_VOID(event_source_
));
89 // create the event hook
90 HtmlEventMonitorHook
*event_hook
= CreateHtmlEventMonitorHook(context
);
91 ScopedNPObject
event_hook_scoped(event_hook
);
92 event_hook
->Init(function_
, user_param_
);
94 // call window.addEventListener(event_name, event_hook, false)
95 NPObject
* window
= event_source
;
97 NPIdentifier add_event_listener_id
=
98 NPN_GetStringIdentifier("addEventListener");
100 std::string event_name_utf8
;
101 if (!String16ToUTF8(&event_name_
[2], &event_name_utf8
)) // skip leading "on"
105 STDSTRING_TO_NPVARIANT(event_name_utf8
, args
[0]);
106 OBJECT_TO_NPVARIANT(event_hook
, args
[1]);
107 BOOLEAN_TO_NPVARIANT(false, args
[2]);
110 ScopedNPVariant result
;
111 if (!NPN_Invoke(context
, window
, add_event_listener_id
, args
,
112 ARRAYSIZE(args
), &result
))
115 // only modify data members if everything succeeded
116 event_hook_scoped
.release();
117 event_context_
= context
;
118 event_hook_
= event_hook
;
119 event_source_
.Reset(event_source
);
123 void HtmlEventMonitor::Stop() {
124 assert(NPVARIANT_IS_OBJECT(event_source_
));
127 // call window.removeEventListener(event_name, event_hook, false)
128 NPObject
* window
= NPVARIANT_TO_OBJECT(event_source_
);
130 NPIdentifier remove_event_listener_id
=
131 NPN_GetStringIdentifier("removeEventListener");
133 std::string event_name_utf8
;
134 if (!String16ToUTF8(&event_name_
[2], &event_name_utf8
)) // skip leading "on"
138 STDSTRING_TO_NPVARIANT(event_name_utf8
, args
[0]);
139 OBJECT_TO_NPVARIANT(event_hook_
, args
[1]);
140 BOOLEAN_TO_NPVARIANT(false, args
[2]);
143 ScopedNPVariant result
;
144 if (!NPN_Invoke(event_context_
, window
, remove_event_listener_id
,
148 // destroy the event hook
149 NPN_ReleaseObject(event_hook_
);
150 event_context_
= NULL
;
152 event_source_
.Reset();