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 /* DOM object representing values in DOM computed style */
40 #include "nsROCSSPrimitiveValue.h"
42 #include "nsPresContext.h"
43 #include "nsStyleUtil.h"
44 #include "nsDOMCSSRGBColor.h"
45 #include "nsIDOMRect.h"
47 nsROCSSPrimitiveValue::nsROCSSPrimitiveValue()
54 nsROCSSPrimitiveValue::~nsROCSSPrimitiveValue()
59 NS_IMPL_ADDREF(nsROCSSPrimitiveValue
)
60 NS_IMPL_RELEASE(nsROCSSPrimitiveValue
)
63 DOMCI_DATA(ROCSSPrimitiveValue
, nsROCSSPrimitiveValue
)
65 // QueryInterface implementation for nsROCSSPrimitiveValue
66 NS_INTERFACE_MAP_BEGIN(nsROCSSPrimitiveValue
)
67 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSPrimitiveValue
)
68 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSValue
)
69 NS_INTERFACE_MAP_ENTRY(nsISupports
)
70 NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(ROCSSPrimitiveValue
)
78 nsROCSSPrimitiveValue::GetCssText(nsAString
& aCssText
)
82 nsresult result
= NS_OK
;
87 float val
= nsPresContext::AppUnitsToFloatCSSPixels(mValue
.mAppUnits
);
88 tmpStr
.AppendFloat(val
);
89 tmpStr
.AppendLiteral("px");
94 AppendUTF8toUTF16(nsCSSKeywords::GetStringValue(mValue
.mKeyword
),
99 case CSS_COUNTER
: /* FIXME: COUNTER should use an object */
101 tmpStr
.Append(mValue
.mString
);
107 nsCAutoString specUTF8
;
108 mValue
.mURI
->GetSpec(specUTF8
);
110 tmpStr
.AssignLiteral("url(");
111 nsStyleUtil::AppendEscapedCSSString(NS_ConvertUTF8toUTF16(specUTF8
),
113 tmpStr
.AppendLiteral(")");
115 // XXXldb Any better ideas? It's good to have something that
116 // doesn't parse so that things round-trip "correctly".
117 tmpStr
.Assign(NS_LITERAL_STRING("url(invalid-url:)"));
123 tmpStr
.AppendLiteral("attr(");
124 tmpStr
.Append(mValue
.mString
);
125 tmpStr
.Append(PRUnichar(')'));
128 case CSS_PERCENTAGE
:
130 tmpStr
.AppendFloat(mValue
.mFloat
* 100);
131 tmpStr
.Append(PRUnichar('%'));
136 tmpStr
.AppendFloat(mValue
.mFloat
);
141 NS_ASSERTION(mValue
.mRect
, "mValue.mRect should never be null");
142 NS_NAMED_LITERAL_STRING(comma
, ", ");
143 nsCOMPtr
<nsIDOMCSSPrimitiveValue
> sideCSSValue
;
144 nsAutoString sideValue
;
145 tmpStr
.AssignLiteral("rect(");
147 result
= mValue
.mRect
->GetTop(getter_AddRefs(sideCSSValue
));
148 if (NS_FAILED(result
))
150 result
= sideCSSValue
->GetCssText(sideValue
);
151 if (NS_FAILED(result
))
153 tmpStr
.Append(sideValue
+ comma
);
155 result
= mValue
.mRect
->GetRight(getter_AddRefs(sideCSSValue
));
156 if (NS_FAILED(result
))
158 result
= sideCSSValue
->GetCssText(sideValue
);
159 if (NS_FAILED(result
))
161 tmpStr
.Append(sideValue
+ comma
);
163 result
= mValue
.mRect
->GetBottom(getter_AddRefs(sideCSSValue
));
164 if (NS_FAILED(result
))
166 result
= sideCSSValue
->GetCssText(sideValue
);
167 if (NS_FAILED(result
))
169 tmpStr
.Append(sideValue
+ comma
);
171 result
= mValue
.mRect
->GetLeft(getter_AddRefs(sideCSSValue
));
172 if (NS_FAILED(result
))
174 result
= sideCSSValue
->GetCssText(sideValue
);
175 if (NS_FAILED(result
))
177 tmpStr
.Append(sideValue
+ NS_LITERAL_STRING(")"));
182 NS_ASSERTION(mValue
.mColor
, "mValue.mColor should never be null");
183 NS_NAMED_LITERAL_STRING(comma
, ", ");
184 nsCOMPtr
<nsIDOMCSSPrimitiveValue
> colorCSSValue
;
185 nsAutoString colorValue
;
186 if (mValue
.mColor
->HasAlpha())
187 tmpStr
.AssignLiteral("rgba(");
189 tmpStr
.AssignLiteral("rgb(");
191 // get the red component
192 result
= mValue
.mColor
->GetRed(getter_AddRefs(colorCSSValue
));
193 if (NS_FAILED(result
))
195 result
= colorCSSValue
->GetCssText(colorValue
);
196 if (NS_FAILED(result
))
198 tmpStr
.Append(colorValue
+ comma
);
200 // get the green component
201 result
= mValue
.mColor
->GetGreen(getter_AddRefs(colorCSSValue
));
202 if (NS_FAILED(result
))
204 result
= colorCSSValue
->GetCssText(colorValue
);
205 if (NS_FAILED(result
))
207 tmpStr
.Append(colorValue
+ comma
);
209 // get the blue component
210 result
= mValue
.mColor
->GetBlue(getter_AddRefs(colorCSSValue
));
211 if (NS_FAILED(result
))
213 result
= colorCSSValue
->GetCssText(colorValue
);
214 if (NS_FAILED(result
))
216 tmpStr
.Append(colorValue
);
218 if (mValue
.mColor
->HasAlpha()) {
219 // get the alpha component
220 result
= mValue
.mColor
->GetAlpha(getter_AddRefs(colorCSSValue
));
221 if (NS_FAILED(result
))
223 result
= colorCSSValue
->GetCssText(colorValue
);
224 if (NS_FAILED(result
))
226 tmpStr
.Append(comma
+ colorValue
);
229 tmpStr
.Append(NS_LITERAL_STRING(")"));
235 tmpStr
.AppendFloat(mValue
.mFloat
);
236 tmpStr
.AppendLiteral("s");
254 NS_ERROR("We have a bogus value set. This should not happen");
255 return NS_ERROR_DOM_INVALID_ACCESS_ERR
;
258 if (NS_SUCCEEDED(result
)) {
259 aCssText
.Assign(tmpStr
);
267 nsROCSSPrimitiveValue::SetCssText(const nsAString
& aCssText
)
269 return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR
;
274 nsROCSSPrimitiveValue::GetCssValueType(PRUint16
* aValueType
)
276 NS_ENSURE_ARG_POINTER(aValueType
);
277 *aValueType
= nsIDOMCSSValue::CSS_PRIMITIVE_VALUE
;
282 // nsIDOMCSSPrimitiveValue
285 nsROCSSPrimitiveValue::GetPrimitiveType(PRUint16
* aPrimitiveType
)
287 NS_ENSURE_ARG_POINTER(aPrimitiveType
);
288 *aPrimitiveType
= mType
;
295 nsROCSSPrimitiveValue::SetFloatValue(PRUint16 aUnitType
, float aFloatValue
)
297 return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR
;
302 nsROCSSPrimitiveValue::GetFloatValue(PRUint16 aUnitType
, float* aReturn
)
304 NS_ENSURE_ARG_POINTER(aReturn
);
310 return NS_ERROR_DOM_INVALID_ACCESS_ERR
;
311 *aReturn
= nsPresContext::AppUnitsToFloatCSSPixels(mValue
.mAppUnits
);
315 return NS_ERROR_DOM_INVALID_ACCESS_ERR
;
316 *aReturn
= mValue
.mAppUnits
* CM_PER_INCH_FLOAT
/
317 nsPresContext::AppUnitsPerCSSInch();
321 return NS_ERROR_DOM_INVALID_ACCESS_ERR
;
322 *aReturn
= mValue
.mAppUnits
* MM_PER_INCH_FLOAT
/
323 nsPresContext::AppUnitsPerCSSInch();
327 return NS_ERROR_DOM_INVALID_ACCESS_ERR
;
328 *aReturn
= mValue
.mAppUnits
/ nsPresContext::AppUnitsPerCSSInch();
332 return NS_ERROR_DOM_INVALID_ACCESS_ERR
;
333 *aReturn
= mValue
.mAppUnits
* POINTS_PER_INCH_FLOAT
/
334 nsPresContext::AppUnitsPerCSSInch();
338 return NS_ERROR_DOM_INVALID_ACCESS_ERR
;
339 *aReturn
= mValue
.mAppUnits
* 6.0f
/
340 nsPresContext::AppUnitsPerCSSInch();
342 case CSS_PERCENTAGE
:
343 if (mType
!= CSS_PERCENTAGE
)
344 return NS_ERROR_DOM_INVALID_ACCESS_ERR
;
345 *aReturn
= mValue
.mFloat
* 100;
348 if (mType
!= CSS_NUMBER
)
349 return NS_ERROR_DOM_INVALID_ACCESS_ERR
;
350 *aReturn
= mValue
.mFloat
;
370 return NS_ERROR_DOM_INVALID_ACCESS_ERR
;
378 nsROCSSPrimitiveValue::SetStringValue(PRUint16 aStringType
,
379 const nsAString
& aStringValue
)
381 return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR
;
386 nsROCSSPrimitiveValue::GetStringValue(nsAString
& aReturn
)
390 CopyUTF8toUTF16(nsCSSKeywords::GetStringValue(mValue
.mKeyword
), aReturn
);
394 aReturn
.Assign(mValue
.mString
);
399 mValue
.mURI
->GetSpec(spec
);
400 CopyUTF8toUTF16(spec
, aReturn
);
404 return NS_ERROR_DOM_INVALID_ACCESS_ERR
;
411 nsROCSSPrimitiveValue::GetCounterValue(nsIDOMCounter
** aReturn
)
413 return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR
;
418 nsROCSSPrimitiveValue::GetRectValue(nsIDOMRect
** aReturn
)
420 if (mType
!= CSS_RECT
) {
422 return NS_ERROR_DOM_INVALID_ACCESS_ERR
;
424 NS_ASSERTION(mValue
.mRect
, "mValue.mRect should never be null");
425 NS_ADDREF(*aReturn
= mValue
.mRect
);
431 nsROCSSPrimitiveValue::GetRGBColorValue(nsIDOMRGBColor
** aReturn
)
433 if (mType
!= CSS_RGBCOLOR
) {
435 return NS_ERROR_DOM_INVALID_ACCESS_ERR
;
437 NS_ASSERTION(mValue
.mColor
, "mValue.mColor should never be null");
438 NS_ADDREF(*aReturn
= mValue
.mColor
);
443 nsROCSSPrimitiveValue::SetNumber(float aValue
)
446 mValue
.mFloat
= aValue
;
451 nsROCSSPrimitiveValue::SetNumber(PRInt32 aValue
)
454 mValue
.mFloat
= float(aValue
);
459 nsROCSSPrimitiveValue::SetNumber(PRUint32 aValue
)
462 mValue
.mFloat
= float(aValue
);
467 nsROCSSPrimitiveValue::SetPercent(float aValue
)
470 mValue
.mFloat
= aValue
;
471 mType
= CSS_PERCENTAGE
;
475 nsROCSSPrimitiveValue::SetAppUnits(nscoord aValue
)
478 mValue
.mAppUnits
= aValue
;
483 nsROCSSPrimitiveValue::SetAppUnits(float aValue
)
485 SetAppUnits(NSToCoordRound(aValue
));
489 nsROCSSPrimitiveValue::SetIdent(nsCSSKeyword aKeyword
)
491 NS_PRECONDITION(aKeyword
!= eCSSKeyword_UNKNOWN
&&
492 0 <= aKeyword
&& aKeyword
< eCSSKeyword_COUNT
,
495 mValue
.mKeyword
= aKeyword
;
499 // FIXME: CSS_STRING should imply a string with "" and a need for escaping.
501 nsROCSSPrimitiveValue::SetString(const nsACString
& aString
, PRUint16 aType
)
504 mValue
.mString
= ToNewUnicode(aString
);
505 if (mValue
.mString
) {
508 // XXXcaa We should probably let the caller know we are out of memory
513 // FIXME: CSS_STRING should imply a string with "" and a need for escaping.
515 nsROCSSPrimitiveValue::SetString(const nsAString
& aString
, PRUint16 aType
)
518 mValue
.mString
= ToNewUnicode(aString
);
519 if (mValue
.mString
) {
522 // XXXcaa We should probably let the caller know we are out of memory
528 nsROCSSPrimitiveValue::SetURI(nsIURI
*aURI
)
532 NS_IF_ADDREF(mValue
.mURI
);
537 nsROCSSPrimitiveValue::SetColor(nsDOMCSSRGBColor
* aColor
)
539 NS_PRECONDITION(aColor
, "Null RGBColor being set!");
541 mValue
.mColor
= aColor
;
543 NS_ADDREF(mValue
.mColor
);
544 mType
= CSS_RGBCOLOR
;
552 nsROCSSPrimitiveValue::SetRect(nsIDOMRect
* aRect
)
554 NS_PRECONDITION(aRect
, "Null rect being set!");
556 mValue
.mRect
= aRect
;
558 NS_ADDREF(mValue
.mRect
);
567 nsROCSSPrimitiveValue::SetTime(float aValue
)
570 mValue
.mFloat
= aValue
;
575 nsROCSSPrimitiveValue::Reset()
582 case CSS_COUNTER
: // FIXME: Counter should use an object
583 NS_ASSERTION(mValue
.mString
, "Null string should never happen");
584 nsMemory::Free(mValue
.mString
);
585 mValue
.mString
= nsnull
;
588 NS_IF_RELEASE(mValue
.mURI
);
591 NS_ASSERTION(mValue
.mRect
, "Null Rect should never happen");
592 NS_RELEASE(mValue
.mRect
);
595 NS_ASSERTION(mValue
.mColor
, "Null RGBColor should never happen");
596 NS_RELEASE(mValue
.mColor
);