chromium/third_party/blink/renderer/core/css/rule_set_diff.h

// Copyright 2023 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_RULE_SET_DIFF_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_CSS_RULE_SET_DIFF_H_

#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/heap/collection_support/heap_hash_set.h"
#include "v8/include/cppgc/garbage-collected.h"

namespace blink {

class RuleSet;
class StyleRule;
class StyleRuleBase;

// When mutating a stylesheet (inserting rules, deleting rules, modifying
// selectors, modifying contents of rules), RuleSetDiff stores a list of
// affected rules. This is so that when we invalidate style based on the
// selectors in the old and new rulesets, we can consider only the selectors
// that were actually changed, instead of every rule in the sheet. This reduces
// recalculation scope significantly in several common situations, such as
// inserting a single rule into a large stylesheet. The RuleSetDiff is
// essentially a mapping from (old ruleset, new ruleset) -> (changed rules),
// which can then be used to create a “diff ruleset” that contains fewer
// selectors to check during invalidation.
//
// For simplicity, we keep a list of StyleRules, even though we only actually
// care about the selectors; CSSSelector is not usually kept alive on its own,
// and comparing StyleRule is cheaper than trying to deduplicate selectors.
// We can have false positives (e.g., if someone changed a rule but then changed
// it back again) but never false negatives. If a stylesheet modifies something
// that is not a StyleRule (such as a @keyframe, or an @import statement),
// we give up and mark the entire diff as “unrepresentable”; this means that
// we will need to test all selectors in both the old and new rule sets.
//
// We do not diff entirely unrelated stylesheets (e.g. if someone changes
// an entire stylesheet with innerText); RuleSetDiff only gets populated
// where people use explicit CSSOM mutation (insertRule etc.).
class CORE_EXPORT RuleSetDiff : public GarbageCollected<RuleSetDiff> {};

}  // namespace blink

#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_CSS_RULE_SET_DIFF_H_