1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is mozilla.org code.
16 : *
17 : * The Initial Developer of the Original Code is
18 : * Netscape Communications Corporation.
19 : * Portions created by the Initial Developer are Copyright (C) 1998
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : *
24 : * Alternatively, the contents of this file may be used under the terms of
25 : * either of the GNU General Public License Version 2 or later (the "GPL"),
26 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 : * in which case the provisions of the GPL or the LGPL are applicable instead
28 : * of those above. If you wish to allow use of your version of this file only
29 : * under the terms of either the GPL or the LGPL, and not to allow others to
30 : * use your version of this file under the terms of the MPL, indicate your
31 : * decision by deleting the provisions above and replace them with the notice
32 : * and other provisions required by the GPL or the LGPL. If you do not delete
33 : * the provisions above, a recipient may use your version of this file under
34 : * the terms of any one of the MPL, the GPL or the LGPL.
35 : *
36 : * ***** END LICENSE BLOCK ***** */
37 :
38 : /* representation of simple property values within CSS declarations */
39 :
40 : #include "nsCSSValue.h"
41 :
42 : #include "imgIRequest.h"
43 : #include "nsIPrincipal.h"
44 : #include "nsCSSProps.h"
45 : #include "nsContentUtils.h"
46 : #include "nsStyleUtil.h"
47 : #include "CSSCalc.h"
48 : #include "nsNetUtil.h"
49 :
50 : namespace css = mozilla::css;
51 :
52 0 : nsCSSValue::nsCSSValue(PRInt32 aValue, nsCSSUnit aUnit)
53 0 : : mUnit(aUnit)
54 : {
55 0 : NS_ABORT_IF_FALSE(aUnit == eCSSUnit_Integer || aUnit == eCSSUnit_Enumerated ||
56 : aUnit == eCSSUnit_EnumColor, "not an int value");
57 0 : if (aUnit == eCSSUnit_Integer || aUnit == eCSSUnit_Enumerated ||
58 : aUnit == eCSSUnit_EnumColor) {
59 0 : mValue.mInt = aValue;
60 : }
61 : else {
62 0 : mUnit = eCSSUnit_Null;
63 0 : mValue.mInt = 0;
64 : }
65 0 : }
66 :
67 0 : nsCSSValue::nsCSSValue(float aValue, nsCSSUnit aUnit)
68 0 : : mUnit(aUnit)
69 : {
70 0 : NS_ABORT_IF_FALSE(eCSSUnit_Percent <= aUnit, "not a float value");
71 0 : if (eCSSUnit_Percent <= aUnit) {
72 0 : mValue.mFloat = aValue;
73 : }
74 : else {
75 0 : mUnit = eCSSUnit_Null;
76 0 : mValue.mInt = 0;
77 : }
78 0 : }
79 :
80 0 : nsCSSValue::nsCSSValue(const nsString& aValue, nsCSSUnit aUnit)
81 0 : : mUnit(aUnit)
82 : {
83 0 : NS_ABORT_IF_FALSE(UnitHasStringValue(), "not a string value");
84 0 : if (UnitHasStringValue()) {
85 0 : mValue.mString = BufferFromString(aValue).get();
86 0 : if (NS_UNLIKELY(!mValue.mString)) {
87 : // XXXbz not much we can do here; just make sure that our promise of a
88 : // non-null mValue.mString holds for string units.
89 0 : mUnit = eCSSUnit_Null;
90 : }
91 : }
92 : else {
93 0 : mUnit = eCSSUnit_Null;
94 0 : mValue.mInt = 0;
95 : }
96 0 : }
97 :
98 0 : nsCSSValue::nsCSSValue(nsCSSValue::Array* aValue, nsCSSUnit aUnit)
99 0 : : mUnit(aUnit)
100 : {
101 0 : NS_ABORT_IF_FALSE(UnitHasArrayValue(), "bad unit");
102 0 : mValue.mArray = aValue;
103 0 : mValue.mArray->AddRef();
104 0 : }
105 :
106 0 : nsCSSValue::nsCSSValue(nsCSSValue::URL* aValue)
107 0 : : mUnit(eCSSUnit_URL)
108 : {
109 0 : mValue.mURL = aValue;
110 0 : mValue.mURL->AddRef();
111 0 : }
112 :
113 0 : nsCSSValue::nsCSSValue(nsCSSValue::Image* aValue)
114 0 : : mUnit(eCSSUnit_Image)
115 : {
116 0 : mValue.mImage = aValue;
117 0 : mValue.mImage->AddRef();
118 0 : }
119 :
120 0 : nsCSSValue::nsCSSValue(nsCSSValueGradient* aValue)
121 0 : : mUnit(eCSSUnit_Gradient)
122 : {
123 0 : mValue.mGradient = aValue;
124 0 : mValue.mGradient->AddRef();
125 0 : }
126 :
127 0 : nsCSSValue::nsCSSValue(const nsCSSValue& aCopy)
128 0 : : mUnit(aCopy.mUnit)
129 : {
130 0 : if (mUnit <= eCSSUnit_DummyInherit) {
131 : // nothing to do, but put this important case first
132 : }
133 0 : else if (eCSSUnit_Percent <= mUnit) {
134 0 : mValue.mFloat = aCopy.mValue.mFloat;
135 : }
136 0 : else if (UnitHasStringValue()) {
137 0 : mValue.mString = aCopy.mValue.mString;
138 0 : mValue.mString->AddRef();
139 : }
140 0 : else if (eCSSUnit_Integer <= mUnit && mUnit <= eCSSUnit_EnumColor) {
141 0 : mValue.mInt = aCopy.mValue.mInt;
142 : }
143 0 : else if (eCSSUnit_Color == mUnit) {
144 0 : mValue.mColor = aCopy.mValue.mColor;
145 : }
146 0 : else if (UnitHasArrayValue()) {
147 0 : mValue.mArray = aCopy.mValue.mArray;
148 0 : mValue.mArray->AddRef();
149 : }
150 0 : else if (eCSSUnit_URL == mUnit) {
151 0 : mValue.mURL = aCopy.mValue.mURL;
152 0 : mValue.mURL->AddRef();
153 : }
154 0 : else if (eCSSUnit_Image == mUnit) {
155 0 : mValue.mImage = aCopy.mValue.mImage;
156 0 : mValue.mImage->AddRef();
157 : }
158 0 : else if (eCSSUnit_Gradient == mUnit) {
159 0 : mValue.mGradient = aCopy.mValue.mGradient;
160 0 : mValue.mGradient->AddRef();
161 : }
162 0 : else if (eCSSUnit_Pair == mUnit) {
163 0 : mValue.mPair = aCopy.mValue.mPair;
164 0 : mValue.mPair->AddRef();
165 : }
166 0 : else if (eCSSUnit_Triplet == mUnit) {
167 0 : mValue.mTriplet = aCopy.mValue.mTriplet;
168 0 : mValue.mTriplet->AddRef();
169 : }
170 0 : else if (eCSSUnit_Rect == mUnit) {
171 0 : mValue.mRect = aCopy.mValue.mRect;
172 0 : mValue.mRect->AddRef();
173 : }
174 0 : else if (eCSSUnit_List == mUnit) {
175 0 : mValue.mList = aCopy.mValue.mList;
176 0 : mValue.mList->AddRef();
177 : }
178 0 : else if (eCSSUnit_ListDep == mUnit) {
179 0 : mValue.mListDependent = aCopy.mValue.mListDependent;
180 : }
181 0 : else if (eCSSUnit_PairList == mUnit) {
182 0 : mValue.mPairList = aCopy.mValue.mPairList;
183 0 : mValue.mPairList->AddRef();
184 : }
185 0 : else if (eCSSUnit_PairListDep == mUnit) {
186 0 : mValue.mPairListDependent = aCopy.mValue.mPairListDependent;
187 : }
188 : else {
189 0 : NS_ABORT_IF_FALSE(false, "unknown unit");
190 : }
191 0 : }
192 :
193 0 : nsCSSValue& nsCSSValue::operator=(const nsCSSValue& aCopy)
194 : {
195 0 : if (this != &aCopy) {
196 0 : Reset();
197 0 : new (this) nsCSSValue(aCopy);
198 : }
199 0 : return *this;
200 : }
201 :
202 0 : bool nsCSSValue::operator==(const nsCSSValue& aOther) const
203 : {
204 0 : NS_ABORT_IF_FALSE(mUnit != eCSSUnit_ListDep &&
205 : aOther.mUnit != eCSSUnit_ListDep &&
206 : mUnit != eCSSUnit_PairListDep &&
207 : aOther.mUnit != eCSSUnit_PairListDep,
208 : "don't use operator== with dependent lists");
209 :
210 0 : if (mUnit == aOther.mUnit) {
211 0 : if (mUnit <= eCSSUnit_DummyInherit) {
212 0 : return true;
213 : }
214 0 : else if (UnitHasStringValue()) {
215 : return (NS_strcmp(GetBufferValue(mValue.mString),
216 0 : GetBufferValue(aOther.mValue.mString)) == 0);
217 : }
218 0 : else if ((eCSSUnit_Integer <= mUnit) && (mUnit <= eCSSUnit_EnumColor)) {
219 0 : return mValue.mInt == aOther.mValue.mInt;
220 : }
221 0 : else if (eCSSUnit_Color == mUnit) {
222 0 : return mValue.mColor == aOther.mValue.mColor;
223 : }
224 0 : else if (UnitHasArrayValue()) {
225 0 : return *mValue.mArray == *aOther.mValue.mArray;
226 : }
227 0 : else if (eCSSUnit_URL == mUnit) {
228 0 : return *mValue.mURL == *aOther.mValue.mURL;
229 : }
230 0 : else if (eCSSUnit_Image == mUnit) {
231 0 : return *mValue.mImage == *aOther.mValue.mImage;
232 : }
233 0 : else if (eCSSUnit_Gradient == mUnit) {
234 0 : return *mValue.mGradient == *aOther.mValue.mGradient;
235 : }
236 0 : else if (eCSSUnit_Pair == mUnit) {
237 0 : return *mValue.mPair == *aOther.mValue.mPair;
238 : }
239 0 : else if (eCSSUnit_Triplet == mUnit) {
240 0 : return *mValue.mTriplet == *aOther.mValue.mTriplet;
241 : }
242 0 : else if (eCSSUnit_Rect == mUnit) {
243 0 : return *mValue.mRect == *aOther.mValue.mRect;
244 : }
245 0 : else if (eCSSUnit_List == mUnit) {
246 0 : return *mValue.mList == *aOther.mValue.mList;
247 : }
248 0 : else if (eCSSUnit_PairList == mUnit) {
249 0 : return *mValue.mPairList == *aOther.mValue.mPairList;
250 : }
251 : else {
252 0 : return mValue.mFloat == aOther.mValue.mFloat;
253 : }
254 : }
255 0 : return false;
256 : }
257 :
258 0 : double nsCSSValue::GetAngleValueInRadians() const
259 : {
260 0 : double angle = GetFloatValue();
261 :
262 0 : switch (GetUnit()) {
263 0 : case eCSSUnit_Radian: return angle;
264 0 : case eCSSUnit_Turn: return angle * 2 * M_PI;
265 0 : case eCSSUnit_Degree: return angle * M_PI / 180.0;
266 0 : case eCSSUnit_Grad: return angle * M_PI / 200.0;
267 :
268 : default:
269 0 : NS_ABORT_IF_FALSE(false, "unrecognized angular unit");
270 0 : return 0.0;
271 : }
272 : }
273 :
274 0 : imgIRequest* nsCSSValue::GetImageValue() const
275 : {
276 0 : NS_ABORT_IF_FALSE(mUnit == eCSSUnit_Image, "not an Image value");
277 0 : return mValue.mImage->mRequest;
278 : }
279 :
280 0 : nscoord nsCSSValue::GetFixedLength(nsPresContext* aPresContext) const
281 : {
282 0 : NS_ABORT_IF_FALSE(mUnit == eCSSUnit_PhysicalMillimeter,
283 : "not a fixed length unit");
284 :
285 0 : float inches = mValue.mFloat / MM_PER_INCH_FLOAT;
286 : return NSToCoordFloorClamped(inches *
287 0 : float(aPresContext->DeviceContext()->AppUnitsPerPhysicalInch()));
288 : }
289 :
290 0 : nscoord nsCSSValue::GetPixelLength() const
291 : {
292 0 : NS_ABORT_IF_FALSE(IsPixelLengthUnit(), "not a fixed length unit");
293 :
294 : double scaleFactor;
295 0 : switch (mUnit) {
296 0 : case eCSSUnit_Pixel: return nsPresContext::CSSPixelsToAppUnits(mValue.mFloat);
297 0 : case eCSSUnit_Pica: scaleFactor = 16.0; break;
298 0 : case eCSSUnit_Point: scaleFactor = 4/3.0; break;
299 0 : case eCSSUnit_Inch: scaleFactor = 96.0; break;
300 0 : case eCSSUnit_Millimeter: scaleFactor = 96/25.4; break;
301 0 : case eCSSUnit_Centimeter: scaleFactor = 96/2.54; break;
302 : default:
303 0 : NS_ERROR("should never get here");
304 0 : return 0;
305 : }
306 0 : return nsPresContext::CSSPixelsToAppUnits(float(mValue.mFloat*scaleFactor));
307 : }
308 :
309 0 : void nsCSSValue::DoReset()
310 : {
311 0 : if (UnitHasStringValue()) {
312 0 : mValue.mString->Release();
313 0 : } else if (UnitHasArrayValue()) {
314 0 : mValue.mArray->Release();
315 0 : } else if (eCSSUnit_URL == mUnit) {
316 0 : mValue.mURL->Release();
317 0 : } else if (eCSSUnit_Image == mUnit) {
318 0 : mValue.mImage->Release();
319 0 : } else if (eCSSUnit_Gradient == mUnit) {
320 0 : mValue.mGradient->Release();
321 0 : } else if (eCSSUnit_Pair == mUnit) {
322 0 : mValue.mPair->Release();
323 0 : } else if (eCSSUnit_Triplet == mUnit) {
324 0 : mValue.mTriplet->Release();
325 0 : } else if (eCSSUnit_Rect == mUnit) {
326 0 : mValue.mRect->Release();
327 0 : } else if (eCSSUnit_List == mUnit) {
328 0 : mValue.mList->Release();
329 0 : } else if (eCSSUnit_PairList == mUnit) {
330 0 : mValue.mPairList->Release();
331 : }
332 0 : mUnit = eCSSUnit_Null;
333 0 : }
334 :
335 0 : void nsCSSValue::SetIntValue(PRInt32 aValue, nsCSSUnit aUnit)
336 : {
337 0 : NS_ABORT_IF_FALSE(aUnit == eCSSUnit_Integer || aUnit == eCSSUnit_Enumerated ||
338 : aUnit == eCSSUnit_EnumColor, "not an int value");
339 0 : Reset();
340 0 : if (aUnit == eCSSUnit_Integer || aUnit == eCSSUnit_Enumerated ||
341 : aUnit == eCSSUnit_EnumColor) {
342 0 : mUnit = aUnit;
343 0 : mValue.mInt = aValue;
344 : }
345 0 : }
346 :
347 0 : void nsCSSValue::SetPercentValue(float aValue)
348 : {
349 0 : Reset();
350 0 : mUnit = eCSSUnit_Percent;
351 0 : mValue.mFloat = aValue;
352 0 : }
353 :
354 0 : void nsCSSValue::SetFloatValue(float aValue, nsCSSUnit aUnit)
355 : {
356 0 : NS_ABORT_IF_FALSE(eCSSUnit_Number <= aUnit, "not a float value");
357 0 : Reset();
358 0 : if (eCSSUnit_Number <= aUnit) {
359 0 : mUnit = aUnit;
360 0 : mValue.mFloat = aValue;
361 : }
362 0 : }
363 :
364 0 : void nsCSSValue::SetStringValue(const nsString& aValue,
365 : nsCSSUnit aUnit)
366 : {
367 0 : Reset();
368 0 : mUnit = aUnit;
369 0 : NS_ABORT_IF_FALSE(UnitHasStringValue(), "not a string unit");
370 0 : if (UnitHasStringValue()) {
371 0 : mValue.mString = BufferFromString(aValue).get();
372 0 : if (NS_UNLIKELY(!mValue.mString)) {
373 : // XXXbz not much we can do here; just make sure that our promise of a
374 : // non-null mValue.mString holds for string units.
375 0 : mUnit = eCSSUnit_Null;
376 : }
377 : } else
378 0 : mUnit = eCSSUnit_Null;
379 0 : }
380 :
381 0 : void nsCSSValue::SetColorValue(nscolor aValue)
382 : {
383 0 : Reset();
384 0 : mUnit = eCSSUnit_Color;
385 0 : mValue.mColor = aValue;
386 0 : }
387 :
388 0 : void nsCSSValue::SetArrayValue(nsCSSValue::Array* aValue, nsCSSUnit aUnit)
389 : {
390 0 : Reset();
391 0 : mUnit = aUnit;
392 0 : NS_ABORT_IF_FALSE(UnitHasArrayValue(), "bad unit");
393 0 : mValue.mArray = aValue;
394 0 : mValue.mArray->AddRef();
395 0 : }
396 :
397 0 : void nsCSSValue::SetURLValue(nsCSSValue::URL* aValue)
398 : {
399 0 : Reset();
400 0 : mUnit = eCSSUnit_URL;
401 0 : mValue.mURL = aValue;
402 0 : mValue.mURL->AddRef();
403 0 : }
404 :
405 0 : void nsCSSValue::SetImageValue(nsCSSValue::Image* aValue)
406 : {
407 0 : Reset();
408 0 : mUnit = eCSSUnit_Image;
409 0 : mValue.mImage = aValue;
410 0 : mValue.mImage->AddRef();
411 0 : }
412 :
413 0 : void nsCSSValue::SetGradientValue(nsCSSValueGradient* aValue)
414 : {
415 0 : Reset();
416 0 : mUnit = eCSSUnit_Gradient;
417 0 : mValue.mGradient = aValue;
418 0 : mValue.mGradient->AddRef();
419 0 : }
420 :
421 0 : void nsCSSValue::SetPairValue(const nsCSSValuePair* aValue)
422 : {
423 : // pairs should not be used for null/inherit/initial values
424 0 : NS_ABORT_IF_FALSE(aValue &&
425 : aValue->mXValue.GetUnit() != eCSSUnit_Null &&
426 : aValue->mYValue.GetUnit() != eCSSUnit_Null &&
427 : aValue->mXValue.GetUnit() != eCSSUnit_Inherit &&
428 : aValue->mYValue.GetUnit() != eCSSUnit_Inherit &&
429 : aValue->mXValue.GetUnit() != eCSSUnit_Initial &&
430 : aValue->mYValue.GetUnit() != eCSSUnit_Initial,
431 : "missing or inappropriate pair value");
432 0 : Reset();
433 0 : mUnit = eCSSUnit_Pair;
434 0 : mValue.mPair = new nsCSSValuePair_heap(aValue->mXValue, aValue->mYValue);
435 0 : mValue.mPair->AddRef();
436 0 : }
437 :
438 0 : void nsCSSValue::SetPairValue(const nsCSSValue& xValue,
439 : const nsCSSValue& yValue)
440 : {
441 0 : NS_ABORT_IF_FALSE(xValue.GetUnit() != eCSSUnit_Null &&
442 : yValue.GetUnit() != eCSSUnit_Null &&
443 : xValue.GetUnit() != eCSSUnit_Inherit &&
444 : yValue.GetUnit() != eCSSUnit_Inherit &&
445 : xValue.GetUnit() != eCSSUnit_Initial &&
446 : yValue.GetUnit() != eCSSUnit_Initial,
447 : "inappropriate pair value");
448 0 : Reset();
449 0 : mUnit = eCSSUnit_Pair;
450 0 : mValue.mPair = new nsCSSValuePair_heap(xValue, yValue);
451 0 : mValue.mPair->AddRef();
452 0 : }
453 :
454 0 : void nsCSSValue::SetTripletValue(const nsCSSValueTriplet* aValue)
455 : {
456 : // triplet should not be used for null/inherit/initial values
457 : // Only allow Null for the z component
458 0 : NS_ABORT_IF_FALSE(aValue &&
459 : aValue->mXValue.GetUnit() != eCSSUnit_Null &&
460 : aValue->mYValue.GetUnit() != eCSSUnit_Null &&
461 : aValue->mXValue.GetUnit() != eCSSUnit_Inherit &&
462 : aValue->mYValue.GetUnit() != eCSSUnit_Inherit &&
463 : aValue->mZValue.GetUnit() != eCSSUnit_Inherit &&
464 : aValue->mXValue.GetUnit() != eCSSUnit_Initial &&
465 : aValue->mYValue.GetUnit() != eCSSUnit_Initial &&
466 : aValue->mZValue.GetUnit() != eCSSUnit_Initial,
467 : "missing or inappropriate triplet value");
468 0 : Reset();
469 0 : mUnit = eCSSUnit_Triplet;
470 0 : mValue.mTriplet = new nsCSSValueTriplet_heap(aValue->mXValue, aValue->mYValue, aValue->mZValue);
471 0 : mValue.mTriplet->AddRef();
472 0 : }
473 :
474 0 : void nsCSSValue::SetTripletValue(const nsCSSValue& xValue,
475 : const nsCSSValue& yValue,
476 : const nsCSSValue& zValue)
477 : {
478 : // Only allow Null for the z component
479 0 : NS_ABORT_IF_FALSE(xValue.GetUnit() != eCSSUnit_Null &&
480 : yValue.GetUnit() != eCSSUnit_Null &&
481 : xValue.GetUnit() != eCSSUnit_Inherit &&
482 : yValue.GetUnit() != eCSSUnit_Inherit &&
483 : zValue.GetUnit() != eCSSUnit_Inherit &&
484 : xValue.GetUnit() != eCSSUnit_Initial &&
485 : yValue.GetUnit() != eCSSUnit_Initial &&
486 : zValue.GetUnit() != eCSSUnit_Initial,
487 : "inappropriate triplet value");
488 0 : Reset();
489 0 : mUnit = eCSSUnit_Triplet;
490 0 : mValue.mTriplet = new nsCSSValueTriplet_heap(xValue, yValue, zValue);
491 0 : mValue.mTriplet->AddRef();
492 0 : }
493 :
494 0 : nsCSSRect& nsCSSValue::SetRectValue()
495 : {
496 0 : Reset();
497 0 : mUnit = eCSSUnit_Rect;
498 0 : mValue.mRect = new nsCSSRect_heap;
499 0 : mValue.mRect->AddRef();
500 0 : return *mValue.mRect;
501 : }
502 :
503 0 : nsCSSValueList* nsCSSValue::SetListValue()
504 : {
505 0 : Reset();
506 0 : mUnit = eCSSUnit_List;
507 0 : mValue.mList = new nsCSSValueList_heap;
508 0 : mValue.mList->AddRef();
509 0 : return mValue.mList;
510 : }
511 :
512 0 : void nsCSSValue::SetDependentListValue(nsCSSValueList* aList)
513 : {
514 0 : Reset();
515 0 : if (aList) {
516 0 : mUnit = eCSSUnit_ListDep;
517 0 : mValue.mListDependent = aList;
518 : }
519 0 : }
520 :
521 0 : nsCSSValuePairList* nsCSSValue::SetPairListValue()
522 : {
523 0 : Reset();
524 0 : mUnit = eCSSUnit_PairList;
525 0 : mValue.mPairList = new nsCSSValuePairList_heap;
526 0 : mValue.mPairList->AddRef();
527 0 : return mValue.mPairList;
528 : }
529 :
530 0 : void nsCSSValue::SetDependentPairListValue(nsCSSValuePairList* aList)
531 : {
532 0 : Reset();
533 0 : if (aList) {
534 0 : mUnit = eCSSUnit_PairListDep;
535 0 : mValue.mPairListDependent = aList;
536 : }
537 0 : }
538 :
539 0 : void nsCSSValue::SetAutoValue()
540 : {
541 0 : Reset();
542 0 : mUnit = eCSSUnit_Auto;
543 0 : }
544 :
545 0 : void nsCSSValue::SetInheritValue()
546 : {
547 0 : Reset();
548 0 : mUnit = eCSSUnit_Inherit;
549 0 : }
550 :
551 0 : void nsCSSValue::SetInitialValue()
552 : {
553 0 : Reset();
554 0 : mUnit = eCSSUnit_Initial;
555 0 : }
556 :
557 0 : void nsCSSValue::SetNoneValue()
558 : {
559 0 : Reset();
560 0 : mUnit = eCSSUnit_None;
561 0 : }
562 :
563 0 : void nsCSSValue::SetAllValue()
564 : {
565 0 : Reset();
566 0 : mUnit = eCSSUnit_All;
567 0 : }
568 :
569 0 : void nsCSSValue::SetNormalValue()
570 : {
571 0 : Reset();
572 0 : mUnit = eCSSUnit_Normal;
573 0 : }
574 :
575 0 : void nsCSSValue::SetSystemFontValue()
576 : {
577 0 : Reset();
578 0 : mUnit = eCSSUnit_System_Font;
579 0 : }
580 :
581 0 : void nsCSSValue::SetDummyValue()
582 : {
583 0 : Reset();
584 0 : mUnit = eCSSUnit_Dummy;
585 0 : }
586 :
587 0 : void nsCSSValue::SetDummyInheritValue()
588 : {
589 0 : Reset();
590 0 : mUnit = eCSSUnit_DummyInherit;
591 0 : }
592 :
593 0 : void nsCSSValue::StartImageLoad(nsIDocument* aDocument) const
594 : {
595 0 : NS_ABORT_IF_FALSE(eCSSUnit_URL == mUnit, "Not a URL value!");
596 : nsCSSValue::Image* image =
597 0 : new nsCSSValue::Image(mValue.mURL->GetURI(),
598 : mValue.mURL->mString,
599 : mValue.mURL->mReferrer,
600 : mValue.mURL->mOriginPrincipal,
601 0 : aDocument);
602 0 : if (image) {
603 0 : nsCSSValue* writable = const_cast<nsCSSValue*>(this);
604 0 : writable->SetImageValue(image);
605 : }
606 0 : }
607 :
608 0 : bool nsCSSValue::IsNonTransparentColor() const
609 : {
610 : // We have the value in the form it was specified in at this point, so we
611 : // have to look for both the keyword 'transparent' and its equivalent in
612 : // rgba notation.
613 0 : nsDependentString buf;
614 : return
615 0 : (mUnit == eCSSUnit_Color && NS_GET_A(GetColorValue()) > 0) ||
616 : (mUnit == eCSSUnit_Ident &&
617 0 : !nsGkAtoms::transparent->Equals(GetStringValue(buf))) ||
618 0 : (mUnit == eCSSUnit_EnumColor);
619 : }
620 :
621 : nsCSSValue::Array*
622 0 : nsCSSValue::InitFunction(nsCSSKeyword aFunctionId, PRUint32 aNumArgs)
623 : {
624 0 : nsRefPtr<nsCSSValue::Array> func = Array::Create(aNumArgs + 1);
625 0 : func->Item(0).SetIntValue(aFunctionId, eCSSUnit_Enumerated);
626 0 : SetArrayValue(func, eCSSUnit_Function);
627 0 : return func;
628 : }
629 :
630 : bool
631 0 : nsCSSValue::EqualsFunction(nsCSSKeyword aFunctionId) const
632 : {
633 0 : if (mUnit != eCSSUnit_Function) {
634 0 : return false;
635 : }
636 :
637 0 : nsCSSValue::Array* func = mValue.mArray;
638 0 : NS_ABORT_IF_FALSE(func && func->Count() >= 1 &&
639 : func->Item(0).GetUnit() == eCSSUnit_Enumerated,
640 : "illegally structured function value");
641 :
642 : nsCSSKeyword thisFunctionId =
643 0 : static_cast<nsCSSKeyword>(func->Item(0).GetIntValue());
644 0 : return thisFunctionId == aFunctionId;
645 : }
646 :
647 : // static
648 : already_AddRefed<nsStringBuffer>
649 0 : nsCSSValue::BufferFromString(const nsString& aValue)
650 : {
651 0 : nsStringBuffer* buffer = nsStringBuffer::FromString(aValue);
652 0 : if (buffer) {
653 0 : buffer->AddRef();
654 0 : return buffer;
655 : }
656 :
657 0 : PRUnichar length = aValue.Length();
658 :
659 : // NOTE: Alloc prouduces a new, already-addref'd (refcnt = 1) buffer.
660 : // NOTE: String buffer allocation is currently fallible.
661 0 : buffer = nsStringBuffer::Alloc((length + 1) * sizeof(PRUnichar));
662 0 : if (NS_UNLIKELY(!buffer)) {
663 0 : NS_RUNTIMEABORT("out of memory");
664 : }
665 :
666 0 : PRUnichar* data = static_cast<PRUnichar*>(buffer->Data());
667 0 : nsCharTraits<PRUnichar>::copy(data, aValue.get(), length);
668 : // Null-terminate.
669 0 : data[length] = 0;
670 0 : return buffer;
671 : }
672 :
673 : namespace {
674 :
675 : struct CSSValueSerializeCalcOps {
676 0 : CSSValueSerializeCalcOps(nsCSSProperty aProperty, nsAString& aResult)
677 : : mProperty(aProperty),
678 0 : mResult(aResult)
679 : {
680 0 : }
681 :
682 : typedef nsCSSValue input_type;
683 : typedef nsCSSValue::Array input_array_type;
684 :
685 0 : static nsCSSUnit GetUnit(const input_type& aValue) {
686 0 : return aValue.GetUnit();
687 : }
688 :
689 0 : void Append(const char* aString)
690 : {
691 0 : mResult.AppendASCII(aString);
692 0 : }
693 :
694 0 : void AppendLeafValue(const input_type& aValue)
695 : {
696 0 : NS_ABORT_IF_FALSE(aValue.GetUnit() == eCSSUnit_Percent ||
697 : aValue.IsLengthUnit(), "unexpected unit");
698 0 : aValue.AppendToString(mProperty, mResult);
699 0 : }
700 :
701 0 : void AppendNumber(const input_type& aValue)
702 : {
703 0 : NS_ABORT_IF_FALSE(aValue.GetUnit() == eCSSUnit_Number, "unexpected unit");
704 0 : aValue.AppendToString(mProperty, mResult);
705 0 : }
706 :
707 : private:
708 : nsCSSProperty mProperty;
709 : nsAString &mResult;
710 : };
711 :
712 : } // anonymous namespace
713 :
714 : void
715 0 : nsCSSValue::AppendToString(nsCSSProperty aProperty, nsAString& aResult) const
716 : {
717 : // eCSSProperty_UNKNOWN gets used for some recursive calls below.
718 0 : NS_ABORT_IF_FALSE((0 <= aProperty &&
719 : aProperty <= eCSSProperty_COUNT_no_shorthands) ||
720 : aProperty == eCSSProperty_UNKNOWN,
721 : "property ID out of range");
722 :
723 0 : nsCSSUnit unit = GetUnit();
724 0 : if (unit == eCSSUnit_Null) {
725 0 : return;
726 : }
727 :
728 0 : if (eCSSUnit_String <= unit && unit <= eCSSUnit_Attr) {
729 0 : if (unit == eCSSUnit_Attr) {
730 0 : aResult.AppendLiteral("attr(");
731 : }
732 0 : nsAutoString buffer;
733 0 : GetStringValue(buffer);
734 0 : if (unit == eCSSUnit_String) {
735 0 : nsStyleUtil::AppendEscapedCSSString(buffer, aResult);
736 0 : } else if (unit == eCSSUnit_Families) {
737 : // XXX We really need to do *some* escaping.
738 0 : aResult.Append(buffer);
739 : } else {
740 0 : nsStyleUtil::AppendEscapedCSSIdent(buffer, aResult);
741 0 : }
742 : }
743 0 : else if (eCSSUnit_Array <= unit && unit <= eCSSUnit_Steps) {
744 0 : switch (unit) {
745 0 : case eCSSUnit_Counter: aResult.AppendLiteral("counter("); break;
746 0 : case eCSSUnit_Counters: aResult.AppendLiteral("counters("); break;
747 0 : case eCSSUnit_Cubic_Bezier: aResult.AppendLiteral("cubic-bezier("); break;
748 0 : case eCSSUnit_Steps: aResult.AppendLiteral("steps("); break;
749 0 : default: break;
750 : }
751 :
752 0 : nsCSSValue::Array *array = GetArrayValue();
753 0 : bool mark = false;
754 0 : for (size_t i = 0, i_end = array->Count(); i < i_end; ++i) {
755 0 : if (aProperty == eCSSProperty_border_image && i >= 5) {
756 0 : if (array->Item(i).GetUnit() == eCSSUnit_Null) {
757 0 : continue;
758 : }
759 0 : if (i == 5) {
760 0 : aResult.AppendLiteral(" /");
761 : }
762 : }
763 0 : if (mark && array->Item(i).GetUnit() != eCSSUnit_Null) {
764 0 : if (unit == eCSSUnit_Array &&
765 : eCSSProperty_transition_timing_function != aProperty)
766 0 : aResult.AppendLiteral(" ");
767 : else
768 0 : aResult.AppendLiteral(", ");
769 : }
770 0 : if (unit == eCSSUnit_Steps && i == 1) {
771 0 : NS_ABORT_IF_FALSE(array->Item(i).GetUnit() == eCSSUnit_Enumerated &&
772 : (array->Item(i).GetIntValue() ==
773 : NS_STYLE_TRANSITION_TIMING_FUNCTION_STEP_START ||
774 : array->Item(i).GetIntValue() ==
775 : NS_STYLE_TRANSITION_TIMING_FUNCTION_STEP_END),
776 : "unexpected value");
777 0 : if (array->Item(i).GetIntValue() ==
778 : NS_STYLE_TRANSITION_TIMING_FUNCTION_STEP_START) {
779 0 : aResult.AppendLiteral("start");
780 : } else {
781 0 : aResult.AppendLiteral("end");
782 : }
783 0 : continue;
784 : }
785 : nsCSSProperty prop =
786 : ((eCSSUnit_Counter <= unit && unit <= eCSSUnit_Counters) &&
787 0 : i == array->Count() - 1)
788 0 : ? eCSSProperty_list_style_type : aProperty;
789 0 : if (array->Item(i).GetUnit() != eCSSUnit_Null) {
790 0 : array->Item(i).AppendToString(prop, aResult);
791 0 : mark = true;
792 : }
793 : }
794 0 : if (eCSSUnit_Array == unit &&
795 : aProperty == eCSSProperty_transition_timing_function) {
796 0 : aResult.AppendLiteral(")");
797 0 : }
798 : }
799 : /* Although Function is backed by an Array, we'll handle it separately
800 : * because it's a bit quirky.
801 : */
802 0 : else if (eCSSUnit_Function == unit) {
803 0 : const nsCSSValue::Array* array = GetArrayValue();
804 0 : NS_ABORT_IF_FALSE(array->Count() >= 1,
805 : "Functions must have at least one element for the name.");
806 :
807 : /* Append the function name. */
808 0 : const nsCSSValue& functionName = array->Item(0);
809 0 : if (functionName.GetUnit() == eCSSUnit_Enumerated) {
810 : // We assume that the first argument is always of nsCSSKeyword type.
811 : const nsCSSKeyword functionId =
812 0 : static_cast<nsCSSKeyword>(functionName.GetIntValue());
813 : nsStyleUtil::AppendEscapedCSSIdent(
814 0 : NS_ConvertASCIItoUTF16(nsCSSKeywords::GetStringValue(functionId)),
815 0 : aResult);
816 : } else {
817 0 : functionName.AppendToString(aProperty, aResult);
818 : }
819 0 : aResult.AppendLiteral("(");
820 :
821 : /* Now, step through the function contents, writing each of them as we go. */
822 0 : for (size_t index = 1; index < array->Count(); ++index) {
823 0 : array->Item(index).AppendToString(aProperty, aResult);
824 :
825 : /* If we're not at the final element, append a comma. */
826 0 : if (index + 1 != array->Count())
827 0 : aResult.AppendLiteral(", ");
828 : }
829 :
830 : /* Finally, append the closing parenthesis. */
831 0 : aResult.AppendLiteral(")");
832 : }
833 0 : else if (IsCalcUnit()) {
834 0 : NS_ABORT_IF_FALSE(GetUnit() == eCSSUnit_Calc, "unexpected unit");
835 0 : CSSValueSerializeCalcOps ops(aProperty, aResult);
836 0 : css::SerializeCalc(*this, ops);
837 : }
838 0 : else if (eCSSUnit_Integer == unit) {
839 0 : aResult.AppendInt(GetIntValue(), 10);
840 : }
841 0 : else if (eCSSUnit_Enumerated == unit) {
842 0 : if (eCSSProperty_text_decoration_line == aProperty) {
843 0 : PRInt32 intValue = GetIntValue();
844 0 : if (NS_STYLE_TEXT_DECORATION_LINE_NONE == intValue) {
845 0 : AppendASCIItoUTF16(nsCSSProps::LookupPropertyValue(aProperty, intValue),
846 0 : aResult);
847 : } else {
848 : // Ignore the "override all" internal value.
849 : // (It doesn't have a string representation.)
850 0 : intValue &= ~NS_STYLE_TEXT_DECORATION_LINE_OVERRIDE_ALL;
851 : nsStyleUtil::AppendBitmaskCSSValue(
852 : aProperty, intValue,
853 : NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE,
854 : NS_STYLE_TEXT_DECORATION_LINE_PREF_ANCHORS,
855 0 : aResult);
856 : }
857 : }
858 0 : else if (eCSSProperty_marks == aProperty) {
859 0 : PRInt32 intValue = GetIntValue();
860 0 : if (intValue == NS_STYLE_PAGE_MARKS_NONE) {
861 0 : AppendASCIItoUTF16(nsCSSProps::LookupPropertyValue(aProperty, intValue),
862 0 : aResult);
863 : } else {
864 : nsStyleUtil::AppendBitmaskCSSValue(aProperty, intValue,
865 : NS_STYLE_PAGE_MARKS_CROP,
866 : NS_STYLE_PAGE_MARKS_REGISTER,
867 0 : aResult);
868 : }
869 : }
870 0 : else if (eCSSProperty_unicode_bidi == aProperty) {
871 : MOZ_STATIC_ASSERT(NS_STYLE_UNICODE_BIDI_NORMAL == 0,
872 : "unicode-bidi style constants not as expected");
873 0 : PRInt32 intValue = GetIntValue();
874 0 : if (NS_STYLE_UNICODE_BIDI_NORMAL == intValue) {
875 0 : AppendASCIItoUTF16(nsCSSProps::LookupPropertyValue(aProperty, intValue),
876 0 : aResult);
877 : } else {
878 : nsStyleUtil::AppendBitmaskCSSValue(
879 : aProperty, intValue,
880 : NS_STYLE_UNICODE_BIDI_EMBED,
881 : NS_STYLE_UNICODE_BIDI_PLAINTEXT,
882 0 : aResult);
883 : }
884 : }
885 : else {
886 0 : const nsAFlatCString& name = nsCSSProps::LookupPropertyValue(aProperty, GetIntValue());
887 0 : AppendASCIItoUTF16(name, aResult);
888 : }
889 : }
890 0 : else if (eCSSUnit_EnumColor == unit) {
891 : // we can lookup the property in the ColorTable and then
892 : // get a string mapping the name
893 0 : nsCAutoString str;
894 0 : if (nsCSSProps::GetColorName(GetIntValue(), str)){
895 0 : AppendASCIItoUTF16(str, aResult);
896 : } else {
897 0 : NS_ABORT_IF_FALSE(false, "bad color value");
898 : }
899 : }
900 0 : else if (eCSSUnit_Color == unit) {
901 0 : nscolor color = GetColorValue();
902 0 : if (color == NS_RGBA(0, 0, 0, 0)) {
903 : // Use the strictest match for 'transparent' so we do correct
904 : // round-tripping of all other rgba() values.
905 0 : aResult.AppendLiteral("transparent");
906 : } else {
907 0 : PRUint8 a = NS_GET_A(color);
908 0 : if (a < 255) {
909 0 : aResult.AppendLiteral("rgba(");
910 : } else {
911 0 : aResult.AppendLiteral("rgb(");
912 : }
913 :
914 0 : NS_NAMED_LITERAL_STRING(comma, ", ");
915 :
916 0 : aResult.AppendInt(NS_GET_R(color), 10);
917 0 : aResult.Append(comma);
918 0 : aResult.AppendInt(NS_GET_G(color), 10);
919 0 : aResult.Append(comma);
920 0 : aResult.AppendInt(NS_GET_B(color), 10);
921 0 : if (a < 255) {
922 0 : aResult.Append(comma);
923 0 : aResult.AppendFloat(nsStyleUtil::ColorComponentToFloat(a));
924 : }
925 0 : aResult.Append(PRUnichar(')'));
926 : }
927 : }
928 0 : else if (eCSSUnit_URL == unit || eCSSUnit_Image == unit) {
929 0 : aResult.Append(NS_LITERAL_STRING("url("));
930 : nsStyleUtil::AppendEscapedCSSString(
931 0 : nsDependentString(GetOriginalURLValue()), aResult);
932 0 : aResult.Append(NS_LITERAL_STRING(")"));
933 : }
934 0 : else if (eCSSUnit_Element == unit) {
935 0 : aResult.Append(NS_LITERAL_STRING("-moz-element(#"));
936 0 : nsAutoString tmpStr;
937 0 : GetStringValue(tmpStr);
938 0 : nsStyleUtil::AppendEscapedCSSIdent(tmpStr, aResult);
939 0 : aResult.Append(NS_LITERAL_STRING(")"));
940 : }
941 0 : else if (eCSSUnit_Percent == unit) {
942 0 : aResult.AppendFloat(GetPercentValue() * 100.0f);
943 : }
944 0 : else if (eCSSUnit_Percent < unit) { // length unit
945 0 : aResult.AppendFloat(GetFloatValue());
946 : }
947 0 : else if (eCSSUnit_Gradient == unit) {
948 0 : nsCSSValueGradient* gradient = GetGradientValue();
949 :
950 0 : if (gradient->mIsRepeating) {
951 0 : if (gradient->mIsRadial)
952 0 : aResult.AppendLiteral("-moz-repeating-radial-gradient(");
953 : else
954 0 : aResult.AppendLiteral("-moz-repeating-linear-gradient(");
955 : } else {
956 0 : if (gradient->mIsRadial)
957 0 : aResult.AppendLiteral("-moz-radial-gradient(");
958 : else
959 0 : aResult.AppendLiteral("-moz-linear-gradient(");
960 : }
961 :
962 0 : if (gradient->mIsToCorner) {
963 0 : aResult.AppendLiteral("to");
964 0 : NS_ABORT_IF_FALSE(gradient->mBgPos.mXValue.GetUnit() == eCSSUnit_Enumerated &&
965 : gradient->mBgPos.mYValue.GetUnit() == eCSSUnit_Enumerated,
966 : "unexpected unit");
967 0 : if (!(gradient->mBgPos.mXValue.GetIntValue() & NS_STYLE_BG_POSITION_CENTER)) {
968 0 : aResult.AppendLiteral(" ");
969 : gradient->mBgPos.mXValue.AppendToString(eCSSProperty_background_position,
970 0 : aResult);
971 : }
972 0 : if (!(gradient->mBgPos.mYValue.GetIntValue() & NS_STYLE_BG_POSITION_CENTER)) {
973 0 : aResult.AppendLiteral(" ");
974 : gradient->mBgPos.mYValue.AppendToString(eCSSProperty_background_position,
975 0 : aResult);
976 : }
977 0 : aResult.AppendLiteral(", ");
978 0 : } else if (gradient->mBgPos.mXValue.GetUnit() != eCSSUnit_None ||
979 0 : gradient->mBgPos.mYValue.GetUnit() != eCSSUnit_None ||
980 0 : gradient->mAngle.GetUnit() != eCSSUnit_None) {
981 0 : if (gradient->mBgPos.mXValue.GetUnit() != eCSSUnit_None) {
982 : gradient->mBgPos.mXValue.AppendToString(eCSSProperty_background_position,
983 0 : aResult);
984 0 : aResult.AppendLiteral(" ");
985 : }
986 0 : if (gradient->mBgPos.mXValue.GetUnit() != eCSSUnit_None) {
987 : gradient->mBgPos.mYValue.AppendToString(eCSSProperty_background_position,
988 0 : aResult);
989 0 : aResult.AppendLiteral(" ");
990 : }
991 0 : if (gradient->mAngle.GetUnit() != eCSSUnit_None) {
992 0 : gradient->mAngle.AppendToString(aProperty, aResult);
993 : }
994 0 : aResult.AppendLiteral(", ");
995 : }
996 :
997 0 : if (gradient->mIsRadial &&
998 0 : (gradient->mRadialShape.GetUnit() != eCSSUnit_None ||
999 0 : gradient->mRadialSize.GetUnit() != eCSSUnit_None)) {
1000 0 : if (gradient->mRadialShape.GetUnit() != eCSSUnit_None) {
1001 0 : NS_ABORT_IF_FALSE(gradient->mRadialShape.GetUnit() ==
1002 : eCSSUnit_Enumerated,
1003 : "bad unit for radial gradient shape");
1004 0 : PRInt32 intValue = gradient->mRadialShape.GetIntValue();
1005 0 : NS_ABORT_IF_FALSE(intValue != NS_STYLE_GRADIENT_SHAPE_LINEAR,
1006 : "radial gradient with linear shape?!");
1007 : AppendASCIItoUTF16(nsCSSProps::ValueToKeyword(intValue,
1008 0 : nsCSSProps::kRadialGradientShapeKTable),
1009 0 : aResult);
1010 0 : aResult.AppendLiteral(" ");
1011 : }
1012 :
1013 0 : if (gradient->mRadialSize.GetUnit() != eCSSUnit_None) {
1014 0 : NS_ABORT_IF_FALSE(gradient->mRadialSize.GetUnit() ==
1015 : eCSSUnit_Enumerated,
1016 : "bad unit for radial gradient size");
1017 0 : PRInt32 intValue = gradient->mRadialSize.GetIntValue();
1018 : AppendASCIItoUTF16(nsCSSProps::ValueToKeyword(intValue,
1019 0 : nsCSSProps::kRadialGradientSizeKTable),
1020 0 : aResult);
1021 : }
1022 0 : aResult.AppendLiteral(", ");
1023 : }
1024 :
1025 0 : for (PRUint32 i = 0 ;;) {
1026 0 : gradient->mStops[i].mColor.AppendToString(aProperty, aResult);
1027 0 : if (gradient->mStops[i].mLocation.GetUnit() != eCSSUnit_None) {
1028 0 : aResult.AppendLiteral(" ");
1029 0 : gradient->mStops[i].mLocation.AppendToString(aProperty, aResult);
1030 : }
1031 0 : if (++i == gradient->mStops.Length()) {
1032 : break;
1033 : }
1034 0 : aResult.AppendLiteral(", ");
1035 : }
1036 :
1037 0 : aResult.AppendLiteral(")");
1038 0 : } else if (eCSSUnit_Pair == unit) {
1039 0 : GetPairValue().AppendToString(aProperty, aResult);
1040 0 : } else if (eCSSUnit_Triplet == unit) {
1041 0 : GetTripletValue().AppendToString(aProperty, aResult);
1042 0 : } else if (eCSSUnit_Rect == unit) {
1043 0 : GetRectValue().AppendToString(aProperty, aResult);
1044 0 : } else if (eCSSUnit_List == unit || eCSSUnit_ListDep == unit) {
1045 0 : GetListValue()->AppendToString(aProperty, aResult);
1046 0 : } else if (eCSSUnit_PairList == unit || eCSSUnit_PairListDep == unit) {
1047 0 : GetPairListValue()->AppendToString(aProperty, aResult);
1048 : }
1049 :
1050 0 : switch (unit) {
1051 0 : case eCSSUnit_Null: break;
1052 0 : case eCSSUnit_Auto: aResult.AppendLiteral("auto"); break;
1053 0 : case eCSSUnit_Inherit: aResult.AppendLiteral("inherit"); break;
1054 0 : case eCSSUnit_Initial: aResult.AppendLiteral("-moz-initial"); break;
1055 0 : case eCSSUnit_None: aResult.AppendLiteral("none"); break;
1056 0 : case eCSSUnit_Normal: aResult.AppendLiteral("normal"); break;
1057 0 : case eCSSUnit_System_Font: aResult.AppendLiteral("-moz-use-system-font"); break;
1058 0 : case eCSSUnit_All: aResult.AppendLiteral("all"); break;
1059 : case eCSSUnit_Dummy:
1060 : case eCSSUnit_DummyInherit:
1061 0 : NS_ABORT_IF_FALSE(false, "should never serialize");
1062 0 : break;
1063 :
1064 0 : case eCSSUnit_String: break;
1065 0 : case eCSSUnit_Ident: break;
1066 0 : case eCSSUnit_Families: break;
1067 0 : case eCSSUnit_URL: break;
1068 0 : case eCSSUnit_Image: break;
1069 0 : case eCSSUnit_Element: break;
1070 0 : case eCSSUnit_Array: break;
1071 : case eCSSUnit_Attr:
1072 : case eCSSUnit_Cubic_Bezier:
1073 : case eCSSUnit_Steps:
1074 : case eCSSUnit_Counter:
1075 0 : case eCSSUnit_Counters: aResult.Append(PRUnichar(')')); break;
1076 0 : case eCSSUnit_Local_Font: break;
1077 0 : case eCSSUnit_Font_Format: break;
1078 0 : case eCSSUnit_Function: break;
1079 0 : case eCSSUnit_Calc: break;
1080 0 : case eCSSUnit_Calc_Plus: break;
1081 0 : case eCSSUnit_Calc_Minus: break;
1082 0 : case eCSSUnit_Calc_Times_L: break;
1083 0 : case eCSSUnit_Calc_Times_R: break;
1084 0 : case eCSSUnit_Calc_Divided: break;
1085 0 : case eCSSUnit_Integer: break;
1086 0 : case eCSSUnit_Enumerated: break;
1087 0 : case eCSSUnit_EnumColor: break;
1088 0 : case eCSSUnit_Color: break;
1089 0 : case eCSSUnit_Percent: aResult.Append(PRUnichar('%')); break;
1090 0 : case eCSSUnit_Number: break;
1091 0 : case eCSSUnit_Gradient: break;
1092 0 : case eCSSUnit_Pair: break;
1093 0 : case eCSSUnit_Triplet: break;
1094 0 : case eCSSUnit_Rect: break;
1095 0 : case eCSSUnit_List: break;
1096 0 : case eCSSUnit_ListDep: break;
1097 0 : case eCSSUnit_PairList: break;
1098 0 : case eCSSUnit_PairListDep: break;
1099 :
1100 0 : case eCSSUnit_Inch: aResult.AppendLiteral("in"); break;
1101 0 : case eCSSUnit_Millimeter: aResult.AppendLiteral("mm"); break;
1102 0 : case eCSSUnit_PhysicalMillimeter: aResult.AppendLiteral("mozmm"); break;
1103 0 : case eCSSUnit_Centimeter: aResult.AppendLiteral("cm"); break;
1104 0 : case eCSSUnit_Point: aResult.AppendLiteral("pt"); break;
1105 0 : case eCSSUnit_Pica: aResult.AppendLiteral("pc"); break;
1106 :
1107 0 : case eCSSUnit_EM: aResult.AppendLiteral("em"); break;
1108 0 : case eCSSUnit_XHeight: aResult.AppendLiteral("ex"); break;
1109 0 : case eCSSUnit_Char: aResult.AppendLiteral("ch"); break;
1110 0 : case eCSSUnit_RootEM: aResult.AppendLiteral("rem"); break;
1111 :
1112 0 : case eCSSUnit_Pixel: aResult.AppendLiteral("px"); break;
1113 :
1114 0 : case eCSSUnit_Degree: aResult.AppendLiteral("deg"); break;
1115 0 : case eCSSUnit_Grad: aResult.AppendLiteral("grad"); break;
1116 0 : case eCSSUnit_Radian: aResult.AppendLiteral("rad"); break;
1117 0 : case eCSSUnit_Turn: aResult.AppendLiteral("turn"); break;
1118 :
1119 0 : case eCSSUnit_Hertz: aResult.AppendLiteral("Hz"); break;
1120 0 : case eCSSUnit_Kilohertz: aResult.AppendLiteral("kHz"); break;
1121 :
1122 0 : case eCSSUnit_Seconds: aResult.Append(PRUnichar('s')); break;
1123 0 : case eCSSUnit_Milliseconds: aResult.AppendLiteral("ms"); break;
1124 : }
1125 : }
1126 :
1127 : size_t
1128 0 : nsCSSValue::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const
1129 : {
1130 0 : size_t n = 0;
1131 :
1132 0 : switch (GetUnit()) {
1133 : // No value: nothing extra to measure.
1134 : case eCSSUnit_Null:
1135 : case eCSSUnit_Auto:
1136 : case eCSSUnit_Inherit:
1137 : case eCSSUnit_Initial:
1138 : case eCSSUnit_None:
1139 : case eCSSUnit_Normal:
1140 : case eCSSUnit_System_Font:
1141 : case eCSSUnit_All:
1142 : case eCSSUnit_Dummy:
1143 : case eCSSUnit_DummyInherit:
1144 0 : break;
1145 :
1146 : // String
1147 : case eCSSUnit_String:
1148 : case eCSSUnit_Ident:
1149 : case eCSSUnit_Families:
1150 : case eCSSUnit_Attr:
1151 : case eCSSUnit_Local_Font:
1152 : case eCSSUnit_Font_Format:
1153 : case eCSSUnit_Element:
1154 0 : n += mValue.mString->SizeOfIncludingThisIfUnshared(aMallocSizeOf);
1155 0 : break;
1156 :
1157 : // Array
1158 : case eCSSUnit_Array:
1159 : case eCSSUnit_Counter:
1160 : case eCSSUnit_Counters:
1161 : case eCSSUnit_Cubic_Bezier:
1162 : case eCSSUnit_Steps:
1163 : case eCSSUnit_Function:
1164 : case eCSSUnit_Calc:
1165 : case eCSSUnit_Calc_Plus:
1166 : case eCSSUnit_Calc_Minus:
1167 : case eCSSUnit_Calc_Times_L:
1168 : case eCSSUnit_Calc_Times_R:
1169 : case eCSSUnit_Calc_Divided:
1170 0 : break;
1171 :
1172 : // URL
1173 : case eCSSUnit_URL:
1174 0 : n += mValue.mURL->SizeOfIncludingThis(aMallocSizeOf);
1175 0 : break;
1176 :
1177 : // Image
1178 : case eCSSUnit_Image:
1179 : // Not yet measured. Measurement may be added later if DMD finds it
1180 : // worthwhile.
1181 0 : break;
1182 :
1183 : // Gradient
1184 : case eCSSUnit_Gradient:
1185 0 : n += mValue.mGradient->SizeOfIncludingThis(aMallocSizeOf);
1186 0 : break;
1187 :
1188 : // Pair
1189 : case eCSSUnit_Pair:
1190 0 : n += mValue.mPair->SizeOfIncludingThis(aMallocSizeOf);
1191 0 : break;
1192 :
1193 : // Triplet
1194 : case eCSSUnit_Triplet:
1195 0 : n += mValue.mTriplet->SizeOfIncludingThis(aMallocSizeOf);
1196 0 : break;
1197 :
1198 : // Rect
1199 : case eCSSUnit_Rect:
1200 0 : n += mValue.mRect->SizeOfIncludingThis(aMallocSizeOf);
1201 0 : break;
1202 :
1203 : // List
1204 : case eCSSUnit_List:
1205 0 : n += mValue.mList->SizeOfIncludingThis(aMallocSizeOf);
1206 0 : break;
1207 :
1208 : // ListDep: not measured because it's non-owning.
1209 : case eCSSUnit_ListDep:
1210 0 : break;
1211 :
1212 : // PairList
1213 : case eCSSUnit_PairList:
1214 0 : n += mValue.mPairList->SizeOfIncludingThis(aMallocSizeOf);
1215 0 : break;
1216 :
1217 : // PairListDep: not measured because it's non-owning.
1218 : case eCSSUnit_PairListDep:
1219 0 : break;
1220 :
1221 : // Int: nothing extra to measure.
1222 : case eCSSUnit_Integer:
1223 : case eCSSUnit_Enumerated:
1224 : case eCSSUnit_EnumColor:
1225 0 : break;
1226 :
1227 : // Color: nothing extra to measure.
1228 : case eCSSUnit_Color:
1229 0 : break;
1230 :
1231 : // Float: nothing extra to measure.
1232 : case eCSSUnit_Percent:
1233 : case eCSSUnit_Number:
1234 : case eCSSUnit_PhysicalMillimeter:
1235 : case eCSSUnit_EM:
1236 : case eCSSUnit_XHeight:
1237 : case eCSSUnit_Char:
1238 : case eCSSUnit_RootEM:
1239 : case eCSSUnit_Point:
1240 : case eCSSUnit_Inch:
1241 : case eCSSUnit_Millimeter:
1242 : case eCSSUnit_Centimeter:
1243 : case eCSSUnit_Pica:
1244 : case eCSSUnit_Pixel:
1245 : case eCSSUnit_Degree:
1246 : case eCSSUnit_Grad:
1247 : case eCSSUnit_Turn:
1248 : case eCSSUnit_Radian:
1249 : case eCSSUnit_Hertz:
1250 : case eCSSUnit_Kilohertz:
1251 : case eCSSUnit_Seconds:
1252 : case eCSSUnit_Milliseconds:
1253 0 : break;
1254 :
1255 : default:
1256 0 : NS_ABORT_IF_FALSE(false, "bad nsCSSUnit");
1257 0 : break;
1258 : }
1259 :
1260 0 : return n;
1261 : }
1262 :
1263 : // --- nsCSSValueList -----------------
1264 :
1265 0 : nsCSSValueList::~nsCSSValueList()
1266 : {
1267 0 : MOZ_COUNT_DTOR(nsCSSValueList);
1268 0 : NS_CSS_DELETE_LIST_MEMBER(nsCSSValueList, this, mNext);
1269 0 : }
1270 :
1271 : nsCSSValueList*
1272 0 : nsCSSValueList::Clone() const
1273 : {
1274 0 : nsCSSValueList* result = new nsCSSValueList(*this);
1275 0 : nsCSSValueList* dest = result;
1276 0 : const nsCSSValueList* src = this->mNext;
1277 0 : while (src) {
1278 0 : dest->mNext = new nsCSSValueList(*src);
1279 0 : dest = dest->mNext;
1280 0 : src = src->mNext;
1281 : }
1282 0 : return result;
1283 : }
1284 :
1285 : void
1286 0 : nsCSSValueList::CloneInto(nsCSSValueList* aList) const
1287 : {
1288 0 : NS_ASSERTION(!aList->mNext, "Must be an empty list!");
1289 0 : aList->mValue = mValue;
1290 0 : aList->mNext = mNext ? mNext->Clone() : nsnull;
1291 0 : }
1292 :
1293 : void
1294 0 : nsCSSValueList::AppendToString(nsCSSProperty aProperty, nsAString& aResult) const
1295 : {
1296 0 : const nsCSSValueList* val = this;
1297 0 : for (;;) {
1298 0 : val->mValue.AppendToString(aProperty, aResult);
1299 0 : val = val->mNext;
1300 0 : if (!val)
1301 : break;
1302 :
1303 0 : if (nsCSSProps::PropHasFlags(aProperty,
1304 : CSS_PROPERTY_VALUE_LIST_USES_COMMAS))
1305 0 : aResult.Append(PRUnichar(','));
1306 0 : aResult.Append(PRUnichar(' '));
1307 : }
1308 0 : }
1309 :
1310 : bool
1311 0 : nsCSSValueList::operator==(const nsCSSValueList& aOther) const
1312 : {
1313 0 : if (this == &aOther)
1314 0 : return true;
1315 :
1316 0 : const nsCSSValueList *p1 = this, *p2 = &aOther;
1317 0 : for ( ; p1 && p2; p1 = p1->mNext, p2 = p2->mNext) {
1318 0 : if (p1->mValue != p2->mValue)
1319 0 : return false;
1320 : }
1321 0 : return !p1 && !p2; // true if same length, false otherwise
1322 : }
1323 :
1324 : size_t
1325 0 : nsCSSValueList::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const
1326 : {
1327 0 : size_t n = 0;
1328 0 : const nsCSSValueList* v = this;
1329 0 : while (v) {
1330 0 : n += aMallocSizeOf(v);
1331 0 : n += v->mValue.SizeOfExcludingThis(aMallocSizeOf);
1332 0 : v = v->mNext;
1333 : }
1334 0 : return n;
1335 : }
1336 :
1337 : size_t
1338 0 : nsCSSValueList_heap::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const
1339 : {
1340 0 : size_t n = aMallocSizeOf(this);
1341 0 : n += mValue.SizeOfExcludingThis(aMallocSizeOf);
1342 0 : n += mNext ? mNext->SizeOfIncludingThis(aMallocSizeOf) : 0;
1343 0 : return n;
1344 : }
1345 :
1346 : // --- nsCSSRect -----------------
1347 :
1348 0 : nsCSSRect::nsCSSRect(void)
1349 : {
1350 0 : MOZ_COUNT_CTOR(nsCSSRect);
1351 0 : }
1352 :
1353 0 : nsCSSRect::nsCSSRect(const nsCSSRect& aCopy)
1354 : : mTop(aCopy.mTop),
1355 : mRight(aCopy.mRight),
1356 : mBottom(aCopy.mBottom),
1357 0 : mLeft(aCopy.mLeft)
1358 : {
1359 0 : MOZ_COUNT_CTOR(nsCSSRect);
1360 0 : }
1361 :
1362 0 : nsCSSRect::~nsCSSRect()
1363 : {
1364 0 : MOZ_COUNT_DTOR(nsCSSRect);
1365 0 : }
1366 :
1367 : void
1368 0 : nsCSSRect::AppendToString(nsCSSProperty aProperty, nsAString& aResult) const
1369 : {
1370 0 : NS_ABORT_IF_FALSE(mTop.GetUnit() != eCSSUnit_Null &&
1371 : mTop.GetUnit() != eCSSUnit_Inherit &&
1372 : mTop.GetUnit() != eCSSUnit_Initial,
1373 : "parser should have used a bare value");
1374 :
1375 0 : NS_NAMED_LITERAL_STRING(comma, ", ");
1376 :
1377 0 : aResult.AppendLiteral("rect(");
1378 0 : mTop.AppendToString(aProperty, aResult);
1379 0 : aResult.Append(comma);
1380 0 : mRight.AppendToString(aProperty, aResult);
1381 0 : aResult.Append(comma);
1382 0 : mBottom.AppendToString(aProperty, aResult);
1383 0 : aResult.Append(comma);
1384 0 : mLeft.AppendToString(aProperty, aResult);
1385 0 : aResult.Append(PRUnichar(')'));
1386 0 : }
1387 :
1388 0 : void nsCSSRect::SetAllSidesTo(const nsCSSValue& aValue)
1389 : {
1390 0 : mTop = aValue;
1391 0 : mRight = aValue;
1392 0 : mBottom = aValue;
1393 0 : mLeft = aValue;
1394 0 : }
1395 :
1396 : size_t
1397 0 : nsCSSRect_heap::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const
1398 : {
1399 0 : size_t n = aMallocSizeOf(this);
1400 0 : n += mTop .SizeOfExcludingThis(aMallocSizeOf);
1401 0 : n += mRight .SizeOfExcludingThis(aMallocSizeOf);
1402 0 : n += mBottom.SizeOfExcludingThis(aMallocSizeOf);
1403 0 : n += mLeft .SizeOfExcludingThis(aMallocSizeOf);
1404 0 : return n;
1405 : }
1406 :
1407 : MOZ_STATIC_ASSERT(NS_SIDE_TOP == 0 && NS_SIDE_RIGHT == 1 &&
1408 : NS_SIDE_BOTTOM == 2 && NS_SIDE_LEFT == 3,
1409 : "box side constants not top/right/bottom/left == 0/1/2/3");
1410 :
1411 : /* static */ const nsCSSRect::side_type nsCSSRect::sides[4] = {
1412 : &nsCSSRect::mTop,
1413 : &nsCSSRect::mRight,
1414 : &nsCSSRect::mBottom,
1415 : &nsCSSRect::mLeft,
1416 : };
1417 :
1418 : // --- nsCSSValuePair -----------------
1419 :
1420 : void
1421 0 : nsCSSValuePair::AppendToString(nsCSSProperty aProperty,
1422 : nsAString& aResult) const
1423 : {
1424 0 : mXValue.AppendToString(aProperty, aResult);
1425 0 : if (mYValue.GetUnit() != eCSSUnit_Null) {
1426 0 : aResult.Append(PRUnichar(' '));
1427 0 : mYValue.AppendToString(aProperty, aResult);
1428 : }
1429 0 : }
1430 :
1431 : size_t
1432 0 : nsCSSValuePair::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const
1433 : {
1434 0 : size_t n = 0;
1435 0 : n += mXValue.SizeOfExcludingThis(aMallocSizeOf);
1436 0 : n += mYValue.SizeOfExcludingThis(aMallocSizeOf);
1437 0 : return n;
1438 : }
1439 :
1440 : size_t
1441 0 : nsCSSValuePair_heap::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const
1442 : {
1443 0 : size_t n = aMallocSizeOf(this);
1444 0 : n += mXValue.SizeOfExcludingThis(aMallocSizeOf);
1445 0 : n += mYValue.SizeOfExcludingThis(aMallocSizeOf);
1446 0 : return n;
1447 : }
1448 :
1449 : // --- nsCSSValueTriplet -----------------
1450 :
1451 : void
1452 0 : nsCSSValueTriplet::AppendToString(nsCSSProperty aProperty,
1453 : nsAString& aResult) const
1454 : {
1455 0 : mXValue.AppendToString(aProperty, aResult);
1456 0 : if (mYValue.GetUnit() != eCSSUnit_Null) {
1457 0 : aResult.Append(PRUnichar(' '));
1458 0 : mYValue.AppendToString(aProperty, aResult);
1459 0 : if (mZValue.GetUnit() != eCSSUnit_Null) {
1460 0 : aResult.Append(PRUnichar(' '));
1461 0 : mZValue.AppendToString(aProperty, aResult);
1462 : }
1463 : }
1464 0 : }
1465 :
1466 : size_t
1467 0 : nsCSSValueTriplet_heap::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const
1468 : {
1469 0 : size_t n = aMallocSizeOf(this);
1470 0 : n += mXValue.SizeOfExcludingThis(aMallocSizeOf);
1471 0 : n += mYValue.SizeOfExcludingThis(aMallocSizeOf);
1472 0 : n += mZValue.SizeOfExcludingThis(aMallocSizeOf);
1473 0 : return n;
1474 : }
1475 :
1476 : // --- nsCSSValuePairList -----------------
1477 :
1478 0 : nsCSSValuePairList::~nsCSSValuePairList()
1479 : {
1480 0 : MOZ_COUNT_DTOR(nsCSSValuePairList);
1481 0 : NS_CSS_DELETE_LIST_MEMBER(nsCSSValuePairList, this, mNext);
1482 0 : }
1483 :
1484 : nsCSSValuePairList*
1485 0 : nsCSSValuePairList::Clone() const
1486 : {
1487 0 : nsCSSValuePairList* result = new nsCSSValuePairList(*this);
1488 0 : nsCSSValuePairList* dest = result;
1489 0 : const nsCSSValuePairList* src = this->mNext;
1490 0 : while (src) {
1491 0 : dest->mNext = new nsCSSValuePairList(*src);
1492 0 : dest = dest->mNext;
1493 0 : src = src->mNext;
1494 : }
1495 0 : return result;
1496 : }
1497 :
1498 : void
1499 0 : nsCSSValuePairList::AppendToString(nsCSSProperty aProperty,
1500 : nsAString& aResult) const
1501 : {
1502 0 : const nsCSSValuePairList* item = this;
1503 0 : for (;;) {
1504 0 : NS_ABORT_IF_FALSE(item->mXValue.GetUnit() != eCSSUnit_Null,
1505 : "unexpected null unit");
1506 0 : item->mXValue.AppendToString(aProperty, aResult);
1507 0 : if (item->mXValue.GetUnit() != eCSSUnit_Inherit &&
1508 0 : item->mXValue.GetUnit() != eCSSUnit_Initial &&
1509 0 : item->mYValue.GetUnit() != eCSSUnit_Null) {
1510 0 : aResult.Append(PRUnichar(' '));
1511 0 : item->mYValue.AppendToString(aProperty, aResult);
1512 : }
1513 0 : item = item->mNext;
1514 0 : if (!item)
1515 : break;
1516 :
1517 0 : if (nsCSSProps::PropHasFlags(aProperty,
1518 : CSS_PROPERTY_VALUE_LIST_USES_COMMAS))
1519 0 : aResult.Append(PRUnichar(','));
1520 0 : aResult.Append(PRUnichar(' '));
1521 : }
1522 0 : }
1523 :
1524 : bool
1525 0 : nsCSSValuePairList::operator==(const nsCSSValuePairList& aOther) const
1526 : {
1527 0 : if (this == &aOther)
1528 0 : return true;
1529 :
1530 0 : const nsCSSValuePairList *p1 = this, *p2 = &aOther;
1531 0 : for ( ; p1 && p2; p1 = p1->mNext, p2 = p2->mNext) {
1532 0 : if (p1->mXValue != p2->mXValue ||
1533 0 : p1->mYValue != p2->mYValue)
1534 0 : return false;
1535 : }
1536 0 : return !p1 && !p2; // true if same length, false otherwise
1537 : }
1538 :
1539 : size_t
1540 0 : nsCSSValuePairList::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const
1541 : {
1542 0 : size_t n = 0;
1543 0 : const nsCSSValuePairList* v = this;
1544 0 : while (v) {
1545 0 : n += aMallocSizeOf(v);
1546 0 : n += v->mXValue.SizeOfExcludingThis(aMallocSizeOf);
1547 0 : n += v->mYValue.SizeOfExcludingThis(aMallocSizeOf);
1548 0 : v = v->mNext;
1549 : }
1550 0 : return n;
1551 : }
1552 :
1553 : size_t
1554 0 : nsCSSValuePairList_heap::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const
1555 : {
1556 0 : size_t n = aMallocSizeOf(this);
1557 0 : n += mXValue.SizeOfExcludingThis(aMallocSizeOf);
1558 0 : n += mYValue.SizeOfExcludingThis(aMallocSizeOf);
1559 0 : n += mNext ? mNext->SizeOfIncludingThis(aMallocSizeOf) : 0;
1560 0 : return n;
1561 : }
1562 :
1563 : size_t
1564 0 : nsCSSValue::Array::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const
1565 : {
1566 0 : size_t n = aMallocSizeOf(this);
1567 0 : for (size_t i = 0; i < mCount; i++) {
1568 0 : n += mArray[i].SizeOfExcludingThis(aMallocSizeOf);
1569 : }
1570 0 : return n;
1571 : }
1572 :
1573 0 : nsCSSValue::URL::URL(nsIURI* aURI, nsStringBuffer* aString,
1574 : nsIURI* aReferrer, nsIPrincipal* aOriginPrincipal)
1575 : : mURI(aURI),
1576 : mString(aString),
1577 : mReferrer(aReferrer),
1578 : mOriginPrincipal(aOriginPrincipal),
1579 0 : mURIResolved(true)
1580 : {
1581 0 : NS_ABORT_IF_FALSE(aOriginPrincipal, "Must have an origin principal");
1582 0 : mString->AddRef();
1583 0 : }
1584 :
1585 0 : nsCSSValue::URL::URL(nsStringBuffer* aString, nsIURI* aBaseURI,
1586 : nsIURI* aReferrer, nsIPrincipal* aOriginPrincipal)
1587 : : mURI(aBaseURI),
1588 : mString(aString),
1589 : mReferrer(aReferrer),
1590 : mOriginPrincipal(aOriginPrincipal),
1591 0 : mURIResolved(false)
1592 : {
1593 0 : NS_ABORT_IF_FALSE(aOriginPrincipal, "Must have an origin principal");
1594 0 : mString->AddRef();
1595 0 : }
1596 :
1597 0 : nsCSSValue::URL::~URL()
1598 : {
1599 0 : mString->Release();
1600 0 : }
1601 :
1602 : bool
1603 0 : nsCSSValue::URL::operator==(const URL& aOther) const
1604 : {
1605 : bool eq;
1606 : return NS_strcmp(GetBufferValue(mString),
1607 0 : GetBufferValue(aOther.mString)) == 0 &&
1608 0 : (GetURI() == aOther.GetURI() || // handles null == null
1609 0 : (mURI && aOther.mURI &&
1610 0 : NS_SUCCEEDED(mURI->Equals(aOther.mURI, &eq)) &&
1611 : eq)) &&
1612 0 : (mOriginPrincipal == aOther.mOriginPrincipal ||
1613 0 : (NS_SUCCEEDED(mOriginPrincipal->Equals(aOther.mOriginPrincipal,
1614 0 : &eq)) && eq));
1615 : }
1616 :
1617 : bool
1618 0 : nsCSSValue::URL::URIEquals(const URL& aOther) const
1619 : {
1620 0 : NS_ABORT_IF_FALSE(mURIResolved && aOther.mURIResolved,
1621 : "How do you know the URIs aren't null?");
1622 : bool eq;
1623 : // Worth comparing GetURI() to aOther.GetURI() and mOriginPrincipal to
1624 : // aOther.mOriginPrincipal, because in the (probably common) case when this
1625 : // value was one of the ones that in fact did not change this will be our
1626 : // fast path to equality
1627 0 : return (mURI == aOther.mURI ||
1628 0 : (NS_SUCCEEDED(mURI->Equals(aOther.mURI, &eq)) && eq)) &&
1629 0 : (mOriginPrincipal == aOther.mOriginPrincipal ||
1630 0 : (NS_SUCCEEDED(mOriginPrincipal->Equals(aOther.mOriginPrincipal,
1631 0 : &eq)) && eq));
1632 : }
1633 :
1634 : nsIURI*
1635 0 : nsCSSValue::URL::GetURI() const
1636 : {
1637 0 : if (!mURIResolved) {
1638 0 : mURIResolved = true;
1639 : // Be careful to not null out mURI before we've passed it as the base URI
1640 0 : nsCOMPtr<nsIURI> newURI;
1641 0 : NS_NewURI(getter_AddRefs(newURI),
1642 0 : NS_ConvertUTF16toUTF8(GetBufferValue(mString)), nsnull, mURI);
1643 0 : newURI.swap(mURI);
1644 : }
1645 :
1646 0 : return mURI;
1647 : }
1648 :
1649 : size_t
1650 0 : nsCSSValue::URL::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const
1651 : {
1652 0 : size_t n = aMallocSizeOf(this);
1653 :
1654 : // This string is unshared.
1655 0 : n += mString->SizeOfIncludingThisMustBeUnshared(aMallocSizeOf);
1656 :
1657 : // Measurement of the following members may be added later if DMD finds it is
1658 : // worthwhile:
1659 : // - mURI
1660 : // - mReferrer
1661 : // - mOriginPrincipal
1662 :
1663 0 : return n;
1664 : }
1665 :
1666 :
1667 0 : nsCSSValue::Image::Image(nsIURI* aURI, nsStringBuffer* aString,
1668 : nsIURI* aReferrer, nsIPrincipal* aOriginPrincipal,
1669 : nsIDocument* aDocument)
1670 0 : : URL(aURI, aString, aReferrer, aOriginPrincipal)
1671 : {
1672 0 : if (aDocument->GetOriginalDocument()) {
1673 0 : aDocument = aDocument->GetOriginalDocument();
1674 : }
1675 0 : if (aURI &&
1676 : nsContentUtils::CanLoadImage(aURI, aDocument, aDocument,
1677 0 : aOriginPrincipal)) {
1678 : nsContentUtils::LoadImage(aURI, aDocument, aOriginPrincipal, aReferrer,
1679 : nsnull, nsIRequest::LOAD_NORMAL,
1680 0 : getter_AddRefs(mRequest));
1681 : }
1682 0 : }
1683 :
1684 0 : nsCSSValue::Image::~Image()
1685 : {
1686 0 : }
1687 :
1688 0 : nsCSSValueGradientStop::nsCSSValueGradientStop()
1689 : : mLocation(eCSSUnit_None),
1690 0 : mColor(eCSSUnit_Null)
1691 : {
1692 0 : MOZ_COUNT_CTOR(nsCSSValueGradientStop);
1693 0 : }
1694 :
1695 0 : nsCSSValueGradientStop::nsCSSValueGradientStop(const nsCSSValueGradientStop& aOther)
1696 : : mLocation(aOther.mLocation),
1697 0 : mColor(aOther.mColor)
1698 : {
1699 0 : MOZ_COUNT_CTOR(nsCSSValueGradientStop);
1700 0 : }
1701 :
1702 0 : nsCSSValueGradientStop::~nsCSSValueGradientStop()
1703 : {
1704 0 : MOZ_COUNT_DTOR(nsCSSValueGradientStop);
1705 0 : }
1706 :
1707 : size_t
1708 0 : nsCSSValueGradientStop::SizeOfExcludingThis(nsMallocSizeOfFun aMallocSizeOf) const
1709 : {
1710 0 : size_t n = 0;
1711 0 : n += mLocation.SizeOfExcludingThis(aMallocSizeOf);
1712 0 : n += mColor .SizeOfExcludingThis(aMallocSizeOf);
1713 0 : return n;
1714 : }
1715 :
1716 0 : nsCSSValueGradient::nsCSSValueGradient(bool aIsRadial,
1717 : bool aIsRepeating)
1718 : : mIsRadial(aIsRadial),
1719 : mIsRepeating(aIsRepeating),
1720 : mIsToCorner(false),
1721 : mBgPos(eCSSUnit_None),
1722 : mAngle(eCSSUnit_None),
1723 : mRadialShape(eCSSUnit_None),
1724 0 : mRadialSize(eCSSUnit_None)
1725 : {
1726 0 : }
1727 :
1728 : size_t
1729 0 : nsCSSValueGradient::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf) const
1730 : {
1731 0 : size_t n = aMallocSizeOf(this);
1732 0 : n += mBgPos .SizeOfExcludingThis(aMallocSizeOf);
1733 0 : n += mAngle .SizeOfExcludingThis(aMallocSizeOf);
1734 0 : n += mRadialShape.SizeOfExcludingThis(aMallocSizeOf);
1735 0 : n += mRadialSize .SizeOfExcludingThis(aMallocSizeOf);
1736 0 : n += mStops .SizeOfExcludingThis(aMallocSizeOf);
1737 0 : for (PRUint32 i = 0; i < mStops.Length(); i++) {
1738 0 : n += mStops[i].SizeOfExcludingThis(aMallocSizeOf);
1739 : }
1740 0 : return n;
1741 : }
1742 :
1743 : // --- nsCSSCornerSizes -----------------
1744 :
1745 0 : nsCSSCornerSizes::nsCSSCornerSizes(void)
1746 : {
1747 0 : MOZ_COUNT_CTOR(nsCSSCornerSizes);
1748 0 : }
1749 :
1750 0 : nsCSSCornerSizes::nsCSSCornerSizes(const nsCSSCornerSizes& aCopy)
1751 : : mTopLeft(aCopy.mTopLeft),
1752 : mTopRight(aCopy.mTopRight),
1753 : mBottomRight(aCopy.mBottomRight),
1754 0 : mBottomLeft(aCopy.mBottomLeft)
1755 : {
1756 0 : MOZ_COUNT_CTOR(nsCSSCornerSizes);
1757 0 : }
1758 :
1759 0 : nsCSSCornerSizes::~nsCSSCornerSizes()
1760 : {
1761 0 : MOZ_COUNT_DTOR(nsCSSCornerSizes);
1762 0 : }
1763 :
1764 : void
1765 0 : nsCSSCornerSizes::Reset()
1766 : {
1767 0 : NS_FOR_CSS_FULL_CORNERS(corner) {
1768 0 : this->GetCorner(corner).Reset();
1769 : }
1770 0 : }
1771 :
1772 : MOZ_STATIC_ASSERT(NS_CORNER_TOP_LEFT == 0 && NS_CORNER_TOP_RIGHT == 1 &&
1773 : NS_CORNER_BOTTOM_RIGHT == 2 && NS_CORNER_BOTTOM_LEFT == 3,
1774 : "box corner constants not tl/tr/br/bl == 0/1/2/3");
1775 :
1776 : /* static */ const nsCSSCornerSizes::corner_type
1777 : nsCSSCornerSizes::corners[4] = {
1778 : &nsCSSCornerSizes::mTopLeft,
1779 : &nsCSSCornerSizes::mTopRight,
1780 : &nsCSSCornerSizes::mBottomRight,
1781 : &nsCSSCornerSizes::mBottomLeft,
1782 : };
1783 :
|