|
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 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
4 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
6 |
|
7 /* representation of simple property values within CSS declarations */ |
|
8 |
|
9 #include "nsCSSValue.h" |
|
10 |
|
11 #include "mozilla/Likely.h" |
|
12 #include "mozilla/MemoryReporting.h" |
|
13 #include "mozilla/css/ImageLoader.h" |
|
14 #include "CSSCalc.h" |
|
15 #include "gfxFontConstants.h" |
|
16 #include "imgIRequest.h" |
|
17 #include "imgRequestProxy.h" |
|
18 #include "nsIDocument.h" |
|
19 #include "nsIPrincipal.h" |
|
20 #include "nsCSSProps.h" |
|
21 #include "nsCSSStyleSheet.h" |
|
22 #include "nsNetUtil.h" |
|
23 #include "nsPresContext.h" |
|
24 #include "nsStyleUtil.h" |
|
25 #include "nsDeviceContext.h" |
|
26 |
|
27 using namespace mozilla; |
|
28 |
|
29 nsCSSValue::nsCSSValue(int32_t aValue, nsCSSUnit aUnit) |
|
30 : mUnit(aUnit) |
|
31 { |
|
32 NS_ABORT_IF_FALSE(aUnit == eCSSUnit_Integer || aUnit == eCSSUnit_Enumerated || |
|
33 aUnit == eCSSUnit_EnumColor, "not an int value"); |
|
34 if (aUnit == eCSSUnit_Integer || aUnit == eCSSUnit_Enumerated || |
|
35 aUnit == eCSSUnit_EnumColor) { |
|
36 mValue.mInt = aValue; |
|
37 } |
|
38 else { |
|
39 mUnit = eCSSUnit_Null; |
|
40 mValue.mInt = 0; |
|
41 } |
|
42 } |
|
43 |
|
44 nsCSSValue::nsCSSValue(float aValue, nsCSSUnit aUnit) |
|
45 : mUnit(aUnit) |
|
46 { |
|
47 NS_ABORT_IF_FALSE(eCSSUnit_Percent <= aUnit, "not a float value"); |
|
48 if (eCSSUnit_Percent <= aUnit) { |
|
49 mValue.mFloat = aValue; |
|
50 MOZ_ASSERT(!mozilla::IsNaN(mValue.mFloat)); |
|
51 } |
|
52 else { |
|
53 mUnit = eCSSUnit_Null; |
|
54 mValue.mInt = 0; |
|
55 } |
|
56 } |
|
57 |
|
58 nsCSSValue::nsCSSValue(const nsString& aValue, nsCSSUnit aUnit) |
|
59 : mUnit(aUnit) |
|
60 { |
|
61 NS_ABORT_IF_FALSE(UnitHasStringValue(), "not a string value"); |
|
62 if (UnitHasStringValue()) { |
|
63 mValue.mString = BufferFromString(aValue).take(); |
|
64 } |
|
65 else { |
|
66 mUnit = eCSSUnit_Null; |
|
67 mValue.mInt = 0; |
|
68 } |
|
69 } |
|
70 |
|
71 nsCSSValue::nsCSSValue(nsCSSValue::Array* aValue, nsCSSUnit aUnit) |
|
72 : mUnit(aUnit) |
|
73 { |
|
74 NS_ABORT_IF_FALSE(UnitHasArrayValue(), "bad unit"); |
|
75 mValue.mArray = aValue; |
|
76 mValue.mArray->AddRef(); |
|
77 } |
|
78 |
|
79 nsCSSValue::nsCSSValue(mozilla::css::URLValue* aValue) |
|
80 : mUnit(eCSSUnit_URL) |
|
81 { |
|
82 mValue.mURL = aValue; |
|
83 mValue.mURL->AddRef(); |
|
84 } |
|
85 |
|
86 nsCSSValue::nsCSSValue(mozilla::css::ImageValue* aValue) |
|
87 : mUnit(eCSSUnit_Image) |
|
88 { |
|
89 mValue.mImage = aValue; |
|
90 mValue.mImage->AddRef(); |
|
91 } |
|
92 |
|
93 nsCSSValue::nsCSSValue(nsCSSValueGradient* aValue) |
|
94 : mUnit(eCSSUnit_Gradient) |
|
95 { |
|
96 mValue.mGradient = aValue; |
|
97 mValue.mGradient->AddRef(); |
|
98 } |
|
99 |
|
100 nsCSSValue::nsCSSValue(nsCSSValueTokenStream* aValue) |
|
101 : mUnit(eCSSUnit_TokenStream) |
|
102 { |
|
103 mValue.mTokenStream = aValue; |
|
104 mValue.mTokenStream->AddRef(); |
|
105 } |
|
106 |
|
107 nsCSSValue::nsCSSValue(mozilla::css::GridTemplateAreasValue* aValue) |
|
108 : mUnit(eCSSUnit_GridTemplateAreas) |
|
109 { |
|
110 mValue.mGridTemplateAreas = aValue; |
|
111 mValue.mGridTemplateAreas->AddRef(); |
|
112 } |
|
113 |
|
114 nsCSSValue::nsCSSValue(const nsCSSValue& aCopy) |
|
115 : mUnit(aCopy.mUnit) |
|
116 { |
|
117 if (mUnit <= eCSSUnit_DummyInherit) { |
|
118 // nothing to do, but put this important case first |
|
119 } |
|
120 else if (eCSSUnit_Percent <= mUnit) { |
|
121 mValue.mFloat = aCopy.mValue.mFloat; |
|
122 MOZ_ASSERT(!mozilla::IsNaN(mValue.mFloat)); |
|
123 } |
|
124 else if (UnitHasStringValue()) { |
|
125 mValue.mString = aCopy.mValue.mString; |
|
126 mValue.mString->AddRef(); |
|
127 } |
|
128 else if (eCSSUnit_Integer <= mUnit && mUnit <= eCSSUnit_EnumColor) { |
|
129 mValue.mInt = aCopy.mValue.mInt; |
|
130 } |
|
131 else if (IsIntegerColorUnit()) { |
|
132 mValue.mColor = aCopy.mValue.mColor; |
|
133 } |
|
134 else if (IsFloatColorUnit()) { |
|
135 mValue.mFloatColor = aCopy.mValue.mFloatColor; |
|
136 mValue.mFloatColor->AddRef(); |
|
137 } |
|
138 else if (UnitHasArrayValue()) { |
|
139 mValue.mArray = aCopy.mValue.mArray; |
|
140 mValue.mArray->AddRef(); |
|
141 } |
|
142 else if (eCSSUnit_URL == mUnit) { |
|
143 mValue.mURL = aCopy.mValue.mURL; |
|
144 mValue.mURL->AddRef(); |
|
145 } |
|
146 else if (eCSSUnit_Image == mUnit) { |
|
147 mValue.mImage = aCopy.mValue.mImage; |
|
148 mValue.mImage->AddRef(); |
|
149 } |
|
150 else if (eCSSUnit_Gradient == mUnit) { |
|
151 mValue.mGradient = aCopy.mValue.mGradient; |
|
152 mValue.mGradient->AddRef(); |
|
153 } |
|
154 else if (eCSSUnit_TokenStream == mUnit) { |
|
155 mValue.mTokenStream = aCopy.mValue.mTokenStream; |
|
156 mValue.mTokenStream->AddRef(); |
|
157 } |
|
158 else if (eCSSUnit_Pair == mUnit) { |
|
159 mValue.mPair = aCopy.mValue.mPair; |
|
160 mValue.mPair->AddRef(); |
|
161 } |
|
162 else if (eCSSUnit_Triplet == mUnit) { |
|
163 mValue.mTriplet = aCopy.mValue.mTriplet; |
|
164 mValue.mTriplet->AddRef(); |
|
165 } |
|
166 else if (eCSSUnit_Rect == mUnit) { |
|
167 mValue.mRect = aCopy.mValue.mRect; |
|
168 mValue.mRect->AddRef(); |
|
169 } |
|
170 else if (eCSSUnit_List == mUnit) { |
|
171 mValue.mList = aCopy.mValue.mList; |
|
172 mValue.mList->AddRef(); |
|
173 } |
|
174 else if (eCSSUnit_ListDep == mUnit) { |
|
175 mValue.mListDependent = aCopy.mValue.mListDependent; |
|
176 } |
|
177 else if (eCSSUnit_SharedList == mUnit) { |
|
178 mValue.mSharedList = aCopy.mValue.mSharedList; |
|
179 mValue.mSharedList->AddRef(); |
|
180 } |
|
181 else if (eCSSUnit_PairList == mUnit) { |
|
182 mValue.mPairList = aCopy.mValue.mPairList; |
|
183 mValue.mPairList->AddRef(); |
|
184 } |
|
185 else if (eCSSUnit_PairListDep == mUnit) { |
|
186 mValue.mPairListDependent = aCopy.mValue.mPairListDependent; |
|
187 } |
|
188 else if (eCSSUnit_GridTemplateAreas == mUnit) { |
|
189 mValue.mGridTemplateAreas = aCopy.mValue.mGridTemplateAreas; |
|
190 mValue.mGridTemplateAreas->AddRef(); |
|
191 } |
|
192 else { |
|
193 NS_ABORT_IF_FALSE(false, "unknown unit"); |
|
194 } |
|
195 } |
|
196 |
|
197 nsCSSValue& nsCSSValue::operator=(const nsCSSValue& aCopy) |
|
198 { |
|
199 if (this != &aCopy) { |
|
200 Reset(); |
|
201 new (this) nsCSSValue(aCopy); |
|
202 } |
|
203 return *this; |
|
204 } |
|
205 |
|
206 bool nsCSSValue::operator==(const nsCSSValue& aOther) const |
|
207 { |
|
208 NS_ABORT_IF_FALSE(mUnit != eCSSUnit_ListDep && |
|
209 aOther.mUnit != eCSSUnit_ListDep && |
|
210 mUnit != eCSSUnit_PairListDep && |
|
211 aOther.mUnit != eCSSUnit_PairListDep, |
|
212 "don't use operator== with dependent lists"); |
|
213 |
|
214 if (mUnit == aOther.mUnit) { |
|
215 if (mUnit <= eCSSUnit_DummyInherit) { |
|
216 return true; |
|
217 } |
|
218 else if (UnitHasStringValue()) { |
|
219 return (NS_strcmp(GetBufferValue(mValue.mString), |
|
220 GetBufferValue(aOther.mValue.mString)) == 0); |
|
221 } |
|
222 else if ((eCSSUnit_Integer <= mUnit) && (mUnit <= eCSSUnit_EnumColor)) { |
|
223 return mValue.mInt == aOther.mValue.mInt; |
|
224 } |
|
225 else if (IsIntegerColorUnit()) { |
|
226 return mValue.mColor == aOther.mValue.mColor; |
|
227 } |
|
228 else if (IsFloatColorUnit()) { |
|
229 return *mValue.mFloatColor == *aOther.mValue.mFloatColor; |
|
230 } |
|
231 else if (UnitHasArrayValue()) { |
|
232 return *mValue.mArray == *aOther.mValue.mArray; |
|
233 } |
|
234 else if (eCSSUnit_URL == mUnit) { |
|
235 return *mValue.mURL == *aOther.mValue.mURL; |
|
236 } |
|
237 else if (eCSSUnit_Image == mUnit) { |
|
238 return *mValue.mImage == *aOther.mValue.mImage; |
|
239 } |
|
240 else if (eCSSUnit_Gradient == mUnit) { |
|
241 return *mValue.mGradient == *aOther.mValue.mGradient; |
|
242 } |
|
243 else if (eCSSUnit_TokenStream == mUnit) { |
|
244 return *mValue.mTokenStream == *aOther.mValue.mTokenStream; |
|
245 } |
|
246 else if (eCSSUnit_Pair == mUnit) { |
|
247 return *mValue.mPair == *aOther.mValue.mPair; |
|
248 } |
|
249 else if (eCSSUnit_Triplet == mUnit) { |
|
250 return *mValue.mTriplet == *aOther.mValue.mTriplet; |
|
251 } |
|
252 else if (eCSSUnit_Rect == mUnit) { |
|
253 return *mValue.mRect == *aOther.mValue.mRect; |
|
254 } |
|
255 else if (eCSSUnit_List == mUnit) { |
|
256 return *mValue.mList == *aOther.mValue.mList; |
|
257 } |
|
258 else if (eCSSUnit_SharedList == mUnit) { |
|
259 return *mValue.mSharedList == *aOther.mValue.mSharedList; |
|
260 } |
|
261 else if (eCSSUnit_PairList == mUnit) { |
|
262 return *mValue.mPairList == *aOther.mValue.mPairList; |
|
263 } |
|
264 else if (eCSSUnit_GridTemplateAreas == mUnit) { |
|
265 return *mValue.mGridTemplateAreas == *aOther.mValue.mGridTemplateAreas; |
|
266 } |
|
267 else { |
|
268 return mValue.mFloat == aOther.mValue.mFloat; |
|
269 } |
|
270 } |
|
271 return false; |
|
272 } |
|
273 |
|
274 double nsCSSValue::GetAngleValueInRadians() const |
|
275 { |
|
276 double angle = GetFloatValue(); |
|
277 |
|
278 switch (GetUnit()) { |
|
279 case eCSSUnit_Radian: return angle; |
|
280 case eCSSUnit_Turn: return angle * 2 * M_PI; |
|
281 case eCSSUnit_Degree: return angle * M_PI / 180.0; |
|
282 case eCSSUnit_Grad: return angle * M_PI / 200.0; |
|
283 |
|
284 default: |
|
285 NS_ABORT_IF_FALSE(false, "unrecognized angular unit"); |
|
286 return 0.0; |
|
287 } |
|
288 } |
|
289 |
|
290 imgRequestProxy* nsCSSValue::GetImageValue(nsIDocument* aDocument) const |
|
291 { |
|
292 NS_ABORT_IF_FALSE(mUnit == eCSSUnit_Image, "not an Image value"); |
|
293 return mValue.mImage->mRequests.GetWeak(aDocument); |
|
294 } |
|
295 |
|
296 nscoord nsCSSValue::GetFixedLength(nsPresContext* aPresContext) const |
|
297 { |
|
298 NS_ABORT_IF_FALSE(mUnit == eCSSUnit_PhysicalMillimeter, |
|
299 "not a fixed length unit"); |
|
300 |
|
301 float inches = mValue.mFloat / MM_PER_INCH_FLOAT; |
|
302 return NSToCoordFloorClamped(inches * |
|
303 float(aPresContext->DeviceContext()->AppUnitsPerPhysicalInch())); |
|
304 } |
|
305 |
|
306 nscoord nsCSSValue::GetPixelLength() const |
|
307 { |
|
308 NS_ABORT_IF_FALSE(IsPixelLengthUnit(), "not a fixed length unit"); |
|
309 |
|
310 double scaleFactor; |
|
311 switch (mUnit) { |
|
312 case eCSSUnit_Pixel: return nsPresContext::CSSPixelsToAppUnits(mValue.mFloat); |
|
313 case eCSSUnit_Pica: scaleFactor = 16.0; break; |
|
314 case eCSSUnit_Point: scaleFactor = 4/3.0; break; |
|
315 case eCSSUnit_Inch: scaleFactor = 96.0; break; |
|
316 case eCSSUnit_Millimeter: scaleFactor = 96/25.4; break; |
|
317 case eCSSUnit_Centimeter: scaleFactor = 96/2.54; break; |
|
318 default: |
|
319 NS_ERROR("should never get here"); |
|
320 return 0; |
|
321 } |
|
322 return nsPresContext::CSSPixelsToAppUnits(float(mValue.mFloat*scaleFactor)); |
|
323 } |
|
324 |
|
325 void nsCSSValue::DoReset() |
|
326 { |
|
327 if (UnitHasStringValue()) { |
|
328 mValue.mString->Release(); |
|
329 } else if (IsFloatColorUnit()) { |
|
330 mValue.mFloatColor->Release(); |
|
331 } else if (UnitHasArrayValue()) { |
|
332 mValue.mArray->Release(); |
|
333 } else if (eCSSUnit_URL == mUnit) { |
|
334 mValue.mURL->Release(); |
|
335 } else if (eCSSUnit_Image == mUnit) { |
|
336 mValue.mImage->Release(); |
|
337 } else if (eCSSUnit_Gradient == mUnit) { |
|
338 mValue.mGradient->Release(); |
|
339 } else if (eCSSUnit_TokenStream == mUnit) { |
|
340 mValue.mTokenStream->Release(); |
|
341 } else if (eCSSUnit_Pair == mUnit) { |
|
342 mValue.mPair->Release(); |
|
343 } else if (eCSSUnit_Triplet == mUnit) { |
|
344 mValue.mTriplet->Release(); |
|
345 } else if (eCSSUnit_Rect == mUnit) { |
|
346 mValue.mRect->Release(); |
|
347 } else if (eCSSUnit_List == mUnit) { |
|
348 mValue.mList->Release(); |
|
349 } else if (eCSSUnit_SharedList == mUnit) { |
|
350 mValue.mSharedList->Release(); |
|
351 } else if (eCSSUnit_PairList == mUnit) { |
|
352 mValue.mPairList->Release(); |
|
353 } else if (eCSSUnit_GridTemplateAreas == mUnit) { |
|
354 mValue.mGridTemplateAreas->Release(); |
|
355 } |
|
356 mUnit = eCSSUnit_Null; |
|
357 } |
|
358 |
|
359 void nsCSSValue::SetIntValue(int32_t aValue, nsCSSUnit aUnit) |
|
360 { |
|
361 NS_ABORT_IF_FALSE(aUnit == eCSSUnit_Integer || aUnit == eCSSUnit_Enumerated || |
|
362 aUnit == eCSSUnit_EnumColor, "not an int value"); |
|
363 Reset(); |
|
364 if (aUnit == eCSSUnit_Integer || aUnit == eCSSUnit_Enumerated || |
|
365 aUnit == eCSSUnit_EnumColor) { |
|
366 mUnit = aUnit; |
|
367 mValue.mInt = aValue; |
|
368 } |
|
369 } |
|
370 |
|
371 void nsCSSValue::SetPercentValue(float aValue) |
|
372 { |
|
373 Reset(); |
|
374 mUnit = eCSSUnit_Percent; |
|
375 mValue.mFloat = aValue; |
|
376 MOZ_ASSERT(!mozilla::IsNaN(mValue.mFloat)); |
|
377 } |
|
378 |
|
379 void nsCSSValue::SetFloatValue(float aValue, nsCSSUnit aUnit) |
|
380 { |
|
381 NS_ABORT_IF_FALSE(eCSSUnit_Number <= aUnit, "not a float value"); |
|
382 Reset(); |
|
383 if (eCSSUnit_Number <= aUnit) { |
|
384 mUnit = aUnit; |
|
385 mValue.mFloat = aValue; |
|
386 MOZ_ASSERT(!mozilla::IsNaN(mValue.mFloat)); |
|
387 } |
|
388 } |
|
389 |
|
390 void nsCSSValue::SetStringValue(const nsString& aValue, |
|
391 nsCSSUnit aUnit) |
|
392 { |
|
393 Reset(); |
|
394 mUnit = aUnit; |
|
395 NS_ABORT_IF_FALSE(UnitHasStringValue(), "not a string unit"); |
|
396 if (UnitHasStringValue()) { |
|
397 mValue.mString = BufferFromString(aValue).take(); |
|
398 } else |
|
399 mUnit = eCSSUnit_Null; |
|
400 } |
|
401 |
|
402 void nsCSSValue::SetColorValue(nscolor aValue) |
|
403 { |
|
404 SetIntegerColorValue(aValue, eCSSUnit_RGBAColor); |
|
405 } |
|
406 |
|
407 void nsCSSValue::SetIntegerColorValue(nscolor aValue, nsCSSUnit aUnit) |
|
408 { |
|
409 Reset(); |
|
410 mUnit = aUnit; |
|
411 NS_ABORT_IF_FALSE(IsIntegerColorUnit(), "bad unit"); |
|
412 mValue.mColor = aValue; |
|
413 } |
|
414 |
|
415 void nsCSSValue::SetFloatColorValue(float aComponent1, |
|
416 float aComponent2, |
|
417 float aComponent3, |
|
418 float aAlpha, |
|
419 nsCSSUnit aUnit) |
|
420 { |
|
421 Reset(); |
|
422 mUnit = aUnit; |
|
423 NS_ABORT_IF_FALSE(IsFloatColorUnit(), "bad unit"); |
|
424 mValue.mFloatColor = |
|
425 new nsCSSValueFloatColor(aComponent1, aComponent2, aComponent3, aAlpha); |
|
426 mValue.mFloatColor->AddRef(); |
|
427 } |
|
428 |
|
429 void nsCSSValue::SetArrayValue(nsCSSValue::Array* aValue, nsCSSUnit aUnit) |
|
430 { |
|
431 Reset(); |
|
432 mUnit = aUnit; |
|
433 NS_ABORT_IF_FALSE(UnitHasArrayValue(), "bad unit"); |
|
434 mValue.mArray = aValue; |
|
435 mValue.mArray->AddRef(); |
|
436 } |
|
437 |
|
438 void nsCSSValue::SetURLValue(mozilla::css::URLValue* aValue) |
|
439 { |
|
440 Reset(); |
|
441 mUnit = eCSSUnit_URL; |
|
442 mValue.mURL = aValue; |
|
443 mValue.mURL->AddRef(); |
|
444 } |
|
445 |
|
446 void nsCSSValue::SetImageValue(mozilla::css::ImageValue* aValue) |
|
447 { |
|
448 Reset(); |
|
449 mUnit = eCSSUnit_Image; |
|
450 mValue.mImage = aValue; |
|
451 mValue.mImage->AddRef(); |
|
452 } |
|
453 |
|
454 void nsCSSValue::SetGradientValue(nsCSSValueGradient* aValue) |
|
455 { |
|
456 Reset(); |
|
457 mUnit = eCSSUnit_Gradient; |
|
458 mValue.mGradient = aValue; |
|
459 mValue.mGradient->AddRef(); |
|
460 } |
|
461 |
|
462 void nsCSSValue::SetTokenStreamValue(nsCSSValueTokenStream* aValue) |
|
463 { |
|
464 Reset(); |
|
465 mUnit = eCSSUnit_TokenStream; |
|
466 mValue.mTokenStream = aValue; |
|
467 mValue.mTokenStream->AddRef(); |
|
468 } |
|
469 |
|
470 void nsCSSValue::SetGridTemplateAreas(mozilla::css::GridTemplateAreasValue* aValue) |
|
471 { |
|
472 Reset(); |
|
473 mUnit = eCSSUnit_GridTemplateAreas; |
|
474 mValue.mGridTemplateAreas = aValue; |
|
475 mValue.mGridTemplateAreas->AddRef(); |
|
476 } |
|
477 |
|
478 void nsCSSValue::SetPairValue(const nsCSSValuePair* aValue) |
|
479 { |
|
480 // pairs should not be used for null/inherit/initial values |
|
481 NS_ABORT_IF_FALSE(aValue && |
|
482 aValue->mXValue.GetUnit() != eCSSUnit_Null && |
|
483 aValue->mYValue.GetUnit() != eCSSUnit_Null && |
|
484 aValue->mXValue.GetUnit() != eCSSUnit_Inherit && |
|
485 aValue->mYValue.GetUnit() != eCSSUnit_Inherit && |
|
486 aValue->mXValue.GetUnit() != eCSSUnit_Initial && |
|
487 aValue->mYValue.GetUnit() != eCSSUnit_Initial && |
|
488 aValue->mXValue.GetUnit() != eCSSUnit_Unset && |
|
489 aValue->mYValue.GetUnit() != eCSSUnit_Unset, |
|
490 "missing or inappropriate pair value"); |
|
491 Reset(); |
|
492 mUnit = eCSSUnit_Pair; |
|
493 mValue.mPair = new nsCSSValuePair_heap(aValue->mXValue, aValue->mYValue); |
|
494 mValue.mPair->AddRef(); |
|
495 } |
|
496 |
|
497 void nsCSSValue::SetPairValue(const nsCSSValue& xValue, |
|
498 const nsCSSValue& yValue) |
|
499 { |
|
500 NS_ABORT_IF_FALSE(xValue.GetUnit() != eCSSUnit_Null && |
|
501 yValue.GetUnit() != eCSSUnit_Null && |
|
502 xValue.GetUnit() != eCSSUnit_Inherit && |
|
503 yValue.GetUnit() != eCSSUnit_Inherit && |
|
504 xValue.GetUnit() != eCSSUnit_Initial && |
|
505 yValue.GetUnit() != eCSSUnit_Initial && |
|
506 xValue.GetUnit() != eCSSUnit_Unset && |
|
507 yValue.GetUnit() != eCSSUnit_Unset, |
|
508 "inappropriate pair value"); |
|
509 Reset(); |
|
510 mUnit = eCSSUnit_Pair; |
|
511 mValue.mPair = new nsCSSValuePair_heap(xValue, yValue); |
|
512 mValue.mPair->AddRef(); |
|
513 } |
|
514 |
|
515 void nsCSSValue::SetTripletValue(const nsCSSValueTriplet* aValue) |
|
516 { |
|
517 // triplet should not be used for null/inherit/initial values |
|
518 NS_ABORT_IF_FALSE(aValue && |
|
519 aValue->mXValue.GetUnit() != eCSSUnit_Null && |
|
520 aValue->mYValue.GetUnit() != eCSSUnit_Null && |
|
521 aValue->mZValue.GetUnit() != eCSSUnit_Null && |
|
522 aValue->mXValue.GetUnit() != eCSSUnit_Inherit && |
|
523 aValue->mYValue.GetUnit() != eCSSUnit_Inherit && |
|
524 aValue->mZValue.GetUnit() != eCSSUnit_Inherit && |
|
525 aValue->mXValue.GetUnit() != eCSSUnit_Initial && |
|
526 aValue->mYValue.GetUnit() != eCSSUnit_Initial && |
|
527 aValue->mZValue.GetUnit() != eCSSUnit_Initial && |
|
528 aValue->mXValue.GetUnit() != eCSSUnit_Unset && |
|
529 aValue->mYValue.GetUnit() != eCSSUnit_Unset && |
|
530 aValue->mZValue.GetUnit() != eCSSUnit_Unset, |
|
531 "missing or inappropriate triplet value"); |
|
532 Reset(); |
|
533 mUnit = eCSSUnit_Triplet; |
|
534 mValue.mTriplet = new nsCSSValueTriplet_heap(aValue->mXValue, aValue->mYValue, aValue->mZValue); |
|
535 mValue.mTriplet->AddRef(); |
|
536 } |
|
537 |
|
538 void nsCSSValue::SetTripletValue(const nsCSSValue& xValue, |
|
539 const nsCSSValue& yValue, |
|
540 const nsCSSValue& zValue) |
|
541 { |
|
542 // Only allow Null for the z component |
|
543 NS_ABORT_IF_FALSE(xValue.GetUnit() != eCSSUnit_Null && |
|
544 yValue.GetUnit() != eCSSUnit_Null && |
|
545 xValue.GetUnit() != eCSSUnit_Inherit && |
|
546 yValue.GetUnit() != eCSSUnit_Inherit && |
|
547 zValue.GetUnit() != eCSSUnit_Inherit && |
|
548 xValue.GetUnit() != eCSSUnit_Initial && |
|
549 yValue.GetUnit() != eCSSUnit_Initial && |
|
550 zValue.GetUnit() != eCSSUnit_Initial && |
|
551 xValue.GetUnit() != eCSSUnit_Unset && |
|
552 yValue.GetUnit() != eCSSUnit_Unset && |
|
553 zValue.GetUnit() != eCSSUnit_Unset, |
|
554 "inappropriate triplet value"); |
|
555 Reset(); |
|
556 mUnit = eCSSUnit_Triplet; |
|
557 mValue.mTriplet = new nsCSSValueTriplet_heap(xValue, yValue, zValue); |
|
558 mValue.mTriplet->AddRef(); |
|
559 } |
|
560 |
|
561 nsCSSRect& nsCSSValue::SetRectValue() |
|
562 { |
|
563 Reset(); |
|
564 mUnit = eCSSUnit_Rect; |
|
565 mValue.mRect = new nsCSSRect_heap; |
|
566 mValue.mRect->AddRef(); |
|
567 return *mValue.mRect; |
|
568 } |
|
569 |
|
570 nsCSSValueList* nsCSSValue::SetListValue() |
|
571 { |
|
572 Reset(); |
|
573 mUnit = eCSSUnit_List; |
|
574 mValue.mList = new nsCSSValueList_heap; |
|
575 mValue.mList->AddRef(); |
|
576 return mValue.mList; |
|
577 } |
|
578 |
|
579 void nsCSSValue::SetSharedListValue(nsCSSValueSharedList* aList) |
|
580 { |
|
581 Reset(); |
|
582 mUnit = eCSSUnit_SharedList; |
|
583 mValue.mSharedList = aList; |
|
584 mValue.mSharedList->AddRef(); |
|
585 } |
|
586 |
|
587 void nsCSSValue::SetDependentListValue(nsCSSValueList* aList) |
|
588 { |
|
589 Reset(); |
|
590 if (aList) { |
|
591 mUnit = eCSSUnit_ListDep; |
|
592 mValue.mListDependent = aList; |
|
593 } |
|
594 } |
|
595 |
|
596 nsCSSValuePairList* nsCSSValue::SetPairListValue() |
|
597 { |
|
598 Reset(); |
|
599 mUnit = eCSSUnit_PairList; |
|
600 mValue.mPairList = new nsCSSValuePairList_heap; |
|
601 mValue.mPairList->AddRef(); |
|
602 return mValue.mPairList; |
|
603 } |
|
604 |
|
605 void nsCSSValue::SetDependentPairListValue(nsCSSValuePairList* aList) |
|
606 { |
|
607 Reset(); |
|
608 if (aList) { |
|
609 mUnit = eCSSUnit_PairListDep; |
|
610 mValue.mPairListDependent = aList; |
|
611 } |
|
612 } |
|
613 |
|
614 void nsCSSValue::SetAutoValue() |
|
615 { |
|
616 Reset(); |
|
617 mUnit = eCSSUnit_Auto; |
|
618 } |
|
619 |
|
620 void nsCSSValue::SetInheritValue() |
|
621 { |
|
622 Reset(); |
|
623 mUnit = eCSSUnit_Inherit; |
|
624 } |
|
625 |
|
626 void nsCSSValue::SetInitialValue() |
|
627 { |
|
628 Reset(); |
|
629 mUnit = eCSSUnit_Initial; |
|
630 } |
|
631 |
|
632 void nsCSSValue::SetUnsetValue() |
|
633 { |
|
634 Reset(); |
|
635 mUnit = eCSSUnit_Unset; |
|
636 } |
|
637 |
|
638 void nsCSSValue::SetNoneValue() |
|
639 { |
|
640 Reset(); |
|
641 mUnit = eCSSUnit_None; |
|
642 } |
|
643 |
|
644 void nsCSSValue::SetAllValue() |
|
645 { |
|
646 Reset(); |
|
647 mUnit = eCSSUnit_All; |
|
648 } |
|
649 |
|
650 void nsCSSValue::SetNormalValue() |
|
651 { |
|
652 Reset(); |
|
653 mUnit = eCSSUnit_Normal; |
|
654 } |
|
655 |
|
656 void nsCSSValue::SetSystemFontValue() |
|
657 { |
|
658 Reset(); |
|
659 mUnit = eCSSUnit_System_Font; |
|
660 } |
|
661 |
|
662 void nsCSSValue::SetDummyValue() |
|
663 { |
|
664 Reset(); |
|
665 mUnit = eCSSUnit_Dummy; |
|
666 } |
|
667 |
|
668 void nsCSSValue::SetDummyInheritValue() |
|
669 { |
|
670 Reset(); |
|
671 mUnit = eCSSUnit_DummyInherit; |
|
672 } |
|
673 |
|
674 void nsCSSValue::StartImageLoad(nsIDocument* aDocument) const |
|
675 { |
|
676 NS_ABORT_IF_FALSE(eCSSUnit_URL == mUnit, "Not a URL value!"); |
|
677 mozilla::css::ImageValue* image = |
|
678 new mozilla::css::ImageValue(mValue.mURL->GetURI(), |
|
679 mValue.mURL->mString, |
|
680 mValue.mURL->mReferrer, |
|
681 mValue.mURL->mOriginPrincipal, |
|
682 aDocument); |
|
683 |
|
684 nsCSSValue* writable = const_cast<nsCSSValue*>(this); |
|
685 writable->SetImageValue(image); |
|
686 } |
|
687 |
|
688 nscolor nsCSSValue::GetColorValue() const |
|
689 { |
|
690 NS_ABORT_IF_FALSE(IsNumericColorUnit(), "not a color value"); |
|
691 if (IsFloatColorUnit()) { |
|
692 return mValue.mFloatColor->GetColorValue(mUnit); |
|
693 } |
|
694 return mValue.mColor; |
|
695 } |
|
696 |
|
697 bool nsCSSValue::IsNonTransparentColor() const |
|
698 { |
|
699 // We have the value in the form it was specified in at this point, so we |
|
700 // have to look for both the keyword 'transparent' and its equivalent in |
|
701 // rgba notation. |
|
702 nsDependentString buf; |
|
703 return |
|
704 (IsIntegerColorUnit() && NS_GET_A(GetColorValue()) > 0) || |
|
705 (IsFloatColorUnit() && mValue.mFloatColor->IsNonTransparentColor()) || |
|
706 (mUnit == eCSSUnit_Ident && |
|
707 !nsGkAtoms::transparent->Equals(GetStringValue(buf))) || |
|
708 (mUnit == eCSSUnit_EnumColor); |
|
709 } |
|
710 |
|
711 nsCSSValue::Array* |
|
712 nsCSSValue::InitFunction(nsCSSKeyword aFunctionId, uint32_t aNumArgs) |
|
713 { |
|
714 nsRefPtr<nsCSSValue::Array> func = Array::Create(aNumArgs + 1); |
|
715 func->Item(0).SetIntValue(aFunctionId, eCSSUnit_Enumerated); |
|
716 SetArrayValue(func, eCSSUnit_Function); |
|
717 return func; |
|
718 } |
|
719 |
|
720 bool |
|
721 nsCSSValue::EqualsFunction(nsCSSKeyword aFunctionId) const |
|
722 { |
|
723 if (mUnit != eCSSUnit_Function) { |
|
724 return false; |
|
725 } |
|
726 |
|
727 nsCSSValue::Array* func = mValue.mArray; |
|
728 NS_ABORT_IF_FALSE(func && func->Count() >= 1 && |
|
729 func->Item(0).GetUnit() == eCSSUnit_Enumerated, |
|
730 "illegally structured function value"); |
|
731 |
|
732 nsCSSKeyword thisFunctionId = func->Item(0).GetKeywordValue(); |
|
733 return thisFunctionId == aFunctionId; |
|
734 } |
|
735 |
|
736 // static |
|
737 already_AddRefed<nsStringBuffer> |
|
738 nsCSSValue::BufferFromString(const nsString& aValue) |
|
739 { |
|
740 nsRefPtr<nsStringBuffer> buffer = nsStringBuffer::FromString(aValue); |
|
741 if (buffer) { |
|
742 return buffer.forget(); |
|
743 } |
|
744 |
|
745 nsString::size_type length = aValue.Length(); |
|
746 |
|
747 // NOTE: Alloc prouduces a new, already-addref'd (refcnt = 1) buffer. |
|
748 // NOTE: String buffer allocation is currently fallible. |
|
749 buffer = nsStringBuffer::Alloc((length + 1) * sizeof(char16_t)); |
|
750 if (MOZ_UNLIKELY(!buffer)) { |
|
751 NS_RUNTIMEABORT("out of memory"); |
|
752 } |
|
753 |
|
754 char16_t* data = static_cast<char16_t*>(buffer->Data()); |
|
755 nsCharTraits<char16_t>::copy(data, aValue.get(), length); |
|
756 // Null-terminate. |
|
757 data[length] = 0; |
|
758 return buffer.forget(); |
|
759 } |
|
760 |
|
761 namespace { |
|
762 |
|
763 struct CSSValueSerializeCalcOps { |
|
764 CSSValueSerializeCalcOps(nsCSSProperty aProperty, nsAString& aResult, |
|
765 nsCSSValue::Serialization aSerialization) |
|
766 : mProperty(aProperty), |
|
767 mResult(aResult), |
|
768 mValueSerialization(aSerialization) |
|
769 { |
|
770 } |
|
771 |
|
772 typedef nsCSSValue input_type; |
|
773 typedef nsCSSValue::Array input_array_type; |
|
774 |
|
775 static nsCSSUnit GetUnit(const input_type& aValue) { |
|
776 return aValue.GetUnit(); |
|
777 } |
|
778 |
|
779 void Append(const char* aString) |
|
780 { |
|
781 mResult.AppendASCII(aString); |
|
782 } |
|
783 |
|
784 void AppendLeafValue(const input_type& aValue) |
|
785 { |
|
786 NS_ABORT_IF_FALSE(aValue.GetUnit() == eCSSUnit_Percent || |
|
787 aValue.IsLengthUnit(), "unexpected unit"); |
|
788 aValue.AppendToString(mProperty, mResult, mValueSerialization); |
|
789 } |
|
790 |
|
791 void AppendNumber(const input_type& aValue) |
|
792 { |
|
793 NS_ABORT_IF_FALSE(aValue.GetUnit() == eCSSUnit_Number, "unexpected unit"); |
|
794 aValue.AppendToString(mProperty, mResult, mValueSerialization); |
|
795 } |
|
796 |
|
797 private: |
|
798 nsCSSProperty mProperty; |
|
799 nsAString &mResult; |
|
800 nsCSSValue::Serialization mValueSerialization; |
|
801 }; |
|
802 |
|
803 } // anonymous namespace |
|
804 |
|
805 void |
|
806 nsCSSValue::AppendToString(nsCSSProperty aProperty, nsAString& aResult, |
|
807 Serialization aSerialization) const |
|
808 { |
|
809 // eCSSProperty_UNKNOWN gets used for some recursive calls below. |
|
810 NS_ABORT_IF_FALSE((0 <= aProperty && |
|
811 aProperty <= eCSSProperty_COUNT_no_shorthands) || |
|
812 aProperty == eCSSProperty_UNKNOWN, |
|
813 "property ID out of range"); |
|
814 |
|
815 nsCSSUnit unit = GetUnit(); |
|
816 if (unit == eCSSUnit_Null) { |
|
817 return; |
|
818 } |
|
819 |
|
820 if (eCSSUnit_String <= unit && unit <= eCSSUnit_Attr) { |
|
821 if (unit == eCSSUnit_Attr) { |
|
822 aResult.AppendLiteral("attr("); |
|
823 } |
|
824 nsAutoString buffer; |
|
825 GetStringValue(buffer); |
|
826 if (unit == eCSSUnit_String) { |
|
827 nsStyleUtil::AppendEscapedCSSString(buffer, aResult); |
|
828 } else if (unit == eCSSUnit_Families) { |
|
829 // XXX We really need to do *some* escaping. |
|
830 aResult.Append(buffer); |
|
831 } else { |
|
832 nsStyleUtil::AppendEscapedCSSIdent(buffer, aResult); |
|
833 } |
|
834 } |
|
835 else if (eCSSUnit_Array <= unit && unit <= eCSSUnit_Steps) { |
|
836 switch (unit) { |
|
837 case eCSSUnit_Counter: aResult.AppendLiteral("counter("); break; |
|
838 case eCSSUnit_Counters: aResult.AppendLiteral("counters("); break; |
|
839 case eCSSUnit_Cubic_Bezier: aResult.AppendLiteral("cubic-bezier("); break; |
|
840 case eCSSUnit_Steps: aResult.AppendLiteral("steps("); break; |
|
841 default: break; |
|
842 } |
|
843 |
|
844 nsCSSValue::Array *array = GetArrayValue(); |
|
845 bool mark = false; |
|
846 for (size_t i = 0, i_end = array->Count(); i < i_end; ++i) { |
|
847 if (mark && array->Item(i).GetUnit() != eCSSUnit_Null) { |
|
848 if (unit == eCSSUnit_Array && |
|
849 eCSSProperty_transition_timing_function != aProperty) |
|
850 aResult.AppendLiteral(" "); |
|
851 else |
|
852 aResult.AppendLiteral(", "); |
|
853 } |
|
854 if (unit == eCSSUnit_Steps && i == 1) { |
|
855 NS_ABORT_IF_FALSE(array->Item(i).GetUnit() == eCSSUnit_Enumerated && |
|
856 (array->Item(i).GetIntValue() == |
|
857 NS_STYLE_TRANSITION_TIMING_FUNCTION_STEP_START || |
|
858 array->Item(i).GetIntValue() == |
|
859 NS_STYLE_TRANSITION_TIMING_FUNCTION_STEP_END), |
|
860 "unexpected value"); |
|
861 if (array->Item(i).GetIntValue() == |
|
862 NS_STYLE_TRANSITION_TIMING_FUNCTION_STEP_START) { |
|
863 aResult.AppendLiteral("start"); |
|
864 } else { |
|
865 aResult.AppendLiteral("end"); |
|
866 } |
|
867 continue; |
|
868 } |
|
869 nsCSSProperty prop = |
|
870 ((eCSSUnit_Counter <= unit && unit <= eCSSUnit_Counters) && |
|
871 i == array->Count() - 1) |
|
872 ? eCSSProperty_list_style_type : aProperty; |
|
873 if (array->Item(i).GetUnit() != eCSSUnit_Null) { |
|
874 array->Item(i).AppendToString(prop, aResult, aSerialization); |
|
875 mark = true; |
|
876 } |
|
877 } |
|
878 if (eCSSUnit_Array == unit && |
|
879 aProperty == eCSSProperty_transition_timing_function) { |
|
880 aResult.AppendLiteral(")"); |
|
881 } |
|
882 } |
|
883 /* Although Function is backed by an Array, we'll handle it separately |
|
884 * because it's a bit quirky. |
|
885 */ |
|
886 else if (eCSSUnit_Function == unit) { |
|
887 const nsCSSValue::Array* array = GetArrayValue(); |
|
888 NS_ABORT_IF_FALSE(array->Count() >= 1, |
|
889 "Functions must have at least one element for the name."); |
|
890 |
|
891 /* Append the function name. */ |
|
892 const nsCSSValue& functionName = array->Item(0); |
|
893 if (functionName.GetUnit() == eCSSUnit_Enumerated) { |
|
894 // We assume that the first argument is always of nsCSSKeyword type. |
|
895 const nsCSSKeyword functionId = functionName.GetKeywordValue(); |
|
896 NS_ConvertASCIItoUTF16 ident(nsCSSKeywords::GetStringValue(functionId)); |
|
897 // Bug 721136: Normalize the identifier to lowercase, except that things |
|
898 // like scaleX should have the last character capitalized. This matches |
|
899 // what other browsers do. |
|
900 switch (functionId) { |
|
901 case eCSSKeyword_rotatex: |
|
902 case eCSSKeyword_scalex: |
|
903 case eCSSKeyword_skewx: |
|
904 case eCSSKeyword_translatex: |
|
905 ident.Replace(ident.Length() - 1, 1, char16_t('X')); |
|
906 break; |
|
907 |
|
908 case eCSSKeyword_rotatey: |
|
909 case eCSSKeyword_scaley: |
|
910 case eCSSKeyword_skewy: |
|
911 case eCSSKeyword_translatey: |
|
912 ident.Replace(ident.Length() - 1, 1, char16_t('Y')); |
|
913 break; |
|
914 |
|
915 case eCSSKeyword_rotatez: |
|
916 case eCSSKeyword_scalez: |
|
917 case eCSSKeyword_translatez: |
|
918 ident.Replace(ident.Length() - 1, 1, char16_t('Z')); |
|
919 break; |
|
920 |
|
921 default: |
|
922 break; |
|
923 } |
|
924 nsStyleUtil::AppendEscapedCSSIdent(ident, aResult); |
|
925 } else { |
|
926 MOZ_ASSERT(false, "should no longer have non-enumerated functions"); |
|
927 } |
|
928 aResult.AppendLiteral("("); |
|
929 |
|
930 /* Now, step through the function contents, writing each of them as we go. */ |
|
931 for (size_t index = 1; index < array->Count(); ++index) { |
|
932 array->Item(index).AppendToString(aProperty, aResult, |
|
933 aSerialization); |
|
934 |
|
935 /* If we're not at the final element, append a comma. */ |
|
936 if (index + 1 != array->Count()) |
|
937 aResult.AppendLiteral(", "); |
|
938 } |
|
939 |
|
940 /* Finally, append the closing parenthesis. */ |
|
941 aResult.AppendLiteral(")"); |
|
942 } |
|
943 else if (IsCalcUnit()) { |
|
944 NS_ABORT_IF_FALSE(GetUnit() == eCSSUnit_Calc, "unexpected unit"); |
|
945 CSSValueSerializeCalcOps ops(aProperty, aResult, aSerialization); |
|
946 css::SerializeCalc(*this, ops); |
|
947 } |
|
948 else if (eCSSUnit_Integer == unit) { |
|
949 aResult.AppendInt(GetIntValue(), 10); |
|
950 } |
|
951 else if (eCSSUnit_Enumerated == unit) { |
|
952 int32_t intValue = GetIntValue(); |
|
953 switch(aProperty) { |
|
954 |
|
955 |
|
956 case eCSSProperty_text_combine_upright: |
|
957 if (intValue <= NS_STYLE_TEXT_COMBINE_UPRIGHT_ALL) { |
|
958 AppendASCIItoUTF16(nsCSSProps::LookupPropertyValue(aProperty, intValue), |
|
959 aResult); |
|
960 } else if (intValue == NS_STYLE_TEXT_COMBINE_UPRIGHT_DIGITS_2) { |
|
961 aResult.AppendLiteral("digits 2"); |
|
962 } else if (intValue == NS_STYLE_TEXT_COMBINE_UPRIGHT_DIGITS_3) { |
|
963 aResult.AppendLiteral("digits 3"); |
|
964 } else { |
|
965 aResult.AppendLiteral("digits 4"); |
|
966 } |
|
967 break; |
|
968 |
|
969 case eCSSProperty_text_decoration_line: |
|
970 if (NS_STYLE_TEXT_DECORATION_LINE_NONE == intValue) { |
|
971 AppendASCIItoUTF16(nsCSSProps::LookupPropertyValue(aProperty, intValue), |
|
972 aResult); |
|
973 } else { |
|
974 // Ignore the "override all" internal value. |
|
975 // (It doesn't have a string representation.) |
|
976 intValue &= ~NS_STYLE_TEXT_DECORATION_LINE_OVERRIDE_ALL; |
|
977 nsStyleUtil::AppendBitmaskCSSValue( |
|
978 aProperty, intValue, |
|
979 NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE, |
|
980 NS_STYLE_TEXT_DECORATION_LINE_PREF_ANCHORS, |
|
981 aResult); |
|
982 } |
|
983 break; |
|
984 |
|
985 case eCSSProperty_marks: |
|
986 if (intValue == NS_STYLE_PAGE_MARKS_NONE) { |
|
987 AppendASCIItoUTF16(nsCSSProps::LookupPropertyValue(aProperty, intValue), |
|
988 aResult); |
|
989 } else { |
|
990 nsStyleUtil::AppendBitmaskCSSValue(aProperty, intValue, |
|
991 NS_STYLE_PAGE_MARKS_CROP, |
|
992 NS_STYLE_PAGE_MARKS_REGISTER, |
|
993 aResult); |
|
994 } |
|
995 break; |
|
996 |
|
997 case eCSSProperty_paint_order: |
|
998 static_assert |
|
999 (NS_STYLE_PAINT_ORDER_BITWIDTH * NS_STYLE_PAINT_ORDER_LAST_VALUE <= 8, |
|
1000 "SVGStyleStruct::mPaintOrder and the following cast not big enough"); |
|
1001 nsStyleUtil::AppendPaintOrderValue(static_cast<uint8_t>(GetIntValue()), |
|
1002 aResult); |
|
1003 break; |
|
1004 |
|
1005 case eCSSProperty_font_synthesis: |
|
1006 nsStyleUtil::AppendBitmaskCSSValue(aProperty, intValue, |
|
1007 NS_FONT_SYNTHESIS_WEIGHT, |
|
1008 NS_FONT_SYNTHESIS_STYLE, |
|
1009 aResult); |
|
1010 break; |
|
1011 |
|
1012 case eCSSProperty_font_variant_east_asian: |
|
1013 nsStyleUtil::AppendBitmaskCSSValue(aProperty, intValue, |
|
1014 NS_FONT_VARIANT_EAST_ASIAN_JIS78, |
|
1015 NS_FONT_VARIANT_EAST_ASIAN_RUBY, |
|
1016 aResult); |
|
1017 break; |
|
1018 |
|
1019 case eCSSProperty_font_variant_ligatures: |
|
1020 nsStyleUtil::AppendBitmaskCSSValue(aProperty, intValue, |
|
1021 NS_FONT_VARIANT_LIGATURES_NONE, |
|
1022 NS_FONT_VARIANT_LIGATURES_NO_CONTEXTUAL, |
|
1023 aResult); |
|
1024 break; |
|
1025 |
|
1026 case eCSSProperty_font_variant_numeric: |
|
1027 nsStyleUtil::AppendBitmaskCSSValue(aProperty, intValue, |
|
1028 NS_FONT_VARIANT_NUMERIC_LINING, |
|
1029 NS_FONT_VARIANT_NUMERIC_ORDINAL, |
|
1030 aResult); |
|
1031 break; |
|
1032 |
|
1033 case eCSSProperty_grid_auto_flow: |
|
1034 nsStyleUtil::AppendBitmaskCSSValue(aProperty, intValue, |
|
1035 NS_STYLE_GRID_AUTO_FLOW_NONE, |
|
1036 NS_STYLE_GRID_AUTO_FLOW_DENSE, |
|
1037 aResult); |
|
1038 break; |
|
1039 |
|
1040 case eCSSProperty_grid_auto_position: |
|
1041 case eCSSProperty_grid_column_start: |
|
1042 case eCSSProperty_grid_column_end: |
|
1043 case eCSSProperty_grid_row_start: |
|
1044 case eCSSProperty_grid_row_end: |
|
1045 // "span" is the only enumerated-unit value for these properties |
|
1046 aResult.AppendLiteral("span"); |
|
1047 break; |
|
1048 |
|
1049 case eCSSProperty_touch_action: |
|
1050 nsStyleUtil::AppendBitmaskCSSValue(aProperty, intValue, |
|
1051 NS_STYLE_TOUCH_ACTION_NONE, |
|
1052 NS_STYLE_TOUCH_ACTION_MANIPULATION, |
|
1053 aResult); |
|
1054 break; |
|
1055 |
|
1056 default: |
|
1057 const nsAFlatCString& name = nsCSSProps::LookupPropertyValue(aProperty, intValue); |
|
1058 AppendASCIItoUTF16(name, aResult); |
|
1059 break; |
|
1060 } |
|
1061 } |
|
1062 else if (eCSSUnit_EnumColor == unit) { |
|
1063 // we can lookup the property in the ColorTable and then |
|
1064 // get a string mapping the name |
|
1065 nsAutoCString str; |
|
1066 if (nsCSSProps::GetColorName(GetIntValue(), str)){ |
|
1067 AppendASCIItoUTF16(str, aResult); |
|
1068 } else { |
|
1069 NS_ABORT_IF_FALSE(false, "bad color value"); |
|
1070 } |
|
1071 } |
|
1072 else if (IsNumericColorUnit(unit)) { |
|
1073 if (aSerialization == eNormalized || |
|
1074 unit == eCSSUnit_RGBColor || |
|
1075 unit == eCSSUnit_RGBAColor) { |
|
1076 nscolor color = GetColorValue(); |
|
1077 if (aSerialization == eNormalized && |
|
1078 color == NS_RGBA(0, 0, 0, 0)) { |
|
1079 // Use the strictest match for 'transparent' so we do correct |
|
1080 // round-tripping of all other rgba() values. |
|
1081 aResult.AppendLiteral("transparent"); |
|
1082 } else { |
|
1083 uint8_t a = NS_GET_A(color); |
|
1084 bool showAlpha = |
|
1085 (aSerialization == eNormalized && a < 255) || |
|
1086 (aSerialization == eAuthorSpecified && |
|
1087 unit == eCSSUnit_RGBAColor); |
|
1088 if (showAlpha) { |
|
1089 aResult.AppendLiteral("rgba("); |
|
1090 } else { |
|
1091 aResult.AppendLiteral("rgb("); |
|
1092 } |
|
1093 |
|
1094 NS_NAMED_LITERAL_STRING(comma, ", "); |
|
1095 |
|
1096 aResult.AppendInt(NS_GET_R(color), 10); |
|
1097 aResult.Append(comma); |
|
1098 aResult.AppendInt(NS_GET_G(color), 10); |
|
1099 aResult.Append(comma); |
|
1100 aResult.AppendInt(NS_GET_B(color), 10); |
|
1101 if (showAlpha) { |
|
1102 aResult.Append(comma); |
|
1103 aResult.AppendFloat(nsStyleUtil::ColorComponentToFloat(a)); |
|
1104 } |
|
1105 aResult.Append(char16_t(')')); |
|
1106 } |
|
1107 } else if (eCSSUnit_HexColor == unit) { |
|
1108 nscolor color = GetColorValue(); |
|
1109 aResult.Append('#'); |
|
1110 aResult.AppendPrintf("%02x", NS_GET_R(color)); |
|
1111 aResult.AppendPrintf("%02x", NS_GET_G(color)); |
|
1112 aResult.AppendPrintf("%02x", NS_GET_B(color)); |
|
1113 } else if (eCSSUnit_ShortHexColor == unit) { |
|
1114 nscolor color = GetColorValue(); |
|
1115 aResult.Append('#'); |
|
1116 aResult.AppendInt(NS_GET_R(color) / 0x11, 16); |
|
1117 aResult.AppendInt(NS_GET_G(color) / 0x11, 16); |
|
1118 aResult.AppendInt(NS_GET_B(color) / 0x11, 16); |
|
1119 } else { |
|
1120 MOZ_ASSERT(IsFloatColorUnit()); |
|
1121 mValue.mFloatColor->AppendToString(unit, aResult); |
|
1122 } |
|
1123 } |
|
1124 else if (eCSSUnit_URL == unit || eCSSUnit_Image == unit) { |
|
1125 aResult.Append(NS_LITERAL_STRING("url(")); |
|
1126 nsStyleUtil::AppendEscapedCSSString( |
|
1127 nsDependentString(GetOriginalURLValue()), aResult); |
|
1128 aResult.Append(NS_LITERAL_STRING(")")); |
|
1129 } |
|
1130 else if (eCSSUnit_Element == unit) { |
|
1131 aResult.Append(NS_LITERAL_STRING("-moz-element(#")); |
|
1132 nsAutoString tmpStr; |
|
1133 GetStringValue(tmpStr); |
|
1134 nsStyleUtil::AppendEscapedCSSIdent(tmpStr, aResult); |
|
1135 aResult.Append(NS_LITERAL_STRING(")")); |
|
1136 } |
|
1137 else if (eCSSUnit_Percent == unit) { |
|
1138 aResult.AppendFloat(GetPercentValue() * 100.0f); |
|
1139 } |
|
1140 else if (eCSSUnit_Percent < unit) { // length unit |
|
1141 aResult.AppendFloat(GetFloatValue()); |
|
1142 } |
|
1143 else if (eCSSUnit_Gradient == unit) { |
|
1144 nsCSSValueGradient* gradient = GetGradientValue(); |
|
1145 |
|
1146 if (gradient->mIsLegacySyntax) { |
|
1147 aResult.AppendLiteral("-moz-"); |
|
1148 } |
|
1149 if (gradient->mIsRepeating) { |
|
1150 aResult.AppendLiteral("repeating-"); |
|
1151 } |
|
1152 if (gradient->mIsRadial) { |
|
1153 aResult.AppendLiteral("radial-gradient("); |
|
1154 } else { |
|
1155 aResult.AppendLiteral("linear-gradient("); |
|
1156 } |
|
1157 |
|
1158 bool needSep = false; |
|
1159 if (gradient->mIsRadial && !gradient->mIsLegacySyntax) { |
|
1160 if (!gradient->mIsExplicitSize) { |
|
1161 if (gradient->GetRadialShape().GetUnit() != eCSSUnit_None) { |
|
1162 NS_ABORT_IF_FALSE(gradient->GetRadialShape().GetUnit() == |
|
1163 eCSSUnit_Enumerated, |
|
1164 "bad unit for radial gradient shape"); |
|
1165 int32_t intValue = gradient->GetRadialShape().GetIntValue(); |
|
1166 NS_ABORT_IF_FALSE(intValue != NS_STYLE_GRADIENT_SHAPE_LINEAR, |
|
1167 "radial gradient with linear shape?!"); |
|
1168 AppendASCIItoUTF16(nsCSSProps::ValueToKeyword(intValue, |
|
1169 nsCSSProps::kRadialGradientShapeKTable), |
|
1170 aResult); |
|
1171 needSep = true; |
|
1172 } |
|
1173 |
|
1174 if (gradient->GetRadialSize().GetUnit() != eCSSUnit_None) { |
|
1175 if (needSep) { |
|
1176 aResult.AppendLiteral(" "); |
|
1177 } |
|
1178 NS_ABORT_IF_FALSE(gradient->GetRadialSize().GetUnit() == |
|
1179 eCSSUnit_Enumerated, |
|
1180 "bad unit for radial gradient size"); |
|
1181 int32_t intValue = gradient->GetRadialSize().GetIntValue(); |
|
1182 AppendASCIItoUTF16(nsCSSProps::ValueToKeyword(intValue, |
|
1183 nsCSSProps::kRadialGradientSizeKTable), |
|
1184 aResult); |
|
1185 needSep = true; |
|
1186 } |
|
1187 } else { |
|
1188 NS_ABORT_IF_FALSE(gradient->GetRadiusX().GetUnit() != eCSSUnit_None, |
|
1189 "bad unit for radial gradient explicit size"); |
|
1190 gradient->GetRadiusX().AppendToString(aProperty, aResult, |
|
1191 aSerialization); |
|
1192 if (gradient->GetRadiusY().GetUnit() != eCSSUnit_None) { |
|
1193 aResult.AppendLiteral(" "); |
|
1194 gradient->GetRadiusY().AppendToString(aProperty, aResult, |
|
1195 aSerialization); |
|
1196 } |
|
1197 needSep = true; |
|
1198 } |
|
1199 } |
|
1200 if (!gradient->mIsRadial && !gradient->mIsLegacySyntax) { |
|
1201 if (gradient->mBgPos.mXValue.GetUnit() != eCSSUnit_None || |
|
1202 gradient->mBgPos.mYValue.GetUnit() != eCSSUnit_None) { |
|
1203 MOZ_ASSERT(gradient->mAngle.GetUnit() == eCSSUnit_None); |
|
1204 NS_ABORT_IF_FALSE(gradient->mBgPos.mXValue.GetUnit() == eCSSUnit_Enumerated && |
|
1205 gradient->mBgPos.mYValue.GetUnit() == eCSSUnit_Enumerated, |
|
1206 "unexpected unit"); |
|
1207 aResult.AppendLiteral("to"); |
|
1208 if (!(gradient->mBgPos.mXValue.GetIntValue() & NS_STYLE_BG_POSITION_CENTER)) { |
|
1209 aResult.AppendLiteral(" "); |
|
1210 gradient->mBgPos.mXValue.AppendToString(eCSSProperty_background_position, |
|
1211 aResult, aSerialization); |
|
1212 } |
|
1213 if (!(gradient->mBgPos.mYValue.GetIntValue() & NS_STYLE_BG_POSITION_CENTER)) { |
|
1214 aResult.AppendLiteral(" "); |
|
1215 gradient->mBgPos.mYValue.AppendToString(eCSSProperty_background_position, |
|
1216 aResult, aSerialization); |
|
1217 } |
|
1218 needSep = true; |
|
1219 } else if (gradient->mAngle.GetUnit() != eCSSUnit_None) { |
|
1220 gradient->mAngle.AppendToString(aProperty, aResult, aSerialization); |
|
1221 needSep = true; |
|
1222 } |
|
1223 } else if (gradient->mBgPos.mXValue.GetUnit() != eCSSUnit_None || |
|
1224 gradient->mBgPos.mYValue.GetUnit() != eCSSUnit_None || |
|
1225 gradient->mAngle.GetUnit() != eCSSUnit_None) { |
|
1226 if (needSep) { |
|
1227 aResult.AppendLiteral(" "); |
|
1228 } |
|
1229 if (gradient->mIsRadial && !gradient->mIsLegacySyntax) { |
|
1230 aResult.AppendLiteral("at "); |
|
1231 } |
|
1232 if (gradient->mBgPos.mXValue.GetUnit() != eCSSUnit_None) { |
|
1233 gradient->mBgPos.mXValue.AppendToString(eCSSProperty_background_position, |
|
1234 aResult, aSerialization); |
|
1235 aResult.AppendLiteral(" "); |
|
1236 } |
|
1237 if (gradient->mBgPos.mXValue.GetUnit() != eCSSUnit_None) { |
|
1238 gradient->mBgPos.mYValue.AppendToString(eCSSProperty_background_position, |
|
1239 aResult, aSerialization); |
|
1240 aResult.AppendLiteral(" "); |
|
1241 } |
|
1242 if (gradient->mAngle.GetUnit() != eCSSUnit_None) { |
|
1243 NS_ABORT_IF_FALSE(gradient->mIsLegacySyntax, |
|
1244 "angle is allowed only for legacy syntax"); |
|
1245 gradient->mAngle.AppendToString(aProperty, aResult, aSerialization); |
|
1246 } |
|
1247 needSep = true; |
|
1248 } |
|
1249 |
|
1250 if (gradient->mIsRadial && gradient->mIsLegacySyntax && |
|
1251 (gradient->GetRadialShape().GetUnit() != eCSSUnit_None || |
|
1252 gradient->GetRadialSize().GetUnit() != eCSSUnit_None)) { |
|
1253 MOZ_ASSERT(!gradient->mIsExplicitSize); |
|
1254 if (needSep) { |
|
1255 aResult.AppendLiteral(", "); |
|
1256 } |
|
1257 if (gradient->GetRadialShape().GetUnit() != eCSSUnit_None) { |
|
1258 NS_ABORT_IF_FALSE(gradient->GetRadialShape().GetUnit() == |
|
1259 eCSSUnit_Enumerated, |
|
1260 "bad unit for radial gradient shape"); |
|
1261 int32_t intValue = gradient->GetRadialShape().GetIntValue(); |
|
1262 NS_ABORT_IF_FALSE(intValue != NS_STYLE_GRADIENT_SHAPE_LINEAR, |
|
1263 "radial gradient with linear shape?!"); |
|
1264 AppendASCIItoUTF16(nsCSSProps::ValueToKeyword(intValue, |
|
1265 nsCSSProps::kRadialGradientShapeKTable), |
|
1266 aResult); |
|
1267 aResult.AppendLiteral(" "); |
|
1268 } |
|
1269 |
|
1270 if (gradient->GetRadialSize().GetUnit() != eCSSUnit_None) { |
|
1271 NS_ABORT_IF_FALSE(gradient->GetRadialSize().GetUnit() == |
|
1272 eCSSUnit_Enumerated, |
|
1273 "bad unit for radial gradient size"); |
|
1274 int32_t intValue = gradient->GetRadialSize().GetIntValue(); |
|
1275 AppendASCIItoUTF16(nsCSSProps::ValueToKeyword(intValue, |
|
1276 nsCSSProps::kRadialGradientSizeKTable), |
|
1277 aResult); |
|
1278 } |
|
1279 needSep = true; |
|
1280 } |
|
1281 if (needSep) { |
|
1282 aResult.AppendLiteral(", "); |
|
1283 } |
|
1284 |
|
1285 for (uint32_t i = 0 ;;) { |
|
1286 gradient->mStops[i].mColor.AppendToString(aProperty, aResult, |
|
1287 aSerialization); |
|
1288 if (gradient->mStops[i].mLocation.GetUnit() != eCSSUnit_None) { |
|
1289 aResult.AppendLiteral(" "); |
|
1290 gradient->mStops[i].mLocation.AppendToString(aProperty, aResult, |
|
1291 aSerialization); |
|
1292 } |
|
1293 if (++i == gradient->mStops.Length()) { |
|
1294 break; |
|
1295 } |
|
1296 aResult.AppendLiteral(", "); |
|
1297 } |
|
1298 |
|
1299 aResult.AppendLiteral(")"); |
|
1300 } else if (eCSSUnit_TokenStream == unit) { |
|
1301 nsCSSProperty shorthand = mValue.mTokenStream->mShorthandPropertyID; |
|
1302 if (shorthand == eCSSProperty_UNKNOWN || |
|
1303 nsCSSProps::PropHasFlags(shorthand, CSS_PROPERTY_IS_ALIAS) || |
|
1304 aProperty == eCSSProperty__x_system_font) { |
|
1305 // We treat serialization of aliases like '-moz-transform' as a special |
|
1306 // case, since it really wants to be serialized as if it were a longhand |
|
1307 // even though it is implemented as a shorthand. |
|
1308 aResult.Append(mValue.mTokenStream->mTokenStream); |
|
1309 } |
|
1310 } else if (eCSSUnit_Pair == unit) { |
|
1311 if (eCSSProperty_font_variant_alternates == aProperty) { |
|
1312 int32_t intValue = GetPairValue().mXValue.GetIntValue(); |
|
1313 nsAutoString out; |
|
1314 |
|
1315 // simple, enumerated values |
|
1316 nsStyleUtil::AppendBitmaskCSSValue(aProperty, |
|
1317 intValue & NS_FONT_VARIANT_ALTERNATES_ENUMERATED_MASK, |
|
1318 NS_FONT_VARIANT_ALTERNATES_HISTORICAL, |
|
1319 NS_FONT_VARIANT_ALTERNATES_HISTORICAL, |
|
1320 out); |
|
1321 |
|
1322 // functional values |
|
1323 const nsCSSValueList *list = GetPairValue().mYValue.GetListValue(); |
|
1324 nsAutoTArray<gfxAlternateValue,8> altValues; |
|
1325 |
|
1326 nsStyleUtil::ComputeFunctionalAlternates(list, altValues); |
|
1327 nsStyleUtil::SerializeFunctionalAlternates(altValues, out); |
|
1328 aResult.Append(out); |
|
1329 } else if (eCSSProperty_grid_auto_position == aProperty) { |
|
1330 GetPairValue().mXValue.AppendToString(aProperty, aResult, aSerialization); |
|
1331 aResult.AppendLiteral(" / "); |
|
1332 GetPairValue().mYValue.AppendToString(aProperty, aResult, aSerialization); |
|
1333 } else { |
|
1334 GetPairValue().AppendToString(aProperty, aResult, aSerialization); |
|
1335 } |
|
1336 } else if (eCSSUnit_Triplet == unit) { |
|
1337 GetTripletValue().AppendToString(aProperty, aResult, aSerialization); |
|
1338 } else if (eCSSUnit_Rect == unit) { |
|
1339 GetRectValue().AppendToString(aProperty, aResult, aSerialization); |
|
1340 } else if (eCSSUnit_List == unit || eCSSUnit_ListDep == unit) { |
|
1341 GetListValue()->AppendToString(aProperty, aResult, aSerialization); |
|
1342 } else if (eCSSUnit_SharedList == unit) { |
|
1343 GetSharedListValue()->AppendToString(aProperty, aResult, aSerialization); |
|
1344 } else if (eCSSUnit_PairList == unit || eCSSUnit_PairListDep == unit) { |
|
1345 switch (aProperty) { |
|
1346 case eCSSProperty_font_feature_settings: |
|
1347 nsStyleUtil::AppendFontFeatureSettings(*this, aResult); |
|
1348 break; |
|
1349 default: |
|
1350 GetPairListValue()->AppendToString(aProperty, aResult, aSerialization); |
|
1351 break; |
|
1352 } |
|
1353 } else if (eCSSUnit_GridTemplateAreas == unit) { |
|
1354 const mozilla::css::GridTemplateAreasValue* areas = GetGridTemplateAreas(); |
|
1355 MOZ_ASSERT(!areas->mTemplates.IsEmpty(), |
|
1356 "Unexpected empty array in GridTemplateAreasValue"); |
|
1357 nsStyleUtil::AppendEscapedCSSString(areas->mTemplates[0], aResult); |
|
1358 for (uint32_t i = 1; i < areas->mTemplates.Length(); i++) { |
|
1359 aResult.Append(char16_t(' ')); |
|
1360 nsStyleUtil::AppendEscapedCSSString(areas->mTemplates[i], aResult); |
|
1361 } |
|
1362 } |
|
1363 |
|
1364 switch (unit) { |
|
1365 case eCSSUnit_Null: break; |
|
1366 case eCSSUnit_Auto: aResult.AppendLiteral("auto"); break; |
|
1367 case eCSSUnit_Inherit: aResult.AppendLiteral("inherit"); break; |
|
1368 case eCSSUnit_Initial: aResult.AppendLiteral("initial"); break; |
|
1369 case eCSSUnit_Unset: aResult.AppendLiteral("unset"); break; |
|
1370 case eCSSUnit_None: aResult.AppendLiteral("none"); break; |
|
1371 case eCSSUnit_Normal: aResult.AppendLiteral("normal"); break; |
|
1372 case eCSSUnit_System_Font: aResult.AppendLiteral("-moz-use-system-font"); break; |
|
1373 case eCSSUnit_All: aResult.AppendLiteral("all"); break; |
|
1374 case eCSSUnit_Dummy: |
|
1375 case eCSSUnit_DummyInherit: |
|
1376 NS_ABORT_IF_FALSE(false, "should never serialize"); |
|
1377 break; |
|
1378 |
|
1379 case eCSSUnit_String: break; |
|
1380 case eCSSUnit_Ident: break; |
|
1381 case eCSSUnit_Families: break; |
|
1382 case eCSSUnit_URL: break; |
|
1383 case eCSSUnit_Image: break; |
|
1384 case eCSSUnit_Element: break; |
|
1385 case eCSSUnit_Array: break; |
|
1386 case eCSSUnit_Attr: |
|
1387 case eCSSUnit_Cubic_Bezier: |
|
1388 case eCSSUnit_Steps: |
|
1389 case eCSSUnit_Counter: |
|
1390 case eCSSUnit_Counters: aResult.Append(char16_t(')')); break; |
|
1391 case eCSSUnit_Local_Font: break; |
|
1392 case eCSSUnit_Font_Format: break; |
|
1393 case eCSSUnit_Function: break; |
|
1394 case eCSSUnit_Calc: break; |
|
1395 case eCSSUnit_Calc_Plus: break; |
|
1396 case eCSSUnit_Calc_Minus: break; |
|
1397 case eCSSUnit_Calc_Times_L: break; |
|
1398 case eCSSUnit_Calc_Times_R: break; |
|
1399 case eCSSUnit_Calc_Divided: break; |
|
1400 case eCSSUnit_Integer: break; |
|
1401 case eCSSUnit_Enumerated: break; |
|
1402 case eCSSUnit_EnumColor: break; |
|
1403 case eCSSUnit_RGBColor: break; |
|
1404 case eCSSUnit_RGBAColor: break; |
|
1405 case eCSSUnit_HexColor: break; |
|
1406 case eCSSUnit_ShortHexColor: break; |
|
1407 case eCSSUnit_PercentageRGBColor: break; |
|
1408 case eCSSUnit_PercentageRGBAColor: break; |
|
1409 case eCSSUnit_HSLColor: break; |
|
1410 case eCSSUnit_HSLAColor: break; |
|
1411 case eCSSUnit_Percent: aResult.Append(char16_t('%')); break; |
|
1412 case eCSSUnit_Number: break; |
|
1413 case eCSSUnit_Gradient: break; |
|
1414 case eCSSUnit_TokenStream: break; |
|
1415 case eCSSUnit_Pair: break; |
|
1416 case eCSSUnit_Triplet: break; |
|
1417 case eCSSUnit_Rect: break; |
|
1418 case eCSSUnit_List: break; |
|
1419 case eCSSUnit_ListDep: break; |
|
1420 case eCSSUnit_SharedList: break; |
|
1421 case eCSSUnit_PairList: break; |
|
1422 case eCSSUnit_PairListDep: break; |
|
1423 case eCSSUnit_GridTemplateAreas: break; |
|
1424 |
|
1425 case eCSSUnit_Inch: aResult.AppendLiteral("in"); break; |
|
1426 case eCSSUnit_Millimeter: aResult.AppendLiteral("mm"); break; |
|
1427 case eCSSUnit_PhysicalMillimeter: aResult.AppendLiteral("mozmm"); break; |
|
1428 case eCSSUnit_Centimeter: aResult.AppendLiteral("cm"); break; |
|
1429 case eCSSUnit_Point: aResult.AppendLiteral("pt"); break; |
|
1430 case eCSSUnit_Pica: aResult.AppendLiteral("pc"); break; |
|
1431 |
|
1432 case eCSSUnit_ViewportWidth: aResult.AppendLiteral("vw"); break; |
|
1433 case eCSSUnit_ViewportHeight: aResult.AppendLiteral("vh"); break; |
|
1434 case eCSSUnit_ViewportMin: aResult.AppendLiteral("vmin"); break; |
|
1435 case eCSSUnit_ViewportMax: aResult.AppendLiteral("vmax"); break; |
|
1436 |
|
1437 case eCSSUnit_EM: aResult.AppendLiteral("em"); break; |
|
1438 case eCSSUnit_XHeight: aResult.AppendLiteral("ex"); break; |
|
1439 case eCSSUnit_Char: aResult.AppendLiteral("ch"); break; |
|
1440 case eCSSUnit_RootEM: aResult.AppendLiteral("rem"); break; |
|
1441 |
|
1442 case eCSSUnit_Pixel: aResult.AppendLiteral("px"); break; |
|
1443 |
|
1444 case eCSSUnit_Degree: aResult.AppendLiteral("deg"); break; |
|
1445 case eCSSUnit_Grad: aResult.AppendLiteral("grad"); break; |
|
1446 case eCSSUnit_Radian: aResult.AppendLiteral("rad"); break; |
|
1447 case eCSSUnit_Turn: aResult.AppendLiteral("turn"); break; |
|
1448 |
|
1449 case eCSSUnit_Hertz: aResult.AppendLiteral("Hz"); break; |
|
1450 case eCSSUnit_Kilohertz: aResult.AppendLiteral("kHz"); break; |
|
1451 |
|
1452 case eCSSUnit_Seconds: aResult.Append(char16_t('s')); break; |
|
1453 case eCSSUnit_Milliseconds: aResult.AppendLiteral("ms"); break; |
|
1454 |
|
1455 case eCSSUnit_FlexFraction: aResult.AppendLiteral("fr"); break; |
|
1456 } |
|
1457 } |
|
1458 |
|
1459 size_t |
|
1460 nsCSSValue::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const |
|
1461 { |
|
1462 size_t n = 0; |
|
1463 |
|
1464 switch (GetUnit()) { |
|
1465 // No value: nothing extra to measure. |
|
1466 case eCSSUnit_Null: |
|
1467 case eCSSUnit_Auto: |
|
1468 case eCSSUnit_Inherit: |
|
1469 case eCSSUnit_Initial: |
|
1470 case eCSSUnit_Unset: |
|
1471 case eCSSUnit_None: |
|
1472 case eCSSUnit_Normal: |
|
1473 case eCSSUnit_System_Font: |
|
1474 case eCSSUnit_All: |
|
1475 case eCSSUnit_Dummy: |
|
1476 case eCSSUnit_DummyInherit: |
|
1477 break; |
|
1478 |
|
1479 // String |
|
1480 case eCSSUnit_String: |
|
1481 case eCSSUnit_Ident: |
|
1482 case eCSSUnit_Families: |
|
1483 case eCSSUnit_Attr: |
|
1484 case eCSSUnit_Local_Font: |
|
1485 case eCSSUnit_Font_Format: |
|
1486 case eCSSUnit_Element: |
|
1487 n += mValue.mString->SizeOfIncludingThisIfUnshared(aMallocSizeOf); |
|
1488 break; |
|
1489 |
|
1490 // Array |
|
1491 case eCSSUnit_Array: |
|
1492 case eCSSUnit_Counter: |
|
1493 case eCSSUnit_Counters: |
|
1494 case eCSSUnit_Cubic_Bezier: |
|
1495 case eCSSUnit_Steps: |
|
1496 case eCSSUnit_Function: |
|
1497 case eCSSUnit_Calc: |
|
1498 case eCSSUnit_Calc_Plus: |
|
1499 case eCSSUnit_Calc_Minus: |
|
1500 case eCSSUnit_Calc_Times_L: |
|
1501 case eCSSUnit_Calc_Times_R: |
|
1502 case eCSSUnit_Calc_Divided: |
|
1503 break; |
|
1504 |
|
1505 // URL |
|
1506 case eCSSUnit_URL: |
|
1507 n += mValue.mURL->SizeOfIncludingThis(aMallocSizeOf); |
|
1508 break; |
|
1509 |
|
1510 // Image |
|
1511 case eCSSUnit_Image: |
|
1512 // Not yet measured. Measurement may be added later if DMD finds it |
|
1513 // worthwhile. |
|
1514 break; |
|
1515 |
|
1516 // Gradient |
|
1517 case eCSSUnit_Gradient: |
|
1518 n += mValue.mGradient->SizeOfIncludingThis(aMallocSizeOf); |
|
1519 break; |
|
1520 |
|
1521 // TokenStream |
|
1522 case eCSSUnit_TokenStream: |
|
1523 n += mValue.mTokenStream->SizeOfIncludingThis(aMallocSizeOf); |
|
1524 break; |
|
1525 |
|
1526 // Pair |
|
1527 case eCSSUnit_Pair: |
|
1528 n += mValue.mPair->SizeOfIncludingThis(aMallocSizeOf); |
|
1529 break; |
|
1530 |
|
1531 // Triplet |
|
1532 case eCSSUnit_Triplet: |
|
1533 n += mValue.mTriplet->SizeOfIncludingThis(aMallocSizeOf); |
|
1534 break; |
|
1535 |
|
1536 // Rect |
|
1537 case eCSSUnit_Rect: |
|
1538 n += mValue.mRect->SizeOfIncludingThis(aMallocSizeOf); |
|
1539 break; |
|
1540 |
|
1541 // List |
|
1542 case eCSSUnit_List: |
|
1543 n += mValue.mList->SizeOfIncludingThis(aMallocSizeOf); |
|
1544 break; |
|
1545 |
|
1546 // ListDep: not measured because it's non-owning. |
|
1547 case eCSSUnit_ListDep: |
|
1548 break; |
|
1549 |
|
1550 // SharedList |
|
1551 case eCSSUnit_SharedList: |
|
1552 // Makes more sense not to measure, since it most cases the list |
|
1553 // will be shared. |
|
1554 break; |
|
1555 |
|
1556 // PairList |
|
1557 case eCSSUnit_PairList: |
|
1558 n += mValue.mPairList->SizeOfIncludingThis(aMallocSizeOf); |
|
1559 break; |
|
1560 |
|
1561 // PairListDep: not measured because it's non-owning. |
|
1562 case eCSSUnit_PairListDep: |
|
1563 break; |
|
1564 |
|
1565 // GridTemplateAreas |
|
1566 case eCSSUnit_GridTemplateAreas: |
|
1567 n += mValue.mGridTemplateAreas->SizeOfIncludingThis(aMallocSizeOf); |
|
1568 break; |
|
1569 |
|
1570 // Int: nothing extra to measure. |
|
1571 case eCSSUnit_Integer: |
|
1572 case eCSSUnit_Enumerated: |
|
1573 case eCSSUnit_EnumColor: |
|
1574 break; |
|
1575 |
|
1576 // Integer Color: nothing extra to measure. |
|
1577 case eCSSUnit_RGBColor: |
|
1578 case eCSSUnit_RGBAColor: |
|
1579 case eCSSUnit_HexColor: |
|
1580 case eCSSUnit_ShortHexColor: |
|
1581 break; |
|
1582 |
|
1583 // Float Color |
|
1584 case eCSSUnit_PercentageRGBColor: |
|
1585 case eCSSUnit_PercentageRGBAColor: |
|
1586 case eCSSUnit_HSLColor: |
|
1587 case eCSSUnit_HSLAColor: |
|
1588 n += mValue.mFloatColor->SizeOfIncludingThis(aMallocSizeOf); |
|
1589 break; |
|
1590 |
|
1591 // Float: nothing extra to measure. |
|
1592 case eCSSUnit_Percent: |
|
1593 case eCSSUnit_Number: |
|
1594 case eCSSUnit_PhysicalMillimeter: |
|
1595 case eCSSUnit_ViewportWidth: |
|
1596 case eCSSUnit_ViewportHeight: |
|
1597 case eCSSUnit_ViewportMin: |
|
1598 case eCSSUnit_ViewportMax: |
|
1599 case eCSSUnit_EM: |
|
1600 case eCSSUnit_XHeight: |
|
1601 case eCSSUnit_Char: |
|
1602 case eCSSUnit_RootEM: |
|
1603 case eCSSUnit_Point: |
|
1604 case eCSSUnit_Inch: |
|
1605 case eCSSUnit_Millimeter: |
|
1606 case eCSSUnit_Centimeter: |
|
1607 case eCSSUnit_Pica: |
|
1608 case eCSSUnit_Pixel: |
|
1609 case eCSSUnit_Degree: |
|
1610 case eCSSUnit_Grad: |
|
1611 case eCSSUnit_Turn: |
|
1612 case eCSSUnit_Radian: |
|
1613 case eCSSUnit_Hertz: |
|
1614 case eCSSUnit_Kilohertz: |
|
1615 case eCSSUnit_Seconds: |
|
1616 case eCSSUnit_Milliseconds: |
|
1617 case eCSSUnit_FlexFraction: |
|
1618 break; |
|
1619 |
|
1620 default: |
|
1621 NS_ABORT_IF_FALSE(false, "bad nsCSSUnit"); |
|
1622 break; |
|
1623 } |
|
1624 |
|
1625 return n; |
|
1626 } |
|
1627 |
|
1628 // --- nsCSSValueList ----------------- |
|
1629 |
|
1630 nsCSSValueList::~nsCSSValueList() |
|
1631 { |
|
1632 MOZ_COUNT_DTOR(nsCSSValueList); |
|
1633 NS_CSS_DELETE_LIST_MEMBER(nsCSSValueList, this, mNext); |
|
1634 } |
|
1635 |
|
1636 nsCSSValueList* |
|
1637 nsCSSValueList::Clone() const |
|
1638 { |
|
1639 nsCSSValueList* result = new nsCSSValueList(*this); |
|
1640 nsCSSValueList* dest = result; |
|
1641 const nsCSSValueList* src = this->mNext; |
|
1642 while (src) { |
|
1643 dest->mNext = new nsCSSValueList(*src); |
|
1644 dest = dest->mNext; |
|
1645 src = src->mNext; |
|
1646 } |
|
1647 return result; |
|
1648 } |
|
1649 |
|
1650 void |
|
1651 nsCSSValueList::CloneInto(nsCSSValueList* aList) const |
|
1652 { |
|
1653 NS_ASSERTION(!aList->mNext, "Must be an empty list!"); |
|
1654 aList->mValue = mValue; |
|
1655 aList->mNext = mNext ? mNext->Clone() : nullptr; |
|
1656 } |
|
1657 |
|
1658 static void |
|
1659 AppendValueListToString(const nsCSSValueList* val, |
|
1660 nsCSSProperty aProperty, nsAString& aResult, |
|
1661 nsCSSValue::Serialization aSerialization) |
|
1662 { |
|
1663 for (;;) { |
|
1664 val->mValue.AppendToString(aProperty, aResult, aSerialization); |
|
1665 val = val->mNext; |
|
1666 if (!val) |
|
1667 break; |
|
1668 |
|
1669 if (nsCSSProps::PropHasFlags(aProperty, |
|
1670 CSS_PROPERTY_VALUE_LIST_USES_COMMAS)) |
|
1671 aResult.Append(char16_t(',')); |
|
1672 aResult.Append(char16_t(' ')); |
|
1673 } |
|
1674 } |
|
1675 |
|
1676 static void |
|
1677 AppendGridTemplateToString(const nsCSSValueList* val, |
|
1678 nsCSSProperty aProperty, nsAString& aResult, |
|
1679 nsCSSValue::Serialization aSerialization) |
|
1680 { |
|
1681 // This is called for the "list" that's the top-level value of the property. |
|
1682 bool isSubgrid = false; |
|
1683 for (;;) { |
|
1684 bool addSpaceSeparator = true; |
|
1685 nsCSSUnit unit = val->mValue.GetUnit(); |
|
1686 |
|
1687 if (unit == eCSSUnit_Enumerated && |
|
1688 val->mValue.GetIntValue() == NS_STYLE_GRID_TEMPLATE_SUBGRID) { |
|
1689 isSubgrid = true; |
|
1690 aResult.AppendLiteral("subgrid"); |
|
1691 |
|
1692 } else if (unit == eCSSUnit_Null) { |
|
1693 // Empty or omitted <line-names>. |
|
1694 if (isSubgrid) { |
|
1695 aResult.AppendLiteral("()"); |
|
1696 } else { |
|
1697 // Serializes to nothing. |
|
1698 addSpaceSeparator = false; // Avoid a double space. |
|
1699 } |
|
1700 |
|
1701 } else if (unit == eCSSUnit_List || unit == eCSSUnit_ListDep) { |
|
1702 // Non-empty <line-names> |
|
1703 aResult.AppendLiteral("("); |
|
1704 AppendValueListToString(val->mValue.GetListValue(), aProperty, |
|
1705 aResult, aSerialization); |
|
1706 aResult.AppendLiteral(")"); |
|
1707 |
|
1708 } else { |
|
1709 // <track-size> |
|
1710 val->mValue.AppendToString(aProperty, aResult, aSerialization); |
|
1711 if (!isSubgrid && |
|
1712 val->mNext && |
|
1713 val->mNext->mValue.GetUnit() == eCSSUnit_Null && |
|
1714 !val->mNext->mNext) { |
|
1715 // Break out of the loop early to avoid a trailing space. |
|
1716 break; |
|
1717 } |
|
1718 } |
|
1719 |
|
1720 val = val->mNext; |
|
1721 if (!val) { |
|
1722 break; |
|
1723 } |
|
1724 |
|
1725 if (addSpaceSeparator) { |
|
1726 aResult.Append(char16_t(' ')); |
|
1727 } |
|
1728 } |
|
1729 } |
|
1730 |
|
1731 void |
|
1732 nsCSSValueList::AppendToString(nsCSSProperty aProperty, nsAString& aResult, |
|
1733 nsCSSValue::Serialization aSerialization) const |
|
1734 { |
|
1735 if (aProperty == eCSSProperty_grid_template_columns || |
|
1736 aProperty == eCSSProperty_grid_template_rows) { |
|
1737 AppendGridTemplateToString(this, aProperty, aResult, aSerialization); |
|
1738 } else { |
|
1739 AppendValueListToString(this, aProperty, aResult, aSerialization); |
|
1740 } |
|
1741 } |
|
1742 |
|
1743 bool |
|
1744 nsCSSValueList::operator==(const nsCSSValueList& aOther) const |
|
1745 { |
|
1746 if (this == &aOther) |
|
1747 return true; |
|
1748 |
|
1749 const nsCSSValueList *p1 = this, *p2 = &aOther; |
|
1750 for ( ; p1 && p2; p1 = p1->mNext, p2 = p2->mNext) { |
|
1751 if (p1->mValue != p2->mValue) |
|
1752 return false; |
|
1753 } |
|
1754 return !p1 && !p2; // true if same length, false otherwise |
|
1755 } |
|
1756 |
|
1757 size_t |
|
1758 nsCSSValueList::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const |
|
1759 { |
|
1760 size_t n = 0; |
|
1761 const nsCSSValueList* v = this; |
|
1762 while (v) { |
|
1763 n += aMallocSizeOf(v); |
|
1764 n += v->mValue.SizeOfExcludingThis(aMallocSizeOf); |
|
1765 v = v->mNext; |
|
1766 } |
|
1767 return n; |
|
1768 } |
|
1769 |
|
1770 size_t |
|
1771 nsCSSValueList_heap::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const |
|
1772 { |
|
1773 size_t n = aMallocSizeOf(this); |
|
1774 n += mValue.SizeOfExcludingThis(aMallocSizeOf); |
|
1775 n += mNext ? mNext->SizeOfIncludingThis(aMallocSizeOf) : 0; |
|
1776 return n; |
|
1777 } |
|
1778 |
|
1779 // --- nsCSSValueSharedList ----------------- |
|
1780 |
|
1781 nsCSSValueSharedList::~nsCSSValueSharedList() |
|
1782 { |
|
1783 MOZ_COUNT_DTOR(nsCSSValueSharedList); |
|
1784 if (mHead) { |
|
1785 NS_CSS_DELETE_LIST_MEMBER(nsCSSValueList, mHead, mNext); |
|
1786 delete mHead; |
|
1787 } |
|
1788 } |
|
1789 |
|
1790 void |
|
1791 nsCSSValueSharedList::AppendToString(nsCSSProperty aProperty, nsAString& aResult, |
|
1792 nsCSSValue::Serialization aSerialization) const |
|
1793 { |
|
1794 if (mHead) { |
|
1795 mHead->AppendToString(aProperty, aResult, aSerialization); |
|
1796 } |
|
1797 } |
|
1798 |
|
1799 bool |
|
1800 nsCSSValueSharedList::operator==(const nsCSSValueSharedList& aOther) const |
|
1801 { |
|
1802 return !mHead == !aOther.mHead && |
|
1803 (!mHead || *mHead == *aOther.mHead); |
|
1804 } |
|
1805 |
|
1806 size_t |
|
1807 nsCSSValueSharedList::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const |
|
1808 { |
|
1809 size_t n = 0; |
|
1810 n += aMallocSizeOf(this); |
|
1811 n += mHead->SizeOfIncludingThis(aMallocSizeOf); |
|
1812 return n; |
|
1813 } |
|
1814 |
|
1815 // --- nsCSSRect ----------------- |
|
1816 |
|
1817 nsCSSRect::nsCSSRect(void) |
|
1818 { |
|
1819 MOZ_COUNT_CTOR(nsCSSRect); |
|
1820 } |
|
1821 |
|
1822 nsCSSRect::nsCSSRect(const nsCSSRect& aCopy) |
|
1823 : mTop(aCopy.mTop), |
|
1824 mRight(aCopy.mRight), |
|
1825 mBottom(aCopy.mBottom), |
|
1826 mLeft(aCopy.mLeft) |
|
1827 { |
|
1828 MOZ_COUNT_CTOR(nsCSSRect); |
|
1829 } |
|
1830 |
|
1831 nsCSSRect::~nsCSSRect() |
|
1832 { |
|
1833 MOZ_COUNT_DTOR(nsCSSRect); |
|
1834 } |
|
1835 |
|
1836 void |
|
1837 nsCSSRect::AppendToString(nsCSSProperty aProperty, nsAString& aResult, |
|
1838 nsCSSValue::Serialization aSerialization) const |
|
1839 { |
|
1840 NS_ABORT_IF_FALSE(mTop.GetUnit() != eCSSUnit_Null && |
|
1841 mTop.GetUnit() != eCSSUnit_Inherit && |
|
1842 mTop.GetUnit() != eCSSUnit_Initial && |
|
1843 mTop.GetUnit() != eCSSUnit_Unset, |
|
1844 "parser should have used a bare value"); |
|
1845 |
|
1846 if (eCSSProperty_border_image_slice == aProperty || |
|
1847 eCSSProperty_border_image_width == aProperty || |
|
1848 eCSSProperty_border_image_outset == aProperty) { |
|
1849 NS_NAMED_LITERAL_STRING(space, " "); |
|
1850 |
|
1851 mTop.AppendToString(aProperty, aResult, aSerialization); |
|
1852 aResult.Append(space); |
|
1853 mRight.AppendToString(aProperty, aResult, aSerialization); |
|
1854 aResult.Append(space); |
|
1855 mBottom.AppendToString(aProperty, aResult, aSerialization); |
|
1856 aResult.Append(space); |
|
1857 mLeft.AppendToString(aProperty, aResult, aSerialization); |
|
1858 } else { |
|
1859 NS_NAMED_LITERAL_STRING(comma, ", "); |
|
1860 |
|
1861 aResult.AppendLiteral("rect("); |
|
1862 mTop.AppendToString(aProperty, aResult, aSerialization); |
|
1863 aResult.Append(comma); |
|
1864 mRight.AppendToString(aProperty, aResult, aSerialization); |
|
1865 aResult.Append(comma); |
|
1866 mBottom.AppendToString(aProperty, aResult, aSerialization); |
|
1867 aResult.Append(comma); |
|
1868 mLeft.AppendToString(aProperty, aResult, aSerialization); |
|
1869 aResult.Append(char16_t(')')); |
|
1870 } |
|
1871 } |
|
1872 |
|
1873 void nsCSSRect::SetAllSidesTo(const nsCSSValue& aValue) |
|
1874 { |
|
1875 mTop = aValue; |
|
1876 mRight = aValue; |
|
1877 mBottom = aValue; |
|
1878 mLeft = aValue; |
|
1879 } |
|
1880 |
|
1881 size_t |
|
1882 nsCSSRect_heap::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const |
|
1883 { |
|
1884 size_t n = aMallocSizeOf(this); |
|
1885 n += mTop .SizeOfExcludingThis(aMallocSizeOf); |
|
1886 n += mRight .SizeOfExcludingThis(aMallocSizeOf); |
|
1887 n += mBottom.SizeOfExcludingThis(aMallocSizeOf); |
|
1888 n += mLeft .SizeOfExcludingThis(aMallocSizeOf); |
|
1889 return n; |
|
1890 } |
|
1891 |
|
1892 static_assert(NS_SIDE_TOP == 0 && NS_SIDE_RIGHT == 1 && |
|
1893 NS_SIDE_BOTTOM == 2 && NS_SIDE_LEFT == 3, |
|
1894 "box side constants not top/right/bottom/left == 0/1/2/3"); |
|
1895 |
|
1896 /* static */ const nsCSSRect::side_type nsCSSRect::sides[4] = { |
|
1897 &nsCSSRect::mTop, |
|
1898 &nsCSSRect::mRight, |
|
1899 &nsCSSRect::mBottom, |
|
1900 &nsCSSRect::mLeft, |
|
1901 }; |
|
1902 |
|
1903 // --- nsCSSValuePair ----------------- |
|
1904 |
|
1905 void |
|
1906 nsCSSValuePair::AppendToString(nsCSSProperty aProperty, |
|
1907 nsAString& aResult, |
|
1908 nsCSSValue::Serialization aSerialization) const |
|
1909 { |
|
1910 mXValue.AppendToString(aProperty, aResult, aSerialization); |
|
1911 if (mYValue.GetUnit() != eCSSUnit_Null) { |
|
1912 aResult.Append(char16_t(' ')); |
|
1913 mYValue.AppendToString(aProperty, aResult, aSerialization); |
|
1914 } |
|
1915 } |
|
1916 |
|
1917 size_t |
|
1918 nsCSSValuePair::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const |
|
1919 { |
|
1920 size_t n = 0; |
|
1921 n += mXValue.SizeOfExcludingThis(aMallocSizeOf); |
|
1922 n += mYValue.SizeOfExcludingThis(aMallocSizeOf); |
|
1923 return n; |
|
1924 } |
|
1925 |
|
1926 size_t |
|
1927 nsCSSValuePair_heap::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const |
|
1928 { |
|
1929 size_t n = aMallocSizeOf(this); |
|
1930 n += mXValue.SizeOfExcludingThis(aMallocSizeOf); |
|
1931 n += mYValue.SizeOfExcludingThis(aMallocSizeOf); |
|
1932 return n; |
|
1933 } |
|
1934 |
|
1935 // --- nsCSSValueTriplet ----------------- |
|
1936 |
|
1937 void |
|
1938 nsCSSValueTriplet::AppendToString(nsCSSProperty aProperty, |
|
1939 nsAString& aResult, |
|
1940 nsCSSValue::Serialization aSerialization) const |
|
1941 { |
|
1942 mXValue.AppendToString(aProperty, aResult, aSerialization); |
|
1943 if (mYValue.GetUnit() != eCSSUnit_Null) { |
|
1944 aResult.Append(char16_t(' ')); |
|
1945 mYValue.AppendToString(aProperty, aResult, aSerialization); |
|
1946 if (mZValue.GetUnit() != eCSSUnit_Null) { |
|
1947 aResult.Append(char16_t(' ')); |
|
1948 mZValue.AppendToString(aProperty, aResult, aSerialization); |
|
1949 } |
|
1950 } |
|
1951 } |
|
1952 |
|
1953 size_t |
|
1954 nsCSSValueTriplet_heap::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const |
|
1955 { |
|
1956 size_t n = aMallocSizeOf(this); |
|
1957 n += mXValue.SizeOfExcludingThis(aMallocSizeOf); |
|
1958 n += mYValue.SizeOfExcludingThis(aMallocSizeOf); |
|
1959 n += mZValue.SizeOfExcludingThis(aMallocSizeOf); |
|
1960 return n; |
|
1961 } |
|
1962 |
|
1963 // --- nsCSSValuePairList ----------------- |
|
1964 |
|
1965 nsCSSValuePairList::~nsCSSValuePairList() |
|
1966 { |
|
1967 MOZ_COUNT_DTOR(nsCSSValuePairList); |
|
1968 NS_CSS_DELETE_LIST_MEMBER(nsCSSValuePairList, this, mNext); |
|
1969 } |
|
1970 |
|
1971 nsCSSValuePairList* |
|
1972 nsCSSValuePairList::Clone() const |
|
1973 { |
|
1974 nsCSSValuePairList* result = new nsCSSValuePairList(*this); |
|
1975 nsCSSValuePairList* dest = result; |
|
1976 const nsCSSValuePairList* src = this->mNext; |
|
1977 while (src) { |
|
1978 dest->mNext = new nsCSSValuePairList(*src); |
|
1979 dest = dest->mNext; |
|
1980 src = src->mNext; |
|
1981 } |
|
1982 return result; |
|
1983 } |
|
1984 |
|
1985 void |
|
1986 nsCSSValuePairList::AppendToString(nsCSSProperty aProperty, |
|
1987 nsAString& aResult, |
|
1988 nsCSSValue::Serialization aSerialization) const |
|
1989 { |
|
1990 const nsCSSValuePairList* item = this; |
|
1991 for (;;) { |
|
1992 NS_ABORT_IF_FALSE(item->mXValue.GetUnit() != eCSSUnit_Null, |
|
1993 "unexpected null unit"); |
|
1994 item->mXValue.AppendToString(aProperty, aResult, aSerialization); |
|
1995 if (item->mXValue.GetUnit() != eCSSUnit_Inherit && |
|
1996 item->mXValue.GetUnit() != eCSSUnit_Initial && |
|
1997 item->mXValue.GetUnit() != eCSSUnit_Unset && |
|
1998 item->mYValue.GetUnit() != eCSSUnit_Null) { |
|
1999 aResult.Append(char16_t(' ')); |
|
2000 item->mYValue.AppendToString(aProperty, aResult, aSerialization); |
|
2001 } |
|
2002 item = item->mNext; |
|
2003 if (!item) |
|
2004 break; |
|
2005 |
|
2006 if (nsCSSProps::PropHasFlags(aProperty, |
|
2007 CSS_PROPERTY_VALUE_LIST_USES_COMMAS)) |
|
2008 aResult.Append(char16_t(',')); |
|
2009 aResult.Append(char16_t(' ')); |
|
2010 } |
|
2011 } |
|
2012 |
|
2013 bool |
|
2014 nsCSSValuePairList::operator==(const nsCSSValuePairList& aOther) const |
|
2015 { |
|
2016 if (this == &aOther) |
|
2017 return true; |
|
2018 |
|
2019 const nsCSSValuePairList *p1 = this, *p2 = &aOther; |
|
2020 for ( ; p1 && p2; p1 = p1->mNext, p2 = p2->mNext) { |
|
2021 if (p1->mXValue != p2->mXValue || |
|
2022 p1->mYValue != p2->mYValue) |
|
2023 return false; |
|
2024 } |
|
2025 return !p1 && !p2; // true if same length, false otherwise |
|
2026 } |
|
2027 |
|
2028 size_t |
|
2029 nsCSSValuePairList::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const |
|
2030 { |
|
2031 size_t n = 0; |
|
2032 const nsCSSValuePairList* v = this; |
|
2033 while (v) { |
|
2034 n += aMallocSizeOf(v); |
|
2035 n += v->mXValue.SizeOfExcludingThis(aMallocSizeOf); |
|
2036 n += v->mYValue.SizeOfExcludingThis(aMallocSizeOf); |
|
2037 v = v->mNext; |
|
2038 } |
|
2039 return n; |
|
2040 } |
|
2041 |
|
2042 size_t |
|
2043 nsCSSValuePairList_heap::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const |
|
2044 { |
|
2045 size_t n = aMallocSizeOf(this); |
|
2046 n += mXValue.SizeOfExcludingThis(aMallocSizeOf); |
|
2047 n += mYValue.SizeOfExcludingThis(aMallocSizeOf); |
|
2048 n += mNext ? mNext->SizeOfIncludingThis(aMallocSizeOf) : 0; |
|
2049 return n; |
|
2050 } |
|
2051 |
|
2052 size_t |
|
2053 nsCSSValue::Array::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const |
|
2054 { |
|
2055 size_t n = aMallocSizeOf(this); |
|
2056 for (size_t i = 0; i < mCount; i++) { |
|
2057 n += mArray[i].SizeOfExcludingThis(aMallocSizeOf); |
|
2058 } |
|
2059 return n; |
|
2060 } |
|
2061 |
|
2062 css::URLValue::URLValue(nsIURI* aURI, nsStringBuffer* aString, |
|
2063 nsIURI* aReferrer, nsIPrincipal* aOriginPrincipal) |
|
2064 : mURI(aURI), |
|
2065 mString(aString), |
|
2066 mReferrer(aReferrer), |
|
2067 mOriginPrincipal(aOriginPrincipal), |
|
2068 mURIResolved(true) |
|
2069 { |
|
2070 NS_ABORT_IF_FALSE(aOriginPrincipal, "Must have an origin principal"); |
|
2071 mString->AddRef(); |
|
2072 } |
|
2073 |
|
2074 css::URLValue::URLValue(nsStringBuffer* aString, nsIURI* aBaseURI, |
|
2075 nsIURI* aReferrer, nsIPrincipal* aOriginPrincipal) |
|
2076 : mURI(aBaseURI), |
|
2077 mString(aString), |
|
2078 mReferrer(aReferrer), |
|
2079 mOriginPrincipal(aOriginPrincipal), |
|
2080 mURIResolved(false) |
|
2081 { |
|
2082 NS_ABORT_IF_FALSE(aOriginPrincipal, "Must have an origin principal"); |
|
2083 mString->AddRef(); |
|
2084 } |
|
2085 |
|
2086 css::URLValue::~URLValue() |
|
2087 { |
|
2088 mString->Release(); |
|
2089 } |
|
2090 |
|
2091 bool |
|
2092 css::URLValue::operator==(const URLValue& aOther) const |
|
2093 { |
|
2094 bool eq; |
|
2095 return NS_strcmp(nsCSSValue::GetBufferValue(mString), |
|
2096 nsCSSValue::GetBufferValue(aOther.mString)) == 0 && |
|
2097 (GetURI() == aOther.GetURI() || // handles null == null |
|
2098 (mURI && aOther.mURI && |
|
2099 NS_SUCCEEDED(mURI->Equals(aOther.mURI, &eq)) && |
|
2100 eq)) && |
|
2101 (mOriginPrincipal == aOther.mOriginPrincipal || |
|
2102 (NS_SUCCEEDED(mOriginPrincipal->Equals(aOther.mOriginPrincipal, |
|
2103 &eq)) && eq)); |
|
2104 } |
|
2105 |
|
2106 bool |
|
2107 css::URLValue::URIEquals(const URLValue& aOther) const |
|
2108 { |
|
2109 NS_ABORT_IF_FALSE(mURIResolved && aOther.mURIResolved, |
|
2110 "How do you know the URIs aren't null?"); |
|
2111 bool eq; |
|
2112 // Worth comparing GetURI() to aOther.GetURI() and mOriginPrincipal to |
|
2113 // aOther.mOriginPrincipal, because in the (probably common) case when this |
|
2114 // value was one of the ones that in fact did not change this will be our |
|
2115 // fast path to equality |
|
2116 return (mURI == aOther.mURI || |
|
2117 (NS_SUCCEEDED(mURI->Equals(aOther.mURI, &eq)) && eq)) && |
|
2118 (mOriginPrincipal == aOther.mOriginPrincipal || |
|
2119 (NS_SUCCEEDED(mOriginPrincipal->Equals(aOther.mOriginPrincipal, |
|
2120 &eq)) && eq)); |
|
2121 } |
|
2122 |
|
2123 nsIURI* |
|
2124 css::URLValue::GetURI() const |
|
2125 { |
|
2126 if (!mURIResolved) { |
|
2127 mURIResolved = true; |
|
2128 // Be careful to not null out mURI before we've passed it as the base URI |
|
2129 nsCOMPtr<nsIURI> newURI; |
|
2130 NS_NewURI(getter_AddRefs(newURI), |
|
2131 NS_ConvertUTF16toUTF8(nsCSSValue::GetBufferValue(mString)), |
|
2132 nullptr, mURI); |
|
2133 newURI.swap(mURI); |
|
2134 } |
|
2135 |
|
2136 return mURI; |
|
2137 } |
|
2138 |
|
2139 size_t |
|
2140 css::URLValue::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const |
|
2141 { |
|
2142 size_t n = aMallocSizeOf(this); |
|
2143 |
|
2144 // This string is unshared. |
|
2145 n += mString->SizeOfIncludingThisMustBeUnshared(aMallocSizeOf); |
|
2146 |
|
2147 // Measurement of the following members may be added later if DMD finds it is |
|
2148 // worthwhile: |
|
2149 // - mURI |
|
2150 // - mReferrer |
|
2151 // - mOriginPrincipal |
|
2152 |
|
2153 return n; |
|
2154 } |
|
2155 |
|
2156 |
|
2157 css::ImageValue::ImageValue(nsIURI* aURI, nsStringBuffer* aString, |
|
2158 nsIURI* aReferrer, nsIPrincipal* aOriginPrincipal, |
|
2159 nsIDocument* aDocument) |
|
2160 : URLValue(aURI, aString, aReferrer, aOriginPrincipal) |
|
2161 { |
|
2162 // NB: If aDocument is not the original document, we may not be able to load |
|
2163 // images from aDocument. Instead we do the image load from the original doc |
|
2164 // and clone it to aDocument. |
|
2165 nsIDocument* loadingDoc = aDocument->GetOriginalDocument(); |
|
2166 if (!loadingDoc) { |
|
2167 loadingDoc = aDocument; |
|
2168 } |
|
2169 |
|
2170 loadingDoc->StyleImageLoader()->LoadImage(aURI, aOriginPrincipal, aReferrer, |
|
2171 this); |
|
2172 |
|
2173 if (loadingDoc != aDocument) { |
|
2174 aDocument->StyleImageLoader()->MaybeRegisterCSSImage(this); |
|
2175 } |
|
2176 } |
|
2177 |
|
2178 static PLDHashOperator |
|
2179 ClearRequestHashtable(nsISupports* aKey, nsRefPtr<imgRequestProxy>& aValue, |
|
2180 void* aClosure) |
|
2181 { |
|
2182 mozilla::css::ImageValue* image = |
|
2183 static_cast<mozilla::css::ImageValue*>(aClosure); |
|
2184 nsIDocument* doc = static_cast<nsIDocument*>(aKey); |
|
2185 |
|
2186 #ifdef DEBUG |
|
2187 { |
|
2188 nsCOMPtr<nsIDocument> slowDoc = do_QueryInterface(aKey); |
|
2189 MOZ_ASSERT(slowDoc == doc); |
|
2190 } |
|
2191 #endif |
|
2192 |
|
2193 if (doc) { |
|
2194 doc->StyleImageLoader()->DeregisterCSSImage(image); |
|
2195 } |
|
2196 |
|
2197 if (aValue) { |
|
2198 aValue->CancelAndForgetObserver(NS_BINDING_ABORTED); |
|
2199 } |
|
2200 |
|
2201 return PL_DHASH_REMOVE; |
|
2202 } |
|
2203 |
|
2204 css::ImageValue::~ImageValue() |
|
2205 { |
|
2206 mRequests.Enumerate(&ClearRequestHashtable, this); |
|
2207 } |
|
2208 |
|
2209 nsCSSValueGradientStop::nsCSSValueGradientStop() |
|
2210 : mLocation(eCSSUnit_None), |
|
2211 mColor(eCSSUnit_Null) |
|
2212 { |
|
2213 MOZ_COUNT_CTOR(nsCSSValueGradientStop); |
|
2214 } |
|
2215 |
|
2216 nsCSSValueGradientStop::nsCSSValueGradientStop(const nsCSSValueGradientStop& aOther) |
|
2217 : mLocation(aOther.mLocation), |
|
2218 mColor(aOther.mColor) |
|
2219 { |
|
2220 MOZ_COUNT_CTOR(nsCSSValueGradientStop); |
|
2221 } |
|
2222 |
|
2223 nsCSSValueGradientStop::~nsCSSValueGradientStop() |
|
2224 { |
|
2225 MOZ_COUNT_DTOR(nsCSSValueGradientStop); |
|
2226 } |
|
2227 |
|
2228 size_t |
|
2229 nsCSSValueGradientStop::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const |
|
2230 { |
|
2231 size_t n = 0; |
|
2232 n += mLocation.SizeOfExcludingThis(aMallocSizeOf); |
|
2233 n += mColor .SizeOfExcludingThis(aMallocSizeOf); |
|
2234 return n; |
|
2235 } |
|
2236 |
|
2237 nsCSSValueGradient::nsCSSValueGradient(bool aIsRadial, |
|
2238 bool aIsRepeating) |
|
2239 : mIsRadial(aIsRadial), |
|
2240 mIsRepeating(aIsRepeating), |
|
2241 mIsLegacySyntax(false), |
|
2242 mIsExplicitSize(false), |
|
2243 mBgPos(eCSSUnit_None), |
|
2244 mAngle(eCSSUnit_None) |
|
2245 { |
|
2246 mRadialValues[0].SetNoneValue(); |
|
2247 mRadialValues[1].SetNoneValue(); |
|
2248 } |
|
2249 |
|
2250 size_t |
|
2251 nsCSSValueGradient::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const |
|
2252 { |
|
2253 size_t n = aMallocSizeOf(this); |
|
2254 n += mBgPos.SizeOfExcludingThis(aMallocSizeOf); |
|
2255 n += mAngle.SizeOfExcludingThis(aMallocSizeOf); |
|
2256 n += mRadialValues[0].SizeOfExcludingThis(aMallocSizeOf); |
|
2257 n += mRadialValues[1].SizeOfExcludingThis(aMallocSizeOf); |
|
2258 n += mStops.SizeOfExcludingThis(aMallocSizeOf); |
|
2259 for (uint32_t i = 0; i < mStops.Length(); i++) { |
|
2260 n += mStops[i].SizeOfExcludingThis(aMallocSizeOf); |
|
2261 } |
|
2262 return n; |
|
2263 } |
|
2264 |
|
2265 // --- nsCSSValueTokenStream ------------ |
|
2266 |
|
2267 nsCSSValueTokenStream::nsCSSValueTokenStream() |
|
2268 : mPropertyID(eCSSProperty_UNKNOWN) |
|
2269 , mShorthandPropertyID(eCSSProperty_UNKNOWN) |
|
2270 { |
|
2271 MOZ_COUNT_CTOR(nsCSSValueTokenStream); |
|
2272 } |
|
2273 |
|
2274 nsCSSValueTokenStream::~nsCSSValueTokenStream() |
|
2275 { |
|
2276 MOZ_COUNT_DTOR(nsCSSValueTokenStream); |
|
2277 } |
|
2278 |
|
2279 size_t |
|
2280 nsCSSValueTokenStream::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const |
|
2281 { |
|
2282 size_t n = aMallocSizeOf(this); |
|
2283 n += mTokenStream.SizeOfExcludingThisIfUnshared(aMallocSizeOf); |
|
2284 return n; |
|
2285 } |
|
2286 |
|
2287 // --- nsCSSValueFloatColor ------------- |
|
2288 |
|
2289 bool |
|
2290 nsCSSValueFloatColor::operator==(nsCSSValueFloatColor& aOther) const |
|
2291 { |
|
2292 return mComponent1 == aOther.mComponent1 && |
|
2293 mComponent2 == aOther.mComponent2 && |
|
2294 mComponent3 == aOther.mComponent3 && |
|
2295 mAlpha == aOther.mAlpha; |
|
2296 } |
|
2297 |
|
2298 nscolor |
|
2299 nsCSSValueFloatColor::GetColorValue(nsCSSUnit aUnit) const |
|
2300 { |
|
2301 MOZ_ASSERT(nsCSSValue::IsFloatColorUnit(aUnit), "unexpected unit"); |
|
2302 |
|
2303 if (aUnit == eCSSUnit_PercentageRGBColor || |
|
2304 aUnit == eCSSUnit_PercentageRGBAColor) { |
|
2305 return NS_RGBA(NSToIntRound(mComponent1 * 255.0f), |
|
2306 NSToIntRound(mComponent2 * 255.0f), |
|
2307 NSToIntRound(mComponent3 * 255.0f), |
|
2308 NSToIntRound(mAlpha * 255.0f)); |
|
2309 } |
|
2310 |
|
2311 // HSL color |
|
2312 MOZ_ASSERT(aUnit == eCSSUnit_HSLColor || |
|
2313 aUnit == eCSSUnit_HSLAColor); |
|
2314 nscolor hsl = NS_HSL2RGB(mComponent1, mComponent2, mComponent3); |
|
2315 return NS_RGBA(NS_GET_R(hsl), |
|
2316 NS_GET_G(hsl), |
|
2317 NS_GET_B(hsl), |
|
2318 NSToIntRound(mAlpha * 255.0f)); |
|
2319 } |
|
2320 |
|
2321 bool |
|
2322 nsCSSValueFloatColor::IsNonTransparentColor() const |
|
2323 { |
|
2324 return mAlpha > 0.0f; |
|
2325 } |
|
2326 |
|
2327 void |
|
2328 nsCSSValueFloatColor::AppendToString(nsCSSUnit aUnit, nsAString& aResult) const |
|
2329 { |
|
2330 MOZ_ASSERT(nsCSSValue::IsFloatColorUnit(aUnit), "unexpected unit"); |
|
2331 |
|
2332 bool hasAlpha = aUnit == eCSSUnit_PercentageRGBAColor || |
|
2333 aUnit == eCSSUnit_HSLAColor; |
|
2334 bool isHSL = aUnit == eCSSUnit_HSLColor || |
|
2335 aUnit == eCSSUnit_HSLAColor; |
|
2336 |
|
2337 if (isHSL) { |
|
2338 aResult.AppendLiteral("hsl"); |
|
2339 } else { |
|
2340 aResult.AppendLiteral("rgb"); |
|
2341 } |
|
2342 if (hasAlpha) { |
|
2343 aResult.AppendLiteral("a("); |
|
2344 } else { |
|
2345 aResult.Append('('); |
|
2346 } |
|
2347 if (isHSL) { |
|
2348 aResult.AppendFloat(mComponent1 * 360.0f); |
|
2349 aResult.AppendLiteral(", "); |
|
2350 } else { |
|
2351 aResult.AppendFloat(mComponent1 * 100.0f); |
|
2352 aResult.AppendLiteral("%, "); |
|
2353 } |
|
2354 aResult.AppendFloat(mComponent2 * 100.0f); |
|
2355 aResult.AppendLiteral("%, "); |
|
2356 aResult.AppendFloat(mComponent3 * 100.0f); |
|
2357 if (hasAlpha) { |
|
2358 aResult.AppendLiteral("%, "); |
|
2359 aResult.AppendFloat(mAlpha); |
|
2360 aResult.Append(')'); |
|
2361 } else { |
|
2362 aResult.AppendLiteral("%)"); |
|
2363 } |
|
2364 } |
|
2365 |
|
2366 size_t |
|
2367 nsCSSValueFloatColor::SizeOfIncludingThis( |
|
2368 mozilla::MallocSizeOf aMallocSizeOf) const |
|
2369 { |
|
2370 size_t n = aMallocSizeOf(this); |
|
2371 return n; |
|
2372 } |
|
2373 |
|
2374 // --- nsCSSCornerSizes ----------------- |
|
2375 |
|
2376 nsCSSCornerSizes::nsCSSCornerSizes(void) |
|
2377 { |
|
2378 MOZ_COUNT_CTOR(nsCSSCornerSizes); |
|
2379 } |
|
2380 |
|
2381 nsCSSCornerSizes::nsCSSCornerSizes(const nsCSSCornerSizes& aCopy) |
|
2382 : mTopLeft(aCopy.mTopLeft), |
|
2383 mTopRight(aCopy.mTopRight), |
|
2384 mBottomRight(aCopy.mBottomRight), |
|
2385 mBottomLeft(aCopy.mBottomLeft) |
|
2386 { |
|
2387 MOZ_COUNT_CTOR(nsCSSCornerSizes); |
|
2388 } |
|
2389 |
|
2390 nsCSSCornerSizes::~nsCSSCornerSizes() |
|
2391 { |
|
2392 MOZ_COUNT_DTOR(nsCSSCornerSizes); |
|
2393 } |
|
2394 |
|
2395 void |
|
2396 nsCSSCornerSizes::Reset() |
|
2397 { |
|
2398 NS_FOR_CSS_FULL_CORNERS(corner) { |
|
2399 this->GetCorner(corner).Reset(); |
|
2400 } |
|
2401 } |
|
2402 |
|
2403 static_assert(NS_CORNER_TOP_LEFT == 0 && NS_CORNER_TOP_RIGHT == 1 && |
|
2404 NS_CORNER_BOTTOM_RIGHT == 2 && NS_CORNER_BOTTOM_LEFT == 3, |
|
2405 "box corner constants not tl/tr/br/bl == 0/1/2/3"); |
|
2406 |
|
2407 /* static */ const nsCSSCornerSizes::corner_type |
|
2408 nsCSSCornerSizes::corners[4] = { |
|
2409 &nsCSSCornerSizes::mTopLeft, |
|
2410 &nsCSSCornerSizes::mTopRight, |
|
2411 &nsCSSCornerSizes::mBottomRight, |
|
2412 &nsCSSCornerSizes::mBottomLeft, |
|
2413 }; |
|
2414 |
|
2415 size_t |
|
2416 mozilla::css::GridTemplateAreasValue::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const |
|
2417 { |
|
2418 size_t n = mNamedAreas.SizeOfExcludingThis(aMallocSizeOf); |
|
2419 n += mTemplates.SizeOfIncludingThis(aMallocSizeOf); |
|
2420 return n; |
|
2421 } |