1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is mozilla.org code.
16 : *
17 : * The Initial Developer of the Original Code is
18 : * Netscape Communications Corporation.
19 : * Portions created by the Initial Developer are Copyright (C) 1998
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : *
24 : * Alternatively, the contents of this file may be used under the terms of
25 : * either of the GNU General Public License Version 2 or later (the "GPL"),
26 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 : * in which case the provisions of the GPL or the LGPL are applicable instead
28 : * of those above. If you wish to allow use of your version of this file only
29 : * under the terms of either the GPL or the LGPL, and not to allow others to
30 : * use your version of this file under the terms of the MPL, indicate your
31 : * decision by deleting the provisions above and replace them with the notice
32 : * and other provisions required by the GPL or the LGPL. If you do not delete
33 : * the provisions above, a recipient may use your version of this file under
34 : * the terms of any one of the MPL, the GPL or the LGPL.
35 : *
36 : * ***** END LICENSE BLOCK ***** */
37 :
38 : /* representation of simple property values within CSS declarations */
39 :
40 : #ifndef nsCSSValue_h___
41 : #define nsCSSValue_h___
42 :
43 : #include "mozilla/Attributes.h"
44 :
45 : #include "nsCOMPtr.h"
46 : #include "nsCRTGlue.h"
47 : #include "nsCSSKeywords.h"
48 : #include "nsCSSProperty.h"
49 : #include "nsColor.h"
50 : #include "nsCoord.h"
51 : #include "nsString.h"
52 : #include "nsStringBuffer.h"
53 : #include "nsTArray.h"
54 : #include "nsStyleConsts.h"
55 :
56 : class imgIRequest;
57 : class nsIDocument;
58 : class nsIPrincipal;
59 : class nsPresContext;
60 : class nsIURI;
61 :
62 : // Deletes a linked list iteratively to avoid blowing up the stack (bug 456196).
63 : #define NS_CSS_DELETE_LIST_MEMBER(type_, ptr_, member_) \
64 : { \
65 : type_ *cur = (ptr_)->member_; \
66 : (ptr_)->member_ = nsnull; \
67 : while (cur) { \
68 : type_ *next = cur->member_; \
69 : cur->member_ = nsnull; \
70 : delete cur; \
71 : cur = next; \
72 : } \
73 : }
74 :
75 : // Clones a linked list iteratively to avoid blowing up the stack.
76 : // If it fails to clone the entire list then 'to_' is deleted and
77 : // we return null.
78 : #define NS_CSS_CLONE_LIST_MEMBER(type_, from_, member_, to_, args_) \
79 : { \
80 : type_ *dest = (to_); \
81 : (to_)->member_ = nsnull; \
82 : for (const type_ *src = (from_)->member_; src; src = src->member_) { \
83 : type_ *clone = src->Clone args_; \
84 : if (!clone) { \
85 : delete (to_); \
86 : return nsnull; \
87 : } \
88 : dest->member_ = clone; \
89 : dest = clone; \
90 : } \
91 : }
92 :
93 : enum nsCSSUnit {
94 : eCSSUnit_Null = 0, // (n/a) null unit, value is not specified
95 : eCSSUnit_Auto = 1, // (n/a) value is algorithmic
96 : eCSSUnit_Inherit = 2, // (n/a) value is inherited
97 : eCSSUnit_Initial = 3, // (n/a) value is default UA value
98 : eCSSUnit_None = 4, // (n/a) value is none
99 : eCSSUnit_Normal = 5, // (n/a) value is normal (algorithmic, different than auto)
100 : eCSSUnit_System_Font = 6, // (n/a) value is -moz-use-system-font
101 : eCSSUnit_All = 7, // (n/a) value is all
102 : eCSSUnit_Dummy = 8, // (n/a) a fake but specified value, used
103 : // only in temporary values
104 : eCSSUnit_DummyInherit = 9, // (n/a) a fake but specified value, used
105 : // only in temporary values
106 :
107 : eCSSUnit_String = 11, // (PRUnichar*) a string value
108 : eCSSUnit_Ident = 12, // (PRUnichar*) a string value
109 : eCSSUnit_Families = 13, // (PRUnichar*) a string value
110 : eCSSUnit_Attr = 14, // (PRUnichar*) a attr(string) value
111 : eCSSUnit_Local_Font = 15, // (PRUnichar*) a local font name
112 : eCSSUnit_Font_Format = 16, // (PRUnichar*) a font format name
113 : eCSSUnit_Element = 17, // (PRUnichar*) an element id
114 :
115 : eCSSUnit_Array = 20, // (nsCSSValue::Array*) a list of values
116 : eCSSUnit_Counter = 21, // (nsCSSValue::Array*) a counter(string,[string]) value
117 : eCSSUnit_Counters = 22, // (nsCSSValue::Array*) a counters(string,string[,string]) value
118 : eCSSUnit_Cubic_Bezier = 23, // (nsCSSValue::Array*) a list of float values
119 : eCSSUnit_Steps = 24, // (nsCSSValue::Array*) a list of (integer, enumerated)
120 : eCSSUnit_Function = 25, // (nsCSSValue::Array*) a function with
121 : // parameters. First elem of array is name,
122 : // the rest of the values are arguments.
123 :
124 : // The top level of a calc() expression is eCSSUnit_Calc. All
125 : // remaining eCSSUnit_Calc_* units only occur inside these toplevel
126 : // calc values.
127 :
128 : // eCSSUnit_Calc has an array with exactly 1 element. eCSSUnit_Calc
129 : // exists so we can distinguish calc(2em) from 2em as specified values
130 : // (but we drop this distinction for nsStyleCoord when we store
131 : // computed values).
132 : eCSSUnit_Calc = 30, // (nsCSSValue::Array*) calc() value
133 : // Plus, Minus, Times_* and Divided have arrays with exactly 2
134 : // elements. a + b + c + d is grouped as ((a + b) + c) + d
135 : eCSSUnit_Calc_Plus = 31, // (nsCSSValue::Array*) + node within calc()
136 : eCSSUnit_Calc_Minus = 32, // (nsCSSValue::Array*) - within calc
137 : eCSSUnit_Calc_Times_L = 33, // (nsCSSValue::Array*) num * val within calc
138 : eCSSUnit_Calc_Times_R = 34, // (nsCSSValue::Array*) val * num within calc
139 : eCSSUnit_Calc_Divided = 35, // (nsCSSValue::Array*) / within calc
140 :
141 : eCSSUnit_URL = 40, // (nsCSSValue::URL*) value
142 : eCSSUnit_Image = 41, // (nsCSSValue::Image*) value
143 : eCSSUnit_Gradient = 42, // (nsCSSValueGradient*) value
144 :
145 : eCSSUnit_Pair = 50, // (nsCSSValuePair*) pair of values
146 : eCSSUnit_Triplet = 51, // (nsCSSValueTriplet*) triplet of values
147 : eCSSUnit_Rect = 52, // (nsCSSRect*) rectangle (four values)
148 : eCSSUnit_List = 53, // (nsCSSValueList*) list of values
149 : eCSSUnit_ListDep = 54, // (nsCSSValueList*) same as List
150 : // but does not own the list
151 : eCSSUnit_PairList = 55, // (nsCSSValuePairList*) list of value pairs
152 : eCSSUnit_PairListDep = 56, // (nsCSSValuePairList*) same as PairList
153 : // but does not own the list
154 :
155 : eCSSUnit_Integer = 70, // (int) simple value
156 : eCSSUnit_Enumerated = 71, // (int) value has enumerated meaning
157 :
158 : eCSSUnit_EnumColor = 80, // (int) enumerated color (kColorKTable)
159 : eCSSUnit_Color = 81, // (nscolor) an RGBA value
160 :
161 : eCSSUnit_Percent = 90, // (float) 1.0 == 100%) value is percentage of something
162 : eCSSUnit_Number = 91, // (float) value is numeric (usually multiplier, different behavior that percent)
163 :
164 : // Physical length units
165 : eCSSUnit_PhysicalMillimeter = 200, // (float) 1/25.4 inch
166 :
167 : // Length units - relative
168 : // Font relative measure
169 : eCSSUnit_EM = 800, // (float) == current font size
170 : eCSSUnit_XHeight = 801, // (float) distance from top of lower case x to baseline
171 : eCSSUnit_Char = 802, // (float) number of characters, used for width with monospace font
172 : eCSSUnit_RootEM = 803, // (float) == root element font size
173 :
174 : // Screen relative measure
175 : eCSSUnit_Point = 900, // (float) 4/3 of a CSS pixel
176 : eCSSUnit_Inch = 901, // (float) 96 CSS pixels
177 : eCSSUnit_Millimeter = 902, // (float) 96/25.4 CSS pixels
178 : eCSSUnit_Centimeter = 903, // (float) 96/2.54 CSS pixels
179 : eCSSUnit_Pica = 904, // (float) 12 points == 16 CSS pixls
180 : eCSSUnit_Pixel = 905, // (float) CSS pixel unit
181 :
182 : // Angular units
183 : eCSSUnit_Degree = 1000, // (float) 360 per circle
184 : eCSSUnit_Grad = 1001, // (float) 400 per circle
185 : eCSSUnit_Radian = 1002, // (float) 2*pi per circle
186 : eCSSUnit_Turn = 1003, // (float) 1 per circle
187 :
188 : // Frequency units
189 : eCSSUnit_Hertz = 2000, // (float) 1/seconds
190 : eCSSUnit_Kilohertz = 2001, // (float) 1000 Hertz
191 :
192 : // Time units
193 : eCSSUnit_Seconds = 3000, // (float) Standard time
194 : eCSSUnit_Milliseconds = 3001 // (float) 1/1000 second
195 : };
196 :
197 : struct nsCSSValueGradient;
198 : struct nsCSSValuePair;
199 : struct nsCSSValuePair_heap;
200 : struct nsCSSRect;
201 : struct nsCSSRect_heap;
202 : struct nsCSSValueList;
203 : struct nsCSSValueList_heap;
204 : struct nsCSSValuePairList;
205 : struct nsCSSValuePairList_heap;
206 : struct nsCSSValueTriplet;
207 : struct nsCSSValueTriplet_heap;
208 :
209 : class nsCSSValue {
210 : public:
211 : struct Array;
212 : friend struct Array;
213 :
214 : struct URL;
215 : friend struct URL;
216 :
217 : struct Image;
218 : friend struct Image;
219 :
220 : // for valueless units only (null, auto, inherit, none, all, normal)
221 0 : explicit nsCSSValue(nsCSSUnit aUnit = eCSSUnit_Null)
222 0 : : mUnit(aUnit)
223 : {
224 0 : NS_ABORT_IF_FALSE(aUnit <= eCSSUnit_DummyInherit, "not a valueless unit");
225 0 : }
226 :
227 : nsCSSValue(PRInt32 aValue, nsCSSUnit aUnit);
228 : nsCSSValue(float aValue, nsCSSUnit aUnit);
229 : nsCSSValue(const nsString& aValue, nsCSSUnit aUnit);
230 : nsCSSValue(Array* aArray, nsCSSUnit aUnit);
231 : explicit nsCSSValue(URL* aValue);
232 : explicit nsCSSValue(Image* aValue);
233 : explicit nsCSSValue(nsCSSValueGradient* aValue);
234 : nsCSSValue(const nsCSSValue& aCopy);
235 0 : ~nsCSSValue() { Reset(); }
236 :
237 : nsCSSValue& operator=(const nsCSSValue& aCopy);
238 : bool operator==(const nsCSSValue& aOther) const;
239 :
240 : bool operator!=(const nsCSSValue& aOther) const
241 : {
242 : return !(*this == aOther);
243 : }
244 :
245 : /**
246 : * Serialize |this| as a specified value for |aProperty| and append
247 : * it to |aResult|.
248 : */
249 : void AppendToString(nsCSSProperty aProperty, nsAString& aResult) const;
250 :
251 0 : nsCSSUnit GetUnit() const { return mUnit; }
252 : bool IsLengthUnit() const
253 : { return eCSSUnit_PhysicalMillimeter <= mUnit && mUnit <= eCSSUnit_Pixel; }
254 : /**
255 : * A "fixed" length unit is one that means a specific physical length
256 : * which we try to match based on the physical characteristics of an
257 : * output device.
258 : */
259 : bool IsFixedLengthUnit() const
260 : { return mUnit == eCSSUnit_PhysicalMillimeter; }
261 : /**
262 : * What the spec calls relative length units is, for us, split
263 : * between relative length units and pixel length units.
264 : *
265 : * A "relative" length unit is a multiple of some derived metric,
266 : * such as a font em-size, which itself was controlled by an input CSS
267 : * length. Relative length units should not be scaled by zooming, since
268 : * the underlying CSS length would already have been scaled.
269 : */
270 : bool IsRelativeLengthUnit() const
271 : { return eCSSUnit_EM <= mUnit && mUnit <= eCSSUnit_RootEM; }
272 : /**
273 : * A "pixel" length unit is a some multiple of CSS pixels.
274 : */
275 : bool IsPixelLengthUnit() const
276 : { return eCSSUnit_Point <= mUnit && mUnit <= eCSSUnit_Pixel; }
277 : bool IsAngularUnit() const
278 : { return eCSSUnit_Degree <= mUnit && mUnit <= eCSSUnit_Turn; }
279 : bool IsFrequencyUnit() const
280 : { return eCSSUnit_Hertz <= mUnit && mUnit <= eCSSUnit_Kilohertz; }
281 : bool IsTimeUnit() const
282 : { return eCSSUnit_Seconds <= mUnit && mUnit <= eCSSUnit_Milliseconds; }
283 : bool IsCalcUnit() const
284 : { return eCSSUnit_Calc <= mUnit && mUnit <= eCSSUnit_Calc_Divided; }
285 :
286 : bool UnitHasStringValue() const
287 : { return eCSSUnit_String <= mUnit && mUnit <= eCSSUnit_Element; }
288 : bool UnitHasArrayValue() const
289 : { return eCSSUnit_Array <= mUnit && mUnit <= eCSSUnit_Calc_Divided; }
290 :
291 0 : PRInt32 GetIntValue() const
292 : {
293 0 : NS_ABORT_IF_FALSE(mUnit == eCSSUnit_Integer ||
294 : mUnit == eCSSUnit_Enumerated ||
295 : mUnit == eCSSUnit_EnumColor,
296 : "not an int value");
297 0 : return mValue.mInt;
298 : }
299 :
300 : float GetPercentValue() const
301 : {
302 : NS_ABORT_IF_FALSE(mUnit == eCSSUnit_Percent, "not a percent value");
303 : return mValue.mFloat;
304 : }
305 :
306 : float GetFloatValue() const
307 : {
308 : NS_ABORT_IF_FALSE(eCSSUnit_Number <= mUnit, "not a float value");
309 : return mValue.mFloat;
310 : }
311 :
312 : float GetAngleValue() const
313 : {
314 : NS_ABORT_IF_FALSE(eCSSUnit_Degree <= mUnit &&
315 : mUnit <= eCSSUnit_Turn, "not an angle value");
316 : return mValue.mFloat;
317 : }
318 :
319 : // Converts any angle to radians.
320 : double GetAngleValueInRadians() const;
321 :
322 : nsAString& GetStringValue(nsAString& aBuffer) const
323 : {
324 : NS_ABORT_IF_FALSE(UnitHasStringValue(), "not a string value");
325 : aBuffer.Truncate();
326 : PRUint32 len = NS_strlen(GetBufferValue(mValue.mString));
327 : mValue.mString->ToString(len, aBuffer);
328 : return aBuffer;
329 : }
330 :
331 : const PRUnichar* GetStringBufferValue() const
332 : {
333 : NS_ABORT_IF_FALSE(UnitHasStringValue(), "not a string value");
334 : return GetBufferValue(mValue.mString);
335 : }
336 :
337 : nscolor GetColorValue() const
338 : {
339 : NS_ABORT_IF_FALSE((mUnit == eCSSUnit_Color), "not a color value");
340 : return mValue.mColor;
341 : }
342 :
343 : bool IsNonTransparentColor() const;
344 :
345 : Array* GetArrayValue() const
346 : {
347 : NS_ABORT_IF_FALSE(UnitHasArrayValue(), "not an array value");
348 : return mValue.mArray;
349 : }
350 :
351 : nsIURI* GetURLValue() const
352 : {
353 : NS_ABORT_IF_FALSE(mUnit == eCSSUnit_URL || mUnit == eCSSUnit_Image,
354 : "not a URL value");
355 : return mUnit == eCSSUnit_URL ?
356 : mValue.mURL->GetURI() : mValue.mImage->GetURI();
357 : }
358 :
359 : nsCSSValueGradient* GetGradientValue() const
360 : {
361 : NS_ABORT_IF_FALSE(mUnit == eCSSUnit_Gradient, "not a gradient value");
362 : return mValue.mGradient;
363 : }
364 :
365 : // bodies of these are below
366 : inline nsCSSValuePair& GetPairValue();
367 : inline const nsCSSValuePair& GetPairValue() const;
368 :
369 : inline nsCSSRect& GetRectValue();
370 : inline const nsCSSRect& GetRectValue() const;
371 :
372 : inline nsCSSValueList* GetListValue();
373 : inline const nsCSSValueList* GetListValue() const;
374 :
375 : inline nsCSSValuePairList* GetPairListValue();
376 : inline const nsCSSValuePairList* GetPairListValue() const;
377 :
378 : inline nsCSSValueTriplet& GetTripletValue();
379 : inline const nsCSSValueTriplet& GetTripletValue() const;
380 :
381 : URL* GetURLStructValue() const
382 : {
383 : // Not allowing this for Image values, because if the caller takes
384 : // a ref to them they won't be able to delete them properly.
385 : NS_ABORT_IF_FALSE(mUnit == eCSSUnit_URL, "not a URL value");
386 : return mValue.mURL;
387 : }
388 :
389 : const PRUnichar* GetOriginalURLValue() const
390 : {
391 : NS_ABORT_IF_FALSE(mUnit == eCSSUnit_URL || mUnit == eCSSUnit_Image,
392 : "not a URL value");
393 : return GetBufferValue(mUnit == eCSSUnit_URL ?
394 : mValue.mURL->mString :
395 : mValue.mImage->mString);
396 : }
397 :
398 : // Not making this inline because that would force us to include
399 : // imgIRequest.h, which leads to REQUIRES hell, since this header is included
400 : // all over.
401 : imgIRequest* GetImageValue() const;
402 :
403 : nscoord GetFixedLength(nsPresContext* aPresContext) const;
404 : nscoord GetPixelLength() const;
405 :
406 0 : void Reset() // sets to null
407 : {
408 0 : if (mUnit != eCSSUnit_Null)
409 0 : DoReset();
410 0 : }
411 : private:
412 : void DoReset();
413 :
414 : public:
415 : void SetIntValue(PRInt32 aValue, nsCSSUnit aUnit);
416 : void SetPercentValue(float aValue);
417 : void SetFloatValue(float aValue, nsCSSUnit aUnit);
418 : void SetStringValue(const nsString& aValue, nsCSSUnit aUnit);
419 : void SetColorValue(nscolor aValue);
420 : void SetArrayValue(nsCSSValue::Array* aArray, nsCSSUnit aUnit);
421 : void SetURLValue(nsCSSValue::URL* aURI);
422 : void SetImageValue(nsCSSValue::Image* aImage);
423 : void SetGradientValue(nsCSSValueGradient* aGradient);
424 : void SetPairValue(const nsCSSValuePair* aPair);
425 : void SetPairValue(const nsCSSValue& xValue, const nsCSSValue& yValue);
426 : void SetDependentListValue(nsCSSValueList* aList);
427 : void SetDependentPairListValue(nsCSSValuePairList* aList);
428 : void SetTripletValue(const nsCSSValueTriplet* aTriplet);
429 : void SetTripletValue(const nsCSSValue& xValue, const nsCSSValue& yValue, const nsCSSValue& zValue);
430 : void SetAutoValue();
431 : void SetInheritValue();
432 : void SetInitialValue();
433 : void SetNoneValue();
434 : void SetAllValue();
435 : void SetNormalValue();
436 : void SetSystemFontValue();
437 : void SetDummyValue();
438 : void SetDummyInheritValue();
439 :
440 : // These are a little different - they allocate storage for you and
441 : // return a handle.
442 : nsCSSRect& SetRectValue();
443 : nsCSSValueList* SetListValue();
444 : nsCSSValuePairList* SetPairListValue();
445 :
446 : void StartImageLoad(nsIDocument* aDocument) const; // Only pretend const
447 :
448 : // Initializes as a function value with the specified function id.
449 : Array* InitFunction(nsCSSKeyword aFunctionId, PRUint32 aNumArgs);
450 : // Checks if this is a function value with the specified function id.
451 : bool EqualsFunction(nsCSSKeyword aFunctionId) const;
452 :
453 : // Returns an already addrefed buffer. Can return null on allocation
454 : // failure.
455 : static already_AddRefed<nsStringBuffer>
456 : BufferFromString(const nsString& aValue);
457 :
458 : size_t SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const;
459 :
460 : struct URL {
461 : // Methods are not inline because using an nsIPrincipal means requiring
462 : // caps, which leads to REQUIRES hell, since this header is included all
463 : // over.
464 :
465 : // For both constructors aString must not be null.
466 : // For both constructors aOriginPrincipal must not be null.
467 : // Construct with a base URI; this will create the actual URI lazily from
468 : // aString and aBaseURI.
469 : URL(nsStringBuffer* aString, nsIURI* aBaseURI, nsIURI* aReferrer,
470 : nsIPrincipal* aOriginPrincipal);
471 : // Construct with the actual URI.
472 : URL(nsIURI* aURI, nsStringBuffer* aString, nsIURI* aReferrer,
473 : nsIPrincipal* aOriginPrincipal);
474 :
475 : ~URL();
476 :
477 : bool operator==(const URL& aOther) const;
478 :
479 : // URIEquals only compares URIs and principals (unlike operator==, which
480 : // also compares the original strings). URIEquals also assumes that the
481 : // mURI member of both URL objects is non-null. Do NOT call this method
482 : // unless you're sure this is the case.
483 : bool URIEquals(const URL& aOther) const;
484 :
485 : nsIURI* GetURI() const;
486 :
487 : size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const;
488 :
489 : private:
490 : // If mURIResolved is false, mURI stores the base URI.
491 : // If mURIResolved is true, mURI stores the URI we resolve to; this may be
492 : // null if the URI is invalid.
493 : mutable nsCOMPtr<nsIURI> mURI;
494 : public:
495 : nsStringBuffer* mString; // Could use nsRefPtr, but it'd add useless
496 : // null-checks; this is never null.
497 : nsCOMPtr<nsIURI> mReferrer;
498 : nsCOMPtr<nsIPrincipal> mOriginPrincipal;
499 :
500 : NS_INLINE_DECL_REFCOUNTING(nsCSSValue::URL)
501 :
502 : private:
503 : mutable bool mURIResolved;
504 :
505 : URL(const URL& aOther) MOZ_DELETE;
506 : URL& operator=(const URL& aOther) MOZ_DELETE;
507 : };
508 :
509 : struct Image : public URL {
510 : // Not making the constructor and destructor inline because that would
511 : // force us to include imgIRequest.h, which leads to REQUIRES hell, since
512 : // this header is included all over.
513 : // aString must not be null.
514 : Image(nsIURI* aURI, nsStringBuffer* aString, nsIURI* aReferrer,
515 : nsIPrincipal* aOriginPrincipal, nsIDocument* aDocument);
516 : ~Image();
517 :
518 : // Inherit operator== from nsCSSValue::URL
519 :
520 : nsCOMPtr<imgIRequest> mRequest; // null == image load blocked or somehow failed
521 :
522 : // Override AddRef and Release to not only log ourselves correctly, but
523 : // also so that we delete correctly without a virtual destructor
524 : NS_INLINE_DECL_REFCOUNTING(nsCSSValue::Image)
525 : };
526 :
527 : private:
528 : static const PRUnichar* GetBufferValue(nsStringBuffer* aBuffer) {
529 : return static_cast<PRUnichar*>(aBuffer->Data());
530 : }
531 :
532 : protected:
533 : nsCSSUnit mUnit;
534 : union {
535 : PRInt32 mInt;
536 : float mFloat;
537 : // Note: the capacity of the buffer may exceed the length of the string.
538 : // If we're of a string type, mString is not null.
539 : nsStringBuffer* mString;
540 : nscolor mColor;
541 : Array* mArray;
542 : URL* mURL;
543 : Image* mImage;
544 : nsCSSValueGradient* mGradient;
545 : nsCSSValuePair_heap* mPair;
546 : nsCSSRect_heap* mRect;
547 : nsCSSValueTriplet_heap* mTriplet;
548 : nsCSSValueList_heap* mList;
549 : nsCSSValueList* mListDependent;
550 : nsCSSValuePairList_heap* mPairList;
551 : nsCSSValuePairList* mPairListDependent;
552 : } mValue;
553 : };
554 :
555 : struct nsCSSValue::Array {
556 :
557 : // return |Array| with reference count of zero
558 : static Array* Create(size_t aItemCount) {
559 : return new (aItemCount) Array(aItemCount);
560 : }
561 :
562 : nsCSSValue& operator[](size_t aIndex) {
563 : NS_ABORT_IF_FALSE(aIndex < mCount, "out of range");
564 : return mArray[aIndex];
565 : }
566 :
567 : const nsCSSValue& operator[](size_t aIndex) const {
568 : NS_ABORT_IF_FALSE(aIndex < mCount, "out of range");
569 : return mArray[aIndex];
570 : }
571 :
572 : nsCSSValue& Item(size_t aIndex) { return (*this)[aIndex]; }
573 : const nsCSSValue& Item(size_t aIndex) const { return (*this)[aIndex]; }
574 :
575 : size_t Count() const { return mCount; }
576 :
577 : bool operator==(const Array& aOther) const
578 : {
579 : if (mCount != aOther.mCount)
580 : return false;
581 : for (size_t i = 0; i < mCount; ++i)
582 : if ((*this)[i] != aOther[i])
583 : return false;
584 : return true;
585 : }
586 :
587 : // XXXdholbert This uses a size_t ref count. Should we use a variant
588 : // of NS_INLINE_DECL_REFCOUNTING that takes a type as an argument?
589 : void AddRef() {
590 : if (mRefCnt == size_t(-1)) { // really want SIZE_MAX
591 : NS_WARNING("refcount overflow, leaking nsCSSValue::Array");
592 : return;
593 : }
594 : ++mRefCnt;
595 : NS_LOG_ADDREF(this, mRefCnt, "nsCSSValue::Array", sizeof(*this));
596 : }
597 : void Release() {
598 : if (mRefCnt == size_t(-1)) { // really want SIZE_MAX
599 : NS_WARNING("refcount overflow, leaking nsCSSValue::Array");
600 : return;
601 : }
602 : --mRefCnt;
603 : NS_LOG_RELEASE(this, mRefCnt, "nsCSSValue::Array");
604 : if (mRefCnt == 0)
605 : delete this;
606 : }
607 :
608 : private:
609 :
610 : size_t mRefCnt;
611 : const size_t mCount;
612 : // This must be the last sub-object, since we extend this array to
613 : // be of size mCount; it needs to be a sub-object so it gets proper
614 : // alignment.
615 : nsCSSValue mArray[1];
616 :
617 : void* operator new(size_t aSelfSize, size_t aItemCount) CPP_THROW_NEW {
618 : NS_ABORT_IF_FALSE(aItemCount > 0, "cannot have a 0 item count");
619 : return ::operator new(aSelfSize + sizeof(nsCSSValue) * (aItemCount - 1));
620 : }
621 :
622 : void operator delete(void* aPtr) { ::operator delete(aPtr); }
623 :
624 : nsCSSValue* First() { return mArray; }
625 :
626 : const nsCSSValue* First() const { return mArray; }
627 :
628 : #define CSSVALUE_LIST_FOR_EXTRA_VALUES(var) \
629 : for (nsCSSValue *var = First() + 1, *var##_end = First() + mCount; \
630 : var != var##_end; ++var)
631 :
632 : Array(size_t aItemCount)
633 : : mRefCnt(0)
634 : , mCount(aItemCount)
635 : {
636 : MOZ_COUNT_CTOR(nsCSSValue::Array);
637 : CSSVALUE_LIST_FOR_EXTRA_VALUES(val) {
638 : new (val) nsCSSValue();
639 : }
640 : }
641 :
642 : ~Array()
643 : {
644 : MOZ_COUNT_DTOR(nsCSSValue::Array);
645 : CSSVALUE_LIST_FOR_EXTRA_VALUES(val) {
646 : val->~nsCSSValue();
647 : }
648 : }
649 :
650 : size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const;
651 :
652 : #undef CSSVALUE_LIST_FOR_EXTRA_VALUES
653 :
654 : private:
655 : Array(const Array& aOther) MOZ_DELETE;
656 : Array& operator=(const Array& aOther) MOZ_DELETE;
657 : };
658 :
659 : // Prefer nsCSSValue::Array for lists of fixed size.
660 : struct nsCSSValueList {
661 : nsCSSValueList() : mNext(nsnull) { MOZ_COUNT_CTOR(nsCSSValueList); }
662 : ~nsCSSValueList();
663 :
664 : nsCSSValueList* Clone() const; // makes a deep copy
665 : void CloneInto(nsCSSValueList* aList) const; // makes a deep copy into aList
666 : void AppendToString(nsCSSProperty aProperty, nsAString& aResult) const;
667 :
668 : bool operator==(nsCSSValueList const& aOther) const;
669 : bool operator!=(const nsCSSValueList& aOther) const
670 : { return !(*this == aOther); }
671 :
672 : size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const;
673 :
674 : nsCSSValue mValue;
675 : nsCSSValueList* mNext;
676 :
677 : private:
678 : nsCSSValueList(const nsCSSValueList& aCopy) // makes a shallow copy
679 : : mValue(aCopy.mValue), mNext(nsnull)
680 : {
681 : MOZ_COUNT_CTOR(nsCSSValueList);
682 : }
683 : };
684 :
685 : // nsCSSValueList_heap differs from nsCSSValueList only in being
686 : // refcounted. It should not be necessary to use this class directly;
687 : // it's an implementation detail of nsCSSValue.
688 : struct nsCSSValueList_heap : public nsCSSValueList {
689 : NS_INLINE_DECL_REFCOUNTING(nsCSSValueList_heap)
690 :
691 : size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const;
692 : };
693 :
694 : // This has to be here so that the relationship between nsCSSValueList
695 : // and nsCSSValueList_heap is visible.
696 : inline nsCSSValueList*
697 : nsCSSValue::GetListValue()
698 : {
699 : if (mUnit == eCSSUnit_List)
700 : return mValue.mList;
701 : else {
702 : NS_ABORT_IF_FALSE(mUnit == eCSSUnit_ListDep, "not a pairlist value");
703 : return mValue.mListDependent;
704 : }
705 : }
706 :
707 : inline const nsCSSValueList*
708 : nsCSSValue::GetListValue() const
709 : {
710 : if (mUnit == eCSSUnit_List)
711 : return mValue.mList;
712 : else {
713 : NS_ABORT_IF_FALSE(mUnit == eCSSUnit_ListDep, "not a pairlist value");
714 : return mValue.mListDependent;
715 : }
716 : }
717 :
718 : struct nsCSSRect {
719 : nsCSSRect(void);
720 : nsCSSRect(const nsCSSRect& aCopy);
721 : ~nsCSSRect();
722 :
723 : void AppendToString(nsCSSProperty aProperty, nsAString& aResult) const;
724 :
725 : bool operator==(const nsCSSRect& aOther) const {
726 : return mTop == aOther.mTop &&
727 : mRight == aOther.mRight &&
728 : mBottom == aOther.mBottom &&
729 : mLeft == aOther.mLeft;
730 : }
731 :
732 : bool operator!=(const nsCSSRect& aOther) const {
733 : return mTop != aOther.mTop ||
734 : mRight != aOther.mRight ||
735 : mBottom != aOther.mBottom ||
736 : mLeft != aOther.mLeft;
737 : }
738 :
739 : void SetAllSidesTo(const nsCSSValue& aValue);
740 :
741 : void Reset() {
742 : mTop.Reset();
743 : mRight.Reset();
744 : mBottom.Reset();
745 : mLeft.Reset();
746 : }
747 :
748 : bool HasValue() const {
749 : return
750 : mTop.GetUnit() != eCSSUnit_Null ||
751 : mRight.GetUnit() != eCSSUnit_Null ||
752 : mBottom.GetUnit() != eCSSUnit_Null ||
753 : mLeft.GetUnit() != eCSSUnit_Null;
754 : }
755 :
756 : nsCSSValue mTop;
757 : nsCSSValue mRight;
758 : nsCSSValue mBottom;
759 : nsCSSValue mLeft;
760 :
761 : typedef nsCSSValue nsCSSRect::*side_type;
762 : static const side_type sides[4];
763 : };
764 :
765 : // nsCSSRect_heap differs from nsCSSRect only in being
766 : // refcounted. It should not be necessary to use this class directly;
767 : // it's an implementation detail of nsCSSValue.
768 : struct nsCSSRect_heap : public nsCSSRect {
769 : NS_INLINE_DECL_REFCOUNTING(nsCSSRect_heap)
770 :
771 : size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const;
772 : };
773 :
774 : // This has to be here so that the relationship between nsCSSRect
775 : // and nsCSSRect_heap is visible.
776 : inline nsCSSRect&
777 : nsCSSValue::GetRectValue()
778 : {
779 : NS_ABORT_IF_FALSE(mUnit == eCSSUnit_Rect, "not a pair value");
780 : return *mValue.mRect;
781 : }
782 :
783 : inline const nsCSSRect&
784 : nsCSSValue::GetRectValue() const
785 : {
786 : NS_ABORT_IF_FALSE(mUnit == eCSSUnit_Rect, "not a pair value");
787 : return *mValue.mRect;
788 : }
789 :
790 : struct nsCSSValuePair {
791 : nsCSSValuePair()
792 : {
793 : MOZ_COUNT_CTOR(nsCSSValuePair);
794 : }
795 : nsCSSValuePair(nsCSSUnit aUnit)
796 : : mXValue(aUnit), mYValue(aUnit)
797 : {
798 : MOZ_COUNT_CTOR(nsCSSValuePair);
799 : }
800 : nsCSSValuePair(const nsCSSValue& aXValue, const nsCSSValue& aYValue)
801 : : mXValue(aXValue), mYValue(aYValue)
802 : {
803 : MOZ_COUNT_CTOR(nsCSSValuePair);
804 : }
805 : nsCSSValuePair(const nsCSSValuePair& aCopy)
806 : : mXValue(aCopy.mXValue), mYValue(aCopy.mYValue)
807 : {
808 : MOZ_COUNT_CTOR(nsCSSValuePair);
809 : }
810 : ~nsCSSValuePair()
811 : {
812 : MOZ_COUNT_DTOR(nsCSSValuePair);
813 : }
814 :
815 : bool operator==(const nsCSSValuePair& aOther) const {
816 : return mXValue == aOther.mXValue &&
817 : mYValue == aOther.mYValue;
818 : }
819 :
820 : bool operator!=(const nsCSSValuePair& aOther) const {
821 : return mXValue != aOther.mXValue ||
822 : mYValue != aOther.mYValue;
823 : }
824 :
825 : void SetBothValuesTo(const nsCSSValue& aValue) {
826 : mXValue = aValue;
827 : mYValue = aValue;
828 : }
829 :
830 : void Reset() {
831 : mXValue.Reset();
832 : mYValue.Reset();
833 : }
834 :
835 : bool HasValue() const {
836 : return mXValue.GetUnit() != eCSSUnit_Null ||
837 : mYValue.GetUnit() != eCSSUnit_Null;
838 : }
839 :
840 : void AppendToString(nsCSSProperty aProperty, nsAString& aResult) const;
841 :
842 : size_t SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const;
843 :
844 : nsCSSValue mXValue;
845 : nsCSSValue mYValue;
846 : };
847 :
848 : // nsCSSValuePair_heap differs from nsCSSValuePair only in being
849 : // refcounted. It should not be necessary to use this class directly;
850 : // it's an implementation detail of nsCSSValue.
851 : struct nsCSSValuePair_heap : public nsCSSValuePair {
852 : // forward constructor
853 : nsCSSValuePair_heap(const nsCSSValue& aXValue, const nsCSSValue& aYValue)
854 : : nsCSSValuePair(aXValue, aYValue)
855 : {}
856 :
857 : NS_INLINE_DECL_REFCOUNTING(nsCSSValuePair_heap)
858 :
859 : size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const;
860 : };
861 :
862 : struct nsCSSValueTriplet {
863 : nsCSSValueTriplet()
864 : {
865 : MOZ_COUNT_CTOR(nsCSSValueTriplet);
866 : }
867 : nsCSSValueTriplet(nsCSSUnit aUnit)
868 : : mXValue(aUnit), mYValue(aUnit), mZValue(aUnit)
869 : {
870 : MOZ_COUNT_CTOR(nsCSSValueTriplet);
871 : }
872 : nsCSSValueTriplet(const nsCSSValue& aXValue,
873 : const nsCSSValue& aYValue,
874 : const nsCSSValue& aZValue)
875 : : mXValue(aXValue), mYValue(aYValue), mZValue(aZValue)
876 : {
877 : MOZ_COUNT_CTOR(nsCSSValueTriplet);
878 : }
879 : nsCSSValueTriplet(const nsCSSValueTriplet& aCopy)
880 : : mXValue(aCopy.mXValue), mYValue(aCopy.mYValue), mZValue(aCopy.mZValue)
881 : {
882 : MOZ_COUNT_CTOR(nsCSSValueTriplet);
883 : }
884 : ~nsCSSValueTriplet()
885 : {
886 : MOZ_COUNT_DTOR(nsCSSValueTriplet);
887 : }
888 :
889 : bool operator==(const nsCSSValueTriplet& aOther) const {
890 : return mXValue == aOther.mXValue &&
891 : mYValue == aOther.mYValue &&
892 : mZValue == aOther.mZValue;
893 : }
894 :
895 : bool operator!=(const nsCSSValueTriplet& aOther) const {
896 : return mXValue != aOther.mXValue ||
897 : mYValue != aOther.mYValue ||
898 : mZValue != aOther.mZValue;
899 : }
900 :
901 : void SetAllValuesTo(const nsCSSValue& aValue) {
902 : mXValue = aValue;
903 : mYValue = aValue;
904 : mZValue = aValue;
905 : }
906 :
907 : void Reset() {
908 : mXValue.Reset();
909 : mYValue.Reset();
910 : mZValue.Reset();
911 : }
912 :
913 : bool HasValue() const {
914 : return mXValue.GetUnit() != eCSSUnit_Null ||
915 : mYValue.GetUnit() != eCSSUnit_Null ||
916 : mZValue.GetUnit() != eCSSUnit_Null;
917 : }
918 :
919 : void AppendToString(nsCSSProperty aProperty, nsAString& aResult) const;
920 :
921 : nsCSSValue mXValue;
922 : nsCSSValue mYValue;
923 : nsCSSValue mZValue;
924 : };
925 :
926 : // nsCSSValueTriplet_heap differs from nsCSSValueTriplet only in being
927 : // refcounted. It should not be necessary to use this class directly;
928 : // it's an implementation detail of nsCSSValue.
929 : struct nsCSSValueTriplet_heap : public nsCSSValueTriplet {
930 : // forward constructor
931 : nsCSSValueTriplet_heap(const nsCSSValue& aXValue, const nsCSSValue& aYValue, const nsCSSValue& aZValue)
932 : : nsCSSValueTriplet(aXValue, aYValue, aZValue)
933 : {}
934 :
935 : NS_INLINE_DECL_REFCOUNTING(nsCSSValueTriplet_heap)
936 :
937 : size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const;
938 : };
939 :
940 : // This has to be here so that the relationship between nsCSSValuePair
941 : // and nsCSSValuePair_heap is visible.
942 : inline nsCSSValuePair&
943 : nsCSSValue::GetPairValue()
944 : {
945 : NS_ABORT_IF_FALSE(mUnit == eCSSUnit_Pair, "not a pair value");
946 : return *mValue.mPair;
947 : }
948 :
949 : inline const nsCSSValuePair&
950 : nsCSSValue::GetPairValue() const
951 : {
952 : NS_ABORT_IF_FALSE(mUnit == eCSSUnit_Pair, "not a pair value");
953 : return *mValue.mPair;
954 : }
955 :
956 : inline nsCSSValueTriplet&
957 : nsCSSValue::GetTripletValue()
958 : {
959 : NS_ABORT_IF_FALSE(mUnit == eCSSUnit_Triplet, "not a triplet value");
960 : return *mValue.mTriplet;
961 : }
962 :
963 : inline const nsCSSValueTriplet&
964 : nsCSSValue::GetTripletValue() const
965 : {
966 : NS_ABORT_IF_FALSE(mUnit == eCSSUnit_Triplet, "not a triplet value");
967 : return *mValue.mTriplet;
968 : }
969 :
970 : // Maybe should be replaced with nsCSSValueList and nsCSSValue::Array?
971 : struct nsCSSValuePairList {
972 : nsCSSValuePairList() : mNext(nsnull) { MOZ_COUNT_CTOR(nsCSSValuePairList); }
973 : ~nsCSSValuePairList();
974 :
975 : nsCSSValuePairList* Clone() const; // makes a deep copy
976 : void AppendToString(nsCSSProperty aProperty, nsAString& aResult) const;
977 :
978 : bool operator==(const nsCSSValuePairList& aOther) const;
979 : bool operator!=(const nsCSSValuePairList& aOther) const
980 : { return !(*this == aOther); }
981 :
982 : size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const;
983 :
984 : nsCSSValue mXValue;
985 : nsCSSValue mYValue;
986 : nsCSSValuePairList* mNext;
987 :
988 : private:
989 : nsCSSValuePairList(const nsCSSValuePairList& aCopy) // makes a shallow copy
990 : : mXValue(aCopy.mXValue), mYValue(aCopy.mYValue), mNext(nsnull)
991 : {
992 : MOZ_COUNT_CTOR(nsCSSValuePairList);
993 : }
994 : };
995 :
996 : // nsCSSValuePairList_heap differs from nsCSSValuePairList only in being
997 : // refcounted. It should not be necessary to use this class directly;
998 : // it's an implementation detail of nsCSSValue.
999 : struct nsCSSValuePairList_heap : public nsCSSValuePairList {
1000 : NS_INLINE_DECL_REFCOUNTING(nsCSSValuePairList_heap)
1001 :
1002 : size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const;
1003 : };
1004 :
1005 : // This has to be here so that the relationship between nsCSSValuePairList
1006 : // and nsCSSValuePairList_heap is visible.
1007 : inline nsCSSValuePairList*
1008 : nsCSSValue::GetPairListValue()
1009 : {
1010 : if (mUnit == eCSSUnit_PairList)
1011 : return mValue.mPairList;
1012 : else {
1013 : NS_ABORT_IF_FALSE (mUnit == eCSSUnit_PairListDep, "not a pairlist value");
1014 : return mValue.mPairListDependent;
1015 : }
1016 : }
1017 :
1018 : inline const nsCSSValuePairList*
1019 : nsCSSValue::GetPairListValue() const
1020 : {
1021 : if (mUnit == eCSSUnit_PairList)
1022 : return mValue.mPairList;
1023 : else {
1024 : NS_ABORT_IF_FALSE (mUnit == eCSSUnit_PairListDep, "not a pairlist value");
1025 : return mValue.mPairListDependent;
1026 : }
1027 : }
1028 :
1029 : struct nsCSSValueGradientStop {
1030 : public:
1031 : nsCSSValueGradientStop();
1032 : // needed to keep bloat logs happy when we use the TArray
1033 : // in nsCSSValueGradient
1034 : nsCSSValueGradientStop(const nsCSSValueGradientStop& aOther);
1035 : ~nsCSSValueGradientStop();
1036 :
1037 : nsCSSValue mLocation;
1038 : nsCSSValue mColor;
1039 :
1040 : bool operator==(const nsCSSValueGradientStop& aOther) const
1041 : {
1042 : return (mLocation == aOther.mLocation &&
1043 : mColor == aOther.mColor);
1044 : }
1045 :
1046 : bool operator!=(const nsCSSValueGradientStop& aOther) const
1047 : {
1048 : return !(*this == aOther);
1049 : }
1050 :
1051 : size_t SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const;
1052 : };
1053 :
1054 : struct nsCSSValueGradient {
1055 : nsCSSValueGradient(bool aIsRadial, bool aIsRepeating);
1056 :
1057 : // true if gradient is radial, false if it is linear
1058 : bool mIsRadial;
1059 : bool mIsRepeating;
1060 : bool mIsToCorner;
1061 : // line position and angle
1062 : nsCSSValuePair mBgPos;
1063 : nsCSSValue mAngle;
1064 :
1065 : // Only meaningful if mIsRadial is true
1066 : nsCSSValue mRadialShape;
1067 : nsCSSValue mRadialSize;
1068 :
1069 : InfallibleTArray<nsCSSValueGradientStop> mStops;
1070 :
1071 : bool operator==(const nsCSSValueGradient& aOther) const
1072 : {
1073 : if (mIsRadial != aOther.mIsRadial ||
1074 : mIsRepeating != aOther.mIsRepeating ||
1075 : mIsToCorner != aOther.mIsToCorner ||
1076 : mBgPos != aOther.mBgPos ||
1077 : mAngle != aOther.mAngle ||
1078 : mRadialShape != aOther.mRadialShape ||
1079 : mRadialSize != aOther.mRadialSize)
1080 : return false;
1081 :
1082 : if (mStops.Length() != aOther.mStops.Length())
1083 : return false;
1084 :
1085 : for (PRUint32 i = 0; i < mStops.Length(); i++) {
1086 : if (mStops[i] != aOther.mStops[i])
1087 : return false;
1088 : }
1089 :
1090 : return true;
1091 : }
1092 :
1093 : bool operator!=(const nsCSSValueGradient& aOther) const
1094 : {
1095 : return !(*this == aOther);
1096 : }
1097 :
1098 : NS_INLINE_DECL_REFCOUNTING(nsCSSValueGradient)
1099 :
1100 : size_t SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const;
1101 :
1102 : private:
1103 : nsCSSValueGradient(const nsCSSValueGradient& aOther) MOZ_DELETE;
1104 : nsCSSValueGradient& operator=(const nsCSSValueGradient& aOther) MOZ_DELETE;
1105 : };
1106 :
1107 : struct nsCSSCornerSizes {
1108 : nsCSSCornerSizes(void);
1109 : nsCSSCornerSizes(const nsCSSCornerSizes& aCopy);
1110 : ~nsCSSCornerSizes();
1111 :
1112 : // argument is a "full corner" constant from nsStyleConsts.h
1113 : nsCSSValue const & GetCorner(PRUint32 aCorner) const {
1114 : return this->*corners[aCorner];
1115 : }
1116 : nsCSSValue & GetCorner(PRUint32 aCorner) {
1117 : return this->*corners[aCorner];
1118 : }
1119 :
1120 : bool operator==(const nsCSSCornerSizes& aOther) const {
1121 : NS_FOR_CSS_FULL_CORNERS(corner) {
1122 : if (this->GetCorner(corner) != aOther.GetCorner(corner))
1123 : return false;
1124 : }
1125 : return true;
1126 : }
1127 :
1128 : bool operator!=(const nsCSSCornerSizes& aOther) const {
1129 : NS_FOR_CSS_FULL_CORNERS(corner) {
1130 : if (this->GetCorner(corner) != aOther.GetCorner(corner))
1131 : return true;
1132 : }
1133 : return false;
1134 : }
1135 :
1136 : bool HasValue() const {
1137 : NS_FOR_CSS_FULL_CORNERS(corner) {
1138 : if (this->GetCorner(corner).GetUnit() != eCSSUnit_Null)
1139 : return true;
1140 : }
1141 : return false;
1142 : }
1143 :
1144 : void Reset();
1145 :
1146 : nsCSSValue mTopLeft;
1147 : nsCSSValue mTopRight;
1148 : nsCSSValue mBottomRight;
1149 : nsCSSValue mBottomLeft;
1150 :
1151 : protected:
1152 : typedef nsCSSValue nsCSSCornerSizes::*corner_type;
1153 : static const corner_type corners[4];
1154 : };
1155 :
1156 : #endif /* nsCSSValue_h___ */
1157 :
|