mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-19 19:15:19 +00:00
LibWeb: Retain display: contents
in ancestor stack for continuations
When restructuring inline nodes because of a block element insertion during the layout tree build, we might end up with a `display: contents` element in the ancestor stack that is not part of the actual layout tree, since it's never actually used as a parent for any node. Because we were only rewinding the ancestor stack with actual new layout nodes, it became corrupted and layout nodes were added to the wrong parent. This new logic leaves the ancestor stack intact, only replacing layout nodes whenever a new one is created. Fixes the sidebar on https://reddit.com. Fixes #3590.
This commit is contained in:
parent
dd8cca180f
commit
de7ca7b157
Notes:
github-actions[bot]
2025-02-18 22:32:41 +00:00
Author: https://github.com/gmta Commit: https://github.com/LadybirdBrowser/ladybird/commit/de7ca7b157c Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/3617
3 changed files with 13 additions and 12 deletions
|
@ -305,13 +305,11 @@ void TreeBuilder::restructure_block_node_in_inline_parent(NodeWithStyleAndBoxMod
|
|||
}();
|
||||
nearest_block_ancestor.set_children_are_inline(false);
|
||||
|
||||
// Unwind the ancestor stack to find the topmost inline ancestor.
|
||||
// Find the topmost inline ancestor.
|
||||
GC::Ptr<NodeWithStyleAndBoxModelMetrics> topmost_inline_ancestor;
|
||||
for (auto* ancestor = &parent; ancestor; ancestor = ancestor->parent()) {
|
||||
if (ancestor == &nearest_block_ancestor)
|
||||
break;
|
||||
if (ancestor == m_ancestor_stack.last())
|
||||
m_ancestor_stack.take_last();
|
||||
if (ancestor->is_inline())
|
||||
topmost_inline_ancestor = static_cast<NodeWithStyleAndBoxModelMetrics*>(ancestor);
|
||||
}
|
||||
|
@ -320,7 +318,7 @@ void TreeBuilder::restructure_block_node_in_inline_parent(NodeWithStyleAndBoxMod
|
|||
// We need to host the topmost inline ancestor and its previous siblings in an anonymous "before" wrapper. If an
|
||||
// inline wrapper does not already exist, we create a new one and add it to the nearest block ancestor.
|
||||
GC::Ptr<Node> before_wrapper;
|
||||
if (auto last_child = nearest_block_ancestor.last_child(); last_child->is_anonymous() && last_child->children_are_inline()) {
|
||||
if (auto* last_child = nearest_block_ancestor.last_child(); last_child->is_anonymous() && last_child->children_are_inline()) {
|
||||
before_wrapper = last_child;
|
||||
} else {
|
||||
before_wrapper = nearest_block_ancestor.create_anonymous_wrapper();
|
||||
|
@ -388,7 +386,12 @@ void TreeBuilder::restructure_block_node_in_inline_parent(NodeWithStyleAndBoxMod
|
|||
current_parent->append_child(new_inline_node);
|
||||
current_parent = new_inline_node;
|
||||
|
||||
// Stop recreating nodes when we've reached node's parent
|
||||
// Replace the node in the ancestor stack with the new node.
|
||||
auto& node_with_style = static_cast<NodeWithStyle&>(*inline_node);
|
||||
if (auto stack_index = m_ancestor_stack.find_first_index(node_with_style); stack_index.has_value())
|
||||
m_ancestor_stack[stack_index.release_value()] = new_inline_node;
|
||||
|
||||
// Stop recreating nodes when we've reached node's parent.
|
||||
if (inline_node == &parent)
|
||||
break;
|
||||
}
|
||||
|
@ -396,13 +399,6 @@ void TreeBuilder::restructure_block_node_in_inline_parent(NodeWithStyleAndBoxMod
|
|||
after_wrapper->set_children_are_inline(true);
|
||||
nearest_block_ancestor.append_child(after_wrapper);
|
||||
}
|
||||
|
||||
// Rewind the ancestor stack
|
||||
for (GC::Ptr<Node> inline_node = topmost_inline_ancestor; inline_node; inline_node = inline_node->last_child()) {
|
||||
if (!is<NodeWithStyle>(*inline_node))
|
||||
break;
|
||||
m_ancestor_stack.append(static_cast<NodeWithStyle&>(*inline_node));
|
||||
}
|
||||
}
|
||||
|
||||
static bool is_ignorable_whitespace(Layout::Node const& node)
|
||||
|
|
|
@ -18,5 +18,7 @@
|
|||
<b>foo</b><div><b>bar</b></div><b>baz</b>
|
||||
<hr>
|
||||
<span>foo</span><div>bar</div>
|
||||
<hr>
|
||||
<b>foo</b><div><b>bar</b></div><b>baz</b>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -40,5 +40,8 @@
|
|||
target2.setAttribute('style', null);
|
||||
});
|
||||
</script>
|
||||
<!-- Block inside `display: contents` element -->
|
||||
<hr>
|
||||
<b>foo<div style="display: contents"><div>bar</div></div>baz</b>
|
||||
</body>
|
||||
</html>
|
||||
|
|
Loading…
Add table
Reference in a new issue