Esempio n. 1
0
static unsigned simpleSelectorFunctionalPseudoClassStaticSpecificity(const CSSSelector& simpleSelector, bool& ok)
{
    if (simpleSelector.match() == CSSSelector::PseudoClass) {
        CSSSelector::PseudoClassType pseudoClassType = simpleSelector.pseudoClassType();
        if (pseudoClassType == CSSSelector::PseudoClassMatches || pseudoClassType == CSSSelector::PseudoClassNthChild || pseudoClassType == CSSSelector::PseudoClassNthLastChild) {
            const CSSSelectorList* selectorList = simpleSelector.selectorList();
            if (!selectorList) {
                ASSERT_WITH_MESSAGE(pseudoClassType != CSSSelector::PseudoClassMatches, ":matches() should never be created without a valid selector list.");
                return 0;
            }

            const CSSSelector& firstSubselector = *selectorList->first();

            unsigned initialSpecificity = staticSpecificityInternal(firstSubselector, ok);
            if (!ok)
                return 0;

            const CSSSelector* subselector = &firstSubselector;
            while ((subselector = CSSSelectorList::next(subselector))) {
                unsigned subSelectorSpecificity = staticSpecificityInternal(*subselector, ok);
                if (initialSpecificity != subSelectorSpecificity)
                    ok = false;
                if (!ok)
                    return 0;
            }
            return initialSpecificity;
        }
    }
    return 0;
}
Esempio n. 2
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;
}
Esempio n. 3
0
static unsigned simpleSelectorSpecificityInternal(const CSSSelector& simpleSelector, bool isComputingMaximumSpecificity)
{
    ASSERT_WITH_MESSAGE(!simpleSelector.isForPage(), "At the time of this writing, page selectors are not treated as real selectors that are matched. The value computed here only account for real selectors.");

    switch (simpleSelector.match()) {
    case CSSSelector::Id:
        return static_cast<unsigned>(SelectorSpecificityIncrement::ClassA);

    case CSSSelector::PagePseudoClass:
        break;
    case CSSSelector::PseudoClass:
        if (simpleSelector.pseudoClassType() == CSSSelector::PseudoClassMatches) {
            ASSERT_WITH_MESSAGE(simpleSelector.selectorList() && simpleSelector.selectorList()->first(), "The parser should never generate a valid selector for an empty :matches().");
            if (!isComputingMaximumSpecificity)
                return 0;
            return maxSpecificity(*simpleSelector.selectorList());
        }

        if (simpleSelector.pseudoClassType() == CSSSelector::PseudoClassNot) {
            ASSERT_WITH_MESSAGE(simpleSelector.selectorList() && simpleSelector.selectorList()->first(), "The parser should never generate a valid selector for an empty :not().");
            return maxSpecificity(*simpleSelector.selectorList());
        }
        FALLTHROUGH;
    case CSSSelector::Exact:
    case CSSSelector::Class:
    case CSSSelector::Set:
    case CSSSelector::List:
    case CSSSelector::Hyphen:
    case CSSSelector::Contain:
    case CSSSelector::Begin:
    case CSSSelector::End:
        return static_cast<unsigned>(SelectorSpecificityIncrement::ClassB);
    case CSSSelector::Tag:
        return (simpleSelector.tagQName().localName() != starAtom) ? static_cast<unsigned>(SelectorSpecificityIncrement::ClassC) : 0;
    case CSSSelector::PseudoElement:
        return static_cast<unsigned>(SelectorSpecificityIncrement::ClassC);
    case CSSSelector::Unknown:
        return 0;
    }
    ASSERT_NOT_REACHED();
    return 0;
}