/src/mozilla-central/layout/style/nsCSSValue.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
2 | | /* vim: set ts=8 sts=2 et sw=2 tw=80: */ |
3 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
4 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
5 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
6 | | |
7 | | /* representation of simple property values within CSS declarations */ |
8 | | |
9 | | #include "nsCSSValue.h" |
10 | | |
11 | | #include "mozilla/CORSMode.h" |
12 | | #include "mozilla/FontPropertyTypes.h" |
13 | | #include "mozilla/ServoBindings.h" |
14 | | #include "mozilla/ServoStyleSet.h" |
15 | | #include "mozilla/ServoTypes.h" |
16 | | #include "mozilla/StyleSheetInlines.h" |
17 | | #include "mozilla/Likely.h" |
18 | | #include "mozilla/MemoryReporting.h" |
19 | | #include "mozilla/css/ImageLoader.h" |
20 | | #include "gfxFontConstants.h" |
21 | | #include "imgIRequest.h" |
22 | | #include "imgRequestProxy.h" |
23 | | #include "nsIDocument.h" |
24 | | #include "nsIURIMutator.h" |
25 | | #include "nsCSSProps.h" |
26 | | #include "nsNetUtil.h" |
27 | | #include "nsPresContext.h" |
28 | | #include "nsStyleUtil.h" |
29 | | #include "nsDeviceContext.h" |
30 | | #include "nsContentUtils.h" |
31 | | |
32 | | using namespace mozilla; |
33 | | using namespace mozilla::css; |
34 | | |
35 | | template<class T> |
36 | | static bool MightHaveRef(const T& aString) |
37 | 0 | { |
38 | 0 | const typename T::char_type* current = aString.BeginReading(); |
39 | 0 | for (; current != aString.EndReading(); current++) { |
40 | 0 | if (*current == '#') { |
41 | 0 | return true; |
42 | 0 | } |
43 | 0 | } |
44 | 0 |
|
45 | 0 | return false; |
46 | 0 | } |
47 | | |
48 | | nsCSSValue::nsCSSValue(int32_t aValue, nsCSSUnit aUnit) |
49 | | : mUnit(aUnit) |
50 | 0 | { |
51 | 0 | MOZ_ASSERT(aUnit == eCSSUnit_Integer || aUnit == eCSSUnit_Enumerated, |
52 | 0 | "not an int value"); |
53 | 0 | if (aUnit == eCSSUnit_Integer || aUnit == eCSSUnit_Enumerated) { |
54 | 0 | mValue.mInt = aValue; |
55 | 0 | } |
56 | 0 | else { |
57 | 0 | mUnit = eCSSUnit_Null; |
58 | 0 | mValue.mInt = 0; |
59 | 0 | } |
60 | 0 | } |
61 | | |
62 | | nsCSSValue::nsCSSValue(float aValue, nsCSSUnit aUnit) |
63 | | : mUnit(aUnit) |
64 | 0 | { |
65 | 0 | MOZ_ASSERT(eCSSUnit_Percent <= aUnit, "not a float value"); |
66 | 0 | if (eCSSUnit_Percent <= aUnit) { |
67 | 0 | mValue.mFloat = aValue; |
68 | 0 | MOZ_ASSERT(!mozilla::IsNaN(mValue.mFloat)); |
69 | 0 | } |
70 | 0 | else { |
71 | 0 | mUnit = eCSSUnit_Null; |
72 | 0 | mValue.mInt = 0; |
73 | 0 | } |
74 | 0 | } |
75 | | |
76 | | nsCSSValue::nsCSSValue(const nsString& aValue, nsCSSUnit aUnit) |
77 | | : mUnit(aUnit) |
78 | 0 | { |
79 | 0 | MOZ_ASSERT(UnitHasStringValue(), "not a string value"); |
80 | 0 | if (UnitHasStringValue()) { |
81 | 0 | mValue.mString = BufferFromString(aValue).take(); |
82 | 0 | } |
83 | 0 | else { |
84 | 0 | mUnit = eCSSUnit_Null; |
85 | 0 | mValue.mInt = 0; |
86 | 0 | } |
87 | 0 | } |
88 | | |
89 | | nsCSSValue::nsCSSValue(nsCSSValue::Array* aValue, nsCSSUnit aUnit) |
90 | | : mUnit(aUnit) |
91 | 0 | { |
92 | 0 | MOZ_ASSERT(UnitHasArrayValue(), "bad unit"); |
93 | 0 | mValue.mArray = aValue; |
94 | 0 | mValue.mArray->AddRef(); |
95 | 0 | } |
96 | | |
97 | | nsCSSValue::nsCSSValue(mozilla::css::URLValue* aValue) |
98 | | : mUnit(eCSSUnit_URL) |
99 | 0 | { |
100 | 0 | mValue.mURL = aValue; |
101 | 0 | mValue.mURL->AddRef(); |
102 | 0 | } |
103 | | |
104 | | nsCSSValue::nsCSSValue(mozilla::css::GridTemplateAreasValue* aValue) |
105 | | : mUnit(eCSSUnit_GridTemplateAreas) |
106 | 0 | { |
107 | 0 | mValue.mGridTemplateAreas = aValue; |
108 | 0 | mValue.mGridTemplateAreas->AddRef(); |
109 | 0 | } |
110 | | |
111 | | nsCSSValue::nsCSSValue(SharedFontList* aValue) |
112 | | : mUnit(eCSSUnit_FontFamilyList) |
113 | 0 | { |
114 | 0 | mValue.mFontFamilyList = aValue; |
115 | 0 | mValue.mFontFamilyList->AddRef(); |
116 | 0 | } |
117 | | |
118 | | nsCSSValue::nsCSSValue(FontStretch aStretch) |
119 | | : mUnit(eCSSUnit_FontStretch) |
120 | 0 | { |
121 | 0 | mValue.mFontStretch = aStretch; |
122 | 0 | } |
123 | | |
124 | | nsCSSValue::nsCSSValue(FontSlantStyle aStyle) |
125 | | : mUnit(eCSSUnit_FontSlantStyle) |
126 | 0 | { |
127 | 0 | mValue.mFontSlantStyle = aStyle; |
128 | 0 | } |
129 | | |
130 | | nsCSSValue::nsCSSValue(FontWeight aWeight) |
131 | | : mUnit(eCSSUnit_FontWeight) |
132 | 0 | { |
133 | 0 | mValue.mFontWeight = aWeight; |
134 | 0 | } |
135 | | |
136 | | nsCSSValue::nsCSSValue(const nsCSSValue& aCopy) |
137 | | : mUnit(aCopy.mUnit) |
138 | 0 | { |
139 | 0 | if (mUnit <= eCSSUnit_DummyInherit) { |
140 | 0 | // nothing to do, but put this important case first |
141 | 0 | } |
142 | 0 | else if (eCSSUnit_Percent <= mUnit) { |
143 | 0 | mValue.mFloat = aCopy.mValue.mFloat; |
144 | 0 | MOZ_ASSERT(!mozilla::IsNaN(mValue.mFloat)); |
145 | 0 | } |
146 | 0 | else if (UnitHasStringValue()) { |
147 | 0 | mValue.mString = aCopy.mValue.mString; |
148 | 0 | mValue.mString->AddRef(); |
149 | 0 | } |
150 | 0 | else if (eCSSUnit_Integer <= mUnit && mUnit <= eCSSUnit_Enumerated) { |
151 | 0 | mValue.mInt = aCopy.mValue.mInt; |
152 | 0 | } |
153 | 0 | else if (UnitHasArrayValue()) { |
154 | 0 | mValue.mArray = aCopy.mValue.mArray; |
155 | 0 | mValue.mArray->AddRef(); |
156 | 0 | } |
157 | 0 | else if (eCSSUnit_URL == mUnit) { |
158 | 0 | mValue.mURL = aCopy.mValue.mURL; |
159 | 0 | mValue.mURL->AddRef(); |
160 | 0 | } |
161 | 0 | else if (eCSSUnit_Pair == mUnit) { |
162 | 0 | mValue.mPair = aCopy.mValue.mPair; |
163 | 0 | mValue.mPair->AddRef(); |
164 | 0 | } |
165 | 0 | else if (eCSSUnit_List == mUnit) { |
166 | 0 | mValue.mList = aCopy.mValue.mList; |
167 | 0 | mValue.mList->AddRef(); |
168 | 0 | } |
169 | 0 | else if (eCSSUnit_ListDep == mUnit) { |
170 | 0 | mValue.mListDependent = aCopy.mValue.mListDependent; |
171 | 0 | } |
172 | 0 | else if (eCSSUnit_SharedList == mUnit) { |
173 | 0 | mValue.mSharedList = aCopy.mValue.mSharedList; |
174 | 0 | mValue.mSharedList->AddRef(); |
175 | 0 | } |
176 | 0 | else if (eCSSUnit_PairList == mUnit) { |
177 | 0 | mValue.mPairList = aCopy.mValue.mPairList; |
178 | 0 | mValue.mPairList->AddRef(); |
179 | 0 | } |
180 | 0 | else if (eCSSUnit_PairListDep == mUnit) { |
181 | 0 | mValue.mPairListDependent = aCopy.mValue.mPairListDependent; |
182 | 0 | } |
183 | 0 | else if (eCSSUnit_GridTemplateAreas == mUnit) { |
184 | 0 | mValue.mGridTemplateAreas = aCopy.mValue.mGridTemplateAreas; |
185 | 0 | mValue.mGridTemplateAreas->AddRef(); |
186 | 0 | } |
187 | 0 | else if (eCSSUnit_FontFamilyList == mUnit) { |
188 | 0 | mValue.mFontFamilyList = aCopy.mValue.mFontFamilyList; |
189 | 0 | mValue.mFontFamilyList->AddRef(); |
190 | 0 | } |
191 | 0 | else if (eCSSUnit_FontStretch == mUnit) { |
192 | 0 | mValue.mFontStretch = aCopy.mValue.mFontStretch; |
193 | 0 | } |
194 | 0 | else if (eCSSUnit_FontSlantStyle == mUnit) { |
195 | 0 | mValue.mFontSlantStyle = aCopy.mValue.mFontSlantStyle; |
196 | 0 | } |
197 | 0 | else if (eCSSUnit_FontWeight == mUnit) { |
198 | 0 | mValue.mFontWeight = aCopy.mValue.mFontWeight; |
199 | 0 | } |
200 | 0 | else if (eCSSUnit_AtomIdent == mUnit) { |
201 | 0 | mValue.mAtom = aCopy.mValue.mAtom; |
202 | 0 | mValue.mAtom->AddRef(); |
203 | 0 | } |
204 | 0 | else { |
205 | 0 | MOZ_ASSERT(false, "unknown unit"); |
206 | 0 | } |
207 | 0 | } |
208 | | |
209 | | nsCSSValue& nsCSSValue::operator=(const nsCSSValue& aCopy) |
210 | 0 | { |
211 | 0 | if (this != &aCopy) { |
212 | 0 | Reset(); |
213 | 0 | new (this) nsCSSValue(aCopy); |
214 | 0 | } |
215 | 0 | return *this; |
216 | 0 | } |
217 | | |
218 | | nsCSSValue& |
219 | | nsCSSValue::operator=(nsCSSValue&& aOther) |
220 | 0 | { |
221 | 0 | MOZ_ASSERT(this != &aOther, "Self assigment with rvalue reference"); |
222 | 0 |
|
223 | 0 | Reset(); |
224 | 0 | mUnit = aOther.mUnit; |
225 | 0 | mValue = aOther.mValue; |
226 | 0 | aOther.mUnit = eCSSUnit_Null; |
227 | 0 |
|
228 | 0 | return *this; |
229 | 0 | } |
230 | | |
231 | | bool nsCSSValue::operator==(const nsCSSValue& aOther) const |
232 | 0 | { |
233 | 0 | MOZ_ASSERT(mUnit != eCSSUnit_ListDep && |
234 | 0 | aOther.mUnit != eCSSUnit_ListDep && |
235 | 0 | mUnit != eCSSUnit_PairListDep && |
236 | 0 | aOther.mUnit != eCSSUnit_PairListDep, |
237 | 0 | "don't use operator== with dependent lists"); |
238 | 0 |
|
239 | 0 | if (mUnit == aOther.mUnit) { |
240 | 0 | if (mUnit <= eCSSUnit_DummyInherit) { |
241 | 0 | return true; |
242 | 0 | } |
243 | 0 | else if (UnitHasStringValue()) { |
244 | 0 | return (NS_strcmp(GetBufferValue(mValue.mString), |
245 | 0 | GetBufferValue(aOther.mValue.mString)) == 0); |
246 | 0 | } |
247 | 0 | else if ((eCSSUnit_Integer <= mUnit) && (mUnit <= eCSSUnit_Enumerated)) { |
248 | 0 | return mValue.mInt == aOther.mValue.mInt; |
249 | 0 | } |
250 | 0 | else if (UnitHasArrayValue()) { |
251 | 0 | return *mValue.mArray == *aOther.mValue.mArray; |
252 | 0 | } |
253 | 0 | else if (eCSSUnit_URL == mUnit) { |
254 | 0 | return mValue.mURL->Equals(*aOther.mValue.mURL); |
255 | 0 | } |
256 | 0 | else if (eCSSUnit_Pair == mUnit) { |
257 | 0 | return *mValue.mPair == *aOther.mValue.mPair; |
258 | 0 | } |
259 | 0 | else if (eCSSUnit_List == mUnit) { |
260 | 0 | return nsCSSValueList::Equal(mValue.mList, aOther.mValue.mList); |
261 | 0 | } |
262 | 0 | else if (eCSSUnit_SharedList == mUnit) { |
263 | 0 | return *mValue.mSharedList == *aOther.mValue.mSharedList; |
264 | 0 | } |
265 | 0 | else if (eCSSUnit_PairList == mUnit) { |
266 | 0 | return nsCSSValuePairList::Equal(mValue.mPairList, |
267 | 0 | aOther.mValue.mPairList); |
268 | 0 | } |
269 | 0 | else if (eCSSUnit_GridTemplateAreas == mUnit) { |
270 | 0 | return *mValue.mGridTemplateAreas == *aOther.mValue.mGridTemplateAreas; |
271 | 0 | } |
272 | 0 | else if (eCSSUnit_FontFamilyList == mUnit) { |
273 | 0 | return mValue.mFontFamilyList->mNames == |
274 | 0 | aOther.mValue.mFontFamilyList->mNames; |
275 | 0 | } |
276 | 0 | else if (eCSSUnit_FontStretch == mUnit) { |
277 | 0 | return mValue.mFontStretch == aOther.mValue.mFontStretch; |
278 | 0 | } |
279 | 0 | else if (eCSSUnit_FontSlantStyle == mUnit) { |
280 | 0 | return mValue.mFontSlantStyle == aOther.mValue.mFontSlantStyle; |
281 | 0 | } |
282 | 0 | else if (eCSSUnit_FontWeight == mUnit) { |
283 | 0 | return mValue.mFontWeight == aOther.mValue.mFontWeight; |
284 | 0 | } |
285 | 0 | else if (eCSSUnit_AtomIdent == mUnit) { |
286 | 0 | return mValue.mAtom == aOther.mValue.mAtom; |
287 | 0 | } |
288 | 0 | else { |
289 | 0 | return mValue.mFloat == aOther.mValue.mFloat; |
290 | 0 | } |
291 | 0 | } |
292 | 0 | return false; |
293 | 0 | } |
294 | | |
295 | | double |
296 | | nsCSSValue::GetAngleValueInRadians() const |
297 | 0 | { |
298 | 0 | double angle = GetFloatValue(); |
299 | 0 |
|
300 | 0 | switch (GetUnit()) { |
301 | 0 | case eCSSUnit_Radian: return angle; |
302 | 0 | case eCSSUnit_Turn: return angle * 2 * M_PI; |
303 | 0 | case eCSSUnit_Degree: return angle * M_PI / 180.0; |
304 | 0 | case eCSSUnit_Grad: return angle * M_PI / 200.0; |
305 | 0 |
|
306 | 0 | default: |
307 | 0 | MOZ_ASSERT(false, "unrecognized angular unit"); |
308 | 0 | return 0.0; |
309 | 0 | } |
310 | 0 | } |
311 | | |
312 | | double |
313 | | nsCSSValue::GetAngleValueInDegrees() const |
314 | 0 | { |
315 | 0 | double angle = GetFloatValue(); |
316 | 0 |
|
317 | 0 | switch (GetUnit()) { |
318 | 0 | case eCSSUnit_Degree: return angle; |
319 | 0 | case eCSSUnit_Grad: return angle * 0.9; // grad / 400 * 360 |
320 | 0 | case eCSSUnit_Radian: return angle * 180.0 / M_PI; // rad / 2pi * 360 |
321 | 0 | case eCSSUnit_Turn: return angle * 360.0; |
322 | 0 |
|
323 | 0 | default: |
324 | 0 | MOZ_ASSERT(false, "unrecognized angular unit"); |
325 | 0 | return 0.0; |
326 | 0 | } |
327 | 0 | } |
328 | | |
329 | | nscoord nsCSSValue::GetPixelLength() const |
330 | 0 | { |
331 | 0 | MOZ_ASSERT(IsPixelLengthUnit(), "not a fixed length unit"); |
332 | 0 |
|
333 | 0 | double scaleFactor; |
334 | 0 | switch (mUnit) { |
335 | 0 | case eCSSUnit_Pixel: return nsPresContext::CSSPixelsToAppUnits(mValue.mFloat); |
336 | 0 | case eCSSUnit_Pica: scaleFactor = 16.0; break; |
337 | 0 | case eCSSUnit_Point: scaleFactor = 4/3.0; break; |
338 | 0 | case eCSSUnit_Inch: scaleFactor = 96.0; break; |
339 | 0 | case eCSSUnit_Millimeter: scaleFactor = 96/25.4; break; |
340 | 0 | case eCSSUnit_Centimeter: scaleFactor = 96/2.54; break; |
341 | 0 | case eCSSUnit_Quarter: scaleFactor = 96/101.6; break; |
342 | 0 | default: |
343 | 0 | NS_ERROR("should never get here"); |
344 | 0 | return 0; |
345 | 0 | } |
346 | 0 | return nsPresContext::CSSPixelsToAppUnits(float(mValue.mFloat*scaleFactor)); |
347 | 0 | } |
348 | | |
349 | | // Assert against resetting non-trivial CSS values from the parallel Servo |
350 | | // traversal, since the refcounts aren't thread-safe. |
351 | | // Note that the caller might be an OMTA thread, which is allowed to operate off |
352 | | // main thread because it owns all of the corresponding nsCSSValues and any that |
353 | | // they might be sharing members with. Since this can happen concurrently with |
354 | | // the servo traversal, we have to use a more-precise (but slower) test. |
355 | 0 | #define DO_RELEASE(member) { \ |
356 | 0 | MOZ_ASSERT(!ServoStyleSet::IsCurrentThreadInServoTraversal()); \ |
357 | 0 | mValue.member->Release(); \ |
358 | 0 | } |
359 | | |
360 | | void nsCSSValue::DoReset() |
361 | 0 | { |
362 | 0 | if (UnitHasStringValue()) { |
363 | 0 | mValue.mString->Release(); |
364 | 0 | } else if (UnitHasArrayValue()) { |
365 | 0 | DO_RELEASE(mArray); |
366 | 0 | } else if (eCSSUnit_URL == mUnit) { |
367 | 0 | DO_RELEASE(mURL); |
368 | 0 | } else if (eCSSUnit_Pair == mUnit) { |
369 | 0 | DO_RELEASE(mPair); |
370 | 0 | } else if (eCSSUnit_List == mUnit) { |
371 | 0 | DO_RELEASE(mList); |
372 | 0 | } else if (eCSSUnit_SharedList == mUnit) { |
373 | 0 | DO_RELEASE(mSharedList); |
374 | 0 | } else if (eCSSUnit_PairList == mUnit) { |
375 | 0 | DO_RELEASE(mPairList); |
376 | 0 | } else if (eCSSUnit_GridTemplateAreas == mUnit) { |
377 | 0 | DO_RELEASE(mGridTemplateAreas); |
378 | 0 | } else if (eCSSUnit_FontFamilyList == mUnit) { |
379 | 0 | DO_RELEASE(mFontFamilyList); |
380 | 0 | } else if (eCSSUnit_AtomIdent == mUnit) { |
381 | 0 | DO_RELEASE(mAtom); |
382 | 0 | } |
383 | 0 | mUnit = eCSSUnit_Null; |
384 | 0 | } |
385 | | |
386 | | #undef DO_RELEASE |
387 | | |
388 | | void nsCSSValue::SetIntValue(int32_t aValue, nsCSSUnit aUnit) |
389 | 0 | { |
390 | 0 | MOZ_ASSERT(aUnit == eCSSUnit_Integer || aUnit == eCSSUnit_Enumerated, |
391 | 0 | "not an int value"); |
392 | 0 | Reset(); |
393 | 0 | if (aUnit == eCSSUnit_Integer || aUnit == eCSSUnit_Enumerated) { |
394 | 0 | mUnit = aUnit; |
395 | 0 | mValue.mInt = aValue; |
396 | 0 | } |
397 | 0 | } |
398 | | |
399 | | void nsCSSValue::SetPercentValue(float aValue) |
400 | 0 | { |
401 | 0 | Reset(); |
402 | 0 | mUnit = eCSSUnit_Percent; |
403 | 0 | mValue.mFloat = aValue; |
404 | 0 | MOZ_ASSERT(!mozilla::IsNaN(mValue.mFloat)); |
405 | 0 | } |
406 | | |
407 | | void nsCSSValue::SetFloatValue(float aValue, nsCSSUnit aUnit) |
408 | 0 | { |
409 | 0 | MOZ_ASSERT(IsFloatUnit(aUnit), "not a float value"); |
410 | 0 | Reset(); |
411 | 0 | if (IsFloatUnit(aUnit)) { |
412 | 0 | mUnit = aUnit; |
413 | 0 | mValue.mFloat = aValue; |
414 | 0 | MOZ_ASSERT(!mozilla::IsNaN(mValue.mFloat)); |
415 | 0 | } |
416 | 0 | } |
417 | | |
418 | | void nsCSSValue::SetStringValue(const nsString& aValue, |
419 | | nsCSSUnit aUnit) |
420 | 0 | { |
421 | 0 | Reset(); |
422 | 0 | mUnit = aUnit; |
423 | 0 | MOZ_ASSERT(UnitHasStringValue(), "not a string unit"); |
424 | 0 | if (UnitHasStringValue()) { |
425 | 0 | mValue.mString = BufferFromString(aValue).take(); |
426 | 0 | } else |
427 | 0 | mUnit = eCSSUnit_Null; |
428 | 0 | } |
429 | | |
430 | | void |
431 | | nsCSSValue::SetAtomIdentValue(already_AddRefed<nsAtom> aValue) |
432 | 0 | { |
433 | 0 | Reset(); |
434 | 0 | mUnit = eCSSUnit_AtomIdent; |
435 | 0 | mValue.mAtom = aValue.take(); |
436 | 0 | } |
437 | | |
438 | | void nsCSSValue::SetIntegerCoordValue(nscoord aValue) |
439 | 0 | { |
440 | 0 | SetFloatValue(nsPresContext::AppUnitsToFloatCSSPixels(aValue), |
441 | 0 | eCSSUnit_Pixel); |
442 | 0 | } |
443 | | |
444 | | void nsCSSValue::SetArrayValue(nsCSSValue::Array* aValue, nsCSSUnit aUnit) |
445 | 0 | { |
446 | 0 | Reset(); |
447 | 0 | mUnit = aUnit; |
448 | 0 | MOZ_ASSERT(UnitHasArrayValue(), "bad unit"); |
449 | 0 | mValue.mArray = aValue; |
450 | 0 | mValue.mArray->AddRef(); |
451 | 0 | } |
452 | | |
453 | | void nsCSSValue::SetURLValue(mozilla::css::URLValue* aValue) |
454 | 0 | { |
455 | 0 | Reset(); |
456 | 0 | mUnit = eCSSUnit_URL; |
457 | 0 | mValue.mURL = aValue; |
458 | 0 | mValue.mURL->AddRef(); |
459 | 0 | } |
460 | | |
461 | | void nsCSSValue::SetGridTemplateAreas(mozilla::css::GridTemplateAreasValue* aValue) |
462 | 0 | { |
463 | 0 | Reset(); |
464 | 0 | mUnit = eCSSUnit_GridTemplateAreas; |
465 | 0 | mValue.mGridTemplateAreas = aValue; |
466 | 0 | mValue.mGridTemplateAreas->AddRef(); |
467 | 0 | } |
468 | | |
469 | | void nsCSSValue::SetFontFamilyListValue(already_AddRefed<SharedFontList> aValue) |
470 | 0 | { |
471 | 0 | Reset(); |
472 | 0 | mUnit = eCSSUnit_FontFamilyList; |
473 | 0 | mValue.mFontFamilyList = aValue.take(); |
474 | 0 | } |
475 | | |
476 | | void nsCSSValue::SetFontStretch(FontStretch aStretch) |
477 | 0 | { |
478 | 0 | Reset(); |
479 | 0 | mUnit = eCSSUnit_FontStretch; |
480 | 0 | mValue.mFontStretch = aStretch; |
481 | 0 | } |
482 | | |
483 | | void nsCSSValue::SetFontSlantStyle(FontSlantStyle aStyle) |
484 | 0 | { |
485 | 0 | Reset(); |
486 | 0 | mUnit = eCSSUnit_FontSlantStyle; |
487 | 0 | mValue.mFontSlantStyle = aStyle; |
488 | 0 | } |
489 | | |
490 | | void nsCSSValue::SetFontWeight(FontWeight aWeight) |
491 | 0 | { |
492 | 0 | Reset(); |
493 | 0 | mUnit = eCSSUnit_FontWeight; |
494 | 0 | mValue.mFontWeight = aWeight; |
495 | 0 | } |
496 | | |
497 | | void nsCSSValue::SetPairValue(const nsCSSValuePair* aValue) |
498 | 0 | { |
499 | 0 | // pairs should not be used for null/inherit/initial values |
500 | 0 | MOZ_ASSERT(aValue && |
501 | 0 | aValue->mXValue.GetUnit() != eCSSUnit_Null && |
502 | 0 | aValue->mYValue.GetUnit() != eCSSUnit_Null && |
503 | 0 | aValue->mXValue.GetUnit() != eCSSUnit_Inherit && |
504 | 0 | aValue->mYValue.GetUnit() != eCSSUnit_Inherit && |
505 | 0 | aValue->mXValue.GetUnit() != eCSSUnit_Initial && |
506 | 0 | aValue->mYValue.GetUnit() != eCSSUnit_Initial && |
507 | 0 | aValue->mXValue.GetUnit() != eCSSUnit_Unset && |
508 | 0 | aValue->mYValue.GetUnit() != eCSSUnit_Unset, |
509 | 0 | "missing or inappropriate pair value"); |
510 | 0 | Reset(); |
511 | 0 | mUnit = eCSSUnit_Pair; |
512 | 0 | mValue.mPair = new nsCSSValuePair_heap(aValue->mXValue, aValue->mYValue); |
513 | 0 | mValue.mPair->AddRef(); |
514 | 0 | } |
515 | | |
516 | | void nsCSSValue::SetPairValue(const nsCSSValue& xValue, |
517 | | const nsCSSValue& yValue) |
518 | 0 | { |
519 | 0 | MOZ_ASSERT(xValue.GetUnit() != eCSSUnit_Null && |
520 | 0 | yValue.GetUnit() != eCSSUnit_Null && |
521 | 0 | xValue.GetUnit() != eCSSUnit_Inherit && |
522 | 0 | yValue.GetUnit() != eCSSUnit_Inherit && |
523 | 0 | xValue.GetUnit() != eCSSUnit_Initial && |
524 | 0 | yValue.GetUnit() != eCSSUnit_Initial && |
525 | 0 | xValue.GetUnit() != eCSSUnit_Unset && |
526 | 0 | yValue.GetUnit() != eCSSUnit_Unset, |
527 | 0 | "inappropriate pair value"); |
528 | 0 | Reset(); |
529 | 0 | mUnit = eCSSUnit_Pair; |
530 | 0 | mValue.mPair = new nsCSSValuePair_heap(xValue, yValue); |
531 | 0 | mValue.mPair->AddRef(); |
532 | 0 | } |
533 | | |
534 | | nsCSSValueList* nsCSSValue::SetListValue() |
535 | 0 | { |
536 | 0 | Reset(); |
537 | 0 | mUnit = eCSSUnit_List; |
538 | 0 | mValue.mList = new nsCSSValueList_heap; |
539 | 0 | mValue.mList->AddRef(); |
540 | 0 | return mValue.mList; |
541 | 0 | } |
542 | | |
543 | | void nsCSSValue::SetSharedListValue(nsCSSValueSharedList* aList) |
544 | 0 | { |
545 | 0 | Reset(); |
546 | 0 | mUnit = eCSSUnit_SharedList; |
547 | 0 | mValue.mSharedList = aList; |
548 | 0 | mValue.mSharedList->AddRef(); |
549 | 0 | } |
550 | | |
551 | | void nsCSSValue::SetDependentListValue(nsCSSValueList* aList) |
552 | 0 | { |
553 | 0 | Reset(); |
554 | 0 | if (aList) { |
555 | 0 | mUnit = eCSSUnit_ListDep; |
556 | 0 | mValue.mListDependent = aList; |
557 | 0 | } |
558 | 0 | } |
559 | | |
560 | | void |
561 | | nsCSSValue::AdoptListValue(UniquePtr<nsCSSValueList> aValue) |
562 | 0 | { |
563 | 0 | // We have to copy the first element since for owned lists the first |
564 | 0 | // element should be an nsCSSValueList_heap object. |
565 | 0 | SetListValue(); |
566 | 0 | mValue.mList->mValue = std::move(aValue->mValue); |
567 | 0 | mValue.mList->mNext = aValue->mNext; |
568 | 0 | aValue->mNext = nullptr; |
569 | 0 | aValue.reset(); |
570 | 0 | } |
571 | | |
572 | | nsCSSValuePairList* nsCSSValue::SetPairListValue() |
573 | 0 | { |
574 | 0 | Reset(); |
575 | 0 | mUnit = eCSSUnit_PairList; |
576 | 0 | mValue.mPairList = new nsCSSValuePairList_heap; |
577 | 0 | mValue.mPairList->AddRef(); |
578 | 0 | return mValue.mPairList; |
579 | 0 | } |
580 | | |
581 | | void nsCSSValue::SetDependentPairListValue(nsCSSValuePairList* aList) |
582 | 0 | { |
583 | 0 | Reset(); |
584 | 0 | if (aList) { |
585 | 0 | mUnit = eCSSUnit_PairListDep; |
586 | 0 | mValue.mPairListDependent = aList; |
587 | 0 | } |
588 | 0 | } |
589 | | |
590 | | void |
591 | | nsCSSValue::AdoptPairListValue(UniquePtr<nsCSSValuePairList> aValue) |
592 | 0 | { |
593 | 0 | // We have to copy the first element, since for owned pair lists, the first |
594 | 0 | // element should be an nsCSSValuePairList_heap object. |
595 | 0 | SetPairListValue(); |
596 | 0 | mValue.mPairList->mXValue = std::move(aValue->mXValue); |
597 | 0 | mValue.mPairList->mYValue = std::move(aValue->mYValue); |
598 | 0 | mValue.mPairList->mNext = aValue->mNext; |
599 | 0 | aValue->mNext = nullptr; |
600 | 0 | aValue.reset(); |
601 | 0 | } |
602 | | |
603 | | void nsCSSValue::SetAutoValue() |
604 | 0 | { |
605 | 0 | Reset(); |
606 | 0 | mUnit = eCSSUnit_Auto; |
607 | 0 | } |
608 | | |
609 | | void nsCSSValue::SetInheritValue() |
610 | 0 | { |
611 | 0 | Reset(); |
612 | 0 | mUnit = eCSSUnit_Inherit; |
613 | 0 | } |
614 | | |
615 | | void nsCSSValue::SetInitialValue() |
616 | 0 | { |
617 | 0 | Reset(); |
618 | 0 | mUnit = eCSSUnit_Initial; |
619 | 0 | } |
620 | | |
621 | | void nsCSSValue::SetUnsetValue() |
622 | 0 | { |
623 | 0 | Reset(); |
624 | 0 | mUnit = eCSSUnit_Unset; |
625 | 0 | } |
626 | | |
627 | | void nsCSSValue::SetNoneValue() |
628 | 0 | { |
629 | 0 | Reset(); |
630 | 0 | mUnit = eCSSUnit_None; |
631 | 0 | } |
632 | | |
633 | | void nsCSSValue::SetAllValue() |
634 | 0 | { |
635 | 0 | Reset(); |
636 | 0 | mUnit = eCSSUnit_All; |
637 | 0 | } |
638 | | |
639 | | void nsCSSValue::SetNormalValue() |
640 | 0 | { |
641 | 0 | Reset(); |
642 | 0 | mUnit = eCSSUnit_Normal; |
643 | 0 | } |
644 | | |
645 | | void nsCSSValue::SetSystemFontValue() |
646 | 0 | { |
647 | 0 | Reset(); |
648 | 0 | mUnit = eCSSUnit_System_Font; |
649 | 0 | } |
650 | | |
651 | | void nsCSSValue::SetDummyValue() |
652 | 0 | { |
653 | 0 | Reset(); |
654 | 0 | mUnit = eCSSUnit_Dummy; |
655 | 0 | } |
656 | | |
657 | | void nsCSSValue::SetDummyInheritValue() |
658 | 0 | { |
659 | 0 | Reset(); |
660 | 0 | mUnit = eCSSUnit_DummyInherit; |
661 | 0 | } |
662 | | |
663 | | void nsCSSValue::SetCalcValue(const nsStyleCoord::CalcValue* aCalc) |
664 | 0 | { |
665 | 0 | RefPtr<nsCSSValue::Array> arr = nsCSSValue::Array::Create(1); |
666 | 0 | if (!aCalc->mHasPercent) { |
667 | 0 | arr->Item(0).SetIntegerCoordValue(aCalc->mLength); |
668 | 0 | } else { |
669 | 0 | nsCSSValue::Array *arr2 = nsCSSValue::Array::Create(2); |
670 | 0 | arr->Item(0).SetArrayValue(arr2, eCSSUnit_Calc_Plus); |
671 | 0 | arr2->Item(0).SetIntegerCoordValue(aCalc->mLength); |
672 | 0 | arr2->Item(1).SetPercentValue(aCalc->mPercent); |
673 | 0 | } |
674 | 0 |
|
675 | 0 | SetArrayValue(arr, eCSSUnit_Calc); |
676 | 0 | } |
677 | | |
678 | | nsStyleCoord::CalcValue |
679 | | nsCSSValue::GetCalcValue() const |
680 | 0 | { |
681 | 0 | MOZ_ASSERT(mUnit == eCSSUnit_Calc, |
682 | 0 | "The unit should be eCSSUnit_Calc"); |
683 | 0 |
|
684 | 0 | const nsCSSValue::Array* array = GetArrayValue(); |
685 | 0 | MOZ_ASSERT(array->Count() == 1, |
686 | 0 | "There should be a 1-length array"); |
687 | 0 |
|
688 | 0 | const nsCSSValue& rootValue = array->Item(0); |
689 | 0 |
|
690 | 0 | nsStyleCoord::CalcValue result; |
691 | 0 |
|
692 | 0 | if (rootValue.GetUnit() == eCSSUnit_Pixel) { |
693 | 0 | result.mLength = rootValue.GetPixelLength(); |
694 | 0 | result.mPercent = 0.0f; |
695 | 0 | result.mHasPercent = false; |
696 | 0 | } else { |
697 | 0 | MOZ_ASSERT(rootValue.GetUnit() == eCSSUnit_Calc_Plus, |
698 | 0 | "Calc unit should be eCSSUnit_Calc_Plus"); |
699 | 0 |
|
700 | 0 | const nsCSSValue::Array *calcPlusArray = rootValue.GetArrayValue(); |
701 | 0 | MOZ_ASSERT(calcPlusArray->Count() == 2, |
702 | 0 | "eCSSUnit_Calc_Plus should have a 2-length array"); |
703 | 0 |
|
704 | 0 | const nsCSSValue& length = calcPlusArray->Item(0); |
705 | 0 | const nsCSSValue& percent = calcPlusArray->Item(1); |
706 | 0 | MOZ_ASSERT(length.GetUnit() == eCSSUnit_Pixel, |
707 | 0 | "The first value should be eCSSUnit_Pixel"); |
708 | 0 | MOZ_ASSERT(percent.GetUnit() == eCSSUnit_Percent, |
709 | 0 | "The first value should be eCSSUnit_Percent"); |
710 | 0 | result.mLength = length.GetPixelLength(); |
711 | 0 | result.mPercent = percent.GetPercentValue(); |
712 | 0 | result.mHasPercent = true; |
713 | 0 | } |
714 | 0 |
|
715 | 0 | return result; |
716 | 0 | } |
717 | | |
718 | | nsCSSValue::Array* |
719 | | nsCSSValue::InitFunction(nsCSSKeyword aFunctionId, uint32_t aNumArgs) |
720 | 0 | { |
721 | 0 | RefPtr<nsCSSValue::Array> func = Array::Create(aNumArgs + 1); |
722 | 0 | func->Item(0).SetIntValue(aFunctionId, eCSSUnit_Enumerated); |
723 | 0 | SetArrayValue(func, eCSSUnit_Function); |
724 | 0 | return func; |
725 | 0 | } |
726 | | |
727 | | bool |
728 | | nsCSSValue::EqualsFunction(nsCSSKeyword aFunctionId) const |
729 | 0 | { |
730 | 0 | if (mUnit != eCSSUnit_Function) { |
731 | 0 | return false; |
732 | 0 | } |
733 | 0 | |
734 | 0 | nsCSSValue::Array* func = mValue.mArray; |
735 | 0 | MOZ_ASSERT(func && func->Count() >= 1 && |
736 | 0 | func->Item(0).GetUnit() == eCSSUnit_Enumerated, |
737 | 0 | "illegally structured function value"); |
738 | 0 |
|
739 | 0 | nsCSSKeyword thisFunctionId = func->Item(0).GetKeywordValue(); |
740 | 0 | return thisFunctionId == aFunctionId; |
741 | 0 | } |
742 | | |
743 | | // static |
744 | | already_AddRefed<nsStringBuffer> |
745 | | nsCSSValue::BufferFromString(const nsString& aValue) |
746 | 0 | { |
747 | 0 | RefPtr<nsStringBuffer> buffer = nsStringBuffer::FromString(aValue); |
748 | 0 | if (buffer) { |
749 | 0 | return buffer.forget(); |
750 | 0 | } |
751 | 0 | |
752 | 0 | nsString::size_type length = aValue.Length(); |
753 | 0 |
|
754 | 0 | // NOTE: Alloc prouduces a new, already-addref'd (refcnt = 1) buffer. |
755 | 0 | // NOTE: String buffer allocation is currently fallible. |
756 | 0 | size_t sz = (length + 1) * sizeof(char16_t); |
757 | 0 | buffer = nsStringBuffer::Alloc(sz); |
758 | 0 | if (MOZ_UNLIKELY(!buffer)) { |
759 | 0 | NS_ABORT_OOM(sz); |
760 | 0 | } |
761 | 0 |
|
762 | 0 | char16_t* data = static_cast<char16_t*>(buffer->Data()); |
763 | 0 | nsCharTraits<char16_t>::copy(data, aValue.get(), length); |
764 | 0 | // Null-terminate. |
765 | 0 | data[length] = 0; |
766 | 0 | return buffer.forget(); |
767 | 0 | } |
768 | | |
769 | | void |
770 | | nsCSSValue::AtomizeIdentValue() |
771 | 0 | { |
772 | 0 | MOZ_ASSERT(mUnit == eCSSUnit_Ident); |
773 | 0 | RefPtr<nsAtom> atom = NS_Atomize(GetStringBufferValue()); |
774 | 0 | Reset(); |
775 | 0 | mUnit = eCSSUnit_AtomIdent; |
776 | 0 | mValue.mAtom = atom.forget().take(); |
777 | 0 | } |
778 | | |
779 | | /* static */ void |
780 | | nsCSSValue::AppendAlignJustifyValueToString(int32_t aValue, nsAString& aResult) |
781 | 0 | { |
782 | 0 | auto legacy = aValue & NS_STYLE_ALIGN_LEGACY; |
783 | 0 | if (legacy) { |
784 | 0 | aValue &= ~legacy; |
785 | 0 | aResult.AppendLiteral("legacy"); |
786 | 0 | if (!aValue) { |
787 | 0 | return; |
788 | 0 | } |
789 | 0 | aResult.AppendLiteral(" "); |
790 | 0 | } |
791 | 0 | // Don't serialize the 'unsafe' keyword; it's the default. |
792 | 0 | auto overflowPos = aValue & (NS_STYLE_ALIGN_SAFE | NS_STYLE_ALIGN_UNSAFE); |
793 | 0 | if (MOZ_UNLIKELY(overflowPos == NS_STYLE_ALIGN_SAFE)) { |
794 | 0 | aResult.AppendLiteral("safe "); |
795 | 0 | } |
796 | 0 | aValue &= ~overflowPos; |
797 | 0 | MOZ_ASSERT(!(aValue & NS_STYLE_ALIGN_FLAG_BITS), |
798 | 0 | "unknown bits in align/justify value"); |
799 | 0 | MOZ_ASSERT((aValue != NS_STYLE_ALIGN_AUTO && |
800 | 0 | aValue != NS_STYLE_ALIGN_NORMAL && |
801 | 0 | aValue != NS_STYLE_ALIGN_BASELINE && |
802 | 0 | aValue != NS_STYLE_ALIGN_LAST_BASELINE) || |
803 | 0 | (!legacy && !overflowPos), |
804 | 0 | "auto/normal/baseline/'last baseline' never have any flags"); |
805 | 0 | MOZ_ASSERT(legacy == 0 || overflowPos == 0, |
806 | 0 | "'legacy' together with <overflow-position>"); |
807 | 0 | if (aValue == NS_STYLE_ALIGN_LAST_BASELINE) { |
808 | 0 | aResult.AppendLiteral("last "); |
809 | 0 | aValue = NS_STYLE_ALIGN_BASELINE; |
810 | 0 | } |
811 | 0 | const auto& kwtable(nsCSSProps::kAlignAllKeywords); |
812 | 0 | AppendASCIItoUTF16(nsCSSProps::ValueToKeyword(aValue, kwtable), aResult); |
813 | 0 | } |
814 | | |
815 | | size_t |
816 | | nsCSSValue::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const |
817 | 0 | { |
818 | 0 | size_t n = 0; |
819 | 0 |
|
820 | 0 | switch (GetUnit()) { |
821 | 0 | // No value: nothing extra to measure. |
822 | 0 | case eCSSUnit_Null: |
823 | 0 | case eCSSUnit_Auto: |
824 | 0 | case eCSSUnit_Inherit: |
825 | 0 | case eCSSUnit_Initial: |
826 | 0 | case eCSSUnit_Unset: |
827 | 0 | case eCSSUnit_None: |
828 | 0 | case eCSSUnit_Normal: |
829 | 0 | case eCSSUnit_System_Font: |
830 | 0 | case eCSSUnit_All: |
831 | 0 | case eCSSUnit_Dummy: |
832 | 0 | case eCSSUnit_DummyInherit: |
833 | 0 | break; |
834 | 0 |
|
835 | 0 | // String |
836 | 0 | case eCSSUnit_String: |
837 | 0 | case eCSSUnit_Ident: |
838 | 0 | case eCSSUnit_Attr: |
839 | 0 | case eCSSUnit_Local_Font: |
840 | 0 | case eCSSUnit_Font_Format: |
841 | 0 | case eCSSUnit_Element: |
842 | 0 | n += mValue.mString->SizeOfIncludingThisIfUnshared(aMallocSizeOf); |
843 | 0 | break; |
844 | 0 |
|
845 | 0 | // Array |
846 | 0 | case eCSSUnit_Array: |
847 | 0 | case eCSSUnit_Counter: |
848 | 0 | case eCSSUnit_Counters: |
849 | 0 | case eCSSUnit_Cubic_Bezier: |
850 | 0 | case eCSSUnit_Steps: |
851 | 0 | case eCSSUnit_Symbols: |
852 | 0 | case eCSSUnit_Function: |
853 | 0 | case eCSSUnit_Calc: |
854 | 0 | case eCSSUnit_Calc_Plus: |
855 | 0 | case eCSSUnit_Calc_Minus: |
856 | 0 | case eCSSUnit_Calc_Times_L: |
857 | 0 | case eCSSUnit_Calc_Times_R: |
858 | 0 | case eCSSUnit_Calc_Divided: |
859 | 0 | break; |
860 | 0 |
|
861 | 0 | // URL |
862 | 0 | case eCSSUnit_URL: |
863 | 0 | n += mValue.mURL->SizeOfIncludingThis(aMallocSizeOf); |
864 | 0 | break; |
865 | 0 |
|
866 | 0 | // Pair |
867 | 0 | case eCSSUnit_Pair: |
868 | 0 | n += mValue.mPair->SizeOfIncludingThis(aMallocSizeOf); |
869 | 0 | break; |
870 | 0 |
|
871 | 0 | // List |
872 | 0 | case eCSSUnit_List: |
873 | 0 | n += mValue.mList->SizeOfIncludingThis(aMallocSizeOf); |
874 | 0 | break; |
875 | 0 |
|
876 | 0 | // ListDep: not measured because it's non-owning. |
877 | 0 | case eCSSUnit_ListDep: |
878 | 0 | break; |
879 | 0 |
|
880 | 0 | // SharedList |
881 | 0 | case eCSSUnit_SharedList: |
882 | 0 | // Makes more sense not to measure, since it most cases the list |
883 | 0 | // will be shared. |
884 | 0 | break; |
885 | 0 |
|
886 | 0 | // PairList |
887 | 0 | case eCSSUnit_PairList: |
888 | 0 | n += mValue.mPairList->SizeOfIncludingThis(aMallocSizeOf); |
889 | 0 | break; |
890 | 0 |
|
891 | 0 | // PairListDep: not measured because it's non-owning. |
892 | 0 | case eCSSUnit_PairListDep: |
893 | 0 | break; |
894 | 0 |
|
895 | 0 | // GridTemplateAreas |
896 | 0 | case eCSSUnit_GridTemplateAreas: |
897 | 0 | n += mValue.mGridTemplateAreas->SizeOfIncludingThis(aMallocSizeOf); |
898 | 0 | break; |
899 | 0 |
|
900 | 0 | case eCSSUnit_FontFamilyList: |
901 | 0 | // The SharedFontList is a refcounted object, but is unique per |
902 | 0 | // declaration. We don't measure the references from computed |
903 | 0 | // values. |
904 | 0 | n += mValue.mFontFamilyList->SizeOfIncludingThis(aMallocSizeOf); |
905 | 0 | break; |
906 | 0 |
|
907 | 0 | // Atom is always shared, and thus should not be counted. |
908 | 0 | case eCSSUnit_AtomIdent: |
909 | 0 | break; |
910 | 0 |
|
911 | 0 | // Int: nothing extra to measure. |
912 | 0 | case eCSSUnit_Integer: |
913 | 0 | case eCSSUnit_Enumerated: |
914 | 0 | case eCSSUnit_FontStretch: |
915 | 0 | case eCSSUnit_FontSlantStyle: |
916 | 0 | case eCSSUnit_FontWeight: |
917 | 0 | break; |
918 | 0 |
|
919 | 0 | // Float: nothing extra to measure. |
920 | 0 | case eCSSUnit_Percent: |
921 | 0 | case eCSSUnit_Number: |
922 | 0 | case eCSSUnit_ViewportWidth: |
923 | 0 | case eCSSUnit_ViewportHeight: |
924 | 0 | case eCSSUnit_ViewportMin: |
925 | 0 | case eCSSUnit_ViewportMax: |
926 | 0 | case eCSSUnit_EM: |
927 | 0 | case eCSSUnit_XHeight: |
928 | 0 | case eCSSUnit_Char: |
929 | 0 | case eCSSUnit_RootEM: |
930 | 0 | case eCSSUnit_Point: |
931 | 0 | case eCSSUnit_Inch: |
932 | 0 | case eCSSUnit_Millimeter: |
933 | 0 | case eCSSUnit_Centimeter: |
934 | 0 | case eCSSUnit_Pica: |
935 | 0 | case eCSSUnit_Pixel: |
936 | 0 | case eCSSUnit_Quarter: |
937 | 0 | case eCSSUnit_Degree: |
938 | 0 | case eCSSUnit_Grad: |
939 | 0 | case eCSSUnit_Turn: |
940 | 0 | case eCSSUnit_Radian: |
941 | 0 | case eCSSUnit_Hertz: |
942 | 0 | case eCSSUnit_Kilohertz: |
943 | 0 | case eCSSUnit_Seconds: |
944 | 0 | case eCSSUnit_Milliseconds: |
945 | 0 | case eCSSUnit_FlexFraction: |
946 | 0 | break; |
947 | 0 |
|
948 | 0 | default: |
949 | 0 | MOZ_ASSERT(false, "bad nsCSSUnit"); |
950 | 0 | break; |
951 | 0 | } |
952 | 0 |
|
953 | 0 | return n; |
954 | 0 | } |
955 | | |
956 | | // --- nsCSSValueList ----------------- |
957 | | |
958 | | nsCSSValueList::~nsCSSValueList() |
959 | 0 | { |
960 | 0 | MOZ_COUNT_DTOR(nsCSSValueList); |
961 | 0 | NS_CSS_DELETE_LIST_MEMBER(nsCSSValueList, this, mNext); |
962 | 0 | } |
963 | | |
964 | | nsCSSValueList* |
965 | | nsCSSValueList::Clone() const |
966 | 0 | { |
967 | 0 | nsCSSValueList* result = new nsCSSValueList(*this); |
968 | 0 | nsCSSValueList* dest = result; |
969 | 0 | const nsCSSValueList* src = this->mNext; |
970 | 0 | while (src) { |
971 | 0 | dest->mNext = new nsCSSValueList(*src); |
972 | 0 | dest = dest->mNext; |
973 | 0 | src = src->mNext; |
974 | 0 | } |
975 | 0 |
|
976 | 0 | MOZ_ASSERT(result, "shouldn't return null; supposed to be infallible"); |
977 | 0 | return result; |
978 | 0 | } |
979 | | |
980 | | void |
981 | | nsCSSValueList::CloneInto(nsCSSValueList* aList) const |
982 | 0 | { |
983 | 0 | NS_ASSERTION(!aList->mNext, "Must be an empty list!"); |
984 | 0 | aList->mValue = mValue; |
985 | 0 | aList->mNext = mNext ? mNext->Clone() : nullptr; |
986 | 0 | } |
987 | | |
988 | | /* static */ bool |
989 | | nsCSSValueList::Equal(const nsCSSValueList* aList1, |
990 | | const nsCSSValueList* aList2) |
991 | 0 | { |
992 | 0 | if (aList1 == aList2) { |
993 | 0 | return true; |
994 | 0 | } |
995 | 0 | |
996 | 0 | const nsCSSValueList *p1 = aList1, *p2 = aList2; |
997 | 0 | for ( ; p1 && p2; p1 = p1->mNext, p2 = p2->mNext) { |
998 | 0 | if (p1->mValue != p2->mValue) |
999 | 0 | return false; |
1000 | 0 | } |
1001 | 0 | return !p1 && !p2; // true if same length, false otherwise |
1002 | 0 | } |
1003 | | |
1004 | | size_t |
1005 | | nsCSSValueList::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const |
1006 | 0 | { |
1007 | 0 | size_t n = 0; |
1008 | 0 | const nsCSSValueList* v = this; |
1009 | 0 | while (v) { |
1010 | 0 | n += aMallocSizeOf(v); |
1011 | 0 | n += v->mValue.SizeOfExcludingThis(aMallocSizeOf); |
1012 | 0 | v = v->mNext; |
1013 | 0 | } |
1014 | 0 | return n; |
1015 | 0 | } |
1016 | | |
1017 | | size_t |
1018 | | nsCSSValueList_heap::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const |
1019 | 0 | { |
1020 | 0 | // Only measure it if it's unshared, to avoid double-counting. |
1021 | 0 | size_t n = 0; |
1022 | 0 | if (mRefCnt <= 1) { |
1023 | 0 | n += aMallocSizeOf(this); |
1024 | 0 | n += mValue.SizeOfExcludingThis(aMallocSizeOf); |
1025 | 0 | n += mNext ? mNext->SizeOfIncludingThis(aMallocSizeOf) : 0; |
1026 | 0 | } |
1027 | 0 | return n; |
1028 | 0 | } |
1029 | | |
1030 | | // --- nsCSSValueSharedList ----------------- |
1031 | | |
1032 | | nsCSSValueSharedList::~nsCSSValueSharedList() |
1033 | 0 | { |
1034 | 0 | if (mHead) { |
1035 | 0 | NS_CSS_DELETE_LIST_MEMBER(nsCSSValueList, mHead, mNext); |
1036 | 0 | delete mHead; |
1037 | 0 | } |
1038 | 0 | } |
1039 | | |
1040 | | bool |
1041 | | nsCSSValueSharedList::operator==(const nsCSSValueSharedList& aOther) const |
1042 | 0 | { |
1043 | 0 | return nsCSSValueList::Equal(mHead, aOther.mHead); |
1044 | 0 | } |
1045 | | |
1046 | | size_t |
1047 | | nsCSSValueSharedList::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const |
1048 | 0 | { |
1049 | 0 | // Only measure it if it's unshared, to avoid double-counting. |
1050 | 0 | size_t n = 0; |
1051 | 0 | if (mRefCnt <= 1) { |
1052 | 0 | n += aMallocSizeOf(this); |
1053 | 0 | n += mHead->SizeOfIncludingThis(aMallocSizeOf); |
1054 | 0 | } |
1055 | 0 | return n; |
1056 | 0 | } |
1057 | | |
1058 | | // --- nsCSSValuePair ----------------- |
1059 | | |
1060 | | size_t |
1061 | | nsCSSValuePair::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const |
1062 | 0 | { |
1063 | 0 | size_t n = 0; |
1064 | 0 | n += mXValue.SizeOfExcludingThis(aMallocSizeOf); |
1065 | 0 | n += mYValue.SizeOfExcludingThis(aMallocSizeOf); |
1066 | 0 | return n; |
1067 | 0 | } |
1068 | | |
1069 | | size_t |
1070 | | nsCSSValuePair_heap::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const |
1071 | 0 | { |
1072 | 0 | // Only measure it if it's unshared, to avoid double-counting. |
1073 | 0 | size_t n = 0; |
1074 | 0 | if (mRefCnt <= 1) { |
1075 | 0 | n += aMallocSizeOf(this); |
1076 | 0 | n += mXValue.SizeOfExcludingThis(aMallocSizeOf); |
1077 | 0 | n += mYValue.SizeOfExcludingThis(aMallocSizeOf); |
1078 | 0 | } |
1079 | 0 | return n; |
1080 | 0 | } |
1081 | | |
1082 | | // --- nsCSSValuePairList ----------------- |
1083 | | |
1084 | | nsCSSValuePairList::~nsCSSValuePairList() |
1085 | 0 | { |
1086 | 0 | MOZ_COUNT_DTOR(nsCSSValuePairList); |
1087 | 0 | NS_CSS_DELETE_LIST_MEMBER(nsCSSValuePairList, this, mNext); |
1088 | 0 | } |
1089 | | |
1090 | | nsCSSValuePairList* |
1091 | | nsCSSValuePairList::Clone() const |
1092 | 0 | { |
1093 | 0 | nsCSSValuePairList* result = new nsCSSValuePairList(*this); |
1094 | 0 | nsCSSValuePairList* dest = result; |
1095 | 0 | const nsCSSValuePairList* src = this->mNext; |
1096 | 0 | while (src) { |
1097 | 0 | dest->mNext = new nsCSSValuePairList(*src); |
1098 | 0 | dest = dest->mNext; |
1099 | 0 | src = src->mNext; |
1100 | 0 | } |
1101 | 0 |
|
1102 | 0 | MOZ_ASSERT(result, "shouldn't return null; supposed to be infallible"); |
1103 | 0 | return result; |
1104 | 0 | } |
1105 | | |
1106 | | /* static */ bool |
1107 | | nsCSSValuePairList::Equal(const nsCSSValuePairList* aList1, |
1108 | | const nsCSSValuePairList* aList2) |
1109 | 0 | { |
1110 | 0 | if (aList1 == aList2) { |
1111 | 0 | return true; |
1112 | 0 | } |
1113 | 0 | |
1114 | 0 | const nsCSSValuePairList *p1 = aList1, *p2 = aList2; |
1115 | 0 | for ( ; p1 && p2; p1 = p1->mNext, p2 = p2->mNext) { |
1116 | 0 | if (p1->mXValue != p2->mXValue || |
1117 | 0 | p1->mYValue != p2->mYValue) |
1118 | 0 | return false; |
1119 | 0 | } |
1120 | 0 | return !p1 && !p2; // true if same length, false otherwise |
1121 | 0 | } |
1122 | | |
1123 | | size_t |
1124 | | nsCSSValuePairList::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const |
1125 | 0 | { |
1126 | 0 | size_t n = 0; |
1127 | 0 | const nsCSSValuePairList* v = this; |
1128 | 0 | while (v) { |
1129 | 0 | n += aMallocSizeOf(v); |
1130 | 0 | n += v->mXValue.SizeOfExcludingThis(aMallocSizeOf); |
1131 | 0 | n += v->mYValue.SizeOfExcludingThis(aMallocSizeOf); |
1132 | 0 | v = v->mNext; |
1133 | 0 | } |
1134 | 0 | return n; |
1135 | 0 | } |
1136 | | |
1137 | | size_t |
1138 | | nsCSSValuePairList_heap::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const |
1139 | 0 | { |
1140 | 0 | // Only measure it if it's unshared, to avoid double-counting. |
1141 | 0 | size_t n = 0; |
1142 | 0 | if (mRefCnt <= 1) { |
1143 | 0 | n += aMallocSizeOf(this); |
1144 | 0 | n += mXValue.SizeOfExcludingThis(aMallocSizeOf); |
1145 | 0 | n += mYValue.SizeOfExcludingThis(aMallocSizeOf); |
1146 | 0 | n += mNext ? mNext->SizeOfIncludingThis(aMallocSizeOf) : 0; |
1147 | 0 | } |
1148 | 0 | return n; |
1149 | 0 | } |
1150 | | |
1151 | | size_t |
1152 | | nsCSSValue::Array::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const |
1153 | 0 | { |
1154 | 0 | size_t n = aMallocSizeOf(this); |
1155 | 0 | for (size_t i = 0; i < mCount; i++) { |
1156 | 0 | n += mArray[i].SizeOfExcludingThis(aMallocSizeOf); |
1157 | 0 | } |
1158 | 0 | return n; |
1159 | 0 | } |
1160 | | |
1161 | | css::URLValueData::URLValueData(already_AddRefed<nsIURI> aURI, |
1162 | | ServoRawOffsetArc<RustString> aString, |
1163 | | already_AddRefed<URLExtraData> aExtraData, |
1164 | | CORSMode aCORSMode) |
1165 | | : mURI(std::move(aURI)) |
1166 | | , mExtraData(std::move(aExtraData)) |
1167 | | , mURIResolved(true) |
1168 | | , mString(aString) |
1169 | | , mCORSMode(aCORSMode) |
1170 | 0 | { |
1171 | 0 | MOZ_ASSERT(mExtraData); |
1172 | 0 | MOZ_ASSERT(mExtraData->GetPrincipal()); |
1173 | 0 | } |
1174 | | |
1175 | | css::URLValueData::URLValueData(ServoRawOffsetArc<RustString> aString, |
1176 | | already_AddRefed<URLExtraData> aExtraData, |
1177 | | CORSMode aCORSMode) |
1178 | | : mExtraData(std::move(aExtraData)) |
1179 | | , mURIResolved(false) |
1180 | | , mString(aString) |
1181 | | , mCORSMode(aCORSMode) |
1182 | 0 | { |
1183 | 0 | MOZ_ASSERT(mExtraData); |
1184 | 0 | MOZ_ASSERT(mExtraData->GetPrincipal()); |
1185 | 0 | } |
1186 | | |
1187 | | css::URLValueData::~URLValueData() |
1188 | 0 | { |
1189 | 0 | Servo_ReleaseArcStringData(&mString); |
1190 | 0 | } |
1191 | | |
1192 | | bool |
1193 | | css::URLValueData::Equals(const URLValueData& aOther) const |
1194 | 0 | { |
1195 | 0 | MOZ_ASSERT(NS_IsMainThread()); |
1196 | 0 |
|
1197 | 0 | bool eq; |
1198 | 0 | const URLExtraData* self = mExtraData; |
1199 | 0 | const URLExtraData* other = aOther.mExtraData; |
1200 | 0 | return GetString() == aOther.GetString() && |
1201 | 0 | (GetURI() == aOther.GetURI() || // handles null == null |
1202 | 0 | (mURI && aOther.mURI && |
1203 | 0 | NS_SUCCEEDED(mURI->Equals(aOther.mURI, &eq)) && |
1204 | 0 | eq)) && |
1205 | 0 | (self->BaseURI() == other->BaseURI() || |
1206 | 0 | (NS_SUCCEEDED(self->BaseURI()->Equals(other->BaseURI(), &eq)) && |
1207 | 0 | eq)) && |
1208 | 0 | (self->GetPrincipal() == other->GetPrincipal() || |
1209 | 0 | self->GetPrincipal()->Equals(other->GetPrincipal())) && |
1210 | 0 | IsLocalRef() == aOther.IsLocalRef(); |
1211 | 0 | } |
1212 | | |
1213 | | bool |
1214 | | css::URLValueData::DefinitelyEqualURIs(const URLValueData& aOther) const |
1215 | 0 | { |
1216 | 0 | if (mExtraData->BaseURI() != aOther.mExtraData->BaseURI()) { |
1217 | 0 | return false; |
1218 | 0 | } |
1219 | 0 | return GetString() == aOther.GetString(); |
1220 | 0 | } |
1221 | | |
1222 | | bool |
1223 | | css::URLValueData::DefinitelyEqualURIsAndPrincipal( |
1224 | | const URLValueData& aOther) const |
1225 | 0 | { |
1226 | 0 | return mExtraData->GetPrincipal() == aOther.mExtraData->GetPrincipal() && |
1227 | 0 | DefinitelyEqualURIs(aOther); |
1228 | 0 | } |
1229 | | |
1230 | | nsDependentCSubstring |
1231 | | css::URLValueData::GetString() const |
1232 | 0 | { |
1233 | 0 | const uint8_t* chars; |
1234 | 0 | uint32_t len; |
1235 | 0 | Servo_GetArcStringData(mString.mPtr, &chars, &len); |
1236 | 0 | return nsDependentCSubstring(reinterpret_cast<const char*>(chars), len); |
1237 | 0 | } |
1238 | | |
1239 | | nsIURI* |
1240 | | css::URLValueData::GetURI() const |
1241 | 0 | { |
1242 | 0 | MOZ_ASSERT(NS_IsMainThread()); |
1243 | 0 |
|
1244 | 0 | if (!mURIResolved) { |
1245 | 0 | MOZ_ASSERT(!mURI); |
1246 | 0 | nsCOMPtr<nsIURI> newURI; |
1247 | 0 | NS_NewURI(getter_AddRefs(newURI), |
1248 | 0 | GetString(), |
1249 | 0 | nullptr, mExtraData->BaseURI()); |
1250 | 0 | mURI = newURI.forget(); |
1251 | 0 | mURIResolved = true; |
1252 | 0 | } |
1253 | 0 |
|
1254 | 0 | return mURI; |
1255 | 0 | } |
1256 | | |
1257 | | bool |
1258 | | css::URLValueData::IsLocalRef() const |
1259 | 0 | { |
1260 | 0 | if (mIsLocalRef.isNothing()) { |
1261 | 0 | // IsLocalRefURL is O(N), use it only when IsLocalRef is called. |
1262 | 0 | mIsLocalRef.emplace(nsContentUtils::IsLocalRefURL(GetString())); |
1263 | 0 | } |
1264 | 0 | return mIsLocalRef.value(); |
1265 | 0 | } |
1266 | | |
1267 | | bool |
1268 | | css::URLValueData::HasRef() const |
1269 | 0 | { |
1270 | 0 | bool result = false; |
1271 | 0 |
|
1272 | 0 | if (IsLocalRef()) { |
1273 | 0 | result = true; |
1274 | 0 | } else { |
1275 | 0 | if (nsIURI* uri = GetURI()) { |
1276 | 0 | nsAutoCString ref; |
1277 | 0 | nsresult rv = uri->GetRef(ref); |
1278 | 0 | if (NS_SUCCEEDED(rv) && !ref.IsEmpty()) { |
1279 | 0 | result = true; |
1280 | 0 | } |
1281 | 0 | } |
1282 | 0 | } |
1283 | 0 |
|
1284 | 0 | mMightHaveRef = Some(result); |
1285 | 0 |
|
1286 | 0 | return result; |
1287 | 0 | } |
1288 | | |
1289 | | bool |
1290 | | css::URLValueData::MightHaveRef() const |
1291 | 0 | { |
1292 | 0 | if (mMightHaveRef.isNothing()) { |
1293 | 0 | bool result = ::MightHaveRef(GetString()); |
1294 | 0 | if (!ServoStyleSet::IsInServoTraversal()) { |
1295 | 0 | // Can only cache the result if we're not on a style worker thread. |
1296 | 0 | mMightHaveRef.emplace(result); |
1297 | 0 | } |
1298 | 0 | return result; |
1299 | 0 | } |
1300 | 0 |
|
1301 | 0 | return mMightHaveRef.value(); |
1302 | 0 | } |
1303 | | |
1304 | | already_AddRefed<nsIURI> |
1305 | | css::URLValueData::ResolveLocalRef(nsIURI* aURI) const |
1306 | 0 | { |
1307 | 0 | nsCOMPtr<nsIURI> result = GetURI(); |
1308 | 0 |
|
1309 | 0 | if (result && IsLocalRef()) { |
1310 | 0 | nsCString ref; |
1311 | 0 | mURI->GetRef(ref); |
1312 | 0 |
|
1313 | 0 | nsresult rv = NS_MutateURI(aURI) |
1314 | 0 | .SetRef(ref) |
1315 | 0 | .Finalize(result); |
1316 | 0 |
|
1317 | 0 | if (NS_FAILED(rv)) { |
1318 | 0 | // If setting the ref failed, just return the original URI. |
1319 | 0 | result = aURI; |
1320 | 0 | } |
1321 | 0 | } |
1322 | 0 |
|
1323 | 0 | return result.forget(); |
1324 | 0 | } |
1325 | | |
1326 | | already_AddRefed<nsIURI> |
1327 | | css::URLValueData::ResolveLocalRef(nsIContent* aContent) const |
1328 | 0 | { |
1329 | 0 | nsCOMPtr<nsIURI> url = aContent->GetBaseURI(); |
1330 | 0 | return ResolveLocalRef(url); |
1331 | 0 | } |
1332 | | |
1333 | | void |
1334 | | css::URLValueData::GetSourceString(nsString& aRef) const |
1335 | 0 | { |
1336 | 0 | nsIURI* uri = GetURI(); |
1337 | 0 | if (!uri) { |
1338 | 0 | aRef.Truncate(); |
1339 | 0 | return; |
1340 | 0 | } |
1341 | 0 | |
1342 | 0 | nsCString cref; |
1343 | 0 | if (IsLocalRef()) { |
1344 | 0 | // XXXheycam It's possible we can just return mString in this case, since |
1345 | 0 | // it should be the "#fragment" string the URLValueData was created with. |
1346 | 0 | uri->GetRef(cref); |
1347 | 0 | cref.Insert('#', 0); |
1348 | 0 | } else { |
1349 | 0 | // It's not entirely clear how to best handle failure here. Ensuring the |
1350 | 0 | // string is empty seems safest. |
1351 | 0 | nsresult rv = uri->GetSpec(cref); |
1352 | 0 | if (NS_FAILED(rv)) { |
1353 | 0 | cref.Truncate(); |
1354 | 0 | } |
1355 | 0 | } |
1356 | 0 |
|
1357 | 0 | aRef = NS_ConvertUTF8toUTF16(cref); |
1358 | 0 | } |
1359 | | |
1360 | | bool |
1361 | | css::URLValueData::EqualsExceptRef(nsIURI* aURI) const |
1362 | 0 | { |
1363 | 0 | nsIURI* uri = GetURI(); |
1364 | 0 | if (!uri) { |
1365 | 0 | return false; |
1366 | 0 | } |
1367 | 0 | |
1368 | 0 | bool ret = false; |
1369 | 0 | uri->EqualsExceptRef(aURI, &ret); |
1370 | 0 | return ret; |
1371 | 0 | } |
1372 | | |
1373 | | size_t |
1374 | | css::URLValueData::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const |
1375 | 0 | { |
1376 | 0 | // Measurement of the following members may be added later if DMD finds it |
1377 | 0 | // is worthwhile: |
1378 | 0 | // - mURI |
1379 | 0 | // - mString |
1380 | 0 | // - mExtraData |
1381 | 0 | return 0; |
1382 | 0 | } |
1383 | | |
1384 | | size_t |
1385 | | css::URLValue::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const |
1386 | 0 | { |
1387 | 0 | // Only measure it if it's unshared, to avoid double-counting. |
1388 | 0 | size_t n = 0; |
1389 | 0 | if (mRefCnt <= 1) { |
1390 | 0 | n += aMallocSizeOf(this); |
1391 | 0 | n += URLValueData::SizeOfExcludingThis(aMallocSizeOf); |
1392 | 0 | } |
1393 | 0 | return n; |
1394 | 0 | } |
1395 | | |
1396 | | css::ImageValue::ImageValue(nsIURI* aURI, |
1397 | | ServoRawOffsetArc<RustString> aString, |
1398 | | already_AddRefed<URLExtraData> aExtraData, |
1399 | | nsIDocument* aDocument, |
1400 | | CORSMode aCORSMode) |
1401 | | : URLValueData(do_AddRef(aURI), aString, std::move(aExtraData), aCORSMode) |
1402 | 0 | { |
1403 | 0 | Initialize(aDocument); |
1404 | 0 | } |
1405 | | |
1406 | | css::ImageValue::ImageValue(ServoRawOffsetArc<RustString> aString, |
1407 | | already_AddRefed<URLExtraData> aExtraData, |
1408 | | CORSMode aCORSMode) |
1409 | | : URLValueData(aString, std::move(aExtraData), aCORSMode) |
1410 | 0 | { |
1411 | 0 | } |
1412 | | |
1413 | | /*static*/ already_AddRefed<css::ImageValue> |
1414 | | css::ImageValue::CreateFromURLValue(URLValue* aUrl, |
1415 | | nsIDocument* aDocument, |
1416 | | CORSMode aCORSMode) |
1417 | 0 | { |
1418 | 0 | return do_AddRef( |
1419 | 0 | new css::ImageValue(aUrl->GetURI(), |
1420 | 0 | Servo_CloneArcStringData(&aUrl->mString), |
1421 | 0 | do_AddRef(aUrl->mExtraData), |
1422 | 0 | aDocument, |
1423 | 0 | aCORSMode)); |
1424 | 0 | } |
1425 | | |
1426 | | void |
1427 | | css::ImageValue::Initialize(nsIDocument* aDocument) |
1428 | 0 | { |
1429 | 0 | MOZ_ASSERT(NS_IsMainThread()); |
1430 | 0 |
|
1431 | 0 | // NB: If aDocument is not the original document, we may not be able to load |
1432 | 0 | // images from aDocument. Instead we do the image load from the original doc |
1433 | 0 | // and clone it to aDocument. |
1434 | 0 | nsIDocument* loadingDoc = aDocument->GetOriginalDocument(); |
1435 | 0 | if (!loadingDoc) { |
1436 | 0 | loadingDoc = aDocument; |
1437 | 0 | } |
1438 | 0 |
|
1439 | 0 | if (!mLoadedImage) { |
1440 | 0 | loadingDoc->StyleImageLoader()->LoadImage(GetURI(), |
1441 | 0 | mExtraData->GetPrincipal(), |
1442 | 0 | mExtraData->GetReferrer(), |
1443 | 0 | mExtraData->GetReferrerPolicy(), |
1444 | 0 | this, |
1445 | 0 | mCORSMode); |
1446 | 0 |
|
1447 | 0 | mLoadedImage = true; |
1448 | 0 | } |
1449 | 0 |
|
1450 | 0 | aDocument->StyleImageLoader()->MaybeRegisterCSSImage(this); |
1451 | 0 | } |
1452 | | |
1453 | | css::ImageValue::~ImageValue() |
1454 | 0 | { |
1455 | 0 | MOZ_ASSERT(NS_IsMainThread() || mRequests.Count() == 0, |
1456 | 0 | "Destructor should run on main thread, or on non-main thread " |
1457 | 0 | "when mRequest is empty!"); |
1458 | 0 |
|
1459 | 0 | for (auto iter = mRequests.Iter(); !iter.Done(); iter.Next()) { |
1460 | 0 | nsIDocument* doc = iter.Key(); |
1461 | 0 | RefPtr<imgRequestProxy>& proxy = iter.Data(); |
1462 | 0 |
|
1463 | 0 | if (doc) { |
1464 | 0 | doc->StyleImageLoader()->DeregisterCSSImage(this); |
1465 | 0 | } |
1466 | 0 |
|
1467 | 0 | if (proxy) { |
1468 | 0 | proxy->CancelAndForgetObserver(NS_BINDING_ABORTED); |
1469 | 0 | } |
1470 | 0 |
|
1471 | 0 | iter.Remove(); |
1472 | 0 | } |
1473 | 0 | } |
1474 | | |
1475 | | size_t |
1476 | | css::ImageValue::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const |
1477 | 0 | { |
1478 | 0 | size_t n = aMallocSizeOf(this); |
1479 | 0 | n += css::URLValueData::SizeOfExcludingThis(aMallocSizeOf); |
1480 | 0 | n += mRequests.ShallowSizeOfExcludingThis(aMallocSizeOf); |
1481 | 0 | return n; |
1482 | 0 | } |
1483 | | |
1484 | | size_t |
1485 | | mozilla::css::GridTemplateAreasValue::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const |
1486 | 0 | { |
1487 | 0 | // Only measure it if it's unshared, to avoid double-counting. |
1488 | 0 | size_t n = 0; |
1489 | 0 | if (mRefCnt <= 1) { |
1490 | 0 | n += aMallocSizeOf(this); |
1491 | 0 | n += mNamedAreas.ShallowSizeOfExcludingThis(aMallocSizeOf); |
1492 | 0 | n += mTemplates.ShallowSizeOfExcludingThis(aMallocSizeOf); |
1493 | 0 | } |
1494 | 0 | return n; |
1495 | 0 | } |