nsCSSPseudoElements.h (5949B)
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-elements */ 8 9 #ifndef nsCSSPseudoElements_h___ 10 #define nsCSSPseudoElements_h___ 11 12 #include "mozilla/CSSEnabledState.h" 13 #include "mozilla/PseudoStyleType.h" 14 #include "mozilla/StaticPrefs_dom.h" 15 #include "mozilla/StaticPrefs_layout.h" 16 #include "nsGkAtoms.h" 17 18 // Is this pseudo-element a CSS2 pseudo-element that can be specified 19 // with the single colon syntax (in addition to the double-colon syntax, 20 // which can be used for all pseudo-elements)? 21 // 22 // Note: We also rely on this for IsEagerlyCascadedInServo. 23 #define CSS_PSEUDO_ELEMENT_IS_CSS2 (1 << 0) 24 // Flag that indicate the pseudo-element supports a user action pseudo-class 25 // following it, such as :active or :hover. This would normally correspond 26 // to whether the pseudo-element is tree-like, but we don't support these 27 // pseudo-classes on ::before and ::after generated content yet. See 28 // http://dev.w3.org/csswg/selectors4/#pseudo-elements. 29 #define CSS_PSEUDO_ELEMENT_SUPPORTS_USER_ACTION_STATE (1 << 3) 30 // Should this pseudo-element be enabled only for UA sheets? 31 #define CSS_PSEUDO_ELEMENT_ENABLED_IN_UA_SHEETS (1 << 4) 32 // Should this pseudo-element be enabled only for UA sheets and chrome 33 // stylesheets? 34 #define CSS_PSEUDO_ELEMENT_ENABLED_IN_CHROME (1 << 5) 35 36 #define CSS_PSEUDO_ELEMENT_ENABLED_IN_UA_SHEETS_AND_CHROME \ 37 (CSS_PSEUDO_ELEMENT_ENABLED_IN_UA_SHEETS | \ 38 CSS_PSEUDO_ELEMENT_ENABLED_IN_CHROME) 39 40 // Can we use the ChromeOnly document.createElement(..., { pseudo: "::foo" }) 41 // API for creating pseudo-implementing native anonymous content in JS with this 42 // pseudo-element? 43 #define CSS_PSEUDO_ELEMENT_IS_JS_CREATED_NAC (1 << 6) 44 // Does this pseudo-element act like an item for containers (such as flex and 45 // grid containers) and thus needs parent display-based style fixup? 46 #define CSS_PSEUDO_ELEMENT_IS_FLEX_OR_GRID_ITEM (1 << 7) 47 48 class nsCSSPseudoElements { 49 using EnabledState = mozilla::CSSEnabledState; 50 using Request = mozilla::PseudoStyleRequest; 51 using Type = mozilla::PseudoStyleType; 52 53 public: 54 static bool IsEagerlyCascadedInServo(const Type aType) { 55 return PseudoElementHasFlags(aType, CSS_PSEUDO_ELEMENT_IS_CSS2); 56 } 57 58 public: 59 #ifdef DEBUG 60 static void AssertAtoms(); 61 #endif 62 63 // Alias nsCSSPseudoElements::foo() to nsGkAtoms::foo. 64 #define CSS_PSEUDO_ELEMENT(name_, value_, flags_) \ 65 static nsCSSPseudoElementStaticAtom* name_() { \ 66 return const_cast<nsCSSPseudoElementStaticAtom*>( \ 67 static_cast<const nsCSSPseudoElementStaticAtom*>( \ 68 nsGkAtoms::PseudoElement_##name_)); \ 69 } 70 #include "nsCSSPseudoElementList.h" 71 #undef CSS_PSEUDO_ELEMENT 72 73 // Returns an empty Request for a syntactically invalid pseudo-element, and 74 // NotPseudo for the empty / null string. 75 static mozilla::Maybe<Request> ParsePseudoElement( 76 const nsAString& aPseudoElement, 77 EnabledState = EnabledState::ForAllContent); 78 79 // Get the atom for a given Type. aType must be < 80 // PseudoType::CSSPseudoElementsEnd. 81 // This only ever returns static atoms, so it's fine to return a raw pointer. 82 static nsAtom* GetPseudoAtom(Type aType); 83 84 static bool PseudoElementSupportsUserActionState(const Type aType); 85 86 static bool PseudoElementIsJSCreatedNAC(Type aType) { 87 return PseudoElementHasFlags(aType, CSS_PSEUDO_ELEMENT_IS_JS_CREATED_NAC); 88 } 89 90 static bool PseudoElementIsFlexOrGridItem(const Type aType) { 91 return PseudoElementHasFlags(aType, 92 CSS_PSEUDO_ELEMENT_IS_FLEX_OR_GRID_ITEM); 93 } 94 95 static bool EnabledInContent(Type aType) { 96 switch (aType) { 97 case Type::highlight: 98 return mozilla::StaticPrefs::dom_customHighlightAPI_enabled(); 99 case Type::targetText: 100 return mozilla::StaticPrefs::dom_text_fragments_enabled(); 101 case Type::sliderTrack: 102 case Type::sliderThumb: 103 case Type::sliderFill: 104 return mozilla::StaticPrefs::layout_css_modern_range_pseudos_enabled(); 105 case Type::detailsContent: 106 return mozilla::StaticPrefs::layout_css_details_content_enabled(); 107 case Type::viewTransition: 108 case Type::viewTransitionGroup: 109 case Type::viewTransitionImagePair: 110 case Type::viewTransitionOld: 111 case Type::viewTransitionNew: 112 return mozilla::StaticPrefs::dom_viewTransitions_enabled(); 113 default: 114 return !PseudoElementHasAnyFlag( 115 aType, CSS_PSEUDO_ELEMENT_ENABLED_IN_UA_SHEETS_AND_CHROME); 116 } 117 } 118 119 static bool IsEnabled(Type aType, EnabledState aEnabledState) { 120 if (EnabledInContent(aType)) { 121 return true; 122 } 123 124 if ((aEnabledState & EnabledState::InUASheets) && 125 PseudoElementHasFlags(aType, CSS_PSEUDO_ELEMENT_ENABLED_IN_UA_SHEETS)) { 126 return true; 127 } 128 129 if ((aEnabledState & EnabledState::InChrome) && 130 PseudoElementHasFlags(aType, CSS_PSEUDO_ELEMENT_ENABLED_IN_CHROME)) { 131 return true; 132 } 133 134 return false; 135 } 136 137 static nsString PseudoRequestAsString(const Request& aPseudoRequest); 138 139 private: 140 // Does the given pseudo-element have all of the flags given? 141 static bool PseudoElementHasFlags(const Type aType, uint32_t aFlags) { 142 MOZ_ASSERT(aType < Type::CSSPseudoElementsEnd); 143 return (kPseudoElementFlags[size_t(aType)] & aFlags) == aFlags; 144 } 145 146 static bool PseudoElementHasAnyFlag(const Type aType, uint32_t aFlags) { 147 MOZ_ASSERT(aType < Type::CSSPseudoElementsEnd); 148 return (kPseudoElementFlags[size_t(aType)] & aFlags) != 0; 149 } 150 151 static nsStaticAtom* GetAtomBase(); 152 153 static const uint32_t kPseudoElementFlags[size_t(Type::CSSPseudoElementsEnd)]; 154 }; 155 156 #endif /* nsCSSPseudoElements_h___ */