1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 /* DOM object representing values in DOM computed style */
8 
9 #include "nsROCSSPrimitiveValue.h"
10 
11 #include "mozilla/dom/CSSPrimitiveValueBinding.h"
12 #include "nsPresContext.h"
13 #include "nsStyleUtil.h"
14 #include "nsDOMCSSRGBColor.h"
15 #include "nsDOMCSSRect.h"
16 #include "nsIURI.h"
17 #include "nsError.h"
18 
19 using namespace mozilla;
20 
nsROCSSPrimitiveValue()21 nsROCSSPrimitiveValue::nsROCSSPrimitiveValue()
22   : CSSValue(), mType(CSS_PX)
23 {
24   mValue.mAppUnits = 0;
25 }
26 
27 
~nsROCSSPrimitiveValue()28 nsROCSSPrimitiveValue::~nsROCSSPrimitiveValue()
29 {
30   Reset();
31 }
32 
33 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsROCSSPrimitiveValue)
34 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsROCSSPrimitiveValue)
35 
36 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsROCSSPrimitiveValue)
37   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
38   NS_INTERFACE_MAP_ENTRY(nsIDOMCSSPrimitiveValue)
39   NS_INTERFACE_MAP_ENTRY(nsIDOMCSSValue)
40   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, CSSValue)
41 NS_INTERFACE_MAP_END
42 
43 NS_IMPL_CYCLE_COLLECTION_CLASS(nsROCSSPrimitiveValue)
44 
45 NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(nsROCSSPrimitiveValue)
46 
47 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsROCSSPrimitiveValue)
48   if (tmp->mType == CSS_URI) {
49     NS_IMPL_CYCLE_COLLECTION_TRAVERSE_RAWPTR(mValue.mURI)
50   } else if (tmp->mType == CSS_RGBCOLOR) {
51     NS_IMPL_CYCLE_COLLECTION_TRAVERSE_RAWPTR(mValue.mColor)
52   } else if (tmp->mType == CSS_RECT) {
53     NS_IMPL_CYCLE_COLLECTION_TRAVERSE_RAWPTR(mValue.mRect)
54   }
55   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
56 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
57 
58 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsROCSSPrimitiveValue)
59   NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
60   tmp->Reset();
61 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
62 
63 JSObject*
WrapObject(JSContext * cx,JS::Handle<JSObject * > aGivenProto)64 nsROCSSPrimitiveValue::WrapObject(JSContext *cx, JS::Handle<JSObject*> aGivenProto)
65 {
66   return dom::CSSPrimitiveValueBinding::Wrap(cx, this, aGivenProto);
67 }
68 
69 // nsIDOMCSSValue
70 
71 
72 NS_IMETHODIMP
GetCssText(nsAString & aCssText)73 nsROCSSPrimitiveValue::GetCssText(nsAString& aCssText)
74 {
75   nsAutoString tmpStr;
76   aCssText.Truncate();
77   nsresult result = NS_OK;
78 
79   switch (mType) {
80     case CSS_PX :
81       {
82         float val = nsPresContext::AppUnitsToFloatCSSPixels(mValue.mAppUnits);
83         nsStyleUtil::AppendCSSNumber(val, tmpStr);
84         tmpStr.AppendLiteral("px");
85         break;
86       }
87     case CSS_IDENT :
88       {
89         AppendUTF8toUTF16(nsCSSKeywords::GetStringValue(mValue.mKeyword),
90                           tmpStr);
91         break;
92       }
93     case CSS_STRING :
94     case CSS_COUNTER : /* FIXME: COUNTER should use an object */
95       {
96         tmpStr.Append(mValue.mString);
97         break;
98       }
99     case CSS_URI :
100       {
101         if (mValue.mURI) {
102           nsAutoCString specUTF8;
103           nsresult rv = mValue.mURI->GetSpec(specUTF8);
104           NS_ENSURE_SUCCESS(rv, rv);
105 
106           tmpStr.AssignLiteral("url(");
107           nsStyleUtil::AppendEscapedCSSString(NS_ConvertUTF8toUTF16(specUTF8),
108                                               tmpStr);
109           tmpStr.Append(')');
110         } else {
111           // http://dev.w3.org/csswg/css3-values/#attr defines
112           // 'about:invalid' as the default value for url attributes,
113           // so let's also use it here as the default computed value
114           // for invalid URLs.
115           tmpStr.AssignLiteral(u"url(about:invalid)");
116         }
117         break;
118       }
119     case CSS_ATTR :
120       {
121         tmpStr.AppendLiteral("attr(");
122         tmpStr.Append(mValue.mString);
123         tmpStr.Append(char16_t(')'));
124         break;
125       }
126     case CSS_PERCENTAGE :
127       {
128         nsStyleUtil::AppendCSSNumber(mValue.mFloat * 100, tmpStr);
129         tmpStr.Append(char16_t('%'));
130         break;
131       }
132     case CSS_NUMBER :
133       {
134         nsStyleUtil::AppendCSSNumber(mValue.mFloat, tmpStr);
135         break;
136       }
137     case CSS_NUMBER_INT32 :
138       {
139         tmpStr.AppendInt(mValue.mInt32);
140         break;
141       }
142     case CSS_NUMBER_UINT32 :
143       {
144         tmpStr.AppendInt(mValue.mUint32);
145         break;
146       }
147     case CSS_DEG :
148       {
149         nsStyleUtil::AppendCSSNumber(mValue.mFloat, tmpStr);
150         tmpStr.AppendLiteral("deg");
151         break;
152       }
153     case CSS_GRAD :
154       {
155         nsStyleUtil::AppendCSSNumber(mValue.mFloat, tmpStr);
156         tmpStr.AppendLiteral("grad");
157         break;
158       }
159     case CSS_RAD :
160       {
161         nsStyleUtil::AppendCSSNumber(mValue.mFloat, tmpStr);
162         tmpStr.AppendLiteral("rad");
163         break;
164       }
165     case CSS_TURN :
166       {
167         nsStyleUtil::AppendCSSNumber(mValue.mFloat, tmpStr);
168         tmpStr.AppendLiteral("turn");
169         break;
170       }
171     case CSS_RECT :
172       {
173         NS_ASSERTION(mValue.mRect, "mValue.mRect should never be null");
174         NS_NAMED_LITERAL_STRING(comma, ", ");
175         nsCOMPtr<nsIDOMCSSPrimitiveValue> sideCSSValue;
176         nsAutoString sideValue;
177         tmpStr.AssignLiteral("rect(");
178         // get the top
179         result = mValue.mRect->GetTop(getter_AddRefs(sideCSSValue));
180         if (NS_FAILED(result))
181           break;
182         result = sideCSSValue->GetCssText(sideValue);
183         if (NS_FAILED(result))
184           break;
185         tmpStr.Append(sideValue + comma);
186         // get the right
187         result = mValue.mRect->GetRight(getter_AddRefs(sideCSSValue));
188         if (NS_FAILED(result))
189           break;
190         result = sideCSSValue->GetCssText(sideValue);
191         if (NS_FAILED(result))
192           break;
193         tmpStr.Append(sideValue + comma);
194         // get the bottom
195         result = mValue.mRect->GetBottom(getter_AddRefs(sideCSSValue));
196         if (NS_FAILED(result))
197           break;
198         result = sideCSSValue->GetCssText(sideValue);
199         if (NS_FAILED(result))
200           break;
201         tmpStr.Append(sideValue + comma);
202         // get the left
203         result = mValue.mRect->GetLeft(getter_AddRefs(sideCSSValue));
204         if (NS_FAILED(result))
205           break;
206         result = sideCSSValue->GetCssText(sideValue);
207         if (NS_FAILED(result))
208           break;
209         tmpStr.Append(sideValue + NS_LITERAL_STRING(")"));
210         break;
211       }
212     case CSS_RGBCOLOR :
213       {
214         NS_ASSERTION(mValue.mColor, "mValue.mColor should never be null");
215         ErrorResult error;
216         NS_NAMED_LITERAL_STRING(comma, ", ");
217         nsAutoString colorValue;
218         if (mValue.mColor->HasAlpha())
219           tmpStr.AssignLiteral("rgba(");
220         else
221           tmpStr.AssignLiteral("rgb(");
222 
223         // get the red component
224         mValue.mColor->Red()->GetCssText(colorValue, error);
225         if (error.Failed())
226           break;
227         tmpStr.Append(colorValue + comma);
228 
229         // get the green component
230         mValue.mColor->Green()->GetCssText(colorValue, error);
231         if (error.Failed())
232           break;
233         tmpStr.Append(colorValue + comma);
234 
235         // get the blue component
236         mValue.mColor->Blue()->GetCssText(colorValue, error);
237         if (error.Failed())
238           break;
239         tmpStr.Append(colorValue);
240 
241         if (mValue.mColor->HasAlpha()) {
242           // get the alpha component
243           mValue.mColor->Alpha()->GetCssText(colorValue, error);
244           if (error.Failed())
245             break;
246           tmpStr.Append(comma + colorValue);
247         }
248 
249         tmpStr.Append(')');
250 
251         break;
252       }
253     case CSS_S :
254       {
255         nsStyleUtil::AppendCSSNumber(mValue.mFloat, tmpStr);
256         tmpStr.Append('s');
257         break;
258       }
259     case CSS_CM :
260     case CSS_MM :
261     case CSS_IN :
262     case CSS_PT :
263     case CSS_PC :
264     case CSS_UNKNOWN :
265     case CSS_EMS :
266     case CSS_EXS :
267     case CSS_MS :
268     case CSS_HZ :
269     case CSS_KHZ :
270     case CSS_DIMENSION :
271       NS_ERROR("We have a bogus value set.  This should not happen");
272       return NS_ERROR_DOM_INVALID_ACCESS_ERR;
273   }
274 
275   if (NS_SUCCEEDED(result)) {
276     aCssText.Assign(tmpStr);
277   }
278 
279   return NS_OK;
280 }
281 
282 void
GetCssText(nsString & aText,ErrorResult & aRv)283 nsROCSSPrimitiveValue::GetCssText(nsString& aText, ErrorResult& aRv)
284 {
285   aRv = GetCssText(aText);
286 }
287 
288 NS_IMETHODIMP
SetCssText(const nsAString & aCssText)289 nsROCSSPrimitiveValue::SetCssText(const nsAString& aCssText)
290 {
291   return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
292 }
293 
294 void
SetCssText(const nsAString & aText,ErrorResult & aRv)295 nsROCSSPrimitiveValue::SetCssText(const nsAString& aText, ErrorResult& aRv)
296 {
297   aRv = SetCssText(aText);
298 }
299 
300 
301 NS_IMETHODIMP
GetCssValueType(uint16_t * aValueType)302 nsROCSSPrimitiveValue::GetCssValueType(uint16_t* aValueType)
303 {
304   NS_ENSURE_ARG_POINTER(aValueType);
305   *aValueType = nsIDOMCSSValue::CSS_PRIMITIVE_VALUE;
306   return NS_OK;
307 }
308 
309 uint16_t
CssValueType() const310 nsROCSSPrimitiveValue::CssValueType() const
311 {
312   return nsIDOMCSSValue::CSS_PRIMITIVE_VALUE;
313 }
314 
315 
316 // nsIDOMCSSPrimitiveValue
317 
318 NS_IMETHODIMP
GetPrimitiveType(uint16_t * aPrimitiveType)319 nsROCSSPrimitiveValue::GetPrimitiveType(uint16_t* aPrimitiveType)
320 {
321   NS_ENSURE_ARG_POINTER(aPrimitiveType);
322   *aPrimitiveType = PrimitiveType();
323 
324   return NS_OK;
325 }
326 
327 
328 NS_IMETHODIMP
SetFloatValue(uint16_t aUnitType,float aFloatValue)329 nsROCSSPrimitiveValue::SetFloatValue(uint16_t aUnitType, float aFloatValue)
330 {
331   return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
332 }
333 
334 void
SetFloatValue(uint16_t aType,float aVal,ErrorResult & aRv)335 nsROCSSPrimitiveValue::SetFloatValue(uint16_t aType, float aVal,
336                                      ErrorResult& aRv)
337 {
338   aRv = SetFloatValue(aType, aVal);
339 }
340 
341 float
GetFloatValue(uint16_t aUnitType,ErrorResult & aRv)342 nsROCSSPrimitiveValue::GetFloatValue(uint16_t aUnitType, ErrorResult& aRv)
343 {
344   switch(aUnitType) {
345     case CSS_PX :
346       if (mType == CSS_PX) {
347         return nsPresContext::AppUnitsToFloatCSSPixels(mValue.mAppUnits);
348       }
349 
350       break;
351     case CSS_CM :
352       if (mType == CSS_PX) {
353         return mValue.mAppUnits * CM_PER_INCH_FLOAT /
354           nsPresContext::AppUnitsPerCSSInch();
355       }
356 
357       break;
358     case CSS_MM :
359       if (mType == CSS_PX) {
360         return mValue.mAppUnits * MM_PER_INCH_FLOAT /
361           nsPresContext::AppUnitsPerCSSInch();
362       }
363 
364       break;
365     case CSS_IN :
366       if (mType == CSS_PX) {
367         return mValue.mAppUnits / nsPresContext::AppUnitsPerCSSInch();
368       }
369 
370       break;
371     case CSS_PT :
372       if (mType == CSS_PX) {
373         return mValue.mAppUnits * POINTS_PER_INCH_FLOAT /
374           nsPresContext::AppUnitsPerCSSInch();
375       }
376 
377       break;
378     case CSS_PC :
379       if (mType == CSS_PX) {
380         return mValue.mAppUnits * 6.0f /
381           nsPresContext::AppUnitsPerCSSInch();
382       }
383 
384       break;
385     case CSS_PERCENTAGE :
386       if (mType == CSS_PERCENTAGE) {
387         return mValue.mFloat * 100;
388       }
389 
390       break;
391     case CSS_NUMBER :
392       if (mType == CSS_NUMBER) {
393         return mValue.mFloat;
394       }
395       if (mType == CSS_NUMBER_INT32) {
396         return mValue.mInt32;
397       }
398       if (mType == CSS_NUMBER_UINT32) {
399         return mValue.mUint32;
400       }
401 
402       break;
403     case CSS_UNKNOWN :
404     case CSS_EMS :
405     case CSS_EXS :
406     case CSS_DEG :
407     case CSS_RAD :
408     case CSS_GRAD :
409     case CSS_MS :
410     case CSS_S :
411     case CSS_HZ :
412     case CSS_KHZ :
413     case CSS_DIMENSION :
414     case CSS_STRING :
415     case CSS_URI :
416     case CSS_IDENT :
417     case CSS_ATTR :
418     case CSS_COUNTER :
419     case CSS_RECT :
420     case CSS_RGBCOLOR :
421       break;
422   }
423 
424   aRv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR);
425   return 0;
426 }
427 
428 NS_IMETHODIMP
GetFloatValue(uint16_t aType,float * aVal)429 nsROCSSPrimitiveValue::GetFloatValue(uint16_t aType, float *aVal)
430 {
431   ErrorResult rv;
432   *aVal = GetFloatValue(aType, rv);
433   return rv.StealNSResult();
434 }
435 
436 
437 NS_IMETHODIMP
SetStringValue(uint16_t aStringType,const nsAString & aStringValue)438 nsROCSSPrimitiveValue::SetStringValue(uint16_t aStringType,
439                                       const nsAString& aStringValue)
440 {
441   return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
442 }
443 
444 void
SetStringValue(uint16_t aType,const nsAString & aString,mozilla::ErrorResult & aRv)445 nsROCSSPrimitiveValue::SetStringValue(uint16_t aType, const nsAString& aString,
446                                       mozilla::ErrorResult& aRv)
447 {
448   aRv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
449 }
450 
451 
452 NS_IMETHODIMP
GetStringValue(nsAString & aReturn)453 nsROCSSPrimitiveValue::GetStringValue(nsAString& aReturn)
454 {
455   switch (mType) {
456     case CSS_IDENT:
457       CopyUTF8toUTF16(nsCSSKeywords::GetStringValue(mValue.mKeyword), aReturn);
458       break;
459     case CSS_STRING:
460     case CSS_ATTR:
461       aReturn.Assign(mValue.mString);
462       break;
463     case CSS_URI: {
464       nsAutoCString spec;
465       if (mValue.mURI) {
466         nsresult rv = mValue.mURI->GetSpec(spec);
467         NS_ENSURE_SUCCESS(rv, rv);
468       }
469       CopyUTF8toUTF16(spec, aReturn);
470       break;
471     }
472     default:
473       aReturn.Truncate();
474       return NS_ERROR_DOM_INVALID_ACCESS_ERR;
475   }
476   return NS_OK;
477 }
478 
479 void
GetStringValue(nsString & aString,ErrorResult & aRv)480 nsROCSSPrimitiveValue::GetStringValue(nsString& aString, ErrorResult& aRv)
481 {
482   aRv = GetStringValue(aString);
483 }
484 
485 
486 NS_IMETHODIMP
GetCounterValue(nsIDOMCounter ** aReturn)487 nsROCSSPrimitiveValue::GetCounterValue(nsIDOMCounter** aReturn)
488 {
489   return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
490 }
491 
492 already_AddRefed<nsIDOMCounter>
GetCounterValue(ErrorResult & aRv)493 nsROCSSPrimitiveValue::GetCounterValue(ErrorResult& aRv)
494 {
495   aRv.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR);
496   return nullptr;
497 }
498 
499 nsDOMCSSRect*
GetRectValue(ErrorResult & aRv)500 nsROCSSPrimitiveValue::GetRectValue(ErrorResult& aRv)
501 {
502   if (mType != CSS_RECT) {
503     aRv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR);
504     return nullptr;
505   }
506 
507   NS_ASSERTION(mValue.mRect, "mValue.mRect should never be null");
508   return mValue.mRect;
509 }
510 
511 NS_IMETHODIMP
GetRectValue(nsIDOMRect ** aRect)512 nsROCSSPrimitiveValue::GetRectValue(nsIDOMRect** aRect)
513 {
514   ErrorResult error;
515   NS_IF_ADDREF(*aRect = GetRectValue(error));
516   return error.StealNSResult();
517 }
518 
519 nsDOMCSSRGBColor*
GetRGBColorValue(ErrorResult & aRv)520 nsROCSSPrimitiveValue::GetRGBColorValue(ErrorResult& aRv)
521 {
522   if (mType != CSS_RGBCOLOR) {
523     aRv.Throw(NS_ERROR_DOM_INVALID_ACCESS_ERR);
524     return nullptr;
525   }
526 
527   NS_ASSERTION(mValue.mColor, "mValue.mColor should never be null");
528   return mValue.mColor;
529 }
530 
531 void
SetNumber(float aValue)532 nsROCSSPrimitiveValue::SetNumber(float aValue)
533 {
534   Reset();
535   mValue.mFloat = aValue;
536   mType = CSS_NUMBER;
537 }
538 
539 void
SetNumber(int32_t aValue)540 nsROCSSPrimitiveValue::SetNumber(int32_t aValue)
541 {
542   Reset();
543   mValue.mInt32 = aValue;
544   mType = CSS_NUMBER_INT32;
545 }
546 
547 void
SetNumber(uint32_t aValue)548 nsROCSSPrimitiveValue::SetNumber(uint32_t aValue)
549 {
550   Reset();
551   mValue.mUint32 = aValue;
552   mType = CSS_NUMBER_UINT32;
553 }
554 
555 void
SetPercent(float aValue)556 nsROCSSPrimitiveValue::SetPercent(float aValue)
557 {
558   Reset();
559   mValue.mFloat = aValue;
560   mType = CSS_PERCENTAGE;
561 }
562 
563 void
SetDegree(float aValue)564 nsROCSSPrimitiveValue::SetDegree(float aValue)
565 {
566   Reset();
567   mValue.mFloat = aValue;
568   mType = CSS_DEG;
569 }
570 
571 void
SetGrad(float aValue)572 nsROCSSPrimitiveValue::SetGrad(float aValue)
573 {
574   Reset();
575   mValue.mFloat = aValue;
576   mType = CSS_GRAD;
577 }
578 
579 void
SetRadian(float aValue)580 nsROCSSPrimitiveValue::SetRadian(float aValue)
581 {
582   Reset();
583   mValue.mFloat = aValue;
584   mType = CSS_RAD;
585 }
586 
587 void
SetTurn(float aValue)588 nsROCSSPrimitiveValue::SetTurn(float aValue)
589 {
590   Reset();
591   mValue.mFloat = aValue;
592   mType = CSS_TURN;
593 }
594 
595 void
SetAppUnits(nscoord aValue)596 nsROCSSPrimitiveValue::SetAppUnits(nscoord aValue)
597 {
598   Reset();
599   mValue.mAppUnits = aValue;
600   mType = CSS_PX;
601 }
602 
603 void
SetAppUnits(float aValue)604 nsROCSSPrimitiveValue::SetAppUnits(float aValue)
605 {
606   SetAppUnits(NSToCoordRound(aValue));
607 }
608 
609 void
SetIdent(nsCSSKeyword aKeyword)610 nsROCSSPrimitiveValue::SetIdent(nsCSSKeyword aKeyword)
611 {
612   NS_PRECONDITION(aKeyword != eCSSKeyword_UNKNOWN &&
613                   0 <= aKeyword && aKeyword < eCSSKeyword_COUNT,
614                   "bad keyword");
615   Reset();
616   mValue.mKeyword = aKeyword;
617   mType = CSS_IDENT;
618 }
619 
620 // FIXME: CSS_STRING should imply a string with "" and a need for escaping.
621 void
SetString(const nsACString & aString,uint16_t aType)622 nsROCSSPrimitiveValue::SetString(const nsACString& aString, uint16_t aType)
623 {
624   Reset();
625   mValue.mString = ToNewUnicode(aString);
626   if (mValue.mString) {
627     mType = aType;
628   } else {
629     // XXXcaa We should probably let the caller know we are out of memory
630     mType = CSS_UNKNOWN;
631   }
632 }
633 
634 // FIXME: CSS_STRING should imply a string with "" and a need for escaping.
635 void
SetString(const nsAString & aString,uint16_t aType)636 nsROCSSPrimitiveValue::SetString(const nsAString& aString, uint16_t aType)
637 {
638   Reset();
639   mValue.mString = ToNewUnicode(aString);
640   if (mValue.mString) {
641     mType = aType;
642   } else {
643     // XXXcaa We should probably let the caller know we are out of memory
644     mType = CSS_UNKNOWN;
645   }
646 }
647 
648 void
SetURI(nsIURI * aURI)649 nsROCSSPrimitiveValue::SetURI(nsIURI *aURI)
650 {
651   Reset();
652   mValue.mURI = aURI;
653   NS_IF_ADDREF(mValue.mURI);
654   mType = CSS_URI;
655 }
656 
657 void
SetColor(nsDOMCSSRGBColor * aColor)658 nsROCSSPrimitiveValue::SetColor(nsDOMCSSRGBColor* aColor)
659 {
660   NS_PRECONDITION(aColor, "Null RGBColor being set!");
661   Reset();
662   mValue.mColor = aColor;
663   if (mValue.mColor) {
664     NS_ADDREF(mValue.mColor);
665     mType = CSS_RGBCOLOR;
666   }
667   else {
668     mType = CSS_UNKNOWN;
669   }
670 }
671 
672 void
SetRect(nsDOMCSSRect * aRect)673 nsROCSSPrimitiveValue::SetRect(nsDOMCSSRect* aRect)
674 {
675   NS_PRECONDITION(aRect, "Null rect being set!");
676   Reset();
677   mValue.mRect = aRect;
678   if (mValue.mRect) {
679     NS_ADDREF(mValue.mRect);
680     mType = CSS_RECT;
681   }
682   else {
683     mType = CSS_UNKNOWN;
684   }
685 }
686 
687 void
SetTime(float aValue)688 nsROCSSPrimitiveValue::SetTime(float aValue)
689 {
690   Reset();
691   mValue.mFloat = aValue;
692   mType = CSS_S;
693 }
694 
695 void
Reset()696 nsROCSSPrimitiveValue::Reset()
697 {
698   switch (mType) {
699     case CSS_IDENT:
700       break;
701     case CSS_STRING:
702     case CSS_ATTR:
703     case CSS_COUNTER: // FIXME: Counter should use an object
704       NS_ASSERTION(mValue.mString, "Null string should never happen");
705       free(mValue.mString);
706       mValue.mString = nullptr;
707       break;
708     case CSS_URI:
709       NS_IF_RELEASE(mValue.mURI);
710       break;
711     case CSS_RECT:
712       NS_ASSERTION(mValue.mRect, "Null Rect should never happen");
713       NS_RELEASE(mValue.mRect);
714       break;
715     case CSS_RGBCOLOR:
716       NS_ASSERTION(mValue.mColor, "Null RGBColor should never happen");
717       NS_RELEASE(mValue.mColor);
718       break;
719   }
720 
721   mType = CSS_UNKNOWN;
722 }
723