nsCSSPseudoElements.cpp (4487B)
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 #include "nsCSSPseudoElements.h" 10 11 #include "mozilla/ServoBindings.h" 12 #include "nsCSSAnonBoxes.h" 13 #include "nsDOMString.h" 14 #include "nsGkAtomConsts.h" 15 #include "nsStaticAtomUtils.h" 16 #include "nsStringFwd.h" 17 18 using namespace mozilla; 19 20 // Flags data for each of the pseudo-elements. 21 /* static */ const uint32_t nsCSSPseudoElements::kPseudoElementFlags[] = { 22 #define CSS_PSEUDO_ELEMENT(name_, value_, flags_) flags_, 23 #include "nsCSSPseudoElementList.h" 24 #undef CSS_PSEUDO_ELEMENT 25 }; 26 27 /* static */ 28 nsStaticAtom* nsCSSPseudoElements::GetAtomBase() { 29 return const_cast<nsStaticAtom*>( 30 nsGkAtoms::GetAtomByIndex(kAtomIndex_PseudoElements)); 31 } 32 33 /* static */ 34 nsAtom* nsCSSPseudoElements::GetPseudoAtom(Type aType) { 35 MOZ_ASSERT(PseudoStyle::IsPseudoElement(aType), "Unexpected type"); 36 size_t index = kAtomIndex_PseudoElements + static_cast<size_t>(aType); 37 return nsGkAtoms::GetAtomByIndex(index); 38 } 39 40 /* static */ 41 Maybe<PseudoStyleRequest> nsCSSPseudoElements::ParsePseudoElement( 42 const nsAString& aPseudoElement, CSSEnabledState aEnabledState) { 43 PseudoStyleRequest result; 44 45 // Not a pseudo-element, use default PseudoStyleReqeust. 46 if (DOMStringIsNull(aPseudoElement) || aPseudoElement.IsEmpty()) { 47 return Some(result); 48 } 49 50 // Parse the pseudo-element string. 51 if (!Servo_ParsePseudoElement(&aPseudoElement, &result)) { 52 return Nothing(); 53 } 54 55 // Servo_ParsePseudoElement() doesn't do enabled check, so it may return all 56 // possible PseudoElements, including tree pseudo-elements and anoymous boxes, 57 // so we have to filter out the pseudo-elements not defined in 58 // "nsCSSPseudoElementList.h" as well. 59 // Also, IsEnabled() checks if this pseudo-element should be enabled here 60 // (e.g. preference check and ua stylesheet check). 61 if (!PseudoStyle::IsPseudoElement(result.mType) || 62 !IsEnabled(result.mType, aEnabledState)) { 63 return Nothing(); 64 } 65 return Some(result); 66 } 67 68 /* static */ 69 bool nsCSSPseudoElements::PseudoElementSupportsUserActionState( 70 const Type aType) { 71 return PseudoElementHasFlags(aType, 72 CSS_PSEUDO_ELEMENT_SUPPORTS_USER_ACTION_STATE); 73 } 74 75 /* static */ 76 nsString nsCSSPseudoElements::PseudoRequestAsString( 77 const Request& aPseudoRequest) { 78 switch (aPseudoRequest.mType) { 79 case PseudoStyleType::before: 80 return u"::before"_ns; 81 case PseudoStyleType::after: 82 return u"::after"_ns; 83 case PseudoStyleType::backdrop: 84 return u"::backdrop"_ns; 85 case PseudoStyleType::marker: 86 return u"::marker"_ns; 87 case PseudoStyleType::viewTransition: 88 return u"::view-transition"_ns; 89 case PseudoStyleType::viewTransitionGroup: 90 return u"::view-transition-group("_ns + 91 nsAtomString(aPseudoRequest.mIdentifier) + u")"_ns; 92 case PseudoStyleType::viewTransitionImagePair: 93 return u"::view-transition-image-pair("_ns + 94 nsAtomString(aPseudoRequest.mIdentifier) + u")"_ns; 95 case PseudoStyleType::viewTransitionOld: 96 return u"::view-transition-old("_ns + 97 nsAtomString(aPseudoRequest.mIdentifier) + u")"_ns; 98 case PseudoStyleType::viewTransitionNew: 99 return u"::view-transition-new("_ns + 100 nsAtomString(aPseudoRequest.mIdentifier) + u")"_ns; 101 default: 102 MOZ_ASSERT(aPseudoRequest.IsNotPseudo(), "Unexpected pseudo type"); 103 return u""_ns; 104 } 105 } 106 107 #ifdef DEBUG 108 /* static */ 109 void nsCSSPseudoElements::AssertAtoms() { 110 nsStaticAtom* base = GetAtomBase(); 111 # define CSS_PSEUDO_ELEMENT(name_, value_, flags_) \ 112 { \ 113 RefPtr<nsAtom> atom = NS_Atomize(value_); \ 114 size_t index = static_cast<size_t>(PseudoStyleType::name_); \ 115 MOZ_ASSERT(atom == nsGkAtoms::PseudoElement_##name_, \ 116 "Static atom for " #name_ " has incorrect value"); \ 117 MOZ_ASSERT(atom == &base[index], \ 118 "Static atom for " #name_ " not at expected index"); \ 119 } 120 # include "nsCSSPseudoElementList.h" 121 # undef CSS_PSEUDO_ELEMENT 122 } 123 #endif