mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-10-23 01:23:19 +00:00

Implements idea described in https://docs.google.com/document/d/1vEW86DaeVs4uQzNFI5R-_xS9TcS1Cs_EUsHRSgCHGu8 Invalidation sets are used to reduce the number of elements marked for style recalculation by collecting metadata from style rules about the dependencies between properties that could affect an element’s style. Currently, this optimization is only applied to style invalidation triggered by class list mutations on an element.
90 lines
2.9 KiB
C++
90 lines
2.9 KiB
C++
/*
|
|
* Copyright (c) 2025, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#include <LibWeb/CSS/InvalidationSet.h>
|
|
|
|
namespace Web::CSS {
|
|
|
|
void InvalidationSet::include_all_from(InvalidationSet const& other)
|
|
{
|
|
m_needs_invalidate_self |= other.m_needs_invalidate_self;
|
|
m_needs_invalidate_whole_subtree |= other.m_needs_invalidate_whole_subtree;
|
|
for (auto const& property : other.m_properties)
|
|
m_properties.set(property);
|
|
}
|
|
|
|
bool InvalidationSet::is_empty() const
|
|
{
|
|
return !m_needs_invalidate_self && !m_needs_invalidate_whole_subtree && m_properties.is_empty();
|
|
}
|
|
|
|
void InvalidationSet::for_each_property(Function<void(Property const&)> const& callback) const
|
|
{
|
|
if (m_needs_invalidate_self)
|
|
callback({ Property::Type::InvalidateSelf });
|
|
if (m_needs_invalidate_whole_subtree)
|
|
callback({ Property::Type::InvalidateWholeSubtree });
|
|
for (auto const& property : m_properties)
|
|
callback(property);
|
|
}
|
|
|
|
}
|
|
|
|
namespace AK {
|
|
|
|
unsigned Traits<Web::CSS::InvalidationSet::Property>::hash(Web::CSS::InvalidationSet::Property const& invalidation_set_property)
|
|
{
|
|
return pair_int_hash(to_underlying(invalidation_set_property.type), invalidation_set_property.name.hash());
|
|
}
|
|
|
|
ErrorOr<void> Formatter<Web::CSS::InvalidationSet::Property>::format(FormatBuilder& builder, Web::CSS::InvalidationSet::Property const& invalidation_set_property)
|
|
{
|
|
switch (invalidation_set_property.type) {
|
|
case Web::CSS::InvalidationSet::Property::Type::InvalidateSelf: {
|
|
TRY(builder.put_string("$"sv));
|
|
return {};
|
|
}
|
|
case Web::CSS::InvalidationSet::Property::Type::Class: {
|
|
TRY(builder.put_string("."sv));
|
|
TRY(builder.put_string(invalidation_set_property.name));
|
|
return {};
|
|
}
|
|
case Web::CSS::InvalidationSet::Property::Type::Id: {
|
|
TRY(builder.put_string("#"sv));
|
|
TRY(builder.put_string(invalidation_set_property.name));
|
|
return {};
|
|
}
|
|
case Web::CSS::InvalidationSet::Property::Type::TagName: {
|
|
TRY(builder.put_string(invalidation_set_property.name));
|
|
return {};
|
|
}
|
|
case Web::CSS::InvalidationSet::Property::Type::Attribute: {
|
|
TRY(builder.put_string("["sv));
|
|
TRY(builder.put_string(invalidation_set_property.name));
|
|
TRY(builder.put_string("]"sv));
|
|
return {};
|
|
}
|
|
case Web::CSS::InvalidationSet::Property::Type::InvalidateWholeSubtree: {
|
|
TRY(builder.put_string("*"sv));
|
|
return {};
|
|
}
|
|
default:
|
|
VERIFY_NOT_REACHED();
|
|
}
|
|
}
|
|
|
|
ErrorOr<void> Formatter<Web::CSS::InvalidationSet>::format(FormatBuilder& builder, Web::CSS::InvalidationSet const& invalidation_set)
|
|
{
|
|
bool first = true;
|
|
invalidation_set.for_each_property([&](auto const& property) {
|
|
if (!first)
|
|
builder.builder().append(", "sv);
|
|
builder.builder().appendff("{}", property);
|
|
});
|
|
return {};
|
|
}
|
|
|
|
}
|