2009-12-07 Rolf Bjarne Kvinge <RKvinge@novell.com>
[moon.git] / plugin / firefox / ff3 / ff3-dom.cpp
blob6c715e466d7f9082851ae9817153c3e8487cd05b
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3 * ff3-dom.cpp: Firefox 3.x DOM wrapper
5 * Contact:
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"
15 #include "plugin.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 {
24 NS_DECL_ISUPPORTS
25 NS_DECL_NSIDOMEVENTLISTENER
27 public:
29 FF3DomEventWrapper () {
30 callback = NULL;
32 NS_INIT_ISUPPORTS ();
35 callback_dom_event *callback;
36 nsCOMPtr<nsIDOMEventTarget> target;
37 gpointer context;
38 NPP npp;
41 NS_IMPL_ISUPPORTS1(FF3DomEventWrapper, nsIDOMEventListener)
43 NS_IMETHODIMP
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;
48 nsString str_event;
50 if (callback == NULL)
51 return NS_OK;
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);
91 key_code = ukey_code;
92 char_code = uchar_code;
94 if (char_code == 0 && key_code != 0)
95 char_code = key_code;
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);
105 return NS_OK;
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)));
113 if (!dom_window) {
114 d (printf ("No DOM window available\n"));
115 return NULL;
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"));
122 return NULL;
125 return dom_document;
128 FF3BrowserBridge::FF3BrowserBridge ()
130 FFDomEventClass = new FFDomEventType ();
133 const char*
134 FF3BrowserBridge::HtmlElementGetText (NPP npp, const char *element_id)
136 nsresult rv = NS_OK;
138 nsCOMPtr<nsIDOMDocument> document;
139 document = ff3_get_dom_document (npp);
140 if (!document)
141 return NULL;
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)
147 return NULL;
149 nsCOMPtr<nsIDOMDocument> owner;
150 element->GetOwnerDocument (getter_AddRefs (owner));
152 nsCOMPtr<nsIDOMDocumentRange> doc_range = do_QueryInterface (owner);
153 if (!doc_range)
154 return NULL;
156 nsCOMPtr<nsIDOMRange> range;
157 doc_range->CreateRange (getter_AddRefs (range));
158 if (!range)
159 return NULL;
161 range->SelectNodeContents (element);
163 nsString text;
164 range->ToString (text);
165 return g_strdup (NS_ConvertUTF16toUTF8 (text).get ());
168 gpointer
169 FF3BrowserBridge::HtmlObjectAttachEvent (NPP npp, NPObject *npobj, const char *name, callback_dom_event cb, gpointer context)
171 nsresult rv;
172 NPVariant npresult;
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) {
187 return NULL;
190 item = element;
191 } else {
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)));
197 } else {
198 NPVariant docresult;
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);
205 } else {
206 const char *temp_id = "__moonlight_temp_id";
207 NPVariant npvalue;
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"));
220 return NULL;
223 item = element;
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;
237 wrapper->npp = npp;
239 rv = target->AddEventListener (NS_ConvertUTF8toUTF16 (name, strlen (name)), wrapper, PR_TRUE);
241 return wrapper;
244 void
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;
253 static NPObject *
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;
268 bool
269 FFDomEvent::GetProperty (int id, NPIdentifier name, NPVariant *result)
271 NULL_TO_NPVARIANT (*result);
273 #if ds(!)0
274 NPUTF8 *strname = NPN_UTF8FromIdentifier (name);
275 printf ("getting event property %s\n", strname);
276 NPN_MemFree (strname);
277 #endif
279 switch (id) {
280 case MoonId_Detail: {
281 nsCOMPtr<nsIDOMUIEvent> uievent = do_QueryInterface (event);
282 if (uievent) {
283 int detail;
284 uievent->GetDetail (&detail);
285 INT32_TO_NPVARIANT (detail, *result);
287 return true;
291 return false;
294 bool
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"));
300 switch (id) {
301 case MoonId_StopPropagation: {
302 if (event) {
303 ds(printf("FFDomEvent::StopPropagation\n"));
304 event->StopPropagation ();
306 return true;
308 case MoonId_PreventDefault: {
309 if (event) {
310 ds(printf("FFDomEvent::PreventDefault\n"));
311 event->PreventDefault ();
313 return true;
315 default: {
316 return MoonlightObject::Invoke (id, name, args, argCount, result);