LibWeb: Use optimized invalidation for target-related pseudo classes

This commit is contained in:
Andreas Kling 2025-04-17 13:58:43 +02:00
parent 4efc553f46
commit 280e82094c
2 changed files with 25 additions and 5 deletions

View file

@ -2523,16 +2523,36 @@ void Document::set_active_element(Element* element)
paintable()->set_needs_display();
}
void Document::set_target_element(Element* element)
void Document::set_target_element(GC::Ptr<Element> element)
{
if (m_target_element.ptr() == element)
return;
GC::Ptr<Element> old_target_element = move(m_target_element);
m_target_element = element;
if (auto* invalidation_target = find_common_ancestor(old_target_element, m_target_element) ?: this)
invalidation_target->invalidate_style(StyleInvalidationReason::TargetElementChange);
auto* common_ancestor = find_common_ancestor(old_target_element, element);
GC::Ptr<Node> old_target_node_root = nullptr;
GC::Ptr<Node> new_target_node_root = nullptr;
if (old_target_element)
old_target_node_root = old_target_element->root();
if (element)
new_target_node_root = element->root();
if (old_target_node_root != new_target_node_root) {
if (old_target_node_root) {
invalidate_style_for_elements_affected_by_pseudo_class_change(CSS::PseudoClass::Target, m_target_element, *old_target_node_root, element);
invalidate_style_for_elements_affected_by_pseudo_class_change(CSS::PseudoClass::TargetWithin, m_target_element, *old_target_node_root, element);
}
if (new_target_node_root) {
invalidate_style_for_elements_affected_by_pseudo_class_change(CSS::PseudoClass::Target, m_target_element, *new_target_node_root, element);
invalidate_style_for_elements_affected_by_pseudo_class_change(CSS::PseudoClass::TargetWithin, m_target_element, *new_target_node_root, element);
}
} else {
invalidate_style_for_elements_affected_by_pseudo_class_change(CSS::PseudoClass::Target, m_target_element, *common_ancestor, element);
invalidate_style_for_elements_affected_by_pseudo_class_change(CSS::PseudoClass::TargetWithin, m_target_element, *common_ancestor, element);
}
m_target_element = element;
if (paintable())
paintable()->set_needs_display();

View file

@ -435,7 +435,7 @@ public:
void set_active_element(Element*);
Element const* target_element() const { return m_target_element.ptr(); }
void set_target_element(Element*);
void set_target_element(GC::Ptr<Element>);
void try_to_scroll_to_the_fragment();
void scroll_to_the_fragment();