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