1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 01:47:34 +00:00

LibWeb: Allow inline nodes to establish a stacking context

With this change, a stacking context can be established by any
paintable, including inline paintables. The stacking context traversal
is updated to remove the assumption that the stacking context root is
paintable box.
This commit is contained in:
Aliaksandr Kalenik 2024-01-03 02:40:31 +01:00 committed by Andreas Kling
parent 6c645f3a9f
commit 3cf5ad002a
12 changed files with 253 additions and 151 deletions

View file

@ -8,6 +8,7 @@
#include <LibWeb/Layout/BlockContainer.h>
#include <LibWeb/Painting/Paintable.h>
#include <LibWeb/Painting/PaintableBox.h>
#include <LibWeb/Painting/StackingContext.h>
namespace Web::Painting {
@ -17,6 +18,10 @@ Paintable::Paintable(Layout::Node const& layout_node)
{
}
Paintable::~Paintable()
{
}
void Paintable::visit_edges(Cell::Visitor& visitor)
{
Base::visit_edges(visitor);
@ -28,6 +33,11 @@ void Paintable::visit_edges(Cell::Visitor& visitor)
visitor.visit(m_containing_block.value());
}
bool Paintable::is_visible() const
{
return computed_values().visibility() == CSS::Visibility::Visible && computed_values().opacity() != 0;
}
bool Paintable::is_positioned() const
{
if (layout_node().is_grid_item() && computed_values().z_index().has_value()) {
@ -88,11 +98,37 @@ Optional<HitTestResult> Paintable::hit_test(CSSPixelPoint, HitTestType) const
return {};
}
StackingContext const* Paintable::stacking_context_rooted_here() const
StackingContext* Paintable::enclosing_stacking_context()
{
if (!is<PaintableBox>(*this))
return nullptr;
return static_cast<PaintableBox const&>(*this).stacking_context();
for (auto* ancestor = parent(); ancestor; ancestor = ancestor->parent()) {
if (auto* stacking_context = ancestor->stacking_context())
return const_cast<StackingContext*>(stacking_context);
}
// We should always reach the viewport's stacking context.
VERIFY_NOT_REACHED();
}
void Paintable::set_stacking_context(NonnullOwnPtr<StackingContext> stacking_context)
{
m_stacking_context = move(stacking_context);
}
void Paintable::invalidate_stacking_context()
{
m_stacking_context = nullptr;
}
PaintableBox const* Paintable::nearest_scrollable_ancestor_within_stacking_context() const
{
auto* ancestor = parent();
while (ancestor) {
if (ancestor->stacking_context())
return nullptr;
if (ancestor->is_paintable_box() && static_cast<PaintableBox const*>(ancestor)->has_scrollable_overflow())
return static_cast<PaintableBox const*>(ancestor);
ancestor = ancestor->parent();
}
return nullptr;
}
}