diff --git a/Tests/LibWeb/Layout/expected/element-use-pseudo-element.txt b/Tests/LibWeb/Layout/expected/element-use-pseudo-element.txt new file mode 100644 index 0000000000..2eb3401e89 --- /dev/null +++ b/Tests/LibWeb/Layout/expected/element-use-pseudo-element.txt @@ -0,0 +1,17 @@ +Viewport <#document> at (0,0) content-size 800x600 children: not-inline + BlockContainer at (0,0) content-size 800x600 [BFC] children: not-inline + BlockContainer at (8,8) content-size 784x21.84375 children: inline + line 0 width: 300, height: 21.84375, bottom: 21.84375, baseline: 16.921875 + frag 0 from BlockContainer start: 0, length: 0, rect: [8,12 300x12] + BlockContainer at (8,12) content-size 300x12 inline-block [BFC] children: not-inline + BlockContainer
at (9,13) content-size 298x12 children: not-inline + BlockContainer
at (9,13) content-size 298x12 children: not-inline + TextNode <#text> + TextNode <#text> + +ViewportPaintable (Viewport<#document>) [0,0 800x600] + PaintableWithLines (BlockContainer) [0,0 800x600] + PaintableWithLines (BlockContainer) [8,8 784x21.84375] + PaintableWithLines (BlockContainer#a) [8,12 300x12] overflow: [8,12 300x14] + PaintableWithLines (BlockContainer
) [8,12 300x14] + PaintableWithLines (BlockContainer
) [9,13 298x12] diff --git a/Tests/LibWeb/Layout/input/element-use-pseudo-element.html b/Tests/LibWeb/Layout/input/element-use-pseudo-element.html new file mode 100644 index 0000000000..d94848d540 --- /dev/null +++ b/Tests/LibWeb/Layout/input/element-use-pseudo-element.html @@ -0,0 +1,9 @@ + + + diff --git a/Userland/Libraries/LibWeb/CSS/CSSStyleDeclaration.cpp b/Userland/Libraries/LibWeb/CSS/CSSStyleDeclaration.cpp index 9596f9dedb..792922821e 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSStyleDeclaration.cpp +++ b/Userland/Libraries/LibWeb/CSS/CSSStyleDeclaration.cpp @@ -59,11 +59,6 @@ String PropertyOwningCSSStyleDeclaration::item(size_t index) const return MUST(String::from_utf8(CSS::string_from_property_id(m_properties[index].property_id))); } -CSS::PropertyID PropertyOwningCSSStyleDeclaration::property_id_by_index(size_t index) const -{ - return m_properties[index].property_id; -} - JS::NonnullGCPtr ElementInlineCSSStyleDeclaration::create(DOM::Element& element, Vector properties, HashMap custom_properties) { auto& realm = element.realm(); diff --git a/Userland/Libraries/LibWeb/CSS/CSSStyleDeclaration.h b/Userland/Libraries/LibWeb/CSS/CSSStyleDeclaration.h index 864ccfda36..b485a6169d 100644 --- a/Userland/Libraries/LibWeb/CSS/CSSStyleDeclaration.h +++ b/Userland/Libraries/LibWeb/CSS/CSSStyleDeclaration.h @@ -24,7 +24,6 @@ public: virtual size_t length() const = 0; virtual String item(size_t index) const = 0; - virtual CSS::PropertyID property_id_by_index(size_t index) const = 0; virtual Optional property(PropertyID) const = 0; @@ -64,7 +63,6 @@ public: virtual size_t length() const override; virtual String item(size_t index) const override; - virtual CSS::PropertyID property_id_by_index(size_t index) const override; virtual Optional property(PropertyID) const override; diff --git a/Userland/Libraries/LibWeb/CSS/ResolvedCSSStyleDeclaration.cpp b/Userland/Libraries/LibWeb/CSS/ResolvedCSSStyleDeclaration.cpp index a8246800f8..0b2f71d216 100644 --- a/Userland/Libraries/LibWeb/CSS/ResolvedCSSStyleDeclaration.cpp +++ b/Userland/Libraries/LibWeb/CSS/ResolvedCSSStyleDeclaration.cpp @@ -82,11 +82,6 @@ String ResolvedCSSStyleDeclaration::item(size_t index) const return MUST(String::from_utf8(string_from_property_id(property_id))); } -CSS::PropertyID ResolvedCSSStyleDeclaration::property_id_by_index(size_t index) const -{ - return static_cast(index + to_underlying(first_longhand_property_id)); -} - static NonnullRefPtr style_value_for_background_property(Layout::NodeWithStyle const& layout_node, Function(BackgroundLayerData const&)> callback, Function()> default_value) { auto const& background_layers = layout_node.background_layers(); diff --git a/Userland/Libraries/LibWeb/CSS/ResolvedCSSStyleDeclaration.h b/Userland/Libraries/LibWeb/CSS/ResolvedCSSStyleDeclaration.h index 8682e0ff48..422f82d1a3 100644 --- a/Userland/Libraries/LibWeb/CSS/ResolvedCSSStyleDeclaration.h +++ b/Userland/Libraries/LibWeb/CSS/ResolvedCSSStyleDeclaration.h @@ -21,7 +21,6 @@ public: virtual size_t length() const override; virtual String item(size_t index) const override; - virtual CSS::PropertyID property_id_by_index(size_t index) const override; virtual Optional property(PropertyID) const override; virtual WebIDL::ExceptionOr set_property(PropertyID, StringView css_text, StringView priority) override; diff --git a/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp b/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp index 79a295befb..8dcb2a31fa 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp +++ b/Userland/Libraries/LibWeb/CSS/StyleComputer.cpp @@ -2136,6 +2136,20 @@ ErrorOr> StyleComputer::compute_style_impl(DOM::Element& { build_rule_cache_if_needed(); + // Special path for elements that use pseudo element as style selector + if (element.use_pseudo_element().has_value()) { + auto& parent_element = verify_cast(*element.root().parent_or_shadow_host()); + auto style = TRY(compute_style(parent_element, *element.use_pseudo_element())); + + // Merge back inline styles + if (element.has_attribute(HTML::AttributeNames::style)) { + auto* inline_style = parse_css_style_attribute(CSS::Parser::ParsingContext(document()), *element.get_attribute(HTML::AttributeNames::style), element); + for (auto const& property : inline_style->properties()) + style->set_property(property.property_id, property.value); + } + return style; + } + auto style = StyleProperties::create(); // 1. Perform the cascade. This produces the "specified style" bool did_match_any_pseudo_element_rules = false; diff --git a/Userland/Libraries/LibWeb/HTML/HTMLMeterElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLMeterElement.cpp index d42c1daf8d..e677cdbbd3 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLMeterElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLMeterElement.cpp @@ -55,7 +55,6 @@ WebIDL::ExceptionOr HTMLMeterElement::set_value(double value) { TRY(set_attribute(HTML::AttributeNames::value, MUST(String::number(value)))); update_meter_value_element(); - document().invalidate_layout(); return {}; } @@ -74,7 +73,6 @@ WebIDL::ExceptionOr HTMLMeterElement::set_min(double value) { TRY(set_attribute(HTML::AttributeNames::min, MUST(String::number(value)))); update_meter_value_element(); - document().invalidate_layout(); return {}; } @@ -96,7 +94,6 @@ WebIDL::ExceptionOr HTMLMeterElement::set_max(double value) { TRY(set_attribute(HTML::AttributeNames::max, MUST(String::number(value)))); update_meter_value_element(); - document().invalidate_layout(); return {}; } @@ -120,7 +117,6 @@ WebIDL::ExceptionOr HTMLMeterElement::set_low(double value) { TRY(set_attribute(HTML::AttributeNames::low, MUST(String::number(value)))); update_meter_value_element(); - document().invalidate_layout(); return {}; } @@ -144,7 +140,6 @@ WebIDL::ExceptionOr HTMLMeterElement::set_high(double value) { TRY(set_attribute(HTML::AttributeNames::high, MUST(String::number(value)))); update_meter_value_element(); - document().invalidate_layout(); return {}; } @@ -168,7 +163,6 @@ WebIDL::ExceptionOr HTMLMeterElement::set_optimum(double value) { TRY(set_attribute(HTML::AttributeNames::optimum, MUST(String::number(value)))); update_meter_value_element(); - document().invalidate_layout(); return {}; } diff --git a/Userland/Libraries/LibWeb/HTML/HTMLProgressElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLProgressElement.cpp index c5ac8a5a54..bf394a134e 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLProgressElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLProgressElement.cpp @@ -53,7 +53,6 @@ WebIDL::ExceptionOr HTMLProgressElement::set_value(double value) TRY(set_attribute(HTML::AttributeNames::value, MUST(String::number(value)))); update_progress_value_element(); - document().invalidate_layout(); return {}; } @@ -74,7 +73,6 @@ WebIDL::ExceptionOr HTMLProgressElement::set_max(double value) TRY(set_attribute(HTML::AttributeNames::max, MUST(String::number(value)))); update_progress_value_element(); - document().invalidate_layout(); return {}; } diff --git a/Userland/Libraries/LibWeb/HTML/HTMLSelectElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLSelectElement.cpp index 3cb37b8545..3b61ce936e 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLSelectElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLSelectElement.cpp @@ -213,7 +213,6 @@ WebIDL::ExceptionOr HTMLSelectElement::set_value(String const& value) for (auto const& option_element : list_of_options()) option_element->set_selected(option_element->value() == value); update_inner_text_element(); - document().invalidate_layout(); // When the user agent is to send select update notifications, queue an element task on the user interaction task source given the select element to run these steps: queue_an_element_task(HTML::Task::Source::UserInteraction, [this] { @@ -323,7 +322,6 @@ void HTMLSelectElement::form_associated_element_was_inserted() if (options.size() > 0) { options.at(0)->set_selected(true); update_inner_text_element(); - document().invalidate_layout(); } } }); diff --git a/Userland/Libraries/LibWeb/Layout/TreeBuilder.cpp b/Userland/Libraries/LibWeb/Layout/TreeBuilder.cpp index 47ef98f662..4e49093547 100644 --- a/Userland/Libraries/LibWeb/Layout/TreeBuilder.cpp +++ b/Userland/Libraries/LibWeb/Layout/TreeBuilder.cpp @@ -313,32 +313,10 @@ ErrorOr TreeBuilder::create_layout_tree(DOM::Node& dom_node, TreeBuilder:: if (is(dom_node)) { auto& element = static_cast(dom_node); - - // Special path for elements that use pseudo element as style selector. - if (element.use_pseudo_element().has_value()) { - // Get base psuedo element selector style properties - auto& parent_element = verify_cast(*element.root().parent_or_shadow_host()); - style = TRY(style_computer.compute_style(parent_element, *element.use_pseudo_element())); - - // Merge back inline styles - auto const* inline_style = element.inline_style(); - if (inline_style) { - auto const& computed_style = element.computed_css_values(); - for (size_t i = 0; i < inline_style->length(); i++) { - auto property_id = inline_style->property_id_by_index(i); - if (auto property = computed_style->maybe_null_property(property_id); property) - style->set_property(property_id, *property); - } - } - display = style->display(); - } - // Common path: this is a regular DOM element. Style should be present already, thanks to Document::update_style(). - else { - element.clear_pseudo_element_nodes({}); - VERIFY(!element.needs_style_update()); - style = element.computed_css_values(); - display = style->display(); - } + element.clear_pseudo_element_nodes({}); + VERIFY(!element.needs_style_update()); + style = element.computed_css_values(); + display = style->display(); if (display.is_none()) return {}; layout_node = element.create_layout_node(*style);