mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-04 23:30:20 +00:00
LibWeb: Modify range start & end directly where applicable
We were calling into `Range::set_start_or_end()` indirectly through `::set_start()` and `::set_end()`, but that algorithm only calls for an invocation whenever the start or end of a range needs to be set to a boundary point. If an algorithm step calls for setting the node or offset, we should directly modify the range. The problem with calling into `::set_start_or_end()` is that this algorithm potentially modifies _both_ the start and end of the range, but algorithms trying to update a range's start or end often have explicit steps to take both the start and end into account and end up overcompensating for the start or end offset resulting in an invalid range (e.g. with an end offset beyond a node's length). This makes updating a range's start/end a bit more efficient and removes a piece of ad-hoc code in CharacterData needed to make it work before.
This commit is contained in:
parent
e2db9790b0
commit
0d83426a49
Notes:
github-actions[bot]
2025-05-15 10:45:47 +00:00
Author: https://github.com/gmta
Commit: 0d83426a49
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/4734
Reviewed-by: https://github.com/tcl3 ✅
5 changed files with 112 additions and 95 deletions
|
@ -2,7 +2,7 @@
|
|||
* Copyright (c) 2018-2024, Andreas Kling <andreas@ladybird.org>
|
||||
* Copyright (c) 2021-2022, Linus Groh <linusg@serenityos.org>
|
||||
* Copyright (c) 2021, Luke Wilde <lukew@serenityos.org>
|
||||
* Copyright (c) 2024, Jelle Raaijmakers <jelle@ladybird.org>
|
||||
* Copyright (c) 2024-2025, Jelle Raaijmakers <jelle@ladybird.org>
|
||||
* Copyright (c) 2025, Shannon Booth <shannon@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
|
@ -299,28 +299,40 @@ WebIDL::ExceptionOr<void> Node::normalize()
|
|||
|
||||
// 6. While currentNode is an exclusive Text node:
|
||||
while (current_node && current_node->is_exclusive_text()) {
|
||||
// 1. For each live range whose start node is currentNode, add length to its start offset and set its start node to node.
|
||||
// 1. For each live range whose start node is currentNode, add length to its start offset and set its start
|
||||
// node to node.
|
||||
for (auto& range : Range::live_ranges()) {
|
||||
if (range->start_container() == current_node)
|
||||
TRY(range->set_start(node, range->start_offset() + length));
|
||||
if (range->start_container() == current_node) {
|
||||
range->increase_start_offset(length);
|
||||
range->set_start_node(node);
|
||||
}
|
||||
}
|
||||
|
||||
// 2. For each live range whose end node is currentNode, add length to its end offset and set its end node to node.
|
||||
// 2. For each live range whose end node is currentNode, add length to its end offset and set its end node
|
||||
// to node.
|
||||
for (auto& range : Range::live_ranges()) {
|
||||
if (range->end_container() == current_node)
|
||||
TRY(range->set_end(node, range->end_offset() + length));
|
||||
if (range->end_container() == current_node) {
|
||||
range->increase_end_offset(length);
|
||||
range->set_end_node(node);
|
||||
}
|
||||
}
|
||||
|
||||
// 3. For each live range whose start node is currentNode’s parent and start offset is currentNode’s index, set its start node to node and its start offset to length.
|
||||
// 3. For each live range whose start node is currentNode’s parent and start offset is currentNode’s index,
|
||||
// set its start node to node and its start offset to length.
|
||||
for (auto& range : Range::live_ranges()) {
|
||||
if (range->start_container() == current_node->parent() && range->start_offset() == current_node->index())
|
||||
TRY(range->set_start(node, length));
|
||||
if (range->start_container() == current_node->parent() && range->start_offset() == current_node->index()) {
|
||||
range->set_start_node(node);
|
||||
range->set_start_offset(length);
|
||||
}
|
||||
}
|
||||
|
||||
// 4. For each live range whose end node is currentNode’s parent and end offset is currentNode’s index, set its end node to node and its end offset to length.
|
||||
// 4. For each live range whose end node is currentNode’s parent and end offset is currentNode’s index, set
|
||||
// its end node to node and its end offset to length.
|
||||
for (auto& range : Range::live_ranges()) {
|
||||
if (range->end_container() == current_node->parent() && range->end_offset() == current_node->index())
|
||||
TRY(range->set_end(node, length));
|
||||
if (range->end_container() == current_node->parent() && range->end_offset() == current_node->index()) {
|
||||
range->set_end_node(node);
|
||||
range->set_end_offset(length);
|
||||
}
|
||||
}
|
||||
|
||||
// 5. Add currentNode’s length to length.
|
||||
|
@ -681,16 +693,18 @@ void Node::insert_before(GC::Ref<Node> node, GC::Ptr<Node> child, bool suppress_
|
|||
|
||||
// 5. If child is non-null, then:
|
||||
if (child) {
|
||||
// 1. For each live range whose start node is parent and start offset is greater than child’s index, increase its start offset by count.
|
||||
// 1. For each live range whose start node is parent and start offset is greater than child’s index, increase
|
||||
// its start offset by count.
|
||||
for (auto& range : Range::live_ranges()) {
|
||||
if (range->start_container() == this && range->start_offset() > child->index())
|
||||
range->increase_start_offset({}, count);
|
||||
range->increase_start_offset(count);
|
||||
}
|
||||
|
||||
// 2. For each live range whose end node is parent and end offset is greater than child’s index, increase its end offset by count.
|
||||
// 2. For each live range whose end node is parent and end offset is greater than child’s index, increase its
|
||||
// end offset by count.
|
||||
for (auto& range : Range::live_ranges()) {
|
||||
if (range->end_container() == this && range->end_offset() > child->index())
|
||||
range->increase_end_offset({}, count);
|
||||
range->increase_end_offset(count);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -866,27 +880,28 @@ void Node::live_range_pre_remove()
|
|||
auto index = this->index();
|
||||
|
||||
// 4. For each live range whose start node is an inclusive descendant of node, set its start to (parent, index).
|
||||
for (auto& range : Range::live_ranges()) {
|
||||
for (auto* range : Range::live_ranges()) {
|
||||
if (range->start_container()->is_inclusive_descendant_of(*this))
|
||||
MUST(range->set_start(*parent, index));
|
||||
}
|
||||
|
||||
// 5. For each live range whose end node is an inclusive descendant of node, set its end to (parent, index).
|
||||
for (auto& range : Range::live_ranges()) {
|
||||
for (auto* range : Range::live_ranges()) {
|
||||
if (range->end_container()->is_inclusive_descendant_of(*this))
|
||||
MUST(range->set_end(*parent, index));
|
||||
}
|
||||
|
||||
// 6. For each live range whose start node is parent and start offset is greater than index, decrease its start offset by 1.
|
||||
for (auto& range : Range::live_ranges()) {
|
||||
// 6. For each live range whose start node is parent and start offset is greater than index, decrease its start
|
||||
// offset by 1.
|
||||
for (auto* range : Range::live_ranges()) {
|
||||
if (range->start_container() == parent && range->start_offset() > index)
|
||||
range->decrease_start_offset({}, 1);
|
||||
range->decrease_start_offset(1);
|
||||
}
|
||||
|
||||
// 7. For each live range whose end node is parent and end offset is greater than index, decrease its end offset by 1.
|
||||
for (auto& range : Range::live_ranges()) {
|
||||
for (auto* range : Range::live_ranges()) {
|
||||
if (range->end_container() == parent && range->end_offset() > index)
|
||||
range->decrease_end_offset({}, 1);
|
||||
range->decrease_end_offset(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1259,16 +1274,18 @@ WebIDL::ExceptionOr<void> Node::move_node(Node& new_parent, Node* child)
|
|||
|
||||
// 17. If child is non-null:
|
||||
if (child) {
|
||||
// 1. For each live range whose start node is newParent and start offset is greater than child’s index, increase its start offset by 1.
|
||||
// 1. For each live range whose start node is newParent and start offset is greater than child’s index, increase
|
||||
// its start offset by 1.
|
||||
for (auto& range : Range::live_ranges()) {
|
||||
if (range->start_container() == &new_parent && range->start_offset() > child->index())
|
||||
range->increase_start_offset({}, 1);
|
||||
range->increase_start_offset(1);
|
||||
}
|
||||
|
||||
// 2. For each live range whose end node is newParent and end offset is greater than child’s index, increase its end offset by 1.
|
||||
// 2. For each live range whose end node is newParent and end offset is greater than child’s index, increase its
|
||||
// end offset by 1.
|
||||
for (auto& range : Range::live_ranges()) {
|
||||
if (range->end_container() == &new_parent && range->end_offset() > child->index())
|
||||
range->increase_end_offset({}, 1);
|
||||
range->increase_end_offset(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue