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