1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/layout/style/nsHTMLStyleSheet.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,564 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- 1.5 + * 1.6 + * This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. 1.9 + * 1.10 + * This Original Code has been modified by IBM Corporation. Modifications made by IBM 1.11 + * described herein are Copyright (c) International Business Machines Corporation, 2000. 1.12 + * Modifications to Mozilla code or documentation identified per MPL Section 3.3 1.13 + * 1.14 + * Date Modified by Description of modification 1.15 + * 04/20/2000 IBM Corp. OS/2 VisualAge build. 1.16 + */ 1.17 + 1.18 +/* 1.19 + * style sheet and style rule processor representing data from presentational 1.20 + * HTML attributes 1.21 + */ 1.22 + 1.23 +#include "nsHTMLStyleSheet.h" 1.24 +#include "nsMappedAttributes.h" 1.25 +#include "nsGkAtoms.h" 1.26 +#include "nsPresContext.h" 1.27 +#include "mozilla/EventStates.h" 1.28 +#include "nsIDocument.h" 1.29 +#include "nsIPresShell.h" 1.30 +#include "nsStyleConsts.h" 1.31 +#include "nsRuleWalker.h" 1.32 +#include "nsRuleData.h" 1.33 +#include "nsError.h" 1.34 +#include "nsRuleProcessorData.h" 1.35 +#include "nsCSSRuleProcessor.h" 1.36 +#include "mozilla/MemoryReporting.h" 1.37 +#include "mozilla/dom/Element.h" 1.38 +#include "nsHashKeys.h" 1.39 +#include "RestyleManager.h" 1.40 + 1.41 +using namespace mozilla; 1.42 +using namespace mozilla::dom; 1.43 + 1.44 +NS_IMPL_ISUPPORTS(nsHTMLStyleSheet::HTMLColorRule, nsIStyleRule) 1.45 + 1.46 +/* virtual */ void 1.47 +nsHTMLStyleSheet::HTMLColorRule::MapRuleInfoInto(nsRuleData* aRuleData) 1.48 +{ 1.49 + if (aRuleData->mSIDs & NS_STYLE_INHERIT_BIT(Color)) { 1.50 + nsCSSValue* color = aRuleData->ValueForColor(); 1.51 + if (color->GetUnit() == eCSSUnit_Null && 1.52 + aRuleData->mPresContext->UseDocumentColors()) 1.53 + color->SetColorValue(mColor); 1.54 + } 1.55 +} 1.56 + 1.57 +#ifdef DEBUG 1.58 +/* virtual */ void 1.59 +nsHTMLStyleSheet::HTMLColorRule::List(FILE* out, int32_t aIndent) const 1.60 +{ 1.61 + for (int32_t index = aIndent; --index >= 0; ) fputs(" ", out); 1.62 + fputs("[html color rule] {}\n", out); 1.63 +} 1.64 +#endif 1.65 + 1.66 + 1.67 +NS_IMPL_ISUPPORTS(nsHTMLStyleSheet::GenericTableRule, nsIStyleRule) 1.68 + 1.69 +#ifdef DEBUG 1.70 +/* virtual */ void 1.71 +nsHTMLStyleSheet::GenericTableRule::List(FILE* out, int32_t aIndent) const 1.72 +{ 1.73 + for (int32_t index = aIndent; --index >= 0; ) fputs(" ", out); 1.74 + fputs("[generic table rule] {}\n", out); 1.75 +} 1.76 +#endif 1.77 + 1.78 +/* virtual */ void 1.79 +nsHTMLStyleSheet::TableTHRule::MapRuleInfoInto(nsRuleData* aRuleData) 1.80 +{ 1.81 + if (aRuleData->mSIDs & NS_STYLE_INHERIT_BIT(Text)) { 1.82 + nsCSSValue* textAlign = aRuleData->ValueForTextAlign(); 1.83 + if (textAlign->GetUnit() == eCSSUnit_Null) { 1.84 + textAlign->SetIntValue(NS_STYLE_TEXT_ALIGN_MOZ_CENTER_OR_INHERIT, 1.85 + eCSSUnit_Enumerated); 1.86 + } 1.87 + } 1.88 +} 1.89 + 1.90 +/* virtual */ void 1.91 +nsHTMLStyleSheet::TableQuirkColorRule::MapRuleInfoInto(nsRuleData* aRuleData) 1.92 +{ 1.93 + if (aRuleData->mSIDs & NS_STYLE_INHERIT_BIT(Color)) { 1.94 + nsCSSValue* color = aRuleData->ValueForColor(); 1.95 + // We do not check UseDocumentColors() here, because we want to 1.96 + // use the body color no matter what. 1.97 + if (color->GetUnit() == eCSSUnit_Null) 1.98 + color->SetIntValue(NS_STYLE_COLOR_INHERIT_FROM_BODY, 1.99 + eCSSUnit_Enumerated); 1.100 + } 1.101 +} 1.102 + 1.103 + 1.104 +NS_IMPL_ISUPPORTS(nsHTMLStyleSheet::LangRule, nsIStyleRule) 1.105 + 1.106 +/* virtual */ void 1.107 +nsHTMLStyleSheet::LangRule::MapRuleInfoInto(nsRuleData* aRuleData) 1.108 +{ 1.109 + if (aRuleData->mSIDs & NS_STYLE_INHERIT_BIT(Font)) { 1.110 + nsCSSValue* lang = aRuleData->ValueForLang(); 1.111 + if (lang->GetUnit() == eCSSUnit_Null) { 1.112 + lang->SetStringValue(mLang, eCSSUnit_Ident); 1.113 + } 1.114 + } 1.115 +} 1.116 + 1.117 +#ifdef DEBUG 1.118 +/* virtual */ void 1.119 +nsHTMLStyleSheet::LangRule::List(FILE* out, int32_t aIndent) const 1.120 +{ 1.121 + for (int32_t index = aIndent; --index >= 0; ) fputs(" ", out); 1.122 + fputs("[lang rule] { language: \"", out); 1.123 + fputs(NS_ConvertUTF16toUTF8(mLang).get(), out); 1.124 + fputs("\" }\n", out); 1.125 +} 1.126 +#endif 1.127 + 1.128 +// ----------------------------------------------------------- 1.129 + 1.130 +struct MappedAttrTableEntry : public PLDHashEntryHdr { 1.131 + nsMappedAttributes *mAttributes; 1.132 +}; 1.133 + 1.134 +static PLDHashNumber 1.135 +MappedAttrTable_HashKey(PLDHashTable *table, const void *key) 1.136 +{ 1.137 + nsMappedAttributes *attributes = 1.138 + static_cast<nsMappedAttributes*>(const_cast<void*>(key)); 1.139 + 1.140 + return attributes->HashValue(); 1.141 +} 1.142 + 1.143 +static void 1.144 +MappedAttrTable_ClearEntry(PLDHashTable *table, PLDHashEntryHdr *hdr) 1.145 +{ 1.146 + MappedAttrTableEntry *entry = static_cast<MappedAttrTableEntry*>(hdr); 1.147 + 1.148 + entry->mAttributes->DropStyleSheetReference(); 1.149 + memset(entry, 0, sizeof(MappedAttrTableEntry)); 1.150 +} 1.151 + 1.152 +static bool 1.153 +MappedAttrTable_MatchEntry(PLDHashTable *table, const PLDHashEntryHdr *hdr, 1.154 + const void *key) 1.155 +{ 1.156 + nsMappedAttributes *attributes = 1.157 + static_cast<nsMappedAttributes*>(const_cast<void*>(key)); 1.158 + const MappedAttrTableEntry *entry = 1.159 + static_cast<const MappedAttrTableEntry*>(hdr); 1.160 + 1.161 + return attributes->Equals(entry->mAttributes); 1.162 +} 1.163 + 1.164 +static const PLDHashTableOps MappedAttrTable_Ops = { 1.165 + PL_DHashAllocTable, 1.166 + PL_DHashFreeTable, 1.167 + MappedAttrTable_HashKey, 1.168 + MappedAttrTable_MatchEntry, 1.169 + PL_DHashMoveEntryStub, 1.170 + MappedAttrTable_ClearEntry, 1.171 + PL_DHashFinalizeStub, 1.172 + nullptr 1.173 +}; 1.174 + 1.175 +// ----------------------------------------------------------- 1.176 + 1.177 +struct LangRuleTableEntry : public PLDHashEntryHdr { 1.178 + nsRefPtr<nsHTMLStyleSheet::LangRule> mRule; 1.179 +}; 1.180 + 1.181 +static PLDHashNumber 1.182 +LangRuleTable_HashKey(PLDHashTable *table, const void *key) 1.183 +{ 1.184 + const nsString *lang = static_cast<const nsString*>(key); 1.185 + return HashString(*lang); 1.186 +} 1.187 + 1.188 +static void 1.189 +LangRuleTable_ClearEntry(PLDHashTable *table, PLDHashEntryHdr *hdr) 1.190 +{ 1.191 + LangRuleTableEntry *entry = static_cast<LangRuleTableEntry*>(hdr); 1.192 + 1.193 + entry->~LangRuleTableEntry(); 1.194 + memset(entry, 0, sizeof(LangRuleTableEntry)); 1.195 +} 1.196 + 1.197 +static bool 1.198 +LangRuleTable_MatchEntry(PLDHashTable *table, const PLDHashEntryHdr *hdr, 1.199 + const void *key) 1.200 +{ 1.201 + const nsString *lang = static_cast<const nsString*>(key); 1.202 + const LangRuleTableEntry *entry = static_cast<const LangRuleTableEntry*>(hdr); 1.203 + 1.204 + return entry->mRule->mLang == *lang; 1.205 +} 1.206 + 1.207 +static bool 1.208 +LangRuleTable_InitEntry(PLDHashTable *table, PLDHashEntryHdr *hdr, 1.209 + const void *key) 1.210 +{ 1.211 + const nsString *lang = static_cast<const nsString*>(key); 1.212 + 1.213 + LangRuleTableEntry *entry = new (hdr) LangRuleTableEntry(); 1.214 + 1.215 + // Create the unique rule for this language 1.216 + entry->mRule = new nsHTMLStyleSheet::LangRule(*lang); 1.217 + 1.218 + return true; 1.219 +} 1.220 + 1.221 +static const PLDHashTableOps LangRuleTable_Ops = { 1.222 + PL_DHashAllocTable, 1.223 + PL_DHashFreeTable, 1.224 + LangRuleTable_HashKey, 1.225 + LangRuleTable_MatchEntry, 1.226 + PL_DHashMoveEntryStub, 1.227 + LangRuleTable_ClearEntry, 1.228 + PL_DHashFinalizeStub, 1.229 + LangRuleTable_InitEntry 1.230 +}; 1.231 + 1.232 +// ----------------------------------------------------------- 1.233 + 1.234 +nsHTMLStyleSheet::nsHTMLStyleSheet(nsIDocument* aDocument) 1.235 + : mDocument(aDocument) 1.236 + , mTableQuirkColorRule(new TableQuirkColorRule()) 1.237 + , mTableTHRule(new TableTHRule()) 1.238 +{ 1.239 + MOZ_ASSERT(aDocument); 1.240 + mMappedAttrTable.ops = nullptr; 1.241 + mLangRuleTable.ops = nullptr; 1.242 +} 1.243 + 1.244 +nsHTMLStyleSheet::~nsHTMLStyleSheet() 1.245 +{ 1.246 + if (mLangRuleTable.ops) 1.247 + PL_DHashTableFinish(&mLangRuleTable); 1.248 + if (mMappedAttrTable.ops) 1.249 + PL_DHashTableFinish(&mMappedAttrTable); 1.250 +} 1.251 + 1.252 +NS_IMPL_ISUPPORTS(nsHTMLStyleSheet, nsIStyleRuleProcessor) 1.253 + 1.254 +/* virtual */ void 1.255 +nsHTMLStyleSheet::RulesMatching(ElementRuleProcessorData* aData) 1.256 +{ 1.257 + nsRuleWalker *ruleWalker = aData->mRuleWalker; 1.258 + if (aData->mElement->IsHTML() && !ruleWalker->AuthorStyleDisabled()) { 1.259 + nsIAtom* tag = aData->mElement->Tag(); 1.260 + 1.261 + // if we have anchor colors, check if this is an anchor with an href 1.262 + if (tag == nsGkAtoms::a) { 1.263 + if (mLinkRule || mVisitedRule || mActiveRule) { 1.264 + EventStates state = 1.265 + nsCSSRuleProcessor::GetContentStateForVisitedHandling( 1.266 + aData->mElement, 1.267 + aData->mTreeMatchContext, 1.268 + aData->mTreeMatchContext.VisitedHandling(), 1.269 + // If the node being matched is a link, 1.270 + // it's the relevant link. 1.271 + nsCSSRuleProcessor::IsLink(aData->mElement)); 1.272 + if (mLinkRule && state.HasState(NS_EVENT_STATE_UNVISITED)) { 1.273 + ruleWalker->Forward(mLinkRule); 1.274 + aData->mTreeMatchContext.SetHaveRelevantLink(); 1.275 + } 1.276 + else if (mVisitedRule && state.HasState(NS_EVENT_STATE_VISITED)) { 1.277 + ruleWalker->Forward(mVisitedRule); 1.278 + aData->mTreeMatchContext.SetHaveRelevantLink(); 1.279 + } 1.280 + 1.281 + // No need to add to the active rule if it's not a link 1.282 + if (mActiveRule && nsCSSRuleProcessor::IsLink(aData->mElement) && 1.283 + state.HasState(NS_EVENT_STATE_ACTIVE)) { 1.284 + ruleWalker->Forward(mActiveRule); 1.285 + } 1.286 + } // end link/visited/active rules 1.287 + } // end A tag 1.288 + // add the rule to handle text-align for a <th> 1.289 + else if (tag == nsGkAtoms::th) { 1.290 + ruleWalker->Forward(mTableTHRule); 1.291 + } 1.292 + else if (tag == nsGkAtoms::table) { 1.293 + if (aData->mTreeMatchContext.mCompatMode == eCompatibility_NavQuirks) { 1.294 + ruleWalker->Forward(mTableQuirkColorRule); 1.295 + } 1.296 + } 1.297 + } // end html element 1.298 + 1.299 + // just get the style rules from the content. For SVG we do this even if 1.300 + // author style is disabled, because SVG presentational hints aren't 1.301 + // considered style. 1.302 + if (!ruleWalker->AuthorStyleDisabled() || aData->mElement->IsSVG()) { 1.303 + aData->mElement->WalkContentStyleRules(ruleWalker); 1.304 + } 1.305 + 1.306 + // http://www.whatwg.org/specs/web-apps/current-work/multipage/elements.html#language 1.307 + // says that the xml:lang attribute overrides HTML's lang attribute, 1.308 + // so we need to do this after WalkContentStyleRules. 1.309 + nsString lang; 1.310 + if (aData->mElement->GetAttr(kNameSpaceID_XML, nsGkAtoms::lang, lang)) { 1.311 + ruleWalker->Forward(LangRuleFor(lang)); 1.312 + } 1.313 +} 1.314 + 1.315 +// Test if style is dependent on content state 1.316 +/* virtual */ nsRestyleHint 1.317 +nsHTMLStyleSheet::HasStateDependentStyle(StateRuleProcessorData* aData) 1.318 +{ 1.319 + if (aData->mElement->IsHTML(nsGkAtoms::a) && 1.320 + nsCSSRuleProcessor::IsLink(aData->mElement) && 1.321 + ((mActiveRule && aData->mStateMask.HasState(NS_EVENT_STATE_ACTIVE)) || 1.322 + (mLinkRule && aData->mStateMask.HasState(NS_EVENT_STATE_VISITED)) || 1.323 + (mVisitedRule && aData->mStateMask.HasState(NS_EVENT_STATE_VISITED)))) { 1.324 + return eRestyle_Self; 1.325 + } 1.326 + 1.327 + return nsRestyleHint(0); 1.328 +} 1.329 + 1.330 +/* virtual */ nsRestyleHint 1.331 +nsHTMLStyleSheet::HasStateDependentStyle(PseudoElementStateRuleProcessorData* aData) 1.332 +{ 1.333 + return nsRestyleHint(0); 1.334 +} 1.335 + 1.336 +/* virtual */ bool 1.337 +nsHTMLStyleSheet::HasDocumentStateDependentStyle(StateRuleProcessorData* aData) 1.338 +{ 1.339 + return false; 1.340 +} 1.341 + 1.342 +/* virtual */ nsRestyleHint 1.343 +nsHTMLStyleSheet::HasAttributeDependentStyle(AttributeRuleProcessorData* aData) 1.344 +{ 1.345 + // Do nothing on before-change checks 1.346 + if (!aData->mAttrHasChanged) { 1.347 + return nsRestyleHint(0); 1.348 + } 1.349 + 1.350 + // Note: no need to worry about whether some states changed with this 1.351 + // attribute here, because we handle that under HasStateDependentStyle() as 1.352 + // needed. 1.353 + 1.354 + // Result is true for |href| changes on HTML links if we have link rules. 1.355 + Element *element = aData->mElement; 1.356 + if (aData->mAttribute == nsGkAtoms::href && 1.357 + (mLinkRule || mVisitedRule || mActiveRule) && 1.358 + element->IsHTML(nsGkAtoms::a)) { 1.359 + return eRestyle_Self; 1.360 + } 1.361 + 1.362 + // Don't worry about the mDocumentColorRule since it only applies 1.363 + // to descendants of body, when we're already reresolving. 1.364 + 1.365 + // Handle the content style rules. 1.366 + if (element->IsAttributeMapped(aData->mAttribute)) { 1.367 + // cellpadding on tables is special and requires reresolving all 1.368 + // the cells in the table 1.369 + if (aData->mAttribute == nsGkAtoms::cellpadding && 1.370 + element->IsHTML(nsGkAtoms::table)) { 1.371 + return eRestyle_Subtree; 1.372 + } 1.373 + return eRestyle_Self; 1.374 + } 1.375 + 1.376 + return nsRestyleHint(0); 1.377 +} 1.378 + 1.379 +/* virtual */ bool 1.380 +nsHTMLStyleSheet::MediumFeaturesChanged(nsPresContext* aPresContext) 1.381 +{ 1.382 + return false; 1.383 +} 1.384 + 1.385 +/* virtual */ size_t 1.386 +nsHTMLStyleSheet::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const 1.387 +{ 1.388 + return 0; // nsHTMLStyleSheets are charged to the DOM, not layout 1.389 +} 1.390 + 1.391 +/* virtual */ size_t 1.392 +nsHTMLStyleSheet::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const 1.393 +{ 1.394 + return 0; // nsHTMLStyleSheets are charged to the DOM, not layout 1.395 +} 1.396 + 1.397 +/* virtual */ void 1.398 +nsHTMLStyleSheet::RulesMatching(PseudoElementRuleProcessorData* aData) 1.399 +{ 1.400 +} 1.401 + 1.402 +/* virtual */ void 1.403 +nsHTMLStyleSheet::RulesMatching(AnonBoxRuleProcessorData* aData) 1.404 +{ 1.405 +} 1.406 + 1.407 +#ifdef MOZ_XUL 1.408 +/* virtual */ void 1.409 +nsHTMLStyleSheet::RulesMatching(XULTreeRuleProcessorData* aData) 1.410 +{ 1.411 +} 1.412 +#endif 1.413 + 1.414 +void 1.415 +nsHTMLStyleSheet::SetOwningDocument(nsIDocument* aDocument) 1.416 +{ 1.417 + mDocument = aDocument; // not refcounted 1.418 +} 1.419 + 1.420 +void 1.421 +nsHTMLStyleSheet::Reset() 1.422 +{ 1.423 + mLinkRule = nullptr; 1.424 + mVisitedRule = nullptr; 1.425 + mActiveRule = nullptr; 1.426 + 1.427 + if (mLangRuleTable.ops) { 1.428 + PL_DHashTableFinish(&mLangRuleTable); 1.429 + mLangRuleTable.ops = nullptr; 1.430 + } 1.431 + if (mMappedAttrTable.ops) { 1.432 + PL_DHashTableFinish(&mMappedAttrTable); 1.433 + mMappedAttrTable.ops = nullptr; 1.434 + } 1.435 +} 1.436 + 1.437 +nsresult 1.438 +nsHTMLStyleSheet::ImplLinkColorSetter(nsRefPtr<HTMLColorRule>& aRule, nscolor aColor) 1.439 +{ 1.440 + if (aRule && aRule->mColor == aColor) { 1.441 + return NS_OK; 1.442 + } 1.443 + 1.444 + aRule = new HTMLColorRule(); 1.445 + if (!aRule) 1.446 + return NS_ERROR_OUT_OF_MEMORY; 1.447 + 1.448 + aRule->mColor = aColor; 1.449 + // Now make sure we restyle any links that might need it. This 1.450 + // shouldn't happen often, so just rebuilding everything is ok. 1.451 + if (mDocument && mDocument->GetShell()) { 1.452 + Element* root = mDocument->GetRootElement(); 1.453 + if (root) { 1.454 + mDocument->GetShell()->GetPresContext()->RestyleManager()-> 1.455 + PostRestyleEvent(root, eRestyle_Subtree, NS_STYLE_HINT_NONE); 1.456 + } 1.457 + } 1.458 + return NS_OK; 1.459 +} 1.460 + 1.461 +nsresult 1.462 +nsHTMLStyleSheet::SetLinkColor(nscolor aColor) 1.463 +{ 1.464 + return ImplLinkColorSetter(mLinkRule, aColor); 1.465 +} 1.466 + 1.467 + 1.468 +nsresult 1.469 +nsHTMLStyleSheet::SetActiveLinkColor(nscolor aColor) 1.470 +{ 1.471 + return ImplLinkColorSetter(mActiveRule, aColor); 1.472 +} 1.473 + 1.474 +nsresult 1.475 +nsHTMLStyleSheet::SetVisitedLinkColor(nscolor aColor) 1.476 +{ 1.477 + return ImplLinkColorSetter(mVisitedRule, aColor); 1.478 +} 1.479 + 1.480 +already_AddRefed<nsMappedAttributes> 1.481 +nsHTMLStyleSheet::UniqueMappedAttributes(nsMappedAttributes* aMapped) 1.482 +{ 1.483 + if (!mMappedAttrTable.ops) { 1.484 + PL_DHashTableInit(&mMappedAttrTable, &MappedAttrTable_Ops, 1.485 + nullptr, sizeof(MappedAttrTableEntry), 16); 1.486 + } 1.487 + MappedAttrTableEntry *entry = static_cast<MappedAttrTableEntry*> 1.488 + (PL_DHashTableOperate(&mMappedAttrTable, aMapped, PL_DHASH_ADD)); 1.489 + if (!entry) 1.490 + return nullptr; 1.491 + if (!entry->mAttributes) { 1.492 + // We added a new entry to the hashtable, so we have a new unique set. 1.493 + entry->mAttributes = aMapped; 1.494 + } 1.495 + nsRefPtr<nsMappedAttributes> ret = entry->mAttributes; 1.496 + return ret.forget(); 1.497 +} 1.498 + 1.499 +void 1.500 +nsHTMLStyleSheet::DropMappedAttributes(nsMappedAttributes* aMapped) 1.501 +{ 1.502 + NS_ENSURE_TRUE_VOID(aMapped); 1.503 + 1.504 + NS_ASSERTION(mMappedAttrTable.ops, "table uninitialized"); 1.505 +#ifdef DEBUG 1.506 + uint32_t entryCount = mMappedAttrTable.entryCount - 1; 1.507 +#endif 1.508 + 1.509 + PL_DHashTableOperate(&mMappedAttrTable, aMapped, PL_DHASH_REMOVE); 1.510 + 1.511 + NS_ASSERTION(entryCount == mMappedAttrTable.entryCount, "not removed"); 1.512 +} 1.513 + 1.514 +nsIStyleRule* 1.515 +nsHTMLStyleSheet::LangRuleFor(const nsString& aLanguage) 1.516 +{ 1.517 + if (!mLangRuleTable.ops) { 1.518 + PL_DHashTableInit(&mLangRuleTable, &LangRuleTable_Ops, 1.519 + nullptr, sizeof(LangRuleTableEntry), 16); 1.520 + } 1.521 + LangRuleTableEntry *entry = static_cast<LangRuleTableEntry*> 1.522 + (PL_DHashTableOperate(&mLangRuleTable, &aLanguage, PL_DHASH_ADD)); 1.523 + if (!entry) { 1.524 + NS_ASSERTION(false, "out of memory"); 1.525 + return nullptr; 1.526 + } 1.527 + return entry->mRule; 1.528 +} 1.529 + 1.530 +static size_t 1.531 +SizeOfAttributesEntryExcludingThis(PLDHashEntryHdr* aEntry, 1.532 + MallocSizeOf aMallocSizeOf, 1.533 + void* aArg) 1.534 +{ 1.535 + NS_PRECONDITION(aEntry, "The entry should not be null!"); 1.536 + 1.537 + MappedAttrTableEntry* entry = static_cast<MappedAttrTableEntry*>(aEntry); 1.538 + NS_ASSERTION(entry->mAttributes, "entry->mAttributes should not be null!"); 1.539 + return entry->mAttributes->SizeOfIncludingThis(aMallocSizeOf); 1.540 +} 1.541 + 1.542 +size_t 1.543 +nsHTMLStyleSheet::DOMSizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const 1.544 +{ 1.545 + size_t n = aMallocSizeOf(this); 1.546 + 1.547 + if (mMappedAttrTable.ops) { 1.548 + n += PL_DHashTableSizeOfExcludingThis(&mMappedAttrTable, 1.549 + SizeOfAttributesEntryExcludingThis, 1.550 + aMallocSizeOf); 1.551 + } 1.552 + 1.553 + // Measurement of the following members may be added later if DMD finds it is 1.554 + // worthwhile: 1.555 + // - mURL 1.556 + // - mLinkRule 1.557 + // - mVisitedRule 1.558 + // - mActiveRule 1.559 + // - mTableQuirkColorRule 1.560 + // - mTableTHRule 1.561 + // - mLangRuleTable 1.562 + // 1.563 + // The following members are not measured: 1.564 + // - mDocument, because it's non-owning 1.565 + 1.566 + return n; 1.567 +}