// Copyright 2024 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_CSS_INVALIDATION_RULE_INVALIDATION_DATA_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_INVALIDATION_RULE_INVALIDATION_DATA_H_ #include "third_party/blink/renderer/core/css/css_selector.h" #include "third_party/blink/renderer/core/css/invalidation/invalidation_set.h" #include "third_party/blink/renderer/platform/wtf/bloom_filter.h" #include "third_party/blink/renderer/platform/wtf/hash_map.h" #include "third_party/blink/renderer/platform/wtf/text/atomic_string.h" namespace blink { enum class RuleInvalidationDataVisitorType; // Summarizes and indexes the contents of CSS selectors. It creates // invalidation sets from them and makes them available via several // CollectInvalidationSetForFoo methods which use the indices to quickly gather // the relevant InvalidationSets for a particular DOM mutation. // Also captures several pieces of metadata that describe the entire set of // indexed selectors, for example "does any selector use ::first-line". // // In addition to complete invalidation (where we just throw up our // hands and invalidate everything) and :has() (which is described in // detail below), we have fundamentally four types of invalidation. // All will be described for a class selector, but apply equally to // id etc.: // // - Self-invalidation: When an element gets or loses class .c, // that element needs to be invalidated (.c exists as a subject in // some selector). We represent this by a bit in .c's invalidation // set (or by inserting the class name in a Bloom filter; see // class_invalidation_sets_). // // - Descendant invalidation: When an element gets or loses class .c, // all of its children with class .d need to be invalidated // (a selector of the form .c .d or .c > .d exists). We represent // this by storing .d in .c's descendant invalidation set. // // - Sibling invalidation: When an element gets or loses class .c, // all of its _siblings_ with class .d need to be invalidated // (a selector of the form .c ~ .d or .c + .d exists). // We represent this by storing .d in c's sibling invalidation set. // // - nth-child invalidation: Described immediately below. // // nth-child invalidation deals with peculiarities for :nth-child() // and related selectors (such as :only-of-type). We have a couple // of distinct strategies for dealing with them: // // - When we add or insert a node in the DOM tree where any child // of the parent has matched such a selector, we forcibly schedule // the (global) NthSiblingInvalidationSet. In other words, this // is hardly related to the normal invalidation mechanism at all. // // - Finally, for :nth_child(... of :has()), we get a signal when // a node is affected by :has() subject invalidation // (in StyleEngine::InvalidateElementAffectedByHas()), and can // forcibly schedule the NthSiblingInvalidationSet, much like // the previous point. // // - When we have :nth-child(... of S) as a subject (ie., not just // pure :nth-child(), but anything with a selector), we set the // invalidates_nth_ bit on all invalidation sets for S. This means // that whenever we schedule invalidation sets for anything in S, // and any child of the parent has matched any :nth-child() selector, // we'll schedule the NthSiblingInvalidationSet. // // - For all ancestors, we go through them recursively to find // S within :nth-child(), and set their invalidates_nth_ similarly. // This is conceptually the same thing as the previous point, // but since we already handle subjects and ancestors differently, // it was convenient with some mild code duplication here. // // - When we have sibling selectors against :nth-child, special // provisions apply; see comments NthSiblingInvalidationSet. class CORE_EXPORT RuleInvalidationData { … }; } // namespace blink #endif // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_INVALIDATION_RULE_INVALIDATION_DATA_H_