Exemple #1
0
bool SelectorChecker::checkPseudoClass(const CSSSelector& selector)
{
    switch (selector.pseudoType()) {
    case CSSSelector::PseudoFocus:
        m_matchedFocusSelector = true;
        return matchesFocusPseudoClass(m_element);

    case CSSSelector::PseudoHover:
        m_matchedHoverSelector = true;
        return m_element.hovered();

    case CSSSelector::PseudoActive:
        m_matchedActiveSelector = true;
        return m_element.active();

    case CSSSelector::PseudoLang:
    {
        AtomicString value = m_element.computeInheritedLanguage();
        const AtomicString& argument = selector.argument();
        if (value.isEmpty() || !value.startsWith(argument, false))
            break;
        if (value.length() != argument.length() && value[argument.length()] != '-')
            break;
        return true;
    }

    case CSSSelector::PseudoHost:
    {
        // We can only get here if the selector was defined in the right
        // scope so we don't need to check it.

        // For empty parameter case, i.e. just :host or :host().
        if (!selector.selectorList())
            return true;
        for (const CSSSelector* current = selector.selectorList()->first(); current; current = CSSSelectorList::next(*current)) {
            if (match(*current))
                return true;
        }
        return false;
    }

    case CSSSelector::PseudoUnknown:
    case CSSSelector::PseudoNotParsed:
    case CSSSelector::PseudoUserAgentCustomElement:
        return false;
    }
    ASSERT_NOT_REACHED();
    return false;
}
Exemple #2
0
bool SelectorChecker::checkPseudoClass(const SelectorCheckingContext& context) const
{
    ASSERT(context.element);
    Element& element = *context.element;
    ASSERT(context.selector);
    const CSSSelector& selector = *context.selector;
    ASSERT(selector.match() == CSSSelector::PseudoClass);

    // Normal element pseudo class checking.
    switch (selector.pseudoType()) {
    case CSSSelector::PseudoFocus:
        if (m_mode == ResolvingStyle) {
            if (context.elementStyle)
                context.elementStyle->setAffectedByFocus();
        }
        return matchesFocusPseudoClass(element);

    case CSSSelector::PseudoHover:
        if (m_mode == ResolvingStyle) {
            if (context.elementStyle)
                context.elementStyle->setAffectedByHover();
        }
        return element.hovered();

    case CSSSelector::PseudoActive:
        if (m_mode == ResolvingStyle) {
            if (context.elementStyle)
                context.elementStyle->setAffectedByActive();
        }
        return element.active();

    case CSSSelector::PseudoLang:
        {
            AtomicString value = element.computeInheritedLanguage();
            const AtomicString& argument = selector.argument();
            if (value.isEmpty() || !value.startsWith(argument, false))
                break;
            if (value.length() != argument.length() && value[argument.length()] != '-')
                break;
            return true;
        }

    case CSSSelector::PseudoUnresolved:
        return element.isUnresolvedCustomElement();

    case CSSSelector::PseudoHost:
        {
            if (m_mode == SharingRules)
                return true;
            // :host only matches a shadow host when :host is in a shadow tree of the shadow host.
            if (!context.scope)
                return false;
            const ContainerNode* shadowHost = context.scope->shadowHost();
            if (!shadowHost || shadowHost != element)
                return false;
            ASSERT(element.shadow());

            // For empty parameter case, i.e. just :host or :host().
            if (!selector.selectorList())
                return true;

            SelectorCheckingContext subContext(context);
            subContext.contextFlags = TreatShadowHostAsNormalScope;

            for (subContext.selector = selector.selectorList()->first(); subContext.selector; subContext.selector = CSSSelectorList::next(*subContext.selector)) {
                if (match(subContext))
                    return true;
            }
            return false;
        }

    case CSSSelector::PseudoUnknown:
    case CSSSelector::PseudoNotParsed:
    case CSSSelector::PseudoUserAgentCustomElement:
        return false;
    }
    ASSERT_NOT_REACHED();
    return false;
}