Changeset 268800 in webkit
- Timestamp:
- Oct 21, 2020, 9:39:37 AM (6 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 8 edited
-
LayoutTests/ChangeLog (modified) (1 diff)
-
LayoutTests/fast/dom/Range/ranges-across-trees-expected.txt (added)
-
LayoutTests/fast/dom/Range/ranges-across-trees.html (added)
-
Source/WebCore/ChangeLog (modified) (1 diff)
-
Source/WebCore/dom/BoundaryPoint.h (modified) (1 diff)
-
Source/WebCore/dom/Node.cpp (modified) (8 diffs)
-
Source/WebCore/dom/Node.h (modified) (1 diff)
-
Source/WebCore/dom/Range.cpp (modified) (7 diffs)
-
Source/WebCore/dom/SimpleRange.cpp (modified) (8 diffs)
-
Source/WebCore/dom/SimpleRange.h (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r268799 r268800 1 2020-10-20 Darin Adler <darin@apple.com> 2 3 REGRESSION(r266295): Range allows start and end containers to belong to different trees 4 https://bugs.webkit.org/show_bug.cgi?id=217895 5 6 Reviewed by Ryosuke Niwa. 7 8 * fast/dom/Range/ranges-across-trees.html: Added. 9 1 10 2020-10-21 Hector Lopez <hector_i_lopez@apple.com> 2 11 -
trunk/Source/WebCore/ChangeLog
r268798 r268800 1 2020-10-20 Darin Adler <darin@apple.com> 2 3 REGRESSION(r266295): Range allows start and end containers to belong to different trees 4 https://bugs.webkit.org/show_bug.cgi?id=217895 5 6 Reviewed by Ryosuke Niwa. 7 8 Test: fast/dom/Range/ranges-across-trees.html 9 10 * dom/BoundaryPoint.h: Added treeOrder<TreeType>. 11 12 * dom/Node.cpp: 13 (WebCore::parent<Tree>): Added. 14 (WebCore::parent<ComposedTree>): Added. 15 (WebCore::depth): Changed into a template that takes TreeType. 16 (WebCore::commonInclusiveAncestorAndChildren): Ditto. 17 (WebCore::commonInclusiveAncestor): Changed to explicitly use ComposedTree to preserve 18 the current behavior, but likely will return later to make this a template and have it 19 us the normal tree by default. 20 (WebCore::treeOrder): Changed into a template that takes TreeType. 21 (WebCore::documentOrder): Call treeOrder<ComposedTree> to preserve the current behavior. 22 Likely will delete this later after changing callers to use treeOrder. 23 24 * dom/Node.h: Added Tree, ShadowIncludingTree, and ComposedTree. Added parent and 25 treeOrder function templates. TreeType currently is a set of classes but they could 26 also be objects of another type. Maybe an enumeration named TreeType instead? 27 28 * dom/Range.cpp: 29 (WebCore::Range::setStart): Use treeOrder instead of documentOrder to use the normal 30 tree instead of the composed tree. 31 (WebCore::Range::setEnd): Ditto. 32 (WebCore::Range::isPointInRange): Use isPointInRange<Tree> instead of isPointInRange 33 to use the normal tree instead of the composed tree. 34 (WebCore::Range::comparePoint const): Use treeOrder instead of documentOrder to use 35 the normal tree instead of the composed tree. 36 (WebCore::Range::compareNode const): Ditto. 37 (WebCore::Range::compareBoundaryPoints const): Ditto. 38 (WebCore::Range::intersectsNode const): Use intersects<Tree> instead of isPointInRange 39 to use the normal tree instead of the composed tree. 40 41 * dom/SimpleRange.cpp: 42 (WebCore::treeOrder): Changed into a template that takes TreeType. 43 (WebCore::documentOrder): Call treeOrder<ComposedTree> to preserve the current behavior. 44 Likely will delete this later after changing callers to use treeOrder. 45 (WebCore::isPointInRange): Changed into a template that takes TreeType. 46 For now the default tree type is still ComposedTree, but will change that later. 47 (WebCore::intersects): Ditto. 48 (WebCore::contains<Tree>): Added. 49 (WebCore::contains<ComposedTree>): Added. 50 51 * dom/SimpleRange.h: Added isPointInRange, intersects, and treeOrder function templates. 52 1 53 2020-10-21 Antti Koivisto <antti@apple.com> 2 54 -
trunk/Source/WebCore/dom/BoundaryPoint.h
r266026 r268800 41 41 bool operator==(const BoundaryPoint&, const BoundaryPoint&); 42 42 bool operator!=(const BoundaryPoint&, const BoundaryPoint&); 43 44 template<typename TreeType = Tree> PartialOrdering treeOrder(const BoundaryPoint&, const BoundaryPoint&); 43 45 WEBCORE_EXPORT PartialOrdering documentOrder(const BoundaryPoint&, const BoundaryPoint&); 44 46 -
trunk/Source/WebCore/dom/Node.cpp
r268695 r268800 2623 2623 } 2624 2624 2625 static size_t depthInComposedTree(const Node& node) 2625 template<> ContainerNode* parent<Tree>(const Node& node) 2626 { 2627 return node.parentNode(); 2628 } 2629 2630 template<> ContainerNode* parent<ComposedTree>(const Node& node) 2631 { 2632 return node.parentInComposedTree(); 2633 } 2634 2635 template<typename TreeType> size_t depth(const Node& node) 2626 2636 { 2627 2637 size_t depth = 0; 2628 2638 auto ancestor = &node; 2629 while ((ancestor = ancestor->parentInComposedTree()))2639 while ((ancestor = parent<TreeType>(*ancestor))) 2630 2640 ++depth; 2631 2641 return depth; … … 2638 2648 }; 2639 2649 2640 // FIXME: This function's name is not explicit about the fact that it's the common inclusive ancestor in the composed tree. 2641 static AncestorAndChildren commonInclusiveAncestorAndChildren(const Node& a, const Node& b) 2650 template<typename TreeType> AncestorAndChildren commonInclusiveAncestorAndChildren(const Node& a, const Node& b) 2642 2651 { 2643 2652 // This check isn't needed for correctness, but it is cheap and likely to be … … 2648 2657 // FIXME: Could optimize cases where nodes are in different documents to quickly return false. 2649 2658 // FIXME: Could optimize cases where one node is connected and the other is not to quickly return false. 2650 auto [depthA, depthB] = std::make_tuple(depth InComposedTree(a), depthInComposedTree(b));2659 auto [depthA, depthB] = std::make_tuple(depth<TreeType>(a), depth<TreeType>(b)); 2651 2660 auto [x, y, difference] = depthA >= depthB 2652 2661 ? std::make_tuple(&a, &b, depthA - depthB) … … 2655 2664 for (decltype(difference) i = 0; i < difference; ++i) { 2656 2665 distinctAncestorA = x; 2657 x = x->parentInComposedTree();2666 x = parent<TreeType>(*x); 2658 2667 } 2659 2668 decltype(y) distinctAncestorB = nullptr; … … 2661 2670 distinctAncestorA = x; 2662 2671 distinctAncestorB = y; 2663 x = x->parentInComposedTree();2664 y = y->parentInComposedTree();2672 x = parent<TreeType>(*x); 2673 y = parent<TreeType>(*y); 2665 2674 } 2666 2675 if (depthA < depthB) … … 2669 2678 } 2670 2679 2671 // FIXME: This function's name is not explicit about the fact that it's the common inclusive ancestor in the composed tree.2680 // FIXME: Change this to work within the normal tree instead of the composed tree. Or rename and/or split into multiple functions. 2672 2681 RefPtr<Node> commonInclusiveAncestor(Node& a, Node& b) 2673 2682 { 2674 return const_cast<Node*>(commonInclusiveAncestorAndChildren (a, b).commonAncestor);2683 return const_cast<Node*>(commonInclusiveAncestorAndChildren<ComposedTree>(a, b).commonAncestor); 2675 2684 } 2676 2685 … … 2687 2696 } 2688 2697 2689 PartialOrdering documentOrder(const Node& a, const Node& b)2698 template<typename TreeType> PartialOrdering treeOrder(const Node& a, const Node& b) 2690 2699 { 2691 2700 if (&a == &b) 2692 2701 return PartialOrdering::equivalent; 2693 auto result = commonInclusiveAncestorAndChildren (a, b);2702 auto result = commonInclusiveAncestorAndChildren<TreeType>(a, b); 2694 2703 if (!result.commonAncestor) 2695 2704 return PartialOrdering::unordered; … … 2711 2720 } 2712 2721 2722 template PartialOrdering treeOrder<Tree>(const Node&, const Node&); 2723 template PartialOrdering treeOrder<ComposedTree>(const Node&, const Node&); 2724 2725 PartialOrdering documentOrder(const Node& a, const Node& b) 2726 { 2727 return treeOrder<ComposedTree>(a, b); 2728 } 2729 2713 2730 TextStream& operator<<(TextStream& ts, const Node& node) 2714 2731 { -
trunk/Source/WebCore/dom/Node.h
r268695 r268800 756 756 constexpr bool is_gteq(PartialOrdering); 757 757 758 struct Tree { }; 759 struct ShadowIncludingTree { }; 760 struct ComposedTree { }; 761 template<typename TreeType = Tree> ContainerNode* parent(const Node&); 762 template<typename TreeType = Tree> PartialOrdering treeOrder(const Node&, const Node&); 763 758 764 WEBCORE_EXPORT PartialOrdering documentOrder(const Node&, const Node&); 759 765 -
trunk/Source/WebCore/dom/Range.cpp
r268648 r268800 117 117 118 118 m_start.set(WTFMove(container), offset, childNode.releaseReturnValue()); 119 if (!is_lteq( documentOrder(makeBoundaryPoint(m_start), makeBoundaryPoint(m_end))))119 if (!is_lteq(treeOrder(makeBoundaryPoint(m_start), makeBoundaryPoint(m_end)))) 120 120 m_end = m_start; 121 121 updateAssociatedSelection(); … … 131 131 132 132 m_end.set(WTFMove(container), offset, childNode.releaseReturnValue()); 133 if (!is_lteq( documentOrder(makeBoundaryPoint(m_start), makeBoundaryPoint(m_end))))133 if (!is_lteq(treeOrder(makeBoundaryPoint(m_start), makeBoundaryPoint(m_end)))) 134 134 m_start = m_end; 135 135 updateAssociatedSelection(); … … 156 156 return checkResult.releaseException(); 157 157 } 158 return WebCore::isPointInRange (makeSimpleRange(*this), { container, offset });158 return WebCore::isPointInRange<Tree>(makeSimpleRange(*this), { container, offset }); 159 159 } 160 160 … … 168 168 return checkResult.releaseException(); 169 169 } 170 auto ordering = documentOrder({ container, offset }, makeSimpleRange(*this));170 auto ordering = treeOrder({ container, offset }, makeSimpleRange(*this)); 171 171 if (is_lt(ordering)) 172 172 return -1; … … 199 199 } 200 200 201 auto startOrdering = documentOrder(nodeRange->start, makeBoundaryPoint(m_start));202 auto endOrdering = documentOrder(nodeRange->end, makeBoundaryPoint(m_end));201 auto startOrdering = treeOrder(nodeRange->start, makeBoundaryPoint(m_start)); 202 auto endOrdering = treeOrder(nodeRange->end, makeBoundaryPoint(m_end)); 203 203 if (is_gteq(startOrdering) && is_lteq(endOrdering)) 204 204 return NODE_INSIDE; … … 236 236 return Exception { NotSupportedError }; 237 237 } 238 auto ordering = documentOrder(makeBoundaryPoint(*thisPoint), makeBoundaryPoint(*otherPoint));238 auto ordering = treeOrder(makeBoundaryPoint(*thisPoint), makeBoundaryPoint(*otherPoint)); 239 239 if (is_lt(ordering)) 240 240 return -1; … … 256 256 bool Range::intersectsNode(Node& node) const 257 257 { 258 return intersects (makeSimpleRange(*this), node);258 return intersects<Tree>(makeSimpleRange(*this), node); 259 259 } 260 260 -
trunk/Source/WebCore/dom/SimpleRange.cpp
r266987 r268800 96 96 } 97 97 98 // FIXME: Create BoundaryPoint.cpp and move this there. 99 PartialOrdering documentOrder(const BoundaryPoint& a, const BoundaryPoint& b) 98 template<typename TreeType> PartialOrdering treeOrder(const BoundaryPoint& a, const BoundaryPoint& b) 100 99 { 101 100 if (a.container.ptr() == b.container.ptr()) … … 103 102 104 103 for (auto ancestor = b.container.ptr(); ancestor; ) { 105 auto nextAncestor = ancestor->parentInComposedTree();104 auto nextAncestor = parent<TreeType>(*ancestor); 106 105 if (nextAncestor == a.container.ptr()) 107 106 return isOffsetBeforeChild(*nextAncestor, a.offset, *ancestor) ? PartialOrdering::less : PartialOrdering::greater; … … 110 109 111 110 for (auto ancestor = a.container.ptr(); ancestor; ) { 112 auto nextAncestor = ancestor->parentInComposedTree();111 auto nextAncestor = parent<TreeType>(*ancestor); 113 112 if (nextAncestor == b.container.ptr()) 114 113 return isOffsetBeforeChild(*nextAncestor, b.offset, *ancestor) ? PartialOrdering::greater : PartialOrdering::less; … … 116 115 } 117 116 118 return documentOrder(a.container, b.container); 117 return treeOrder<TreeType>(a.container, b.container); 118 } 119 120 PartialOrdering documentOrder(const BoundaryPoint& a, const BoundaryPoint& b) 121 { 122 return treeOrder<ComposedTree>(a, b); 119 123 } 120 124 … … 209 213 } 210 214 215 template<typename TreeType> bool isPointInRange(const SimpleRange& range, const BoundaryPoint& point) 216 { 217 return is_lteq(treeOrder<TreeType>(range.start, point)) && is_lteq(treeOrder<TreeType>(point, range.end)); 218 } 219 220 template bool isPointInRange<Tree>(const SimpleRange&, const BoundaryPoint&); 221 222 template<typename TreeType> bool isPointInRange(const SimpleRange& range, const Optional<BoundaryPoint>& point) 223 { 224 return point && isPointInRange<TreeType>(range, *point); 225 } 226 211 227 bool isPointInRange(const SimpleRange& range, const BoundaryPoint& point) 212 228 { 213 return is _lteq(documentOrder(range.start, point)) && is_lteq(documentOrder(point, range.end));229 return isPointInRange<ComposedTree>(range, point); 214 230 } 215 231 216 232 bool isPointInRange(const SimpleRange& range, const Optional<BoundaryPoint>& point) 217 233 { 218 return point && isPointInRange(range, *point);219 } 220 221 PartialOrdering documentOrder(const SimpleRange& range, const BoundaryPoint& point)222 { 223 if (auto order = documentOrder(range.start, point); !is_lt(order))234 return isPointInRange<ComposedTree>(range, point); 235 } 236 237 template<typename TreeType> PartialOrdering treeOrder(const SimpleRange& range, const BoundaryPoint& point) 238 { 239 if (auto order = treeOrder<TreeType>(range.start, point); !is_lt(order)) 224 240 return order; 225 if (auto order = documentOrder(range.end, point); !is_gt(order))241 if (auto order = treeOrder<TreeType>(range.end, point); !is_gt(order)) 226 242 return order; 227 243 return PartialOrdering::equivalent; 228 244 } 229 245 230 PartialOrdering documentOrder(const BoundaryPoint& point, const SimpleRange& range)231 { 232 if (auto order = documentOrder(point, range.start); !is_gt(order))246 template<typename TreeType> PartialOrdering treeOrder(const BoundaryPoint& point, const SimpleRange& range) 247 { 248 if (auto order = treeOrder<TreeType>(point, range.start); !is_gt(order)) 233 249 return order; 234 if (auto order = documentOrder(point, range.end); !is_lt(order))250 if (auto order = treeOrder<TreeType>(point, range.end); !is_lt(order)) 235 251 return order; 236 252 return PartialOrdering::equivalent; 237 253 } 238 254 255 template PartialOrdering treeOrder<Tree>(const SimpleRange&, const BoundaryPoint&); 256 template PartialOrdering treeOrder<Tree>(const BoundaryPoint&, const SimpleRange&); 257 258 PartialOrdering documentOrder(const SimpleRange& range, const BoundaryPoint& point) 259 { 260 return treeOrder<ComposedTree>(range, point); 261 } 262 263 PartialOrdering documentOrder(const BoundaryPoint& point, const SimpleRange& range) 264 { 265 return treeOrder<ComposedTree>(point, range); 266 } 267 239 268 bool contains(const SimpleRange& outerRange, const SimpleRange& innerRange) 240 269 { … … 242 271 } 243 272 273 template<typename TreeType> bool intersects(const SimpleRange& a, const SimpleRange& b) 274 { 275 return is_lteq(treeOrder<TreeType>(a.start, b.end)) && is_lteq(treeOrder<TreeType>(b.start, a.end)); 276 } 277 278 template bool intersects<Tree>(const SimpleRange&, const SimpleRange&); 279 244 280 bool intersects(const SimpleRange& a, const SimpleRange& b) 245 281 { 246 return i s_lteq(documentOrder(a.start, b.end)) && is_lteq(documentOrder(b.start, a.end));282 return intersects<ComposedTree>(a, b); 247 283 } 248 284 … … 273 309 } 274 310 275 bool intersects(const SimpleRange& range, const Node& node) 311 template<typename TreeType> bool contains(const Node& outer, const Node& inner); 312 313 template<> bool contains<Tree>(const Node& outer, const Node& inner) 314 { 315 return outer.contains(inner); 316 } 317 318 template<> bool contains<ComposedTree>(const Node& outer, const Node& inner) 319 { 320 // FIXME: This is what the code did before, but it is not correct! 321 return outer.contains(inner); 322 } 323 324 template<typename TreeType> bool intersects(const SimpleRange& range, const Node& node) 276 325 { 277 326 // FIXME: Consider a more efficient algorithm that avoids always computing the node index. … … 279 328 auto nodeRange = makeRangeSelectingNode(const_cast<Node&>(node)); 280 329 if (!nodeRange) 281 return node.contains(range.start.container.ptr()); 282 return is_lt(documentOrder(nodeRange->start, range.end)) && is_lt(documentOrder(range.start, nodeRange->end)); 283 284 } 285 286 } 330 return contains<TreeType>(node, range.start.container); 331 return is_lt(treeOrder<TreeType>(nodeRange->start, range.end)) && is_lt(treeOrder<TreeType>(range.start, nodeRange->end)); 332 333 } 334 335 template bool intersects<Tree>(const SimpleRange&, const Node&); 336 337 bool intersects(const SimpleRange& range, const Node& node) 338 { 339 return intersects<ComposedTree>(range, node); 340 341 } 342 343 } -
trunk/Source/WebCore/dom/SimpleRange.h
r266987 r268800 66 66 bool operator==(const SimpleRange&, const SimpleRange&); 67 67 68 template<typename TreeType> bool isPointInRange(const SimpleRange&, const BoundaryPoint&); 69 template<typename TreeType> bool isPointInRange(const SimpleRange&, const Optional<BoundaryPoint>&); 68 70 WEBCORE_EXPORT bool isPointInRange(const SimpleRange&, const BoundaryPoint&); 69 71 bool isPointInRange(const SimpleRange&, const Optional<BoundaryPoint>&); 70 72 71 73 WEBCORE_EXPORT bool contains(const SimpleRange& outerRange, const SimpleRange& innerRange); 74 template<typename TreeType> bool intersects(const SimpleRange&, const SimpleRange&); 72 75 WEBCORE_EXPORT bool intersects(const SimpleRange&, const SimpleRange&); 73 76 WEBCORE_EXPORT SimpleRange unionRange(const SimpleRange&, const SimpleRange&); … … 75 78 76 79 WEBCORE_EXPORT bool contains(const SimpleRange&, const Node&); 80 template<typename TreeType> bool intersects(const SimpleRange&, const Node&); 77 81 WEBCORE_EXPORT bool intersects(const SimpleRange&, const Node&); 78 82 79 83 // Returns equivalent if point is in range. 84 template<typename TreeType = Tree> PartialOrdering treeOrder(const SimpleRange&, const BoundaryPoint&); 85 template<typename TreeType = Tree> PartialOrdering treeOrder(const BoundaryPoint&, const SimpleRange&); 80 86 WEBCORE_EXPORT PartialOrdering documentOrder(const SimpleRange&, const BoundaryPoint&); 81 87 WEBCORE_EXPORT PartialOrdering documentOrder(const BoundaryPoint&, const SimpleRange&);
Note:
See TracChangeset
for help on using the changeset viewer.