layout/style/nsHTMLStyleSheet.cpp

Wed, 31 Dec 2014 07:16:47 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:16:47 +0100
branch
TOR_BUG_9701
changeset 3
141e0f1194b1
permissions
-rw-r--r--

Revert simplistic fix pending revisit of Mozilla integration attempt.

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

mercurial