From a9eecf76df3891c4e5ce8ce6a7743ef5596eaf48 Mon Sep 17 00:00:00 2001 From: Callum Law Date: Mon, 9 Jun 2025 14:11:22 +1200 Subject: [PATCH] LibWeb: Dont compute style when CSSStyleProperties lacks owner node Some instances of CSSStyleProperties can lack an owner node, for instance the return value of a call to `window.getComputedStyle` where the specified pseudo-element is invalid. In this case we should treat the computed style as empty, as there is no node to compute the style for. --- Libraries/LibWeb/CSS/CSSStyleProperties.cpp | 16 +- .../css/cssom/getComputedStyle-pseudo.txt | 33 ++ .../css/cssom/getComputedStyle-pseudo.html | 294 ++++++++++++++++++ 3 files changed, 342 insertions(+), 1 deletion(-) create mode 100644 Tests/LibWeb/Text/expected/wpt-import/css/cssom/getComputedStyle-pseudo.txt create mode 100644 Tests/LibWeb/Text/input/wpt-import/css/cssom/getComputedStyle-pseudo.html diff --git a/Libraries/LibWeb/CSS/CSSStyleProperties.cpp b/Libraries/LibWeb/CSS/CSSStyleProperties.cpp index b621c4990a9..b1ff78a5eb7 100644 --- a/Libraries/LibWeb/CSS/CSSStyleProperties.cpp +++ b/Libraries/LibWeb/CSS/CSSStyleProperties.cpp @@ -125,8 +125,11 @@ size_t CSSStyleProperties::length() const // The length attribute must return the number of CSS declarations in the declarations. // FIXME: Include the number of custom properties. - if (is_computed()) + if (is_computed()) { + if (!owner_node().has_value()) + return 0; return to_underlying(last_longhand_property_id) - to_underlying(first_longhand_property_id) + 1; + } return m_properties.size(); } @@ -150,6 +153,9 @@ String CSSStyleProperties::item(size_t index) const Optional CSSStyleProperties::property(PropertyID property_id) const { if (is_computed()) { + if (!owner_node().has_value()) + return {}; + auto& element = owner_node()->element(); auto pseudo_element = owner_node()->pseudo_element(); @@ -211,6 +217,9 @@ Optional CSSStyleProperties::property(PropertyID property_id) con Optional CSSStyleProperties::custom_property(FlyString const& custom_property_name) const { if (is_computed()) { + if (!owner_node().has_value()) + return {}; + auto& element = owner_node()->element(); auto pseudo_element = owner_node()->pseudo_element(); @@ -676,6 +685,11 @@ static RefPtr resolve_color_style_value(CSSStyleValue const RefPtr CSSStyleProperties::style_value_for_computed_property(Layout::NodeWithStyle const& layout_node, PropertyID property_id) const { + if (!owner_node().has_value()) { + dbgln_if(LIBWEB_CSS_DEBUG, "Computed style for CSSStyleProperties without owner node was requested"); + return nullptr; + } + auto used_value_for_property = [&layout_node, property_id](Function&& used_value_getter) -> Optional { auto const& display = layout_node.computed_values().display(); if (!display.is_none() && !display.is_contents() && layout_node.first_paintable()) { diff --git a/Tests/LibWeb/Text/expected/wpt-import/css/cssom/getComputedStyle-pseudo.txt b/Tests/LibWeb/Text/expected/wpt-import/css/cssom/getComputedStyle-pseudo.txt new file mode 100644 index 00000000000..6afdc1cdf0d --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/css/cssom/getComputedStyle-pseudo.txt @@ -0,0 +1,33 @@ +Harness status: OK + +Found 26 tests + +22 Pass +1 Fail +3 Optional Feature Unsupported +Pass Resolution of width is correct when pseudo-element argument is ignored (due to no colon) +Fail Resolution of width is correct when pseudo-element argument is invalid (due to a trailing token) +Pass Resolution of width is correct for ::before and ::after pseudo-elements (single-colon) +Pass Resolution of width is correct for ::before and ::after pseudo-elements (double-colon) +Pass Pseudo-elements can use the full range of CSS syntax +Pass Resolution of width is correct for ::before and ::after pseudo-elements of display: contents elements +Pass Resolution of nonexistent pseudo-element styles +Pass Resolution of pseudo-element styles in display: none elements +Pass Item-based blockification of pseudo-elements +Pass Item-based blockification of nonexistent pseudo-elements +Pass display: contents on pseudo-elements +Pass Dynamically change to display: contents on pseudo-elements +Pass Unknown pseudo-elements +Pass CSSStyleDeclaration is immutable +Pass Unknown pseudo-element with a known identifier: backdrop +Pass Unknown pseudo-element with a known identifier: file-selector-button +Optional Feature Unsupported Unknown pseudo-element with a known identifier: grammar-error +Optional Feature Unsupported Unknown pseudo-element with a known identifier: highlight(name) +Pass Unknown pseudo-element with a known identifier: marker +Pass Unknown pseudo-element with a known identifier: placeholder +Optional Feature Unsupported Unknown pseudo-element with a known identifier: spelling-error +Pass Unknown pseudo-element with a known identifier: view-transition +Pass Unknown pseudo-element with a known identifier: view-transition-image-pair(name) +Pass Unknown pseudo-element with a known identifier: view-transition-group(name) +Pass Unknown pseudo-element with a known identifier: view-transition-old(name) +Pass Unknown pseudo-element with a known identifier: view-transition-new(name) \ No newline at end of file diff --git a/Tests/LibWeb/Text/input/wpt-import/css/cssom/getComputedStyle-pseudo.html b/Tests/LibWeb/Text/input/wpt-import/css/cssom/getComputedStyle-pseudo.html new file mode 100644 index 00000000000..35523e66718 --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/css/cssom/getComputedStyle-pseudo.html @@ -0,0 +1,294 @@ + + +CSSOM: Correct resolution of resolved value for display-affected pseudo-elements + + + + + + + +
+
+
+
+
+
+
+
  • Item
+
+