mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-21 09:49:21 +00:00
LibWeb: Move selection state from layout tree to paint tree
Where we paint the selection is obviously paint-related information, so let's keep it in the paint tree.
This commit is contained in:
parent
d18a5b904d
commit
1987318cc2
Notes:
sideshowbarker
2024-07-17 11:29:41 +09:00
Author: https://github.com/awesomekling
Commit: 1987318cc2
Pull-request: https://github.com/SerenityOS/serenity/pull/23626
9 changed files with 100 additions and 98 deletions
|
@ -20,77 +20,6 @@ Viewport::Viewport(DOM::Document& document, NonnullRefPtr<CSS::StyleProperties>
|
|||
|
||||
Viewport::~Viewport() = default;
|
||||
|
||||
JS::GCPtr<Selection::Selection> Viewport::selection() const
|
||||
{
|
||||
return const_cast<DOM::Document&>(document()).get_selection();
|
||||
}
|
||||
|
||||
void Viewport::recompute_selection_states()
|
||||
{
|
||||
// 1. Start by resetting the selection state of all layout nodes to None.
|
||||
for_each_in_inclusive_subtree([&](auto& layout_node) {
|
||||
layout_node.set_selection_state(SelectionState::None);
|
||||
return IterationDecision::Continue;
|
||||
});
|
||||
|
||||
// 2. If there is no active Selection or selected Range, return.
|
||||
auto selection = document().get_selection();
|
||||
if (!selection)
|
||||
return;
|
||||
auto range = selection->range();
|
||||
if (!range)
|
||||
return;
|
||||
|
||||
auto* start_container = range->start_container();
|
||||
auto* end_container = range->end_container();
|
||||
|
||||
// 3. If the selection starts and ends in the same node:
|
||||
if (start_container == end_container) {
|
||||
// 1. If the selection starts and ends at the same offset, return.
|
||||
if (range->start_offset() == range->end_offset()) {
|
||||
// NOTE: A zero-length selection should not be visible.
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. If it's a text node, mark it as StartAndEnd and return.
|
||||
if (is<DOM::Text>(*start_container)) {
|
||||
if (auto* layout_node = start_container->layout_node()) {
|
||||
layout_node->set_selection_state(SelectionState::StartAndEnd);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (start_container == end_container && is<DOM::Text>(*start_container)) {
|
||||
if (auto* layout_node = start_container->layout_node()) {
|
||||
layout_node->set_selection_state(SelectionState::StartAndEnd);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 4. Mark the selection start node as Start (if text) or Full (if anything else).
|
||||
if (auto* layout_node = start_container->layout_node()) {
|
||||
if (is<DOM::Text>(*start_container))
|
||||
layout_node->set_selection_state(SelectionState::Start);
|
||||
else
|
||||
layout_node->set_selection_state(SelectionState::Full);
|
||||
}
|
||||
|
||||
// 5. Mark the selection end node as End (if text) or Full (if anything else).
|
||||
if (auto* layout_node = end_container->layout_node()) {
|
||||
if (is<DOM::Text>(*end_container))
|
||||
layout_node->set_selection_state(SelectionState::End);
|
||||
else
|
||||
layout_node->set_selection_state(SelectionState::Full);
|
||||
}
|
||||
|
||||
// 6. Mark the nodes between start node and end node (in tree order) as Full.
|
||||
for (auto* node = start_container->next_in_pre_order(); node && node != end_container; node = node->next_in_pre_order()) {
|
||||
if (auto* layout_node = node->layout_node())
|
||||
layout_node->set_selection_state(SelectionState::Full);
|
||||
}
|
||||
}
|
||||
|
||||
JS::GCPtr<Painting::Paintable> Viewport::create_paintable() const
|
||||
{
|
||||
return Painting::ViewportPaintable::create(*this);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue