/* * Copyright (c) 2025, Aliaksandr Kalenik * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include namespace Web::CSS::Invalidation { class StyleInvalidator : public GC::Cell { GC_CELL(StyleInvalidator, GC::Cell); GC_DECLARE_ALLOCATOR(StyleInvalidator); public: void invalidate(DOM::Node& node); bool enqueue_invalidation_plan(DOM::Node&, DOM::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 { DOM::StyleInvalidationReason reason; CSS::DescendantInvalidationRule rule; bool operator==(PendingDescendantInvalidation const&) const = default; }; void add_pending_invalidation(GC::Ref, DOM::StyleInvalidationReason, CSS::InvalidationPlan const&); void apply_invalidation_plan(DOM::Element&, DOM::StyleInvalidationReason, CSS::InvalidationPlan const&, bool& invalidate_entire_subtree); void apply_sibling_invalidation(DOM::Element&, DOM::StyleInvalidationReason, CSS::SiblingInvalidationRule const&); void perform_pending_style_invalidations(DOM::Node& node, bool invalidate_entire_subtree); HashMap, Vector> m_pending_invalidations; Vector m_active_descendant_invalidations; }; }