Adam Martinson : msxml3: Implement preserveWhiteSpace property.
Alexandre Julliard
julliard at winehq.org
Fri Oct 1 11:38:46 CDT 2010
Module: wine
Branch: master
Commit: 49fa9de580814028e3224e9d9eb6472bf11092be
URL: http://source.winehq.org/git/wine.git/?a=commit;h=49fa9de580814028e3224e9d9eb6472bf11092be
Author: Adam Martinson <amartinson at 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();
More information about the wine-cvs
mailing list