diff --git a/Libraries/LibWeb/DOM/AbstractRange.h b/Libraries/LibWeb/DOM/AbstractRange.h index 9b54702f42b86..cbcfdd6797b7e 100644 --- a/Libraries/LibWeb/DOM/AbstractRange.h +++ b/Libraries/LibWeb/DOM/AbstractRange.h @@ -13,6 +13,12 @@ namespace Web::DOM { +// https://dom.spec.whatwg.org/#concept-range-bp +struct BoundaryPoint { + GC::Ref node; + WebIDL::UnsignedLong offset; +}; + // https://dom.spec.whatwg.org/#abstractrange class AbstractRange : public Bindings::PlatformObject { WEB_PLATFORM_OBJECT(AbstractRange, Bindings::PlatformObject); @@ -20,9 +26,11 @@ class AbstractRange : public Bindings::PlatformObject { public: virtual ~AbstractRange() override; + BoundaryPoint start() const { return { m_start_container, m_start_offset }; } GC::Ref start_container() const { return m_start_container; } WebIDL::UnsignedLong start_offset() const { return m_start_offset; } + BoundaryPoint end() const { return { m_end_container, m_end_offset }; } GC::Ref end_container() const { return m_end_container; } WebIDL::UnsignedLong end_offset() const { return m_end_offset; } diff --git a/Libraries/LibWeb/DOM/Range.cpp b/Libraries/LibWeb/DOM/Range.cpp index 91c103b6536ed..1c1dc239c9391 100644 --- a/Libraries/LibWeb/DOM/Range.cpp +++ b/Libraries/LibWeb/DOM/Range.cpp @@ -117,27 +117,27 @@ GC::Ref Range::root() const } // https://dom.spec.whatwg.org/#concept-range-bp-position -RelativeBoundaryPointPosition position_of_boundary_point_relative_to_other_boundary_point(GC::Ref node_a, u32 offset_a, GC::Ref node_b, u32 offset_b) +RelativeBoundaryPointPosition position_of_boundary_point_relative_to_other_boundary_point(BoundaryPoint a, BoundaryPoint b) { // 1. Assert: nodeA and nodeB have the same root. // NOTE: Nodes may not share the same root if they belong to different shadow trees, // so we assert that they share the same shadow-including root instead. - VERIFY(&node_a->shadow_including_root() == &node_b->shadow_including_root()); + VERIFY(&a.node->shadow_including_root() == &b.node->shadow_including_root()); // 2. If nodeA is nodeB, then return equal if offsetA is offsetB, before if offsetA is less than offsetB, and after if offsetA is greater than offsetB. - if (node_a == node_b) { - if (offset_a == offset_b) + if (a.node == b.node) { + if (a.offset == b.offset) return RelativeBoundaryPointPosition::Equal; - if (offset_a < offset_b) + if (a.offset < b.offset) return RelativeBoundaryPointPosition::Before; return RelativeBoundaryPointPosition::After; } // 3. If nodeA is following nodeB, then if the position of (nodeB, offsetB) relative to (nodeA, offsetA) is before, return after, and if it is after, return before. - if (node_a->is_following(node_b)) { - auto relative_position = position_of_boundary_point_relative_to_other_boundary_point(node_b, offset_b, node_a, offset_a); + if (a.node->is_following(b.node)) { + auto relative_position = position_of_boundary_point_relative_to_other_boundary_point(b, a); if (relative_position == RelativeBoundaryPointPosition::Before) return RelativeBoundaryPointPosition::After; @@ -147,19 +147,19 @@ RelativeBoundaryPointPosition position_of_boundary_point_relative_to_other_bound } // 4. If nodeA is an ancestor of nodeB: - if (node_a->is_ancestor_of(node_b)) { + if (a.node->is_ancestor_of(b.node)) { // 1. Let child be nodeB. - GC::Ref child = node_b; + GC::Ref child = b.node; // 2. While child is not a child of nodeA, set child to its parent. - while (!node_a->is_parent_of(child)) { + while (!a.node->is_parent_of(child)) { auto* parent = child->parent(); VERIFY(parent); child = *parent; } // 3. If child’s index is less than offsetA, then return after. - if (child->index() < offset_a) + if (child->index() < a.offset) return RelativeBoundaryPointPosition::After; } @@ -185,7 +185,7 @@ WebIDL::ExceptionOr Range::set_start_or_end(GC::Ref node, u32 offset // -> If these steps were invoked as "set the start" // 1. If range’s root is not equal to node’s root, or if bp is after the range’s end, set range’s end to bp. - if (root().ptr() != &node->root() || position_of_boundary_point_relative_to_other_boundary_point(node, offset, m_end_container, m_end_offset) == RelativeBoundaryPointPosition::After) { + if (root().ptr() != &node->root() || position_of_boundary_point_relative_to_other_boundary_point({ node, offset }, end()) == RelativeBoundaryPointPosition::After) { m_end_container = node; m_end_offset = offset; } @@ -198,7 +198,7 @@ WebIDL::ExceptionOr Range::set_start_or_end(GC::Ref node, u32 offset VERIFY(start_or_end == StartOrEnd::End); // 1. If range’s root is not equal to node’s root, or if bp is before the range’s start, set range’s start to bp. - if (root().ptr() != &node->root() || position_of_boundary_point_relative_to_other_boundary_point(node, offset, m_start_container, m_start_offset) == RelativeBoundaryPointPosition::Before) { + if (root().ptr() != &node->root() || position_of_boundary_point_relative_to_other_boundary_point({ node, offset }, start()) == RelativeBoundaryPointPosition::Before) { m_start_container = node; m_start_offset = offset; } @@ -349,7 +349,7 @@ WebIDL::ExceptionOr Range::compare_boundary_points(WebIDL::Unsign VERIFY(other_point_node); // 4. If the position of this point relative to other point is - auto relative_position = position_of_boundary_point_relative_to_other_boundary_point(*this_point_node, this_point_offset, *other_point_node, other_point_offset); + auto relative_position = position_of_boundary_point_relative_to_other_boundary_point({ *this_point_node, this_point_offset }, { *other_point_node, other_point_offset }); switch (relative_position) { case RelativeBoundaryPointPosition::Before: // -> before @@ -492,11 +492,11 @@ bool Range::intersects_node(GC::Ref node) const return true; // 4. Let offset be node’s index. - auto offset = node->index(); + WebIDL::UnsignedLong offset = node->index(); // 5. If (parent, offset) is before end and (parent, offset plus 1) is after start, return true - auto relative_position_to_end = position_of_boundary_point_relative_to_other_boundary_point(*parent, offset, m_end_container, m_end_offset); - auto relative_position_to_start = position_of_boundary_point_relative_to_other_boundary_point(*parent, offset + 1, m_start_container, m_start_offset); + auto relative_position_to_end = position_of_boundary_point_relative_to_other_boundary_point({ *parent, offset }, end()); + auto relative_position_to_start = position_of_boundary_point_relative_to_other_boundary_point({ *parent, offset + 1 }, start()); if (relative_position_to_end == RelativeBoundaryPointPosition::Before && relative_position_to_start == RelativeBoundaryPointPosition::After) return true; @@ -520,8 +520,8 @@ WebIDL::ExceptionOr Range::is_point_in_range(GC::Ref node, WebIDL::U return WebIDL::IndexSizeError::create(realm(), MUST(String::formatted("Node does not contain a child at offset {}", offset))); // 4. If (node, offset) is before start or after end, return false. - auto relative_position_to_start = position_of_boundary_point_relative_to_other_boundary_point(node, offset, m_start_container, m_start_offset); - auto relative_position_to_end = position_of_boundary_point_relative_to_other_boundary_point(node, offset, m_end_container, m_end_offset); + auto relative_position_to_start = position_of_boundary_point_relative_to_other_boundary_point({ node, offset }, start()); + auto relative_position_to_end = position_of_boundary_point_relative_to_other_boundary_point({ node, offset }, end()); if (relative_position_to_start == RelativeBoundaryPointPosition::Before || relative_position_to_end == RelativeBoundaryPointPosition::After) return false; @@ -545,12 +545,12 @@ WebIDL::ExceptionOr Range::compare_point(GC::Ref node, WebI return WebIDL::IndexSizeError::create(realm(), MUST(String::formatted("Node does not contain a child at offset {}", offset))); // 4. If (node, offset) is before start, return −1. - auto relative_position_to_start = position_of_boundary_point_relative_to_other_boundary_point(node, offset, m_start_container, m_start_offset); + auto relative_position_to_start = position_of_boundary_point_relative_to_other_boundary_point({ node, offset }, start()); if (relative_position_to_start == RelativeBoundaryPointPosition::Before) return -1; // 5. If (node, offset) is after end, return 1. - auto relative_position_to_end = position_of_boundary_point_relative_to_other_boundary_point(node, offset, m_end_container, m_end_offset); + auto relative_position_to_end = position_of_boundary_point_relative_to_other_boundary_point({ node, offset }, end()); if (relative_position_to_end == RelativeBoundaryPointPosition::After) return 1; @@ -794,11 +794,11 @@ bool Range::contains_node(GC::Ref node) const return false; // and (node, 0) is after range’s start, - if (position_of_boundary_point_relative_to_other_boundary_point(node, 0, m_start_container, m_start_offset) != RelativeBoundaryPointPosition::After) + if (position_of_boundary_point_relative_to_other_boundary_point({ node, 0 }, start()) != RelativeBoundaryPointPosition::After) return false; // and (node, node’s length) is before range’s end. - if (position_of_boundary_point_relative_to_other_boundary_point(node, node->length(), m_end_container, m_end_offset) != RelativeBoundaryPointPosition::Before) + if (position_of_boundary_point_relative_to_other_boundary_point({ node, static_cast(node->length()) }, end()) != RelativeBoundaryPointPosition::Before) return false; return true; diff --git a/Libraries/LibWeb/DOM/Range.h b/Libraries/LibWeb/DOM/Range.h index 393d039a1d57f..cd59a5121b5ea 100644 --- a/Libraries/LibWeb/DOM/Range.h +++ b/Libraries/LibWeb/DOM/Range.h @@ -22,7 +22,7 @@ enum class RelativeBoundaryPointPosition { }; // https://dom.spec.whatwg.org/#concept-range-bp-position -RelativeBoundaryPointPosition position_of_boundary_point_relative_to_other_boundary_point(GC::Ref node_a, u32 offset_a, GC::Ref node_b, u32 offset_b); +RelativeBoundaryPointPosition position_of_boundary_point_relative_to_other_boundary_point(BoundaryPoint a, BoundaryPoint b); class Range final : public AbstractRange { WEB_PLATFORM_OBJECT(Range, AbstractRange); diff --git a/Libraries/LibWeb/Editing/Commands.cpp b/Libraries/LibWeb/Editing/Commands.cpp index 3ee882bf3b6be..af7fd8b2c61cb 100644 --- a/Libraries/LibWeb/Editing/Commands.cpp +++ b/Libraries/LibWeb/Editing/Commands.cpp @@ -65,7 +65,7 @@ bool command_delete_action(DOM::Document& document, String const&) } // 2. Canonicalize whitespace at the active range's start. - canonicalize_whitespace(active_range.start_container(), active_range.start_offset()); + canonicalize_whitespace(active_range.start()); // 3. Let node and offset be the active range's start node and offset. GC::Ptr node = active_range.start_container(); diff --git a/Libraries/LibWeb/Editing/Internal/Algorithms.cpp b/Libraries/LibWeb/Editing/Internal/Algorithms.cpp index 5298fc81471cd..a5fccd35161b8 100644 --- a/Libraries/LibWeb/Editing/Internal/Algorithms.cpp +++ b/Libraries/LibWeb/Editing/Internal/Algorithms.cpp @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include @@ -59,7 +58,7 @@ GC::Ref block_extend_a_range(DOM::Range& range) } // 3. If (start node, start offset) is not a block start point, repeat the following steps: - if (!is_block_start_point(*start_node, start_offset)) { + if (!is_block_start_point({ *start_node, start_offset })) { do { // 1. If start offset is zero, set it to start node's index, then set start node to its parent. if (start_offset == 0) { @@ -73,7 +72,7 @@ GC::Ref block_extend_a_range(DOM::Range& range) } // 3. If (start node, start offset) is a block boundary point, break from this loop. - } while (!is_block_boundary_point(*start_node, start_offset)); + } while (!is_block_boundary_point({ *start_node, start_offset })); } // 4. While start offset is zero and start node's parent is not null, set start offset to start node's index, then @@ -96,7 +95,7 @@ GC::Ref block_extend_a_range(DOM::Range& range) } // 6. If (end node, end offset) is not a block end point, repeat the following steps: - if (!is_block_end_point(*end_node, end_offset)) { + if (!is_block_end_point({ *end_node, end_offset })) { do { // 1. If end offset is end node's length, set it to one plus end node's index, then set end node to its // parent. @@ -111,7 +110,7 @@ GC::Ref block_extend_a_range(DOM::Range& range) } // 3. If (end node, end offset) is a block boundary point, break from this loop. - } while (!is_block_boundary_point(*end_node, end_offset)); + } while (!is_block_boundary_point({ *end_node, end_offset })); } // 7. While end offset is end node's length and end node's parent is not null, set end offset to one plus end node's @@ -221,8 +220,11 @@ String canonical_space_sequence(u32 length, bool non_breaking_start, bool non_br } // https://w3c.github.io/editing/docs/execCommand/#canonicalize-whitespace -void canonicalize_whitespace(GC::Ref node, u32 offset, bool fix_collapsed_space) +void canonicalize_whitespace(DOM::BoundaryPoint boundary, bool fix_collapsed_space) { + auto node = boundary.node; + auto offset = boundary.offset; + // 1. If node is neither editable nor an editing host, abort these steps. if (!node->is_editable_or_editing_host()) return; @@ -348,7 +350,7 @@ void canonicalize_whitespace(GC::Ref node, u32 offset, bool fix_colla // end offset): if (fix_collapsed_space) { while (true) { - auto relative_position = position_of_boundary_point_relative_to_other_boundary_point(*start_node, start_offset, *end_node, end_offset); + auto relative_position = DOM::position_of_boundary_point_relative_to_other_boundary_point({ *start_node, start_offset }, { *end_node, end_offset }); if (relative_position != DOM::RelativeBoundaryPointPosition::Before) break; @@ -407,7 +409,7 @@ void canonicalize_whitespace(GC::Ref node, u32 offset, bool fix_colla // 10. While (start node, start offset) is before (end node, end offset): while (true) { - auto relative_position = position_of_boundary_point_relative_to_other_boundary_point(start_node, start_offset, end_node, end_offset); + auto relative_position = DOM::position_of_boundary_point_relative_to_other_boundary_point({ start_node, start_offset }, { end_node, end_offset }); if (relative_position != DOM::RelativeBoundaryPointPosition::Before) break; @@ -467,19 +469,19 @@ void delete_the_selection(Selection& selection, bool block_merging, bool strip_w return; // 2. Canonicalize whitespace at the active range's start. - canonicalize_whitespace(active_range()->start_container(), active_range()->start_offset()); + canonicalize_whitespace(active_range()->start()); // 3. Canonicalize whitespace at the active range's end. - canonicalize_whitespace(active_range()->end_container(), active_range()->end_offset()); + canonicalize_whitespace(active_range()->end()); // 4. Let (start node, start offset) be the last equivalent point for the active range's start. - auto start = last_equivalent_point({ active_range()->start_container(), active_range()->start_offset() }); + auto start = last_equivalent_point(active_range()->start()); // 5. Let (end node, end offset) be the first equivalent point for the active range's end. - auto end = first_equivalent_point({ active_range()->end_container(), active_range()->end_offset() }); + auto end = first_equivalent_point(active_range()->end()); // 6. If (end node, end offset) is not after (start node, start offset): - auto relative_position = position_of_boundary_point_relative_to_other_boundary_point(end.node, end.offset, start.node, start.offset); + auto relative_position = DOM::position_of_boundary_point_relative_to_other_boundary_point({ end.node, end.offset }, { start.node, start.offset }); if (relative_position != DOM::RelativeBoundaryPointPosition::After) { // 1. If direction is "forward", call collapseToStart() on the context object's selection. if (direction == Selection::Direction::Forwards) { @@ -558,7 +560,7 @@ void delete_the_selection(Selection& selection, bool block_merging, bool strip_w MUST(static_cast(*start.node).delete_data(start.offset, end.offset - start.offset)); // 2. Canonicalize whitespace at (start node, start offset), with fix collapsed space false. - canonicalize_whitespace(start.node, start.offset, false); + canonicalize_whitespace(start, false); // 3. If direction is "forward", call collapseToStart() on the context object's selection. if (direction == Selection::Direction::Forwards) { @@ -636,10 +638,10 @@ void delete_the_selection(Selection& selection, bool block_merging, bool strip_w MUST(static_cast(*end.node).delete_data(0, end.offset)); // 27. Canonicalize whitespace at the active range's start, with fix collapsed space false. - canonicalize_whitespace(active_range()->start_container(), active_range()->start_offset(), false); + canonicalize_whitespace(active_range()->start(), false); // 28. Canonicalize whitespace at the active range's end, with fix collapsed space false. - canonicalize_whitespace(active_range()->end_container(), active_range()->end_offset(), false); + canonicalize_whitespace(active_range()->end(), false); // 30. If block merging is false, or start block or end block is null, or start block is not in the same editing // host as end block, or start block and end block are the same: @@ -1043,7 +1045,7 @@ Optional effective_command_value(GC::Ptr node, FlyString cons } // https://w3c.github.io/editing/docs/execCommand/#first-equivalent-point -BoundaryPoint first_equivalent_point(BoundaryPoint boundary_point) +DOM::BoundaryPoint first_equivalent_point(DOM::BoundaryPoint boundary_point) { // 1. While (node, offset)'s previous equivalent point is not null, set (node, offset) to its previous equivalent // point. @@ -1143,10 +1145,10 @@ void fix_disallowed_ancestors_of_node(GC::Ref node) bool follows_a_line_break(GC::Ref node) { // 1. Let offset be zero. - auto offset = 0; + auto offset = 0u; // 2. While (node, offset) is not a block boundary point: - while (!is_block_boundary_point(node, offset)) { + while (!is_block_boundary_point({ node, offset })) { // 1. If node has a visible child with index offset minus one, return false. auto* offset_minus_one_child = node->child_at_index(offset - 1); if (offset_minus_one_child && is_visible_node(*offset_minus_one_child)) @@ -1382,22 +1384,22 @@ bool is_allowed_child_of_node(Variant, FlyString> child, Vari } // https://w3c.github.io/editing/docs/execCommand/#block-boundary-point -bool is_block_boundary_point(GC::Ref node, u32 offset) +bool is_block_boundary_point(DOM::BoundaryPoint boundary_point) { // A boundary point is a block boundary point if it is either a block start point or a block end point. - return is_block_start_point(node, offset) || is_block_end_point(node, offset); + return is_block_start_point(boundary_point) || is_block_end_point(boundary_point); } // https://w3c.github.io/editing/docs/execCommand/#block-end-point -bool is_block_end_point(GC::Ref node, u32 offset) +bool is_block_end_point(DOM::BoundaryPoint boundary_point) { // A boundary point (node, offset) is a block end point if either node's parent is null and // offset is node's length; - if (!node->parent() && offset == node->length()) + if (!boundary_point.node->parent() && boundary_point.offset == boundary_point.node->length()) return true; // or node has a child with index offset, and that child is a visible block node. - auto offset_child = node->child_at_index(offset); + auto offset_child = boundary_point.node->child_at_index(boundary_point.offset); return offset_child && is_visible_node(*offset_child) && is_block_node(*offset_child); } @@ -1417,19 +1419,17 @@ bool is_block_node(GC::Ref node) } // https://w3c.github.io/editing/docs/execCommand/#block-start-point -bool is_block_start_point(GC::Ref node, u32 offset) +bool is_block_start_point(DOM::BoundaryPoint boundary_point) { // A boundary point (node, offset) is a block start point if either node's parent is null and // offset is zero; - if (!node->parent() && offset == 0) + if (!boundary_point.node->parent() && boundary_point.offset == 0) return true; // or node has a child with index offset − 1, and that child is either a visible block node or a // visible br. - auto offset_minus_one_child = node->child_at_index(offset - 1); - if (!offset_minus_one_child) - return false; - return is_visible_node(*offset_minus_one_child) + auto offset_minus_one_child = boundary_point.node->child_at_index(boundary_point.offset - 1); + return offset_minus_one_child && is_visible_node(*offset_minus_one_child) && (is_block_node(*offset_minus_one_child) || is(*offset_minus_one_child)); } @@ -1889,7 +1889,7 @@ bool is_whitespace_node(GC::Ref node) } // https://w3c.github.io/editing/docs/execCommand/#last-equivalent-point -BoundaryPoint last_equivalent_point(BoundaryPoint boundary_point) +DOM::BoundaryPoint last_equivalent_point(DOM::BoundaryPoint boundary_point) { // 1. While (node, offset)'s next equivalent point is not null, set (node, offset) to its next equivalent point. while (true) { @@ -1937,7 +1937,7 @@ void move_node_preserving_ranges(GC::Ref node, GC::Ref new } // https://w3c.github.io/editing/docs/execCommand/#next-equivalent-point -Optional next_equivalent_point(BoundaryPoint boundary_point) +Optional next_equivalent_point(DOM::BoundaryPoint boundary_point) { // 1. If node's length is zero, return null. auto node = boundary_point.node; @@ -1948,13 +1948,13 @@ Optional next_equivalent_point(BoundaryPoint boundary_point) // 3. If offset is node's length, and node's parent is not null, and node is an inline node, return (node's parent, // 1 + node's index). if (boundary_point.offset == node_length && node->parent() && is_inline_node(*node)) - return BoundaryPoint { *node->parent(), static_cast(node->index() + 1) }; + return DOM::BoundaryPoint { *node->parent(), static_cast(node->index() + 1) }; // 5. If node has a child with index offset, and that child's length is not zero, and that child is an inline node, // return (that child, 0). auto child_at_offset = node->child_at_index(boundary_point.offset); if (child_at_offset && child_at_offset->length() != 0 && is_inline_node(*child_at_offset)) - return BoundaryPoint { *child_at_offset, 0 }; + return DOM::BoundaryPoint { *child_at_offset, 0 }; // 7. Return null. return {}; @@ -2010,10 +2010,10 @@ void normalize_sublists_in_node(GC::Ref item) bool precedes_a_line_break(GC::Ref node) { // 1. Let offset be node's length. - auto offset = node->length(); + WebIDL::UnsignedLong offset = node->length(); // 2. While (node, offset) is not a block boundary point: - while (!is_block_boundary_point(node, offset)) { + while (!is_block_boundary_point({ node, offset })) { // 1. If node has a visible child with index offset, return false. auto* offset_child = node->child_at_index(offset); if (offset_child && is_visible_node(*offset_child)) @@ -2038,7 +2038,7 @@ bool precedes_a_line_break(GC::Ref node) } // https://w3c.github.io/editing/docs/execCommand/#previous-equivalent-point -Optional previous_equivalent_point(BoundaryPoint boundary_point) +Optional previous_equivalent_point(DOM::BoundaryPoint boundary_point) { // 1. If node's length is zero, return null. auto node = boundary_point.node; @@ -2049,13 +2049,13 @@ Optional previous_equivalent_point(BoundaryPoint boundary_point) // 2. If offset is 0, and node's parent is not null, and node is an inline node, return (node's parent, node's // index). if (boundary_point.offset == 0 && node->parent() && is_inline_node(*node)) - return BoundaryPoint { *node->parent(), static_cast(node->index()) }; + return DOM::BoundaryPoint { *node->parent(), static_cast(node->index()) }; // 3. If node has a child with index offset − 1, and that child's length is not zero, and that child is an inline // node, return (that child, that child's length). auto child_at_offset = node->child_at_index(boundary_point.offset - 1); if (child_at_offset && child_at_offset->length() != 0 && is_inline_node(*child_at_offset)) - return BoundaryPoint { *child_at_offset, static_cast(child_at_offset->length()) }; + return DOM::BoundaryPoint { *child_at_offset, static_cast(child_at_offset->length()) }; // 4. Return null. return {}; diff --git a/Libraries/LibWeb/Editing/Internal/Algorithms.h b/Libraries/LibWeb/Editing/Internal/Algorithms.h index 5a81786cfcef4..ca37bb4e2e517 100644 --- a/Libraries/LibWeb/Editing/Internal/Algorithms.h +++ b/Libraries/LibWeb/Editing/Internal/Algorithms.h @@ -8,6 +8,7 @@ #include #include +#include #include namespace Web::Editing { @@ -27,32 +28,25 @@ struct RecordedOverride { using Selection::Selection; -// https://dom.spec.whatwg.org/#concept-range-bp -// FIXME: This should be defined by DOM::Range -struct BoundaryPoint { - GC::Ref node; - WebIDL::UnsignedLong offset; -}; - // Below algorithms are specified here: // https://w3c.github.io/editing/docs/execCommand/#assorted-common-algorithms GC::Ref block_extend_a_range(DOM::Range&); GC::Ptr block_node_of_node(GC::Ref); String canonical_space_sequence(u32 length, bool non_breaking_start, bool non_breaking_end); -void canonicalize_whitespace(GC::Ref, u32 offset, bool fix_collapsed_space = true); +void canonicalize_whitespace(DOM::BoundaryPoint, bool fix_collapsed_space = true); void delete_the_selection(Selection&, bool block_merging = true, bool strip_wrappers = true, Selection::Direction direction = Selection::Direction::Forwards); GC::Ptr editing_host_of_node(GC::Ref); Optional effective_command_value(GC::Ptr, FlyString const& command); -BoundaryPoint first_equivalent_point(BoundaryPoint); +DOM::BoundaryPoint first_equivalent_point(DOM::BoundaryPoint); void fix_disallowed_ancestors_of_node(GC::Ref); bool follows_a_line_break(GC::Ref); bool is_allowed_child_of_node(Variant, FlyString> child, Variant, FlyString> parent); -bool is_block_boundary_point(GC::Ref, u32 offset); -bool is_block_end_point(GC::Ref, u32 offset); +bool is_block_boundary_point(DOM::BoundaryPoint); +bool is_block_end_point(DOM::BoundaryPoint); bool is_block_node(GC::Ref); -bool is_block_start_point(GC::Ref, u32 offset); +bool is_block_start_point(DOM::BoundaryPoint); bool is_collapsed_block_prop(GC::Ref); bool is_collapsed_line_break(GC::Ref); bool is_collapsed_whitespace_node(GC::Ref); @@ -70,12 +64,12 @@ bool is_prohibited_paragraph_child_name(FlyString const&); bool is_single_line_container(GC::Ref); bool is_visible_node(GC::Ref); bool is_whitespace_node(GC::Ref); -BoundaryPoint last_equivalent_point(BoundaryPoint); +DOM::BoundaryPoint last_equivalent_point(DOM::BoundaryPoint); void move_node_preserving_ranges(GC::Ref, GC::Ref new_parent, u32 new_index); -Optional next_equivalent_point(BoundaryPoint); +Optional next_equivalent_point(DOM::BoundaryPoint); void normalize_sublists_in_node(GC::Ref); bool precedes_a_line_break(GC::Ref); -Optional previous_equivalent_point(BoundaryPoint); +Optional previous_equivalent_point(DOM::BoundaryPoint); Vector record_current_states_and_values(GC::Ref); Vector record_the_values_of_nodes(Vector> const&); void remove_extraneous_line_breaks_at_the_end_of_node(GC::Ref); diff --git a/Libraries/LibWeb/Selection/Selection.cpp b/Libraries/LibWeb/Selection/Selection.cpp index 3577056a07d4f..c005b0c67a8b4 100644 --- a/Libraries/LibWeb/Selection/Selection.cpp +++ b/Libraries/LibWeb/Selection/Selection.cpp @@ -296,7 +296,7 @@ WebIDL::ExceptionOr Selection::extend(GC::Ref node, unsigned of TRY(new_range->set_end(new_focus_node, new_focus_offset)); } // 6. Otherwise, if oldAnchor is before or equal to newFocus, set the start newRange's start to oldAnchor, then set its end to newFocus. - else if (position_of_boundary_point_relative_to_other_boundary_point(old_anchor_node, old_anchor_offset, new_focus_node, new_focus_offset) != DOM::RelativeBoundaryPointPosition::After) { + else if (DOM::position_of_boundary_point_relative_to_other_boundary_point({ old_anchor_node, old_anchor_offset }, { new_focus_node, new_focus_offset }) != DOM::RelativeBoundaryPointPosition::After) { TRY(new_range->set_start(old_anchor_node, old_anchor_offset)); TRY(new_range->set_end(new_focus_node, new_focus_offset)); } @@ -310,7 +310,7 @@ WebIDL::ExceptionOr Selection::extend(GC::Ref node, unsigned of set_range(new_range); // 9. If newFocus is before oldAnchor, set this's direction to backwards. Otherwise, set it to forwards. - if (position_of_boundary_point_relative_to_other_boundary_point(new_focus_node, new_focus_offset, old_anchor_node, old_anchor_offset) == DOM::RelativeBoundaryPointPosition::Before) { + if (DOM::position_of_boundary_point_relative_to_other_boundary_point({ new_focus_node, new_focus_offset }, { old_anchor_node, old_anchor_offset }) == DOM::RelativeBoundaryPointPosition::Before) { m_direction = Direction::Backwards; } else { m_direction = Direction::Forwards; @@ -339,7 +339,7 @@ WebIDL::ExceptionOr Selection::set_base_and_extent(GC::Ref anch auto new_range = DOM::Range::create(*m_document); // 5. If anchor is before focus, set the start the newRange's start to anchor and its end to focus. Otherwise, set the start them to focus and anchor respectively. - auto position_of_anchor_relative_to_focus = DOM::position_of_boundary_point_relative_to_other_boundary_point(anchor_node, anchor_offset, focus_node, focus_offset); + auto position_of_anchor_relative_to_focus = DOM::position_of_boundary_point_relative_to_other_boundary_point({ anchor_node, anchor_offset }, { focus_node, focus_offset }); if (position_of_anchor_relative_to_focus == DOM::RelativeBoundaryPointPosition::Before) { TRY(new_range->set_start(anchor_node, anchor_offset)); TRY(new_range->set_end(focus_node, focus_offset)); @@ -414,16 +414,8 @@ bool Selection::contains_node(GC::Ref node, bool allow_partial_contai // start of its range is before or visually equivalent to the first boundary point in the node // and end of its range is after or visually equivalent to the last boundary point in the node. if (!allow_partial_containment) { - auto start_relative_position = DOM::position_of_boundary_point_relative_to_other_boundary_point( - *m_range->start_container(), - m_range->start_offset(), - node, - 0); - auto end_relative_position = DOM::position_of_boundary_point_relative_to_other_boundary_point( - *m_range->end_container(), - m_range->end_offset(), - node, - node->length()); + auto start_relative_position = DOM::position_of_boundary_point_relative_to_other_boundary_point(m_range->start(), { node, 0 }); + auto end_relative_position = DOM::position_of_boundary_point_relative_to_other_boundary_point(m_range->end(), { node, static_cast(node->length()) }); return (start_relative_position == DOM::RelativeBoundaryPointPosition::Before || start_relative_position == DOM::RelativeBoundaryPointPosition::Equal) && (end_relative_position == DOM::RelativeBoundaryPointPosition::Equal || end_relative_position == DOM::RelativeBoundaryPointPosition::After); @@ -433,16 +425,8 @@ bool Selection::contains_node(GC::Ref node, bool allow_partial_contai // start of its range is before or visually equivalent to the last boundary point in the node // and end of its range is after or visually equivalent to the first boundary point in the node. - auto start_relative_position = DOM::position_of_boundary_point_relative_to_other_boundary_point( - *m_range->start_container(), - m_range->start_offset(), - node, - node->length()); - auto end_relative_position = DOM::position_of_boundary_point_relative_to_other_boundary_point( - *m_range->end_container(), - m_range->end_offset(), - node, - 0); + auto start_relative_position = DOM::position_of_boundary_point_relative_to_other_boundary_point(m_range->start(), { node, static_cast(node->length()) }); + auto end_relative_position = DOM::position_of_boundary_point_relative_to_other_boundary_point(m_range->end(), { node, 0 }); return (start_relative_position == DOM::RelativeBoundaryPointPosition::Before || start_relative_position == DOM::RelativeBoundaryPointPosition::Equal) && (end_relative_position == DOM::RelativeBoundaryPointPosition::Equal || end_relative_position == DOM::RelativeBoundaryPointPosition::After);