Skip to content

Commit

Permalink
compareDocumentPosition() should report PRECEDING or FOLLOWING inform…
Browse files Browse the repository at this point in the history
…ation 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:


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@153660 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
ch.dumez@sisa.samsung.com committed Aug 2, 2013
1 parent 3a01a34 commit 072d959
Show file tree
Hide file tree
Showing 9 changed files with 169 additions and 22 deletions.
23 changes: 23 additions & 0 deletions LayoutTests/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,26 @@
2013-08-02 Christophe Dumez <ch.dumez@sisa.samsung.com>

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 <mitica@adobe.com>

Implement canvas blending test that should validate the following scenarios:
Expand Down
15 changes: 15 additions & 0 deletions LayoutTests/TestExpectations
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,21 @@ webkit.org/b/116473 editing/selection/user-drag-element-and-user-select-none.htm
# 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.
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -1,9 +1,58 @@
* 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
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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,36 @@
<head>
<script src="../js/resources/js-test-pre.js"></script>
<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="../js/resources/js-test-post.js"></script>
</head>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,14 @@ PASS a2.compareDocumentPosition(a3) is Node.DOCUMENT_POSITION_FOLLOWING
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
Expand Down
13 changes: 9 additions & 4 deletions LayoutTests/fast/dom/shadow/compare-document-position.html
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
19 changes: 19 additions & 0 deletions Source/WebCore/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,22 @@
2013-08-02 Christophe Dumez <ch.dumez@sisa.samsung.com>

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 <simon.fraser@apple.com>

Revert r153632, since it caused fast/forms/change-form-element-document-crash.html
Expand Down
22 changes: 16 additions & 6 deletions Source/WebCore/dom/Node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1621,6 +1621,18 @@ bool Node::offsetInCharacters() const
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.
Expand All @@ -1639,7 +1651,7 @@ unsigned short Node::compareDocumentPosition(Node* otherNode)
// 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;
Expand Down Expand Up @@ -1675,7 +1687,7 @@ unsigned short Node::compareDocumentPosition(Node* otherNode)
// 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;
Expand All @@ -1688,10 +1700,8 @@ unsigned short Node::compareDocumentPosition(Node* otherNode)
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) {
Expand Down

0 comments on commit 072d959

Please sign in to comment.