示例#1
0
static inline MatchBasedOnRuleHash computeMatchBasedOnRuleHash(const CSSSelector& selector)
{
    if (selector.tagHistory())
        return MatchBasedOnRuleHash::None;

    if (selector.match() == CSSSelector::Tag) {
        const QualifiedName& tagQualifiedName = selector.tagQName();
        const AtomicString& selectorNamespace = tagQualifiedName.namespaceURI();
        if (selectorNamespace == starAtom || selectorNamespace == xhtmlNamespaceURI) {
            if (tagQualifiedName == anyQName())
                return MatchBasedOnRuleHash::Universal;
            return MatchBasedOnRuleHash::ClassC;
        }
        return MatchBasedOnRuleHash::None;
    }
    if (SelectorChecker::isCommonPseudoClassSelector(&selector))
        return MatchBasedOnRuleHash::ClassB;
#if ENABLE(SHADOW_DOM)
    if (selector.match() == CSSSelector::PseudoClass && selector.pseudoClassType() == CSSSelector::PseudoClassHost)
        return MatchBasedOnRuleHash::ClassB;
#endif
    if (selector.match() == CSSSelector::Id)
        return MatchBasedOnRuleHash::ClassA;
    if (selector.match() == CSSSelector::Class)
        return MatchBasedOnRuleHash::ClassB;
    return MatchBasedOnRuleHash::None;
}
示例#2
0
static inline bool isSelectorMatchingHTMLBasedOnRuleHash(const CSSSelector& selector)
{
    if (selector.match() == CSSSelector::Tag) {
        const AtomicString& selectorNamespace = selector.tagQName().namespaceURI();
        if (selectorNamespace != starAtom && selectorNamespace != xhtmlNamespaceURI)
            return false;
        if (selector.relation() == CSSSelector::SubSelector) {
            ASSERT(selector.tagHistory());
            return isSelectorMatchingHTMLBasedOnRuleHash(*selector.tagHistory());
        }
        return true;
    }
    if (SelectorChecker::isCommonPseudoClassSelector(selector))
        return true;
    return selector.match() == CSSSelector::Id || selector.match() == CSSSelector::Class;
}
示例#3
0
static bool determineSelectorScopes(const CSSSelectorList& selectorList, HashSet<AtomicStringImpl*>& idScopes, HashSet<AtomicStringImpl*>& classScopes)
{
    for (CSSSelector* selector = selectorList.first(); selector; selector = CSSSelectorList::next(selector)) {
        CSSSelector* scopeSelector = 0;
        // This picks the widest scope, not the narrowest, to minimize the number of found scopes.
        for (CSSSelector* current = selector; current; current = current->tagHistory()) {
            // Prefer ids over classes.
            if (current->m_match == CSSSelector::Id)
                scopeSelector = current;
            else if (current->m_match == CSSSelector::Class && (!scopeSelector || scopeSelector->m_match != CSSSelector::Id))
                scopeSelector = current;
            CSSSelector::Relation relation = current->relation();
            if (relation != CSSSelector::Descendant && relation != CSSSelector::Child && relation != CSSSelector::SubSelector)
                break;
        }
        if (!scopeSelector)
            return false;
        ASSERT(scopeSelector->m_match == CSSSelector::Class || scopeSelector->m_match == CSSSelector::Id);
        if (scopeSelector->m_match == CSSSelector::Id)
            idScopes.add(scopeSelector->value().impl());
        else
            classScopes.add(scopeSelector->value().impl());
    }
    return true;
}
示例#4
0
static unsigned selectorSpecificity(const CSSSelector& firstSimpleSelector, bool isComputingMaximumSpecificity)
{
    unsigned total = simpleSelectorSpecificityInternal(firstSimpleSelector, isComputingMaximumSpecificity);

    for (const CSSSelector* selector = firstSimpleSelector.tagHistory(); selector; selector = selector->tagHistory())
        total = CSSSelector::addSpecificities(total, simpleSelectorSpecificityInternal(*selector, isComputingMaximumSpecificity));
    return total;
}
示例#5
0
void SelectorFilter::collectIdentifierHashes(const CSSSelector& selector,
                                             unsigned* identifierHashes,
                                             unsigned maximumIdentifierCount) {
  unsigned* hash = identifierHashes;
  unsigned* end = identifierHashes + maximumIdentifierCount;
  CSSSelector::RelationType relation = selector.relation();
  if (selector.relationIsAffectedByPseudoContent()) {
    // Disable fastRejectSelector.
    *identifierHashes = 0;
    return;
  }

  // Skip the topmost selector. It is handled quickly by the rule hashes.
  bool skipOverSubselectors = true;
  for (const CSSSelector* current = selector.tagHistory(); current;
       current = current->tagHistory()) {
    // Only collect identifiers that match ancestors.
    switch (relation) {
      case CSSSelector::SubSelector:
        if (!skipOverSubselectors)
          collectDescendantSelectorIdentifierHashes(*current, hash);
        break;
      case CSSSelector::DirectAdjacent:
      case CSSSelector::IndirectAdjacent:
        skipOverSubselectors = true;
        break;
      case CSSSelector::ShadowSlot:
        // Disable fastRejectSelector.
        *identifierHashes = 0;
        return;
      case CSSSelector::Descendant:
      case CSSSelector::Child:
      // Fall through.
      case CSSSelector::ShadowPseudo:
      case CSSSelector::ShadowDeep:
        skipOverSubselectors = false;
        collectDescendantSelectorIdentifierHashes(*current, hash);
        break;
    }
    if (hash == end)
      return;
    relation = current->relation();
    if (current->relationIsAffectedByPseudoContent()) {
      // Disable fastRejectSelector.
      *identifierHashes = 0;
      return;
    }
  }
  *hash = 0;
}
示例#6
0
static void collectFeaturesFromRuleData(RuleFeatureSet& features, const RuleData& ruleData)
{
    bool foundSiblingSelector = false;
    for (CSSSelector* selector = ruleData.selector(); selector; selector = selector->tagHistory()) {
        features.collectFeaturesFromSelector(selector);
        
        if (CSSSelectorList* selectorList = selector->selectorList()) {
            for (CSSSelector* subSelector = selectorList->first(); subSelector; subSelector = CSSSelectorList::next(subSelector)) {
                if (!foundSiblingSelector && selector->isSiblingSelector())
                    foundSiblingSelector = true;
                features.collectFeaturesFromSelector(subSelector);
            }
        } else if (!foundSiblingSelector && selector->isSiblingSelector())
            foundSiblingSelector = true;
    }
    if (foundSiblingSelector)
        features.siblingRules.append(RuleFeature(ruleData.rule(), ruleData.selectorIndex(), ruleData.hasDocumentSecurityOrigin()));
    if (ruleData.containsUncommonAttributeSelector())
        features.uncommonAttributeRules.append(RuleFeature(ruleData.rule(), ruleData.selectorIndex(), ruleData.hasDocumentSecurityOrigin()));
}
示例#7
0
static bool validateSelector(CSSSelector* selector)
{
    ASSERT(selector);

    if (!validateSubSelector(selector))
        return false;

    CSSSelector* prevSubSelector = selector;
    CSSSelector* subSelector = selector->tagHistory();

    while (subSelector) {
        if (prevSubSelector->relation() != CSSSelector::SubSelector)
            return false;
        if (!validateSubSelector(subSelector))
            return false;

        prevSubSelector = subSelector;
        subSelector = subSelector->tagHistory();
    }

    return true;
}