Repository: LadybirdBrowser/ladybird
File: Libraries/LibWeb/DOM/Document.cpp (C++)

Code before:
        invalidate_display_list();

    if (invalidation.rebuild_accumulated_visual_contexts)
        set_needs_accumulated_visual_contexts_update(true);

    if (invalidation.rebuild_stacking_context_tree)
        invalidate_stacking_context_tree();
    m_needs_full_style_update = false;
}

bool Document::element_needs_style_update(AbstractElement const& abstract_element) const
{
    // If there are document-level reasons to update style, we can't skip.
    if (m_needs_full_style_update)
        return true;
    if (m_needs_animated_style_update)
        return true;
    if (m_needs_invalidation_of_elements_affected_by_has)
        return true;
    if (m_style_invalidator->has_pending_invalidations())
        return true;

    // Walk from the element to the document root. If any node on the path
    // has its own style marked dirty, the element's computed style could
    // change (e.g. via inherited properties), so we must update.
    for (Node const* node = &abstract_element.element(); node; node = node->parent_or_shadow_host()) {
        if (node->needs_style_update())
            return true;
        if (node->entire_subtree_needs_style_update())
            return true;
    }

    return false;
}

void Document::update_animated_style_if_needed()
{
    if (!m_needs_animated_style_update)
        return;

    Animations::AnimationUpdateContext context;

    for (auto& timeline : m_associated_animation_timelines) {
        for (auto& animation : timeline->associated_animations()) {
            if (animation->is_idle())
                continue;
            if (auto effect = animation->effect())
                effect->update_computed_properties(context);
        }
    }


Review comment (suggestion):
I suspect this should use `node->flat_tree_parent()` instead of `node->parent_or_shadow_host()`? Otherwise slotted elements don't look at their slot.

Code after:
    // NOTE: If this is a document hosting <template> contents, style update is unnecessary.
    if (m_created_for_appropriate_template_contents)
        return;

    // Fetch the viewport rect once, instead of repeatedly, during style computation.
    style_computer().set_viewport_rect({}, viewport_rect());

    evaluate_media_rules();

    style_computer().reset_has_result_cache();
    style_computer().reset_ancestor_filter();

    build_registered_properties_cache();

    auto invalidation = update_style_recursively(*this, style_computer(), false, false, false);
    if (!invalidation.is_none())
        invalidate_display_list();

    if (invalidation.rebuild_accumulated_visual_contexts)
        set_needs_accumulated_visual_contexts_update(true);

    if (invalidation.rebuild_stacking_context_tree)
        invalidate_stacking_context_tree();
    m_needs_full_style_update = false;
}

bool Document::element_needs_style_update(AbstractElement const& abstract_element) const
{
    // If there are document-level reasons to update style, we can't skip.
    if (m_needs_full_style_update)
        return true;
    if (m_needs_animated_style_update)
        return true;
    if (m_needs_invalidation_of_elements_affected_by_has)
        return true;
    if (m_style_invalidator->has_pending_invalidations())
        return true;

    // Check the element itself.
    if (abstract_element.element().needs_style_update())
        return true;
    if (abstract_element.element().entire_subtree_needs_style_update())
        return true;

    // Walk the inheritance ancestor chain. We use element_to_inherit_style_from()
    // because style inheritance follows the flat tree (slotted elements inherit
    // from their assigned slot, not their DOM parent). If any ancestor on the
    // path has its style marked dirty, the target element's computed style could
    // change via inherited properties, so we must update.
    for (auto ancestor = abstract_element.element_to_inherit_style_from(); ancestor.has_value(); ancestor = ancestor->element_to_inherit_style_from()) {
        if (ancestor->element().needs_style_update())