nsCSSProps.h (9062B)
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 /* 8 * methods for dealing with CSS properties and tables of the keyword 9 * values they accept 10 */ 11 12 #ifndef nsCSSProps_h___ 13 #define nsCSSProps_h___ 14 15 #include <ostream> 16 17 #include "NonCustomCSSPropertyId.h" 18 #include "mozilla/CSSEnabledState.h" 19 #include "mozilla/CSSPropFlags.h" 20 #include "mozilla/Preferences.h" 21 #include "mozilla/UseCounter.h" 22 #include "nsString.h" 23 #include "nsStyleStructFwd.h" 24 25 // Length of the "--" prefix on custom names (such as custom property names, 26 // and, in the future, custom media query names). 27 #define CSS_CUSTOM_NAME_PREFIX_LENGTH 2 28 29 namespace mozilla { 30 class ComputedStyle; 31 namespace gfx { 32 class gfxVarReceiver; 33 } 34 } // namespace mozilla 35 36 extern "C" { 37 NonCustomCSSPropertyId Servo_ResolveLogicalProperty( 38 NonCustomCSSPropertyId, const mozilla::ComputedStyle*); 39 NonCustomCSSPropertyId Servo_Property_LookupEnabledForAllContent( 40 const nsACString*); 41 const uint8_t* Servo_Property_GetName(NonCustomCSSPropertyId, 42 uint32_t* aLength); 43 } 44 45 class nsCSSProps { 46 public: 47 using EnabledState = mozilla::CSSEnabledState; 48 using Flags = mozilla::CSSPropFlags; 49 50 static void Init(); 51 52 // Looks up the property with name aProperty and returns its corresponding 53 // NonCustomCSSPropertyId value. If aProperty is the name of a custom 54 // property, then eCSSPropertyExtra_variable will be returned. 55 // 56 // This only returns properties enabled for all content, and resolves aliases 57 // to return the aliased property. 58 static NonCustomCSSPropertyId LookupProperty(const nsACString& aProperty) { 59 return Servo_Property_LookupEnabledForAllContent(&aProperty); 60 } 61 62 // As above, but looked up using a property's IDL name. 63 // eCSSPropertyExtra_variable won't be returned from this method. 64 static NonCustomCSSPropertyId LookupPropertyByIDLName( 65 const nsACString& aPropertyIDLName, EnabledState aEnabled); 66 67 // Returns whether aProperty is a custom property name, i.e. begins with 68 // "--". This assumes that the CSS Variables pref has been enabled. 69 static bool IsCustomPropertyName(const nsACString& aProperty); 70 71 static bool IsShorthand(NonCustomCSSPropertyId aProperty) { 72 if (aProperty == eCSSPropertyExtra_variable) { 73 return false; 74 } 75 MOZ_ASSERT( 76 aProperty != eCSSProperty_UNKNOWN && aProperty < eCSSProperty_COUNT, 77 "out of range"); 78 return aProperty >= eCSSProperty_COUNT_no_shorthands; 79 } 80 81 // Same but for @font-face descriptors 82 static nsCSSFontDesc LookupFontDesc(const nsACString&); 83 84 // The relevant invariants are asserted in Document.cpp 85 static mozilla::UseCounter UseCounterFor(NonCustomCSSPropertyId aProperty) { 86 MOZ_ASSERT(aProperty != eCSSProperty_UNKNOWN && 87 aProperty < eCSSProperty_COUNT_with_aliases, 88 "out of range"); 89 return mozilla::UseCounter(size_t(mozilla::eUseCounter_FirstCSSProperty) + 90 size_t(aProperty)); 91 } 92 93 // Given a property enum, get the string value 94 // 95 // This string is static. 96 static nsDependentCSubstring GetStringValue( 97 NonCustomCSSPropertyId aProperty) { 98 uint32_t len; 99 const uint8_t* chars = Servo_Property_GetName(aProperty, &len); 100 return nsDependentCSubstring(reinterpret_cast<const char*>(chars), len); 101 } 102 103 static const nsCString& GetStringValue(nsCSSFontDesc aFontDesc); 104 static const nsCString& GetStringValue(nsCSSCounterDesc aCounterDesc); 105 106 static Flags PropFlags(NonCustomCSSPropertyId); 107 static bool PropHasFlags(NonCustomCSSPropertyId aProperty, Flags aFlags) { 108 return (PropFlags(aProperty) & aFlags) == aFlags; 109 } 110 111 static NonCustomCSSPropertyId Physicalize( 112 NonCustomCSSPropertyId aProperty, const mozilla::ComputedStyle& aStyle) { 113 MOZ_ASSERT(!IsShorthand(aProperty)); 114 if (PropHasFlags(aProperty, Flags::IsLogical)) { 115 return Servo_ResolveLogicalProperty(aProperty, &aStyle); 116 } 117 return aProperty; 118 } 119 120 private: 121 // A table for shorthand properties. The appropriate index is the 122 // property id minus eCSSProperty_COUNT_no_shorthands. 123 static const NonCustomCSSPropertyId* const 124 kSubpropertyTable[eCSSProperty_COUNT - eCSSProperty_COUNT_no_shorthands]; 125 126 public: 127 /** 128 * Returns true if the backdrop-filter pref and the gfx blocklist are enabled. 129 */ 130 static bool IsBackdropFilterAvailable(JSContext*, JSObject*) { 131 return IsEnabled(eCSSProperty_backdrop_filter, EnabledState::ForAllContent); 132 } 133 134 /** 135 * Recoumputes the enabled state of a pref. If aPrefName is nullptr, 136 * recomputes the state of all prefs in gPropertyEnabled. 137 * aClosure is the pref callback closure data, which is not used. 138 */ 139 static void RecomputeEnabledState(const char* aPrefName, 140 void* aClosure = nullptr); 141 142 /** 143 * Retrieve a singleton receiver to register with gfxVars 144 */ 145 static mozilla::gfx::gfxVarReceiver& GfxVarReceiver(); 146 147 static const NonCustomCSSPropertyId* SubpropertyEntryFor( 148 NonCustomCSSPropertyId aProperty) { 149 MOZ_ASSERT(eCSSProperty_COUNT_no_shorthands <= aProperty && 150 aProperty < eCSSProperty_COUNT, 151 "out of range"); 152 return kSubpropertyTable[aProperty - eCSSProperty_COUNT_no_shorthands]; 153 } 154 155 private: 156 static bool gPropertyEnabled[eCSSProperty_COUNT_with_aliases]; 157 // Defined in the generated nsCSSPropsGenerated.inc. 158 static const char* const kIDLNameTable[eCSSProperty_COUNT]; 159 static const int32_t kIDLNameSortPositionTable[eCSSProperty_COUNT]; 160 161 public: 162 /** 163 * Returns the IDL name of the specified property, which must be a 164 * longhand, logical or shorthand property. The IDL name is the property 165 * name with any hyphen-lowercase character pairs replaced by an 166 * uppercase character: 167 * https://drafts.csswg.org/cssom/#css-property-to-idl-attribute 168 * 169 * As a special case, the string "cssFloat" is returned for the float 170 * property. nullptr is returned for internal properties. 171 */ 172 static const char* PropertyIDLName(NonCustomCSSPropertyId aProperty) { 173 MOZ_ASSERT( 174 aProperty != eCSSProperty_UNKNOWN && aProperty < eCSSProperty_COUNT, 175 "out of range"); 176 return kIDLNameTable[aProperty]; 177 } 178 179 /** 180 * Returns the position of the specified property in a list of all 181 * properties sorted by their IDL name. 182 */ 183 static int32_t PropertyIDLNameSortPosition(NonCustomCSSPropertyId aProperty) { 184 MOZ_ASSERT( 185 aProperty != eCSSProperty_UNKNOWN && aProperty < eCSSProperty_COUNT, 186 "out of range"); 187 return kIDLNameSortPositionTable[aProperty]; 188 } 189 190 static bool IsEnabled(NonCustomCSSPropertyId aProperty, 191 EnabledState aEnabled) { 192 MOZ_ASSERT(aProperty != eCSSProperty_UNKNOWN && 193 aProperty < eCSSProperty_COUNT_with_aliases, 194 "out of range"); 195 // In the child process, assert that we're not trying to parse stylesheets 196 // before we've gotten all our prefs. 197 MOZ_ASSERT_IF(!XRE_IsParentProcess(), 198 mozilla::Preferences::ArePrefsInitedInContentProcess()); 199 if (gPropertyEnabled[aProperty]) { 200 return true; 201 } 202 if (aEnabled == EnabledState::IgnoreEnabledState) { 203 return true; 204 } 205 if ((aEnabled & EnabledState::InUASheets) && 206 PropHasFlags(aProperty, Flags::EnabledInUASheets)) { 207 return true; 208 } 209 if ((aEnabled & EnabledState::InChrome) && 210 PropHasFlags(aProperty, Flags::EnabledInChrome)) { 211 return true; 212 } 213 return false; 214 } 215 216 struct PropertyPref { 217 NonCustomCSSPropertyId mPropId; 218 const char* mPref; 219 }; 220 static const PropertyPref kPropertyPrefTable[]; 221 222 // Storing the enabledstate_ value in an NonCustomCSSPropertyId variable is a 223 // small hack to avoid needing a separate variable declaration for its real type 224 // (CSSEnabledState), which would then require using a block and 225 // therefore a pair of macros by consumers for the start and end of the loop. 226 #define CSSPROPS_FOR_SHORTHAND_SUBPROPERTIES(it_, prop_, enabledstate_) \ 227 for (const NonCustomCSSPropertyId * \ 228 it_ = nsCSSProps::SubpropertyEntryFor(prop_), \ 229 es_ = \ 230 (NonCustomCSSPropertyId)((enabledstate_) | CSSEnabledState(0)); \ 231 *it_ != eCSSProperty_UNKNOWN; ++it_) \ 232 if (nsCSSProps::IsEnabled(*it_, (mozilla::CSSEnabledState)es_)) 233 }; 234 235 // MOZ_DBG support for NonCustomCSSPropertyId 236 237 inline std::ostream& operator<<(std::ostream& aOut, 238 NonCustomCSSPropertyId aProperty) { 239 return aOut << nsCSSProps::GetStringValue(aProperty); 240 } 241 242 #endif /* nsCSSProps_h___ */