mshtml: Added IHTMLFrameBase2::get_contentWidnow implementation.
authorJacek Caban <jacek@codeweavers.com>
Fri, 10 Oct 2008 20:48:32 +0000 (15:48 -0500)
committerAlexandre Julliard <julliard@winehq.org>
Mon, 13 Oct 2008 09:16:39 +0000 (11:16 +0200)
dlls/mshtml/htmldoc.c
dlls/mshtml/htmliframe.c
dlls/mshtml/mshtml_private.h
dlls/mshtml/tests/dom.c

index f39688bf471fd3e8dde53a2ea1189c3cfaf5c057..4e8f0634c7be381f10c39456f186059e4c0f5c95 100644 (file)
@@ -1549,62 +1549,104 @@ static dispex_static_data_t HTMLDocument_dispex = {
     HTMLDocument_iface_tids
 };
 
-HRESULT HTMLDocument_Create(IUnknown *pUnkOuter, REFIID riid, void** ppvObject)
+static HRESULT alloc_doc(HTMLDocument **ret)
+{
+    HTMLDocument *doc;
+
+    doc = heap_alloc_zero(sizeof(HTMLDocument));
+    doc->lpHTMLDocument2Vtbl = &HTMLDocumentVtbl;
+    doc->lpIDispatchExVtbl = &DocDispatchExVtbl;
+    doc->ref = 1;
+    doc->readystate = READYSTATE_UNINITIALIZED;
+    doc->scriptmode = SCRIPTMODE_GECKO;
+
+    list_init(&doc->bindings);
+    list_init(&doc->script_hosts);
+    list_init(&doc->selection_list);
+    list_init(&doc->range_list);
+
+    HTMLDocument_HTMLDocument3_Init(doc);
+    HTMLDocument_HTMLDocument5_Init(doc);
+    HTMLDocument_Persist_Init(doc);
+    HTMLDocument_OleCmd_Init(doc);
+    HTMLDocument_OleObj_Init(doc);
+    HTMLDocument_View_Init(doc);
+    HTMLDocument_Window_Init(doc);
+    HTMLDocument_Service_Init(doc);
+    HTMLDocument_Hlink_Init(doc);
+
+    ConnectionPointContainer_Init(&doc->cp_container, (IUnknown*)HTMLDOC(doc));
+    ConnectionPoint_Init(&doc->cp_propnotif, &doc->cp_container, &IID_IPropertyNotifySink);
+    ConnectionPoint_Init(&doc->cp_htmldocevents, &doc->cp_container, &DIID_HTMLDocumentEvents);
+    ConnectionPoint_Init(&doc->cp_htmldocevents2, &doc->cp_container, &DIID_HTMLDocumentEvents2);
+
+    init_dispex(&doc->dispex, (IUnknown*)HTMLDOC(doc), &HTMLDocument_dispex);
+
+    *ret = doc;
+    return S_OK;
+}
+
+HRESULT create_doc_from_nsdoc(nsIDOMHTMLDocument *nsdoc, HTMLDocument **ret)
 {
-    nsIDOMWindow *nswindow;
-    HTMLDocument *ret;
+    HTMLDocument *doc;
     HRESULT hres;
 
-    TRACE("(%p %s %p)\n", pUnkOuter, debugstr_guid(riid), ppvObject);
-
-    ret = heap_alloc_zero(sizeof(HTMLDocument));
-    ret->lpHTMLDocument2Vtbl = &HTMLDocumentVtbl;
-    ret->lpIDispatchExVtbl = &DocDispatchExVtbl;
-    ret->ref = 0;
-    ret->readystate = READYSTATE_UNINITIALIZED;
-    ret->scriptmode = SCRIPTMODE_GECKO;
+    hres = alloc_doc(&doc);
+    if(FAILED(hres))
+        return hres;
 
-    list_init(&ret->bindings);
-    list_init(&ret->script_hosts);
-    list_init(&ret->selection_list);
-    list_init(&ret->range_list);
+    nsIDOMHTMLDocument_AddRef(nsdoc);
+    doc->nsdoc = nsdoc;
 
-    hres = IHTMLDocument_QueryInterface(HTMLDOC(ret), riid, ppvObject);
+    hres = HTMLWindow_Create(doc, NULL, &doc->window);
     if(FAILED(hres)) {
-        heap_free(ret);
+        IHTMLDocument_Release(HTMLDOC(doc));
         return hres;
     }
 
-    LOCK_MODULE();
+    *ret = doc;
+    return S_OK;
+}
 
-    HTMLDocument_HTMLDocument3_Init(ret);
-    HTMLDocument_HTMLDocument5_Init(ret);
-    HTMLDocument_Persist_Init(ret);
-    HTMLDocument_OleCmd_Init(ret);
-    HTMLDocument_OleObj_Init(ret);
-    HTMLDocument_View_Init(ret);
-    HTMLDocument_Window_Init(ret);
-    HTMLDocument_Service_Init(ret);
-    HTMLDocument_Hlink_Init(ret);
+HRESULT HTMLDocument_Create(IUnknown *pUnkOuter, REFIID riid, void** ppvObject)
+{
+    HTMLDocument *doc;
+    nsIDOMWindow *nswindow;
+    HRESULT hres;
+
+    TRACE("(%p %s %p)\n", pUnkOuter, debugstr_guid(riid), ppvObject);
 
-    ConnectionPointContainer_Init(&ret->cp_container, (IUnknown*)HTMLDOC(ret));
-    ConnectionPoint_Init(&ret->cp_propnotif, &ret->cp_container, &IID_IPropertyNotifySink);
-    ConnectionPoint_Init(&ret->cp_htmldocevents, &ret->cp_container, &DIID_HTMLDocumentEvents);
-    ConnectionPoint_Init(&ret->cp_htmldocevents2, &ret->cp_container, &DIID_HTMLDocumentEvents2);
+    hres = alloc_doc(&doc);
+    if(FAILED(hres))
+        return hres;
 
-    init_dispex(&ret->dispex, (IUnknown*)HTMLDOC(ret), &HTMLDocument_dispex);
+    hres = IHTMLDocument_QueryInterface(HTMLDOC(doc), riid, ppvObject);
+    IHTMLDocument_Release(HTMLDOC(doc));
+    if(FAILED(hres))
+        return hres;
+
+    LOCK_MODULE();
 
-    ret->nscontainer = NSContainer_Create(ret, NULL);
-    update_nsdocument(ret);
+    doc->nscontainer = NSContainer_Create(doc, NULL);
+    update_nsdocument(doc);
 
-    if(ret->nscontainer)
-        nsIWebBrowser_GetContentDOMWindow(ret->nscontainer->webbrowser, &nswindow);
+    if(doc->nscontainer) {
+        nsresult nsres;
 
-    HTMLWindow_Create(ret, nswindow, &ret->window);
+        nsres = nsIWebBrowser_GetContentDOMWindow(doc->nscontainer->webbrowser, &nswindow);
+        if(NS_FAILED(nsres))
+            ERR("GetContentDOMWindow failed: %08x\n", nsres);
+    }
+
+    hres = HTMLWindow_Create(doc, nswindow, &doc->window);
     if(nswindow)
         nsIDOMWindow_Release(nswindow);
+    if(FAILED(hres)) {
+        IHTMLDocument_Release(HTMLDOC(doc));
+        return hres;
+    }
 
     get_thread_hwnd();
 
-    return hres;
+    return S_OK;
 }
index 232cbfb66203d7fa50aef5aeca817395fbfe4bc9..f56bc16fda212dd55a0ffa26ad7a061e9864b6b0 100644 (file)
@@ -38,6 +38,7 @@ typedef struct {
     LONG ref;
 
     nsIDOMHTMLIFrameElement *nsiframe;
+    HTMLDocument *content_doc;
 } HTMLIFrame;
 
 #define HTMLFRAMEBASE2(x)  ((IHTMLFrameBase2*)  &(x)->lpIHTMLFrameBase2Vtbl)
@@ -100,8 +101,40 @@ static HRESULT WINAPI HTMLIFrameBase2_Invoke(IHTMLFrameBase2 *iface, DISPID disp
 static HRESULT WINAPI HTMLIFrameBase2_get_contentWindow(IHTMLFrameBase2 *iface, IHTMLWindow2 **p)
 {
     HTMLIFrame *This = HTMLFRAMEBASE2_THIS(iface);
-    FIXME("(%p)->(%p)\n", This, p);
-    return E_NOTIMPL;
+
+    TRACE("(%p)->(%p)\n", This, p);
+
+    if(!This->content_doc) {
+        nsIDOMHTMLDocument *nshtmldoc;
+        nsIDOMDocument *nsdoc;
+        nsresult nsres;
+        HRESULT hres;
+
+        nsres = nsIDOMHTMLIFrameElement_GetContentDocument(This->nsiframe, &nsdoc);
+        if(NS_FAILED(nsres)) {
+            ERR("GetContentDocument failed: %08x\n", nsres);
+            return E_FAIL;
+        }
+
+        if(!nsdoc) {
+            FIXME("NULL contentDocument\n");
+            return E_FAIL;
+        }
+
+        nsres = nsIDOMDocument_QueryInterface(nsdoc, &IID_nsIDOMHTMLDocument, (void**)&nshtmldoc);
+        nsIDOMDocument_Release(nsdoc);
+        if(NS_FAILED(nsres)) {
+            ERR("Could not get nsIDOMHTMLDocument iface: %08x\n", nsres);
+            return E_FAIL;
+        }
+
+        hres = create_doc_from_nsdoc(nshtmldoc, &This->content_doc);
+        nsIDOMHTMLDocument_Release(nshtmldoc);
+        if(FAILED(hres))
+            return hres;
+    }
+
+    return IHTMLDocument2_get_parentWindow(HTMLDOC(This->content_doc), p);
 }
 
 static HRESULT WINAPI HTMLIFrameBase2_put_onload(IHTMLFrameBase2 *iface, VARIANT v)
@@ -196,6 +229,8 @@ static void HTMLIFrame_destructor(HTMLDOMNode *iface)
 {
     HTMLIFrame *This = HTMLIFRAME_NODE_THIS(iface);
 
+    if(This->content_doc)
+        IHTMLDocument2_Release(HTMLDOC(This->content_doc));
     if(This->nsiframe)
         nsIDOMHTMLIFrameElement_Release(This->nsiframe);
 
index c39d245d56bd463899bd107e063b007f684a6e37..cdd42937fc07bbad2071207c4215725aeea3c86a 100644 (file)
@@ -459,6 +459,7 @@ typedef struct {
 
 HRESULT HTMLDocument_Create(IUnknown*,REFIID,void**);
 HRESULT HTMLLoadOptions_Create(IUnknown*,REFIID,void**);
+HRESULT create_doc_from_nsdoc(nsIDOMHTMLDocument*,HTMLDocument**);
 
 HRESULT HTMLWindow_Create(HTMLDocument*,nsIDOMWindow*,HTMLWindow**);
 HTMLWindow *nswindow_to_window(const nsIDOMWindow*);
index e15b6077b23f04b55ece308eea14d762070df76a..2f91a1c2b8a80c82a33cb5a177dd81082e342014 100644 (file)
@@ -49,7 +49,7 @@ static const char elem_test_str[] =
     "<script id=\"sc\" type=\"text/javascript\"></script>"
     "<test />"
     "<img id=\"imgid\"/>"
-    "<iframe src=\"about:blank\"></iframe>"
+    "<iframe src=\"about:blank\" id=\"ifr\"></iframe>"
     "</body></html>";
 static const char indent_test_str[] =
     "<html><head><title>test</title></head><body>abc<br /><a href=\"about:blank\">123</a></body></html>";
@@ -2630,6 +2630,31 @@ static void test_table_elem(IHTMLElement *elem)
     IHTMLTable_Release(table);
 }
 
+static void test_iframe_elem(IHTMLElement *elem)
+{
+    IHTMLDocument2 *content_doc;
+    IHTMLWindow2 *content_window;
+    IHTMLFrameBase2 *base2;
+    HRESULT hres;
+
+    hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLFrameBase2, (void**)&base2);
+    ok(hres == S_OK, "Could not get IHTMFrameBase2 iface: %08x\n", hres);
+
+    content_window = NULL;
+    hres = IHTMLFrameBase2_get_contentWindow(base2, &content_window);
+    IHTMLFrameBase2_Release(base2);
+    ok(hres == S_OK, "get_contentWindow failed: %08x\n", hres);
+    ok(content_window != NULL, "contentWindow = NULL\n");
+
+    content_doc = NULL;
+    hres = IHTMLWindow2_get_document(content_window, &content_doc);
+    IHTMLWindow2_Release(content_window);
+    ok(hres == S_OK, "get_document failed: %08x\n", hres);
+    ok(content_doc != NULL, "content_doc = NULL\n");
+
+    IHTMLDocument2_Release(content_doc);
+}
+
 static void test_stylesheet(IDispatch *disp)
 {
     IHTMLStyleSheetRulesCollection *col = NULL;
@@ -2748,6 +2773,7 @@ static void test_elems(IHTMLDocument2 *doc)
     static const WCHAR xxxW[] = {'x','x','x',0};
     static const WCHAR tblW[] = {'t','b','l',0};
     static const WCHAR row2W[] = {'r','o','w','2',0};
+    static const WCHAR ifrW[] = {'i','f','r',0};
 
     static const elem_type_t all_types[] = {
         ET_HTML,
@@ -2948,6 +2974,13 @@ static void test_elems(IHTMLDocument2 *doc)
         IHTMLElement_Release(elem);
     }
 
+    elem = get_doc_elem_by_id(doc, ifrW);
+    ok(elem != NULL, "elem == NULL\n");
+    if(elem) {
+        test_iframe_elem(elem);
+        IHTMLElement_Release(elem);
+    }
+
     hres = IHTMLDocument2_get_body(doc, &elem);
     ok(hres == S_OK, "get_body failed: %08x\n", hres);