1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 /* atom list for CSS pseudo-classes */ 8 9 #ifndef nsCSSPseudoClasses_h___ 10 #define nsCSSPseudoClasses_h___ 11 12 #include "nsStringFwd.h" 13 #include "mozilla/CSSEnabledState.h" 14 #include "mozilla/EventStates.h" 15 #include "mozilla/Maybe.h" 16 17 // The following two flags along with the pref defines where this pseudo 18 // class can be used: 19 // * If none of the two flags is presented, the pref completely controls 20 // the availability of this pseudo class. And in that case, if it has 21 // no pref, this property is usable everywhere. 22 // * If any of the flags is set, this pseudo class is always enabled in 23 // the specific contexts regardless of the value of the pref. If there 24 // is no pref for this pseudo class at all in this case, it is an 25 // internal-only pseudo class, which cannot be used anywhere else. 26 #define CSS_PSEUDO_CLASS_ENABLED_MASK (3 << 0) 27 #define CSS_PSEUDO_CLASS_ENABLED_IN_UA_SHEETS (1 << 0) 28 #define CSS_PSEUDO_CLASS_ENABLED_IN_CHROME (1 << 1) 29 #define CSS_PSEUDO_CLASS_ENABLED_IN_UA_SHEETS_AND_CHROME \ 30 (CSS_PSEUDO_CLASS_ENABLED_IN_UA_SHEETS | CSS_PSEUDO_CLASS_ENABLED_IN_CHROME) 31 32 class nsAtom; 33 class nsIDocument; 34 35 namespace mozilla { 36 namespace dom { 37 class Element; 38 } // namespace dom 39 40 // The total count of CSSPseudoClassType is less than 256, 41 // so use uint8_t as its underlying type. 42 typedef uint8_t CSSPseudoClassTypeBase; 43 enum class CSSPseudoClassType : CSSPseudoClassTypeBase { 44 #define CSS_PSEUDO_CLASS(_name, _value, _flags, _pref) _name, 45 #include "nsCSSPseudoClassList.h" 46 #undef CSS_PSEUDO_CLASS 47 Count, 48 NotPseudo, // This value MUST be second last! SelectorMatches depends on it. 49 MAX 50 }; 51 52 } // namespace mozilla 53 54 class nsCSSPseudoClasses { 55 typedef mozilla::CSSPseudoClassType Type; 56 typedef mozilla::CSSEnabledState EnabledState; 57 58 public: 59 static void AddRefAtoms(); 60 61 static Type GetPseudoType(nsAtom* aAtom, EnabledState aEnabledState); 62 static bool HasStringArg(Type aType); 63 static bool HasNthPairArg(Type aType); HasSelectorListArg(Type aType)64 static bool HasSelectorListArg(Type aType) { return aType == Type::any; } 65 static bool IsUserActionPseudoClass(Type aType); 66 67 // Should only be used on types other than Count and NotPseudoClass 68 static void PseudoTypeToString(Type aType, nsAString& aString); 69 IsEnabled(Type aType,EnabledState aEnabledState)70 static bool IsEnabled(Type aType, EnabledState aEnabledState) { 71 auto index = static_cast<size_t>(aType); 72 MOZ_ASSERT(index < static_cast<size_t>(Type::Count)); 73 if (sPseudoClassEnabled[index] || 74 aEnabledState == EnabledState::eIgnoreEnabledState) { 75 return true; 76 } 77 auto flags = kPseudoClassFlags[index]; 78 if (((aEnabledState & EnabledState::eInChrome) && 79 (flags & CSS_PSEUDO_CLASS_ENABLED_IN_CHROME)) || 80 ((aEnabledState & EnabledState::eInUASheets) && 81 (flags & CSS_PSEUDO_CLASS_ENABLED_IN_UA_SHEETS))) { 82 return true; 83 } 84 return false; 85 } 86 87 // Checks whether the given pseudo class matches the element. 88 // It returns Some(result) if this function is able to check 89 // the pseudo-class, Nothing() otherwise. 90 static mozilla::Maybe<bool> MatchesElement( 91 Type aType, const mozilla::dom::Element* aElement); 92 93 /** 94 * Checks if a function-like ident-containing pseudo (:pseudo(ident)) 95 * matches a given element. 96 * 97 * Returns true if it parses and matches, Some(false) if it 98 * parses but does not match. Asserts if it fails to parse; only 99 * call this when you're sure it's a string-like pseudo. 100 * 101 * In Servo mode, please ensure that UpdatePossiblyStaleDocumentState() 102 * has been called first. 103 * 104 * @param aElement The element we are trying to match 105 * @param aPseudo The name of the pseudoselector 106 * @param aString The identifier inside the pseudoselector (cannot be null) 107 * @param aDocument The document 108 * @param aStateMask Mask containing states which we should exclude. 109 * Ignored if aDependence is null 110 * @param aDependence Pointer to be set to true if we ignored a state due to 111 * aStateMask. Can be null. 112 */ 113 static bool StringPseudoMatches(const mozilla::dom::Element* aElement, 114 mozilla::CSSPseudoClassType aPseudo, 115 const char16_t* aString, 116 const nsIDocument* aDocument, 117 mozilla::EventStates aStateMask, 118 bool* const aDependence = nullptr); 119 120 static bool LangPseudoMatches(const mozilla::dom::Element* aElement, 121 const nsAtom* aOverrideLang, 122 bool aHasOverrideLang, const char16_t* aString, 123 const nsIDocument* aDocument); 124 125 static const mozilla::EventStates 126 sPseudoClassStateDependences[size_t(Type::Count) + 2]; 127 128 private: 129 static const uint32_t kPseudoClassFlags[size_t(Type::Count)]; 130 static bool sPseudoClassEnabled[size_t(Type::Count)]; 131 }; 132 133 #endif /* nsCSSPseudoClasses_h___ */ 134