mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-10-05 15:49:15 +00:00
Some checks are pending
CI / macOS, arm64, Sanitizer, Clang (push) Waiting to run
CI / Linux, x86_64, Fuzzers, Clang (push) Waiting to run
CI / Linux, x86_64, Sanitizer, GNU (push) Waiting to run
CI / Linux, x86_64, Sanitizer, Clang (push) Waiting to run
Package the js repl as a binary artifact / Linux, arm64 (push) Waiting to run
Package the js repl as a binary artifact / macOS, arm64 (push) Waiting to run
Package the js repl as a binary artifact / Linux, x86_64 (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Label PRs with merge conflicts / auto-labeler (push) Waiting to run
Push notes / build (push) Waiting to run
This partially reverts commit 3aff3327c4
by removing the code change but keeping the added test.
Now that paintables visibility caching has been reverted, this is no
longer doing anything except causing excessive relayouts on pages
like https://linear.app/
77 lines
3.8 KiB
C++
77 lines
3.8 KiB
C++
/*
|
|
* Copyright (c) 2024, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
|
|
* Copyright (c) 2025, Manuel Zahariev <manuel@duck.com>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#include <LibWeb/CSS/ComputedProperties.h>
|
|
#include <LibWeb/CSS/StyleInvalidation.h>
|
|
#include <LibWeb/CSS/StyleValues/KeywordStyleValue.h>
|
|
|
|
namespace Web::CSS {
|
|
|
|
RequiredInvalidationAfterStyleChange compute_property_invalidation(CSS::PropertyID property_id, RefPtr<StyleValue const> const& old_value, RefPtr<StyleValue const> const& new_value)
|
|
{
|
|
RequiredInvalidationAfterStyleChange invalidation;
|
|
|
|
bool const property_value_changed = (!old_value || !new_value) || *old_value != *new_value;
|
|
if (!property_value_changed)
|
|
return invalidation;
|
|
|
|
// NOTE: If the computed CSS display, position, content, or content-visibility property changes, we have to rebuild the entire layout tree.
|
|
// In the future, we should figure out ways to rebuild a smaller part of the tree.
|
|
if (AK::first_is_one_of(property_id, CSS::PropertyID::Display, CSS::PropertyID::Position, CSS::PropertyID::Content, CSS::PropertyID::ContentVisibility)) {
|
|
return RequiredInvalidationAfterStyleChange::full();
|
|
}
|
|
|
|
// NOTE: If the text-transform property changes, it may affect layout. Furthermore, since the
|
|
// Layout::TextNode caches the post-transform text, we have to update the layout tree.
|
|
if (property_id == CSS::PropertyID::TextTransform) {
|
|
invalidation.rebuild_layout_tree = true;
|
|
invalidation.relayout = true;
|
|
invalidation.repaint = true;
|
|
return invalidation;
|
|
}
|
|
|
|
// NOTE: If one of the overflow properties change, we rebuild the entire layout tree.
|
|
// This ensures that overflow propagation from root/body to viewport happens correctly.
|
|
// In the future, we can make this invalidation narrower.
|
|
if (property_id == CSS::PropertyID::OverflowX || property_id == CSS::PropertyID::OverflowY) {
|
|
return RequiredInvalidationAfterStyleChange::full();
|
|
}
|
|
|
|
if (AK::first_is_one_of(property_id, CSS::PropertyID::CounterReset, CSS::PropertyID::CounterSet, CSS::PropertyID::CounterIncrement)) {
|
|
invalidation.rebuild_layout_tree = property_value_changed;
|
|
return invalidation;
|
|
}
|
|
|
|
// OPTIMIZATION: Special handling for CSS `visibility`:
|
|
if (property_id == CSS::PropertyID::Visibility) {
|
|
// We don't need to relayout if the visibility changes from visible to hidden or vice versa. Only collapse requires relayout.
|
|
if ((old_value && old_value->to_keyword() == CSS::Keyword::Collapse) != (new_value && new_value->to_keyword() == CSS::Keyword::Collapse))
|
|
invalidation.relayout = true;
|
|
// Of course, we still have to repaint on any visibility change.
|
|
invalidation.repaint = true;
|
|
} else if (CSS::property_affects_layout(property_id)) {
|
|
invalidation.relayout = true;
|
|
}
|
|
|
|
if (property_id == CSS::PropertyID::Opacity && old_value && new_value) {
|
|
// OPTIMIZATION: An element creates a stacking context when its opacity changes from 1 to less than 1
|
|
// and stops to create one when opacity returns to 1. So stacking context tree rebuild is
|
|
// not required for opacity changes within the range below 1.
|
|
auto old_value_opacity = CSS::ComputedProperties::resolve_opacity_value(*old_value);
|
|
auto new_value_opacity = CSS::ComputedProperties::resolve_opacity_value(*new_value);
|
|
if (old_value_opacity != new_value_opacity && (old_value_opacity == 1 || new_value_opacity == 1)) {
|
|
invalidation.rebuild_stacking_context_tree = true;
|
|
}
|
|
} else if (CSS::property_affects_stacking_context(property_id)) {
|
|
invalidation.rebuild_stacking_context_tree = true;
|
|
}
|
|
invalidation.repaint = true;
|
|
|
|
return invalidation;
|
|
}
|
|
|
|
}
|