15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *           (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com)
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2006, 2007 Nicholas Shanks (webkit@nickshanks.com)
5926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved.
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org>
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org>
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) Research In Motion Limited 2011. All rights reserved.
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is free software; you can redistribute it and/or
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modify it under the terms of the GNU Library General Public
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * License as published by the Free Software Foundation; either
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * version 2 of the License, or (at your option) any later version.
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is distributed in the hope that it will be useful,
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * but WITHOUT ANY WARRANTY; without even the implied warranty of
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Library General Public License for more details.
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * You should have received a copy of the GNU Library General Public License
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * along with this library; see the file COPYING.LIB.  If not, write to
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Boston, MA 02110-1301, USA.
265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h"
2953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/css/SelectorChecker.h"
3053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
315d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#include "core/HTMLNames.h"
3253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/css/CSSSelectorList.h"
3353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/css/SiblingTraversalStrategies.h"
3453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/Document.h"
3509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)#include "core/dom/ElementTraversal.h"
369e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)#include "core/dom/Fullscreen.h"
3753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/NodeRenderStyle.h"
38197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "core/dom/StyleEngine.h"
3953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/Text.h"
40e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)#include "core/dom/shadow/InsertionPoint.h"
41e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)#include "core/dom/shadow/ShadowRoot.h"
4253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/editing/FrameSelection.h"
43d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "core/frame/LocalFrame.h"
4453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/html/HTMLDocument.h"
4553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/html/HTMLFrameElementBase.h"
4653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/html/HTMLInputElement.h"
4753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/html/HTMLOptionElement.h"
48e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)#include "core/html/HTMLSelectElement.h"
4993ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#include "core/html/parser/HTMLParserIdioms.h"
5051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "core/html/track/vtt/VTTElement.h"
5153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/inspector/InspectorInstrumentation.h"
5253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/page/FocusController.h"
53197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch#include "core/page/Page.h"
5453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderObject.h"
5553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderScrollbar.h"
5653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/style/RenderStyle.h"
57a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/scroll/ScrollableArea.h"
58a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/scroll/ScrollbarTheme.h"
5953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
60c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)using namespace HTMLNames;
635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
648abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)SelectorChecker::SelectorChecker(Document& document, Mode mode)
658abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    : m_strictParsing(!document.inQuirksMode())
66926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    , m_mode(mode)
675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
7009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)static bool matchesCustomPseudoElement(const Element* element, const CSSSelector& selector)
71f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles){
72f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)    ShadowRoot* root = element->containingShadowRoot();
7307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    if (!root || root->type() != ShadowRoot::UserAgentShadowRoot)
74f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)        return false;
7507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
7609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (element->shadowPseudoId() != selector.value())
77f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)        return false;
7809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
79f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)    return true;
80f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)}
81f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)
82197021e6b966cfb06891637935ef33fff06433d1Ben Murdochstatic Element* parentElement(const SelectorChecker::SelectorCheckingContext& context)
833c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch{
84c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    // - If context.scope is a shadow root, we should walk up to its shadow host.
85c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    // - If context.scope is some element in some shadow tree and querySelector initialized the context,
86c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    //   e.g. shadowRoot.querySelector(':host *'),
87c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    //   (a) context.element has the same treescope as context.scope, need to walk up to its shadow host.
88c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    //   (b) Otherwise, should not walk up from a shadow root to a shadow host.
89c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (context.scope && (context.scope == context.element->containingShadowRoot() || context.scope->treeScope() == context.element->treeScope()))
90d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return context.element->parentOrShadowHostElement();
91d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return context.element->parentElement();
923c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch}
933c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch
94197021e6b966cfb06891637935ef33fff06433d1Ben Murdochstatic bool scopeContainsLastMatchedElement(const SelectorChecker::SelectorCheckingContext& context)
953c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch{
96197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (!(context.contextFlags & SelectorChecker::ScopeContainsLastMatchedElement))
973c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch        return true;
983c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch
993c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch    ASSERT(context.scope);
100197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (context.scope->treeScope() == context.element->treeScope())
1013c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch        return true;
1023c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch
103197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    // Because Blink treats a shadow host's TreeScope as a separate one from its descendent shadow roots,
104197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    // if the last matched element is a shadow host, the condition above isn't met, even though it
105197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    // should be.
106197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return context.element == context.scope->shadowHost() && (!context.previousElement || context.previousElement->isInDescendantTreeOf(context.element));
1073c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch}
1083c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch
109a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)static inline bool nextSelectorExceedsScope(const SelectorChecker::SelectorCheckingContext& context)
110a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles){
111d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (context.scope && context.scope->isInShadowTree())
1125d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        return context.element == context.scope->shadowHost();
1135d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)
114d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return false;
115a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)}
116a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Recursive check of selectors and combinators
1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// It can return 4 different values:
1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// * SelectorMatches          - the selector matches the element e
1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// * SelectorFailsLocally     - the selector fails for the element e
1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// * SelectorFailsAllSiblings - the selector fails for e and any sibling of e
1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// * SelectorFailsCompletely  - the selector fails for e and any sibling or ancestor of e
123926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)template<typename SiblingTraversalStrategy>
124a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)SelectorChecker::Match SelectorChecker::match(const SelectorCheckingContext& context, const SiblingTraversalStrategy& siblingTraversalStrategy, MatchResult* result) const
1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // first selector has to match
127a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    unsigned specificity = 0;
128a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    if (!checkOne(context, siblingTraversalStrategy, &specificity))
1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return SelectorFailsLocally;
1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1315d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    if (context.selector->match() == CSSSelector::PseudoElement) {
1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (context.selector->isCustomPseudoElement()) {
13309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            if (!matchesCustomPseudoElement(context.element, *context.selector))
1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return SelectorFailsLocally;
13507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        } else if (context.selector->isContentPseudoElement()) {
13607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch            if (!context.element->isInShadowTree() || !context.element->isInsertionPoint())
13707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch                return SelectorFailsLocally;
13807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        } else if (context.selector->isShadowPseudoElement()) {
139323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)            if (!context.element->isInShadowTree() || !context.previousElement)
140323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)                return SelectorFailsCompletely;
1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        } else {
1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if ((!context.elementStyle && m_mode == ResolvingStyle) || m_mode == QueryingRules)
1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return SelectorFailsLocally;
1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            PseudoId pseudoId = CSSSelector::pseudoId(context.selector->pseudoType());
1468abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)            if (pseudoId == FIRST_LETTER)
1479bbd2f5e390b01907d97ecffde80aa1b06113aacTorne (Richard Coles)                context.element->document().styleEngine()->setUsesFirstLetterRules(true);
148a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)            if (pseudoId != NOPSEUDO && m_mode != SharingRules && result)
149a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                result->dynamicPseudo = pseudoId;
1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Prepare next selector
154197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    if (context.selector->isLastInTagHistory()) {
155a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        if (scopeContainsLastMatchedElement(context)) {
156a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)            if (result)
157a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                result->specificity += specificity;
158a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)            return SelectorMatches;
159a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        }
160a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        return SelectorFailsLocally;
161a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    }
1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
163a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    Match match;
164a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    if (context.selector->relation() != CSSSelector::SubSelector) {
1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Abort if the next selector would exceed the scope.
166a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        if (nextSelectorExceedsScope(context))
1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return SelectorFailsCompletely;
1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
169926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        // Bail-out if this selector is irrelevant for the pseudoId
170a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        if (context.pseudoId != NOPSEUDO && (!result || context.pseudoId != result->dynamicPseudo))
1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return SelectorFailsCompletely;
1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
173a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        if (result) {
174a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)            TemporaryChange<PseudoId> dynamicPseudoScope(result->dynamicPseudo, NOPSEUDO);
175a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)            match = matchForRelation(context, siblingTraversalStrategy, result);
176a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        } else {
177a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)            return matchForRelation(context, siblingTraversalStrategy, 0);
178a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        }
179a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    } else {
180a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        match = matchForSubSelector(context, siblingTraversalStrategy, result);
1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
182a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    if (match != SelectorMatches || !result)
183a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        return match;
184a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
185a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    result->specificity += specificity;
186a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    return SelectorMatches;
187a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)}
188a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
189a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)static inline SelectorChecker::SelectorCheckingContext prepareNextContextForRelation(const SelectorChecker::SelectorCheckingContext& context)
190a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles){
191a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    SelectorChecker::SelectorCheckingContext nextContext(context);
192a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    ASSERT(context.selector->tagHistory());
193a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    nextContext.selector = context.selector->tagHistory();
194a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    return nextContext;
195a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)}
196a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
19707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdochstatic inline bool isAuthorShadowRoot(const Node* node)
19807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch{
19907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    return node && node->isShadowRoot() && toShadowRoot(node)->type() == ShadowRoot::AuthorShadowRoot;
20007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch}
20107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
202a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)template<typename SiblingTraversalStrategy>
203a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)SelectorChecker::Match SelectorChecker::matchForSubSelector(const SelectorCheckingContext& context, const SiblingTraversalStrategy& siblingTraversalStrategy, MatchResult* result) const
204a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles){
205a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    SelectorCheckingContext nextContext = prepareNextContextForRelation(context);
206a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
207a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    PseudoId dynamicPseudo = result ? result->dynamicPseudo : NOPSEUDO;
208a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    // a selector is invalid if something follows a pseudo-element
209a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    // We make an exception for scrollbar pseudo elements and allow a set of pseudo classes (but nothing else)
210a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    // to follow the pseudo elements.
211a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    nextContext.hasScrollbarPseudo = dynamicPseudo != NOPSEUDO && (context.scrollbar || dynamicPseudo == SCROLLBAR_CORNER || dynamicPseudo == RESIZER);
212a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    nextContext.hasSelectionPseudo = dynamicPseudo == SELECTION;
213a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    if ((context.elementStyle || m_mode == CollectingCSSRules || m_mode == CollectingStyleRules || m_mode == QueryingRules) && dynamicPseudo != NOPSEUDO
214a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        && !nextContext.hasSelectionPseudo
2155d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        && !(nextContext.hasScrollbarPseudo && nextContext.selector->match() == CSSSelector::PseudoClass))
216a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        return SelectorFailsCompletely;
217a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
218a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    nextContext.isSubSelector = true;
219a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    return match(nextContext, siblingTraversalStrategy, result);
220a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)}
221a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
22207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdochstatic bool selectorMatchesShadowRoot(const CSSSelector* selector)
22307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch{
22407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    return selector && selector->isShadowPseudoElement();
22507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch}
22607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
22707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdochtemplate<typename SiblingTraversalStrategy>
22807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben MurdochSelectorChecker::Match SelectorChecker::matchForPseudoShadow(const ContainerNode* node, const SelectorCheckingContext& context, const SiblingTraversalStrategy& siblingTraversalStrategy, MatchResult* result) const
22907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch{
23007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    if (!isAuthorShadowRoot(node))
23107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        return SelectorFailsCompletely;
23207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    return match(context, siblingTraversalStrategy, result);
23307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch}
23407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
235a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)template<typename SiblingTraversalStrategy>
236a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)SelectorChecker::Match SelectorChecker::matchForRelation(const SelectorCheckingContext& context, const SiblingTraversalStrategy& siblingTraversalStrategy, MatchResult* result) const
237a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles){
238a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    SelectorCheckingContext nextContext = prepareNextContextForRelation(context);
239f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu    nextContext.previousElement = context.element;
240a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
241a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    CSSSelector::Relation relation = context.selector->relation();
242a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
243a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    // Disable :visited matching when we see the first link or try to match anything else than an ancestors.
244a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    if (!context.isSubSelector && (context.element->isLink() || (relation != CSSSelector::Descendant && relation != CSSSelector::Child)))
245a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        nextContext.visitedMatchType = VisitedMatchDisabled;
246a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
247a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    nextContext.pseudoId = NOPSEUDO;
2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    switch (relation) {
2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case CSSSelector::Descendant:
251df95704c49daea886ddad70775bda23618d6274dBen Murdoch        if (context.selector->relationIsAffectedByPseudoContent()) {
25293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            for (Element* element = context.element; element; element = element->parentElement()) {
253a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                if (matchForShadowDistributed(element, siblingTraversalStrategy, nextContext, result) == SelectorMatches)
25493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)                    return SelectorMatches;
25593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            }
25693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            return SelectorFailsCompletely;
25793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        }
2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        nextContext.isSubSelector = false;
2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        nextContext.elementStyle = 0;
26007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
26107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        if (selectorMatchesShadowRoot(nextContext.selector))
26207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch            return matchForPseudoShadow(context.element->containingShadowRoot(), nextContext, siblingTraversalStrategy, result);
26307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
2643c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch        for (nextContext.element = parentElement(context); nextContext.element; nextContext.element = parentElement(nextContext)) {
265a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)            Match match = this->match(nextContext, siblingTraversalStrategy, result);
2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (match == SelectorMatches || match == SelectorFailsCompletely)
2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return match;
268a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)            if (nextSelectorExceedsScope(nextContext))
2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return SelectorFailsCompletely;
2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return SelectorFailsCompletely;
2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case CSSSelector::Child:
2733c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch        {
2743c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch            if (context.selector->relationIsAffectedByPseudoContent())
275a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                return matchForShadowDistributed(context.element, siblingTraversalStrategy, nextContext, result);
2763c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch
27707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch            nextContext.isSubSelector = false;
27807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch            nextContext.elementStyle = 0;
27907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
28007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch            if (selectorMatchesShadowRoot(nextContext.selector))
28107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch                return matchForPseudoShadow(context.element->parentNode(), nextContext, siblingTraversalStrategy, result);
28207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
2833c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch            nextContext.element = parentElement(context);
2843c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch            if (!nextContext.element)
2853c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch                return SelectorFailsCompletely;
286a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)            return match(nextContext, siblingTraversalStrategy, result);
2873c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch        }
2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case CSSSelector::DirectAdjacent:
289323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        // Shadow roots can't have sibling elements
290323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        if (selectorMatchesShadowRoot(nextContext.selector))
291323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)            return SelectorFailsCompletely;
292323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
293926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (m_mode == ResolvingStyle) {
29407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch            if (ContainerNode* parent = context.element->parentElementOrShadowRoot())
29507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch                parent->setChildrenAffectedByDirectAdjacentRules();
2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
29709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        nextContext.element = ElementTraversal::previousSibling(*context.element);
2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!nextContext.element)
2995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return SelectorFailsAllSiblings;
3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        nextContext.isSubSelector = false;
3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        nextContext.elementStyle = 0;
302a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        return match(nextContext, siblingTraversalStrategy, result);
3035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case CSSSelector::IndirectAdjacent:
305323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        // Shadow roots can't have sibling elements
306323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        if (selectorMatchesShadowRoot(nextContext.selector))
307323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)            return SelectorFailsCompletely;
308323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)
309926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        if (m_mode == ResolvingStyle) {
31007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch            if (ContainerNode* parent = context.element->parentElementOrShadowRoot())
31107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch                parent->setChildrenAffectedByIndirectAdjacentRules();
3125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
31309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        nextContext.element = ElementTraversal::previousSibling(*context.element);
3145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        nextContext.isSubSelector = false;
3155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        nextContext.elementStyle = 0;
31609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        for (; nextContext.element; nextContext.element = ElementTraversal::previousSibling(*nextContext.element)) {
317a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)            Match match = this->match(nextContext, siblingTraversalStrategy, result);
3185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (match == SelectorMatches || match == SelectorFailsAllSiblings || match == SelectorFailsCompletely)
3195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return match;
3205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        };
3215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return SelectorFailsAllSiblings;
3225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
32393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    case CSSSelector::ShadowPseudo:
3245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        {
3255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // If we're in the same tree-scope as the scoping element, then following a shadow descendant combinator would escape that and thus the scope.
326197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            if (context.scope && context.scope->shadowHost() && context.scope->shadowHost()->treeScope() == context.element->treeScope())
3275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return SelectorFailsCompletely;
328f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)
329f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)            Element* shadowHost = context.element->shadowHost();
330f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)            if (!shadowHost)
3315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return SelectorFailsCompletely;
332f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)            nextContext.element = shadowHost;
3335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            nextContext.isSubSelector = false;
3345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            nextContext.elementStyle = 0;
335a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)            return this->match(nextContext, siblingTraversalStrategy, result);
336f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)        }
337f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)
338d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    case CSSSelector::ShadowDeep:
339f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)        {
340f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)            nextContext.isSubSelector = false;
341f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)            nextContext.elementStyle = 0;
342197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            for (nextContext.element = context.element->parentOrShadowHostElement(); nextContext.element; nextContext.element = nextContext.element->parentOrShadowHostElement()) {
343a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                Match match = this->match(nextContext, siblingTraversalStrategy, result);
344f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)                if (match == SelectorMatches || match == SelectorFailsCompletely)
345f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)                    return match;
346a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                if (nextSelectorExceedsScope(nextContext))
347f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)                    return SelectorFailsCompletely;
348f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)            }
349f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)            return SelectorFailsCompletely;
350926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        }
351a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
352a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    case CSSSelector::SubSelector:
353a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        ASSERT_NOT_REACHED();
3545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT_NOT_REACHED();
3575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return SelectorFailsCompletely;
3585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
3595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
36093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)template<typename SiblingTraversalStrategy>
361a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)SelectorChecker::Match SelectorChecker::matchForShadowDistributed(const Element* element, const SiblingTraversalStrategy& siblingTraversalStrategy, SelectorCheckingContext& nextContext, MatchResult* result) const
36293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
36319cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    ASSERT(element);
364d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    WillBeHeapVector<RawPtrWillBeMember<InsertionPoint>, 8> insertionPoints;
36519cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    collectDestinationInsertionPoints(*element, insertionPoints);
36693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    for (size_t i = 0; i < insertionPoints.size(); ++i) {
36793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        nextContext.element = insertionPoints[i];
368197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        if (m_mode == SharingRules)
3695d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)            nextContext.scope = insertionPoints[i]->containingShadowRoot();
37093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        nextContext.isSubSelector = false;
37193ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        nextContext.elementStyle = 0;
372a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        if (match(nextContext, siblingTraversalStrategy, result) == SelectorMatches)
37393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            return SelectorMatches;
37493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    }
37507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch    return SelectorFailsLocally;
37693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
37793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
378f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)template<typename CharType>
379f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)static inline bool containsHTMLSpaceTemplate(const CharType* string, unsigned length)
38093ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
381f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    for (unsigned i = 0; i < length; ++i)
382f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        if (isHTMLSpace<CharType>(string[i]))
38393ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            return true;
38493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    return false;
38593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
38693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
387f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)static inline bool containsHTMLSpace(const AtomicString& string)
388f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles){
389f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    if (LIKELY(string.is8Bit()))
390f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        return containsHTMLSpaceTemplate<LChar>(string.characters8(), string.length());
391f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    return containsHTMLSpaceTemplate<UChar>(string.characters16(), string.length());
392f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)}
393f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
394d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)static bool attributeValueMatches(const Attribute& attributeItem, CSSSelector::Match match, const AtomicString& selectorValue, bool caseSensitive)
3955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
396d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    const AtomicString& value = attributeItem.value();
3975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (value.isNull())
3985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
3995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    switch (match) {
4015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case CSSSelector::Exact:
4025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (caseSensitive ? selectorValue != value : !equalIgnoringCase(selectorValue, value))
4035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return false;
4045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        break;
4055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case CSSSelector::List:
4065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        {
40793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)            // Ignore empty selectors or selectors containing HTML spaces
408f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)            if (selectorValue.isEmpty() || containsHTMLSpace(selectorValue))
4095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return false;
4105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            unsigned startSearchAt = 0;
4125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            while (true) {
4135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                size_t foundPos = value.find(selectorValue, startSearchAt, caseSensitive);
41406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                if (foundPos == kNotFound)
4155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    return false;
41606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                if (!foundPos || isHTMLSpace<UChar>(value[foundPos - 1])) {
4175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    unsigned endStr = foundPos + selectorValue.length();
41806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                    if (endStr == value.length() || isHTMLSpace<UChar>(value[endStr]))
4195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        break; // We found a match.
4205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
4215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                // No match. Keep looking.
4235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                startSearchAt = foundPos + 1;
4245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
4255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
4265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
4275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case CSSSelector::Contain:
4285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!value.contains(selectorValue, caseSensitive) || selectorValue.isEmpty())
4295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return false;
4305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        break;
4315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case CSSSelector::Begin:
4325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!value.startsWith(selectorValue, caseSensitive) || selectorValue.isEmpty())
4335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return false;
4345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        break;
4355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case CSSSelector::End:
4365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!value.endsWith(selectorValue, caseSensitive) || selectorValue.isEmpty())
4375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return false;
4385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        break;
4395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case CSSSelector::Hyphen:
4405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (value.length() < selectorValue.length())
4415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return false;
4425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!value.startsWith(selectorValue, caseSensitive))
4435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return false;
4445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // It they start the same, check for exact match or following '-':
4455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (value.length() != selectorValue.length() && value[selectorValue.length()] != '-')
4465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return false;
4475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        break;
4485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case CSSSelector::PseudoClass:
4495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case CSSSelector::PseudoElement:
4505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    default:
4515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        break;
4525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
4535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return true;
4555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
457a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)static bool anyAttributeMatches(Element& element, CSSSelector::Match match, const CSSSelector& selector)
4585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
459a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    const QualifiedName& selectorAttr = selector.attribute();
460a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    ASSERT(selectorAttr.localName() != starAtom); // Should not be possible from the CSS grammar.
461a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
462a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    // Synchronize the attribute in case it is lazy-computed.
463a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    // Currently all lazy properties have a null namespace, so only pass localName().
464a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    element.synchronizeAttribute(selectorAttr.localName());
465a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
466c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    const AtomicString& selectorValue = selector.value();
467c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    bool caseInsensitive = selector.attributeMatchType() == CSSSelector::CaseInsensitive;
468a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
469c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    AttributeCollection attributes = element.attributesWithoutUpdate();
470e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    AttributeCollection::iterator end = attributes.end();
471e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    for (AttributeCollection::iterator it = attributes.begin(); it != end; ++it) {
47276c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)        const Attribute& attributeItem = *it;
4735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
474d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if (!attributeItem.matches(selectorAttr))
4755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue;
4765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
477c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        if (attributeValueMatches(attributeItem, match, selectorValue, !caseInsensitive))
4785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return true;
47909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
480c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        if (caseInsensitive)
481c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            continue;
482c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)
483c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        // Legacy dictates that values of some attributes should be compared in
484c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        // a case-insensitive manner regardless of whether the case insensitive
485c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        // flag is set or not.
486c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        bool legacyCaseInsensitive = element.document().isHTMLDocument() && !HTMLDocument::isCaseSensitiveAttribute(selectorAttr);
48709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
48809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        // If case-insensitive, re-check, and count if result differs.
48909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        // See http://code.google.com/p/chromium/issues/detail?id=327060
490c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        if (legacyCaseInsensitive && attributeValueMatches(attributeItem, match, selectorValue, false)) {
49109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            UseCounter::count(element.document(), UseCounter::CaseInsensitiveAttrSelectorMatch);
49209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            return true;
49309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        }
4945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
4955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return false;
4975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)template<typename SiblingTraversalStrategy>
500a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)bool SelectorChecker::checkOne(const SelectorCheckingContext& context, const SiblingTraversalStrategy& siblingTraversalStrategy, unsigned* specificity) const
5015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
50219cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    ASSERT(context.element);
50319cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    Element& element = *context.element;
50409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    ASSERT(context.selector);
50509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    const CSSSelector& selector = *context.selector;
50609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
507197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    bool elementIsHostInItsShadowTree = isHostInItsShadowTree(element, context.scope);
5085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5097242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    // Only :host and :host-context() should match the host: http://drafts.csswg.org/css-scoping/#host-element
5107242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (elementIsHostInItsShadowTree && (!selector.isHostPseudoClass()
5117242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        && !(context.contextFlags & TreatShadowHostAsNormalScope)
5127242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        && selector.match() != CSSSelector::PseudoElement))
5137242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            return false;
51407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch
5155d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    if (selector.match() == CSSSelector::Tag)
51607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        return SelectorChecker::tagMatches(element, selector.tagQName());
5175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5185d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    if (selector.match() == CSSSelector::Class)
51907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        return element.hasClass() && element.classNames().contains(selector.value());
5205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5215d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    if (selector.match() == CSSSelector::Id)
52207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        return element.hasID() && element.idForStyleResolution() == selector.value();
5235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
524f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    if (selector.isAttributeSelector())
5255d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)        return anyAttributeMatches(element, selector.match(), selector);
5265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5275d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    if (selector.match() == CSSSelector::PseudoClass) {
5285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Handle :not up front.
52909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        if (selector.pseudoType() == CSSSelector::PseudoNot) {
5305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            SelectorCheckingContext subContext(context);
5315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            subContext.isSubSelector = true;
53209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            ASSERT(selector.selectorList());
53309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            for (subContext.selector = selector.selectorList()->first(); subContext.selector; subContext.selector = subContext.selector->tagHistory()) {
5345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                // :not cannot nest. I don't really know why this is a
5355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                // restriction in CSS3, but it is, so let's honor it.
5365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                // the parser enforces that this never occurs
5375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                ASSERT(subContext.selector->pseudoType() != CSSSelector::PseudoNot);
5385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                // We select between :visited and :link when applying. We don't know which one applied (or not) yet.
5395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (subContext.selector->pseudoType() == CSSSelector::PseudoVisited || (subContext.selector->pseudoType() == CSSSelector::PseudoLink && subContext.visitedMatchType == VisitedMatchEnabled))
5405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    return true;
54107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch                // context.scope is not available if m_mode == SharingRules.
54207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch                // We cannot determine whether :host or :scope matches a given element or not.
54307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch                if (m_mode == SharingRules && (subContext.selector->isHostPseudoClass() || subContext.selector->pseudoType() == CSSSelector::PseudoScope))
54407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch                    return true;
545926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                if (!checkOne(subContext, DOMSiblingTraversalStrategy()))
5465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    return true;
5475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
5485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        } else if (context.hasScrollbarPseudo) {
5495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // CSS scrollbars match a specific subset of pseudo classes, and they have specialized rules for each
5505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // (since there are no elements involved).
55119cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)            return checkScrollbarPseudoClass(context, &element.document(), selector);
5525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        } else if (context.hasSelectionPseudo) {
55309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            if (selector.pseudoType() == CSSSelector::PseudoWindowInactive)
55419cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)                return !element.document().page()->focusController().isActive();
5555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
5565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Normal element pseudo class checking.
55809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        switch (selector.pseudoType()) {
5595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // Pseudo classes:
5605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case CSSSelector::PseudoNot:
5615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break; // Already handled up above.
5625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case CSSSelector::PseudoEmpty:
5635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            {
5645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                bool result = true;
56519cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)                for (Node* n = element.firstChild(); n; n = n->nextSibling()) {
5665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    if (n->isElementNode()) {
5675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        result = false;
5685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        break;
5695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    }
5705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    if (n->isTextNode()) {
5715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        Text* textNode = toText(n);
5725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        if (!textNode->data().isEmpty()) {
5735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                            result = false;
5745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                            break;
5755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        }
5765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    }
5775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
5785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (m_mode == ResolvingStyle) {
57919cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)                    element.setStyleAffectedByEmpty();
5805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    if (context.elementStyle)
5815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        context.elementStyle->setEmptyState(result);
58219cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)                    else if (element.renderStyle() && (element.document().styleEngine()->usesSiblingRules() || element.renderStyle()->unique()))
58319cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)                        element.renderStyle()->setEmptyState(result);
5845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
5855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return result;
5865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
5875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case CSSSelector::PseudoFirstChild:
5885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // first-child matches the first child that is an element
589d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            if (ContainerNode* parent = element.parentElementOrDocumentFragment()) {
59009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                bool result = siblingTraversalStrategy.isFirstChild(element);
5915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (m_mode == ResolvingStyle) {
59219cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)                    RenderStyle* childStyle = context.elementStyle ? context.elementStyle : element.renderStyle();
59307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch                    parent->setChildrenAffectedByFirstChildRules();
5945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    if (result && childStyle)
5955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        childStyle->setFirstChildState();
5965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
5975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return result;
5985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
5995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
6005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case CSSSelector::PseudoFirstOfType:
6015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // first-of-type matches the first element of its type
602d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            if (ContainerNode* parent = element.parentElementOrDocumentFragment()) {
60309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                bool result = siblingTraversalStrategy.isFirstOfType(element, element.tagQName());
604926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                if (m_mode == ResolvingStyle)
60507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch                    parent->setChildrenAffectedByForwardPositionalRules();
6065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return result;
6075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
6085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
6095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case CSSSelector::PseudoLastChild:
6105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // last-child matches the last child that is an element
611d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            if (ContainerNode* parent = element.parentElementOrDocumentFragment()) {
61207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch                bool result = parent->isFinishedParsingChildren() && siblingTraversalStrategy.isLastChild(element);
6135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (m_mode == ResolvingStyle) {
61419cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)                    RenderStyle* childStyle = context.elementStyle ? context.elementStyle : element.renderStyle();
61507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch                    parent->setChildrenAffectedByLastChildRules();
6165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    if (result && childStyle)
6175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        childStyle->setLastChildState();
6185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
6195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return result;
6205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
6215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
6225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case CSSSelector::PseudoLastOfType:
6235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // last-of-type matches the last element of its type
624d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            if (ContainerNode* parent = element.parentElementOrDocumentFragment()) {
625926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                if (m_mode == ResolvingStyle)
62607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch                    parent->setChildrenAffectedByBackwardPositionalRules();
62707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch                if (!parent->isFinishedParsingChildren())
6285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    return false;
62909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                return siblingTraversalStrategy.isLastOfType(element, element.tagQName());
6305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
6315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
6325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case CSSSelector::PseudoOnlyChild:
633d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            if (ContainerNode* parent = element.parentElementOrDocumentFragment()) {
63409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                bool firstChild = siblingTraversalStrategy.isFirstChild(element);
63507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch                bool onlyChild = firstChild && parent->isFinishedParsingChildren() && siblingTraversalStrategy.isLastChild(element);
6365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (m_mode == ResolvingStyle) {
63719cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)                    RenderStyle* childStyle = context.elementStyle ? context.elementStyle : element.renderStyle();
63807a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch                    parent->setChildrenAffectedByFirstChildRules();
63907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch                    parent->setChildrenAffectedByLastChildRules();
6405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    if (firstChild && childStyle)
6415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        childStyle->setFirstChildState();
6425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    if (onlyChild && childStyle)
6435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        childStyle->setLastChildState();
6445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
6455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return onlyChild;
6465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
6475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
6485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case CSSSelector::PseudoOnlyOfType:
6495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // FIXME: This selector is very slow.
650d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            if (ContainerNode* parent = element.parentElementOrDocumentFragment()) {
6515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (m_mode == ResolvingStyle) {
65207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch                    parent->setChildrenAffectedByForwardPositionalRules();
65307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch                    parent->setChildrenAffectedByBackwardPositionalRules();
6545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
65507a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch                if (!parent->isFinishedParsingChildren())
6565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    return false;
65709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                return siblingTraversalStrategy.isFirstOfType(element, element.tagQName()) && siblingTraversalStrategy.isLastOfType(element, element.tagQName());
6585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
6595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
6605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case CSSSelector::PseudoNthChild:
66109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            if (!selector.parseNth())
6625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                break;
663d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            if (ContainerNode* parent = element.parentElementOrDocumentFragment()) {
66409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                int count = 1 + siblingTraversalStrategy.countElementsBefore(element);
6655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (m_mode == ResolvingStyle) {
66619cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)                    RenderStyle* childStyle = context.elementStyle ? context.elementStyle : element.renderStyle();
6675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    if (childStyle)
668926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                        childStyle->setUnique();
66907a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch                    parent->setChildrenAffectedByForwardPositionalRules();
6705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
6715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
67209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                if (selector.matchNth(count))
6735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    return true;
6745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
6755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
6765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case CSSSelector::PseudoNthOfType:
67709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            if (!selector.parseNth())
6785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                break;
679d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            if (ContainerNode* parent = element.parentElementOrDocumentFragment()) {
68009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                int count = 1 + siblingTraversalStrategy.countElementsOfTypeBefore(element, element.tagQName());
681926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                if (m_mode == ResolvingStyle)
68207a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch                    parent->setChildrenAffectedByForwardPositionalRules();
6835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
68409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                if (selector.matchNth(count))
6855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    return true;
6865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
6875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
6885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case CSSSelector::PseudoNthLastChild:
68909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            if (!selector.parseNth())
6905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                break;
691d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            if (ContainerNode* parent = element.parentElementOrDocumentFragment()) {
692926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                if (m_mode == ResolvingStyle)
69307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch                    parent->setChildrenAffectedByBackwardPositionalRules();
69407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch                if (!parent->isFinishedParsingChildren())
6955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    return false;
69609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                int count = 1 + siblingTraversalStrategy.countElementsAfter(element);
69709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                if (selector.matchNth(count))
6985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    return true;
6995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
7005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
7015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case CSSSelector::PseudoNthLastOfType:
70209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            if (!selector.parseNth())
7035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                break;
704d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            if (ContainerNode* parent = element.parentElementOrDocumentFragment()) {
705926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                if (m_mode == ResolvingStyle)
70607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch                    parent->setChildrenAffectedByBackwardPositionalRules();
70707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch                if (!parent->isFinishedParsingChildren())
7085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    return false;
7095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
71009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                int count = 1 + siblingTraversalStrategy.countElementsOfTypeAfter(element, element.tagQName());
71109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                if (selector.matchNth(count))
7125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    return true;
7135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
7145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
7155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case CSSSelector::PseudoTarget:
71619cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)            if (element == element.document().cssTarget())
7175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return true;
7185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
7195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case CSSSelector::PseudoAny:
7205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            {
7215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                SelectorCheckingContext subContext(context);
7225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                subContext.isSubSelector = true;
72309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                ASSERT(selector.selectorList());
72409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                for (subContext.selector = selector.selectorList()->first(); subContext.selector; subContext.selector = CSSSelectorList::next(*subContext.selector)) {
725a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                    if (match(subContext, siblingTraversalStrategy) == SelectorMatches)
7265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        return true;
7275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
7285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
7295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
7305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case CSSSelector::PseudoAutofill:
73119cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)            if (!element.isFormControlElement())
7325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                break;
73319cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)            return toHTMLFormControlElement(element).isAutofilled();
7345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case CSSSelector::PseudoAnyLink:
7355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case CSSSelector::PseudoLink:
7365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // :visited and :link matches are separated later when applying the style. Here both classes match all links...
73719cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)            return element.isLink();
7385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case CSSSelector::PseudoVisited:
7395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // ...except if :visited matching is disabled for ancestor/sibling matching.
74019cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)            return element.isLink() && context.visitedMatchType == VisitedMatchEnabled;
7415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case CSSSelector::PseudoDrag:
742926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            if (m_mode == ResolvingStyle) {
743926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                if (context.elementStyle)
744926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                    context.elementStyle->setAffectedByDrag();
745926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                else
746f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)                    element.setChildrenOrSiblingsAffectedByDrag();
747926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            }
74819cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)            if (element.renderer() && element.renderer()->isDragging())
7495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return true;
7505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
7515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case CSSSelector::PseudoFocus:
75251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            if (m_mode == ResolvingStyle) {
75351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                if (context.elementStyle)
75451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                    context.elementStyle->setAffectedByFocus();
75551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                else
756f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)                    element.setChildrenOrSiblingsAffectedByFocus();
75751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            }
7585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return matchesFocusPseudoClass(element);
7595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case CSSSelector::PseudoHover:
7605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // If we're in quirks mode, then hover should never match anchors with no
7615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // href and *:hover should not match anything. This is important for sites like wsj.com.
7625d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)            if (m_strictParsing || context.isSubSelector || element.isLink()) {
763926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                if (m_mode == ResolvingStyle) {
764926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                    if (context.elementStyle)
765926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                        context.elementStyle->setAffectedByHover();
766926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                    else
767f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)                        element.setChildrenOrSiblingsAffectedByHover();
768926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                }
76919cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)                if (element.hovered() || InspectorInstrumentation::forcePseudoState(&element, CSSSelector::PseudoHover))
7705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    return true;
7715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
7725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
7735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case CSSSelector::PseudoActive:
7745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // If we're in quirks mode, then :active should never match anchors with no
7755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // href and *:active should not match anything.
7765d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)            if (m_strictParsing || context.isSubSelector || element.isLink()) {
777926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                if (m_mode == ResolvingStyle) {
778926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                    if (context.elementStyle)
779926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                        context.elementStyle->setAffectedByActive();
780926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                    else
781f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)                        element.setChildrenOrSiblingsAffectedByActive();
782926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                }
78319cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)                if (element.active() || InspectorInstrumentation::forcePseudoState(&element, CSSSelector::PseudoActive))
7845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    return true;
7855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
7865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
7875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case CSSSelector::PseudoEnabled:
788d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            if (element.isFormControlElement() || isHTMLOptionElement(element) || isHTMLOptGroupElement(element))
78919cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)                return !element.isDisabledFormControl();
790c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            else if (isHTMLAnchorElement(element) || isHTMLAreaElement(element))
791c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)                return element.isLink();
7925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
7935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case CSSSelector::PseudoFullPageMedia:
79419cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)            return element.document().isMediaDocument();
7955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
7965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case CSSSelector::PseudoDefault:
79719cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)            return element.isDefaultButtonForForm();
7985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case CSSSelector::PseudoDisabled:
799d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            if (element.isFormControlElement() || isHTMLOptionElement(element) || isHTMLOptGroupElement(element))
80019cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)                return element.isDisabledFormControl();
8015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
8025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case CSSSelector::PseudoReadOnly:
80319cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)            return element.matchesReadOnlyPseudoClass();
8045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case CSSSelector::PseudoReadWrite:
80519cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)            return element.matchesReadWritePseudoClass();
8065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case CSSSelector::PseudoOptional:
80719cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)            return element.isOptionalFormControl();
8085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case CSSSelector::PseudoRequired:
80919cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)            return element.isRequiredFormControl();
8105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case CSSSelector::PseudoValid:
81119cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)            element.document().setContainsValidityStyleRules();
81219cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)            return element.willValidate() && element.isValidFormControlElement();
8135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case CSSSelector::PseudoInvalid:
81419cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)            element.document().setContainsValidityStyleRules();
81519cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)            return element.willValidate() && !element.isValidFormControlElement();
8165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case CSSSelector::PseudoChecked:
8175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            {
818d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                if (isHTMLInputElement(element)) {
81919cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)                    HTMLInputElement& inputElement = toHTMLInputElement(element);
820521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)                    // Even though WinIE allows checked and indeterminate to
821521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)                    // co-exist, the CSS selector spec says that you can't be
822521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)                    // both checked and indeterminate. We will behave like WinIE
823521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)                    // behind the scenes and just obey the CSS spec here in the
824521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)                    // test for matching the pseudo.
82519cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)                    if (inputElement.shouldAppearChecked() && !inputElement.shouldAppearIndeterminate())
826521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)                        return true;
827d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                } else if (isHTMLOptionElement(element) && toHTMLOptionElement(element).selected())
8285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    return true;
8295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                break;
8305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
8315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case CSSSelector::PseudoIndeterminate:
83219cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)            return element.shouldAppearIndeterminate();
8335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case CSSSelector::PseudoRoot:
83419cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)            if (element == element.document().documentElement())
8355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return true;
8365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
8375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case CSSSelector::PseudoLang:
8385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            {
839926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                AtomicString value;
84051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                if (element.isVTTElement())
84151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                    value = toVTTElement(element).language();
842926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                else
84319cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)                    value = element.computeInheritedLanguage();
84409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                const AtomicString& argument = selector.argument();
8455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (value.isEmpty() || !value.startsWith(argument, false))
8465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    break;
8475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                if (value.length() != argument.length() && value[argument.length()] != '-')
8485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    break;
8495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return true;
8505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
8515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case CSSSelector::PseudoFullScreen:
8525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // While a Document is in the fullscreen state, and the document's current fullscreen
8535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // element is an element in the document, the 'full-screen' pseudoclass applies to
8545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // that element. Also, an <iframe>, <object> or <embed> element whose child browsing
8555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // context's Document is in the fullscreen state has the 'full-screen' pseudoclass applied.
85643e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)            if (isHTMLFrameElementBase(element) && element.containsFullScreenElement())
8575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return true;
8589e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)            return Fullscreen::isActiveFullScreenElement(element);
8595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case CSSSelector::PseudoFullScreenAncestor:
86019cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)            return element.containsFullScreenElement();
8615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case CSSSelector::PseudoFullScreenDocument:
8625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // While a Document is in the fullscreen state, the 'full-screen-document' pseudoclass applies
8635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // to all elements of that Document.
8649e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)            if (!Fullscreen::isFullScreen(element.document()))
8655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return false;
8665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return true;
8675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case CSSSelector::PseudoInRange:
86819cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)            element.document().setContainsValidityStyleRules();
86919cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)            return element.isInRange();
8705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case CSSSelector::PseudoOutOfRange:
87119cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)            element.document().setContainsValidityStyleRules();
87219cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)            return element.isOutOfRange();
873926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        case CSSSelector::PseudoFutureCue:
87451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            return (element.isVTTElement() && !toVTTElement(element).isPastNode());
875926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        case CSSSelector::PseudoPastCue:
87651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)            return (element.isVTTElement() && toVTTElement(element).isPastNode());
877926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
878926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        case CSSSelector::PseudoScope:
879926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            {
88007a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch                if (m_mode == SharingRules)
88107a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch                    return true;
88209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                const Node* contextualReferenceNode = !context.scope ? element.document().documentElement() : context.scope;
883926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                if (element == contextualReferenceNode)
884926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                    return true;
885926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                break;
886926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            }
887926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
88853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)        case CSSSelector::PseudoUnresolved:
88919cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)            if (element.isUnresolvedCustomElement())
89053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                return true;
89153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)            break;
89253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
8933c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch        case CSSSelector::PseudoHost:
89407a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch        case CSSSelector::PseudoHostContext:
8953c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch            {
89607a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch                if (m_mode == SharingRules)
89707a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch                    return true;
8983c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch                // :host only matches a shadow host when :host is in a shadow tree of the shadow host.
899d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                if (!context.scope)
900d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                    return false;
9015d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)                const ContainerNode* shadowHost = context.scope->shadowHost();
902d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                if (!shadowHost || shadowHost != element)
9033c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch                    return false;
90419cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)                ASSERT(element.shadow());
9053c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch
9063c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch                // For empty parameter case, i.e. just :host or :host().
90709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                if (!selector.selectorList()) // Use *'s specificity. So just 0.
9083c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch                    return true;
9093c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch
9103c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch                SelectorCheckingContext subContext(context);
9113c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch                subContext.isSubSelector = true;
912a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
913a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                bool matched = false;
914a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                unsigned maxSpecificity = 0;
915a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
916a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                // If one of simple selectors matches an element, returns SelectorMatches. Just "OR".
91709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                for (subContext.selector = selector.selectorList()->first(); subContext.selector; subContext.selector = CSSSelectorList::next(*subContext.selector)) {
918197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch                    subContext.contextFlags = TreatShadowHostAsNormalScope;
9195d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)                    subContext.scope = context.scope;
920a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                    // Use NodeRenderingTraversal to traverse a composed ancestor list of a given element.
92109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                    Element* nextElement = &element;
92243e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)                    SelectorCheckingContext hostContext(subContext);
92309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                    do {
924a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                        MatchResult subResult;
92543e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)                        hostContext.element = nextElement;
92643e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)                        if (match(hostContext, siblingTraversalStrategy, &subResult) == SelectorMatches) {
927a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                            matched = true;
928a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                            // Consider div:host(div:host(div:host(div:host...))).
92943e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)                            maxSpecificity = std::max(maxSpecificity, hostContext.selector->specificity() + subResult.specificity);
930a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                            break;
931a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                        }
932197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch                        hostContext.contextFlags = DefaultBehavior;
933c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)                        hostContext.scope = nullptr;
93409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
93509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                        if (selector.pseudoType() == CSSSelector::PseudoHost)
93609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                            break;
93709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
93843e7502580f146aa5b3db8267ba6dbb5c733a489Torne (Richard Coles)                        hostContext.elementStyle = 0;
93909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                        nextElement = NodeRenderingTraversal::parentElement(nextElement);
94009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                    } while (nextElement);
941a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                }
942a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                if (matched) {
943a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                    if (specificity)
944a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                        *specificity = maxSpecificity;
945a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)                    return true;
9463c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch                }
9473c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch            }
9483c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch            break;
949197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        case CSSSelector::PseudoSpatialNavigationFocus:
950197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch            return context.isUARule && matchesSpatialNavigationFocusPseudoClass(element);
951e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        case CSSSelector::PseudoListBox:
952e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)            return context.isUARule && matchesListBoxPseudoClass(element);
9533c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch
954926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        case CSSSelector::PseudoHorizontal:
955926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        case CSSSelector::PseudoVertical:
956926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        case CSSSelector::PseudoDecrement:
957926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        case CSSSelector::PseudoIncrement:
958926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        case CSSSelector::PseudoStart:
959926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        case CSSSelector::PseudoEnd:
960926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        case CSSSelector::PseudoDoubleButton:
961926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        case CSSSelector::PseudoSingleButton:
962926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        case CSSSelector::PseudoNoButton:
963926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        case CSSSelector::PseudoCornerPresent:
964926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)            return false;
965926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
9665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case CSSSelector::PseudoUnknown:
9675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case CSSSelector::PseudoNotParsed:
9685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        default:
9695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ASSERT_NOT_REACHED();
9705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
9715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
9725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
9735d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    } else if (selector.match() == CSSSelector::PseudoElement && selector.pseudoType() == CSSSelector::PseudoCue) {
974926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        SelectorCheckingContext subContext(context);
975926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        subContext.isSubSelector = true;
976197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        subContext.contextFlags = DefaultBehavior;
977926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
97809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        const CSSSelector* contextSelector = context.selector;
97909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        ASSERT(contextSelector);
98009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        for (subContext.selector = contextSelector->selectorList()->first(); subContext.selector; subContext.selector = CSSSelectorList::next(*subContext.selector)) {
981a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)            if (match(subContext, siblingTraversalStrategy) == SelectorMatches)
982926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)                return true;
983926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        }
984926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return false;
985926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    }
9865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // ### add the rest of the checks...
9875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return true;
9885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
9895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
99009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)bool SelectorChecker::checkScrollbarPseudoClass(const SelectorCheckingContext& context, Document* document, const CSSSelector& selector) const
9915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
992926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    RenderScrollbar* scrollbar = context.scrollbar;
993926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)    ScrollbarPart part = context.scrollbarPart;
9945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // FIXME: This is a temporary hack for resizers and scrollbar corners. Eventually :window-inactive should become a real
9965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // pseudo class and just apply to everything.
99709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (selector.pseudoType() == CSSSelector::PseudoWindowInactive)
9983c9e4aeaee9f9b0a9a814da07bcb33319c7ea363Ben Murdoch        return !document->page()->focusController().isActive();
9995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!scrollbar)
10015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
10025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10035d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)    ASSERT(selector.match() == CSSSelector::PseudoClass);
100409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    switch (selector.pseudoType()) {
10055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case CSSSelector::PseudoEnabled:
10065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return scrollbar->enabled();
10075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case CSSSelector::PseudoDisabled:
10085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return !scrollbar->enabled();
10095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case CSSSelector::PseudoHover:
10105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        {
10115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ScrollbarPart hoveredPart = scrollbar->hoveredPart();
10125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (part == ScrollbarBGPart)
10135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return hoveredPart != NoPart;
10145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (part == TrackBGPart)
10155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return hoveredPart == BackTrackPart || hoveredPart == ForwardTrackPart || hoveredPart == ThumbPart;
10165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return part == hoveredPart;
10175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
10185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case CSSSelector::PseudoActive:
10195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        {
10205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ScrollbarPart pressedPart = scrollbar->pressedPart();
10215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (part == ScrollbarBGPart)
10225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return pressedPart != NoPart;
10235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (part == TrackBGPart)
10245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return pressedPart == BackTrackPart || pressedPart == ForwardTrackPart || pressedPart == ThumbPart;
10255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return part == pressedPart;
10265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
10275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case CSSSelector::PseudoHorizontal:
10285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return scrollbar->orientation() == HorizontalScrollbar;
10295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case CSSSelector::PseudoVertical:
10305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return scrollbar->orientation() == VerticalScrollbar;
10315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case CSSSelector::PseudoDecrement:
10325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return part == BackButtonStartPart || part == BackButtonEndPart || part == BackTrackPart;
10335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case CSSSelector::PseudoIncrement:
10345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return part == ForwardButtonStartPart || part == ForwardButtonEndPart || part == ForwardTrackPart;
10355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case CSSSelector::PseudoStart:
10365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return part == BackButtonStartPart || part == ForwardButtonStartPart || part == BackTrackPart;
10375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case CSSSelector::PseudoEnd:
10385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return part == BackButtonEndPart || part == ForwardButtonEndPart || part == ForwardTrackPart;
10395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case CSSSelector::PseudoDoubleButton:
10405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        {
10415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ScrollbarButtonsPlacement buttonsPlacement = scrollbar->theme()->buttonsPlacement();
10425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (part == BackButtonStartPart || part == ForwardButtonStartPart || part == BackTrackPart)
10435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return buttonsPlacement == ScrollbarButtonsDoubleStart || buttonsPlacement == ScrollbarButtonsDoubleBoth;
10445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (part == BackButtonEndPart || part == ForwardButtonEndPart || part == ForwardTrackPart)
10455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return buttonsPlacement == ScrollbarButtonsDoubleEnd || buttonsPlacement == ScrollbarButtonsDoubleBoth;
10465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return false;
10475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
10485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case CSSSelector::PseudoSingleButton:
10495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        {
10505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ScrollbarButtonsPlacement buttonsPlacement = scrollbar->theme()->buttonsPlacement();
10515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (part == BackButtonStartPart || part == ForwardButtonEndPart || part == BackTrackPart || part == ForwardTrackPart)
10525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return buttonsPlacement == ScrollbarButtonsSingle;
10535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return false;
10545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
10555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case CSSSelector::PseudoNoButton:
10565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        {
10575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ScrollbarButtonsPlacement buttonsPlacement = scrollbar->theme()->buttonsPlacement();
10585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (part == BackTrackPart)
10595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return buttonsPlacement == ScrollbarButtonsNone || buttonsPlacement == ScrollbarButtonsDoubleEnd;
10605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (part == ForwardTrackPart)
10615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                return buttonsPlacement == ScrollbarButtonsNone || buttonsPlacement == ScrollbarButtonsDoubleStart;
10625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return false;
10635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
10645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    case CSSSelector::PseudoCornerPresent:
10655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return scrollbar->scrollableArea()->isScrollCornerVisible();
10665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    default:
10675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
10685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
10695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
10705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
107109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)unsigned SelectorChecker::determineLinkMatchType(const CSSSelector& selector)
10725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
10735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    unsigned linkMatchType = MatchAll;
10745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
10755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Statically determine if this selector will match a link in visited, unvisited or any state, or never.
10765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // :visited never matches other elements than the innermost link element.
107709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    for (const CSSSelector* current = &selector; current; current = current->tagHistory()) {
107809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        switch (current->pseudoType()) {
10795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case CSSSelector::PseudoNot:
10805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            {
10815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                // :not(:visited) is equivalent to :link. Parser enforces that :not can't nest.
108209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                ASSERT(current->selectorList());
108309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                for (const CSSSelector* subSelector = current->selectorList()->first(); subSelector; subSelector = subSelector->tagHistory()) {
10845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    CSSSelector::PseudoType subType = subSelector->pseudoType();
10855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    if (subType == CSSSelector::PseudoVisited)
10865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        linkMatchType &= ~SelectorChecker::MatchVisited;
10875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    else if (subType == CSSSelector::PseudoLink)
10885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                        linkMatchType &= ~SelectorChecker::MatchLink;
10895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                }
10905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
10915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
10925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case CSSSelector::PseudoLink:
10935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            linkMatchType &= ~SelectorChecker::MatchVisited;
10945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
10955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        case CSSSelector::PseudoVisited:
10965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            linkMatchType &= ~SelectorChecker::MatchLink;
10975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
10985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        default:
10995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // We don't support :link and :visited inside :-webkit-any.
11005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
11015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
110209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        CSSSelector::Relation relation = current->relation();
11035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (relation == CSSSelector::SubSelector)
11045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            continue;
11055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (relation != CSSSelector::Descendant && relation != CSSSelector::Child)
11065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return linkMatchType;
11075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (linkMatchType != MatchAll)
11085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return linkMatchType;
11095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
11105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return linkMatchType;
11115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
11125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
111319cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)bool SelectorChecker::isFrameFocused(const Element& element)
11145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
111519cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    return element.document().frame() && element.document().frame()->selection().isFocusedAndActive();
11165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
11175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
111819cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)bool SelectorChecker::matchesFocusPseudoClass(const Element& element)
1119926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles){
112019cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    if (InspectorInstrumentation::forcePseudoState(const_cast<Element*>(&element), CSSSelector::PseudoFocus))
1121926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)        return true;
112219cde67944066db31e633d9e386f2aa9bf9fadb3Torne (Richard Coles)    return element.focused() && isFrameFocused(element);
1123926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)}
1124926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
1125197021e6b966cfb06891637935ef33fff06433d1Ben Murdochbool SelectorChecker::matchesSpatialNavigationFocusPseudoClass(const Element& element)
1126197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch{
1127197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    return isHTMLOptionElement(element) && toHTMLOptionElement(element).spatialNavigationFocused() && isFrameFocused(element);
1128197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch}
1129197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch
1130e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)bool SelectorChecker::matchesListBoxPseudoClass(const Element& element)
1131e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles){
1132e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    return isHTMLSelectElement(element) && !toHTMLSelectElement(element).usesMenuList();
1133e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)}
1134e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)
1135926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)template
1136a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)SelectorChecker::Match SelectorChecker::match(const SelectorCheckingContext&, const DOMSiblingTraversalStrategy&, MatchResult*) const;
1137926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles)
11385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)template
1139a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)SelectorChecker::Match SelectorChecker::match(const SelectorCheckingContext&, const ShadowDOMSiblingTraversalStrategy&, MatchResult*) const;
11405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
11415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1142