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);
}
}