1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 /* 7 * methods for dealing with CSS properties and tables of the keyword 8 * values they accept 9 */ 10 11 #ifndef nsCSSProps_h___ 12 #define nsCSSProps_h___ 13 14 #include <limits> 15 #include <type_traits> 16 #include "nsIAtom.h" 17 #include "nsString.h" 18 #include "nsCSSPropertyID.h" 19 #include "nsStyleStructFwd.h" 20 #include "nsCSSKeywords.h" 21 #include "mozilla/CSSEnabledState.h" 22 #include "mozilla/UseCounter.h" 23 #include "mozilla/EnumTypeTraits.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 // Flags for ParseVariant method 30 #define VARIANT_KEYWORD 0x000001 // K 31 #define VARIANT_LENGTH 0x000002 // L 32 #define VARIANT_PERCENT 0x000004 // P 33 #define VARIANT_COLOR 0x000008 // C eCSSUnit_*Color, eCSSUnit_Ident (e.g. "red") 34 #define VARIANT_URL 0x000010 // U 35 #define VARIANT_NUMBER 0x000020 // N 36 #define VARIANT_INTEGER 0x000040 // I 37 #define VARIANT_ANGLE 0x000080 // G 38 #define VARIANT_FREQUENCY 0x000100 // F 39 #define VARIANT_TIME 0x000200 // T 40 #define VARIANT_STRING 0x000400 // S 41 #define VARIANT_COUNTER 0x000800 // 42 #define VARIANT_ATTR 0x001000 // 43 #define VARIANT_IDENTIFIER 0x002000 // D 44 #define VARIANT_IDENTIFIER_NO_INHERIT 0x004000 // like above, but excluding 45 // 'inherit' and 'initial' 46 #define VARIANT_AUTO 0x010000 // A 47 #define VARIANT_INHERIT 0x020000 // H eCSSUnit_Initial, eCSSUnit_Inherit, eCSSUnit_Unset 48 #define VARIANT_NONE 0x040000 // O 49 #define VARIANT_NORMAL 0x080000 // M 50 #define VARIANT_SYSFONT 0x100000 // eCSSUnit_System_Font 51 #define VARIANT_GRADIENT 0x200000 // eCSSUnit_Gradient 52 #define VARIANT_TIMING_FUNCTION 0x400000 // cubic-bezier() and steps() 53 #define VARIANT_ALL 0x800000 // 54 #define VARIANT_IMAGE_RECT 0x01000000 // eCSSUnit_Function 55 // This is an extra bit that says that a VARIANT_ANGLE allows unitless zero: 56 #define VARIANT_ZERO_ANGLE 0x02000000 // unitless zero for angles 57 #define VARIANT_CALC 0x04000000 // eCSSUnit_Calc 58 #define VARIANT_ELEMENT 0x08000000 // eCSSUnit_Element 59 #define VARIANT_NONNEGATIVE_DIMENSION 0x10000000 // Only lengths greater than or equal to 0.0 60 // Keyword used iff gfx.font_rendering.opentype_svg.enabled is true: 61 #define VARIANT_OPENTYPE_SVG_KEYWORD 0x20000000 62 #define VARIANT_ABSOLUTE_DIMENSION 0x40000000 // B Only lengths with absolute length unit 63 64 // Variants that can consume more than one token 65 #define VARIANT_MULTIPLE_TOKENS \ 66 (VARIANT_COLOR | /* rgb(...), hsl(...), etc. */ \ 67 VARIANT_COUNTER | /* counter(...), counters(...) */ \ 68 VARIANT_ATTR | /* attr(...) */ \ 69 VARIANT_GRADIENT | /* linear-gradient(...), etc. */ \ 70 VARIANT_TIMING_FUNCTION | /* cubic-bezier(...), steps(...) */ \ 71 VARIANT_IMAGE_RECT | /* -moz-image-rect(...) */ \ 72 VARIANT_CALC | /* calc(...) */ \ 73 VARIANT_ELEMENT) /* -moz-element(...) */ 74 75 // Common combinations of variants 76 #define VARIANT_AL (VARIANT_AUTO | VARIANT_LENGTH) 77 #define VARIANT_LP (VARIANT_LENGTH | VARIANT_PERCENT) 78 #define VARIANT_LN (VARIANT_LENGTH | VARIANT_NUMBER) 79 #define VARIANT_AH (VARIANT_AUTO | VARIANT_INHERIT) 80 #define VARIANT_AHLP (VARIANT_AH | VARIANT_LP) 81 #define VARIANT_AHI (VARIANT_AH | VARIANT_INTEGER) 82 #define VARIANT_AHK (VARIANT_AH | VARIANT_KEYWORD) 83 #define VARIANT_AHKLP (VARIANT_AHLP | VARIANT_KEYWORD) 84 #define VARIANT_AHL (VARIANT_AH | VARIANT_LENGTH) 85 #define VARIANT_AHKL (VARIANT_AHK | VARIANT_LENGTH) 86 #define VARIANT_HK (VARIANT_INHERIT | VARIANT_KEYWORD) 87 #define VARIANT_HKF (VARIANT_HK | VARIANT_FREQUENCY) 88 #define VARIANT_HKI (VARIANT_HK | VARIANT_INTEGER) 89 #define VARIANT_HKL (VARIANT_HK | VARIANT_LENGTH) 90 #define VARIANT_HKLP (VARIANT_HK | VARIANT_LP) 91 #define VARIANT_HKLPO (VARIANT_HKLP | VARIANT_NONE) 92 #define VARIANT_HL (VARIANT_INHERIT | VARIANT_LENGTH) 93 #define VARIANT_HI (VARIANT_INHERIT | VARIANT_INTEGER) 94 #define VARIANT_HLP (VARIANT_HL | VARIANT_PERCENT) 95 #define VARIANT_HLPN (VARIANT_HLP | VARIANT_NUMBER) 96 #define VARIANT_HLPO (VARIANT_HLP | VARIANT_NONE) 97 #define VARIANT_HTP (VARIANT_INHERIT | VARIANT_TIME | VARIANT_PERCENT) 98 #define VARIANT_HMK (VARIANT_HK | VARIANT_NORMAL) 99 #define VARIANT_HC (VARIANT_INHERIT | VARIANT_COLOR) 100 #define VARIANT_HCK (VARIANT_HK | VARIANT_COLOR) 101 #define VARIANT_HUK (VARIANT_HK | VARIANT_URL) 102 #define VARIANT_HUO (VARIANT_INHERIT | VARIANT_URL | VARIANT_NONE) 103 #define VARIANT_AHUO (VARIANT_AUTO | VARIANT_HUO) 104 #define VARIANT_HPN (VARIANT_INHERIT | VARIANT_PERCENT | VARIANT_NUMBER) 105 #define VARIANT_PN (VARIANT_PERCENT | VARIANT_NUMBER) 106 #define VARIANT_ALPN (VARIANT_AL | VARIANT_PN) 107 #define VARIANT_HN (VARIANT_INHERIT | VARIANT_NUMBER) 108 #define VARIANT_HON (VARIANT_HN | VARIANT_NONE) 109 #define VARIANT_HOS (VARIANT_INHERIT | VARIANT_NONE | VARIANT_STRING) 110 #define VARIANT_LPN (VARIANT_LP | VARIANT_NUMBER) 111 #define VARIANT_UK (VARIANT_URL | VARIANT_KEYWORD) 112 #define VARIANT_UO (VARIANT_URL | VARIANT_NONE) 113 #define VARIANT_ANGLE_OR_ZERO (VARIANT_ANGLE | VARIANT_ZERO_ANGLE) 114 #define VARIANT_LB (VARIANT_LENGTH | VARIANT_ABSOLUTE_DIMENSION) 115 #define VARIANT_LBCALC (VARIANT_LB | VARIANT_CALC) 116 #define VARIANT_LCALC (VARIANT_LENGTH | VARIANT_CALC) 117 #define VARIANT_LPCALC (VARIANT_LCALC | VARIANT_PERCENT) 118 #define VARIANT_LNCALC (VARIANT_LCALC | VARIANT_NUMBER) 119 #define VARIANT_LPNCALC (VARIANT_LNCALC | VARIANT_PERCENT) 120 #define VARIANT_IMAGE (VARIANT_URL | VARIANT_NONE | VARIANT_GRADIENT | \ 121 VARIANT_IMAGE_RECT | VARIANT_ELEMENT) 122 123 // Flags for the kFlagsTable bitfield (flags_ in nsCSSPropList.h) 124 125 // This property is a logical property (such as padding-inline-start). 126 #define CSS_PROPERTY_LOGICAL (1<<0) 127 128 #define CSS_PROPERTY_VALUE_LIST_USES_COMMAS (1<<1) /* otherwise spaces */ 129 130 #define CSS_PROPERTY_APPLIES_TO_FIRST_LETTER (1<<2) 131 #define CSS_PROPERTY_APPLIES_TO_FIRST_LINE (1<<3) 132 #define CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE \ 133 (CSS_PROPERTY_APPLIES_TO_FIRST_LETTER | CSS_PROPERTY_APPLIES_TO_FIRST_LINE) 134 135 // Note that 'background-color' is ignored differently from the other 136 // properties that have this set, but that's just special-cased. 137 #define CSS_PROPERTY_IGNORED_WHEN_COLORS_DISABLED (1<<4) 138 139 // A property that needs to have image loads started when a URL value 140 // for the property is used for an element. This is supported only 141 // for a few possible value formats: image directly in the value; list 142 // of images; and with CSS_PROPERTY_IMAGE_IS_IN_ARRAY_0, image in slot 143 // 0 of an array, or list of such arrays. 144 #define CSS_PROPERTY_START_IMAGE_LOADS (1<<5) 145 146 // Should be set only for properties with START_IMAGE_LOADS. Indicates 147 // that the property has an array value with a URL/image value at index 148 // 0 in the array, rather than the URL/image being in the value or value 149 // list. 150 #define CSS_PROPERTY_IMAGE_IS_IN_ARRAY_0 (1<<6) 151 152 // This is a logical property that represents some value associated with 153 // a logical axis rather than a logical box side, and thus has two 154 // corresponding physical properties it could set rather than four. For 155 // example, the block-size logical property has this flag set, as it 156 // represents the size in either the block or inline axis dimensions, and 157 // has two corresponding physical properties, width and height. Must not 158 // be used in conjunction with CSS_PROPERTY_LOGICAL_END_EDGE. 159 #define CSS_PROPERTY_LOGICAL_AXIS (1<<7) 160 161 // This property allows calc() between lengths and percentages and 162 // stores such calc() expressions in its style structs (typically in an 163 // nsStyleCoord, although this is not the case for 'background-position' 164 // and 'background-size'). 165 #define CSS_PROPERTY_STORES_CALC (1<<8) 166 167 // Define what mechanism the CSS parser uses for parsing the property. 168 // See CSSParserImpl::ParseProperty(nsCSSPropertyID). Don't use 0 so that 169 // we can verify that every property sets one of the values. 170 // 171 // CSS_PROPERTY_PARSE_FUNCTION must be used for shorthand properties, 172 // since it's the only mechanism that allows appending values for 173 // separate properties. Longhand properties that require custom parsing 174 // functions should prefer using CSS_PROPERTY_PARSE_VALUE (or 175 // CSS_PROPERTY_PARSE_VALUE_LIST) and 176 // CSS_PROPERTY_VALUE_PARSER_FUNCTION, though a number of existing 177 // longhand properties use CSS_PROPERTY_PARSE_FUNCTION instead. 178 #define CSS_PROPERTY_PARSE_PROPERTY_MASK (7<<9) 179 #define CSS_PROPERTY_PARSE_INACCESSIBLE (1<<9) 180 #define CSS_PROPERTY_PARSE_FUNCTION (2<<9) 181 #define CSS_PROPERTY_PARSE_VALUE (3<<9) 182 #define CSS_PROPERTY_PARSE_VALUE_LIST (4<<9) 183 184 // See CSSParserImpl::ParseSingleValueProperty and comment above 185 // CSS_PROPERTY_PARSE_FUNCTION (which is different). 186 #define CSS_PROPERTY_VALUE_PARSER_FUNCTION (1<<12) 187 static_assert((CSS_PROPERTY_PARSE_PROPERTY_MASK & 188 CSS_PROPERTY_VALUE_PARSER_FUNCTION) == 0, 189 "didn't leave enough room for the parse property constants"); 190 191 #define CSS_PROPERTY_VALUE_RESTRICTION_MASK (3<<13) 192 // The parser (in particular, CSSParserImpl::ParseSingleValueProperty) 193 // should enforce that the value of this property must be 0 or larger. 194 #define CSS_PROPERTY_VALUE_NONNEGATIVE (1<<13) 195 // The parser (in particular, CSSParserImpl::ParseSingleValueProperty) 196 // should enforce that the value of this property must be 1 or larger. 197 #define CSS_PROPERTY_VALUE_AT_LEAST_ONE (2<<13) 198 199 // Does this property support the hashless hex color quirk in quirks mode? 200 #define CSS_PROPERTY_HASHLESS_COLOR_QUIRK (1<<15) 201 202 // Does this property support the unitless length quirk in quirks mode? 203 #define CSS_PROPERTY_UNITLESS_LENGTH_QUIRK (1<<16) 204 205 // Is this property (which must be a shorthand) really an alias? 206 #define CSS_PROPERTY_IS_ALIAS (1<<17) 207 208 // Does the property apply to ::placeholder? 209 #define CSS_PROPERTY_APPLIES_TO_PLACEHOLDER (1<<18) 210 211 // This property is allowed in an @page rule. 212 #define CSS_PROPERTY_APPLIES_TO_PAGE_RULE (1<<19) 213 214 // This property's getComputedStyle implementation requires layout to be 215 // flushed. 216 #define CSS_PROPERTY_GETCS_NEEDS_LAYOUT_FLUSH (1<<20) 217 218 // This property requires a stacking context. 219 #define CSS_PROPERTY_CREATES_STACKING_CONTEXT (1<<21) 220 221 // The following two flags along with the pref defines where the this 222 // property can be used: 223 // * If none of the two flags is presented, the pref completely controls 224 // the availability of this property. And in that case, if it has no 225 // pref, this property is usable everywhere. 226 // * If any of the flags is set, this property is always enabled in the 227 // specific contexts regardless of the value of the pref. If there is 228 // no pref for this property at all in this case, it is an internal- 229 // only property, which cannot be used anywhere else, and should be 230 // wrapped in "#ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL". 231 // Note that, these flags have no effect on the use of aliases of this 232 // property. 233 // Furthermore, for the purposes of animation (including triggering 234 // transitions) these flags are ignored. That is, if the property is disabled 235 // by a pref, we will *not* run animations or transitions on it even in 236 // UA sheets or chrome. 237 #define CSS_PROPERTY_ENABLED_MASK (3<<22) 238 #define CSS_PROPERTY_ENABLED_IN_UA_SHEETS (1<<22) 239 #define CSS_PROPERTY_ENABLED_IN_CHROME (1<<23) 240 #define CSS_PROPERTY_ENABLED_IN_UA_SHEETS_AND_CHROME \ 241 (CSS_PROPERTY_ENABLED_IN_UA_SHEETS | CSS_PROPERTY_ENABLED_IN_CHROME) 242 243 // This property's unitless values are pixels. 244 #define CSS_PROPERTY_NUMBERS_ARE_PIXELS (1<<24) 245 246 // This property is a logical property for one of the two block axis 247 // sides (such as margin-block-start or margin-block-end). Must only be 248 // set if CSS_PROPERTY_LOGICAL is set. When not set, the logical 249 // property is for one of the two inline axis sides (such as 250 // margin-inline-start or margin-inline-end). 251 #define CSS_PROPERTY_LOGICAL_BLOCK_AXIS (1<<25) 252 253 // This property is a logical property for the "end" edge of the 254 // axis determined by the presence or absence of 255 // CSS_PROPERTY_LOGICAL_BLOCK_AXIS (such as margin-block-end or 256 // margin-inline-end). Must only be set if CSS_PROPERTY_LOGICAL is set. 257 // When not set, the logical property is for the "start" edge (such as 258 // margin-block-start or margin-inline-start). 259 #define CSS_PROPERTY_LOGICAL_END_EDGE (1<<26) 260 261 // This property can be animated on the compositor. 262 #define CSS_PROPERTY_CAN_ANIMATE_ON_COMPOSITOR (1<<27) 263 264 // This property is an internal property that is not represented 265 // in the DOM. Properties with this flag must be defined in an #ifndef 266 // CSS_PROP_LIST_EXCLUDE_INTERNAL section of nsCSSPropList.h. 267 #define CSS_PROPERTY_INTERNAL (1<<28) 268 269 // This property has values that can establish a containing block for 270 // fixed positioned and absolutely positioned elements. 271 // This should be set for any properties that can cause an element to be 272 // such a containing block, as implemented in 273 // nsStyleDisplay::IsFixedPosContainingBlock. 274 #define CSS_PROPERTY_FIXPOS_CB (1<<29) 275 276 // This property has values that can establish a containing block for 277 // absolutely positioned elements. 278 // This should be set for any properties that can cause an element to be 279 // such a containing block, as implemented in 280 // nsStyleDisplay::IsAbsPosContainingBlock. 281 // It does not need to be set for properties that also have 282 // CSS_PROPERTY_FIXPOS_CB set. 283 #define CSS_PROPERTY_ABSPOS_CB (1<<30) 284 285 /** 286 * Types of animatable values. 287 */ 288 enum nsStyleAnimType { 289 // requires a custom implementation in 290 // StyleAnimationValue::ExtractComputedValue 291 eStyleAnimType_Custom, 292 293 // nsStyleCoord with animatable values 294 eStyleAnimType_Coord, 295 296 // same as Coord, except for one side of an nsStyleSides 297 // listed in the same order as the NS_STYLE_* constants 298 eStyleAnimType_Sides_Top, 299 eStyleAnimType_Sides_Right, 300 eStyleAnimType_Sides_Bottom, 301 eStyleAnimType_Sides_Left, 302 303 // similar, but for the *pair* of coord members of an nsStyleCorners 304 // for the relevant corner 305 eStyleAnimType_Corner_TopLeft, 306 eStyleAnimType_Corner_TopRight, 307 eStyleAnimType_Corner_BottomRight, 308 eStyleAnimType_Corner_BottomLeft, 309 310 // nscoord values 311 eStyleAnimType_nscoord, 312 313 // float values 314 eStyleAnimType_float, 315 316 // nscolor values 317 eStyleAnimType_Color, 318 319 // StyleComplexColor values 320 eStyleAnimType_ComplexColor, 321 322 // nsStyleSVGPaint values 323 eStyleAnimType_PaintServer, 324 325 // RefPtr<nsCSSShadowArray> values 326 eStyleAnimType_Shadow, 327 328 // discrete values 329 eStyleAnimType_Discrete, 330 331 // property not animatable 332 eStyleAnimType_None 333 }; 334 335 // Empty class derived from nsIAtom so that function signatures can 336 // require an atom from the atom list. 337 class nsICSSProperty : public nsIAtom {}; 338 339 class nsCSSProps { 340 public: 341 typedef mozilla::CSSEnabledState EnabledState; 342 343 struct KTableEntry 344 { 345 // KTableEntry objects can be initialized either with an int16_t value 346 // or a value of an enumeration type that can fit within an int16_t. 347 KTableEntryKTableEntry348 constexpr KTableEntry(nsCSSKeyword aKeyword, int16_t aValue) 349 : mKeyword(aKeyword) 350 , mValue(aValue) 351 { 352 } 353 354 template<typename T, 355 typename = typename std::enable_if<std::is_enum<T>::value>::type> KTableEntryKTableEntry356 constexpr KTableEntry(nsCSSKeyword aKeyword, T aValue) 357 : mKeyword(aKeyword) 358 , mValue(static_cast<int16_t>(aValue)) 359 { 360 static_assert(mozilla::EnumTypeFitsWithin<T, int16_t>::value, 361 "aValue must be an enum that fits within mValue"); 362 } 363 364 nsCSSKeyword mKeyword; 365 int16_t mValue; 366 }; 367 368 static void AddRefTable(void); 369 static void ReleaseTable(void); 370 371 // Looks up the property with name aProperty and returns its corresponding 372 // nsCSSPropertyID value. If aProperty is the name of a custom property, 373 // then eCSSPropertyExtra_variable will be returned. 374 static nsCSSPropertyID LookupProperty(const nsAString& aProperty, 375 EnabledState aEnabled); 376 static nsCSSPropertyID LookupProperty(const nsACString& aProperty, 377 EnabledState aEnabled); 378 // As above, but looked up using a property's IDL name. 379 // eCSSPropertyExtra_variable won't be returned from these methods. 380 static nsCSSPropertyID LookupPropertyByIDLName( 381 const nsAString& aPropertyIDLName, 382 EnabledState aEnabled); 383 static nsCSSPropertyID LookupPropertyByIDLName( 384 const nsACString& aPropertyIDLName, 385 EnabledState aEnabled); 386 387 // Returns whether aProperty is a custom property name, i.e. begins with 388 // "--". This assumes that the CSS Variables pref has been enabled. 389 static bool IsCustomPropertyName(const nsAString& aProperty); 390 static bool IsCustomPropertyName(const nsACString& aProperty); 391 IsShorthand(nsCSSPropertyID aProperty)392 static inline bool IsShorthand(nsCSSPropertyID aProperty) { 393 MOZ_ASSERT(0 <= aProperty && aProperty < eCSSProperty_COUNT, 394 "out of range"); 395 return (aProperty >= eCSSProperty_COUNT_no_shorthands); 396 } 397 398 // Must be given a longhand property. 399 static bool IsInherited(nsCSSPropertyID aProperty); 400 401 // Same but for @font-face descriptors 402 static nsCSSFontDesc LookupFontDesc(const nsAString& aProperty); 403 static nsCSSFontDesc LookupFontDesc(const nsACString& aProperty); 404 405 // For @counter-style descriptors 406 static nsCSSCounterDesc LookupCounterDesc(const nsAString& aProperty); 407 static nsCSSCounterDesc LookupCounterDesc(const nsACString& aProperty); 408 409 // For predefined counter styles which need to be lower-cased during parse 410 static bool IsPredefinedCounterStyle(const nsAString& aStyle); 411 static bool IsPredefinedCounterStyle(const nsACString& aStyle); 412 413 // Given a property enum, get the string value 414 static const nsAFlatCString& GetStringValue(nsCSSPropertyID aProperty); 415 static const nsAFlatCString& GetStringValue(nsCSSFontDesc aFontDesc); 416 static const nsAFlatCString& GetStringValue(nsCSSCounterDesc aCounterDesc); 417 418 // Given a CSS Property and a Property Enum Value 419 // Return back a const nsString& representation of the 420 // value. Return back nullstr if no value is found 421 static const nsAFlatCString& LookupPropertyValue(nsCSSPropertyID aProperty, int32_t aValue); 422 423 // Get a color name for a predefined color value like buttonhighlight or activeborder 424 // Sets the aStr param to the name of the propertyID 425 static bool GetColorName(int32_t aPropID, nsCString &aStr); 426 427 // Returns the index of |aKeyword| in |aTable|, if it exists there; 428 // otherwise, returns -1. 429 // NOTE: Generally, clients should call FindKeyword() instead of this method. 430 static int32_t FindIndexOfKeyword(nsCSSKeyword aKeyword, 431 const KTableEntry aTable[]); 432 433 // Find |aKeyword| in |aTable|, if found set |aValue| to its corresponding value. 434 // If not found, return false and do not set |aValue|. 435 static bool FindKeyword(nsCSSKeyword aKeyword, const KTableEntry aTable[], 436 int32_t& aValue); 437 // Return the first keyword in |aTable| that has the corresponding value |aValue|. 438 // Return |eCSSKeyword_UNKNOWN| if not found. 439 static nsCSSKeyword ValueToKeywordEnum(int32_t aValue, 440 const KTableEntry aTable[]); 441 template<typename T, 442 typename = typename std::enable_if<std::is_enum<T>::value>::type> ValueToKeywordEnum(T aValue,const KTableEntry aTable[])443 static nsCSSKeyword ValueToKeywordEnum(T aValue, 444 const KTableEntry aTable[]) 445 { 446 static_assert(mozilla::EnumTypeFitsWithin<T, int16_t>::value, 447 "aValue must be an enum that fits within KTableEntry::mValue"); 448 return ValueToKeywordEnum(static_cast<int16_t>(aValue), aTable); 449 } 450 // Ditto but as a string, return "" when not found. 451 static const nsAFlatCString& ValueToKeyword(int32_t aValue, 452 const KTableEntry aTable[]); 453 template<typename T, 454 typename = typename std::enable_if<std::is_enum<T>::value>::type> ValueToKeyword(T aValue,const KTableEntry aTable[])455 static const nsAFlatCString& ValueToKeyword(T aValue, 456 const KTableEntry aTable[]) 457 { 458 static_assert(mozilla::EnumTypeFitsWithin<T, int16_t>::value, 459 "aValue must be an enum that fits within KTableEntry::mValue"); 460 return ValueToKeyword(static_cast<int16_t>(aValue), aTable); 461 } 462 463 static const nsStyleStructID kSIDTable[eCSSProperty_COUNT_no_shorthands]; 464 static const KTableEntry* const kKeywordTableTable[eCSSProperty_COUNT_no_shorthands]; 465 static const nsStyleAnimType kAnimTypeTable[eCSSProperty_COUNT_no_shorthands]; 466 static const ptrdiff_t 467 kStyleStructOffsetTable[eCSSProperty_COUNT_no_shorthands]; 468 469 private: 470 static const uint32_t kFlagsTable[eCSSProperty_COUNT]; 471 472 public: PropHasFlags(nsCSSPropertyID aProperty,uint32_t aFlags)473 static inline bool PropHasFlags(nsCSSPropertyID aProperty, uint32_t aFlags) 474 { 475 MOZ_ASSERT(0 <= aProperty && aProperty < eCSSProperty_COUNT, 476 "out of range"); 477 MOZ_ASSERT(!(aFlags & CSS_PROPERTY_PARSE_PROPERTY_MASK), 478 "The CSS_PROPERTY_PARSE_* values are not bitflags; don't pass " 479 "them to PropHasFlags. You probably want PropertyParseType " 480 "instead."); 481 return (nsCSSProps::kFlagsTable[aProperty] & aFlags) == aFlags; 482 } 483 PropertyParseType(nsCSSPropertyID aProperty)484 static inline uint32_t PropertyParseType(nsCSSPropertyID aProperty) 485 { 486 MOZ_ASSERT(0 <= aProperty && aProperty < eCSSProperty_COUNT, 487 "out of range"); 488 return nsCSSProps::kFlagsTable[aProperty] & 489 CSS_PROPERTY_PARSE_PROPERTY_MASK; 490 } 491 ValueRestrictions(nsCSSPropertyID aProperty)492 static inline uint32_t ValueRestrictions(nsCSSPropertyID aProperty) 493 { 494 MOZ_ASSERT(0 <= aProperty && aProperty < eCSSProperty_COUNT, 495 "out of range"); 496 return nsCSSProps::kFlagsTable[aProperty] & 497 CSS_PROPERTY_VALUE_RESTRICTION_MASK; 498 } 499 500 private: 501 // Lives in nsCSSParser.cpp for the macros it depends on. 502 static const uint32_t kParserVariantTable[eCSSProperty_COUNT_no_shorthands]; 503 504 public: ParserVariant(nsCSSPropertyID aProperty)505 static inline uint32_t ParserVariant(nsCSSPropertyID aProperty) { 506 MOZ_ASSERT(0 <= aProperty && aProperty < eCSSProperty_COUNT_no_shorthands, 507 "out of range"); 508 return nsCSSProps::kParserVariantTable[aProperty]; 509 } 510 511 private: 512 // A table for shorthand properties. The appropriate index is the 513 // property ID minus eCSSProperty_COUNT_no_shorthands. 514 static const nsCSSPropertyID *const 515 kSubpropertyTable[eCSSProperty_COUNT - eCSSProperty_COUNT_no_shorthands]; 516 517 public: 518 static inline SubpropertyEntryFor(nsCSSPropertyID aProperty)519 const nsCSSPropertyID * SubpropertyEntryFor(nsCSSPropertyID aProperty) { 520 MOZ_ASSERT(eCSSProperty_COUNT_no_shorthands <= aProperty && 521 aProperty < eCSSProperty_COUNT, 522 "out of range"); 523 return nsCSSProps::kSubpropertyTable[aProperty - 524 eCSSProperty_COUNT_no_shorthands]; 525 } 526 527 // Returns an eCSSProperty_UNKNOWN-terminated array of the shorthand 528 // properties containing |aProperty|, sorted from those that contain 529 // the most properties to those that contain the least. ShorthandsContaining(nsCSSPropertyID aProperty)530 static const nsCSSPropertyID * ShorthandsContaining(nsCSSPropertyID aProperty) { 531 MOZ_ASSERT(gShorthandsContainingPool, "uninitialized"); 532 MOZ_ASSERT(0 <= aProperty && aProperty < eCSSProperty_COUNT_no_shorthands, 533 "out of range"); 534 return gShorthandsContainingTable[aProperty]; 535 } 536 private: 537 // gShorthandsContainingTable is an array of the return values for 538 // ShorthandsContaining (arrays of nsCSSPropertyID terminated by 539 // eCSSProperty_UNKNOWN) pointing into memory in 540 // gShorthandsContainingPool (which contains all of those arrays in a 541 // single allocation, and is the one pointer that should be |free|d). 542 static nsCSSPropertyID *gShorthandsContainingTable[eCSSProperty_COUNT_no_shorthands]; 543 static nsCSSPropertyID* gShorthandsContainingPool; 544 static bool BuildShorthandsContainingTable(); 545 546 private: 547 static const size_t gPropertyCountInStruct[nsStyleStructID_Length]; 548 static const size_t gPropertyIndexInStruct[eCSSProperty_COUNT_no_shorthands]; 549 public: 550 /** 551 * Return the number of properties that must be cascaded when 552 * nsRuleNode builds the nsStyle* for aSID. 553 */ PropertyCountInStruct(nsStyleStructID aSID)554 static size_t PropertyCountInStruct(nsStyleStructID aSID) { 555 MOZ_ASSERT(0 <= aSID && aSID < nsStyleStructID_Length, 556 "out of range"); 557 return gPropertyCountInStruct[aSID]; 558 } 559 /** 560 * Return an index for aProperty that is unique within its SID and in 561 * the range 0 <= index < PropertyCountInStruct(aSID). 562 */ PropertyIndexInStruct(nsCSSPropertyID aProperty)563 static size_t PropertyIndexInStruct(nsCSSPropertyID aProperty) { 564 MOZ_ASSERT(0 <= aProperty && aProperty < eCSSProperty_COUNT_no_shorthands, 565 "out of range"); 566 return gPropertyIndexInStruct[aProperty]; 567 } 568 569 private: 570 // A table for logical property groups. Indexes are 571 // nsCSSPropertyLogicalGroup values. 572 static const nsCSSPropertyID* const 573 kLogicalGroupTable[eCSSPropertyLogicalGroup_COUNT]; 574 575 public: 576 /** 577 * Returns an array of longhand physical properties which can be set by 578 * the argument, which must be a logical longhand property. The returned 579 * array is terminated by an eCSSProperty_UNKNOWN value. For example, 580 * given eCSSProperty_margin_block_start, returns an array of the four 581 * properties eCSSProperty_margin_top, eCSSProperty_margin_right, 582 * eCSSProperty_margin_bottom and eCSSProperty_margin_left, followed 583 * by the sentinel. 584 * 585 * When called with a property that has the CSS_PROPERTY_LOGICAL_AXIS 586 * flag, the returned array will have two values preceding the sentinel; 587 * otherwise it will have four. 588 * 589 * (Note that the running time of this function is proportional to the 590 * number of logical longhand properties that exist. If we start 591 * getting too many of these properties, we should make kLogicalGroupTable 592 * be a simple array of eCSSProperty_COUNT length.) 593 */ 594 static const nsCSSPropertyID* LogicalGroup(nsCSSPropertyID aProperty); 595 596 private: 597 static bool gPropertyEnabled[eCSSProperty_COUNT_with_aliases]; 598 599 private: 600 // Defined in the generated nsCSSPropsGenerated.inc. 601 static const char* const kIDLNameTable[eCSSProperty_COUNT]; 602 603 public: 604 /** 605 * Returns the IDL name of the specified property, which must be a 606 * longhand, logical or shorthand property. The IDL name is the property 607 * name with any hyphen-lowercase character pairs replaced by an 608 * uppercase character: 609 * https://drafts.csswg.org/cssom/#css-property-to-idl-attribute 610 * 611 * As a special case, the string "cssFloat" is returned for the float 612 * property. nullptr is returned for internal properties. 613 */ PropertyIDLName(nsCSSPropertyID aProperty)614 static const char* PropertyIDLName(nsCSSPropertyID aProperty) 615 { 616 MOZ_ASSERT(0 <= aProperty && aProperty < eCSSProperty_COUNT, 617 "out of range"); 618 return kIDLNameTable[aProperty]; 619 } 620 621 private: 622 static const int32_t kIDLNameSortPositionTable[eCSSProperty_COUNT]; 623 624 public: 625 /** 626 * Returns the position of the specified property in a list of all 627 * properties sorted by their IDL name. 628 */ PropertyIDLNameSortPosition(nsCSSPropertyID aProperty)629 static int32_t PropertyIDLNameSortPosition(nsCSSPropertyID aProperty) 630 { 631 MOZ_ASSERT(0 <= aProperty && aProperty < eCSSProperty_COUNT, 632 "out of range"); 633 return kIDLNameSortPositionTable[aProperty]; 634 } 635 IsEnabled(nsCSSPropertyID aProperty)636 static bool IsEnabled(nsCSSPropertyID aProperty) { 637 MOZ_ASSERT(0 <= aProperty && aProperty < eCSSProperty_COUNT_with_aliases, 638 "out of range"); 639 return gPropertyEnabled[aProperty]; 640 } 641 642 // A table for the use counter associated with each CSS property. If a 643 // property does not have a use counter defined in UseCounters.conf, then 644 // its associated entry is |eUseCounter_UNKNOWN|. 645 static const mozilla::UseCounter gPropertyUseCounter[eCSSProperty_COUNT_no_shorthands]; 646 647 public: 648 UseCounterFor(nsCSSPropertyID aProperty)649 static mozilla::UseCounter UseCounterFor(nsCSSPropertyID aProperty) { 650 MOZ_ASSERT(0 <= aProperty && aProperty < eCSSProperty_COUNT_no_shorthands, 651 "out of range"); 652 return gPropertyUseCounter[aProperty]; 653 } 654 IsEnabled(nsCSSPropertyID aProperty,EnabledState aEnabled)655 static bool IsEnabled(nsCSSPropertyID aProperty, EnabledState aEnabled) 656 { 657 if (IsEnabled(aProperty)) { 658 return true; 659 } 660 if (aEnabled == EnabledState::eIgnoreEnabledState) { 661 return true; 662 } 663 if ((aEnabled & EnabledState::eInUASheets) && 664 PropHasFlags(aProperty, CSS_PROPERTY_ENABLED_IN_UA_SHEETS)) 665 { 666 return true; 667 } 668 if ((aEnabled & EnabledState::eInChrome) && 669 PropHasFlags(aProperty, CSS_PROPERTY_ENABLED_IN_CHROME)) 670 { 671 return true; 672 } 673 return false; 674 } 675 676 public: 677 static void AddRefAtoms(); AtomForProperty(nsCSSPropertyID aProperty)678 static nsICSSProperty* AtomForProperty(nsCSSPropertyID aProperty) 679 { 680 MOZ_ASSERT(0 <= aProperty && aProperty < eCSSProperty_COUNT); 681 return gPropertyAtomTable[aProperty]; 682 } 683 684 #define CSS_PROP(name_, id_, ...) static nsICSSProperty* id_; 685 #define CSS_PROP_SHORTHAND(name_, id_, ...) CSS_PROP(name_, id_, ...) 686 #define CSS_PROP_LIST_INCLUDE_LOGICAL 687 #include "nsCSSPropList.h" 688 #undef CSS_PROP_LIST_INCLUDE_LOGICAL 689 #undef CSS_PROP_SHORTHAND 690 #undef CSS_PROP 691 692 private: 693 static nsICSSProperty* gPropertyAtomTable[eCSSProperty_COUNT]; 694 695 public: 696 697 // Storing the enabledstate_ value in an nsCSSPropertyID variable is a small hack 698 // to avoid needing a separate variable declaration for its real type 699 // (CSSEnabledState), which would then require using a block and 700 // therefore a pair of macros by consumers for the start and end of the loop. 701 #define CSSPROPS_FOR_SHORTHAND_SUBPROPERTIES(it_, prop_, enabledstate_) \ 702 for (const nsCSSPropertyID *it_ = nsCSSProps::SubpropertyEntryFor(prop_), \ 703 es_ = (nsCSSPropertyID)((enabledstate_) | \ 704 CSSEnabledState(0)); \ 705 *it_ != eCSSProperty_UNKNOWN; ++it_) \ 706 if (nsCSSProps::IsEnabled(*it_, (mozilla::CSSEnabledState) es_)) 707 708 // Keyword/Enum value tables 709 static const KTableEntry kAnimationDirectionKTable[]; 710 static const KTableEntry kAnimationFillModeKTable[]; 711 static const KTableEntry kAnimationIterationCountKTable[]; 712 static const KTableEntry kAnimationPlayStateKTable[]; 713 static const KTableEntry kAnimationTimingFunctionKTable[]; 714 static const KTableEntry kAppearanceKTable[]; 715 static const KTableEntry kAzimuthKTable[]; 716 static const KTableEntry kBackfaceVisibilityKTable[]; 717 static const KTableEntry kTransformStyleKTable[]; 718 static const KTableEntry kImageLayerAttachmentKTable[]; 719 static const KTableEntry kImageLayerOriginKTable[]; 720 static const KTableEntry kImageLayerPositionKTable[]; 721 static const KTableEntry kImageLayerRepeatKTable[]; 722 static const KTableEntry kImageLayerRepeatPartKTable[]; 723 static const KTableEntry kImageLayerSizeKTable[]; 724 static const KTableEntry kImageLayerCompositeKTable[]; 725 static const KTableEntry kImageLayerModeKTable[]; 726 // Not const because we modify its entries when the pref 727 // "layout.css.background-clip.text" changes: 728 static KTableEntry kBackgroundClipKTable[]; 729 static const KTableEntry kBlendModeKTable[]; 730 static const KTableEntry kBorderCollapseKTable[]; 731 static const KTableEntry kBorderImageRepeatKTable[]; 732 static const KTableEntry kBorderImageSliceKTable[]; 733 static const KTableEntry kBorderStyleKTable[]; 734 static const KTableEntry kBorderWidthKTable[]; 735 static const KTableEntry kBoxAlignKTable[]; 736 static const KTableEntry kBoxDecorationBreakKTable[]; 737 static const KTableEntry kBoxDirectionKTable[]; 738 static const KTableEntry kBoxOrientKTable[]; 739 static const KTableEntry kBoxPackKTable[]; 740 static const KTableEntry kClipPathGeometryBoxKTable[]; 741 static const KTableEntry kCounterRangeKTable[]; 742 static const KTableEntry kCounterSpeakAsKTable[]; 743 static const KTableEntry kCounterSymbolsSystemKTable[]; 744 static const KTableEntry kCounterSystemKTable[]; 745 static const KTableEntry kDominantBaselineKTable[]; 746 static const KTableEntry kShapeRadiusKTable[]; 747 static const KTableEntry kFillRuleKTable[]; 748 static const KTableEntry kFilterFunctionKTable[]; 749 static const KTableEntry kImageRenderingKTable[]; 750 static const KTableEntry kShapeOutsideShapeBoxKTable[]; 751 static const KTableEntry kShapeRenderingKTable[]; 752 static const KTableEntry kStrokeLinecapKTable[]; 753 static const KTableEntry kStrokeLinejoinKTable[]; 754 static const KTableEntry kStrokeContextValueKTable[]; 755 static const KTableEntry kVectorEffectKTable[]; 756 static const KTableEntry kTextAnchorKTable[]; 757 static const KTableEntry kTextRenderingKTable[]; 758 static const KTableEntry kColorAdjustKTable[]; 759 static const KTableEntry kColorInterpolationKTable[]; 760 static const KTableEntry kColumnFillKTable[]; 761 static const KTableEntry kBoxPropSourceKTable[]; 762 static const KTableEntry kBoxShadowTypeKTable[]; 763 static const KTableEntry kBoxSizingKTable[]; 764 static const KTableEntry kCaptionSideKTable[]; 765 // Not const because we modify its entries when the pref 766 // "layout.css.float-logical-values.enabled" changes: 767 static KTableEntry kClearKTable[]; 768 static const KTableEntry kColorKTable[]; 769 static const KTableEntry kContentKTable[]; 770 static const KTableEntry kControlCharacterVisibilityKTable[]; 771 static const KTableEntry kCursorKTable[]; 772 static const KTableEntry kDirectionKTable[]; 773 // Not const because we modify its entries when various 774 // "layout.css.*.enabled" prefs changes: 775 static KTableEntry kDisplayKTable[]; 776 static const KTableEntry kElevationKTable[]; 777 static const KTableEntry kEmptyCellsKTable[]; 778 // -- tables for parsing the {align,justify}-{content,items,self} properties -- 779 static const KTableEntry kAlignAllKeywords[]; 780 static const KTableEntry kAlignOverflowPosition[]; // <overflow-position> 781 static const KTableEntry kAlignSelfPosition[]; // <self-position> 782 static const KTableEntry kAlignLegacy[]; // 'legacy' 783 static const KTableEntry kAlignLegacyPosition[]; // 'left/right/center' 784 static const KTableEntry kAlignAutoNormalStretchBaseline[]; // 'auto/normal/stretch/baseline' 785 static const KTableEntry kAlignNormalStretchBaseline[]; // 'normal/stretch/baseline' 786 static const KTableEntry kAlignNormalBaseline[]; // 'normal/baseline' 787 static const KTableEntry kAlignContentDistribution[]; // <content-distribution> 788 static const KTableEntry kAlignContentPosition[]; // <content-position> 789 // -- tables for auto-completion of the {align,justify}-{content,items,self} properties -- 790 static const KTableEntry kAutoCompletionAlignJustifySelf[]; 791 static const KTableEntry kAutoCompletionAlignItems[]; 792 static const KTableEntry kAutoCompletionAlignJustifyContent[]; 793 // ------------------------------------------------------------------ 794 static const KTableEntry kFlexDirectionKTable[]; 795 static const KTableEntry kFlexWrapKTable[]; 796 // Not const because we modify its entries when the pref 797 // "layout.css.float-logical-values.enabled" changes: 798 static KTableEntry kFloatKTable[]; 799 static const KTableEntry kFloatEdgeKTable[]; 800 static const KTableEntry kFontDisplayKTable[]; 801 static const KTableEntry kFontKTable[]; 802 static const KTableEntry kFontKerningKTable[]; 803 static const KTableEntry kFontSizeKTable[]; 804 static const KTableEntry kFontSmoothingKTable[]; 805 static const KTableEntry kFontStretchKTable[]; 806 static const KTableEntry kFontStyleKTable[]; 807 static const KTableEntry kFontSynthesisKTable[]; 808 static const KTableEntry kFontVariantKTable[]; 809 static const KTableEntry kFontVariantAlternatesKTable[]; 810 static const KTableEntry kFontVariantAlternatesFuncsKTable[]; 811 static const KTableEntry kFontVariantCapsKTable[]; 812 static const KTableEntry kFontVariantEastAsianKTable[]; 813 static const KTableEntry kFontVariantLigaturesKTable[]; 814 static const KTableEntry kFontVariantNumericKTable[]; 815 static const KTableEntry kFontVariantPositionKTable[]; 816 static const KTableEntry kFontWeightKTable[]; 817 static const KTableEntry kGridAutoFlowKTable[]; 818 static const KTableEntry kGridTrackBreadthKTable[]; 819 static const KTableEntry kHyphensKTable[]; 820 static const KTableEntry kImageOrientationKTable[]; 821 static const KTableEntry kImageOrientationFlipKTable[]; 822 static const KTableEntry kIsolationKTable[]; 823 static const KTableEntry kIMEModeKTable[]; 824 static const KTableEntry kLineHeightKTable[]; 825 static const KTableEntry kListStylePositionKTable[]; 826 static const KTableEntry kListStyleKTable[]; 827 static const KTableEntry kMaskTypeKTable[]; 828 static const KTableEntry kMathVariantKTable[]; 829 static const KTableEntry kMathDisplayKTable[]; 830 static const KTableEntry kContainKTable[]; 831 static const KTableEntry kContextOpacityKTable[]; 832 static const KTableEntry kContextPatternKTable[]; 833 static const KTableEntry kObjectFitKTable[]; 834 static const KTableEntry kOrientKTable[]; 835 static const KTableEntry kOutlineStyleKTable[]; 836 static const KTableEntry kOverflowKTable[]; 837 static const KTableEntry kOverflowSubKTable[]; 838 static const KTableEntry kOverflowClipBoxKTable[]; 839 static const KTableEntry kOverflowWrapKTable[]; 840 static const KTableEntry kPageBreakKTable[]; 841 static const KTableEntry kPageBreakInsideKTable[]; 842 static const KTableEntry kPageMarksKTable[]; 843 static const KTableEntry kPageSizeKTable[]; 844 static const KTableEntry kPitchKTable[]; 845 static const KTableEntry kPointerEventsKTable[]; 846 static const KTableEntry kPositionKTable[]; 847 static const KTableEntry kRadialGradientShapeKTable[]; 848 static const KTableEntry kRadialGradientSizeKTable[]; 849 static const KTableEntry kRadialGradientLegacySizeKTable[]; 850 static const KTableEntry kResizeKTable[]; 851 static const KTableEntry kRubyAlignKTable[]; 852 static const KTableEntry kRubyPositionKTable[]; 853 static const KTableEntry kScrollBehaviorKTable[]; 854 static const KTableEntry kScrollSnapTypeKTable[]; 855 static const KTableEntry kSpeakKTable[]; 856 static const KTableEntry kSpeakHeaderKTable[]; 857 static const KTableEntry kSpeakNumeralKTable[]; 858 static const KTableEntry kSpeakPunctuationKTable[]; 859 static const KTableEntry kSpeechRateKTable[]; 860 static const KTableEntry kStackSizingKTable[]; 861 static const KTableEntry kTableLayoutKTable[]; 862 // Not const because we modify its entries when the pref 863 // "layout.css.text-align-unsafe-value.enabled" changes: 864 static KTableEntry kTextAlignKTable[]; 865 static KTableEntry kTextAlignLastKTable[]; 866 static const KTableEntry kTextCombineUprightKTable[]; 867 static const KTableEntry kTextDecorationLineKTable[]; 868 static const KTableEntry kTextDecorationStyleKTable[]; 869 static const KTableEntry kTextEmphasisPositionKTable[]; 870 static const KTableEntry kTextEmphasisStyleFillKTable[]; 871 static const KTableEntry kTextEmphasisStyleShapeKTable[]; 872 static const KTableEntry kTextOrientationKTable[]; 873 static const KTableEntry kTextOverflowKTable[]; 874 static const KTableEntry kTextTransformKTable[]; 875 static const KTableEntry kTouchActionKTable[]; 876 static const KTableEntry kTopLayerKTable[]; 877 static const KTableEntry kTransformBoxKTable[]; 878 static const KTableEntry kTransitionTimingFunctionKTable[]; 879 static const KTableEntry kUnicodeBidiKTable[]; 880 static const KTableEntry kUserFocusKTable[]; 881 static const KTableEntry kUserInputKTable[]; 882 static const KTableEntry kUserModifyKTable[]; 883 static const KTableEntry kUserSelectKTable[]; 884 static const KTableEntry kVerticalAlignKTable[]; 885 static const KTableEntry kVisibilityKTable[]; 886 static const KTableEntry kVolumeKTable[]; 887 static const KTableEntry kWhitespaceKTable[]; 888 static const KTableEntry kWidthKTable[]; // also min-width, max-width 889 static const KTableEntry kWindowDraggingKTable[]; 890 static const KTableEntry kWindowShadowKTable[]; 891 static const KTableEntry kWordBreakKTable[]; 892 static const KTableEntry kWritingModeKTable[]; 893 }; 894 895 #endif /* nsCSSProps_h___ */ 896