mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-01-22 09:12:13 -05:00
LibWeb: Use invalidation sets for "style" attribute invalidation
This commit is contained in:
parent
bf36d829ef
commit
e0051db62e
Notes:
github-actions[bot]
2025-01-20 17:24:39 +00:00
Author: https://github.com/kalenikaliaksandr Commit: https://github.com/LadybirdBrowser/ladybird/commit/e0051db62e6 Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/3310
3 changed files with 19 additions and 39 deletions
|
@ -1970,34 +1970,23 @@ ErrorOr<void> Element::scroll_into_view(Optional<Variant<bool, ScrollIntoViewOpt
|
|||
|
||||
void Element::invalidate_style_after_attribute_change(FlyString const& attribute_name, Optional<String> const& old_value, Optional<String> 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<Element&>(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<CSS::InvalidationSet::Property> 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<StringView> old_classes;
|
||||
Vector<StringView> 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<CSS::InvalidationSet::Property> 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<CSS::InvalidationSet::Property> 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<CSS::InvalidationSet::Property> 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
|
||||
|
|
|
@ -470,7 +470,7 @@ void Node::invalidate_style(StyleInvalidationReason reason)
|
|||
document().schedule_style_update();
|
||||
}
|
||||
|
||||
void Node::invalidate_style(StyleInvalidationReason reason, Vector<CSS::InvalidationSet::Property> const& properties)
|
||||
void Node::invalidate_style(StyleInvalidationReason reason, Vector<CSS::InvalidationSet::Property> const& properties, ForceSelfStyleInvalidation force_self_invalidation)
|
||||
{
|
||||
if (is_character_data())
|
||||
return;
|
||||
|
@ -485,6 +485,8 @@ void Node::invalidate_style(StyleInvalidationReason reason, Vector<CSS::Invalida
|
|||
}
|
||||
|
||||
auto invalidation_set = document().style_computer().invalidation_set_for_properties(properties);
|
||||
if (force_self_invalidation == ForceSelfStyleInvalidation::Yes)
|
||||
invalidation_set.set_needs_invalidate_self();
|
||||
if (invalidation_set.is_empty())
|
||||
return;
|
||||
|
||||
|
|
|
@ -297,8 +297,12 @@ public:
|
|||
bool child_needs_style_update() const { return m_child_needs_style_update; }
|
||||
void set_child_needs_style_update(bool b) { m_child_needs_style_update = b; }
|
||||
|
||||
enum class ForceSelfStyleInvalidation : bool {
|
||||
Yes,
|
||||
No
|
||||
};
|
||||
void invalidate_style(StyleInvalidationReason);
|
||||
void invalidate_style(StyleInvalidationReason, Vector<CSS::InvalidationSet::Property> const&);
|
||||
void invalidate_style(StyleInvalidationReason, Vector<CSS::InvalidationSet::Property> const&, ForceSelfStyleInvalidation = ForceSelfStyleInvalidation::No);
|
||||
|
||||
void set_document(Badge<Document>, Document&);
|
||||
|
||||
|
|
Loading…
Reference in a new issue