Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/layout/style/nsCSSProps.h
Line
Count
Source (jump to first uncovered line)
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 <limits>
16
#include <type_traits>
17
#include "nsString.h"
18
#include "nsCSSPropertyID.h"
19
#include "nsStyleStructFwd.h"
20
#include "nsCSSKeywords.h"
21
#include "mozilla/CSSEnabledState.h"
22
#include "mozilla/CSSPropFlags.h"
23
#include "mozilla/UseCounter.h"
24
#include "mozilla/EnumTypeTraits.h"
25
#include "mozilla/Preferences.h"
26
#include "nsXULAppAPI.h"
27
28
// Length of the "--" prefix on custom names (such as custom property names,
29
// and, in the future, custom media query names).
30
0
#define CSS_CUSTOM_NAME_PREFIX_LENGTH 2
31
32
namespace mozilla {
33
class ComputedStyle;
34
}
35
36
extern "C" {
37
  nsCSSPropertyID Servo_ResolveLogicalProperty(nsCSSPropertyID,
38
                                               const mozilla::ComputedStyle*);
39
  nsCSSPropertyID Servo_Property_LookupEnabledForAllContent(const nsACString*);
40
  const uint8_t* Servo_Property_GetName(nsCSSPropertyID, uint32_t* aLength);
41
}
42
43
struct nsCSSKTableEntry
44
{
45
  // nsCSSKTableEntry objects can be initialized either with an int16_t value
46
  // or a value of an enumeration type that can fit within an int16_t.
47
48
  constexpr nsCSSKTableEntry(nsCSSKeyword aKeyword, int16_t aValue)
49
    : mKeyword(aKeyword)
50
    , mValue(aValue)
51
0
  {
52
0
  }
53
54
  template<typename T,
55
           typename = typename std::enable_if<std::is_enum<T>::value>::type>
56
  constexpr nsCSSKTableEntry(nsCSSKeyword aKeyword, T aValue)
57
    : mKeyword(aKeyword)
58
    , mValue(static_cast<int16_t>(aValue))
59
  {
60
    static_assert(mozilla::EnumTypeFitsWithin<T, int16_t>::value,
61
                  "aValue must be an enum that fits within mValue");
62
  }
63
64
  bool IsSentinel() const
65
0
  {
66
0
    return mKeyword == eCSSKeyword_UNKNOWN && mValue == -1;
67
0
  }
68
69
  nsCSSKeyword mKeyword;
70
  int16_t mValue;
71
};
72
73
class nsCSSProps {
74
public:
75
  typedef mozilla::CSSEnabledState EnabledState;
76
  typedef mozilla::CSSPropFlags Flags;
77
  typedef nsCSSKTableEntry KTableEntry;
78
79
  static void AddRefTable(void);
80
  static void ReleaseTable(void);
81
82
  // Looks up the property with name aProperty and returns its corresponding
83
  // nsCSSPropertyID value.  If aProperty is the name of a custom property,
84
  // then eCSSPropertyExtra_variable will be returned.
85
  //
86
  // This only returns properties enabled for all content, and resolves aliases
87
  // to return the aliased property.
88
  static nsCSSPropertyID LookupProperty(const nsACString& aProperty)
89
0
  {
90
0
    return Servo_Property_LookupEnabledForAllContent(&aProperty);
91
0
  }
92
93
  static nsCSSPropertyID LookupProperty(const nsAString& aProperty)
94
0
  {
95
0
    NS_ConvertUTF16toUTF8 utf8(aProperty);
96
0
    return LookupProperty(utf8);
97
0
  }
98
99
  // As above, but looked up using a property's IDL name.
100
  // eCSSPropertyExtra_variable won't be returned from these methods.
101
  static nsCSSPropertyID LookupPropertyByIDLName(
102
      const nsAString& aPropertyIDLName,
103
      EnabledState aEnabled);
104
  static nsCSSPropertyID LookupPropertyByIDLName(
105
      const nsACString& aPropertyIDLName,
106
      EnabledState aEnabled);
107
108
  // Returns whether aProperty is a custom property name, i.e. begins with
109
  // "--".  This assumes that the CSS Variables pref has been enabled.
110
  static bool IsCustomPropertyName(const nsAString& aProperty);
111
112
  static bool IsShorthand(nsCSSPropertyID aProperty)
113
0
  {
114
0
    MOZ_ASSERT(0 <= aProperty && aProperty < eCSSProperty_COUNT,
115
0
               "out of range");
116
0
    return (aProperty >= eCSSProperty_COUNT_no_shorthands);
117
0
  }
118
119
  // Same but for @font-face descriptors
120
  static nsCSSFontDesc LookupFontDesc(const nsAString& aProperty);
121
122
  // Given a property enum, get the string value
123
  //
124
  // This string is static.
125
  static const nsDependentCSubstring GetStringValue(nsCSSPropertyID aProperty)
126
0
  {
127
0
    uint32_t len;
128
0
    const uint8_t* chars = Servo_Property_GetName(aProperty, &len);
129
0
    return nsDependentCSubstring(reinterpret_cast<const char*>(chars), len);
130
0
  }
131
132
  static const nsCString& GetStringValue(nsCSSFontDesc aFontDesc);
133
  static const nsCString& GetStringValue(nsCSSCounterDesc aCounterDesc);
134
135
  // Returns the index of |aKeyword| in |aTable|, if it exists there;
136
  // otherwise, returns -1.
137
  // NOTE: Generally, clients should call FindKeyword() instead of this method.
138
  static int32_t FindIndexOfKeyword(nsCSSKeyword aKeyword,
139
                                    const KTableEntry aTable[]);
140
141
  // Find |aKeyword| in |aTable|, if found set |aValue| to its corresponding value.
142
  // If not found, return false and do not set |aValue|.
143
  static bool FindKeyword(nsCSSKeyword aKeyword, const KTableEntry aTable[],
144
                          int32_t& aValue);
145
  // Return the first keyword in |aTable| that has the corresponding value |aValue|.
146
  // Return |eCSSKeyword_UNKNOWN| if not found.
147
  static nsCSSKeyword ValueToKeywordEnum(int32_t aValue,
148
                                         const KTableEntry aTable[]);
149
  template<typename T,
150
           typename = typename std::enable_if<std::is_enum<T>::value>::type>
151
  static nsCSSKeyword ValueToKeywordEnum(T aValue,
152
                                         const KTableEntry aTable[])
153
0
  {
154
0
    static_assert(mozilla::EnumTypeFitsWithin<T, int16_t>::value,
155
0
                  "aValue must be an enum that fits within KTableEntry::mValue");
156
0
    return ValueToKeywordEnum(static_cast<int16_t>(aValue), aTable);
157
0
  }
Unexecuted instantiation: nsCSSKeyword nsCSSProps::ValueToKeywordEnum<mozilla::StyleImageLayerRepeat, void>(mozilla::StyleImageLayerRepeat, nsCSSKTableEntry const*)
Unexecuted instantiation: nsCSSKeyword nsCSSProps::ValueToKeywordEnum<mozilla::StyleOverscrollBehavior, void>(mozilla::StyleOverscrollBehavior, nsCSSKTableEntry const*)
Unexecuted instantiation: nsCSSKeyword nsCSSProps::ValueToKeywordEnum<mozilla::StyleBorderImageRepeat, void>(mozilla::StyleBorderImageRepeat, nsCSSKTableEntry const*)
Unexecuted instantiation: nsCSSKeyword nsCSSProps::ValueToKeywordEnum<mozilla::StyleDisplay, void>(mozilla::StyleDisplay, nsCSSKTableEntry const*)
158
  // Ditto but as a string, return "" when not found.
159
  static const nsCString& ValueToKeyword(int32_t aValue,
160
                                         const KTableEntry aTable[]);
161
  template<typename T,
162
           typename = typename std::enable_if<std::is_enum<T>::value>::type>
163
  static const nsCString& ValueToKeyword(T aValue, const KTableEntry aTable[])
164
0
  {
165
0
    static_assert(mozilla::EnumTypeFitsWithin<T, int16_t>::value,
166
0
                  "aValue must be an enum that fits within KTableEntry::mValue");
167
0
    return ValueToKeyword(static_cast<int16_t>(aValue), aTable);
168
0
  }
169
170
private:
171
  static const Flags kFlagsTable[eCSSProperty_COUNT];
172
173
public:
174
  static bool PropHasFlags(nsCSSPropertyID aProperty, Flags aFlags)
175
0
  {
176
0
    MOZ_ASSERT(0 <= aProperty && aProperty < eCSSProperty_COUNT,
177
0
               "out of range");
178
0
    return (nsCSSProps::kFlagsTable[aProperty] & aFlags) == aFlags;
179
0
  }
180
181
  static nsCSSPropertyID Physicalize(nsCSSPropertyID aProperty,
182
                                     const mozilla::ComputedStyle& aStyle)
183
0
  {
184
0
    if (PropHasFlags(aProperty, Flags::IsLogical)) {
185
0
      return Servo_ResolveLogicalProperty(aProperty, &aStyle);
186
0
    }
187
0
    return aProperty;
188
0
  }
189
190
private:
191
  // A table for shorthand properties.  The appropriate index is the
192
  // property ID minus eCSSProperty_COUNT_no_shorthands.
193
  static const nsCSSPropertyID* const
194
    kSubpropertyTable[eCSSProperty_COUNT - eCSSProperty_COUNT_no_shorthands];
195
196
public:
197
  static const nsCSSPropertyID* SubpropertyEntryFor(nsCSSPropertyID aProperty)
198
0
  {
199
0
    MOZ_ASSERT(eCSSProperty_COUNT_no_shorthands <= aProperty &&
200
0
               aProperty < eCSSProperty_COUNT,
201
0
               "out of range");
202
0
    return nsCSSProps::kSubpropertyTable[aProperty -
203
0
                                         eCSSProperty_COUNT_no_shorthands];
204
0
  }
205
206
private:
207
  static bool gPropertyEnabled[eCSSProperty_COUNT_with_aliases];
208
209
private:
210
  // Defined in the generated nsCSSPropsGenerated.inc.
211
  static const char* const kIDLNameTable[eCSSProperty_COUNT];
212
213
public:
214
  /**
215
   * Returns the IDL name of the specified property, which must be a
216
   * longhand, logical or shorthand property.  The IDL name is the property
217
   * name with any hyphen-lowercase character pairs replaced by an
218
   * uppercase character:
219
   * https://drafts.csswg.org/cssom/#css-property-to-idl-attribute
220
   *
221
   * As a special case, the string "cssFloat" is returned for the float
222
   * property.  nullptr is returned for internal properties.
223
   */
224
  static const char* PropertyIDLName(nsCSSPropertyID aProperty)
225
0
  {
226
0
    MOZ_ASSERT(0 <= aProperty && aProperty < eCSSProperty_COUNT,
227
0
               "out of range");
228
0
    return kIDLNameTable[aProperty];
229
0
  }
230
231
private:
232
  static const int32_t kIDLNameSortPositionTable[eCSSProperty_COUNT];
233
234
public:
235
  /**
236
   * Returns the position of the specified property in a list of all
237
   * properties sorted by their IDL name.
238
   */
239
  static int32_t PropertyIDLNameSortPosition(nsCSSPropertyID aProperty)
240
0
  {
241
0
    MOZ_ASSERT(0 <= aProperty && aProperty < eCSSProperty_COUNT,
242
0
               "out of range");
243
0
    return kIDLNameSortPositionTable[aProperty];
244
0
  }
245
246
0
  static bool IsEnabled(nsCSSPropertyID aProperty) {
247
0
    MOZ_ASSERT(0 <= aProperty && aProperty < eCSSProperty_COUNT_with_aliases,
248
0
               "out of range");
249
0
    // In the child process, assert that we're not trying to parse stylesheets
250
0
    // before we've gotten all our prefs.
251
0
    MOZ_ASSERT_IF(!XRE_IsParentProcess(),
252
0
                  mozilla::Preferences::ArePrefsInitedInContentProcess());
253
0
    return gPropertyEnabled[aProperty];
254
0
  }
255
256
  // A table for the use counter associated with each CSS property.  If a
257
  // property does not have a use counter defined in UseCounters.conf, then
258
  // its associated entry is |eUseCounter_UNKNOWN|.
259
  static const mozilla::UseCounter gPropertyUseCounter[eCSSProperty_COUNT_no_shorthands];
260
261
public:
262
263
0
  static mozilla::UseCounter UseCounterFor(nsCSSPropertyID aProperty) {
264
0
    MOZ_ASSERT(0 <= aProperty && aProperty < eCSSProperty_COUNT_no_shorthands,
265
0
               "out of range");
266
0
    return gPropertyUseCounter[aProperty];
267
0
  }
268
269
  static bool IsEnabled(nsCSSPropertyID aProperty, EnabledState aEnabled)
270
0
  {
271
0
    if (IsEnabled(aProperty)) {
272
0
      return true;
273
0
    }
274
0
    if (aEnabled == EnabledState::eIgnoreEnabledState) {
275
0
      return true;
276
0
    }
277
0
    if ((aEnabled & EnabledState::eInUASheets) &&
278
0
        PropHasFlags(aProperty, Flags::EnabledInUASheets))
279
0
    {
280
0
      return true;
281
0
    }
282
0
    if ((aEnabled & EnabledState::eInChrome) &&
283
0
        PropHasFlags(aProperty, Flags::EnabledInChrome))
284
0
    {
285
0
      return true;
286
0
    }
287
0
    return false;
288
0
  }
289
290
public:
291
  struct PropertyPref
292
  {
293
    nsCSSPropertyID mPropID;
294
    const char* mPref;
295
  };
296
  static const PropertyPref kPropertyPrefTable[];
297
298
// Storing the enabledstate_ value in an nsCSSPropertyID variable is a small hack
299
// to avoid needing a separate variable declaration for its real type
300
// (CSSEnabledState), which would then require using a block and
301
// therefore a pair of macros by consumers for the start and end of the loop.
302
#define CSSPROPS_FOR_SHORTHAND_SUBPROPERTIES(it_, prop_, enabledstate_)   \
303
0
  for (const nsCSSPropertyID *it_ = nsCSSProps::SubpropertyEntryFor(prop_), \
304
0
                            es_ = (nsCSSPropertyID)((enabledstate_) |       \
305
0
                                                  CSSEnabledState(0));    \
306
0
       *it_ != eCSSProperty_UNKNOWN; ++it_)                               \
307
0
    if (nsCSSProps::IsEnabled(*it_, (mozilla::CSSEnabledState) es_))
308
309
  // Keyword/Enum value tables
310
  static const KTableEntry kTransformStyleKTable[];
311
  static const KTableEntry kImageLayerRepeatKTable[];
312
  // Not const because we modify its entries when the pref
313
  // "layout.css.background-clip.text" changes:
314
  static const KTableEntry kBorderImageRepeatKTable[];
315
  static const KTableEntry kBorderStyleKTable[];
316
  static const KTableEntry kShapeRadiusKTable[];
317
  static const KTableEntry kFilterFunctionKTable[];
318
  static const KTableEntry kBoxShadowTypeKTable[];
319
  static const KTableEntry kCursorKTable[];
320
  // Not const because we modify its entries when various
321
  // "layout.css.*.enabled" prefs changes:
322
  static KTableEntry kDisplayKTable[];
323
  // -- tables for parsing the {align,justify}-{content,items,self} properties --
324
  static const KTableEntry kAlignAllKeywords[];
325
  static const KTableEntry kAlignOverflowPosition[]; // <overflow-position>
326
  static const KTableEntry kAlignSelfPosition[];     // <self-position>
327
  static const KTableEntry kAlignLegacy[];           // 'legacy'
328
  static const KTableEntry kAlignLegacyPosition[];   // 'left/right/center'
329
  static const KTableEntry kAlignAutoNormalStretchBaseline[]; // 'auto/normal/stretch/baseline'
330
  static const KTableEntry kAlignNormalStretchBaseline[]; // 'normal/stretch/baseline'
331
  static const KTableEntry kAlignNormalBaseline[]; // 'normal/baseline'
332
  static const KTableEntry kAlignContentDistribution[]; // <content-distribution>
333
  static const KTableEntry kAlignContentPosition[]; // <content-position>
334
  // -- tables for auto-completion of the {align,justify}-{content,items,self} properties --
335
  static const KTableEntry kAutoCompletionAlignJustifySelf[];
336
  static const KTableEntry kAutoCompletionAlignItems[];
337
  static const KTableEntry kAutoCompletionAlignJustifyContent[];
338
  // ------------------------------------------------------------------
339
  static const KTableEntry kFontSmoothingKTable[];
340
  static const KTableEntry kGridAutoFlowKTable[];
341
  static const KTableEntry kGridTrackBreadthKTable[];
342
  static const KTableEntry kLineHeightKTable[];
343
  static const KTableEntry kContainKTable[];
344
  static const KTableEntry kOutlineStyleKTable[];
345
  static const KTableEntry kOverflowKTable[];
346
  static const KTableEntry kOverflowSubKTable[];
347
  static const KTableEntry kOverflowClipBoxKTable[];
348
  static const KTableEntry kRadialGradientSizeKTable[];
349
  static const KTableEntry kOverscrollBehaviorKTable[];
350
  static const KTableEntry kScrollSnapTypeKTable[];
351
  // Not const because we modify its entries when the pref
352
  // "layout.css.text-align-unsafe-value.enabled" changes:
353
  static KTableEntry kTextAlignKTable[];
354
  static const KTableEntry kTextDecorationLineKTable[];
355
  static const KTableEntry kTextDecorationStyleKTable[];
356
  static const KTableEntry kTextEmphasisStyleShapeKTable[];
357
  static const KTableEntry kTextOverflowKTable[];
358
  static const KTableEntry kTouchActionKTable[];
359
  static const KTableEntry kTransitionTimingFunctionKTable[];
360
  static const KTableEntry kVerticalAlignKTable[];
361
  static const KTableEntry kWidthKTable[]; // also min-width, max-width
362
  static const KTableEntry kFlexBasisKTable[];
363
};
364
365
#endif /* nsCSSProps_h___ */