LCOV - code coverage report
Current view: top level - layout/style - nsHTMLStyleSheet.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 67 245 27.3 %
Date: 2017-07-14 16:53:18 Functions: 17 59 28.8 %
Legend: Lines: hit not hit

          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             : }

Generated by: LCOV version 1.13