Title: [153660] trunk
Revision
153660
Author
[email protected]
Date
2013-08-02 11:52:52 -0700 (Fri, 02 Aug 2013)

Log Message

compareDocumentPosition() should report PRECEDING or FOLLOWING information even if nodes are disconnected
https://bugs.webkit.org/show_bug.cgi?id=119316

Reviewed by Ryosuke Niwa.

Source/WebCore:

As per the latest specification, compareDocumentPosition() should report PRECEDING or FOLLOWING
information even if nodes are disconnected:
- http://dom.spec.whatwg.org/#dom-node-comparedocumentposition

This behavior is consistent with both IE10, Firefox 22 and since recently Blink.

No new tests, covered by existing tests.

* dom/Node.cpp:
(WebCore::compareDetachedElementsPosition):
(WebCore::Node::compareDocumentPosition):

LayoutTests:

Update fast/dom/compare-document-position-disconnected-nodes.html to check that compareDocumentPosition()
now returns one of the following values for disconnected nodes:
- DOCUMENT_POSITION_DISCONNECTED | DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC | DOCUMENT_POSITION_PRECEDING
- DOCUMENT_POSITION_DISCONNECTED | DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC | DOCUMENT_POSITION_FOLLOWING

Several dom/xhtml/level3 are skipped and marked as WonfFix because they are outdated and no longer match
the DOM4 specification. They expect compareDocumentPosition() not to return PRECEDING / FOLLOWING
information for disconnected nodes.

* TestExpectations:
* dom/xhtml/level3/core/nodecomparedocumentposition38-expected.txt:
* fast/dom/compare-document-position-disconnected-nodes-expected.txt:
* fast/dom/compare-document-position-disconnected-nodes.html:
* fast/dom/shadow/compare-document-position-expected.txt:
* fast/dom/shadow/compare-document-position.html:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (153659 => 153660)


--- trunk/LayoutTests/ChangeLog	2013-08-02 18:45:21 UTC (rev 153659)
+++ trunk/LayoutTests/ChangeLog	2013-08-02 18:52:52 UTC (rev 153660)
@@ -1,3 +1,26 @@
+2013-08-02  Christophe Dumez  <[email protected]>
+
+        compareDocumentPosition() should report PRECEDING or FOLLOWING information even if nodes are disconnected
+        https://bugs.webkit.org/show_bug.cgi?id=119316
+
+        Reviewed by Ryosuke Niwa.
+
+        Update fast/dom/compare-document-position-disconnected-nodes.html to check that compareDocumentPosition()
+        now returns one of the following values for disconnected nodes:
+        - DOCUMENT_POSITION_DISCONNECTED | DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC | DOCUMENT_POSITION_PRECEDING
+        - DOCUMENT_POSITION_DISCONNECTED | DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC | DOCUMENT_POSITION_FOLLOWING
+
+        Several dom/xhtml/level3 are skipped and marked as WonfFix because they are outdated and no longer match
+        the DOM4 specification. They expect compareDocumentPosition() not to return PRECEDING / FOLLOWING
+        information for disconnected nodes.
+
+        * TestExpectations:
+        * dom/xhtml/level3/core/nodecomparedocumentposition38-expected.txt:
+        * fast/dom/compare-document-position-disconnected-nodes-expected.txt:
+        * fast/dom/compare-document-position-disconnected-nodes.html:
+        * fast/dom/shadow/compare-document-position-expected.txt:
+        * fast/dom/shadow/compare-document-position.html:
+
 2013-08-02  Mihai Tica  <[email protected]>
 
         Implement canvas blending test that should validate the following scenarios:

Modified: trunk/LayoutTests/TestExpectations (153659 => 153660)


--- trunk/LayoutTests/TestExpectations	2013-08-02 18:45:21 UTC (rev 153659)
+++ trunk/LayoutTests/TestExpectations	2013-08-02 18:52:52 UTC (rev 153660)
@@ -16,6 +16,21 @@
 # media/W3C/video/networkState/networkState_during_progress.html is flaky
 webkit.org/b/76280 media/W3C/video/networkState/networkState_during_progress.html [ Pass Failure ]
 
+# These conformace tests are no longer in sync with the latest specification
+# and expect compareDocumentPosition() to return:
+# DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC | DOCUMENT_POSITION_DISCONNECTED
+# for disconnected nodes (missing PRECEDING / FOLLOWING information).
+# We cannot check rebaseline them because their output is likely to change
+# between test runs as it decides PRECEDING / FOLLOWING using pointer
+# comparison.
+dom/xhtml/level3/core/nodecomparedocumentposition03.xhtml [ WontFix ]
+dom/xhtml/level3/core/nodecomparedocumentposition05.xhtml [ WontFix ]
+dom/xhtml/level3/core/nodecomparedocumentposition16.xhtml [ WontFix ]
+dom/xhtml/level3/core/nodecomparedocumentposition33.xhtml [ WontFix ]
+
+# Node::compareDocumentPosition() wrongly reports an attribute and its content as disconnected.
+webkit.org/b/119325 dom/xhtml/level3/core/nodecomparedocumentposition38.xhtml [ Failure ]
+
 # The CSS Shapes spec has changed the positioning model for floats with shape-outside.
 # Thus all of the tests need to be rewitten to work as the implementation of
 # the new model is completed.

Modified: trunk/LayoutTests/dom/xhtml/level3/core/nodecomparedocumentposition38-expected.txt (153659 => 153660)


--- trunk/LayoutTests/dom/xhtml/level3/core/nodecomparedocumentposition38-expected.txt	2013-08-02 18:45:21 UTC (rev 153659)
+++ trunk/LayoutTests/dom/xhtml/level3/core/nodecomparedocumentposition38-expected.txt	2013-08-02 18:52:52 UTC (rev 153660)
@@ -1,3 +1,2 @@
 Test	http://www.w3.org/2001/DOM-Test-Suite/level3/core/nodecomparedocumentposition38
-Status	failure
-Message	nodecomparedocumentpositionIsContainsFollowing38: assertEquals failed, actual 33, expected 20.
+Status	Success

Modified: trunk/LayoutTests/fast/dom/compare-document-position-disconnected-nodes-expected.txt (153659 => 153660)


--- trunk/LayoutTests/fast/dom/compare-document-position-disconnected-nodes-expected.txt	2013-08-02 18:45:21 UTC (rev 153659)
+++ trunk/LayoutTests/fast/dom/compare-document-position-disconnected-nodes-expected.txt	2013-08-02 18:52:52 UTC (rev 153660)
@@ -1,3 +1,4 @@
+* Test with 2 disconnected elements
 PASS a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_DISCONNECTED is Node.DOCUMENT_POSITION_DISCONNECTED
 PASS b.compareDocumentPosition(a) & Node.DOCUMENT_POSITION_DISCONNECTED is Node.DOCUMENT_POSITION_DISCONNECTED
 PASS a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC is Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC
@@ -4,6 +5,54 @@
 PASS b.compareDocumentPosition(a) & Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC is Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC
 PASS a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_PRECEDING is not b.compareDocumentPosition(a) & Node.DOCUMENT_POSITION_PRECEDING
 PASS a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_FOLLOWING is not b.compareDocumentPosition(a) & Node.DOCUMENT_POSITION_FOLLOWING
+PASS a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_PRECEDING || a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_FOLLOWING is non-zero.
+PASS b.compareDocumentPosition(a) & Node.DOCUMENT_POSITION_PRECEDING || b.compareDocumentPosition(a) & Node.DOCUMENT_POSITION_FOLLOWING is non-zero.
+PASS a.compareDocumentPosition(b) is a.compareDocumentPosition(b)
+PASS b.compareDocumentPosition(a) is b.compareDocumentPosition(a)
+* Test with document and a disconnected element
+PASS a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_DISCONNECTED is Node.DOCUMENT_POSITION_DISCONNECTED
+PASS b.compareDocumentPosition(a) & Node.DOCUMENT_POSITION_DISCONNECTED is Node.DOCUMENT_POSITION_DISCONNECTED
+PASS a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC is Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC
+PASS b.compareDocumentPosition(a) & Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC is Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC
+PASS a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_PRECEDING is not b.compareDocumentPosition(a) & Node.DOCUMENT_POSITION_PRECEDING
+PASS a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_FOLLOWING is not b.compareDocumentPosition(a) & Node.DOCUMENT_POSITION_FOLLOWING
+PASS a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_PRECEDING || a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_FOLLOWING is non-zero.
+PASS b.compareDocumentPosition(a) & Node.DOCUMENT_POSITION_PRECEDING || b.compareDocumentPosition(a) & Node.DOCUMENT_POSITION_FOLLOWING is non-zero.
+PASS a.compareDocumentPosition(b) is a.compareDocumentPosition(b)
+PASS b.compareDocumentPosition(a) is b.compareDocumentPosition(a)
+* Test with document and a disconnected attribute
+PASS a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_DISCONNECTED is Node.DOCUMENT_POSITION_DISCONNECTED
+PASS b.compareDocumentPosition(a) & Node.DOCUMENT_POSITION_DISCONNECTED is Node.DOCUMENT_POSITION_DISCONNECTED
+PASS a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC is Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC
+PASS b.compareDocumentPosition(a) & Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC is Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC
+PASS a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_PRECEDING is not b.compareDocumentPosition(a) & Node.DOCUMENT_POSITION_PRECEDING
+PASS a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_FOLLOWING is not b.compareDocumentPosition(a) & Node.DOCUMENT_POSITION_FOLLOWING
+PASS a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_PRECEDING || a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_FOLLOWING is non-zero.
+PASS b.compareDocumentPosition(a) & Node.DOCUMENT_POSITION_PRECEDING || b.compareDocumentPosition(a) & Node.DOCUMENT_POSITION_FOLLOWING is non-zero.
+PASS a.compareDocumentPosition(b) is a.compareDocumentPosition(b)
+PASS b.compareDocumentPosition(a) is b.compareDocumentPosition(a)
+* Test with 2 disconnected attributes
+PASS a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_DISCONNECTED is Node.DOCUMENT_POSITION_DISCONNECTED
+PASS b.compareDocumentPosition(a) & Node.DOCUMENT_POSITION_DISCONNECTED is Node.DOCUMENT_POSITION_DISCONNECTED
+PASS a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC is Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC
+PASS b.compareDocumentPosition(a) & Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC is Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC
+PASS a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_PRECEDING is not b.compareDocumentPosition(a) & Node.DOCUMENT_POSITION_PRECEDING
+PASS a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_FOLLOWING is not b.compareDocumentPosition(a) & Node.DOCUMENT_POSITION_FOLLOWING
+PASS a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_PRECEDING || a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_FOLLOWING is non-zero.
+PASS b.compareDocumentPosition(a) & Node.DOCUMENT_POSITION_PRECEDING || b.compareDocumentPosition(a) & Node.DOCUMENT_POSITION_FOLLOWING is non-zero.
+PASS a.compareDocumentPosition(b) is a.compareDocumentPosition(b)
+PASS b.compareDocumentPosition(a) is b.compareDocumentPosition(a)
+* Test with disconnected attribute and element
+PASS a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_DISCONNECTED is Node.DOCUMENT_POSITION_DISCONNECTED
+PASS b.compareDocumentPosition(a) & Node.DOCUMENT_POSITION_DISCONNECTED is Node.DOCUMENT_POSITION_DISCONNECTED
+PASS a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC is Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC
+PASS b.compareDocumentPosition(a) & Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC is Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC
+PASS a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_PRECEDING is not b.compareDocumentPosition(a) & Node.DOCUMENT_POSITION_PRECEDING
+PASS a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_FOLLOWING is not b.compareDocumentPosition(a) & Node.DOCUMENT_POSITION_FOLLOWING
+PASS a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_PRECEDING || a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_FOLLOWING is non-zero.
+PASS b.compareDocumentPosition(a) & Node.DOCUMENT_POSITION_PRECEDING || b.compareDocumentPosition(a) & Node.DOCUMENT_POSITION_FOLLOWING is non-zero.
+PASS a.compareDocumentPosition(b) is a.compareDocumentPosition(b)
+PASS b.compareDocumentPosition(a) is b.compareDocumentPosition(a)
 PASS successfullyParsed is true
 
 TEST COMPLETE

Modified: trunk/LayoutTests/fast/dom/compare-document-position-disconnected-nodes.html (153659 => 153660)


--- trunk/LayoutTests/fast/dom/compare-document-position-disconnected-nodes.html	2013-08-02 18:45:21 UTC (rev 153659)
+++ trunk/LayoutTests/fast/dom/compare-document-position-disconnected-nodes.html	2013-08-02 18:52:52 UTC (rev 153660)
@@ -3,15 +3,36 @@
 <head>
     <script src=""
     <script>
-        window.a = document.createElement('a');
-        window.b = document.createElement('b');
+        var a;
+        var b;
 
-        shouldBe('a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_DISCONNECTED', 'Node.DOCUMENT_POSITION_DISCONNECTED');
-        shouldBe('b.compareDocumentPosition(a) & Node.DOCUMENT_POSITION_DISCONNECTED', 'Node.DOCUMENT_POSITION_DISCONNECTED');
-        shouldBe('a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC', 'Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC');
-        shouldBe('b.compareDocumentPosition(a) & Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC', 'Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC');
-        shouldNotBe('a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_PRECEDING', 'b.compareDocumentPosition(a) & Node.DOCUMENT_POSITION_PRECEDING');
-        shouldNotBe('a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_FOLLOWING', 'b.compareDocumentPosition(a) & Node.DOCUMENT_POSITION_FOLLOWING');
+        function testElements(_a, _b) {
+            a = _a;
+            b = _b;
+
+            shouldBe('a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_DISCONNECTED', 'Node.DOCUMENT_POSITION_DISCONNECTED');
+            shouldBe('b.compareDocumentPosition(a) & Node.DOCUMENT_POSITION_DISCONNECTED', 'Node.DOCUMENT_POSITION_DISCONNECTED');
+            shouldBe('a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC', 'Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC');
+            shouldBe('b.compareDocumentPosition(a) & Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC', 'Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC');
+            shouldNotBe('a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_PRECEDING', 'b.compareDocumentPosition(a) & Node.DOCUMENT_POSITION_PRECEDING');
+            shouldNotBe('a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_FOLLOWING', 'b.compareDocumentPosition(a) & Node.DOCUMENT_POSITION_FOLLOWING');
+            shouldBeNonZero('a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_PRECEDING || a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_FOLLOWING');
+            shouldBeNonZero('b.compareDocumentPosition(a) & Node.DOCUMENT_POSITION_PRECEDING || b.compareDocumentPosition(a) & Node.DOCUMENT_POSITION_FOLLOWING');
+            // Make sure the returned result is consistent.
+            shouldBe('a.compareDocumentPosition(b)', 'a.compareDocumentPosition(b)');
+            shouldBe('b.compareDocumentPosition(a)', 'b.compareDocumentPosition(a)');
+        }
+
+        debug("* Test with 2 disconnected elements");
+        testElements(document.createElement('a'), document.createElement('b'));
+        debug("* Test with document and a disconnected element");
+        testElements(document, document.createElement('b'));
+        debug("* Test with document and a disconnected attribute");
+        testElements(document, document.createAttribute('b'));
+        debug("* Test with 2 disconnected attributes");
+        testElements(document.createAttribute("a"), document.createAttribute("b"));
+        debug("* Test with disconnected attribute and element");
+        testElements(document.createAttribute("a"), document.createElement("b"));
     </script>
     <script src=""
 </head>

Modified: trunk/LayoutTests/fast/dom/shadow/compare-document-position-expected.txt (153659 => 153660)


--- trunk/LayoutTests/fast/dom/shadow/compare-document-position-expected.txt	2013-08-02 18:45:21 UTC (rev 153659)
+++ trunk/LayoutTests/fast/dom/shadow/compare-document-position-expected.txt	2013-08-02 18:52:52 UTC (rev 153660)
@@ -9,8 +9,14 @@
 PASS b1.compareDocumentPosition(b2) is Node.DOCUMENT_POSITION_CONTAINED_BY | Node.DOCUMENT_POSITION_FOLLOWING
 PASS b2.compareDocumentPosition(b1) is Node.DOCUMENT_POSITION_CONTAINS | Node.DOCUMENT_POSITION_PRECEDING
 PASS b2.compareDocumentPosition(b3) is Node.DOCUMENT_POSITION_FOLLOWING
-PASS a1.compareDocumentPosition(b1) is Node.DOCUMENT_POSITION_DISCONNECTED | Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC
-PASS b1.compareDocumentPosition(c1) is Node.DOCUMENT_POSITION_DISCONNECTED | Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC
+PASS a1.compareDocumentPosition(b1) & Node.DOCUMENT_POSITION_PRECEDING || a1.compareDocumentPosition(b1) & Node.DOCUMENT_POSITION_FOLLOWING is non-zero.
+PASS a1.compareDocumentPosition(b1) & Node.DOCUMENT_POSITION_DISCONNECTED is Node.DOCUMENT_POSITION_DISCONNECTED
+PASS a1.compareDocumentPosition(b1) & Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC is Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC
+PASS a1.compareDocumentPosition(b1) is a1.compareDocumentPosition(b1)
+PASS b1.compareDocumentPosition(c1) & Node.DOCUMENT_POSITION_PRECEDING || b1.compareDocumentPosition(c1) & Node.DOCUMENT_POSITION_FOLLOWING is non-zero.
+PASS b1.compareDocumentPosition(c1) & Node.DOCUMENT_POSITION_DISCONNECTED is Node.DOCUMENT_POSITION_DISCONNECTED
+PASS b1.compareDocumentPosition(c1) & Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC is Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC
+PASS b1.compareDocumentPosition(c1) is b1.compareDocumentPosition(c1)
 PASS successfullyParsed is true
 
 TEST COMPLETE

Modified: trunk/LayoutTests/fast/dom/shadow/compare-document-position.html (153659 => 153660)


--- trunk/LayoutTests/fast/dom/shadow/compare-document-position.html	2013-08-02 18:45:21 UTC (rev 153659)
+++ trunk/LayoutTests/fast/dom/shadow/compare-document-position.html	2013-08-02 18:52:52 UTC (rev 153660)
@@ -45,10 +45,15 @@
     shouldBe('b2.compareDocumentPosition(b1)', 'Node.DOCUMENT_POSITION_CONTAINS | Node.DOCUMENT_POSITION_PRECEDING');
     shouldBe('b2.compareDocumentPosition(b3)', 'Node.DOCUMENT_POSITION_FOLLOWING');
 
-    // The current implementation does not return FOLLOWING OR PRECEDING flag.
-    // We need a stable implementation which decides the total order between nodes in different shadow trees.
-    shouldBe('a1.compareDocumentPosition(b1)', 'Node.DOCUMENT_POSITION_DISCONNECTED | Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC');
-    shouldBe('b1.compareDocumentPosition(c1)', 'Node.DOCUMENT_POSITION_DISCONNECTED | Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC');
+    // Nodes in different shadow trees.
+    shouldBeNonZero('a1.compareDocumentPosition(b1) & Node.DOCUMENT_POSITION_PRECEDING || a1.compareDocumentPosition(b1) & Node.DOCUMENT_POSITION_FOLLOWING');
+    shouldBe('a1.compareDocumentPosition(b1) & Node.DOCUMENT_POSITION_DISCONNECTED', 'Node.DOCUMENT_POSITION_DISCONNECTED');
+    shouldBe('a1.compareDocumentPosition(b1) & Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC', 'Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC');
+    shouldBe('a1.compareDocumentPosition(b1)', 'a1.compareDocumentPosition(b1)');
+    shouldBeNonZero('b1.compareDocumentPosition(c1) & Node.DOCUMENT_POSITION_PRECEDING || b1.compareDocumentPosition(c1) & Node.DOCUMENT_POSITION_FOLLOWING');
+    shouldBe('b1.compareDocumentPosition(c1) & Node.DOCUMENT_POSITION_DISCONNECTED', 'Node.DOCUMENT_POSITION_DISCONNECTED');
+    shouldBe('b1.compareDocumentPosition(c1) & Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC', 'Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC');
+    shouldBe('b1.compareDocumentPosition(c1)', 'b1.compareDocumentPosition(c1)');
 }
 
 testCompareDocumentPosition();

Modified: trunk/Source/WebCore/ChangeLog (153659 => 153660)


--- trunk/Source/WebCore/ChangeLog	2013-08-02 18:45:21 UTC (rev 153659)
+++ trunk/Source/WebCore/ChangeLog	2013-08-02 18:52:52 UTC (rev 153660)
@@ -1,3 +1,22 @@
+2013-08-02  Christophe Dumez  <[email protected]>
+
+        compareDocumentPosition() should report PRECEDING or FOLLOWING information even if nodes are disconnected
+        https://bugs.webkit.org/show_bug.cgi?id=119316
+
+        Reviewed by Ryosuke Niwa.
+
+        As per the latest specification, compareDocumentPosition() should report PRECEDING or FOLLOWING
+        information even if nodes are disconnected:
+        - http://dom.spec.whatwg.org/#dom-node-comparedocumentposition
+
+        This behavior is consistent with both IE10, Firefox 22 and since recently Blink.
+
+        No new tests, covered by existing tests.
+
+        * dom/Node.cpp:
+        (WebCore::compareDetachedElementsPosition):
+        (WebCore::Node::compareDocumentPosition):
+
 2013-08-02  Simon Fraser  <[email protected]>
 
         Revert r153632, since it caused fast/forms/change-form-element-document-crash.html

Modified: trunk/Source/WebCore/dom/Node.cpp (153659 => 153660)


--- trunk/Source/WebCore/dom/Node.cpp	2013-08-02 18:45:21 UTC (rev 153659)
+++ trunk/Source/WebCore/dom/Node.cpp	2013-08-02 18:52:52 UTC (rev 153660)
@@ -1621,6 +1621,18 @@
     return false;
 }
 
+static inline unsigned short compareDetachedElementsPosition(Node* firstNode, Node* secondNode)
+{
+    // If the 2 nodes are not in the same tree, return the result of adding DOCUMENT_POSITION_DISCONNECTED,
+    // DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC, and either DOCUMENT_POSITION_PRECEDING or
+    // DOCUMENT_POSITION_FOLLOWING, with the constraint that this is to be consistent. Whether to return
+    // DOCUMENT_POSITION_PRECEDING or DOCUMENT_POSITION_FOLLOWING is implemented here via pointer
+    // comparison.
+    // See step 3 in http://www.w3.org/TR/2012/WD-dom-20121206/#dom-node-comparedocumentposition
+    unsigned short direction = (firstNode > secondNode) ? Node::DOCUMENT_POSITION_PRECEDING : Node::DOCUMENT_POSITION_FOLLOWING;
+    return Node::DOCUMENT_POSITION_DISCONNECTED | Node::DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC | direction;
+}
+
 unsigned short Node::compareDocumentPosition(Node* otherNode)
 {
     // It is not clear what should be done if |otherNode| is 0.
@@ -1639,7 +1651,7 @@
     // If either of start1 or start2 is null, then we are disconnected, since one of the nodes is
     // an orphaned attribute node.
     if (!start1 || !start2)
-        return DOCUMENT_POSITION_DISCONNECTED | DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC;
+        return compareDetachedElementsPosition(this, otherNode);
 
     Vector<Node*, 16> chain1;
     Vector<Node*, 16> chain2;
@@ -1675,7 +1687,7 @@
     // comparing Attr nodes here, since they return false from inDocument() all the time (which seems like a bug).
     if (start1->inDocument() != start2->inDocument() ||
         start1->treeScope() != start2->treeScope())
-        return DOCUMENT_POSITION_DISCONNECTED | DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC;
+        return compareDetachedElementsPosition(this, otherNode);
 
     // We need to find a common ancestor container, and then compare the indices of the two immediate children.
     Node* current;
@@ -1688,10 +1700,8 @@
     unsigned index2 = chain2.size();
 
     // If the two elements don't have a common root, they're not in the same tree.
-    if (chain1[index1 - 1] != chain2[index2 - 1]) {
-        unsigned short direction = (start1 > start2) ? DOCUMENT_POSITION_PRECEDING : DOCUMENT_POSITION_FOLLOWING;
-        return DOCUMENT_POSITION_DISCONNECTED | DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC | direction;
-    }
+    if (chain1[index1 - 1] != chain2[index2 - 1])
+        return compareDetachedElementsPosition(this, otherNode);
 
     // Walk the two chains backwards and look for the first difference.
     for (unsigned i = min(index1, index2); i; --i) {
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to