ReactOS  0.4.13-dev-563-g0561610
nsevents.c
Go to the documentation of this file.
1 /*
2  * Copyright 2007-2008 Jacek Caban for CodeWeavers
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18 
19 #include "mshtml_private.h"
20 
21 static const PRUnichar blurW[] = {'b','l','u','r',0};
22 static const PRUnichar focusW[] = {'f','o','c','u','s',0};
23 static const PRUnichar keypressW[] = {'k','e','y','p','r','e','s','s',0};
24 static const PRUnichar loadW[] = {'l','o','a','d',0};
25 
26 typedef struct {
30 
37 
39 
41 };
42 
44 {
46 
47  TRACE("(%p) ref=%d\n", This, ref);
48 
49  if(!ref)
50  heap_free(This);
51 
52  return ref;
53 }
54 
56 {
57  return CONTAINING_RECORD(iface, nsEventListener, nsIDOMEventListener_iface);
58 }
59 
61  nsIIDRef riid, void **result)
62 {
64 
65  *result = NULL;
66 
67  if(IsEqualGUID(&IID_nsISupports, riid)) {
68  TRACE("(%p)->(IID_nsISupports, %p)\n", This, result);
69  *result = &This->nsIDOMEventListener_iface;
70  }else if(IsEqualGUID(&IID_nsIDOMEventListener, riid)) {
71  TRACE("(%p)->(IID_nsIDOMEventListener %p)\n", This, result);
72  *result = &This->nsIDOMEventListener_iface;
73  }
74 
75  if(*result) {
76  nsIDOMEventListener_AddRef(&This->nsIDOMEventListener_iface);
77  return NS_OK;
78  }
79 
80  TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), result);
81  return NS_NOINTERFACE;
82 }
83 
85 {
87  LONG ref = InterlockedIncrement(&This->This->ref);
88 
89  TRACE("(%p) ref=%d\n", This->This, ref);
90 
91  return ref;
92 }
93 
95 {
97 
98  return release_listener(This->This);
99 }
100 
101 static BOOL is_doc_child_focus(NSContainer *nscontainer)
102 {
103  HWND hwnd;
104 
105  for(hwnd = GetFocus(); hwnd && hwnd != nscontainer->hwnd; hwnd = GetParent(hwnd));
106 
107  return hwnd != NULL;
108 }
109 
111 {
113  HTMLDocumentNode *doc = This->This->doc;
114  HTMLDocumentObj *doc_obj;
115 
116  TRACE("(%p)\n", doc);
117 
118  if(!doc || !doc->basedoc.doc_obj)
119  return NS_ERROR_FAILURE;
120  doc_obj = doc->basedoc.doc_obj;
121 
122  if(doc_obj->focus && !is_doc_child_focus(doc_obj->nscontainer)) {
123  doc_obj->focus = FALSE;
124  notif_focus(doc_obj);
125  }
126 
127  return NS_OK;
128 }
129 
131 {
133  HTMLDocumentNode *doc = This->This->doc;
134  HTMLDocumentObj *doc_obj;
135 
136  TRACE("(%p)\n", doc);
137 
138  if(!doc)
139  return NS_ERROR_FAILURE;
140  doc_obj = doc->basedoc.doc_obj;
141 
142  if(!doc_obj->focus) {
143  doc_obj->focus = TRUE;
144  notif_focus(doc_obj);
145  }
146 
147  return NS_OK;
148 }
149 
152 {
154  HTMLDocumentNode *doc = This->This->doc;
155  HTMLDocumentObj *doc_obj;
156 
157  if(!doc)
158  return NS_ERROR_FAILURE;
159  doc_obj = doc->basedoc.doc_obj;
160 
161  TRACE("(%p)->(%p)\n", doc, event);
162 
163  update_doc(&doc_obj->basedoc, UPDATE_UI);
164  if(doc_obj->usermode == EDITMODE)
165  handle_edit_event(&doc_obj->basedoc, event);
166 
167  return NS_OK;
168 }
169 
171 {
172  IOleCommandTarget *olecmd = NULL;
173  HRESULT hres;
174 
175  if(doc->nscontainer->editor_controller) {
176  nsIController_Release(doc->nscontainer->editor_controller);
178  }
179 
180  if(doc->usermode == EDITMODE)
181  handle_edit_load(&doc->basedoc);
182 
183  if(doc->client) {
184  hres = IOleClientSite_QueryInterface(doc->client, &IID_IOleCommandTarget, (void**)&olecmd);
185  if(FAILED(hres))
186  olecmd = NULL;
187  }
188 
189  if(doc->download_state) {
190  if(olecmd) {
192 
193  V_VT(&progress) = VT_I4;
194  V_I4(&progress) = 0;
195  IOleCommandTarget_Exec(olecmd, NULL, OLECMDID_SETPROGRESSPOS,
196  OLECMDEXECOPT_DONTPROMPTUSER, &progress, NULL);
197  }
198 
199  set_download_state(doc, 0);
200  }
201 
202  if(olecmd) {
203  IOleCommandTarget_Exec(olecmd, &CGID_ShellDocView, 103, 0, NULL, NULL);
204  IOleCommandTarget_Exec(olecmd, &CGID_MSHTML, IDM_PARSECOMPLETE, 0, NULL, NULL);
205  IOleCommandTarget_Exec(olecmd, NULL, OLECMDID_HTTPEQUIV_DONE, 0, NULL, NULL);
206 
207  IOleCommandTarget_Release(olecmd);
208  }
209 }
210 
212 {
214  HTMLDocumentNode *doc = This->This->doc;
215  HTMLDocumentObj *doc_obj = NULL;
216  nsresult nsres = NS_OK;
217 
218  TRACE("(%p)\n", doc);
219 
220  if(!doc || !doc->basedoc.window)
221  return NS_ERROR_FAILURE;
222  if(doc->basedoc.doc_obj && doc->basedoc.doc_obj->basedoc.doc_node == doc)
223  doc_obj = doc->basedoc.doc_obj;
224 
225  connect_scripts(doc->window);
226 
227  htmldoc_addref(&doc->basedoc);
228 
229  if(doc_obj)
230  handle_docobj_load(doc_obj);
231 
232  set_ready_state(doc->basedoc.window, READYSTATE_COMPLETE);
233 
234  if(doc_obj) {
235  if(doc_obj->view_sink)
236  IAdviseSink_OnViewChange(doc_obj->view_sink, DVASPECT_CONTENT, -1);
237 
239 
240  update_title(doc_obj);
241  }
242 
243  if(doc_obj && doc_obj->usermode!=EDITMODE && doc_obj->doc_object_service
245  IDocObjectService_FireDocumentComplete(doc_obj->doc_object_service,
247 
248  if(doc->nsdoc) {
249  nsIDOMHTMLElement *nsbody;
250 
252 
253  nsres = nsIDOMHTMLDocument_GetBody(doc->nsdoc, &nsbody);
254  if(NS_SUCCEEDED(nsres) && nsbody) {
256  nsIDOMHTMLElement_Release(nsbody);
257  }
258  }else {
259  ERR("NULL nsdoc\n");
260  nsres = NS_ERROR_FAILURE;
261  }
262 
263  htmldoc_release(&doc->basedoc);
264  return nsres;
265 }
266 
268 {
270  HTMLDocumentNode *doc = This->This->doc;
271  const PRUnichar *type;
272  nsIDOMEventTarget *event_target;
273  nsIDOMNode *nsnode;
274  nsAString type_str;
275  eventid_t eid;
276  nsresult nsres;
277 
278  TRACE("%p\n", This->This);
279 
280  if(!doc) {
281  WARN("NULL doc\n");
282  return NS_OK;
283  }
284 
285  nsAString_Init(&type_str, NULL);
286  nsIDOMEvent_GetType(event, &type_str);
287  nsAString_GetData(&type_str, &type);
288  eid = str_to_eid(type);
289  nsAString_Finish(&type_str);
290 
291  nsres = nsIDOMEvent_GetTarget(event, &event_target);
292  if(NS_FAILED(nsres) || !event_target) {
293  ERR("GetEventTarget failed: %08x\n", nsres);
294  return NS_OK;
295  }
296 
297  nsres = nsIDOMEventTarget_QueryInterface(event_target, &IID_nsIDOMNode, (void**)&nsnode);
298  nsIDOMEventTarget_Release(event_target);
299  if(NS_FAILED(nsres)) {
300  ERR("Could not get nsIDOMNode: %08x\n", nsres);
301  return NS_OK;
302  }
303 
304  fire_event(doc, eid, TRUE, nsnode, event, NULL);
305 
306  nsIDOMNode_Release(nsnode);
307 
308  return NS_OK;
309 }
310 
311 #define EVENTLISTENER_VTBL(handler) \
312  { \
313  nsDOMEventListener_QueryInterface, \
314  nsDOMEventListener_AddRef, \
315  nsDOMEventListener_Release, \
316  handler, \
317  }
318 
319 static const nsIDOMEventListenerVtbl blur_vtbl = EVENTLISTENER_VTBL(handle_blur);
320 static const nsIDOMEventListenerVtbl focus_vtbl = EVENTLISTENER_VTBL(handle_focus);
321 static const nsIDOMEventListenerVtbl keypress_vtbl = EVENTLISTENER_VTBL(handle_keypress);
322 static const nsIDOMEventListenerVtbl load_vtbl = EVENTLISTENER_VTBL(handle_load);
323 static const nsIDOMEventListenerVtbl htmlevent_vtbl = EVENTLISTENER_VTBL(handle_htmlevent);
324 
326  nsIDOMEventListener *listener, BOOL capture)
327 {
328  nsAString type_str;
329  nsresult nsres;
330 
331  nsAString_InitDepend(&type_str, type);
332  nsres = nsIDOMEventTarget_AddEventListener(target, &type_str, listener, capture, FALSE, 1);
333  nsAString_Finish(&type_str);
334  if(NS_FAILED(nsres))
335  ERR("AddEventTarget failed: %08x\n", nsres);
336 
337 }
338 
340  const nsIDOMEventListenerVtbl *vtbl)
341 {
342  This->nsIDOMEventListener_iface.lpVtbl = vtbl;
343  This->This = listener;
344 }
345 
347 {
349  nsresult nsres;
350 
351  if(nsnode)
352  nsres = nsIDOMNode_QueryInterface(nsnode, &IID_nsIDOMEventTarget, (void**)&target);
353  else
354  nsres = nsIDOMWindow_QueryInterface(doc->basedoc.window->nswindow, &IID_nsIDOMEventTarget, (void**)&target);
355  if(NS_FAILED(nsres)) {
356  ERR("Could not get nsIDOMEventTarget interface: %08x\n", nsres);
357  return;
358  }
359 
361  TRUE);
362  nsIDOMEventTarget_Release(target);
363 }
364 
365 static void detach_nslistener(HTMLDocumentNode *doc, const WCHAR *type, nsEventListener *listener, cpp_bool is_capture)
366 {
368  nsAString type_str;
369  nsresult nsres;
370 
371  if(!doc->basedoc.window)
372  return;
373 
374  nsres = nsIDOMWindow_QueryInterface(doc->basedoc.window->nswindow, &IID_nsIDOMEventTarget, (void**)&target);
375  if(NS_FAILED(nsres)) {
376  ERR("Could not get nsIDOMEventTarget interface: %08x\n", nsres);
377  return;
378  }
379 
380  nsAString_InitDepend(&type_str, type);
381  nsres = nsIDOMEventTarget_RemoveEventListener(target, &type_str,
382  &listener->nsIDOMEventListener_iface, is_capture);
383  nsAString_Finish(&type_str);
384  nsIDOMEventTarget_Release(target);
385  if(NS_FAILED(nsres))
386  ERR("RemoveEventTarget failed: %08x\n", nsres);
387 }
388 
390 {
392 }
393 
395 {
396  nsDocumentEventListener *listener = doc->nsevent_listener;
397 
398  TRACE("%p %p\n", doc, doc->nsevent_listener);
399 
400  if(!listener)
401  return;
402 
403  detach_nslistener(doc, blurW, &listener->blur_listener, TRUE);
404  detach_nslistener(doc, focusW, &listener->focus_listener, TRUE);
406  detach_nslistener(doc, loadW, &listener->load_listener, TRUE);
407 
408  listener->doc = NULL;
409  release_listener(listener);
410  doc->nsevent_listener = NULL;
411 }
412 
414 {
415  nsDocumentEventListener *listener;
417  nsresult nsres;
418 
419  listener = heap_alloc(sizeof(nsDocumentEventListener));
420  if(!listener)
421  return;
422 
423  TRACE("%p %p\n", doc, listener);
424 
425  listener->ref = 1;
426  listener->doc = doc;
427 
428  init_listener(&listener->blur_listener, listener, &blur_vtbl);
429  init_listener(&listener->focus_listener, listener, &focus_vtbl);
430  init_listener(&listener->keypress_listener, listener, &keypress_vtbl);
431  init_listener(&listener->load_listener, listener, &load_vtbl);
432  init_listener(&listener->htmlevent_listener, listener, &htmlevent_vtbl);
433 
434  doc->nsevent_listener = listener;
435 
436  nsres = nsIDOMWindow_QueryInterface(doc->basedoc.window->nswindow, &IID_nsIDOMEventTarget, (void**)&target);
437  if(NS_FAILED(nsres)) {
438  ERR("Could not get nsIDOMEventTarget interface: %08x\n", nsres);
439  return;
440  }
441 
446 
447  nsIDOMEventTarget_Release(target);
448 }
#define UPDATE_UI
static nsresult NSAPI handle_blur(nsIDOMEventListener *iface, nsIDOMEvent *event)
Definition: nsevents.c:110
static void init_listener(nsEventListener *This, nsDocumentEventListener *listener, const nsIDOMEventListenerVtbl *vtbl)
Definition: nsevents.c:339
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
static LONG release_listener(nsDocumentEventListener *This)
Definition: nsevents.c:43
static nsrefcnt NSAPI nsDOMEventListener_AddRef(nsIDOMEventListener *iface)
Definition: nsevents.c:84
void handle_edit_event(HTMLDocument *This, nsIDOMEvent *event)
Definition: editor.c:384
static const nsIDOMEventListenerVtbl keypress_vtbl
Definition: nsevents.c:321
#define TRUE
Definition: types.h:120
static const PRUnichar loadW[]
Definition: nsevents.c:24
void update_doc(HTMLDocument *, DWORD) DECLSPEC_HIDDEN
Definition: view.c:62
Definition: compat.h:1939
HTMLDocumentObj * doc_obj
nsIDOMHTMLDocument * nsdoc
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
static nsresult NSAPI handle_focus(nsIDOMEventListener *iface, nsIDOMEvent *event)
Definition: nsevents.c:130
IOleClientSite * client
#define NSAPI
REFIID riid
Definition: precomp.h:44
HTMLInnerWindow * window
static const PRUnichar blurW[]
Definition: nsevents.c:21
#define WARN(fmt,...)
Definition: debug.h:111
HTMLOuterWindow * window
REFIID nsIIDRef
Definition: nsiface.idl:45
void connect_scripts(HTMLInnerWindow *) DECLSPEC_HIDDEN
Definition: script.c:213
static nsresult NSAPI handle_load(nsIDOMEventListener *iface, nsIDOMEvent *event)
Definition: nsevents.c:211
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
void handle_edit_load(HTMLDocument *This)
Definition: editor.c:482
static nsresult NSAPI nsDOMEventListener_QueryInterface(nsIDOMEventListener *iface, nsIIDRef riid, void **result)
Definition: nsevents.c:60
static const nsIDOMEventListenerVtbl htmlevent_vtbl
Definition: nsevents.c:323
static void init_event(nsIDOMEventTarget *target, const PRUnichar *type, nsIDOMEventListener *listener, BOOL capture)
Definition: nsevents.c:325
HTMLDocument basedoc
Definition: send.c:47
static void * heap_alloc(size_t len)
Definition: appwiz.h:65
HTMLDocumentNode * doc_node
#define V_I4(A)
Definition: oleauto.h:247
static const PRUnichar keypressW[]
Definition: nsevents.c:23
#define NS_OK
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
void set_statustext(HTMLDocumentObj *doc, INT id, LPCWSTR arg)
Definition: main.c:104
GLenum GLint ref
Definition: glext.h:6028
nsIController * editor_controller
void set_download_state(HTMLDocumentObj *, int) DECLSPEC_HIDDEN
Definition: persist.c:170
NSContainer * nscontainer
nsIDOMEventListener nsIDOMEventListener_iface
Definition: nsevents.c:27
smooth NULL
Definition: ftsmooth.c:416
static BOOL is_doc_child_focus(NSContainer *nscontainer)
Definition: nsevents.c:101
static nsresult NSAPI handle_htmlevent(nsIDOMEventListener *iface, nsIDOMEvent *event)
Definition: nsevents.c:267
void release_nsevents(HTMLDocumentNode *doc)
Definition: nsevents.c:394
void detach_nsevent(HTMLDocumentNode *doc, const WCHAR *type)
Definition: nsevents.c:389
#define debugstr_guid
Definition: kernel32.h:35
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define NS_FAILED(res)
IDispatchEx IDispatchEx_iface
void update_title(HTMLDocumentObj *) DECLSPEC_HIDDEN
Definition: view.c:70
eventid_t str_to_eid(LPCWSTR str)
Definition: htmlevent.c:217
static nsresult NSAPI handle_keypress(nsIDOMEventListener *iface, nsIDOMEvent *event)
Definition: nsevents.c:150
#define NS_ERROR_FAILURE
unsigned char cpp_bool
Definition: atl.c:39
#define TRACE(s)
Definition: solgame.cpp:4
HRESULT hres
Definition: protocol.c:465
static nsrefcnt NSAPI nsDOMEventListener_Release(nsIDOMEventListener *iface)
Definition: nsevents.c:94
__wchar_t WCHAR
Definition: xmlstorage.h:180
LONG HRESULT
Definition: typedefs.h:77
#define IDM_PARSECOMPLETE
Definition: mshtmcid.h:305
HTMLDocument basedoc
void add_nsevent_listener(HTMLDocumentNode *doc, nsIDOMNode *nsnode, LPCWSTR type)
Definition: nsevents.c:346
#define NS_SUCCEEDED(res)
static void detach_nslistener(HTMLDocumentNode *doc, const WCHAR *type, nsEventListener *listener, cpp_bool is_capture)
Definition: nsevents.c:365
#define IDS_STATUS_DONE
Definition: resource.h:25
static void handle_docobj_load(HTMLDocumentObj *doc)
Definition: nsevents.c:170
#define InterlockedDecrement
Definition: armddk.h:52
void notif_focus(HTMLDocumentObj *) DECLSPEC_HIDDEN
Definition: view.c:130
nsIDOMWindow * nswindow
#define V_VT(A)
Definition: oleauto.h:211
static const nsIDOMEventListenerVtbl focus_vtbl
Definition: nsevents.c:320
nsEventListener blur_listener
Definition: nsevents.c:32
#define EVENTLISTENER_VTBL(handler)
Definition: nsevents.c:311
UINT32 nsAString_GetData(const nsAString *, const PRUnichar **) DECLSPEC_HIDDEN
Definition: nsembed.c:831
struct _cl_event * event
Definition: glext.h:7739
nsEventListener focus_listener
Definition: nsevents.c:33
static ULONG htmldoc_release(HTMLDocument *This)
HTMLDocumentNode * doc
Definition: nsevents.c:40
static nsEventListener * impl_from_nsIDOMEventListener(nsIDOMEventListener *iface)
Definition: nsevents.c:55
#define BINDING_REFRESH
Definition: binding.h:130
#define ERR(fmt,...)
Definition: debug.h:109
void init_nsevents(HTMLDocumentNode *doc)
Definition: nsevents.c:413
HWND WINAPI GetParent(_In_ HWND)
IAdviseSink * view_sink
#define InterlockedIncrement
Definition: armddk.h:53
static const PRUnichar focusW[]
Definition: nsevents.c:22
nsEventListener load_listener
Definition: nsevents.c:35
IDocObjectService * doc_object_service
void flush_pending_tasks(LONG) DECLSPEC_HIDDEN
Definition: task.c:88
#define NS_NOINTERFACE
eventid_t
Definition: htmlevent.h:21
static ULONG htmldoc_addref(HTMLDocument *This)
void nsAString_InitDepend(nsAString *, const PRUnichar *) DECLSPEC_HIDDEN
Definition: nsembed.c:826
void set_ready_state(HTMLOuterWindow *, READYSTATE) DECLSPEC_HIDDEN
Definition: persist.c:450
BOOL WINAPI IsEqualGUID(REFGUID rguid1, REFGUID rguid2)
Definition: compobj.c:4021
cd_progress_ptr progress
Definition: cdjpeg.h:150
BOOL nsAString_Init(nsAString *, const PRUnichar *) DECLSPEC_HIDDEN
Definition: nsembed.c:817
static const nsIDOMEventListenerVtbl blur_vtbl
Definition: nsevents.c:319
void nsAString_Finish(nsAString *) DECLSPEC_HIDDEN
Definition: nsembed.c:836
HWND WINAPI GetFocus(void)
Definition: window.c:1875
IHTMLWindow2 IHTMLWindow2_iface
HRESULT nsresult
Definition: nsiface.idl:39
WCHAR PRUnichar
Definition: nsiface.idl:48
GLenum target
Definition: glext.h:7315
nsEventListener keypress_listener
Definition: nsevents.c:34
nsDocumentEventListener * This
Definition: nsevents.c:28
nsEventListener htmlevent_listener
Definition: nsevents.c:36
GLuint64EXT * result
Definition: glext.h:11304
static const nsIDOMEventListenerVtbl load_vtbl
Definition: nsevents.c:322
ULONG nsrefcnt
Definition: nsiface.idl:40
nsDocumentEventListener * nsevent_listener
static BOOL heap_free(void *mem)
Definition: appwiz.h:75
void fire_event(HTMLDocumentNode *doc, eventid_t eid, BOOL set_event, nsIDOMNode *target, nsIDOMEvent *nsevent, IDispatch *script_this)
Definition: htmlevent.c:1195