/* * Copyright (c) 2018-2024, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include namespace Web::SelectorEngine { enum class SelectorKind { Normal, Relative, }; enum class HasMatchResult : u8 { Matched, NotMatched, }; struct HasResultCacheKey { CSS::Selector const* selector; GC::Ptr element; void visit_edges(GC::Cell::Visitor& visitor) { visitor.visit(element); } bool operator==(HasResultCacheKey const&) const = default; }; struct HasResultCacheKeyTraits : Traits { static unsigned hash(HasResultCacheKey const& key) { return pair_int_hash(ptr_hash(key.selector), ptr_hash(key.element.ptr())); } }; using HasResultCache = HashMap; struct MatchContext { GC::Ptr style_sheet_for_rule {}; GC::Ptr subject {}; GC::Ptr slotted_element {}; // Only set when matching a ::slotted() pseudo-element GC::Ptr part_owning_parent {}; // Only set temporarily when matching a ::part() pseudo-element GC::Ptr rule_shadow_root {}; // Shadow root the matched rule belongs to bool collect_per_element_selector_involvement_metadata { false }; bool for_host_part_matching { false }; // True while we are evaluating the argument of a :has() pseudo-class. // Elements visited by selector walks (descendants, siblings, etc.) while // this is set get marked as in_has_scope so the invalidation walker can // later terminate once it leaves the scope. Transparent to callers; set // by matches_has_pseudo_class with a ScopeGuard. bool inside_has_argument_match { false }; CSS::PseudoClassBitmap attempted_pseudo_class_matches {}; HasResultCache* has_result_cache { nullptr }; }; bool matches(CSS::Selector const&, DOM::AbstractElement const&, GC::Ptr shadow_host, MatchContext& context, GC::Ptr scope = {}, SelectorKind selector_kind = SelectorKind::Normal, GC::Ptr anchor = nullptr); }