bool RuleSet::findBestRuleSetAndAdd(const CSSSelector& component, RuleData& ruleData) { AtomicString id; AtomicString className; AtomicString customPseudoElementName; AtomicString tagName; #ifndef NDEBUG m_allRules.append(ruleData); #endif const CSSSelector* it = &component; for (; it && it->relation() == CSSSelector::SubSelector; it = it->tagHistory()) extractValuesforSelector(it, id, className, customPseudoElementName, tagName); if (it) extractValuesforSelector(it, id, className, customPseudoElementName, tagName); // Prefer rule sets in order of most likely to apply infrequently. if (!id.isEmpty()) { addToRuleSet(id, ensurePendingRules()->idRules, ruleData); return true; } if (!className.isEmpty()) { addToRuleSet(className, ensurePendingRules()->classRules, ruleData); return true; } if (!customPseudoElementName.isEmpty()) { // Custom pseudos come before ids and classes in the order of tagHistory, and have a relation of // ShadowPseudo between them. Therefore we should never be a situation where extractValuesforSelector // finsd id and className in addition to custom pseudo. ASSERT(id.isEmpty() && className.isEmpty()); addToRuleSet(customPseudoElementName, ensurePendingRules()->shadowPseudoElementRules, ruleData); return true; } if (component.pseudoType() == CSSSelector::PseudoCue) { m_cuePseudoRules.append(ruleData); return true; } if (SelectorChecker::isCommonPseudoClassSelector(component)) { switch (component.pseudoType()) { case CSSSelector::PseudoLink: case CSSSelector::PseudoVisited: case CSSSelector::PseudoAnyLink: m_linkPseudoClassRules.append(ruleData); return true; case CSSSelector::PseudoFocus: m_focusPseudoClassRules.append(ruleData); return true; default: ASSERT_NOT_REACHED(); return true; } } if (!tagName.isEmpty()) { addToRuleSet(tagName, ensurePendingRules()->tagRules, ruleData); return true; } if (component.isHostPseudoClass()) { m_shadowHostRules.append(ruleData); return true; } return false; }
bool RuleSet::findBestRuleSetAndAdd(const CSSSelector& component, RuleData& ruleData) { AtomicString id; AtomicString className; AtomicString customPseudoElementName; AtomicString tagName; #ifndef NDEBUG m_allRules.append(ruleData); #endif const CSSSelector* it = &component; for (; it && it->relation() == CSSSelector::SubSelector; it = it->tagHistory()) extractValuesforSelector(it, id, className, customPseudoElementName, tagName); if (it) extractValuesforSelector(it, id, className, customPseudoElementName, tagName); // Prefer rule sets in order of most likely to apply infrequently. if (!id.isEmpty()) { addToRuleSet(id, ensurePendingRules()->idRules, ruleData); return true; } if (!className.isEmpty()) { addToRuleSet(className, ensurePendingRules()->classRules, ruleData); return true; } if (!customPseudoElementName.isEmpty()) { // Custom pseudos come before ids and classes in the order of tagHistory, and have a relation of // ShadowPseudo between them. Therefore we should never be a situation where extractValuesforSelector // finsd id and className in addition to custom pseudo. ASSERT(id.isEmpty() && className.isEmpty()); addToRuleSet(customPseudoElementName, ensurePendingRules()->shadowPseudoElementRules, ruleData); return true; } switch (component.pseudoType()) { case CSSSelector::PseudoCue: m_cuePseudoRules.append(ruleData); return true; case CSSSelector::PseudoLink: case CSSSelector::PseudoVisited: case CSSSelector::PseudoAnyLink: m_linkPseudoClassRules.append(ruleData); return true; case CSSSelector::PseudoFocus: m_focusPseudoClassRules.append(ruleData); return true; default: break; } if (!tagName.isEmpty()) { addToRuleSet(tagName, ensurePendingRules()->tagRules, ruleData); return true; } // TODO(esprehn): We shouldn't favor tagName over m_shadowHostRules, it means // selectors with div:host end up in the tagName list matched against all tags // even though they can't match anything at all. if (component.isHostPseudoClass()) { m_shadowHostRules.append(ruleData); return true; } return false; }