Skip to content

Commit 010b0b0

Browse files
lpasgmta
authored andcommitted
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.
1 parent 46acdbd commit 010b0b0

File tree

4 files changed

+37
-7
lines changed

4 files changed

+37
-7
lines changed

Libraries/LibWeb/Layout/Node.cpp

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -922,6 +922,15 @@ void NodeWithStyle::apply_style(CSS::ComputedProperties const& computed_style)
922922
box_node->propagate_style_along_continuation(computed_style);
923923
}
924924

925+
void NodeWithStyle::propagate_non_inherit_values(NodeWithStyle& target_node) const
926+
{
927+
// NOTE: These properties are not inherited, but we still have to propagate them to anonymous wrappers.
928+
target_node.mutable_computed_values().set_text_decoration_line(computed_values().text_decoration_line());
929+
target_node.mutable_computed_values().set_text_decoration_thickness(computed_values().text_decoration_thickness());
930+
target_node.mutable_computed_values().set_text_decoration_color(computed_values().text_decoration_color());
931+
target_node.mutable_computed_values().set_text_decoration_style(computed_values().text_decoration_style());
932+
}
933+
925934
void NodeWithStyle::propagate_style_to_anonymous_wrappers()
926935
{
927936
// Update the style of any anonymous wrappers that inherit from this node.
@@ -940,6 +949,8 @@ void NodeWithStyle::propagate_style_to_anonymous_wrappers()
940949
if (child.is_anonymous() && !is<TableWrapper>(child)) {
941950
auto& child_computed_values = static_cast<CSS::MutableComputedValues&>(static_cast<CSS::ComputedValues&>(const_cast<CSS::ImmutableComputedValues&>(child.computed_values())));
942951
child_computed_values.inherit_from(computed_values());
952+
propagate_non_inherit_values(child);
953+
child.propagate_style_to_anonymous_wrappers();
943954
}
944955
return IterationDecision::Continue;
945956
});
@@ -1019,13 +1030,7 @@ GC::Ref<NodeWithStyle> NodeWithStyle::create_anonymous_wrapper() const
10191030
{
10201031
auto wrapper = heap().allocate<BlockContainer>(const_cast<DOM::Document&>(document()), nullptr, computed_values().clone_inherited_values());
10211032
wrapper->mutable_computed_values().set_display(CSS::Display(CSS::DisplayOutside::Block, CSS::DisplayInside::Flow));
1022-
1023-
// NOTE: These properties are not inherited, but we still have to propagate them to anonymous wrappers.
1024-
wrapper->mutable_computed_values().set_text_decoration_line(computed_values().text_decoration_line());
1025-
wrapper->mutable_computed_values().set_text_decoration_thickness(computed_values().text_decoration_thickness());
1026-
wrapper->mutable_computed_values().set_text_decoration_color(computed_values().text_decoration_color());
1027-
wrapper->mutable_computed_values().set_text_decoration_style(computed_values().text_decoration_style());
1028-
1033+
propagate_non_inherit_values(*wrapper);
10291034
// CSS 2.2 9.2.1.1 creates anonymous block boxes, but 9.4.1 states inline-block creates a BFC.
10301035
// Set wrapper to inline-block to participate correctly in the IFC within the parent inline-block.
10311036
if (display().is_inline_block() && !has_children()) {

Libraries/LibWeb/Layout/Node.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,7 @@ class WEB_API NodeWithStyle : public Node {
271271
virtual bool is_node_with_style() const final { return true; }
272272

273273
void reset_table_box_computed_values_used_by_wrapper_to_init_values();
274+
void propagate_non_inherit_values(NodeWithStyle& target_node) const;
274275
void propagate_style_to_anonymous_wrappers();
275276

276277
NonnullOwnPtr<CSS::ComputedValues> m_computed_values;
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<!DOCTYPE html>
2+
<style>
3+
.btn {
4+
color: white;
5+
background: black;
6+
}
7+
</style>
8+
<button type="button" class="btn">BUTTON</button>
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<!DOCTYPE html>
2+
<link rel="match" href="../expected/button-hover-text-color-ref.html" />
3+
<style>
4+
.btn {
5+
background: black;
6+
color: red;
7+
}
8+
9+
.btn:hover {
10+
color: white;
11+
}
12+
</style>
13+
<button type="button" class="btn">BUTTON</button>
14+
<script>
15+
requestAnimationFrame(() => internals.movePointerTo(15, 15));
16+
</script>

0 commit comments

Comments
 (0)