Module: wine Branch: master Commit: 49fa9de580814028e3224e9d9eb6472bf11092be URL: http://source.winehq.org/git/wine.git/?a=commit;h=49fa9de580814028e3224e9d9e...
Author: Adam Martinson amartinson@codeweavers.com Date: Thu Sep 30 09:49:10 2010 -0500
msxml3: Implement preserveWhiteSpace property.
---
dlls/msxml3/domdoc.c | 36 ++++++++++++- dlls/msxml3/tests/domdoc.c | 129 +++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 156 insertions(+), 9 deletions(-)
diff --git a/dlls/msxml3/domdoc.c b/dlls/msxml3/domdoc.c index ad1a858..1eed582 100644 --- a/dlls/msxml3/domdoc.c +++ b/dlls/msxml3/domdoc.c @@ -288,6 +288,38 @@ xmlNodePtr xmldoc_unlink_xmldecl(xmlDocPtr doc) return node; }
+static inline BOOL strn_isspace(xmlChar const* str, int len) +{ + for (; str && len > 0 && *str; ++str, --len) + if (!isspace(*str)) + break; + + return len == 0; +} + +static void sax_characters(void *ctx, const xmlChar *ch, int len) +{ + xmlParserCtxtPtr pctx; + domdoc const* This; + + pctx = (xmlParserCtxtPtr) ctx; + This = (domdoc const*) pctx->_private; + + if (!This->preserving) + { + xmlChar* ws = xmlGetNsProp(pctx->node, BAD_CAST "space", XML_XML_NAMESPACE); + if ((!ws || xmlStrcmp(ws, BAD_CAST "preserve") != 0) && + strn_isspace(ch, len)) + { + xmlFree(ws); + return; + } + xmlFree(ws); + } + + xmlSAX2Characters(ctx, ch, len); +} + static xmlDocPtr doparse(domdoc* This, char *ptr, int len) { xmlDocPtr doc; @@ -309,8 +341,8 @@ static xmlDocPtr doparse(domdoc* This, char *ptr, int len) xmlSAX2StartElement, /* startElement */ xmlSAX2EndElement, /* endElement */ xmlSAX2Reference, /* reference */ - xmlSAX2Characters, /* characters */ - NULL, /* TODO: ignorableWhitespace */ + sax_characters, /* characters */ + sax_characters, /* ignorableWhitespace */ xmlSAX2ProcessingInstruction, /* processingInstruction */ xmlSAX2Comment, /* comment */ NULL, /* TODO: warning */ diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c index 012b6aa..8d7399e 100644 --- a/dlls/msxml3/tests/domdoc.c +++ b/dlls/msxml3/tests/domdoc.c @@ -112,6 +112,9 @@ static const CHAR szExampleXML[] = " <html xmlns='http://www.w3.org/1999/xhtml'>\n" " This is <strong>a</strong> <i>description</i>. bar:x/\n" " </html>\n" +" <html xml:space='preserve' xmlns='http://www.w3.org/1999/xhtml'>\n" +" This is <strong>a</strong> <i>description</i> with preserved whitespace. bar:x/\n" +" </html>\n" " </description>\n" " </elem>\n" "\n" @@ -377,6 +380,9 @@ static void get_str_for_type(DOMNodeType type, char *buf) case NODE_DOCUMENT: strcpy(buf, "D"); break; + case NODE_TEXT: + strcpy(buf, "T"); + break; default: wsprintfA(buf, "[%d]", type); } @@ -3064,6 +3070,120 @@ static void test_IXMLDOMDocument2(void) free_bstrs(); }
+static inline void check_ws_ignored(IXMLDOMDocument2* doc) +{ + IXMLDOMNode *node1, *node2; + IXMLDOMNodeList *list; + + ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//*[local-name()='html']"), &list)); + ole_check(IXMLDOMNodeList_get_item(list, 0, &node1)); + ole_check(IXMLDOMNodeList_get_item(list, 1, &node2)); + ole_check(IXMLDOMNodeList_reset(list)); + expect_list_and_release(list, "E1.E4.E1.E2.D1 E2.E4.E1.E2.D1"); + + ole_check(IXMLDOMNode_get_childNodes(node1, &list)); + expect_list_and_release(list, "T1.E1.E4.E1.E2.D1 E2.E1.E4.E1.E2.D1 E3.E1.E4.E1.E2.D1 T4.E1.E4.E1.E2.D1 E5.E1.E4.E1.E2.D1"); + IXMLDOMNode_Release(node1); + ole_check(IXMLDOMNode_get_childNodes(node2, &list)); + expect_list_and_release(list, "T1.E2.E4.E1.E2.D1 E2.E2.E4.E1.E2.D1 T3.E2.E4.E1.E2.D1 E4.E2.E4.E1.E2.D1 T5.E2.E4.E1.E2.D1 E6.E2.E4.E1.E2.D1 T7.E2.E4.E1.E2.D1"); + IXMLDOMNode_Release(node2); +} + +static inline void check_ws_preserved(IXMLDOMDocument2* doc) +{ + IXMLDOMNode *node1, *node2; + IXMLDOMNodeList *list; + + ole_check(IXMLDOMDocument2_selectNodes(doc, _bstr_("//*[local-name()='html']"), &list)); + ole_check(IXMLDOMNodeList_get_item(list, 0, &node1)); + ole_check(IXMLDOMNodeList_get_item(list, 1, &node2)); + ole_check(IXMLDOMNodeList_reset(list)); + expect_list_and_release(list, "E2.E8.E2.E2.D1 E4.E8.E2.E2.D1"); + + ole_check(IXMLDOMNode_get_childNodes(node1, &list)); + expect_list_and_release(list, "T1.E2.E8.E2.E2.D1 E2.E2.E8.E2.E2.D1 T3.E2.E8.E2.E2.D1 E4.E2.E8.E2.E2.D1 T5.E2.E8.E2.E2.D1 E6.E2.E8.E2.E2.D1 T7.E2.E8.E2.E2.D1"); + IXMLDOMNode_Release(node1); + ole_check(IXMLDOMNode_get_childNodes(node2, &list)); + expect_list_and_release(list, "T1.E4.E8.E2.E2.D1 E2.E4.E8.E2.E2.D1 T3.E4.E8.E2.E2.D1 E4.E4.E8.E2.E2.D1 T5.E4.E8.E2.E2.D1 E6.E4.E8.E2.E2.D1 T7.E4.E8.E2.E2.D1"); + IXMLDOMNode_Release(node2); +} + +static void test_whitespace(void) +{ + VARIANT_BOOL b; + IXMLDOMDocument2 *doc1, *doc2, *doc3, *doc4; + + doc1 = create_document(&IID_IXMLDOMDocument2); + doc2 = create_document(&IID_IXMLDOMDocument2); + if (!doc1 || !doc2) return; + + ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc2, VARIANT_TRUE)); + ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc1, &b)); + ok(b == VARIANT_FALSE, "expected false\n"); + ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc2, &b)); + ok(b == VARIANT_TRUE, "expected true\n"); + + ole_check(IXMLDOMDocument2_loadXML(doc1, _bstr_(szExampleXML), &b)); + ok(b == VARIANT_TRUE, "failed to load XML string\n"); + ole_check(IXMLDOMDocument2_loadXML(doc2, _bstr_(szExampleXML), &b)); + ok(b == VARIANT_TRUE, "failed to load XML string\n"); + + /* switch to XPath */ + ole_check(IXMLDOMDocument2_setProperty(doc1, _bstr_("SelectionLanguage"), _variantbstr_("XPath"))); + ole_check(IXMLDOMDocument2_setProperty(doc2, _bstr_("SelectionLanguage"), _variantbstr_("XPath"))); + + check_ws_ignored(doc1); + check_ws_preserved(doc2); + + /* new instances copy the property */ + ole_check(IXMLDOMDocument2_QueryInterface(doc1, &IID_IXMLDOMDocument2, (void**) &doc3)); + ole_check(IXMLDOMDocument2_QueryInterface(doc2, &IID_IXMLDOMDocument2, (void**) &doc4)); + + ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc3, &b)); + ok(b == VARIANT_FALSE, "expected false\n"); + ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc4, &b)); + ok(b == VARIANT_TRUE, "expected true\n"); + + check_ws_ignored(doc3); + check_ws_preserved(doc4); + + /* setting after loading xml does nothing */ + ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc1, VARIANT_TRUE)); + ole_check(IXMLDOMDocument2_put_preserveWhiteSpace(doc2, VARIANT_FALSE)); + + check_ws_ignored(doc1); + check_ws_preserved(doc2); + + /* it takes effect on reload */ + ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc1, &b)); + ok(b == VARIANT_TRUE, "expected true\n"); + ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc2, &b)); + ok(b == VARIANT_FALSE, "expected false\n"); + + ole_check(IXMLDOMDocument2_loadXML(doc1, _bstr_(szExampleXML), &b)); + ok(b == VARIANT_TRUE, "failed to load XML string\n"); + ole_check(IXMLDOMDocument2_loadXML(doc2, _bstr_(szExampleXML), &b)); + ok(b == VARIANT_TRUE, "failed to load XML string\n"); + + check_ws_preserved(doc1); + check_ws_ignored(doc2); + + /* other instances follow suit */ + ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc3, &b)); + ok(b == VARIANT_TRUE, "expected true\n"); + ole_check(IXMLDOMDocument2_get_preserveWhiteSpace(doc4, &b)); + ok(b == VARIANT_FALSE, "expected false\n"); + + check_ws_preserved(doc3); + check_ws_ignored(doc4); + + IXMLDOMDocument_Release(doc1); + IXMLDOMDocument_Release(doc2); + IXMLDOMDocument_Release(doc3); + IXMLDOMDocument_Release(doc4); + free_bstrs(); +} + static void test_XPath(void) { VARIANT var; @@ -3159,13 +3279,7 @@ static void test_XPath(void) ole_check(IXMLDOMNode_selectNodes(elem1Node, _bstr_("//test:c"), &list)); expect_list_and_release(list, "E3.E3.E2.D1 E3.E4.E2.D1"); ole_check(IXMLDOMNode_selectNodes(elem1Node, _bstr_(".//test:x"), &list)); - { - char *str = list_to_string(list); - /* it's the correct node, just the wrong index due to whitespace-only nodes */ - todo_wine ok(strcmp(str, "E5.E1.E4.E1.E2.D1")==0, "Invalid node list: %s, expected %s\n", str, "E5.E1.E4.E1.E2.D1"); - if (list) - IXMLDOMNodeList_Release(list); - } + expect_list_and_release(list, "E5.E1.E4.E1.E2.D1 E6.E2.E4.E1.E2.D1");
/* SelectionNamespaces syntax error - the namespaces doesn't work anymore but the value is stored */ ole_expect(IXMLDOMDocument2_setProperty(doc, _bstr_("SelectionNamespaces"), @@ -6178,6 +6292,7 @@ START_TEST(domdoc) test_replaceChild(); test_removeNamedItem(); test_IXMLDOMDocument2(); + test_whitespace(); test_XPath(); test_XSLPattern(); test_cloneNode();