mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 00:57:45 +00:00
LibWeb: Remove is<BlockContainer> check for fragments in hit testing
This change introduces a method for direct access to the paintable of a PaintableFragment. This method is intended to replace the usage of the layout node pointer. Currently, we are only eliminating the use of `layout_node()` in hit testing. Additionally, we no longer check if a fragment's layout node is a `BlockContainer` before recursing into its children during hit testing. This check was likely relevant when all fragments were owned by `PaintableWithLines`, but now it should be safe to remove this check.
This commit is contained in:
parent
09124fc3a5
commit
270bbf43ab
3 changed files with 13 additions and 12 deletions
|
@ -163,13 +163,13 @@ void InlinePaintable::for_each_fragment(Callback callback) const
|
||||||
Optional<HitTestResult> InlinePaintable::hit_test(CSSPixelPoint position, HitTestType type) const
|
Optional<HitTestResult> InlinePaintable::hit_test(CSSPixelPoint position, HitTestType type) const
|
||||||
{
|
{
|
||||||
for (auto& fragment : m_fragments) {
|
for (auto& fragment : m_fragments) {
|
||||||
if (is<Layout::Box>(fragment.layout_node()) && static_cast<Layout::Box const&>(fragment.layout_node()).paintable_box()->stacking_context())
|
if (fragment.paintable().stacking_context())
|
||||||
continue;
|
continue;
|
||||||
auto fragment_absolute_rect = fragment.absolute_rect();
|
auto fragment_absolute_rect = fragment.absolute_rect();
|
||||||
if (fragment_absolute_rect.contains(position)) {
|
if (fragment_absolute_rect.contains(position)) {
|
||||||
if (is<Layout::BlockContainer>(fragment.layout_node()) && fragment.layout_node().paintable())
|
if (auto result = fragment.paintable().hit_test(position, type); result.has_value())
|
||||||
return fragment.layout_node().paintable()->hit_test(position, type);
|
return result;
|
||||||
return HitTestResult { const_cast<Paintable&>(const_cast<Paintable&>(*fragment.layout_node().paintable())),
|
return HitTestResult { const_cast<Paintable&>(fragment.paintable()),
|
||||||
fragment.text_index_at(position.x()) };
|
fragment.text_index_at(position.x()) };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -752,17 +752,17 @@ Optional<HitTestResult> PaintableWithLines::hit_test(CSSPixelPoint position, Hit
|
||||||
|
|
||||||
Optional<HitTestResult> last_good_candidate;
|
Optional<HitTestResult> last_good_candidate;
|
||||||
for (auto const& fragment : fragments()) {
|
for (auto const& fragment : fragments()) {
|
||||||
if (is<Layout::Box>(fragment.layout_node()) && static_cast<Layout::Box const&>(fragment.layout_node()).paintable_box()->stacking_context())
|
if (fragment.paintable().stacking_context())
|
||||||
continue;
|
continue;
|
||||||
if (!fragment.layout_node().containing_block()) {
|
if (!fragment.paintable().containing_block()) {
|
||||||
dbgln("FIXME: PaintableWithLines::hit_test(): Missing containing block on {}", fragment.layout_node().debug_description());
|
dbgln("FIXME: PaintableWithLines::hit_test(): Missing containing block on {}", fragment.layout_node().debug_description());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
auto fragment_absolute_rect = fragment.absolute_rect();
|
auto fragment_absolute_rect = fragment.absolute_rect();
|
||||||
if (fragment_absolute_rect.contains(position)) {
|
if (fragment_absolute_rect.contains(position)) {
|
||||||
if (is<Layout::BlockContainer>(fragment.layout_node()) && fragment.layout_node().paintable())
|
if (auto result = fragment.paintable().hit_test(position, type); result.has_value())
|
||||||
return fragment.layout_node().paintable()->hit_test(position, type);
|
return result;
|
||||||
return HitTestResult { const_cast<Paintable&>(const_cast<Paintable&>(*fragment.layout_node().paintable())), fragment.text_index_at(position.x()) };
|
return HitTestResult { const_cast<Paintable&>(fragment.paintable()), fragment.text_index_at(position.x()) };
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we reached this point, the position is not within the fragment. However, the fragment start or end might be the place to place the cursor.
|
// If we reached this point, the position is not within the fragment. However, the fragment start or end might be the place to place the cursor.
|
||||||
|
@ -771,14 +771,14 @@ Optional<HitTestResult> PaintableWithLines::hit_test(CSSPixelPoint position, Hit
|
||||||
// We arbitrarily choose to consider the end of the line above and ignore the beginning of the line below.
|
// We arbitrarily choose to consider the end of the line above and ignore the beginning of the line below.
|
||||||
// If we knew the direction of selection, we could make a better choice.
|
// If we knew the direction of selection, we could make a better choice.
|
||||||
if (fragment_absolute_rect.bottom() - 1 <= position.y()) { // fully below the fragment
|
if (fragment_absolute_rect.bottom() - 1 <= position.y()) { // fully below the fragment
|
||||||
last_good_candidate = HitTestResult { const_cast<Paintable&>(*fragment.layout_node().paintable()), fragment.start() + fragment.length() };
|
last_good_candidate = HitTestResult { const_cast<Paintable&>(fragment.paintable()), fragment.start() + fragment.length() };
|
||||||
} else if (fragment_absolute_rect.top() <= position.y()) { // vertically within the fragment
|
} else if (fragment_absolute_rect.top() <= position.y()) { // vertically within the fragment
|
||||||
if (position.x() < fragment_absolute_rect.left()) { // left of the fragment
|
if (position.x() < fragment_absolute_rect.left()) { // left of the fragment
|
||||||
if (!last_good_candidate.has_value()) { // first fragment of the line
|
if (!last_good_candidate.has_value()) { // first fragment of the line
|
||||||
last_good_candidate = HitTestResult { const_cast<Paintable&>(*fragment.layout_node().paintable()), fragment.start() };
|
last_good_candidate = HitTestResult { const_cast<Paintable&>(fragment.paintable()), fragment.start() };
|
||||||
}
|
}
|
||||||
} else { // right of the fragment
|
} else { // right of the fragment
|
||||||
last_good_candidate = HitTestResult { const_cast<Paintable&>(*fragment.layout_node().paintable()), fragment.start() + fragment.length() };
|
last_good_candidate = HitTestResult { const_cast<Paintable&>(fragment.paintable()), fragment.start() + fragment.length() };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ public:
|
||||||
explicit PaintableFragment(Layout::LineBoxFragment const&);
|
explicit PaintableFragment(Layout::LineBoxFragment const&);
|
||||||
|
|
||||||
Layout::Node const& layout_node() const { return m_layout_node; }
|
Layout::Node const& layout_node() const { return m_layout_node; }
|
||||||
|
Paintable const& paintable() const { return *m_layout_node->paintable(); }
|
||||||
|
|
||||||
int start() const { return m_start; }
|
int start() const { return m_start; }
|
||||||
int length() const { return m_length; }
|
int length() const { return m_length; }
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue