summaryrefslogtreecommitdiff
path: root/Source/WebCore/css/SelectorChecker.h
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
commit1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch)
tree46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/css/SelectorChecker.h
parent32761a6cee1d0dee366b885b7b9c777e67885688 (diff)
downloadWebKitGtk-tarball-master.tar.gz
Diffstat (limited to 'Source/WebCore/css/SelectorChecker.h')
-rw-r--r--Source/WebCore/css/SelectorChecker.h147
1 files changed, 67 insertions, 80 deletions
diff --git a/Source/WebCore/css/SelectorChecker.h b/Source/WebCore/css/SelectorChecker.h
index ac6886287..85e94ceb0 100644
--- a/Source/WebCore/css/SelectorChecker.h
+++ b/Source/WebCore/css/SelectorChecker.h
@@ -2,7 +2,7 @@
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
* (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com)
* Copyright (C) 2006, 2007 Nicholas Shanks (webkit@nickshanks.com)
- * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2005-2016 Apple Inc. All rights reserved.
* Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org>
* Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org>
* Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
@@ -25,14 +25,12 @@
* Boston, MA 02110-1301, USA.
*/
-#ifndef SelectorChecker_h
-#define SelectorChecker_h
+#pragma once
#include "CSSSelector.h"
#include "Element.h"
#include "SpaceSplitString.h"
-#include <wtf/HashSet.h>
-#include <wtf/Vector.h>
+#include "StyleRelations.h"
namespace WebCore {
@@ -43,101 +41,90 @@ class RenderStyle;
class SelectorChecker {
WTF_MAKE_NONCOPYABLE(SelectorChecker);
- enum Match { SelectorMatches, SelectorFailsLocally, SelectorFailsAllSiblings, SelectorFailsCompletely };
+ enum class Match { SelectorMatches, SelectorFailsLocally, SelectorFailsAllSiblings, SelectorFailsCompletely };
+
+ enum class MatchType { VirtualPseudoElementOnly, Element };
+
+ struct MatchResult {
+ Match match;
+ MatchType matchType;
+
+ static MatchResult matches(MatchType matchType)
+ {
+ return { Match::SelectorMatches, matchType };
+ }
+
+ static MatchResult updateWithMatchType(MatchResult result, MatchType matchType)
+ {
+ if (matchType == MatchType::VirtualPseudoElementOnly)
+ result.matchType = MatchType::VirtualPseudoElementOnly;
+ return result;
+ }
+
+ static MatchResult fails(Match match)
+ {
+ return { match, MatchType::Element };
+ }
+ };
public:
- enum VisitedMatchType { VisitedMatchDisabled, VisitedMatchEnabled };
- enum Mode { ResolvingStyle = 0, CollectingRules, QueryingRules, SharingRules };
-
- SelectorChecker(Document&, Mode);
-
- struct SelectorCheckingContext {
- // Initial selector constructor
- SelectorCheckingContext(const CSSSelector* selector, Element* element, VisitedMatchType visitedMatchType)
- : selector(selector)
- , element(element)
- , scope(0)
- , visitedMatchType(visitedMatchType)
- , pseudoId(NOPSEUDO)
- , elementStyle(0)
- , scrollbar(0)
- , scrollbarPart(NoPart)
- , isSubSelector(false)
- , hasScrollbarPseudo(false)
- , hasSelectionPseudo(false)
+ enum class Mode : unsigned char {
+ ResolvingStyle = 0, CollectingRules, CollectingRulesIgnoringVirtualPseudoElements, QueryingRules
+ };
+
+ SelectorChecker(Document&);
+
+ struct CheckingContext {
+ CheckingContext(SelectorChecker::Mode resolvingMode)
+ : resolvingMode(resolvingMode)
{ }
- const CSSSelector* selector;
- Element* element;
- const ContainerNode* scope;
- VisitedMatchType visitedMatchType;
- PseudoId pseudoId;
- RenderStyle* elementStyle;
- RenderScrollbar* scrollbar;
- ScrollbarPart scrollbarPart;
- bool isSubSelector;
- bool hasScrollbarPseudo;
- bool hasSelectionPseudo;
+ const SelectorChecker::Mode resolvingMode;
+ PseudoId pseudoId { NOPSEUDO };
+ RenderScrollbar* scrollbar { nullptr };
+ ScrollbarPart scrollbarPart { NoPart };
+ const ContainerNode* scope { nullptr };
+ bool isMatchingHostPseudoClass { false };
+
+ // FIXME: It would be nicer to have a separate object for return values. This requires some more work in the selector compiler.
+ Style::Relations styleRelations;
+ PseudoIdSet pseudoIDSet;
};
- bool match(const SelectorCheckingContext& context, PseudoId& pseudoId) const
- {
- return matchRecursively(context, pseudoId) == SelectorMatches;
- }
+ bool match(const CSSSelector&, const Element&, CheckingContext&, unsigned& specificity) const;
+
+ bool matchHostPseudoClass(const CSSSelector&, const Element&, CheckingContext&, unsigned& specificity) const;
- static bool tagMatches(const Element*, const QualifiedName&);
static bool isCommonPseudoClassSelector(const CSSSelector*);
- static bool matchesFocusPseudoClass(const Element*);
- static bool checkExactAttribute(const Element*, const CSSSelector*, const QualifiedName& selectorAttributeName, const AtomicStringImpl* value);
+ static bool matchesFocusPseudoClass(const Element&);
+ static bool attributeSelectorMatches(const Element&, const QualifiedName&, const AtomicString& attributeValue, const CSSSelector&);
- enum LinkMatchMask { MatchLink = 1, MatchVisited = 2, MatchAll = MatchLink | MatchVisited };
+ enum LinkMatchMask { MatchDefault = 0, MatchLink = 1, MatchVisited = 2, MatchAll = MatchLink | MatchVisited };
static unsigned determineLinkMatchType(const CSSSelector*);
+ struct LocalContext;
+
private:
- Match matchRecursively(const SelectorCheckingContext&, PseudoId&) const;
- bool checkOne(const SelectorCheckingContext&) const;
+ MatchResult matchRecursively(CheckingContext&, const LocalContext&, PseudoIdSet&, unsigned& specificity) const;
+ bool checkOne(CheckingContext&, const LocalContext&, PseudoIdSet&, MatchType&, unsigned& specificity) const;
+ bool matchSelectorList(CheckingContext&, const LocalContext&, const Element&, const CSSSelectorList&, unsigned& specificity) const;
- bool checkScrollbarPseudoClass(const SelectorCheckingContext&, Document*, const CSSSelector*) const;
+ bool checkScrollbarPseudoClass(const CheckingContext&, const Element&, const CSSSelector&) const;
bool m_strictParsing;
bool m_documentIsHTML;
- Mode m_mode;
};
inline bool SelectorChecker::isCommonPseudoClassSelector(const CSSSelector* selector)
{
- if (selector->m_match != CSSSelector::PseudoClass)
- return false;
- CSSSelector::PseudoType pseudoType = selector->pseudoType();
- return pseudoType == CSSSelector::PseudoLink
- || pseudoType == CSSSelector::PseudoAnyLink
- || pseudoType == CSSSelector::PseudoVisited
- || pseudoType == CSSSelector::PseudoFocus;
-}
-
-inline bool SelectorChecker::tagMatches(const Element* element, const QualifiedName& tagQName)
-{
- if (tagQName == anyQName())
- return true;
- const AtomicString& localName = tagQName.localName();
- if (localName != starAtom && localName != element->localName())
- return false;
- const AtomicString& namespaceURI = tagQName.namespaceURI();
- return namespaceURI == starAtom || namespaceURI == element->namespaceURI();
-}
-
-inline bool SelectorChecker::checkExactAttribute(const Element* element, const CSSSelector* selector, const QualifiedName& selectorAttributeName, const AtomicStringImpl* value)
-{
- if (!element->hasAttributesWithoutUpdate())
+ if (selector->match() != CSSSelector::PseudoClass)
return false;
- const AtomicString& localName = element->isHTMLElement() ? selector->attributeCanonicalLocalName() : selectorAttributeName.localName();
- for (const Attribute& attribute : element->attributesIterator()) {
- if (attribute.matches(selectorAttributeName.prefix(), localName, selectorAttributeName.namespaceURI()) && (!value || attribute.value().impl() == value))
- return true;
- }
- return false;
-}
-
+ CSSSelector::PseudoClassType pseudoType = selector->pseudoClassType();
+ return pseudoType == CSSSelector::PseudoClassLink
+ || pseudoType == CSSSelector::PseudoClassAnyLink
+ || pseudoType == CSSSelector::PseudoClassAnyLinkDeprecated
+ || pseudoType == CSSSelector::PseudoClassVisited
+ || pseudoType == CSSSelector::PseudoClassFocus;
}
-#endif
+} // namespace WebCore