Title: [269010] branches/safari-611.1.4-branch
Revision
269010
Author
[email protected]
Date
2020-10-26 18:13:07 -0700 (Mon, 26 Oct 2020)

Log Message

Cherry-pick r268800. rdar://problem/70702272

    REGRESSION(r266295): Range allows start and end containers to belong to different trees
    https://bugs.webkit.org/show_bug.cgi?id=217895

    Reviewed by Ryosuke Niwa.

    Source/WebCore:

    Test: fast/dom/Range/ranges-across-trees.html

    * dom/BoundaryPoint.h: Added treeOrder<TreeType>.

    * dom/Node.cpp:
    (WebCore::parent<Tree>): Added.
    (WebCore::parent<ComposedTree>): Added.
    (WebCore::depth): Changed into a template that takes TreeType.
    (WebCore::commonInclusiveAncestorAndChildren): Ditto.
    (WebCore::commonInclusiveAncestor): Changed to explicitly use ComposedTree to preserve
    the current behavior, but likely will return later to make this a template and have it
    us the normal tree by default.
    (WebCore::treeOrder): Changed into a template that takes TreeType.
    (WebCore::documentOrder): Call treeOrder<ComposedTree> to preserve the current behavior.
    Likely will delete this later after changing callers to use treeOrder.

    * dom/Node.h: Added Tree, ShadowIncludingTree, and ComposedTree. Added parent and
    treeOrder function templates. TreeType currently is a set of classes but they could
    also be objects of another type. Maybe an enumeration named TreeType instead?

    * dom/Range.cpp:
    (WebCore::Range::setStart): Use treeOrder instead of documentOrder to use the normal
    tree instead of the composed tree.
    (WebCore::Range::setEnd): Ditto.
    (WebCore::Range::isPointInRange): Use isPointInRange<Tree> instead of isPointInRange
    to use the normal tree instead of the composed tree.
    (WebCore::Range::comparePoint const): Use treeOrder instead of documentOrder to use
    the normal tree instead of the composed tree.
    (WebCore::Range::compareNode const): Ditto.
    (WebCore::Range::compareBoundaryPoints const): Ditto.
    (WebCore::Range::intersectsNode const): Use intersects<Tree> instead of isPointInRange
    to use the normal tree instead of the composed tree.

    * dom/SimpleRange.cpp:
    (WebCore::treeOrder): Changed into a template that takes TreeType.
    (WebCore::documentOrder): Call treeOrder<ComposedTree> to preserve the current behavior.
    Likely will delete this later after changing callers to use treeOrder.
    (WebCore::isPointInRange): Changed into a template that takes TreeType.
    For now the default tree type is still ComposedTree, but will change that later.
    (WebCore::intersects): Ditto.
    (WebCore::contains<Tree>): Added.
    (WebCore::contains<ComposedTree>): Added.

    * dom/SimpleRange.h: Added isPointInRange, intersects, and treeOrder function templates.

    LayoutTests:

    * fast/dom/Range/ranges-across-trees.html: Added.

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

Modified Paths

Added Paths

Diff

Modified: branches/safari-611.1.4-branch/LayoutTests/ChangeLog (269009 => 269010)


--- branches/safari-611.1.4-branch/LayoutTests/ChangeLog	2020-10-27 01:13:03 UTC (rev 269009)
+++ branches/safari-611.1.4-branch/LayoutTests/ChangeLog	2020-10-27 01:13:07 UTC (rev 269010)
@@ -1,5 +1,76 @@
 2020-10-26  Alan Coon  <[email protected]>
 
+        Cherry-pick r268800. rdar://problem/70702272
+
+    REGRESSION(r266295): Range allows start and end containers to belong to different trees
+    https://bugs.webkit.org/show_bug.cgi?id=217895
+    
+    Reviewed by Ryosuke Niwa.
+    
+    Source/WebCore:
+    
+    Test: fast/dom/Range/ranges-across-trees.html
+    
+    * dom/BoundaryPoint.h: Added treeOrder<TreeType>.
+    
+    * dom/Node.cpp:
+    (WebCore::parent<Tree>): Added.
+    (WebCore::parent<ComposedTree>): Added.
+    (WebCore::depth): Changed into a template that takes TreeType.
+    (WebCore::commonInclusiveAncestorAndChildren): Ditto.
+    (WebCore::commonInclusiveAncestor): Changed to explicitly use ComposedTree to preserve
+    the current behavior, but likely will return later to make this a template and have it
+    us the normal tree by default.
+    (WebCore::treeOrder): Changed into a template that takes TreeType.
+    (WebCore::documentOrder): Call treeOrder<ComposedTree> to preserve the current behavior.
+    Likely will delete this later after changing callers to use treeOrder.
+    
+    * dom/Node.h: Added Tree, ShadowIncludingTree, and ComposedTree. Added parent and
+    treeOrder function templates. TreeType currently is a set of classes but they could
+    also be objects of another type. Maybe an enumeration named TreeType instead?
+    
+    * dom/Range.cpp:
+    (WebCore::Range::setStart): Use treeOrder instead of documentOrder to use the normal
+    tree instead of the composed tree.
+    (WebCore::Range::setEnd): Ditto.
+    (WebCore::Range::isPointInRange): Use isPointInRange<Tree> instead of isPointInRange
+    to use the normal tree instead of the composed tree.
+    (WebCore::Range::comparePoint const): Use treeOrder instead of documentOrder to use
+    the normal tree instead of the composed tree.
+    (WebCore::Range::compareNode const): Ditto.
+    (WebCore::Range::compareBoundaryPoints const): Ditto.
+    (WebCore::Range::intersectsNode const): Use intersects<Tree> instead of isPointInRange
+    to use the normal tree instead of the composed tree.
+    
+    * dom/SimpleRange.cpp:
+    (WebCore::treeOrder): Changed into a template that takes TreeType.
+    (WebCore::documentOrder): Call treeOrder<ComposedTree> to preserve the current behavior.
+    Likely will delete this later after changing callers to use treeOrder.
+    (WebCore::isPointInRange): Changed into a template that takes TreeType.
+    For now the default tree type is still ComposedTree, but will change that later.
+    (WebCore::intersects): Ditto.
+    (WebCore::contains<Tree>): Added.
+    (WebCore::contains<ComposedTree>): Added.
+    
+    * dom/SimpleRange.h: Added isPointInRange, intersects, and treeOrder function templates.
+    
+    LayoutTests:
+    
+    * fast/dom/Range/ranges-across-trees.html: Added.
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@268800 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2020-10-20  Darin Adler  <[email protected]>
+
+            REGRESSION(r266295): Range allows start and end containers to belong to different trees
+            https://bugs.webkit.org/show_bug.cgi?id=217895
+
+            Reviewed by Ryosuke Niwa.
+
+            * fast/dom/Range/ranges-across-trees.html: Added.
+
+2020-10-26  Alan Coon  <[email protected]>
+
         Cherry-pick r268695. rdar://problem/70702399
 
     Unreviewed, reverting r267175 and r267779.

Added: branches/safari-611.1.4-branch/LayoutTests/fast/dom/Range/ranges-across-trees-expected.txt (0 => 269010)


--- branches/safari-611.1.4-branch/LayoutTests/fast/dom/Range/ranges-across-trees-expected.txt	                        (rev 0)
+++ branches/safari-611.1.4-branch/LayoutTests/fast/dom/Range/ranges-across-trees-expected.txt	2020-10-27 01:13:07 UTC (rev 269010)
@@ -0,0 +1,21 @@
+PASS range.setStart(shadowRoot, 0); collapsedRangeNode(range) is shadowRoot
+PASS range.setEnd(shadowRoot, 0); collapsedRangeNode(range) is shadowRoot
+PASS range.setStartBefore(shadowNode); collapsedRangeNode(range) is shadowRoot
+PASS range.setStartAfter(shadowNode); collapsedRangeNode(range) is shadowRoot
+PASS range.setEndBefore(shadowNode); collapsedRangeNode(range) is shadowRoot
+PASS range.setEndAfter(shadowNode); collapsedRangeNode(range) is shadowRoot
+PASS bodyRange().isPointInRange(shadowNode, 0) is false
+PASS bodyRange().comparePoint(shadowNode, 0) threw exception WrongDocumentError: The object is in the wrong document..
+PASS bodyRange().intersectsNode(shadowNode) is false
+PASS bodyRange().compareNode(shadowNode) threw exception WrongDocumentError: The object is in the wrong document..
+PASS document.body.compareDocumentPosition(shadowNode) & Node.DOCUMENT_POSITION_DISCONNECTED is Node.DOCUMENT_POSITION_DISCONNECTED
+PASS (document.body.compareDocumentPosition(shadowNode) & (Node.DOCUMENT_POSITION_PRECEDING | Node.DOCUMENT_POSITION_FOLLOWING)) != 0 is true
+PASS document.body.compareDocumentPosition(shadowNode) & Node.DOCUMENT_POSITION_CONTAINS is 0
+PASS document.body.compareDocumentPosition(shadowNode) & Node.DOCUMENT_POSITION_CONTAINED_BY is 0
+PASS document.body.compareDocumentPosition(shadowNode) & Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC is Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC
+PASS document.body.compareDocumentPosition(shadowNode) & ~(Node.DOCUMENT_POSITION_DISCONNECTED | Node.DOCUMENT_POSITION_PRECEDING | Node.DOCUMENT_POSITION_FOLLOWING | Node.DOCUMENT_POSITION_CONTAINS | Node.DOCUMENT_POSITION_CONTAINED_BY | Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC) is 0
+PASS document.body.contains(shadowNode) is false
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: branches/safari-611.1.4-branch/LayoutTests/fast/dom/Range/ranges-across-trees.html (0 => 269010)


--- branches/safari-611.1.4-branch/LayoutTests/fast/dom/Range/ranges-across-trees.html	                        (rev 0)
+++ branches/safari-611.1.4-branch/LayoutTests/fast/dom/Range/ranges-across-trees.html	2020-10-27 01:13:07 UTC (rev 269010)
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <script src=""
+</head>
+<body>
+    <script>
+        const shadowHost = document.body.appendChild(document.createElement('div'));
+        const shadowRoot = shadowHost.attachShadow({mode: 'closed'});
+        shadowRoot.textContent = 'hello';
+        const shadowNode = shadowRoot.firstChild;
+
+        function bodyRange()
+        {
+            const range = document.createRange();
+            range.selectNode(document.body);
+            return range;
+        }
+
+        function collapsedRangeNode(range)
+        {
+            return range.collapsed ? range.startContainer : "not collapsed";
+        }
+
+        function testRangeMutation(test)
+        {
+            range = bodyRange();
+            shouldBe("range." + test + "; collapsedRangeNode(range)", "shadowRoot");
+        }
+
+        testRangeMutation("setStart(shadowRoot, 0)");
+        testRangeMutation("setEnd(shadowRoot, 0)");
+        testRangeMutation("setStartBefore(shadowNode)");
+        testRangeMutation("setStartAfter(shadowNode)");
+        testRangeMutation("setEndBefore(shadowNode)");
+        testRangeMutation("setEndAfter(shadowNode)");
+
+        shouldBeFalse("bodyRange().isPointInRange(shadowNode, 0)");
+        shouldThrowErrorName("bodyRange().comparePoint(shadowNode, 0)", "WrongDocumentError");
+        shouldBeFalse("bodyRange().intersectsNode(shadowNode)");
+        shouldThrowErrorName("bodyRange().compareNode(shadowNode)", "WrongDocumentError");
+
+        // FIXME: These are Node methods, not Range, so we might want to move them into a separate test.
+
+        shouldBe("document.body.compareDocumentPosition(shadowNode) & Node.DOCUMENT_POSITION_DISCONNECTED", "Node.DOCUMENT_POSITION_DISCONNECTED");
+        shouldBeTrue("(document.body.compareDocumentPosition(shadowNode) & (Node.DOCUMENT_POSITION_PRECEDING | Node.DOCUMENT_POSITION_FOLLOWING)) != 0");
+        shouldBe("document.body.compareDocumentPosition(shadowNode) & Node.DOCUMENT_POSITION_CONTAINS", "0");
+        shouldBe("document.body.compareDocumentPosition(shadowNode) & Node.DOCUMENT_POSITION_CONTAINED_BY", "0");
+        shouldBe("document.body.compareDocumentPosition(shadowNode) & Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC", "Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC");
+        shouldBe("document.body.compareDocumentPosition(shadowNode) & ~(Node.DOCUMENT_POSITION_DISCONNECTED | Node.DOCUMENT_POSITION_PRECEDING | Node.DOCUMENT_POSITION_FOLLOWING | Node.DOCUMENT_POSITION_CONTAINS | Node.DOCUMENT_POSITION_CONTAINED_BY | Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC)", "0");
+
+        shouldBeFalse("document.body.contains(shadowNode)");
+
+        document.body.removeChild(shadowHost);
+
+        successfullyParsed = true;
+    </script>
+</html>

Modified: branches/safari-611.1.4-branch/Source/WebCore/ChangeLog (269009 => 269010)


--- branches/safari-611.1.4-branch/Source/WebCore/ChangeLog	2020-10-27 01:13:03 UTC (rev 269009)
+++ branches/safari-611.1.4-branch/Source/WebCore/ChangeLog	2020-10-27 01:13:07 UTC (rev 269010)
@@ -1,5 +1,119 @@
 2020-10-26  Alan Coon  <[email protected]>
 
+        Cherry-pick r268800. rdar://problem/70702272
+
+    REGRESSION(r266295): Range allows start and end containers to belong to different trees
+    https://bugs.webkit.org/show_bug.cgi?id=217895
+    
+    Reviewed by Ryosuke Niwa.
+    
+    Source/WebCore:
+    
+    Test: fast/dom/Range/ranges-across-trees.html
+    
+    * dom/BoundaryPoint.h: Added treeOrder<TreeType>.
+    
+    * dom/Node.cpp:
+    (WebCore::parent<Tree>): Added.
+    (WebCore::parent<ComposedTree>): Added.
+    (WebCore::depth): Changed into a template that takes TreeType.
+    (WebCore::commonInclusiveAncestorAndChildren): Ditto.
+    (WebCore::commonInclusiveAncestor): Changed to explicitly use ComposedTree to preserve
+    the current behavior, but likely will return later to make this a template and have it
+    us the normal tree by default.
+    (WebCore::treeOrder): Changed into a template that takes TreeType.
+    (WebCore::documentOrder): Call treeOrder<ComposedTree> to preserve the current behavior.
+    Likely will delete this later after changing callers to use treeOrder.
+    
+    * dom/Node.h: Added Tree, ShadowIncludingTree, and ComposedTree. Added parent and
+    treeOrder function templates. TreeType currently is a set of classes but they could
+    also be objects of another type. Maybe an enumeration named TreeType instead?
+    
+    * dom/Range.cpp:
+    (WebCore::Range::setStart): Use treeOrder instead of documentOrder to use the normal
+    tree instead of the composed tree.
+    (WebCore::Range::setEnd): Ditto.
+    (WebCore::Range::isPointInRange): Use isPointInRange<Tree> instead of isPointInRange
+    to use the normal tree instead of the composed tree.
+    (WebCore::Range::comparePoint const): Use treeOrder instead of documentOrder to use
+    the normal tree instead of the composed tree.
+    (WebCore::Range::compareNode const): Ditto.
+    (WebCore::Range::compareBoundaryPoints const): Ditto.
+    (WebCore::Range::intersectsNode const): Use intersects<Tree> instead of isPointInRange
+    to use the normal tree instead of the composed tree.
+    
+    * dom/SimpleRange.cpp:
+    (WebCore::treeOrder): Changed into a template that takes TreeType.
+    (WebCore::documentOrder): Call treeOrder<ComposedTree> to preserve the current behavior.
+    Likely will delete this later after changing callers to use treeOrder.
+    (WebCore::isPointInRange): Changed into a template that takes TreeType.
+    For now the default tree type is still ComposedTree, but will change that later.
+    (WebCore::intersects): Ditto.
+    (WebCore::contains<Tree>): Added.
+    (WebCore::contains<ComposedTree>): Added.
+    
+    * dom/SimpleRange.h: Added isPointInRange, intersects, and treeOrder function templates.
+    
+    LayoutTests:
+    
+    * fast/dom/Range/ranges-across-trees.html: Added.
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@268800 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2020-10-20  Darin Adler  <[email protected]>
+
+            REGRESSION(r266295): Range allows start and end containers to belong to different trees
+            https://bugs.webkit.org/show_bug.cgi?id=217895
+
+            Reviewed by Ryosuke Niwa.
+
+            Test: fast/dom/Range/ranges-across-trees.html
+
+            * dom/BoundaryPoint.h: Added treeOrder<TreeType>.
+
+            * dom/Node.cpp:
+            (WebCore::parent<Tree>): Added.
+            (WebCore::parent<ComposedTree>): Added.
+            (WebCore::depth): Changed into a template that takes TreeType.
+            (WebCore::commonInclusiveAncestorAndChildren): Ditto.
+            (WebCore::commonInclusiveAncestor): Changed to explicitly use ComposedTree to preserve
+            the current behavior, but likely will return later to make this a template and have it
+            us the normal tree by default.
+            (WebCore::treeOrder): Changed into a template that takes TreeType.
+            (WebCore::documentOrder): Call treeOrder<ComposedTree> to preserve the current behavior.
+            Likely will delete this later after changing callers to use treeOrder.
+
+            * dom/Node.h: Added Tree, ShadowIncludingTree, and ComposedTree. Added parent and
+            treeOrder function templates. TreeType currently is a set of classes but they could
+            also be objects of another type. Maybe an enumeration named TreeType instead?
+
+            * dom/Range.cpp:
+            (WebCore::Range::setStart): Use treeOrder instead of documentOrder to use the normal
+            tree instead of the composed tree.
+            (WebCore::Range::setEnd): Ditto.
+            (WebCore::Range::isPointInRange): Use isPointInRange<Tree> instead of isPointInRange
+            to use the normal tree instead of the composed tree.
+            (WebCore::Range::comparePoint const): Use treeOrder instead of documentOrder to use
+            the normal tree instead of the composed tree.
+            (WebCore::Range::compareNode const): Ditto.
+            (WebCore::Range::compareBoundaryPoints const): Ditto.
+            (WebCore::Range::intersectsNode const): Use intersects<Tree> instead of isPointInRange
+            to use the normal tree instead of the composed tree.
+
+            * dom/SimpleRange.cpp:
+            (WebCore::treeOrder): Changed into a template that takes TreeType.
+            (WebCore::documentOrder): Call treeOrder<ComposedTree> to preserve the current behavior.
+            Likely will delete this later after changing callers to use treeOrder.
+            (WebCore::isPointInRange): Changed into a template that takes TreeType.
+            For now the default tree type is still ComposedTree, but will change that later.
+            (WebCore::intersects): Ditto.
+            (WebCore::contains<Tree>): Added.
+            (WebCore::contains<ComposedTree>): Added.
+
+            * dom/SimpleRange.h: Added isPointInRange, intersects, and treeOrder function templates.
+
+2020-10-26  Alan Coon  <[email protected]>
+
         Cherry-pick r268730. rdar://problem/70702315
 
     Web Inspector: REGRESSION(r260076): crash under InspectorInstrumentation::willApplyKeyframeEffect

Modified: branches/safari-611.1.4-branch/Source/WebCore/dom/BoundaryPoint.h (269009 => 269010)


--- branches/safari-611.1.4-branch/Source/WebCore/dom/BoundaryPoint.h	2020-10-27 01:13:03 UTC (rev 269009)
+++ branches/safari-611.1.4-branch/Source/WebCore/dom/BoundaryPoint.h	2020-10-27 01:13:07 UTC (rev 269010)
@@ -40,6 +40,8 @@
 
 bool operator==(const BoundaryPoint&, const BoundaryPoint&);
 bool operator!=(const BoundaryPoint&, const BoundaryPoint&);
+
+template<typename TreeType = Tree> PartialOrdering treeOrder(const BoundaryPoint&, const BoundaryPoint&);
 WEBCORE_EXPORT PartialOrdering documentOrder(const BoundaryPoint&, const BoundaryPoint&);
 
 WEBCORE_EXPORT Optional<BoundaryPoint> makeBoundaryPointBeforeNode(Node&);

Modified: branches/safari-611.1.4-branch/Source/WebCore/dom/Node.cpp (269009 => 269010)


--- branches/safari-611.1.4-branch/Source/WebCore/dom/Node.cpp	2020-10-27 01:13:03 UTC (rev 269009)
+++ branches/safari-611.1.4-branch/Source/WebCore/dom/Node.cpp	2020-10-27 01:13:07 UTC (rev 269010)
@@ -2622,11 +2622,21 @@
     return const_cast<void*>(static_cast<const void*>(node));
 }
 
-static size_t depthInComposedTree(const Node& node)
+template<> ContainerNode* parent<Tree>(const Node& node)
 {
+    return node.parentNode();
+}
+
+template<> ContainerNode* parent<ComposedTree>(const Node& node)
+{
+    return node.parentInComposedTree();
+}
+
+template<typename TreeType> size_t depth(const Node& node)
+{
     size_t depth = 0;
     auto ancestor = &node;
-    while ((ancestor = ancestor->parentInComposedTree()))
+    while ((ancestor = parent<TreeType>(*ancestor)))
         ++depth;
     return depth;
 }
@@ -2637,8 +2647,7 @@
     const Node* distinctAncestorB;
 };
 
-// FIXME: This function's name is not explicit about the fact that it's the common inclusive ancestor in the composed tree.
-static AncestorAndChildren commonInclusiveAncestorAndChildren(const Node& a, const Node& b)
+template<typename TreeType> AncestorAndChildren commonInclusiveAncestorAndChildren(const Node& a, const Node& b)
 {
     // This check isn't needed for correctness, but it is cheap and likely to be
     // common enough to be worth optimizing so we don't have to walk to the root.
@@ -2647,7 +2656,7 @@
     // FIXME: Could optimize cases where nodes are both in the same shadow tree.
     // FIXME: Could optimize cases where nodes are in different documents to quickly return false.
     // FIXME: Could optimize cases where one node is connected and the other is not to quickly return false.
-    auto [depthA, depthB] = std::make_tuple(depthInComposedTree(a), depthInComposedTree(b));
+    auto [depthA, depthB] = std::make_tuple(depth<TreeType>(a), depth<TreeType>(b));
     auto [x, y, difference] = depthA >= depthB
         ? std::make_tuple(&a, &b, depthA - depthB)
         : std::make_tuple(&b, &a, depthB - depthA);
@@ -2654,14 +2663,14 @@
     decltype(x) distinctAncestorA = nullptr;
     for (decltype(difference) i = 0; i < difference; ++i) {
         distinctAncestorA = x;
-        x = x->parentInComposedTree();
+        x = parent<TreeType>(*x);
     }
     decltype(y) distinctAncestorB = nullptr;
     while (x != y) {
         distinctAncestorA = x;
         distinctAncestorB = y;
-        x = x->parentInComposedTree();
-        y = y->parentInComposedTree();
+        x = parent<TreeType>(*x);
+        y = parent<TreeType>(*y);
     }
     if (depthA < depthB)
         std::swap(distinctAncestorA, distinctAncestorB);
@@ -2668,10 +2677,10 @@
     return { x, distinctAncestorA, distinctAncestorB };
 }
 
-// FIXME: This function's name is not explicit about the fact that it's the common inclusive ancestor in the composed tree.
+// FIXME: Change this to work within the normal tree instead of the composed tree. Or rename and/or split into multiple functions.
 RefPtr<Node> commonInclusiveAncestor(Node& a, Node& b)
 {
-    return const_cast<Node*>(commonInclusiveAncestorAndChildren(a, b).commonAncestor);
+    return const_cast<Node*>(commonInclusiveAncestorAndChildren<ComposedTree>(a, b).commonAncestor);
 }
 
 static bool isSiblingSubsequent(const Node& siblingA, const Node& siblingB)
@@ -2686,11 +2695,11 @@
     return false;
 }
 
-PartialOrdering documentOrder(const Node& a, const Node& b)
+template<typename TreeType> PartialOrdering treeOrder(const Node& a, const Node& b)
 {
     if (&a == &b)
         return PartialOrdering::equivalent;
-    auto result = commonInclusiveAncestorAndChildren(a, b);
+    auto result = commonInclusiveAncestorAndChildren<TreeType>(a, b);
     if (!result.commonAncestor)
         return PartialOrdering::unordered;
     if (!result.distinctAncestorA)
@@ -2710,6 +2719,14 @@
     return isSiblingSubsequent(*result.distinctAncestorA, *result.distinctAncestorB) ? PartialOrdering::less : PartialOrdering::greater;
 }
 
+template PartialOrdering treeOrder<Tree>(const Node&, const Node&);
+template PartialOrdering treeOrder<ComposedTree>(const Node&, const Node&);
+
+PartialOrdering documentOrder(const Node& a, const Node& b)
+{
+    return treeOrder<ComposedTree>(a, b);
+}
+
 TextStream& operator<<(TextStream& ts, const Node& node)
 {
     ts << "node " << &node << " " << node.debugDescription();

Modified: branches/safari-611.1.4-branch/Source/WebCore/dom/Node.h (269009 => 269010)


--- branches/safari-611.1.4-branch/Source/WebCore/dom/Node.h	2020-10-27 01:13:03 UTC (rev 269009)
+++ branches/safari-611.1.4-branch/Source/WebCore/dom/Node.h	2020-10-27 01:13:07 UTC (rev 269010)
@@ -755,6 +755,12 @@
 constexpr bool is_lteq(PartialOrdering);
 constexpr bool is_gteq(PartialOrdering);
 
+struct Tree { };
+struct ShadowIncludingTree { };
+struct ComposedTree { };
+template<typename TreeType = Tree> ContainerNode* parent(const Node&);
+template<typename TreeType = Tree> PartialOrdering treeOrder(const Node&, const Node&);
+
 WEBCORE_EXPORT PartialOrdering documentOrder(const Node&, const Node&);
 
 #if ASSERT_ENABLED

Modified: branches/safari-611.1.4-branch/Source/WebCore/dom/Range.cpp (269009 => 269010)


--- branches/safari-611.1.4-branch/Source/WebCore/dom/Range.cpp	2020-10-27 01:13:03 UTC (rev 269009)
+++ branches/safari-611.1.4-branch/Source/WebCore/dom/Range.cpp	2020-10-27 01:13:07 UTC (rev 269010)
@@ -116,7 +116,7 @@
         return childNode.releaseException();
 
     m_start.set(WTFMove(container), offset, childNode.releaseReturnValue());
-    if (!is_lteq(documentOrder(makeBoundaryPoint(m_start), makeBoundaryPoint(m_end))))
+    if (!is_lteq(treeOrder(makeBoundaryPoint(m_start), makeBoundaryPoint(m_end))))
         m_end = m_start;
     updateAssociatedSelection();
     updateDocument();
@@ -130,7 +130,7 @@
         return childNode.releaseException();
 
     m_end.set(WTFMove(container), offset, childNode.releaseReturnValue());
-    if (!is_lteq(documentOrder(makeBoundaryPoint(m_start), makeBoundaryPoint(m_end))))
+    if (!is_lteq(treeOrder(makeBoundaryPoint(m_start), makeBoundaryPoint(m_end))))
         m_start = m_end;
     updateAssociatedSelection();
     updateDocument();
@@ -155,7 +155,7 @@
             return false;
         return checkResult.releaseException();
     }
-    return WebCore::isPointInRange(makeSimpleRange(*this), { container, offset });
+    return WebCore::isPointInRange<Tree>(makeSimpleRange(*this), { container, offset });
 }
 
 ExceptionOr<short> Range::comparePoint(Node& container, unsigned offset) const
@@ -167,7 +167,7 @@
             return Exception { WrongDocumentError };
         return checkResult.releaseException();
     }
-    auto ordering = documentOrder({ container, offset }, makeSimpleRange(*this));
+    auto ordering = treeOrder({ container, offset }, makeSimpleRange(*this));
     if (is_lt(ordering))
         return -1;
     if (is_eq(ordering))
@@ -198,8 +198,8 @@
         return Exception { NotFoundError };
     }
 
-    auto startOrdering = documentOrder(nodeRange->start, makeBoundaryPoint(m_start));
-    auto endOrdering = documentOrder(nodeRange->end, makeBoundaryPoint(m_end));
+    auto startOrdering = treeOrder(nodeRange->start, makeBoundaryPoint(m_start));
+    auto endOrdering = treeOrder(nodeRange->end, makeBoundaryPoint(m_end));
     if (is_gteq(startOrdering) && is_lteq(endOrdering))
         return NODE_INSIDE;
     if (is_lteq(startOrdering) && is_gteq(endOrdering))
@@ -235,7 +235,7 @@
     default:
         return Exception { NotSupportedError };
     }
-    auto ordering = documentOrder(makeBoundaryPoint(*thisPoint), makeBoundaryPoint(*otherPoint));
+    auto ordering = treeOrder(makeBoundaryPoint(*thisPoint), makeBoundaryPoint(*otherPoint));
     if (is_lt(ordering))
         return -1;
     if (is_eq(ordering))
@@ -255,7 +255,7 @@
 
 bool Range::intersectsNode(Node& node) const
 {
-    return intersects(makeSimpleRange(*this), node);
+    return intersects<Tree>(makeSimpleRange(*this), node);
 }
 
 static inline Node* highestAncestorUnderCommonRoot(Node* node, Node* commonRoot)

Modified: branches/safari-611.1.4-branch/Source/WebCore/dom/SimpleRange.cpp (269009 => 269010)


--- branches/safari-611.1.4-branch/Source/WebCore/dom/SimpleRange.cpp	2020-10-27 01:13:03 UTC (rev 269009)
+++ branches/safari-611.1.4-branch/Source/WebCore/dom/SimpleRange.cpp	2020-10-27 01:13:07 UTC (rev 269010)
@@ -95,14 +95,13 @@
     return PartialOrdering::equivalent;
 }
 
-// FIXME: Create BoundaryPoint.cpp and move this there.
-PartialOrdering documentOrder(const BoundaryPoint& a, const BoundaryPoint& b)
+template<typename TreeType> PartialOrdering treeOrder(const BoundaryPoint& a, const BoundaryPoint& b)
 {
     if (a.container.ptr() == b.container.ptr())
         return order(a.offset, b.offset);
 
     for (auto ancestor = b.container.ptr(); ancestor; ) {
-        auto nextAncestor = ancestor->parentInComposedTree();
+        auto nextAncestor = parent<TreeType>(*ancestor);
         if (nextAncestor == a.container.ptr())
             return isOffsetBeforeChild(*nextAncestor, a.offset, *ancestor) ? PartialOrdering::less : PartialOrdering::greater;
         ancestor = nextAncestor;
@@ -109,15 +108,20 @@
     }
 
     for (auto ancestor = a.container.ptr(); ancestor; ) {
-        auto nextAncestor = ancestor->parentInComposedTree();
+        auto nextAncestor = parent<TreeType>(*ancestor);
         if (nextAncestor == b.container.ptr())
             return isOffsetBeforeChild(*nextAncestor, b.offset, *ancestor) ? PartialOrdering::greater : PartialOrdering::less;
         ancestor = nextAncestor;
     }
 
-    return documentOrder(a.container, b.container);
+    return treeOrder<TreeType>(a.container, b.container);
 }
 
+PartialOrdering documentOrder(const BoundaryPoint& a, const BoundaryPoint& b)
+{
+    return treeOrder<ComposedTree>(a, b);
+}
+
 Optional<SimpleRange> makeRangeSelectingNode(Node& node)
 {
     auto parent = node.parentNode();
@@ -208,42 +212,74 @@
     return commonInclusiveAncestor(range.start.container, range.end.container);
 }
 
+template<typename TreeType> bool isPointInRange(const SimpleRange& range, const BoundaryPoint& point)
+{
+    return is_lteq(treeOrder<TreeType>(range.start, point)) && is_lteq(treeOrder<TreeType>(point, range.end));
+}
+
+template bool isPointInRange<Tree>(const SimpleRange&, const BoundaryPoint&);
+
+template<typename TreeType> bool isPointInRange(const SimpleRange& range, const Optional<BoundaryPoint>& point)
+{
+    return point && isPointInRange<TreeType>(range, *point);
+}
+
 bool isPointInRange(const SimpleRange& range, const BoundaryPoint& point)
 {
-    return is_lteq(documentOrder(range.start, point)) && is_lteq(documentOrder(point, range.end));
+    return isPointInRange<ComposedTree>(range, point);
 }
 
 bool isPointInRange(const SimpleRange& range, const Optional<BoundaryPoint>& point)
 {
-    return point && isPointInRange(range, *point);
+    return isPointInRange<ComposedTree>(range, point);
 }
 
-PartialOrdering documentOrder(const SimpleRange& range, const BoundaryPoint& point)
+template<typename TreeType> PartialOrdering treeOrder(const SimpleRange& range, const BoundaryPoint& point)
 {
-    if (auto order = documentOrder(range.start, point); !is_lt(order))
+    if (auto order = treeOrder<TreeType>(range.start, point); !is_lt(order))
         return order;
-    if (auto order = documentOrder(range.end, point); !is_gt(order))
+    if (auto order = treeOrder<TreeType>(range.end, point); !is_gt(order))
         return order;
     return PartialOrdering::equivalent;
 }
 
-PartialOrdering documentOrder(const BoundaryPoint& point, const SimpleRange& range)
+template<typename TreeType> PartialOrdering treeOrder(const BoundaryPoint& point, const SimpleRange& range)
 {
-    if (auto order = documentOrder(point, range.start); !is_gt(order))
+    if (auto order = treeOrder<TreeType>(point, range.start); !is_gt(order))
         return order;
-    if (auto order = documentOrder(point, range.end); !is_lt(order))
+    if (auto order = treeOrder<TreeType>(point, range.end); !is_lt(order))
         return order;
     return PartialOrdering::equivalent;
 }
 
+template PartialOrdering treeOrder<Tree>(const SimpleRange&, const BoundaryPoint&);
+template PartialOrdering treeOrder<Tree>(const BoundaryPoint&, const SimpleRange&);
+
+PartialOrdering documentOrder(const SimpleRange& range, const BoundaryPoint& point)
+{
+    return treeOrder<ComposedTree>(range, point);
+}
+
+PartialOrdering documentOrder(const BoundaryPoint& point, const SimpleRange& range)
+{
+    return treeOrder<ComposedTree>(point, range);
+}
+
 bool contains(const SimpleRange& outerRange, const SimpleRange& innerRange)
 {
     return is_lteq(documentOrder(outerRange.start, innerRange.start)) && is_gteq(documentOrder(outerRange.end, innerRange.end));
 }
 
+template<typename TreeType> bool intersects(const SimpleRange& a, const SimpleRange& b)
+{
+    return is_lteq(treeOrder<TreeType>(a.start, b.end)) && is_lteq(treeOrder<TreeType>(b.start, a.end));
+}
+
+template bool intersects<Tree>(const SimpleRange&, const SimpleRange&);
+
 bool intersects(const SimpleRange& a, const SimpleRange& b)
 {
-    return is_lteq(documentOrder(a.start, b.end)) && is_lteq(documentOrder(b.start, a.end));
+    return intersects<ComposedTree>(a, b);
 }
 
 static bool compareByDocumentOrder(const BoundaryPoint& a, const BoundaryPoint& b)
@@ -272,15 +308,36 @@
     return nodeRange && contains(range, *nodeRange);
 }
 
-bool intersects(const SimpleRange& range, const Node& node)
+template<typename TreeType> bool contains(const Node& outer, const Node& inner);
+
+template<> bool contains<Tree>(const Node& outer, const Node& inner)
 {
+    return outer.contains(inner);
+}
+
+template<> bool contains<ComposedTree>(const Node& outer, const Node& inner)
+{
+    // FIXME: This is what the code did before, but it is not correct!
+    return outer.contains(inner);
+}
+
+template<typename TreeType> bool intersects(const SimpleRange& range, const Node& node)
+{
     // FIXME: Consider a more efficient algorithm that avoids always computing the node index.
     // FIXME: Does this const_cast point to a design problem?
     auto nodeRange = makeRangeSelectingNode(const_cast<Node&>(node));
     if (!nodeRange)
-        return node.contains(range.start.container.ptr());
-    return is_lt(documentOrder(nodeRange->start, range.end)) && is_lt(documentOrder(range.start, nodeRange->end));
+        return contains<TreeType>(node, range.start.container);
+    return is_lt(treeOrder<TreeType>(nodeRange->start, range.end)) && is_lt(treeOrder<TreeType>(range.start, nodeRange->end));
 
 }
 
+template bool intersects<Tree>(const SimpleRange&, const Node&);
+
+bool intersects(const SimpleRange& range, const Node& node)
+{
+    return intersects<ComposedTree>(range, node);
+
 }
+
+}

Modified: branches/safari-611.1.4-branch/Source/WebCore/dom/SimpleRange.h (269009 => 269010)


--- branches/safari-611.1.4-branch/Source/WebCore/dom/SimpleRange.h	2020-10-27 01:13:03 UTC (rev 269009)
+++ branches/safari-611.1.4-branch/Source/WebCore/dom/SimpleRange.h	2020-10-27 01:13:07 UTC (rev 269010)
@@ -65,18 +65,24 @@
 
 bool operator==(const SimpleRange&, const SimpleRange&);
 
+template<typename TreeType> bool isPointInRange(const SimpleRange&, const BoundaryPoint&);
+template<typename TreeType> bool isPointInRange(const SimpleRange&, const Optional<BoundaryPoint>&);
 WEBCORE_EXPORT bool isPointInRange(const SimpleRange&, const BoundaryPoint&);
 bool isPointInRange(const SimpleRange&, const Optional<BoundaryPoint>&);
 
 WEBCORE_EXPORT bool contains(const SimpleRange& outerRange, const SimpleRange& innerRange);
+template<typename TreeType> bool intersects(const SimpleRange&, const SimpleRange&);
 WEBCORE_EXPORT bool intersects(const SimpleRange&, const SimpleRange&);
 WEBCORE_EXPORT SimpleRange unionRange(const SimpleRange&, const SimpleRange&);
 WEBCORE_EXPORT Optional<SimpleRange> intersection(const Optional<SimpleRange>&, const Optional<SimpleRange>&);
 
 WEBCORE_EXPORT bool contains(const SimpleRange&, const Node&);
+template<typename TreeType> bool intersects(const SimpleRange&, const Node&);
 WEBCORE_EXPORT bool intersects(const SimpleRange&, const Node&);
 
 // Returns equivalent if point is in range.
+template<typename TreeType = Tree> PartialOrdering treeOrder(const SimpleRange&, const BoundaryPoint&);
+template<typename TreeType = Tree> PartialOrdering treeOrder(const BoundaryPoint&, const SimpleRange&);
 WEBCORE_EXPORT PartialOrdering documentOrder(const SimpleRange&, const BoundaryPoint&);
 WEBCORE_EXPORT PartialOrdering documentOrder(const BoundaryPoint&, const SimpleRange&);
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to