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
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/
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
15 * The Original Code is mozilla.org code.
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.
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.
36 * ***** END LICENSE BLOCK ***** */
38 /* representation of simple property values within CSS declarations */
40 #ifndef nsCSSValue_h___
41 #define nsCSSValue_h___
46 #include "nsCSSProperty.h"
49 #include "nsAutoPtr.h"
50 #include "nsCRTGlue.h"
51 #include "nsStringBuffer.h"
57 // Deletes a linked list iteratively to avoid blowing up the stack (bug 456196).
58 #define NS_CSS_DELETE_LIST_MEMBER(type_, ptr_, member_) \
60 type_ *cur = (ptr_)->member_; \
61 (ptr_)->member_ = nsnull; \
63 type_ *next = cur->member_; \
64 cur->member_ = nsnull; \
70 // Clones a linked list iteratively to avoid blowing up the stack.
71 // If it fails to clone the entire list then 'to_' is deleted and
73 #define NS_CSS_CLONE_LIST_MEMBER(type_, from_, member_, to_, args_) \
75 type_ *dest = (to_); \
76 (to_)->member_ = nsnull; \
77 for (const type_ *src = (from_)->member_; src; src = src->member_) { \
78 type_ *clone = src->Clone args_; \
83 dest->member_ = clone; \
89 eCSSUnit_Null
= 0, // (n/a) null unit, value is not specified
90 eCSSUnit_Auto
= 1, // (n/a) value is algorithmic
91 eCSSUnit_Inherit
= 2, // (n/a) value is inherited
92 eCSSUnit_Initial
= 3, // (n/a) value is default UA value
93 eCSSUnit_None
= 4, // (n/a) value is none
94 eCSSUnit_Normal
= 5, // (n/a) value is normal (algorithmic, different than auto)
95 eCSSUnit_System_Font
= 6, // (n/a) value is -moz-use-system-font
96 eCSSUnit_Dummy
= 7, // (n/a) a fake but specified value, used
97 // only in temporary values
98 eCSSUnit_DummyInherit
= 8, // (n/a) a fake but specified value, used
99 // only in temporary values
100 eCSSUnit_String
= 10, // (PRUnichar*) a string value
101 eCSSUnit_Attr
= 11, // (PRUnichar*) a attr(string) value
102 eCSSUnit_Local_Font
= 12, // (PRUnichar*) a local font name
103 eCSSUnit_Font_Format
= 13, // (PRUnichar*) a font format name
104 eCSSUnit_Array
= 20, // (nsCSSValue::Array*) a list of values
105 eCSSUnit_Counter
= 21, // (nsCSSValue::Array*) a counter(string,[string]) value
106 eCSSUnit_Counters
= 22, // (nsCSSValue::Array*) a counters(string,string[,string]) value
107 eCSSUnit_Function
= 23, // (nsCSSValue::Array*) a function with parameters. First elem of array is name,
108 // the rest of the values are arguments.
110 eCSSUnit_URL
= 30, // (nsCSSValue::URL*) value
111 eCSSUnit_Image
= 31, // (nsCSSValue::Image*) value
112 eCSSUnit_Integer
= 50, // (int) simple value
113 eCSSUnit_Enumerated
= 51, // (int) value has enumerated meaning
114 eCSSUnit_EnumColor
= 80, // (int) enumerated color (kColorKTable)
115 eCSSUnit_Color
= 81, // (nscolor) an RGBA value
116 eCSSUnit_Percent
= 90, // (float) 1.0 == 100%) value is percentage of something
117 eCSSUnit_Number
= 91, // (float) value is numeric (usually multiplier, different behavior that percent)
119 // Length units - fixed
121 eCSSUnit_Inch
= 100, // (float) 0.0254 meters
122 eCSSUnit_Foot
= 101, // (float) 12 inches
123 eCSSUnit_Mile
= 102, // (float) 5280 feet
126 eCSSUnit_Millimeter
= 207, // (float) 1/1000 meter
127 eCSSUnit_Centimeter
= 208, // (float) 1/100 meter
128 eCSSUnit_Meter
= 210, // (float) Standard length
129 eCSSUnit_Kilometer
= 213, // (float) 1000 meters
132 eCSSUnit_Point
= 300, // (float) 1/72 inch
133 eCSSUnit_Pica
= 301, // (float) 12 points == 1/6 inch
135 // European Typographic
136 eCSSUnit_Didot
= 400, // (float) 15 didots == 16 points
137 eCSSUnit_Cicero
= 401, // (float) 12 didots
139 // Length units - relative
140 // Font relative measure
141 eCSSUnit_EM
= 800, // (float) == current font size
142 eCSSUnit_EN
= 801, // (float) .5 em
143 eCSSUnit_XHeight
= 802, // (float) distance from top of lower case x to baseline
144 eCSSUnit_CapHeight
= 803, // (float) distance from top of uppercase case H to baseline
145 eCSSUnit_Char
= 804, // (float) number of characters, used for width with monospace font
147 // Screen relative measure
148 eCSSUnit_Pixel
= 900, // (float) CSS pixel unit
151 eCSSUnit_Degree
= 1000, // (float) 360 per circle
152 eCSSUnit_Grad
= 1001, // (float) 400 per circle
153 eCSSUnit_Radian
= 1002, // (float) 2*pi per circle
156 eCSSUnit_Hertz
= 2000, // (float) 1/seconds
157 eCSSUnit_Kilohertz
= 2001, // (float) 1000 Hertz
160 eCSSUnit_Seconds
= 3000, // (float) Standard time
161 eCSSUnit_Milliseconds
= 3001 // (float) 1/1000 second
175 // for valueless units only (null, auto, inherit, none, normal)
176 explicit nsCSSValue(nsCSSUnit aUnit
= eCSSUnit_Null
)
179 NS_ASSERTION(aUnit
<= eCSSUnit_DummyInherit
, "not a valueless unit");
182 nsCSSValue(PRInt32 aValue
, nsCSSUnit aUnit
) NS_HIDDEN
;
183 nsCSSValue(float aValue
, nsCSSUnit aUnit
) NS_HIDDEN
;
184 nsCSSValue(const nsString
& aValue
, nsCSSUnit aUnit
) NS_HIDDEN
;
185 explicit nsCSSValue(nscolor aValue
) NS_HIDDEN
;
186 nsCSSValue(Array
* aArray
, nsCSSUnit aUnit
) NS_HIDDEN
;
187 explicit nsCSSValue(URL
* aValue
) NS_HIDDEN
;
188 explicit nsCSSValue(Image
* aValue
) NS_HIDDEN
;
189 nsCSSValue(const nsCSSValue
& aCopy
) NS_HIDDEN
;
190 ~nsCSSValue() { Reset(); }
192 NS_HIDDEN_(nsCSSValue
&) operator=(const nsCSSValue
& aCopy
);
193 NS_HIDDEN_(PRBool
) operator==(const nsCSSValue
& aOther
) const;
195 PRBool
operator!=(const nsCSSValue
& aOther
) const
197 return !(*this == aOther
);
200 nsCSSUnit
GetUnit() const { return mUnit
; }
201 PRBool
IsLengthUnit() const
202 { return eCSSUnit_Inch
<= mUnit
&& mUnit
<= eCSSUnit_Pixel
; }
203 PRBool
IsFixedLengthUnit() const
204 { return eCSSUnit_Inch
<= mUnit
&& mUnit
<= eCSSUnit_Cicero
; }
205 PRBool
IsRelativeLengthUnit() const
206 { return eCSSUnit_EM
<= mUnit
&& mUnit
<= eCSSUnit_Pixel
; }
207 PRBool
IsAngularUnit() const
208 { return eCSSUnit_Degree
<= mUnit
&& mUnit
<= eCSSUnit_Radian
; }
209 PRBool
IsFrequencyUnit() const
210 { return eCSSUnit_Hertz
<= mUnit
&& mUnit
<= eCSSUnit_Kilohertz
; }
211 PRBool
IsTimeUnit() const
212 { return eCSSUnit_Seconds
<= mUnit
&& mUnit
<= eCSSUnit_Milliseconds
; }
214 PRBool
UnitHasStringValue() const
215 { return eCSSUnit_String
<= mUnit
&& mUnit
<= eCSSUnit_Font_Format
; }
217 PRInt32
GetIntValue() const
219 NS_ASSERTION(mUnit
== eCSSUnit_Integer
|| mUnit
== eCSSUnit_Enumerated
||
220 mUnit
== eCSSUnit_EnumColor
,
225 float GetPercentValue() const
227 NS_ASSERTION(mUnit
== eCSSUnit_Percent
, "not a percent value");
228 return mValue
.mFloat
;
231 float GetFloatValue() const
233 NS_ASSERTION(eCSSUnit_Number
<= mUnit
, "not a float value");
234 return mValue
.mFloat
;
237 nsAString
& GetStringValue(nsAString
& aBuffer
) const
239 NS_ASSERTION(UnitHasStringValue(), "not a string value");
241 PRUint32 len
= NS_strlen(GetBufferValue(mValue
.mString
));
242 mValue
.mString
->ToString(len
, aBuffer
);
246 const PRUnichar
* GetStringBufferValue() const
248 NS_ASSERTION(UnitHasStringValue(), "not a string value");
249 return GetBufferValue(mValue
.mString
);
252 nscolor
GetColorValue() const
254 NS_ASSERTION((mUnit
== eCSSUnit_Color
), "not a color value");
255 return mValue
.mColor
;
258 Array
* GetArrayValue() const
260 NS_ASSERTION(eCSSUnit_Array
<= mUnit
&& mUnit
<= eCSSUnit_Function
,
261 "not an array value");
262 return mValue
.mArray
;
265 nsIURI
* GetURLValue() const
267 NS_ASSERTION(mUnit
== eCSSUnit_URL
|| mUnit
== eCSSUnit_Image
,
269 return mUnit
== eCSSUnit_URL
?
270 mValue
.mURL
->mURI
: mValue
.mImage
->mURI
;
273 URL
* GetURLStructValue() const
275 // Not allowing this for Image values, because if the caller takes
276 // a ref to them they won't be able to delete them properly.
277 NS_ASSERTION(mUnit
== eCSSUnit_URL
, "not a URL value");
281 const PRUnichar
* GetOriginalURLValue() const
283 NS_ASSERTION(mUnit
== eCSSUnit_URL
|| mUnit
== eCSSUnit_Image
,
285 return GetBufferValue(mUnit
== eCSSUnit_URL
?
286 mValue
.mURL
->mString
:
287 mValue
.mImage
->mString
);
290 // Not making this inline because that would force us to include
291 // imgIRequest.h, which leads to REQUIRES hell, since this header is included
293 NS_HIDDEN_(imgIRequest
*) GetImageValue() const;
295 NS_HIDDEN_(nscoord
) GetLengthTwips() const;
297 NS_HIDDEN_(void) Reset() // sets to null
299 if (mUnit
!= eCSSUnit_Null
)
303 NS_HIDDEN_(void) DoReset();
306 NS_HIDDEN_(void) SetIntValue(PRInt32 aValue
, nsCSSUnit aUnit
);
307 NS_HIDDEN_(void) SetPercentValue(float aValue
);
308 NS_HIDDEN_(void) SetFloatValue(float aValue
, nsCSSUnit aUnit
);
309 NS_HIDDEN_(void) SetStringValue(const nsString
& aValue
, nsCSSUnit aUnit
);
310 NS_HIDDEN_(void) SetColorValue(nscolor aValue
);
311 NS_HIDDEN_(void) SetArrayValue(nsCSSValue::Array
* aArray
, nsCSSUnit aUnit
);
312 NS_HIDDEN_(void) SetURLValue(nsCSSValue::URL
* aURI
);
313 NS_HIDDEN_(void) SetImageValue(nsCSSValue::Image
* aImage
);
314 NS_HIDDEN_(void) SetAutoValue();
315 NS_HIDDEN_(void) SetInheritValue();
316 NS_HIDDEN_(void) SetInitialValue();
317 NS_HIDDEN_(void) SetNoneValue();
318 NS_HIDDEN_(void) SetNormalValue();
319 NS_HIDDEN_(void) SetSystemFontValue();
320 NS_HIDDEN_(void) SetDummyValue();
321 NS_HIDDEN_(void) SetDummyInheritValue();
322 NS_HIDDEN_(void) StartImageLoad(nsIDocument
* aDocument
)
323 const; // Not really const, but pretending
325 // Returns an already addrefed buffer. Can return null on allocation
327 static nsStringBuffer
* BufferFromString(const nsString
& aValue
);
331 // return |Array| with reference count of zero
332 static Array
* Create(PRUint16 aItemCount
) {
333 return new (aItemCount
) Array(aItemCount
);
336 nsCSSValue
& operator[](PRUint16 aIndex
) {
337 NS_ASSERTION(aIndex
< mCount
, "out of range");
338 return *(First() + aIndex
);
341 const nsCSSValue
& operator[](PRUint16 aIndex
) const {
342 NS_ASSERTION(aIndex
< mCount
, "out of range");
343 return *(First() + aIndex
);
346 nsCSSValue
& Item(PRUint16 aIndex
) { return (*this)[aIndex
]; }
347 const nsCSSValue
& Item(PRUint16 aIndex
) const { return (*this)[aIndex
]; }
349 PRUint16
Count() const { return mCount
; }
351 PRBool
operator==(const Array
& aOther
) const
353 if (mCount
!= aOther
.mCount
)
355 for (PRUint16 i
= 0; i
< mCount
; ++i
)
356 if ((*this)[i
] != aOther
[i
])
362 if (mRefCnt
== PR_UINT16_MAX
) {
363 NS_WARNING("refcount overflow, leaking nsCSSValue::Array");
367 NS_LOG_ADDREF(this, mRefCnt
, "nsCSSValue::Array", sizeof(*this));
370 if (mRefCnt
== PR_UINT16_MAX
) {
371 NS_WARNING("refcount overflow, leaking nsCSSValue::Array");
375 NS_LOG_RELEASE(this, mRefCnt
, "nsCSSValue::Array");
385 void* operator new(size_t aSelfSize
, PRUint16 aItemCount
) CPP_THROW_NEW
{
386 return ::operator new(aSelfSize
+ sizeof(nsCSSValue
)*aItemCount
);
389 void operator delete(void* aPtr
) { ::operator delete(aPtr
); }
391 nsCSSValue
* First() {
392 return (nsCSSValue
*) (((char*)this) + sizeof(*this));
395 const nsCSSValue
* First() const {
396 return (const nsCSSValue
*) (((const char*)this) + sizeof(*this));
399 #define CSSVALUE_LIST_FOR_VALUES(var) \
400 for (nsCSSValue *var = First(), *var##_end = var + mCount; \
401 var != var##_end; ++var)
403 Array(PRUint16 aItemCount
)
407 MOZ_COUNT_CTOR(nsCSSValue::Array
);
408 CSSVALUE_LIST_FOR_VALUES(val
) {
409 new (val
) nsCSSValue();
415 MOZ_COUNT_DTOR(nsCSSValue::Array
);
416 CSSVALUE_LIST_FOR_VALUES(val
) {
421 #undef CSSVALUE_LIST_FOR_VALUES
424 Array(const Array
& aOther
); // not to be implemented
428 // Methods are not inline because using an nsIPrincipal means requiring
429 // caps, which leads to REQUIRES hell, since this header is included all
432 // aString must not be null.
433 // aOriginPrincipal must not be null.
434 URL(nsIURI
* aURI
, nsStringBuffer
* aString
, nsIURI
* aReferrer
,
435 nsIPrincipal
* aOriginPrincipal
) NS_HIDDEN
;
439 NS_HIDDEN_(PRBool
) operator==(const URL
& aOther
) const;
441 // URIEquals only compares URIs and principals (unlike operator==, which
442 // also compares the original strings). URIEquals also assumes that the
443 // mURI member of both URL objects is non-null. Do NOT call this method
444 // unless you're sure this is the case.
445 NS_HIDDEN_(PRBool
) URIEquals(const URL
& aOther
) const;
447 nsCOMPtr
<nsIURI
> mURI
; // null == invalid URL
448 nsStringBuffer
* mString
; // Could use nsRefPtr, but it'd add useless
449 // null-checks; this is never null.
450 nsCOMPtr
<nsIURI
> mReferrer
;
451 nsCOMPtr
<nsIPrincipal
> mOriginPrincipal
;
453 void AddRef() { ++mRefCnt
; }
454 void Release() { if (--mRefCnt
== 0) delete this; }
459 struct Image
: public URL
{
460 // Not making the constructor and destructor inline because that would
461 // force us to include imgIRequest.h, which leads to REQUIRES hell, since
462 // this header is included all over.
463 // aString must not be null.
464 Image(nsIURI
* aURI
, nsStringBuffer
* aString
, nsIURI
* aReferrer
,
465 nsIPrincipal
* aOriginPrincipal
, nsIDocument
* aDocument
) NS_HIDDEN
;
468 // Inherit operator== from nsCSSValue::URL
470 nsCOMPtr
<imgIRequest
> mRequest
; // null == image load blocked or somehow failed
472 // Override AddRef/Release so we delete ourselves via the right pointer.
473 void AddRef() { ++mRefCnt
; }
474 void Release() { if (--mRefCnt
== 0) delete this; }
478 static const PRUnichar
* GetBufferValue(nsStringBuffer
* aBuffer
) {
479 return static_cast<PRUnichar
*>(aBuffer
->Data());
487 // Note: the capacity of the buffer may exceed the length of the string.
488 // If we're of a string type, mString is not null.
489 nsStringBuffer
* mString
;
497 #endif /* nsCSSValue_h___ */