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&);