LibWeb: Improve style propagation to anonymous wrappers
- We now propagate changes in font and line-height to anonymous wrappers when doing a partial style update after invalidation. - We no longer (incorrectly) propagate style from table wrapper boxes to the table root, since inheritance works in the other direction. Fixes #22395
This commit is contained in:
parent
242d1d8eba
commit
4a35693dd7
Notes:
sideshowbarker
2024-07-17 03:03:15 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/4a35693dd7 Pull-request: https://github.com/SerenityOS/serenity/pull/22642 Issue: https://github.com/SerenityOS/serenity/issues/22395
6 changed files with 94 additions and 8 deletions
Tests/LibWeb/Layout
Userland/Libraries/LibWeb/Layout
|
@ -0,0 +1,21 @@
|
|||
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
|
||||
BlockContainer <html> at (0,0) content-size 800x36 [BFC] children: not-inline
|
||||
BlockContainer <body> at (8,8) content-size 784x20 children: not-inline
|
||||
BlockContainer <div> at (8,8) content-size 784x10 children: inline
|
||||
line 0 width: 98, height: 10, bottom: 10, baseline: 9.796875
|
||||
frag 0 from TextNode start: 0, length: 11, rect: [8,8 98x10]
|
||||
"foo bar baz"
|
||||
TextNode <#text>
|
||||
BlockContainer <(anonymous)> at (8,18) content-size 784x10 children: inline
|
||||
line 0 width: 98, height: 10, bottom: 10, baseline: 9.796875
|
||||
frag 0 from TextNode start: 0, length: 11, rect: [8,18 98x10]
|
||||
"foo bar baz"
|
||||
TextNode <#text>
|
||||
|
||||
ViewportPaintable (Viewport<#document>) [0,0 800x600]
|
||||
PaintableWithLines (BlockContainer<HTML>) [0,0 800x36]
|
||||
PaintableWithLines (BlockContainer<BODY>) [8,8 784x20]
|
||||
PaintableWithLines (BlockContainer<DIV>) [8,8 784x10]
|
||||
TextPaintable (TextNode<#text>)
|
||||
PaintableWithLines (BlockContainer(anonymous)) [8,18 784x10]
|
||||
TextPaintable (TextNode<#text>)
|
|
@ -0,0 +1,20 @@
|
|||
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
|
||||
BlockContainer <html> at (0,0) content-size 800x120 [BFC] children: not-inline
|
||||
BlockContainer <body> at (8,8) content-size 784x104 children: not-inline
|
||||
BlockContainer <center> at (8,8) content-size 784x104 children: not-inline
|
||||
TableWrapper <(anonymous)> at (204,8) content-size 392x104 [BFC] children: not-inline
|
||||
Box <table> at (204,8) content-size 392x104 table-box [TFC] children: not-inline
|
||||
Box <tbody> at (204,8) content-size 388x100 table-row-group children: not-inline
|
||||
Box <tr> at (206,10) content-size 388x100 table-row children: not-inline
|
||||
BlockContainer <td> at (207,60) content-size 386x0 table-cell [BFC] children: inline
|
||||
TextNode <#text>
|
||||
|
||||
ViewportPaintable (Viewport<#document>) [0,0 800x600]
|
||||
PaintableWithLines (BlockContainer<HTML>) [0,0 800x120]
|
||||
PaintableWithLines (BlockContainer<BODY>) [8,8 784x104]
|
||||
PaintableWithLines (BlockContainer<CENTER>) [8,8 784x104]
|
||||
PaintableWithLines (TableWrapper(anonymous)) [204,8 392x104]
|
||||
PaintableBox (Box<TABLE>) [204,8 392x104]
|
||||
PaintableBox (Box<TBODY>) [204,8 388x100] overflow: [204,8 390x102]
|
||||
PaintableBox (Box<TR>) [206,10 388x100]
|
||||
PaintableWithLines (BlockContainer<TD>) [206,10 388x100]
|
|
@ -0,0 +1,13 @@
|
|||
<!DOCTYPE html><style>
|
||||
* {
|
||||
outline: 1px solid black;
|
||||
}
|
||||
body {
|
||||
line-height: 20px;
|
||||
}
|
||||
</style><script>
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
document.body.offsetWidth // Force a layout
|
||||
document.body.style.lineHeight = '10px' // Trigger a line-height change that everyone should inherit
|
||||
});
|
||||
</script><body><div>foo bar baz</div>foo bar baz
|
|
@ -0,0 +1,17 @@
|
|||
<!doctype html><style>
|
||||
body {
|
||||
background: black;
|
||||
}
|
||||
table {
|
||||
background: white;
|
||||
width: 50%;
|
||||
}
|
||||
td {
|
||||
height: 100px;
|
||||
background: magenta;
|
||||
}
|
||||
</style><center><table><td><script>
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
document.querySelector("center").style.left = "1px";
|
||||
});
|
||||
</script>
|
|
@ -846,10 +846,6 @@ void NodeWithStyle::apply_style(const CSS::StyleProperties& computed_style)
|
|||
} else if (aspect_ratio->is_ratio()) {
|
||||
computed_values.set_aspect_ratio({ false, aspect_ratio->as_ratio().ratio() });
|
||||
}
|
||||
if (display().is_table_inside() && is<TableWrapper>(parent())) {
|
||||
auto& wrapper_computed_values = static_cast<TableWrapper*>(parent())->m_computed_values;
|
||||
transfer_table_box_computed_values_to_wrapper_computed_values(wrapper_computed_values);
|
||||
}
|
||||
|
||||
auto math_shift_value = computed_style.property(CSS::PropertyID::MathShift);
|
||||
if (auto math_shift = value_id_to_math_shift(math_shift_value->to_identifier()); math_shift.has_value())
|
||||
|
@ -862,13 +858,31 @@ void NodeWithStyle::apply_style(const CSS::StyleProperties& computed_style)
|
|||
computed_values.set_math_depth(computed_style.math_depth());
|
||||
computed_values.set_quotes(computed_style.quotes());
|
||||
|
||||
// Update any anonymous children that inherit from this node.
|
||||
propagate_style_to_anonymous_wrappers();
|
||||
}
|
||||
|
||||
void NodeWithStyle::propagate_style_to_anonymous_wrappers()
|
||||
{
|
||||
// Update the style of any anonymous wrappers that inherit from this node.
|
||||
// FIXME: This is pretty hackish. It would be nicer if they shared the inherited style
|
||||
// data structure somehow, so this wasn't necessary.
|
||||
for_each_child([&](auto& child) {
|
||||
if (child.is_anonymous()) {
|
||||
|
||||
// If this is a `display:table` box with an anonymous wrapper parent,
|
||||
// the parent inherits style from *this* node, not the other way around.
|
||||
if (display().is_table_inside() && is<TableWrapper>(parent())) {
|
||||
auto& table_wrapper = *static_cast<TableWrapper*>(parent());
|
||||
transfer_table_box_computed_values_to_wrapper_computed_values(table_wrapper.m_computed_values);
|
||||
table_wrapper.set_font_list(*m_font_list);
|
||||
table_wrapper.set_line_height(m_line_height);
|
||||
}
|
||||
|
||||
// Propagate style to all anonymous children (except table wrappers!)
|
||||
for_each_child_of_type<NodeWithStyle>([&](NodeWithStyle& child) {
|
||||
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);
|
||||
child_computed_values.inherit_from(m_computed_values);
|
||||
child.set_font_list(*m_font_list);
|
||||
child.set_line_height(m_line_height);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -237,6 +237,7 @@ protected:
|
|||
|
||||
private:
|
||||
void reset_table_box_computed_values_used_by_wrapper_to_init_values();
|
||||
void propagate_style_to_anonymous_wrappers();
|
||||
|
||||
CSS::ComputedValues m_computed_values;
|
||||
RefPtr<Gfx::FontCascadeList const> m_font_list;
|
||||
|
|
Loading…
Add table
Reference in a new issue