mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 23:37:35 +00:00
LibWeb: Don't hit test all child stacking contexts twice
We're supposed to hit test positive z-index stacking contexts first,
and negative z-index stacking contexts later. Instead, we were hit
testing all stacking contexts both times.
This made hit testing unbearably slow on some websites.
While we're here, also add an extra comment about why stacking contexts
are traversed in reverse order. It tripped me up while looking at this,
so I'm sure it could trip someone else up too.
Regressed in 44057c9482
.
This commit is contained in:
parent
102e02d336
commit
90b66533d0
1 changed files with 6 additions and 2 deletions
|
@ -369,8 +369,6 @@ Optional<HitTestResult> StackingContext::hit_test(Gfx::FloatPoint const& positio
|
|||
{
|
||||
if (!m_box.is_visible())
|
||||
return {};
|
||||
if (m_box.computed_values().z_index().value_or(0) < 0)
|
||||
return {};
|
||||
|
||||
auto transform_origin = this->transform_origin();
|
||||
auto transformed_position = affine_transform_matrix().inverse().value_or({}).map(position - transform_origin) + transform_origin;
|
||||
|
@ -385,8 +383,11 @@ Optional<HitTestResult> StackingContext::hit_test(Gfx::FloatPoint const& positio
|
|||
// https://www.w3.org/TR/CSS22/visuren.html#z-index
|
||||
|
||||
// 7. the child stacking contexts with positive stack levels (least positive first).
|
||||
// NOTE: Hit testing follows reverse painting order, that's why the conditions here are reversed.
|
||||
for (ssize_t i = m_children.size() - 1; i >= 0; --i) {
|
||||
auto const& child = *m_children[i];
|
||||
if (child.m_box.computed_values().z_index().value_or(0) < 0)
|
||||
break;
|
||||
auto result = child.hit_test(transformed_position, type);
|
||||
if (result.has_value())
|
||||
return result;
|
||||
|
@ -457,8 +458,11 @@ Optional<HitTestResult> StackingContext::hit_test(Gfx::FloatPoint const& positio
|
|||
}
|
||||
|
||||
// 2. the child stacking contexts with negative stack levels (most negative first).
|
||||
// NOTE: Hit testing follows reverse painting order, that's why the conditions here are reversed.
|
||||
for (ssize_t i = m_children.size() - 1; i >= 0; --i) {
|
||||
auto const& child = *m_children[i];
|
||||
if (child.m_box.computed_values().z_index().value_or(0) >= 0)
|
||||
break;
|
||||
auto result = child.hit_test(transformed_position, type);
|
||||
if (result.has_value())
|
||||
return result;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue