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; }
bool operator()(const CSSSelector& selector) { return selector.relationIsAffectedByPseudoContent(); }