mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-12-07 21:59:54 +00:00
LibWeb: Propagate style values in deep anonymous wrappers
The style propagation logic in `NodeWithStyle::apply_style()`
was incomplete for anonymous nodes created during layout
(e.g., within `wrap_in_button_layout_tree_if_needed`).
1. **Non-inherited CSS values** were not being propagated to the
anonymous wrappers.
2. Propagation did not recurse into **nested anonymous wrappers**
(descendants).
This fix adds calls to `propagate_non_inherit_values(child)` and
`child.propagate_style_to_anonymous_wrappers()`, ensuring all computed
styles reach the entire anonymous wrapper hierarchy.
This commit is contained in:
parent
46acdbd10a
commit
010b0b00ff
Notes:
github-actions[bot]
2025-11-23 20:39:34 +00:00
Author: https://github.com/lpas
Commit: 010b0b00ff
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/6690
Reviewed-by: https://github.com/awesomekling
Reviewed-by: https://github.com/gmta ✅
4 changed files with 37 additions and 7 deletions
|
|
@ -922,6 +922,15 @@ void NodeWithStyle::apply_style(CSS::ComputedProperties const& computed_style)
|
|||
box_node->propagate_style_along_continuation(computed_style);
|
||||
}
|
||||
|
||||
void NodeWithStyle::propagate_non_inherit_values(NodeWithStyle& target_node) const
|
||||
{
|
||||
// NOTE: These properties are not inherited, but we still have to propagate them to anonymous wrappers.
|
||||
target_node.mutable_computed_values().set_text_decoration_line(computed_values().text_decoration_line());
|
||||
target_node.mutable_computed_values().set_text_decoration_thickness(computed_values().text_decoration_thickness());
|
||||
target_node.mutable_computed_values().set_text_decoration_color(computed_values().text_decoration_color());
|
||||
target_node.mutable_computed_values().set_text_decoration_style(computed_values().text_decoration_style());
|
||||
}
|
||||
|
||||
void NodeWithStyle::propagate_style_to_anonymous_wrappers()
|
||||
{
|
||||
// Update the style of any anonymous wrappers that inherit from this node.
|
||||
|
|
@ -940,6 +949,8 @@ void NodeWithStyle::propagate_style_to_anonymous_wrappers()
|
|||
if (child.is_anonymous() && !is<TableWrapper>(child)) {
|
||||
auto& child_computed_values = static_cast<CSS::MutableComputedValues&>(static_cast<CSS::ComputedValues&>(const_cast<CSS::ImmutableComputedValues&>(child.computed_values())));
|
||||
child_computed_values.inherit_from(computed_values());
|
||||
propagate_non_inherit_values(child);
|
||||
child.propagate_style_to_anonymous_wrappers();
|
||||
}
|
||||
return IterationDecision::Continue;
|
||||
});
|
||||
|
|
@ -1019,13 +1030,7 @@ GC::Ref<NodeWithStyle> NodeWithStyle::create_anonymous_wrapper() const
|
|||
{
|
||||
auto wrapper = heap().allocate<BlockContainer>(const_cast<DOM::Document&>(document()), nullptr, computed_values().clone_inherited_values());
|
||||
wrapper->mutable_computed_values().set_display(CSS::Display(CSS::DisplayOutside::Block, CSS::DisplayInside::Flow));
|
||||
|
||||
// NOTE: These properties are not inherited, but we still have to propagate them to anonymous wrappers.
|
||||
wrapper->mutable_computed_values().set_text_decoration_line(computed_values().text_decoration_line());
|
||||
wrapper->mutable_computed_values().set_text_decoration_thickness(computed_values().text_decoration_thickness());
|
||||
wrapper->mutable_computed_values().set_text_decoration_color(computed_values().text_decoration_color());
|
||||
wrapper->mutable_computed_values().set_text_decoration_style(computed_values().text_decoration_style());
|
||||
|
||||
propagate_non_inherit_values(*wrapper);
|
||||
// CSS 2.2 9.2.1.1 creates anonymous block boxes, but 9.4.1 states inline-block creates a BFC.
|
||||
// Set wrapper to inline-block to participate correctly in the IFC within the parent inline-block.
|
||||
if (display().is_inline_block() && !has_children()) {
|
||||
|
|
|
|||
|
|
@ -271,6 +271,7 @@ private:
|
|||
virtual bool is_node_with_style() const final { return true; }
|
||||
|
||||
void reset_table_box_computed_values_used_by_wrapper_to_init_values();
|
||||
void propagate_non_inherit_values(NodeWithStyle& target_node) const;
|
||||
void propagate_style_to_anonymous_wrappers();
|
||||
|
||||
NonnullOwnPtr<CSS::ComputedValues> m_computed_values;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
<!DOCTYPE html>
|
||||
<style>
|
||||
.btn {
|
||||
color: white;
|
||||
background: black;
|
||||
}
|
||||
</style>
|
||||
<button type="button" class="btn">BUTTON</button>
|
||||
16
Tests/LibWeb/Ref/input/button-hover-text-color.html
Normal file
16
Tests/LibWeb/Ref/input/button-hover-text-color.html
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
<!DOCTYPE html>
|
||||
<link rel="match" href="../expected/button-hover-text-color-ref.html" />
|
||||
<style>
|
||||
.btn {
|
||||
background: black;
|
||||
color: red;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
color: white;
|
||||
}
|
||||
</style>
|
||||
<button type="button" class="btn">BUTTON</button>
|
||||
<script>
|
||||
requestAnimationFrame(() => internals.movePointerTo(15, 15));
|
||||
</script>
|
||||
Loading…
Add table
Add a link
Reference in a new issue