1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * ff3-dom.cpp: Firefox 3.x DOM wrapper
6 * Moonlight List (moonlight-list@lists.ximian.com)
8 * Copyright 2007 Novell, Inc. (http://www.novell.com)
10 * See the LICENSE file included with the distribution for details.
14 #include "../ff-common.h"
17 #include "ff3-bridge.h"
19 // this is the only one that differs between ff2 and ff3
20 #include <nsIDOMKeyEvent.h>
22 class FF3DomEventWrapper
: public nsIDOMEventListener
{
25 NS_DECL_NSIDOMEVENTLISTENER
29 FF3DomEventWrapper () {
35 callback_dom_event
*callback
;
36 nsCOMPtr
<nsIDOMEventTarget
> target
;
41 NS_IMPL_ISUPPORTS1(FF3DomEventWrapper
, nsIDOMEventListener
)
44 FF3DomEventWrapper::HandleEvent (nsIDOMEvent
*aDOMEvent
)
46 int client_x
, client_y
, offset_x
, offset_y
, mouse_button
, key_code
, char_code
;
47 gboolean alt_key
, ctrl_key
, shift_key
;
53 aDOMEvent
->GetType (str_event
);
55 client_x
= client_y
= offset_x
= offset_y
= mouse_button
= 0;
56 alt_key
= ctrl_key
= shift_key
= FALSE
;
57 key_code
= char_code
= 0;
59 FFDomEvent
*obj
= (FFDomEvent
*) NPN_CreateObject (npp
, FFDomEventClass
);
60 obj
->event
= aDOMEvent
;
62 nsCOMPtr
<nsIDOMMouseEvent
> mouse_event
= do_QueryInterface (aDOMEvent
);
63 if (mouse_event
!= nsnull
) {
64 int screen_x
, screen_y
;
66 mouse_event
->GetScreenX (&screen_x
);
67 mouse_event
->GetScreenY (&screen_y
);
69 mouse_event
->GetClientX (&client_x
);
70 mouse_event
->GetClientY (&client_y
);
72 offset_x
= screen_x
- client_x
;
73 offset_y
= screen_y
- client_y
;
75 mouse_event
->GetAltKey (&alt_key
);
76 mouse_event
->GetCtrlKey (&ctrl_key
);
77 mouse_event
->GetShiftKey (&shift_key
);
79 PRUint16 umouse_button
;
80 mouse_event
->GetButton (&umouse_button
);
81 mouse_button
= umouse_button
;
84 nsCOMPtr
<nsIDOMKeyEvent
> key_event
= do_QueryInterface (aDOMEvent
);
85 if (key_event
!= nsnull
) {
86 PRUint32 ukey_code
, uchar_code
;
88 key_event
->GetKeyCode (&ukey_code
);
89 key_event
->GetCharCode (&uchar_code
);
92 char_code
= uchar_code
;
94 if (char_code
== 0 && key_code
!= 0)
97 key_event
->GetAltKey (&alt_key
);
98 key_event
->GetCtrlKey (&ctrl_key
);
99 key_event
->GetShiftKey (&shift_key
);
102 callback (context
, strdup (NS_ConvertUTF16toUTF8 (str_event
).get ()), client_x
, client_y
, offset_x
, offset_y
,
103 alt_key
, ctrl_key
, shift_key
, mouse_button
, key_code
, char_code
, obj
);
108 static nsCOMPtr
<nsIDOMDocument
>
109 ff3_get_dom_document (NPP npp
)
111 nsCOMPtr
<nsIDOMWindow
> dom_window
;
112 NPN_GetValue (npp
, NPNVDOMWindow
, static_cast<nsIDOMWindow
**>(getter_AddRefs(dom_window
)));
114 d (printf ("No DOM window available\n"));
118 nsCOMPtr
<nsIDOMDocument
> dom_document
;
119 dom_window
->GetDocument (getter_AddRefs (dom_document
));
120 if (dom_document
== nsnull
) {
121 d(printf ("No DOM document available\n"));
128 FF3BrowserBridge::FF3BrowserBridge ()
130 FFDomEventClass
= new FFDomEventType ();
134 FF3BrowserBridge::HtmlElementGetText (NPP npp
, const char *element_id
)
138 nsCOMPtr
<nsIDOMDocument
> document
;
139 document
= ff3_get_dom_document (npp
);
143 nsString ns_id
= NS_ConvertUTF8toUTF16 (element_id
, strlen (element_id
));
144 nsCOMPtr
<nsIDOMElement
> element
;
145 rv
= document
->GetElementById (ns_id
, getter_AddRefs (element
));
146 if (NS_FAILED (rv
) || element
== NULL
)
149 nsCOMPtr
<nsIDOMDocument
> owner
;
150 element
->GetOwnerDocument (getter_AddRefs (owner
));
152 nsCOMPtr
<nsIDOMDocumentRange
> doc_range
= do_QueryInterface (owner
);
156 nsCOMPtr
<nsIDOMRange
> range
;
157 doc_range
->CreateRange (getter_AddRefs (range
));
161 range
->SelectNodeContents (element
);
164 range
->ToString (text
);
165 return g_strdup (NS_ConvertUTF16toUTF8 (text
).get ());
169 FF3BrowserBridge::HtmlObjectAttachEvent (NPP npp
, NPObject
*npobj
, const char *name
, callback_dom_event cb
, gpointer context
)
173 NPIdentifier id_identifier
= NPN_GetStringIdentifier ("id");
174 nsCOMPtr
<nsISupports
> item
;
176 NPN_GetProperty (npp
, npobj
, id_identifier
, &npresult
);
178 if (NPVARIANT_IS_STRING (npresult
) && strlen (STR_FROM_VARIANT (npresult
)) > 0) {
179 NPString np_id
= NPVARIANT_TO_STRING (npresult
);
181 nsString ns_id
= NS_ConvertUTF8toUTF16 (np_id
.utf8characters
, strlen (np_id
.utf8characters
));
182 nsCOMPtr
<nsIDOMDocument
> dom_document
= ff3_get_dom_document (npp
);
184 nsCOMPtr
<nsIDOMElement
> element
;
185 rv
= dom_document
->GetElementById (ns_id
, getter_AddRefs (element
));
186 if (NS_FAILED (rv
) || element
== nsnull
) {
192 NPObject
*window
= NULL
;
193 NPN_GetValue (npp
, NPNVWindowNPObject
, &window
);
195 if (window
&& npobj
->_class
== window
->_class
) {
196 NPN_GetValue (npp
, NPNVDOMWindow
, static_cast<nsISupports
**>(getter_AddRefs (item
)));
199 NPIdentifier document_identifier
= NPN_GetStringIdentifier ("document");
201 NPN_GetProperty (npp
, window
, document_identifier
, &docresult
);
203 if (npobj
== NPVARIANT_TO_OBJECT (docresult
)) {
204 item
= ff3_get_dom_document (npp
);
206 const char *temp_id
= "__moonlight_temp_id";
209 string_to_npvariant (temp_id
, &npvalue
);
210 NPN_SetProperty (npp
, npobj
, id_identifier
, &npvalue
);
211 NPN_ReleaseVariantValue (&npvalue
);
213 nsString ns_id
= NS_ConvertUTF8toUTF16 (temp_id
, strlen (temp_id
));
214 nsCOMPtr
<nsIDOMDocument
> dom_document
= ff3_get_dom_document (npp
);
216 nsCOMPtr
<nsIDOMElement
> element
;
217 dom_document
->GetElementById (ns_id
, getter_AddRefs (element
));
218 if (element
== nsnull
) {
219 d(printf ("Unable to find temp_id element\n"));
225 // reset to it's original empty value
226 NPN_SetProperty (npp
, npobj
, id_identifier
, &npresult
);
231 nsCOMPtr
<nsIDOMEventTarget
> target
= do_QueryInterface (item
);
233 FF3DomEventWrapper
*wrapper
= new FF3DomEventWrapper ();
234 wrapper
->callback
= cb
;
235 wrapper
->target
= target
;
236 wrapper
->context
= context
;
239 rv
= target
->AddEventListener (NS_ConvertUTF8toUTF16 (name
, strlen (name
)), wrapper
, PR_TRUE
);
245 FF3BrowserBridge::HtmlObjectDetachEvent (NPP instance
, const char *name
, gpointer listener_ptr
)
247 FF3DomEventWrapper
*wrapper
= (FF3DomEventWrapper
*) listener_ptr
;
249 wrapper
->target
->RemoveEventListener (NS_ConvertUTF8toUTF16 (name
, strlen (name
)), wrapper
, PR_TRUE
);
250 wrapper
->callback
= NULL
;
254 dom_event_allocate (NPP instance
, NPClass
*klass
)
256 return new FFDomEvent (instance
);
259 FFDomEventType::FFDomEventType ()
261 allocate
= dom_event_allocate
;
262 AddMapping (dom_event_mapping
, G_N_ELEMENTS (dom_event_mapping
));
265 FFDomEventType
*FFDomEventClass
;
269 FFDomEvent::GetProperty (int id
, NPIdentifier name
, NPVariant
*result
)
271 NULL_TO_NPVARIANT (*result
);
274 NPUTF8
*strname
= NPN_UTF8FromIdentifier (name
);
275 printf ("getting event property %s\n", strname
);
276 NPN_MemFree (strname
);
280 case MoonId_Detail
: {
281 nsCOMPtr
<nsIDOMUIEvent
> uievent
= do_QueryInterface (event
);
284 uievent
->GetDetail (&detail
);
285 INT32_TO_NPVARIANT (detail
, *result
);
295 FFDomEvent::Invoke (int id
, NPIdentifier name
,
296 const NPVariant
*args
, uint32_t argCount
, NPVariant
*result
)
298 NULL_TO_NPVARIANT (*result
);
299 ds(printf("FFDomEvent::Invoke\n"));
301 case MoonId_StopPropagation
: {
303 ds(printf("FFDomEvent::StopPropagation\n"));
304 event
->StopPropagation ();
308 case MoonId_PreventDefault
: {
310 ds(printf("FFDomEvent::PreventDefault\n"));
311 event
->PreventDefault ();
316 return MoonlightObject::Invoke (id
, name
, args
, argCount
, result
);