mirror of
https://github.com/LadybirdBrowser/ladybird
synced 2026-05-03 13:02:09 +02:00
CharacterData.cpp still handled the style invalidation fallout from text mutations under dir=auto ancestors directly. Move that behavior into the CSS language invalidation helper. CharacterData continues to own text replacement and layout text updates. The helper now owns the inherited :dir() restyle and :has(:dir(...)) ancestor scheduling that can follow from text content changes.
59 lines
2.3 KiB
C++
59 lines
2.3 KiB
C++
/*
|
|
* Copyright (c) 2026-present, the Ladybird developers
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#include <LibWeb/CSS/Invalidation/LanguageInvalidator.h>
|
|
#include <LibWeb/CSS/StyleScope.h>
|
|
#include <LibWeb/DOM/CharacterData.h>
|
|
#include <LibWeb/DOM/Element.h>
|
|
#include <LibWeb/DOM/ShadowRoot.h>
|
|
#include <LibWeb/TraversalDecision.h>
|
|
|
|
namespace Web::CSS::Invalidation {
|
|
|
|
static void invalidate_descendants_affected_by_language_or_directionality(DOM::Element& element, bool is_directionality_change)
|
|
{
|
|
// dir and lang both inherit, so all descendants' :dir() / :lang() matches and direction-dependent layout/text
|
|
// need to be recomputed.
|
|
element.for_each_shadow_including_inclusive_descendant([is_directionality_change](auto& node) {
|
|
if (auto* element = as_if<DOM::Element>(node)) {
|
|
if (!is_directionality_change)
|
|
element->invalidate_lang_value();
|
|
element->set_needs_style_update(true);
|
|
}
|
|
return TraversalDecision::Continue;
|
|
});
|
|
|
|
// :has(:dir(...)) and :has(:lang(...)) on ancestors aren't keyed on any property the regular invalidation
|
|
// plan tracks, so explicitly schedule the :has() ancestor walk here.
|
|
element.for_each_style_scope_which_may_observe_the_node([&](CSS::StyleScope& scope) {
|
|
scope.schedule_ancestors_style_invalidation_due_to_presence_of_has(element);
|
|
});
|
|
}
|
|
|
|
void invalidate_style_after_language_change(DOM::Element& element)
|
|
{
|
|
invalidate_descendants_affected_by_language_or_directionality(element, false);
|
|
}
|
|
|
|
void invalidate_style_after_directionality_change(DOM::Element& element)
|
|
{
|
|
invalidate_descendants_affected_by_language_or_directionality(element, true);
|
|
}
|
|
|
|
void invalidate_style_after_text_directionality_change(DOM::CharacterData& character_data)
|
|
{
|
|
// dir=auto resolves an element's effective directionality from its text content, so any ancestor with dir=auto
|
|
// can flip its :dir() match when this text changes. Recompute style on each such ancestor's subtree and propagate
|
|
// :has(:dir(...)) invalidation up its ancestor chain.
|
|
for (auto ancestor = character_data.parent_element(); ancestor; ancestor = ancestor->parent_element()) {
|
|
if (ancestor->dir() != DOM::Element::Dir::Auto)
|
|
continue;
|
|
invalidate_descendants_affected_by_language_or_directionality(*ancestor, true);
|
|
}
|
|
}
|
|
|
|
}
|