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.
23 * Daniel Glazman <glazman@netscape.com>
24 * Mats Palmgren <mats.palmgren@bredband.net>
26 * Alternatively, the contents of this file may be used under the terms of
27 * either of the GNU General Public License Version 2 or later (the "GPL"),
28 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 * in which case the provisions of the GPL or the LGPL are applicable instead
30 * of those above. If you wish to allow use of your version of this file only
31 * under the terms of either the GPL or the LGPL, and not to allow others to
32 * use your version of this file under the terms of the MPL, indicate your
33 * decision by deleting the provisions above and replace them with the notice
34 * and other provisions required by the GPL or the LGPL. If you do not delete
35 * the provisions above, a recipient may use your version of this file under
36 * the terms of any one of the MPL, the GPL or the LGPL.
38 * ***** END LICENSE BLOCK ***** */
41 * representation of a declaration block (or style attribute) in a CSS
47 #include "nsCSSDeclaration.h"
50 #include "nsUnicharUtils.h"
51 #include "nsReadableUtils.h"
53 #include "nsCSSProps.h"
55 #include "nsReadableUtils.h"
56 #include "nsStyleUtil.h"
58 #include "nsStyleConsts.h"
62 #define B_BORDER_TOP_STYLE 0x001
63 #define B_BORDER_LEFT_STYLE 0x002
64 #define B_BORDER_RIGHT_STYLE 0x004
65 #define B_BORDER_BOTTOM_STYLE 0x008
66 #define B_BORDER_TOP_COLOR 0x010
67 #define B_BORDER_LEFT_COLOR 0x020
68 #define B_BORDER_RIGHT_COLOR 0x040
69 #define B_BORDER_BOTTOM_COLOR 0x080
70 #define B_BORDER_TOP_WIDTH 0x100
71 #define B_BORDER_LEFT_WIDTH 0x200
72 #define B_BORDER_RIGHT_WIDTH 0x400
73 #define B_BORDER_BOTTOM_WIDTH 0x800
75 #define B_BORDER_STYLE 0x00f
76 #define B_BORDER_COLOR 0x0f0
77 #define B_BORDER_WIDTH 0xf00
79 #define B_BORDER_TOP 0x111
80 #define B_BORDER_LEFT 0x222
81 #define B_BORDER_RIGHT 0x444
82 #define B_BORDER_BOTTOM 0x888
84 #define B_BORDER 0xfff
86 nsCSSDeclaration::nsCSSDeclaration()
88 mImportantData(nsnull
)
90 // check that we can fit all the CSS properties into a PRUint8
91 // for the mOrder array - if not, might need to use PRUint16!
92 PR_STATIC_ASSERT(eCSSProperty_COUNT_no_shorthands
- 1 <= PR_UINT8_MAX
);
94 MOZ_COUNT_CTOR(nsCSSDeclaration
);
97 nsCSSDeclaration::nsCSSDeclaration(const nsCSSDeclaration
& aCopy
)
98 : mOrder(aCopy
.mOrder
),
99 mData(aCopy
.mData
? aCopy
.mData
->Clone() : nsnull
),
100 mImportantData(aCopy
.mImportantData
? aCopy
.mImportantData
->Clone()
103 MOZ_COUNT_CTOR(nsCSSDeclaration
);
106 nsCSSDeclaration::~nsCSSDeclaration(void)
111 if (mImportantData
) {
112 mImportantData
->Destroy();
115 MOZ_COUNT_DTOR(nsCSSDeclaration
);
119 nsCSSDeclaration::ValueAppended(nsCSSProperty aProperty
)
121 // order IS important for CSS, so remove and add to the end
122 if (nsCSSProps::IsShorthand(aProperty
)) {
123 CSSPROPS_FOR_SHORTHAND_SUBPROPERTIES(p
, aProperty
) {
124 mOrder
.RemoveElement(*p
);
125 mOrder
.AppendElement(*p
);
128 mOrder
.RemoveElement(aProperty
);
129 mOrder
.AppendElement(aProperty
);
135 nsCSSDeclaration::RemoveProperty(nsCSSProperty aProperty
)
137 nsCSSExpandedDataBlock data
;
138 data
.Expand(&mData
, &mImportantData
);
139 NS_ASSERTION(!mData
&& !mImportantData
, "Expand didn't null things out");
141 if (nsCSSProps::IsShorthand(aProperty
)) {
142 CSSPROPS_FOR_SHORTHAND_SUBPROPERTIES(p
, aProperty
) {
143 data
.ClearProperty(*p
);
144 mOrder
.RemoveElement(*p
);
147 data
.ClearProperty(aProperty
);
148 mOrder
.RemoveElement(aProperty
);
151 data
.Compress(&mData
, &mImportantData
);
156 nsCSSDeclaration::AppendComment(const nsAString
& aComment
)
158 return /* NS_ERROR_NOT_IMPLEMENTED, or not any longer that is */ NS_OK
;
162 nsCSSDeclaration::GetValueOrImportantValue(nsCSSProperty aProperty
, nsCSSValue
& aValue
) const
166 NS_ASSERTION(aProperty
>= 0, "out of range");
167 if (aProperty
>= eCSSProperty_COUNT_no_shorthands
||
168 nsCSSProps::kTypeTable
[aProperty
] != eCSSType_Value
) {
169 NS_ERROR("can't query for shorthand properties");
170 return NS_ERROR_ILLEGAL_VALUE
;
173 nsCSSCompressedDataBlock
*data
= GetValueIsImportant(aProperty
)
174 ? mImportantData
: mData
;
175 const void *storage
= data
->StorageFor(aProperty
);
178 aValue
= *static_cast<const nsCSSValue
*>(storage
);
183 nsCSSDeclaration::GetValue(const nsAString
& aProperty
,
184 nsAString
& aValue
) const
186 nsCSSProperty propID
= nsCSSProps::LookupProperty(aProperty
);
187 return GetValue(propID
, aValue
);
190 PRBool
nsCSSDeclaration::AppendValueToString(nsCSSProperty aProperty
, nsAString
& aResult
) const
192 nsCSSCompressedDataBlock
*data
= GetValueIsImportant(aProperty
)
193 ? mImportantData
: mData
;
194 const void *storage
= data
->StorageFor(aProperty
);
196 switch (nsCSSProps::kTypeTable
[aProperty
]) {
197 case eCSSType_Value
: {
198 const nsCSSValue
*val
= static_cast<const nsCSSValue
*>(storage
);
199 AppendCSSValueToString(aProperty
, *val
, aResult
);
201 case eCSSType_Rect
: {
202 const nsCSSRect
*rect
= static_cast<const nsCSSRect
*>(storage
);
203 if (rect
->mTop
.GetUnit() == eCSSUnit_Inherit
||
204 rect
->mTop
.GetUnit() == eCSSUnit_Initial
) {
205 NS_ASSERTION(rect
->mRight
.GetUnit() == rect
->mTop
.GetUnit(),
206 "Top inherit or initial, right isn't. Fix the parser!");
207 NS_ASSERTION(rect
->mBottom
.GetUnit() == rect
->mTop
.GetUnit(),
208 "Top inherit or initial, bottom isn't. Fix the parser!");
209 NS_ASSERTION(rect
->mLeft
.GetUnit() == rect
->mTop
.GetUnit(),
210 "Top inherit or initial, left isn't. Fix the parser!");
211 AppendCSSValueToString(aProperty
, rect
->mTop
, aResult
);
213 aResult
.AppendLiteral("rect(");
214 AppendCSSValueToString(aProperty
, rect
->mTop
, aResult
);
215 NS_NAMED_LITERAL_STRING(comma
, ", ");
216 aResult
.Append(comma
);
217 AppendCSSValueToString(aProperty
, rect
->mRight
, aResult
);
218 aResult
.Append(comma
);
219 AppendCSSValueToString(aProperty
, rect
->mBottom
, aResult
);
220 aResult
.Append(comma
);
221 AppendCSSValueToString(aProperty
, rect
->mLeft
, aResult
);
222 aResult
.Append(PRUnichar(')'));
225 case eCSSType_ValuePair
: {
226 const nsCSSValuePair
*pair
= static_cast<const nsCSSValuePair
*>(storage
);
227 AppendCSSValueToString(aProperty
, pair
->mXValue
, aResult
);
228 if (pair
->mYValue
!= pair
->mXValue
||
229 (aProperty
== eCSSProperty_background_position
&&
230 pair
->mXValue
.GetUnit() != eCSSUnit_Inherit
&&
231 pair
->mXValue
.GetUnit() != eCSSUnit_Initial
)) {
232 // Only output a Y value if it's different from the X value
233 // or if it's a background-position value other than 'initial'
235 aResult
.Append(PRUnichar(' '));
236 AppendCSSValueToString(aProperty
, pair
->mYValue
, aResult
);
239 case eCSSType_ValueList
: {
240 const nsCSSValueList
* val
=
241 *static_cast<nsCSSValueList
*const*>(storage
);
243 AppendCSSValueToString(aProperty
, val
->mValue
, aResult
);
246 if (aProperty
== eCSSProperty_cursor
247 || aProperty
== eCSSProperty_text_shadow
248 || aProperty
== eCSSProperty_box_shadow
250 || aProperty
== eCSSProperty_stroke_dasharray
253 aResult
.Append(PRUnichar(','));
254 aResult
.Append(PRUnichar(' '));
258 case eCSSType_ValuePairList
: {
259 const nsCSSValuePairList
* item
=
260 *static_cast<nsCSSValuePairList
*const*>(storage
);
262 NS_ASSERTION(item
->mXValue
.GetUnit() != eCSSUnit_Null
,
263 "unexpected null unit");
264 AppendCSSValueToString(aProperty
, item
->mXValue
, aResult
);
265 if (item
->mYValue
.GetUnit() != eCSSUnit_Null
) {
266 aResult
.Append(PRUnichar(' '));
267 AppendCSSValueToString(aProperty
, item
->mYValue
, aResult
);
271 aResult
.Append(PRUnichar(' '));
277 return storage
!= nsnull
;
281 nsCSSDeclaration::AppendCSSValueToString(nsCSSProperty aProperty
,
282 const nsCSSValue
& aValue
,
285 nsCSSUnit unit
= aValue
.GetUnit();
287 if (eCSSUnit_Null
== unit
) {
291 if (eCSSUnit_String
<= unit
&& unit
<= eCSSUnit_Attr
) {
292 if (unit
== eCSSUnit_Attr
) {
293 aResult
.AppendLiteral("attr(");
296 aValue
.GetStringValue(buffer
);
297 aResult
.Append(buffer
);
299 else if (eCSSUnit_Array
<= unit
&& unit
<= eCSSUnit_Counters
) {
301 case eCSSUnit_Counter
: aResult
.AppendLiteral("counter("); break;
302 case eCSSUnit_Counters
: aResult
.AppendLiteral("counters("); break;
306 nsCSSValue::Array
*array
= aValue
.GetArrayValue();
307 PRBool mark
= PR_FALSE
;
308 for (PRUint16 i
= 0, i_end
= array
->Count(); i
< i_end
; ++i
) {
309 if (aProperty
== eCSSProperty_border_image
&& i
>= 5) {
310 if (array
->Item(i
).GetUnit() == eCSSUnit_Null
) {
314 aResult
.AppendLiteral(" /");
317 if (mark
&& array
->Item(i
).GetUnit() != eCSSUnit_Null
) {
318 if (unit
== eCSSUnit_Array
)
319 aResult
.AppendLiteral(" ");
321 aResult
.AppendLiteral(", ");
324 ((eCSSUnit_Counter
<= unit
&& unit
<= eCSSUnit_Counters
) &&
325 i
== array
->Count() - 1)
326 ? eCSSProperty_list_style_type
: aProperty
;
327 if (AppendCSSValueToString(prop
, array
->Item(i
), aResult
)) {
332 else if (eCSSUnit_Integer
== unit
) {
334 tmpStr
.AppendInt(aValue
.GetIntValue(), 10);
335 aResult
.Append(tmpStr
);
337 else if (eCSSUnit_Enumerated
== unit
) {
338 if (eCSSProperty_text_decoration
== aProperty
) {
339 PRInt32 intValue
= aValue
.GetIntValue();
340 if (NS_STYLE_TEXT_DECORATION_NONE
!= intValue
) {
342 for (mask
= NS_STYLE_TEXT_DECORATION_UNDERLINE
;
343 mask
<= NS_STYLE_TEXT_DECORATION_BLINK
;
345 if ((mask
& intValue
) == mask
) {
346 AppendASCIItoUTF16(nsCSSProps::LookupPropertyValue(aProperty
, mask
), aResult
);
348 if (0 != intValue
) { // more left
349 aResult
.Append(PRUnichar(' '));
355 AppendASCIItoUTF16(nsCSSProps::LookupPropertyValue(aProperty
, NS_STYLE_TEXT_DECORATION_NONE
), aResult
);
358 else if (eCSSProperty_azimuth
== aProperty
) {
359 PRInt32 intValue
= aValue
.GetIntValue();
360 AppendASCIItoUTF16(nsCSSProps::LookupPropertyValue(aProperty
, (intValue
& ~NS_STYLE_AZIMUTH_BEHIND
)), aResult
);
361 if ((NS_STYLE_AZIMUTH_BEHIND
& intValue
) != 0) {
362 aResult
.Append(PRUnichar(' '));
363 AppendASCIItoUTF16(nsCSSProps::LookupPropertyValue(aProperty
, NS_STYLE_AZIMUTH_BEHIND
), aResult
);
366 else if (eCSSProperty_marks
== aProperty
) {
367 PRInt32 intValue
= aValue
.GetIntValue();
368 if ((NS_STYLE_PAGE_MARKS_CROP
& intValue
) != 0) {
369 AppendASCIItoUTF16(nsCSSProps::LookupPropertyValue(aProperty
, NS_STYLE_PAGE_MARKS_CROP
), aResult
);
371 if ((NS_STYLE_PAGE_MARKS_REGISTER
& intValue
) != 0) {
372 if ((NS_STYLE_PAGE_MARKS_CROP
& intValue
) != 0) {
373 aResult
.Append(PRUnichar(' '));
375 AppendASCIItoUTF16(nsCSSProps::LookupPropertyValue(aProperty
, NS_STYLE_PAGE_MARKS_REGISTER
), aResult
);
379 const nsAFlatCString
& name
= nsCSSProps::LookupPropertyValue(aProperty
, aValue
.GetIntValue());
380 AppendASCIItoUTF16(name
, aResult
);
383 else if (eCSSUnit_EnumColor
== unit
) {
384 // we can lookup the property in the ColorTable and then
385 // get a string mapping the name
387 if (nsCSSProps::GetColorName(aValue
.GetIntValue(), str
)){
388 AppendASCIItoUTF16(str
, aResult
);
390 NS_NOTREACHED("bad color value");
393 else if (eCSSUnit_Color
== unit
) {
394 nscolor color
= aValue
.GetColorValue();
395 if (color
== NS_RGBA(0, 0, 0, 0)) {
396 // Use the strictest match for 'transparent' so we do correct
397 // round-tripping of all other rgba() values.
398 aResult
.AppendLiteral("transparent");
401 PRUint8 a
= NS_GET_A(color
);
403 tmpStr
.AppendLiteral("rgba(");
405 tmpStr
.AppendLiteral("rgb(");
408 NS_NAMED_LITERAL_STRING(comma
, ", ");
410 tmpStr
.AppendInt(NS_GET_R(color
), 10);
411 tmpStr
.Append(comma
);
412 tmpStr
.AppendInt(NS_GET_G(color
), 10);
413 tmpStr
.Append(comma
);
414 tmpStr
.AppendInt(NS_GET_B(color
), 10);
416 tmpStr
.Append(comma
);
417 tmpStr
.AppendFloat(nsStyleUtil::ColorComponentToFloat(a
));
419 tmpStr
.Append(PRUnichar(')'));
421 aResult
.Append(tmpStr
);
424 else if (eCSSUnit_URL
== unit
|| eCSSUnit_Image
== unit
) {
425 aResult
.Append(NS_LITERAL_STRING("url(") +
426 nsDependentString(aValue
.GetOriginalURLValue()) +
427 NS_LITERAL_STRING(")"));
429 else if (eCSSUnit_Percent
== unit
) {
431 tmpStr
.AppendFloat(aValue
.GetPercentValue() * 100.0f
);
432 aResult
.Append(tmpStr
);
434 else if (eCSSUnit_Percent
< unit
) { // length unit
436 tmpStr
.AppendFloat(aValue
.GetFloatValue());
437 aResult
.Append(tmpStr
);
441 case eCSSUnit_Null
: break;
442 case eCSSUnit_Auto
: aResult
.AppendLiteral("auto"); break;
443 case eCSSUnit_Inherit
: aResult
.AppendLiteral("inherit"); break;
444 case eCSSUnit_Initial
: aResult
.AppendLiteral("-moz-initial"); break;
445 case eCSSUnit_None
: aResult
.AppendLiteral("none"); break;
446 case eCSSUnit_Normal
: aResult
.AppendLiteral("normal"); break;
447 case eCSSUnit_System_Font
: aResult
.AppendLiteral("-moz-use-system-font"); break;
449 case eCSSUnit_String
: break;
450 case eCSSUnit_URL
: break;
451 case eCSSUnit_Image
: break;
452 case eCSSUnit_Array
: break;
454 case eCSSUnit_Counter
:
455 case eCSSUnit_Counters
: aResult
.Append(PRUnichar(')')); break;
456 case eCSSUnit_Integer
: break;
457 case eCSSUnit_Enumerated
: break;
458 case eCSSUnit_EnumColor
: break;
459 case eCSSUnit_Color
: break;
460 case eCSSUnit_Percent
: aResult
.Append(PRUnichar('%')); break;
461 case eCSSUnit_Number
: break;
463 case eCSSUnit_Inch
: aResult
.AppendLiteral("in"); break;
464 case eCSSUnit_Foot
: aResult
.AppendLiteral("ft"); break;
465 case eCSSUnit_Mile
: aResult
.AppendLiteral("mi"); break;
466 case eCSSUnit_Millimeter
: aResult
.AppendLiteral("mm"); break;
467 case eCSSUnit_Centimeter
: aResult
.AppendLiteral("cm"); break;
468 case eCSSUnit_Meter
: aResult
.AppendLiteral("m"); break;
469 case eCSSUnit_Kilometer
: aResult
.AppendLiteral("km"); break;
470 case eCSSUnit_Point
: aResult
.AppendLiteral("pt"); break;
471 case eCSSUnit_Pica
: aResult
.AppendLiteral("pc"); break;
472 case eCSSUnit_Didot
: aResult
.AppendLiteral("dt"); break;
473 case eCSSUnit_Cicero
: aResult
.AppendLiteral("cc"); break;
475 case eCSSUnit_EM
: aResult
.AppendLiteral("em"); break;
476 case eCSSUnit_EN
: aResult
.AppendLiteral("en"); break;
477 case eCSSUnit_XHeight
: aResult
.AppendLiteral("ex"); break;
478 case eCSSUnit_CapHeight
: aResult
.AppendLiteral("cap"); break;
479 case eCSSUnit_Char
: aResult
.AppendLiteral("ch"); break;
481 case eCSSUnit_Pixel
: aResult
.AppendLiteral("px"); break;
483 case eCSSUnit_Degree
: aResult
.AppendLiteral("deg"); break;
484 case eCSSUnit_Grad
: aResult
.AppendLiteral("grad"); break;
485 case eCSSUnit_Radian
: aResult
.AppendLiteral("rad"); break;
487 case eCSSUnit_Hertz
: aResult
.AppendLiteral("Hz"); break;
488 case eCSSUnit_Kilohertz
: aResult
.AppendLiteral("kHz"); break;
490 case eCSSUnit_Seconds
: aResult
.Append(PRUnichar('s')); break;
491 case eCSSUnit_Milliseconds
: aResult
.AppendLiteral("ms"); break;
498 nsCSSDeclaration::GetValue(nsCSSProperty aProperty
,
499 nsAString
& aValue
) const
503 // simple properties are easy.
504 if (!nsCSSProps::IsShorthand(aProperty
)) {
505 AppendValueToString(aProperty
, aValue
);
510 CSSPROPS_FOR_SHORTHAND_SUBPROPERTIES(p
, aProperty
) {
511 if (!mData
->StorageFor(*p
) &&
512 (!mImportantData
|| !mImportantData
->StorageFor(*p
)))
513 // We don't have all the properties in the shorthand.
514 if (*p
!= eCSSProperty__x_system_font
)
519 // XXX What about checking the consistency of '!important'?
520 // XXX What about checking that we don't serialize inherit,
521 // -moz-initial, or other illegal values?
522 // XXXldb Can we share shorthand logic with ToString?
524 case eCSSProperty_margin
:
525 case eCSSProperty_padding
:
526 case eCSSProperty_border_color
:
527 case eCSSProperty_border_style
:
528 case eCSSProperty__moz_border_radius
:
529 case eCSSProperty__moz_outline_radius
:
530 case eCSSProperty_border_width
: {
531 const nsCSSProperty
* subprops
=
532 nsCSSProps::SubpropertyEntryFor(aProperty
);
533 NS_ASSERTION(nsCSSProps::kTypeTable
[subprops
[0]] == eCSSType_Value
&&
534 nsCSSProps::kTypeTable
[subprops
[1]] == eCSSType_Value
&&
535 nsCSSProps::kTypeTable
[subprops
[2]] == eCSSType_Value
&&
536 nsCSSProps::kTypeTable
[subprops
[3]] == eCSSType_Value
,
538 if (!AppendValueToString(subprops
[0], aValue
) ||
539 !(aValue
.Append(PRUnichar(' ')),
540 AppendValueToString(subprops
[1], aValue
)) ||
541 !(aValue
.Append(PRUnichar(' ')),
542 AppendValueToString(subprops
[2], aValue
)) ||
543 !(aValue
.Append(PRUnichar(' ')),
544 AppendValueToString(subprops
[3], aValue
))) {
549 case eCSSProperty_border
:
550 // XXX More consistency checking needed before falling through.
551 aProperty
= eCSSProperty_border_top
;
552 case eCSSProperty_border_top
:
553 case eCSSProperty_border_right
:
554 case eCSSProperty_border_bottom
:
555 case eCSSProperty_border_left
:
556 case eCSSProperty_border_start
:
557 case eCSSProperty_border_end
:
558 case eCSSProperty__moz_column_rule
:
559 case eCSSProperty_outline
: {
560 const nsCSSProperty
* subprops
=
561 nsCSSProps::SubpropertyEntryFor(aProperty
);
562 NS_ASSERTION(nsCSSProps::kTypeTable
[subprops
[0]] == eCSSType_Value
&&
563 nsCSSProps::kTypeTable
[subprops
[1]] == eCSSType_Value
&&
564 nsCSSProps::kTypeTable
[subprops
[2]] == eCSSType_Value
,
566 if (!AppendValueToString(subprops
[0], aValue
) ||
567 !(aValue
.Append(PRUnichar(' ')),
568 AppendValueToString(subprops
[1], aValue
)) ||
569 !(aValue
.Append(PRUnichar(' ')),
570 AppendValueToString(subprops
[2], aValue
))) {
575 case eCSSProperty_margin_left
:
576 case eCSSProperty_margin_right
:
577 case eCSSProperty_margin_start
:
578 case eCSSProperty_margin_end
:
579 case eCSSProperty_padding_left
:
580 case eCSSProperty_padding_right
:
581 case eCSSProperty_padding_start
:
582 case eCSSProperty_padding_end
:
583 case eCSSProperty_border_left_color
:
584 case eCSSProperty_border_left_style
:
585 case eCSSProperty_border_left_width
:
586 case eCSSProperty_border_right_color
:
587 case eCSSProperty_border_right_style
:
588 case eCSSProperty_border_right_width
:
589 case eCSSProperty_border_start_color
:
590 case eCSSProperty_border_start_style
:
591 case eCSSProperty_border_start_width
:
592 case eCSSProperty_border_end_color
:
593 case eCSSProperty_border_end_style
:
594 case eCSSProperty_border_end_width
: {
595 const nsCSSProperty
* subprops
=
596 nsCSSProps::SubpropertyEntryFor(aProperty
);
597 NS_ASSERTION(subprops
[3] == eCSSProperty_UNKNOWN
,
598 "not box property with physical vs. logical cascading");
599 AppendValueToString(subprops
[0], aValue
);
602 case eCSSProperty_background
: {
603 PRBool appendedSomething
= PR_FALSE
;
604 if (AppendValueToString(eCSSProperty_background_color
, aValue
)) {
605 appendedSomething
= PR_TRUE
;
606 aValue
.Append(PRUnichar(' '));
608 if (AppendValueToString(eCSSProperty_background_image
, aValue
)) {
609 aValue
.Append(PRUnichar(' '));
610 appendedSomething
= PR_TRUE
;
612 if (AppendValueToString(eCSSProperty_background_repeat
, aValue
)) {
613 aValue
.Append(PRUnichar(' '));
614 appendedSomething
= PR_TRUE
;
616 if (AppendValueToString(eCSSProperty_background_attachment
, aValue
)) {
617 aValue
.Append(PRUnichar(' '));
618 appendedSomething
= PR_TRUE
;
620 if (!AppendValueToString(eCSSProperty_background_position
, aValue
) &&
622 NS_ASSERTION(!aValue
.IsEmpty() && aValue
.Last() == PRUnichar(' '),
623 "We appended a space before!");
624 // We appended an extra space. Let's get rid of it
625 aValue
.Truncate(aValue
.Length() - 1);
629 case eCSSProperty_cue
: {
630 if (AppendValueToString(eCSSProperty_cue_before
, aValue
)) {
631 aValue
.Append(PRUnichar(' '));
632 if (!AppendValueToString(eCSSProperty_cue_after
, aValue
))
637 case eCSSProperty_font
: {
638 nsCSSValue style
, variant
, weight
, size
, lh
, family
, systemFont
;
639 GetValueOrImportantValue(eCSSProperty__x_system_font
, systemFont
);
640 GetValueOrImportantValue(eCSSProperty_font_style
, style
);
641 GetValueOrImportantValue(eCSSProperty_font_variant
, variant
);
642 GetValueOrImportantValue(eCSSProperty_font_weight
, weight
);
643 GetValueOrImportantValue(eCSSProperty_font_size
, size
);
644 GetValueOrImportantValue(eCSSProperty_line_height
, lh
);
645 GetValueOrImportantValue(eCSSProperty_font_family
, family
);
647 if (systemFont
.GetUnit() != eCSSUnit_None
&&
648 systemFont
.GetUnit() != eCSSUnit_Null
) {
649 AppendCSSValueToString(eCSSProperty__x_system_font
, systemFont
, aValue
);
651 if (style
.GetUnit() != eCSSUnit_Normal
) {
652 AppendCSSValueToString(eCSSProperty_font_style
, style
, aValue
);
653 aValue
.Append(PRUnichar(' '));
655 if (variant
.GetUnit() != eCSSUnit_Normal
) {
656 AppendCSSValueToString(eCSSProperty_font_variant
, variant
, aValue
);
657 aValue
.Append(PRUnichar(' '));
659 if (weight
.GetUnit() != eCSSUnit_Normal
) {
660 AppendCSSValueToString(eCSSProperty_font_weight
, weight
, aValue
);
661 aValue
.Append(PRUnichar(' '));
663 AppendCSSValueToString(eCSSProperty_font_size
, size
, aValue
);
664 if (lh
.GetUnit() != eCSSUnit_Normal
) {
665 aValue
.Append(PRUnichar('/'));
666 AppendCSSValueToString(eCSSProperty_line_height
, lh
, aValue
);
668 aValue
.Append(PRUnichar(' '));
669 AppendCSSValueToString(eCSSProperty_font_family
, family
, aValue
);
673 case eCSSProperty_list_style
:
674 if (AppendValueToString(eCSSProperty_list_style_type
, aValue
))
675 aValue
.Append(PRUnichar(' '));
676 if (AppendValueToString(eCSSProperty_list_style_position
, aValue
))
677 aValue
.Append(PRUnichar(' '));
678 AppendValueToString(eCSSProperty_list_style_image
, aValue
);
680 case eCSSProperty_overflow
: {
681 nsCSSValue xValue
, yValue
;
682 GetValueOrImportantValue(eCSSProperty_overflow_x
, xValue
);
683 GetValueOrImportantValue(eCSSProperty_overflow_y
, yValue
);
684 if (xValue
== yValue
)
685 AppendValueToString(eCSSProperty_overflow_x
, aValue
);
688 case eCSSProperty_pause
: {
689 if (AppendValueToString(eCSSProperty_pause_before
, aValue
)) {
690 aValue
.Append(PRUnichar(' '));
691 if (!AppendValueToString(eCSSProperty_pause_after
, aValue
))
697 case eCSSProperty_marker
: {
698 nsCSSValue endValue
, midValue
, startValue
;
699 GetValueOrImportantValue(eCSSProperty_marker_end
, endValue
);
700 GetValueOrImportantValue(eCSSProperty_marker_mid
, midValue
);
701 GetValueOrImportantValue(eCSSProperty_marker_start
, startValue
);
702 if (endValue
== midValue
&& midValue
== startValue
)
703 AppendValueToString(eCSSProperty_marker_end
, aValue
);
708 NS_NOTREACHED("no other shorthands");
715 nsCSSDeclaration::GetValueIsImportant(const nsAString
& aProperty
) const
717 nsCSSProperty propID
= nsCSSProps::LookupProperty(aProperty
);
718 return GetValueIsImportant(propID
);
722 nsCSSDeclaration::GetValueIsImportant(nsCSSProperty aProperty
) const
727 // Inefficient, but we can assume '!important' is rare.
728 return mImportantData
->StorageFor(aProperty
) != nsnull
;
731 // XXXldb Bug 376075 All callers of AllPropertiesSameImportance also
732 // need to check for 'inherit' and 'initial' values, since you can't
733 // output a mix of either mixed with other values in the same shorthand!
735 nsCSSDeclaration::AllPropertiesSameImportance(PRInt32 aFirst
, PRInt32 aSecond
,
736 PRInt32 aThird
, PRInt32 aFourth
,
738 PRBool
& aImportance
) const
740 aImportance
= GetValueIsImportant(OrderValueAt(aFirst
-1));
741 if ((aSecond
&& aImportance
!= GetValueIsImportant(OrderValueAt(aSecond
-1))) ||
742 (aThird
&& aImportance
!= GetValueIsImportant(OrderValueAt(aThird
-1))) ||
743 (aFourth
&& aImportance
!= GetValueIsImportant(OrderValueAt(aFourth
-1))) ||
744 (aFifth
&& aImportance
!= GetValueIsImportant(OrderValueAt(aFifth
-1)))) {
751 nsCSSDeclaration::AllPropertiesSameValue(PRInt32 aFirst
, PRInt32 aSecond
,
752 PRInt32 aThird
, PRInt32 aFourth
) const
754 nsCSSValue firstValue
, otherValue
;
755 // TryBorderShorthand does the bounds-checking for us; valid values there
756 // are > 0; 0 is a flag for "not set". We here are passed the actual
757 // index, which comes from finding the value in the mOrder property array.
758 // Of course, re-getting the mOrder value here is pretty silly.
759 GetValueOrImportantValue(OrderValueAt(aFirst
-1), firstValue
);
760 GetValueOrImportantValue(OrderValueAt(aSecond
-1), otherValue
);
761 if (firstValue
!= otherValue
) {
764 GetValueOrImportantValue(OrderValueAt(aThird
-1), otherValue
);
765 if (firstValue
!= otherValue
) {
768 GetValueOrImportantValue(OrderValueAt(aFourth
-1), otherValue
);
769 if (firstValue
!= otherValue
) {
776 nsCSSDeclaration::AppendImportanceToString(PRBool aIsImportant
,
780 aString
.AppendLiteral(" ! important");
785 nsCSSDeclaration::AppendPropertyAndValueToString(nsCSSProperty aProperty
,
786 nsCSSProperty aPropertyName
,
787 nsAString
& aResult
) const
789 NS_ASSERTION(0 <= aProperty
&& aProperty
< eCSSProperty_COUNT_no_shorthands
,
790 "property enum out of range");
791 AppendASCIItoUTF16(nsCSSProps::GetStringValue(aPropertyName
), aResult
);
792 aResult
.AppendLiteral(": ");
793 AppendValueToString(aProperty
, aResult
);
794 PRBool isImportant
= GetValueIsImportant(aProperty
);
795 AppendImportanceToString(isImportant
, aResult
);
796 aResult
.AppendLiteral("; ");
800 nsCSSDeclaration::TryBorderShorthand(nsAString
& aString
, PRUint32 aPropertiesSet
,
801 PRInt32 aBorderTopWidth
,
802 PRInt32 aBorderTopStyle
,
803 PRInt32 aBorderTopColor
,
804 PRInt32 aBorderBottomWidth
,
805 PRInt32 aBorderBottomStyle
,
806 PRInt32 aBorderBottomColor
,
807 PRInt32 aBorderLeftWidth
,
808 PRInt32 aBorderLeftStyle
,
809 PRInt32 aBorderLeftColor
,
810 PRInt32 aBorderRightWidth
,
811 PRInt32 aBorderRightStyle
,
812 PRInt32 aBorderRightColor
) const
814 PRBool border
= PR_FALSE
, isImportant
= PR_FALSE
;
815 // 0 means not in the mOrder array; otherwise it's index+1
816 if (B_BORDER
== aPropertiesSet
817 && AllPropertiesSameValue(aBorderTopWidth
, aBorderBottomWidth
,
818 aBorderLeftWidth
, aBorderRightWidth
)
819 && AllPropertiesSameValue(aBorderTopStyle
, aBorderBottomStyle
,
820 aBorderLeftStyle
, aBorderRightStyle
)
821 && AllPropertiesSameValue(aBorderTopColor
, aBorderBottomColor
,
822 aBorderLeftColor
, aBorderRightColor
)) {
827 PRBool isWidthImportant
, isStyleImportant
, isColorImportant
;
828 if (AllPropertiesSameImportance(aBorderTopWidth
, aBorderBottomWidth
,
829 aBorderLeftWidth
, aBorderRightWidth
,
832 AllPropertiesSameImportance(aBorderTopStyle
, aBorderBottomStyle
,
833 aBorderLeftStyle
, aBorderRightStyle
,
836 AllPropertiesSameImportance(aBorderTopColor
, aBorderBottomColor
,
837 aBorderLeftColor
, aBorderRightColor
,
840 if (isWidthImportant
== isStyleImportant
&& isWidthImportant
== isColorImportant
) {
842 isImportant
= isWidthImportant
;
847 AppendASCIItoUTF16(nsCSSProps::GetStringValue(eCSSProperty_border
), aString
);
848 aString
.AppendLiteral(": ");
850 AppendValueToString(eCSSProperty_border_top_width
, aString
);
851 aString
.Append(PRUnichar(' '));
853 AppendValueToString(eCSSProperty_border_top_style
, aString
);
854 aString
.Append(PRUnichar(' '));
856 nsAutoString valueString
;
857 AppendValueToString(eCSSProperty_border_top_color
, valueString
);
858 if (!valueString
.EqualsLiteral("-moz-use-text-color")) {
859 /* don't output this value, it's proprietary Mozilla and */
860 /* not intended to be exposed ; we can remove it from the */
861 /* values of the shorthand since this value represents the */
862 /* initial value of border-*-color */
863 aString
.Append(valueString
);
865 AppendImportanceToString(isImportant
, aString
);
866 aString
.AppendLiteral("; ");
872 nsCSSDeclaration::TryBorderSideShorthand(nsAString
& aString
,
873 nsCSSProperty aShorthand
,
874 PRInt32 aBorderWidth
,
875 PRInt32 aBorderStyle
,
876 PRInt32 aBorderColor
) const
879 if (AllPropertiesSameImportance(aBorderWidth
, aBorderStyle
, aBorderColor
,
882 AppendASCIItoUTF16(nsCSSProps::GetStringValue(aShorthand
), aString
);
883 aString
.AppendLiteral(": ");
885 AppendValueToString(OrderValueAt(aBorderWidth
-1), aString
);
887 aString
.Append(PRUnichar(' '));
888 AppendValueToString(OrderValueAt(aBorderStyle
-1), aString
);
890 nsAutoString valueString
;
891 AppendValueToString(OrderValueAt(aBorderColor
-1), valueString
);
892 if (!valueString
.EqualsLiteral("-moz-use-text-color")) {
893 aString
.AppendLiteral(" ");
894 aString
.Append(valueString
);
896 AppendImportanceToString(isImportant
, aString
);
897 aString
.AppendLiteral("; ");
904 nsCSSDeclaration::TryFourSidesShorthand(nsAString
& aString
,
905 nsCSSProperty aShorthand
,
910 PRBool aClearIndexes
) const
912 // 0 means not in the mOrder array; otherwise it's index+1
914 if (aTop
&& aBottom
&& aLeft
&& aRight
&&
915 AllPropertiesSameImportance(aTop
, aBottom
, aLeft
, aRight
,
918 // all 4 properties are set, we can output a shorthand
919 AppendASCIItoUTF16(nsCSSProps::GetStringValue(aShorthand
), aString
);
920 aString
.AppendLiteral(": ");
921 nsCSSValue topValue
, bottomValue
, leftValue
, rightValue
;
922 nsCSSProperty topProp
= OrderValueAt(aTop
-1);
923 nsCSSProperty bottomProp
= OrderValueAt(aBottom
-1);
924 nsCSSProperty leftProp
= OrderValueAt(aLeft
-1);
925 nsCSSProperty rightProp
= OrderValueAt(aRight
-1);
926 GetValueOrImportantValue(topProp
, topValue
);
927 GetValueOrImportantValue(bottomProp
, bottomValue
);
928 GetValueOrImportantValue(leftProp
, leftValue
);
929 GetValueOrImportantValue(rightProp
, rightValue
);
930 AppendCSSValueToString(topProp
, topValue
, aString
);
931 if (topValue
!= rightValue
|| topValue
!= leftValue
|| topValue
!= bottomValue
) {
932 aString
.Append(PRUnichar(' '));
933 AppendCSSValueToString(rightProp
, rightValue
, aString
);
934 if (topValue
!= bottomValue
|| rightValue
!= leftValue
) {
935 aString
.Append(PRUnichar(' '));
936 AppendCSSValueToString(bottomProp
, bottomValue
, aString
);
937 if (rightValue
!= leftValue
) {
938 aString
.Append(PRUnichar(' '));
939 AppendCSSValueToString(leftProp
, leftValue
, aString
);
944 aTop
= 0; aBottom
= 0; aLeft
= 0; aRight
= 0;
946 AppendImportanceToString(isImportant
, aString
);
947 aString
.AppendLiteral("; ");
954 nsCSSDeclaration::TryBackgroundShorthand(nsAString
& aString
,
958 PRInt32
& aBgAttachment
,
959 PRInt32
& aBgPosition
) const
961 // 0 means not in the mOrder array; otherwise it's index+1
962 // check if we have at least two properties set; otherwise, no need to
965 if (aBgColor
&& aBgImage
&& aBgRepeat
&& aBgAttachment
&& aBgPosition
&&
966 AllPropertiesSameImportance(aBgColor
, aBgImage
, aBgRepeat
, aBgAttachment
,
967 aBgPosition
, isImportant
)) {
968 AppendASCIItoUTF16(nsCSSProps::GetStringValue(eCSSProperty_background
), aString
);
969 aString
.AppendLiteral(": ");
971 AppendValueToString(eCSSProperty_background_color
, aString
);
974 aString
.Append(PRUnichar(' '));
975 AppendValueToString(eCSSProperty_background_image
, aString
);
978 aString
.Append(PRUnichar(' '));
979 AppendValueToString(eCSSProperty_background_repeat
, aString
);
982 aString
.Append(PRUnichar(' '));
983 AppendValueToString(eCSSProperty_background_attachment
, aString
);
986 aString
.Append(PRUnichar(' '));
987 AppendValueToString(eCSSProperty_background_position
, aString
);
990 AppendImportanceToString(isImportant
, aString
);
991 aString
.AppendLiteral("; ");
996 nsCSSDeclaration::TryOverflowShorthand(nsAString
& aString
,
997 PRInt32
& aOverflowX
,
998 PRInt32
& aOverflowY
) const
1001 if (aOverflowX
&& aOverflowY
&&
1002 AllPropertiesSameImportance(aOverflowX
, aOverflowY
,
1003 0, 0, 0, isImportant
)) {
1004 nsCSSValue xValue
, yValue
;
1005 GetValueOrImportantValue(eCSSProperty_overflow_x
, xValue
);
1006 GetValueOrImportantValue(eCSSProperty_overflow_y
, yValue
);
1007 if (xValue
== yValue
) {
1008 AppendASCIItoUTF16(nsCSSProps::GetStringValue(eCSSProperty_overflow
),
1010 aString
.AppendLiteral(": ");
1012 AppendCSSValueToString(eCSSProperty_overflow_x
, xValue
, aString
);
1013 AppendImportanceToString(isImportant
, aString
);
1014 aString
.AppendLiteral("; ");
1015 aOverflowX
= aOverflowY
= 0;
1022 nsCSSDeclaration::TryMarkerShorthand(nsAString
& aString
,
1023 PRInt32
& aMarkerEnd
,
1024 PRInt32
& aMarkerMid
,
1025 PRInt32
& aMarkerStart
) const
1028 if (aMarkerEnd
&& aMarkerMid
&& aMarkerEnd
&&
1029 AllPropertiesSameImportance(aMarkerEnd
, aMarkerMid
, aMarkerStart
,
1030 0, 0, isImportant
)) {
1031 nsCSSValue endValue
, midValue
, startValue
;
1032 GetValueOrImportantValue(eCSSProperty_marker_end
, endValue
);
1033 GetValueOrImportantValue(eCSSProperty_marker_mid
, midValue
);
1034 GetValueOrImportantValue(eCSSProperty_marker_start
, startValue
);
1035 if (endValue
== midValue
&& midValue
== startValue
) {
1036 AppendASCIItoUTF16(nsCSSProps::GetStringValue(eCSSProperty_marker
),
1038 aString
.AppendLiteral(": ");
1040 AppendCSSValueToString(eCSSProperty_marker_end
, endValue
, aString
);
1041 AppendImportanceToString(isImportant
, aString
);
1042 aString
.AppendLiteral("; ");
1043 aMarkerEnd
= aMarkerMid
= aMarkerStart
= 0;
1049 #define NS_CASE_OUTPUT_PROPERTY_VALUE(_prop, _index) \
1052 AppendPropertyAndValueToString(property, aString); \
1057 #define NS_CASE_OUTPUT_PROPERTY_VALUE_AS(_prop, _propas, _index) \
1060 AppendPropertyAndValueToString(property, _propas, aString); \
1065 #define NS_CASE_CONDITIONAL_OUTPUT_PROPERTY_VALUE(_condition, _prop, _index) \
1067 if ((_condition) && _index) { \
1068 AppendPropertyAndValueToString(property, aString); \
1073 #define NS_CASE_CONDITIONAL_OUTPUT_PROPERTY_VALUE_AS(_condition, _prop, _propas, _index) \
1075 if ((_condition) && _index) { \
1076 AppendPropertyAndValueToString(property, _propas, aString); \
1081 void nsCSSDeclaration::PropertyIsSet(PRInt32
& aPropertyIndex
, PRInt32 aIndex
, PRUint32
& aSet
, PRUint32 aValue
) const
1083 aPropertyIndex
= aIndex
+ 1;
1088 nsCSSDeclaration::ToString(nsAString
& aString
) const
1090 PRInt32 count
= mOrder
.Length();
1092 // 0 means not in the mOrder array; otherwise it's index+1
1093 PRInt32 borderTopWidth
= 0, borderTopStyle
= 0, borderTopColor
= 0;
1094 PRInt32 borderBottomWidth
= 0, borderBottomStyle
= 0, borderBottomColor
= 0;
1095 PRInt32 borderLeftWidth
= 0, borderLeftStyle
= 0, borderLeftColor
= 0;
1096 PRInt32 borderRightWidth
= 0, borderRightStyle
= 0, borderRightColor
= 0;
1097 PRInt32 borderStartWidth
= 0, borderStartStyle
= 0, borderStartColor
= 0;
1098 PRInt32 borderEndWidth
= 0, borderEndStyle
= 0, borderEndColor
= 0;
1099 PRInt32 marginTop
= 0, marginBottom
= 0, marginLeft
= 0, marginRight
= 0;
1100 PRInt32 paddingTop
= 0, paddingBottom
= 0, paddingLeft
= 0, paddingRight
= 0;
1101 PRInt32 bgColor
= 0, bgImage
= 0, bgRepeat
= 0, bgAttachment
= 0;
1102 PRInt32 bgPosition
= 0;
1103 PRInt32 overflowX
= 0, overflowY
= 0;
1104 PRInt32 columnRuleWidth
= 0, columnRuleStyle
= 0, columnRuleColor
= 0;
1105 PRUint32 borderPropertiesSet
= 0, finalBorderPropertiesToSet
= 0;
1107 PRInt32 markerEnd
= 0, markerMid
= 0, markerStart
= 0;
1110 for (index
= 0; index
< count
; index
++) {
1111 nsCSSProperty property
= OrderValueAt(index
);
1113 case eCSSProperty_border_top_width
:
1114 PropertyIsSet(borderTopWidth
, index
, borderPropertiesSet
, B_BORDER_TOP_WIDTH
);
1116 case eCSSProperty_border_bottom_width
:
1117 PropertyIsSet(borderBottomWidth
, index
, borderPropertiesSet
, B_BORDER_BOTTOM_WIDTH
);
1119 case eCSSProperty_border_left_width_value
:
1120 PropertyIsSet(borderLeftWidth
, index
, borderPropertiesSet
, B_BORDER_LEFT_WIDTH
);
1122 case eCSSProperty_border_right_width_value
:
1123 PropertyIsSet(borderRightWidth
, index
, borderPropertiesSet
, B_BORDER_RIGHT_WIDTH
);
1125 case eCSSProperty_border_start_width_value
:
1126 borderStartWidth
= index
+1;
1128 case eCSSProperty_border_end_width_value
:
1129 borderEndWidth
= index
+1;
1132 case eCSSProperty_border_top_style
:
1133 PropertyIsSet(borderTopStyle
, index
, borderPropertiesSet
, B_BORDER_TOP_STYLE
);
1135 case eCSSProperty_border_bottom_style
:
1136 PropertyIsSet(borderBottomStyle
, index
, borderPropertiesSet
, B_BORDER_BOTTOM_STYLE
);
1138 case eCSSProperty_border_left_style_value
:
1139 PropertyIsSet(borderLeftStyle
, index
, borderPropertiesSet
, B_BORDER_LEFT_STYLE
);
1141 case eCSSProperty_border_right_style_value
:
1142 PropertyIsSet(borderRightStyle
, index
, borderPropertiesSet
, B_BORDER_RIGHT_STYLE
);
1144 case eCSSProperty_border_start_style_value
:
1145 borderStartStyle
= index
+1;
1147 case eCSSProperty_border_end_style_value
:
1148 borderEndStyle
= index
+1;
1151 case eCSSProperty_border_top_color
:
1152 PropertyIsSet(borderTopColor
, index
, borderPropertiesSet
, B_BORDER_TOP_COLOR
);
1154 case eCSSProperty_border_bottom_color
:
1155 PropertyIsSet(borderBottomColor
, index
, borderPropertiesSet
, B_BORDER_BOTTOM_COLOR
);
1157 case eCSSProperty_border_left_color_value
:
1158 PropertyIsSet(borderLeftColor
, index
, borderPropertiesSet
, B_BORDER_LEFT_COLOR
);
1160 case eCSSProperty_border_right_color_value
:
1161 PropertyIsSet(borderRightColor
, index
, borderPropertiesSet
, B_BORDER_RIGHT_COLOR
);
1163 case eCSSProperty_border_start_color_value
:
1164 borderStartColor
= index
+1;
1166 case eCSSProperty_border_end_color_value
:
1167 borderEndColor
= index
+1;
1170 case eCSSProperty_margin_top
: marginTop
= index
+1; break;
1171 case eCSSProperty_margin_bottom
: marginBottom
= index
+1; break;
1172 case eCSSProperty_margin_left_value
: marginLeft
= index
+1; break;
1173 case eCSSProperty_margin_right_value
: marginRight
= index
+1; break;
1175 case eCSSProperty_padding_top
: paddingTop
= index
+1; break;
1176 case eCSSProperty_padding_bottom
: paddingBottom
= index
+1; break;
1177 case eCSSProperty_padding_left_value
: paddingLeft
= index
+1; break;
1178 case eCSSProperty_padding_right_value
: paddingRight
= index
+1; break;
1180 case eCSSProperty_background_color
: bgColor
= index
+1; break;
1181 case eCSSProperty_background_image
: bgImage
= index
+1; break;
1182 case eCSSProperty_background_repeat
: bgRepeat
= index
+1; break;
1183 case eCSSProperty_background_attachment
: bgAttachment
= index
+1; break;
1184 case eCSSProperty_background_position
: bgPosition
= index
+1; break;
1186 case eCSSProperty_overflow_x
: overflowX
= index
+1; break;
1187 case eCSSProperty_overflow_y
: overflowY
= index
+1; break;
1189 case eCSSProperty__moz_column_rule_width
: columnRuleWidth
= index
+1; break;
1190 case eCSSProperty__moz_column_rule_style
: columnRuleStyle
= index
+1; break;
1191 case eCSSProperty__moz_column_rule_color
: columnRuleColor
= index
+1; break;
1194 case eCSSProperty_marker_end
: markerEnd
= index
+1; break;
1195 case eCSSProperty_marker_mid
: markerMid
= index
+1; break;
1196 case eCSSProperty_marker_start
: markerStart
= index
+1; break;
1203 if (!TryBorderShorthand(aString
, borderPropertiesSet
,
1204 borderTopWidth
, borderTopStyle
, borderTopColor
,
1205 borderBottomWidth
, borderBottomStyle
, borderBottomColor
,
1206 borderLeftWidth
, borderLeftStyle
, borderLeftColor
,
1207 borderRightWidth
, borderRightStyle
, borderRightColor
)) {
1208 PRUint32 borderPropertiesToSet
= 0;
1209 if ((borderPropertiesSet
& B_BORDER_STYLE
) != B_BORDER_STYLE
||
1210 !TryFourSidesShorthand(aString
, eCSSProperty_border_style
,
1211 borderTopStyle
, borderBottomStyle
,
1212 borderLeftStyle
, borderRightStyle
,
1214 borderPropertiesToSet
|= B_BORDER_STYLE
;
1216 if ((borderPropertiesSet
& B_BORDER_COLOR
) != B_BORDER_COLOR
||
1217 !TryFourSidesShorthand(aString
, eCSSProperty_border_color
,
1218 borderTopColor
, borderBottomColor
,
1219 borderLeftColor
, borderRightColor
,
1221 borderPropertiesToSet
|= B_BORDER_COLOR
;
1223 if ((borderPropertiesSet
& B_BORDER_WIDTH
) != B_BORDER_WIDTH
||
1224 !TryFourSidesShorthand(aString
, eCSSProperty_border_width
,
1225 borderTopWidth
, borderBottomWidth
,
1226 borderLeftWidth
, borderRightWidth
,
1228 borderPropertiesToSet
|= B_BORDER_WIDTH
;
1230 borderPropertiesToSet
&= borderPropertiesSet
;
1231 if (borderPropertiesToSet
) {
1232 if ((borderPropertiesSet
& B_BORDER_TOP
) != B_BORDER_TOP
||
1233 !TryBorderSideShorthand(aString
, eCSSProperty_border_top
,
1234 borderTopWidth
, borderTopStyle
, borderTopColor
)) {
1235 finalBorderPropertiesToSet
|= B_BORDER_TOP
;
1237 if ((borderPropertiesSet
& B_BORDER_LEFT
) != B_BORDER_LEFT
||
1238 !TryBorderSideShorthand(aString
, eCSSProperty_border_left
,
1239 borderLeftWidth
, borderLeftStyle
, borderLeftColor
)) {
1240 finalBorderPropertiesToSet
|= B_BORDER_LEFT
;
1242 if ((borderPropertiesSet
& B_BORDER_RIGHT
) != B_BORDER_RIGHT
||
1243 !TryBorderSideShorthand(aString
, eCSSProperty_border_right
,
1244 borderRightWidth
, borderRightStyle
, borderRightColor
)) {
1245 finalBorderPropertiesToSet
|= B_BORDER_RIGHT
;
1247 if ((borderPropertiesSet
& B_BORDER_BOTTOM
) != B_BORDER_BOTTOM
||
1248 !TryBorderSideShorthand(aString
, eCSSProperty_border_bottom
,
1249 borderBottomWidth
, borderBottomStyle
, borderBottomColor
)) {
1250 finalBorderPropertiesToSet
|= B_BORDER_BOTTOM
;
1252 finalBorderPropertiesToSet
&= borderPropertiesToSet
;
1256 TryFourSidesShorthand(aString
, eCSSProperty_margin
,
1257 marginTop
, marginBottom
,
1258 marginLeft
, marginRight
,
1260 TryFourSidesShorthand(aString
, eCSSProperty_padding
,
1261 paddingTop
, paddingBottom
,
1262 paddingLeft
, paddingRight
,
1264 TryBackgroundShorthand(aString
,
1265 bgColor
, bgImage
, bgRepeat
, bgAttachment
,
1267 TryOverflowShorthand(aString
, overflowX
, overflowY
);
1269 TryMarkerShorthand(aString
, markerEnd
, markerMid
, markerStart
);
1272 if (columnRuleColor
&& columnRuleStyle
&& columnRuleWidth
) {
1273 TryBorderSideShorthand(aString
, eCSSProperty__moz_column_rule
,
1274 columnRuleWidth
, columnRuleStyle
, columnRuleColor
);
1275 columnRuleWidth
= columnRuleStyle
= columnRuleColor
= 0;
1278 // FIXME The order of the declarations should depend on the *-source
1280 if (borderStartWidth
&& borderStartStyle
&& borderStartColor
&&
1281 TryBorderSideShorthand(aString
, eCSSProperty_border_start
,
1282 borderStartWidth
, borderStartStyle
, borderStartColor
))
1283 borderStartWidth
= borderStartStyle
= borderStartColor
= 0;
1284 if (borderEndWidth
&& borderEndStyle
&& borderEndColor
&&
1285 TryBorderSideShorthand(aString
, eCSSProperty_border_end
,
1286 borderEndWidth
, borderEndStyle
, borderEndColor
))
1287 borderEndWidth
= borderEndStyle
= borderEndColor
= 0;
1289 for (index
= 0; index
< count
; index
++) {
1290 nsCSSProperty property
= OrderValueAt(index
);
1293 NS_CASE_CONDITIONAL_OUTPUT_PROPERTY_VALUE(finalBorderPropertiesToSet
& B_BORDER_TOP_STYLE
,
1294 eCSSProperty_border_top_style
, borderTopStyle
)
1295 NS_CASE_CONDITIONAL_OUTPUT_PROPERTY_VALUE_AS(finalBorderPropertiesToSet
& B_BORDER_LEFT_STYLE
,
1296 eCSSProperty_border_left_style_value
,
1297 eCSSProperty_border_left_style
, borderLeftStyle
)
1298 NS_CASE_CONDITIONAL_OUTPUT_PROPERTY_VALUE_AS(finalBorderPropertiesToSet
& B_BORDER_RIGHT_STYLE
,
1299 eCSSProperty_border_right_style_value
,
1300 eCSSProperty_border_right_style
, borderRightStyle
)
1301 NS_CASE_CONDITIONAL_OUTPUT_PROPERTY_VALUE(finalBorderPropertiesToSet
& B_BORDER_BOTTOM_STYLE
,
1302 eCSSProperty_border_bottom_style
, borderBottomStyle
)
1303 NS_CASE_OUTPUT_PROPERTY_VALUE_AS(eCSSProperty_border_start_style_value
,
1304 eCSSProperty_border_start_style
, borderStartStyle
)
1305 NS_CASE_OUTPUT_PROPERTY_VALUE_AS(eCSSProperty_border_end_style_value
,
1306 eCSSProperty_border_end_style
, borderEndStyle
)
1308 NS_CASE_CONDITIONAL_OUTPUT_PROPERTY_VALUE(finalBorderPropertiesToSet
& B_BORDER_TOP_COLOR
,
1309 eCSSProperty_border_top_color
, borderTopColor
)
1310 NS_CASE_CONDITIONAL_OUTPUT_PROPERTY_VALUE_AS(finalBorderPropertiesToSet
& B_BORDER_LEFT_COLOR
,
1311 eCSSProperty_border_left_color_value
,
1312 eCSSProperty_border_left_color
, borderLeftColor
)
1313 NS_CASE_CONDITIONAL_OUTPUT_PROPERTY_VALUE_AS(finalBorderPropertiesToSet
& B_BORDER_RIGHT_COLOR
,
1314 eCSSProperty_border_right_color_value
,
1315 eCSSProperty_border_right_color
, borderRightColor
)
1316 NS_CASE_CONDITIONAL_OUTPUT_PROPERTY_VALUE(finalBorderPropertiesToSet
& B_BORDER_BOTTOM_COLOR
,
1317 eCSSProperty_border_bottom_color
, borderBottomColor
)
1318 NS_CASE_OUTPUT_PROPERTY_VALUE_AS(eCSSProperty_border_start_color_value
,
1319 eCSSProperty_border_start_color
, borderStartColor
)
1320 NS_CASE_OUTPUT_PROPERTY_VALUE_AS(eCSSProperty_border_end_color_value
,
1321 eCSSProperty_border_end_color
, borderEndColor
)
1323 NS_CASE_CONDITIONAL_OUTPUT_PROPERTY_VALUE(finalBorderPropertiesToSet
& B_BORDER_TOP_WIDTH
,
1324 eCSSProperty_border_top_width
, borderTopWidth
)
1325 NS_CASE_CONDITIONAL_OUTPUT_PROPERTY_VALUE_AS(finalBorderPropertiesToSet
& B_BORDER_LEFT_WIDTH
,
1326 eCSSProperty_border_left_width_value
,
1327 eCSSProperty_border_left_width
, borderLeftWidth
)
1328 NS_CASE_CONDITIONAL_OUTPUT_PROPERTY_VALUE_AS(finalBorderPropertiesToSet
& B_BORDER_RIGHT_WIDTH
,
1329 eCSSProperty_border_right_width_value
,
1330 eCSSProperty_border_right_width
, borderRightWidth
)
1331 NS_CASE_CONDITIONAL_OUTPUT_PROPERTY_VALUE(finalBorderPropertiesToSet
& B_BORDER_BOTTOM_WIDTH
,
1332 eCSSProperty_border_bottom_width
, borderBottomWidth
)
1333 NS_CASE_OUTPUT_PROPERTY_VALUE_AS(eCSSProperty_border_start_width_value
,
1334 eCSSProperty_border_start_width
, borderStartWidth
)
1335 NS_CASE_OUTPUT_PROPERTY_VALUE_AS(eCSSProperty_border_end_width_value
,
1336 eCSSProperty_border_end_width
, borderEndWidth
)
1338 NS_CASE_OUTPUT_PROPERTY_VALUE(eCSSProperty_margin_top
, marginTop
)
1339 NS_CASE_OUTPUT_PROPERTY_VALUE(eCSSProperty_margin_bottom
, marginBottom
)
1340 NS_CASE_OUTPUT_PROPERTY_VALUE_AS(eCSSProperty_margin_left_value
,
1341 eCSSProperty_margin_left
, marginLeft
)
1342 NS_CASE_OUTPUT_PROPERTY_VALUE_AS(eCSSProperty_margin_right_value
,
1343 eCSSProperty_margin_right
, marginRight
)
1345 NS_CASE_OUTPUT_PROPERTY_VALUE(eCSSProperty_padding_top
, paddingTop
)
1346 NS_CASE_OUTPUT_PROPERTY_VALUE(eCSSProperty_padding_bottom
, paddingBottom
)
1347 NS_CASE_OUTPUT_PROPERTY_VALUE_AS(eCSSProperty_padding_left_value
,
1348 eCSSProperty_padding_left
, paddingLeft
)
1349 NS_CASE_OUTPUT_PROPERTY_VALUE_AS(eCSSProperty_padding_right_value
,
1350 eCSSProperty_padding_right
, paddingRight
)
1352 NS_CASE_OUTPUT_PROPERTY_VALUE(eCSSProperty_background_color
, bgColor
)
1353 NS_CASE_OUTPUT_PROPERTY_VALUE(eCSSProperty_background_image
, bgImage
)
1354 NS_CASE_OUTPUT_PROPERTY_VALUE(eCSSProperty_background_repeat
, bgRepeat
)
1355 NS_CASE_OUTPUT_PROPERTY_VALUE(eCSSProperty_background_attachment
, bgAttachment
)
1356 NS_CASE_OUTPUT_PROPERTY_VALUE(eCSSProperty_background_position
, bgPosition
)
1358 NS_CASE_OUTPUT_PROPERTY_VALUE(eCSSProperty_overflow_x
, overflowX
)
1359 NS_CASE_OUTPUT_PROPERTY_VALUE(eCSSProperty_overflow_y
, overflowY
)
1362 NS_CASE_OUTPUT_PROPERTY_VALUE(eCSSProperty_marker_end
, markerEnd
)
1363 NS_CASE_OUTPUT_PROPERTY_VALUE(eCSSProperty_marker_mid
, markerMid
)
1364 NS_CASE_OUTPUT_PROPERTY_VALUE(eCSSProperty_marker_start
, markerStart
)
1367 NS_CASE_OUTPUT_PROPERTY_VALUE(eCSSProperty__moz_column_rule_width
, columnRuleWidth
)
1368 NS_CASE_OUTPUT_PROPERTY_VALUE(eCSSProperty__moz_column_rule_style
, columnRuleStyle
)
1369 NS_CASE_OUTPUT_PROPERTY_VALUE(eCSSProperty__moz_column_rule_color
, columnRuleColor
)
1371 case eCSSProperty_margin_left_ltr_source
:
1372 case eCSSProperty_margin_left_rtl_source
:
1373 case eCSSProperty_margin_right_ltr_source
:
1374 case eCSSProperty_margin_right_rtl_source
:
1375 case eCSSProperty_padding_left_ltr_source
:
1376 case eCSSProperty_padding_left_rtl_source
:
1377 case eCSSProperty_padding_right_ltr_source
:
1378 case eCSSProperty_padding_right_rtl_source
:
1379 case eCSSProperty_border_left_color_ltr_source
:
1380 case eCSSProperty_border_left_color_rtl_source
:
1381 case eCSSProperty_border_left_style_ltr_source
:
1382 case eCSSProperty_border_left_style_rtl_source
:
1383 case eCSSProperty_border_left_width_ltr_source
:
1384 case eCSSProperty_border_left_width_rtl_source
:
1385 case eCSSProperty_border_right_color_ltr_source
:
1386 case eCSSProperty_border_right_color_rtl_source
:
1387 case eCSSProperty_border_right_style_ltr_source
:
1388 case eCSSProperty_border_right_style_rtl_source
:
1389 case eCSSProperty_border_right_width_ltr_source
:
1390 case eCSSProperty_border_right_width_rtl_source
:
1393 case eCSSProperty_margin_start_value
:
1394 AppendPropertyAndValueToString(property
, eCSSProperty_margin_start
,
1397 case eCSSProperty_margin_end_value
:
1398 AppendPropertyAndValueToString(property
, eCSSProperty_margin_end
,
1401 case eCSSProperty_padding_start_value
:
1402 AppendPropertyAndValueToString(property
, eCSSProperty_padding_start
,
1405 case eCSSProperty_padding_end_value
:
1406 AppendPropertyAndValueToString(property
, eCSSProperty_padding_end
,
1411 if (0 <= property
) {
1412 AppendPropertyAndValueToString(property
, aString
);
1417 if (! aString
.IsEmpty()) {
1418 // if the string is not empty, we have a trailing whitespace we should remove
1419 aString
.Truncate(aString
.Length() - 1);
1425 void nsCSSDeclaration::List(FILE* out
, PRInt32 aIndent
) const
1427 for (PRInt32 index
= aIndent
; --index
>= 0; ) fputs(" ", out
);
1432 fputs(NS_ConvertUTF16toUTF8(s
).get(), out
);
1438 nsCSSDeclaration::GetNthProperty(PRUint32 aIndex
, nsAString
& aReturn
) const
1441 if (aIndex
< mOrder
.Length()) {
1442 nsCSSProperty property
= OrderValueAt(aIndex
);
1443 if (0 <= property
) {
1444 AppendASCIItoUTF16(nsCSSProps::GetStringValue(property
), aReturn
);
1452 nsCSSDeclaration::Clone() const
1454 return new nsCSSDeclaration(*this);
1458 nsCSSDeclaration::InitializeEmpty()
1460 NS_ASSERTION(!mData
&& !mImportantData
, "already initialized");
1461 mData
= nsCSSCompressedDataBlock::CreateEmptyBlock();
1462 return mData
!= nsnull
;