예제 #1
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;
}
예제 #2
0
 bool operator()(const CSSSelector& selector)
 {
     return selector.relationIsAffectedByPseudoContent();
 }