mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-01 13:49:16 +00:00
LibWeb: Assign sticky insets to Layout::InlineNode
Before this change we were ignoring boxes with `display: inline` while assigning sticky insets. This was not correct because inline boxes are allowed to have sticky positioning. Fixes: https://github.com/LadybirdBrowser/ladybird/issues/3718 https://github.com/LadybirdBrowser/ladybird/issues/3507 https://github.com/LadybirdBrowser/ladybird/issues/3133
This commit is contained in:
parent
4ca330adef
commit
da5d4e9f6a
Notes:
github-actions[bot]
2025-02-27 18:56:39 +00:00
Author: https://github.com/kalenikaliaksandr
Commit: da5d4e9f6a
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/3723
3 changed files with 81 additions and 26 deletions
|
@ -445,38 +445,42 @@ void LayoutState::commit(Box& root)
|
||||||
|
|
||||||
for (auto& it : used_values_per_layout_node) {
|
for (auto& it : used_values_per_layout_node) {
|
||||||
auto& used_values = *it.value;
|
auto& used_values = *it.value;
|
||||||
if (!used_values.node().is_box())
|
auto& node = used_values.node();
|
||||||
continue;
|
for (auto& paintable : node.paintables()) {
|
||||||
auto const& box = static_cast<Layout::Box const&>(used_values.node());
|
Painting::PaintableBox* paintable_box = nullptr;
|
||||||
|
if (is<Painting::PaintableBox>(paintable))
|
||||||
|
paintable_box = &static_cast<Painting::PaintableBox&>(paintable);
|
||||||
|
|
||||||
auto& paintable_box = const_cast<Painting::PaintableBox&>(*box.paintable_box());
|
if (!paintable_box)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (box.is_sticky_position()) {
|
if (node.is_sticky_position()) {
|
||||||
// https://drafts.csswg.org/css-position/#insets
|
// https://drafts.csswg.org/css-position/#insets
|
||||||
// For sticky positioned boxes, the inset is instead relative to the relevant scrollport’s size. Negative values are allowed.
|
// For sticky positioned boxes, the inset is instead relative to the relevant scrollport’s size. Negative values are allowed.
|
||||||
|
|
||||||
auto sticky_insets = make<Painting::PaintableBox::StickyInsets>();
|
auto sticky_insets = make<Painting::PaintableBox::StickyInsets>();
|
||||||
auto const& inset = box.computed_values().inset();
|
auto const& inset = node.computed_values().inset();
|
||||||
|
|
||||||
auto const* nearest_scrollable_ancestor = paintable_box.nearest_scrollable_ancestor();
|
auto const* nearest_scrollable_ancestor = paintable_box->nearest_scrollable_ancestor();
|
||||||
CSSPixelSize scrollport_size;
|
CSSPixelSize scrollport_size;
|
||||||
if (nearest_scrollable_ancestor) {
|
if (nearest_scrollable_ancestor) {
|
||||||
scrollport_size = nearest_scrollable_ancestor->absolute_rect().size();
|
scrollport_size = nearest_scrollable_ancestor->absolute_rect().size();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!inset.top().is_auto()) {
|
if (!inset.top().is_auto()) {
|
||||||
sticky_insets->top = inset.top().to_px(box, scrollport_size.height());
|
sticky_insets->top = inset.top().to_px(node, scrollport_size.height());
|
||||||
|
}
|
||||||
|
if (!inset.right().is_auto()) {
|
||||||
|
sticky_insets->right = inset.right().to_px(node, scrollport_size.width());
|
||||||
|
}
|
||||||
|
if (!inset.bottom().is_auto()) {
|
||||||
|
sticky_insets->bottom = inset.bottom().to_px(node, scrollport_size.height());
|
||||||
|
}
|
||||||
|
if (!inset.left().is_auto()) {
|
||||||
|
sticky_insets->left = inset.left().to_px(node, scrollport_size.width());
|
||||||
|
}
|
||||||
|
paintable_box->set_sticky_insets(move(sticky_insets));
|
||||||
}
|
}
|
||||||
if (!inset.right().is_auto()) {
|
|
||||||
sticky_insets->right = inset.right().to_px(box, scrollport_size.width());
|
|
||||||
}
|
|
||||||
if (!inset.bottom().is_auto()) {
|
|
||||||
sticky_insets->bottom = inset.bottom().to_px(box, scrollport_size.height());
|
|
||||||
}
|
|
||||||
if (!inset.left().is_auto()) {
|
|
||||||
sticky_insets->left = inset.left().to_px(box, scrollport_size.width());
|
|
||||||
}
|
|
||||||
paintable_box.set_sticky_insets(move(sticky_insets));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,6 +73,7 @@ struct LayoutState {
|
||||||
|
|
||||||
struct UsedValues {
|
struct UsedValues {
|
||||||
NodeWithStyle const& node() const { return *m_node; }
|
NodeWithStyle const& node() const { return *m_node; }
|
||||||
|
NodeWithStyle& node() { return const_cast<NodeWithStyle&>(*m_node); }
|
||||||
void set_node(NodeWithStyle&, UsedValues const* containing_block_used_values);
|
void set_node(NodeWithStyle&, UsedValues const* containing_block_used_values);
|
||||||
|
|
||||||
UsedValues const* containing_block_used_values() const { return m_containing_block_used_values; }
|
UsedValues const* containing_block_used_values() const { return m_containing_block_used_values; }
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<style>
|
||||||
|
.container {
|
||||||
|
width: 80%;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sticky-inline {
|
||||||
|
display: inline;
|
||||||
|
position: sticky;
|
||||||
|
top: 10px;
|
||||||
|
background: yellow;
|
||||||
|
padding: 5px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<p>
|
||||||
|
This is an example of an inline box with <span class="sticky-inline">position: sticky</span>.
|
||||||
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum euismod, nulla id consequat facilisis,
|
||||||
|
libero risus placerat lacus, sed fermentum nisl nunc non sapien. Vivamus scelerisque feugiat dui, ac
|
||||||
|
venenatis ligula ultricies vel. Duis id nunc in felis feugiat cursus. Pellentesque habitant morbi tristique
|
||||||
|
senectus et netus et malesuada fames ac turpis egestas.
|
||||||
|
Curabitur at felis ac massa aliquet dictum. Ut auctor ligula non ante interdum, a euismod dui tristique. Nam
|
||||||
|
consequat, massa ut ultrices fermentum, lacus libero vulputate nulla, sit amet vehicula erat odio a metus.
|
||||||
|
Nulla vitae lectus sed erat scelerisque sodales.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
This is an example of an inline box with <span class="sticky-inline">position: sticky</span>.
|
||||||
|
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum euismod, nulla id consequat facilisis,
|
||||||
|
libero risus placerat lacus, sed fermentum nisl nunc non sapien. Vivamus scelerisque feugiat dui, ac
|
||||||
|
venenatis ligula ultricies vel. Duis id nunc in felis feugiat cursus. Pellentesque habitant morbi tristique
|
||||||
|
senectus et netus et malesuada fames ac turpis egestas.
|
||||||
|
Curabitur at felis ac massa aliquet dictum. Ut auctor ligula non ante interdum, a euismod dui tristique. Nam
|
||||||
|
consequat, massa ut ultrices fermentum, lacus libero vulputate nulla, sit amet vehicula erat odio a metus.
|
||||||
|
Nulla vitae lectus sed erat scelerisque sodales.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
Loading…
Add table
Add a link
Reference in a new issue