mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-07 00:29:15 +00: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: e0051db62e
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)
|
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.
|
if (is_presentational_hint(attribute_name)) {
|
||||||
|
invalidate_style(StyleInvalidationReason::ElementAttributeChange);
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
return;
|
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> old_classes;
|
||||||
Vector<StringView> new_classes;
|
Vector<StringView> new_classes;
|
||||||
if (old_value.has_value())
|
if (old_value.has_value())
|
||||||
old_classes = old_value->bytes_as_string_view().split_view_if(Infra::is_ascii_whitespace);
|
old_classes = old_value->bytes_as_string_view().split_view_if(Infra::is_ascii_whitespace);
|
||||||
if (new_value.has_value())
|
if (new_value.has_value())
|
||||||
new_classes = new_value->bytes_as_string_view().split_view_if(Infra::is_ascii_whitespace);
|
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) {
|
for (auto& old_class : old_classes) {
|
||||||
if (!new_classes.contains_slow(old_class)) {
|
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()) });
|
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_ });
|
changed_properties.append({ .type = CSS::InvalidationSet::Property::Type::Attribute, .value = HTML::AttributeNames::class_ });
|
||||||
invalidate_style(StyleInvalidationReason::ElementAttributeChange, changed_properties);
|
} else if (attribute_name == HTML::AttributeNames::id) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (attribute_name == HTML::AttributeNames::id) {
|
|
||||||
Vector<CSS::InvalidationSet::Property> changed_properties;
|
|
||||||
if (old_value.has_value())
|
if (old_value.has_value())
|
||||||
changed_properties.append({ .type = CSS::InvalidationSet::Property::Type::Id, .value = FlyString(old_value.value()) });
|
changed_properties.append({ .type = CSS::InvalidationSet::Property::Type::Id, .value = FlyString(old_value.value()) });
|
||||||
if (new_value.has_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::Id, .value = FlyString(new_value.value()) });
|
||||||
changed_properties.append({ .type = CSS::InvalidationSet::Property::Type::Attribute, .value = HTML::AttributeNames::id });
|
changed_properties.append({ .type = CSS::InvalidationSet::Property::Type::Attribute, .value = HTML::AttributeNames::id });
|
||||||
invalidate_style(StyleInvalidationReason::ElementAttributeChange, changed_properties);
|
} else if (attribute_name == HTML::AttributeNames::disabled) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector<CSS::InvalidationSet::Property> changed_properties;
|
|
||||||
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::Disabled });
|
||||||
changed_properties.append({ .type = CSS::InvalidationSet::Property::Type::PseudoClass, .value = CSS::PseudoClass::Enabled });
|
changed_properties.append({ .type = CSS::InvalidationSet::Property::Type::PseudoClass, .value = CSS::PseudoClass::Enabled });
|
||||||
} else if (attribute_name == HTML::AttributeNames::placeholder) {
|
} 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 });
|
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 });
|
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
|
bool Element::is_hidden() const
|
||||||
|
|
|
@ -470,7 +470,7 @@ void Node::invalidate_style(StyleInvalidationReason reason)
|
||||||
document().schedule_style_update();
|
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())
|
if (is_character_data())
|
||||||
return;
|
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);
|
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())
|
if (invalidation_set.is_empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
@ -297,8 +297,12 @@ public:
|
||||||
bool child_needs_style_update() const { return m_child_needs_style_update; }
|
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; }
|
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);
|
||||||
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&);
|
void set_document(Badge<Document>, Document&);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue