Skip to content

Commit f9cab32

Browse files
committed
LibWeb: Only propagate CSS overflow to the viewport once per tree build
Before this change, we were doing it after every layout, which meant that already-propagated overflow could be propagated again, which led to incorrect scrolling behavior.
1 parent bc6f19d commit f9cab32

File tree

5 files changed

+13
-6
lines changed

5 files changed

+13
-6
lines changed

Tests/LibWeb/Layout/expected/replaced-within-max-content.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline
88
frag 0 from ImageBox start: 0, length: 0, rect: [8,8 150x150]
99
ImageBox <img.replaced> at (8,8) content-size 150x150 children: not-inline
1010
(SVG-as-image isolated context)
11-
Viewport <#document> at (0,0) content-size 150x150 children: inline
11+
Viewport <#document> at (0,0) content-size 150x150 [BFC] children: inline
1212
SVGSVGBox <svg> at (0,0) content-size 150x150 [SVG] children: not-inline
1313
SVGGeometryBox <path> at (0,0) content-size 150x150 children: not-inline
1414
TextNode <#text>

Tests/LibWeb/Layout/expected/svg/svg-as-image-implicit-viewbox.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline
33
BlockContainer <body> at (8,8) content-size 784x100 children: not-inline
44
ImageBox <img> at (8,8) content-size 50x100 children: not-inline
55
(SVG-as-image isolated context)
6-
Viewport <#document> at (0,0) content-size 50x100 children: inline
6+
Viewport <#document> at (0,0) content-size 50x100 [BFC] children: inline
77
SVGSVGBox <svg> at (0,0) content-size 50x100 [SVG] children: not-inline
88
SVGGeometryBox <rect> at (0,0) content-size 50x100 children: not-inline
99

Tests/LibWeb/Layout/expected/svg/svg-as-image.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ Viewport <#document> at (0,0) content-size 800x600 children: not-inline
33
BlockContainer <body> at (8,8) content-size 784x1568 children: not-inline
44
ImageBox <img> at (8,8) content-size 784x1568 children: not-inline
55
(SVG-as-image isolated context)
6-
Viewport <#document> at (0,0) content-size 784x1568 children: inline
6+
Viewport <#document> at (0,0) content-size 784x1568 [BFC] children: inline
77
SVGSVGBox <svg> at (0,0) content-size 784x1568 [SVG] children: inline
88
TextNode <#text>
99
SVGGeometryBox <rect> at (0,0) content-size 784x1568 children: not-inline

Userland/Libraries/LibWeb/DOM/Document.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -984,10 +984,10 @@ void Document::update_layout()
984984
if (!m_layout_root) {
985985
Layout::TreeBuilder tree_builder;
986986
m_layout_root = verify_cast<Layout::Viewport>(*tree_builder.build(*this));
987-
}
988987

989-
if (auto* document_element = this->document_element()) {
990-
propagate_overflow_to_viewport(*document_element, *m_layout_root);
988+
if (auto* document_element = this->document_element()) {
989+
propagate_overflow_to_viewport(*document_element, *m_layout_root);
990+
}
991991
}
992992

993993
Layout::LayoutState layout_state;

Userland/Libraries/LibWeb/DOM/Element.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,13 @@ static Element::RequiredInvalidationAfterStyleChange compute_required_invalidati
542542
return Element::RequiredInvalidationAfterStyleChange::full();
543543
}
544544

545+
// NOTE: If one of the overflow properties change, we rebuild the entire layout tree.
546+
// This ensures that overflow propagation from root/body to viewport happens correctly.
547+
// In the future, we can make this invalidation narrower.
548+
if (property_id == CSS::PropertyID::OverflowX || property_id == CSS::PropertyID::OverflowY) {
549+
return Element::RequiredInvalidationAfterStyleChange::full();
550+
}
551+
545552
// OPTIMIZATION: Special handling for CSS `visibility`:
546553
if (property_id == CSS::PropertyID::Visibility) {
547554
// We don't need to relayout if the visibility changes from visible to hidden or vice versa. Only collapse requires relayout.

0 commit comments

Comments
 (0)