Coverage Report

Created: 2018-09-25 14:53

/work/obj-fuzz/dist/include/nsCSSValue.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
/* representation of simple property values within CSS declarations */
8
9
#ifndef nsCSSValue_h___
10
#define nsCSSValue_h___
11
12
#include "mozilla/Attributes.h"
13
#include "mozilla/CORSMode.h"
14
#include "mozilla/FontPropertyTypes.h"
15
#include "mozilla/MemoryReporting.h"
16
#include "mozilla/ServoTypes.h"
17
#include "mozilla/SheetType.h"
18
#include "mozilla/URLExtraData.h"
19
#include "mozilla/UniquePtr.h"
20
21
#include "nsCSSKeywords.h"
22
#include "nsCSSPropertyID.h"
23
#include "nsCoord.h"
24
#include "nsProxyRelease.h"
25
#include "nsRefPtrHashtable.h"
26
#include "nsString.h"
27
#include "nsStringBuffer.h"
28
#include "nsTArray.h"
29
#include "nsStyleConsts.h"
30
#include "nsStyleCoord.h"
31
#include "gfxFontFamilyList.h"
32
33
#include <type_traits>
34
35
class imgRequestProxy;
36
class nsAtom;
37
class nsIContent;
38
class nsIDocument;
39
class nsIPrincipal;
40
class nsIURI;
41
class nsPresContext;
42
template <class T>
43
class nsPtrHashKey;
44
struct RustString;
45
46
namespace mozilla {
47
class CSSStyleSheet;
48
} // namespace mozilla
49
50
// Deletes a linked list iteratively to avoid blowing up the stack (bug 456196).
51
#define NS_CSS_DELETE_LIST_MEMBER(type_, ptr_, member_)                        \
52
  {                                                                            \
53
    type_ *cur = (ptr_)->member_;                                              \
54
    (ptr_)->member_ = nullptr;                                                 \
55
    while (cur) {                                                              \
56
      type_ *dlm_next = cur->member_;                                          \
57
      cur->member_ = nullptr;                                                  \
58
      delete cur;                                                              \
59
      cur = dlm_next;                                                          \
60
    }                                                                          \
61
  }
62
// Ditto, but use NS_RELEASE instead of 'delete' (bug 1221902).
63
#define NS_CSS_NS_RELEASE_LIST_MEMBER(type_, ptr_, member_)                    \
64
  {                                                                            \
65
    type_ *cur = (ptr_)->member_;                                              \
66
    (ptr_)->member_ = nullptr;                                                 \
67
    while (cur) {                                                              \
68
      type_ *dlm_next = cur->member_;                                          \
69
      cur->member_ = nullptr;                                                  \
70
      NS_RELEASE(cur);                                                         \
71
      cur = dlm_next;                                                          \
72
    }                                                                          \
73
  }
74
75
// Clones a linked list iteratively to avoid blowing up the stack.
76
// If it fails to clone the entire list then 'to_' is deleted and
77
// we return null.
78
#define NS_CSS_CLONE_LIST_MEMBER(type_, from_, member_, to_, args_)            \
79
  {                                                                            \
80
    type_ *dest = (to_);                                                       \
81
    (to_)->member_ = nullptr;                                                  \
82
    for (const type_ *src = (from_)->member_; src; src = src->member_) {       \
83
      type_ *clm_clone = src->Clone args_;                                     \
84
      if (!clm_clone) {                                                        \
85
        delete (to_);                                                          \
86
        return nullptr;                                                        \
87
      }                                                                        \
88
      dest->member_ = clm_clone;                                               \
89
      dest = clm_clone;                                                        \
90
    }                                                                          \
91
  }
92
93
namespace mozilla {
94
namespace css {
95
96
struct URLValueData
97
{
98
protected:
99
  // Methods are not inline because using an nsIPrincipal means requiring
100
  // caps, which leads to REQUIRES hell, since this header is included all
101
  // over.
102
103
  // aString must not be null.
104
  // principal of aExtraData must not be null.
105
  // Construct with a base URI; this will create the actual URI lazily from
106
  // aString and aExtraData.
107
  URLValueData(ServoRawOffsetArc<RustString> aString,
108
               already_AddRefed<URLExtraData> aExtraData,
109
               CORSMode aCORSMode);
110
  // Construct with the actual URI.
111
  URLValueData(already_AddRefed<nsIURI> aURI,
112
               ServoRawOffsetArc<RustString> aString,
113
               already_AddRefed<URLExtraData> aExtraData,
114
               CORSMode aCORSMode);
115
116
public:
117
  // Returns true iff all fields of the two URLValueData objects are equal.
118
  //
119
  // Only safe to call on the main thread, since this will call Equals on the
120
  // nsIURI and nsIPrincipal objects stored on the URLValueData objects.
121
  bool Equals(const URLValueData& aOther) const;
122
123
  // Returns true iff we know for sure, by comparing the mBaseURI pointer,
124
  // the specified url() value mString, and the mIsLocalRef, that these
125
  // two URLValueData objects represent the same computed url() value.
126
  //
127
  // Doesn't look at mReferrer or mOriginPrincipal.
128
  //
129
  // Safe to call from any thread.
130
  bool DefinitelyEqualURIs(const URLValueData& aOther) const;
131
132
  // Smae as DefinitelyEqualURIs but additionally compares the nsIPrincipal
133
  // pointers of the two URLValueData objects.
134
  bool DefinitelyEqualURIsAndPrincipal(const URLValueData& aOther) const;
135
136
  nsIURI* GetURI() const;
137
138
  bool IsLocalRef() const;
139
140
  bool HasRef() const;
141
142
  // This function takes a guess whether the URL has a fragment, by searching
143
  // for a hash character. It definitely returns false if we know it can't
144
  // have a fragment because it has no hash character.
145
  //
146
  // MightHaveRef can be used in any thread, whereas HasRef can only be used
147
  // in the main thread.
148
  bool MightHaveRef() const;
149
150
  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(URLValueData)
151
152
  // When matching a url with mIsLocalRef set, resolve it against aURI;
153
  // Otherwise, ignore aURL and return mURL directly.
154
  already_AddRefed<nsIURI> ResolveLocalRef(nsIURI* aURI) const;
155
  already_AddRefed<nsIURI> ResolveLocalRef(nsIContent* aContent) const;
156
157
  // Serializes mURI as a computed URI value, taking into account mIsLocalRef
158
  // and serializing just the fragment if true.
159
  void GetSourceString(nsString& aRef) const;
160
161
  bool EqualsExceptRef(nsIURI* aURI) const;
162
163
  bool IsStringEmpty() const
164
0
  {
165
0
    return GetString().IsEmpty();
166
0
  }
167
168
  nsDependentCSubstring GetString() const;
169
170
private:
171
  // mURI stores the lazily resolved URI.  This may be null if the URI is
172
  // invalid, even once resolved.
173
  mutable nsCOMPtr<nsIURI> mURI;
174
175
public:
176
  RefPtr<URLExtraData> mExtraData;
177
178
private:
179
  mutable bool mURIResolved;
180
181
  // mIsLocalRef is set when url starts with a U+0023 number sign(#) character.
182
  mutable Maybe<bool> mIsLocalRef;
183
  mutable Maybe<bool> mMightHaveRef;
184
185
  mozilla::ServoRawOffsetArc<RustString> mString;
186
187
protected:
188
  // Only used by ImageValue.  Declared up here because otherwise bindgen gets
189
  // confused by the non-standard-layout packing of the variable up into
190
  // URLValueData.
191
  bool mLoadedImage = false;
192
  const CORSMode mCORSMode;
193
194
  virtual ~URLValueData();
195
196
  size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
197
198
private:
199
  URLValueData(const URLValueData& aOther) = delete;
200
  URLValueData& operator=(const URLValueData& aOther) = delete;
201
202
  friend struct ImageValue;
203
};
204
205
struct URLValue final : public URLValueData
206
{
207
  URLValue(ServoRawOffsetArc<RustString> aString,
208
           already_AddRefed<URLExtraData> aExtraData)
209
    : URLValueData(aString, std::move(aExtraData), CORSMode::CORS_NONE)
210
  { }
211
212
  URLValue(const URLValue&) = delete;
213
  URLValue& operator=(const URLValue&) = delete;
214
215
  size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
216
};
217
218
struct ImageValue final : public URLValueData
219
{
220
  static already_AddRefed<ImageValue>
221
    CreateFromURLValue(URLValue*, nsIDocument*, CORSMode);
222
223
  // Not making the constructor and destructor inline because that would
224
  // force us to include imgIRequest.h, which leads to REQUIRES hell, since
225
  // this header is included all over.
226
  //
227
  // This constructor is only safe to call from the main thread.
228
  ImageValue(nsIURI* aURI, const nsAString& aString,
229
             already_AddRefed<URLExtraData> aExtraData,
230
             nsIDocument* aDocument,
231
             CORSMode aCORSMode);
232
233
  // This constructor is only safe to call from the main thread.
234
  ImageValue(nsIURI* aURI, ServoRawOffsetArc<RustString> aString,
235
             already_AddRefed<URLExtraData> aExtraData,
236
             nsIDocument* aDocument,
237
             CORSMode aCORSMode);
238
239
  // This constructor is safe to call from any thread, but Initialize
240
  // must be called later for the object to be useful.
241
  ImageValue(const nsAString& aString,
242
             already_AddRefed<URLExtraData> aExtraData,
243
             CORSMode aCORSMode);
244
245
  // This constructor is safe to call from any thread, but Initialize
246
  // must be called later for the object to be useful.
247
  ImageValue(ServoRawOffsetArc<RustString> aURIString,
248
             already_AddRefed<URLExtraData> aExtraData,
249
             CORSMode aCORSMode);
250
251
  ImageValue(const ImageValue&) = delete;
252
  ImageValue& operator=(const ImageValue&) = delete;
253
254
  void Initialize(nsIDocument* aDocument);
255
256
  size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
257
258
protected:
259
  ~ImageValue();
260
261
public:
262
  // Inherit Equals from URLValueData
263
264
  nsRefPtrHashtable<nsPtrHashKey<nsIDocument>, imgRequestProxy> mRequests;
265
};
266
267
struct GridNamedArea {
268
  nsString mName;
269
  uint32_t mColumnStart;
270
  uint32_t mColumnEnd;
271
  uint32_t mRowStart;
272
  uint32_t mRowEnd;
273
};
274
275
struct GridTemplateAreasValue final {
276
  // Parsed value
277
  nsTArray<GridNamedArea> mNamedAreas;
278
279
  // Original <string> values. Length gives the number of rows,
280
  // content makes serialization easier.
281
  nsTArray<nsString> mTemplates;
282
283
  // How many columns grid-template-areas contributes to the explicit grid.
284
  // http://dev.w3.org/csswg/css-grid/#explicit-grid
285
  uint32_t mNColumns;
286
287
  // How many rows grid-template-areas contributes to the explicit grid.
288
  // http://dev.w3.org/csswg/css-grid/#explicit-grid
289
  uint32_t NRows() const {
290
    return mTemplates.Length();
291
  }
292
293
  GridTemplateAreasValue()
294
    : mNColumns(0)
295
    // Default constructors for mNamedAreas and mTemplates: empty arrays.
296
  {
297
  }
298
299
  bool operator==(const GridTemplateAreasValue& aOther) const
300
  {
301
    return mTemplates == aOther.mTemplates;
302
  }
303
304
  bool operator!=(const GridTemplateAreasValue& aOther) const
305
0
  {
306
0
    return !(*this == aOther);
307
0
  }
308
309
  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GridTemplateAreasValue)
310
311
  size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
312
313
private:
314
  // Private destructor to make sure this isn't used as a stack variable
315
  // or member variable.
316
  ~GridTemplateAreasValue()
317
  {
318
  }
319
320
  GridTemplateAreasValue(const GridTemplateAreasValue& aOther) = delete;
321
  GridTemplateAreasValue&
322
  operator=(const GridTemplateAreasValue& aOther) = delete;
323
};
324
325
} // namespace css
326
} // namespace mozilla
327
328
enum nsCSSUnit {
329
  eCSSUnit_Null         = 0,      // (n/a) null unit, value is not specified
330
  eCSSUnit_Auto         = 1,      // (n/a) value is algorithmic
331
  eCSSUnit_Inherit      = 2,      // (n/a) value is inherited
332
  eCSSUnit_Initial      = 3,      // (n/a) value is default UA value
333
  eCSSUnit_Unset        = 4,      // (n/a) value equivalent to 'initial' if on a reset property, 'inherit' otherwise
334
  eCSSUnit_None         = 5,      // (n/a) value is none
335
  eCSSUnit_Normal       = 6,      // (n/a) value is normal (algorithmic, different than auto)
336
  eCSSUnit_System_Font  = 7,      // (n/a) value is -moz-use-system-font
337
  eCSSUnit_All          = 8,      // (n/a) value is all
338
  eCSSUnit_Dummy        = 9,      // (n/a) a fake but specified value, used
339
                                  //       only in temporary values
340
  eCSSUnit_DummyInherit = 10,     // (n/a) a fake but specified value, used
341
                                  //       only in temporary values
342
343
  eCSSUnit_String       = 11,     // (char16_t*) a string value
344
  eCSSUnit_Ident        = 12,     // (char16_t*) a string value
345
  eCSSUnit_Attr         = 14,     // (char16_t*) a attr(string) value
346
  eCSSUnit_Local_Font   = 15,     // (char16_t*) a local font name
347
  eCSSUnit_Font_Format  = 16,     // (char16_t*) a font format name
348
  eCSSUnit_Element      = 17,     // (char16_t*) an element id
349
350
  eCSSUnit_Array        = 20,     // (nsCSSValue::Array*) a list of values
351
  eCSSUnit_Counter      = 21,     // (nsCSSValue::Array*) a counter(string,[string]) value
352
  eCSSUnit_Counters     = 22,     // (nsCSSValue::Array*) a counters(string,string[,string]) value
353
  eCSSUnit_Cubic_Bezier = 23,     // (nsCSSValue::Array*) a list of float values
354
  eCSSUnit_Steps        = 24,     // (nsCSSValue::Array*) a list of (integer, enumerated)
355
  eCSSUnit_Symbols      = 25,     // (nsCSSValue::Array*) a symbols(enumerated, symbols) value
356
  eCSSUnit_Function     = 26,     // (nsCSSValue::Array*) a function with
357
                                  //  parameters.  First elem of array is name,
358
                                  //  an nsCSSKeyword as eCSSUnit_Enumerated,
359
                                  //  the rest of the values are arguments.
360
361
  // The top level of a calc() expression is eCSSUnit_Calc.  All
362
  // remaining eCSSUnit_Calc_* units only occur inside these toplevel
363
  // calc values.
364
365
  // eCSSUnit_Calc has an array with exactly 1 element.  eCSSUnit_Calc
366
  // exists so we can distinguish calc(2em) from 2em as specified values
367
  // (but we drop this distinction for nsStyleCoord when we store
368
  // computed values).
369
  eCSSUnit_Calc         = 30,     // (nsCSSValue::Array*) calc() value
370
  // Plus, Minus, Times_* and Divided have arrays with exactly 2
371
  // elements.  a + b + c + d is grouped as ((a + b) + c) + d
372
  eCSSUnit_Calc_Plus    = 31,     // (nsCSSValue::Array*) + node within calc()
373
  eCSSUnit_Calc_Minus   = 32,     // (nsCSSValue::Array*) - within calc
374
  eCSSUnit_Calc_Times_L = 33,     // (nsCSSValue::Array*) num * val within calc
375
  eCSSUnit_Calc_Times_R = 34,     // (nsCSSValue::Array*) val * num within calc
376
  eCSSUnit_Calc_Divided = 35,     // (nsCSSValue::Array*) / within calc
377
378
  eCSSUnit_URL          = 40,     // (nsCSSValue::URL*) value
379
  eCSSUnit_GridTemplateAreas   = 44,   // (GridTemplateAreasValue*)
380
                                       // for grid-template-areas
381
382
  eCSSUnit_Pair         = 50,     // (nsCSSValuePair*) pair of values
383
  eCSSUnit_List         = 53,     // (nsCSSValueList*) list of values
384
  eCSSUnit_ListDep      = 54,     // (nsCSSValueList*) same as List
385
                                  //   but does not own the list
386
  eCSSUnit_SharedList   = 55,     // (nsCSSValueSharedList*) same as list
387
                                  //   but reference counted and shared
388
  eCSSUnit_PairList     = 56,     // (nsCSSValuePairList*) list of value pairs
389
  eCSSUnit_PairListDep  = 57,     // (nsCSSValuePairList*) same as PairList
390
                                  //   but does not own the list
391
392
  eCSSUnit_FontFamilyList = 58,   // (SharedFontList*) value
393
394
  // Atom units
395
  eCSSUnit_AtomIdent    = 60,     // (nsAtom*) for its string as an identifier
396
397
  eCSSUnit_Integer      = 70,     // (int) simple value
398
  eCSSUnit_Enumerated   = 71,     // (int) value has enumerated meaning
399
400
  eCSSUnit_Percent      = 100,     // (float) 1.0 == 100%) value is percentage of something
401
  eCSSUnit_Number       = 101,     // (float) value is numeric (usually multiplier, different behavior than percent)
402
403
  // Length units - relative
404
  // Viewport relative measure
405
  eCSSUnit_ViewportWidth  = 700,    // (float) 1% of the width of the initial containing block
406
  eCSSUnit_ViewportHeight = 701,    // (float) 1% of the height of the initial containing block
407
  eCSSUnit_ViewportMin    = 702,    // (float) smaller of ViewportWidth and ViewportHeight
408
  eCSSUnit_ViewportMax    = 703,    // (float) larger of ViewportWidth and ViewportHeight
409
410
  // Font relative measure
411
  eCSSUnit_EM           = 800,    // (float) == current font size
412
  eCSSUnit_XHeight      = 801,    // (float) distance from top of lower case x to baseline
413
  eCSSUnit_Char         = 802,    // (float) number of characters, used for width with monospace font
414
  eCSSUnit_RootEM       = 803,    // (float) == root element font size
415
416
  // Screen relative measure
417
  eCSSUnit_Point        = 900,    // (float) 4/3 of a CSS pixel
418
  eCSSUnit_Inch         = 901,    // (float) 96 CSS pixels
419
  eCSSUnit_Millimeter   = 902,    // (float) 96/25.4 CSS pixels
420
  eCSSUnit_Centimeter   = 903,    // (float) 96/2.54 CSS pixels
421
  eCSSUnit_Pica         = 904,    // (float) 12 points == 16 CSS pixls
422
  eCSSUnit_Quarter      = 905,    // (float) 96/101.6 CSS pixels
423
  eCSSUnit_Pixel        = 906,    // (float) CSS pixel unit
424
425
  // Angular units
426
  eCSSUnit_Degree       = 1000,    // (float) 360 per circle
427
  eCSSUnit_Grad         = 1001,    // (float) 400 per circle
428
  eCSSUnit_Radian       = 1002,    // (float) 2*pi per circle
429
  eCSSUnit_Turn         = 1003,    // (float) 1 per circle
430
431
  // Frequency units
432
  eCSSUnit_Hertz        = 2000,    // (float) 1/seconds
433
  eCSSUnit_Kilohertz    = 2001,    // (float) 1000 Hertz
434
435
  // Time units
436
  eCSSUnit_Seconds      = 3000,    // (float) Standard time
437
  eCSSUnit_Milliseconds = 3001,    // (float) 1/1000 second
438
439
  // Flexible fraction (CSS Grid)
440
  eCSSUnit_FlexFraction = 4000,    // (float) Fraction of free space
441
442
  // Font property types
443
  eCSSUnit_FontWeight   = 5000,    // An encoded font-weight
444
  eCSSUnit_FontStretch  = 5001,    // An encoded font-stretch
445
  eCSSUnit_FontSlantStyle    = 5002,    // An encoded font-style
446
};
447
448
struct nsCSSValuePair;
449
struct nsCSSValuePair_heap;
450
struct nsCSSValueList;
451
struct nsCSSValueList_heap;
452
struct nsCSSValueSharedList;
453
struct nsCSSValuePairList;
454
struct nsCSSValuePairList_heap;
455
456
class nsCSSValue {
457
public:
458
  struct Array;
459
  friend struct Array;
460
461
  friend struct mozilla::css::URLValueData;
462
463
  friend struct mozilla::css::ImageValue;
464
465
  // for valueless units only (null, auto, inherit, none, all, normal)
466
  explicit nsCSSValue(nsCSSUnit aUnit = eCSSUnit_Null)
467
    : mUnit(aUnit)
468
0
  {
469
0
    MOZ_ASSERT(aUnit <= eCSSUnit_DummyInherit, "not a valueless unit");
470
0
  }
471
472
  nsCSSValue(int32_t aValue, nsCSSUnit aUnit);
473
  nsCSSValue(float aValue, nsCSSUnit aUnit);
474
  nsCSSValue(const nsString& aValue, nsCSSUnit aUnit);
475
  nsCSSValue(Array* aArray, nsCSSUnit aUnit);
476
  explicit nsCSSValue(mozilla::css::URLValue* aValue);
477
  explicit nsCSSValue(mozilla::css::ImageValue* aValue);
478
  explicit nsCSSValue(mozilla::css::GridTemplateAreasValue* aValue);
479
  explicit nsCSSValue(mozilla::SharedFontList* aValue);
480
  explicit nsCSSValue(mozilla::FontStretch aStretch);
481
  explicit nsCSSValue(mozilla::FontSlantStyle aStyle);
482
  explicit nsCSSValue(mozilla::FontWeight aWeight);
483
  nsCSSValue(const nsCSSValue& aCopy);
484
  nsCSSValue(nsCSSValue&& aOther)
485
    : mUnit(aOther.mUnit)
486
    , mValue(aOther.mValue)
487
0
  {
488
0
    aOther.mUnit = eCSSUnit_Null;
489
0
  }
490
  template<typename T,
491
           typename = typename std::enable_if<std::is_enum<T>::value>::type>
492
  explicit nsCSSValue(T aValue)
493
    : mUnit(eCSSUnit_Enumerated)
494
  {
495
    static_assert(mozilla::EnumTypeFitsWithin<T, int32_t>::value,
496
                  "aValue must be an enum that fits within mValue.mInt");
497
    mValue.mInt = static_cast<int32_t>(aValue);
498
  }
499
500
0
  ~nsCSSValue() { Reset(); }
501
502
  nsCSSValue&  operator=(const nsCSSValue& aCopy);
503
  nsCSSValue&  operator=(nsCSSValue&& aCopy);
504
  bool        operator==(const nsCSSValue& aOther) const;
505
506
  bool operator!=(const nsCSSValue& aOther) const
507
  {
508
    return !(*this == aOther);
509
  }
510
511
0
  nsCSSUnit GetUnit() const { return mUnit; }
512
  bool      IsLengthUnit() const
513
    { return eCSSUnit_ViewportWidth <= mUnit && mUnit <= eCSSUnit_Pixel; }
514
  bool      IsLengthPercentCalcUnit() const
515
0
    { return IsLengthUnit() || mUnit == eCSSUnit_Percent || IsCalcUnit(); }
516
  /**
517
   * What the spec calls relative length units is, for us, split
518
   * between relative length units and pixel length units.
519
   *
520
   * A "relative" length unit is a multiple of some derived metric,
521
   * such as a font em-size, which itself was controlled by an input CSS
522
   * length. Relative length units should not be scaled by zooming, since
523
   * the underlying CSS length would already have been scaled.
524
   */
525
  bool      IsRelativeLengthUnit() const
526
0
    { return eCSSUnit_EM <= mUnit && mUnit <= eCSSUnit_RootEM; }
527
  /**
528
   * A "pixel" length unit is a some multiple of CSS pixels.
529
   */
530
  static bool IsPixelLengthUnit(nsCSSUnit aUnit)
531
    { return eCSSUnit_Point <= aUnit && aUnit <= eCSSUnit_Pixel; }
532
  bool      IsPixelLengthUnit() const
533
    { return IsPixelLengthUnit(mUnit); }
534
  static bool IsPercentLengthUnit(nsCSSUnit aUnit)
535
0
    { return aUnit == eCSSUnit_Percent; }
536
  bool      IsPercentLengthUnit()
537
0
    { return IsPercentLengthUnit(mUnit); }
538
  static bool IsFloatUnit(nsCSSUnit aUnit)
539
    { return eCSSUnit_Number <= aUnit; }
540
  bool      IsAngularUnit() const
541
0
    { return eCSSUnit_Degree <= mUnit && mUnit <= eCSSUnit_Turn; }
542
  bool      IsFrequencyUnit() const
543
0
    { return eCSSUnit_Hertz <= mUnit && mUnit <= eCSSUnit_Kilohertz; }
544
  bool      IsTimeUnit() const
545
0
    { return eCSSUnit_Seconds <= mUnit && mUnit <= eCSSUnit_Milliseconds; }
546
  bool      IsCalcUnit() const
547
    { return eCSSUnit_Calc <= mUnit && mUnit <= eCSSUnit_Calc_Divided; }
548
549
  bool      UnitHasStringValue() const
550
    { return eCSSUnit_String <= mUnit && mUnit <= eCSSUnit_Element; }
551
  bool      UnitHasArrayValue() const
552
    { return eCSSUnit_Array <= mUnit && mUnit <= eCSSUnit_Calc_Divided; }
553
554
  int32_t GetIntValue() const
555
  {
556
    MOZ_ASSERT(mUnit == eCSSUnit_Integer ||
557
               mUnit == eCSSUnit_Enumerated,
558
               "not an int value");
559
    return mValue.mInt;
560
  }
561
562
  nsCSSKeyword GetKeywordValue() const
563
  {
564
    MOZ_ASSERT(mUnit == eCSSUnit_Enumerated, "not a keyword value");
565
    return static_cast<nsCSSKeyword>(mValue.mInt);
566
  }
567
568
  float GetPercentValue() const
569
0
  {
570
0
    MOZ_ASSERT(mUnit == eCSSUnit_Percent, "not a percent value");
571
0
    return mValue.mFloat;
572
0
  }
573
574
  float GetFloatValue() const
575
0
  {
576
0
    MOZ_ASSERT(eCSSUnit_Number <= mUnit, "not a float value");
577
0
    MOZ_ASSERT(!mozilla::IsNaN(mValue.mFloat));
578
0
    return mValue.mFloat;
579
0
  }
580
581
  float GetAngleValue() const
582
  {
583
    MOZ_ASSERT(eCSSUnit_Degree <= mUnit && mUnit <= eCSSUnit_Turn,
584
               "not an angle value");
585
    return mValue.mFloat;
586
  }
587
588
  // Converts any angle to radians.
589
  double GetAngleValueInRadians() const;
590
591
  // Converts any angle to degrees.
592
  double GetAngleValueInDegrees() const;
593
594
  nsAString& GetStringValue(nsAString& aBuffer) const
595
  {
596
    MOZ_ASSERT(UnitHasStringValue(), "not a string value");
597
    aBuffer.Truncate();
598
    uint32_t len = NS_strlen(GetBufferValue(mValue.mString));
599
    mValue.mString->ToString(len, aBuffer);
600
    return aBuffer;
601
  }
602
603
  const char16_t* GetStringBufferValue() const
604
  {
605
    MOZ_ASSERT(UnitHasStringValue(), "not a string value");
606
    return GetBufferValue(mValue.mString);
607
  }
608
609
  Array* GetArrayValue() const
610
  {
611
    MOZ_ASSERT(UnitHasArrayValue(), "not an array value");
612
    return mValue.mArray;
613
  }
614
615
  nsIURI* GetURLValue() const
616
  {
617
    MOZ_ASSERT(mUnit == eCSSUnit_URL, "not a URL value");
618
    return mValue.mURL->GetURI();
619
  }
620
621
  nsCSSValueSharedList* GetSharedListValue() const
622
  {
623
    MOZ_ASSERT(mUnit == eCSSUnit_SharedList, "not a shared list value");
624
    return mValue.mSharedList;
625
  }
626
627
  mozilla::NotNull<mozilla::SharedFontList*> GetFontFamilyListValue() const
628
0
  {
629
0
    MOZ_ASSERT(mUnit == eCSSUnit_FontFamilyList,
630
0
               "not a font family list value");
631
0
    NS_ASSERTION(mValue.mFontFamilyList != nullptr,
632
0
                 "font family list value should never be null");
633
0
    return mozilla::WrapNotNull(mValue.mFontFamilyList);
634
0
  }
635
636
  mozilla::FontStretch GetFontStretch() const
637
  {
638
    MOZ_ASSERT(mUnit == eCSSUnit_FontStretch, "not a font stretch value");
639
    return mValue.mFontStretch;
640
  }
641
642
  mozilla::FontSlantStyle GetFontSlantStyle() const
643
  {
644
    MOZ_ASSERT(mUnit == eCSSUnit_FontSlantStyle, "not a font style value");
645
    return mValue.mFontSlantStyle;
646
  }
647
648
  mozilla::FontWeight GetFontWeight() const
649
  {
650
    MOZ_ASSERT(mUnit == eCSSUnit_FontWeight, "not a font weight value");
651
    return mValue.mFontWeight;
652
  }
653
654
  // bodies of these are below
655
  inline nsCSSValuePair& GetPairValue();
656
  inline const nsCSSValuePair& GetPairValue() const;
657
658
  inline nsCSSValueList* GetListValue();
659
  inline const nsCSSValueList* GetListValue() const;
660
661
  inline nsCSSValuePairList* GetPairListValue();
662
  inline const nsCSSValuePairList* GetPairListValue() const;
663
664
  mozilla::css::URLValue* GetURLStructValue() const
665
  {
666
    // Not allowing this for Image values, because if the caller takes
667
    // a ref to them they won't be able to delete them properly.
668
    MOZ_ASSERT(mUnit == eCSSUnit_URL, "not a URL value");
669
    return mValue.mURL;
670
  }
671
672
  mozilla::css::GridTemplateAreasValue* GetGridTemplateAreas() const
673
0
  {
674
0
    MOZ_ASSERT(mUnit == eCSSUnit_GridTemplateAreas,
675
0
               "not a grid-template-areas value");
676
0
    return mValue.mGridTemplateAreas;
677
0
  }
678
679
  // Not making this inline because that would force us to include
680
  // imgIRequest.h, which leads to REQUIRES hell, since this header is included
681
  // all over.
682
  imgRequestProxy* GetImageValue(nsIDocument* aDocument) const;
683
684
  // Like GetImageValue, but additionally will pass the imgRequestProxy
685
  // through nsContentUtils::GetStaticRequest if aPresContent is static.
686
  already_AddRefed<imgRequestProxy> GetPossiblyStaticImageValue(
687
      nsIDocument* aDocument, nsPresContext* aPresContext) const;
688
689
  nscoord GetPixelLength() const;
690
691
  nsAtom* GetAtomValue() const {
692
    MOZ_ASSERT(mUnit == eCSSUnit_AtomIdent);
693
    return mValue.mAtom;
694
  }
695
696
  void Reset()  // sets to null
697
0
  {
698
0
    if (mUnit != eCSSUnit_Null)
699
0
      DoReset();
700
0
  }
701
private:
702
  void DoReset();
703
704
public:
705
  void SetIntValue(int32_t aValue, nsCSSUnit aUnit);
706
  template<typename T,
707
           typename = typename std::enable_if<std::is_enum<T>::value>::type>
708
  void SetEnumValue(T aValue)
709
  {
710
    static_assert(mozilla::EnumTypeFitsWithin<T, int32_t>::value,
711
                  "aValue must be an enum that fits within mValue.mInt");
712
    SetIntValue(static_cast<int32_t>(aValue), eCSSUnit_Enumerated);
713
  }
714
  void SetPercentValue(float aValue);
715
  void SetFloatValue(float aValue, nsCSSUnit aUnit);
716
  void SetStringValue(const nsString& aValue, nsCSSUnit aUnit);
717
  void SetAtomIdentValue(already_AddRefed<nsAtom> aValue);
718
  // converts the nscoord to pixels
719
  void SetIntegerCoordValue(nscoord aCoord);
720
  void SetArrayValue(nsCSSValue::Array* aArray, nsCSSUnit aUnit);
721
  void SetURLValue(mozilla::css::URLValue* aURI);
722
  void SetGridTemplateAreas(mozilla::css::GridTemplateAreasValue* aValue);
723
  void SetFontFamilyListValue(already_AddRefed<mozilla::SharedFontList> aFontListValue);
724
  void SetFontStretch(mozilla::FontStretch aStretch);
725
  void SetFontSlantStyle(mozilla::FontSlantStyle aStyle);
726
  void SetFontWeight(mozilla::FontWeight aWeight);
727
  void SetPairValue(const nsCSSValuePair* aPair);
728
  void SetPairValue(const nsCSSValue& xValue, const nsCSSValue& yValue);
729
  void SetSharedListValue(nsCSSValueSharedList* aList);
730
  void SetDependentListValue(nsCSSValueList* aList);
731
  void SetDependentPairListValue(nsCSSValuePairList* aList);
732
  void SetAutoValue();
733
  void SetInheritValue();
734
  void SetInitialValue();
735
  void SetUnsetValue();
736
  void SetNoneValue();
737
  void SetAllValue();
738
  void SetNormalValue();
739
  void SetSystemFontValue();
740
  void SetDummyValue();
741
  void SetDummyInheritValue();
742
743
  // Converts an nsStyleCoord::CalcValue back into a CSSValue
744
  void SetCalcValue(const nsStyleCoord::CalcValue* aCalc);
745
746
  nsStyleCoord::CalcValue GetCalcValue() const;
747
748
  // These are a little different - they allocate storage for you and
749
  // return a handle.
750
  nsCSSValueList* SetListValue();
751
  nsCSSValuePairList* SetPairListValue();
752
753
  // These take ownership of the passed-in resource.
754
  void AdoptListValue(mozilla::UniquePtr<nsCSSValueList> aValue);
755
  void AdoptPairListValue(mozilla::UniquePtr<nsCSSValuePairList> aValue);
756
757
  void StartImageLoad(nsIDocument* aDocument,
758
                      mozilla::CORSMode aCORSMode) const;  // Only pretend const
759
760
  // Initializes as a function value with the specified function id.
761
  Array* InitFunction(nsCSSKeyword aFunctionId, uint32_t aNumArgs);
762
  // Checks if this is a function value with the specified function id.
763
  bool EqualsFunction(nsCSSKeyword aFunctionId) const;
764
765
  // Returns an already addrefed buffer.  Guaranteed to return non-null.
766
  // (Will abort on allocation failure.)
767
  static already_AddRefed<nsStringBuffer>
768
    BufferFromString(const nsString& aValue);
769
770
  // Convert the given Ident value into AtomIdent.
771
  void AtomizeIdentValue();
772
773
  size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
774
775
  static void
776
  AppendAlignJustifyValueToString(int32_t aValue, nsAString& aResult);
777
778
private:
779
  static const char16_t* GetBufferValue(nsStringBuffer* aBuffer) {
780
    return static_cast<char16_t*>(aBuffer->Data());
781
  }
782
783
protected:
784
  nsCSSUnit mUnit;
785
  union {
786
    int32_t    mInt;
787
    float      mFloat;
788
    // Note: the capacity of the buffer may exceed the length of the string.
789
    // If we're of a string type, mString is not null.
790
    nsStringBuffer* MOZ_OWNING_REF mString;
791
    nsAtom* MOZ_OWNING_REF mAtom;
792
    Array* MOZ_OWNING_REF mArray;
793
    mozilla::css::URLValue* MOZ_OWNING_REF mURL;
794
    mozilla::css::GridTemplateAreasValue* MOZ_OWNING_REF mGridTemplateAreas;
795
    nsCSSValuePair_heap* MOZ_OWNING_REF mPair;
796
    nsCSSValueList_heap* MOZ_OWNING_REF mList;
797
    nsCSSValueList* mListDependent;
798
    nsCSSValueSharedList* MOZ_OWNING_REF mSharedList;
799
    nsCSSValuePairList_heap* MOZ_OWNING_REF mPairList;
800
    nsCSSValuePairList* mPairListDependent;
801
    mozilla::SharedFontList* MOZ_OWNING_REF mFontFamilyList;
802
    mozilla::FontStretch mFontStretch;
803
    mozilla::FontSlantStyle mFontSlantStyle;
804
    mozilla::FontWeight mFontWeight;
805
  } mValue;
806
};
807
808
struct nsCSSValue::Array final {
809
810
  // return |Array| with reference count of zero
811
  static Array* Create(size_t aItemCount) {
812
    return new (aItemCount) Array(aItemCount);
813
  }
814
815
0
  nsCSSValue& operator[](size_t aIndex) {
816
0
    MOZ_ASSERT(aIndex < mCount, "out of range");
817
0
    return mArray[aIndex];
818
0
  }
819
820
  const nsCSSValue& operator[](size_t aIndex) const {
821
    MOZ_ASSERT(aIndex < mCount, "out of range");
822
    return mArray[aIndex];
823
  }
824
825
0
  nsCSSValue& Item(size_t aIndex) { return (*this)[aIndex]; }
826
  const nsCSSValue& Item(size_t aIndex) const { return (*this)[aIndex]; }
827
828
  size_t Count() const { return mCount; }
829
830
  // callers depend on the items being contiguous
831
0
  nsCSSValue* ItemStorage() {
832
0
    return this->First();
833
0
  }
834
835
  bool operator==(const Array& aOther) const
836
  {
837
    if (mCount != aOther.mCount)
838
      return false;
839
    for (size_t i = 0; i < mCount; ++i)
840
      if ((*this)[i] != aOther[i])
841
        return false;
842
    return true;
843
  }
844
845
  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(Array);
846
private:
847
848
  const size_t mCount;
849
  // This must be the last sub-object, since we extend this array to
850
  // be of size mCount; it needs to be a sub-object so it gets proper
851
  // alignment.
852
  nsCSSValue mArray[1];
853
854
  void* operator new(size_t aSelfSize, size_t aItemCount) CPP_THROW_NEW {
855
    MOZ_ASSERT(aItemCount > 0, "cannot have a 0 item count");
856
    return ::operator new(aSelfSize + sizeof(nsCSSValue) * (aItemCount - 1));
857
  }
858
859
0
  void operator delete(void* aPtr) { ::operator delete(aPtr); }
860
861
0
  nsCSSValue* First() { return mArray; }
862
863
0
  const nsCSSValue* First() const { return mArray; }
864
865
#define CSSVALUE_LIST_FOR_EXTRA_VALUES(var)                                   \
866
0
  for (nsCSSValue *var = First() + 1, *var##_end = First() + mCount;          \
867
0
       var != var##_end; ++var)
868
869
  explicit Array(size_t aItemCount)
870
    : mRefCnt(0)
871
    , mCount(aItemCount)
872
  {
873
    CSSVALUE_LIST_FOR_EXTRA_VALUES(val) {
874
      new (val) nsCSSValue();
875
    }
876
  }
877
878
  ~Array()
879
0
  {
880
0
    CSSVALUE_LIST_FOR_EXTRA_VALUES(val) {
881
0
      val->~nsCSSValue();
882
0
    }
883
0
  }
884
885
  size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
886
887
#undef CSSVALUE_LIST_FOR_EXTRA_VALUES
888
889
private:
890
  Array(const Array& aOther) = delete;
891
  Array& operator=(const Array& aOther) = delete;
892
};
893
894
// Prefer nsCSSValue::Array for lists of fixed size.
895
struct nsCSSValueList {
896
0
  nsCSSValueList() : mNext(nullptr) { MOZ_COUNT_CTOR(nsCSSValueList); }
897
  ~nsCSSValueList();
898
899
  nsCSSValueList* Clone() const;  // makes a deep copy. Infallible.
900
  void CloneInto(nsCSSValueList* aList) const; // makes a deep copy into aList
901
902
  static bool Equal(const nsCSSValueList* aList1,
903
                    const nsCSSValueList* aList2);
904
905
  size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
906
907
  nsCSSValue      mValue;
908
  nsCSSValueList* mNext;
909
910
private:
911
  nsCSSValueList(const nsCSSValueList& aCopy) // makes a shallow copy
912
    : mValue(aCopy.mValue), mNext(nullptr)
913
  {
914
    MOZ_COUNT_CTOR(nsCSSValueList);
915
  }
916
917
  // We don't want operator== or operator!= because they wouldn't be
918
  // null-safe, which is generally what we need.  Use |Equal| method
919
  // above instead.
920
  bool operator==(nsCSSValueList const& aOther) const = delete;
921
  bool operator!=(const nsCSSValueList& aOther) const = delete;
922
};
923
924
// nsCSSValueList_heap differs from nsCSSValueList only in being
925
// refcounted.  It should not be necessary to use this class directly;
926
// it's an implementation detail of nsCSSValue.
927
struct nsCSSValueList_heap final : public nsCSSValueList {
928
  NS_INLINE_DECL_REFCOUNTING(nsCSSValueList_heap)
929
930
  size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
931
932
private:
933
  // Private destructor, to discourage deletion outside of Release():
934
  ~nsCSSValueList_heap()
935
0
  {
936
0
  }
937
};
938
939
// This is a reference counted list value.  Note that the object is
940
// a wrapper for the reference count and a pointer to the head of the
941
// list, whereas the other list types (such as nsCSSValueList) do
942
// not have such a wrapper.
943
struct nsCSSValueSharedList final {
944
  nsCSSValueSharedList()
945
    : mHead(nullptr)
946
  {
947
  }
948
949
  // Takes ownership of aList.
950
  explicit nsCSSValueSharedList(nsCSSValueList* aList)
951
    : mHead(aList)
952
0
  {
953
0
  }
954
955
private:
956
  // Private destructor, to discourage deletion outside of Release():
957
  ~nsCSSValueSharedList();
958
959
public:
960
  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(nsCSSValueSharedList)
961
962
  bool operator==(nsCSSValueSharedList const& aOther) const;
963
  bool operator!=(const nsCSSValueSharedList& aOther) const
964
  { return !(*this == aOther); }
965
966
  size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
967
968
  nsCSSValueList* mHead;
969
};
970
971
// This has to be here so that the relationship between nsCSSValueList
972
// and nsCSSValueList_heap is visible.
973
inline nsCSSValueList*
974
nsCSSValue::GetListValue()
975
{
976
  if (mUnit == eCSSUnit_List)
977
    return mValue.mList;
978
  else {
979
    MOZ_ASSERT(mUnit == eCSSUnit_ListDep, "not a list value");
980
    return mValue.mListDependent;
981
  }
982
}
983
984
inline const nsCSSValueList*
985
nsCSSValue::GetListValue() const
986
{
987
  if (mUnit == eCSSUnit_List)
988
    return mValue.mList;
989
  else {
990
    MOZ_ASSERT(mUnit == eCSSUnit_ListDep, "not a list value");
991
    return mValue.mListDependent;
992
  }
993
}
994
995
struct nsCSSValuePair {
996
  nsCSSValuePair()
997
0
  {
998
0
    MOZ_COUNT_CTOR(nsCSSValuePair);
999
0
  }
1000
  explicit nsCSSValuePair(nsCSSUnit aUnit)
1001
    : mXValue(aUnit), mYValue(aUnit)
1002
0
  {
1003
0
    MOZ_COUNT_CTOR(nsCSSValuePair);
1004
0
  }
1005
  nsCSSValuePair(const nsCSSValue& aXValue, const nsCSSValue& aYValue)
1006
    : mXValue(aXValue), mYValue(aYValue)
1007
  {
1008
    MOZ_COUNT_CTOR(nsCSSValuePair);
1009
  }
1010
  nsCSSValuePair(const nsCSSValuePair& aCopy)
1011
    : mXValue(aCopy.mXValue), mYValue(aCopy.mYValue)
1012
0
  {
1013
0
    MOZ_COUNT_CTOR(nsCSSValuePair);
1014
0
  }
1015
  ~nsCSSValuePair()
1016
  {
1017
    MOZ_COUNT_DTOR(nsCSSValuePair);
1018
  }
1019
1020
0
  nsCSSValuePair& operator=(const nsCSSValuePair& aOther) {
1021
0
    mXValue = aOther.mXValue;
1022
0
    mYValue = aOther.mYValue;
1023
0
    return *this;
1024
0
  }
1025
1026
  bool operator==(const nsCSSValuePair& aOther) const {
1027
    return mXValue == aOther.mXValue &&
1028
           mYValue == aOther.mYValue;
1029
  }
1030
1031
0
  bool operator!=(const nsCSSValuePair& aOther) const {
1032
0
    return mXValue != aOther.mXValue ||
1033
0
           mYValue != aOther.mYValue;
1034
0
  }
1035
1036
0
  bool BothValuesEqualTo(const nsCSSValue& aValue) const {
1037
0
    return mXValue == aValue &&
1038
0
           mYValue == aValue;
1039
0
  }
1040
1041
0
  void SetBothValuesTo(const nsCSSValue& aValue) {
1042
0
    mXValue = aValue;
1043
0
    mYValue = aValue;
1044
0
  }
1045
1046
0
  void Reset() {
1047
0
    mXValue.Reset();
1048
0
    mYValue.Reset();
1049
0
  }
1050
1051
0
  bool HasValue() const {
1052
0
    return mXValue.GetUnit() != eCSSUnit_Null ||
1053
0
           mYValue.GetUnit() != eCSSUnit_Null;
1054
0
  }
1055
1056
  size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
1057
1058
  nsCSSValue mXValue;
1059
  nsCSSValue mYValue;
1060
};
1061
1062
// nsCSSValuePair_heap differs from nsCSSValuePair only in being
1063
// refcounted.  It should not be necessary to use this class directly;
1064
// it's an implementation detail of nsCSSValue.
1065
struct nsCSSValuePair_heap final : public nsCSSValuePair {
1066
  // forward constructor
1067
  nsCSSValuePair_heap(const nsCSSValue& aXValue, const nsCSSValue& aYValue)
1068
      : nsCSSValuePair(aXValue, aYValue)
1069
  {}
1070
1071
  NS_INLINE_DECL_REFCOUNTING(nsCSSValuePair_heap)
1072
1073
  size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
1074
1075
private:
1076
  // Private destructor, to discourage deletion outside of Release():
1077
  ~nsCSSValuePair_heap()
1078
0
  {
1079
0
  }
1080
};
1081
1082
// This has to be here so that the relationship between nsCSSValuePair
1083
// and nsCSSValuePair_heap is visible.
1084
inline nsCSSValuePair&
1085
nsCSSValue::GetPairValue()
1086
{
1087
  MOZ_ASSERT(mUnit == eCSSUnit_Pair, "not a pair value");
1088
  return *mValue.mPair;
1089
}
1090
1091
inline const nsCSSValuePair&
1092
nsCSSValue::GetPairValue() const
1093
{
1094
  MOZ_ASSERT(mUnit == eCSSUnit_Pair, "not a pair value");
1095
  return *mValue.mPair;
1096
}
1097
1098
// Maybe should be replaced with nsCSSValueList and nsCSSValue::Array?
1099
struct nsCSSValuePairList {
1100
  nsCSSValuePairList() : mNext(nullptr) { MOZ_COUNT_CTOR(nsCSSValuePairList); }
1101
  ~nsCSSValuePairList();
1102
1103
  nsCSSValuePairList* Clone() const; // makes a deep copy. Infallible.
1104
1105
  static bool Equal(const nsCSSValuePairList* aList1,
1106
                    const nsCSSValuePairList* aList2);
1107
1108
  size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
1109
1110
  nsCSSValue          mXValue;
1111
  nsCSSValue          mYValue;
1112
  nsCSSValuePairList* mNext;
1113
1114
private:
1115
  nsCSSValuePairList(const nsCSSValuePairList& aCopy) // makes a shallow copy
1116
    : mXValue(aCopy.mXValue), mYValue(aCopy.mYValue), mNext(nullptr)
1117
  {
1118
    MOZ_COUNT_CTOR(nsCSSValuePairList);
1119
  }
1120
1121
  // We don't want operator== or operator!= because they wouldn't be
1122
  // null-safe, which is generally what we need.  Use |Equal| method
1123
  // above instead.
1124
  bool operator==(const nsCSSValuePairList& aOther) const = delete;
1125
  bool operator!=(const nsCSSValuePairList& aOther) const = delete;
1126
};
1127
1128
// nsCSSValuePairList_heap differs from nsCSSValuePairList only in being
1129
// refcounted.  It should not be necessary to use this class directly;
1130
// it's an implementation detail of nsCSSValue.
1131
struct nsCSSValuePairList_heap final : public nsCSSValuePairList {
1132
  NS_INLINE_DECL_REFCOUNTING(nsCSSValuePairList_heap)
1133
1134
  size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
1135
1136
private:
1137
  // Private destructor, to discourage deletion outside of Release():
1138
  ~nsCSSValuePairList_heap()
1139
0
  {
1140
0
  }
1141
};
1142
1143
// This has to be here so that the relationship between nsCSSValuePairList
1144
// and nsCSSValuePairList_heap is visible.
1145
inline nsCSSValuePairList*
1146
nsCSSValue::GetPairListValue()
1147
{
1148
  if (mUnit == eCSSUnit_PairList)
1149
    return mValue.mPairList;
1150
  else {
1151
    MOZ_ASSERT (mUnit == eCSSUnit_PairListDep, "not a pairlist value");
1152
    return mValue.mPairListDependent;
1153
  }
1154
}
1155
1156
inline const nsCSSValuePairList*
1157
nsCSSValue::GetPairListValue() const
1158
0
{
1159
0
  if (mUnit == eCSSUnit_PairList)
1160
0
    return mValue.mPairList;
1161
0
  else {
1162
0
    MOZ_ASSERT (mUnit == eCSSUnit_PairListDep, "not a pairlist value");
1163
0
    return mValue.mPairListDependent;
1164
0
  }
1165
0
}
1166
1167
#endif /* nsCSSValue_h___ */
1168