Module: wine Branch: master Commit: 02e0e122a56fa33d7738c059f34a3638bd6dc9fb URL: http://source.winehq.org/git/wine.git/?a=commit;h=02e0e122a56fa33d7738c059f3...
Author: Nikolay Sivov nsivov@codeweavers.com Date: Wed Dec 30 11:47:11 2015 +0300
msxml3: Fix cloneNode() for document nodes.
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/msxml3/domdoc.c | 31 +++++++++++++++++++++++++---- dlls/msxml3/tests/domdoc.c | 49 +++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 71 insertions(+), 9 deletions(-)
diff --git a/dlls/msxml3/domdoc.c b/dlls/msxml3/domdoc.c index e9f2504..3643219 100644 --- a/dlls/msxml3/domdoc.c +++ b/dlls/msxml3/domdoc.c @@ -1244,8 +1244,31 @@ static HRESULT WINAPI domdoc_cloneNode( IXMLDOMNode** outNode) { domdoc *This = impl_from_IXMLDOMDocument3( iface ); + xmlNodePtr clone; + TRACE("(%p)->(%d %p)\n", This, deep, outNode); - return node_clone( &This->node, deep, outNode ); + + if (!outNode) + return E_INVALIDARG; + + *outNode = NULL; + + clone = xmlCopyNode((xmlNodePtr)get_doc(This), deep ? 1 : 2); + if (!clone) + return E_FAIL; + + clone->doc->_private = create_priv(); + xmldoc_add_orphan(clone->doc, clone); + xmldoc_add_ref(clone->doc); + + priv_from_xmlDocPtr(clone->doc)->properties = copy_properties(This->properties); + if (!(*outNode = (IXMLDOMNode*)create_domdoc(clone))) + { + xmldoc_release(clone->doc); + return E_FAIL; + } + + return S_OK; }
@@ -3640,16 +3663,16 @@ HRESULT DOMDocument_create(MSXML_VERSION version, void **ppObj)
IUnknown* create_domdoc( xmlNodePtr document ) { - void* pObj = NULL; + IUnknown *obj = NULL; HRESULT hr;
TRACE("(%p)\n", document);
- hr = get_domdoc_from_xmldoc((xmlDocPtr)document, (IXMLDOMDocument3**)&pObj); + hr = get_domdoc_from_xmldoc((xmlDocPtr)document, (IXMLDOMDocument3**)&obj); if (FAILED(hr)) return NULL;
- return pObj; + return obj; }
#else diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c index 81b0256..788b39f 100644 --- a/dlls/msxml3/tests/domdoc.c +++ b/dlls/msxml3/tests/domdoc.c @@ -4821,7 +4821,8 @@ if (0)
static void test_cloneNode(void ) { - IXMLDOMDocument *doc, *doc2; + IXMLDOMDocument2 *doc, *doc_clone; + IXMLDOMDocument *doc2; VARIANT_BOOL b; IXMLDOMNodeList *pList; IXMLDOMNamedNodeMap *mapAttr; @@ -4830,14 +4831,52 @@ static void test_cloneNode(void ) IXMLDOMNode *node, *attr; IXMLDOMNode *node_clone; IXMLDOMNode *node_first; + VARIANT v; HRESULT hr;
- doc = create_document(&IID_IXMLDOMDocument); + doc = create_document(&IID_IXMLDOMDocument2);
- ole_check(IXMLDOMDocument_loadXML(doc, _bstr_(complete4A), &b)); + hr = IXMLDOMDocument2_loadXML(doc, _bstr_(complete4A), &b); + ok(hr == S_OK, "got 0x%08x\n", hr); ok(b == VARIANT_TRUE, "failed to load XML string\n");
- hr = IXMLDOMDocument_selectSingleNode(doc, _bstr_("lc/pr"), &node); + hr = IXMLDOMDocument2_getProperty(doc, _bstr_("SelectionLanguage"), &v); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(!lstrcmpW(V_BSTR(&v), _bstr_("XSLPattern")), "got prop value %s\n", wine_dbgstr_w(V_BSTR(&v))); + VariantClear(&v); + + V_BSTR(&v) = _bstr_("XPath"); + V_VT(&v) = VT_BSTR; + hr = IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionLanguage"), v); + ok(hr == S_OK, "got 0x%08x\n", hr); + VariantClear(&v); + + /* clone document node */ + hr = IXMLDOMDocument2_cloneNode(doc, VARIANT_TRUE, &node); + ok( hr == S_OK, "ret %08x\n", hr ); + ok( node != NULL, "node %p\n", node ); + + hr = IXMLDOMNode_get_childNodes(node, &pList); + ok( hr == S_OK, "ret %08x\n", hr ); + length = 0; + hr = IXMLDOMNodeList_get_length(pList, &length); + ok( hr == S_OK, "ret %08x\n", hr ); + ok(length == 2, "got %d\n", length); + IXMLDOMNodeList_Release(pList); + + hr = IXMLDOMNode_QueryInterface(node, &IID_IXMLDOMDocument2, (void**)&doc_clone); + ok(hr == S_OK, "got 0x%08x\n", hr); + + /* cloned document inherits properties */ + hr = IXMLDOMDocument2_getProperty(doc_clone, _bstr_("SelectionLanguage"), &v); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(!lstrcmpW(V_BSTR(&v), _bstr_("XPath")), "got prop value %s\n", wine_dbgstr_w(V_BSTR(&v))); + VariantClear(&v); + + IXMLDOMDocument2_Release(doc_clone); + IXMLDOMNode_Release(node); + + hr = IXMLDOMDocument2_selectSingleNode(doc, _bstr_("lc/pr"), &node); ok( hr == S_OK, "ret %08x\n", hr ); ok( node != NULL, "node %p\n", node );
@@ -4925,7 +4964,7 @@ static void test_cloneNode(void ) IXMLDOMNode_Release(node_clone);
IXMLDOMNode_Release(node); - IXMLDOMDocument_Release(doc); + IXMLDOMDocument2_Release(doc); free_bstrs(); }