Line data Source code
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 "mozilla/OperatorNewExtensions.h"
37 : #include "mozilla/RestyleManager.h"
38 : #include "mozilla/RestyleManagerInlines.h"
39 : #include "mozilla/ServoStyleSet.h"
40 :
41 : using namespace mozilla;
42 : using namespace mozilla::dom;
43 :
44 0 : NS_IMPL_ISUPPORTS(nsHTMLStyleSheet::HTMLColorRule, nsIStyleRule)
45 :
46 : /* virtual */ void
47 0 : nsHTMLStyleSheet::HTMLColorRule::MapRuleInfoInto(nsRuleData* aRuleData)
48 : {
49 0 : if (aRuleData->mSIDs & NS_STYLE_INHERIT_BIT(Color)) {
50 0 : nsCSSValue* color = aRuleData->ValueForColor();
51 0 : if (color->GetUnit() == eCSSUnit_Null &&
52 0 : aRuleData->mPresContext->UseDocumentColors())
53 0 : color->SetColorValue(mColor);
54 : }
55 0 : }
56 :
57 : /* virtual */ bool
58 0 : nsHTMLStyleSheet::HTMLColorRule::MightMapInheritedStyleData()
59 : {
60 0 : return true;
61 : }
62 :
63 : /* virtual */ bool
64 0 : nsHTMLStyleSheet::HTMLColorRule::
65 : GetDiscretelyAnimatedCSSValue(nsCSSPropertyID aProperty, nsCSSValue* aValue)
66 : {
67 0 : MOZ_ASSERT(false, "GetDiscretelyAnimatedCSSValue is not implemented yet");
68 : return false;
69 : }
70 :
71 : #ifdef DEBUG
72 : /* virtual */ void
73 0 : nsHTMLStyleSheet::HTMLColorRule::List(FILE* out, int32_t aIndent) const
74 : {
75 0 : nsAutoCString indentStr;
76 0 : for (int32_t index = aIndent; --index >= 0; ) {
77 0 : indentStr.AppendLiteral(" ");
78 : }
79 0 : fprintf_stderr(out, "%s[html color rule] {}\n", indentStr.get());
80 0 : }
81 : #endif
82 :
83 :
84 60 : NS_IMPL_ISUPPORTS(nsHTMLStyleSheet::GenericTableRule, nsIStyleRule)
85 :
86 : #ifdef DEBUG
87 : /* virtual */ void
88 0 : nsHTMLStyleSheet::GenericTableRule::List(FILE* out, int32_t aIndent) const
89 : {
90 0 : nsAutoCString indentStr;
91 0 : for (int32_t index = aIndent; --index >= 0; ) {
92 0 : indentStr.AppendLiteral(" ");
93 : }
94 0 : fprintf_stderr(out, "%s[generic table rule] {}\n", indentStr.get());
95 0 : }
96 : #endif
97 :
98 : /* virtual */ void
99 0 : nsHTMLStyleSheet::TableTHRule::MapRuleInfoInto(nsRuleData* aRuleData)
100 : {
101 0 : if (aRuleData->mSIDs & NS_STYLE_INHERIT_BIT(Text)) {
102 0 : nsCSSValue* textAlign = aRuleData->ValueForTextAlign();
103 0 : if (textAlign->GetUnit() == eCSSUnit_Null) {
104 : textAlign->SetIntValue(NS_STYLE_TEXT_ALIGN_MOZ_CENTER_OR_INHERIT,
105 0 : eCSSUnit_Enumerated);
106 : }
107 : }
108 0 : }
109 :
110 : /* virtual */ bool
111 0 : nsHTMLStyleSheet::TableTHRule::MightMapInheritedStyleData()
112 : {
113 0 : return true;
114 : }
115 :
116 : /* virtual */ bool
117 0 : nsHTMLStyleSheet::TableTHRule::
118 : GetDiscretelyAnimatedCSSValue(nsCSSPropertyID aProperty, nsCSSValue* aValue)
119 : {
120 0 : MOZ_ASSERT(false, "GetDiscretelyAnimatedCSSValue is not implemented yet");
121 : return false;
122 : }
123 :
124 : /* virtual */ void
125 0 : nsHTMLStyleSheet::TableQuirkColorRule::MapRuleInfoInto(nsRuleData* aRuleData)
126 : {
127 0 : if (aRuleData->mSIDs & NS_STYLE_INHERIT_BIT(Color)) {
128 0 : nsCSSValue* color = aRuleData->ValueForColor();
129 : // We do not check UseDocumentColors() here, because we want to
130 : // use the body color no matter what.
131 0 : if (color->GetUnit() == eCSSUnit_Null)
132 : color->SetIntValue(NS_STYLE_COLOR_INHERIT_FROM_BODY,
133 0 : eCSSUnit_Enumerated);
134 : }
135 0 : }
136 :
137 : /* virtual */ bool
138 0 : nsHTMLStyleSheet::TableQuirkColorRule::MightMapInheritedStyleData()
139 : {
140 0 : return true;
141 : }
142 :
143 : /* virtual */ bool
144 0 : nsHTMLStyleSheet::TableQuirkColorRule::
145 : GetDiscretelyAnimatedCSSValue(nsCSSPropertyID aProperty, nsCSSValue* aValue)
146 : {
147 0 : MOZ_ASSERT(false, "GetDiscretelyAnimatedCSSValue is not implemented yet");
148 : return false;
149 : }
150 :
151 0 : NS_IMPL_ISUPPORTS(nsHTMLStyleSheet::LangRule, nsIStyleRule)
152 :
153 : /* virtual */ void
154 0 : nsHTMLStyleSheet::LangRule::MapRuleInfoInto(nsRuleData* aRuleData)
155 : {
156 0 : if (aRuleData->mSIDs & NS_STYLE_INHERIT_BIT(Font)) {
157 0 : nsCSSValue* lang = aRuleData->ValueForLang();
158 0 : if (lang->GetUnit() == eCSSUnit_Null) {
159 0 : nsCOMPtr<nsIAtom> langAtom = mLang;
160 0 : lang->SetAtomIdentValue(langAtom.forget());
161 : }
162 : }
163 0 : }
164 :
165 : /* virtual */ bool
166 0 : nsHTMLStyleSheet::LangRule::MightMapInheritedStyleData()
167 : {
168 0 : return true;
169 : }
170 :
171 : /* virtual */ bool
172 0 : nsHTMLStyleSheet::LangRule::
173 : GetDiscretelyAnimatedCSSValue(nsCSSPropertyID aProperty, nsCSSValue* aValue)
174 : {
175 0 : MOZ_ASSERT(false, "GetDiscretelyAnimatedCSSValue is not implemented yet");
176 : return false;
177 : }
178 :
179 : #ifdef DEBUG
180 : /* virtual */ void
181 0 : nsHTMLStyleSheet::LangRule::List(FILE* out, int32_t aIndent) const
182 : {
183 0 : nsAutoCString str;
184 0 : for (int32_t index = aIndent; --index >= 0; ) {
185 0 : str.AppendLiteral(" ");
186 : }
187 0 : str.AppendLiteral("[lang rule] { language: \"");
188 0 : AppendUTF16toUTF8(nsDependentAtomString(mLang), str);
189 0 : str.AppendLiteral("\" }\n");
190 0 : fprintf_stderr(out, "%s", str.get());
191 0 : }
192 : #endif
193 :
194 : // -----------------------------------------------------------
195 :
196 : struct MappedAttrTableEntry : public PLDHashEntryHdr {
197 : nsMappedAttributes *mAttributes;
198 : };
199 :
200 : static PLDHashNumber
201 33 : MappedAttrTable_HashKey(const void *key)
202 : {
203 : nsMappedAttributes *attributes =
204 33 : static_cast<nsMappedAttributes*>(const_cast<void*>(key));
205 :
206 33 : return attributes->HashValue();
207 : }
208 :
209 : static void
210 0 : MappedAttrTable_ClearEntry(PLDHashTable *table, PLDHashEntryHdr *hdr)
211 : {
212 0 : MappedAttrTableEntry *entry = static_cast<MappedAttrTableEntry*>(hdr);
213 :
214 0 : entry->mAttributes->DropStyleSheetReference();
215 0 : memset(entry, 0, sizeof(MappedAttrTableEntry));
216 0 : }
217 :
218 : static bool
219 1 : MappedAttrTable_MatchEntry(const PLDHashEntryHdr *hdr, const void *key)
220 : {
221 : nsMappedAttributes *attributes =
222 1 : static_cast<nsMappedAttributes*>(const_cast<void*>(key));
223 : const MappedAttrTableEntry *entry =
224 1 : static_cast<const MappedAttrTableEntry*>(hdr);
225 :
226 1 : return attributes->Equals(entry->mAttributes);
227 : }
228 :
229 : static const PLDHashTableOps MappedAttrTable_Ops = {
230 : MappedAttrTable_HashKey,
231 : MappedAttrTable_MatchEntry,
232 : PLDHashTable::MoveEntryStub,
233 : MappedAttrTable_ClearEntry,
234 : nullptr
235 : };
236 :
237 : // -----------------------------------------------------------
238 :
239 0 : struct LangRuleTableEntry : public PLDHashEntryHdr {
240 : RefPtr<nsHTMLStyleSheet::LangRule> mRule;
241 : };
242 :
243 : static PLDHashNumber
244 0 : LangRuleTable_HashKey(const void *key)
245 : {
246 0 : auto* lang = static_cast<const nsIAtom*>(key);
247 0 : return lang->hash();
248 : }
249 :
250 : static void
251 0 : LangRuleTable_ClearEntry(PLDHashTable *table, PLDHashEntryHdr *hdr)
252 : {
253 0 : LangRuleTableEntry *entry = static_cast<LangRuleTableEntry*>(hdr);
254 :
255 0 : entry->~LangRuleTableEntry();
256 0 : memset(entry, 0, sizeof(LangRuleTableEntry));
257 0 : }
258 :
259 : static bool
260 0 : LangRuleTable_MatchEntry(const PLDHashEntryHdr *hdr, const void *key)
261 : {
262 0 : auto* lang = static_cast<const nsIAtom*>(key);
263 0 : const LangRuleTableEntry *entry = static_cast<const LangRuleTableEntry*>(hdr);
264 :
265 0 : return entry->mRule->mLang == lang;
266 : }
267 :
268 : static void
269 0 : LangRuleTable_InitEntry(PLDHashEntryHdr *hdr, const void *key)
270 : {
271 0 : auto* lang = static_cast<const nsIAtom*>(key);
272 :
273 0 : LangRuleTableEntry* entry = new (KnownNotNull, hdr) LangRuleTableEntry();
274 :
275 : // Create the unique rule for this language
276 0 : entry->mRule = new nsHTMLStyleSheet::LangRule(const_cast<nsIAtom*>(lang));
277 0 : }
278 :
279 : static const PLDHashTableOps LangRuleTable_Ops = {
280 : LangRuleTable_HashKey,
281 : LangRuleTable_MatchEntry,
282 : PLDHashTable::MoveEntryStub,
283 : LangRuleTable_ClearEntry,
284 : LangRuleTable_InitEntry
285 : };
286 :
287 : // -----------------------------------------------------------
288 :
289 30 : nsHTMLStyleSheet::nsHTMLStyleSheet(nsIDocument* aDocument)
290 : : mDocument(aDocument)
291 30 : , mTableQuirkColorRule(new TableQuirkColorRule())
292 30 : , mTableTHRule(new TableTHRule())
293 : , mMappedAttrTable(&MappedAttrTable_Ops, sizeof(MappedAttrTableEntry))
294 : , mMappedAttrsDirty(false)
295 90 : , mLangRuleTable(&LangRuleTable_Ops, sizeof(LangRuleTableEntry))
296 : {
297 30 : MOZ_ASSERT(aDocument);
298 30 : }
299 :
300 146 : NS_IMPL_ISUPPORTS(nsHTMLStyleSheet, nsIStyleRuleProcessor)
301 :
302 : /* virtual */ void
303 2501 : nsHTMLStyleSheet::RulesMatching(ElementRuleProcessorData* aData)
304 : {
305 2501 : nsRuleWalker *ruleWalker = aData->mRuleWalker;
306 2501 : if (!ruleWalker->AuthorStyleDisabled()) {
307 : // if we have anchor colors, check if this is an anchor with an href
308 2501 : if (aData->mElement->IsHTMLElement(nsGkAtoms::a)) {
309 0 : if (mLinkRule || mVisitedRule || mActiveRule) {
310 : EventStates state =
311 : nsCSSRuleProcessor::GetContentStateForVisitedHandling(
312 0 : aData->mElement,
313 0 : aData->mTreeMatchContext.VisitedHandling(),
314 : // If the node being matched is a link,
315 : // it's the relevant link.
316 0 : nsCSSRuleProcessor::IsLink(aData->mElement));
317 0 : if (mLinkRule && state.HasState(NS_EVENT_STATE_UNVISITED)) {
318 0 : ruleWalker->Forward(mLinkRule);
319 0 : aData->mTreeMatchContext.SetHaveRelevantLink();
320 : }
321 0 : else if (mVisitedRule && state.HasState(NS_EVENT_STATE_VISITED)) {
322 0 : ruleWalker->Forward(mVisitedRule);
323 0 : aData->mTreeMatchContext.SetHaveRelevantLink();
324 : }
325 :
326 : // No need to add to the active rule if it's not a link
327 0 : if (mActiveRule && nsCSSRuleProcessor::IsLink(aData->mElement) &&
328 0 : state.HasState(NS_EVENT_STATE_ACTIVE)) {
329 0 : ruleWalker->Forward(mActiveRule);
330 : }
331 : } // end link/visited/active rules
332 : } // end A tag
333 : // add the rule to handle text-align for a <th>
334 2501 : else if (aData->mElement->IsHTMLElement(nsGkAtoms::th)) {
335 0 : ruleWalker->Forward(mTableTHRule);
336 : }
337 2501 : else if (aData->mElement->IsHTMLElement(nsGkAtoms::table)) {
338 0 : if (aData->mTreeMatchContext.mCompatMode == eCompatibility_NavQuirks) {
339 0 : ruleWalker->Forward(mTableQuirkColorRule);
340 : }
341 : }
342 : } // end html element
343 :
344 : // just get the style rules from the content. For SVG we do this even if
345 : // author style is disabled, because SVG presentational hints aren't
346 : // considered style.
347 2501 : if (!ruleWalker->AuthorStyleDisabled() || aData->mElement->IsSVGElement()) {
348 2501 : aData->mElement->WalkContentStyleRules(ruleWalker);
349 : }
350 :
351 : // http://www.whatwg.org/specs/web-apps/current-work/multipage/elements.html#language
352 : // says that the xml:lang attribute overrides HTML's lang attribute,
353 : // so we need to do this after WalkContentStyleRules.
354 : const nsAttrValue* langAttr =
355 2501 : aData->mElement->GetParsedAttr(nsGkAtoms::lang, kNameSpaceID_XML);
356 2501 : if (langAttr) {
357 0 : MOZ_ASSERT(langAttr->Type() == nsAttrValue::eAtom);
358 0 : ruleWalker->Forward(LangRuleFor(langAttr->GetAtomValue()));
359 : }
360 :
361 : // Set the language to "x-math" on the <math> element, so that appropriate
362 : // font settings are used for MathML.
363 2501 : if (aData->mElement->IsMathMLElement(nsGkAtoms::math)) {
364 0 : ruleWalker->Forward(LangRuleFor(nsGkAtoms::x_math));
365 : }
366 2501 : }
367 :
368 : // Test if style is dependent on content state
369 : /* virtual */ nsRestyleHint
370 51 : nsHTMLStyleSheet::HasStateDependentStyle(StateRuleProcessorData* aData)
371 : {
372 204 : if (aData->mElement->IsHTMLElement(nsGkAtoms::a) &&
373 102 : nsCSSRuleProcessor::IsLink(aData->mElement) &&
374 51 : ((mActiveRule && aData->mStateMask.HasState(NS_EVENT_STATE_ACTIVE)) ||
375 51 : (mLinkRule && aData->mStateMask.HasState(NS_EVENT_STATE_VISITED)) ||
376 51 : (mVisitedRule && aData->mStateMask.HasState(NS_EVENT_STATE_VISITED)))) {
377 0 : return eRestyle_Self;
378 : }
379 :
380 51 : return nsRestyleHint(0);
381 : }
382 :
383 : /* virtual */ nsRestyleHint
384 0 : nsHTMLStyleSheet::HasStateDependentStyle(PseudoElementStateRuleProcessorData* aData)
385 : {
386 0 : return nsRestyleHint(0);
387 : }
388 :
389 : /* virtual */ bool
390 2 : nsHTMLStyleSheet::HasDocumentStateDependentStyle(StateRuleProcessorData* aData)
391 : {
392 2 : return false;
393 : }
394 :
395 : /* virtual */ nsRestyleHint
396 648 : nsHTMLStyleSheet::HasAttributeDependentStyle(
397 : AttributeRuleProcessorData* aData,
398 : RestyleHintData& aRestyleHintDataResult)
399 : {
400 : // Do nothing on before-change checks
401 648 : if (!aData->mAttrHasChanged) {
402 326 : return nsRestyleHint(0);
403 : }
404 :
405 : // Note: no need to worry about whether some states changed with this
406 : // attribute here, because we handle that under HasStateDependentStyle() as
407 : // needed.
408 :
409 : // Result is true for |href| changes on HTML links if we have link rules.
410 322 : Element *element = aData->mElement;
411 644 : if (aData->mAttribute == nsGkAtoms::href &&
412 322 : (mLinkRule || mVisitedRule || mActiveRule) &&
413 0 : element->IsHTMLElement(nsGkAtoms::a)) {
414 0 : return eRestyle_Self;
415 : }
416 :
417 : // Don't worry about the mDocumentColorRule since it only applies
418 : // to descendants of body, when we're already reresolving.
419 :
420 : // Handle the content style rules.
421 322 : if (element->IsAttributeMapped(aData->mAttribute)) {
422 : // cellpadding on tables is special and requires reresolving all
423 : // the cells in the table
424 0 : if (aData->mAttribute == nsGkAtoms::cellpadding &&
425 0 : element->IsHTMLElement(nsGkAtoms::table)) {
426 0 : return eRestyle_Subtree;
427 : }
428 0 : return eRestyle_Self;
429 : }
430 :
431 322 : return nsRestyleHint(0);
432 : }
433 :
434 : /* virtual */ bool
435 21 : nsHTMLStyleSheet::MediumFeaturesChanged(nsPresContext* aPresContext)
436 : {
437 21 : return false;
438 : }
439 :
440 : /* virtual */ size_t
441 0 : nsHTMLStyleSheet::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
442 : {
443 0 : return 0; // nsHTMLStyleSheets are charged to the DOM, not layout
444 : }
445 :
446 : /* virtual */ size_t
447 21 : nsHTMLStyleSheet::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
448 : {
449 21 : return 0; // nsHTMLStyleSheets are charged to the DOM, not layout
450 : }
451 :
452 : /* virtual */ void
453 1288 : nsHTMLStyleSheet::RulesMatching(PseudoElementRuleProcessorData* aData)
454 : {
455 1288 : }
456 :
457 : /* virtual */ void
458 210 : nsHTMLStyleSheet::RulesMatching(AnonBoxRuleProcessorData* aData)
459 : {
460 210 : }
461 :
462 : #ifdef MOZ_XUL
463 : /* virtual */ void
464 0 : nsHTMLStyleSheet::RulesMatching(XULTreeRuleProcessorData* aData)
465 : {
466 0 : }
467 : #endif
468 :
469 : void
470 0 : nsHTMLStyleSheet::SetOwningDocument(nsIDocument* aDocument)
471 : {
472 0 : mDocument = aDocument; // not refcounted
473 0 : }
474 :
475 : void
476 0 : nsHTMLStyleSheet::Reset()
477 : {
478 0 : mLinkRule = nullptr;
479 0 : mVisitedRule = nullptr;
480 0 : mActiveRule = nullptr;
481 :
482 0 : mServoUnvisitedLinkDecl = nullptr;
483 0 : mServoVisitedLinkDecl = nullptr;
484 0 : mServoActiveLinkDecl = nullptr;
485 :
486 0 : mLangRuleTable.Clear();
487 0 : mMappedAttrTable.Clear();
488 0 : mMappedAttrsDirty = false;
489 0 : }
490 :
491 : nsresult
492 0 : nsHTMLStyleSheet::ImplLinkColorSetter(
493 : RefPtr<HTMLColorRule>& aRule,
494 : RefPtr<RawServoDeclarationBlock>& aDecl,
495 : nscolor aColor)
496 : {
497 0 : if (!mDocument || !mDocument->GetShell()) {
498 0 : return NS_OK;
499 : }
500 :
501 : RestyleManager* restyle =
502 0 : mDocument->GetShell()->GetPresContext()->RestyleManager();
503 :
504 0 : if (restyle->IsServo()) {
505 0 : MOZ_ASSERT(!ServoStyleSet::IsInServoTraversal());
506 0 : aDecl = Servo_DeclarationBlock_CreateEmpty().Consume();
507 0 : Servo_DeclarationBlock_SetColorValue(aDecl.get(), eCSSProperty_color,
508 0 : aColor);
509 : } else {
510 0 : if (aRule && aRule->mColor == aColor) {
511 0 : return NS_OK;
512 : }
513 :
514 0 : aRule = new HTMLColorRule(aColor);
515 0 : if (!aRule) {
516 0 : return NS_ERROR_OUT_OF_MEMORY;
517 : }
518 : }
519 :
520 : // Now make sure we restyle any links that might need it. This
521 : // shouldn't happen often, so just rebuilding everything is ok.
522 0 : Element* root = mDocument->GetRootElement();
523 0 : if (root) {
524 0 : restyle->PostRestyleEvent(root, eRestyle_Subtree, nsChangeHint(0));
525 : }
526 0 : return NS_OK;
527 : }
528 :
529 : nsresult
530 0 : nsHTMLStyleSheet::SetLinkColor(nscolor aColor)
531 : {
532 0 : return ImplLinkColorSetter(mLinkRule, mServoUnvisitedLinkDecl, aColor);
533 : }
534 :
535 :
536 : nsresult
537 0 : nsHTMLStyleSheet::SetActiveLinkColor(nscolor aColor)
538 : {
539 0 : return ImplLinkColorSetter(mActiveRule, mServoActiveLinkDecl, aColor);
540 : }
541 :
542 : nsresult
543 0 : nsHTMLStyleSheet::SetVisitedLinkColor(nscolor aColor)
544 : {
545 0 : return ImplLinkColorSetter(mVisitedRule, mServoVisitedLinkDecl, aColor);
546 : }
547 :
548 : already_AddRefed<nsMappedAttributes>
549 33 : nsHTMLStyleSheet::UniqueMappedAttributes(nsMappedAttributes* aMapped)
550 : {
551 33 : mMappedAttrsDirty = true;
552 : auto entry = static_cast<MappedAttrTableEntry*>
553 33 : (mMappedAttrTable.Add(aMapped, fallible));
554 33 : if (!entry)
555 0 : return nullptr;
556 33 : if (!entry->mAttributes) {
557 : // We added a new entry to the hashtable, so we have a new unique set.
558 32 : entry->mAttributes = aMapped;
559 : }
560 66 : RefPtr<nsMappedAttributes> ret = entry->mAttributes;
561 33 : return ret.forget();
562 : }
563 :
564 : void
565 0 : nsHTMLStyleSheet::DropMappedAttributes(nsMappedAttributes* aMapped)
566 : {
567 0 : NS_ENSURE_TRUE_VOID(aMapped);
568 : #ifdef DEBUG
569 0 : uint32_t entryCount = mMappedAttrTable.EntryCount() - 1;
570 : #endif
571 :
572 0 : mMappedAttrTable.Remove(aMapped);
573 :
574 0 : NS_ASSERTION(entryCount == mMappedAttrTable.EntryCount(), "not removed");
575 : }
576 :
577 : void
578 0 : nsHTMLStyleSheet::CalculateMappedServoDeclarations(nsPresContext* aPresContext)
579 : {
580 0 : MOZ_ASSERT(!mDocument->GetShell() ||
581 : mDocument->GetShell()->GetPresContext() == aPresContext);
582 :
583 0 : for (auto iter = mMappedAttrTable.Iter(); !iter.Done(); iter.Next()) {
584 0 : MappedAttrTableEntry* attr = static_cast<MappedAttrTableEntry*>(iter.Get());
585 0 : if (attr->mAttributes->GetServoStyle()) {
586 : // Only handle cases which haven't been filled in already
587 0 : continue;
588 : }
589 0 : attr->mAttributes->LazilyResolveServoDeclaration(aPresContext);
590 : }
591 0 : }
592 :
593 : nsIStyleRule*
594 0 : nsHTMLStyleSheet::LangRuleFor(const nsIAtom* aLanguage)
595 : {
596 : auto entry =
597 0 : static_cast<LangRuleTableEntry*>(mLangRuleTable.Add(aLanguage, fallible));
598 0 : if (!entry) {
599 0 : NS_ASSERTION(false, "out of memory");
600 0 : return nullptr;
601 : }
602 0 : return entry->mRule;
603 : }
604 :
605 : size_t
606 21 : nsHTMLStyleSheet::DOMSizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
607 : {
608 21 : size_t n = aMallocSizeOf(this);
609 :
610 21 : n += mMappedAttrTable.ShallowSizeOfExcludingThis(aMallocSizeOf);
611 42 : for (auto iter = mMappedAttrTable.ConstIter(); !iter.Done(); iter.Next()) {
612 21 : auto entry = static_cast<MappedAttrTableEntry*>(iter.Get());
613 21 : n += entry->mAttributes->SizeOfIncludingThis(aMallocSizeOf);
614 : }
615 :
616 : // Measurement of the following members may be added later if DMD finds it is
617 : // worthwhile:
618 : // - mURL
619 : // - mLinkRule
620 : // - mVisitedRule
621 : // - mActiveRule
622 : // - mTableQuirkColorRule
623 : // - mTableTHRule
624 : // - mLangRuleTable
625 : //
626 : // The following members are not measured:
627 : // - mDocument, because it's non-owning
628 :
629 21 : return n;
630 : }
|