Fri, 16 Jan 2015 18:13:44 +0100
Integrate suggestion from review to improve consistency with existing 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/. */
6 /* representation of simple property values within CSS declarations */
8 #ifndef nsCSSValue_h___
9 #define nsCSSValue_h___
11 #include "mozilla/Attributes.h"
12 #include "mozilla/FloatingPoint.h"
13 #include "mozilla/MemoryReporting.h"
15 #include "nsIPrincipal.h"
16 #include "nsIURI.h"
17 #include "nsCOMPtr.h"
18 #include "nsCRTGlue.h"
19 #include "nsCSSKeywords.h"
20 #include "nsCSSProperty.h"
21 #include "nsColor.h"
22 #include "nsCoord.h"
23 #include "nsRefPtrHashtable.h"
24 #include "nsString.h"
25 #include "nsStringBuffer.h"
26 #include "nsTArray.h"
27 #include "nsStyleConsts.h"
29 class imgRequestProxy;
30 class nsCSSStyleSheet;
31 class nsIDocument;
32 class nsIPrincipal;
33 class nsIURI;
34 class nsPresContext;
35 template <class T>
36 class nsPtrHashKey;
38 // Deletes a linked list iteratively to avoid blowing up the stack (bug 456196).
39 #define NS_CSS_DELETE_LIST_MEMBER(type_, ptr_, member_) \
40 { \
41 type_ *cur = (ptr_)->member_; \
42 (ptr_)->member_ = nullptr; \
43 while (cur) { \
44 type_ *dlm_next = cur->member_; \
45 cur->member_ = nullptr; \
46 delete cur; \
47 cur = dlm_next; \
48 } \
49 }
51 // Clones a linked list iteratively to avoid blowing up the stack.
52 // If it fails to clone the entire list then 'to_' is deleted and
53 // we return null.
54 #define NS_CSS_CLONE_LIST_MEMBER(type_, from_, member_, to_, args_) \
55 { \
56 type_ *dest = (to_); \
57 (to_)->member_ = nullptr; \
58 for (const type_ *src = (from_)->member_; src; src = src->member_) { \
59 type_ *clm_clone = src->Clone args_; \
60 if (!clm_clone) { \
61 delete (to_); \
62 return nullptr; \
63 } \
64 dest->member_ = clm_clone; \
65 dest = clm_clone; \
66 } \
67 }
69 namespace mozilla {
70 namespace css {
72 struct URLValue {
73 // Methods are not inline because using an nsIPrincipal means requiring
74 // caps, which leads to REQUIRES hell, since this header is included all
75 // over.
77 // For both constructors aString must not be null.
78 // For both constructors aOriginPrincipal must not be null.
79 // Construct with a base URI; this will create the actual URI lazily from
80 // aString and aBaseURI.
81 URLValue(nsStringBuffer* aString, nsIURI* aBaseURI, nsIURI* aReferrer,
82 nsIPrincipal* aOriginPrincipal);
83 // Construct with the actual URI.
84 URLValue(nsIURI* aURI, nsStringBuffer* aString, nsIURI* aReferrer,
85 nsIPrincipal* aOriginPrincipal);
87 ~URLValue();
89 bool operator==(const URLValue& aOther) const;
91 // URIEquals only compares URIs and principals (unlike operator==, which
92 // also compares the original strings). URIEquals also assumes that the
93 // mURI member of both URL objects is non-null. Do NOT call this method
94 // unless you're sure this is the case.
95 bool URIEquals(const URLValue& aOther) const;
97 nsIURI* GetURI() const;
99 size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
101 private:
102 // If mURIResolved is false, mURI stores the base URI.
103 // If mURIResolved is true, mURI stores the URI we resolve to; this may be
104 // null if the URI is invalid.
105 mutable nsCOMPtr<nsIURI> mURI;
106 public:
107 nsStringBuffer* mString; // Could use nsRefPtr, but it'd add useless
108 // null-checks; this is never null.
109 nsCOMPtr<nsIURI> mReferrer;
110 nsCOMPtr<nsIPrincipal> mOriginPrincipal;
112 NS_INLINE_DECL_REFCOUNTING(URLValue)
114 private:
115 mutable bool mURIResolved;
117 URLValue(const URLValue& aOther) MOZ_DELETE;
118 URLValue& operator=(const URLValue& aOther) MOZ_DELETE;
119 };
121 struct ImageValue : public URLValue {
122 // Not making the constructor and destructor inline because that would
123 // force us to include imgIRequest.h, which leads to REQUIRES hell, since
124 // this header is included all over.
125 // aString must not be null.
126 ImageValue(nsIURI* aURI, nsStringBuffer* aString, nsIURI* aReferrer,
127 nsIPrincipal* aOriginPrincipal, nsIDocument* aDocument);
128 ~ImageValue();
130 // Inherit operator== from URLValue
132 nsRefPtrHashtable<nsPtrHashKey<nsISupports>, imgRequestProxy> mRequests;
134 // Override AddRef and Release to not only log ourselves correctly, but
135 // also so that we delete correctly without a virtual destructor
136 NS_INLINE_DECL_REFCOUNTING(ImageValue)
137 };
139 struct GridNamedArea {
140 nsString mName;
141 uint32_t mColumnStart;
142 uint32_t mColumnEnd;
143 uint32_t mRowStart;
144 uint32_t mRowEnd;
145 };
147 struct GridTemplateAreasValue MOZ_FINAL {
148 // Parsed value
149 nsTArray<GridNamedArea> mNamedAreas;
151 // Original <string> values. Length gives the number of rows,
152 // content makes serialization easier.
153 nsTArray<nsString> mTemplates;
155 // How many columns grid-template-areas contributes to the explicit grid.
156 // http://dev.w3.org/csswg/css-grid/#explicit-grid
157 uint32_t mNColumns;
159 // How many rows grid-template-areas contributes to the explicit grid.
160 // http://dev.w3.org/csswg/css-grid/#explicit-grid
161 uint32_t NRows() const {
162 return mTemplates.Length();
163 }
165 GridTemplateAreasValue()
166 : mNColumns(0)
167 // Default constructors for mNamedAreas and mTemplates: empty arrays.
168 {
169 }
171 bool operator==(const GridTemplateAreasValue& aOther) const
172 {
173 return mTemplates == aOther.mTemplates;
174 }
176 bool operator!=(const GridTemplateAreasValue& aOther) const
177 {
178 return !(*this == aOther);
179 }
181 NS_INLINE_DECL_REFCOUNTING(GridTemplateAreasValue)
183 size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
185 private:
186 // Private destructor to make sure this isn't used as a stack variable
187 // or member variable.
188 ~GridTemplateAreasValue()
189 {
190 }
192 GridTemplateAreasValue(const GridTemplateAreasValue& aOther) MOZ_DELETE;
193 GridTemplateAreasValue&
194 operator=(const GridTemplateAreasValue& aOther) MOZ_DELETE;
195 };
197 }
198 }
200 enum nsCSSUnit {
201 eCSSUnit_Null = 0, // (n/a) null unit, value is not specified
202 eCSSUnit_Auto = 1, // (n/a) value is algorithmic
203 eCSSUnit_Inherit = 2, // (n/a) value is inherited
204 eCSSUnit_Initial = 3, // (n/a) value is default UA value
205 eCSSUnit_Unset = 4, // (n/a) value equivalent to 'initial' if on a reset property, 'inherit' otherwise
206 eCSSUnit_None = 5, // (n/a) value is none
207 eCSSUnit_Normal = 6, // (n/a) value is normal (algorithmic, different than auto)
208 eCSSUnit_System_Font = 7, // (n/a) value is -moz-use-system-font
209 eCSSUnit_All = 8, // (n/a) value is all
210 eCSSUnit_Dummy = 9, // (n/a) a fake but specified value, used
211 // only in temporary values
212 eCSSUnit_DummyInherit = 10, // (n/a) a fake but specified value, used
213 // only in temporary values
215 eCSSUnit_String = 11, // (char16_t*) a string value
216 eCSSUnit_Ident = 12, // (char16_t*) a string value
217 eCSSUnit_Families = 13, // (char16_t*) a string value
218 eCSSUnit_Attr = 14, // (char16_t*) a attr(string) value
219 eCSSUnit_Local_Font = 15, // (char16_t*) a local font name
220 eCSSUnit_Font_Format = 16, // (char16_t*) a font format name
221 eCSSUnit_Element = 17, // (char16_t*) an element id
223 eCSSUnit_Array = 20, // (nsCSSValue::Array*) a list of values
224 eCSSUnit_Counter = 21, // (nsCSSValue::Array*) a counter(string,[string]) value
225 eCSSUnit_Counters = 22, // (nsCSSValue::Array*) a counters(string,string[,string]) value
226 eCSSUnit_Cubic_Bezier = 23, // (nsCSSValue::Array*) a list of float values
227 eCSSUnit_Steps = 24, // (nsCSSValue::Array*) a list of (integer, enumerated)
228 eCSSUnit_Function = 25, // (nsCSSValue::Array*) a function with
229 // parameters. First elem of array is name,
230 // an nsCSSKeyword as eCSSUnit_Enumerated,
231 // the rest of the values are arguments.
233 // The top level of a calc() expression is eCSSUnit_Calc. All
234 // remaining eCSSUnit_Calc_* units only occur inside these toplevel
235 // calc values.
237 // eCSSUnit_Calc has an array with exactly 1 element. eCSSUnit_Calc
238 // exists so we can distinguish calc(2em) from 2em as specified values
239 // (but we drop this distinction for nsStyleCoord when we store
240 // computed values).
241 eCSSUnit_Calc = 30, // (nsCSSValue::Array*) calc() value
242 // Plus, Minus, Times_* and Divided have arrays with exactly 2
243 // elements. a + b + c + d is grouped as ((a + b) + c) + d
244 eCSSUnit_Calc_Plus = 31, // (nsCSSValue::Array*) + node within calc()
245 eCSSUnit_Calc_Minus = 32, // (nsCSSValue::Array*) - within calc
246 eCSSUnit_Calc_Times_L = 33, // (nsCSSValue::Array*) num * val within calc
247 eCSSUnit_Calc_Times_R = 34, // (nsCSSValue::Array*) val * num within calc
248 eCSSUnit_Calc_Divided = 35, // (nsCSSValue::Array*) / within calc
250 eCSSUnit_URL = 40, // (nsCSSValue::URL*) value
251 eCSSUnit_Image = 41, // (nsCSSValue::Image*) value
252 eCSSUnit_Gradient = 42, // (nsCSSValueGradient*) value
253 eCSSUnit_TokenStream = 43, // (nsCSSValueTokenStream*) value
254 eCSSUnit_GridTemplateAreas = 44, // (GridTemplateAreasValue*)
255 // for grid-template-areas
257 eCSSUnit_Pair = 50, // (nsCSSValuePair*) pair of values
258 eCSSUnit_Triplet = 51, // (nsCSSValueTriplet*) triplet of values
259 eCSSUnit_Rect = 52, // (nsCSSRect*) rectangle (four values)
260 eCSSUnit_List = 53, // (nsCSSValueList*) list of values
261 eCSSUnit_ListDep = 54, // (nsCSSValueList*) same as List
262 // but does not own the list
263 eCSSUnit_SharedList = 55, // (nsCSSValueSharedList*) same as list
264 // but reference counted and shared
265 eCSSUnit_PairList = 56, // (nsCSSValuePairList*) list of value pairs
266 eCSSUnit_PairListDep = 57, // (nsCSSValuePairList*) same as PairList
267 // but does not own the list
269 eCSSUnit_Integer = 70, // (int) simple value
270 eCSSUnit_Enumerated = 71, // (int) value has enumerated meaning
272 eCSSUnit_EnumColor = 80, // (int) enumerated color (kColorKTable)
273 eCSSUnit_RGBColor = 81, // (nscolor) an opaque RGBA value specified as rgb()
274 eCSSUnit_RGBAColor = 82, // (nscolor) an RGBA value specified as rgba()
275 eCSSUnit_HexColor = 83, // (nscolor) an opaque RGBA value specified as #rrggbb
276 eCSSUnit_ShortHexColor = 84, // (nscolor) an opaque RGBA value specified as #rgb
277 eCSSUnit_PercentageRGBColor = 85, // (nsCSSValueFloatColor*)
278 eCSSUnit_PercentageRGBAColor = 86, // (nsCSSValueFloatColor*)
279 eCSSUnit_HSLColor = 87, // (nsCSSValueFloatColor*)
280 eCSSUnit_HSLAColor = 88, // (nsCSSValueFloatColor*)
282 eCSSUnit_Percent = 90, // (float) 1.0 == 100%) value is percentage of something
283 eCSSUnit_Number = 91, // (float) value is numeric (usually multiplier, different behavior that percent)
285 // Physical length units
286 eCSSUnit_PhysicalMillimeter = 200, // (float) 1/25.4 inch
288 // Length units - relative
289 // Viewport relative measure
290 eCSSUnit_ViewportWidth = 700, // (float) 1% of the width of the initial containing block
291 eCSSUnit_ViewportHeight = 701, // (float) 1% of the height of the initial containing block
292 eCSSUnit_ViewportMin = 702, // (float) smaller of ViewportWidth and ViewportHeight
293 eCSSUnit_ViewportMax = 703, // (float) larger of ViewportWidth and ViewportHeight
295 // Font relative measure
296 eCSSUnit_EM = 800, // (float) == current font size
297 eCSSUnit_XHeight = 801, // (float) distance from top of lower case x to baseline
298 eCSSUnit_Char = 802, // (float) number of characters, used for width with monospace font
299 eCSSUnit_RootEM = 803, // (float) == root element font size
301 // Screen relative measure
302 eCSSUnit_Point = 900, // (float) 4/3 of a CSS pixel
303 eCSSUnit_Inch = 901, // (float) 96 CSS pixels
304 eCSSUnit_Millimeter = 902, // (float) 96/25.4 CSS pixels
305 eCSSUnit_Centimeter = 903, // (float) 96/2.54 CSS pixels
306 eCSSUnit_Pica = 904, // (float) 12 points == 16 CSS pixls
307 eCSSUnit_Pixel = 905, // (float) CSS pixel unit
309 // Angular units
310 eCSSUnit_Degree = 1000, // (float) 360 per circle
311 eCSSUnit_Grad = 1001, // (float) 400 per circle
312 eCSSUnit_Radian = 1002, // (float) 2*pi per circle
313 eCSSUnit_Turn = 1003, // (float) 1 per circle
315 // Frequency units
316 eCSSUnit_Hertz = 2000, // (float) 1/seconds
317 eCSSUnit_Kilohertz = 2001, // (float) 1000 Hertz
319 // Time units
320 eCSSUnit_Seconds = 3000, // (float) Standard time
321 eCSSUnit_Milliseconds = 3001, // (float) 1/1000 second
323 // Flexible fraction (CSS Grid)
324 eCSSUnit_FlexFraction = 4000 // (float) Fraction of free space
325 };
327 struct nsCSSValueGradient;
328 struct nsCSSValuePair;
329 struct nsCSSValuePair_heap;
330 struct nsCSSValueTokenStream;
331 struct nsCSSRect;
332 struct nsCSSRect_heap;
333 struct nsCSSValueList;
334 struct nsCSSValueList_heap;
335 struct nsCSSValueSharedList;
336 struct nsCSSValuePairList;
337 struct nsCSSValuePairList_heap;
338 struct nsCSSValueTriplet;
339 struct nsCSSValueTriplet_heap;
340 class nsCSSValueFloatColor;
342 class nsCSSValue {
343 public:
344 struct Array;
345 friend struct Array;
347 friend struct mozilla::css::URLValue;
349 friend struct mozilla::css::ImageValue;
351 // for valueless units only (null, auto, inherit, none, all, normal)
352 explicit nsCSSValue(nsCSSUnit aUnit = eCSSUnit_Null)
353 : mUnit(aUnit)
354 {
355 NS_ABORT_IF_FALSE(aUnit <= eCSSUnit_DummyInherit, "not a valueless unit");
356 }
358 nsCSSValue(int32_t aValue, nsCSSUnit aUnit);
359 nsCSSValue(float aValue, nsCSSUnit aUnit);
360 nsCSSValue(const nsString& aValue, nsCSSUnit aUnit);
361 nsCSSValue(Array* aArray, nsCSSUnit aUnit);
362 explicit nsCSSValue(mozilla::css::URLValue* aValue);
363 explicit nsCSSValue(mozilla::css::ImageValue* aValue);
364 explicit nsCSSValue(nsCSSValueGradient* aValue);
365 explicit nsCSSValue(nsCSSValueTokenStream* aValue);
366 explicit nsCSSValue(mozilla::css::GridTemplateAreasValue* aValue);
367 nsCSSValue(const nsCSSValue& aCopy);
368 ~nsCSSValue() { Reset(); }
370 nsCSSValue& operator=(const nsCSSValue& aCopy);
371 bool operator==(const nsCSSValue& aOther) const;
373 bool operator!=(const nsCSSValue& aOther) const
374 {
375 return !(*this == aOther);
376 }
378 // Enum for AppendToString's aValueSerialization argument.
379 enum Serialization { eNormalized, eAuthorSpecified };
381 /**
382 * Serialize |this| as a specified value for |aProperty| and append
383 * it to |aResult|.
384 */
385 void AppendToString(nsCSSProperty aProperty, nsAString& aResult,
386 Serialization aValueSerialization) const;
388 nsCSSUnit GetUnit() const { return mUnit; }
389 bool IsLengthUnit() const
390 { return eCSSUnit_PhysicalMillimeter <= mUnit && mUnit <= eCSSUnit_Pixel; }
391 /**
392 * A "fixed" length unit is one that means a specific physical length
393 * which we try to match based on the physical characteristics of an
394 * output device.
395 */
396 bool IsFixedLengthUnit() const
397 { return mUnit == eCSSUnit_PhysicalMillimeter; }
398 /**
399 * What the spec calls relative length units is, for us, split
400 * between relative length units and pixel length units.
401 *
402 * A "relative" length unit is a multiple of some derived metric,
403 * such as a font em-size, which itself was controlled by an input CSS
404 * length. Relative length units should not be scaled by zooming, since
405 * the underlying CSS length would already have been scaled.
406 */
407 bool IsRelativeLengthUnit() const
408 { return eCSSUnit_EM <= mUnit && mUnit <= eCSSUnit_RootEM; }
409 /**
410 * A "pixel" length unit is a some multiple of CSS pixels.
411 */
412 bool IsPixelLengthUnit() const
413 { return eCSSUnit_Point <= mUnit && mUnit <= eCSSUnit_Pixel; }
414 bool IsAngularUnit() const
415 { return eCSSUnit_Degree <= mUnit && mUnit <= eCSSUnit_Turn; }
416 bool IsFrequencyUnit() const
417 { return eCSSUnit_Hertz <= mUnit && mUnit <= eCSSUnit_Kilohertz; }
418 bool IsTimeUnit() const
419 { return eCSSUnit_Seconds <= mUnit && mUnit <= eCSSUnit_Milliseconds; }
420 bool IsCalcUnit() const
421 { return eCSSUnit_Calc <= mUnit && mUnit <= eCSSUnit_Calc_Divided; }
423 bool UnitHasStringValue() const
424 { return eCSSUnit_String <= mUnit && mUnit <= eCSSUnit_Element; }
425 bool UnitHasArrayValue() const
426 { return eCSSUnit_Array <= mUnit && mUnit <= eCSSUnit_Calc_Divided; }
428 // Checks for the nsCSSValue being of a particular type of color unit:
429 //
430 // - IsIntegerColorUnit returns true for:
431 // eCSSUnit_RGBColor -- rgb(int,int,int)
432 // eCSSUnit_RGBAColor -- rgba(int,int,int,float)
433 // eCSSUnit_HexColor -- #rrggbb
434 // eCSSUnit_ShortHexColor -- #rgb
435 //
436 // - IsFLoatColorUnit returns true for:
437 // eCSSUnit_PercentageRGBColor -- rgb(%,%,%)
438 // eCSSUnit_PercentageRGBAColor -- rgba(%,%,%,float)
439 // eCSSUnit_HSLColor -- hsl(float,%,%)
440 // eCSSUnit_HSLAColor -- hsla(float,%,%,float)
441 //
442 // - IsNumericColorUnit returns true for any of the above units.
443 //
444 // Note that color keywords and system colors are represented by
445 // eCSSUnit_EnumColor and eCSSUnit_Ident.
446 bool IsIntegerColorUnit() const { return IsIntegerColorUnit(mUnit); }
447 bool IsFloatColorUnit() const { return IsFloatColorUnit(mUnit); }
448 bool IsNumericColorUnit() const { return IsNumericColorUnit(mUnit); }
449 static bool IsIntegerColorUnit(nsCSSUnit aUnit)
450 { return eCSSUnit_RGBColor <= aUnit && aUnit <= eCSSUnit_ShortHexColor; }
451 static bool IsFloatColorUnit(nsCSSUnit aUnit)
452 { return eCSSUnit_PercentageRGBColor <= aUnit &&
453 aUnit <= eCSSUnit_HSLAColor; }
454 static bool IsNumericColorUnit(nsCSSUnit aUnit)
455 { return IsIntegerColorUnit(aUnit) || IsFloatColorUnit(aUnit); }
457 int32_t GetIntValue() const
458 {
459 NS_ABORT_IF_FALSE(mUnit == eCSSUnit_Integer ||
460 mUnit == eCSSUnit_Enumerated ||
461 mUnit == eCSSUnit_EnumColor,
462 "not an int value");
463 return mValue.mInt;
464 }
466 nsCSSKeyword GetKeywordValue() const
467 {
468 NS_ABORT_IF_FALSE(mUnit == eCSSUnit_Enumerated, "not a keyword value");
469 return static_cast<nsCSSKeyword>(mValue.mInt);
470 }
472 float GetPercentValue() const
473 {
474 NS_ABORT_IF_FALSE(mUnit == eCSSUnit_Percent, "not a percent value");
475 return mValue.mFloat;
476 }
478 float GetFloatValue() const
479 {
480 NS_ABORT_IF_FALSE(eCSSUnit_Number <= mUnit, "not a float value");
481 MOZ_ASSERT(!mozilla::IsNaN(mValue.mFloat));
482 return mValue.mFloat;
483 }
485 float GetAngleValue() const
486 {
487 NS_ABORT_IF_FALSE(eCSSUnit_Degree <= mUnit &&
488 mUnit <= eCSSUnit_Turn, "not an angle value");
489 return mValue.mFloat;
490 }
492 // Converts any angle to radians.
493 double GetAngleValueInRadians() const;
495 nsAString& GetStringValue(nsAString& aBuffer) const
496 {
497 NS_ABORT_IF_FALSE(UnitHasStringValue(), "not a string value");
498 aBuffer.Truncate();
499 uint32_t len = NS_strlen(GetBufferValue(mValue.mString));
500 mValue.mString->ToString(len, aBuffer);
501 return aBuffer;
502 }
504 const char16_t* GetStringBufferValue() const
505 {
506 NS_ABORT_IF_FALSE(UnitHasStringValue(), "not a string value");
507 return GetBufferValue(mValue.mString);
508 }
510 nscolor GetColorValue() const;
511 bool IsNonTransparentColor() const;
513 Array* GetArrayValue() const
514 {
515 NS_ABORT_IF_FALSE(UnitHasArrayValue(), "not an array value");
516 return mValue.mArray;
517 }
519 nsIURI* GetURLValue() const
520 {
521 NS_ABORT_IF_FALSE(mUnit == eCSSUnit_URL || mUnit == eCSSUnit_Image,
522 "not a URL value");
523 return mUnit == eCSSUnit_URL ?
524 mValue.mURL->GetURI() : mValue.mImage->GetURI();
525 }
527 nsCSSValueGradient* GetGradientValue() const
528 {
529 NS_ABORT_IF_FALSE(mUnit == eCSSUnit_Gradient, "not a gradient value");
530 return mValue.mGradient;
531 }
533 nsCSSValueTokenStream* GetTokenStreamValue() const
534 {
535 NS_ABORT_IF_FALSE(mUnit == eCSSUnit_TokenStream, "not a token stream value");
536 return mValue.mTokenStream;
537 }
539 nsCSSValueSharedList* GetSharedListValue() const
540 {
541 NS_ABORT_IF_FALSE(mUnit == eCSSUnit_SharedList, "not a shared list value");
542 return mValue.mSharedList;
543 }
545 // bodies of these are below
546 inline nsCSSValuePair& GetPairValue();
547 inline const nsCSSValuePair& GetPairValue() const;
549 inline nsCSSRect& GetRectValue();
550 inline const nsCSSRect& GetRectValue() const;
552 inline nsCSSValueList* GetListValue();
553 inline const nsCSSValueList* GetListValue() const;
555 inline nsCSSValuePairList* GetPairListValue();
556 inline const nsCSSValuePairList* GetPairListValue() const;
558 inline nsCSSValueTriplet& GetTripletValue();
559 inline const nsCSSValueTriplet& GetTripletValue() const;
562 mozilla::css::URLValue* GetURLStructValue() const
563 {
564 // Not allowing this for Image values, because if the caller takes
565 // a ref to them they won't be able to delete them properly.
566 NS_ABORT_IF_FALSE(mUnit == eCSSUnit_URL, "not a URL value");
567 return mValue.mURL;
568 }
570 mozilla::css::ImageValue* GetImageStructValue() const
571 {
572 NS_ABORT_IF_FALSE(mUnit == eCSSUnit_Image, "not an Image value");
573 return mValue.mImage;
574 }
576 mozilla::css::GridTemplateAreasValue* GetGridTemplateAreas() const
577 {
578 NS_ABORT_IF_FALSE(mUnit == eCSSUnit_GridTemplateAreas,
579 "not a grid-template-areas value");
580 return mValue.mGridTemplateAreas;
581 }
583 const char16_t* GetOriginalURLValue() const
584 {
585 NS_ABORT_IF_FALSE(mUnit == eCSSUnit_URL || mUnit == eCSSUnit_Image,
586 "not a URL value");
587 return GetBufferValue(mUnit == eCSSUnit_URL ?
588 mValue.mURL->mString :
589 mValue.mImage->mString);
590 }
592 // Not making this inline because that would force us to include
593 // imgIRequest.h, which leads to REQUIRES hell, since this header is included
594 // all over.
595 imgRequestProxy* GetImageValue(nsIDocument* aDocument) const;
597 nscoord GetFixedLength(nsPresContext* aPresContext) const;
598 nscoord GetPixelLength() const;
600 void Reset() // sets to null
601 {
602 if (mUnit != eCSSUnit_Null)
603 DoReset();
604 }
605 private:
606 void DoReset();
608 public:
609 void SetIntValue(int32_t aValue, nsCSSUnit aUnit);
610 void SetPercentValue(float aValue);
611 void SetFloatValue(float aValue, nsCSSUnit aUnit);
612 void SetStringValue(const nsString& aValue, nsCSSUnit aUnit);
613 void SetColorValue(nscolor aValue);
614 void SetIntegerColorValue(nscolor aValue, nsCSSUnit aUnit);
615 void SetFloatColorValue(float aComponent1,
616 float aComponent2,
617 float aComponent3,
618 float aAlpha, nsCSSUnit aUnit);
619 void SetArrayValue(nsCSSValue::Array* aArray, nsCSSUnit aUnit);
620 void SetURLValue(mozilla::css::URLValue* aURI);
621 void SetImageValue(mozilla::css::ImageValue* aImage);
622 void SetGradientValue(nsCSSValueGradient* aGradient);
623 void SetTokenStreamValue(nsCSSValueTokenStream* aTokenStream);
624 void SetGridTemplateAreas(mozilla::css::GridTemplateAreasValue* aValue);
625 void SetPairValue(const nsCSSValuePair* aPair);
626 void SetPairValue(const nsCSSValue& xValue, const nsCSSValue& yValue);
627 void SetSharedListValue(nsCSSValueSharedList* aList);
628 void SetDependentListValue(nsCSSValueList* aList);
629 void SetDependentPairListValue(nsCSSValuePairList* aList);
630 void SetTripletValue(const nsCSSValueTriplet* aTriplet);
631 void SetTripletValue(const nsCSSValue& xValue, const nsCSSValue& yValue, const nsCSSValue& zValue);
632 void SetAutoValue();
633 void SetInheritValue();
634 void SetInitialValue();
635 void SetUnsetValue();
636 void SetNoneValue();
637 void SetAllValue();
638 void SetNormalValue();
639 void SetSystemFontValue();
640 void SetDummyValue();
641 void SetDummyInheritValue();
643 // These are a little different - they allocate storage for you and
644 // return a handle.
645 nsCSSRect& SetRectValue();
646 nsCSSValueList* SetListValue();
647 nsCSSValuePairList* SetPairListValue();
649 void StartImageLoad(nsIDocument* aDocument) const; // Only pretend const
651 // Initializes as a function value with the specified function id.
652 Array* InitFunction(nsCSSKeyword aFunctionId, uint32_t aNumArgs);
653 // Checks if this is a function value with the specified function id.
654 bool EqualsFunction(nsCSSKeyword aFunctionId) const;
656 // Returns an already addrefed buffer. Guaranteed to return non-null.
657 // (Will abort on allocation failure.)
658 static already_AddRefed<nsStringBuffer>
659 BufferFromString(const nsString& aValue);
661 size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
663 private:
664 static const char16_t* GetBufferValue(nsStringBuffer* aBuffer) {
665 return static_cast<char16_t*>(aBuffer->Data());
666 }
668 protected:
669 nsCSSUnit mUnit;
670 union {
671 int32_t mInt;
672 float mFloat;
673 // Note: the capacity of the buffer may exceed the length of the string.
674 // If we're of a string type, mString is not null.
675 nsStringBuffer* mString;
676 nscolor mColor;
677 Array* mArray;
678 mozilla::css::URLValue* mURL;
679 mozilla::css::ImageValue* mImage;
680 mozilla::css::GridTemplateAreasValue* mGridTemplateAreas;
681 nsCSSValueGradient* mGradient;
682 nsCSSValueTokenStream* mTokenStream;
683 nsCSSValuePair_heap* mPair;
684 nsCSSRect_heap* mRect;
685 nsCSSValueTriplet_heap* mTriplet;
686 nsCSSValueList_heap* mList;
687 nsCSSValueList* mListDependent;
688 nsCSSValueSharedList* mSharedList;
689 nsCSSValuePairList_heap* mPairList;
690 nsCSSValuePairList* mPairListDependent;
691 nsCSSValueFloatColor* mFloatColor;
692 } mValue;
693 };
695 struct nsCSSValue::Array MOZ_FINAL {
697 // return |Array| with reference count of zero
698 static Array* Create(size_t aItemCount) {
699 return new (aItemCount) Array(aItemCount);
700 }
702 nsCSSValue& operator[](size_t aIndex) {
703 NS_ABORT_IF_FALSE(aIndex < mCount, "out of range");
704 return mArray[aIndex];
705 }
707 const nsCSSValue& operator[](size_t aIndex) const {
708 NS_ABORT_IF_FALSE(aIndex < mCount, "out of range");
709 return mArray[aIndex];
710 }
712 nsCSSValue& Item(size_t aIndex) { return (*this)[aIndex]; }
713 const nsCSSValue& Item(size_t aIndex) const { return (*this)[aIndex]; }
715 size_t Count() const { return mCount; }
717 bool operator==(const Array& aOther) const
718 {
719 if (mCount != aOther.mCount)
720 return false;
721 for (size_t i = 0; i < mCount; ++i)
722 if ((*this)[i] != aOther[i])
723 return false;
724 return true;
725 }
727 // XXXdholbert This uses a size_t ref count. Should we use a variant
728 // of NS_INLINE_DECL_REFCOUNTING that takes a type as an argument?
729 void AddRef() {
730 if (mRefCnt == size_t(-1)) { // really want SIZE_MAX
731 NS_WARNING("refcount overflow, leaking nsCSSValue::Array");
732 return;
733 }
734 ++mRefCnt;
735 NS_LOG_ADDREF(this, mRefCnt, "nsCSSValue::Array", sizeof(*this));
736 }
737 void Release() {
738 if (mRefCnt == size_t(-1)) { // really want SIZE_MAX
739 NS_WARNING("refcount overflow, leaking nsCSSValue::Array");
740 return;
741 }
742 --mRefCnt;
743 NS_LOG_RELEASE(this, mRefCnt, "nsCSSValue::Array");
744 if (mRefCnt == 0)
745 delete this;
746 }
748 private:
750 size_t mRefCnt;
751 const size_t mCount;
752 // This must be the last sub-object, since we extend this array to
753 // be of size mCount; it needs to be a sub-object so it gets proper
754 // alignment.
755 nsCSSValue mArray[1];
757 void* operator new(size_t aSelfSize, size_t aItemCount) CPP_THROW_NEW {
758 NS_ABORT_IF_FALSE(aItemCount > 0, "cannot have a 0 item count");
759 return ::operator new(aSelfSize + sizeof(nsCSSValue) * (aItemCount - 1));
760 }
762 void operator delete(void* aPtr) { ::operator delete(aPtr); }
764 nsCSSValue* First() { return mArray; }
766 const nsCSSValue* First() const { return mArray; }
768 #define CSSVALUE_LIST_FOR_EXTRA_VALUES(var) \
769 for (nsCSSValue *var = First() + 1, *var##_end = First() + mCount; \
770 var != var##_end; ++var)
772 Array(size_t aItemCount)
773 : mRefCnt(0)
774 , mCount(aItemCount)
775 {
776 MOZ_COUNT_CTOR(nsCSSValue::Array);
777 CSSVALUE_LIST_FOR_EXTRA_VALUES(val) {
778 new (val) nsCSSValue();
779 }
780 }
782 ~Array()
783 {
784 MOZ_COUNT_DTOR(nsCSSValue::Array);
785 CSSVALUE_LIST_FOR_EXTRA_VALUES(val) {
786 val->~nsCSSValue();
787 }
788 }
790 size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
792 #undef CSSVALUE_LIST_FOR_EXTRA_VALUES
794 private:
795 Array(const Array& aOther) MOZ_DELETE;
796 Array& operator=(const Array& aOther) MOZ_DELETE;
797 };
799 // Prefer nsCSSValue::Array for lists of fixed size.
800 struct nsCSSValueList {
801 nsCSSValueList() : mNext(nullptr) { MOZ_COUNT_CTOR(nsCSSValueList); }
802 ~nsCSSValueList();
804 nsCSSValueList* Clone() const; // makes a deep copy
805 void CloneInto(nsCSSValueList* aList) const; // makes a deep copy into aList
806 void AppendToString(nsCSSProperty aProperty, nsAString& aResult,
807 nsCSSValue::Serialization aValueSerialization) const;
809 bool operator==(nsCSSValueList const& aOther) const;
810 bool operator!=(const nsCSSValueList& aOther) const
811 { return !(*this == aOther); }
813 size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
815 nsCSSValue mValue;
816 nsCSSValueList* mNext;
818 private:
819 nsCSSValueList(const nsCSSValueList& aCopy) // makes a shallow copy
820 : mValue(aCopy.mValue), mNext(nullptr)
821 {
822 MOZ_COUNT_CTOR(nsCSSValueList);
823 }
824 };
826 // nsCSSValueList_heap differs from nsCSSValueList only in being
827 // refcounted. It should not be necessary to use this class directly;
828 // it's an implementation detail of nsCSSValue.
829 struct nsCSSValueList_heap MOZ_FINAL : public nsCSSValueList {
830 NS_INLINE_DECL_REFCOUNTING(nsCSSValueList_heap)
832 size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
834 private:
835 // Private destructor, to discourage deletion outside of Release():
836 ~nsCSSValueList_heap()
837 {
838 }
839 };
841 // This is a reference counted list value. Note that the object is
842 // a wrapper for the reference count and a pointer to the head of the
843 // list, whereas the other list types (such as nsCSSValueList) do
844 // not have such a wrapper.
845 struct nsCSSValueSharedList MOZ_FINAL {
846 nsCSSValueSharedList()
847 : mHead(nullptr)
848 {
849 MOZ_COUNT_CTOR(nsCSSValueSharedList);
850 }
852 // Takes ownership of aList.
853 nsCSSValueSharedList(nsCSSValueList* aList)
854 : mHead(aList)
855 {
856 MOZ_COUNT_CTOR(nsCSSValueSharedList);
857 }
859 private:
860 // Private destructor, to discourage deletion outside of Release():
861 ~nsCSSValueSharedList();
863 public:
864 NS_INLINE_DECL_REFCOUNTING(nsCSSValueSharedList)
866 void AppendToString(nsCSSProperty aProperty, nsAString& aResult,
867 nsCSSValue::Serialization aValueSerialization) const;
869 bool operator==(nsCSSValueSharedList const& aOther) const;
870 bool operator!=(const nsCSSValueSharedList& aOther) const
871 { return !(*this == aOther); }
873 size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
875 nsCSSValueList* mHead;
876 };
878 // This has to be here so that the relationship between nsCSSValueList
879 // and nsCSSValueList_heap is visible.
880 inline nsCSSValueList*
881 nsCSSValue::GetListValue()
882 {
883 if (mUnit == eCSSUnit_List)
884 return mValue.mList;
885 else {
886 NS_ABORT_IF_FALSE(mUnit == eCSSUnit_ListDep, "not a pairlist value");
887 return mValue.mListDependent;
888 }
889 }
891 inline const nsCSSValueList*
892 nsCSSValue::GetListValue() const
893 {
894 if (mUnit == eCSSUnit_List)
895 return mValue.mList;
896 else {
897 NS_ABORT_IF_FALSE(mUnit == eCSSUnit_ListDep, "not a pairlist value");
898 return mValue.mListDependent;
899 }
900 }
902 struct nsCSSRect {
903 nsCSSRect(void);
904 nsCSSRect(const nsCSSRect& aCopy);
905 ~nsCSSRect();
907 void AppendToString(nsCSSProperty aProperty, nsAString& aResult,
908 nsCSSValue::Serialization aValueSerialization) const;
910 bool operator==(const nsCSSRect& aOther) const {
911 return mTop == aOther.mTop &&
912 mRight == aOther.mRight &&
913 mBottom == aOther.mBottom &&
914 mLeft == aOther.mLeft;
915 }
917 bool operator!=(const nsCSSRect& aOther) const {
918 return mTop != aOther.mTop ||
919 mRight != aOther.mRight ||
920 mBottom != aOther.mBottom ||
921 mLeft != aOther.mLeft;
922 }
924 void SetAllSidesTo(const nsCSSValue& aValue);
926 bool AllSidesEqualTo(const nsCSSValue& aValue) const {
927 return mTop == aValue &&
928 mRight == aValue &&
929 mBottom == aValue &&
930 mLeft == aValue;
931 }
933 void Reset() {
934 mTop.Reset();
935 mRight.Reset();
936 mBottom.Reset();
937 mLeft.Reset();
938 }
940 bool HasValue() const {
941 return
942 mTop.GetUnit() != eCSSUnit_Null ||
943 mRight.GetUnit() != eCSSUnit_Null ||
944 mBottom.GetUnit() != eCSSUnit_Null ||
945 mLeft.GetUnit() != eCSSUnit_Null;
946 }
948 nsCSSValue mTop;
949 nsCSSValue mRight;
950 nsCSSValue mBottom;
951 nsCSSValue mLeft;
953 typedef nsCSSValue nsCSSRect::*side_type;
954 static const side_type sides[4];
955 };
957 // nsCSSRect_heap differs from nsCSSRect only in being
958 // refcounted. It should not be necessary to use this class directly;
959 // it's an implementation detail of nsCSSValue.
960 struct nsCSSRect_heap MOZ_FINAL : public nsCSSRect {
961 NS_INLINE_DECL_REFCOUNTING(nsCSSRect_heap)
963 size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
965 private:
966 // Private destructor, to discourage deletion outside of Release():
967 ~nsCSSRect_heap()
968 {
969 }
970 };
972 // This has to be here so that the relationship between nsCSSRect
973 // and nsCSSRect_heap is visible.
974 inline nsCSSRect&
975 nsCSSValue::GetRectValue()
976 {
977 NS_ABORT_IF_FALSE(mUnit == eCSSUnit_Rect, "not a rect value");
978 return *mValue.mRect;
979 }
981 inline const nsCSSRect&
982 nsCSSValue::GetRectValue() const
983 {
984 NS_ABORT_IF_FALSE(mUnit == eCSSUnit_Rect, "not a rect value");
985 return *mValue.mRect;
986 }
988 struct nsCSSValuePair {
989 nsCSSValuePair()
990 {
991 MOZ_COUNT_CTOR(nsCSSValuePair);
992 }
993 nsCSSValuePair(nsCSSUnit aUnit)
994 : mXValue(aUnit), mYValue(aUnit)
995 {
996 MOZ_COUNT_CTOR(nsCSSValuePair);
997 }
998 nsCSSValuePair(const nsCSSValue& aXValue, const nsCSSValue& aYValue)
999 : mXValue(aXValue), mYValue(aYValue)
1000 {
1001 MOZ_COUNT_CTOR(nsCSSValuePair);
1002 }
1003 nsCSSValuePair(const nsCSSValuePair& aCopy)
1004 : mXValue(aCopy.mXValue), mYValue(aCopy.mYValue)
1005 {
1006 MOZ_COUNT_CTOR(nsCSSValuePair);
1007 }
1008 ~nsCSSValuePair()
1009 {
1010 MOZ_COUNT_DTOR(nsCSSValuePair);
1011 }
1013 bool operator==(const nsCSSValuePair& aOther) const {
1014 return mXValue == aOther.mXValue &&
1015 mYValue == aOther.mYValue;
1016 }
1018 bool operator!=(const nsCSSValuePair& aOther) const {
1019 return mXValue != aOther.mXValue ||
1020 mYValue != aOther.mYValue;
1021 }
1023 bool BothValuesEqualTo(const nsCSSValue& aValue) const {
1024 return mXValue == aValue &&
1025 mYValue == aValue;
1026 }
1028 void SetBothValuesTo(const nsCSSValue& aValue) {
1029 mXValue = aValue;
1030 mYValue = aValue;
1031 }
1033 void Reset() {
1034 mXValue.Reset();
1035 mYValue.Reset();
1036 }
1038 bool HasValue() const {
1039 return mXValue.GetUnit() != eCSSUnit_Null ||
1040 mYValue.GetUnit() != eCSSUnit_Null;
1041 }
1043 void AppendToString(nsCSSProperty aProperty, nsAString& aResult,
1044 nsCSSValue::Serialization aValueSerialization) const;
1046 size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
1048 nsCSSValue mXValue;
1049 nsCSSValue mYValue;
1050 };
1052 // nsCSSValuePair_heap differs from nsCSSValuePair only in being
1053 // refcounted. It should not be necessary to use this class directly;
1054 // it's an implementation detail of nsCSSValue.
1055 struct nsCSSValuePair_heap MOZ_FINAL : public nsCSSValuePair {
1056 // forward constructor
1057 nsCSSValuePair_heap(const nsCSSValue& aXValue, const nsCSSValue& aYValue)
1058 : nsCSSValuePair(aXValue, aYValue)
1059 {}
1061 NS_INLINE_DECL_REFCOUNTING(nsCSSValuePair_heap)
1063 size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
1065 private:
1066 // Private destructor, to discourage deletion outside of Release():
1067 ~nsCSSValuePair_heap()
1068 {
1069 }
1070 };
1072 struct nsCSSValueTriplet {
1073 nsCSSValueTriplet()
1074 {
1075 MOZ_COUNT_CTOR(nsCSSValueTriplet);
1076 }
1077 nsCSSValueTriplet(nsCSSUnit aUnit)
1078 : mXValue(aUnit), mYValue(aUnit), mZValue(aUnit)
1079 {
1080 MOZ_COUNT_CTOR(nsCSSValueTriplet);
1081 }
1082 nsCSSValueTriplet(const nsCSSValue& aXValue,
1083 const nsCSSValue& aYValue,
1084 const nsCSSValue& aZValue)
1085 : mXValue(aXValue), mYValue(aYValue), mZValue(aZValue)
1086 {
1087 MOZ_COUNT_CTOR(nsCSSValueTriplet);
1088 }
1089 nsCSSValueTriplet(const nsCSSValueTriplet& aCopy)
1090 : mXValue(aCopy.mXValue), mYValue(aCopy.mYValue), mZValue(aCopy.mZValue)
1091 {
1092 MOZ_COUNT_CTOR(nsCSSValueTriplet);
1093 }
1094 ~nsCSSValueTriplet()
1095 {
1096 MOZ_COUNT_DTOR(nsCSSValueTriplet);
1097 }
1099 bool operator==(const nsCSSValueTriplet& aOther) const {
1100 return mXValue == aOther.mXValue &&
1101 mYValue == aOther.mYValue &&
1102 mZValue == aOther.mZValue;
1103 }
1105 bool operator!=(const nsCSSValueTriplet& aOther) const {
1106 return mXValue != aOther.mXValue ||
1107 mYValue != aOther.mYValue ||
1108 mZValue != aOther.mZValue;
1109 }
1111 bool AllValuesEqualTo(const nsCSSValue& aValue) const {
1112 return mXValue == aValue &&
1113 mYValue == aValue &&
1114 mZValue == aValue;
1115 }
1117 void SetAllValuesTo(const nsCSSValue& aValue) {
1118 mXValue = aValue;
1119 mYValue = aValue;
1120 mZValue = aValue;
1121 }
1123 void Reset() {
1124 mXValue.Reset();
1125 mYValue.Reset();
1126 mZValue.Reset();
1127 }
1129 bool HasValue() const {
1130 return mXValue.GetUnit() != eCSSUnit_Null ||
1131 mYValue.GetUnit() != eCSSUnit_Null ||
1132 mZValue.GetUnit() != eCSSUnit_Null;
1133 }
1135 void AppendToString(nsCSSProperty aProperty, nsAString& aResult,
1136 nsCSSValue::Serialization aValueSerialization) const;
1138 nsCSSValue mXValue;
1139 nsCSSValue mYValue;
1140 nsCSSValue mZValue;
1141 };
1143 // nsCSSValueTriplet_heap differs from nsCSSValueTriplet only in being
1144 // refcounted. It should not be necessary to use this class directly;
1145 // it's an implementation detail of nsCSSValue.
1146 struct nsCSSValueTriplet_heap MOZ_FINAL : public nsCSSValueTriplet {
1147 // forward constructor
1148 nsCSSValueTriplet_heap(const nsCSSValue& aXValue, const nsCSSValue& aYValue, const nsCSSValue& aZValue)
1149 : nsCSSValueTriplet(aXValue, aYValue, aZValue)
1150 {}
1152 NS_INLINE_DECL_REFCOUNTING(nsCSSValueTriplet_heap)
1154 size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
1156 private:
1157 // Private destructor, to discourage deletion outside of Release():
1158 ~nsCSSValueTriplet_heap()
1159 {
1160 }
1161 };
1163 // This has to be here so that the relationship between nsCSSValuePair
1164 // and nsCSSValuePair_heap is visible.
1165 inline nsCSSValuePair&
1166 nsCSSValue::GetPairValue()
1167 {
1168 NS_ABORT_IF_FALSE(mUnit == eCSSUnit_Pair, "not a pair value");
1169 return *mValue.mPair;
1170 }
1172 inline const nsCSSValuePair&
1173 nsCSSValue::GetPairValue() const
1174 {
1175 NS_ABORT_IF_FALSE(mUnit == eCSSUnit_Pair, "not a pair value");
1176 return *mValue.mPair;
1177 }
1179 inline nsCSSValueTriplet&
1180 nsCSSValue::GetTripletValue()
1181 {
1182 NS_ABORT_IF_FALSE(mUnit == eCSSUnit_Triplet, "not a triplet value");
1183 return *mValue.mTriplet;
1184 }
1186 inline const nsCSSValueTriplet&
1187 nsCSSValue::GetTripletValue() const
1188 {
1189 NS_ABORT_IF_FALSE(mUnit == eCSSUnit_Triplet, "not a triplet value");
1190 return *mValue.mTriplet;
1191 }
1193 // Maybe should be replaced with nsCSSValueList and nsCSSValue::Array?
1194 struct nsCSSValuePairList {
1195 nsCSSValuePairList() : mNext(nullptr) { MOZ_COUNT_CTOR(nsCSSValuePairList); }
1196 ~nsCSSValuePairList();
1198 nsCSSValuePairList* Clone() const; // makes a deep copy
1199 void AppendToString(nsCSSProperty aProperty, nsAString& aResult,
1200 nsCSSValue::Serialization aValueSerialization) const;
1202 bool operator==(const nsCSSValuePairList& aOther) const;
1203 bool operator!=(const nsCSSValuePairList& aOther) const
1204 { return !(*this == aOther); }
1206 size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
1208 nsCSSValue mXValue;
1209 nsCSSValue mYValue;
1210 nsCSSValuePairList* mNext;
1212 private:
1213 nsCSSValuePairList(const nsCSSValuePairList& aCopy) // makes a shallow copy
1214 : mXValue(aCopy.mXValue), mYValue(aCopy.mYValue), mNext(nullptr)
1215 {
1216 MOZ_COUNT_CTOR(nsCSSValuePairList);
1217 }
1218 };
1220 // nsCSSValuePairList_heap differs from nsCSSValuePairList only in being
1221 // refcounted. It should not be necessary to use this class directly;
1222 // it's an implementation detail of nsCSSValue.
1223 struct nsCSSValuePairList_heap MOZ_FINAL : public nsCSSValuePairList {
1224 NS_INLINE_DECL_REFCOUNTING(nsCSSValuePairList_heap)
1226 size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
1228 private:
1229 // Private destructor, to discourage deletion outside of Release():
1230 ~nsCSSValuePairList_heap()
1231 {
1232 }
1233 };
1235 // This has to be here so that the relationship between nsCSSValuePairList
1236 // and nsCSSValuePairList_heap is visible.
1237 inline nsCSSValuePairList*
1238 nsCSSValue::GetPairListValue()
1239 {
1240 if (mUnit == eCSSUnit_PairList)
1241 return mValue.mPairList;
1242 else {
1243 NS_ABORT_IF_FALSE (mUnit == eCSSUnit_PairListDep, "not a pairlist value");
1244 return mValue.mPairListDependent;
1245 }
1246 }
1248 inline const nsCSSValuePairList*
1249 nsCSSValue::GetPairListValue() const
1250 {
1251 if (mUnit == eCSSUnit_PairList)
1252 return mValue.mPairList;
1253 else {
1254 NS_ABORT_IF_FALSE (mUnit == eCSSUnit_PairListDep, "not a pairlist value");
1255 return mValue.mPairListDependent;
1256 }
1257 }
1259 struct nsCSSValueGradientStop {
1260 public:
1261 nsCSSValueGradientStop();
1262 // needed to keep bloat logs happy when we use the TArray
1263 // in nsCSSValueGradient
1264 nsCSSValueGradientStop(const nsCSSValueGradientStop& aOther);
1265 ~nsCSSValueGradientStop();
1267 nsCSSValue mLocation;
1268 nsCSSValue mColor;
1270 bool operator==(const nsCSSValueGradientStop& aOther) const
1271 {
1272 return (mLocation == aOther.mLocation &&
1273 mColor == aOther.mColor);
1274 }
1276 bool operator!=(const nsCSSValueGradientStop& aOther) const
1277 {
1278 return !(*this == aOther);
1279 }
1281 size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
1282 };
1284 struct nsCSSValueGradient MOZ_FINAL {
1285 nsCSSValueGradient(bool aIsRadial, bool aIsRepeating);
1287 // true if gradient is radial, false if it is linear
1288 bool mIsRadial;
1289 bool mIsRepeating;
1290 bool mIsLegacySyntax;
1291 bool mIsExplicitSize;
1292 // line position and angle
1293 nsCSSValuePair mBgPos;
1294 nsCSSValue mAngle;
1296 // Only meaningful if mIsRadial is true
1297 private:
1298 nsCSSValue mRadialValues[2];
1299 public:
1300 nsCSSValue& GetRadialShape()
1301 {
1302 MOZ_ASSERT(!mIsExplicitSize);
1303 return mRadialValues[0];
1304 }
1305 const nsCSSValue& GetRadialShape() const
1306 {
1307 MOZ_ASSERT(!mIsExplicitSize);
1308 return mRadialValues[0];
1309 }
1310 nsCSSValue& GetRadialSize()
1311 {
1312 MOZ_ASSERT(!mIsExplicitSize);
1313 return mRadialValues[1];
1314 }
1315 const nsCSSValue& GetRadialSize() const
1316 {
1317 MOZ_ASSERT(!mIsExplicitSize);
1318 return mRadialValues[1];
1319 }
1320 nsCSSValue& GetRadiusX()
1321 {
1322 MOZ_ASSERT(mIsExplicitSize);
1323 return mRadialValues[0];
1324 }
1325 const nsCSSValue& GetRadiusX() const
1326 {
1327 MOZ_ASSERT(mIsExplicitSize);
1328 return mRadialValues[0];
1329 }
1330 nsCSSValue& GetRadiusY()
1331 {
1332 MOZ_ASSERT(mIsExplicitSize);
1333 return mRadialValues[1];
1334 }
1335 const nsCSSValue& GetRadiusY() const
1336 {
1337 MOZ_ASSERT(mIsExplicitSize);
1338 return mRadialValues[1];
1339 }
1341 InfallibleTArray<nsCSSValueGradientStop> mStops;
1343 bool operator==(const nsCSSValueGradient& aOther) const
1344 {
1345 if (mIsRadial != aOther.mIsRadial ||
1346 mIsRepeating != aOther.mIsRepeating ||
1347 mIsLegacySyntax != aOther.mIsLegacySyntax ||
1348 mIsExplicitSize != aOther.mIsExplicitSize ||
1349 mBgPos != aOther.mBgPos ||
1350 mAngle != aOther.mAngle ||
1351 mRadialValues[0] != aOther.mRadialValues[0] ||
1352 mRadialValues[1] != aOther.mRadialValues[1])
1353 return false;
1355 if (mStops.Length() != aOther.mStops.Length())
1356 return false;
1358 for (uint32_t i = 0; i < mStops.Length(); i++) {
1359 if (mStops[i] != aOther.mStops[i])
1360 return false;
1361 }
1363 return true;
1364 }
1366 bool operator!=(const nsCSSValueGradient& aOther) const
1367 {
1368 return !(*this == aOther);
1369 }
1371 NS_INLINE_DECL_REFCOUNTING(nsCSSValueGradient)
1373 size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
1375 private:
1376 // Private destructor, to discourage deletion outside of Release():
1377 ~nsCSSValueGradient()
1378 {
1379 }
1381 nsCSSValueGradient(const nsCSSValueGradient& aOther) MOZ_DELETE;
1382 nsCSSValueGradient& operator=(const nsCSSValueGradient& aOther) MOZ_DELETE;
1383 };
1385 struct nsCSSValueTokenStream MOZ_FINAL {
1386 nsCSSValueTokenStream();
1388 private:
1389 // Private destructor, to discourage deletion outside of Release():
1390 ~nsCSSValueTokenStream();
1392 public:
1393 bool operator==(const nsCSSValueTokenStream& aOther) const
1394 {
1395 bool eq;
1396 return mPropertyID == aOther.mPropertyID &&
1397 mShorthandPropertyID == aOther.mShorthandPropertyID &&
1398 mTokenStream.Equals(aOther.mTokenStream) &&
1399 (mBaseURI == aOther.mBaseURI ||
1400 (mBaseURI && aOther.mBaseURI &&
1401 NS_SUCCEEDED(mBaseURI->Equals(aOther.mBaseURI, &eq)) &&
1402 eq)) &&
1403 (mSheetURI == aOther.mSheetURI ||
1404 (mSheetURI && aOther.mSheetURI &&
1405 NS_SUCCEEDED(mSheetURI->Equals(aOther.mSheetURI, &eq)) &&
1406 eq)) &&
1407 (mSheetPrincipal == aOther.mSheetPrincipal ||
1408 (mSheetPrincipal && aOther.mSheetPrincipal &&
1409 NS_SUCCEEDED(mSheetPrincipal->Equals(aOther.mSheetPrincipal,
1410 &eq)) &&
1411 eq));
1412 }
1414 bool operator!=(const nsCSSValueTokenStream& aOther) const
1415 {
1416 return !(*this == aOther);
1417 }
1419 NS_INLINE_DECL_REFCOUNTING(nsCSSValueTokenStream)
1421 size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
1423 // The property that has mTokenStream as its unparsed specified value.
1424 // When a variable reference is used in a shorthand property, a
1425 // TokenStream value is stored as the specified value for each of its
1426 // component longhand properties.
1427 nsCSSProperty mPropertyID;
1429 // The shorthand property that had a value with a variable reference,
1430 // which caused the longhand property identified by mPropertyID to have
1431 // a TokenStream value.
1432 nsCSSProperty mShorthandPropertyID;
1434 // The unparsed CSS corresponding to the specified value of the property.
1435 // When the value of a shorthand property has a variable reference, the
1436 // same mTokenStream value is used on each of the nsCSSValueTokenStream
1437 // objects that will be set by parsing the shorthand.
1438 nsString mTokenStream;
1440 nsCOMPtr<nsIURI> mBaseURI;
1441 nsCOMPtr<nsIURI> mSheetURI;
1442 nsCOMPtr<nsIPrincipal> mSheetPrincipal;
1443 nsCSSStyleSheet* mSheet;
1444 uint32_t mLineNumber;
1445 uint32_t mLineOffset;
1447 // This table is used to hold a reference on to any ImageValue that results
1448 // from re-parsing this token stream at computed value time. When properties
1449 // like background-image contain a normal url(), the Declaration's data block
1450 // will hold a reference to the ImageValue. When a token stream is used,
1451 // the Declaration only holds on to this nsCSSValueTokenStream object, and
1452 // the ImageValue would only exist for the duration of
1453 // nsRuleNode::WalkRuleTree, in the AutoCSSValueArray. So instead when
1454 // we re-parse a token stream and get an ImageValue, we record it in this
1455 // table so that the Declaration can be the object that keeps holding
1456 // a reference to it.
1457 nsTHashtable<nsRefPtrHashKey<mozilla::css::ImageValue> > mImageValues;
1459 private:
1460 nsCSSValueTokenStream(const nsCSSValueTokenStream& aOther) MOZ_DELETE;
1461 nsCSSValueTokenStream& operator=(const nsCSSValueTokenStream& aOther) MOZ_DELETE;
1462 };
1464 class nsCSSValueFloatColor MOZ_FINAL {
1465 public:
1466 nsCSSValueFloatColor(float aComponent1, float aComponent2, float aComponent3,
1467 float aAlpha)
1468 : mComponent1(aComponent1)
1469 , mComponent2(aComponent2)
1470 , mComponent3(aComponent3)
1471 , mAlpha(aAlpha)
1472 {
1473 MOZ_COUNT_CTOR(nsCSSValueFloatColor);
1474 }
1476 private:
1477 // Private destructor, to discourage deletion outside of Release():
1478 ~nsCSSValueFloatColor()
1479 {
1480 MOZ_COUNT_DTOR(nsCSSValueFloatColor);
1481 }
1483 public:
1484 bool operator==(nsCSSValueFloatColor& aOther) const;
1486 nscolor GetColorValue(nsCSSUnit aUnit) const;
1487 bool IsNonTransparentColor() const;
1489 void AppendToString(nsCSSUnit aUnit, nsAString& aResult) const;
1491 size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
1493 NS_INLINE_DECL_REFCOUNTING(nsCSSValueFloatColor)
1495 private:
1496 // FIXME: We should not be clamping specified RGB color components.
1497 float mComponent1; // 0..1 for RGB, 0..360 for HSL
1498 float mComponent2; // 0..1
1499 float mComponent3; // 0..1
1500 float mAlpha; // 0..1
1502 nsCSSValueFloatColor(const nsCSSValueFloatColor& aOther) MOZ_DELETE;
1503 nsCSSValueFloatColor& operator=(const nsCSSValueFloatColor& aOther)
1504 MOZ_DELETE;
1505 };
1507 struct nsCSSCornerSizes {
1508 nsCSSCornerSizes(void);
1509 nsCSSCornerSizes(const nsCSSCornerSizes& aCopy);
1510 ~nsCSSCornerSizes();
1512 // argument is a "full corner" constant from nsStyleConsts.h
1513 nsCSSValue const & GetCorner(uint32_t aCorner) const {
1514 return this->*corners[aCorner];
1515 }
1516 nsCSSValue & GetCorner(uint32_t aCorner) {
1517 return this->*corners[aCorner];
1518 }
1520 bool operator==(const nsCSSCornerSizes& aOther) const {
1521 NS_FOR_CSS_FULL_CORNERS(corner) {
1522 if (this->GetCorner(corner) != aOther.GetCorner(corner))
1523 return false;
1524 }
1525 return true;
1526 }
1528 bool operator!=(const nsCSSCornerSizes& aOther) const {
1529 NS_FOR_CSS_FULL_CORNERS(corner) {
1530 if (this->GetCorner(corner) != aOther.GetCorner(corner))
1531 return true;
1532 }
1533 return false;
1534 }
1536 bool HasValue() const {
1537 NS_FOR_CSS_FULL_CORNERS(corner) {
1538 if (this->GetCorner(corner).GetUnit() != eCSSUnit_Null)
1539 return true;
1540 }
1541 return false;
1542 }
1544 void Reset();
1546 nsCSSValue mTopLeft;
1547 nsCSSValue mTopRight;
1548 nsCSSValue mBottomRight;
1549 nsCSSValue mBottomLeft;
1551 protected:
1552 typedef nsCSSValue nsCSSCornerSizes::*corner_type;
1553 static const corner_type corners[4];
1554 };
1556 #endif /* nsCSSValue_h___ */