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/MemoryReporting.h"
15 #include "mozilla/ServoTypes.h"
16 #include "mozilla/SheetType.h"
17 #include "mozilla/StyleComplexColor.h"
18 #include "mozilla/URLExtraData.h"
19 #include "mozilla/UniquePtr.h"
20
21 #include "nsCSSKeywords.h"
22 #include "nsCSSPropertyID.h"
23 #include "nsCSSProps.h"
24 #include "nsColor.h"
25 #include "nsCoord.h"
26 #include "nsProxyRelease.h"
27 #include "nsRefPtrHashtable.h"
28 #include "nsString.h"
29 #include "nsStringBuffer.h"
30 #include "nsTArray.h"
31 #include "nsStyleConsts.h"
32 #include "nsStyleCoord.h"
33 #include "gfxFontFamilyList.h"
34
35 #include <type_traits>
36
37 class imgRequestProxy;
38 class nsAtom;
39 class nsIContent;
40 class nsIDocument;
41 class nsIPrincipal;
42 class nsIURI;
43 class nsPresContext;
44 template <class T>
45 class nsPtrHashKey;
46 struct RustString;
47
48 namespace mozilla {
49 class CSSStyleSheet;
50 } // namespace mozilla
51
52 // Deletes a linked list iteratively to avoid blowing up the stack (bug 456196).
53 #define NS_CSS_DELETE_LIST_MEMBER(type_, ptr_, member_) \
54 { \
55 type_* cur = (ptr_)->member_; \
56 (ptr_)->member_ = nullptr; \
57 while (cur) { \
58 type_* dlm_next = cur->member_; \
59 cur->member_ = nullptr; \
60 delete cur; \
61 cur = dlm_next; \
62 } \
63 }
64 // Ditto, but use NS_RELEASE instead of 'delete' (bug 1221902).
65 #define NS_CSS_NS_RELEASE_LIST_MEMBER(type_, ptr_, member_) \
66 { \
67 type_* cur = (ptr_)->member_; \
68 (ptr_)->member_ = nullptr; \
69 while (cur) { \
70 type_* dlm_next = cur->member_; \
71 cur->member_ = nullptr; \
72 NS_RELEASE(cur); \
73 cur = dlm_next; \
74 } \
75 }
76
77 // Clones a linked list iteratively to avoid blowing up the stack.
78 // If it fails to clone the entire list then 'to_' is deleted and
79 // we return null.
80 #define NS_CSS_CLONE_LIST_MEMBER(type_, from_, member_, to_, args_) \
81 { \
82 type_* dest = (to_); \
83 (to_)->member_ = nullptr; \
84 for (const type_* src = (from_)->member_; src; src = src->member_) { \
85 type_* clm_clone = src->Clone args_; \
86 if (!clm_clone) { \
87 delete (to_); \
88 return nullptr; \
89 } \
90 dest->member_ = clm_clone; \
91 dest = clm_clone; \
92 } \
93 }
94
95 namespace mozilla {
96 namespace css {
97
98 struct URLValueData {
99 protected:
100 // Methods are not inline because using an nsIPrincipal means requiring
101 // caps, which leads to REQUIRES hell, since this header is included all
102 // over.
103
104 // For both constructors aString must not be null.
105 // For both constructors principal of aExtraData must not be null.
106 // Construct with a base URI; this will create the actual URI lazily from
107 // aString and aExtraData.
108 URLValueData(const nsAString& aString,
109 already_AddRefed<URLExtraData> aExtraData, CORSMode aCORSMode);
110 URLValueData(ServoRawOffsetArc<RustString> aString,
111 already_AddRefed<URLExtraData> aExtraData, CORSMode aCORSMode);
112 // Construct with the actual URI.
113 URLValueData(already_AddRefed<PtrHolder<nsIURI>> aURI,
114 const nsAString& aString,
115 already_AddRefed<URLExtraData> aExtraData, CORSMode aCORSMode);
116 URLValueData(already_AddRefed<PtrHolder<nsIURI>> aURI,
117 ServoRawOffsetArc<RustString> aString,
118 already_AddRefed<URLExtraData> aExtraData, CORSMode aCORSMode);
119
120 public:
121 // Returns true iff all fields of the two URLValueData objects are equal.
122 //
123 // Only safe to call on the main thread, since this will call Equals on the
124 // nsIURI and nsIPrincipal objects stored on the URLValueData objects.
125 bool Equals(const URLValueData& aOther) const;
126
127 // Returns true iff we know for sure, by comparing the mBaseURI pointer,
128 // the specified url() value mString, and the mIsLocalRef, that these
129 // two URLValueData objects represent the same computed url() value.
130 //
131 // Doesn't look at mReferrer or mOriginPrincipal.
132 //
133 // Safe to call from any thread.
134 bool DefinitelyEqualURIs(const URLValueData& aOther) const;
135
136 // Smae as DefinitelyEqualURIs but additionally compares the nsIPrincipal
137 // pointers of the two URLValueData objects.
138 bool DefinitelyEqualURIsAndPrincipal(const URLValueData& aOther) const;
139
140 nsIURI* GetURI() const;
141
142 bool IsLocalRef() const;
143
144 bool HasRef() const;
145
146 // This function takes a guess whether the URL has a fragment, by searching
147 // for a hash character. It definitely returns false if we know it can't
148 // have a fragment because it has no hash character.
149 //
150 // MightHaveRef can be used in any thread, whereas HasRef can only be used
151 // in the main thread.
152 bool MightHaveRef() const;
153
154 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(URLValueData)
155
156 // When matching a url with mIsLocalRef set, resolve it against aURI;
157 // Otherwise, ignore aURL and return mURL directly.
158 already_AddRefed<nsIURI> ResolveLocalRef(nsIURI* aURI) const;
159 already_AddRefed<nsIURI> ResolveLocalRef(nsIContent* aContent) const;
160
161 // Serializes mURI as a computed URI value, taking into account mIsLocalRef
162 // and serializing just the fragment if true.
163 void GetSourceString(nsString& aRef) const;
164
165 bool EqualsExceptRef(nsIURI* aURI) const;
166
167 // Can only be called from the main thread. Returns this URL's UTF-16
168 // representation, converting and caching its value if necessary.
169 const nsString& GetUTF16String() const;
170 // Returns this URL's UTF-16 representation, converting if necessary.
171 nsString GetUTF16StringForAnyThread() const;
172
173 bool IsStringEmpty() const;
174
175 private:
176 // mURI stores the lazily resolved URI. This may be null if the URI is
177 // invalid, even once resolved.
178 mutable PtrHandle<nsIURI> mURI;
179
180 public:
181 RefPtr<URLExtraData> mExtraData;
182
183 private:
184 // Returns a substring based on mStrings.mRustString which should not be
185 // exposed to external consumers.
186 nsDependentCSubstring GetRustString() const;
187
188 mutable bool mURIResolved;
189 // mIsLocalRef is set when url starts with a U+0023 number sign(#) character.
190 mutable Maybe<bool> mIsLocalRef;
191 mutable Maybe<bool> mMightHaveRef;
192
193 mutable union RustOrGeckoString {
RustOrGeckoString(const nsAString & aString)194 explicit RustOrGeckoString(const nsAString& aString) : mString(aString) {}
RustOrGeckoString(ServoRawOffsetArc<RustString> aString)195 explicit RustOrGeckoString(ServoRawOffsetArc<RustString> aString)
196 : mRustString(aString) {}
~RustOrGeckoString()197 ~RustOrGeckoString() {}
198 nsString mString;
199 mozilla::ServoRawOffsetArc<RustString> mRustString;
200 } mStrings;
201 mutable bool mUsingRustString;
202
203 protected:
204 // Only used by ImageValue. Declared up here because otherwise bindgen gets
205 // confused by the non-standard-layout packing of the variable up into
206 // URLValueData.
207 bool mLoadedImage = false;
208 const CORSMode mCORSMode;
209
210 virtual ~URLValueData();
211
212 size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
213
214 private:
215 URLValueData(const URLValueData& aOther) = delete;
216 URLValueData& operator=(const URLValueData& aOther) = delete;
217
218 friend struct ImageValue;
219 };
220
221 struct URLValue final : public URLValueData {
222 // These two constructors are safe to call only on the main thread.
223 URLValue(const nsAString& aString, nsIURI* aBaseURI, nsIURI* aReferrer,
224 nsIPrincipal* aOriginPrincipal);
225 URLValue(nsIURI* aURI, const nsAString& aString, nsIURI* aBaseURI,
226 nsIURI* aReferrer, nsIPrincipal* aOriginPrincipal);
227
228 // This constructor is safe to call from any thread.
URLValuefinal229 URLValue(ServoRawOffsetArc<RustString> aString,
230 already_AddRefed<URLExtraData> aExtraData)
231 : URLValueData(aString, Move(aExtraData), CORSMode::CORS_NONE) {}
232
233 URLValue(const URLValue&) = delete;
234 URLValue& operator=(const URLValue&) = delete;
235
236 size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
237 };
238
239 struct ImageValue final : public URLValueData {
240 static ImageValue* CreateFromURLValue(URLValue* url, nsIDocument* aDocument,
241 CORSMode aCORSMode);
242
243 // Not making the constructor and destructor inline because that would
244 // force us to include imgIRequest.h, which leads to REQUIRES hell, since
245 // this header is included all over.
246 //
247 // This constructor is only safe to call from the main thread.
248 ImageValue(nsIURI* aURI, const nsAString& aString,
249 already_AddRefed<URLExtraData> aExtraData, nsIDocument* aDocument,
250 CORSMode aCORSMode);
251
252 // This constructor is only safe to call from the main thread.
253 ImageValue(nsIURI* aURI, ServoRawOffsetArc<RustString> aString,
254 already_AddRefed<URLExtraData> aExtraData, nsIDocument* aDocument,
255 CORSMode aCORSMode);
256
257 // This constructor is safe to call from any thread, but Initialize
258 // must be called later for the object to be useful.
259 ImageValue(const nsAString& aString,
260 already_AddRefed<URLExtraData> aExtraData, CORSMode aCORSMode);
261
262 // This constructor is safe to call from any thread, but Initialize
263 // must be called later for the object to be useful.
264 ImageValue(ServoRawOffsetArc<RustString> aURIString,
265 already_AddRefed<URLExtraData> aExtraData, CORSMode aCORSMode);
266
267 ImageValue(const ImageValue&) = delete;
268 ImageValue& operator=(const ImageValue&) = delete;
269
270 void Initialize(nsIDocument* aDocument);
271
272 size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
273
274 protected:
275 ~ImageValue();
276
277 public:
278 // Inherit Equals from URLValueData
279
280 nsRefPtrHashtable<nsPtrHashKey<nsIDocument>, imgRequestProxy> mRequests;
281 };
282
283 struct GridNamedArea {
284 nsString mName;
285 uint32_t mColumnStart;
286 uint32_t mColumnEnd;
287 uint32_t mRowStart;
288 uint32_t mRowEnd;
289 };
290
291 struct GridTemplateAreasValue final {
292 // Parsed value
293 nsTArray<GridNamedArea> mNamedAreas;
294
295 // Original <string> values. Length gives the number of rows,
296 // content makes serialization easier.
297 nsTArray<nsString> mTemplates;
298
299 // How many columns grid-template-areas contributes to the explicit grid.
300 // http://dev.w3.org/csswg/css-grid/#explicit-grid
301 uint32_t mNColumns;
302
303 // How many rows grid-template-areas contributes to the explicit grid.
304 // http://dev.w3.org/csswg/css-grid/#explicit-grid
NRowsfinal305 uint32_t NRows() const { return mTemplates.Length(); }
306
GridTemplateAreasValuefinal307 GridTemplateAreasValue()
308 : mNColumns(0)
309 // Default constructors for mNamedAreas and mTemplates: empty arrays.
310 {}
311
312 bool operator==(const GridTemplateAreasValue& aOther) const {
313 return mTemplates == aOther.mTemplates;
314 }
315
316 bool operator!=(const GridTemplateAreasValue& aOther) const {
317 return !(*this == aOther);
318 }
319
320 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GridTemplateAreasValue)
321
322 size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
323
324 private:
325 // Private destructor to make sure this isn't used as a stack variable
326 // or member variable.
~GridTemplateAreasValuefinal327 ~GridTemplateAreasValue() {}
328
329 GridTemplateAreasValue(const GridTemplateAreasValue& aOther) = delete;
330 GridTemplateAreasValue& operator=(const GridTemplateAreasValue& aOther) =
331 delete;
332 };
333
334 struct RGBAColorData {
335 // 1.0 means 100% for all components, but the value may fall outside
336 // the range of [0.0, 1.0], so it is necessary to clamp them when
337 // converting to nscolor.
338 float mR;
339 float mG;
340 float mB;
341 float mA;
342
343 RGBAColorData() = default;
RGBAColorDataRGBAColorData344 MOZ_IMPLICIT RGBAColorData(nscolor aColor)
345 : mR(NS_GET_R(aColor) * (1.0f / 255.0f)),
346 mG(NS_GET_G(aColor) * (1.0f / 255.0f)),
347 mB(NS_GET_B(aColor) * (1.0f / 255.0f)),
348 mA(NS_GET_A(aColor) * (1.0f / 255.0f)) {}
RGBAColorDataRGBAColorData349 RGBAColorData(float aR, float aG, float aB, float aA)
350 : mR(aR), mG(aG), mB(aB), mA(aA) {}
351
352 bool operator==(const RGBAColorData& aOther) const {
353 return mR == aOther.mR && mG == aOther.mG && mB == aOther.mB &&
354 mA == aOther.mA;
355 }
356 bool operator!=(const RGBAColorData& aOther) const {
357 return !(*this == aOther);
358 }
359
ToColorRGBAColorData360 nscolor ToColor() const {
361 return NS_RGBA(ClampColor(mR * 255.0f), ClampColor(mG * 255.0f),
362 ClampColor(mB * 255.0f), ClampColor(mA * 255.0f));
363 }
364
WithAlphaRGBAColorData365 RGBAColorData WithAlpha(float aAlpha) const {
366 RGBAColorData result = *this;
367 result.mA = aAlpha;
368 return result;
369 }
370 };
371
372 struct ComplexColorData {
373 RGBAColorData mColor;
374 float mForegroundRatio;
375
376 ComplexColorData() = default;
ComplexColorDataComplexColorData377 ComplexColorData(const RGBAColorData& aColor, float aForegroundRatio)
378 : mColor(aColor), mForegroundRatio(aForegroundRatio) {}
ComplexColorDataComplexColorData379 ComplexColorData(nscolor aColor, float aForegroundRatio)
380 : mColor(aColor), mForegroundRatio(aForegroundRatio) {}
ComplexColorDataComplexColorData381 explicit ComplexColorData(const StyleComplexColor& aColor)
382 : mColor(aColor.mColor),
383 mForegroundRatio(aColor.mForegroundRatio * (1.0f / 255.0f)) {}
384
385 bool operator==(const ComplexColorData& aOther) const {
386 return mForegroundRatio == aOther.mForegroundRatio &&
387 (IsCurrentColor() || mColor == aOther.mColor);
388 }
389 bool operator!=(const ComplexColorData& aOther) const {
390 return !(*this == aOther);
391 }
392
IsCurrentColorComplexColorData393 bool IsCurrentColor() const { return mForegroundRatio >= 1.0f; }
IsNumericColorComplexColorData394 bool IsNumericColor() const { return mForegroundRatio <= 0.0f; }
395
ToComplexColorComplexColorData396 StyleComplexColor ToComplexColor() const {
397 return {mColor.ToColor(), ClampColor(mForegroundRatio * 255.0f)};
398 }
399 };
400
401 struct ComplexColorValue final : public ComplexColorData {
402 // Just redirect any parameter to the data struct.
403 template <typename... Args>
ComplexColorValuefinal404 explicit ComplexColorValue(Args&&... aArgs)
405 : ComplexColorData(Forward<Args>(aArgs)...) {}
406 ComplexColorValue(const ComplexColorValue&) = delete;
407
408 NS_INLINE_DECL_REFCOUNTING(ComplexColorValue)
409
410 size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const;
411
412 private:
~ComplexColorValuefinal413 ~ComplexColorValue() {}
414 };
415
416 } // namespace css
417 } // namespace mozilla
418
419 enum nsCSSUnit {
420 eCSSUnit_Null = 0, // (n/a) null unit, value is not specified
421 eCSSUnit_Auto = 1, // (n/a) value is algorithmic
422 eCSSUnit_Inherit = 2, // (n/a) value is inherited
423 eCSSUnit_Initial = 3, // (n/a) value is default UA value
424 eCSSUnit_Unset = 4, // (n/a) value equivalent to 'initial' if on a reset
425 // property, 'inherit' otherwise
426 eCSSUnit_None = 5, // (n/a) value is none
427 eCSSUnit_Normal =
428 6, // (n/a) value is normal (algorithmic, different than auto)
429 eCSSUnit_System_Font = 7, // (n/a) value is -moz-use-system-font
430 eCSSUnit_All = 8, // (n/a) value is all
431 eCSSUnit_Dummy = 9, // (n/a) a fake but specified value, used
432 // only in temporary values
433 eCSSUnit_DummyInherit = 10, // (n/a) a fake but specified value, used
434 // only in temporary values
435
436 eCSSUnit_String = 11, // (char16_t*) a string value
437 eCSSUnit_Ident = 12, // (char16_t*) a string value
438 eCSSUnit_Attr = 14, // (char16_t*) a attr(string) value
439 eCSSUnit_Local_Font = 15, // (char16_t*) a local font name
440 eCSSUnit_Font_Format = 16, // (char16_t*) a font format name
441 eCSSUnit_Element = 17, // (char16_t*) an element id
442
443 eCSSUnit_Array = 20, // (nsCSSValue::Array*) a list of values
444 eCSSUnit_Counter =
445 21, // (nsCSSValue::Array*) a counter(string,[string]) value
446 eCSSUnit_Counters =
447 22, // (nsCSSValue::Array*) a counters(string,string[,string]) value
448 eCSSUnit_Cubic_Bezier = 23, // (nsCSSValue::Array*) a list of float values
449 eCSSUnit_Steps = 24, // (nsCSSValue::Array*) a list of (integer, enumerated)
450 eCSSUnit_Symbols =
451 25, // (nsCSSValue::Array*) a symbols(enumerated, symbols) value
452 eCSSUnit_Function = 26, // (nsCSSValue::Array*) a function with
453 // parameters. First elem of array is name,
454 // an nsCSSKeyword as eCSSUnit_Enumerated,
455 // the rest of the values are arguments.
456
457 // The top level of a calc() expression is eCSSUnit_Calc. All
458 // remaining eCSSUnit_Calc_* units only occur inside these toplevel
459 // calc values.
460
461 // eCSSUnit_Calc has an array with exactly 1 element. eCSSUnit_Calc
462 // exists so we can distinguish calc(2em) from 2em as specified values
463 // (but we drop this distinction for nsStyleCoord when we store
464 // computed values).
465 eCSSUnit_Calc = 30, // (nsCSSValue::Array*) calc() value
466 // Plus, Minus, Times_* and Divided have arrays with exactly 2
467 // elements. a + b + c + d is grouped as ((a + b) + c) + d
468 eCSSUnit_Calc_Plus = 31, // (nsCSSValue::Array*) + node within calc()
469 eCSSUnit_Calc_Minus = 32, // (nsCSSValue::Array*) - within calc
470 eCSSUnit_Calc_Times_L = 33, // (nsCSSValue::Array*) num * val within calc
471 eCSSUnit_Calc_Times_R = 34, // (nsCSSValue::Array*) val * num within calc
472 eCSSUnit_Calc_Divided = 35, // (nsCSSValue::Array*) / within calc
473
474 eCSSUnit_URL = 40, // (nsCSSValue::URL*) value
475 eCSSUnit_Image = 41, // (nsCSSValue::Image*) value
476 eCSSUnit_Gradient = 42, // (nsCSSValueGradient*) value
477 eCSSUnit_TokenStream = 43, // (nsCSSValueTokenStream*) value
478 eCSSUnit_GridTemplateAreas = 44, // (GridTemplateAreasValue*)
479 // for grid-template-areas
480
481 eCSSUnit_Pair = 50, // (nsCSSValuePair*) pair of values
482 eCSSUnit_Triplet = 51, // (nsCSSValueTriplet*) triplet of values
483 eCSSUnit_Rect = 52, // (nsCSSRect*) rectangle (four values)
484 eCSSUnit_List = 53, // (nsCSSValueList*) list of values
485 eCSSUnit_ListDep = 54, // (nsCSSValueList*) same as List
486 // but does not own the list
487 eCSSUnit_SharedList = 55, // (nsCSSValueSharedList*) same as list
488 // but reference counted and shared
489 eCSSUnit_PairList = 56, // (nsCSSValuePairList*) list of value pairs
490 eCSSUnit_PairListDep = 57, // (nsCSSValuePairList*) same as PairList
491 // but does not own the list
492
493 eCSSUnit_FontFamilyList = 58, // (SharedFontList*) value
494
495 // Atom units
496 eCSSUnit_AtomIdent = 60, // (nsAtom*) for its string as an identifier
497
498 eCSSUnit_Integer = 70, // (int) simple value
499 eCSSUnit_Enumerated = 71, // (int) value has enumerated meaning
500
501 eCSSUnit_EnumColor = 80, // (int) enumerated color (kColorKTable)
502 eCSSUnit_RGBColor = 81, // (nscolor) an opaque RGBA value specified as rgb()
503 eCSSUnit_RGBAColor = 82, // (nscolor) an RGBA value specified as rgba()
504 eCSSUnit_HexColor =
505 83, // (nscolor) an opaque RGBA value specified as #rrggbb
506 eCSSUnit_ShortHexColor =
507 84, // (nscolor) an opaque RGBA value specified as #rgb
508 eCSSUnit_HexColorAlpha =
509 85, // (nscolor) an opaque RGBA value specified as #rrggbbaa
510 eCSSUnit_ShortHexColorAlpha =
511 86, // (nscolor) an opaque RGBA value specified as #rgba
512 eCSSUnit_PercentageRGBColor = 87, // (nsCSSValueFloatColor*) an opaque
513 // RGBA value specified as rgb() with
514 // percentage components. Values over
515 // 100% are allowed.
516 eCSSUnit_PercentageRGBAColor = 88, // (nsCSSValueFloatColor*) an RGBA value
517 // specified as rgba() with percentage
518 // components. Values over 100% are
519 // allowed.
520 eCSSUnit_HSLColor = 89, // (nsCSSValueFloatColor*)
521 eCSSUnit_HSLAColor = 90, // (nsCSSValueFloatColor*)
522 eCSSUnit_ComplexColor = 91, // (ComplexColorValue*)
523
524 eCSSUnit_Percent =
525 100, // (float) 1.0 == 100%) value is percentage of something
526 eCSSUnit_Number = 101, // (float) value is numeric (usually multiplier,
527 // different behavior than percent)
528
529 // Length units - relative
530 // Viewport relative measure
531 eCSSUnit_ViewportWidth =
532 700, // (float) 1% of the width of the initial containing block
533 eCSSUnit_ViewportHeight =
534 701, // (float) 1% of the height of the initial containing block
535 eCSSUnit_ViewportMin =
536 702, // (float) smaller of ViewportWidth and ViewportHeight
537 eCSSUnit_ViewportMax =
538 703, // (float) larger of ViewportWidth and ViewportHeight
539
540 // Font relative measure
541 eCSSUnit_EM = 800, // (float) == current font size
542 eCSSUnit_XHeight =
543 801, // (float) distance from top of lower case x to baseline
544 eCSSUnit_Char =
545 802, // (float) number of characters, used for width with monospace font
546 eCSSUnit_RootEM = 803, // (float) == root element font size
547
548 // Screen relative measure
549 eCSSUnit_Point = 900, // (float) 4/3 of a CSS pixel
550 eCSSUnit_Inch = 901, // (float) 96 CSS pixels
551 eCSSUnit_Millimeter = 902, // (float) 96/25.4 CSS pixels
552 eCSSUnit_Centimeter = 903, // (float) 96/2.54 CSS pixels
553 eCSSUnit_Pica = 904, // (float) 12 points == 16 CSS pixls
554 eCSSUnit_Quarter = 905, // (float) 96/101.6 CSS pixels
555 eCSSUnit_Pixel = 906, // (float) CSS pixel unit
556
557 // Angular units
558 eCSSUnit_Degree = 1000, // (float) 360 per circle
559 eCSSUnit_Grad = 1001, // (float) 400 per circle
560 eCSSUnit_Radian = 1002, // (float) 2*pi per circle
561 eCSSUnit_Turn = 1003, // (float) 1 per circle
562
563 // Frequency units
564 eCSSUnit_Hertz = 2000, // (float) 1/seconds
565 eCSSUnit_Kilohertz = 2001, // (float) 1000 Hertz
566
567 // Time units
568 eCSSUnit_Seconds = 3000, // (float) Standard time
569 eCSSUnit_Milliseconds = 3001, // (float) 1/1000 second
570
571 // Flexible fraction (CSS Grid)
572 eCSSUnit_FlexFraction = 4000 // (float) Fraction of free space
573 };
574
575 struct nsCSSValueGradient;
576 struct nsCSSValuePair;
577 struct nsCSSValuePair_heap;
578 struct nsCSSValueTokenStream;
579 struct nsCSSRect;
580 struct nsCSSRect_heap;
581 struct nsCSSValueList;
582 struct nsCSSValueList_heap;
583 struct nsCSSValueSharedList;
584 struct nsCSSValuePairList;
585 struct nsCSSValuePairList_heap;
586 struct nsCSSValueTriplet;
587 struct nsCSSValueTriplet_heap;
588 class nsCSSValueFloatColor;
589
590 class nsCSSValue {
591 public:
592 struct Array;
593 friend struct Array;
594
595 friend struct mozilla::css::URLValueData;
596
597 friend struct mozilla::css::ImageValue;
598
599 // for valueless units only (null, auto, inherit, none, all, normal)
mUnit(aUnit)600 explicit nsCSSValue(nsCSSUnit aUnit = eCSSUnit_Null) : mUnit(aUnit) {
601 MOZ_ASSERT(aUnit <= eCSSUnit_DummyInherit, "not a valueless unit");
602 }
603
604 nsCSSValue(int32_t aValue, nsCSSUnit aUnit);
605 nsCSSValue(float aValue, nsCSSUnit aUnit);
606 nsCSSValue(const nsString& aValue, nsCSSUnit aUnit);
607 nsCSSValue(Array* aArray, nsCSSUnit aUnit);
608 explicit nsCSSValue(mozilla::css::URLValue* aValue);
609 explicit nsCSSValue(mozilla::css::ImageValue* aValue);
610 explicit nsCSSValue(nsCSSValueGradient* aValue);
611 explicit nsCSSValue(nsCSSValueTokenStream* aValue);
612 explicit nsCSSValue(mozilla::css::GridTemplateAreasValue* aValue);
613 explicit nsCSSValue(mozilla::SharedFontList* aValue);
614 nsCSSValue(const nsCSSValue& aCopy);
nsCSSValue(nsCSSValue && aOther)615 nsCSSValue(nsCSSValue&& aOther) : mUnit(aOther.mUnit), mValue(aOther.mValue) {
616 aOther.mUnit = eCSSUnit_Null;
617 }
618 template <typename T,
619 typename = typename std::enable_if<std::is_enum<T>::value>::type>
nsCSSValue(T aValue)620 explicit nsCSSValue(T aValue) : mUnit(eCSSUnit_Enumerated) {
621 static_assert(mozilla::EnumTypeFitsWithin<T, int32_t>::value,
622 "aValue must be an enum that fits within mValue.mInt");
623 mValue.mInt = static_cast<int32_t>(aValue);
624 }
625
~nsCSSValue()626 ~nsCSSValue() { Reset(); }
627
628 nsCSSValue& operator=(const nsCSSValue& aCopy);
629 nsCSSValue& operator=(nsCSSValue&& aCopy);
630 bool operator==(const nsCSSValue& aOther) const;
631
632 bool operator!=(const nsCSSValue& aOther) const { return !(*this == aOther); }
633
634 /**
635 * Serialize |this| as a specified value for |aProperty| and append
636 * it to |aResult|.
637 */
638 void AppendToString(nsCSSPropertyID aProperty, nsAString& aResult) const;
639
GetUnit()640 nsCSSUnit GetUnit() const { return mUnit; }
IsLengthUnit()641 bool IsLengthUnit() const {
642 return eCSSUnit_ViewportWidth <= mUnit && mUnit <= eCSSUnit_Pixel;
643 }
IsLengthPercentCalcUnit()644 bool IsLengthPercentCalcUnit() const {
645 return IsLengthUnit() || mUnit == eCSSUnit_Percent || IsCalcUnit();
646 }
647 /**
648 * What the spec calls relative length units is, for us, split
649 * between relative length units and pixel length units.
650 *
651 * A "relative" length unit is a multiple of some derived metric,
652 * such as a font em-size, which itself was controlled by an input CSS
653 * length. Relative length units should not be scaled by zooming, since
654 * the underlying CSS length would already have been scaled.
655 */
IsRelativeLengthUnit()656 bool IsRelativeLengthUnit() const {
657 return eCSSUnit_EM <= mUnit && mUnit <= eCSSUnit_RootEM;
658 }
659 /**
660 * A "pixel" length unit is a some multiple of CSS pixels.
661 */
IsPixelLengthUnit(nsCSSUnit aUnit)662 static bool IsPixelLengthUnit(nsCSSUnit aUnit) {
663 return eCSSUnit_Point <= aUnit && aUnit <= eCSSUnit_Pixel;
664 }
IsPixelLengthUnit()665 bool IsPixelLengthUnit() const { return IsPixelLengthUnit(mUnit); }
IsPercentLengthUnit(nsCSSUnit aUnit)666 static bool IsPercentLengthUnit(nsCSSUnit aUnit) {
667 return aUnit == eCSSUnit_Percent;
668 }
IsPercentLengthUnit()669 bool IsPercentLengthUnit() { return IsPercentLengthUnit(mUnit); }
IsFloatUnit(nsCSSUnit aUnit)670 static bool IsFloatUnit(nsCSSUnit aUnit) { return eCSSUnit_Number <= aUnit; }
IsAngularUnit()671 bool IsAngularUnit() const {
672 return eCSSUnit_Degree <= mUnit && mUnit <= eCSSUnit_Turn;
673 }
IsFrequencyUnit()674 bool IsFrequencyUnit() const {
675 return eCSSUnit_Hertz <= mUnit && mUnit <= eCSSUnit_Kilohertz;
676 }
IsTimeUnit()677 bool IsTimeUnit() const {
678 return eCSSUnit_Seconds <= mUnit && mUnit <= eCSSUnit_Milliseconds;
679 }
IsCalcUnit()680 bool IsCalcUnit() const {
681 return eCSSUnit_Calc <= mUnit && mUnit <= eCSSUnit_Calc_Divided;
682 }
683
UnitHasStringValue()684 bool UnitHasStringValue() const {
685 return eCSSUnit_String <= mUnit && mUnit <= eCSSUnit_Element;
686 }
UnitHasArrayValue()687 bool UnitHasArrayValue() const {
688 return eCSSUnit_Array <= mUnit && mUnit <= eCSSUnit_Calc_Divided;
689 }
690
691 // Checks for the nsCSSValue being of a particular type of color unit:
692 //
693 // - IsIntegerColorUnit returns true for:
694 // eCSSUnit_RGBColor -- rgb(int,int,int)
695 // eCSSUnit_RGBAColor -- rgba(int,int,int,float)
696 // eCSSUnit_HexColor -- #rrggbb
697 // eCSSUnit_ShortHexColor -- #rgb
698 // eCSSUnit_HexColorAlpha -- #rrggbbaa
699 // eCSSUnit_ShortHexColorAlpha -- #rgba
700 //
701 // - IsFloatColorUnit returns true for:
702 // eCSSUnit_PercentageRGBColor -- rgb(%,%,%)
703 // eCSSUnit_PercentageRGBAColor -- rgba(%,%,%,float)
704 // eCSSUnit_HSLColor -- hsl(float,%,%)
705 // eCSSUnit_HSLAColor -- hsla(float,%,%,float)
706 //
707 // - IsNumericColorUnit returns true for any of the above units.
708 //
709 // Note that color keywords and system colors are represented by
710 // eCSSUnit_EnumColor and eCSSUnit_Ident.
IsIntegerColorUnit()711 bool IsIntegerColorUnit() const { return IsIntegerColorUnit(mUnit); }
IsFloatColorUnit()712 bool IsFloatColorUnit() const { return IsFloatColorUnit(mUnit); }
IsNumericColorUnit()713 bool IsNumericColorUnit() const { return IsNumericColorUnit(mUnit); }
IsIntegerColorUnit(nsCSSUnit aUnit)714 static bool IsIntegerColorUnit(nsCSSUnit aUnit) {
715 return eCSSUnit_RGBColor <= aUnit && aUnit <= eCSSUnit_ShortHexColorAlpha;
716 }
IsFloatColorUnit(nsCSSUnit aUnit)717 static bool IsFloatColorUnit(nsCSSUnit aUnit) {
718 return eCSSUnit_PercentageRGBColor <= aUnit && aUnit <= eCSSUnit_HSLAColor;
719 }
IsNumericColorUnit(nsCSSUnit aUnit)720 static bool IsNumericColorUnit(nsCSSUnit aUnit) {
721 return IsIntegerColorUnit(aUnit) || IsFloatColorUnit(aUnit);
722 }
723
GetIntValue()724 int32_t GetIntValue() const {
725 MOZ_ASSERT(mUnit == eCSSUnit_Integer || mUnit == eCSSUnit_Enumerated ||
726 mUnit == eCSSUnit_EnumColor,
727 "not an int value");
728 return mValue.mInt;
729 }
730
GetKeywordValue()731 nsCSSKeyword GetKeywordValue() const {
732 MOZ_ASSERT(mUnit == eCSSUnit_Enumerated, "not a keyword value");
733 return static_cast<nsCSSKeyword>(mValue.mInt);
734 }
735
GetPercentValue()736 float GetPercentValue() const {
737 MOZ_ASSERT(mUnit == eCSSUnit_Percent, "not a percent value");
738 return mValue.mFloat;
739 }
740
GetFloatValue()741 float GetFloatValue() const {
742 MOZ_ASSERT(eCSSUnit_Number <= mUnit, "not a float value");
743 MOZ_ASSERT(!mozilla::IsNaN(mValue.mFloat));
744 return mValue.mFloat;
745 }
746
GetAngleValue()747 float GetAngleValue() const {
748 MOZ_ASSERT(eCSSUnit_Degree <= mUnit && mUnit <= eCSSUnit_Turn,
749 "not an angle value");
750 return mValue.mFloat;
751 }
752
753 // Converts any angle to radians.
754 double GetAngleValueInRadians() const;
755
756 // Converts any angle to degrees.
757 double GetAngleValueInDegrees() const;
758
GetStringValue(nsAString & aBuffer)759 nsAString& GetStringValue(nsAString& aBuffer) const {
760 MOZ_ASSERT(UnitHasStringValue(), "not a string value");
761 aBuffer.Truncate();
762 uint32_t len = NS_strlen(GetBufferValue(mValue.mString));
763 mValue.mString->ToString(len, aBuffer);
764 return aBuffer;
765 }
766
GetStringBufferValue()767 const char16_t* GetStringBufferValue() const {
768 MOZ_ASSERT(UnitHasStringValue(), "not a string value");
769 return GetBufferValue(mValue.mString);
770 }
771
772 nscolor GetColorValue() const;
773 bool IsNonTransparentColor() const;
GetStyleComplexColorValue()774 mozilla::StyleComplexColor GetStyleComplexColorValue() const {
775 MOZ_ASSERT(mUnit == eCSSUnit_ComplexColor);
776 return mValue.mComplexColor->ToComplexColor();
777 }
778
GetArrayValue()779 Array* GetArrayValue() const {
780 MOZ_ASSERT(UnitHasArrayValue(), "not an array value");
781 return mValue.mArray;
782 }
783
GetURLValue()784 nsIURI* GetURLValue() const {
785 MOZ_ASSERT(mUnit == eCSSUnit_URL || mUnit == eCSSUnit_Image,
786 "not a URL value");
787 return mUnit == eCSSUnit_URL ? mValue.mURL->GetURI()
788 : mValue.mImage->GetURI();
789 }
790
GetGradientValue()791 nsCSSValueGradient* GetGradientValue() const {
792 MOZ_ASSERT(mUnit == eCSSUnit_Gradient, "not a gradient value");
793 return mValue.mGradient;
794 }
795
GetTokenStreamValue()796 nsCSSValueTokenStream* GetTokenStreamValue() const {
797 MOZ_ASSERT(mUnit == eCSSUnit_TokenStream, "not a token stream value");
798 return mValue.mTokenStream;
799 }
800
GetSharedListValue()801 nsCSSValueSharedList* GetSharedListValue() const {
802 MOZ_ASSERT(mUnit == eCSSUnit_SharedList, "not a shared list value");
803 return mValue.mSharedList;
804 }
805
GetFontFamilyListValue()806 mozilla::NotNull<mozilla::SharedFontList*> GetFontFamilyListValue() const {
807 MOZ_ASSERT(mUnit == eCSSUnit_FontFamilyList,
808 "not a font family list value");
809 NS_ASSERTION(mValue.mFontFamilyList != nullptr,
810 "font family list value should never be null");
811 return mozilla::WrapNotNull(mValue.mFontFamilyList);
812 }
813
814 // bodies of these are below
815 inline nsCSSValuePair& GetPairValue();
816 inline const nsCSSValuePair& GetPairValue() const;
817
818 inline nsCSSRect& GetRectValue();
819 inline const nsCSSRect& GetRectValue() const;
820
821 inline nsCSSValueList* GetListValue();
822 inline const nsCSSValueList* GetListValue() const;
823
824 inline nsCSSValuePairList* GetPairListValue();
825 inline const nsCSSValuePairList* GetPairListValue() const;
826
827 inline nsCSSValueTriplet& GetTripletValue();
828 inline const nsCSSValueTriplet& GetTripletValue() const;
829
GetURLStructValue()830 mozilla::css::URLValue* GetURLStructValue() const {
831 // Not allowing this for Image values, because if the caller takes
832 // a ref to them they won't be able to delete them properly.
833 MOZ_ASSERT(mUnit == eCSSUnit_URL, "not a URL value");
834 return mValue.mURL;
835 }
836
GetImageStructValue()837 mozilla::css::ImageValue* GetImageStructValue() const {
838 MOZ_ASSERT(mUnit == eCSSUnit_Image, "not an Image value");
839 return mValue.mImage;
840 }
841
GetGridTemplateAreas()842 mozilla::css::GridTemplateAreasValue* GetGridTemplateAreas() const {
843 MOZ_ASSERT(mUnit == eCSSUnit_GridTemplateAreas,
844 "not a grid-template-areas value");
845 return mValue.mGridTemplateAreas;
846 }
847
GetOriginalURLValue()848 const char16_t* GetOriginalURLValue() const {
849 MOZ_ASSERT(mUnit == eCSSUnit_URL || mUnit == eCSSUnit_Image,
850 "not a URL value");
851 return mUnit == eCSSUnit_URL ? mValue.mURL->GetUTF16String().get()
852 : mValue.mImage->GetUTF16String().get();
853 }
854
855 // Not making this inline because that would force us to include
856 // imgIRequest.h, which leads to REQUIRES hell, since this header is included
857 // all over.
858 imgRequestProxy* GetImageValue(nsIDocument* aDocument) const;
859
860 // Like GetImageValue, but additionally will pass the imgRequestProxy
861 // through nsContentUtils::GetStaticRequest if aPresContent is static.
862 already_AddRefed<imgRequestProxy> GetPossiblyStaticImageValue(
863 nsIDocument* aDocument, nsPresContext* aPresContext) const;
864
865 nscoord GetPixelLength() const;
866
GetFloatColorValue()867 nsCSSValueFloatColor* GetFloatColorValue() const {
868 MOZ_ASSERT(IsFloatColorUnit(), "not a float color value");
869 return mValue.mFloatColor;
870 }
871
GetAtomValue()872 nsAtom* GetAtomValue() const {
873 MOZ_ASSERT(mUnit == eCSSUnit_AtomIdent);
874 return mValue.mAtom;
875 }
876
Reset()877 void Reset() // sets to null
878 {
879 if (mUnit != eCSSUnit_Null) DoReset();
880 }
881
882 private:
883 void DoReset();
884
885 public:
886 void SetIntValue(int32_t aValue, nsCSSUnit aUnit);
887 template <typename T,
888 typename = typename std::enable_if<std::is_enum<T>::value>::type>
SetEnumValue(T aValue)889 void SetEnumValue(T aValue) {
890 static_assert(mozilla::EnumTypeFitsWithin<T, int32_t>::value,
891 "aValue must be an enum that fits within mValue.mInt");
892 SetIntValue(static_cast<int32_t>(aValue), eCSSUnit_Enumerated);
893 }
894 void SetPercentValue(float aValue);
895 void SetFloatValue(float aValue, nsCSSUnit aUnit);
896 void SetStringValue(const nsString& aValue, nsCSSUnit aUnit);
897 void SetAtomIdentValue(already_AddRefed<nsAtom> aValue);
898 void SetColorValue(nscolor aValue);
899 void SetIntegerColorValue(nscolor aValue, nsCSSUnit aUnit);
900 // converts the nscoord to pixels
901 void SetIntegerCoordValue(nscoord aCoord);
902 void SetFloatColorValue(float aComponent1, float aComponent2,
903 float aComponent3, float aAlpha, nsCSSUnit aUnit);
904 void SetRGBAColorValue(const mozilla::css::RGBAColorData& aValue);
905 void SetComplexColorValue(
906 already_AddRefed<mozilla::css::ComplexColorValue> aValue);
907 void SetArrayValue(nsCSSValue::Array* aArray, nsCSSUnit aUnit);
908 void SetURLValue(mozilla::css::URLValue* aURI);
909 void SetImageValue(mozilla::css::ImageValue* aImage);
910 void SetGradientValue(nsCSSValueGradient* aGradient);
911 void SetTokenStreamValue(nsCSSValueTokenStream* aTokenStream);
912 void SetGridTemplateAreas(mozilla::css::GridTemplateAreasValue* aValue);
913 void SetFontFamilyListValue(
914 already_AddRefed<mozilla::SharedFontList> aFontListValue);
915 void SetPairValue(const nsCSSValuePair* aPair);
916 void SetPairValue(const nsCSSValue& xValue, const nsCSSValue& yValue);
917 void SetSharedListValue(nsCSSValueSharedList* aList);
918 void SetDependentListValue(nsCSSValueList* aList);
919 void SetDependentPairListValue(nsCSSValuePairList* aList);
920 void SetTripletValue(const nsCSSValueTriplet* aTriplet);
921 void SetTripletValue(const nsCSSValue& xValue, const nsCSSValue& yValue,
922 const nsCSSValue& zValue);
923 void SetAutoValue();
924 void SetInheritValue();
925 void SetInitialValue();
926 void SetUnsetValue();
927 void SetNoneValue();
928 void SetAllValue();
929 void SetNormalValue();
930 void SetSystemFontValue();
931 void SetDummyValue();
932 void SetDummyInheritValue();
933
934 // Converts an nsStyleCoord::CalcValue back into a CSSValue
935 void SetCalcValue(const nsStyleCoord::CalcValue* aCalc);
936
937 nsStyleCoord::CalcValue GetCalcValue() const;
938
939 // These are a little different - they allocate storage for you and
940 // return a handle.
941 nsCSSRect& SetRectValue();
942 nsCSSValueList* SetListValue();
943 nsCSSValuePairList* SetPairListValue();
944
945 // These take ownership of the passed-in resource.
946 void AdoptListValue(mozilla::UniquePtr<nsCSSValueList> aValue);
947 void AdoptPairListValue(mozilla::UniquePtr<nsCSSValuePairList> aValue);
948
949 void StartImageLoad(nsIDocument* aDocument,
950 mozilla::CORSMode aCORSMode) const; // Only pretend const
951
952 // Initializes as a function value with the specified function id.
953 Array* InitFunction(nsCSSKeyword aFunctionId, uint32_t aNumArgs);
954 // Checks if this is a function value with the specified function id.
955 bool EqualsFunction(nsCSSKeyword aFunctionId) const;
956
957 // Returns an already addrefed buffer. Guaranteed to return non-null.
958 // (Will abort on allocation failure.)
959 static already_AddRefed<nsStringBuffer> BufferFromString(
960 const nsString& aValue);
961
962 // Convert the given Ident value into AtomIdent.
963 void AtomizeIdentValue();
964
965 size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
966
967 static void AppendSidesShorthandToString(const nsCSSPropertyID aProperties[],
968 const nsCSSValue* aValues[],
969 nsAString& aString);
970 static void AppendBasicShapeRadiusToString(
971 const nsCSSPropertyID aProperties[], const nsCSSValue* aValues[],
972 nsAString& aResult);
973 static void AppendAlignJustifyValueToString(int32_t aValue,
974 nsAString& aResult);
975
976 private:
GetBufferValue(nsStringBuffer * aBuffer)977 static const char16_t* GetBufferValue(nsStringBuffer* aBuffer) {
978 return static_cast<char16_t*>(aBuffer->Data());
979 }
980
981 void AppendPolygonToString(nsCSSPropertyID aProperty,
982 nsAString& aResult) const;
983 void AppendPositionCoordinateToString(const nsCSSValue& aValue,
984 nsCSSPropertyID aProperty,
985 nsAString& aResult) const;
986 void AppendCircleOrEllipseToString(nsCSSKeyword aFunctionId,
987 nsCSSPropertyID aProperty,
988 nsAString& aResult) const;
989 void AppendBasicShapePositionToString(nsAString& aResult) const;
990 void AppendInsetToString(nsCSSPropertyID aProperty, nsAString& aResult) const;
991
992 protected:
993 nsCSSUnit mUnit;
994 union {
995 int32_t mInt;
996 float mFloat;
997 // Note: the capacity of the buffer may exceed the length of the string.
998 // If we're of a string type, mString is not null.
999 nsStringBuffer* MOZ_OWNING_REF mString;
1000 nscolor mColor;
1001 nsAtom* MOZ_OWNING_REF mAtom;
1002 Array* MOZ_OWNING_REF mArray;
1003 mozilla::css::URLValue* MOZ_OWNING_REF mURL;
1004 mozilla::css::ImageValue* MOZ_OWNING_REF mImage;
1005 mozilla::css::GridTemplateAreasValue* MOZ_OWNING_REF mGridTemplateAreas;
1006 nsCSSValueGradient* MOZ_OWNING_REF mGradient;
1007 nsCSSValueTokenStream* MOZ_OWNING_REF mTokenStream;
1008 nsCSSValuePair_heap* MOZ_OWNING_REF mPair;
1009 nsCSSRect_heap* MOZ_OWNING_REF mRect;
1010 nsCSSValueTriplet_heap* MOZ_OWNING_REF mTriplet;
1011 nsCSSValueList_heap* MOZ_OWNING_REF mList;
1012 nsCSSValueList* mListDependent;
1013 nsCSSValueSharedList* MOZ_OWNING_REF mSharedList;
1014 nsCSSValuePairList_heap* MOZ_OWNING_REF mPairList;
1015 nsCSSValuePairList* mPairListDependent;
1016 nsCSSValueFloatColor* MOZ_OWNING_REF mFloatColor;
1017 mozilla::SharedFontList* MOZ_OWNING_REF mFontFamilyList;
1018 mozilla::css::ComplexColorValue* MOZ_OWNING_REF mComplexColor;
1019 } mValue;
1020 };
1021
1022 struct nsCSSValue::Array final {
1023 // return |Array| with reference count of zero
Createfinal1024 static Array* Create(size_t aItemCount) {
1025 return new (aItemCount) Array(aItemCount);
1026 }
1027
1028 nsCSSValue& operator[](size_t aIndex) {
1029 MOZ_ASSERT(aIndex < mCount, "out of range");
1030 return mArray[aIndex];
1031 }
1032
1033 const nsCSSValue& operator[](size_t aIndex) const {
1034 MOZ_ASSERT(aIndex < mCount, "out of range");
1035 return mArray[aIndex];
1036 }
1037
Itemfinal1038 nsCSSValue& Item(size_t aIndex) { return (*this)[aIndex]; }
Itemfinal1039 const nsCSSValue& Item(size_t aIndex) const { return (*this)[aIndex]; }
1040
Countfinal1041 size_t Count() const { return mCount; }
1042
1043 // callers depend on the items being contiguous
ItemStoragefinal1044 nsCSSValue* ItemStorage() { return this->First(); }
1045
1046 bool operator==(const Array& aOther) const {
1047 if (mCount != aOther.mCount) return false;
1048 for (size_t i = 0; i < mCount; ++i)
1049 if ((*this)[i] != aOther[i]) return false;
1050 return true;
1051 }
1052
1053 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(Array);
1054
1055 private:
1056 const size_t mCount;
1057 // This must be the last sub-object, since we extend this array to
1058 // be of size mCount; it needs to be a sub-object so it gets proper
1059 // alignment.
1060 nsCSSValue mArray[1];
1061
newfinal1062 void* operator new(size_t aSelfSize, size_t aItemCount) CPP_THROW_NEW {
1063 MOZ_ASSERT(aItemCount > 0, "cannot have a 0 item count");
1064 return ::operator new(aSelfSize + sizeof(nsCSSValue) * (aItemCount - 1));
1065 }
1066
deletefinal1067 void operator delete(void* aPtr) { ::operator delete(aPtr); }
1068
Firstfinal1069 nsCSSValue* First() { return mArray; }
1070
Firstfinal1071 const nsCSSValue* First() const { return mArray; }
1072
1073 #define CSSVALUE_LIST_FOR_EXTRA_VALUES(var) \
1074 for (nsCSSValue* var = First() + 1, *var##_end = First() + mCount; \
1075 var != var##_end; ++var)
1076
Arrayfinal1077 explicit Array(size_t aItemCount) : mRefCnt(0), mCount(aItemCount) {
1078 CSSVALUE_LIST_FOR_EXTRA_VALUES(val) { new (val) nsCSSValue(); }
1079 }
1080
~Arrayfinal1081 ~Array() {
1082 CSSVALUE_LIST_FOR_EXTRA_VALUES(val) { val->~nsCSSValue(); }
1083 }
1084
1085 size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
1086
1087 #undef CSSVALUE_LIST_FOR_EXTRA_VALUES
1088
1089 private:
1090 Array(const Array& aOther) = delete;
1091 Array& operator=(const Array& aOther) = delete;
1092 };
1093
1094 // Prefer nsCSSValue::Array for lists of fixed size.
1095 struct nsCSSValueList {
nsCSSValueListnsCSSValueList1096 nsCSSValueList() : mNext(nullptr) { MOZ_COUNT_CTOR(nsCSSValueList); }
1097 ~nsCSSValueList();
1098
1099 nsCSSValueList* Clone() const; // makes a deep copy. Infallible.
1100 void CloneInto(nsCSSValueList* aList) const; // makes a deep copy into aList
1101 void AppendToString(nsCSSPropertyID aProperty, nsAString& aResult) const;
1102
1103 static bool Equal(const nsCSSValueList* aList1, const nsCSSValueList* aList2);
1104
1105 size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
1106
1107 nsCSSValue mValue;
1108 nsCSSValueList* mNext;
1109
1110 private:
nsCSSValueListnsCSSValueList1111 nsCSSValueList(const nsCSSValueList& aCopy) // makes a shallow copy
1112 : mValue(aCopy.mValue), mNext(nullptr) {
1113 MOZ_COUNT_CTOR(nsCSSValueList);
1114 }
1115
1116 // We don't want operator== or operator!= because they wouldn't be
1117 // null-safe, which is generally what we need. Use |Equal| method
1118 // above instead.
1119 bool operator==(nsCSSValueList const& aOther) const = delete;
1120 bool operator!=(const nsCSSValueList& aOther) const = delete;
1121 };
1122
1123 // nsCSSValueList_heap differs from nsCSSValueList only in being
1124 // refcounted. It should not be necessary to use this class directly;
1125 // it's an implementation detail of nsCSSValue.
1126 struct nsCSSValueList_heap final : public nsCSSValueList {
1127 NS_INLINE_DECL_REFCOUNTING(nsCSSValueList_heap)
1128
1129 size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
1130
1131 private:
1132 // Private destructor, to discourage deletion outside of Release():
~nsCSSValueList_heapfinal1133 ~nsCSSValueList_heap() {}
1134 };
1135
1136 // This is a reference counted list value. Note that the object is
1137 // a wrapper for the reference count and a pointer to the head of the
1138 // list, whereas the other list types (such as nsCSSValueList) do
1139 // not have such a wrapper.
1140 struct nsCSSValueSharedList final {
nsCSSValueSharedListfinal1141 nsCSSValueSharedList() : mHead(nullptr) {}
1142
1143 // Takes ownership of aList.
nsCSSValueSharedListfinal1144 explicit nsCSSValueSharedList(nsCSSValueList* aList) : mHead(aList) {}
1145
1146 private:
1147 // Private destructor, to discourage deletion outside of Release():
1148 ~nsCSSValueSharedList();
1149
1150 public:
1151 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(nsCSSValueSharedList)
1152
1153 void AppendToString(nsCSSPropertyID aProperty, nsAString& aResult) const;
1154
1155 bool operator==(nsCSSValueSharedList const& aOther) const;
1156 bool operator!=(const nsCSSValueSharedList& aOther) const {
1157 return !(*this == aOther);
1158 }
1159
1160 size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
1161
1162 nsCSSValueList* mHead;
1163 };
1164
1165 // This has to be here so that the relationship between nsCSSValueList
1166 // and nsCSSValueList_heap is visible.
GetListValue()1167 inline nsCSSValueList* nsCSSValue::GetListValue() {
1168 if (mUnit == eCSSUnit_List)
1169 return mValue.mList;
1170 else {
1171 MOZ_ASSERT(mUnit == eCSSUnit_ListDep, "not a list value");
1172 return mValue.mListDependent;
1173 }
1174 }
1175
GetListValue()1176 inline const nsCSSValueList* nsCSSValue::GetListValue() const {
1177 if (mUnit == eCSSUnit_List)
1178 return mValue.mList;
1179 else {
1180 MOZ_ASSERT(mUnit == eCSSUnit_ListDep, "not a list value");
1181 return mValue.mListDependent;
1182 }
1183 }
1184
1185 struct nsCSSRect {
1186 nsCSSRect(void);
1187 nsCSSRect(const nsCSSRect& aCopy);
1188 ~nsCSSRect();
1189
1190 void AppendToString(nsCSSPropertyID aProperty, nsAString& aResult) const;
1191
1192 bool operator==(const nsCSSRect& aOther) const {
1193 return mTop == aOther.mTop && mRight == aOther.mRight &&
1194 mBottom == aOther.mBottom && mLeft == aOther.mLeft;
1195 }
1196
1197 bool operator!=(const nsCSSRect& aOther) const {
1198 return mTop != aOther.mTop || mRight != aOther.mRight ||
1199 mBottom != aOther.mBottom || mLeft != aOther.mLeft;
1200 }
1201
1202 void SetAllSidesTo(const nsCSSValue& aValue);
1203
AllSidesEqualTonsCSSRect1204 bool AllSidesEqualTo(const nsCSSValue& aValue) const {
1205 return mTop == aValue && mRight == aValue && mBottom == aValue &&
1206 mLeft == aValue;
1207 }
1208
ResetnsCSSRect1209 void Reset() {
1210 mTop.Reset();
1211 mRight.Reset();
1212 mBottom.Reset();
1213 mLeft.Reset();
1214 }
1215
HasValuensCSSRect1216 bool HasValue() const {
1217 return mTop.GetUnit() != eCSSUnit_Null ||
1218 mRight.GetUnit() != eCSSUnit_Null ||
1219 mBottom.GetUnit() != eCSSUnit_Null ||
1220 mLeft.GetUnit() != eCSSUnit_Null;
1221 }
1222
1223 nsCSSValue mTop;
1224 nsCSSValue mRight;
1225 nsCSSValue mBottom;
1226 nsCSSValue mLeft;
1227
1228 typedef nsCSSValue nsCSSRect::*side_type;
1229 static const side_type sides[4];
1230 };
1231
1232 // nsCSSRect_heap differs from nsCSSRect only in being
1233 // refcounted. It should not be necessary to use this class directly;
1234 // it's an implementation detail of nsCSSValue.
1235 struct nsCSSRect_heap final : public nsCSSRect {
1236 NS_INLINE_DECL_REFCOUNTING(nsCSSRect_heap)
1237
1238 size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
1239
1240 private:
1241 // Private destructor, to discourage deletion outside of Release():
~nsCSSRect_heapfinal1242 ~nsCSSRect_heap() {}
1243 };
1244
1245 // This has to be here so that the relationship between nsCSSRect
1246 // and nsCSSRect_heap is visible.
GetRectValue()1247 inline nsCSSRect& nsCSSValue::GetRectValue() {
1248 MOZ_ASSERT(mUnit == eCSSUnit_Rect, "not a rect value");
1249 return *mValue.mRect;
1250 }
1251
GetRectValue()1252 inline const nsCSSRect& nsCSSValue::GetRectValue() const {
1253 MOZ_ASSERT(mUnit == eCSSUnit_Rect, "not a rect value");
1254 return *mValue.mRect;
1255 }
1256
1257 struct nsCSSValuePair {
nsCSSValuePairnsCSSValuePair1258 nsCSSValuePair() { MOZ_COUNT_CTOR(nsCSSValuePair); }
nsCSSValuePairnsCSSValuePair1259 explicit nsCSSValuePair(nsCSSUnit aUnit) : mXValue(aUnit), mYValue(aUnit) {
1260 MOZ_COUNT_CTOR(nsCSSValuePair);
1261 }
nsCSSValuePairnsCSSValuePair1262 nsCSSValuePair(const nsCSSValue& aXValue, const nsCSSValue& aYValue)
1263 : mXValue(aXValue), mYValue(aYValue) {
1264 MOZ_COUNT_CTOR(nsCSSValuePair);
1265 }
nsCSSValuePairnsCSSValuePair1266 nsCSSValuePair(const nsCSSValuePair& aCopy)
1267 : mXValue(aCopy.mXValue), mYValue(aCopy.mYValue) {
1268 MOZ_COUNT_CTOR(nsCSSValuePair);
1269 }
~nsCSSValuePairnsCSSValuePair1270 ~nsCSSValuePair() { MOZ_COUNT_DTOR(nsCSSValuePair); }
1271
1272 nsCSSValuePair& operator=(const nsCSSValuePair& aOther) {
1273 mXValue = aOther.mXValue;
1274 mYValue = aOther.mYValue;
1275 return *this;
1276 }
1277
1278 bool operator==(const nsCSSValuePair& aOther) const {
1279 return mXValue == aOther.mXValue && mYValue == aOther.mYValue;
1280 }
1281
1282 bool operator!=(const nsCSSValuePair& aOther) const {
1283 return mXValue != aOther.mXValue || mYValue != aOther.mYValue;
1284 }
1285
BothValuesEqualTonsCSSValuePair1286 bool BothValuesEqualTo(const nsCSSValue& aValue) const {
1287 return mXValue == aValue && mYValue == aValue;
1288 }
1289
SetBothValuesTonsCSSValuePair1290 void SetBothValuesTo(const nsCSSValue& aValue) {
1291 mXValue = aValue;
1292 mYValue = aValue;
1293 }
1294
ResetnsCSSValuePair1295 void Reset() {
1296 mXValue.Reset();
1297 mYValue.Reset();
1298 }
1299
HasValuensCSSValuePair1300 bool HasValue() const {
1301 return mXValue.GetUnit() != eCSSUnit_Null ||
1302 mYValue.GetUnit() != eCSSUnit_Null;
1303 }
1304
1305 void AppendToString(nsCSSPropertyID aProperty, nsAString& aResult) const;
1306
1307 size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
1308
1309 nsCSSValue mXValue;
1310 nsCSSValue mYValue;
1311 };
1312
1313 // nsCSSValuePair_heap differs from nsCSSValuePair only in being
1314 // refcounted. It should not be necessary to use this class directly;
1315 // it's an implementation detail of nsCSSValue.
1316 struct nsCSSValuePair_heap final : public nsCSSValuePair {
1317 // forward constructor
nsCSSValuePair_heapfinal1318 nsCSSValuePair_heap(const nsCSSValue& aXValue, const nsCSSValue& aYValue)
1319 : nsCSSValuePair(aXValue, aYValue) {}
1320
1321 NS_INLINE_DECL_REFCOUNTING(nsCSSValuePair_heap)
1322
1323 size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
1324
1325 private:
1326 // Private destructor, to discourage deletion outside of Release():
~nsCSSValuePair_heapfinal1327 ~nsCSSValuePair_heap() {}
1328 };
1329
1330 struct nsCSSValueTriplet {
nsCSSValueTripletnsCSSValueTriplet1331 nsCSSValueTriplet() { MOZ_COUNT_CTOR(nsCSSValueTriplet); }
nsCSSValueTripletnsCSSValueTriplet1332 explicit nsCSSValueTriplet(nsCSSUnit aUnit)
1333 : mXValue(aUnit), mYValue(aUnit), mZValue(aUnit) {
1334 MOZ_COUNT_CTOR(nsCSSValueTriplet);
1335 }
nsCSSValueTripletnsCSSValueTriplet1336 nsCSSValueTriplet(const nsCSSValue& aXValue, const nsCSSValue& aYValue,
1337 const nsCSSValue& aZValue)
1338 : mXValue(aXValue), mYValue(aYValue), mZValue(aZValue) {
1339 MOZ_COUNT_CTOR(nsCSSValueTriplet);
1340 }
nsCSSValueTripletnsCSSValueTriplet1341 nsCSSValueTriplet(const nsCSSValueTriplet& aCopy)
1342 : mXValue(aCopy.mXValue), mYValue(aCopy.mYValue), mZValue(aCopy.mZValue) {
1343 MOZ_COUNT_CTOR(nsCSSValueTriplet);
1344 }
~nsCSSValueTripletnsCSSValueTriplet1345 ~nsCSSValueTriplet() { MOZ_COUNT_DTOR(nsCSSValueTriplet); }
1346
1347 bool operator==(const nsCSSValueTriplet& aOther) const {
1348 return mXValue == aOther.mXValue && mYValue == aOther.mYValue &&
1349 mZValue == aOther.mZValue;
1350 }
1351
1352 bool operator!=(const nsCSSValueTriplet& aOther) const {
1353 return mXValue != aOther.mXValue || mYValue != aOther.mYValue ||
1354 mZValue != aOther.mZValue;
1355 }
1356
AllValuesEqualTonsCSSValueTriplet1357 bool AllValuesEqualTo(const nsCSSValue& aValue) const {
1358 return mXValue == aValue && mYValue == aValue && mZValue == aValue;
1359 }
1360
SetAllValuesTonsCSSValueTriplet1361 void SetAllValuesTo(const nsCSSValue& aValue) {
1362 mXValue = aValue;
1363 mYValue = aValue;
1364 mZValue = aValue;
1365 }
1366
ResetnsCSSValueTriplet1367 void Reset() {
1368 mXValue.Reset();
1369 mYValue.Reset();
1370 mZValue.Reset();
1371 }
1372
HasValuensCSSValueTriplet1373 bool HasValue() const {
1374 return mXValue.GetUnit() != eCSSUnit_Null ||
1375 mYValue.GetUnit() != eCSSUnit_Null ||
1376 mZValue.GetUnit() != eCSSUnit_Null;
1377 }
1378
1379 void AppendToString(nsCSSPropertyID aProperty, nsAString& aResult) const;
1380
1381 nsCSSValue mXValue;
1382 nsCSSValue mYValue;
1383 nsCSSValue mZValue;
1384 };
1385
1386 // nsCSSValueTriplet_heap differs from nsCSSValueTriplet only in being
1387 // refcounted. It should not be necessary to use this class directly;
1388 // it's an implementation detail of nsCSSValue.
1389 struct nsCSSValueTriplet_heap final : public nsCSSValueTriplet {
1390 // forward constructor
nsCSSValueTriplet_heapfinal1391 nsCSSValueTriplet_heap(const nsCSSValue& aXValue, const nsCSSValue& aYValue,
1392 const nsCSSValue& aZValue)
1393 : nsCSSValueTriplet(aXValue, aYValue, aZValue) {}
1394
1395 NS_INLINE_DECL_REFCOUNTING(nsCSSValueTriplet_heap)
1396
1397 size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
1398
1399 private:
1400 // Private destructor, to discourage deletion outside of Release():
~nsCSSValueTriplet_heapfinal1401 ~nsCSSValueTriplet_heap() {}
1402 };
1403
1404 // This has to be here so that the relationship between nsCSSValuePair
1405 // and nsCSSValuePair_heap is visible.
GetPairValue()1406 inline nsCSSValuePair& nsCSSValue::GetPairValue() {
1407 MOZ_ASSERT(mUnit == eCSSUnit_Pair, "not a pair value");
1408 return *mValue.mPair;
1409 }
1410
GetPairValue()1411 inline const nsCSSValuePair& nsCSSValue::GetPairValue() const {
1412 MOZ_ASSERT(mUnit == eCSSUnit_Pair, "not a pair value");
1413 return *mValue.mPair;
1414 }
1415
GetTripletValue()1416 inline nsCSSValueTriplet& nsCSSValue::GetTripletValue() {
1417 MOZ_ASSERT(mUnit == eCSSUnit_Triplet, "not a triplet value");
1418 return *mValue.mTriplet;
1419 }
1420
GetTripletValue()1421 inline const nsCSSValueTriplet& nsCSSValue::GetTripletValue() const {
1422 MOZ_ASSERT(mUnit == eCSSUnit_Triplet, "not a triplet value");
1423 return *mValue.mTriplet;
1424 }
1425
1426 // Maybe should be replaced with nsCSSValueList and nsCSSValue::Array?
1427 struct nsCSSValuePairList {
nsCSSValuePairListnsCSSValuePairList1428 nsCSSValuePairList() : mNext(nullptr) { MOZ_COUNT_CTOR(nsCSSValuePairList); }
1429 ~nsCSSValuePairList();
1430
1431 nsCSSValuePairList* Clone() const; // makes a deep copy. Infallible.
1432 void AppendToString(nsCSSPropertyID aProperty, nsAString& aResult) const;
1433
1434 static bool Equal(const nsCSSValuePairList* aList1,
1435 const nsCSSValuePairList* aList2);
1436
1437 size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
1438
1439 nsCSSValue mXValue;
1440 nsCSSValue mYValue;
1441 nsCSSValuePairList* mNext;
1442
1443 private:
nsCSSValuePairListnsCSSValuePairList1444 nsCSSValuePairList(const nsCSSValuePairList& aCopy) // makes a shallow copy
1445 : mXValue(aCopy.mXValue), mYValue(aCopy.mYValue), mNext(nullptr) {
1446 MOZ_COUNT_CTOR(nsCSSValuePairList);
1447 }
1448
1449 // We don't want operator== or operator!= because they wouldn't be
1450 // null-safe, which is generally what we need. Use |Equal| method
1451 // above instead.
1452 bool operator==(const nsCSSValuePairList& aOther) const = delete;
1453 bool operator!=(const nsCSSValuePairList& aOther) const = delete;
1454 };
1455
1456 // nsCSSValuePairList_heap differs from nsCSSValuePairList only in being
1457 // refcounted. It should not be necessary to use this class directly;
1458 // it's an implementation detail of nsCSSValue.
1459 struct nsCSSValuePairList_heap final : public nsCSSValuePairList {
1460 NS_INLINE_DECL_REFCOUNTING(nsCSSValuePairList_heap)
1461
1462 size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
1463
1464 private:
1465 // Private destructor, to discourage deletion outside of Release():
~nsCSSValuePairList_heapfinal1466 ~nsCSSValuePairList_heap() {}
1467 };
1468
1469 // This has to be here so that the relationship between nsCSSValuePairList
1470 // and nsCSSValuePairList_heap is visible.
GetPairListValue()1471 inline nsCSSValuePairList* nsCSSValue::GetPairListValue() {
1472 if (mUnit == eCSSUnit_PairList)
1473 return mValue.mPairList;
1474 else {
1475 MOZ_ASSERT(mUnit == eCSSUnit_PairListDep, "not a pairlist value");
1476 return mValue.mPairListDependent;
1477 }
1478 }
1479
GetPairListValue()1480 inline const nsCSSValuePairList* nsCSSValue::GetPairListValue() const {
1481 if (mUnit == eCSSUnit_PairList)
1482 return mValue.mPairList;
1483 else {
1484 MOZ_ASSERT(mUnit == eCSSUnit_PairListDep, "not a pairlist value");
1485 return mValue.mPairListDependent;
1486 }
1487 }
1488
1489 struct nsCSSValueGradientStop {
1490 public:
1491 nsCSSValueGradientStop();
1492 // needed to keep bloat logs happy when we use the TArray
1493 // in nsCSSValueGradient
1494 nsCSSValueGradientStop(const nsCSSValueGradientStop& aOther);
1495 ~nsCSSValueGradientStop();
1496
1497 nsCSSValue mLocation;
1498 nsCSSValue mColor;
1499 // If mIsInterpolationHint is true, there is no color, just
1500 // a location.
1501 bool mIsInterpolationHint;
1502
1503 bool operator==(const nsCSSValueGradientStop& aOther) const {
1504 return (mLocation == aOther.mLocation &&
1505 mIsInterpolationHint == aOther.mIsInterpolationHint &&
1506 (mIsInterpolationHint || mColor == aOther.mColor));
1507 }
1508
1509 bool operator!=(const nsCSSValueGradientStop& aOther) const {
1510 return !(*this == aOther);
1511 }
1512
1513 size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
1514 };
1515
1516 struct nsCSSValueGradient final {
1517 nsCSSValueGradient(bool aIsRadial, bool aIsRepeating);
1518
1519 // true if gradient is radial, false if it is linear
1520 bool mIsRadial;
1521 bool mIsRepeating;
1522 bool mIsLegacySyntax; // If true, serialization should use a vendor prefix.
1523 // XXXdholbert This will hopefully be going away soon, if bug 1337655 sticks:
1524 bool mIsMozLegacySyntax; // (Only makes sense when mIsLegacySyntax is true.)
1525 // If true, serialization should use -moz prefix.
1526 // Else, serialization should use -webkit prefix.
1527 bool mIsExplicitSize;
1528 // line position and angle
1529 nsCSSValuePair mBgPos;
1530 nsCSSValue mAngle;
1531
1532 // Only meaningful if mIsRadial is true
1533 private:
1534 nsCSSValue mRadialValues[2];
1535
1536 public:
GetRadialShapefinal1537 nsCSSValue& GetRadialShape() {
1538 MOZ_ASSERT(!mIsExplicitSize);
1539 return mRadialValues[0];
1540 }
GetRadialShapefinal1541 const nsCSSValue& GetRadialShape() const {
1542 MOZ_ASSERT(!mIsExplicitSize);
1543 return mRadialValues[0];
1544 }
GetRadialSizefinal1545 nsCSSValue& GetRadialSize() {
1546 MOZ_ASSERT(!mIsExplicitSize);
1547 return mRadialValues[1];
1548 }
GetRadialSizefinal1549 const nsCSSValue& GetRadialSize() const {
1550 MOZ_ASSERT(!mIsExplicitSize);
1551 return mRadialValues[1];
1552 }
GetRadiusXfinal1553 nsCSSValue& GetRadiusX() {
1554 MOZ_ASSERT(mIsExplicitSize);
1555 return mRadialValues[0];
1556 }
GetRadiusXfinal1557 const nsCSSValue& GetRadiusX() const {
1558 MOZ_ASSERT(mIsExplicitSize);
1559 return mRadialValues[0];
1560 }
GetRadiusYfinal1561 nsCSSValue& GetRadiusY() {
1562 MOZ_ASSERT(mIsExplicitSize);
1563 return mRadialValues[1];
1564 }
GetRadiusYfinal1565 const nsCSSValue& GetRadiusY() const {
1566 MOZ_ASSERT(mIsExplicitSize);
1567 return mRadialValues[1];
1568 }
1569
1570 InfallibleTArray<nsCSSValueGradientStop> mStops;
1571
1572 bool operator==(const nsCSSValueGradient& aOther) const {
1573 if (mIsRadial != aOther.mIsRadial || mIsRepeating != aOther.mIsRepeating ||
1574 mIsLegacySyntax != aOther.mIsLegacySyntax ||
1575 mIsMozLegacySyntax != aOther.mIsMozLegacySyntax ||
1576 mIsExplicitSize != aOther.mIsExplicitSize || mBgPos != aOther.mBgPos ||
1577 mAngle != aOther.mAngle ||
1578 mRadialValues[0] != aOther.mRadialValues[0] ||
1579 mRadialValues[1] != aOther.mRadialValues[1])
1580 return false;
1581
1582 if (mStops.Length() != aOther.mStops.Length()) return false;
1583
1584 for (uint32_t i = 0; i < mStops.Length(); i++) {
1585 if (mStops[i] != aOther.mStops[i]) return false;
1586 }
1587
1588 return true;
1589 }
1590
1591 bool operator!=(const nsCSSValueGradient& aOther) const {
1592 return !(*this == aOther);
1593 }
1594
1595 NS_INLINE_DECL_REFCOUNTING(nsCSSValueGradient)
1596
1597 size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
1598
1599 private:
1600 // Private destructor, to discourage deletion outside of Release():
~nsCSSValueGradientfinal1601 ~nsCSSValueGradient() {}
1602
1603 nsCSSValueGradient(const nsCSSValueGradient& aOther) = delete;
1604 nsCSSValueGradient& operator=(const nsCSSValueGradient& aOther) = delete;
1605 };
1606
1607 // A string value used primarily to represent variable references.
1608 //
1609 // Animation code, specifically the KeyframeUtils class, also uses this
1610 // type as a container for various string values including:
1611 //
1612 // * Shorthand property values
1613 // * Shorthand sentinel values used for testing failure conditions
1614 // * Invalid longhand property values
1615 //
1616 // For the most part, the above values are not passed to functions that
1617 // manipulate nsCSSValue objects in a generic fashion. Instead KeyframeUtils
1618 // extracts the string from the nsCSSValueTokenStream and passes that around
1619 // instead. The single exception is nsCSSValue::AppendToString which we use
1620 // to serialize the string contained in the nsCSSValueTokenStream by ensuring
1621 // the mShorthandPropertyID is set to eCSSProperty_UNKNOWN.
1622 struct nsCSSValueTokenStream final {
1623 nsCSSValueTokenStream();
1624
1625 private:
1626 // Private destructor, to discourage deletion outside of Release():
1627 ~nsCSSValueTokenStream();
1628
1629 public:
1630 bool operator==(const nsCSSValueTokenStream& aOther) const {
1631 // This is not safe to call OMT, due to the URI/Principal Equals calls.
1632 MOZ_ASSERT(NS_IsMainThread());
1633
1634 bool eq;
1635 return mPropertyID == aOther.mPropertyID &&
1636 mShorthandPropertyID == aOther.mShorthandPropertyID &&
1637 mTokenStream.Equals(aOther.mTokenStream) &&
1638 mLevel == aOther.mLevel &&
1639 (mBaseURI == aOther.mBaseURI ||
1640 (mBaseURI && aOther.mBaseURI &&
1641 NS_SUCCEEDED(mBaseURI->Equals(aOther.mBaseURI, &eq)) && eq)) &&
1642 (mSheetURI == aOther.mSheetURI ||
1643 (mSheetURI && aOther.mSheetURI &&
1644 NS_SUCCEEDED(mSheetURI->Equals(aOther.mSheetURI, &eq)) && eq)) &&
1645 (mSheetPrincipal == aOther.mSheetPrincipal ||
1646 (mSheetPrincipal && aOther.mSheetPrincipal &&
1647 NS_SUCCEEDED(
1648 mSheetPrincipal->Equals(aOther.mSheetPrincipal, &eq)) &&
1649 eq));
1650 }
1651
1652 bool operator!=(const nsCSSValueTokenStream& aOther) const {
1653 return !(*this == aOther);
1654 }
1655
1656 NS_INLINE_DECL_REFCOUNTING(nsCSSValueTokenStream)
1657
1658 size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
1659
1660 // The property that has mTokenStream as its unparsed specified value.
1661 // When a variable reference is used in a shorthand property, a
1662 // TokenStream value is stored as the specified value for each of its
1663 // component longhand properties.
1664 nsCSSPropertyID mPropertyID;
1665
1666 // The shorthand property that had a value with a variable reference,
1667 // which caused the longhand property identified by mPropertyID to have
1668 // a TokenStream value.
1669 nsCSSPropertyID mShorthandPropertyID;
1670
1671 // The unparsed CSS corresponding to the specified value of the property.
1672 // When the value of a shorthand property has a variable reference, the
1673 // same mTokenStream value is used on each of the nsCSSValueTokenStream
1674 // objects that will be set by parsing the shorthand.
1675 nsString mTokenStream;
1676
1677 nsCOMPtr<nsIURI> mBaseURI;
1678 nsCOMPtr<nsIURI> mSheetURI;
1679 nsCOMPtr<nsIPrincipal> mSheetPrincipal;
1680 // XXX Should store sheet here (see Bug 952338)
1681 // mozilla::CSSStyleSheet* mSheet;
1682 uint32_t mLineNumber;
1683 uint32_t mLineOffset;
1684 mozilla::SheetType mLevel;
1685
1686 private:
1687 nsCSSValueTokenStream(const nsCSSValueTokenStream& aOther) = delete;
1688 nsCSSValueTokenStream& operator=(const nsCSSValueTokenStream& aOther) =
1689 delete;
1690 };
1691
1692 class nsCSSValueFloatColor final {
1693 public:
nsCSSValueFloatColor(float aComponent1,float aComponent2,float aComponent3,float aAlpha)1694 nsCSSValueFloatColor(float aComponent1, float aComponent2, float aComponent3,
1695 float aAlpha)
1696 : mComponent1(aComponent1),
1697 mComponent2(aComponent2),
1698 mComponent3(aComponent3),
1699 mAlpha(aAlpha) {
1700 // We may copy nsCSSValueFloatColor and do some comparisons on them.
1701 // In order to get the correct result, we have to make sure each component
1702 // is finite.
1703 MOZ_ASSERT(mozilla::IsFinite(aComponent1) &&
1704 mozilla::IsFinite(aComponent2) &&
1705 mozilla::IsFinite(aComponent3) && mozilla::IsFinite(aAlpha),
1706 "Caller must ensure color components are finite");
1707 }
1708
1709 private:
1710 // Private destructor, to discourage deletion outside of Release():
~nsCSSValueFloatColor()1711 ~nsCSSValueFloatColor() {}
1712
1713 public:
1714 bool operator==(nsCSSValueFloatColor& aOther) const;
1715
1716 nscolor GetColorValue(nsCSSUnit aUnit) const;
Comp1()1717 float Comp1() const { return mComponent1; }
Comp2()1718 float Comp2() const { return mComponent2; }
Comp3()1719 float Comp3() const { return mComponent3; }
Alpha()1720 float Alpha() const { return mAlpha; }
1721 bool IsNonTransparentColor() const;
1722
1723 void AppendToString(nsCSSUnit aUnit, nsAString& aResult) const;
1724
1725 size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
1726
1727 NS_INLINE_DECL_REFCOUNTING(nsCSSValueFloatColor)
1728
1729 private:
1730 // The range of each component is.
1731 // [0, 1] for HSLColor and HSLAColor. mComponent1 for hue, mComponent2 for
1732 // saturation, mComponent3 for lightness.
1733 // [0, 1] for saturation and lightness
1734 // represents [0%, 100%].
1735 // [0, 1] for hue represents
1736 // [0deg, 360deg].
1737 //
1738 // [-float::max(), float::max()] for PercentageRGBColor, PercentageRGBAColor.
1739 // 1.0 means 100%.
1740 float mComponent1;
1741 float mComponent2;
1742 float mComponent3;
1743 float mAlpha;
1744
1745 nsCSSValueFloatColor(const nsCSSValueFloatColor& aOther) = delete;
1746 nsCSSValueFloatColor& operator=(const nsCSSValueFloatColor& aOther) = delete;
1747 };
1748
1749 struct nsCSSCornerSizes {
1750 nsCSSCornerSizes(void);
1751 nsCSSCornerSizes(const nsCSSCornerSizes& aCopy);
1752 ~nsCSSCornerSizes();
1753
1754 // argument is a "full corner" constant from nsStyleConsts.h
GetCornernsCSSCornerSizes1755 nsCSSValue const& GetCorner(uint32_t aCorner) const {
1756 return this->*corners[aCorner];
1757 }
GetCornernsCSSCornerSizes1758 nsCSSValue& GetCorner(uint32_t aCorner) { return this->*corners[aCorner]; }
1759
1760 bool operator==(const nsCSSCornerSizes& aOther) const {
NS_FOR_CSS_FULL_CORNERSnsCSSCornerSizes1761 NS_FOR_CSS_FULL_CORNERS(corner) {
1762 if (this->GetCorner(corner) != aOther.GetCorner(corner)) return false;
1763 }
1764 return true;
1765 }
1766
1767 bool operator!=(const nsCSSCornerSizes& aOther) const {
NS_FOR_CSS_FULL_CORNERSnsCSSCornerSizes1768 NS_FOR_CSS_FULL_CORNERS(corner) {
1769 if (this->GetCorner(corner) != aOther.GetCorner(corner)) return true;
1770 }
1771 return false;
1772 }
1773
HasValuensCSSCornerSizes1774 bool HasValue() const {
1775 NS_FOR_CSS_FULL_CORNERS(corner) {
1776 if (this->GetCorner(corner).GetUnit() != eCSSUnit_Null) return true;
1777 }
1778 return false;
1779 }
1780
1781 void Reset();
1782
1783 nsCSSValue mTopLeft;
1784 nsCSSValue mTopRight;
1785 nsCSSValue mBottomRight;
1786 nsCSSValue mBottomLeft;
1787
1788 protected:
1789 typedef nsCSSValue nsCSSCornerSizes::*corner_type;
1790 static const corner_type corners[4];
1791 };
1792
1793 #endif /* nsCSSValue_h___ */
1794