This functions should also work with document fragments, in wine they only return NULL.
From: Santino Mazza smazza@codeweavers.com
--- dlls/mshtml/tests/dom.c | 48 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-)
diff --git a/dlls/mshtml/tests/dom.c b/dlls/mshtml/tests/dom.c index 6a960bfa21f..91bc73fd2d0 100644 --- a/dlls/mshtml/tests/dom.c +++ b/dlls/mshtml/tests/dom.c @@ -10984,7 +10984,7 @@ static IHTMLDocument2 *create_docfrag(IHTMLDocument2 *doc) static void test_docfrag(IHTMLDocument2 *doc) { IHTMLDocument2 *frag, *owner_doc, *doc_node; - IHTMLElement *div, *body, *br; + IHTMLElement *div, *body, *br,*html; IHTMLElementCollection *col; IHTMLLocation *location; HRESULT hres; @@ -10998,6 +10998,13 @@ static void test_docfrag(IHTMLDocument2 *doc) ET_BR };
+ static const elem_type_t frag_types[] = { + ET_HTML, + ET_DIV, + ET_DIV, + ET_BODY + }; + frag = create_docfrag(doc);
test_disp((IUnknown*)frag, &DIID_DispHTMLDocument, &CLSID_HTMLDocument, L"[object]"); @@ -11030,6 +11037,45 @@ static void test_docfrag(IHTMLDocument2 *doc) test_elem_collection((IUnknown*)col, all_types, ARRAY_SIZE(all_types)); IHTMLElementCollection_Release(col);
+ html = test_create_elem(doc, L"HTML"); + test_elem_source_index(html, -1); + test_node_append_child((IUnknown*)frag, (IUnknown*)html); + test_elem_source_index(html, 0); + + div = test_create_elem(doc, L"DIV"); + test_elem_source_index(div, -1); + test_node_append_child((IUnknown*)html, (IUnknown*)div); + test_elem_source_index(div, 1); + IHTMLElement_Release(div); + + div = test_create_elem(doc, L"DIV"); + test_elem_source_index(div, -1); + test_node_append_child((IUnknown*)html, (IUnknown*)div); + test_elem_source_index(div, 2); + + body = test_create_elem(doc, L"BODY"); + test_elem_source_index(body, -1); + test_node_append_child((IUnknown*)div, (IUnknown*)body); + test_elem_source_index(body, 3); + IHTMLElement_Release(body); + IHTMLElement_Release(div); + IHTMLElement_Release(html); + + hres = IHTMLDocument2_get_body(frag, &body); + ok(hres == S_OK, "get_body failed: %08lx\n", hres); + todo_wine ok(body != NULL, "body == NULL\n"); + if (body) + IHTMLElement_Release(body); + + col = NULL; + hres = IHTMLDocument2_get_all(frag, &col); + todo_wine ok(hres == S_OK, "get_all failed: %08lx\n", hres); + todo_wine ok(col != NULL, "got null elements collection\n"); + if (col) { + test_elem_collection((IUnknown *) col, frag_types, ARRAY_SIZE(frag_types)); + IHTMLElementCollection_Release(col); + } + div = test_create_elem(frag, L"div"); owner_doc = get_owner_doc((IUnknown*)div); doc_node = get_doc_node(doc);
From: Santino Mazza smazza@codeweavers.com
--- dlls/mshtml/htmldoc.c | 4 ++-- dlls/mshtml/tests/dom.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/dlls/mshtml/htmldoc.c b/dlls/mshtml/htmldoc.c index 90c4706abee..ac471e9e1a8 100644 --- a/dlls/mshtml/htmldoc.c +++ b/dlls/mshtml/htmldoc.c @@ -495,8 +495,8 @@ static HRESULT WINAPI HTMLDocument_get_all(IHTMLDocument2 *iface, IHTMLElementCo TRACE("(%p)->(%p)\n", This, p);
if(!This->dom_document) { - WARN("NULL dom_document\n"); - return E_UNEXPECTED; + *p = create_all_collection(&This->node, FALSE); + return S_OK; }
nsres = nsIDOMDocument_GetDocumentElement(This->dom_document, &nselem); diff --git a/dlls/mshtml/tests/dom.c b/dlls/mshtml/tests/dom.c index 91bc73fd2d0..a726801a43e 100644 --- a/dlls/mshtml/tests/dom.c +++ b/dlls/mshtml/tests/dom.c @@ -11069,8 +11069,8 @@ static void test_docfrag(IHTMLDocument2 *doc)
col = NULL; hres = IHTMLDocument2_get_all(frag, &col); - todo_wine ok(hres == S_OK, "get_all failed: %08lx\n", hres); - todo_wine ok(col != NULL, "got null elements collection\n"); + ok(hres == S_OK, "get_all failed: %08lx\n", hres); + ok(col != NULL, "got null elements collection\n"); if (col) { test_elem_collection((IUnknown *) col, frag_types, ARRAY_SIZE(frag_types)); IHTMLElementCollection_Release(col);
From: Santino Mazza smazza@codeweavers.com
--- dlls/mshtml/htmldoc.c | 47 +++++++++++++++++++++++++++++++++++++++++ dlls/mshtml/tests/dom.c | 2 +- 2 files changed, 48 insertions(+), 1 deletion(-)
diff --git a/dlls/mshtml/htmldoc.c b/dlls/mshtml/htmldoc.c index ac471e9e1a8..cc6c6ff4338 100644 --- a/dlls/mshtml/htmldoc.c +++ b/dlls/mshtml/htmldoc.c @@ -520,6 +520,51 @@ static HRESULT WINAPI HTMLDocument_get_all(IHTMLDocument2 *iface, IHTMLElementCo return hres; }
+static void get_next_node(nsIDOMNode **node) +{ + HRESULT hres; + nsIDOMNode *parent_node, *tmp_node = NULL; + + hres = nsIDOMNode_GetFirstChild(*node, &tmp_node); + if(hres != S_OK) return; + + while(!tmp_node && (nsIDOMNode_GetNextSibling(*node, &tmp_node) == S_OK) && !tmp_node) { + if((nsIDOMNode_GetParentNode(*node, &parent_node) != S_OK) || !parent_node) + break; + + nsIDOMNode_Release(*node); + *node = parent_node; + } + + nsIDOMNode_Release(*node); + *node = tmp_node; +} + +static HRESULT search_body_element_in_node(nsIDOMNode *node, nsIDOMHTMLElement **body) +{ + nsAString nsnode_name; + const PRUnichar *node_name; + + *body = NULL; + nsIDOMNode_AddRef(node); + + for(nsIDOMNode *current_node = node; current_node; get_next_node(¤t_node)) { + nsAString_Init(&nsnode_name, NULL); + nsIDOMNode_GetNodeName(current_node, &nsnode_name); + nsAString_GetData(&nsnode_name, &node_name); + nsAString_Finish(&nsnode_name); + + if(!wcscmp(node_name, L"BODY")) { + nsIDOMNode_QueryInterface(current_node, &IID_nsIDOMHTMLElement, (void **)body); + nsIDOMNode_Release(current_node); + } + + free((void*)node_name); + if(*body) break; + } + return S_OK; +} + static HRESULT WINAPI HTMLDocument_get_body(IHTMLDocument2 *iface, IHTMLElement **p) { HTMLDocumentNode *This = impl_from_IHTMLDocument2(iface); @@ -538,6 +583,8 @@ static HRESULT WINAPI HTMLDocument_get_body(IHTMLDocument2 *iface, IHTMLElement return E_UNEXPECTED; } } + else if(This->node.nsnode) + search_body_element_in_node(This->node.nsnode, &nsbody);
if(!nsbody) { *p = NULL; diff --git a/dlls/mshtml/tests/dom.c b/dlls/mshtml/tests/dom.c index a726801a43e..eea3dbe7126 100644 --- a/dlls/mshtml/tests/dom.c +++ b/dlls/mshtml/tests/dom.c @@ -11063,7 +11063,7 @@ static void test_docfrag(IHTMLDocument2 *doc)
hres = IHTMLDocument2_get_body(frag, &body); ok(hres == S_OK, "get_body failed: %08lx\n", hres); - todo_wine ok(body != NULL, "body == NULL\n"); + ok(body != NULL, "body == NULL\n"); if (body) IHTMLElement_Release(body);
Gabriel Ivăncescu (@insn) commented about dlls/mshtml/htmldoc.c:
nsAString_Init(&nsnode_name, NULL);
nsIDOMNode_GetNodeName(current_node, &nsnode_name);
nsAString_GetData(&nsnode_name, &node_name);
nsAString_Finish(&nsnode_name);
if(!wcscmp(node_name, L"BODY")) {
nsIDOMNode_QueryInterface(current_node, &IID_nsIDOMHTMLElement, (void **)body);
nsIDOMNode_Release(current_node);
}
free((void*)node_name);
if(*body) break;
- }
- return S_OK;
+}
Any reason you're not using `nsIDOMDocumentFragment_QuerySelector` here with `body` selector to look for the body?
On Fri Jan 6 14:55:56 2023 +0000, Gabriel Ivăncescu wrote:
Any reason you're not using `nsIDOMDocumentFragment_QuerySelector` here with `body` selector to look for the body?
Oh I thought I couldn't use that because I didn't have the nsIDOMDocumentFragment object, now I saw that I can just cast it and it works.