|
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- |
|
2 * |
|
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 * This Original Code has been modified by IBM Corporation. Modifications made by IBM |
|
8 * described herein are Copyright (c) International Business Machines Corporation, 2000. |
|
9 * Modifications to Mozilla code or documentation identified per MPL Section 3.3 |
|
10 * |
|
11 * Date Modified by Description of modification |
|
12 * 04/20/2000 IBM Corp. OS/2 VisualAge build. |
|
13 */ |
|
14 |
|
15 /* |
|
16 * style sheet and style rule processor representing data from presentational |
|
17 * HTML attributes |
|
18 */ |
|
19 |
|
20 #include "nsHTMLStyleSheet.h" |
|
21 #include "nsMappedAttributes.h" |
|
22 #include "nsGkAtoms.h" |
|
23 #include "nsPresContext.h" |
|
24 #include "mozilla/EventStates.h" |
|
25 #include "nsIDocument.h" |
|
26 #include "nsIPresShell.h" |
|
27 #include "nsStyleConsts.h" |
|
28 #include "nsRuleWalker.h" |
|
29 #include "nsRuleData.h" |
|
30 #include "nsError.h" |
|
31 #include "nsRuleProcessorData.h" |
|
32 #include "nsCSSRuleProcessor.h" |
|
33 #include "mozilla/MemoryReporting.h" |
|
34 #include "mozilla/dom/Element.h" |
|
35 #include "nsHashKeys.h" |
|
36 #include "RestyleManager.h" |
|
37 |
|
38 using namespace mozilla; |
|
39 using namespace mozilla::dom; |
|
40 |
|
41 NS_IMPL_ISUPPORTS(nsHTMLStyleSheet::HTMLColorRule, nsIStyleRule) |
|
42 |
|
43 /* virtual */ void |
|
44 nsHTMLStyleSheet::HTMLColorRule::MapRuleInfoInto(nsRuleData* aRuleData) |
|
45 { |
|
46 if (aRuleData->mSIDs & NS_STYLE_INHERIT_BIT(Color)) { |
|
47 nsCSSValue* color = aRuleData->ValueForColor(); |
|
48 if (color->GetUnit() == eCSSUnit_Null && |
|
49 aRuleData->mPresContext->UseDocumentColors()) |
|
50 color->SetColorValue(mColor); |
|
51 } |
|
52 } |
|
53 |
|
54 #ifdef DEBUG |
|
55 /* virtual */ void |
|
56 nsHTMLStyleSheet::HTMLColorRule::List(FILE* out, int32_t aIndent) const |
|
57 { |
|
58 for (int32_t index = aIndent; --index >= 0; ) fputs(" ", out); |
|
59 fputs("[html color rule] {}\n", out); |
|
60 } |
|
61 #endif |
|
62 |
|
63 |
|
64 NS_IMPL_ISUPPORTS(nsHTMLStyleSheet::GenericTableRule, nsIStyleRule) |
|
65 |
|
66 #ifdef DEBUG |
|
67 /* virtual */ void |
|
68 nsHTMLStyleSheet::GenericTableRule::List(FILE* out, int32_t aIndent) const |
|
69 { |
|
70 for (int32_t index = aIndent; --index >= 0; ) fputs(" ", out); |
|
71 fputs("[generic table rule] {}\n", out); |
|
72 } |
|
73 #endif |
|
74 |
|
75 /* virtual */ void |
|
76 nsHTMLStyleSheet::TableTHRule::MapRuleInfoInto(nsRuleData* aRuleData) |
|
77 { |
|
78 if (aRuleData->mSIDs & NS_STYLE_INHERIT_BIT(Text)) { |
|
79 nsCSSValue* textAlign = aRuleData->ValueForTextAlign(); |
|
80 if (textAlign->GetUnit() == eCSSUnit_Null) { |
|
81 textAlign->SetIntValue(NS_STYLE_TEXT_ALIGN_MOZ_CENTER_OR_INHERIT, |
|
82 eCSSUnit_Enumerated); |
|
83 } |
|
84 } |
|
85 } |
|
86 |
|
87 /* virtual */ void |
|
88 nsHTMLStyleSheet::TableQuirkColorRule::MapRuleInfoInto(nsRuleData* aRuleData) |
|
89 { |
|
90 if (aRuleData->mSIDs & NS_STYLE_INHERIT_BIT(Color)) { |
|
91 nsCSSValue* color = aRuleData->ValueForColor(); |
|
92 // We do not check UseDocumentColors() here, because we want to |
|
93 // use the body color no matter what. |
|
94 if (color->GetUnit() == eCSSUnit_Null) |
|
95 color->SetIntValue(NS_STYLE_COLOR_INHERIT_FROM_BODY, |
|
96 eCSSUnit_Enumerated); |
|
97 } |
|
98 } |
|
99 |
|
100 |
|
101 NS_IMPL_ISUPPORTS(nsHTMLStyleSheet::LangRule, nsIStyleRule) |
|
102 |
|
103 /* virtual */ void |
|
104 nsHTMLStyleSheet::LangRule::MapRuleInfoInto(nsRuleData* aRuleData) |
|
105 { |
|
106 if (aRuleData->mSIDs & NS_STYLE_INHERIT_BIT(Font)) { |
|
107 nsCSSValue* lang = aRuleData->ValueForLang(); |
|
108 if (lang->GetUnit() == eCSSUnit_Null) { |
|
109 lang->SetStringValue(mLang, eCSSUnit_Ident); |
|
110 } |
|
111 } |
|
112 } |
|
113 |
|
114 #ifdef DEBUG |
|
115 /* virtual */ void |
|
116 nsHTMLStyleSheet::LangRule::List(FILE* out, int32_t aIndent) const |
|
117 { |
|
118 for (int32_t index = aIndent; --index >= 0; ) fputs(" ", out); |
|
119 fputs("[lang rule] { language: \"", out); |
|
120 fputs(NS_ConvertUTF16toUTF8(mLang).get(), out); |
|
121 fputs("\" }\n", out); |
|
122 } |
|
123 #endif |
|
124 |
|
125 // ----------------------------------------------------------- |
|
126 |
|
127 struct MappedAttrTableEntry : public PLDHashEntryHdr { |
|
128 nsMappedAttributes *mAttributes; |
|
129 }; |
|
130 |
|
131 static PLDHashNumber |
|
132 MappedAttrTable_HashKey(PLDHashTable *table, const void *key) |
|
133 { |
|
134 nsMappedAttributes *attributes = |
|
135 static_cast<nsMappedAttributes*>(const_cast<void*>(key)); |
|
136 |
|
137 return attributes->HashValue(); |
|
138 } |
|
139 |
|
140 static void |
|
141 MappedAttrTable_ClearEntry(PLDHashTable *table, PLDHashEntryHdr *hdr) |
|
142 { |
|
143 MappedAttrTableEntry *entry = static_cast<MappedAttrTableEntry*>(hdr); |
|
144 |
|
145 entry->mAttributes->DropStyleSheetReference(); |
|
146 memset(entry, 0, sizeof(MappedAttrTableEntry)); |
|
147 } |
|
148 |
|
149 static bool |
|
150 MappedAttrTable_MatchEntry(PLDHashTable *table, const PLDHashEntryHdr *hdr, |
|
151 const void *key) |
|
152 { |
|
153 nsMappedAttributes *attributes = |
|
154 static_cast<nsMappedAttributes*>(const_cast<void*>(key)); |
|
155 const MappedAttrTableEntry *entry = |
|
156 static_cast<const MappedAttrTableEntry*>(hdr); |
|
157 |
|
158 return attributes->Equals(entry->mAttributes); |
|
159 } |
|
160 |
|
161 static const PLDHashTableOps MappedAttrTable_Ops = { |
|
162 PL_DHashAllocTable, |
|
163 PL_DHashFreeTable, |
|
164 MappedAttrTable_HashKey, |
|
165 MappedAttrTable_MatchEntry, |
|
166 PL_DHashMoveEntryStub, |
|
167 MappedAttrTable_ClearEntry, |
|
168 PL_DHashFinalizeStub, |
|
169 nullptr |
|
170 }; |
|
171 |
|
172 // ----------------------------------------------------------- |
|
173 |
|
174 struct LangRuleTableEntry : public PLDHashEntryHdr { |
|
175 nsRefPtr<nsHTMLStyleSheet::LangRule> mRule; |
|
176 }; |
|
177 |
|
178 static PLDHashNumber |
|
179 LangRuleTable_HashKey(PLDHashTable *table, const void *key) |
|
180 { |
|
181 const nsString *lang = static_cast<const nsString*>(key); |
|
182 return HashString(*lang); |
|
183 } |
|
184 |
|
185 static void |
|
186 LangRuleTable_ClearEntry(PLDHashTable *table, PLDHashEntryHdr *hdr) |
|
187 { |
|
188 LangRuleTableEntry *entry = static_cast<LangRuleTableEntry*>(hdr); |
|
189 |
|
190 entry->~LangRuleTableEntry(); |
|
191 memset(entry, 0, sizeof(LangRuleTableEntry)); |
|
192 } |
|
193 |
|
194 static bool |
|
195 LangRuleTable_MatchEntry(PLDHashTable *table, const PLDHashEntryHdr *hdr, |
|
196 const void *key) |
|
197 { |
|
198 const nsString *lang = static_cast<const nsString*>(key); |
|
199 const LangRuleTableEntry *entry = static_cast<const LangRuleTableEntry*>(hdr); |
|
200 |
|
201 return entry->mRule->mLang == *lang; |
|
202 } |
|
203 |
|
204 static bool |
|
205 LangRuleTable_InitEntry(PLDHashTable *table, PLDHashEntryHdr *hdr, |
|
206 const void *key) |
|
207 { |
|
208 const nsString *lang = static_cast<const nsString*>(key); |
|
209 |
|
210 LangRuleTableEntry *entry = new (hdr) LangRuleTableEntry(); |
|
211 |
|
212 // Create the unique rule for this language |
|
213 entry->mRule = new nsHTMLStyleSheet::LangRule(*lang); |
|
214 |
|
215 return true; |
|
216 } |
|
217 |
|
218 static const PLDHashTableOps LangRuleTable_Ops = { |
|
219 PL_DHashAllocTable, |
|
220 PL_DHashFreeTable, |
|
221 LangRuleTable_HashKey, |
|
222 LangRuleTable_MatchEntry, |
|
223 PL_DHashMoveEntryStub, |
|
224 LangRuleTable_ClearEntry, |
|
225 PL_DHashFinalizeStub, |
|
226 LangRuleTable_InitEntry |
|
227 }; |
|
228 |
|
229 // ----------------------------------------------------------- |
|
230 |
|
231 nsHTMLStyleSheet::nsHTMLStyleSheet(nsIDocument* aDocument) |
|
232 : mDocument(aDocument) |
|
233 , mTableQuirkColorRule(new TableQuirkColorRule()) |
|
234 , mTableTHRule(new TableTHRule()) |
|
235 { |
|
236 MOZ_ASSERT(aDocument); |
|
237 mMappedAttrTable.ops = nullptr; |
|
238 mLangRuleTable.ops = nullptr; |
|
239 } |
|
240 |
|
241 nsHTMLStyleSheet::~nsHTMLStyleSheet() |
|
242 { |
|
243 if (mLangRuleTable.ops) |
|
244 PL_DHashTableFinish(&mLangRuleTable); |
|
245 if (mMappedAttrTable.ops) |
|
246 PL_DHashTableFinish(&mMappedAttrTable); |
|
247 } |
|
248 |
|
249 NS_IMPL_ISUPPORTS(nsHTMLStyleSheet, nsIStyleRuleProcessor) |
|
250 |
|
251 /* virtual */ void |
|
252 nsHTMLStyleSheet::RulesMatching(ElementRuleProcessorData* aData) |
|
253 { |
|
254 nsRuleWalker *ruleWalker = aData->mRuleWalker; |
|
255 if (aData->mElement->IsHTML() && !ruleWalker->AuthorStyleDisabled()) { |
|
256 nsIAtom* tag = aData->mElement->Tag(); |
|
257 |
|
258 // if we have anchor colors, check if this is an anchor with an href |
|
259 if (tag == nsGkAtoms::a) { |
|
260 if (mLinkRule || mVisitedRule || mActiveRule) { |
|
261 EventStates state = |
|
262 nsCSSRuleProcessor::GetContentStateForVisitedHandling( |
|
263 aData->mElement, |
|
264 aData->mTreeMatchContext, |
|
265 aData->mTreeMatchContext.VisitedHandling(), |
|
266 // If the node being matched is a link, |
|
267 // it's the relevant link. |
|
268 nsCSSRuleProcessor::IsLink(aData->mElement)); |
|
269 if (mLinkRule && state.HasState(NS_EVENT_STATE_UNVISITED)) { |
|
270 ruleWalker->Forward(mLinkRule); |
|
271 aData->mTreeMatchContext.SetHaveRelevantLink(); |
|
272 } |
|
273 else if (mVisitedRule && state.HasState(NS_EVENT_STATE_VISITED)) { |
|
274 ruleWalker->Forward(mVisitedRule); |
|
275 aData->mTreeMatchContext.SetHaveRelevantLink(); |
|
276 } |
|
277 |
|
278 // No need to add to the active rule if it's not a link |
|
279 if (mActiveRule && nsCSSRuleProcessor::IsLink(aData->mElement) && |
|
280 state.HasState(NS_EVENT_STATE_ACTIVE)) { |
|
281 ruleWalker->Forward(mActiveRule); |
|
282 } |
|
283 } // end link/visited/active rules |
|
284 } // end A tag |
|
285 // add the rule to handle text-align for a <th> |
|
286 else if (tag == nsGkAtoms::th) { |
|
287 ruleWalker->Forward(mTableTHRule); |
|
288 } |
|
289 else if (tag == nsGkAtoms::table) { |
|
290 if (aData->mTreeMatchContext.mCompatMode == eCompatibility_NavQuirks) { |
|
291 ruleWalker->Forward(mTableQuirkColorRule); |
|
292 } |
|
293 } |
|
294 } // end html element |
|
295 |
|
296 // just get the style rules from the content. For SVG we do this even if |
|
297 // author style is disabled, because SVG presentational hints aren't |
|
298 // considered style. |
|
299 if (!ruleWalker->AuthorStyleDisabled() || aData->mElement->IsSVG()) { |
|
300 aData->mElement->WalkContentStyleRules(ruleWalker); |
|
301 } |
|
302 |
|
303 // http://www.whatwg.org/specs/web-apps/current-work/multipage/elements.html#language |
|
304 // says that the xml:lang attribute overrides HTML's lang attribute, |
|
305 // so we need to do this after WalkContentStyleRules. |
|
306 nsString lang; |
|
307 if (aData->mElement->GetAttr(kNameSpaceID_XML, nsGkAtoms::lang, lang)) { |
|
308 ruleWalker->Forward(LangRuleFor(lang)); |
|
309 } |
|
310 } |
|
311 |
|
312 // Test if style is dependent on content state |
|
313 /* virtual */ nsRestyleHint |
|
314 nsHTMLStyleSheet::HasStateDependentStyle(StateRuleProcessorData* aData) |
|
315 { |
|
316 if (aData->mElement->IsHTML(nsGkAtoms::a) && |
|
317 nsCSSRuleProcessor::IsLink(aData->mElement) && |
|
318 ((mActiveRule && aData->mStateMask.HasState(NS_EVENT_STATE_ACTIVE)) || |
|
319 (mLinkRule && aData->mStateMask.HasState(NS_EVENT_STATE_VISITED)) || |
|
320 (mVisitedRule && aData->mStateMask.HasState(NS_EVENT_STATE_VISITED)))) { |
|
321 return eRestyle_Self; |
|
322 } |
|
323 |
|
324 return nsRestyleHint(0); |
|
325 } |
|
326 |
|
327 /* virtual */ nsRestyleHint |
|
328 nsHTMLStyleSheet::HasStateDependentStyle(PseudoElementStateRuleProcessorData* aData) |
|
329 { |
|
330 return nsRestyleHint(0); |
|
331 } |
|
332 |
|
333 /* virtual */ bool |
|
334 nsHTMLStyleSheet::HasDocumentStateDependentStyle(StateRuleProcessorData* aData) |
|
335 { |
|
336 return false; |
|
337 } |
|
338 |
|
339 /* virtual */ nsRestyleHint |
|
340 nsHTMLStyleSheet::HasAttributeDependentStyle(AttributeRuleProcessorData* aData) |
|
341 { |
|
342 // Do nothing on before-change checks |
|
343 if (!aData->mAttrHasChanged) { |
|
344 return nsRestyleHint(0); |
|
345 } |
|
346 |
|
347 // Note: no need to worry about whether some states changed with this |
|
348 // attribute here, because we handle that under HasStateDependentStyle() as |
|
349 // needed. |
|
350 |
|
351 // Result is true for |href| changes on HTML links if we have link rules. |
|
352 Element *element = aData->mElement; |
|
353 if (aData->mAttribute == nsGkAtoms::href && |
|
354 (mLinkRule || mVisitedRule || mActiveRule) && |
|
355 element->IsHTML(nsGkAtoms::a)) { |
|
356 return eRestyle_Self; |
|
357 } |
|
358 |
|
359 // Don't worry about the mDocumentColorRule since it only applies |
|
360 // to descendants of body, when we're already reresolving. |
|
361 |
|
362 // Handle the content style rules. |
|
363 if (element->IsAttributeMapped(aData->mAttribute)) { |
|
364 // cellpadding on tables is special and requires reresolving all |
|
365 // the cells in the table |
|
366 if (aData->mAttribute == nsGkAtoms::cellpadding && |
|
367 element->IsHTML(nsGkAtoms::table)) { |
|
368 return eRestyle_Subtree; |
|
369 } |
|
370 return eRestyle_Self; |
|
371 } |
|
372 |
|
373 return nsRestyleHint(0); |
|
374 } |
|
375 |
|
376 /* virtual */ bool |
|
377 nsHTMLStyleSheet::MediumFeaturesChanged(nsPresContext* aPresContext) |
|
378 { |
|
379 return false; |
|
380 } |
|
381 |
|
382 /* virtual */ size_t |
|
383 nsHTMLStyleSheet::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const |
|
384 { |
|
385 return 0; // nsHTMLStyleSheets are charged to the DOM, not layout |
|
386 } |
|
387 |
|
388 /* virtual */ size_t |
|
389 nsHTMLStyleSheet::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const |
|
390 { |
|
391 return 0; // nsHTMLStyleSheets are charged to the DOM, not layout |
|
392 } |
|
393 |
|
394 /* virtual */ void |
|
395 nsHTMLStyleSheet::RulesMatching(PseudoElementRuleProcessorData* aData) |
|
396 { |
|
397 } |
|
398 |
|
399 /* virtual */ void |
|
400 nsHTMLStyleSheet::RulesMatching(AnonBoxRuleProcessorData* aData) |
|
401 { |
|
402 } |
|
403 |
|
404 #ifdef MOZ_XUL |
|
405 /* virtual */ void |
|
406 nsHTMLStyleSheet::RulesMatching(XULTreeRuleProcessorData* aData) |
|
407 { |
|
408 } |
|
409 #endif |
|
410 |
|
411 void |
|
412 nsHTMLStyleSheet::SetOwningDocument(nsIDocument* aDocument) |
|
413 { |
|
414 mDocument = aDocument; // not refcounted |
|
415 } |
|
416 |
|
417 void |
|
418 nsHTMLStyleSheet::Reset() |
|
419 { |
|
420 mLinkRule = nullptr; |
|
421 mVisitedRule = nullptr; |
|
422 mActiveRule = nullptr; |
|
423 |
|
424 if (mLangRuleTable.ops) { |
|
425 PL_DHashTableFinish(&mLangRuleTable); |
|
426 mLangRuleTable.ops = nullptr; |
|
427 } |
|
428 if (mMappedAttrTable.ops) { |
|
429 PL_DHashTableFinish(&mMappedAttrTable); |
|
430 mMappedAttrTable.ops = nullptr; |
|
431 } |
|
432 } |
|
433 |
|
434 nsresult |
|
435 nsHTMLStyleSheet::ImplLinkColorSetter(nsRefPtr<HTMLColorRule>& aRule, nscolor aColor) |
|
436 { |
|
437 if (aRule && aRule->mColor == aColor) { |
|
438 return NS_OK; |
|
439 } |
|
440 |
|
441 aRule = new HTMLColorRule(); |
|
442 if (!aRule) |
|
443 return NS_ERROR_OUT_OF_MEMORY; |
|
444 |
|
445 aRule->mColor = aColor; |
|
446 // Now make sure we restyle any links that might need it. This |
|
447 // shouldn't happen often, so just rebuilding everything is ok. |
|
448 if (mDocument && mDocument->GetShell()) { |
|
449 Element* root = mDocument->GetRootElement(); |
|
450 if (root) { |
|
451 mDocument->GetShell()->GetPresContext()->RestyleManager()-> |
|
452 PostRestyleEvent(root, eRestyle_Subtree, NS_STYLE_HINT_NONE); |
|
453 } |
|
454 } |
|
455 return NS_OK; |
|
456 } |
|
457 |
|
458 nsresult |
|
459 nsHTMLStyleSheet::SetLinkColor(nscolor aColor) |
|
460 { |
|
461 return ImplLinkColorSetter(mLinkRule, aColor); |
|
462 } |
|
463 |
|
464 |
|
465 nsresult |
|
466 nsHTMLStyleSheet::SetActiveLinkColor(nscolor aColor) |
|
467 { |
|
468 return ImplLinkColorSetter(mActiveRule, aColor); |
|
469 } |
|
470 |
|
471 nsresult |
|
472 nsHTMLStyleSheet::SetVisitedLinkColor(nscolor aColor) |
|
473 { |
|
474 return ImplLinkColorSetter(mVisitedRule, aColor); |
|
475 } |
|
476 |
|
477 already_AddRefed<nsMappedAttributes> |
|
478 nsHTMLStyleSheet::UniqueMappedAttributes(nsMappedAttributes* aMapped) |
|
479 { |
|
480 if (!mMappedAttrTable.ops) { |
|
481 PL_DHashTableInit(&mMappedAttrTable, &MappedAttrTable_Ops, |
|
482 nullptr, sizeof(MappedAttrTableEntry), 16); |
|
483 } |
|
484 MappedAttrTableEntry *entry = static_cast<MappedAttrTableEntry*> |
|
485 (PL_DHashTableOperate(&mMappedAttrTable, aMapped, PL_DHASH_ADD)); |
|
486 if (!entry) |
|
487 return nullptr; |
|
488 if (!entry->mAttributes) { |
|
489 // We added a new entry to the hashtable, so we have a new unique set. |
|
490 entry->mAttributes = aMapped; |
|
491 } |
|
492 nsRefPtr<nsMappedAttributes> ret = entry->mAttributes; |
|
493 return ret.forget(); |
|
494 } |
|
495 |
|
496 void |
|
497 nsHTMLStyleSheet::DropMappedAttributes(nsMappedAttributes* aMapped) |
|
498 { |
|
499 NS_ENSURE_TRUE_VOID(aMapped); |
|
500 |
|
501 NS_ASSERTION(mMappedAttrTable.ops, "table uninitialized"); |
|
502 #ifdef DEBUG |
|
503 uint32_t entryCount = mMappedAttrTable.entryCount - 1; |
|
504 #endif |
|
505 |
|
506 PL_DHashTableOperate(&mMappedAttrTable, aMapped, PL_DHASH_REMOVE); |
|
507 |
|
508 NS_ASSERTION(entryCount == mMappedAttrTable.entryCount, "not removed"); |
|
509 } |
|
510 |
|
511 nsIStyleRule* |
|
512 nsHTMLStyleSheet::LangRuleFor(const nsString& aLanguage) |
|
513 { |
|
514 if (!mLangRuleTable.ops) { |
|
515 PL_DHashTableInit(&mLangRuleTable, &LangRuleTable_Ops, |
|
516 nullptr, sizeof(LangRuleTableEntry), 16); |
|
517 } |
|
518 LangRuleTableEntry *entry = static_cast<LangRuleTableEntry*> |
|
519 (PL_DHashTableOperate(&mLangRuleTable, &aLanguage, PL_DHASH_ADD)); |
|
520 if (!entry) { |
|
521 NS_ASSERTION(false, "out of memory"); |
|
522 return nullptr; |
|
523 } |
|
524 return entry->mRule; |
|
525 } |
|
526 |
|
527 static size_t |
|
528 SizeOfAttributesEntryExcludingThis(PLDHashEntryHdr* aEntry, |
|
529 MallocSizeOf aMallocSizeOf, |
|
530 void* aArg) |
|
531 { |
|
532 NS_PRECONDITION(aEntry, "The entry should not be null!"); |
|
533 |
|
534 MappedAttrTableEntry* entry = static_cast<MappedAttrTableEntry*>(aEntry); |
|
535 NS_ASSERTION(entry->mAttributes, "entry->mAttributes should not be null!"); |
|
536 return entry->mAttributes->SizeOfIncludingThis(aMallocSizeOf); |
|
537 } |
|
538 |
|
539 size_t |
|
540 nsHTMLStyleSheet::DOMSizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const |
|
541 { |
|
542 size_t n = aMallocSizeOf(this); |
|
543 |
|
544 if (mMappedAttrTable.ops) { |
|
545 n += PL_DHashTableSizeOfExcludingThis(&mMappedAttrTable, |
|
546 SizeOfAttributesEntryExcludingThis, |
|
547 aMallocSizeOf); |
|
548 } |
|
549 |
|
550 // Measurement of the following members may be added later if DMD finds it is |
|
551 // worthwhile: |
|
552 // - mURL |
|
553 // - mLinkRule |
|
554 // - mVisitedRule |
|
555 // - mActiveRule |
|
556 // - mTableQuirkColorRule |
|
557 // - mTableTHRule |
|
558 // - mLangRuleTable |
|
559 // |
|
560 // The following members are not measured: |
|
561 // - mDocument, because it's non-owning |
|
562 |
|
563 return n; |
|
564 } |