>From 5bf7d25419d386019690fe0735340d6cffc85ca5 Mon Sep 17 00:00:00 2001
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
Date: Sat, 19 Feb 2011 15:58:30 +1100
Subject: [PATCH] Implement IHTMLDOMNode replaceChild
To: wine-patches <wine-patches@winehq.org>

---
 dlls/mshtml/htmlnode.c  |   31 +++++++++++++++++++++++++++++--
 dlls/mshtml/tests/dom.c |   36 ++++++++++++++++++++++++++++++++++++
 2 files changed, 65 insertions(+), 2 deletions(-)

diff --git a/dlls/mshtml/htmlnode.c b/dlls/mshtml/htmlnode.c
index dbb5888..dd57dbe 100644
--- a/dlls/mshtml/htmlnode.c
+++ b/dlls/mshtml/htmlnode.c
@@ -580,8 +580,35 @@ static HRESULT WINAPI HTMLDOMNode_replaceChild(IHTMLDOMNode *iface, IHTMLDOMNode
                                                IHTMLDOMNode *oldChild, IHTMLDOMNode **node)
 {
     HTMLDOMNode *This = impl_from_IHTMLDOMNode(iface);
-    FIXME("(%p)->(%p %p %p)\n", This, newChild, oldChild, node);
-    return E_NOTIMPL;
+    HTMLDOMNode *nodeNew;
+    HTMLDOMNode *nodeOld;
+    nsIDOMNode *nsnode;
+    nsresult nsres;
+    HRESULT hres;
+
+    TRACE("(%p)->(%p %p %p)\n", This, newChild, oldChild, node);
+
+    nodeNew = get_node_obj(This->doc, (IUnknown*)newChild);
+    if(!nodeNew)
+        return E_FAIL;
+
+    nodeOld = get_node_obj(This->doc, (IUnknown*)oldChild);
+    if(!nodeOld)
+        return E_FAIL;
+
+    nsres = nsIDOMNode_ReplaceChild(This->nsnode, nodeNew->nsnode, nodeOld->nsnode, &nsnode);
+    if(NS_FAILED(nsres)) {
+        nsnode = nodeNew->nsnode;
+    }
+
+    hres = get_node(This->doc, nsnode, TRUE, &nodeNew);
+    nsIDOMNode_Release(nsnode);
+    if(FAILED(hres))
+        return hres;
+
+    *node = &nodeNew->IHTMLDOMNode_iface;
+    IHTMLDOMNode_AddRef(*node);
+    return S_OK;
 }
 
 static HRESULT WINAPI HTMLDOMNode_cloneNode(IHTMLDOMNode *iface, VARIANT_BOOL fDeep,
diff --git a/dlls/mshtml/tests/dom.c b/dlls/mshtml/tests/dom.c
index 0ce3ead..6cc1733 100644
--- a/dlls/mshtml/tests/dom.c
+++ b/dlls/mshtml/tests/dom.c
@@ -5639,6 +5639,41 @@ static void test_create_elems(IHTMLDocument2 *doc)
     IHTMLElement_Release(body);
 }
 
+static void test_replacechild_elems(IHTMLDocument2 *doc)
+{
+    IHTMLElement *body;
+    IHTMLDOMNode *node, *node2, *node3;
+    IHTMLDOMNode *nodeBody, *nodeNew;
+    HRESULT hres;
+    VARIANT var;
+
+    body = doc_get_body(doc);
+
+    node = test_create_text(doc, "insert");
+
+    V_VT(&var) = VT_NULL;
+    V_DISPATCH(&var) = NULL;
+    node2 = test_node_insertbefore((IUnknown*)body, node, &var);
+    IHTMLDOMNode_Release(node);
+
+    test_elem_innertext(body, "insert");
+
+    node3 = test_create_text(doc, "replaced");
+
+    nodeBody = _get_node_iface(__LINE__, (IUnknown *)body);
+
+    hres = IHTMLDOMNode_replaceChild(nodeBody, node3, node2, &nodeNew);
+    ok(hres == S_OK, "Expected S_OK, got 0x%08x\n", hres);
+
+    test_elem_innertext(body, "replaced");
+
+    IHTMLDOMNode_Release(node2);
+    IHTMLDOMNode_Release(node3);
+    IHTMLDOMNode_Release(nodeBody);
+
+    IHTMLElement_Release(body);
+}
+
 static void test_null_write(IHTMLDocument2 *doc)
 {
     HRESULT hres;
@@ -6201,6 +6236,7 @@ START_TEST(dom)
     run_domtest(cond_comment_str, test_cond_comment);
     run_domtest(frameset_str, test_frameset);
     run_domtest(emptydiv_str, test_docfrag);
+    run_domtest(doc_blank, test_replacechild_elems);
 
     CoUninitialize();
 }
-- 
1.7.4.1

