diff --git a/Libraries/LibWeb/DOM/Element.cpp b/Libraries/LibWeb/DOM/Element.cpp index 08791c1ad08..4cfb4581c9b 100644 --- a/Libraries/LibWeb/DOM/Element.cpp +++ b/Libraries/LibWeb/DOM/Element.cpp @@ -1970,34 +1970,23 @@ ErrorOr Element::scroll_into_view(Optional const& old_value, Optional const& new_value) { - // FIXME: Only invalidate if the attribute can actually affect style. - - // OPTIMIZATION: For the `style` attribute, unless it's referenced by an attribute selector, - // only invalidate the element itself, then let inheritance propagate to descendants. - if (attribute_name == HTML::AttributeNames::style) { - if (!document().style_computer().has_attribute_selector(HTML::AttributeNames::style)) { - set_needs_style_update(true); - for_each_shadow_including_descendant([](Node& node) { - if (!node.is_element()) - return TraversalDecision::Continue; - auto& element = static_cast(node); - element.set_needs_inherited_style_update(true); - return TraversalDecision::Continue; - }); - } else { - invalidate_style(StyleInvalidationReason::ElementAttributeChange); - } + if (is_presentational_hint(attribute_name)) { + invalidate_style(StyleInvalidationReason::ElementAttributeChange); return; } - if (attribute_name == HTML::AttributeNames::class_) { + Vector changed_properties; + ForceSelfStyleInvalidation force_self_invalidation = ForceSelfStyleInvalidation::No; + if (attribute_name == HTML::AttributeNames::style) { + force_self_invalidation = ForceSelfStyleInvalidation::Yes; + changed_properties.append({ .type = CSS::InvalidationSet::Property::Type::Attribute, .value = HTML::AttributeNames::style }); + } else if (attribute_name == HTML::AttributeNames::class_) { Vector old_classes; Vector new_classes; if (old_value.has_value()) old_classes = old_value->bytes_as_string_view().split_view_if(Infra::is_ascii_whitespace); if (new_value.has_value()) new_classes = new_value->bytes_as_string_view().split_view_if(Infra::is_ascii_whitespace); - Vector changed_properties; for (auto& old_class : old_classes) { if (!new_classes.contains_slow(old_class)) { changed_properties.append({ .type = CSS::InvalidationSet::Property::Type::Class, .value = FlyString::from_utf8_without_validation(old_class.bytes()) }); @@ -2009,23 +1998,13 @@ void Element::invalidate_style_after_attribute_change(FlyString const& attribute } } changed_properties.append({ .type = CSS::InvalidationSet::Property::Type::Attribute, .value = HTML::AttributeNames::class_ }); - invalidate_style(StyleInvalidationReason::ElementAttributeChange, changed_properties); - return; - } - - if (attribute_name == HTML::AttributeNames::id) { - Vector changed_properties; + } else if (attribute_name == HTML::AttributeNames::id) { if (old_value.has_value()) changed_properties.append({ .type = CSS::InvalidationSet::Property::Type::Id, .value = FlyString(old_value.value()) }); if (new_value.has_value()) changed_properties.append({ .type = CSS::InvalidationSet::Property::Type::Id, .value = FlyString(new_value.value()) }); changed_properties.append({ .type = CSS::InvalidationSet::Property::Type::Attribute, .value = HTML::AttributeNames::id }); - invalidate_style(StyleInvalidationReason::ElementAttributeChange, changed_properties); - return; - } - - Vector changed_properties; - if (attribute_name == HTML::AttributeNames::disabled) { + } else if (attribute_name == HTML::AttributeNames::disabled) { changed_properties.append({ .type = CSS::InvalidationSet::Property::Type::PseudoClass, .value = CSS::PseudoClass::Disabled }); changed_properties.append({ .type = CSS::InvalidationSet::Property::Type::PseudoClass, .value = CSS::PseudoClass::Enabled }); } else if (attribute_name == HTML::AttributeNames::placeholder) { @@ -2034,13 +2013,8 @@ void Element::invalidate_style_after_attribute_change(FlyString const& attribute changed_properties.append({ .type = CSS::InvalidationSet::Property::Type::PseudoClass, .value = CSS::PseudoClass::Checked }); } - if (is_presentational_hint(attribute_name)) { - invalidate_style(StyleInvalidationReason::ElementAttributeChange); - return; - } - changed_properties.append({ .type = CSS::InvalidationSet::Property::Type::Attribute, .value = attribute_name }); - invalidate_style(StyleInvalidationReason::ElementAttributeChange, changed_properties); + invalidate_style(StyleInvalidationReason::ElementAttributeChange, changed_properties, force_self_invalidation); } bool Element::is_hidden() const diff --git a/Libraries/LibWeb/DOM/Node.cpp b/Libraries/LibWeb/DOM/Node.cpp index d2470242565..f19188b5e06 100644 --- a/Libraries/LibWeb/DOM/Node.cpp +++ b/Libraries/LibWeb/DOM/Node.cpp @@ -470,7 +470,7 @@ void Node::invalidate_style(StyleInvalidationReason reason) document().schedule_style_update(); } -void Node::invalidate_style(StyleInvalidationReason reason, Vector const& properties) +void Node::invalidate_style(StyleInvalidationReason reason, Vector const& properties, ForceSelfStyleInvalidation force_self_invalidation) { if (is_character_data()) return; @@ -485,6 +485,8 @@ void Node::invalidate_style(StyleInvalidationReason reason, Vector const&); + void invalidate_style(StyleInvalidationReason, Vector const&, ForceSelfStyleInvalidation = ForceSelfStyleInvalidation::No); void set_document(Badge, Document&);