diff options
Diffstat (limited to 'Source/WebCore/css/CSSSelector.h')
-rw-r--r-- | Source/WebCore/css/CSSSelector.h | 559 |
1 files changed, 363 insertions, 196 deletions
diff --git a/Source/WebCore/css/CSSSelector.h b/Source/WebCore/css/CSSSelector.h index 55ac62463..665a5f951 100644 --- a/Source/WebCore/css/CSSSelector.h +++ b/Source/WebCore/css/CSSSelector.h @@ -1,7 +1,7 @@ /* * Copyright (C) 1999-2003 Lars Knoll (knoll@kde.org) * 1999 Waldo Bastian (bastian@kde.org) - * Copyright (C) 2004, 2006, 2007, 2008, 2009, 2010, 2013 Apple Inc. All rights reserved. + * Copyright (C) 2004, 2006, 2007, 2008, 2009, 2010, 2013, 2014 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -19,18 +19,21 @@ * Boston, MA 02110-1301, USA. */ -#ifndef CSSSelector_h -#define CSSSelector_h +#pragma once #include "QualifiedName.h" #include "RenderStyleConstants.h" #include <wtf/Noncopyable.h> -#include <wtf/OwnPtr.h> -#include <wtf/PassOwnPtr.h> namespace WebCore { class CSSSelectorList; + enum class SelectorSpecificityIncrement { + ClassA = 0x10000, + ClassB = 0x100, + ClassC = 1 + }; + // this class represents a selector for a StyleRule class CSSSelector { WTF_MAKE_FAST_ALLOCATED; @@ -44,14 +47,20 @@ namespace WebCore { /** * Re-create selector text from selector's data */ - String selectorText(const String& = "") const; + String selectorText(const String& = emptyString()) const; // checks if the 2 selectors (including sub selectors) agree. bool operator==(const CSSSelector&) const; - // tag == -1 means apply to all elements (Selector = *) + static const unsigned maxValueMask = 0xffffff; + static const unsigned idMask = 0xff0000; + static const unsigned classMask = 0xff00; + static const unsigned elementMask = 0xff; - unsigned specificity() const; + unsigned staticSpecificity(bool& ok) const; + unsigned specificityForPage() const; + unsigned simpleSelectorSpecificity() const; + static unsigned addSpecificities(unsigned, unsigned); /* how the attribute value has to match.... Default is Exact */ enum Match { @@ -71,101 +80,122 @@ namespace WebCore { PagePseudoClass }; - enum Relation { - Descendant = 0, + enum RelationType { + Subselector, + DescendantSpace, Child, DirectAdjacent, IndirectAdjacent, - SubSelector, - ShadowDescendant, +#if ENABLE(CSS_SELECTORS_LEVEL4) + DescendantDoubleChild, +#endif + ShadowDescendant }; - enum PseudoType { - PseudoNotParsed = 0, - PseudoUnknown, - PseudoEmpty, - PseudoFirstChild, - PseudoFirstOfType, - PseudoLastChild, - PseudoLastOfType, - PseudoOnlyChild, - PseudoOnlyOfType, - PseudoFirstLine, - PseudoFirstLetter, - PseudoNthChild, - PseudoNthOfType, - PseudoNthLastChild, - PseudoNthLastOfType, - PseudoLink, - PseudoVisited, - PseudoAny, - PseudoAnyLink, - PseudoAutofill, - PseudoHover, - PseudoDrag, - PseudoFocus, - PseudoActive, - PseudoChecked, - PseudoEnabled, - PseudoFullPageMedia, - PseudoDefault, - PseudoDisabled, - PseudoOptional, - PseudoRequired, - PseudoReadOnly, - PseudoReadWrite, - PseudoValid, - PseudoInvalid, - PseudoIndeterminate, - PseudoTarget, - PseudoBefore, - PseudoAfter, - PseudoLang, - PseudoNot, - PseudoResizer, - PseudoRoot, - PseudoScope, - PseudoScrollbar, - PseudoScrollbarBack, - PseudoScrollbarButton, - PseudoScrollbarCorner, - PseudoScrollbarForward, - PseudoScrollbarThumb, - PseudoScrollbarTrack, - PseudoScrollbarTrackPiece, - PseudoWindowInactive, - PseudoCornerPresent, - PseudoDecrement, - PseudoIncrement, - PseudoHorizontal, - PseudoVertical, - PseudoStart, - PseudoEnd, - PseudoDoubleButton, - PseudoSingleButton, - PseudoNoButton, - PseudoSelection, - PseudoLeftPage, - PseudoRightPage, - PseudoFirstPage, + enum PseudoClassType { + PseudoClassUnknown = 0, + PseudoClassEmpty, + PseudoClassFirstChild, + PseudoClassFirstOfType, + PseudoClassLastChild, + PseudoClassLastOfType, + PseudoClassOnlyChild, + PseudoClassOnlyOfType, + PseudoClassNthChild, + PseudoClassNthOfType, + PseudoClassNthLastChild, + PseudoClassNthLastOfType, + PseudoClassLink, + PseudoClassVisited, + PseudoClassAny, + PseudoClassAnyLink, + PseudoClassAnyLinkDeprecated, + PseudoClassAutofill, + PseudoClassHover, + PseudoClassDrag, + PseudoClassFocus, + PseudoClassFocusWithin, + PseudoClassActive, + PseudoClassChecked, + PseudoClassEnabled, + PseudoClassFullPageMedia, + PseudoClassDefault, + PseudoClassDisabled, + PseudoClassMatches, + PseudoClassOptional, + PseudoClassPlaceholderShown, + PseudoClassRequired, + PseudoClassReadOnly, + PseudoClassReadWrite, + PseudoClassValid, + PseudoClassInvalid, + PseudoClassIndeterminate, + PseudoClassTarget, + PseudoClassLang, + PseudoClassNot, + PseudoClassRoot, + PseudoClassScope, + PseudoClassWindowInactive, + PseudoClassCornerPresent, + PseudoClassDecrement, + PseudoClassIncrement, + PseudoClassHorizontal, + PseudoClassVertical, + PseudoClassStart, + PseudoClassEnd, + PseudoClassDoubleButton, + PseudoClassSingleButton, + PseudoClassNoButton, #if ENABLE(FULLSCREEN_API) - PseudoFullScreen, - PseudoFullScreenDocument, - PseudoFullScreenAncestor, - PseudoAnimatingFullScreenTransition, + PseudoClassFullScreen, + PseudoClassFullScreenDocument, + PseudoClassFullScreenAncestor, + PseudoClassAnimatingFullScreenTransition, #endif - PseudoInRange, - PseudoOutOfRange, - PseudoUserAgentCustomElement, - PseudoWebKitCustomElement, + PseudoClassInRange, + PseudoClassOutOfRange, #if ENABLE(VIDEO_TRACK) - PseudoCue, - PseudoFutureCue, - PseudoPastCue, + PseudoClassFuture, + PseudoClassPast, #endif -#if ENABLE(IFRAME_SEAMLESS) - PseudoSeamlessDocument, +#if ENABLE(CSS_SELECTORS_LEVEL4) + PseudoClassDir, + PseudoClassRole, #endif + PseudoClassHost, + PseudoClassDefined, + }; + + enum PseudoElementType { + PseudoElementUnknown = 0, + PseudoElementAfter, + PseudoElementBefore, +#if ENABLE(VIDEO_TRACK) + PseudoElementCue, +#endif + PseudoElementFirstLetter, + PseudoElementFirstLine, + PseudoElementResizer, + PseudoElementScrollbar, + PseudoElementScrollbarButton, + PseudoElementScrollbarCorner, + PseudoElementScrollbarThumb, + PseudoElementScrollbarTrack, + PseudoElementScrollbarTrackPiece, + PseudoElementSelection, + PseudoElementSlotted, + PseudoElementUserAgentCustom, + PseudoElementWebKitCustom, + + // WebKitCustom that appeared in an old prefixed form + // and need special handling. + PseudoElementWebKitCustomLegacyPrefixed, + }; + + enum PagePseudoClassType { + PagePseudoClassFirst = 1, + PagePseudoClassLeft, + PagePseudoClassRight, }; enum MarginBoxType { @@ -187,97 +217,181 @@ namespace WebCore { RightBottomMarginBox, }; - PseudoType pseudoType() const - { - if (m_pseudoType == PseudoNotParsed) - extractPseudoType(); - return static_cast<PseudoType>(m_pseudoType); - } + enum AttributeMatchType { + CaseSensitive, + CaseInsensitive, + }; - static PseudoType parsePseudoType(const AtomicString&); - static PseudoId pseudoId(PseudoType); + static PseudoElementType parsePseudoElementType(const String&); + static PseudoId pseudoId(PseudoElementType); // Selectors are kept in an array by CSSSelectorList. The next component of the selector is // the next item in the array. const CSSSelector* tagHistory() const { return m_isLastInTagHistory ? 0 : const_cast<CSSSelector*>(this + 1); } const QualifiedName& tagQName() const; + const AtomicString& tagLowercaseLocalName() const; + const AtomicString& value() const; + const AtomicString& serializingValue() const; const QualifiedName& attribute() const; const AtomicString& attributeCanonicalLocalName() const; const AtomicString& argument() const { return m_hasRareData ? m_data.m_rareData->m_argument : nullAtom; } - const CSSSelectorList* selectorList() const { return m_hasRareData ? m_data.m_rareData->m_selectorList.get() : 0; } + bool attributeValueMatchingIsCaseInsensitive() const; + const Vector<AtomicString>* langArgumentList() const { return m_hasRareData ? m_data.m_rareData->m_langArgumentList.get() : nullptr; } + const CSSSelectorList* selectorList() const { return m_hasRareData ? m_data.m_rareData->m_selectorList.get() : nullptr; } - void setValue(const AtomicString&); - void setAttribute(const QualifiedName&, bool isCaseInsensitive); + void setValue(const AtomicString&, bool matchLowerCase = false); + + // FIXME-NEWPARSER: These two methods can go away once the old parser is gone. + void setAttribute(const QualifiedName&, bool); + void setAttributeValueMatchingIsCaseInsensitive(bool); + void setAttribute(const QualifiedName&, bool convertToLowercase, AttributeMatchType); + void setNth(int a, int b); void setArgument(const AtomicString&); - void setSelectorList(PassOwnPtr<CSSSelectorList>); + void setLangArgumentList(std::unique_ptr<Vector<AtomicString>>); + void setSelectorList(std::unique_ptr<CSSSelectorList>); bool parseNth() const; bool matchNth(int count) const; + int nthA() const; + int nthB() const; + +#if ENABLE(CSS_SELECTORS_LEVEL4) + bool hasDescendantRelation() const { return relation() == DescendantSpace || relation() == DescendantDoubleChild; } +#else + bool hasDescendantRelation() const { return relation() == DescendantSpace; } +#endif + + bool hasDescendantOrChildRelation() const { return relation() == Child || hasDescendantRelation(); } + + PseudoClassType pseudoClassType() const + { + ASSERT(match() == PseudoClass); + return static_cast<PseudoClassType>(m_pseudoType); + } + void setPseudoClassType(PseudoClassType pseudoType) + { + m_pseudoType = pseudoType; + ASSERT(m_pseudoType == pseudoType); + } + + PseudoElementType pseudoElementType() const + { + ASSERT(match() == PseudoElement); + return static_cast<PseudoElementType>(m_pseudoType); + } + void setPseudoElementType(PseudoElementType pseudoElementType) + { + m_pseudoType = pseudoElementType; + ASSERT(m_pseudoType == pseudoElementType); + } + + PagePseudoClassType pagePseudoClassType() const + { + ASSERT(match() == PagePseudoClass); + return static_cast<PagePseudoClassType>(m_pseudoType); + } + void setPagePseudoType(PagePseudoClassType pagePseudoType) + { + m_pseudoType = pagePseudoType; + ASSERT(m_pseudoType == pagePseudoType); + } bool matchesPseudoElement() const; bool isUnknownPseudoElement() const; bool isCustomPseudoElement() const; + bool isWebKitCustomPseudoElement() const; bool isSiblingSelector() const; bool isAttributeSelector() const; - Relation relation() const { return static_cast<Relation>(m_relation); } + RelationType relation() const { return static_cast<RelationType>(m_relation); } + void setRelation(RelationType relation) + { + m_relation = relation; + ASSERT(m_relation == relation); + } + + Match match() const { return static_cast<Match>(m_match); } + void setMatch(Match match) + { + m_match = match; + ASSERT(m_match == match); + } bool isLastInSelectorList() const { return m_isLastInSelectorList; } void setLastInSelectorList() { m_isLastInSelectorList = true; } bool isLastInTagHistory() const { return m_isLastInTagHistory; } void setNotLastInTagHistory() { m_isLastInTagHistory = false; } - bool isSimple() const; - bool isForPage() const { return m_isForPage; } void setForPage() { m_isForPage = true; } - unsigned m_relation : 3; // enum Relation - mutable unsigned m_match : 4; // enum Match - mutable unsigned m_pseudoType : 8; // PseudoType - private: - mutable bool m_parsedNth : 1; // Used for :nth-* - bool m_isLastInSelectorList : 1; - bool m_isLastInTagHistory : 1; - bool m_hasRareData : 1; - bool m_isForPage : 1; - bool m_tagIsForNamespaceRule : 1; - - unsigned specificityForOneSelector() const; - unsigned specificityForPage() const; - void extractPseudoType() const; + unsigned m_relation : 4; // enum RelationType. + mutable unsigned m_match : 4; // enum Match. + mutable unsigned m_pseudoType : 8; // PseudoType. + mutable unsigned m_parsedNth : 1; // Used for :nth-*. + unsigned m_isLastInSelectorList : 1; + unsigned m_isLastInTagHistory : 1; + unsigned m_hasRareData : 1; + unsigned m_hasNameWithCase : 1; + unsigned m_isForPage : 1; + unsigned m_tagIsForNamespaceRule : 1; + unsigned m_caseInsensitiveAttributeValueMatching : 1; +#if !ASSERT_WITH_SECURITY_IMPLICATION_DISABLED + unsigned m_destructorHasBeenCalled : 1; +#endif + + unsigned simpleSelectorSpecificityForPage() const; // Hide. CSSSelector& operator=(const CSSSelector&); struct RareData : public RefCounted<RareData> { - static PassRefPtr<RareData> create(PassRefPtr<AtomicStringImpl> value) { return adoptRef(new RareData(value)); } + static Ref<RareData> create(AtomicString&& value) { return adoptRef(*new RareData(WTFMove(value))); } ~RareData(); bool parseNth(); bool matchNth(int count); - AtomicStringImpl* m_value; // Plain pointer to keep things uniform with the union. + // For quirks mode, class and id are case-insensitive. In the case where uppercase + // letters are used in quirks mode, |m_matchingValue| holds the lowercase class/id + // and |m_serializingValue| holds the original string. + AtomicString m_matchingValue; + AtomicString m_serializingValue; + int m_a; // Used for :nth-* int m_b; // Used for :nth-* QualifiedName m_attribute; // used for attribute selector AtomicString m_attributeCanonicalLocalName; - AtomicString m_argument; // Used for :contains, :lang and :nth-* - OwnPtr<CSSSelectorList> m_selectorList; // Used for :-webkit-any and :not + AtomicString m_argument; // Used for :contains and :nth-* + std::unique_ptr<Vector<AtomicString>> m_langArgumentList; // Used for :lang arguments. + std::unique_ptr<CSSSelectorList> m_selectorList; // Used for :matches() and :not(). private: - RareData(PassRefPtr<AtomicStringImpl> value); + RareData(AtomicString&& value); }; void createRareData(); + struct NameWithCase : public RefCounted<NameWithCase> { + NameWithCase(const QualifiedName& originalName, const AtomicString& lowercaseName) + : m_originalName(originalName) + , m_lowercaseLocalName(lowercaseName) + { + ASSERT(originalName.localName() != lowercaseName); + } + + const QualifiedName m_originalName; + const AtomicString m_lowercaseLocalName; + }; + union DataUnion { DataUnion() : m_value(0) { } AtomicStringImpl* m_value; QualifiedName::QualifiedNameImpl* m_tagQName; RareData* m_rareData; + NameWithCase* m_nameWithCase; } m_data; }; @@ -297,96 +411,98 @@ inline const AtomicString& CSSSelector::attributeCanonicalLocalName() const inline bool CSSSelector::matchesPseudoElement() const { - if (m_pseudoType == PseudoUnknown) - extractPseudoType(); - return m_match == PseudoElement; + return match() == PseudoElement; } inline bool CSSSelector::isUnknownPseudoElement() const { - return m_match == PseudoElement && m_pseudoType == PseudoUnknown; + return match() == PseudoElement && pseudoElementType() == PseudoElementUnknown; } inline bool CSSSelector::isCustomPseudoElement() const { - return m_match == PseudoElement && (m_pseudoType == PseudoUserAgentCustomElement || m_pseudoType == PseudoWebKitCustomElement); + return match() == PseudoElement + && (pseudoElementType() == PseudoElementUserAgentCustom + || pseudoElementType() == PseudoElementWebKitCustom + || pseudoElementType() == PseudoElementWebKitCustomLegacyPrefixed); +} + +inline bool CSSSelector::isWebKitCustomPseudoElement() const +{ + return pseudoElementType() == PseudoElementWebKitCustom || pseudoElementType() == PseudoElementWebKitCustomLegacyPrefixed; +} + +static inline bool pseudoClassIsRelativeToSiblings(CSSSelector::PseudoClassType type) +{ + return type == CSSSelector::PseudoClassEmpty + || type == CSSSelector::PseudoClassFirstChild + || type == CSSSelector::PseudoClassFirstOfType + || type == CSSSelector::PseudoClassLastChild + || type == CSSSelector::PseudoClassLastOfType + || type == CSSSelector::PseudoClassOnlyChild + || type == CSSSelector::PseudoClassOnlyOfType + || type == CSSSelector::PseudoClassNthChild + || type == CSSSelector::PseudoClassNthOfType + || type == CSSSelector::PseudoClassNthLastChild + || type == CSSSelector::PseudoClassNthLastOfType; } inline bool CSSSelector::isSiblingSelector() const { - PseudoType type = pseudoType(); - return m_relation == DirectAdjacent - || m_relation == IndirectAdjacent - || type == PseudoEmpty - || type == PseudoFirstChild - || type == PseudoFirstOfType - || type == PseudoLastChild - || type == PseudoLastOfType - || type == PseudoOnlyChild - || type == PseudoOnlyOfType - || type == PseudoNthChild - || type == PseudoNthOfType - || type == PseudoNthLastChild - || type == PseudoNthLastOfType; + return relation() == DirectAdjacent + || relation() == IndirectAdjacent + || (match() == CSSSelector::PseudoClass && pseudoClassIsRelativeToSiblings(pseudoClassType())); } inline bool CSSSelector::isAttributeSelector() const { - return m_match == CSSSelector::Exact - || m_match == CSSSelector::Set - || m_match == CSSSelector::List - || m_match == CSSSelector::Hyphen - || m_match == CSSSelector::Contain - || m_match == CSSSelector::Begin - || m_match == CSSSelector::End; + return match() == CSSSelector::Exact + || match() == CSSSelector::Set + || match() == CSSSelector::List + || match() == CSSSelector::Hyphen + || match() == CSSSelector::Contain + || match() == CSSSelector::Begin + || match() == CSSSelector::End; } -inline void CSSSelector::setValue(const AtomicString& value) +inline void CSSSelector::setValue(const AtomicString& value, bool matchLowerCase) { - ASSERT(m_match != Tag); - ASSERT(m_pseudoType == PseudoNotParsed); + ASSERT(match() != Tag); + AtomicString matchingValue = matchLowerCase ? value.convertToASCIILowercase() : value; + if (!m_hasRareData && matchingValue != value) + createRareData(); + // Need to do ref counting manually for the union. - if (m_hasRareData) { - if (m_data.m_rareData->m_value) - m_data.m_rareData->m_value->deref(); - m_data.m_rareData->m_value = value.impl(); - m_data.m_rareData->m_value->ref(); + if (!m_hasRareData) { + if (m_data.m_value) + m_data.m_value->deref(); + m_data.m_value = value.impl(); + m_data.m_value->ref(); return; } - if (m_data.m_value) - m_data.m_value->deref(); - m_data.m_value = value.impl(); - m_data.m_value->ref(); + + m_data.m_rareData->m_matchingValue = WTFMove(matchingValue); + m_data.m_rareData->m_serializingValue = value; } inline CSSSelector::CSSSelector() - : m_relation(Descendant) + : m_relation(DescendantSpace) , m_match(Unknown) - , m_pseudoType(PseudoNotParsed) + , m_pseudoType(0) , m_parsedNth(false) , m_isLastInSelectorList(false) , m_isLastInTagHistory(true) , m_hasRareData(false) + , m_hasNameWithCase(false) , m_isForPage(false) , m_tagIsForNamespaceRule(false) + , m_caseInsensitiveAttributeValueMatching(false) +#if !ASSERT_WITH_SECURITY_IMPLICATION_DISABLED + , m_destructorHasBeenCalled(false) +#endif { } -inline CSSSelector::CSSSelector(const QualifiedName& tagQName, bool tagIsForNamespaceRule) - : m_relation(Descendant) - , m_match(Tag) - , m_pseudoType(PseudoNotParsed) - , m_parsedNth(false) - , m_isLastInSelectorList(false) - , m_isLastInTagHistory(true) - , m_hasRareData(false) - , m_isForPage(false) - , m_tagIsForNamespaceRule(tagIsForNamespaceRule) -{ - m_data.m_tagQName = tagQName.impl(); - m_data.m_tagQName->ref(); -} - inline CSSSelector::CSSSelector(const CSSSelector& o) : m_relation(o.m_relation) , m_match(o.m_match) @@ -395,15 +511,23 @@ inline CSSSelector::CSSSelector(const CSSSelector& o) , m_isLastInSelectorList(o.m_isLastInSelectorList) , m_isLastInTagHistory(o.m_isLastInTagHistory) , m_hasRareData(o.m_hasRareData) + , m_hasNameWithCase(o.m_hasNameWithCase) , m_isForPage(o.m_isForPage) , m_tagIsForNamespaceRule(o.m_tagIsForNamespaceRule) + , m_caseInsensitiveAttributeValueMatching(o.m_caseInsensitiveAttributeValueMatching) +#if !ASSERT_WITH_SECURITY_IMPLICATION_DISABLED + , m_destructorHasBeenCalled(false) +#endif { - if (o.m_match == Tag) { - m_data.m_tagQName = o.m_data.m_tagQName; - m_data.m_tagQName->ref(); - } else if (o.m_hasRareData) { + if (o.m_hasRareData) { m_data.m_rareData = o.m_data.m_rareData; m_data.m_rareData->ref(); + } else if (o.m_hasNameWithCase) { + m_data.m_nameWithCase = o.m_data.m_nameWithCase; + m_data.m_nameWithCase->ref(); + } if (o.match() == Tag) { + m_data.m_tagQName = o.m_data.m_tagQName; + m_data.m_tagQName->ref(); } else if (o.m_data.m_value) { m_data.m_value = o.m_data.m_value; m_data.m_value->ref(); @@ -412,29 +536,72 @@ inline CSSSelector::CSSSelector(const CSSSelector& o) inline CSSSelector::~CSSSelector() { - if (m_match == Tag) - m_data.m_tagQName->deref(); - else if (m_hasRareData) + ASSERT_WITH_SECURITY_IMPLICATION(!m_destructorHasBeenCalled); +#if !ASSERT_WITH_SECURITY_IMPLICATION_DISABLED + m_destructorHasBeenCalled = true; +#endif + if (m_hasRareData) { m_data.m_rareData->deref(); - else if (m_data.m_value) + m_data.m_rareData = nullptr; + m_hasRareData = false; + } else if (m_hasNameWithCase) { + m_data.m_nameWithCase->deref(); + m_data.m_nameWithCase = nullptr; + m_hasNameWithCase = false; + } else if (match() == Tag) { + m_data.m_tagQName->deref(); + m_data.m_tagQName = nullptr; + m_match = Unknown; + } else if (m_data.m_value) { m_data.m_value->deref(); + m_data.m_value = nullptr; + } } inline const QualifiedName& CSSSelector::tagQName() const { - ASSERT(m_match == Tag); + ASSERT(match() == Tag); + if (m_hasNameWithCase) + return m_data.m_nameWithCase->m_originalName; return *reinterpret_cast<const QualifiedName*>(&m_data.m_tagQName); } +inline const AtomicString& CSSSelector::tagLowercaseLocalName() const +{ + if (m_hasNameWithCase) + return m_data.m_nameWithCase->m_lowercaseLocalName; + return m_data.m_tagQName->m_localName; +} + inline const AtomicString& CSSSelector::value() const { - ASSERT(m_match != Tag); + ASSERT(match() != Tag); + if (m_hasRareData) + return m_data.m_rareData->m_matchingValue; + // AtomicString is really just an AtomicStringImpl* so the cast below is safe. - // FIXME: Perhaps call sites could be changed to accept AtomicStringImpl? - return *reinterpret_cast<const AtomicString*>(m_hasRareData ? &m_data.m_rareData->m_value : &m_data.m_value); + return *reinterpret_cast<const AtomicString*>(&m_data.m_value); } +inline const AtomicString& CSSSelector::serializingValue() const +{ + ASSERT(match() != Tag); + if (m_hasRareData) + return m_data.m_rareData->m_serializingValue; + + // AtomicString is really just an AtomicStringImpl* so the cast below is safe. + return *reinterpret_cast<const AtomicString*>(&m_data.m_value); +} -} // namespace WebCore +inline void CSSSelector::setAttributeValueMatchingIsCaseInsensitive(bool isCaseInsensitive) +{ + ASSERT(isAttributeSelector() && match() != CSSSelector::Set); + m_caseInsensitiveAttributeValueMatching = isCaseInsensitive; +} + +inline bool CSSSelector::attributeValueMatchingIsCaseInsensitive() const +{ + return m_caseInsensitiveAttributeValueMatching; +} -#endif // CSSSelector_h +} // namespace WebCore |