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
33 #include "mshtml_private.h"
34 #include "htmlscript.h"
35 #include "htmlevent.h"
38 #include "wine/debug.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(mshtml
);
42 const compat_mode_info_t compat_mode_info
[] = {
43 { 5, 7 }, /* DOCMODE_QUIRKS */
44 { 5, 5 }, /* DOCMODE_IE5 */
45 { 7, 7 }, /* DOCMODE_IE7 */
46 { 8, 8 }, /* DOCMODE_IE8 */
47 { 9, 9 }, /* DOCMODE_IE8 */
48 { 10, 10 }, /* DOCMODE_IE10 */
49 { 11, 11 } /* DOCMODE_IE11 */
52 static const IID NS_ICONTENTUTILS_CID
=
53 {0x762C4AE7,0xB923,0x422F,{0xB9,0x7E,0xB9,0xBF,0xC1,0xEF,0x7B,0xF0}};
55 static nsIContentUtils
*content_utils
;
57 static PRUnichar
*handle_insert_comment(HTMLDocumentNode
*doc
, const PRUnichar
*comment
)
59 unsigned majorv
= 0, minorv
= 0, compat_version
;
60 const PRUnichar
*ptr
, *end
;
72 static const PRUnichar endifW
[] = {'<','!','[','e','n','d','i','f',']'};
74 if(comment
[0] != '[' || comment
[1] != 'i' || comment
[2] != 'f')
81 if(ptr
[0] == 'l' && ptr
[1] == 't') {
89 }else if(ptr
[0] == 'g' && ptr
[1] == 't') {
101 while(isspaceW(*ptr
))
104 if(ptr
[0] != 'I' || ptr
[1] != 'E')
108 if(!isspaceW(*ptr
++))
110 while(isspaceW(*ptr
))
115 while(isdigitW(*ptr
))
116 majorv
= majorv
*10 + (*ptr
++ - '0');
122 while(isdigitW(*ptr
))
123 minorv
= minorv
*10 + (*ptr
++ - '0');
126 while(isspaceW(*ptr
))
128 if(ptr
[0] != ']' || ptr
[1] != '>')
133 if(len
< sizeof(endifW
)/sizeof(WCHAR
))
136 end
= ptr
+ len
-sizeof(endifW
)/sizeof(WCHAR
);
137 if(memcmp(end
, endifW
, sizeof(endifW
)))
140 compat_version
= compat_mode_info
[doc
->document_mode
].ie_version
;
141 if(compat_version
> 8) {
143 * Ideally we should handle higher versions, but right now it would cause more problems than it's worth.
144 * We should revisit that once more IE9 features are implemented, most notably new events APIs.
146 WARN("Using compat version 8\n");
152 if(compat_version
== majorv
&& !minorv
)
156 if(compat_version
< majorv
|| (compat_version
== majorv
&& minorv
))
160 if(compat_version
<= majorv
)
164 if(compat_version
> majorv
)
168 if(compat_version
>= majorv
|| (compat_version
== majorv
&& !minorv
))
173 buf
= heap_alloc((end
-ptr
+1)*sizeof(WCHAR
));
177 memcpy(buf
, ptr
, (end
-ptr
)*sizeof(WCHAR
));
183 static nsresult
run_insert_comment(HTMLDocumentNode
*doc
, nsISupports
*comment_iface
, nsISupports
*arg2
)
185 const PRUnichar
*comment
;
186 nsIDOMComment
*nscomment
;
187 PRUnichar
*replace_html
;
188 nsAString comment_str
;
191 nsres
= nsISupports_QueryInterface(comment_iface
, &IID_nsIDOMComment
, (void**)&nscomment
);
192 if(NS_FAILED(nsres
)) {
193 ERR("Could not get nsIDOMComment iface:%08x\n", nsres
);
197 nsAString_Init(&comment_str
, NULL
);
198 nsres
= nsIDOMComment_GetData(nscomment
, &comment_str
);
202 nsAString_GetData(&comment_str
, &comment
);
203 replace_html
= handle_insert_comment(doc
, comment
);
204 nsAString_Finish(&comment_str
);
209 hres
= replace_node_by_html(doc
->nsdoc
, (nsIDOMNode
*)nscomment
, replace_html
);
210 heap_free(replace_html
);
212 nsres
= NS_ERROR_FAILURE
;
216 nsIDOMComment_Release(nscomment
);
220 static nsresult
run_bind_to_tree(HTMLDocumentNode
*doc
, nsISupports
*nsiface
, nsISupports
*arg2
)
227 TRACE("(%p)->(%p)\n", doc
, nsiface
);
229 nsres
= nsISupports_QueryInterface(nsiface
, &IID_nsIDOMNode
, (void**)&nsnode
);
233 hres
= get_node(doc
, nsnode
, TRUE
, &node
);
234 nsIDOMNode_Release(nsnode
);
236 ERR("Could not get node\n");
240 if(node
->vtbl
->bind_to_tree
)
241 node
->vtbl
->bind_to_tree(node
);
247 /* Calls undocumented 69 cmd of CGID_Explorer */
248 static void call_explorer_69(HTMLDocumentObj
*doc
)
250 IOleCommandTarget
*olecmd
;
257 hres
= IOleClientSite_QueryInterface(doc
->client
, &IID_IOleCommandTarget
, (void**)&olecmd
);
262 hres
= IOleCommandTarget_Exec(olecmd
, &CGID_Explorer
, 69, 0, NULL
, &var
);
263 IOleCommandTarget_Release(olecmd
);
264 if(SUCCEEDED(hres
) && V_VT(&var
) != VT_NULL
)
265 FIXME("handle result\n");
268 static void parse_complete(HTMLDocumentObj
*doc
)
270 TRACE("(%p)\n", doc
);
272 if(doc
->usermode
== EDITMODE
)
273 init_editor(&doc
->basedoc
);
275 call_explorer_69(doc
);
277 IAdviseSink_OnViewChange(doc
->view_sink
, DVASPECT_CONTENT
, -1);
278 call_property_onchanged(&doc
->basedoc
.cp_container
, 1005);
279 call_explorer_69(doc
);
281 if(doc
->webbrowser
&& doc
->usermode
!= EDITMODE
&& !(doc
->basedoc
.window
->load_flags
& BINDING_REFRESH
))
282 IDocObjectService_FireNavigateComplete2(doc
->doc_object_service
, &doc
->basedoc
.window
->base
.IHTMLWindow2_iface
, 0);
284 /* FIXME: IE7 calls EnableModelless(TRUE), EnableModelless(FALSE) and sets interactive state here */
287 static nsresult
run_end_load(HTMLDocumentNode
*This
, nsISupports
*arg1
, nsISupports
*arg2
)
289 TRACE("(%p)\n", This
);
291 if(!This
->basedoc
.doc_obj
)
294 if(This
== This
->basedoc
.doc_obj
->basedoc
.doc_node
) {
296 * This should be done in the worker thread that parses HTML,
297 * but we don't have such thread (Gecko parses HTML for us).
299 parse_complete(This
->basedoc
.doc_obj
);
302 bind_event_scripts(This
);
303 set_ready_state(This
->basedoc
.window
, READYSTATE_INTERACTIVE
);
307 static nsresult
run_insert_script(HTMLDocumentNode
*doc
, nsISupports
*script_iface
, nsISupports
*parser_iface
)
309 nsIDOMHTMLScriptElement
*nsscript
;
310 HTMLScriptElement
*script_elem
;
311 nsIParser
*nsparser
= NULL
;
312 script_queue_entry_t
*iter
;
313 HTMLInnerWindow
*window
;
317 TRACE("(%p)->(%p)\n", doc
, script_iface
);
319 window
= doc
->window
;
323 nsres
= nsISupports_QueryInterface(script_iface
, &IID_nsIDOMHTMLScriptElement
, (void**)&nsscript
);
324 if(NS_FAILED(nsres
)) {
325 ERR("Could not get nsIDOMHTMLScriptElement: %08x\n", nsres
);
330 nsres
= nsISupports_QueryInterface(parser_iface
, &IID_nsIParser
, (void**)&nsparser
);
331 if(NS_FAILED(nsres
)) {
332 ERR("Could not get nsIParser iface: %08x\n", nsres
);
337 hres
= script_elem_from_nsscript(doc
, nsscript
, &script_elem
);
338 nsIDOMHTMLScriptElement_Release(nsscript
);
340 return NS_ERROR_FAILURE
;
343 nsIParser_BeginEvaluatingParserInsertedScript(nsparser
);
344 window
->parser_callback_cnt
++;
347 IHTMLWindow2_AddRef(&window
->base
.IHTMLWindow2_iface
);
349 doc_insert_script(window
, script_elem
, TRUE
);
351 while(!list_empty(&window
->script_queue
)) {
352 iter
= LIST_ENTRY(list_head(&window
->script_queue
), script_queue_entry_t
, entry
);
353 list_remove(&iter
->entry
);
354 if(!iter
->script
->parsed
)
355 doc_insert_script(window
, iter
->script
, TRUE
);
356 IHTMLScriptElement_Release(&iter
->script
->IHTMLScriptElement_iface
);
360 IHTMLWindow2_Release(&window
->base
.IHTMLWindow2_iface
);
363 window
->parser_callback_cnt
--;
364 nsIParser_EndEvaluatingParserInsertedScript(nsparser
);
365 nsIParser_Release(nsparser
);
368 IHTMLScriptElement_Release(&script_elem
->IHTMLScriptElement_iface
);
373 static void set_document_mode(HTMLDocumentNode
*doc
, compat_mode_t document_mode
, BOOL lock
)
375 if(doc
->document_mode_locked
) {
376 WARN("attempting to set document mode %d on locked document %p\n", document_mode
, doc
);
380 TRACE("%p: %d\n", doc
, document_mode
);
383 doc
->document_mode_locked
= TRUE
;
384 doc
->document_mode
= document_mode
;
387 static BOOL
parse_ua_compatible(const WCHAR
*p
, compat_mode_t
*r
)
391 static const WCHAR edgeW
[] = {'e','d','g','e',0};
393 if(p
[0] != 'I' || p
[1] != 'E' || p
[2] != '=')
397 if(!strcmpiW(p
, edgeW
)) {
398 *r
= COMPAT_MODE_IE11
;
402 while('0' <= *p
&& *p
<= '9')
403 v
= v
*10 + *(p
++)-'0';
410 *r
= COMPAT_MODE_IE5
;
413 *r
= COMPAT_MODE_IE7
;
416 *r
= COMPAT_MODE_IE8
;
419 *r
= COMPAT_MODE_IE9
;
422 *r
= COMPAT_MODE_IE10
;
425 *r
= v
< 5 ? COMPAT_MODE_QUIRKS
: COMPAT_MODE_IE11
;
431 static void process_meta_element(HTMLDocumentNode
*doc
, nsIDOMHTMLMetaElement
*meta_element
)
433 nsAString http_equiv_str
, content_str
;
436 static const WCHAR x_ua_compatibleW
[] = {'x','-','u','a','-','c','o','m','p','a','t','i','b','l','e',0};
438 nsAString_Init(&http_equiv_str
, NULL
);
439 nsAString_Init(&content_str
, NULL
);
440 nsres
= nsIDOMHTMLMetaElement_GetHttpEquiv(meta_element
, &http_equiv_str
);
441 if(NS_SUCCEEDED(nsres
))
442 nsres
= nsIDOMHTMLMetaElement_GetContent(meta_element
, &content_str
);
444 if(NS_SUCCEEDED(nsres
)) {
445 const PRUnichar
*http_equiv
, *content
;
447 nsAString_GetData(&http_equiv_str
, &http_equiv
);
448 nsAString_GetData(&content_str
, &content
);
450 TRACE("%s: %s\n", debugstr_w(http_equiv
), debugstr_w(content
));
452 if(!strcmpiW(http_equiv
, x_ua_compatibleW
)) {
453 compat_mode_t document_mode
;
454 if(parse_ua_compatible(content
, &document_mode
))
455 set_document_mode(doc
, document_mode
, TRUE
);
457 FIXME("Unsupported document mode %s\n", debugstr_w(content
));
461 nsAString_Finish(&http_equiv_str
);
462 nsAString_Finish(&content_str
);
465 typedef struct nsRunnable nsRunnable
;
467 typedef nsresult (*runnable_proc_t
)(HTMLDocumentNode
*,nsISupports
*,nsISupports
*);
470 nsIRunnable nsIRunnable_iface
;
474 runnable_proc_t proc
;
476 HTMLDocumentNode
*doc
;
481 static inline nsRunnable
*impl_from_nsIRunnable(nsIRunnable
*iface
)
483 return CONTAINING_RECORD(iface
, nsRunnable
, nsIRunnable_iface
);
486 static nsresult NSAPI
nsRunnable_QueryInterface(nsIRunnable
*iface
,
487 nsIIDRef riid
, void **result
)
489 nsRunnable
*This
= impl_from_nsIRunnable(iface
);
491 if(IsEqualGUID(riid
, &IID_nsISupports
)) {
492 TRACE("(%p)->(IID_nsISupports %p)\n", This
, result
);
493 *result
= &This
->nsIRunnable_iface
;
494 }else if(IsEqualGUID(riid
, &IID_nsIRunnable
)) {
495 TRACE("(%p)->(IID_nsIRunnable %p)\n", This
, result
);
496 *result
= &This
->nsIRunnable_iface
;
499 WARN("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), result
);
500 return NS_NOINTERFACE
;
503 nsISupports_AddRef((nsISupports
*)*result
);
507 static nsrefcnt NSAPI
nsRunnable_AddRef(nsIRunnable
*iface
)
509 nsRunnable
*This
= impl_from_nsIRunnable(iface
);
510 LONG ref
= InterlockedIncrement(&This
->ref
);
512 TRACE("(%p) ref=%d\n", This
, ref
);
517 static nsrefcnt NSAPI
nsRunnable_Release(nsIRunnable
*iface
)
519 nsRunnable
*This
= impl_from_nsIRunnable(iface
);
520 LONG ref
= InterlockedDecrement(&This
->ref
);
522 TRACE("(%p) ref=%d\n", This
, ref
);
525 htmldoc_release(&This
->doc
->basedoc
);
527 nsISupports_Release(This
->arg1
);
529 nsISupports_Release(This
->arg2
);
536 static nsresult NSAPI
nsRunnable_Run(nsIRunnable
*iface
)
538 nsRunnable
*This
= impl_from_nsIRunnable(iface
);
540 return This
->proc(This
->doc
, This
->arg1
, This
->arg2
);
543 static const nsIRunnableVtbl nsRunnableVtbl
= {
544 nsRunnable_QueryInterface
,
550 static void add_script_runner(HTMLDocumentNode
*This
, runnable_proc_t proc
, nsISupports
*arg1
, nsISupports
*arg2
)
552 nsRunnable
*runnable
;
554 runnable
= heap_alloc_zero(sizeof(*runnable
));
558 runnable
->nsIRunnable_iface
.lpVtbl
= &nsRunnableVtbl
;
561 htmldoc_addref(&This
->basedoc
);
562 runnable
->doc
= This
;
563 runnable
->proc
= proc
;
566 nsISupports_AddRef(arg1
);
567 runnable
->arg1
= arg1
;
570 nsISupports_AddRef(arg2
);
571 runnable
->arg2
= arg2
;
573 nsIContentUtils_AddScriptRunner(content_utils
, &runnable
->nsIRunnable_iface
);
575 nsIRunnable_Release(&runnable
->nsIRunnable_iface
);
578 static inline HTMLDocumentNode
*impl_from_nsIDocumentObserver(nsIDocumentObserver
*iface
)
580 return CONTAINING_RECORD(iface
, HTMLDocumentNode
, nsIDocumentObserver_iface
);
583 static nsresult NSAPI
nsDocumentObserver_QueryInterface(nsIDocumentObserver
*iface
,
584 nsIIDRef riid
, void **result
)
586 HTMLDocumentNode
*This
= impl_from_nsIDocumentObserver(iface
);
588 if(IsEqualGUID(&IID_nsISupports
, riid
)) {
589 TRACE("(%p)->(IID_nsISupports, %p)\n", This
, result
);
590 *result
= &This
->nsIDocumentObserver_iface
;
591 }else if(IsEqualGUID(&IID_nsIMutationObserver
, riid
)) {
592 TRACE("(%p)->(IID_nsIMutationObserver %p)\n", This
, result
);
593 *result
= &This
->nsIDocumentObserver_iface
;
594 }else if(IsEqualGUID(&IID_nsIDocumentObserver
, riid
)) {
595 TRACE("(%p)->(IID_nsIDocumentObserver %p)\n", This
, result
);
596 *result
= &This
->nsIDocumentObserver_iface
;
599 TRACE("(%p)->(%s %p)\n", This
, debugstr_guid(riid
), result
);
600 return NS_NOINTERFACE
;
603 htmldoc_addref(&This
->basedoc
);
607 static nsrefcnt NSAPI
nsDocumentObserver_AddRef(nsIDocumentObserver
*iface
)
609 HTMLDocumentNode
*This
= impl_from_nsIDocumentObserver(iface
);
610 return htmldoc_addref(&This
->basedoc
);
613 static nsrefcnt NSAPI
nsDocumentObserver_Release(nsIDocumentObserver
*iface
)
615 HTMLDocumentNode
*This
= impl_from_nsIDocumentObserver(iface
);
616 return htmldoc_release(&This
->basedoc
);
619 static void NSAPI
nsDocumentObserver_CharacterDataWillChange(nsIDocumentObserver
*iface
,
620 nsIDocument
*aDocument
, nsIContent
*aContent
, void /*CharacterDataChangeInfo*/ *aInfo
)
624 static void NSAPI
nsDocumentObserver_CharacterDataChanged(nsIDocumentObserver
*iface
,
625 nsIDocument
*aDocument
, nsIContent
*aContent
, void /*CharacterDataChangeInfo*/ *aInfo
)
629 static void NSAPI
nsDocumentObserver_AttributeWillChange(nsIDocumentObserver
*iface
, nsIDocument
*aDocument
,
630 void *aElement
, LONG aNameSpaceID
, nsIAtom
*aAttribute
, LONG aModType
, const nsAttrValue
*aNewValue
)
634 static void NSAPI
nsDocumentObserver_AttributeChanged(nsIDocumentObserver
*iface
, nsIDocument
*aDocument
,
635 void *aElement
, LONG aNameSpaceID
, nsIAtom
*aAttribute
, LONG aModType
, const nsAttrValue
*aOldValue
)
639 static void NSAPI
nsDocumentObserver_NativeAnonymousChildListChange(nsIDocumentObserver
*iface
, nsIDocument
*aDocument
,
640 nsIContent
*aContent
, cpp_bool aIsRemove
)
644 static void NSAPI
nsDocumentObserver_AttributeSetToCurrentValue(nsIDocumentObserver
*iface
, nsIDocument
*aDocument
,
645 void *aElement
, LONG aNameSpaceID
, nsIAtom
*aAttribute
)
649 static void NSAPI
nsDocumentObserver_ContentAppended(nsIDocumentObserver
*iface
, nsIDocument
*aDocument
,
650 nsIContent
*aContainer
, nsIContent
*aFirstNewContent
, LONG aNewIndexInContainer
)
654 static void NSAPI
nsDocumentObserver_ContentInserted(nsIDocumentObserver
*iface
, nsIDocument
*aDocument
,
655 nsIContent
*aContainer
, nsIContent
*aChild
, LONG aIndexInContainer
)
659 static void NSAPI
nsDocumentObserver_ContentRemoved(nsIDocumentObserver
*iface
, nsIDocument
*aDocument
,
660 nsIContent
*aContainer
, nsIContent
*aChild
, LONG aIndexInContainer
,
661 nsIContent
*aProviousSibling
)
665 static void NSAPI
nsDocumentObserver_NodeWillBeDestroyed(nsIDocumentObserver
*iface
, const nsINode
*aNode
)
669 static void NSAPI
nsDocumentObserver_ParentChainChanged(nsIDocumentObserver
*iface
, nsIContent
*aContent
)
673 static void NSAPI
nsDocumentObserver_BeginUpdate(nsIDocumentObserver
*iface
, nsIDocument
*aDocument
,
674 nsUpdateType aUpdateType
)
678 static void NSAPI
nsDocumentObserver_EndUpdate(nsIDocumentObserver
*iface
, nsIDocument
*aDocument
,
679 nsUpdateType aUpdateType
)
683 static void NSAPI
nsDocumentObserver_BeginLoad(nsIDocumentObserver
*iface
, nsIDocument
*aDocument
)
687 static void NSAPI
nsDocumentObserver_EndLoad(nsIDocumentObserver
*iface
, nsIDocument
*aDocument
)
689 HTMLDocumentNode
*This
= impl_from_nsIDocumentObserver(iface
);
691 TRACE("(%p)\n", This
);
693 if(This
->skip_mutation_notif
)
696 This
->content_ready
= TRUE
;
697 add_script_runner(This
, run_end_load
, NULL
, NULL
);
700 static void NSAPI
nsDocumentObserver_ContentStatesChanged(nsIDocumentObserver
*iface
, nsIDocument
*aDocument
,
701 nsIContent
*aContent
, EventStates aStateMask
)
705 static void NSAPI
nsDocumentObserver_DocumentStatesChanged(nsIDocumentObserver
*iface
, nsIDocument
*aDocument
,
706 EventStates aStateMask
)
710 static void NSAPI
nsDocumentObserver_StyleSheetAdded(nsIDocumentObserver
*iface
, mozilla_StyleSheetHandle aStyleSheet
,
711 cpp_bool aDocumentSheet
)
715 static void NSAPI
nsDocumentObserver_StyleSheetRemoved(nsIDocumentObserver
*iface
, mozilla_StyleSheetHandle aStyleSheet
,
716 cpp_bool aDocumentSheet
)
720 static void NSAPI
nsDocumentObserver_StyleSheetApplicableStateChanged(nsIDocumentObserver
*iface
,
721 mozilla_StyleSheetHandle aStyleSheet
)
725 static void NSAPI
nsDocumentObserver_StyleRuleChanged(nsIDocumentObserver
*iface
, mozilla_StyleSheetHandle aStyleSheet
)
729 static void NSAPI
nsDocumentObserver_StyleRuleAdded(nsIDocumentObserver
*iface
, mozilla_StyleSheetHandle aStyleSheet
)
733 static void NSAPI
nsDocumentObserver_StyleRuleRemoved(nsIDocumentObserver
*iface
, mozilla_StyleSheetHandle aStyleSheet
)
737 static void NSAPI
nsDocumentObserver_BindToDocument(nsIDocumentObserver
*iface
, nsIDocument
*aDocument
,
738 nsIContent
*aContent
)
740 HTMLDocumentNode
*This
= impl_from_nsIDocumentObserver(iface
);
741 nsIDOMHTMLIFrameElement
*nsiframe
;
742 nsIDOMHTMLFrameElement
*nsframe
;
743 nsIDOMHTMLScriptElement
*nsscript
;
744 nsIDOMHTMLMetaElement
*nsmeta
;
745 nsIDOMHTMLElement
*nselem
;
746 nsIDOMComment
*nscomment
;
749 TRACE("(%p)->(%p %p)\n", This
, aDocument
, aContent
);
751 nsres
= nsIContent_QueryInterface(aContent
, &IID_nsIDOMComment
, (void**)&nscomment
);
752 if(NS_SUCCEEDED(nsres
)) {
753 TRACE("comment node\n");
755 add_script_runner(This
, run_insert_comment
, (nsISupports
*)nscomment
, NULL
);
756 nsIDOMComment_Release(nscomment
);
760 if(This
->document_mode
== COMPAT_MODE_QUIRKS
) {
761 nsIDOMDocumentType
*nsdoctype
;
762 nsres
= nsIContent_QueryInterface(aContent
, &IID_nsIDOMDocumentType
, (void**)&nsdoctype
);
763 if(NS_SUCCEEDED(nsres
)) {
764 TRACE("doctype node\n");
765 /* FIXME: We should set it to something higher for internet zone. */
766 set_document_mode(This
, COMPAT_MODE_IE7
, FALSE
);
767 nsIDOMDocumentType_Release(nsdoctype
);
771 nsres
= nsIContent_QueryInterface(aContent
, &IID_nsIDOMHTMLElement
, (void**)&nselem
);
775 check_event_attr(This
, nselem
);
776 nsIDOMHTMLElement_Release(nselem
);
778 nsres
= nsIContent_QueryInterface(aContent
, &IID_nsIDOMHTMLIFrameElement
, (void**)&nsiframe
);
779 if(NS_SUCCEEDED(nsres
)) {
780 TRACE("iframe node\n");
782 add_script_runner(This
, run_bind_to_tree
, (nsISupports
*)nsiframe
, NULL
);
783 nsIDOMHTMLIFrameElement_Release(nsiframe
);
787 nsres
= nsIContent_QueryInterface(aContent
, &IID_nsIDOMHTMLFrameElement
, (void**)&nsframe
);
788 if(NS_SUCCEEDED(nsres
)) {
789 TRACE("frame node\n");
791 add_script_runner(This
, run_bind_to_tree
, (nsISupports
*)nsframe
, NULL
);
792 nsIDOMHTMLFrameElement_Release(nsframe
);
796 nsres
= nsIContent_QueryInterface(aContent
, &IID_nsIDOMHTMLScriptElement
, (void**)&nsscript
);
797 if(NS_SUCCEEDED(nsres
)) {
798 TRACE("script element\n");
800 add_script_runner(This
, run_bind_to_tree
, (nsISupports
*)nsscript
, NULL
);
801 nsIDOMHTMLScriptElement_Release(nsscript
);
805 nsres
= nsIContent_QueryInterface(aContent
, &IID_nsIDOMHTMLMetaElement
, (void**)&nsmeta
);
806 if(NS_SUCCEEDED(nsres
)) {
807 process_meta_element(This
, nsmeta
);
808 nsIDOMHTMLMetaElement_Release(nsmeta
);
812 static void NSAPI
nsDocumentObserver_AttemptToExecuteScript(nsIDocumentObserver
*iface
, nsIContent
*aContent
,
813 nsIParser
*aParser
, cpp_bool
*aBlock
)
815 HTMLDocumentNode
*This
= impl_from_nsIDocumentObserver(iface
);
816 nsIDOMHTMLScriptElement
*nsscript
;
819 TRACE("(%p)->(%p %p %p)\n", This
, aContent
, aParser
, aBlock
);
821 nsres
= nsIContent_QueryInterface(aContent
, &IID_nsIDOMHTMLScriptElement
, (void**)&nsscript
);
822 if(NS_SUCCEEDED(nsres
)) {
823 TRACE("script node\n");
825 This
->document_mode_locked
= TRUE
;
827 add_script_runner(This
, run_insert_script
, (nsISupports
*)nsscript
, (nsISupports
*)aParser
);
828 nsIDOMHTMLScriptElement_Release(nsscript
);
832 static const nsIDocumentObserverVtbl nsDocumentObserverVtbl
= {
833 nsDocumentObserver_QueryInterface
,
834 nsDocumentObserver_AddRef
,
835 nsDocumentObserver_Release
,
836 nsDocumentObserver_CharacterDataWillChange
,
837 nsDocumentObserver_CharacterDataChanged
,
838 nsDocumentObserver_AttributeWillChange
,
839 nsDocumentObserver_AttributeChanged
,
840 nsDocumentObserver_NativeAnonymousChildListChange
,
841 nsDocumentObserver_AttributeSetToCurrentValue
,
842 nsDocumentObserver_ContentAppended
,
843 nsDocumentObserver_ContentInserted
,
844 nsDocumentObserver_ContentRemoved
,
845 nsDocumentObserver_NodeWillBeDestroyed
,
846 nsDocumentObserver_ParentChainChanged
,
847 nsDocumentObserver_BeginUpdate
,
848 nsDocumentObserver_EndUpdate
,
849 nsDocumentObserver_BeginLoad
,
850 nsDocumentObserver_EndLoad
,
851 nsDocumentObserver_ContentStatesChanged
,
852 nsDocumentObserver_DocumentStatesChanged
,
853 nsDocumentObserver_StyleSheetAdded
,
854 nsDocumentObserver_StyleSheetRemoved
,
855 nsDocumentObserver_StyleSheetApplicableStateChanged
,
856 nsDocumentObserver_StyleRuleChanged
,
857 nsDocumentObserver_StyleRuleAdded
,
858 nsDocumentObserver_StyleRuleRemoved
,
859 nsDocumentObserver_BindToDocument
,
860 nsDocumentObserver_AttemptToExecuteScript
863 void init_document_mutation(HTMLDocumentNode
*doc
)
868 doc
->nsIDocumentObserver_iface
.lpVtbl
= &nsDocumentObserverVtbl
;
870 nsres
= nsIDOMHTMLDocument_QueryInterface(doc
->nsdoc
, &IID_nsIDocument
, (void**)&nsdoc
);
871 if(NS_FAILED(nsres
)) {
872 ERR("Could not get nsIDocument: %08x\n", nsres
);
876 nsIContentUtils_AddDocumentObserver(content_utils
, nsdoc
, &doc
->nsIDocumentObserver_iface
);
877 nsIDocument_Release(nsdoc
);
880 void release_document_mutation(HTMLDocumentNode
*doc
)
885 nsres
= nsIDOMHTMLDocument_QueryInterface(doc
->nsdoc
, &IID_nsIDocument
, (void**)&nsdoc
);
886 if(NS_FAILED(nsres
)) {
887 ERR("Could not get nsIDocument: %08x\n", nsres
);
891 nsIContentUtils_RemoveDocumentObserver(content_utils
, nsdoc
, &doc
->nsIDocumentObserver_iface
);
892 nsIDocument_Release(nsdoc
);
895 JSContext
*get_context_from_document(nsIDOMHTMLDocument
*nsdoc
)
901 nsres
= nsIDOMHTMLDocument_QueryInterface(nsdoc
, &IID_nsIDocument
, (void**)&doc
);
902 assert(nsres
== NS_OK
);
904 ctx
= nsIContentUtils_GetContextFromDocument(content_utils
, doc
);
905 nsIDocument_Release(doc
);
907 TRACE("ret %p\n", ctx
);
911 void init_mutation(nsIComponentManager
*component_manager
)
916 if(!component_manager
) {
918 nsIContentUtils_Release(content_utils
);
919 content_utils
= NULL
;
924 nsres
= nsIComponentManager_GetClassObject(component_manager
, &NS_ICONTENTUTILS_CID
,
925 &IID_nsIFactory
, (void**)&factory
);
926 if(NS_FAILED(nsres
)) {
927 ERR("Could not create nsIContentUtils service: %08x\n", nsres
);
931 nsres
= nsIFactory_CreateInstance(factory
, NULL
, &IID_nsIContentUtils
, (void**)&content_utils
);
932 nsIFactory_Release(factory
);
934 ERR("Could not create nsIContentUtils instance: %08x\n", nsres
);