From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmldoc.c | 37 ++++++++++++++++++++++++++++++++++-- dlls/mshtml/htmlnode.c | 5 +++++ dlls/mshtml/mshtml_private.h | 2 ++ dlls/mshtml/tests/dom.js | 27 ++++++++++++++++++++++++++ 4 files changed, 69 insertions(+), 2 deletions(-)
diff --git a/dlls/mshtml/htmldoc.c b/dlls/mshtml/htmldoc.c index dd7d9f44d48..0988d34f85b 100644 --- a/dlls/mshtml/htmldoc.c +++ b/dlls/mshtml/htmldoc.c @@ -4375,8 +4375,41 @@ static HRESULT WINAPI HTMLDocument7_importNode(IHTMLDocument7 *iface, IHTMLDOMNo VARIANT_BOOL fDeep, IHTMLDOMNode3 **ppNodeDest) { HTMLDocumentNode *This = impl_from_IHTMLDocument7(iface); - FIXME("(%p)->(%p %x %p)\n", This, pNodeSource, fDeep, ppNodeDest); - return E_NOTIMPL; + nsIDOMNode *nsnode = NULL; + HTMLDOMNode *node; + nsresult nsres; + HRESULT hres; + + TRACE("(%p)->(%p %x %p)\n", This, pNodeSource, fDeep, ppNodeDest); + + if(!This->nsdoc) { + WARN("NULL nsdoc\n"); + return E_UNEXPECTED; + } + + if(!(node = unsafe_impl_from_IHTMLDOMNode(pNodeSource))) { + ERR("not our node\n"); + return E_FAIL; + } + + nsres = nsIDOMHTMLDocument_ImportNode(This->nsdoc, node->nsnode, !!fDeep, 1, &nsnode); + if(NS_FAILED(nsres)) { + ERR("ImportNode failed: %08lx\n", nsres); + return map_nsresult(nsres); + } + + if(!nsnode) { + *ppNodeDest = NULL; + return S_OK; + } + + hres = get_node(nsnode, TRUE, &node); + nsIDOMNode_Release(nsnode); + if(FAILED(hres)) + return hres; + + *ppNodeDest = &node->IHTMLDOMNode3_iface; + return hres; }
static HRESULT WINAPI HTMLDocument7_get_parentWindow(IHTMLDocument7 *iface, IHTMLWindow2 **p) diff --git a/dlls/mshtml/htmlnode.c b/dlls/mshtml/htmlnode.c index 42ac37a7736..a293b332a9f 100644 --- a/dlls/mshtml/htmlnode.c +++ b/dlls/mshtml/htmlnode.c @@ -1067,6 +1067,11 @@ static const IHTMLDOMNodeVtbl HTMLDOMNodeVtbl = { HTMLDOMNode_get_nextSibling };
+HTMLDOMNode *unsafe_impl_from_IHTMLDOMNode(IHTMLDOMNode *iface) +{ + return iface->lpVtbl == &HTMLDOMNodeVtbl ? impl_from_IHTMLDOMNode(iface) : NULL; +} + static HTMLDOMNode *get_node_obj(IHTMLDOMNode *iface) { HTMLDOMNode *ret; diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index c403b4efc54..23eeb0ec11b 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -807,6 +807,8 @@ struct HTMLDOMNode { HTMLDocumentNode *doc; };
+HTMLDOMNode *unsafe_impl_from_IHTMLDOMNode(IHTMLDOMNode*) DECLSPEC_HIDDEN; + static inline void node_addref(HTMLDOMNode *node) { IHTMLDOMNode_AddRef(&node->IHTMLDOMNode_iface); diff --git a/dlls/mshtml/tests/dom.js b/dlls/mshtml/tests/dom.js index 43c52d89757..5a31b869c8f 100644 --- a/dlls/mshtml/tests/dom.js +++ b/dlls/mshtml/tests/dom.js @@ -722,3 +722,30 @@ sync_test("classList", function() { ok(("" + classList) === " testclass foobar ", "Expected classList value ' testclass foobar ', got " + classList); ok(classList.toString() === " testclass foobar ", "Expected classList toString ' testclass foobar ', got " + classList.toString()); }); + +sync_test("importNode", function() { + var node, node2, orig_node, doc = document.implementation.createHTMLDocument("TestDoc"); + doc.body.innerHTML = '<div id="test"><span/></div>'; + orig_node = doc.getElementById("test"); + + node = document.importNode(orig_node, false); + ok(node !== orig_node, "node = orig_node"); + ok(orig_node.hasChildNodes() === true, "orig_node does not have child nodes"); + ok(orig_node.parentNode === doc.body, "orig_node.parentNode = " + orig_node.parentNode); + ok(node.hasChildNodes() === false, "node has child nodes with shallow import"); + ok(node.parentNode === null, "node.parentNode = " + node.parentNode); + + node = document.importNode(orig_node, true); + ok(node !== orig_node, "node = orig_node"); + ok(orig_node.hasChildNodes() === true, "orig_node does not have child nodes"); + ok(orig_node.parentNode === doc.body, "orig_node.parentNode = " + orig_node.parentNode); + ok(node.hasChildNodes() === true, "node does not have child nodes with deep import"); + ok(node.parentNode === null, "node.parentNode = " + node.parentNode); + + node2 = document.importNode(node, false); + ok(node !== node2, "node = node2"); + ok(node.hasChildNodes() === true, "node does not have child nodes"); + ok(node.parentNode === null, "node.parentNode = " + node.parentNode); + ok(node2.hasChildNodes() === false, "node2 has child nodes"); + ok(node2.parentNode === null, "node2.parentNode = " + node2.parentNode); +});