From 451f5b4ad6e4cbad9f5d06f9ee7012b8256bf305 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Thu, 3 Dec 2009 01:12:12 +0100 Subject: [PATCH] mshtml: Added generic bind_to_tree node notification and use it to set frame's content window. --- dlls/mshtml/htmlelem.c | 5 +- dlls/mshtml/htmlframebase.c | 72 ++++++++++++++++++----- dlls/mshtml/htmliframe.c | 61 ++++++++------------ dlls/mshtml/mshtml_private.h | 8 ++- dlls/mshtml/mutation.c | 109 +++++++---------------------------- 5 files changed, 113 insertions(+), 142 deletions(-) diff --git a/dlls/mshtml/htmlelem.c b/dlls/mshtml/htmlelem.c index efcdb6c1906..b3703f3d0b5 100644 --- a/dlls/mshtml/htmlelem.c +++ b/dlls/mshtml/htmlelem.c @@ -1602,6 +1602,7 @@ HTMLElement *HTMLElement_Create(HTMLDocumentNode *doc, nsIDOMNode *nsnode, BOOL static const WCHAR wszA[] = {'A',0}; static const WCHAR wszBODY[] = {'B','O','D','Y',0}; static const WCHAR wszFORM[] = {'F','O','R','M',0}; + static const WCHAR wszFRAME[] = {'F','R','A','M','E',0}; static const WCHAR wszIFRAME[] = {'I','F','R','A','M','E',0}; static const WCHAR wszIMG[] = {'I','M','G',0}; static const WCHAR wszINPUT[] = {'I','N','P','U','T',0}; @@ -1627,8 +1628,10 @@ HTMLElement *HTMLElement_Create(HTMLDocumentNode *doc, nsIDOMNode *nsnode, BOOL ret = HTMLBodyElement_Create(doc, nselem); else if(!strcmpW(class_name, wszFORM)) ret = HTMLFormElement_Create(doc, nselem); + else if(!strcmpW(class_name, wszFRAME)) + ret = HTMLFrameElement_Create(doc, nselem); else if(!strcmpW(class_name, wszIFRAME)) - ret = HTMLIFrame_Create(doc, nselem, NULL); + ret = HTMLIFrame_Create(doc, nselem); else if(!strcmpW(class_name, wszIMG)) ret = HTMLImgElement_Create(doc, nselem); else if(!strcmpW(class_name, wszINPUT)) diff --git a/dlls/mshtml/htmlframebase.c b/dlls/mshtml/htmlframebase.c index cda68499db1..03b48b64e31 100644 --- a/dlls/mshtml/htmlframebase.c +++ b/dlls/mshtml/htmlframebase.c @@ -31,6 +31,32 @@ WINE_DEFAULT_DEBUG_CHANNEL(mshtml); +HRESULT set_frame_doc(HTMLFrameBase *frame, nsIDOMDocument *nsdoc) +{ + nsIDOMWindow *nswindow; + HTMLWindow *window; + HRESULT hres = S_OK; + + if(frame->content_window) + return S_OK; + + nswindow = get_nsdoc_window(nsdoc); + if(!nswindow) + return E_FAIL; + + window = nswindow_to_window(nswindow); + if(!window) + hres = HTMLWindow_Create(frame->element.node.doc->basedoc.doc_obj, nswindow, + frame->element.node.doc->basedoc.window, &window); + nsIDOMWindow_Release(nswindow); + if(FAILED(hres)) + return hres; + + frame->content_window = window; + window->frame_element = frame; + return S_OK; +} + #define HTMLFRAMEBASE_THIS(iface) DEFINE_THIS(HTMLFrameBase, IHTMLFrameBase, iface) static HRESULT WINAPI HTMLFrameBase_QueryInterface(IHTMLFrameBase *iface, REFIID riid, void **ppv) @@ -414,27 +440,19 @@ HRESULT HTMLFrameBase_QI(HTMLFrameBase *This, REFIID riid, void **ppv) void HTMLFrameBase_destructor(HTMLFrameBase *This) { - if(This->content_window) { + if(This->content_window) This->content_window->frame_element = NULL; - IHTMLWindow2_Release(HTMLWINDOW2(This->content_window)); - } HTMLElement_destructor(&This->element.node); } void HTMLFrameBase_Init(HTMLFrameBase *This, HTMLDocumentNode *doc, nsIDOMHTMLElement *nselem, - HTMLWindow *content_window, dispex_static_data_t *dispex_data) + dispex_static_data_t *dispex_data) { This->lpIHTMLFrameBaseVtbl = &HTMLFrameBaseVtbl; This->lpIHTMLFrameBase2Vtbl = &HTMLFrameBase2Vtbl; HTMLElement_Init(&This->element, doc, nselem, dispex_data); - - if(content_window) { - IHTMLWindow2_AddRef(HTMLWINDOW2(content_window)); - content_window->frame_element = This; - } - This->content_window = content_window; } typedef struct { @@ -471,6 +489,30 @@ static HRESULT HTMLFrameElement_get_document(HTMLDOMNode *iface, IDispatch **p) return S_OK; } +static HRESULT HTMLFrameElement_bind_to_tree(HTMLDOMNode *iface) +{ + HTMLFrameElement *This = HTMLFRAME_NODE_THIS(iface); + nsIDOMHTMLFrameElement *nsframe; + nsIDOMDocument *nsdoc; + nsresult nsres; + HRESULT hres; + + nsres = nsIDOMHTMLElement_QueryInterface(This->framebase.element.nselem, &IID_nsIDOMHTMLFrameElement, (void**)&nsframe); + if(NS_FAILED(nsres)) + return E_FAIL; + + nsres = nsIDOMHTMLFrameElement_GetContentDocument(nsframe, &nsdoc); + nsIDOMHTMLFrameElement_Release(nsframe); + if(NS_FAILED(nsres) || !nsdoc) { + ERR("GetContentDocument failed: %08x\n", nsres); + return E_FAIL; + } + + hres = set_frame_doc(&This->framebase, nsdoc); + nsIDOMDocument_Release(nsdoc); + return hres; +} + #undef HTMLFRAME_NODE_THIS static const NodeImplVtbl HTMLFrameElementImplVtbl = { @@ -480,10 +522,14 @@ static const NodeImplVtbl HTMLFrameElementImplVtbl = { NULL, NULL, NULL, - HTMLFrameElement_get_document + HTMLFrameElement_get_document, + NULL, + NULL, + NULL, + HTMLFrameElement_bind_to_tree }; -HTMLElement *HTMLFrameElement_Create(HTMLDocumentNode *doc, nsIDOMHTMLElement *nselem, HTMLWindow *content_window) +HTMLElement *HTMLFrameElement_Create(HTMLDocumentNode *doc, nsIDOMHTMLElement *nselem) { nsIDOMHTMLFrameElement *nsframe; HTMLFrameElement *ret; @@ -497,7 +543,7 @@ HTMLElement *HTMLFrameElement_Create(HTMLDocumentNode *doc, nsIDOMHTMLElement *n if(NS_FAILED(nsres)) ERR("Could not get nsIDOMHTMLFrameElement iface: %08x\n", nsres); - HTMLFrameBase_Init(&ret->framebase, doc, nselem, content_window, NULL); + HTMLFrameBase_Init(&ret->framebase, doc, nselem, NULL); return &ret->framebase.element; } diff --git a/dlls/mshtml/htmliframe.c b/dlls/mshtml/htmliframe.c index 382e04911f3..2132df35308 100644 --- a/dlls/mshtml/htmliframe.c +++ b/dlls/mshtml/htmliframe.c @@ -79,6 +79,24 @@ static HRESULT HTMLIFrame_get_readystate(HTMLDOMNode *iface, BSTR *p) return IHTMLFrameBase2_get_readyState(HTMLFRAMEBASE2(&This->framebase), p); } +static HRESULT HTMLIFrame_bind_to_tree(HTMLDOMNode *iface) +{ + HTMLIFrame *This = HTMLIFRAME_NODE_THIS(iface); + nsIDOMDocument *nsdoc; + nsresult nsres; + HRESULT hres; + + nsres = nsIDOMHTMLIFrameElement_GetContentDocument(This->nsiframe, &nsdoc); + if(NS_FAILED(nsres) || !nsdoc) { + ERR("GetContentDocument failed: %08x\n", nsres); + return E_FAIL; + } + + hres = set_frame_doc(&This->framebase, nsdoc); + nsIDOMDocument_Release(nsdoc); + return hres; +} + #undef HTMLIFRAME_NODE_THIS static const NodeImplVtbl HTMLIFrameImplVtbl = { @@ -89,7 +107,10 @@ static const NodeImplVtbl HTMLIFrameImplVtbl = { NULL, NULL, HTMLIFrame_get_document, - HTMLIFrame_get_readystate + HTMLIFrame_get_readystate, + NULL, + NULL, + HTMLIFrame_bind_to_tree }; static const tid_t HTMLIFrame_iface_tids[] = { @@ -110,38 +131,7 @@ static dispex_static_data_t HTMLIFrame_dispex = { HTMLIFrame_iface_tids }; -static HTMLWindow *get_content_window(nsIDOMHTMLIFrameElement *nsiframe) -{ - HTMLWindow *ret; - nsIDOMWindow *nswindow; - nsIDOMDocument *nsdoc; - nsresult nsres; - - nsres = nsIDOMHTMLIFrameElement_GetContentDocument(nsiframe, &nsdoc); - if(NS_FAILED(nsres)) { - ERR("GetContentDocument failed: %08x\n", nsres); - return NULL; - } - - if(!nsdoc) { - FIXME("NULL contentDocument\n"); - return NULL; - } - - nswindow = get_nsdoc_window(nsdoc); - nsIDOMDocument_Release(nsdoc); - if(!nswindow) - return NULL; - - ret = nswindow_to_window(nswindow); - nsIDOMWindow_Release(nswindow); - if(!ret) - ERR("Could not get window object\n"); - - return ret; -} - -HTMLElement *HTMLIFrame_Create(HTMLDocumentNode *doc, nsIDOMHTMLElement *nselem, HTMLWindow *content_window) +HTMLElement *HTMLIFrame_Create(HTMLDocumentNode *doc, nsIDOMHTMLElement *nselem) { HTMLIFrame *ret; nsresult nsres; @@ -154,10 +144,7 @@ HTMLElement *HTMLIFrame_Create(HTMLDocumentNode *doc, nsIDOMHTMLElement *nselem, if(NS_FAILED(nsres)) ERR("Could not get nsIDOMHTMLIFrameElement iface: %08x\n", nsres); - if(!content_window) - content_window = get_content_window(ret->nsiframe); - - HTMLFrameBase_Init(&ret->framebase, doc, nselem, content_window, &HTMLIFrame_dispex); + HTMLFrameBase_Init(&ret->framebase, doc, nselem, &HTMLIFrame_dispex); return &ret->framebase.element; } diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 804d9189519..6fad6e515f6 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -455,6 +455,7 @@ typedef struct { HRESULT (*get_readystate)(HTMLDOMNode*,BSTR*); HRESULT (*get_dispid)(HTMLDOMNode*,BSTR,DWORD,DISPID*); HRESULT (*invoke)(HTMLDOMNode*,DISPID,LCID,WORD,DISPPARAMS*,VARIANT*,EXCEPINFO*,IServiceProvider*); + HRESULT (*bind_to_tree)(HTMLDOMNode*); } NodeImplVtbl; struct HTMLDOMNode { @@ -675,6 +676,7 @@ HRESULT create_doc_uri(HTMLWindow*,WCHAR*,nsIWineURI**); HRESULT hlink_frame_navigate(HTMLDocument*,LPCWSTR,nsIInputStream*,DWORD); HRESULT navigate_url(HTMLWindow*,const WCHAR*,const WCHAR*); +HRESULT set_frame_doc(HTMLFrameBase*,nsIDOMDocument*); void call_property_onchanged(ConnectionPoint*,DISPID); HRESULT call_set_active_object(IOleInPlaceUIWindow*,IOleInPlaceActiveObject*); @@ -734,8 +736,8 @@ HTMLElement *HTMLCommentElement_Create(HTMLDocumentNode*,nsIDOMNode*); HTMLElement *HTMLAnchorElement_Create(HTMLDocumentNode*,nsIDOMHTMLElement*); HTMLElement *HTMLBodyElement_Create(HTMLDocumentNode*,nsIDOMHTMLElement*); HTMLElement *HTMLFormElement_Create(HTMLDocumentNode*,nsIDOMHTMLElement*); -HTMLElement *HTMLFrameElement_Create(HTMLDocumentNode*,nsIDOMHTMLElement*,HTMLWindow*); -HTMLElement *HTMLIFrame_Create(HTMLDocumentNode*,nsIDOMHTMLElement*,HTMLWindow*); +HTMLElement *HTMLFrameElement_Create(HTMLDocumentNode*,nsIDOMHTMLElement*); +HTMLElement *HTMLIFrame_Create(HTMLDocumentNode*,nsIDOMHTMLElement*); HTMLElement *HTMLImgElement_Create(HTMLDocumentNode*,nsIDOMHTMLElement*); HTMLElement *HTMLInputElement_Create(HTMLDocumentNode*,nsIDOMHTMLElement*); HTMLElement *HTMLOptionElement_Create(HTMLDocumentNode*,nsIDOMHTMLElement*); @@ -751,7 +753,7 @@ void HTMLElement_Init(HTMLElement*,HTMLDocumentNode*,nsIDOMHTMLElement*,dispex_s void HTMLElement2_Init(HTMLElement*); void HTMLElement3_Init(HTMLElement*); void HTMLTextContainer_Init(HTMLTextContainer*,HTMLDocumentNode*,nsIDOMHTMLElement*,dispex_static_data_t*); -void HTMLFrameBase_Init(HTMLFrameBase*,HTMLDocumentNode*,nsIDOMHTMLElement*,HTMLWindow*,dispex_static_data_t*); +void HTMLFrameBase_Init(HTMLFrameBase*,HTMLDocumentNode*,nsIDOMHTMLElement*,dispex_static_data_t*); HRESULT HTMLDOMNode_QI(HTMLDOMNode*,REFIID,void**); void HTMLDOMNode_destructor(HTMLDOMNode*); diff --git a/dlls/mshtml/mutation.c b/dlls/mshtml/mutation.c index 84c92413346..372c467bf53 100644 --- a/dlls/mshtml/mutation.c +++ b/dlls/mshtml/mutation.c @@ -37,10 +37,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(mshtml); enum { + MUTATION_BINDTOTREE, MUTATION_COMMENT, MUTATION_ENDLOAD, - MUTATION_FRAME, - MUTATION_IFRAME, MUTATION_SCRIPT }; @@ -271,87 +270,25 @@ static void pop_mutation_queue(HTMLDocumentNode *doc) heap_free(tmp); } -static nsresult init_nsdoc_window(HTMLDocumentNode *doc, nsIDOMDocument *nsdoc, HTMLWindow **ret) +static void bind_to_tree(HTMLDocumentNode *doc, nsISupports *nsiface) { - nsIDOMWindow *nswindow; - - nswindow = get_nsdoc_window(nsdoc); - if(!nswindow) - return NS_ERROR_FAILURE; - - if(!nswindow_to_window(nswindow)) { - HTMLWindow *window; - HRESULT hres; - - hres = HTMLWindow_Create(doc->basedoc.doc_obj, nswindow, doc->basedoc.window, &window); - if(SUCCEEDED(hres)) - *ret = window; - } - - nsIDOMWindow_Release(nswindow); - return NS_OK; -} - -static nsresult init_iframe_window(HTMLDocumentNode *doc, nsISupports *nsunk) -{ - nsIDOMHTMLIFrameElement *nsiframe; - HTMLWindow *window = NULL; - nsIDOMDocument *nsdoc; + nsIDOMNode *nsnode; + HTMLDOMNode *node; nsresult nsres; - nsres = nsISupports_QueryInterface(nsunk, &IID_nsIDOMHTMLIFrameElement, (void**)&nsiframe); - if(NS_FAILED(nsres)) { - ERR("Could not get nsIDOMHTMLIFrameElement: %08x\n", nsres); - return nsres; + nsres = nsISupports_QueryInterface(nsiface, &IID_nsIDOMNode, (void**)&nsnode); + if(NS_FAILED(nsres)) + return; + + node = get_node(doc, nsnode, TRUE); + nsIDOMNode_Release(nsnode); + if(!node) { + ERR("Could not get node\n"); + return; } - nsres = nsIDOMHTMLIFrameElement_GetContentDocument(nsiframe, &nsdoc); - nsIDOMHTMLIFrameElement_Release(nsiframe); - if(NS_FAILED(nsres) || !nsdoc) { - ERR("GetContentDocument failed: %08x\n", nsres); - return nsres; - } - - nsres = init_nsdoc_window(doc, nsdoc, &window); - - if(window) { - HTMLIFrame_Create(doc, (nsIDOMHTMLElement*)nsiframe, window); - IHTMLWindow2_Release(HTMLWINDOW2(window)); - } - - nsIDOMDocument_Release(nsdoc); - return nsres; -} - -static nsresult init_frame_window(HTMLDocumentNode *doc, nsISupports *nsunk) -{ - nsIDOMHTMLFrameElement *nsframe; - HTMLWindow *window = NULL; - nsIDOMDocument *nsdoc; - nsresult nsres; - - nsres = nsISupports_QueryInterface(nsunk, &IID_nsIDOMHTMLFrameElement, (void**)&nsframe); - if(NS_FAILED(nsres)) { - ERR("Could not get nsIDOMHTMLFrameElement: %08x\n", nsres); - return nsres; - } - - nsres = nsIDOMHTMLFrameElement_GetContentDocument(nsframe, &nsdoc); - nsIDOMHTMLFrameElement_Release(nsframe); - if(NS_FAILED(nsres) || !nsdoc) { - ERR("GetContentDocument failed: %08x\n", nsres); - return nsres; - } - - nsres = init_nsdoc_window(doc, nsdoc, &window); - - if(window) { - HTMLFrameElement_Create(doc, (nsIDOMHTMLElement*)nsframe, window); - IHTMLWindow2_Release(HTMLWINDOW2(window)); - } - - nsIDOMDocument_Release(nsdoc); - return nsres; + if(node->vtbl->bind_to_tree) + node->vtbl->bind_to_tree(node); } /* Calls undocumented 69 cmd of CGID_Explorer */ @@ -426,6 +363,10 @@ static nsresult NSAPI nsRunnable_Run(nsIRunnable *iface) while(This->mutation_queue) { switch(This->mutation_queue->type) { + case MUTATION_BINDTOTREE: + bind_to_tree(This, This->mutation_queue->nsiface); + break; + case MUTATION_COMMENT: { nsIDOMComment *nscomment; nsAString comment_str; @@ -477,14 +418,6 @@ static nsresult NSAPI nsRunnable_Run(nsIRunnable *iface) handle_end_load(This); break; - case MUTATION_FRAME: - init_frame_window(This, This->mutation_queue->nsiface); - break; - - case MUTATION_IFRAME: - init_iframe_window(This, This->mutation_queue->nsiface); - break; - case MUTATION_SCRIPT: { nsIDOMHTMLScriptElement *nsscript; @@ -689,7 +622,7 @@ static void NSAPI nsDocumentObserver_BindToDocument(nsIDocumentObserver *iface, if(NS_SUCCEEDED(nsres)) { TRACE("iframe node\n"); - push_mutation_queue(This, MUTATION_IFRAME, (nsISupports*)nsiframe); + push_mutation_queue(This, MUTATION_BINDTOTREE, (nsISupports*)nsiframe); nsIDOMHTMLIFrameElement_Release(nsiframe); } @@ -697,7 +630,7 @@ static void NSAPI nsDocumentObserver_BindToDocument(nsIDocumentObserver *iface, if(NS_SUCCEEDED(nsres)) { TRACE("frame node\n"); - push_mutation_queue(This, MUTATION_FRAME, (nsISupports*)nsframe); + push_mutation_queue(This, MUTATION_BINDTOTREE, (nsISupports*)nsframe); nsIDOMHTMLFrameElement_Release(nsframe); } }