matchedRules method

List<CSSStyleRule> matchedRules(
  1. RuleSet ruleSet,
  2. Element element, {
  3. SelectorAncestorTokenSet? ancestorTokens,
  4. SelectorEvaluator? evaluator,
})

Implementation

List<CSSStyleRule> matchedRules(RuleSet ruleSet, Element element,
    {SelectorAncestorTokenSet? ancestorTokens,
    SelectorEvaluator? evaluator}) {
  final List<CSSStyleRule> matchedRules = <CSSStyleRule>[];

  // Reuse a single evaluator per matchedRules() to avoid repeated allocations.
  final SelectorEvaluator resolvedEvaluator = evaluator ?? SelectorEvaluator();
  // Share one lazily materialized ancestor token set across all candidate
  // checks in this match pass so we only walk the ancestor chain on demand.
  final SelectorAncestorTokenSet? resolvedAncestorTokens = ancestorTokens ??
      (DebugFlags.enableCssAncestryFastPath
          ? _buildAncestorTokens(element)
          : null);

  if (ruleSet.isEmpty) {
    return matchedRules;
  }

  // #id
  String? id = element.id;
  if (id != null) {
    final list = ruleSet.idRules[id];
    _collectMatchingRulesForList(
      list,
      element,
      evaluator: resolvedEvaluator,
      enableAncestryFastPath: DebugFlags.enableCssAncestryFastPath,
      ancestorTokens: resolvedAncestorTokens,
      matchedRules: matchedRules,
    );
  }

  // .class
  for (String className in element.classList) {
    final list = ruleSet.classRules[className];
    _collectMatchingRulesForList(
      list,
      element,
      evaluator: resolvedEvaluator,
      enableAncestryFastPath: DebugFlags.enableCssAncestryFastPath,
      ancestorTokens: resolvedAncestorTokens,
      matchedRules: matchedRules,
    );
  }

  // attribute selector
  for (String attribute in element.attributes.keys) {
    final list = ruleSet.attributeRules[attribute.toUpperCase()];
    _collectMatchingRulesForList(
      list,
      element,
      evaluator: resolvedEvaluator,
      enableAncestryFastPath: DebugFlags.enableCssAncestryFastPath,
      ancestorTokens: resolvedAncestorTokens,
      matchedRules: matchedRules,
    );
  }

  // tag selectors are stored uppercase; normalize element tag for lookup.
  final String tagLookup = element.tagName.toUpperCase();
  final listTag = ruleSet.tagRules[tagLookup];
  _collectMatchingRulesForList(
    listTag,
    element,
    evaluator: resolvedEvaluator,
    enableAncestryFastPath: DebugFlags.enableCssAncestryFastPath,
    ancestorTokens: resolvedAncestorTokens,
    matchedRules: matchedRules,
  );

  // universal
  _collectMatchingRulesForList(
    ruleSet.universalRules,
    element,
    evaluator: resolvedEvaluator,
    enableAncestryFastPath: DebugFlags.enableCssAncestryFastPath,
    ancestorTokens: resolvedAncestorTokens,
    matchedRules: matchedRules,
  );

  return matchedRules;
}