Jacek Caban : mshtml: Added IHTMLFrameBase2:: get_contentWidnow implementation.

Alexandre Julliard julliard at winehq.org
Mon Oct 13 06:37:39 CDT 2008


Module: wine
Branch: master
Commit: f27386fb815a52a821e1a21adc71b8d4234cf423
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=f27386fb815a52a821e1a21adc71b8d4234cf423

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Fri Oct 10 15:48:32 2008 -0500

mshtml: Added IHTMLFrameBase2::get_contentWidnow implementation.

---

 dlls/mshtml/htmldoc.c        |  118 ++++++++++++++++++++++++++++-------------
 dlls/mshtml/htmliframe.c     |   39 +++++++++++++-
 dlls/mshtml/mshtml_private.h |    1 +
 dlls/mshtml/tests/dom.c      |   35 ++++++++++++-
 4 files changed, 152 insertions(+), 41 deletions(-)

diff --git a/dlls/mshtml/htmldoc.c b/dlls/mshtml/htmldoc.c
index f39688b..4e8f063 100644
--- a/dlls/mshtml/htmldoc.c
+++ b/dlls/mshtml/htmldoc.c
@@ -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;
 }
diff --git a/dlls/mshtml/htmliframe.c b/dlls/mshtml/htmliframe.c
index 232cbfb..f56bc16 100644
--- a/dlls/mshtml/htmliframe.c
+++ b/dlls/mshtml/htmliframe.c
@@ -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);
 
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h
index c39d245..cdd4293 100644
--- a/dlls/mshtml/mshtml_private.h
+++ b/dlls/mshtml/mshtml_private.h
@@ -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*);
diff --git a/dlls/mshtml/tests/dom.c b/dlls/mshtml/tests/dom.c
index e15b607..2f91a1c 100644
--- a/dlls/mshtml/tests/dom.c
+++ b/dlls/mshtml/tests/dom.c
@@ -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);
 




More information about the wine-cvs mailing list