summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibWeb/DOM
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2022-03-04 23:36:36 +0100
committerAndreas Kling <kling@serenityos.org>2022-03-04 23:40:21 +0100
commit7d052250f24b6419e1c3297f2b6a10c71fc2b6e9 (patch)
tree6656820964c8a291745235284b3439aa8e11e874 /Userland/Libraries/LibWeb/DOM
parenta6a8ba80fc9c6bb9660407e3a501217602bcc1e3 (diff)
downloadserenity-7d052250f24b6419e1c3297f2b6a10c71fc2b6e9.zip
LibWeb: Don't create unwanted layout nodes when recomputing style
When recomputing the style for an element that previously didn't have a corresponding layout node, it may become necessary to create a layout node for it. However, we should not do this if it's within a subtree that can't have layout children. Nor should we do it for elements who have an ancestor with display:none.
Diffstat (limited to 'Userland/Libraries/LibWeb/DOM')
-rw-r--r--Userland/Libraries/LibWeb/DOM/Element.cpp12
1 files changed, 11 insertions, 1 deletions
diff --git a/Userland/Libraries/LibWeb/DOM/Element.cpp b/Userland/Libraries/LibWeb/DOM/Element.cpp
index 323f50d888..7cbf512ed2 100644
--- a/Userland/Libraries/LibWeb/DOM/Element.cpp
+++ b/Userland/Libraries/LibWeb/DOM/Element.cpp
@@ -304,9 +304,19 @@ void Element::recompute_style()
auto new_specified_css_values = document().style_computer().compute_style(*this);
m_specified_css_values = new_specified_css_values;
if (!layout_node()) {
+ // This element doesn't have a corresponding layout node.
+
+ // If the new style is display:none, bail.
if (new_specified_css_values->display().is_none())
return;
- // We need a new layout tree here!
+
+ // If we're inside a display:none ancestor or an ancestor that can't have children, bail.
+ for (auto* ancestor = parent_element(); ancestor; ancestor = ancestor->parent_element()) {
+ if (!ancestor->layout_node() || !ancestor->layout_node()->can_have_children())
+ return;
+ }
+
+ // Okay, we need a new layout subtree here.
Layout::TreeBuilder tree_builder;
(void)tree_builder.build(*this);
return;