Reviewed by Darin.
authorap <ap@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 30 Jan 2007 19:01:59 +0000 (19:01 +0000)
committerap <ap@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 30 Jan 2007 19:01:59 +0000 (19:01 +0000)
        http://bugs.webkit.org/show_bug.cgi?id=12452
        XPath id() function is not supported

WebCore:
        * xml/XPathFunctions.cpp:
        (WebCore::XPath::isWhitespace): A helper to detect XML whitespace.

        (WebCore::XPath::FunId::isConstant):
        (WebCore::XPath::FunId::doEvaluate):
        (WebCore::XPath::FunctionMapping::):
        Implemented id().

LayoutTests:
        * dom/svg/level3/xpath/Conformance_ID-expected.txt:
        This test now passes.

        * fast/xpath/complex-id-expected.txt: Added.
        * fast/xpath/complex-id.html: Added.
        A test for more advanced id() capabilities.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@19263 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/dom/svg/level3/xpath/Conformance_ID-expected.txt
LayoutTests/fast/xpath/complex-id-expected.txt [new file with mode: 0644]
LayoutTests/fast/xpath/complex-id.html [new file with mode: 0644]
WebCore/ChangeLog
WebCore/xml/XPathFunctions.cpp

index 546c36c2371e6c925f650ccad89d32aaf4533344..efaa31a13f86b104fb56f260f838f45a63bc2854 100644 (file)
@@ -1,3 +1,17 @@
+2007-01-30  Alexey Proskuryakov  <ap@webkit.org>
+
+        Reviewed by Darin.
+
+        http://bugs.webkit.org/show_bug.cgi?id=12452
+        XPath id() function is not supported
+
+        * dom/svg/level3/xpath/Conformance_ID-expected.txt:
+        This test now passes.
+
+        * fast/xpath/complex-id-expected.txt: Added.
+        * fast/xpath/complex-id.html: Added.
+        A test for more advanced id() capabilities.
+
 2007-01-31  Mark Rowe  <mrowe@apple.com>
 
         Disable editing/pasteboard/paste-{RTFD,TIFF}.html so tests run to completion until a fix is landed for:
index 0edf4b52fd49c563e5c8c15cdf942aeabb50912a..8acac5521bab7fbc4beea77543498e9a933bba1f 100644 (file)
@@ -1,2 +1 @@
-Conformance_ID
-Error: TYPE_ERR: DOM XPath Exception 52
+Conformance_ID: Success
diff --git a/LayoutTests/fast/xpath/complex-id-expected.txt b/LayoutTests/fast/xpath/complex-id-expected.txt
new file mode 100644 (file)
index 0000000..babb752
--- /dev/null
@@ -0,0 +1,3 @@
+Test for bug 12452: XPath id() function is not supported.
+
+SUCCESS
diff --git a/LayoutTests/fast/xpath/complex-id.html b/LayoutTests/fast/xpath/complex-id.html
new file mode 100644 (file)
index 0000000..683e804
--- /dev/null
@@ -0,0 +1,31 @@
+<body>
+<p>Test for <a href="http://bugs.webkit.org/show_bug.cgi?id=12452">bug 12452</a>:
+XPath id() function is not supported.</p>
+
+  <div id=test1 style="display:none">
+    a
+  </div>
+  <div id=test2 style="display:none">
+    b c
+    d
+  </div>
+
+  <div id="a"></div>
+  <div id="b"></div>
+  <div id="c"></div>
+  <div id="d"></div>
+
+<script>
+  if (window.layoutTestController)
+    layoutTestController.dumpAsText();
+
+  var UNORDERED_NODE_SNAPSHOT_TYPE = 6;
+
+  result = document.evaluate("id(id(' test1  test2 '))", document.body, null, UNORDERED_NODE_SNAPSHOT_TYPE, null);
+
+  if (4 == result.snapshotLength)
+    document.write("SUCCESS");
+  else
+    document.write("FAILURE: " + result.snapshotLength + " result nodes (should be 4)");
+</script>
+</body>
index 339379ba5d43849605fc15930bbc2512e5c4c30b..dd8ea8fa6c612a60d76788cfa1ddbda8cd19eb50 100644 (file)
@@ -1,3 +1,18 @@
+2007-01-30  Alexey Proskuryakov  <ap@webkit.org>
+
+        Reviewed by Darin.
+
+        http://bugs.webkit.org/show_bug.cgi?id=12452
+        XPath id() function is not supported
+
+        * xml/XPathFunctions.cpp:
+        (WebCore::XPath::isWhitespace): A helper to detect XML whitespace.
+
+        (WebCore::XPath::FunId::isConstant):
+        (WebCore::XPath::FunId::doEvaluate):
+        (WebCore::XPath::FunctionMapping::):
+        Implemented id().
+
 2007-01-30  Zack Rusin  <zrusin@trolltech.com>
 
         Reviewed by Sam.
index 3ba7fa4cacaa2031192ee110c34702daacb75473..82a5acb161c9d6a5df417f45a3a67d15699bc9a3 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * Copyright 2005 Frerich Raabe <raabe@kde.org>
  * Copyright (C) 2006 Apple Computer, Inc.
+ * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 
 #ifdef XPATH_SUPPORT
 
+#include "Document.h"
 #include "NamedAttrMap.h"
 #include "XPathValue.h"
 #include <wtf/MathExtras.h>
 
 namespace WebCore {
 namespace XPath {
-        
+
+static inline bool isWhitespace(UChar c)
+{
+    return c == ' ' || c == '\n' || c == '\r' || c == '\t';
+}
+
+
 #define DEFINE_FUNCTION_CREATOR(Class) static Function* create##Class() { return new Class; }
 
 class Interval {
@@ -76,6 +84,11 @@ class FunCount : public Function {
     virtual Value doEvaluate() const;
 };
 
+class FunId : public Function {
+    virtual bool isConstant() const;
+    virtual Value doEvaluate() const;
+};
+
 class FunLocalName : public Function {
     virtual bool isConstant() const;
     virtual Value doEvaluate() const;
@@ -177,6 +190,7 @@ class FunRound : public Function {
 DEFINE_FUNCTION_CREATOR(FunLast)
 DEFINE_FUNCTION_CREATOR(FunPosition)
 DEFINE_FUNCTION_CREATOR(FunCount)
+DEFINE_FUNCTION_CREATOR(FunId)
 DEFINE_FUNCTION_CREATOR(FunLocalName)
 DEFINE_FUNCTION_CREATOR(FunNamespaceURI)
 DEFINE_FUNCTION_CREATOR(FunName)
@@ -288,6 +302,59 @@ bool FunPosition::isConstant() const
     return false;
 }
 
+bool FunId::isConstant() const
+{
+    return false;
+}
+
+Value FunId::doEvaluate() const
+{
+    // FIXME: this algorithm does not produce an ordered node-set, as it should.
+
+    Value a = arg(0)->evaluate();
+    Vector<UChar> idList; // A whitespace-separated list of IDs
+
+    if (a.isNodeVector()) {
+        const NodeVector& nodes = a.toNodeVector();
+        for (size_t i = 0; i < nodes.size(); ++i) {
+            String str = stringValue(nodes[i].get());
+            idList.append(str.characters(), str.length());
+            idList.append(' ');
+        }
+    } else {
+        String str = a.toString();
+        idList.append(str.characters(), str.length());
+    }
+    
+    Document* contextDocument = evaluationContext().node->document();
+    NodeVector result;
+    HashSet<Node*> resultSet;
+
+    size_t startPos = 0;
+    size_t length = idList.size();
+    while (true) {
+        while (startPos < length && isWhitespace(idList[startPos]))
+            ++startPos;
+        
+        size_t endPos = startPos;
+        while (endPos < length && !isWhitespace(idList[endPos]))
+            ++endPos;
+
+        if (endPos == length)
+            break;
+
+        // If there are several nodes with the same id, id() should return the first one.
+        // In WebKit, getElementById behaves so, too, although its behavior in this case is formally undefined.
+        Node* node = contextDocument->getElementById(String(&idList[startPos], endPos - startPos));
+        if (node && resultSet.add(node).second)
+            result.append(node);
+        
+        startPos = endPos;
+    }
+    
+    return result;
+}
+
 bool FunLocalName::isConstant() const
 {
     return false;
@@ -615,6 +682,7 @@ static void createFunctionMap()
         { "count", { &createFunCount, 1 } },
         { "false", { &createFunFalse, 0 } },
         { "floor", { &createFunFloor, 1 } },
+        { "id", { &createFunId, 1 } },
         { "lang", { &createFunLang, 1 } },
         { "last", { &createFunLast, 0 } },
         { "local-name", { &createFunLocalName, Interval(0, 1) } },