ole32: Rename PROPSET_BLOCK_SIZE to RAW_DIRENTRY_SIZE.
[wine/testsucceed.git] / dlls / mshtml / mutation.c
blob84c9241334686b2ebc4587a3ace265b6eb6ae801
1 /*
2 * Copyright 2008 Jacek Caban for CodeWeavers
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.
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.
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
19 #include "config.h"
21 #include <stdarg.h>
23 #define COBJMACROS
25 #include "windef.h"
26 #include "winbase.h"
27 #include "winuser.h"
28 #include "winreg.h"
29 #include "ole2.h"
30 #include "shlguid.h"
32 #include "mshtml_private.h"
33 #include "htmlevent.h"
35 #include "wine/debug.h"
37 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
39 enum {
40 MUTATION_COMMENT,
41 MUTATION_ENDLOAD,
42 MUTATION_FRAME,
43 MUTATION_IFRAME,
44 MUTATION_SCRIPT
47 #define IE_MAJOR_VERSION 7
48 #define IE_MINOR_VERSION 0
50 static BOOL handle_insert_comment(HTMLDocumentNode *doc, const PRUnichar *comment)
52 DWORD len;
53 int majorv = 0, minorv = 0;
54 const PRUnichar *ptr, *end;
55 nsAString nsstr;
56 PRUnichar *buf;
57 nsresult nsres;
59 enum {
60 CMP_EQ,
61 CMP_LT,
62 CMP_LTE,
63 CMP_GT,
64 CMP_GTE
65 } cmpt = CMP_EQ;
67 static const PRUnichar endifW[] = {'<','!','[','e','n','d','i','f',']'};
69 if(comment[0] != '[' || comment[1] != 'i' || comment[2] != 'f')
70 return FALSE;
72 ptr = comment+3;
73 while(isspaceW(*ptr))
74 ptr++;
76 if(ptr[0] == 'l' && ptr[1] == 't') {
77 ptr += 2;
78 if(*ptr == 'e') {
79 cmpt = CMP_LTE;
80 ptr++;
81 }else {
82 cmpt = CMP_LT;
84 }else if(ptr[0] == 'g' && ptr[1] == 't') {
85 ptr += 2;
86 if(*ptr == 'e') {
87 cmpt = CMP_GTE;
88 ptr++;
89 }else {
90 cmpt = CMP_GT;
94 if(!isspaceW(*ptr++))
95 return FALSE;
96 while(isspaceW(*ptr))
97 ptr++;
99 if(ptr[0] != 'I' || ptr[1] != 'E')
100 return FALSE;
102 ptr +=2;
103 if(!isspaceW(*ptr++))
104 return FALSE;
105 while(isspaceW(*ptr))
106 ptr++;
108 if(!isdigitW(*ptr))
109 return FALSE;
110 while(isdigitW(*ptr))
111 majorv = majorv*10 + (*ptr++ - '0');
113 if(*ptr == '.') {
114 ptr++;
115 if(!isdigitW(*ptr))
116 return FALSE;
117 while(isdigitW(*ptr))
118 minorv = minorv*10 + (*ptr++ - '0');
121 while(isspaceW(*ptr))
122 ptr++;
123 if(ptr[0] != ']' || ptr[1] != '>')
124 return FALSE;
125 ptr += 2;
127 len = strlenW(ptr);
128 if(len < sizeof(endifW)/sizeof(WCHAR))
129 return FALSE;
131 end = ptr + len-sizeof(endifW)/sizeof(WCHAR);
132 if(memcmp(end, endifW, sizeof(endifW)))
133 return FALSE;
135 switch(cmpt) {
136 case CMP_EQ:
137 if(majorv == IE_MAJOR_VERSION && minorv == IE_MINOR_VERSION)
138 break;
139 return FALSE;
140 case CMP_LT:
141 if(majorv > IE_MAJOR_VERSION)
142 break;
143 if(majorv == IE_MAJOR_VERSION && minorv > IE_MINOR_VERSION)
144 break;
145 return FALSE;
146 case CMP_LTE:
147 if(majorv > IE_MAJOR_VERSION)
148 break;
149 if(majorv == IE_MAJOR_VERSION && minorv >= IE_MINOR_VERSION)
150 break;
151 return FALSE;
152 case CMP_GT:
153 if(majorv < IE_MAJOR_VERSION)
154 break;
155 if(majorv == IE_MAJOR_VERSION && minorv < IE_MINOR_VERSION)
156 break;
157 return FALSE;
158 case CMP_GTE:
159 if(majorv < IE_MAJOR_VERSION)
160 break;
161 if(majorv == IE_MAJOR_VERSION && minorv <= IE_MINOR_VERSION)
162 break;
163 return FALSE;
166 buf = heap_alloc((end-ptr+1)*sizeof(WCHAR));
167 if(!buf)
168 return FALSE;
170 memcpy(buf, ptr, (end-ptr)*sizeof(WCHAR));
171 buf[end-ptr] = 0;
172 nsAString_Init(&nsstr, buf);
173 heap_free(buf);
175 /* FIXME: Find better way to insert HTML to document. */
176 nsres = nsIDOMHTMLDocument_Write(doc->nsdoc, &nsstr);
177 nsAString_Finish(&nsstr);
178 if(NS_FAILED(nsres)) {
179 ERR("Write failed: %08x\n", nsres);
180 return FALSE;
183 return TRUE;
186 static void add_script_runner(HTMLDocumentNode *This)
188 nsIDOMNSDocument *nsdoc;
189 nsresult nsres;
191 nsres = nsIDOMHTMLDocument_QueryInterface(This->nsdoc, &IID_nsIDOMNSDocument, (void**)&nsdoc);
192 if(NS_FAILED(nsres)) {
193 ERR("Could not get nsIDOMNSDocument: %08x\n", nsres);
194 return;
197 nsIDOMNSDocument_WineAddScriptRunner(nsdoc, NSRUNNABLE(This));
198 nsIDOMNSDocument_Release(nsdoc);
201 #define NSRUNNABLE_THIS(iface) DEFINE_THIS(HTMLDocumentNode, IRunnable, iface)
203 static nsresult NSAPI nsRunnable_QueryInterface(nsIRunnable *iface,
204 nsIIDRef riid, nsQIResult result)
206 HTMLDocumentNode *This = NSRUNNABLE_THIS(iface);
208 if(IsEqualGUID(riid, &IID_nsISupports)) {
209 TRACE("(%p)->(IID_nsISupports %p)\n", This, result);
210 *result = NSRUNNABLE(This);
211 }else if(IsEqualGUID(riid, &IID_nsIRunnable)) {
212 TRACE("(%p)->(IID_nsIRunnable %p)\n", This, result);
213 *result = NSRUNNABLE(This);
214 }else {
215 *result = NULL;
216 WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), result);
217 return NS_NOINTERFACE;
220 nsISupports_AddRef((nsISupports*)*result);
221 return NS_OK;
224 static nsrefcnt NSAPI nsRunnable_AddRef(nsIRunnable *iface)
226 HTMLDocumentNode *This = NSRUNNABLE_THIS(iface);
227 return htmldoc_addref(&This->basedoc);
230 static nsrefcnt NSAPI nsRunnable_Release(nsIRunnable *iface)
232 HTMLDocumentNode *This = NSRUNNABLE_THIS(iface);
233 return htmldoc_release(&This->basedoc);
236 static void push_mutation_queue(HTMLDocumentNode *doc, DWORD type, nsISupports *nsiface)
238 mutation_queue_t *elem;
240 elem = heap_alloc(sizeof(mutation_queue_t));
241 if(!elem)
242 return;
244 elem->next = NULL;
245 elem->type = type;
246 elem->nsiface = nsiface;
247 if(nsiface)
248 nsISupports_AddRef(nsiface);
250 if(doc->mutation_queue_tail) {
251 doc->mutation_queue_tail = doc->mutation_queue_tail->next = elem;
252 }else {
253 doc->mutation_queue = doc->mutation_queue_tail = elem;
254 add_script_runner(doc);
258 static void pop_mutation_queue(HTMLDocumentNode *doc)
260 mutation_queue_t *tmp = doc->mutation_queue;
262 if(!tmp)
263 return;
265 doc->mutation_queue = tmp->next;
266 if(!tmp->next)
267 doc->mutation_queue_tail = NULL;
269 if(tmp->nsiface)
270 nsISupports_Release(tmp->nsiface);
271 heap_free(tmp);
274 static nsresult init_nsdoc_window(HTMLDocumentNode *doc, nsIDOMDocument *nsdoc, HTMLWindow **ret)
276 nsIDOMWindow *nswindow;
278 nswindow = get_nsdoc_window(nsdoc);
279 if(!nswindow)
280 return NS_ERROR_FAILURE;
282 if(!nswindow_to_window(nswindow)) {
283 HTMLWindow *window;
284 HRESULT hres;
286 hres = HTMLWindow_Create(doc->basedoc.doc_obj, nswindow, doc->basedoc.window, &window);
287 if(SUCCEEDED(hres))
288 *ret = window;
291 nsIDOMWindow_Release(nswindow);
292 return NS_OK;
295 static nsresult init_iframe_window(HTMLDocumentNode *doc, nsISupports *nsunk)
297 nsIDOMHTMLIFrameElement *nsiframe;
298 HTMLWindow *window = NULL;
299 nsIDOMDocument *nsdoc;
300 nsresult nsres;
302 nsres = nsISupports_QueryInterface(nsunk, &IID_nsIDOMHTMLIFrameElement, (void**)&nsiframe);
303 if(NS_FAILED(nsres)) {
304 ERR("Could not get nsIDOMHTMLIFrameElement: %08x\n", nsres);
305 return nsres;
308 nsres = nsIDOMHTMLIFrameElement_GetContentDocument(nsiframe, &nsdoc);
309 nsIDOMHTMLIFrameElement_Release(nsiframe);
310 if(NS_FAILED(nsres) || !nsdoc) {
311 ERR("GetContentDocument failed: %08x\n", nsres);
312 return nsres;
315 nsres = init_nsdoc_window(doc, nsdoc, &window);
317 if(window) {
318 HTMLIFrame_Create(doc, (nsIDOMHTMLElement*)nsiframe, window);
319 IHTMLWindow2_Release(HTMLWINDOW2(window));
322 nsIDOMDocument_Release(nsdoc);
323 return nsres;
326 static nsresult init_frame_window(HTMLDocumentNode *doc, nsISupports *nsunk)
328 nsIDOMHTMLFrameElement *nsframe;
329 HTMLWindow *window = NULL;
330 nsIDOMDocument *nsdoc;
331 nsresult nsres;
333 nsres = nsISupports_QueryInterface(nsunk, &IID_nsIDOMHTMLFrameElement, (void**)&nsframe);
334 if(NS_FAILED(nsres)) {
335 ERR("Could not get nsIDOMHTMLFrameElement: %08x\n", nsres);
336 return nsres;
339 nsres = nsIDOMHTMLFrameElement_GetContentDocument(nsframe, &nsdoc);
340 nsIDOMHTMLFrameElement_Release(nsframe);
341 if(NS_FAILED(nsres) || !nsdoc) {
342 ERR("GetContentDocument failed: %08x\n", nsres);
343 return nsres;
346 nsres = init_nsdoc_window(doc, nsdoc, &window);
348 if(window) {
349 HTMLFrameElement_Create(doc, (nsIDOMHTMLElement*)nsframe, window);
350 IHTMLWindow2_Release(HTMLWINDOW2(window));
353 nsIDOMDocument_Release(nsdoc);
354 return nsres;
357 /* Calls undocumented 69 cmd of CGID_Explorer */
358 static void call_explorer_69(HTMLDocumentObj *doc)
360 IOleCommandTarget *olecmd;
361 VARIANT var;
362 HRESULT hres;
364 if(!doc->client)
365 return;
367 hres = IOleClientSite_QueryInterface(doc->client, &IID_IOleCommandTarget, (void**)&olecmd);
368 if(FAILED(hres))
369 return;
371 VariantInit(&var);
372 hres = IOleCommandTarget_Exec(olecmd, &CGID_Explorer, 69, 0, NULL, &var);
373 IOleCommandTarget_Release(olecmd);
374 if(SUCCEEDED(hres) && V_VT(&var) != VT_NULL)
375 FIXME("handle result\n");
378 static void parse_complete_proc(task_t *task)
380 HTMLDocumentObj *doc = ((docobj_task_t*)task)->doc;
382 TRACE("(%p)\n", doc);
384 if(doc->usermode == EDITMODE)
385 init_editor(&doc->basedoc);
387 call_explorer_69(doc);
388 call_property_onchanged(&doc->basedoc.cp_propnotif, 1005);
389 call_explorer_69(doc);
391 /* FIXME: IE7 calls EnableModelless(TRUE), EnableModelless(FALSE) and sets interactive state here */
393 set_ready_state(doc->basedoc.window, READYSTATE_INTERACTIVE);
396 static void handle_end_load(HTMLDocumentNode *This)
398 docobj_task_t *task;
400 TRACE("\n");
402 if(This != This->basedoc.doc_obj->basedoc.doc_node) {
403 set_ready_state(This->basedoc.window, READYSTATE_INTERACTIVE);
404 return;
407 task = heap_alloc(sizeof(docobj_task_t));
408 if(!task)
409 return;
411 task->doc = This->basedoc.doc_obj;
414 * This should be done in the worker thread that parses HTML,
415 * but we don't have such thread (Gecko parses HTML for us).
417 push_task(&task->header, &parse_complete_proc, This->basedoc.doc_obj->basedoc.task_magic);
420 static nsresult NSAPI nsRunnable_Run(nsIRunnable *iface)
422 HTMLDocumentNode *This = NSRUNNABLE_THIS(iface);
423 nsresult nsres;
425 TRACE("(%p)\n", This);
427 while(This->mutation_queue) {
428 switch(This->mutation_queue->type) {
429 case MUTATION_COMMENT: {
430 nsIDOMComment *nscomment;
431 nsAString comment_str;
432 BOOL remove_comment = FALSE;
434 nsres = nsISupports_QueryInterface(This->mutation_queue->nsiface, &IID_nsIDOMComment, (void**)&nscomment);
435 if(NS_FAILED(nsres)) {
436 ERR("Could not get nsIDOMComment iface:%08x\n", nsres);
437 return NS_OK;
440 nsAString_Init(&comment_str, NULL);
441 nsres = nsIDOMComment_GetData(nscomment, &comment_str);
442 if(NS_SUCCEEDED(nsres)) {
443 const PRUnichar *comment;
445 nsAString_GetData(&comment_str, &comment);
446 remove_comment = handle_insert_comment(This, comment);
449 nsAString_Finish(&comment_str);
451 if(remove_comment) {
452 nsIDOMNode *nsparent, *tmp;
453 nsAString magic_str;
455 static const PRUnichar remove_comment_magicW[] =
456 {'#','!','w','i','n','e', 'r','e','m','o','v','e','!','#',0};
458 nsAString_Init(&magic_str, remove_comment_magicW);
459 nsres = nsIDOMComment_SetData(nscomment, &magic_str);
460 nsAString_Finish(&magic_str);
461 if(NS_FAILED(nsres))
462 ERR("SetData failed: %08x\n", nsres);
464 nsIDOMComment_GetParentNode(nscomment, &nsparent);
465 if(nsparent) {
466 nsIDOMNode_RemoveChild(nsparent, (nsIDOMNode*)nscomment, &tmp);
467 nsIDOMNode_Release(nsparent);
468 nsIDOMNode_Release(tmp);
472 nsIDOMComment_Release(nscomment);
473 break;
476 case MUTATION_ENDLOAD:
477 handle_end_load(This);
478 break;
480 case MUTATION_FRAME:
481 init_frame_window(This, This->mutation_queue->nsiface);
482 break;
484 case MUTATION_IFRAME:
485 init_iframe_window(This, This->mutation_queue->nsiface);
486 break;
488 case MUTATION_SCRIPT: {
489 nsIDOMHTMLScriptElement *nsscript;
491 nsres = nsISupports_QueryInterface(This->mutation_queue->nsiface, &IID_nsIDOMHTMLScriptElement,
492 (void**)&nsscript);
493 if(NS_FAILED(nsres)) {
494 ERR("Could not get nsIDOMHTMLScriptElement: %08x\n", nsres);
495 break;
498 doc_insert_script(This->basedoc.window, nsscript);
499 nsIDOMHTMLScriptElement_Release(nsscript);
500 break;
503 default:
504 ERR("invalid type %d\n", This->mutation_queue->type);
507 pop_mutation_queue(This);
510 return S_OK;
513 #undef NSRUNNABLE_THIS
515 static const nsIRunnableVtbl nsRunnableVtbl = {
516 nsRunnable_QueryInterface,
517 nsRunnable_AddRef,
518 nsRunnable_Release,
519 nsRunnable_Run
522 #define NSDOCOBS_THIS(iface) DEFINE_THIS(HTMLDocumentNode, IDocumentObserver, iface)
524 static nsresult NSAPI nsDocumentObserver_QueryInterface(nsIDocumentObserver *iface,
525 nsIIDRef riid, nsQIResult result)
527 HTMLDocumentNode *This = NSDOCOBS_THIS(iface);
529 if(IsEqualGUID(&IID_nsISupports, riid)) {
530 TRACE("(%p)->(IID_nsISupports, %p)\n", This, result);
531 *result = NSDOCOBS(This);
532 }else if(IsEqualGUID(&IID_nsIMutationObserver, riid)) {
533 TRACE("(%p)->(IID_nsIMutationObserver %p)\n", This, result);
534 *result = NSDOCOBS(This);
535 }else if(IsEqualGUID(&IID_nsIDocumentObserver, riid)) {
536 TRACE("(%p)->(IID_nsIDocumentObserver %p)\n", This, result);
537 *result = NSDOCOBS(This);
538 }else {
539 *result = NULL;
540 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), result);
541 return NS_NOINTERFACE;
544 htmldoc_addref(&This->basedoc);
545 return NS_OK;
548 static nsrefcnt NSAPI nsDocumentObserver_AddRef(nsIDocumentObserver *iface)
550 HTMLDocumentNode *This = NSDOCOBS_THIS(iface);
551 return htmldoc_addref(&This->basedoc);
554 static nsrefcnt NSAPI nsDocumentObserver_Release(nsIDocumentObserver *iface)
556 HTMLDocumentNode *This = NSDOCOBS_THIS(iface);
557 return htmldoc_release(&This->basedoc);
560 static void NSAPI nsDocumentObserver_CharacterDataWillChange(nsIDocumentObserver *iface,
561 nsIDocument *aDocument, nsIContent *aContent, void /*CharacterDataChangeInfo*/ *aInfo)
565 static void NSAPI nsDocumentObserver_CharacterDataChanged(nsIDocumentObserver *iface,
566 nsIDocument *aDocument, nsIContent *aContent, void /*CharacterDataChangeInfo*/ *aInfo)
570 static void NSAPI nsDocumentObserver_AttributeWillChange(nsIDocumentObserver *iface, nsIDocument *aDocument,
571 nsIContent *aContent, PRInt32 aNameSpaceID, nsIAtom *aAttribute, PRInt32 aModType)
575 static void NSAPI nsDocumentObserver_AttributeChanged(nsIDocumentObserver *iface, nsIDocument *aDocument,
576 nsIContent *aContent, PRInt32 aNameSpaceID, nsIAtom *aAttribute, PRInt32 aModType, PRUint32 aStateMask)
580 static void NSAPI nsDocumentObserver_ContentAppended(nsIDocumentObserver *iface, nsIDocument *aDocument,
581 nsIContent *aContainer, PRInt32 aNewIndexInContainer)
585 static void NSAPI nsDocumentObserver_ContentInserted(nsIDocumentObserver *iface, nsIDocument *aDocument,
586 nsIContent *aContainer, nsIContent *aChild, PRInt32 aIndexInContainer)
590 static void NSAPI nsDocumentObserver_ContentRemoved(nsIDocumentObserver *iface, nsIDocument *aDocument,
591 nsIContent *aContainer, nsIContent *aChild, PRInt32 aIndexInContainer)
595 static void NSAPI nsDocumentObserver_NodeWillBeDestroyed(nsIDocumentObserver *iface, const nsINode *aNode)
599 static void NSAPI nsDocumentObserver_ParentChainChanged(nsIDocumentObserver *iface, nsIContent *aContent)
603 static void NSAPI nsDocumentObserver_BeginUpdate(nsIDocumentObserver *iface, nsIDocument *aDocument,
604 nsUpdateType aUpdateType)
608 static void NSAPI nsDocumentObserver_EndUpdate(nsIDocumentObserver *iface, nsIDocument *aDocument,
609 nsUpdateType aUpdateType)
613 static void NSAPI nsDocumentObserver_BeginLoad(nsIDocumentObserver *iface, nsIDocument *aDocument)
617 static void NSAPI nsDocumentObserver_EndLoad(nsIDocumentObserver *iface, nsIDocument *aDocument)
619 HTMLDocumentNode *This = NSDOCOBS_THIS(iface);
621 TRACE("\n");
623 This->content_ready = TRUE;
624 push_mutation_queue(This, MUTATION_ENDLOAD, NULL);
627 static void NSAPI nsDocumentObserver_ContentStatesChanged(nsIDocumentObserver *iface, nsIDocument *aDocument,
628 nsIContent *aContent1, nsIContent *aContent2, PRInt32 aStateMask)
632 static void NSAPI nsDocumentObserver_StyleSheetAdded(nsIDocumentObserver *iface, nsIDocument *aDocument,
633 nsIStyleSheet *aStyleSheet, PRBool aDocumentSheet)
637 static void NSAPI nsDocumentObserver_StyleSheetRemoved(nsIDocumentObserver *iface, nsIDocument *aDocument,
638 nsIStyleSheet *aStyleSheet, PRBool aDocumentSheet)
642 static void NSAPI nsDocumentObserver_StyleSheetApplicableStateChanged(nsIDocumentObserver *iface,
643 nsIDocument *aDocument, nsIStyleSheet *aStyleSheet, PRBool aApplicable)
647 static void NSAPI nsDocumentObserver_StyleRuleChanged(nsIDocumentObserver *iface, nsIDocument *aDocument,
648 nsIStyleSheet *aStyleSheet, nsIStyleRule *aOldStyleRule, nsIStyleSheet *aNewStyleRule)
652 static void NSAPI nsDocumentObserver_StyleRuleAdded(nsIDocumentObserver *iface, nsIDocument *aDocument,
653 nsIStyleSheet *aStyleSheet, nsIStyleRule *aStyleRule)
657 static void NSAPI nsDocumentObserver_StyleRuleRemoved(nsIDocumentObserver *iface, nsIDocument *aDocument,
658 nsIStyleSheet *aStyleSheet, nsIStyleRule *aStyleRule)
662 static void NSAPI nsDocumentObserver_BindToDocument(nsIDocumentObserver *iface, nsIDocument *aDocument,
663 nsIContent *aContent)
665 HTMLDocumentNode *This = NSDOCOBS_THIS(iface);
666 nsIDOMHTMLIFrameElement *nsiframe;
667 nsIDOMHTMLFrameElement *nsframe;
668 nsIDOMComment *nscomment;
669 nsIDOMElement *nselem;
670 nsresult nsres;
672 TRACE("(%p)\n", This);
674 nsres = nsISupports_QueryInterface(aContent, &IID_nsIDOMElement, (void**)&nselem);
675 if(NS_SUCCEEDED(nsres)) {
676 check_event_attr(This, nselem);
677 nsIDOMElement_Release(nselem);
680 nsres = nsISupports_QueryInterface(aContent, &IID_nsIDOMComment, (void**)&nscomment);
681 if(NS_SUCCEEDED(nsres)) {
682 TRACE("comment node\n");
684 push_mutation_queue(This, MUTATION_COMMENT, (nsISupports*)nscomment);
685 nsIDOMComment_Release(nscomment);
688 nsres = nsISupports_QueryInterface(aContent, &IID_nsIDOMHTMLIFrameElement, (void**)&nsiframe);
689 if(NS_SUCCEEDED(nsres)) {
690 TRACE("iframe node\n");
692 push_mutation_queue(This, MUTATION_IFRAME, (nsISupports*)nsiframe);
693 nsIDOMHTMLIFrameElement_Release(nsiframe);
696 nsres = nsISupports_QueryInterface(aContent, &IID_nsIDOMHTMLFrameElement, (void**)&nsframe);
697 if(NS_SUCCEEDED(nsres)) {
698 TRACE("frame node\n");
700 push_mutation_queue(This, MUTATION_FRAME, (nsISupports*)nsframe);
701 nsIDOMHTMLFrameElement_Release(nsframe);
705 static void NSAPI nsDocumentObserver_DoneAddingChildren(nsIDocumentObserver *iface, nsIContent *aContent,
706 PRBool aHaveNotified)
708 HTMLDocumentNode *This = NSDOCOBS_THIS(iface);
709 nsIDOMHTMLScriptElement *nsscript;
710 nsresult nsres;
712 TRACE("(%p)->(%p %x)\n", This, aContent, aHaveNotified);
714 nsres = nsISupports_QueryInterface(aContent, &IID_nsIDOMHTMLScriptElement, (void**)&nsscript);
715 if(NS_SUCCEEDED(nsres)) {
716 TRACE("script node\n");
718 push_mutation_queue(This, MUTATION_SCRIPT, (nsISupports*)nsscript);
719 nsIDOMHTMLScriptElement_Release(nsscript);
723 #undef NSMUTATIONOBS_THIS
725 static const nsIDocumentObserverVtbl nsDocumentObserverVtbl = {
726 nsDocumentObserver_QueryInterface,
727 nsDocumentObserver_AddRef,
728 nsDocumentObserver_Release,
729 nsDocumentObserver_CharacterDataWillChange,
730 nsDocumentObserver_CharacterDataChanged,
731 nsDocumentObserver_AttributeWillChange,
732 nsDocumentObserver_AttributeChanged,
733 nsDocumentObserver_ContentAppended,
734 nsDocumentObserver_ContentInserted,
735 nsDocumentObserver_ContentRemoved,
736 nsDocumentObserver_NodeWillBeDestroyed,
737 nsDocumentObserver_ParentChainChanged,
738 nsDocumentObserver_BeginUpdate,
739 nsDocumentObserver_EndUpdate,
740 nsDocumentObserver_BeginLoad,
741 nsDocumentObserver_EndLoad,
742 nsDocumentObserver_ContentStatesChanged,
743 nsDocumentObserver_StyleSheetAdded,
744 nsDocumentObserver_StyleSheetRemoved,
745 nsDocumentObserver_StyleSheetApplicableStateChanged,
746 nsDocumentObserver_StyleRuleChanged,
747 nsDocumentObserver_StyleRuleAdded,
748 nsDocumentObserver_StyleRuleRemoved,
749 nsDocumentObserver_BindToDocument,
750 nsDocumentObserver_DoneAddingChildren
753 void init_mutation(HTMLDocumentNode *doc)
755 nsIDOMNSDocument *nsdoc;
756 nsresult nsres;
758 doc->lpIDocumentObserverVtbl = &nsDocumentObserverVtbl;
759 doc->lpIRunnableVtbl = &nsRunnableVtbl;
761 nsres = nsIDOMHTMLDocument_QueryInterface(doc->nsdoc, &IID_nsIDOMNSDocument, (void**)&nsdoc);
762 if(NS_FAILED(nsres)) {
763 ERR("Could not get nsIDOMNSDocument: %08x\n", nsres);
764 return;
767 nsIDOMNSDocument_WineAddObserver(nsdoc, NSDOCOBS(doc));
768 nsIDOMNSDocument_Release(nsdoc);
771 void release_mutation(HTMLDocumentNode *doc)
773 nsIDOMNSDocument *nsdoc;
774 nsresult nsres;
776 nsres = nsIDOMHTMLDocument_QueryInterface(doc->nsdoc, &IID_nsIDOMNSDocument, (void**)&nsdoc);
777 if(NS_FAILED(nsres)) {
778 ERR("Could not get nsIDOMNSDocument: %08x\n", nsres);
779 return;
782 nsIDOMNSDocument_WineRemoveObserver(nsdoc, NSDOCOBS(doc));
783 nsIDOMNSDocument_Release(nsdoc);