/* * Copyright (c) 2025, Aliaksandr Kalenik * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include namespace Web::DOM { class StyleInvalidator : public GC::Cell { GC_CELL(StyleInvalidator, GC::Cell); GC_DECLARE_ALLOCATOR(StyleInvalidator); public: void invalidate(Node& node); bool enqueue_invalidation_plan(Node&, StyleInvalidationReason, CSS::InvalidationPlan const&); bool has_pending_invalidations() const { return !m_pending_invalidations.is_empty(); } virtual void visit_edges(Cell::Visitor& visitor) override; private: struct PendingDescendantInvalidation { StyleInvalidationReason reason; CSS::DescendantInvalidationRule rule; }; void add_pending_invalidation(GC::Ref, StyleInvalidationReason, CSS::InvalidationPlan const&); void apply_invalidation_plan(Element&, StyleInvalidationReason, CSS::InvalidationPlan const&, bool& invalidate_entire_subtree); void apply_sibling_invalidation(Element&, StyleInvalidationReason, CSS::SiblingInvalidationRule const&); void perform_pending_style_invalidations(Node& node, bool invalidate_entire_subtree); HashMap, Vector> m_pending_invalidations; Vector m_active_descendant_invalidations; }; }