LCOV - code coverage report
Current view: top level - layout/style - nsComputedDOMStyle.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 203 3559 5.7 %
Date: 2017-07-14 16:53:18 Functions: 31 420 7.4 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       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             : /* DOM object returned from element.getComputedStyle() */
       8             : 
       9             : #include "nsComputedDOMStyle.h"
      10             : 
      11             : #include "mozilla/ArrayUtils.h"
      12             : #include "mozilla/Preferences.h"
      13             : 
      14             : #include "nsError.h"
      15             : #include "nsIDOMCSSPrimitiveValue.h"
      16             : #include "nsIFrame.h"
      17             : #include "nsIFrameInlines.h"
      18             : #include "nsStyleContext.h"
      19             : #include "nsIScrollableFrame.h"
      20             : #include "nsContentUtils.h"
      21             : #include "nsIContent.h"
      22             : 
      23             : #include "nsDOMCSSRect.h"
      24             : #include "nsDOMCSSRGBColor.h"
      25             : #include "nsDOMCSSValueList.h"
      26             : #include "nsFlexContainerFrame.h"
      27             : #include "nsGridContainerFrame.h"
      28             : #include "nsGkAtoms.h"
      29             : #include "mozilla/ReflowInput.h"
      30             : #include "nsStyleUtil.h"
      31             : #include "nsStyleStructInlines.h"
      32             : #include "nsROCSSPrimitiveValue.h"
      33             : 
      34             : #include "nsPresContext.h"
      35             : #include "nsIDocument.h"
      36             : 
      37             : #include "nsCSSPseudoElements.h"
      38             : #include "mozilla/StyleSetHandle.h"
      39             : #include "mozilla/StyleSetHandleInlines.h"
      40             : #include "mozilla/GeckoRestyleManager.h"
      41             : #include "mozilla/RestyleManagerInlines.h"
      42             : #include "imgIRequest.h"
      43             : #include "nsLayoutUtils.h"
      44             : #include "nsCSSKeywords.h"
      45             : #include "nsStyleCoord.h"
      46             : #include "nsDisplayList.h"
      47             : #include "nsDOMCSSDeclaration.h"
      48             : #include "nsStyleTransformMatrix.h"
      49             : #include "mozilla/dom/Element.h"
      50             : #include "prtime.h"
      51             : #include "nsWrapperCacheInlines.h"
      52             : #include "mozilla/AppUnits.h"
      53             : #include <algorithm>
      54             : #include "nsStyleContextInlines.h"
      55             : 
      56             : using namespace mozilla;
      57             : using namespace mozilla::dom;
      58             : 
      59             : #if defined(DEBUG_bzbarsky) || defined(DEBUG_caillon)
      60             : #define DEBUG_ComputedDOMStyle
      61             : #endif
      62             : 
      63             : /*
      64             :  * This is the implementation of the readonly CSSStyleDeclaration that is
      65             :  * returned by the getComputedStyle() function.
      66             :  */
      67             : 
      68             : already_AddRefed<nsComputedDOMStyle>
      69           4 : NS_NewComputedDOMStyle(dom::Element* aElement, const nsAString& aPseudoElt,
      70             :                        nsIPresShell* aPresShell,
      71             :                        nsComputedDOMStyle::StyleType aStyleType,
      72             :                        nsComputedDOMStyle::AnimationFlag aFlag)
      73             : {
      74           8 :   RefPtr<nsComputedDOMStyle> computedStyle;
      75             :   computedStyle = new nsComputedDOMStyle(aElement, aPseudoElt,
      76           4 :                                          aPresShell, aStyleType, aFlag);
      77           8 :   return computedStyle.forget();
      78             : }
      79             : 
      80             : static nsDOMCSSValueList*
      81           0 : GetROCSSValueList(bool aCommaDelimited)
      82             : {
      83           0 :   return new nsDOMCSSValueList(aCommaDelimited, true);
      84             : }
      85             : 
      86             : template<typename T>
      87             : already_AddRefed<CSSValue>
      88           0 : GetBackgroundList(T nsStyleImageLayers::Layer::* aMember,
      89             :                   uint32_t nsStyleImageLayers::* aCount,
      90             :                   const nsStyleImageLayers& aLayers,
      91             :                   const nsCSSProps::KTableEntry aTable[])
      92             : {
      93           0 :   RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(true);
      94             : 
      95           0 :   for (uint32_t i = 0, i_end = aLayers.*aCount; i < i_end; ++i) {
      96           0 :     RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
      97           0 :     val->SetIdent(nsCSSProps::ValueToKeywordEnum(aLayers.mLayers[i].*aMember, aTable));
      98           0 :     valueList->AppendCSSValue(val.forget());
      99             :   }
     100             : 
     101           0 :   return valueList.forget();
     102             : }
     103             : 
     104             : /**
     105             :  * An object that represents the ordered set of properties that are exposed on
     106             :  * an nsComputedDOMStyle object and how their computed values can be obtained.
     107             :  */
     108             : struct nsComputedStyleMap
     109             : {
     110             :   friend class nsComputedDOMStyle;
     111             : 
     112             :   struct Entry
     113             :   {
     114             :     // Create a pointer-to-member-function type.
     115             :     typedef already_AddRefed<CSSValue> (nsComputedDOMStyle::*ComputeMethod)();
     116             : 
     117             :     nsCSSPropertyID mProperty;
     118             :     ComputeMethod mGetter;
     119             : 
     120           4 :     bool IsLayoutFlushNeeded() const
     121             :     {
     122           4 :       return nsCSSProps::PropHasFlags(mProperty,
     123           4 :                                       CSS_PROPERTY_GETCS_NEEDS_LAYOUT_FLUSH);
     124             :     }
     125             : 
     126         286 :     bool IsEnabled() const
     127             :     {
     128         286 :       return nsCSSProps::IsEnabled(mProperty, CSSEnabledState::eForAllContent);
     129             :     }
     130             :   };
     131             : 
     132             :   // We define this enum just to count the total number of properties that can
     133             :   // be exposed on an nsComputedDOMStyle, including properties that may be
     134             :   // disabled.
     135             :   enum {
     136             : #define COMPUTED_STYLE_PROP(prop_, method_) \
     137             :     eComputedStyleProperty_##prop_,
     138             : #include "nsComputedDOMStylePropertyList.h"
     139             : #undef COMPUTED_STYLE_PROP
     140             :     eComputedStyleProperty_COUNT
     141             :   };
     142             : 
     143             :   /**
     144             :    * Returns the number of properties that should be exposed on an
     145             :    * nsComputedDOMStyle, ecxluding any disabled properties.
     146             :    */
     147           0 :   uint32_t Length()
     148             :   {
     149           0 :     Update();
     150           0 :     return mExposedPropertyCount;
     151             :   }
     152             : 
     153             :   /**
     154             :    * Returns the property at the given index in the list of properties
     155             :    * that should be exposed on an nsComputedDOMStyle, excluding any
     156             :    * disabled properties.
     157             :    */
     158           0 :   nsCSSPropertyID PropertyAt(uint32_t aIndex)
     159             :   {
     160           0 :     Update();
     161           0 :     return kEntries[EntryIndex(aIndex)].mProperty;
     162             :   }
     163             : 
     164             :   /**
     165             :    * Searches for and returns the computed style map entry for the given
     166             :    * property, or nullptr if the property is not exposed on nsComputedDOMStyle
     167             :    * or is currently disabled.
     168             :    */
     169           4 :   const Entry* FindEntryForProperty(nsCSSPropertyID aPropID)
     170             :   {
     171           4 :     Update();
     172         233 :     for (uint32_t i = 0; i < mExposedPropertyCount; i++) {
     173         233 :       const Entry* entry = &kEntries[EntryIndex(i)];
     174         233 :       if (entry->mProperty == aPropID) {
     175           4 :         return entry;
     176             :       }
     177             :     }
     178           0 :     return nullptr;
     179             :   }
     180             : 
     181             :   /**
     182             :    * Records that mIndexMap needs updating, due to prefs changing that could
     183             :    * affect the set of properties exposed on an nsComputedDOMStyle.
     184             :    */
     185           0 :   void MarkDirty() { mExposedPropertyCount = 0; }
     186             : 
     187             :   // The member variables are public so that we can use an initializer in
     188             :   // nsComputedDOMStyle::GetComputedStyleMap.  Use the member functions
     189             :   // above to get information from this object.
     190             : 
     191             :   /**
     192             :    * An entry for each property that can be exposed on an nsComputedDOMStyle.
     193             :    */
     194             :   const Entry kEntries[eComputedStyleProperty_COUNT];
     195             : 
     196             :   /**
     197             :    * The number of properties that should be exposed on an nsComputedDOMStyle.
     198             :    * This will be less than eComputedStyleProperty_COUNT if some property
     199             :    * prefs are disabled.  A value of 0 indicates that it and mIndexMap are out
     200             :    * of date.
     201             :    */
     202             :   uint32_t mExposedPropertyCount;
     203             : 
     204             :   /**
     205             :    * A map of indexes on the nsComputedDOMStyle object to indexes into kEntries.
     206             :    */
     207             :   uint32_t mIndexMap[eComputedStyleProperty_COUNT];
     208             : 
     209             : private:
     210             :   /**
     211             :    * Returns whether mExposedPropertyCount and mIndexMap are out of date.
     212             :    */
     213           4 :   bool IsDirty() { return mExposedPropertyCount == 0; }
     214             : 
     215             :   /**
     216             :    * Updates mExposedPropertyCount and mIndexMap to take into account properties
     217             :    * whose prefs are currently disabled.
     218             :    */
     219             :   void Update();
     220             : 
     221             :   /**
     222             :    * Maps an nsComputedDOMStyle indexed getter index to an index into kEntries.
     223             :    */
     224         233 :   uint32_t EntryIndex(uint32_t aIndex) const
     225             :   {
     226         233 :     MOZ_ASSERT(aIndex < mExposedPropertyCount);
     227         233 :     return mIndexMap[aIndex];
     228             :   }
     229             : };
     230             : 
     231             : void
     232           4 : nsComputedStyleMap::Update()
     233             : {
     234           4 :   if (!IsDirty()) {
     235           3 :     return;
     236             :   }
     237             : 
     238           1 :   uint32_t index = 0;
     239         287 :   for (uint32_t i = 0; i < eComputedStyleProperty_COUNT; i++) {
     240         286 :     if (kEntries[i].IsEnabled()) {
     241         278 :       mIndexMap[index++] = i;
     242             :     }
     243             :   }
     244           1 :   mExposedPropertyCount = index;
     245             : }
     246             : 
     247           4 : nsComputedDOMStyle::nsComputedDOMStyle(dom::Element* aElement,
     248             :                                        const nsAString& aPseudoElt,
     249             :                                        nsIPresShell* aPresShell,
     250             :                                        StyleType aStyleType,
     251           4 :                                        AnimationFlag aFlag)
     252             :   : mDocumentWeak(nullptr)
     253             :   , mOuterFrame(nullptr)
     254             :   , mInnerFrame(nullptr)
     255             :   , mPresShell(nullptr)
     256             :   , mStyleType(aStyleType)
     257             :   , mStyleContextGeneration(0)
     258             :   , mExposeVisitedStyle(false)
     259             :   , mResolvedStyleContext(false)
     260           4 :   , mAnimationFlag(aFlag)
     261             : {
     262           4 :   MOZ_ASSERT(aElement && aPresShell);
     263             : 
     264           4 :   mDocumentWeak = do_GetWeakReference(aPresShell->GetDocument());
     265           4 :   mContent = aElement;
     266           4 :   mPseudo = nsCSSPseudoElements::GetPseudoAtom(aPseudoElt);
     267             : 
     268           4 :   MOZ_ASSERT(aPresShell->GetPresContext());
     269           4 : }
     270             : 
     271           0 : nsComputedDOMStyle::~nsComputedDOMStyle()
     272             : {
     273           0 :   ClearStyleContext();
     274           0 : }
     275             : 
     276             : NS_IMPL_CYCLE_COLLECTION_CLASS(nsComputedDOMStyle)
     277             : 
     278           0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsComputedDOMStyle)
     279           0 :   tmp->ClearStyleContext();  // remove observer before clearing mContent
     280           0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK(mContent)
     281           0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
     282           0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
     283             : 
     284           4 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsComputedDOMStyle)
     285           4 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mContent)
     286           4 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
     287             : 
     288           8 : NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(nsComputedDOMStyle)
     289             : 
     290           0 : NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(nsComputedDOMStyle)
     291           0 :   return tmp->HasKnownLiveWrapper();
     292             : NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_END
     293             : 
     294           0 : NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_BEGIN(nsComputedDOMStyle)
     295           0 :   return tmp->HasKnownLiveWrapper();
     296             : NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_END
     297             : 
     298           0 : NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_BEGIN(nsComputedDOMStyle)
     299           0 :   return tmp->HasKnownLiveWrapper();
     300             : NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_END
     301             : 
     302             : // QueryInterface implementation for nsComputedDOMStyle
     303          40 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsComputedDOMStyle)
     304           4 :   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
     305           0 :   NS_INTERFACE_MAP_ENTRY(nsIMutationObserver)
     306           0 : NS_INTERFACE_MAP_END_INHERITING(nsDOMCSSDeclaration)
     307             : 
     308             : 
     309           8 : NS_IMPL_CYCLE_COLLECTING_ADDREF(nsComputedDOMStyle)
     310           4 : NS_IMPL_CYCLE_COLLECTING_RELEASE(nsComputedDOMStyle)
     311             : 
     312             : NS_IMETHODIMP
     313           4 : nsComputedDOMStyle::GetPropertyValue(const nsCSSPropertyID aPropID,
     314             :                                      nsAString& aValue)
     315             : {
     316             :   // This is mostly to avoid code duplication with GetPropertyCSSValue(); if
     317             :   // perf ever becomes an issue here (doubtful), we can look into changing
     318             :   // this.
     319             :   return GetPropertyValue(
     320           8 :     NS_ConvertASCIItoUTF16(nsCSSProps::GetStringValue(aPropID)),
     321           8 :     aValue);
     322             : }
     323             : 
     324             : NS_IMETHODIMP
     325           0 : nsComputedDOMStyle::SetPropertyValue(const nsCSSPropertyID aPropID,
     326             :                                      const nsAString& aValue)
     327             : {
     328           0 :   return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
     329             : }
     330             : 
     331             : NS_IMETHODIMP
     332           0 : nsComputedDOMStyle::GetCssText(nsAString& aCssText)
     333             : {
     334           0 :   aCssText.Truncate();
     335             : 
     336           0 :   return NS_OK;
     337             : }
     338             : 
     339             : NS_IMETHODIMP
     340           0 : nsComputedDOMStyle::SetCssText(const nsAString& aCssText)
     341             : {
     342           0 :   return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
     343             : }
     344             : 
     345             : NS_IMETHODIMP
     346           0 : nsComputedDOMStyle::GetLength(uint32_t* aLength)
     347             : {
     348           0 :   NS_PRECONDITION(aLength, "Null aLength!  Prepare to die!");
     349             : 
     350           0 :   uint32_t length = GetComputedStyleMap()->Length();
     351             : 
     352             :   // Make sure we have up to date style so that we can include custom
     353             :   // properties.
     354           0 :   UpdateCurrentStyleSources(false);
     355           0 :   if (mStyleContext) {
     356           0 :     length += mStyleContext->IsServo()
     357           0 :       ? Servo_GetCustomPropertiesCount(mStyleContext->ComputedValues())
     358           0 :       : StyleVariables()->mVariables.Count();
     359             :   }
     360             : 
     361           0 :   *aLength = length;
     362             : 
     363           0 :   ClearCurrentStyleSources();
     364             : 
     365           0 :   return NS_OK;
     366             : }
     367             : 
     368             : NS_IMETHODIMP
     369           0 : nsComputedDOMStyle::GetParentRule(nsIDOMCSSRule** aParentRule)
     370             : {
     371           0 :   *aParentRule = nullptr;
     372             : 
     373           0 :   return NS_OK;
     374             : }
     375             : 
     376             : NS_IMETHODIMP
     377           4 : nsComputedDOMStyle::GetPropertyValue(const nsAString& aPropertyName,
     378             :                                      nsAString& aReturn)
     379             : {
     380           4 :   aReturn.Truncate();
     381             : 
     382           8 :   ErrorResult error;
     383           8 :   RefPtr<CSSValue> val = GetPropertyCSSValue(aPropertyName, error);
     384           4 :   if (error.Failed()) {
     385           0 :     return error.StealNSResult();
     386             :   }
     387             : 
     388           4 :   if (val) {
     389           8 :     nsString text;
     390           4 :     val->GetCssText(text, error);
     391           4 :     aReturn.Assign(text);
     392           4 :     return error.StealNSResult();
     393             :   }
     394             : 
     395           0 :   return NS_OK;
     396             : }
     397             : 
     398             : NS_IMETHODIMP
     399           0 : nsComputedDOMStyle::GetAuthoredPropertyValue(const nsAString& aPropertyName,
     400             :                                              nsAString& aReturn)
     401             : {
     402             :   // Authored style doesn't make sense to return from computed DOM style,
     403             :   // so just return whatever GetPropertyValue() returns.
     404           0 :   return GetPropertyValue(aPropertyName, aReturn);
     405             : }
     406             : 
     407             : /* static */
     408             : already_AddRefed<nsStyleContext>
     409           0 : nsComputedDOMStyle::GetStyleContext(Element* aElement,
     410             :                                     nsIAtom* aPseudo,
     411             :                                     nsIPresShell* aPresShell,
     412             :                                     StyleType aStyleType)
     413             : {
     414             :   // If the content has a pres shell, we must use it.  Otherwise we'd
     415             :   // potentially mix rule trees by using the wrong pres shell's style
     416             :   // set.  Using the pres shell from the content also means that any
     417             :   // content that's actually *in* a document will get the style from the
     418             :   // correct document.
     419           0 :   nsCOMPtr<nsIPresShell> presShell = GetPresShellForContent(aElement);
     420           0 :   if (!presShell) {
     421           0 :     presShell = aPresShell;
     422           0 :     if (!presShell)
     423           0 :       return nullptr;
     424             :   }
     425             : 
     426           0 :   presShell->FlushPendingNotifications(FlushType::Style);
     427             : 
     428           0 :   return GetStyleContextNoFlush(aElement, aPseudo, presShell, aStyleType);
     429             : }
     430             : 
     431             : namespace {
     432             : class MOZ_STACK_CLASS StyleResolver final
     433             : {
     434             : public:
     435         237 :   StyleResolver(nsPresContext* aPresContext,
     436             :                 nsComputedDOMStyle::AnimationFlag aAnimationFlag)
     437         237 :     : mAnimationFlag(aAnimationFlag)
     438             :   {
     439         237 :     MOZ_ASSERT(aPresContext);
     440             : 
     441             :     // Nothing to do if we are going to resolve style *with* animation.
     442         237 :     if (mAnimationFlag == nsComputedDOMStyle::eWithAnimation) {
     443         237 :       return;
     444             :     }
     445             : 
     446             :     // Set SkipAnimationRules flag if we are going to resolve style without
     447             :     // animation.
     448           0 :     if (aPresContext->RestyleManager()->IsGecko()) {
     449           0 :       mRestyleManager = aPresContext->RestyleManager()->AsGecko();
     450             : 
     451           0 :       mOldSkipAnimationRules = mRestyleManager->SkipAnimationRules();
     452           0 :       mRestyleManager->SetSkipAnimationRules(true);
     453             :     } else {
     454           0 :       NS_WARNING("stylo: can't skip animaition rules yet");
     455             :     }
     456             :   }
     457             : 
     458             :   already_AddRefed<nsStyleContext>
     459         237 :   ResolveWithAnimation(StyleSetHandle aStyleSet,
     460             :                        Element* aElement,
     461             :                        CSSPseudoElementType aType,
     462             :                        nsStyleContext* aParentContext,
     463             :                        nsComputedDOMStyle::StyleType aStyleType,
     464             :                        bool aInDocWithShell)
     465             :   {
     466         237 :     MOZ_ASSERT(mAnimationFlag == nsComputedDOMStyle::eWithAnimation,
     467             :       "AnimationFlag should be eWithAnimation");
     468             : 
     469         474 :     RefPtr<nsStyleContext> result;
     470             : 
     471         237 :     if (aType != CSSPseudoElementType::NotPseudo) {
     472           0 :       nsIFrame* frame = nsLayoutUtils::GetStyleFrame(aElement);
     473             :       Element* pseudoElement =
     474           0 :         frame && aInDocWithShell ? frame->GetPseudoElement(aType) : nullptr;
     475           0 :       result = aStyleSet->ResolvePseudoElementStyle(aElement, aType,
     476             :                                                     aParentContext,
     477           0 :                                                     pseudoElement);
     478             :     } else {
     479         474 :       result = aStyleSet->ResolveStyleFor(aElement, aParentContext,
     480         237 :                                           LazyComputeBehavior::Allow);
     481             :     }
     482         237 :     if (aStyleType == nsComputedDOMStyle::StyleType::eDefaultOnly) {
     483             :       // We really only want the user and UA rules.  Filter out the other ones.
     484           0 :       nsTArray< nsCOMPtr<nsIStyleRule> > rules;
     485           0 :       for (nsRuleNode* ruleNode = result->RuleNode();
     486           0 :            !ruleNode->IsRoot();
     487             :            ruleNode = ruleNode->GetParent()) {
     488           0 :         if (ruleNode->GetLevel() == SheetType::Agent ||
     489           0 :             ruleNode->GetLevel() == SheetType::User) {
     490           0 :           rules.AppendElement(ruleNode->GetRule());
     491             :         }
     492             :       }
     493             : 
     494             :       // We want to build a list of user/ua rules that is in order from least to
     495             :       // most important, so we have to reverse the list.
     496             :       // Integer division to get "stop" is purposeful here: if length is odd, we
     497             :       // don't have to do anything with the middle element of the array.
     498           0 :       for (uint32_t i = 0, length = rules.Length(), stop = length / 2;
     499           0 :            i < stop; ++i) {
     500           0 :         rules[i].swap(rules[length - i - 1]);
     501             :       }
     502             : 
     503           0 :       result = aStyleSet->AsGecko()->ResolveStyleForRules(aParentContext,
     504           0 :                                                           rules);
     505             :     }
     506         474 :     return result.forget();
     507             :   }
     508             : 
     509             :   already_AddRefed<nsStyleContext>
     510           0 :   ResolveWithoutAnimation(StyleSetHandle aStyleSet,
     511             :                           Element* aElement,
     512             :                           CSSPseudoElementType aType,
     513             :                           nsStyleContext* aParentContext,
     514             :                           bool aInDocWithShell)
     515             :   {
     516           0 :     MOZ_ASSERT(!aStyleSet->IsServo(),
     517             :       "Servo backend should not use this function");
     518           0 :     MOZ_ASSERT(mAnimationFlag == nsComputedDOMStyle::eWithoutAnimation,
     519             :       "AnimationFlag should be eWithoutAnimation");
     520             : 
     521           0 :     RefPtr<nsStyleContext> result;
     522             : 
     523           0 :     if (aType != CSSPseudoElementType::NotPseudo) {
     524           0 :       nsIFrame* frame = nsLayoutUtils::GetStyleFrame(aElement);
     525             :       Element* pseudoElement =
     526           0 :         frame && aInDocWithShell ? frame->GetPseudoElement(aType) : nullptr;
     527             :       result =
     528           0 :         aStyleSet->AsGecko()->ResolvePseudoElementStyleWithoutAnimation(
     529             :           aElement, aType,
     530             :           aParentContext,
     531           0 :           pseudoElement);
     532             :     } else {
     533             :       result =
     534           0 :         aStyleSet->AsGecko()->ResolveStyleWithoutAnimation(aElement,
     535           0 :                                                            aParentContext);
     536             :     }
     537           0 :     return result.forget();
     538             :   }
     539             : 
     540         237 :   ~StyleResolver()
     541         237 :   {
     542         237 :     if (mRestyleManager) {
     543           0 :       mRestyleManager->SetSkipAnimationRules(mOldSkipAnimationRules);
     544             :     }
     545         237 :   }
     546             : 
     547             : private:
     548             :   GeckoRestyleManager* mRestyleManager = nullptr;
     549             :   bool mOldSkipAnimationRules = false;
     550             :   nsComputedDOMStyle::AnimationFlag mAnimationFlag;
     551             : };
     552             : }
     553             : 
     554             : /**
     555             :  * The following function checks whether we need to explicitly resolve the style
     556             :  * again, even though we have a style context coming from the frame.
     557             :  *
     558             :  * This basically checks whether the style is or may be under a ::first-line or
     559             :  * ::first-letter frame, in which case we can't return the frame style, and we
     560             :  * need to resolve it. See bug 505515.
     561             :  */
     562             : static bool
     563         127 : MustReresolveStyle(const nsStyleContext* aContext)
     564             : {
     565         127 :   MOZ_ASSERT(aContext);
     566             : 
     567         127 :   if (aContext->HasPseudoElementData()) {
     568           0 :     if (!aContext->GetPseudo() ||
     569           0 :         aContext->IsServo()) {
     570             :       // TODO(emilio): When ::first-line is supported in Servo, we may want to
     571             :       // fix this to avoid re-resolving pseudo-element styles.
     572           0 :       return true;
     573             :     }
     574             : 
     575           0 :     return aContext->GetParent() &&
     576           0 :            aContext->GetParent()->HasPseudoElementData();
     577             :   }
     578             : 
     579         127 :   return false;
     580             : }
     581             : 
     582             : already_AddRefed<nsStyleContext>
     583         360 : nsComputedDOMStyle::DoGetStyleContextNoFlush(Element* aElement,
     584             :                                              nsIAtom* aPseudo,
     585             :                                              nsIPresShell* aPresShell,
     586             :                                              StyleType aStyleType,
     587             :                                              AnimationFlag aAnimationFlag)
     588             : {
     589         360 :   MOZ_ASSERT(aElement, "NULL element");
     590             :   // If the content has a pres shell, we must use it.  Otherwise we'd
     591             :   // potentially mix rule trees by using the wrong pres shell's style
     592             :   // set.  Using the pres shell from the content also means that any
     593             :   // content that's actually *in* a document will get the style from the
     594             :   // correct document.
     595         360 :   nsIPresShell *presShell = GetPresShellForContent(aElement);
     596         360 :   bool inDocWithShell = true;
     597         360 :   if (!presShell) {
     598           2 :     inDocWithShell = false;
     599           2 :     presShell = aPresShell;
     600           2 :     if (!presShell)
     601           0 :       return nullptr;
     602             :   }
     603             : 
     604         360 :   auto pseudoType = CSSPseudoElementType::NotPseudo;
     605         360 :   if (aPseudo) {
     606             :     pseudoType = nsCSSPseudoElements::
     607           0 :       GetPseudoType(aPseudo, CSSEnabledState::eIgnoreEnabledState);
     608           0 :     if (pseudoType >= CSSPseudoElementType::Count) {
     609           0 :       return nullptr;
     610             :     }
     611             :   }
     612             : 
     613             :   // XXX the !aElement->IsHTMLElement(nsGkAtoms::area)
     614             :   // check is needed due to bug 135040 (to avoid using
     615             :   // mPrimaryFrame). Remove it once that's fixed.
     616         718 :   if (inDocWithShell &&
     617         718 :       aStyleType == eAll &&
     618         358 :       !aElement->IsHTMLElement(nsGkAtoms::area)) {
     619         358 :     nsIFrame* frame = nullptr;
     620         358 :     if (aPseudo == nsCSSPseudoElements::before) {
     621           0 :       frame = nsLayoutUtils::GetBeforeFrame(aElement);
     622         358 :     } else if (aPseudo == nsCSSPseudoElements::after) {
     623           0 :       frame = nsLayoutUtils::GetAfterFrame(aElement);
     624         358 :     } else if (!aPseudo) {
     625         358 :       frame = nsLayoutUtils::GetStyleFrame(aElement);
     626             :     }
     627         358 :     if (frame) {
     628         123 :       nsStyleContext* result = frame->StyleContext();
     629             :       // Don't use the style context if it was influenced by
     630             :       // pseudo-elements, since then it's not the primary style
     631             :       // for this element / pseudo.
     632         123 :       if (!MustReresolveStyle(result)) {
     633             :         // The existing style context may have animation styles so check if we
     634             :         // need to remove them.
     635         123 :         if (aAnimationFlag == eWithoutAnimation) {
     636           0 :           nsPresContext* presContext = presShell->GetPresContext();
     637           0 :           MOZ_ASSERT(presContext, "Should have a prescontext if we have a frame");
     638           0 :           if (presContext && presContext->StyleSet()->IsGecko()) {
     639           0 :             nsStyleSet* styleSet = presContext->StyleSet()->AsGecko();
     640             :             return styleSet->ResolveStyleByRemovingAnimation(
     641           0 :                      aElement, result, eRestyle_AllHintsWithAnimations);
     642             :           } else {
     643             :             RefPtr<ServoComputedValues> baseComputedValues =
     644           0 :               presContext->StyleSet()->AsServo()->
     645           0 :                 GetBaseComputedValuesForElement(
     646           0 :                     aElement, pseudoType, result->ComputedValues());
     647           0 :             return ServoStyleContext::Create(nullptr, presContext, aPseudo,
     648           0 :                                              pseudoType, baseComputedValues.forget());
     649             :           }
     650             :         }
     651             : 
     652             :         // this function returns an addrefed style context
     653         246 :         RefPtr<nsStyleContext> ret = result;
     654         123 :         return ret.forget();
     655             :       }
     656             :     }
     657             :   }
     658             : 
     659             :   // No frame has been created, or we have a pseudo, or we're looking
     660             :   // for the default style, so resolve the style ourselves.
     661             : 
     662         237 :   nsPresContext* presContext = presShell->GetPresContext();
     663         237 :   if (!presContext)
     664           0 :     return nullptr;
     665             : 
     666         237 :   StyleSetHandle styleSet = presShell->StyleSet();
     667             : 
     668             :   // For Servo, compute the result directly without recursively building up
     669             :   // a throwaway style context chain.
     670         237 :   if (ServoStyleSet* servoSet = styleSet->GetAsServo()) {
     671             :     StyleRuleInclusion rules = aStyleType == eDefaultOnly
     672           0 :                                ? StyleRuleInclusion::DefaultOnly
     673           0 :                                : StyleRuleInclusion::All;
     674             :     RefPtr<nsStyleContext> result =
     675           0 :        servoSet->ResolveTransientStyle(aElement, aPseudo, pseudoType, rules);
     676           0 :     if (aAnimationFlag == eWithAnimation) {
     677           0 :       return result.forget();
     678             :     }
     679             : 
     680             :     RefPtr<ServoComputedValues> baseComputedValues =
     681           0 :       servoSet->GetBaseComputedValuesForElement(
     682           0 :           aElement, pseudoType, result->ComputedValues());
     683           0 :     return ServoStyleContext::Create(nullptr, presContext, aPseudo,
     684           0 :                                      pseudoType, baseComputedValues.forget());
     685             :   }
     686             : 
     687         474 :   RefPtr<nsStyleContext> parentContext;
     688         237 :   nsIContent* parent = aPseudo ? aElement : aElement->GetParent();
     689             :   // Don't resolve parent context for document fragments.
     690         237 :   if (parent && parent->IsElement()) {
     691         470 :     parentContext = GetStyleContextNoFlush(parent->AsElement(), nullptr,
     692         235 :                                            aPresShell, aStyleType);
     693             :   }
     694             : 
     695         474 :   StyleResolver styleResolver(presContext, aAnimationFlag);
     696             : 
     697         237 :   if (aAnimationFlag == eWithAnimation) {
     698             :     return styleResolver.ResolveWithAnimation(styleSet,
     699             :                                               aElement, pseudoType,
     700             :                                               parentContext,
     701             :                                               aStyleType,
     702         237 :                                               inDocWithShell);
     703             :   }
     704             : 
     705             :   return styleResolver.ResolveWithoutAnimation(styleSet,
     706             :                                                aElement, pseudoType,
     707             :                                                parentContext,
     708           0 :                                                inDocWithShell);
     709             : }
     710             : 
     711             : nsMargin
     712           0 : nsComputedDOMStyle::GetAdjustedValuesForBoxSizing()
     713             : {
     714             :   // We want the width/height of whatever parts 'width' or 'height' controls,
     715             :   // which can be different depending on the value of the 'box-sizing' property.
     716           0 :   const nsStylePosition* stylePos = StylePosition();
     717             : 
     718           0 :   nsMargin adjustment;
     719           0 :   if (stylePos->mBoxSizing == StyleBoxSizing::Border) {
     720           0 :     adjustment = mInnerFrame->GetUsedBorderAndPadding();
     721             :   }
     722             : 
     723           0 :   return adjustment;
     724             : }
     725             : 
     726             : /* static */
     727             : nsIPresShell*
     728         368 : nsComputedDOMStyle::GetPresShellForContent(const nsIContent* aContent)
     729             : {
     730         368 :   nsIDocument* composedDoc = aContent->GetComposedDoc();
     731         368 :   if (!composedDoc)
     732           2 :     return nullptr;
     733             : 
     734         366 :   return composedDoc->GetShell();
     735             : }
     736             : 
     737             : // nsDOMCSSDeclaration abstract methods which should never be called
     738             : // on a nsComputedDOMStyle object, but must be defined to avoid
     739             : // compile errors.
     740             : DeclarationBlock*
     741           0 : nsComputedDOMStyle::GetCSSDeclaration(Operation)
     742             : {
     743           0 :   NS_RUNTIMEABORT("called nsComputedDOMStyle::GetCSSDeclaration");
     744           0 :   return nullptr;
     745             : }
     746             : 
     747             : nsresult
     748           0 : nsComputedDOMStyle::SetCSSDeclaration(DeclarationBlock*)
     749             : {
     750           0 :   NS_RUNTIMEABORT("called nsComputedDOMStyle::SetCSSDeclaration");
     751           0 :   return NS_ERROR_FAILURE;
     752             : }
     753             : 
     754             : nsIDocument*
     755           0 : nsComputedDOMStyle::DocToUpdate()
     756             : {
     757           0 :   NS_RUNTIMEABORT("called nsComputedDOMStyle::DocToUpdate");
     758           0 :   return nullptr;
     759             : }
     760             : 
     761             : void
     762           0 : nsComputedDOMStyle::GetCSSParsingEnvironment(CSSParsingEnvironment& aCSSParseEnv)
     763             : {
     764           0 :   NS_RUNTIMEABORT("called nsComputedDOMStyle::GetCSSParsingEnvironment");
     765             :   // Just in case NS_RUNTIMEABORT ever stops killing us for some reason
     766           0 :   aCSSParseEnv.mPrincipal = nullptr;
     767           0 : }
     768             : 
     769             : nsDOMCSSDeclaration::ServoCSSParsingEnvironment
     770           0 : nsComputedDOMStyle::GetServoCSSParsingEnvironment() const
     771             : {
     772           0 :   MOZ_CRASH("called nsComputedDOMStyle::GetServoCSSParsingEnvironment");
     773             : }
     774             : 
     775             : void
     776           4 : nsComputedDOMStyle::ClearStyleContext()
     777             : {
     778           4 :   if (mResolvedStyleContext) {
     779           0 :     mResolvedStyleContext = false;
     780           0 :     mContent->RemoveMutationObserver(this);
     781             :   }
     782           4 :   mStyleContext = nullptr;
     783           4 : }
     784             : 
     785             : void
     786           0 : nsComputedDOMStyle::SetResolvedStyleContext(RefPtr<nsStyleContext>&& aContext,
     787             :                                             uint64_t aGeneration)
     788             : {
     789           0 :   if (!mResolvedStyleContext) {
     790           0 :     mResolvedStyleContext = true;
     791           0 :     mContent->AddMutationObserver(this);
     792             :   }
     793           0 :   mStyleContext = aContext;
     794           0 :   mStyleContextGeneration = aGeneration;
     795           0 : }
     796             : 
     797             : void
     798           4 : nsComputedDOMStyle::SetFrameStyleContext(nsStyleContext* aContext,
     799             :                                          uint64_t aGeneration)
     800             : {
     801           4 :   ClearStyleContext();
     802           4 :   mStyleContext = aContext;
     803           4 :   mStyleContextGeneration = aGeneration;
     804           4 : }
     805             : 
     806             : void
     807           4 : nsComputedDOMStyle::UpdateCurrentStyleSources(bool aNeedsLayoutFlush)
     808             : {
     809           8 :   nsCOMPtr<nsIDocument> document = do_QueryReferent(mDocumentWeak);
     810           4 :   if (!document) {
     811           0 :     ClearStyleContext();
     812           0 :     return;
     813             :   }
     814             : 
     815             :   // Flush _before_ getting the presshell, since that could create a new
     816             :   // presshell.  Also note that we want to flush the style on the document
     817             :   // we're computing style in, not on the document mContent is in -- the two
     818             :   // may be different.
     819           8 :   document->FlushPendingNotifications(
     820           8 :     aNeedsLayoutFlush ? FlushType::Layout : FlushType::Style);
     821             : #ifdef DEBUG
     822           4 :   mFlushedPendingReflows = aNeedsLayoutFlush;
     823             : #endif
     824             : 
     825           4 :   mPresShell = document->GetShell();
     826           4 :   if (!mPresShell || !mPresShell->GetPresContext()) {
     827           0 :     ClearStyleContext();
     828           0 :     return;
     829             :   }
     830             : 
     831             :   // We need to use GetUndisplayedRestyleGeneration instead of
     832             :   // GetRestyleGeneration, because the caching of mStyleContext is an
     833             :   // optimization that is useful only for displayed elements.
     834             :   // For undisplayed elements we need to take into account any DOM changes that
     835             :   // might cause a restyle, because Servo will not increase the generation for
     836             :   // undisplayed elements.
     837             :   // As for Gecko, GetUndisplayedRestyleGeneration is effectively equal to
     838             :   // GetRestyleGeneration, since the generation is incremented whenever we
     839             :   // process restyles.
     840             :   uint64_t currentGeneration =
     841           4 :     mPresShell->GetPresContext()->GetUndisplayedRestyleGeneration();
     842             : 
     843           4 :   if (mStyleContext) {
     844             :     // We can't rely on the undisplayed restyle generation if
     845             :     // mContent is out-of-document, since that generation is not
     846             :     // incremented for DOM changes on out-of-document elements.
     847             :     // So we always need to update the style context to ensure it
     848             :     // it up-to-date.
     849           0 :     if (mStyleContextGeneration == currentGeneration
     850           0 :         && mContent->IsInComposedDoc()) {
     851             :       // Our cached style context is still valid.
     852           0 :       return;
     853             :     }
     854             :     // We've processed some restyles, so the cached style context might
     855             :     // be out of date.
     856           0 :     mStyleContext = nullptr;
     857             :   }
     858             : 
     859             :   // XXX the !mContent->IsHTMLElement(nsGkAtoms::area)
     860             :   // check is needed due to bug 135040 (to avoid using
     861             :   // mPrimaryFrame). Remove it once that's fixed.
     862           4 :   if (mStyleType == eAll && !mContent->IsHTMLElement(nsGkAtoms::area)) {
     863           4 :     mOuterFrame = nullptr;
     864             : 
     865           4 :     if (!mPseudo) {
     866           4 :       mOuterFrame = mContent->GetPrimaryFrame();
     867           0 :     } else if (mPseudo == nsCSSPseudoElements::before ||
     868           0 :                mPseudo == nsCSSPseudoElements::after) {
     869           0 :       nsIAtom* property = mPseudo == nsCSSPseudoElements::before
     870           0 :                             ? nsGkAtoms::beforePseudoProperty
     871           0 :                             : nsGkAtoms::afterPseudoProperty;
     872             : 
     873           0 :       auto* pseudo = static_cast<Element*>(mContent->GetProperty(property));
     874           0 :       mOuterFrame = pseudo ? pseudo->GetPrimaryFrame() : nullptr;
     875             :     }
     876             : 
     877           4 :     mInnerFrame = mOuterFrame;
     878           4 :     if (mOuterFrame) {
     879           4 :       LayoutFrameType type = mOuterFrame->Type();
     880           4 :       if (type == LayoutFrameType::TableWrapper) {
     881             :         // If the frame is a table wrapper frame then we should get the style
     882             :         // from the inner table frame.
     883           0 :         mInnerFrame = mOuterFrame->PrincipalChildList().FirstChild();
     884           0 :         NS_ASSERTION(mInnerFrame, "table wrapper must have an inner");
     885           0 :         NS_ASSERTION(!mInnerFrame->GetNextSibling(),
     886             :                      "table wrapper frames should have just one child, "
     887             :                      "the inner table");
     888             :       }
     889             : 
     890           4 :       SetFrameStyleContext(mInnerFrame->StyleContext(), currentGeneration);
     891           4 :       NS_ASSERTION(mStyleContext, "Frame without style context?");
     892             :     }
     893             :   }
     894             : 
     895           4 :   if (!mStyleContext || MustReresolveStyle(mStyleContext)) {
     896             : #ifdef DEBUG
     897           0 :     if (mStyleContext && mStyleContext->IsGecko()) {
     898             :       // We want to check that going through this path because of
     899             :       // HasPseudoElementData is rare, because it slows us down a good
     900             :       // bit.  So check that we're really inside something associated
     901             :       // with a pseudo-element that contains elements.  (We also allow
     902             :       // the element to be NAC, just in case some chrome JS calls
     903             :       // getComputedStyle on a NAC-implemented pseudo.)
     904           0 :       nsStyleContext* topWithPseudoElementData = mStyleContext;
     905           0 :       while (topWithPseudoElementData->GetParent()->HasPseudoElementData()) {
     906           0 :         topWithPseudoElementData = topWithPseudoElementData->GetParent();
     907             :       }
     908           0 :       CSSPseudoElementType pseudo = topWithPseudoElementData->GetPseudoType();
     909           0 :       nsIAtom* pseudoAtom = nsCSSPseudoElements::GetPseudoAtom(pseudo);
     910             :       nsAutoString assertMsg(
     911           0 :         NS_LITERAL_STRING("we should be in a pseudo-element that is expected to contain elements ("));
     912           0 :       assertMsg.Append(nsDependentString(pseudoAtom->GetUTF16String()));
     913           0 :       assertMsg.Append(')');
     914           0 :       NS_ASSERTION(nsCSSPseudoElements::PseudoElementContainsElements(pseudo) ||
     915             :                    mContent->IsNativeAnonymous(),
     916             :                    NS_LossyConvertUTF16toASCII(assertMsg).get());
     917             :     }
     918             : #endif
     919             :     // Need to resolve a style context
     920             :     RefPtr<nsStyleContext> resolvedStyleContext =
     921           0 :       nsComputedDOMStyle::GetStyleContext(mContent->AsElement(),
     922             :                                           mPseudo,
     923             :                                           mPresShell,
     924           0 :                                           mStyleType);
     925           0 :     if (!resolvedStyleContext) {
     926           0 :       ClearStyleContext();
     927           0 :       return;
     928             :     }
     929             : 
     930             :     // No need to re-get the generation, even though GetStyleContext
     931             :     // will flush, since we flushed style at the top of this function.
     932           0 :     NS_ASSERTION(mPresShell &&
     933             :                  currentGeneration ==
     934             :                    mPresShell->GetPresContext()->GetUndisplayedRestyleGeneration(),
     935             :                  "why should we have flushed style again?");
     936             : 
     937           0 :     SetResolvedStyleContext(Move(resolvedStyleContext), currentGeneration);
     938           0 :     NS_ASSERTION(mPseudo || !mStyleContext->HasPseudoElementData(),
     939             :                  "should not have pseudo-element data");
     940             :   }
     941             : 
     942           4 :   if (mAnimationFlag == eWithoutAnimation) {
     943             :     // We will support Servo in bug 1311257.
     944           0 :     MOZ_ASSERT(mPresShell->StyleSet()->IsGecko(),
     945             :                "eWithoutAnimationRules support Gecko only");
     946           0 :     nsStyleSet* styleSet = mPresShell->StyleSet()->AsGecko();
     947             :     RefPtr<nsStyleContext> unanimatedStyleContext =
     948           0 :       styleSet->ResolveStyleByRemovingAnimation(
     949           0 :         mContent->AsElement(), mStyleContext, eRestyle_AllHintsWithAnimations);
     950           0 :     SetResolvedStyleContext(Move(unanimatedStyleContext), currentGeneration);
     951             :   }
     952             : 
     953             :   // mExposeVisitedStyle is set to true only by testing APIs that
     954             :   // require chrome privilege.
     955           4 :   MOZ_ASSERT(!mExposeVisitedStyle || nsContentUtils::IsCallerChrome(),
     956             :              "mExposeVisitedStyle set incorrectly");
     957           4 :   if (mExposeVisitedStyle && mStyleContext->RelevantLinkVisited()) {
     958           0 :     nsStyleContext *styleIfVisited = mStyleContext->GetStyleIfVisited();
     959           0 :     if (styleIfVisited) {
     960           0 :       mStyleContext = styleIfVisited;
     961             :     }
     962             :   }
     963             : }
     964             : 
     965             : void
     966           4 : nsComputedDOMStyle::ClearCurrentStyleSources()
     967             : {
     968           4 :   mOuterFrame = nullptr;
     969           4 :   mInnerFrame = nullptr;
     970           4 :   mPresShell = nullptr;
     971             : 
     972             :   // Release the current style context if we got it off the frame.
     973             :   // For a style context we resolved, keep it around so that we
     974             :   // can re-use it next time this object is queried.
     975           4 :   if (!mResolvedStyleContext) {
     976           4 :     mStyleContext = nullptr;
     977             :   }
     978           4 : }
     979             : 
     980             : already_AddRefed<CSSValue>
     981           4 : nsComputedDOMStyle::GetPropertyCSSValue(const nsAString& aPropertyName, ErrorResult& aRv)
     982             : {
     983             :   nsCSSPropertyID prop =
     984           4 :     nsCSSProps::LookupProperty(aPropertyName, CSSEnabledState::eForAllContent);
     985             : 
     986             :   bool needsLayoutFlush;
     987             :   nsComputedStyleMap::Entry::ComputeMethod getter;
     988             : 
     989           4 :   if (prop == eCSSPropertyExtra_variable) {
     990           0 :     needsLayoutFlush = false;
     991           0 :     getter = nullptr;
     992             :   } else {
     993             :     // We don't (for now, anyway, though it may make sense to change it
     994             :     // for all aliases, including those in nsCSSPropAliasList) want
     995             :     // aliases to be enumerable (via GetLength and IndexedGetter), so
     996             :     // handle them here rather than adding entries to
     997             :     // GetQueryablePropertyMap.
     998           8 :     if (prop != eCSSProperty_UNKNOWN &&
     999           4 :         nsCSSProps::PropHasFlags(prop, CSS_PROPERTY_IS_ALIAS)) {
    1000           0 :       const nsCSSPropertyID* subprops = nsCSSProps::SubpropertyEntryFor(prop);
    1001           0 :       MOZ_ASSERT(subprops[1] == eCSSProperty_UNKNOWN,
    1002             :                  "must have list of length 1");
    1003           0 :       prop = subprops[0];
    1004             :     }
    1005             : 
    1006             :     const nsComputedStyleMap::Entry* propEntry =
    1007           4 :       GetComputedStyleMap()->FindEntryForProperty(prop);
    1008             : 
    1009           4 :     if (!propEntry) {
    1010             : #ifdef DEBUG_ComputedDOMStyle
    1011             :       NS_WARNING(PromiseFlatCString(NS_ConvertUTF16toUTF8(aPropertyName) +
    1012             :                                     NS_LITERAL_CSTRING(" is not queryable!")).get());
    1013             : #endif
    1014             : 
    1015             :       // NOTE:  For branches, we should flush here for compatibility!
    1016           0 :       return nullptr;
    1017             :     }
    1018             : 
    1019           4 :     needsLayoutFlush = propEntry->IsLayoutFlushNeeded();
    1020           4 :     getter = propEntry->mGetter;
    1021             :   }
    1022             : 
    1023           4 :   UpdateCurrentStyleSources(needsLayoutFlush);
    1024           4 :   if (!mStyleContext) {
    1025           0 :     aRv.Throw(NS_ERROR_NOT_AVAILABLE);
    1026           0 :     return nullptr;
    1027             :   }
    1028             : 
    1029           8 :   RefPtr<CSSValue> val;
    1030           4 :   if (prop == eCSSPropertyExtra_variable) {
    1031           0 :     val = DoGetCustomProperty(aPropertyName);
    1032             :   } else {
    1033             :     // Call our pointer-to-member-function.
    1034           4 :     val = (this->*getter)();
    1035             :   }
    1036             : 
    1037           4 :   ClearCurrentStyleSources();
    1038             : 
    1039           4 :   return val.forget();
    1040             : }
    1041             : 
    1042             : NS_IMETHODIMP
    1043           0 : nsComputedDOMStyle::RemoveProperty(const nsAString& aPropertyName,
    1044             :                                    nsAString& aReturn)
    1045             : {
    1046           0 :   return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
    1047             : }
    1048             : 
    1049             : 
    1050             : NS_IMETHODIMP
    1051           0 : nsComputedDOMStyle::GetPropertyPriority(const nsAString& aPropertyName,
    1052             :                                         nsAString& aReturn)
    1053             : {
    1054           0 :   aReturn.Truncate();
    1055             : 
    1056           0 :   return NS_OK;
    1057             : }
    1058             : 
    1059             : NS_IMETHODIMP
    1060           0 : nsComputedDOMStyle::SetProperty(const nsAString& aPropertyName,
    1061             :                                 const nsAString& aValue,
    1062             :                                 const nsAString& aPriority)
    1063             : {
    1064           0 :   return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR;
    1065             : }
    1066             : 
    1067             : NS_IMETHODIMP
    1068           0 : nsComputedDOMStyle::Item(uint32_t aIndex, nsAString& aReturn)
    1069             : {
    1070           0 :   return nsDOMCSSDeclaration::Item(aIndex, aReturn);
    1071             : }
    1072             : 
    1073             : void
    1074           0 : nsComputedDOMStyle::IndexedGetter(uint32_t   aIndex,
    1075             :                                   bool&      aFound,
    1076             :                                   nsAString& aPropName)
    1077             : {
    1078           0 :   nsComputedStyleMap* map = GetComputedStyleMap();
    1079           0 :   uint32_t length = map->Length();
    1080             : 
    1081           0 :   if (aIndex < length) {
    1082           0 :     aFound = true;
    1083           0 :     CopyASCIItoUTF16(nsCSSProps::GetStringValue(map->PropertyAt(aIndex)),
    1084           0 :                      aPropName);
    1085           0 :     return;
    1086             :   }
    1087             : 
    1088             :   // Custom properties are exposed with indexed properties just after all
    1089             :   // of the built-in properties.
    1090           0 :   UpdateCurrentStyleSources(false);
    1091           0 :   if (!mStyleContext) {
    1092           0 :     aFound = false;
    1093           0 :     return;
    1094             :   }
    1095             : 
    1096           0 :   bool isServo = mStyleContext->IsServo();
    1097             : 
    1098             :   const nsStyleVariables* variables = isServo
    1099           0 :     ? nullptr
    1100           0 :     : StyleVariables();
    1101             : 
    1102             :   const uint32_t count = isServo
    1103           0 :     ? Servo_GetCustomPropertiesCount(mStyleContext->ComputedValues())
    1104           0 :     : variables->mVariables.Count();
    1105             : 
    1106           0 :   const uint32_t index = aIndex - length;
    1107           0 :   if (index < count) {
    1108           0 :     aFound = true;
    1109           0 :     nsString varName;
    1110           0 :     if (isServo) {
    1111           0 :       Servo_GetCustomPropertyNameAt(mStyleContext->ComputedValues(),
    1112           0 :                                     index, &varName);
    1113             :     } else {
    1114           0 :       variables->mVariables.GetVariableAt(index, varName);
    1115             :     }
    1116           0 :     aPropName.AssignLiteral("--");
    1117           0 :     aPropName.Append(varName);
    1118             :   } else {
    1119           0 :     aFound = false;
    1120             :   }
    1121             : 
    1122           0 :   ClearCurrentStyleSources();
    1123             : }
    1124             : 
    1125             : // Property getters...
    1126             : 
    1127             : already_AddRefed<CSSValue>
    1128           0 : nsComputedDOMStyle::DoGetBinding()
    1129             : {
    1130           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    1131             : 
    1132           0 :   const nsStyleDisplay* display = StyleDisplay();
    1133             : 
    1134           0 :   if (display->mBinding) {
    1135           0 :     val->SetURI(display->mBinding->GetURI());
    1136             :   } else {
    1137           0 :     val->SetIdent(eCSSKeyword_none);
    1138             :   }
    1139             : 
    1140           0 :   return val.forget();
    1141             : }
    1142             : 
    1143             : already_AddRefed<CSSValue>
    1144           0 : nsComputedDOMStyle::DoGetClear()
    1145             : {
    1146           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    1147           0 :   val->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mBreakType,
    1148           0 :                                                nsCSSProps::kClearKTable));
    1149           0 :   return val.forget();
    1150             : }
    1151             : 
    1152             : already_AddRefed<CSSValue>
    1153           0 : nsComputedDOMStyle::DoGetFloat()
    1154             : {
    1155           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    1156           0 :   val->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mFloat,
    1157           0 :                                                nsCSSProps::kFloatKTable));
    1158           0 :   return val.forget();
    1159             : }
    1160             : 
    1161             : already_AddRefed<CSSValue>
    1162           0 : nsComputedDOMStyle::DoGetBottom()
    1163             : {
    1164           0 :   return GetOffsetWidthFor(eSideBottom);
    1165             : }
    1166             : 
    1167             : already_AddRefed<CSSValue>
    1168           0 : nsComputedDOMStyle::DoGetStackSizing()
    1169             : {
    1170           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    1171           0 :   val->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleXUL()->mStackSizing,
    1172           0 :                                                nsCSSProps::kStackSizingKTable));
    1173           0 :   return val.forget();
    1174             : }
    1175             : 
    1176             : void
    1177           3 : nsComputedDOMStyle::SetToRGBAColor(nsROCSSPrimitiveValue* aValue,
    1178             :                                    nscolor aColor)
    1179             : {
    1180           3 :   nsROCSSPrimitiveValue *red   = new nsROCSSPrimitiveValue;
    1181           3 :   nsROCSSPrimitiveValue *green = new nsROCSSPrimitiveValue;
    1182           3 :   nsROCSSPrimitiveValue *blue  = new nsROCSSPrimitiveValue;
    1183           3 :   nsROCSSPrimitiveValue *alpha  = new nsROCSSPrimitiveValue;
    1184             : 
    1185           3 :   uint8_t a = NS_GET_A(aColor);
    1186             :   nsDOMCSSRGBColor *rgbColor =
    1187           3 :     new nsDOMCSSRGBColor(red, green, blue, alpha, a < 255);
    1188             : 
    1189           3 :   red->SetNumber(NS_GET_R(aColor));
    1190           3 :   green->SetNumber(NS_GET_G(aColor));
    1191           3 :   blue->SetNumber(NS_GET_B(aColor));
    1192           3 :   alpha->SetNumber(nsStyleUtil::ColorComponentToFloat(a));
    1193             : 
    1194           3 :   aValue->SetColor(rgbColor);
    1195           3 : }
    1196             : 
    1197             : void
    1198           0 : nsComputedDOMStyle::SetValueFromComplexColor(nsROCSSPrimitiveValue* aValue,
    1199             :                                              const StyleComplexColor& aColor)
    1200             : {
    1201           0 :   SetToRGBAColor(aValue, StyleColor()->CalcComplexColor(aColor));
    1202           0 : }
    1203             : 
    1204             : already_AddRefed<CSSValue>
    1205           3 : nsComputedDOMStyle::DoGetColor()
    1206             : {
    1207           6 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    1208           3 :   SetToRGBAColor(val, StyleColor()->mColor);
    1209           6 :   return val.forget();
    1210             : }
    1211             : 
    1212             : already_AddRefed<CSSValue>
    1213           0 : nsComputedDOMStyle::DoGetColorAdjust()
    1214             : {
    1215           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    1216           0 :   val->SetIdent(
    1217           0 :     nsCSSProps::ValueToKeywordEnum(StyleVisibility()->mColorAdjust,
    1218           0 :                                    nsCSSProps::kColorAdjustKTable));
    1219           0 :   return val.forget();
    1220             : }
    1221             : 
    1222             : already_AddRefed<CSSValue>
    1223           0 : nsComputedDOMStyle::DoGetOpacity()
    1224             : {
    1225           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    1226           0 :   val->SetNumber(StyleEffects()->mOpacity);
    1227           0 :   return val.forget();
    1228             : }
    1229             : 
    1230             : already_AddRefed<CSSValue>
    1231           0 : nsComputedDOMStyle::DoGetColumnCount()
    1232             : {
    1233           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    1234             : 
    1235           0 :   const nsStyleColumn* column = StyleColumn();
    1236             : 
    1237           0 :   if (column->mColumnCount == NS_STYLE_COLUMN_COUNT_AUTO) {
    1238           0 :     val->SetIdent(eCSSKeyword_auto);
    1239             :   } else {
    1240           0 :     val->SetNumber(column->mColumnCount);
    1241             :   }
    1242             : 
    1243           0 :   return val.forget();
    1244             : }
    1245             : 
    1246             : already_AddRefed<CSSValue>
    1247           0 : nsComputedDOMStyle::DoGetColumnWidth()
    1248             : {
    1249           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    1250             : 
    1251             :   // XXX fix the auto case. When we actually have a column frame, I think
    1252             :   // we should return the computed column width.
    1253           0 :   SetValueToCoord(val, StyleColumn()->mColumnWidth, true);
    1254           0 :   return val.forget();
    1255             : }
    1256             : 
    1257             : already_AddRefed<CSSValue>
    1258           0 : nsComputedDOMStyle::DoGetColumnGap()
    1259             : {
    1260           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    1261             : 
    1262           0 :   const nsStyleColumn* column = StyleColumn();
    1263           0 :   if (column->mColumnGap.GetUnit() == eStyleUnit_Normal) {
    1264           0 :     val->SetAppUnits(StyleFont()->mFont.size);
    1265             :   } else {
    1266           0 :     SetValueToCoord(val, StyleColumn()->mColumnGap, true);
    1267             :   }
    1268             : 
    1269           0 :   return val.forget();
    1270             : }
    1271             : 
    1272             : already_AddRefed<CSSValue>
    1273           0 : nsComputedDOMStyle::DoGetColumnFill()
    1274             : {
    1275           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    1276           0 :   val->SetIdent(
    1277           0 :     nsCSSProps::ValueToKeywordEnum(StyleColumn()->mColumnFill,
    1278           0 :                                    nsCSSProps::kColumnFillKTable));
    1279           0 :   return val.forget();
    1280             : }
    1281             : 
    1282             : already_AddRefed<CSSValue>
    1283           0 : nsComputedDOMStyle::DoGetColumnSpan()
    1284             : {
    1285           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    1286           0 :   val->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleColumn()->mColumnSpan,
    1287           0 :                                                nsCSSProps::kColumnSpanKTable));
    1288           0 :   return val.forget();
    1289             : }
    1290             : 
    1291             : already_AddRefed<CSSValue>
    1292           0 : nsComputedDOMStyle::DoGetColumnRuleWidth()
    1293             : {
    1294           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    1295           0 :   val->SetAppUnits(StyleColumn()->GetComputedColumnRuleWidth());
    1296           0 :   return val.forget();
    1297             : }
    1298             : 
    1299             : already_AddRefed<CSSValue>
    1300           0 : nsComputedDOMStyle::DoGetColumnRuleStyle()
    1301             : {
    1302           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    1303           0 :   val->SetIdent(
    1304           0 :     nsCSSProps::ValueToKeywordEnum(StyleColumn()->mColumnRuleStyle,
    1305           0 :                                    nsCSSProps::kBorderStyleKTable));
    1306           0 :   return val.forget();
    1307             : }
    1308             : 
    1309             : already_AddRefed<CSSValue>
    1310           0 : nsComputedDOMStyle::DoGetColumnRuleColor()
    1311             : {
    1312           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    1313           0 :   SetValueFromComplexColor(val, StyleColumn()->mColumnRuleColor);
    1314           0 :   return val.forget();
    1315             : }
    1316             : 
    1317             : static void
    1318           0 : AppendCounterStyle(CounterStyle* aStyle, nsAString& aString)
    1319             : {
    1320           0 :   AnonymousCounterStyle* anonymous = aStyle->AsAnonymous();
    1321           0 :   if (!anonymous) {
    1322             :     // want SetIdent
    1323           0 :     nsString type;
    1324           0 :     aStyle->GetStyleName(type);
    1325           0 :     nsStyleUtil::AppendEscapedCSSIdent(type, aString);
    1326           0 :   } else if (anonymous->IsSingleString()) {
    1327           0 :     const nsTArray<nsString>& symbols = anonymous->GetSymbols();
    1328           0 :     MOZ_ASSERT(symbols.Length() == 1);
    1329           0 :     nsStyleUtil::AppendEscapedCSSString(symbols[0], aString);
    1330             :   } else {
    1331           0 :     aString.AppendLiteral("symbols(");
    1332             : 
    1333           0 :     uint8_t system = anonymous->GetSystem();
    1334           0 :     NS_ASSERTION(system == NS_STYLE_COUNTER_SYSTEM_CYCLIC ||
    1335             :                  system == NS_STYLE_COUNTER_SYSTEM_NUMERIC ||
    1336             :                  system == NS_STYLE_COUNTER_SYSTEM_ALPHABETIC ||
    1337             :                  system == NS_STYLE_COUNTER_SYSTEM_SYMBOLIC ||
    1338             :                  system == NS_STYLE_COUNTER_SYSTEM_FIXED,
    1339             :                  "Invalid system for anonymous counter style.");
    1340           0 :     if (system != NS_STYLE_COUNTER_SYSTEM_SYMBOLIC) {
    1341           0 :       AppendASCIItoUTF16(nsCSSProps::ValueToKeyword(
    1342           0 :               system, nsCSSProps::kCounterSystemKTable), aString);
    1343           0 :       aString.Append(' ');
    1344             :     }
    1345             : 
    1346           0 :     const nsTArray<nsString>& symbols = anonymous->GetSymbols();
    1347           0 :     NS_ASSERTION(symbols.Length() > 0,
    1348             :                  "No symbols in the anonymous counter style");
    1349           0 :     for (size_t i = 0, iend = symbols.Length(); i < iend; i++) {
    1350           0 :       nsStyleUtil::AppendEscapedCSSString(symbols[i], aString);
    1351           0 :       aString.Append(' ');
    1352             :     }
    1353           0 :     aString.Replace(aString.Length() - 1, 1, char16_t(')'));
    1354             :   }
    1355           0 : }
    1356             : 
    1357             : already_AddRefed<CSSValue>
    1358           0 : nsComputedDOMStyle::DoGetContent()
    1359             : {
    1360           0 :   const nsStyleContent *content = StyleContent();
    1361             : 
    1362           0 :   if (content->ContentCount() == 0) {
    1363           0 :     RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    1364           0 :     val->SetIdent(eCSSKeyword_none);
    1365           0 :     return val.forget();
    1366             :   }
    1367             : 
    1368           0 :   if (content->ContentCount() == 1 &&
    1369           0 :       content->ContentAt(0).GetType() == eStyleContentType_AltContent) {
    1370           0 :     RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    1371           0 :     val->SetIdent(eCSSKeyword__moz_alt_content);
    1372           0 :     return val.forget();
    1373             :   }
    1374             : 
    1375           0 :   RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false);
    1376             : 
    1377           0 :   for (uint32_t i = 0, i_end = content->ContentCount(); i < i_end; ++i) {
    1378           0 :     RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    1379             : 
    1380           0 :     const nsStyleContentData &data = content->ContentAt(i);
    1381           0 :     nsStyleContentType type = data.GetType();
    1382           0 :     switch (type) {
    1383             :       case eStyleContentType_String: {
    1384           0 :         nsAutoString str;
    1385             :         nsStyleUtil::AppendEscapedCSSString(
    1386           0 :           nsDependentString(data.GetString()), str);
    1387           0 :         val->SetString(str);
    1388           0 :         break;
    1389             :       }
    1390             :       case eStyleContentType_Image: {
    1391           0 :         nsCOMPtr<nsIURI> uri;
    1392           0 :         if (imgRequestProxy* image = data.GetImage()) {
    1393           0 :           image->GetURI(getter_AddRefs(uri));
    1394             :         }
    1395           0 :         val->SetURI(uri);
    1396           0 :         break;
    1397             :       }
    1398             :       case eStyleContentType_Attr: {
    1399           0 :         nsAutoString str;
    1400             :         nsStyleUtil::AppendEscapedCSSIdent(
    1401           0 :           nsDependentString(data.GetString()), str);
    1402           0 :         val->SetString(str, nsIDOMCSSPrimitiveValue::CSS_ATTR);
    1403           0 :         break;
    1404             :       }
    1405             :       case eStyleContentType_Counter:
    1406             :       case eStyleContentType_Counters: {
    1407             :         /* FIXME: counters should really use an object */
    1408           0 :         nsAutoString str;
    1409           0 :         if (type == eStyleContentType_Counter) {
    1410           0 :           str.AppendLiteral("counter(");
    1411             :         }
    1412             :         else {
    1413           0 :           str.AppendLiteral("counters(");
    1414             :         }
    1415           0 :         nsStyleContentData::CounterFunction* counters = data.GetCounters();
    1416           0 :         nsStyleUtil::AppendEscapedCSSIdent(counters->mIdent, str);
    1417           0 :         if (type == eStyleContentType_Counters) {
    1418           0 :           str.AppendLiteral(", ");
    1419           0 :           nsStyleUtil::AppendEscapedCSSString(counters->mSeparator, str);
    1420             :         }
    1421           0 :         if (counters->mCounterStyle != CounterStyleManager::GetDecimalStyle()) {
    1422           0 :           str.AppendLiteral(", ");
    1423           0 :           AppendCounterStyle(counters->mCounterStyle, str);
    1424             :         }
    1425             : 
    1426           0 :         str.Append(char16_t(')'));
    1427           0 :         val->SetString(str, nsIDOMCSSPrimitiveValue::CSS_COUNTER);
    1428           0 :         break;
    1429             :       }
    1430             :       case eStyleContentType_OpenQuote:
    1431           0 :         val->SetIdent(eCSSKeyword_open_quote);
    1432           0 :         break;
    1433             :       case eStyleContentType_CloseQuote:
    1434           0 :         val->SetIdent(eCSSKeyword_close_quote);
    1435           0 :         break;
    1436             :       case eStyleContentType_NoOpenQuote:
    1437           0 :         val->SetIdent(eCSSKeyword_no_open_quote);
    1438           0 :         break;
    1439             :       case eStyleContentType_NoCloseQuote:
    1440           0 :         val->SetIdent(eCSSKeyword_no_close_quote);
    1441           0 :         break;
    1442             :       case eStyleContentType_AltContent:
    1443             :       default:
    1444           0 :         NS_NOTREACHED("unexpected type");
    1445           0 :         break;
    1446             :     }
    1447           0 :     valueList->AppendCSSValue(val.forget());
    1448             :   }
    1449             : 
    1450           0 :   return valueList.forget();
    1451             : }
    1452             : 
    1453             : already_AddRefed<CSSValue>
    1454           0 : nsComputedDOMStyle::DoGetCounterIncrement()
    1455             : {
    1456           0 :   const nsStyleContent *content = StyleContent();
    1457             : 
    1458           0 :   if (content->CounterIncrementCount() == 0) {
    1459           0 :     RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    1460           0 :     val->SetIdent(eCSSKeyword_none);
    1461           0 :     return val.forget();
    1462             :   }
    1463             : 
    1464           0 :   RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false);
    1465             : 
    1466           0 :   for (uint32_t i = 0, i_end = content->CounterIncrementCount(); i < i_end; ++i) {
    1467           0 :     RefPtr<nsROCSSPrimitiveValue> name = new nsROCSSPrimitiveValue;
    1468           0 :     RefPtr<nsROCSSPrimitiveValue> value = new nsROCSSPrimitiveValue;
    1469             : 
    1470           0 :     const nsStyleCounterData& data = content->CounterIncrementAt(i);
    1471           0 :     nsAutoString escaped;
    1472           0 :     nsStyleUtil::AppendEscapedCSSIdent(data.mCounter, escaped);
    1473           0 :     name->SetString(escaped);
    1474           0 :     value->SetNumber(data.mValue); // XXX This should really be integer
    1475             : 
    1476           0 :     valueList->AppendCSSValue(name.forget());
    1477           0 :     valueList->AppendCSSValue(value.forget());
    1478             :   }
    1479             : 
    1480           0 :   return valueList.forget();
    1481             : }
    1482             : 
    1483             : /* Convert the stored representation into a list of two values and then hand
    1484             :  * it back.
    1485             :  */
    1486             : already_AddRefed<CSSValue>
    1487           0 : nsComputedDOMStyle::DoGetTransformOrigin()
    1488             : {
    1489             :   /* We need to build up a list of two values.  We'll call them
    1490             :    * width and height.
    1491             :    */
    1492             : 
    1493             :   /* Store things as a value list */
    1494           0 :   RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false);
    1495             : 
    1496             :   /* Now, get the values. */
    1497           0 :   const nsStyleDisplay* display = StyleDisplay();
    1498             : 
    1499           0 :   RefPtr<nsROCSSPrimitiveValue> width = new nsROCSSPrimitiveValue;
    1500           0 :   SetValueToCoord(width, display->mTransformOrigin[0], false,
    1501           0 :                   &nsComputedDOMStyle::GetFrameBoundsWidthForTransform);
    1502           0 :   valueList->AppendCSSValue(width.forget());
    1503             : 
    1504           0 :   RefPtr<nsROCSSPrimitiveValue> height = new nsROCSSPrimitiveValue;
    1505           0 :   SetValueToCoord(height, display->mTransformOrigin[1], false,
    1506           0 :                   &nsComputedDOMStyle::GetFrameBoundsHeightForTransform);
    1507           0 :   valueList->AppendCSSValue(height.forget());
    1508             : 
    1509           0 :   if (display->mTransformOrigin[2].GetUnit() != eStyleUnit_Coord ||
    1510           0 :       display->mTransformOrigin[2].GetCoordValue() != 0) {
    1511           0 :     RefPtr<nsROCSSPrimitiveValue> depth = new nsROCSSPrimitiveValue;
    1512           0 :     SetValueToCoord(depth, display->mTransformOrigin[2], false,
    1513           0 :                     nullptr);
    1514           0 :     valueList->AppendCSSValue(depth.forget());
    1515             :   }
    1516             : 
    1517           0 :   return valueList.forget();
    1518             : }
    1519             : 
    1520             : /* Convert the stored representation into a list of two values and then hand
    1521             :  * it back.
    1522             :  */
    1523             : already_AddRefed<CSSValue>
    1524           0 : nsComputedDOMStyle::DoGetPerspectiveOrigin()
    1525             : {
    1526             :   /* We need to build up a list of two values.  We'll call them
    1527             :    * width and height.
    1528             :    */
    1529             : 
    1530             :   /* Store things as a value list */
    1531           0 :   RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false);
    1532             : 
    1533             :   /* Now, get the values. */
    1534           0 :   const nsStyleDisplay* display = StyleDisplay();
    1535             : 
    1536           0 :   RefPtr<nsROCSSPrimitiveValue> width = new nsROCSSPrimitiveValue;
    1537           0 :   SetValueToCoord(width, display->mPerspectiveOrigin[0], false,
    1538           0 :                   &nsComputedDOMStyle::GetFrameBoundsWidthForTransform);
    1539           0 :   valueList->AppendCSSValue(width.forget());
    1540             : 
    1541           0 :   RefPtr<nsROCSSPrimitiveValue> height = new nsROCSSPrimitiveValue;
    1542           0 :   SetValueToCoord(height, display->mPerspectiveOrigin[1], false,
    1543           0 :                   &nsComputedDOMStyle::GetFrameBoundsHeightForTransform);
    1544           0 :   valueList->AppendCSSValue(height.forget());
    1545             : 
    1546           0 :   return valueList.forget();
    1547             : }
    1548             : 
    1549             : already_AddRefed<CSSValue>
    1550           0 : nsComputedDOMStyle::DoGetPerspective()
    1551             : {
    1552           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    1553           0 :   SetValueToCoord(val, StyleDisplay()->mChildPerspective, false);
    1554           0 :   return val.forget();
    1555             : }
    1556             : 
    1557             : already_AddRefed<CSSValue>
    1558           0 : nsComputedDOMStyle::DoGetBackfaceVisibility()
    1559             : {
    1560           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    1561           0 :   val->SetIdent(
    1562           0 :       nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mBackfaceVisibility,
    1563           0 :                                      nsCSSProps::kBackfaceVisibilityKTable));
    1564           0 :   return val.forget();
    1565             : }
    1566             : 
    1567             : already_AddRefed<CSSValue>
    1568           0 : nsComputedDOMStyle::DoGetTransformStyle()
    1569             : {
    1570           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    1571           0 :   val->SetIdent(
    1572           0 :       nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mTransformStyle,
    1573           0 :                                      nsCSSProps::kTransformStyleKTable));
    1574           0 :   return val.forget();
    1575             : }
    1576             : 
    1577             : already_AddRefed<CSSValue>
    1578           0 : nsComputedDOMStyle::DoGetTransform()
    1579             : {
    1580           0 :   const nsStyleDisplay* display = StyleDisplay();
    1581           0 :   return GetTransformValue(display->mSpecifiedTransform);
    1582             : }
    1583             : 
    1584             : already_AddRefed<CSSValue>
    1585           0 : nsComputedDOMStyle::DoGetTransformBox()
    1586             : {
    1587           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    1588           0 :   val->SetIdent(
    1589           0 :       nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mTransformBox,
    1590           0 :                                      nsCSSProps::kTransformBoxKTable));
    1591           0 :   return val.forget();
    1592             : }
    1593             : 
    1594             : /* static */ already_AddRefed<nsROCSSPrimitiveValue>
    1595           0 : nsComputedDOMStyle::MatrixToCSSValue(const mozilla::gfx::Matrix4x4& matrix)
    1596             : {
    1597           0 :   bool is3D = !matrix.Is2D();
    1598             : 
    1599           0 :   nsAutoString resultString(NS_LITERAL_STRING("matrix"));
    1600           0 :   if (is3D) {
    1601           0 :     resultString.AppendLiteral("3d");
    1602             :   }
    1603             : 
    1604           0 :   resultString.Append('(');
    1605           0 :   resultString.AppendFloat(matrix._11);
    1606           0 :   resultString.AppendLiteral(", ");
    1607           0 :   resultString.AppendFloat(matrix._12);
    1608           0 :   resultString.AppendLiteral(", ");
    1609           0 :   if (is3D) {
    1610           0 :     resultString.AppendFloat(matrix._13);
    1611           0 :     resultString.AppendLiteral(", ");
    1612           0 :     resultString.AppendFloat(matrix._14);
    1613           0 :     resultString.AppendLiteral(", ");
    1614             :   }
    1615           0 :   resultString.AppendFloat(matrix._21);
    1616           0 :   resultString.AppendLiteral(", ");
    1617           0 :   resultString.AppendFloat(matrix._22);
    1618           0 :   resultString.AppendLiteral(", ");
    1619           0 :   if (is3D) {
    1620           0 :     resultString.AppendFloat(matrix._23);
    1621           0 :     resultString.AppendLiteral(", ");
    1622           0 :     resultString.AppendFloat(matrix._24);
    1623           0 :     resultString.AppendLiteral(", ");
    1624           0 :     resultString.AppendFloat(matrix._31);
    1625           0 :     resultString.AppendLiteral(", ");
    1626           0 :     resultString.AppendFloat(matrix._32);
    1627           0 :     resultString.AppendLiteral(", ");
    1628           0 :     resultString.AppendFloat(matrix._33);
    1629           0 :     resultString.AppendLiteral(", ");
    1630           0 :     resultString.AppendFloat(matrix._34);
    1631           0 :     resultString.AppendLiteral(", ");
    1632             :   }
    1633           0 :   resultString.AppendFloat(matrix._41);
    1634           0 :   resultString.AppendLiteral(", ");
    1635           0 :   resultString.AppendFloat(matrix._42);
    1636           0 :   if (is3D) {
    1637           0 :     resultString.AppendLiteral(", ");
    1638           0 :     resultString.AppendFloat(matrix._43);
    1639           0 :     resultString.AppendLiteral(", ");
    1640           0 :     resultString.AppendFloat(matrix._44);
    1641             :   }
    1642           0 :   resultString.Append(')');
    1643             : 
    1644             :   /* Create a value to hold our result. */
    1645           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    1646             : 
    1647           0 :   val->SetString(resultString);
    1648           0 :   return val.forget();
    1649             : }
    1650             : 
    1651             : already_AddRefed<CSSValue>
    1652           0 : nsComputedDOMStyle::DoGetCounterReset()
    1653             : {
    1654           0 :   const nsStyleContent *content = StyleContent();
    1655             : 
    1656           0 :   if (content->CounterResetCount() == 0) {
    1657           0 :     RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    1658           0 :     val->SetIdent(eCSSKeyword_none);
    1659           0 :     return val.forget();
    1660             :   }
    1661             : 
    1662           0 :   RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false);
    1663             : 
    1664           0 :   for (uint32_t i = 0, i_end = content->CounterResetCount(); i < i_end; ++i) {
    1665           0 :     RefPtr<nsROCSSPrimitiveValue> name = new nsROCSSPrimitiveValue;
    1666           0 :     RefPtr<nsROCSSPrimitiveValue> value = new nsROCSSPrimitiveValue;
    1667             : 
    1668           0 :     const nsStyleCounterData& data = content->CounterResetAt(i);
    1669           0 :     nsAutoString escaped;
    1670           0 :     nsStyleUtil::AppendEscapedCSSIdent(data.mCounter, escaped);
    1671           0 :     name->SetString(escaped);
    1672           0 :     value->SetNumber(data.mValue); // XXX This should really be integer
    1673             : 
    1674           0 :     valueList->AppendCSSValue(name.forget());
    1675           0 :     valueList->AppendCSSValue(value.forget());
    1676             :   }
    1677             : 
    1678           0 :   return valueList.forget();
    1679             : }
    1680             : 
    1681             : already_AddRefed<CSSValue>
    1682           0 : nsComputedDOMStyle::DoGetQuotes()
    1683             : {
    1684           0 :   const auto& quotePairs = StyleList()->GetQuotePairs();
    1685             : 
    1686           0 :   if (quotePairs.IsEmpty()) {
    1687           0 :     RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    1688           0 :     val->SetIdent(eCSSKeyword_none);
    1689           0 :     return val.forget();
    1690             :   }
    1691             : 
    1692           0 :   RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false);
    1693             : 
    1694           0 :   for (const auto& quotePair : quotePairs) {
    1695           0 :     RefPtr<nsROCSSPrimitiveValue> openVal = new nsROCSSPrimitiveValue;
    1696           0 :     RefPtr<nsROCSSPrimitiveValue> closeVal = new nsROCSSPrimitiveValue;
    1697             : 
    1698           0 :     nsAutoString s;
    1699           0 :     nsStyleUtil::AppendEscapedCSSString(quotePair.first, s);
    1700           0 :     openVal->SetString(s);
    1701           0 :     s.Truncate();
    1702           0 :     nsStyleUtil::AppendEscapedCSSString(quotePair.second, s);
    1703           0 :     closeVal->SetString(s);
    1704             : 
    1705           0 :     valueList->AppendCSSValue(openVal.forget());
    1706           0 :     valueList->AppendCSSValue(closeVal.forget());
    1707             :   }
    1708             : 
    1709           0 :   return valueList.forget();
    1710             : }
    1711             : 
    1712             : already_AddRefed<CSSValue>
    1713           0 : nsComputedDOMStyle::DoGetFontFamily()
    1714             : {
    1715           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    1716             : 
    1717           0 :   const nsStyleFont* font = StyleFont();
    1718           0 :   nsAutoString fontlistStr;
    1719           0 :   nsStyleUtil::AppendEscapedCSSFontFamilyList(font->mFont.fontlist,
    1720           0 :                                               fontlistStr);
    1721           0 :   val->SetString(fontlistStr);
    1722           0 :   return val.forget();
    1723             : }
    1724             : 
    1725             : already_AddRefed<CSSValue>
    1726           0 : nsComputedDOMStyle::DoGetFontSize()
    1727             : {
    1728           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    1729             : 
    1730             :   // Note: StyleFont()->mSize is the 'computed size';
    1731             :   // StyleFont()->mFont.size is the 'actual size'
    1732           0 :   val->SetAppUnits(StyleFont()->mSize);
    1733           0 :   return val.forget();
    1734             : }
    1735             : 
    1736             : already_AddRefed<CSSValue>
    1737           0 : nsComputedDOMStyle::DoGetFontSizeAdjust()
    1738             : {
    1739           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    1740             : 
    1741           0 :   const nsStyleFont *font = StyleFont();
    1742             : 
    1743           0 :   if (font->mFont.sizeAdjust >= 0.0f) {
    1744           0 :     val->SetNumber(font->mFont.sizeAdjust);
    1745             :   } else {
    1746           0 :     val->SetIdent(eCSSKeyword_none);
    1747             :   }
    1748             : 
    1749           0 :   return val.forget();
    1750             : }
    1751             : 
    1752             : already_AddRefed<CSSValue>
    1753           0 : nsComputedDOMStyle::DoGetOsxFontSmoothing()
    1754             : {
    1755           0 :   if (nsContentUtils::ShouldResistFingerprinting(
    1756           0 :         mPresShell->GetPresContext()->GetDocShell()))
    1757           0 :     return nullptr;
    1758             : 
    1759           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    1760           0 :   val->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleFont()->mFont.smoothing,
    1761           0 :                                                nsCSSProps::kFontSmoothingKTable));
    1762           0 :   return val.forget();
    1763             : }
    1764             : 
    1765             : already_AddRefed<CSSValue>
    1766           0 : nsComputedDOMStyle::DoGetFontStretch()
    1767             : {
    1768           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    1769             : 
    1770           0 :   val->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleFont()->mFont.stretch,
    1771           0 :                                                nsCSSProps::kFontStretchKTable));
    1772             : 
    1773           0 :   return val.forget();
    1774             : }
    1775             : 
    1776             : already_AddRefed<CSSValue>
    1777           0 : nsComputedDOMStyle::DoGetFontStyle()
    1778             : {
    1779           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    1780           0 :   val->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleFont()->mFont.style,
    1781           0 :                                                nsCSSProps::kFontStyleKTable));
    1782           0 :   return val.forget();
    1783             : }
    1784             : 
    1785             : already_AddRefed<CSSValue>
    1786           0 : nsComputedDOMStyle::DoGetFontWeight()
    1787             : {
    1788           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    1789             : 
    1790           0 :   const nsStyleFont* font = StyleFont();
    1791             : 
    1792           0 :   uint16_t weight = font->mFont.weight;
    1793           0 :   NS_ASSERTION(weight % 100 == 0, "unexpected value of font-weight");
    1794           0 :   val->SetNumber(weight);
    1795             : 
    1796           0 :   return val.forget();
    1797             : }
    1798             : 
    1799             : already_AddRefed<CSSValue>
    1800           0 : nsComputedDOMStyle::DoGetFontFeatureSettings()
    1801             : {
    1802           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    1803             : 
    1804           0 :   const nsStyleFont* font = StyleFont();
    1805           0 :   if (font->mFont.fontFeatureSettings.IsEmpty()) {
    1806           0 :     val->SetIdent(eCSSKeyword_normal);
    1807             :   } else {
    1808           0 :     nsAutoString result;
    1809           0 :     nsStyleUtil::AppendFontFeatureSettings(font->mFont.fontFeatureSettings,
    1810           0 :                                            result);
    1811           0 :     val->SetString(result);
    1812             :   }
    1813           0 :   return val.forget();
    1814             : }
    1815             : 
    1816             : already_AddRefed<CSSValue>
    1817           0 : nsComputedDOMStyle::DoGetFontVariationSettings()
    1818             : {
    1819           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    1820             : 
    1821           0 :   const nsStyleFont* font = StyleFont();
    1822           0 :   if (font->mFont.fontVariationSettings.IsEmpty()) {
    1823           0 :     val->SetIdent(eCSSKeyword_normal);
    1824             :   } else {
    1825           0 :     nsAutoString result;
    1826           0 :     nsStyleUtil::AppendFontVariationSettings(font->mFont.fontVariationSettings,
    1827           0 :                                              result);
    1828           0 :     val->SetString(result);
    1829             :   }
    1830           0 :   return val.forget();
    1831             : }
    1832             : 
    1833             : already_AddRefed<CSSValue>
    1834           0 : nsComputedDOMStyle::DoGetFontKerning()
    1835             : {
    1836           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    1837           0 :   val->SetIdent(
    1838           0 :     nsCSSProps::ValueToKeywordEnum(StyleFont()->mFont.kerning,
    1839           0 :                                    nsCSSProps::kFontKerningKTable));
    1840           0 :   return val.forget();
    1841             : }
    1842             : 
    1843             : static void
    1844           0 : SerializeLanguageOverride(uint32_t aLanguageOverride, nsAString& aResult)
    1845             : {
    1846           0 :   aResult.Truncate();
    1847             :   uint32_t i;
    1848           0 :   for (i = 0; i < 4 ; i++) {
    1849           0 :     char16_t ch = aLanguageOverride >> 24;
    1850           0 :     MOZ_ASSERT(nsCRT::IsAscii(ch),
    1851             :                "Invalid tags, we should've handled this during computing!");
    1852           0 :     aResult.Append(ch);
    1853           0 :     aLanguageOverride = aLanguageOverride << 8;
    1854             :   }
    1855             :   // strip trailing whitespaces
    1856           0 :   while (i > 0 && aResult[i - 1] == ' ') {
    1857           0 :     i--;
    1858             :   }
    1859           0 :   aResult.Truncate(i);
    1860           0 : }
    1861             : 
    1862             : already_AddRefed<CSSValue>
    1863           0 : nsComputedDOMStyle::DoGetFontLanguageOverride()
    1864             : {
    1865           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    1866             : 
    1867           0 :   const nsStyleFont* font = StyleFont();
    1868           0 :   if (font->mFont.languageOverride == 0) {
    1869           0 :     val->SetIdent(eCSSKeyword_normal);
    1870             :   } else {
    1871           0 :     nsAutoString serializedStr, escapedStr;
    1872           0 :     SerializeLanguageOverride(font->mFont.languageOverride, serializedStr);
    1873           0 :     nsStyleUtil::AppendEscapedCSSString(serializedStr, escapedStr);
    1874           0 :     val->SetString(escapedStr);
    1875             :   }
    1876           0 :   return val.forget();
    1877             : }
    1878             : 
    1879             : already_AddRefed<CSSValue>
    1880           0 : nsComputedDOMStyle::DoGetFontSynthesis()
    1881             : {
    1882           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    1883             : 
    1884           0 :   int32_t intValue = StyleFont()->mFont.synthesis;
    1885             : 
    1886           0 :   if (0 == intValue) {
    1887           0 :     val->SetIdent(eCSSKeyword_none);
    1888             :   } else {
    1889           0 :     nsAutoString valueStr;
    1890             : 
    1891             :     nsStyleUtil::AppendBitmaskCSSValue(eCSSProperty_font_synthesis,
    1892             :       intValue, NS_FONT_SYNTHESIS_WEIGHT,
    1893           0 :       NS_FONT_SYNTHESIS_STYLE, valueStr);
    1894           0 :     val->SetString(valueStr);
    1895             :   }
    1896             : 
    1897           0 :   return val.forget();
    1898             : }
    1899             : 
    1900             : // return a value *only* for valid longhand values from CSS 2.1, either
    1901             : // normal or small-caps only
    1902             : already_AddRefed<CSSValue>
    1903           0 : nsComputedDOMStyle::DoGetFontVariant()
    1904             : {
    1905           0 :   const nsFont& f = StyleFont()->mFont;
    1906             : 
    1907             :   // if any of the other font-variant subproperties other than
    1908             :   // font-variant-caps are not normal then can't calculate a computed value
    1909           0 :   if (f.variantAlternates || f.variantEastAsian || f.variantLigatures ||
    1910           0 :       f.variantNumeric || f.variantPosition) {
    1911           0 :     return nullptr;
    1912             :   }
    1913             : 
    1914             :   nsCSSKeyword keyword;
    1915           0 :   switch (f.variantCaps) {
    1916             :     case 0:
    1917           0 :       keyword = eCSSKeyword_normal;
    1918           0 :       break;
    1919             :     case NS_FONT_VARIANT_CAPS_SMALLCAPS:
    1920           0 :       keyword = eCSSKeyword_small_caps;
    1921           0 :       break;
    1922             :     default:
    1923           0 :       return nullptr;
    1924             :   }
    1925             : 
    1926           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    1927           0 :   val->SetIdent(keyword);
    1928           0 :   return val.forget();
    1929             : }
    1930             : 
    1931             : already_AddRefed<CSSValue>
    1932           0 : nsComputedDOMStyle::DoGetFontVariantAlternates()
    1933             : {
    1934           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    1935             : 
    1936           0 :   int32_t intValue = StyleFont()->mFont.variantAlternates;
    1937             : 
    1938           0 :   if (0 == intValue) {
    1939           0 :     val->SetIdent(eCSSKeyword_normal);
    1940           0 :     return val.forget();
    1941             :   }
    1942             : 
    1943             :   // first, include enumerated values
    1944           0 :   nsAutoString valueStr;
    1945             : 
    1946           0 :   nsStyleUtil::AppendBitmaskCSSValue(eCSSProperty_font_variant_alternates,
    1947             :     intValue & NS_FONT_VARIANT_ALTERNATES_ENUMERATED_MASK,
    1948             :     NS_FONT_VARIANT_ALTERNATES_HISTORICAL,
    1949           0 :     NS_FONT_VARIANT_ALTERNATES_HISTORICAL, valueStr);
    1950             : 
    1951             :   // next, include functional values if present
    1952           0 :   if (intValue & NS_FONT_VARIANT_ALTERNATES_FUNCTIONAL_MASK) {
    1953           0 :     nsStyleUtil::SerializeFunctionalAlternates(StyleFont()->mFont.alternateValues,
    1954           0 :                                                valueStr);
    1955             :   }
    1956             : 
    1957           0 :   val->SetString(valueStr);
    1958           0 :   return val.forget();
    1959             : }
    1960             : 
    1961             : already_AddRefed<CSSValue>
    1962           0 : nsComputedDOMStyle::DoGetFontVariantCaps()
    1963             : {
    1964           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    1965             : 
    1966           0 :   int32_t intValue = StyleFont()->mFont.variantCaps;
    1967             : 
    1968           0 :   if (0 == intValue) {
    1969           0 :     val->SetIdent(eCSSKeyword_normal);
    1970             :   } else {
    1971           0 :     val->SetIdent(
    1972           0 :       nsCSSProps::ValueToKeywordEnum(intValue,
    1973           0 :                                      nsCSSProps::kFontVariantCapsKTable));
    1974             :   }
    1975             : 
    1976           0 :   return val.forget();
    1977             : }
    1978             : 
    1979             : already_AddRefed<CSSValue>
    1980           0 : nsComputedDOMStyle::DoGetFontVariantEastAsian()
    1981             : {
    1982           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    1983             : 
    1984           0 :   int32_t intValue = StyleFont()->mFont.variantEastAsian;
    1985             : 
    1986           0 :   if (0 == intValue) {
    1987           0 :     val->SetIdent(eCSSKeyword_normal);
    1988             :   } else {
    1989           0 :     nsAutoString valueStr;
    1990             : 
    1991             :     nsStyleUtil::AppendBitmaskCSSValue(eCSSProperty_font_variant_east_asian,
    1992             :       intValue, NS_FONT_VARIANT_EAST_ASIAN_JIS78,
    1993           0 :       NS_FONT_VARIANT_EAST_ASIAN_RUBY, valueStr);
    1994           0 :     val->SetString(valueStr);
    1995             :   }
    1996             : 
    1997           0 :   return val.forget();
    1998             : }
    1999             : 
    2000             : already_AddRefed<CSSValue>
    2001           0 : nsComputedDOMStyle::DoGetFontVariantLigatures()
    2002             : {
    2003           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    2004             : 
    2005           0 :   int32_t intValue = StyleFont()->mFont.variantLigatures;
    2006             : 
    2007           0 :   if (0 == intValue) {
    2008           0 :     val->SetIdent(eCSSKeyword_normal);
    2009           0 :   } else if (NS_FONT_VARIANT_LIGATURES_NONE == intValue) {
    2010           0 :     val->SetIdent(eCSSKeyword_none);
    2011             :   } else {
    2012           0 :     nsAutoString valueStr;
    2013             : 
    2014             :     nsStyleUtil::AppendBitmaskCSSValue(eCSSProperty_font_variant_ligatures,
    2015             :       intValue, NS_FONT_VARIANT_LIGATURES_NONE,
    2016           0 :       NS_FONT_VARIANT_LIGATURES_NO_CONTEXTUAL, valueStr);
    2017           0 :     val->SetString(valueStr);
    2018             :   }
    2019             : 
    2020           0 :   return val.forget();
    2021             : }
    2022             : 
    2023             : already_AddRefed<CSSValue>
    2024           0 : nsComputedDOMStyle::DoGetFontVariantNumeric()
    2025             : {
    2026           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    2027             : 
    2028           0 :   int32_t intValue = StyleFont()->mFont.variantNumeric;
    2029             : 
    2030           0 :   if (0 == intValue) {
    2031           0 :     val->SetIdent(eCSSKeyword_normal);
    2032             :   } else {
    2033           0 :     nsAutoString valueStr;
    2034             : 
    2035             :     nsStyleUtil::AppendBitmaskCSSValue(eCSSProperty_font_variant_numeric,
    2036             :       intValue, NS_FONT_VARIANT_NUMERIC_LINING,
    2037           0 :       NS_FONT_VARIANT_NUMERIC_ORDINAL, valueStr);
    2038           0 :     val->SetString(valueStr);
    2039             :   }
    2040             : 
    2041           0 :   return val.forget();
    2042             : }
    2043             : 
    2044             : already_AddRefed<CSSValue>
    2045           0 : nsComputedDOMStyle::DoGetFontVariantPosition()
    2046             : {
    2047           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    2048             : 
    2049           0 :   int32_t intValue = StyleFont()->mFont.variantPosition;
    2050             : 
    2051           0 :   if (0 == intValue) {
    2052           0 :     val->SetIdent(eCSSKeyword_normal);
    2053             :   } else {
    2054           0 :     val->SetIdent(
    2055           0 :       nsCSSProps::ValueToKeywordEnum(intValue,
    2056           0 :                                      nsCSSProps::kFontVariantPositionKTable));
    2057             :   }
    2058             : 
    2059           0 :   return val.forget();
    2060             : }
    2061             : 
    2062             : already_AddRefed<CSSValue>
    2063           0 : nsComputedDOMStyle::DoGetBackgroundAttachment()
    2064             : {
    2065             :   return GetBackgroundList(&nsStyleImageLayers::Layer::mAttachment,
    2066             :                            &nsStyleImageLayers::mAttachmentCount,
    2067           0 :                            StyleBackground()->mImage,
    2068           0 :                            nsCSSProps::kImageLayerAttachmentKTable);
    2069             : }
    2070             : 
    2071             : already_AddRefed<CSSValue>
    2072           0 : nsComputedDOMStyle::DoGetBackgroundClip()
    2073             : {
    2074             :   return GetBackgroundList(&nsStyleImageLayers::Layer::mClip,
    2075             :                            &nsStyleImageLayers::mClipCount,
    2076           0 :                            StyleBackground()->mImage,
    2077           0 :                            nsCSSProps::kBackgroundClipKTable);
    2078             : }
    2079             : 
    2080             : already_AddRefed<CSSValue>
    2081           0 : nsComputedDOMStyle::DoGetBackgroundColor()
    2082             : {
    2083           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    2084           0 :   SetValueFromComplexColor(val, StyleBackground()->mBackgroundColor);
    2085           0 :   return val.forget();
    2086             : }
    2087             : 
    2088             : static void
    2089           0 : SetValueToCalc(const nsStyleCoord::CalcValue* aCalc,
    2090             :                nsROCSSPrimitiveValue*         aValue)
    2091             : {
    2092           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    2093           0 :   nsAutoString tmp, result;
    2094             : 
    2095           0 :   result.AppendLiteral("calc(");
    2096             : 
    2097           0 :   val->SetAppUnits(aCalc->mLength);
    2098           0 :   val->GetCssText(tmp);
    2099           0 :   result.Append(tmp);
    2100             : 
    2101           0 :   if (aCalc->mHasPercent) {
    2102           0 :     result.AppendLiteral(" + ");
    2103             : 
    2104           0 :     val->SetPercent(aCalc->mPercent);
    2105           0 :     val->GetCssText(tmp);
    2106           0 :     result.Append(tmp);
    2107             :   }
    2108             : 
    2109           0 :   result.Append(')');
    2110             : 
    2111           0 :   aValue->SetString(result); // not really SetString
    2112           0 : }
    2113             : 
    2114             : static void
    2115           0 : AppendCSSGradientLength(const nsStyleCoord&    aValue,
    2116             :                         nsROCSSPrimitiveValue* aPrimitive,
    2117             :                         nsAString&             aString)
    2118             : {
    2119           0 :   nsAutoString tokenString;
    2120           0 :   if (aValue.IsCalcUnit())
    2121           0 :     SetValueToCalc(aValue.GetCalcValue(), aPrimitive);
    2122           0 :   else if (aValue.GetUnit() == eStyleUnit_Coord)
    2123           0 :     aPrimitive->SetAppUnits(aValue.GetCoordValue());
    2124             :   else
    2125           0 :     aPrimitive->SetPercent(aValue.GetPercentValue());
    2126           0 :   aPrimitive->GetCssText(tokenString);
    2127           0 :   aString.Append(tokenString);
    2128           0 : }
    2129             : 
    2130             : static void
    2131           0 : AppendCSSGradientToBoxPosition(const nsStyleGradient* aGradient,
    2132             :                                nsAString&             aString,
    2133             :                                bool&                  aNeedSep)
    2134             : {
    2135             :   // This function only supports box position keywords. Make sure we're not
    2136             :   // calling it with inputs that would have coordinates that aren't
    2137             :   // representable with box-position keywords.
    2138           0 :   MOZ_ASSERT(aGradient->mShape == NS_STYLE_GRADIENT_SHAPE_LINEAR &&
    2139             :              !(aGradient->mLegacySyntax && aGradient->mMozLegacySyntax),
    2140             :              "Only call me for linear-gradient and -webkit-linear-gradient");
    2141             : 
    2142           0 :   float xValue = aGradient->mBgPosX.GetPercentValue();
    2143           0 :   float yValue = aGradient->mBgPosY.GetPercentValue();
    2144             : 
    2145           0 :   if (yValue == 1.0f && xValue == 0.5f) {
    2146             :     // omit "to bottom"
    2147           0 :     return;
    2148             :   }
    2149           0 :   NS_ASSERTION(yValue != 0.5f || xValue != 0.5f, "invalid box position");
    2150             : 
    2151           0 :   if (!aGradient->mLegacySyntax) {
    2152             :     // Modern syntax explicitly includes the word "to". Old syntax does not
    2153             :     // (and is implicitly "from" the given position instead).
    2154           0 :     aString.AppendLiteral("to ");
    2155             :   }
    2156             : 
    2157           0 :   if (xValue == 0.0f) {
    2158           0 :     aString.AppendLiteral("left");
    2159           0 :   } else if (xValue == 1.0f) {
    2160           0 :     aString.AppendLiteral("right");
    2161           0 :   } else if (xValue != 0.5f) { // do not write "center" keyword
    2162           0 :     NS_NOTREACHED("invalid box position");
    2163             :   }
    2164             : 
    2165           0 :   if (xValue != 0.5f && yValue != 0.5f) {
    2166             :     // We're appending both an x-keyword and a y-keyword.
    2167             :     // Add a space between them here.
    2168           0 :     aString.AppendLiteral(" ");
    2169             :   }
    2170             : 
    2171           0 :   if (yValue == 0.0f) {
    2172           0 :     aString.AppendLiteral("top");
    2173           0 :   } else if (yValue == 1.0f) {
    2174           0 :     aString.AppendLiteral("bottom");
    2175           0 :   } else if (yValue != 0.5f) { // do not write "center" keyword
    2176           0 :     NS_NOTREACHED("invalid box position");
    2177             :   }
    2178             : 
    2179             : 
    2180           0 :   aNeedSep = true;
    2181             : }
    2182             : 
    2183             : void
    2184           0 : nsComputedDOMStyle::GetCSSGradientString(const nsStyleGradient* aGradient,
    2185             :                                          nsAString& aString)
    2186             : {
    2187           0 :   if (!aGradient->mLegacySyntax) {
    2188           0 :     aString.Truncate();
    2189             :   } else {
    2190           0 :     if (aGradient->mMozLegacySyntax) {
    2191           0 :       aString.AssignLiteral("-moz-");
    2192             :     } else {
    2193           0 :       aString.AssignLiteral("-webkit-");
    2194             :     }
    2195             :   }
    2196           0 :   if (aGradient->mRepeating) {
    2197           0 :     aString.AppendLiteral("repeating-");
    2198             :   }
    2199           0 :   bool isRadial = aGradient->mShape != NS_STYLE_GRADIENT_SHAPE_LINEAR;
    2200           0 :   if (isRadial) {
    2201           0 :     aString.AppendLiteral("radial-gradient(");
    2202             :   } else {
    2203           0 :     aString.AppendLiteral("linear-gradient(");
    2204             :   }
    2205             : 
    2206           0 :   bool needSep = false;
    2207           0 :   nsAutoString tokenString;
    2208           0 :   RefPtr<nsROCSSPrimitiveValue> tmpVal = new nsROCSSPrimitiveValue;
    2209             : 
    2210           0 :   if (isRadial && !aGradient->mLegacySyntax) {
    2211           0 :     if (aGradient->mSize != NS_STYLE_GRADIENT_SIZE_EXPLICIT_SIZE) {
    2212           0 :       if (aGradient->mShape == NS_STYLE_GRADIENT_SHAPE_CIRCULAR) {
    2213           0 :         aString.AppendLiteral("circle");
    2214           0 :         needSep = true;
    2215             :       }
    2216           0 :       if (aGradient->mSize != NS_STYLE_GRADIENT_SIZE_FARTHEST_CORNER) {
    2217           0 :         if (needSep) {
    2218           0 :           aString.Append(' ');
    2219             :         }
    2220           0 :         AppendASCIItoUTF16(nsCSSProps::
    2221           0 :                            ValueToKeyword(aGradient->mSize,
    2222           0 :                                           nsCSSProps::kRadialGradientSizeKTable),
    2223           0 :                            aString);
    2224           0 :         needSep = true;
    2225             :       }
    2226             :     } else {
    2227           0 :       AppendCSSGradientLength(aGradient->mRadiusX, tmpVal, aString);
    2228           0 :       if (aGradient->mShape != NS_STYLE_GRADIENT_SHAPE_CIRCULAR) {
    2229           0 :         aString.Append(' ');
    2230           0 :         AppendCSSGradientLength(aGradient->mRadiusY, tmpVal, aString);
    2231             :       }
    2232           0 :       needSep = true;
    2233             :     }
    2234             :   }
    2235           0 :   if (aGradient->mBgPosX.GetUnit() != eStyleUnit_None) {
    2236           0 :     MOZ_ASSERT(aGradient->mBgPosY.GetUnit() != eStyleUnit_None);
    2237           0 :     if (!isRadial &&
    2238           0 :         !(aGradient->mLegacySyntax && aGradient->mMozLegacySyntax)) {
    2239             :       // linear-gradient() or -webkit-linear-gradient()
    2240           0 :       AppendCSSGradientToBoxPosition(aGradient, aString, needSep);
    2241           0 :     } else if (aGradient->mBgPosX.GetUnit() != eStyleUnit_Percent ||
    2242           0 :                aGradient->mBgPosX.GetPercentValue() != 0.5f ||
    2243           0 :                aGradient->mBgPosY.GetUnit() != eStyleUnit_Percent ||
    2244           0 :                aGradient->mBgPosY.GetPercentValue() != (isRadial ? 0.5f : 1.0f)) {
    2245           0 :       if (isRadial && !aGradient->mLegacySyntax) {
    2246           0 :         if (needSep) {
    2247           0 :           aString.Append(' ');
    2248             :         }
    2249           0 :         aString.AppendLiteral("at ");
    2250           0 :         needSep = false;
    2251             :       }
    2252           0 :       AppendCSSGradientLength(aGradient->mBgPosX, tmpVal, aString);
    2253           0 :       if (aGradient->mBgPosY.GetUnit() != eStyleUnit_None) {
    2254           0 :         aString.Append(' ');
    2255           0 :         AppendCSSGradientLength(aGradient->mBgPosY, tmpVal, aString);
    2256             :       }
    2257           0 :       needSep = true;
    2258             :     }
    2259             :   }
    2260           0 :   if (aGradient->mAngle.GetUnit() != eStyleUnit_None) {
    2261           0 :     MOZ_ASSERT(!isRadial || aGradient->mLegacySyntax);
    2262           0 :     if (needSep) {
    2263           0 :       aString.Append(' ');
    2264             :     }
    2265           0 :     nsStyleUtil::AppendAngleValue(aGradient->mAngle, aString);
    2266           0 :     needSep = true;
    2267             :   }
    2268             : 
    2269           0 :   if (isRadial && aGradient->mLegacySyntax &&
    2270           0 :       (aGradient->mShape == NS_STYLE_GRADIENT_SHAPE_CIRCULAR ||
    2271           0 :        aGradient->mSize != NS_STYLE_GRADIENT_SIZE_FARTHEST_CORNER)) {
    2272           0 :     MOZ_ASSERT(aGradient->mSize != NS_STYLE_GRADIENT_SIZE_EXPLICIT_SIZE);
    2273           0 :     if (needSep) {
    2274           0 :       aString.AppendLiteral(", ");
    2275           0 :       needSep = false;
    2276             :     }
    2277           0 :     if (aGradient->mShape == NS_STYLE_GRADIENT_SHAPE_CIRCULAR) {
    2278           0 :       aString.AppendLiteral("circle");
    2279           0 :       needSep = true;
    2280             :     }
    2281           0 :     if (aGradient->mSize != NS_STYLE_GRADIENT_SIZE_FARTHEST_CORNER) {
    2282           0 :       if (needSep) {
    2283           0 :         aString.Append(' ');
    2284             :       }
    2285           0 :       AppendASCIItoUTF16(nsCSSProps::
    2286           0 :                          ValueToKeyword(aGradient->mSize,
    2287           0 :                                         nsCSSProps::kRadialGradientSizeKTable),
    2288           0 :                          aString);
    2289             :     }
    2290           0 :     needSep = true;
    2291             :   }
    2292             : 
    2293             : 
    2294             :   // color stops
    2295           0 :   for (uint32_t i = 0; i < aGradient->mStops.Length(); ++i) {
    2296           0 :     if (needSep) {
    2297           0 :       aString.AppendLiteral(", ");
    2298             :     }
    2299             : 
    2300           0 :     const auto& stop = aGradient->mStops[i];
    2301           0 :     if (!stop.mIsInterpolationHint) {
    2302           0 :       SetToRGBAColor(tmpVal, stop.mColor);
    2303           0 :       tmpVal->GetCssText(tokenString);
    2304           0 :       aString.Append(tokenString);
    2305             :     }
    2306             : 
    2307           0 :     if (stop.mLocation.GetUnit() != eStyleUnit_None) {
    2308           0 :       if (!stop.mIsInterpolationHint) {
    2309           0 :         aString.Append(' ');
    2310             :       }
    2311           0 :       AppendCSSGradientLength(stop.mLocation, tmpVal, aString);
    2312             :     }
    2313           0 :     needSep = true;
    2314             :   }
    2315             : 
    2316           0 :   aString.Append(')');
    2317           0 : }
    2318             : 
    2319             : // -moz-image-rect(<uri>, <top>, <right>, <bottom>, <left>)
    2320             : void
    2321           0 : nsComputedDOMStyle::GetImageRectString(nsIURI* aURI,
    2322             :                                        const nsStyleSides& aCropRect,
    2323             :                                        nsString& aString)
    2324             : {
    2325           0 :   RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(true);
    2326             : 
    2327             :   // <uri>
    2328           0 :   RefPtr<nsROCSSPrimitiveValue> valURI = new nsROCSSPrimitiveValue;
    2329           0 :   valURI->SetURI(aURI);
    2330           0 :   valueList->AppendCSSValue(valURI.forget());
    2331             : 
    2332             :   // <top>, <right>, <bottom>, <left>
    2333           0 :   NS_FOR_CSS_SIDES(side) {
    2334           0 :     RefPtr<nsROCSSPrimitiveValue> valSide = new nsROCSSPrimitiveValue;
    2335           0 :     SetValueToCoord(valSide, aCropRect.Get(side), false);
    2336           0 :     valueList->AppendCSSValue(valSide.forget());
    2337             :   }
    2338             : 
    2339           0 :   nsAutoString argumentString;
    2340           0 :   valueList->GetCssText(argumentString);
    2341             : 
    2342           0 :   aString = NS_LITERAL_STRING("-moz-image-rect(") +
    2343           0 :             argumentString +
    2344           0 :             NS_LITERAL_STRING(")");
    2345           0 : }
    2346             : 
    2347             : void
    2348           0 : nsComputedDOMStyle::SetValueToStyleImage(const nsStyleImage& aStyleImage,
    2349             :                                          nsROCSSPrimitiveValue* aValue)
    2350             : {
    2351           0 :   switch (aStyleImage.GetType()) {
    2352             :     case eStyleImageType_Image:
    2353             :     {
    2354           0 :       nsCOMPtr<nsIURI> uri = aStyleImage.GetImageURI();
    2355           0 :       if (!uri) {
    2356           0 :         aValue->SetIdent(eCSSKeyword_none);
    2357           0 :         break;
    2358             :       }
    2359             : 
    2360           0 :       const UniquePtr<nsStyleSides>& cropRect = aStyleImage.GetCropRect();
    2361           0 :       if (cropRect) {
    2362           0 :         nsAutoString imageRectString;
    2363           0 :         GetImageRectString(uri, *cropRect, imageRectString);
    2364           0 :         aValue->SetString(imageRectString);
    2365             :       } else {
    2366           0 :         aValue->SetURI(uri);
    2367             :       }
    2368           0 :       break;
    2369             :     }
    2370             :     case eStyleImageType_Gradient:
    2371             :     {
    2372           0 :       nsAutoString gradientString;
    2373           0 :       GetCSSGradientString(aStyleImage.GetGradientData(),
    2374           0 :                            gradientString);
    2375           0 :       aValue->SetString(gradientString);
    2376           0 :       break;
    2377             :     }
    2378             :     case eStyleImageType_Element:
    2379             :     {
    2380           0 :       nsAutoString elementId;
    2381             :       nsStyleUtil::AppendEscapedCSSIdent(
    2382           0 :         nsDependentAtomString(aStyleImage.GetElementId()),
    2383           0 :                               elementId);
    2384           0 :       nsAutoString elementString = NS_LITERAL_STRING("-moz-element(#") +
    2385           0 :                                    elementId +
    2386           0 :                                    NS_LITERAL_STRING(")");
    2387           0 :       aValue->SetString(elementString);
    2388           0 :       break;
    2389             :     }
    2390             :     case eStyleImageType_Null:
    2391           0 :       aValue->SetIdent(eCSSKeyword_none);
    2392           0 :       break;
    2393             :     case eStyleImageType_URL:
    2394           0 :       SetValueToURLValue(aStyleImage.GetURLValue(), aValue);
    2395           0 :       break;
    2396             :     default:
    2397           0 :       NS_NOTREACHED("unexpected image type");
    2398           0 :       break;
    2399             :   }
    2400           0 : }
    2401             : 
    2402             : already_AddRefed<CSSValue>
    2403           0 : nsComputedDOMStyle::DoGetImageLayerImage(const nsStyleImageLayers& aLayers)
    2404             : {
    2405           0 :   RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(true);
    2406             : 
    2407           0 :   for (uint32_t i = 0, i_end = aLayers.mImageCount; i < i_end; ++i) {
    2408           0 :     RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    2409             : 
    2410           0 :     SetValueToStyleImage(aLayers.mLayers[i].mImage, val);
    2411           0 :     valueList->AppendCSSValue(val.forget());
    2412             :   }
    2413             : 
    2414           0 :   return valueList.forget();
    2415             : }
    2416             : 
    2417             : already_AddRefed<CSSValue>
    2418           0 : nsComputedDOMStyle::DoGetImageLayerPosition(const nsStyleImageLayers& aLayers)
    2419             : {
    2420           0 :   if (aLayers.mPositionXCount != aLayers.mPositionYCount) {
    2421             :     // No value to return.  We can't express this combination of
    2422             :     // values as a shorthand.
    2423           0 :     return nullptr;
    2424             :   }
    2425             : 
    2426           0 :   RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(true);
    2427           0 :   for (uint32_t i = 0, i_end = aLayers.mPositionXCount; i < i_end; ++i) {
    2428           0 :     RefPtr<nsDOMCSSValueList> itemList = GetROCSSValueList(false);
    2429             : 
    2430           0 :     SetValueToPosition(aLayers.mLayers[i].mPosition, itemList);
    2431           0 :     valueList->AppendCSSValue(itemList.forget());
    2432             :   }
    2433             : 
    2434           0 :   return valueList.forget();
    2435             : }
    2436             : 
    2437             : already_AddRefed<CSSValue>
    2438           0 : nsComputedDOMStyle::DoGetImageLayerPositionX(const nsStyleImageLayers& aLayers)
    2439             : {
    2440           0 :   RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(true);
    2441           0 :   for (uint32_t i = 0, i_end = aLayers.mPositionXCount; i < i_end; ++i) {
    2442           0 :     RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    2443           0 :     SetValueToPositionCoord(aLayers.mLayers[i].mPosition.mXPosition, val);
    2444           0 :     valueList->AppendCSSValue(val.forget());
    2445             :   }
    2446             : 
    2447           0 :   return valueList.forget();
    2448             : }
    2449             : 
    2450             : already_AddRefed<CSSValue>
    2451           0 : nsComputedDOMStyle::DoGetImageLayerPositionY(const nsStyleImageLayers& aLayers)
    2452             : {
    2453           0 :   RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(true);
    2454           0 :   for (uint32_t i = 0, i_end = aLayers.mPositionYCount; i < i_end; ++i) {
    2455           0 :     RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    2456           0 :     SetValueToPositionCoord(aLayers.mLayers[i].mPosition.mYPosition, val);
    2457           0 :     valueList->AppendCSSValue(val.forget());
    2458             :   }
    2459             : 
    2460           0 :   return valueList.forget();
    2461             : }
    2462             : 
    2463             : already_AddRefed<CSSValue>
    2464           0 : nsComputedDOMStyle::DoGetImageLayerRepeat(const nsStyleImageLayers& aLayers)
    2465             : {
    2466           0 :   RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(true);
    2467             : 
    2468           0 :   for (uint32_t i = 0, i_end = aLayers.mRepeatCount; i < i_end; ++i) {
    2469           0 :     RefPtr<nsDOMCSSValueList> itemList = GetROCSSValueList(false);
    2470           0 :     RefPtr<nsROCSSPrimitiveValue> valX = new nsROCSSPrimitiveValue;
    2471             : 
    2472           0 :     const StyleImageLayerRepeat xRepeat = aLayers.mLayers[i].mRepeat.mXRepeat;
    2473           0 :     const StyleImageLayerRepeat yRepeat = aLayers.mLayers[i].mRepeat.mYRepeat;
    2474             : 
    2475           0 :     bool hasContraction = true;
    2476             :     unsigned contraction;
    2477           0 :     if (xRepeat == yRepeat) {
    2478           0 :       contraction = uint8_t(xRepeat);
    2479           0 :     } else if (xRepeat == StyleImageLayerRepeat::Repeat &&
    2480             :                yRepeat == StyleImageLayerRepeat::NoRepeat) {
    2481           0 :       contraction = uint8_t(StyleImageLayerRepeat::RepeatX);
    2482           0 :     } else if (xRepeat == StyleImageLayerRepeat::NoRepeat &&
    2483             :                yRepeat == StyleImageLayerRepeat::Repeat) {
    2484           0 :       contraction = uint8_t(StyleImageLayerRepeat::RepeatY);
    2485             :     } else {
    2486           0 :       hasContraction = false;
    2487             :     }
    2488             : 
    2489           0 :     RefPtr<nsROCSSPrimitiveValue> valY;
    2490           0 :     if (hasContraction) {
    2491           0 :       valX->SetIdent(nsCSSProps::ValueToKeywordEnum(contraction,
    2492           0 :                                          nsCSSProps::kImageLayerRepeatKTable));
    2493             :     } else {
    2494           0 :       valY = new nsROCSSPrimitiveValue;
    2495             : 
    2496           0 :       valX->SetIdent(nsCSSProps::ValueToKeywordEnum(xRepeat,
    2497           0 :                                           nsCSSProps::kImageLayerRepeatKTable));
    2498           0 :       valY->SetIdent(nsCSSProps::ValueToKeywordEnum(yRepeat,
    2499           0 :                                           nsCSSProps::kImageLayerRepeatKTable));
    2500             :     }
    2501           0 :     itemList->AppendCSSValue(valX.forget());
    2502           0 :     if (valY) {
    2503           0 :       itemList->AppendCSSValue(valY.forget());
    2504             :     }
    2505           0 :     valueList->AppendCSSValue(itemList.forget());
    2506             :   }
    2507             : 
    2508           0 :   return valueList.forget();
    2509             : }
    2510             : 
    2511             : already_AddRefed<CSSValue>
    2512           0 : nsComputedDOMStyle::DoGetImageLayerSize(const nsStyleImageLayers& aLayers)
    2513             : {
    2514           0 :   RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(true);
    2515             : 
    2516           0 :   for (uint32_t i = 0, i_end = aLayers.mSizeCount; i < i_end; ++i) {
    2517           0 :     const nsStyleImageLayers::Size &size = aLayers.mLayers[i].mSize;
    2518             : 
    2519           0 :     switch (size.mWidthType) {
    2520             :       case nsStyleImageLayers::Size::eContain:
    2521             :       case nsStyleImageLayers::Size::eCover: {
    2522           0 :         MOZ_ASSERT(size.mWidthType == size.mHeightType,
    2523             :                    "unsynced types");
    2524           0 :         nsCSSKeyword keyword = size.mWidthType == nsStyleImageLayers::Size::eContain
    2525           0 :                              ? eCSSKeyword_contain
    2526           0 :                              : eCSSKeyword_cover;
    2527           0 :         RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    2528           0 :         val->SetIdent(keyword);
    2529           0 :         valueList->AppendCSSValue(val.forget());
    2530           0 :         break;
    2531             :       }
    2532             :       default: {
    2533           0 :         RefPtr<nsDOMCSSValueList> itemList = GetROCSSValueList(false);
    2534             : 
    2535           0 :         RefPtr<nsROCSSPrimitiveValue> valX = new nsROCSSPrimitiveValue;
    2536           0 :         RefPtr<nsROCSSPrimitiveValue> valY = new nsROCSSPrimitiveValue;
    2537             : 
    2538           0 :         if (size.mWidthType == nsStyleImageLayers::Size::eAuto) {
    2539           0 :           valX->SetIdent(eCSSKeyword_auto);
    2540             :         } else {
    2541           0 :           MOZ_ASSERT(size.mWidthType ==
    2542             :                        nsStyleImageLayers::Size::eLengthPercentage,
    2543             :                      "bad mWidthType");
    2544           0 :           if (!size.mWidth.mHasPercent &&
    2545             :               // negative values must have come from calc()
    2546           0 :               size.mWidth.mLength >= 0) {
    2547           0 :             MOZ_ASSERT(size.mWidth.mPercent == 0.0f,
    2548             :                        "Shouldn't have mPercent");
    2549           0 :             valX->SetAppUnits(size.mWidth.mLength);
    2550           0 :           } else if (size.mWidth.mLength == 0 &&
    2551             :                      // negative values must have come from calc()
    2552           0 :                      size.mWidth.mPercent >= 0.0f) {
    2553           0 :             valX->SetPercent(size.mWidth.mPercent);
    2554             :           } else {
    2555           0 :             SetValueToCalc(&size.mWidth, valX);
    2556             :           }
    2557             :         }
    2558             : 
    2559           0 :         if (size.mHeightType == nsStyleImageLayers::Size::eAuto) {
    2560           0 :           valY->SetIdent(eCSSKeyword_auto);
    2561             :         } else {
    2562           0 :           MOZ_ASSERT(size.mHeightType ==
    2563             :                        nsStyleImageLayers::Size::eLengthPercentage,
    2564             :                      "bad mHeightType");
    2565           0 :           if (!size.mHeight.mHasPercent &&
    2566             :               // negative values must have come from calc()
    2567           0 :               size.mHeight.mLength >= 0) {
    2568           0 :             MOZ_ASSERT(size.mHeight.mPercent == 0.0f,
    2569             :                        "Shouldn't have mPercent");
    2570           0 :             valY->SetAppUnits(size.mHeight.mLength);
    2571           0 :           } else if (size.mHeight.mLength == 0 &&
    2572             :                      // negative values must have come from calc()
    2573           0 :                      size.mHeight.mPercent >= 0.0f) {
    2574           0 :             valY->SetPercent(size.mHeight.mPercent);
    2575             :           } else {
    2576           0 :             SetValueToCalc(&size.mHeight, valY);
    2577             :           }
    2578             :         }
    2579           0 :         itemList->AppendCSSValue(valX.forget());
    2580           0 :         itemList->AppendCSSValue(valY.forget());
    2581           0 :         valueList->AppendCSSValue(itemList.forget());
    2582           0 :         break;
    2583             :       }
    2584             :     }
    2585             :   }
    2586             : 
    2587           0 :   return valueList.forget();
    2588             : }
    2589             : 
    2590             : already_AddRefed<CSSValue>
    2591           0 : nsComputedDOMStyle::DoGetBackgroundImage()
    2592             : {
    2593           0 :   const nsStyleImageLayers& layers = StyleBackground()->mImage;
    2594           0 :   return DoGetImageLayerImage(layers);
    2595             : }
    2596             : 
    2597             : already_AddRefed<CSSValue>
    2598           0 : nsComputedDOMStyle::DoGetBackgroundBlendMode()
    2599             : {
    2600             :   return GetBackgroundList(&nsStyleImageLayers::Layer::mBlendMode,
    2601             :                            &nsStyleImageLayers::mBlendModeCount,
    2602           0 :                            StyleBackground()->mImage,
    2603           0 :                            nsCSSProps::kBlendModeKTable);
    2604             : }
    2605             : 
    2606             : already_AddRefed<CSSValue>
    2607           0 : nsComputedDOMStyle::DoGetBackgroundOrigin()
    2608             : {
    2609             :   return GetBackgroundList(&nsStyleImageLayers::Layer::mOrigin,
    2610             :                            &nsStyleImageLayers::mOriginCount,
    2611           0 :                            StyleBackground()->mImage,
    2612           0 :                            nsCSSProps::kBackgroundOriginKTable);
    2613             : }
    2614             : 
    2615             : void
    2616           0 : nsComputedDOMStyle::SetValueToPositionCoord(
    2617             :     const Position::Coord& aCoord,
    2618             :     nsROCSSPrimitiveValue* aValue)
    2619             : {
    2620           0 :   if (!aCoord.mHasPercent) {
    2621           0 :     MOZ_ASSERT(aCoord.mPercent == 0.0f,
    2622             :                "Shouldn't have mPercent!");
    2623           0 :     aValue->SetAppUnits(aCoord.mLength);
    2624           0 :   } else if (aCoord.mLength == 0) {
    2625           0 :     aValue->SetPercent(aCoord.mPercent);
    2626             :   } else {
    2627           0 :     SetValueToCalc(&aCoord, aValue);
    2628             :   }
    2629           0 : }
    2630             : 
    2631             : void
    2632           0 : nsComputedDOMStyle::SetValueToPosition(
    2633             :     const Position& aPosition,
    2634             :     nsDOMCSSValueList* aValueList)
    2635             : {
    2636           0 :   RefPtr<nsROCSSPrimitiveValue> valX = new nsROCSSPrimitiveValue;
    2637           0 :   SetValueToPositionCoord(aPosition.mXPosition, valX);
    2638           0 :   aValueList->AppendCSSValue(valX.forget());
    2639             : 
    2640           0 :   RefPtr<nsROCSSPrimitiveValue> valY = new nsROCSSPrimitiveValue;
    2641           0 :   SetValueToPositionCoord(aPosition.mYPosition, valY);
    2642           0 :   aValueList->AppendCSSValue(valY.forget());
    2643           0 : }
    2644             : 
    2645             : 
    2646             : void
    2647           0 : nsComputedDOMStyle::SetValueToURLValue(const css::URLValueData* aURL,
    2648             :                                        nsROCSSPrimitiveValue* aValue)
    2649             : {
    2650           0 :   if (!aURL) {
    2651           0 :     aValue->SetIdent(eCSSKeyword_none);
    2652           0 :     return;
    2653             :   }
    2654             : 
    2655             :   // If we have a usable nsIURI in the URLValueData, and the url() wasn't
    2656             :   // a fragment-only URL, serialize the nsIURI.
    2657           0 :   if (!aURL->IsLocalRef()) {
    2658           0 :     if (nsIURI* uri = aURL->GetURI()) {
    2659           0 :       aValue->SetURI(uri);
    2660           0 :       return;
    2661             :     }
    2662             :   }
    2663             : 
    2664             :   // Otherwise, serialize the specified URL value.
    2665           0 :   nsAutoString source;
    2666           0 :   aURL->GetSourceString(source);
    2667             : 
    2668           0 :   nsAutoString url;
    2669           0 :   url.AppendLiteral(u"url(");
    2670           0 :   nsStyleUtil::AppendEscapedCSSString(source, url, '"');
    2671           0 :   url.Append(')');
    2672           0 :   aValue->SetString(url);
    2673             : }
    2674             : 
    2675             : already_AddRefed<CSSValue>
    2676           0 : nsComputedDOMStyle::DoGetBackgroundPosition()
    2677             : {
    2678           0 :   const nsStyleImageLayers& layers = StyleBackground()->mImage;
    2679           0 :   return DoGetImageLayerPosition(layers);
    2680             : }
    2681             : 
    2682             : already_AddRefed<CSSValue>
    2683           0 : nsComputedDOMStyle::DoGetBackgroundPositionX()
    2684             : {
    2685           0 :   const nsStyleImageLayers& layers = StyleBackground()->mImage;
    2686           0 :   return DoGetImageLayerPositionX(layers);
    2687             : }
    2688             : 
    2689             : already_AddRefed<CSSValue>
    2690           0 : nsComputedDOMStyle::DoGetBackgroundPositionY()
    2691             : {
    2692           0 :   const nsStyleImageLayers& layers = StyleBackground()->mImage;
    2693           0 :   return DoGetImageLayerPositionY(layers);
    2694             : }
    2695             : 
    2696             : already_AddRefed<CSSValue>
    2697           0 : nsComputedDOMStyle::DoGetBackgroundRepeat()
    2698             : {
    2699           0 :   const nsStyleImageLayers& layers = StyleBackground()->mImage;
    2700           0 :   return DoGetImageLayerRepeat(layers);
    2701             : }
    2702             : 
    2703             : already_AddRefed<CSSValue>
    2704           0 : nsComputedDOMStyle::DoGetBackgroundSize()
    2705             : {
    2706           0 :   const nsStyleImageLayers& layers = StyleBackground()->mImage;
    2707           0 :   return DoGetImageLayerSize(layers);
    2708             : }
    2709             : 
    2710             : already_AddRefed<CSSValue>
    2711           0 : nsComputedDOMStyle::DoGetGridTemplateAreas()
    2712             : {
    2713             :   const css::GridTemplateAreasValue* areas =
    2714           0 :     StylePosition()->mGridTemplateAreas;
    2715           0 :   if (!areas) {
    2716           0 :     RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    2717           0 :     val->SetIdent(eCSSKeyword_none);
    2718           0 :     return val.forget();
    2719             :   }
    2720             : 
    2721           0 :   MOZ_ASSERT(!areas->mTemplates.IsEmpty(),
    2722             :              "Unexpected empty array in GridTemplateAreasValue");
    2723           0 :   RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false);
    2724           0 :   for (uint32_t i = 0; i < areas->mTemplates.Length(); i++) {
    2725           0 :     nsAutoString str;
    2726           0 :     nsStyleUtil::AppendEscapedCSSString(areas->mTemplates[i], str);
    2727           0 :     RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    2728           0 :     val->SetString(str);
    2729           0 :     valueList->AppendCSSValue(val.forget());
    2730             :   }
    2731           0 :   return valueList.forget();
    2732             : }
    2733             : 
    2734             : void
    2735           0 : nsComputedDOMStyle::AppendGridLineNames(nsString& aResult,
    2736             :                                         const nsTArray<nsString>& aLineNames)
    2737             : {
    2738           0 :   uint32_t numLines = aLineNames.Length();
    2739           0 :   if (numLines == 0) {
    2740           0 :     return;
    2741             :   }
    2742           0 :   for (uint32_t i = 0;;) {
    2743           0 :     nsStyleUtil::AppendEscapedCSSIdent(aLineNames[i], aResult);
    2744           0 :     if (++i == numLines) {
    2745           0 :       break;
    2746             :     }
    2747           0 :     aResult.Append(' ');
    2748             :   }
    2749             : }
    2750             : 
    2751             : void
    2752           0 : nsComputedDOMStyle::AppendGridLineNames(nsDOMCSSValueList* aValueList,
    2753             :                                         const nsTArray<nsString>& aLineNames,
    2754             :                                         bool aSuppressEmptyList)
    2755             : {
    2756           0 :   if (aLineNames.IsEmpty() && aSuppressEmptyList) {
    2757           0 :     return;
    2758             :   }
    2759           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    2760           0 :   nsAutoString lineNamesString;
    2761           0 :   lineNamesString.Assign('[');
    2762           0 :   AppendGridLineNames(lineNamesString, aLineNames);
    2763           0 :   lineNamesString.Append(']');
    2764           0 :   val->SetString(lineNamesString);
    2765           0 :   aValueList->AppendCSSValue(val.forget());
    2766             : }
    2767             : 
    2768             : void
    2769           0 : nsComputedDOMStyle::AppendGridLineNames(nsDOMCSSValueList* aValueList,
    2770             :                                         const nsTArray<nsString>& aLineNames1,
    2771             :                                         const nsTArray<nsString>& aLineNames2)
    2772             : {
    2773           0 :   if (aLineNames1.IsEmpty() && aLineNames2.IsEmpty()) {
    2774           0 :     return;
    2775             :   }
    2776           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    2777           0 :   nsAutoString lineNamesString;
    2778           0 :   lineNamesString.Assign('[');
    2779           0 :   if (!aLineNames1.IsEmpty()) {
    2780           0 :     AppendGridLineNames(lineNamesString, aLineNames1);
    2781             :   }
    2782           0 :   if (!aLineNames2.IsEmpty()) {
    2783           0 :     if (!aLineNames1.IsEmpty()) {
    2784           0 :       lineNamesString.Append(' ');
    2785             :     }
    2786           0 :     AppendGridLineNames(lineNamesString, aLineNames2);
    2787             :   }
    2788           0 :   lineNamesString.Append(']');
    2789           0 :   val->SetString(lineNamesString);
    2790           0 :   aValueList->AppendCSSValue(val.forget());
    2791             : }
    2792             : 
    2793             : already_AddRefed<CSSValue>
    2794           0 : nsComputedDOMStyle::GetGridTrackSize(const nsStyleCoord& aMinValue,
    2795             :                                      const nsStyleCoord& aMaxValue)
    2796             : {
    2797           0 :   if (aMinValue.GetUnit() == eStyleUnit_None) {
    2798             :     // A fit-content() function.
    2799           0 :     RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    2800           0 :     nsAutoString argumentStr, fitContentStr;
    2801           0 :     fitContentStr.AppendLiteral("fit-content(");
    2802           0 :     MOZ_ASSERT(aMaxValue.IsCoordPercentCalcUnit(),
    2803             :                "unexpected unit for fit-content() argument value");
    2804           0 :     SetValueToCoord(val, aMaxValue, true);
    2805           0 :     val->GetCssText(argumentStr);
    2806           0 :     fitContentStr.Append(argumentStr);
    2807           0 :     fitContentStr.Append(char16_t(')'));
    2808           0 :     val->SetString(fitContentStr);
    2809           0 :     return val.forget();
    2810             :   }
    2811             : 
    2812           0 :   if (aMinValue == aMaxValue) {
    2813           0 :     RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    2814           0 :     SetValueToCoord(val, aMinValue, true,
    2815           0 :                     nullptr, nsCSSProps::kGridTrackBreadthKTable);
    2816           0 :     return val.forget();
    2817             :   }
    2818             : 
    2819             :   // minmax(auto, <flex>) is equivalent to (and is our internal representation
    2820             :   // of) <flex>, and both compute to <flex>
    2821           0 :   if (aMinValue.GetUnit() == eStyleUnit_Auto &&
    2822           0 :       aMaxValue.GetUnit() == eStyleUnit_FlexFraction) {
    2823           0 :     RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    2824           0 :     SetValueToCoord(val, aMaxValue, true);
    2825           0 :     return val.forget();
    2826             :   }
    2827             : 
    2828           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    2829           0 :   nsAutoString argumentStr, minmaxStr;
    2830           0 :   minmaxStr.AppendLiteral("minmax(");
    2831             : 
    2832           0 :   SetValueToCoord(val, aMinValue, true,
    2833           0 :                   nullptr, nsCSSProps::kGridTrackBreadthKTable);
    2834           0 :   val->GetCssText(argumentStr);
    2835           0 :   minmaxStr.Append(argumentStr);
    2836             : 
    2837           0 :   minmaxStr.AppendLiteral(", ");
    2838             : 
    2839           0 :   SetValueToCoord(val, aMaxValue, true,
    2840           0 :                   nullptr, nsCSSProps::kGridTrackBreadthKTable);
    2841           0 :   val->GetCssText(argumentStr);
    2842           0 :   minmaxStr.Append(argumentStr);
    2843             : 
    2844           0 :   minmaxStr.Append(char16_t(')'));
    2845           0 :   val->SetString(minmaxStr);
    2846           0 :   return val.forget();
    2847             : }
    2848             : 
    2849             : already_AddRefed<CSSValue>
    2850           0 : nsComputedDOMStyle::GetGridTemplateColumnsRows(
    2851             :   const nsStyleGridTemplate&   aTrackList,
    2852             :   const ComputedGridTrackInfo* aTrackInfo)
    2853             : {
    2854           0 :   if (aTrackList.mIsSubgrid) {
    2855             :     // XXX TODO: add support for repeat(auto-fill) for 'subgrid' (bug 1234311)
    2856           0 :     NS_ASSERTION(aTrackList.mMinTrackSizingFunctions.IsEmpty() &&
    2857             :                  aTrackList.mMaxTrackSizingFunctions.IsEmpty(),
    2858             :                  "Unexpected sizing functions with subgrid");
    2859           0 :     RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false);
    2860             : 
    2861           0 :     RefPtr<nsROCSSPrimitiveValue> subgridKeyword = new nsROCSSPrimitiveValue;
    2862           0 :     subgridKeyword->SetIdent(eCSSKeyword_subgrid);
    2863           0 :     valueList->AppendCSSValue(subgridKeyword.forget());
    2864             : 
    2865           0 :     for (uint32_t i = 0, len = aTrackList.mLineNameLists.Length(); ; ++i) {
    2866           0 :       if (MOZ_UNLIKELY(aTrackList.IsRepeatAutoIndex(i))) {
    2867           0 :         MOZ_ASSERT(aTrackList.mIsAutoFill, "subgrid can only have 'auto-fill'");
    2868           0 :         MOZ_ASSERT(aTrackList.mRepeatAutoLineNameListAfter.IsEmpty(),
    2869             :                    "mRepeatAutoLineNameListAfter isn't used for subgrid");
    2870           0 :         RefPtr<nsROCSSPrimitiveValue> start = new nsROCSSPrimitiveValue;
    2871           0 :         start->SetString(NS_LITERAL_STRING("repeat(auto-fill,"));
    2872           0 :         valueList->AppendCSSValue(start.forget());
    2873           0 :         AppendGridLineNames(valueList, aTrackList.mRepeatAutoLineNameListBefore,
    2874           0 :                             /*aSuppressEmptyList*/ false);
    2875           0 :         RefPtr<nsROCSSPrimitiveValue> end = new nsROCSSPrimitiveValue;
    2876           0 :         end->SetString(NS_LITERAL_STRING(")"));
    2877           0 :         valueList->AppendCSSValue(end.forget());
    2878             :       }
    2879           0 :       if (i == len) {
    2880           0 :         break;
    2881             :       }
    2882           0 :       AppendGridLineNames(valueList, aTrackList.mLineNameLists[i],
    2883           0 :                           /*aSuppressEmptyList*/ false);
    2884           0 :     }
    2885           0 :     return valueList.forget();
    2886             :   }
    2887             : 
    2888           0 :   uint32_t numSizes = aTrackList.mMinTrackSizingFunctions.Length();
    2889           0 :   MOZ_ASSERT(aTrackList.mMaxTrackSizingFunctions.Length() == numSizes,
    2890             :              "Different number of min and max track sizing functions");
    2891           0 :   if (aTrackInfo) {
    2892             :     DebugOnly<bool> isAutoFill =
    2893           0 :       aTrackList.HasRepeatAuto() && aTrackList.mIsAutoFill;
    2894             :     DebugOnly<bool> isAutoFit =
    2895           0 :       aTrackList.HasRepeatAuto() && !aTrackList.mIsAutoFill;
    2896           0 :     DebugOnly<uint32_t> numExplicitTracks = aTrackInfo->mNumExplicitTracks;
    2897           0 :     MOZ_ASSERT(numExplicitTracks == numSizes ||
    2898             :                (isAutoFill && numExplicitTracks >= numSizes) ||
    2899             :                (isAutoFit && numExplicitTracks + 1 >= numSizes),
    2900             :                "expected all explicit tracks (or possibly one less, if there's "
    2901             :                "an 'auto-fit' track, since that can collapse away)");
    2902           0 :     numSizes = aTrackInfo->mSizes.Length();
    2903             :   }
    2904             : 
    2905             :   // An empty <track-list> without repeats is represented as "none" in syntax.
    2906           0 :   if (numSizes == 0 && !aTrackList.HasRepeatAuto()) {
    2907           0 :     RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    2908           0 :     val->SetIdent(eCSSKeyword_none);
    2909           0 :     return val.forget();
    2910             :   }
    2911             : 
    2912           0 :   RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false);
    2913           0 :   if (aTrackInfo) {
    2914             :     // We've done layout on the grid and have resolved the sizes of its tracks,
    2915             :     // so we'll return those sizes here.  The grid spec says we MAY use
    2916             :     // repeat(<positive-integer>, Npx) here for consecutive tracks with the same
    2917             :     // size, but that doesn't seem worth doing since even for repeat(auto-*)
    2918             :     // the resolved size might differ for the repeated tracks.
    2919           0 :     const nsTArray<nscoord>& trackSizes = aTrackInfo->mSizes;
    2920           0 :     const uint32_t numExplicitTracks = aTrackInfo->mNumExplicitTracks;
    2921           0 :     const uint32_t numLeadingImplicitTracks = aTrackInfo->mNumLeadingImplicitTracks;
    2922           0 :     MOZ_ASSERT(numSizes >= numLeadingImplicitTracks + numExplicitTracks);
    2923             : 
    2924             :     // Add any leading implicit tracks.
    2925           0 :     for (uint32_t i = 0; i < numLeadingImplicitTracks; ++i) {
    2926           0 :       RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    2927           0 :       val->SetAppUnits(trackSizes[i]);
    2928           0 :       valueList->AppendCSSValue(val.forget());
    2929             :     }
    2930             : 
    2931             :     // Then add any explicit tracks and removed auto-fit tracks.
    2932           0 :     if (numExplicitTracks || aTrackList.HasRepeatAuto()) {
    2933           0 :       int32_t endOfRepeat = 0;  // first index after any repeat() tracks
    2934           0 :       int32_t offsetToLastRepeat = 0;
    2935           0 :       if (aTrackList.HasRepeatAuto()) {
    2936             :         // offsetToLastRepeat is -1 if all repeat(auto-fit) tracks are empty
    2937           0 :         offsetToLastRepeat = numExplicitTracks + 1 - aTrackList.mLineNameLists.Length();
    2938           0 :         endOfRepeat = aTrackList.mRepeatAutoIndex + offsetToLastRepeat + 1;
    2939             :       }
    2940             : 
    2941           0 :       uint32_t repeatIndex = 0;
    2942           0 :       uint32_t numRepeatTracks = aTrackInfo->mRemovedRepeatTracks.Length();
    2943             :       enum LinePlacement { LinesPrecede, LinesFollow, LinesBetween };
    2944             :       auto AppendRemovedAutoFits = [this, aTrackInfo, &valueList, aTrackList,
    2945             :                                     &repeatIndex,
    2946           0 :                                     numRepeatTracks](LinePlacement aPlacement)
    2947           0 :       {
    2948             :         // Add in removed auto-fit tracks and lines here, if necessary
    2949           0 :         bool atLeastOneTrackReported = false;
    2950           0 :         while (repeatIndex < numRepeatTracks &&
    2951           0 :              aTrackInfo->mRemovedRepeatTracks[repeatIndex]) {
    2952           0 :           if ((aPlacement == LinesPrecede) ||
    2953           0 :               ((aPlacement == LinesBetween) && atLeastOneTrackReported)) {
    2954             :             // Precede it with the lines between repeats.
    2955           0 :             AppendGridLineNames(valueList,
    2956             :                                 aTrackList.mRepeatAutoLineNameListAfter,
    2957           0 :                                 aTrackList.mRepeatAutoLineNameListBefore);
    2958             :           }
    2959             : 
    2960             :           // Removed 'auto-fit' tracks are reported as 0px.
    2961           0 :           RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    2962           0 :           val->SetAppUnits(0);
    2963           0 :           valueList->AppendCSSValue(val.forget());
    2964           0 :           atLeastOneTrackReported = true;
    2965             : 
    2966           0 :           if (aPlacement == LinesFollow) {
    2967             :             // Follow it with the lines between repeats.
    2968           0 :             AppendGridLineNames(valueList,
    2969             :                                 aTrackList.mRepeatAutoLineNameListAfter,
    2970           0 :                                 aTrackList.mRepeatAutoLineNameListBefore);
    2971             :           }
    2972           0 :           repeatIndex++;
    2973             :         }
    2974           0 :         repeatIndex++;
    2975           0 :       };
    2976             : 
    2977           0 :       for (int32_t i = 0;; i++) {
    2978           0 :         if (aTrackList.HasRepeatAuto()) {
    2979           0 :           if (i == aTrackList.mRepeatAutoIndex) {
    2980           0 :             const nsTArray<nsString>& lineNames = aTrackList.mLineNameLists[i];
    2981           0 :             if (i == endOfRepeat) {
    2982             :               // All auto-fit tracks are empty, but we report them anyway.
    2983           0 :               AppendGridLineNames(valueList, lineNames,
    2984           0 :                                   aTrackList.mRepeatAutoLineNameListBefore);
    2985             : 
    2986           0 :               AppendRemovedAutoFits(LinesBetween);
    2987             : 
    2988           0 :               AppendGridLineNames(valueList,
    2989             :                                   aTrackList.mRepeatAutoLineNameListAfter,
    2990           0 :                                   aTrackList.mLineNameLists[i + 1]);
    2991             :             } else {
    2992           0 :               AppendGridLineNames(valueList, lineNames,
    2993           0 :                                   aTrackList.mRepeatAutoLineNameListBefore);
    2994           0 :               AppendRemovedAutoFits(LinesFollow);
    2995             :             }
    2996           0 :           } else if (i == endOfRepeat) {
    2997             :             // Before appending the last line, finish off any removed auto-fits.
    2998           0 :             AppendRemovedAutoFits(LinesPrecede);
    2999             : 
    3000             :             const nsTArray<nsString>& lineNames =
    3001           0 :               aTrackList.mLineNameLists[aTrackList.mRepeatAutoIndex + 1];
    3002           0 :             AppendGridLineNames(valueList,
    3003             :                                 aTrackList.mRepeatAutoLineNameListAfter,
    3004           0 :                                 lineNames);
    3005           0 :           } else if (i > aTrackList.mRepeatAutoIndex && i < endOfRepeat) {
    3006           0 :             AppendGridLineNames(valueList,
    3007             :                                 aTrackList.mRepeatAutoLineNameListAfter,
    3008           0 :                                 aTrackList.mRepeatAutoLineNameListBefore);
    3009           0 :             AppendRemovedAutoFits(LinesFollow);
    3010             :           } else {
    3011           0 :             uint32_t j = i > endOfRepeat ? i - offsetToLastRepeat : i;
    3012           0 :             const nsTArray<nsString>& lineNames = aTrackList.mLineNameLists[j];
    3013           0 :             AppendGridLineNames(valueList, lineNames);
    3014             :           }
    3015             :         } else {
    3016           0 :           const nsTArray<nsString>& lineNames = aTrackList.mLineNameLists[i];
    3017           0 :           AppendGridLineNames(valueList, lineNames);
    3018             :         }
    3019           0 :         if (uint32_t(i) == numExplicitTracks) {
    3020           0 :           break;
    3021             :         }
    3022           0 :         RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    3023           0 :         val->SetAppUnits(trackSizes[i + numLeadingImplicitTracks]);
    3024           0 :         valueList->AppendCSSValue(val.forget());
    3025           0 :       }
    3026             :     }
    3027             : 
    3028             :     // Add any trailing implicit tracks.
    3029           0 :     for (uint32_t i = numLeadingImplicitTracks + numExplicitTracks;
    3030           0 :          i < numSizes; ++i) {
    3031           0 :       RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    3032           0 :       val->SetAppUnits(trackSizes[i]);
    3033           0 :       valueList->AppendCSSValue(val.forget());
    3034             :     }
    3035             :   } else {
    3036             :     // We don't have a frame.  So, we'll just return a serialization of
    3037             :     // the tracks from the style (without resolved sizes).
    3038           0 :     for (uint32_t i = 0;; i++) {
    3039           0 :       const nsTArray<nsString>& lineNames = aTrackList.mLineNameLists[i];
    3040           0 :       if (!lineNames.IsEmpty()) {
    3041           0 :         AppendGridLineNames(valueList, lineNames);
    3042             :       }
    3043           0 :       if (i == numSizes) {
    3044           0 :         break;
    3045             :       }
    3046           0 :       if (MOZ_UNLIKELY(aTrackList.IsRepeatAutoIndex(i))) {
    3047           0 :         RefPtr<nsROCSSPrimitiveValue> start = new nsROCSSPrimitiveValue;
    3048           0 :         start->SetString(aTrackList.mIsAutoFill ? NS_LITERAL_STRING("repeat(auto-fill,")
    3049           0 :                                                 : NS_LITERAL_STRING("repeat(auto-fit,"));
    3050           0 :         valueList->AppendCSSValue(start.forget());
    3051           0 :         if (!aTrackList.mRepeatAutoLineNameListBefore.IsEmpty()) {
    3052           0 :           AppendGridLineNames(valueList, aTrackList.mRepeatAutoLineNameListBefore);
    3053             :         }
    3054             : 
    3055           0 :         valueList->AppendCSSValue(
    3056           0 :           GetGridTrackSize(aTrackList.mMinTrackSizingFunctions[i],
    3057           0 :                            aTrackList.mMaxTrackSizingFunctions[i]));
    3058           0 :         if (!aTrackList.mRepeatAutoLineNameListAfter.IsEmpty()) {
    3059           0 :           AppendGridLineNames(valueList, aTrackList.mRepeatAutoLineNameListAfter);
    3060             :         }
    3061           0 :         RefPtr<nsROCSSPrimitiveValue> end = new nsROCSSPrimitiveValue;
    3062           0 :         end->SetString(NS_LITERAL_STRING(")"));
    3063           0 :         valueList->AppendCSSValue(end.forget());
    3064             :       } else {
    3065           0 :         valueList->AppendCSSValue(
    3066           0 :           GetGridTrackSize(aTrackList.mMinTrackSizingFunctions[i],
    3067           0 :                            aTrackList.mMaxTrackSizingFunctions[i]));
    3068             :       }
    3069           0 :     }
    3070             :   }
    3071             : 
    3072           0 :   return valueList.forget();
    3073             : }
    3074             : 
    3075             : already_AddRefed<CSSValue>
    3076           0 : nsComputedDOMStyle::DoGetGridAutoFlow()
    3077             : {
    3078           0 :   nsAutoString str;
    3079           0 :   nsStyleUtil::AppendBitmaskCSSValue(eCSSProperty_grid_auto_flow,
    3080           0 :                                      StylePosition()->mGridAutoFlow,
    3081             :                                      NS_STYLE_GRID_AUTO_FLOW_ROW,
    3082             :                                      NS_STYLE_GRID_AUTO_FLOW_DENSE,
    3083           0 :                                      str);
    3084           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    3085           0 :   val->SetString(str);
    3086           0 :   return val.forget();
    3087             : }
    3088             : 
    3089             : already_AddRefed<CSSValue>
    3090           0 : nsComputedDOMStyle::DoGetGridAutoColumns()
    3091             : {
    3092           0 :   return GetGridTrackSize(StylePosition()->mGridAutoColumnsMin,
    3093           0 :                           StylePosition()->mGridAutoColumnsMax);
    3094             : }
    3095             : 
    3096             : already_AddRefed<CSSValue>
    3097           0 : nsComputedDOMStyle::DoGetGridAutoRows()
    3098             : {
    3099           0 :   return GetGridTrackSize(StylePosition()->mGridAutoRowsMin,
    3100           0 :                           StylePosition()->mGridAutoRowsMax);
    3101             : }
    3102             : 
    3103             : already_AddRefed<CSSValue>
    3104           0 : nsComputedDOMStyle::DoGetGridTemplateColumns()
    3105             : {
    3106           0 :   const ComputedGridTrackInfo* info = nullptr;
    3107             : 
    3108             :   nsGridContainerFrame* gridFrame =
    3109           0 :     nsGridContainerFrame::GetGridFrameWithComputedInfo(
    3110           0 :       mContent->GetPrimaryFrame());
    3111             : 
    3112           0 :   if (gridFrame) {
    3113           0 :     info = gridFrame->GetComputedTemplateColumns();
    3114             :   }
    3115             : 
    3116           0 :   return GetGridTemplateColumnsRows(StylePosition()->mGridTemplateColumns, info);
    3117             : }
    3118             : 
    3119             : already_AddRefed<CSSValue>
    3120           0 : nsComputedDOMStyle::DoGetGridTemplateRows()
    3121             : {
    3122           0 :   const ComputedGridTrackInfo* info = nullptr;
    3123             : 
    3124             :   nsGridContainerFrame* gridFrame =
    3125           0 :     nsGridContainerFrame::GetGridFrameWithComputedInfo(
    3126           0 :       mContent->GetPrimaryFrame());
    3127             : 
    3128           0 :   if (gridFrame) {
    3129           0 :     info = gridFrame->GetComputedTemplateRows();
    3130             :   }
    3131             : 
    3132           0 :   return GetGridTemplateColumnsRows(StylePosition()->mGridTemplateRows, info);
    3133             : }
    3134             : 
    3135             : already_AddRefed<CSSValue>
    3136           0 : nsComputedDOMStyle::GetGridLine(const nsStyleGridLine& aGridLine)
    3137             : {
    3138           0 :   if (aGridLine.IsAuto()) {
    3139           0 :     RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    3140           0 :     val->SetIdent(eCSSKeyword_auto);
    3141           0 :     return val.forget();
    3142             :   }
    3143             : 
    3144           0 :   RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false);
    3145             : 
    3146           0 :   if (aGridLine.mHasSpan) {
    3147           0 :     RefPtr<nsROCSSPrimitiveValue> span = new nsROCSSPrimitiveValue;
    3148           0 :     span->SetIdent(eCSSKeyword_span);
    3149           0 :     valueList->AppendCSSValue(span.forget());
    3150             :   }
    3151             : 
    3152           0 :   if (aGridLine.mInteger != 0) {
    3153           0 :     RefPtr<nsROCSSPrimitiveValue> integer = new nsROCSSPrimitiveValue;
    3154           0 :     integer->SetNumber(aGridLine.mInteger);
    3155           0 :     valueList->AppendCSSValue(integer.forget());
    3156             :   }
    3157             : 
    3158           0 :   if (!aGridLine.mLineName.IsEmpty()) {
    3159           0 :     RefPtr<nsROCSSPrimitiveValue> lineName = new nsROCSSPrimitiveValue;
    3160           0 :     nsString escapedLineName;
    3161           0 :     nsStyleUtil::AppendEscapedCSSIdent(aGridLine.mLineName, escapedLineName);
    3162           0 :     lineName->SetString(escapedLineName);
    3163           0 :     valueList->AppendCSSValue(lineName.forget());
    3164             :   }
    3165             : 
    3166           0 :   NS_ASSERTION(valueList->Length() > 0,
    3167             :                "Should have appended at least one value");
    3168           0 :   return valueList.forget();
    3169             : }
    3170             : 
    3171             : already_AddRefed<CSSValue>
    3172           0 : nsComputedDOMStyle::DoGetGridColumnStart()
    3173             : {
    3174           0 :   return GetGridLine(StylePosition()->mGridColumnStart);
    3175             : }
    3176             : 
    3177             : already_AddRefed<CSSValue>
    3178           0 : nsComputedDOMStyle::DoGetGridColumnEnd()
    3179             : {
    3180           0 :   return GetGridLine(StylePosition()->mGridColumnEnd);
    3181             : }
    3182             : 
    3183             : already_AddRefed<CSSValue>
    3184           0 : nsComputedDOMStyle::DoGetGridRowStart()
    3185             : {
    3186           0 :   return GetGridLine(StylePosition()->mGridRowStart);
    3187             : }
    3188             : 
    3189             : already_AddRefed<CSSValue>
    3190           0 : nsComputedDOMStyle::DoGetGridRowEnd()
    3191             : {
    3192           0 :   return GetGridLine(StylePosition()->mGridRowEnd);
    3193             : }
    3194             : 
    3195             : already_AddRefed<CSSValue>
    3196           0 : nsComputedDOMStyle::DoGetGridColumnGap()
    3197             : {
    3198           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    3199           0 :   SetValueToCoord(val, StylePosition()->mGridColumnGap, true);
    3200           0 :   return val.forget();
    3201             : }
    3202             : 
    3203             : already_AddRefed<CSSValue>
    3204           0 : nsComputedDOMStyle::DoGetGridRowGap()
    3205             : {
    3206           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    3207           0 :   SetValueToCoord(val, StylePosition()->mGridRowGap, true);
    3208           0 :   return val.forget();
    3209             : }
    3210             : 
    3211             : already_AddRefed<CSSValue>
    3212           0 : nsComputedDOMStyle::DoGetPaddingTop()
    3213             : {
    3214           0 :   return GetPaddingWidthFor(eSideTop);
    3215             : }
    3216             : 
    3217             : already_AddRefed<CSSValue>
    3218           0 : nsComputedDOMStyle::DoGetPaddingBottom()
    3219             : {
    3220           0 :   return GetPaddingWidthFor(eSideBottom);
    3221             : }
    3222             : 
    3223             : already_AddRefed<CSSValue>
    3224           0 : nsComputedDOMStyle::DoGetPaddingLeft()
    3225             : {
    3226           0 :   return GetPaddingWidthFor(eSideLeft);
    3227             : }
    3228             : 
    3229             : already_AddRefed<CSSValue>
    3230           0 : nsComputedDOMStyle::DoGetPaddingRight()
    3231             : {
    3232           0 :   return GetPaddingWidthFor(eSideRight);
    3233             : }
    3234             : 
    3235             : already_AddRefed<CSSValue>
    3236           0 : nsComputedDOMStyle::DoGetBorderCollapse()
    3237             : {
    3238           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    3239           0 :   val->SetIdent(
    3240           0 :     nsCSSProps::ValueToKeywordEnum(StyleTableBorder()->mBorderCollapse,
    3241           0 :                                    nsCSSProps::kBorderCollapseKTable));
    3242           0 :   return val.forget();
    3243             : }
    3244             : 
    3245             : already_AddRefed<CSSValue>
    3246           0 : nsComputedDOMStyle::DoGetBorderSpacing()
    3247             : {
    3248           0 :   RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false);
    3249             : 
    3250           0 :   RefPtr<nsROCSSPrimitiveValue> xSpacing = new nsROCSSPrimitiveValue;
    3251           0 :   RefPtr<nsROCSSPrimitiveValue> ySpacing = new nsROCSSPrimitiveValue;
    3252             : 
    3253           0 :   const nsStyleTableBorder *border = StyleTableBorder();
    3254           0 :   xSpacing->SetAppUnits(border->mBorderSpacingCol);
    3255           0 :   ySpacing->SetAppUnits(border->mBorderSpacingRow);
    3256             : 
    3257           0 :   valueList->AppendCSSValue(xSpacing.forget());
    3258           0 :   valueList->AppendCSSValue(ySpacing.forget());
    3259             : 
    3260           0 :   return valueList.forget();
    3261             : }
    3262             : 
    3263             : already_AddRefed<CSSValue>
    3264           0 : nsComputedDOMStyle::DoGetCaptionSide()
    3265             : {
    3266           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    3267           0 :   val->SetIdent(
    3268           0 :     nsCSSProps::ValueToKeywordEnum(StyleTableBorder()->mCaptionSide,
    3269           0 :                                    nsCSSProps::kCaptionSideKTable));
    3270           0 :   return val.forget();
    3271             : }
    3272             : 
    3273             : already_AddRefed<CSSValue>
    3274           0 : nsComputedDOMStyle::DoGetEmptyCells()
    3275             : {
    3276           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    3277           0 :   val->SetIdent(
    3278           0 :     nsCSSProps::ValueToKeywordEnum(StyleTableBorder()->mEmptyCells,
    3279           0 :                                    nsCSSProps::kEmptyCellsKTable));
    3280           0 :   return val.forget();
    3281             : }
    3282             : 
    3283             : already_AddRefed<CSSValue>
    3284           0 : nsComputedDOMStyle::DoGetTableLayout()
    3285             : {
    3286           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    3287           0 :   val->SetIdent(
    3288           0 :     nsCSSProps::ValueToKeywordEnum(StyleTable()->mLayoutStrategy,
    3289           0 :                                    nsCSSProps::kTableLayoutKTable));
    3290           0 :   return val.forget();
    3291             : }
    3292             : 
    3293             : already_AddRefed<CSSValue>
    3294           0 : nsComputedDOMStyle::DoGetBorderTopStyle()
    3295             : {
    3296           0 :   return GetBorderStyleFor(eSideTop);
    3297             : }
    3298             : 
    3299             : already_AddRefed<CSSValue>
    3300           0 : nsComputedDOMStyle::DoGetBorderBottomStyle()
    3301             : {
    3302           0 :   return GetBorderStyleFor(eSideBottom);
    3303             : }
    3304             : 
    3305             : already_AddRefed<CSSValue>
    3306           0 : nsComputedDOMStyle::DoGetBorderLeftStyle()
    3307             : {
    3308           0 :   return GetBorderStyleFor(eSideLeft);
    3309             : }
    3310             : 
    3311             : already_AddRefed<CSSValue>
    3312           0 : nsComputedDOMStyle::DoGetBorderRightStyle()
    3313             : {
    3314           0 :   return GetBorderStyleFor(eSideRight);
    3315             : }
    3316             : 
    3317             : already_AddRefed<CSSValue>
    3318           0 : nsComputedDOMStyle::DoGetBorderBottomColors()
    3319             : {
    3320           0 :   return GetBorderColorsFor(eSideBottom);
    3321             : }
    3322             : 
    3323             : already_AddRefed<CSSValue>
    3324           0 : nsComputedDOMStyle::DoGetBorderLeftColors()
    3325             : {
    3326           0 :   return GetBorderColorsFor(eSideLeft);
    3327             : }
    3328             : 
    3329             : already_AddRefed<CSSValue>
    3330           0 : nsComputedDOMStyle::DoGetBorderRightColors()
    3331             : {
    3332           0 :   return GetBorderColorsFor(eSideRight);
    3333             : }
    3334             : 
    3335             : 
    3336             : already_AddRefed<CSSValue>
    3337           0 : nsComputedDOMStyle::DoGetBorderTopColors()
    3338             : {
    3339           0 :   return GetBorderColorsFor(eSideTop);
    3340             : }
    3341             : 
    3342             : already_AddRefed<CSSValue>
    3343           0 : nsComputedDOMStyle::DoGetBorderBottomLeftRadius()
    3344             : {
    3345           0 :   return GetEllipseRadii(StyleBorder()->mBorderRadius,
    3346           0 :                          eCornerBottomLeft);
    3347             : }
    3348             : 
    3349             : already_AddRefed<CSSValue>
    3350           0 : nsComputedDOMStyle::DoGetBorderBottomRightRadius()
    3351             : {
    3352           0 :   return GetEllipseRadii(StyleBorder()->mBorderRadius,
    3353           0 :                          eCornerBottomRight);
    3354             : }
    3355             : 
    3356             : already_AddRefed<CSSValue>
    3357           0 : nsComputedDOMStyle::DoGetBorderTopLeftRadius()
    3358             : {
    3359           0 :   return GetEllipseRadii(StyleBorder()->mBorderRadius,
    3360           0 :                          eCornerTopLeft);
    3361             : }
    3362             : 
    3363             : already_AddRefed<CSSValue>
    3364           0 : nsComputedDOMStyle::DoGetBorderTopRightRadius()
    3365             : {
    3366           0 :   return GetEllipseRadii(StyleBorder()->mBorderRadius,
    3367           0 :                          eCornerTopRight);
    3368             : }
    3369             : 
    3370             : already_AddRefed<CSSValue>
    3371           0 : nsComputedDOMStyle::DoGetBorderTopWidth()
    3372             : {
    3373           0 :   return GetBorderWidthFor(eSideTop);
    3374             : }
    3375             : 
    3376             : already_AddRefed<CSSValue>
    3377           0 : nsComputedDOMStyle::DoGetBorderBottomWidth()
    3378             : {
    3379           0 :   return GetBorderWidthFor(eSideBottom);
    3380             : }
    3381             : 
    3382             : already_AddRefed<CSSValue>
    3383           0 : nsComputedDOMStyle::DoGetBorderLeftWidth()
    3384             : {
    3385           0 :   return GetBorderWidthFor(eSideLeft);
    3386             : }
    3387             : 
    3388             : already_AddRefed<CSSValue>
    3389           0 : nsComputedDOMStyle::DoGetBorderRightWidth()
    3390             : {
    3391           0 :   return GetBorderWidthFor(eSideRight);
    3392             : }
    3393             : 
    3394             : already_AddRefed<CSSValue>
    3395           0 : nsComputedDOMStyle::DoGetBorderTopColor()
    3396             : {
    3397           0 :   return GetBorderColorFor(eSideTop);
    3398             : }
    3399             : 
    3400             : already_AddRefed<CSSValue>
    3401           0 : nsComputedDOMStyle::DoGetBorderBottomColor()
    3402             : {
    3403           0 :   return GetBorderColorFor(eSideBottom);
    3404             : }
    3405             : 
    3406             : already_AddRefed<CSSValue>
    3407           0 : nsComputedDOMStyle::DoGetBorderLeftColor()
    3408             : {
    3409           0 :   return GetBorderColorFor(eSideLeft);
    3410             : }
    3411             : 
    3412             : already_AddRefed<CSSValue>
    3413           0 : nsComputedDOMStyle::DoGetBorderRightColor()
    3414             : {
    3415           0 :   return GetBorderColorFor(eSideRight);
    3416             : }
    3417             : 
    3418             : already_AddRefed<CSSValue>
    3419           0 : nsComputedDOMStyle::DoGetMarginTopWidth()
    3420             : {
    3421           0 :   return GetMarginWidthFor(eSideTop);
    3422             : }
    3423             : 
    3424             : already_AddRefed<CSSValue>
    3425           0 : nsComputedDOMStyle::DoGetMarginBottomWidth()
    3426             : {
    3427           0 :   return GetMarginWidthFor(eSideBottom);
    3428             : }
    3429             : 
    3430             : already_AddRefed<CSSValue>
    3431           0 : nsComputedDOMStyle::DoGetMarginLeftWidth()
    3432             : {
    3433           0 :   return GetMarginWidthFor(eSideLeft);
    3434             : }
    3435             : 
    3436             : already_AddRefed<CSSValue>
    3437           0 : nsComputedDOMStyle::DoGetMarginRightWidth()
    3438             : {
    3439           0 :   return GetMarginWidthFor(eSideRight);
    3440             : }
    3441             : 
    3442             : already_AddRefed<CSSValue>
    3443           0 : nsComputedDOMStyle::DoGetOrient()
    3444             : {
    3445           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    3446           0 :   val->SetIdent(
    3447           0 :     nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mOrient,
    3448           0 :                                    nsCSSProps::kOrientKTable));
    3449           0 :   return val.forget();
    3450             : }
    3451             : 
    3452             : already_AddRefed<CSSValue>
    3453           0 : nsComputedDOMStyle::DoGetScrollBehavior()
    3454             : {
    3455           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    3456           0 :   val->SetIdent(
    3457           0 :     nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mScrollBehavior,
    3458           0 :                                    nsCSSProps::kScrollBehaviorKTable));
    3459           0 :   return val.forget();
    3460             : }
    3461             : 
    3462             : already_AddRefed<CSSValue>
    3463           0 : nsComputedDOMStyle::DoGetScrollSnapType()
    3464             : {
    3465           0 :   const nsStyleDisplay* display = StyleDisplay();
    3466           0 :   if (display->mScrollSnapTypeX != display->mScrollSnapTypeY) {
    3467             :     // No value to return.  We can't express this combination of
    3468             :     // values as a shorthand.
    3469           0 :     return nullptr;
    3470             :   }
    3471           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    3472           0 :   val->SetIdent(
    3473           0 :     nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mScrollSnapTypeX,
    3474           0 :                                    nsCSSProps::kScrollSnapTypeKTable));
    3475           0 :   return val.forget();
    3476             : }
    3477             : 
    3478             : already_AddRefed<CSSValue>
    3479           0 : nsComputedDOMStyle::DoGetScrollSnapTypeX()
    3480             : {
    3481           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    3482           0 :   val->SetIdent(
    3483           0 :     nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mScrollSnapTypeX,
    3484           0 :                                    nsCSSProps::kScrollSnapTypeKTable));
    3485           0 :   return val.forget();
    3486             : }
    3487             : 
    3488             : already_AddRefed<CSSValue>
    3489           0 : nsComputedDOMStyle::DoGetScrollSnapTypeY()
    3490             : {
    3491           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    3492           0 :   val->SetIdent(
    3493           0 :     nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mScrollSnapTypeY,
    3494           0 :                                    nsCSSProps::kScrollSnapTypeKTable));
    3495           0 :   return val.forget();
    3496             : }
    3497             : 
    3498             : already_AddRefed<CSSValue>
    3499           0 : nsComputedDOMStyle::GetScrollSnapPoints(const nsStyleCoord& aCoord)
    3500             : {
    3501           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    3502           0 :   if (aCoord.GetUnit() == eStyleUnit_None) {
    3503           0 :     val->SetIdent(eCSSKeyword_none);
    3504             :   } else {
    3505           0 :     nsAutoString argumentString;
    3506           0 :     SetCssTextToCoord(argumentString, aCoord);
    3507           0 :     nsAutoString tmp;
    3508           0 :     tmp.AppendLiteral("repeat(");
    3509           0 :     tmp.Append(argumentString);
    3510           0 :     tmp.Append(')');
    3511           0 :     val->SetString(tmp);
    3512             :   }
    3513           0 :   return val.forget();
    3514             : }
    3515             : 
    3516             : already_AddRefed<CSSValue>
    3517           0 : nsComputedDOMStyle::DoGetScrollSnapPointsX()
    3518             : {
    3519           0 :   return GetScrollSnapPoints(StyleDisplay()->mScrollSnapPointsX);
    3520             : }
    3521             : 
    3522             : already_AddRefed<CSSValue>
    3523           0 : nsComputedDOMStyle::DoGetScrollSnapPointsY()
    3524             : {
    3525           0 :   return GetScrollSnapPoints(StyleDisplay()->mScrollSnapPointsY);
    3526             : }
    3527             : 
    3528             : already_AddRefed<CSSValue>
    3529           0 : nsComputedDOMStyle::DoGetScrollSnapDestination()
    3530             : {
    3531           0 :   RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false);
    3532           0 :   SetValueToPosition(StyleDisplay()->mScrollSnapDestination, valueList);
    3533           0 :   return valueList.forget();
    3534             : }
    3535             : 
    3536             : already_AddRefed<CSSValue>
    3537           0 : nsComputedDOMStyle::DoGetScrollSnapCoordinate()
    3538             : {
    3539           0 :   const nsStyleDisplay* sd = StyleDisplay();
    3540           0 :   if (sd->mScrollSnapCoordinate.IsEmpty()) {
    3541             :     // Having no snap coordinates is interpreted as "none"
    3542           0 :     RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    3543           0 :     val->SetIdent(eCSSKeyword_none);
    3544           0 :     return val.forget();
    3545             :   } else {
    3546           0 :     RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(true);
    3547           0 :     for (size_t i = 0, i_end = sd->mScrollSnapCoordinate.Length(); i < i_end; ++i) {
    3548           0 :       RefPtr<nsDOMCSSValueList> itemList = GetROCSSValueList(false);
    3549           0 :       SetValueToPosition(sd->mScrollSnapCoordinate[i], itemList);
    3550           0 :       valueList->AppendCSSValue(itemList.forget());
    3551             :     }
    3552           0 :     return valueList.forget();
    3553             :   }
    3554             : }
    3555             : 
    3556             : already_AddRefed<CSSValue>
    3557           0 : nsComputedDOMStyle::DoGetOutlineWidth()
    3558             : {
    3559           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    3560             : 
    3561           0 :   const nsStyleOutline* outline = StyleOutline();
    3562             : 
    3563             :   nscoord width;
    3564           0 :   if (outline->mOutlineStyle == NS_STYLE_BORDER_STYLE_NONE) {
    3565           0 :     NS_ASSERTION(outline->GetOutlineWidth() == 0, "unexpected width");
    3566           0 :     width = 0;
    3567             :   } else {
    3568           0 :     width = outline->GetOutlineWidth();
    3569             :   }
    3570           0 :   val->SetAppUnits(width);
    3571             : 
    3572           0 :   return val.forget();
    3573             : }
    3574             : 
    3575             : already_AddRefed<CSSValue>
    3576           0 : nsComputedDOMStyle::DoGetOutlineStyle()
    3577             : {
    3578           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    3579           0 :   val->SetIdent(
    3580           0 :     nsCSSProps::ValueToKeywordEnum(StyleOutline()->mOutlineStyle,
    3581           0 :                                    nsCSSProps::kOutlineStyleKTable));
    3582           0 :   return val.forget();
    3583             : }
    3584             : 
    3585             : already_AddRefed<CSSValue>
    3586           0 : nsComputedDOMStyle::DoGetOutlineOffset()
    3587             : {
    3588           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    3589           0 :   val->SetAppUnits(StyleOutline()->mOutlineOffset);
    3590           0 :   return val.forget();
    3591             : }
    3592             : 
    3593             : already_AddRefed<CSSValue>
    3594           0 : nsComputedDOMStyle::DoGetOutlineRadiusBottomLeft()
    3595             : {
    3596           0 :   return GetEllipseRadii(StyleOutline()->mOutlineRadius,
    3597           0 :                          eCornerBottomLeft);
    3598             : }
    3599             : 
    3600             : already_AddRefed<CSSValue>
    3601           0 : nsComputedDOMStyle::DoGetOutlineRadiusBottomRight()
    3602             : {
    3603           0 :   return GetEllipseRadii(StyleOutline()->mOutlineRadius,
    3604           0 :                          eCornerBottomRight);
    3605             : }
    3606             : 
    3607             : already_AddRefed<CSSValue>
    3608           0 : nsComputedDOMStyle::DoGetOutlineRadiusTopLeft()
    3609             : {
    3610           0 :   return GetEllipseRadii(StyleOutline()->mOutlineRadius,
    3611           0 :                          eCornerTopLeft);
    3612             : }
    3613             : 
    3614             : already_AddRefed<CSSValue>
    3615           0 : nsComputedDOMStyle::DoGetOutlineRadiusTopRight()
    3616             : {
    3617           0 :   return GetEllipseRadii(StyleOutline()->mOutlineRadius,
    3618           0 :                          eCornerTopRight);
    3619             : }
    3620             : 
    3621             : already_AddRefed<CSSValue>
    3622           0 : nsComputedDOMStyle::DoGetOutlineColor()
    3623             : {
    3624           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    3625           0 :   SetValueFromComplexColor(val, StyleOutline()->mOutlineColor);
    3626           0 :   return val.forget();
    3627             : }
    3628             : 
    3629             : already_AddRefed<CSSValue>
    3630           0 : nsComputedDOMStyle::GetEllipseRadii(const nsStyleCorners& aRadius,
    3631             :                                     Corner aFullCorner)
    3632             : {
    3633           0 :   nsStyleCoord radiusX = aRadius.Get(FullToHalfCorner(aFullCorner, false));
    3634           0 :   nsStyleCoord radiusY = aRadius.Get(FullToHalfCorner(aFullCorner, true));
    3635             : 
    3636             :   // for compatibility, return a single value if X and Y are equal
    3637           0 :   if (radiusX == radiusY) {
    3638           0 :     RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    3639           0 :     SetValueToCoord(val, radiusX, true);
    3640           0 :     return val.forget();
    3641             :   }
    3642             : 
    3643           0 :   RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false);
    3644             : 
    3645           0 :   RefPtr<nsROCSSPrimitiveValue> valX = new nsROCSSPrimitiveValue;
    3646           0 :   RefPtr<nsROCSSPrimitiveValue> valY = new nsROCSSPrimitiveValue;
    3647             : 
    3648           0 :   SetValueToCoord(valX, radiusX, true);
    3649           0 :   SetValueToCoord(valY, radiusY, true);
    3650             : 
    3651           0 :   valueList->AppendCSSValue(valX.forget());
    3652           0 :   valueList->AppendCSSValue(valY.forget());
    3653             : 
    3654           0 :   return valueList.forget();
    3655             : }
    3656             : 
    3657             : already_AddRefed<CSSValue>
    3658           0 : nsComputedDOMStyle::GetCSSShadowArray(nsCSSShadowArray* aArray,
    3659             :                                       const nscolor& aDefaultColor,
    3660             :                                       bool aIsBoxShadow)
    3661             : {
    3662           0 :   if (!aArray) {
    3663           0 :     RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    3664           0 :     val->SetIdent(eCSSKeyword_none);
    3665           0 :     return val.forget();
    3666             :   }
    3667             : 
    3668             :   static nscoord nsCSSShadowItem::* const shadowValuesNoSpread[] = {
    3669             :     &nsCSSShadowItem::mXOffset,
    3670             :     &nsCSSShadowItem::mYOffset,
    3671             :     &nsCSSShadowItem::mRadius
    3672             :   };
    3673             : 
    3674             :   static nscoord nsCSSShadowItem::* const shadowValuesWithSpread[] = {
    3675             :     &nsCSSShadowItem::mXOffset,
    3676             :     &nsCSSShadowItem::mYOffset,
    3677             :     &nsCSSShadowItem::mRadius,
    3678             :     &nsCSSShadowItem::mSpread
    3679             :   };
    3680             : 
    3681             :   nscoord nsCSSShadowItem::* const * shadowValues;
    3682             :   uint32_t shadowValuesLength;
    3683           0 :   if (aIsBoxShadow) {
    3684           0 :     shadowValues = shadowValuesWithSpread;
    3685           0 :     shadowValuesLength = ArrayLength(shadowValuesWithSpread);
    3686             :   } else {
    3687           0 :     shadowValues = shadowValuesNoSpread;
    3688           0 :     shadowValuesLength = ArrayLength(shadowValuesNoSpread);
    3689             :   }
    3690             : 
    3691           0 :   RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(true);
    3692             : 
    3693           0 :   for (nsCSSShadowItem *item = aArray->ShadowAt(0),
    3694           0 :                    *item_end = item + aArray->Length();
    3695           0 :        item < item_end; ++item) {
    3696           0 :     RefPtr<nsDOMCSSValueList> itemList = GetROCSSValueList(false);
    3697             : 
    3698             :     // Color is either the specified shadow color or the foreground color
    3699           0 :     RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    3700             :     nscolor shadowColor;
    3701           0 :     if (item->mHasColor) {
    3702           0 :       shadowColor = item->mColor;
    3703             :     } else {
    3704           0 :       shadowColor = aDefaultColor;
    3705             :     }
    3706           0 :     SetToRGBAColor(val, shadowColor);
    3707           0 :     itemList->AppendCSSValue(val.forget());
    3708             : 
    3709             :     // Set the offsets, blur radius, and spread if available
    3710           0 :     for (uint32_t i = 0; i < shadowValuesLength; ++i) {
    3711           0 :       val = new nsROCSSPrimitiveValue;
    3712           0 :       val->SetAppUnits(item->*(shadowValues[i]));
    3713           0 :       itemList->AppendCSSValue(val.forget());
    3714             :     }
    3715             : 
    3716           0 :     if (item->mInset && aIsBoxShadow) {
    3717             :       // This is an inset box-shadow
    3718           0 :       val = new nsROCSSPrimitiveValue;
    3719           0 :       val->SetIdent(
    3720           0 :         nsCSSProps::ValueToKeywordEnum(
    3721             :             uint8_t(StyleBoxShadowType::Inset),
    3722           0 :             nsCSSProps::kBoxShadowTypeKTable));
    3723           0 :       itemList->AppendCSSValue(val.forget());
    3724             :     }
    3725           0 :     valueList->AppendCSSValue(itemList.forget());
    3726             :   }
    3727             : 
    3728           0 :   return valueList.forget();
    3729             : }
    3730             : 
    3731             : already_AddRefed<CSSValue>
    3732           0 : nsComputedDOMStyle::DoGetBoxDecorationBreak()
    3733             : {
    3734           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    3735           0 :   val->SetIdent(
    3736           0 :     nsCSSProps::ValueToKeywordEnum(StyleBorder()->mBoxDecorationBreak,
    3737           0 :                                    nsCSSProps::kBoxDecorationBreakKTable));
    3738           0 :   return val.forget();
    3739             : }
    3740             : 
    3741             : already_AddRefed<CSSValue>
    3742           0 : nsComputedDOMStyle::DoGetBoxShadow()
    3743             : {
    3744           0 :   return GetCSSShadowArray(StyleEffects()->mBoxShadow,
    3745           0 :                            StyleColor()->mColor,
    3746           0 :                            true);
    3747             : }
    3748             : 
    3749             : already_AddRefed<CSSValue>
    3750           0 : nsComputedDOMStyle::DoGetZIndex()
    3751             : {
    3752           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    3753           0 :   SetValueToCoord(val, StylePosition()->mZIndex, false);
    3754           0 :   return val.forget();
    3755             : }
    3756             : 
    3757             : already_AddRefed<CSSValue>
    3758           0 : nsComputedDOMStyle::DoGetListStyleImage()
    3759             : {
    3760           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    3761             : 
    3762           0 :   nsCOMPtr<nsIURI> uri = StyleList()->GetListStyleImageURI();
    3763           0 :   if (!uri) {
    3764           0 :     val->SetIdent(eCSSKeyword_none);
    3765             :   } else {
    3766           0 :     val->SetURI(uri);
    3767             :   }
    3768             : 
    3769           0 :   return val.forget();
    3770             : }
    3771             : 
    3772             : already_AddRefed<CSSValue>
    3773           0 : nsComputedDOMStyle::DoGetListStylePosition()
    3774             : {
    3775           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    3776           0 :   val->SetIdent(
    3777           0 :     nsCSSProps::ValueToKeywordEnum(StyleList()->mListStylePosition,
    3778           0 :                                    nsCSSProps::kListStylePositionKTable));
    3779           0 :   return val.forget();
    3780             : }
    3781             : 
    3782             : already_AddRefed<CSSValue>
    3783           0 : nsComputedDOMStyle::DoGetListStyleType()
    3784             : {
    3785           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    3786           0 :   nsAutoString tmp;
    3787           0 :   AppendCounterStyle(StyleList()->mCounterStyle, tmp);
    3788           0 :   val->SetString(tmp);
    3789           0 :   return val.forget();
    3790             : }
    3791             : 
    3792             : already_AddRefed<CSSValue>
    3793           0 : nsComputedDOMStyle::DoGetImageRegion()
    3794             : {
    3795           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    3796             : 
    3797           0 :   const nsStyleList* list = StyleList();
    3798             : 
    3799           0 :   if (list->mImageRegion.width <= 0 || list->mImageRegion.height <= 0) {
    3800           0 :     val->SetIdent(eCSSKeyword_auto);
    3801             :   } else {
    3802             :     // create the cssvalues for the sides, stick them in the rect object
    3803           0 :     nsROCSSPrimitiveValue *topVal    = new nsROCSSPrimitiveValue;
    3804           0 :     nsROCSSPrimitiveValue *rightVal  = new nsROCSSPrimitiveValue;
    3805           0 :     nsROCSSPrimitiveValue *bottomVal = new nsROCSSPrimitiveValue;
    3806           0 :     nsROCSSPrimitiveValue *leftVal   = new nsROCSSPrimitiveValue;
    3807             :     nsDOMCSSRect * domRect = new nsDOMCSSRect(topVal, rightVal,
    3808           0 :                                               bottomVal, leftVal);
    3809           0 :     topVal->SetAppUnits(list->mImageRegion.y);
    3810           0 :     rightVal->SetAppUnits(list->mImageRegion.width + list->mImageRegion.x);
    3811           0 :     bottomVal->SetAppUnits(list->mImageRegion.height + list->mImageRegion.y);
    3812           0 :     leftVal->SetAppUnits(list->mImageRegion.x);
    3813           0 :     val->SetRect(domRect);
    3814             :   }
    3815             : 
    3816           0 :   return val.forget();
    3817             : }
    3818             : 
    3819             : already_AddRefed<CSSValue>
    3820           0 : nsComputedDOMStyle::DoGetInitialLetter()
    3821             : {
    3822           0 :   const nsStyleTextReset* textReset = StyleTextReset();
    3823           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    3824           0 :   if (textReset->mInitialLetterSink == 0) {
    3825           0 :     val->SetIdent(eCSSKeyword_normal);
    3826           0 :     return val.forget();
    3827             :   } else {
    3828           0 :     RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false);
    3829           0 :     val->SetNumber(textReset->mInitialLetterSize);
    3830           0 :     valueList->AppendCSSValue(val.forget());
    3831           0 :     RefPtr<nsROCSSPrimitiveValue> second = new nsROCSSPrimitiveValue;
    3832           0 :     second->SetNumber(textReset->mInitialLetterSink);
    3833           0 :     valueList->AppendCSSValue(second.forget());
    3834           0 :     return valueList.forget();
    3835             :   }
    3836             : }
    3837             : 
    3838             : already_AddRefed<CSSValue>
    3839           0 : nsComputedDOMStyle::DoGetLineHeight()
    3840             : {
    3841           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    3842             : 
    3843             :   nscoord lineHeight;
    3844           0 :   if (GetLineHeightCoord(lineHeight)) {
    3845           0 :     val->SetAppUnits(lineHeight);
    3846             :   } else {
    3847           0 :     SetValueToCoord(val, StyleText()->mLineHeight, true,
    3848           0 :                     nullptr, nsCSSProps::kLineHeightKTable);
    3849             :   }
    3850             : 
    3851           0 :   return val.forget();
    3852             : }
    3853             : 
    3854             : already_AddRefed<CSSValue>
    3855           0 : nsComputedDOMStyle::DoGetRubyAlign()
    3856             : {
    3857           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    3858           0 :   val->SetIdent(nsCSSProps::ValueToKeywordEnum(
    3859           0 :     StyleText()->mRubyAlign, nsCSSProps::kRubyAlignKTable));
    3860           0 :   return val.forget();
    3861             : }
    3862             : 
    3863             : already_AddRefed<CSSValue>
    3864           0 : nsComputedDOMStyle::DoGetRubyPosition()
    3865             : {
    3866           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    3867           0 :   val->SetIdent(nsCSSProps::ValueToKeywordEnum(
    3868           0 :     StyleText()->mRubyPosition, nsCSSProps::kRubyPositionKTable));
    3869           0 :   return val.forget();
    3870             : }
    3871             : 
    3872             : already_AddRefed<CSSValue>
    3873           0 : nsComputedDOMStyle::DoGetVerticalAlign()
    3874             : {
    3875           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    3876           0 :   SetValueToCoord(val, StyleDisplay()->mVerticalAlign, false,
    3877           0 :                   nullptr, nsCSSProps::kVerticalAlignKTable);
    3878           0 :   return val.forget();
    3879             : }
    3880             : 
    3881             : already_AddRefed<CSSValue>
    3882           0 : nsComputedDOMStyle::CreateTextAlignValue(uint8_t aAlign, bool aAlignTrue,
    3883             :                                          const KTableEntry aTable[])
    3884             : {
    3885           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    3886           0 :   val->SetIdent(nsCSSProps::ValueToKeywordEnum(aAlign, aTable));
    3887           0 :   if (!aAlignTrue) {
    3888           0 :     return val.forget();
    3889             :   }
    3890             : 
    3891           0 :   RefPtr<nsROCSSPrimitiveValue> first = new nsROCSSPrimitiveValue;
    3892           0 :   first->SetIdent(eCSSKeyword_unsafe);
    3893             : 
    3894           0 :   RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false);
    3895           0 :   valueList->AppendCSSValue(first.forget());
    3896           0 :   valueList->AppendCSSValue(val.forget());
    3897           0 :   return valueList.forget();
    3898             : }
    3899             : 
    3900             : already_AddRefed<CSSValue>
    3901           0 : nsComputedDOMStyle::DoGetTextAlign()
    3902             : {
    3903           0 :   const nsStyleText* style = StyleText();
    3904           0 :   return CreateTextAlignValue(style->mTextAlign, style->mTextAlignTrue,
    3905           0 :                               nsCSSProps::kTextAlignKTable);
    3906             : }
    3907             : 
    3908             : already_AddRefed<CSSValue>
    3909           0 : nsComputedDOMStyle::DoGetTextAlignLast()
    3910             : {
    3911           0 :   const nsStyleText* style = StyleText();
    3912           0 :   return CreateTextAlignValue(style->mTextAlignLast, style->mTextAlignLastTrue,
    3913           0 :                               nsCSSProps::kTextAlignLastKTable);
    3914             : }
    3915             : 
    3916             : already_AddRefed<CSSValue>
    3917           0 : nsComputedDOMStyle::DoGetTextCombineUpright()
    3918             : {
    3919           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    3920           0 :   uint8_t tch = StyleText()->mTextCombineUpright;
    3921             : 
    3922           0 :   if (tch <= NS_STYLE_TEXT_COMBINE_UPRIGHT_ALL) {
    3923           0 :     val->SetIdent(
    3924           0 :       nsCSSProps::ValueToKeywordEnum(tch,
    3925           0 :                                      nsCSSProps::kTextCombineUprightKTable));
    3926           0 :   } else if (tch <= NS_STYLE_TEXT_COMBINE_UPRIGHT_DIGITS_2) {
    3927           0 :     val->SetString(NS_LITERAL_STRING("digits 2"));
    3928           0 :   } else if (tch <= NS_STYLE_TEXT_COMBINE_UPRIGHT_DIGITS_3) {
    3929           0 :     val->SetString(NS_LITERAL_STRING("digits 3"));
    3930             :   } else {
    3931           0 :     val->SetString(NS_LITERAL_STRING("digits 4"));
    3932             :   }
    3933             : 
    3934           0 :   return val.forget();
    3935             : }
    3936             : 
    3937             : already_AddRefed<CSSValue>
    3938           0 : nsComputedDOMStyle::DoGetTextDecoration()
    3939             : {
    3940           0 :   const nsStyleTextReset* textReset = StyleTextReset();
    3941             : 
    3942             :   bool isInitialStyle =
    3943           0 :     textReset->mTextDecorationStyle == NS_STYLE_TEXT_DECORATION_STYLE_SOLID;
    3944           0 :   StyleComplexColor color = textReset->mTextDecorationColor;
    3945             : 
    3946           0 :   if (isInitialStyle && color.IsCurrentColor()) {
    3947           0 :     return DoGetTextDecorationLine();
    3948             :   }
    3949             : 
    3950           0 :   RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false);
    3951             : 
    3952           0 :   valueList->AppendCSSValue(DoGetTextDecorationLine());
    3953           0 :   if (!isInitialStyle) {
    3954           0 :     valueList->AppendCSSValue(DoGetTextDecorationStyle());
    3955             :   }
    3956           0 :   if (!color.IsCurrentColor()) {
    3957           0 :     valueList->AppendCSSValue(DoGetTextDecorationColor());
    3958             :   }
    3959             : 
    3960           0 :   return valueList.forget();
    3961             : }
    3962             : 
    3963             : already_AddRefed<CSSValue>
    3964           0 : nsComputedDOMStyle::DoGetTextDecorationColor()
    3965             : {
    3966           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    3967           0 :   SetValueFromComplexColor(val, StyleTextReset()->mTextDecorationColor);
    3968           0 :   return val.forget();
    3969             : }
    3970             : 
    3971             : already_AddRefed<CSSValue>
    3972           0 : nsComputedDOMStyle::DoGetTextDecorationLine()
    3973             : {
    3974           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    3975             : 
    3976           0 :   int32_t intValue = StyleTextReset()->mTextDecorationLine;
    3977             : 
    3978           0 :   if (NS_STYLE_TEXT_DECORATION_LINE_NONE == intValue) {
    3979           0 :     val->SetIdent(eCSSKeyword_none);
    3980             :   } else {
    3981           0 :     nsAutoString decorationLineString;
    3982             :     // Clear the OVERRIDE_ALL bits -- we don't want these to appear in
    3983             :     // the computed style.
    3984           0 :     intValue &= ~NS_STYLE_TEXT_DECORATION_LINE_OVERRIDE_ALL;
    3985             :     nsStyleUtil::AppendBitmaskCSSValue(eCSSProperty_text_decoration_line,
    3986             :       intValue, NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE,
    3987           0 :       NS_STYLE_TEXT_DECORATION_LINE_BLINK, decorationLineString);
    3988           0 :     val->SetString(decorationLineString);
    3989             :   }
    3990             : 
    3991           0 :   return val.forget();
    3992             : }
    3993             : 
    3994             : already_AddRefed<CSSValue>
    3995           0 : nsComputedDOMStyle::DoGetTextDecorationStyle()
    3996             : {
    3997           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    3998             : 
    3999           0 :   val->SetIdent(
    4000           0 :     nsCSSProps::ValueToKeywordEnum(StyleTextReset()->mTextDecorationStyle,
    4001           0 :                                    nsCSSProps::kTextDecorationStyleKTable));
    4002             : 
    4003           0 :   return val.forget();
    4004             : }
    4005             : 
    4006             : already_AddRefed<CSSValue>
    4007           0 : nsComputedDOMStyle::DoGetTextEmphasisColor()
    4008             : {
    4009           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4010           0 :   SetValueFromComplexColor(val, StyleText()->mTextEmphasisColor);
    4011           0 :   return val.forget();
    4012             : }
    4013             : 
    4014             : already_AddRefed<CSSValue>
    4015           0 : nsComputedDOMStyle::DoGetTextEmphasisPosition()
    4016             : {
    4017           0 :   auto position = StyleText()->mTextEmphasisPosition;
    4018             : 
    4019           0 :   MOZ_ASSERT(!(position & NS_STYLE_TEXT_EMPHASIS_POSITION_OVER) !=
    4020             :              !(position & NS_STYLE_TEXT_EMPHASIS_POSITION_UNDER));
    4021           0 :   RefPtr<nsROCSSPrimitiveValue> first = new nsROCSSPrimitiveValue;
    4022           0 :   first->SetIdent((position & NS_STYLE_TEXT_EMPHASIS_POSITION_OVER) ?
    4023           0 :                   eCSSKeyword_over : eCSSKeyword_under);
    4024             : 
    4025           0 :   MOZ_ASSERT(!(position & NS_STYLE_TEXT_EMPHASIS_POSITION_LEFT) !=
    4026             :              !(position & NS_STYLE_TEXT_EMPHASIS_POSITION_RIGHT));
    4027           0 :   RefPtr<nsROCSSPrimitiveValue> second = new nsROCSSPrimitiveValue;
    4028           0 :   second->SetIdent((position & NS_STYLE_TEXT_EMPHASIS_POSITION_LEFT) ?
    4029           0 :                    eCSSKeyword_left : eCSSKeyword_right);
    4030             : 
    4031           0 :   RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false);
    4032           0 :   valueList->AppendCSSValue(first.forget());
    4033           0 :   valueList->AppendCSSValue(second.forget());
    4034           0 :   return valueList.forget();
    4035             : }
    4036             : 
    4037             : already_AddRefed<CSSValue>
    4038           0 : nsComputedDOMStyle::DoGetTextEmphasisStyle()
    4039             : {
    4040           0 :   auto style = StyleText()->mTextEmphasisStyle;
    4041           0 :   if (style == NS_STYLE_TEXT_EMPHASIS_STYLE_NONE) {
    4042           0 :     RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4043           0 :     val->SetIdent(eCSSKeyword_none);
    4044           0 :     return val.forget();
    4045             :   }
    4046           0 :   if (style == NS_STYLE_TEXT_EMPHASIS_STYLE_STRING) {
    4047           0 :     RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4048           0 :     nsAutoString tmp;
    4049           0 :     nsStyleUtil::AppendEscapedCSSString(
    4050           0 :       StyleText()->mTextEmphasisStyleString, tmp);
    4051           0 :     val->SetString(tmp);
    4052           0 :     return val.forget();
    4053             :   }
    4054             : 
    4055           0 :   RefPtr<nsROCSSPrimitiveValue> fillVal = new nsROCSSPrimitiveValue;
    4056           0 :   if ((style & NS_STYLE_TEXT_EMPHASIS_STYLE_FILL_MASK) ==
    4057             :       NS_STYLE_TEXT_EMPHASIS_STYLE_FILLED) {
    4058           0 :     fillVal->SetIdent(eCSSKeyword_filled);
    4059             :   } else {
    4060           0 :     MOZ_ASSERT((style & NS_STYLE_TEXT_EMPHASIS_STYLE_FILL_MASK) ==
    4061             :                NS_STYLE_TEXT_EMPHASIS_STYLE_OPEN);
    4062           0 :     fillVal->SetIdent(eCSSKeyword_open);
    4063             :   }
    4064             : 
    4065           0 :   RefPtr<nsROCSSPrimitiveValue> shapeVal = new nsROCSSPrimitiveValue;
    4066           0 :   shapeVal->SetIdent(nsCSSProps::ValueToKeywordEnum(
    4067           0 :     style & NS_STYLE_TEXT_EMPHASIS_STYLE_SHAPE_MASK,
    4068           0 :     nsCSSProps::kTextEmphasisStyleShapeKTable));
    4069             : 
    4070           0 :   RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false);
    4071           0 :   valueList->AppendCSSValue(fillVal.forget());
    4072           0 :   valueList->AppendCSSValue(shapeVal.forget());
    4073           0 :   return valueList.forget();
    4074             : }
    4075             : 
    4076             : already_AddRefed<CSSValue>
    4077           0 : nsComputedDOMStyle::DoGetTextIndent()
    4078             : {
    4079           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4080           0 :   SetValueToCoord(val, StyleText()->mTextIndent, false);
    4081           0 :   return val.forget();
    4082             : }
    4083             : 
    4084             : already_AddRefed<CSSValue>
    4085           0 : nsComputedDOMStyle::DoGetTextJustify()
    4086             : {
    4087           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4088           0 :   val->SetIdent(
    4089           0 :     nsCSSProps::ValueToKeywordEnum(StyleText()->mTextJustify,
    4090           0 :                                    nsCSSProps::kTextJustifyKTable));
    4091           0 :   return val.forget();
    4092             : }
    4093             : 
    4094             : already_AddRefed<CSSValue>
    4095           0 : nsComputedDOMStyle::DoGetTextOrientation()
    4096             : {
    4097           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4098           0 :   val->SetIdent(
    4099           0 :     nsCSSProps::ValueToKeywordEnum(StyleVisibility()->mTextOrientation,
    4100           0 :                                    nsCSSProps::kTextOrientationKTable));
    4101           0 :   return val.forget();
    4102             : }
    4103             : 
    4104             : already_AddRefed<CSSValue>
    4105           0 : nsComputedDOMStyle::DoGetTextOverflow()
    4106             : {
    4107           0 :   const nsStyleTextReset *style = StyleTextReset();
    4108           0 :   RefPtr<nsROCSSPrimitiveValue> first = new nsROCSSPrimitiveValue;
    4109           0 :   const nsStyleTextOverflowSide *side = style->mTextOverflow.GetFirstValue();
    4110           0 :   if (side->mType == NS_STYLE_TEXT_OVERFLOW_STRING) {
    4111           0 :     nsAutoString str;
    4112           0 :     nsStyleUtil::AppendEscapedCSSString(side->mString, str);
    4113           0 :     first->SetString(str);
    4114             :   } else {
    4115           0 :     first->SetIdent(
    4116           0 :       nsCSSProps::ValueToKeywordEnum(side->mType,
    4117           0 :                                      nsCSSProps::kTextOverflowKTable));
    4118             :   }
    4119           0 :   side = style->mTextOverflow.GetSecondValue();
    4120           0 :   if (!side) {
    4121           0 :     return first.forget();
    4122             :   }
    4123           0 :   RefPtr<nsROCSSPrimitiveValue> second = new nsROCSSPrimitiveValue;
    4124           0 :   if (side->mType == NS_STYLE_TEXT_OVERFLOW_STRING) {
    4125           0 :     nsAutoString str;
    4126           0 :     nsStyleUtil::AppendEscapedCSSString(side->mString, str);
    4127           0 :     second->SetString(str);
    4128             :   } else {
    4129           0 :     second->SetIdent(
    4130           0 :       nsCSSProps::ValueToKeywordEnum(side->mType,
    4131           0 :                                      nsCSSProps::kTextOverflowKTable));
    4132             :   }
    4133             : 
    4134           0 :   RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false);
    4135           0 :   valueList->AppendCSSValue(first.forget());
    4136           0 :   valueList->AppendCSSValue(second.forget());
    4137           0 :   return valueList.forget();
    4138             : }
    4139             : 
    4140             : already_AddRefed<CSSValue>
    4141           0 : nsComputedDOMStyle::DoGetTextShadow()
    4142             : {
    4143           0 :   return GetCSSShadowArray(StyleText()->mTextShadow,
    4144           0 :                            StyleColor()->mColor,
    4145           0 :                            false);
    4146             : }
    4147             : 
    4148             : already_AddRefed<CSSValue>
    4149           0 : nsComputedDOMStyle::DoGetTextSizeAdjust()
    4150             : {
    4151           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4152           0 :   val->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleText()->mTextSizeAdjust,
    4153           0 :                                                nsCSSProps::kTextSizeAdjustKTable));
    4154           0 :   return val.forget();
    4155             : }
    4156             : 
    4157             : already_AddRefed<CSSValue>
    4158           0 : nsComputedDOMStyle::DoGetTextTransform()
    4159             : {
    4160           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4161           0 :   val->SetIdent(
    4162           0 :     nsCSSProps::ValueToKeywordEnum(StyleText()->mTextTransform,
    4163           0 :                                    nsCSSProps::kTextTransformKTable));
    4164           0 :   return val.forget();
    4165             : }
    4166             : 
    4167             : already_AddRefed<CSSValue>
    4168           0 : nsComputedDOMStyle::DoGetTabSize()
    4169             : {
    4170           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4171           0 :   SetValueToCoord(val, StyleText()->mTabSize, true);
    4172           0 :   return val.forget();
    4173             : }
    4174             : 
    4175             : already_AddRefed<CSSValue>
    4176           0 : nsComputedDOMStyle::DoGetLetterSpacing()
    4177             : {
    4178           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4179           0 :   SetValueToCoord(val, StyleText()->mLetterSpacing, false);
    4180           0 :   return val.forget();
    4181             : }
    4182             : 
    4183             : already_AddRefed<CSSValue>
    4184           0 : nsComputedDOMStyle::DoGetWordSpacing()
    4185             : {
    4186           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4187           0 :   SetValueToCoord(val, StyleText()->mWordSpacing, false);
    4188           0 :   return val.forget();
    4189             : }
    4190             : 
    4191             : already_AddRefed<CSSValue>
    4192           0 : nsComputedDOMStyle::DoGetWhiteSpace()
    4193             : {
    4194           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4195           0 :   val->SetIdent(
    4196           0 :     nsCSSProps::ValueToKeywordEnum(StyleText()->mWhiteSpace,
    4197           0 :                                    nsCSSProps::kWhitespaceKTable));
    4198           0 :   return val.forget();
    4199             : }
    4200             : 
    4201             : already_AddRefed<CSSValue>
    4202           0 : nsComputedDOMStyle::DoGetWindowDragging()
    4203             : {
    4204           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4205           0 :   val->SetIdent(
    4206           0 :     nsCSSProps::ValueToKeywordEnum(StyleUIReset()->mWindowDragging,
    4207           0 :                                    nsCSSProps::kWindowDraggingKTable));
    4208           0 :   return val.forget();
    4209             : }
    4210             : 
    4211             : already_AddRefed<CSSValue>
    4212           0 : nsComputedDOMStyle::DoGetWindowShadow()
    4213             : {
    4214           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4215           0 :   val->SetIdent(
    4216           0 :     nsCSSProps::ValueToKeywordEnum(StyleUIReset()->mWindowShadow,
    4217           0 :                                    nsCSSProps::kWindowShadowKTable));
    4218           0 :   return val.forget();
    4219             : }
    4220             : 
    4221             : already_AddRefed<CSSValue>
    4222           0 : nsComputedDOMStyle::DoGetWindowOpacity()
    4223             : {
    4224           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4225           0 :   val->SetNumber(StyleUIReset()->mWindowOpacity);
    4226           0 :   return val.forget();
    4227             : }
    4228             : 
    4229             : already_AddRefed<CSSValue>
    4230           0 : nsComputedDOMStyle::DoGetWindowTransform()
    4231             : {
    4232           0 :   const nsStyleUIReset* uiReset = StyleUIReset();
    4233           0 :   return GetTransformValue(uiReset->mSpecifiedWindowTransform);
    4234             : }
    4235             : 
    4236             : already_AddRefed<CSSValue>
    4237           0 : nsComputedDOMStyle::DoGetWindowTransformOrigin()
    4238             : {
    4239           0 :   RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false);
    4240             : 
    4241           0 :   const nsStyleUIReset* uiReset = StyleUIReset();
    4242             : 
    4243           0 :   RefPtr<nsROCSSPrimitiveValue> originX = new nsROCSSPrimitiveValue;
    4244           0 :   SetValueToCoord(originX, uiReset->mWindowTransformOrigin[0], false,
    4245           0 :                   &nsComputedDOMStyle::GetFrameBoundsWidthForTransform);
    4246           0 :   valueList->AppendCSSValue(originX.forget());
    4247             : 
    4248           0 :   RefPtr<nsROCSSPrimitiveValue> originY = new nsROCSSPrimitiveValue;
    4249           0 :   SetValueToCoord(originY, uiReset->mWindowTransformOrigin[1], false,
    4250           0 :                   &nsComputedDOMStyle::GetFrameBoundsHeightForTransform);
    4251           0 :   valueList->AppendCSSValue(originY.forget());
    4252             : 
    4253           0 :   return valueList.forget();
    4254             : }
    4255             : 
    4256             : already_AddRefed<CSSValue>
    4257           0 : nsComputedDOMStyle::DoGetWordBreak()
    4258             : {
    4259           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4260           0 :   val->SetIdent(
    4261           0 :     nsCSSProps::ValueToKeywordEnum(StyleText()->mWordBreak,
    4262           0 :                                    nsCSSProps::kWordBreakKTable));
    4263           0 :   return val.forget();
    4264             : }
    4265             : 
    4266             : already_AddRefed<CSSValue>
    4267           0 : nsComputedDOMStyle::DoGetOverflowWrap()
    4268             : {
    4269           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4270           0 :   val->SetIdent(
    4271           0 :     nsCSSProps::ValueToKeywordEnum(StyleText()->mOverflowWrap,
    4272           0 :                                    nsCSSProps::kOverflowWrapKTable));
    4273           0 :   return val.forget();
    4274             : }
    4275             : 
    4276             : already_AddRefed<CSSValue>
    4277           0 : nsComputedDOMStyle::DoGetHyphens()
    4278             : {
    4279           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4280           0 :   val->SetIdent(
    4281           0 :     nsCSSProps::ValueToKeywordEnum(StyleText()->mHyphens,
    4282           0 :                                    nsCSSProps::kHyphensKTable));
    4283           0 :   return val.forget();
    4284             : }
    4285             : 
    4286             : already_AddRefed<CSSValue>
    4287           0 : nsComputedDOMStyle::DoGetWebkitTextFillColor()
    4288             : {
    4289           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4290           0 :   SetValueFromComplexColor(val, StyleText()->mWebkitTextFillColor);
    4291           0 :   return val.forget();
    4292             : }
    4293             : 
    4294             : already_AddRefed<CSSValue>
    4295           0 : nsComputedDOMStyle::DoGetWebkitTextStrokeColor()
    4296             : {
    4297           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4298           0 :   SetValueFromComplexColor(val, StyleText()->mWebkitTextStrokeColor);
    4299           0 :   return val.forget();
    4300             : }
    4301             : 
    4302             : already_AddRefed<CSSValue>
    4303           0 : nsComputedDOMStyle::DoGetWebkitTextStrokeWidth()
    4304             : {
    4305           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4306           0 :   val->SetAppUnits(StyleText()->mWebkitTextStrokeWidth);
    4307           0 :   return val.forget();
    4308             : }
    4309             : 
    4310             : already_AddRefed<CSSValue>
    4311           0 : nsComputedDOMStyle::DoGetPointerEvents()
    4312             : {
    4313           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4314           0 :   val->SetIdent(
    4315           0 :     nsCSSProps::ValueToKeywordEnum(StyleUserInterface()->mPointerEvents,
    4316           0 :                                    nsCSSProps::kPointerEventsKTable));
    4317           0 :   return val.forget();
    4318             : }
    4319             : 
    4320             : already_AddRefed<CSSValue>
    4321           0 : nsComputedDOMStyle::DoGetVisibility()
    4322             : {
    4323           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4324           0 :   val->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleVisibility()->mVisible,
    4325           0 :                                                nsCSSProps::kVisibilityKTable));
    4326           0 :   return val.forget();
    4327             : }
    4328             : 
    4329             : already_AddRefed<CSSValue>
    4330           0 : nsComputedDOMStyle::DoGetWritingMode()
    4331             : {
    4332           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4333           0 :   val->SetIdent(
    4334           0 :     nsCSSProps::ValueToKeywordEnum(StyleVisibility()->mWritingMode,
    4335           0 :                                    nsCSSProps::kWritingModeKTable));
    4336           0 :   return val.forget();
    4337             : }
    4338             : 
    4339             : already_AddRefed<CSSValue>
    4340           1 : nsComputedDOMStyle::DoGetDirection()
    4341             : {
    4342           2 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4343           1 :   val->SetIdent(
    4344           1 :     nsCSSProps::ValueToKeywordEnum(StyleVisibility()->mDirection,
    4345           1 :                                    nsCSSProps::kDirectionKTable));
    4346           2 :   return val.forget();
    4347             : }
    4348             : 
    4349             : static_assert(NS_STYLE_UNICODE_BIDI_NORMAL == 0,
    4350             :               "unicode-bidi style constants not as expected");
    4351             : 
    4352             : already_AddRefed<CSSValue>
    4353           0 : nsComputedDOMStyle::DoGetUnicodeBidi()
    4354             : {
    4355           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4356           0 :   val->SetIdent(
    4357           0 :     nsCSSProps::ValueToKeywordEnum(StyleTextReset()->mUnicodeBidi,
    4358           0 :                                    nsCSSProps::kUnicodeBidiKTable));
    4359           0 :   return val.forget();
    4360             : }
    4361             : 
    4362             : already_AddRefed<CSSValue>
    4363           0 : nsComputedDOMStyle::DoGetCaretColor()
    4364             : {
    4365           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4366           0 :   SetValueFromComplexColor(val, StyleUserInterface()->mCaretColor);
    4367           0 :   return val.forget();
    4368             : }
    4369             : 
    4370             : already_AddRefed<CSSValue>
    4371           0 : nsComputedDOMStyle::DoGetCursor()
    4372             : {
    4373           0 :   RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(true);
    4374             : 
    4375           0 :   const nsStyleUserInterface *ui = StyleUserInterface();
    4376             : 
    4377           0 :   for (const nsCursorImage& item : ui->mCursorImages) {
    4378           0 :     RefPtr<nsDOMCSSValueList> itemList = GetROCSSValueList(false);
    4379             : 
    4380           0 :     RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4381           0 :     SetValueToURLValue(item.mImage->GetImageValue(), val);
    4382           0 :     itemList->AppendCSSValue(val.forget());
    4383             : 
    4384           0 :     if (item.mHaveHotspot) {
    4385           0 :       RefPtr<nsROCSSPrimitiveValue> valX = new nsROCSSPrimitiveValue;
    4386           0 :       RefPtr<nsROCSSPrimitiveValue> valY = new nsROCSSPrimitiveValue;
    4387             : 
    4388           0 :       valX->SetNumber(item.mHotspotX);
    4389           0 :       valY->SetNumber(item.mHotspotY);
    4390             : 
    4391           0 :       itemList->AppendCSSValue(valX.forget());
    4392           0 :       itemList->AppendCSSValue(valY.forget());
    4393             :     }
    4394           0 :     valueList->AppendCSSValue(itemList.forget());
    4395             :   }
    4396             : 
    4397           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4398           0 :   val->SetIdent(nsCSSProps::ValueToKeywordEnum(ui->mCursor,
    4399           0 :                                                nsCSSProps::kCursorKTable));
    4400           0 :   valueList->AppendCSSValue(val.forget());
    4401           0 :   return valueList.forget();
    4402             : }
    4403             : 
    4404             : already_AddRefed<CSSValue>
    4405           0 : nsComputedDOMStyle::DoGetAppearance()
    4406             : {
    4407           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4408           0 :   val->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mAppearance,
    4409           0 :                                                nsCSSProps::kAppearanceKTable));
    4410           0 :   return val.forget();
    4411             : }
    4412             : 
    4413             : 
    4414             : already_AddRefed<CSSValue>
    4415           0 : nsComputedDOMStyle::DoGetBoxAlign()
    4416             : {
    4417           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4418           0 :   val->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleXUL()->mBoxAlign,
    4419           0 :                                                nsCSSProps::kBoxAlignKTable));
    4420           0 :   return val.forget();
    4421             : }
    4422             : 
    4423             : already_AddRefed<CSSValue>
    4424           0 : nsComputedDOMStyle::DoGetBoxDirection()
    4425             : {
    4426           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4427           0 :   val->SetIdent(
    4428           0 :     nsCSSProps::ValueToKeywordEnum(StyleXUL()->mBoxDirection,
    4429           0 :                                    nsCSSProps::kBoxDirectionKTable));
    4430           0 :   return val.forget();
    4431             : }
    4432             : 
    4433             : already_AddRefed<CSSValue>
    4434           0 : nsComputedDOMStyle::DoGetBoxFlex()
    4435             : {
    4436           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4437           0 :   val->SetNumber(StyleXUL()->mBoxFlex);
    4438           0 :   return val.forget();
    4439             : }
    4440             : 
    4441             : already_AddRefed<CSSValue>
    4442           0 : nsComputedDOMStyle::DoGetBoxOrdinalGroup()
    4443             : {
    4444           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4445           0 :   val->SetNumber(StyleXUL()->mBoxOrdinal);
    4446           0 :   return val.forget();
    4447             : }
    4448             : 
    4449             : already_AddRefed<CSSValue>
    4450           0 : nsComputedDOMStyle::DoGetBoxOrient()
    4451             : {
    4452           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4453           0 :   val->SetIdent(
    4454           0 :     nsCSSProps::ValueToKeywordEnum(StyleXUL()->mBoxOrient,
    4455           0 :                                    nsCSSProps::kBoxOrientKTable));
    4456           0 :   return val.forget();
    4457             : }
    4458             : 
    4459             : already_AddRefed<CSSValue>
    4460           0 : nsComputedDOMStyle::DoGetBoxPack()
    4461             : {
    4462           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4463           0 :   val->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleXUL()->mBoxPack,
    4464           0 :                                                nsCSSProps::kBoxPackKTable));
    4465           0 :   return val.forget();
    4466             : }
    4467             : 
    4468             : already_AddRefed<CSSValue>
    4469           0 : nsComputedDOMStyle::DoGetBoxSizing()
    4470             : {
    4471           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4472           0 :   val->SetIdent(
    4473           0 :     nsCSSProps::ValueToKeywordEnum(StylePosition()->mBoxSizing,
    4474           0 :                                    nsCSSProps::kBoxSizingKTable));
    4475           0 :   return val.forget();
    4476             : }
    4477             : 
    4478             : /* Border image properties */
    4479             : 
    4480             : already_AddRefed<CSSValue>
    4481           0 : nsComputedDOMStyle::DoGetBorderImageSource()
    4482             : {
    4483           0 :   const nsStyleBorder* border = StyleBorder();
    4484             : 
    4485           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4486           0 :   const nsStyleImage& image = border->mBorderImageSource;
    4487           0 :   SetValueToStyleImage(image, val);
    4488             : 
    4489           0 :   return val.forget();
    4490             : }
    4491             : 
    4492             : void
    4493           0 : nsComputedDOMStyle::AppendFourSideCoordValues(nsDOMCSSValueList* aList,
    4494             :                                               const nsStyleSides& aValues)
    4495             : {
    4496           0 :   const nsStyleCoord& top = aValues.Get(eSideTop);
    4497           0 :   const nsStyleCoord& right = aValues.Get(eSideRight);
    4498           0 :   const nsStyleCoord& bottom = aValues.Get(eSideBottom);
    4499           0 :   const nsStyleCoord& left = aValues.Get(eSideLeft);
    4500             : 
    4501           0 :   auto appendValue = [this, aList](const nsStyleCoord& value) {
    4502           0 :     RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4503           0 :     SetValueToCoord(val, value, true);
    4504           0 :     aList->AppendCSSValue(val.forget());
    4505           0 :   };
    4506           0 :   appendValue(top);
    4507           0 :   if (top != right || top != bottom || top != left) {
    4508           0 :     appendValue(right);
    4509           0 :     if (top != bottom || right != left) {
    4510           0 :       appendValue(bottom);
    4511           0 :       if (right != left) {
    4512           0 :         appendValue(left);
    4513             :       }
    4514             :     }
    4515             :   }
    4516           0 : }
    4517             : 
    4518             : already_AddRefed<CSSValue>
    4519           0 : nsComputedDOMStyle::DoGetBorderImageSlice()
    4520             : {
    4521           0 :   const nsStyleBorder* border = StyleBorder();
    4522           0 :   RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false);
    4523           0 :   AppendFourSideCoordValues(valueList, border->mBorderImageSlice);
    4524             : 
    4525             :   // Fill keyword.
    4526           0 :   if (NS_STYLE_BORDER_IMAGE_SLICE_FILL == border->mBorderImageFill) {
    4527           0 :     RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4528           0 :     val->SetIdent(eCSSKeyword_fill);
    4529           0 :     valueList->AppendCSSValue(val.forget());
    4530             :   }
    4531             : 
    4532           0 :   return valueList.forget();
    4533             : }
    4534             : 
    4535             : already_AddRefed<CSSValue>
    4536           0 : nsComputedDOMStyle::DoGetBorderImageWidth()
    4537             : {
    4538           0 :   const nsStyleBorder* border = StyleBorder();
    4539           0 :   RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false);
    4540           0 :   AppendFourSideCoordValues(valueList, border->mBorderImageWidth);
    4541           0 :   return valueList.forget();
    4542             : }
    4543             : 
    4544             : already_AddRefed<CSSValue>
    4545           0 : nsComputedDOMStyle::DoGetBorderImageOutset()
    4546             : {
    4547           0 :   const nsStyleBorder* border = StyleBorder();
    4548           0 :   RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false);
    4549           0 :   AppendFourSideCoordValues(valueList, border->mBorderImageOutset);
    4550           0 :   return valueList.forget();
    4551             : }
    4552             : 
    4553             : already_AddRefed<CSSValue>
    4554           0 : nsComputedDOMStyle::DoGetBorderImageRepeat()
    4555             : {
    4556           0 :   RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false);
    4557             : 
    4558           0 :   const nsStyleBorder* border = StyleBorder();
    4559             : 
    4560             :   // horizontal repeat
    4561           0 :   RefPtr<nsROCSSPrimitiveValue> valX = new nsROCSSPrimitiveValue;
    4562           0 :   valX->SetIdent(
    4563           0 :     nsCSSProps::ValueToKeywordEnum(border->mBorderImageRepeatH,
    4564           0 :                                    nsCSSProps::kBorderImageRepeatKTable));
    4565           0 :   valueList->AppendCSSValue(valX.forget());
    4566             : 
    4567             :   // vertical repeat
    4568           0 :   RefPtr<nsROCSSPrimitiveValue> valY = new nsROCSSPrimitiveValue;
    4569           0 :   valY->SetIdent(
    4570           0 :     nsCSSProps::ValueToKeywordEnum(border->mBorderImageRepeatV,
    4571           0 :                                    nsCSSProps::kBorderImageRepeatKTable));
    4572           0 :   valueList->AppendCSSValue(valY.forget());
    4573           0 :   return valueList.forget();
    4574             : }
    4575             : 
    4576             : already_AddRefed<CSSValue>
    4577           0 : nsComputedDOMStyle::DoGetFlexBasis()
    4578             : {
    4579           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4580             : 
    4581             :   // XXXdholbert We could make this more automagic and resolve percentages
    4582             :   // if we wanted, by passing in a PercentageBaseGetter instead of nullptr
    4583             :   // below.  Logic would go like this:
    4584             :   //   if (i'm a flex item) {
    4585             :   //     if (my flex container is horizontal) {
    4586             :   //       percentageBaseGetter = &nsComputedDOMStyle::GetCBContentWidth;
    4587             :   //     } else {
    4588             :   //       percentageBaseGetter = &nsComputedDOMStyle::GetCBContentHeight;
    4589             :   //     }
    4590             :   //   }
    4591             : 
    4592           0 :   SetValueToCoord(val, StylePosition()->mFlexBasis, true,
    4593           0 :                   nullptr, nsCSSProps::kWidthKTable);
    4594           0 :   return val.forget();
    4595             : }
    4596             : 
    4597             : already_AddRefed<CSSValue>
    4598           0 : nsComputedDOMStyle::DoGetFlexDirection()
    4599             : {
    4600           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4601           0 :   val->SetIdent(
    4602           0 :     nsCSSProps::ValueToKeywordEnum(StylePosition()->mFlexDirection,
    4603           0 :                                    nsCSSProps::kFlexDirectionKTable));
    4604           0 :   return val.forget();
    4605             : }
    4606             : 
    4607             : already_AddRefed<CSSValue>
    4608           0 : nsComputedDOMStyle::DoGetFlexGrow()
    4609             : {
    4610           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4611           0 :   val->SetNumber(StylePosition()->mFlexGrow);
    4612           0 :   return val.forget();
    4613             : }
    4614             : 
    4615             : already_AddRefed<CSSValue>
    4616           0 : nsComputedDOMStyle::DoGetFlexShrink()
    4617             : {
    4618           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4619           0 :   val->SetNumber(StylePosition()->mFlexShrink);
    4620           0 :   return val.forget();
    4621             : }
    4622             : 
    4623             : already_AddRefed<CSSValue>
    4624           0 : nsComputedDOMStyle::DoGetFlexWrap()
    4625             : {
    4626           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4627           0 :   val->SetIdent(
    4628           0 :     nsCSSProps::ValueToKeywordEnum(StylePosition()->mFlexWrap,
    4629           0 :                                    nsCSSProps::kFlexWrapKTable));
    4630           0 :   return val.forget();
    4631             : }
    4632             : 
    4633             : already_AddRefed<CSSValue>
    4634           0 : nsComputedDOMStyle::DoGetOrder()
    4635             : {
    4636           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4637           0 :   val->SetNumber(StylePosition()->mOrder);
    4638           0 :   return val.forget();
    4639             : }
    4640             : 
    4641             : already_AddRefed<CSSValue>
    4642           0 : nsComputedDOMStyle::DoGetAlignContent()
    4643             : {
    4644           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4645           0 :   nsAutoString str;
    4646           0 :   auto align = StylePosition()->mAlignContent;
    4647           0 :   nsCSSValue::AppendAlignJustifyValueToString(align & NS_STYLE_ALIGN_ALL_BITS, str);
    4648           0 :   auto fallback = align >> NS_STYLE_ALIGN_ALL_SHIFT;
    4649           0 :   if (fallback) {
    4650           0 :     str.Append(' ');
    4651           0 :     nsCSSValue::AppendAlignJustifyValueToString(fallback, str);
    4652             :   }
    4653           0 :   val->SetString(str);
    4654           0 :   return val.forget();
    4655             : }
    4656             : 
    4657             : already_AddRefed<CSSValue>
    4658           0 : nsComputedDOMStyle::DoGetAlignItems()
    4659             : {
    4660           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4661           0 :   nsAutoString str;
    4662           0 :   auto align = StylePosition()->mAlignItems;
    4663           0 :   nsCSSValue::AppendAlignJustifyValueToString(align, str);
    4664           0 :   val->SetString(str);
    4665           0 :   return val.forget();
    4666             : }
    4667             : 
    4668             : already_AddRefed<CSSValue>
    4669           0 : nsComputedDOMStyle::DoGetAlignSelf()
    4670             : {
    4671           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4672           0 :   nsAutoString str;
    4673           0 :   auto align = StylePosition()->mAlignSelf;
    4674           0 :   nsCSSValue::AppendAlignJustifyValueToString(align, str);
    4675           0 :   val->SetString(str);
    4676           0 :   return val.forget();
    4677             : }
    4678             : 
    4679             : already_AddRefed<CSSValue>
    4680           0 : nsComputedDOMStyle::DoGetJustifyContent()
    4681             : {
    4682           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4683           0 :   nsAutoString str;
    4684           0 :   auto justify = StylePosition()->mJustifyContent;
    4685           0 :   nsCSSValue::AppendAlignJustifyValueToString(justify & NS_STYLE_JUSTIFY_ALL_BITS, str);
    4686           0 :   auto fallback = justify >> NS_STYLE_JUSTIFY_ALL_SHIFT;
    4687           0 :   if (fallback) {
    4688           0 :     MOZ_ASSERT(nsCSSProps::ValueToKeywordEnum(fallback & ~NS_STYLE_JUSTIFY_FLAG_BITS,
    4689             :                                               nsCSSProps::kAlignSelfPosition)
    4690             :                != eCSSKeyword_UNKNOWN, "unknown fallback value");
    4691           0 :     str.Append(' ');
    4692           0 :     nsCSSValue::AppendAlignJustifyValueToString(fallback, str);
    4693             :   }
    4694           0 :   val->SetString(str);
    4695           0 :   return val.forget();
    4696             : }
    4697             : 
    4698             : already_AddRefed<CSSValue>
    4699           0 : nsComputedDOMStyle::DoGetJustifyItems()
    4700             : {
    4701           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4702           0 :   nsAutoString str;
    4703             :   auto justify =
    4704           0 :     StylePosition()->ComputedJustifyItems(mStyleContext->GetParentAllowServo());
    4705           0 :   nsCSSValue::AppendAlignJustifyValueToString(justify, str);
    4706           0 :   val->SetString(str);
    4707           0 :   return val.forget();
    4708             : }
    4709             : 
    4710             : already_AddRefed<CSSValue>
    4711           0 : nsComputedDOMStyle::DoGetJustifySelf()
    4712             : {
    4713           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4714           0 :   nsAutoString str;
    4715           0 :   auto justify = StylePosition()->mJustifySelf;
    4716           0 :   nsCSSValue::AppendAlignJustifyValueToString(justify, str);
    4717           0 :   val->SetString(str);
    4718           0 :   return val.forget();
    4719             : }
    4720             : 
    4721             : already_AddRefed<CSSValue>
    4722           0 : nsComputedDOMStyle::DoGetFloatEdge()
    4723             : {
    4724           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4725           0 :   val->SetIdent(
    4726           0 :     nsCSSProps::ValueToKeywordEnum(uint8_t(StyleBorder()->mFloatEdge),
    4727           0 :                                    nsCSSProps::kFloatEdgeKTable));
    4728           0 :   return val.forget();
    4729             : }
    4730             : 
    4731             : already_AddRefed<CSSValue>
    4732           0 : nsComputedDOMStyle::DoGetForceBrokenImageIcon()
    4733             : {
    4734           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4735           0 :   val->SetNumber(StyleUIReset()->mForceBrokenImageIcon);
    4736           0 :   return val.forget();
    4737             : }
    4738             : 
    4739             : already_AddRefed<CSSValue>
    4740           0 : nsComputedDOMStyle::DoGetImageOrientation()
    4741             : {
    4742           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4743           0 :   nsAutoString string;
    4744           0 :   nsStyleImageOrientation orientation = StyleVisibility()->mImageOrientation;
    4745             : 
    4746           0 :   if (orientation.IsFromImage()) {
    4747           0 :     string.AppendLiteral("from-image");
    4748             :   } else {
    4749           0 :     nsStyleUtil::AppendAngleValue(orientation.AngleAsCoord(), string);
    4750             : 
    4751           0 :     if (orientation.IsFlipped()) {
    4752           0 :       string.AppendLiteral(" flip");
    4753             :     }
    4754             :   }
    4755             : 
    4756           0 :   val->SetString(string);
    4757           0 :   return val.forget();
    4758             : }
    4759             : 
    4760             : already_AddRefed<CSSValue>
    4761           0 : nsComputedDOMStyle::DoGetIMEMode()
    4762             : {
    4763           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4764           0 :   val->SetIdent(
    4765           0 :     nsCSSProps::ValueToKeywordEnum(StyleUIReset()->mIMEMode,
    4766           0 :                                    nsCSSProps::kIMEModeKTable));
    4767           0 :   return val.forget();
    4768             : }
    4769             : 
    4770             : already_AddRefed<CSSValue>
    4771           0 : nsComputedDOMStyle::DoGetUserFocus()
    4772             : {
    4773           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4774           0 :   val->SetIdent(
    4775           0 :     nsCSSProps::ValueToKeywordEnum(uint8_t(StyleUserInterface()->mUserFocus),
    4776           0 :                                    nsCSSProps::kUserFocusKTable));
    4777           0 :   return val.forget();
    4778             : }
    4779             : 
    4780             : already_AddRefed<CSSValue>
    4781           0 : nsComputedDOMStyle::DoGetUserInput()
    4782             : {
    4783           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4784           0 :   val->SetIdent(
    4785           0 :     nsCSSProps::ValueToKeywordEnum(StyleUserInterface()->mUserInput,
    4786           0 :                                    nsCSSProps::kUserInputKTable));
    4787           0 :   return val.forget();
    4788             : }
    4789             : 
    4790             : already_AddRefed<CSSValue>
    4791           0 : nsComputedDOMStyle::DoGetUserModify()
    4792             : {
    4793           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4794           0 :   val->SetIdent(
    4795           0 :     nsCSSProps::ValueToKeywordEnum(StyleUserInterface()->mUserModify,
    4796           0 :                                    nsCSSProps::kUserModifyKTable));
    4797           0 :   return val.forget();
    4798             : }
    4799             : 
    4800             : already_AddRefed<CSSValue>
    4801           0 : nsComputedDOMStyle::DoGetUserSelect()
    4802             : {
    4803           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4804           0 :   val->SetIdent(
    4805           0 :     nsCSSProps::ValueToKeywordEnum(StyleUIReset()->mUserSelect,
    4806           0 :                                    nsCSSProps::kUserSelectKTable));
    4807           0 :   return val.forget();
    4808             : }
    4809             : 
    4810             : already_AddRefed<CSSValue>
    4811           0 : nsComputedDOMStyle::DoGetDisplay()
    4812             : {
    4813           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4814           0 :   val->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mDisplay,
    4815           0 :                                                nsCSSProps::kDisplayKTable));
    4816           0 :   return val.forget();
    4817             : }
    4818             : 
    4819             : already_AddRefed<CSSValue>
    4820           0 : nsComputedDOMStyle::DoGetContain()
    4821             : {
    4822           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4823             : 
    4824           0 :   int32_t mask = StyleDisplay()->mContain;
    4825             : 
    4826           0 :   if (mask == 0) {
    4827           0 :     val->SetIdent(eCSSKeyword_none);
    4828           0 :   } else if (mask & NS_STYLE_CONTAIN_STRICT) {
    4829           0 :     NS_ASSERTION(mask == (NS_STYLE_CONTAIN_STRICT | NS_STYLE_CONTAIN_ALL_BITS),
    4830             :                  "contain: strict should imply contain: layout style paint");
    4831           0 :     val->SetIdent(eCSSKeyword_strict);
    4832             :   } else {
    4833           0 :     nsAutoString valueStr;
    4834             : 
    4835             :     nsStyleUtil::AppendBitmaskCSSValue(eCSSProperty_contain,
    4836             :                                        mask, NS_STYLE_CONTAIN_LAYOUT,
    4837           0 :                                        NS_STYLE_CONTAIN_PAINT, valueStr);
    4838           0 :     val->SetString(valueStr);
    4839             :   }
    4840             : 
    4841           0 :   return val.forget();
    4842             : }
    4843             : 
    4844             : already_AddRefed<CSSValue>
    4845           0 : nsComputedDOMStyle::DoGetPosition()
    4846             : {
    4847           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4848           0 :   val->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mPosition,
    4849           0 :                                                nsCSSProps::kPositionKTable));
    4850           0 :   return val.forget();
    4851             : }
    4852             : 
    4853             : already_AddRefed<CSSValue>
    4854           0 : nsComputedDOMStyle::DoGetClip()
    4855             : {
    4856           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4857             : 
    4858           0 :   const nsStyleEffects* effects = StyleEffects();
    4859             : 
    4860           0 :   if (effects->mClipFlags == NS_STYLE_CLIP_AUTO) {
    4861           0 :     val->SetIdent(eCSSKeyword_auto);
    4862             :   } else {
    4863             :     // create the cssvalues for the sides, stick them in the rect object
    4864           0 :     nsROCSSPrimitiveValue *topVal    = new nsROCSSPrimitiveValue;
    4865           0 :     nsROCSSPrimitiveValue *rightVal  = new nsROCSSPrimitiveValue;
    4866           0 :     nsROCSSPrimitiveValue *bottomVal = new nsROCSSPrimitiveValue;
    4867           0 :     nsROCSSPrimitiveValue *leftVal   = new nsROCSSPrimitiveValue;
    4868             :     nsDOMCSSRect * domRect = new nsDOMCSSRect(topVal, rightVal,
    4869           0 :                                               bottomVal, leftVal);
    4870           0 :     if (effects->mClipFlags & NS_STYLE_CLIP_TOP_AUTO) {
    4871           0 :       topVal->SetIdent(eCSSKeyword_auto);
    4872             :     } else {
    4873           0 :       topVal->SetAppUnits(effects->mClip.y);
    4874             :     }
    4875             : 
    4876           0 :     if (effects->mClipFlags & NS_STYLE_CLIP_RIGHT_AUTO) {
    4877           0 :       rightVal->SetIdent(eCSSKeyword_auto);
    4878             :     } else {
    4879           0 :       rightVal->SetAppUnits(effects->mClip.width + effects->mClip.x);
    4880             :     }
    4881             : 
    4882           0 :     if (effects->mClipFlags & NS_STYLE_CLIP_BOTTOM_AUTO) {
    4883           0 :       bottomVal->SetIdent(eCSSKeyword_auto);
    4884             :     } else {
    4885           0 :       bottomVal->SetAppUnits(effects->mClip.height + effects->mClip.y);
    4886             :     }
    4887             : 
    4888           0 :     if (effects->mClipFlags & NS_STYLE_CLIP_LEFT_AUTO) {
    4889           0 :       leftVal->SetIdent(eCSSKeyword_auto);
    4890             :     } else {
    4891           0 :       leftVal->SetAppUnits(effects->mClip.x);
    4892             :     }
    4893           0 :     val->SetRect(domRect);
    4894             :   }
    4895             : 
    4896           0 :   return val.forget();
    4897             : }
    4898             : 
    4899             : already_AddRefed<CSSValue>
    4900           0 : nsComputedDOMStyle::DoGetWillChange()
    4901             : {
    4902           0 :   const nsCOMArray<nsIAtom>& willChange = StyleDisplay()->mWillChange;
    4903             : 
    4904           0 :   if (willChange.IsEmpty()) {
    4905           0 :     RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4906           0 :     val->SetIdent(eCSSKeyword_auto);
    4907           0 :     return val.forget();
    4908             :   }
    4909             : 
    4910           0 :   RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(true);
    4911           0 :   for (const nsIAtom* ident : willChange) {
    4912           0 :     RefPtr<nsROCSSPrimitiveValue> property = new nsROCSSPrimitiveValue;
    4913           0 :     property->SetString(nsDependentAtomString(ident));
    4914           0 :     valueList->AppendCSSValue(property.forget());
    4915             :   }
    4916             : 
    4917           0 :   return valueList.forget();
    4918             : }
    4919             : 
    4920             : already_AddRefed<CSSValue>
    4921           0 : nsComputedDOMStyle::DoGetOverflow()
    4922             : {
    4923           0 :   const nsStyleDisplay* display = StyleDisplay();
    4924             : 
    4925           0 :   if (display->mOverflowX != display->mOverflowY) {
    4926             :     // No value to return.  We can't express this combination of
    4927             :     // values as a shorthand.
    4928           0 :     return nullptr;
    4929             :   }
    4930             : 
    4931           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4932           0 :   val->SetIdent(nsCSSProps::ValueToKeywordEnum(display->mOverflowX,
    4933           0 :                                                nsCSSProps::kOverflowKTable));
    4934           0 :   return val.forget();
    4935             : }
    4936             : 
    4937             : already_AddRefed<CSSValue>
    4938           0 : nsComputedDOMStyle::DoGetOverflowX()
    4939             : {
    4940           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4941           0 :   val->SetIdent(
    4942           0 :     nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mOverflowX,
    4943           0 :                                    nsCSSProps::kOverflowSubKTable));
    4944           0 :   return val.forget();
    4945             : }
    4946             : 
    4947             : already_AddRefed<CSSValue>
    4948           0 : nsComputedDOMStyle::DoGetOverflowY()
    4949             : {
    4950           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4951           0 :   val->SetIdent(
    4952           0 :     nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mOverflowY,
    4953           0 :                                    nsCSSProps::kOverflowSubKTable));
    4954           0 :   return val.forget();
    4955             : }
    4956             : 
    4957             : already_AddRefed<CSSValue>
    4958           0 : nsComputedDOMStyle::DoGetOverflowClipBox()
    4959             : {
    4960           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4961           0 :   val->SetIdent(
    4962           0 :     nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mOverflowClipBox,
    4963           0 :                                    nsCSSProps::kOverflowClipBoxKTable));
    4964           0 :   return val.forget();
    4965             : }
    4966             : 
    4967             : already_AddRefed<CSSValue>
    4968           0 : nsComputedDOMStyle::DoGetResize()
    4969             : {
    4970           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4971           0 :   val->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mResize,
    4972           0 :                                                nsCSSProps::kResizeKTable));
    4973           0 :   return val.forget();
    4974             : }
    4975             : 
    4976             : 
    4977             : already_AddRefed<CSSValue>
    4978           0 : nsComputedDOMStyle::DoGetPageBreakAfter()
    4979             : {
    4980           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4981             : 
    4982           0 :   const nsStyleDisplay *display = StyleDisplay();
    4983             : 
    4984           0 :   if (display->mBreakAfter) {
    4985           0 :     val->SetIdent(eCSSKeyword_always);
    4986             :   } else {
    4987           0 :     val->SetIdent(eCSSKeyword_auto);
    4988             :   }
    4989             : 
    4990           0 :   return val.forget();
    4991             : }
    4992             : 
    4993             : already_AddRefed<CSSValue>
    4994           0 : nsComputedDOMStyle::DoGetPageBreakBefore()
    4995             : {
    4996           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    4997             : 
    4998           0 :   const nsStyleDisplay *display = StyleDisplay();
    4999             : 
    5000           0 :   if (display->mBreakBefore) {
    5001           0 :     val->SetIdent(eCSSKeyword_always);
    5002             :   } else {
    5003           0 :     val->SetIdent(eCSSKeyword_auto);
    5004             :   }
    5005             : 
    5006           0 :   return val.forget();
    5007             : }
    5008             : 
    5009             : already_AddRefed<CSSValue>
    5010           0 : nsComputedDOMStyle::DoGetPageBreakInside()
    5011             : {
    5012           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    5013           0 :   val->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mBreakInside,
    5014           0 :                                                nsCSSProps::kPageBreakInsideKTable));
    5015           0 :   return val.forget();
    5016             : }
    5017             : 
    5018             : already_AddRefed<CSSValue>
    5019           0 : nsComputedDOMStyle::DoGetTouchAction()
    5020             : {
    5021           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    5022             : 
    5023           0 :   int32_t intValue = StyleDisplay()->mTouchAction;
    5024             : 
    5025             :   // None and Auto and Manipulation values aren't allowed
    5026             :   // to be in conjunction with other values.
    5027             :   // But there are all checks in CSSParserImpl::ParseTouchAction
    5028           0 :   nsAutoString valueStr;
    5029             :   nsStyleUtil::AppendBitmaskCSSValue(eCSSProperty_touch_action, intValue,
    5030             :     NS_STYLE_TOUCH_ACTION_NONE, NS_STYLE_TOUCH_ACTION_MANIPULATION,
    5031           0 :     valueStr);
    5032           0 :   val->SetString(valueStr);
    5033           0 :   return val.forget();
    5034             : }
    5035             : 
    5036             : already_AddRefed<CSSValue>
    5037           0 : nsComputedDOMStyle::DoGetHeight()
    5038             : {
    5039           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    5040             : 
    5041           0 :   bool calcHeight = false;
    5042             : 
    5043           0 :   if (mInnerFrame) {
    5044           0 :     calcHeight = true;
    5045             : 
    5046           0 :     const nsStyleDisplay* displayData = StyleDisplay();
    5047           0 :     if (displayData->mDisplay == mozilla::StyleDisplay::Inline &&
    5048           0 :         !(mInnerFrame->IsFrameOfType(nsIFrame::eReplaced)) &&
    5049             :         // An outer SVG frame should behave the same as eReplaced in this case
    5050           0 :         !mInnerFrame->IsSVGOuterSVGFrame()) {
    5051             : 
    5052           0 :       calcHeight = false;
    5053             :     }
    5054             :   }
    5055             : 
    5056           0 :   if (calcHeight) {
    5057           0 :     AssertFlushedPendingReflows();
    5058           0 :     nsMargin adjustedValues = GetAdjustedValuesForBoxSizing();
    5059           0 :     val->SetAppUnits(mInnerFrame->GetContentRect().height +
    5060           0 :       adjustedValues.TopBottom());
    5061             :   } else {
    5062           0 :     const nsStylePosition *positionData = StylePosition();
    5063             : 
    5064             :     nscoord minHeight =
    5065           0 :       StyleCoordToNSCoord(positionData->mMinHeight,
    5066           0 :                           &nsComputedDOMStyle::GetCBContentHeight, 0, true);
    5067             : 
    5068             :     nscoord maxHeight =
    5069           0 :       StyleCoordToNSCoord(positionData->mMaxHeight,
    5070             :                           &nsComputedDOMStyle::GetCBContentHeight,
    5071           0 :                           nscoord_MAX, true);
    5072             : 
    5073           0 :     SetValueToCoord(val, positionData->mHeight, true, nullptr,
    5074           0 :                     nsCSSProps::kWidthKTable, minHeight, maxHeight);
    5075             :   }
    5076             : 
    5077           0 :   return val.forget();
    5078             : }
    5079             : 
    5080             : already_AddRefed<CSSValue>
    5081           0 : nsComputedDOMStyle::DoGetWidth()
    5082             : {
    5083           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    5084             : 
    5085           0 :   bool calcWidth = false;
    5086             : 
    5087           0 :   if (mInnerFrame) {
    5088           0 :     calcWidth = true;
    5089             : 
    5090           0 :     const nsStyleDisplay *displayData = StyleDisplay();
    5091           0 :     if (displayData->mDisplay == mozilla::StyleDisplay::Inline &&
    5092           0 :         !(mInnerFrame->IsFrameOfType(nsIFrame::eReplaced)) &&
    5093             :         // An outer SVG frame should behave the same as eReplaced in this case
    5094           0 :         !mInnerFrame->IsSVGOuterSVGFrame()) {
    5095             : 
    5096           0 :       calcWidth = false;
    5097             :     }
    5098             :   }
    5099             : 
    5100           0 :   if (calcWidth) {
    5101           0 :     AssertFlushedPendingReflows();
    5102           0 :     nsMargin adjustedValues = GetAdjustedValuesForBoxSizing();
    5103           0 :     val->SetAppUnits(mInnerFrame->GetContentRect().width +
    5104           0 :       adjustedValues.LeftRight());
    5105             :   } else {
    5106           0 :     const nsStylePosition *positionData = StylePosition();
    5107             : 
    5108             :     nscoord minWidth =
    5109           0 :       StyleCoordToNSCoord(positionData->mMinWidth,
    5110           0 :                           &nsComputedDOMStyle::GetCBContentWidth, 0, true);
    5111             : 
    5112             :     nscoord maxWidth =
    5113           0 :       StyleCoordToNSCoord(positionData->mMaxWidth,
    5114             :                           &nsComputedDOMStyle::GetCBContentWidth,
    5115           0 :                           nscoord_MAX, true);
    5116             : 
    5117           0 :     SetValueToCoord(val, positionData->mWidth, true, nullptr,
    5118           0 :                     nsCSSProps::kWidthKTable, minWidth, maxWidth);
    5119             :   }
    5120             : 
    5121           0 :   return val.forget();
    5122             : }
    5123             : 
    5124             : already_AddRefed<CSSValue>
    5125           0 : nsComputedDOMStyle::DoGetMaxHeight()
    5126             : {
    5127           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    5128           0 :   SetValueToCoord(val, StylePosition()->mMaxHeight, true,
    5129           0 :                   nullptr, nsCSSProps::kWidthKTable);
    5130           0 :   return val.forget();
    5131             : }
    5132             : 
    5133             : already_AddRefed<CSSValue>
    5134           0 : nsComputedDOMStyle::DoGetMaxWidth()
    5135             : {
    5136           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    5137           0 :   SetValueToCoord(val, StylePosition()->mMaxWidth, true,
    5138           0 :                   nullptr, nsCSSProps::kWidthKTable);
    5139           0 :   return val.forget();
    5140             : }
    5141             : 
    5142             : bool
    5143           0 : nsComputedDOMStyle::ShouldHonorMinSizeAutoInAxis(PhysicalAxis aAxis)
    5144             : {
    5145             :   // A {flex,grid} item's min-{width|height} "auto" value gets special
    5146             :   // treatment in getComputedStyle().
    5147             :   // https://drafts.csswg.org/css-flexbox-1/#valdef-min-width-auto
    5148             :   // https://drafts.csswg.org/css-grid/#min-size-auto
    5149             :   // In most cases, "min-{width|height}: auto" is mapped to "0px", unless
    5150             :   // we're a flex item (and the min-size is in the flex container's main
    5151             :   // axis), or we're a grid item, AND we also have overflow:visible.
    5152             : 
    5153             :   // Note: We only need to bother checking one "overflow" subproperty for
    5154             :   // "visible", because a non-"visible" value in either axis would force the
    5155             :   // other axis to also be non-"visible" as well.
    5156             : 
    5157           0 :   if (mOuterFrame) {
    5158           0 :     nsIFrame* containerFrame = mOuterFrame->GetParent();
    5159           0 :     if (containerFrame &&
    5160           0 :         StyleDisplay()->mOverflowX == NS_STYLE_OVERFLOW_VISIBLE) {
    5161           0 :       if (containerFrame->IsFlexContainerFrame() &&
    5162           0 :           (static_cast<nsFlexContainerFrame*>(containerFrame)->IsHorizontal() ==
    5163           0 :            (aAxis == eAxisHorizontal))) {
    5164           0 :         return true;
    5165             :       }
    5166           0 :       if (containerFrame->IsGridContainerFrame()) {
    5167           0 :         return true;
    5168             :       }
    5169             :     }
    5170             :   }
    5171           0 :   return false;
    5172             : }
    5173             : 
    5174             : already_AddRefed<CSSValue>
    5175           0 : nsComputedDOMStyle::DoGetMinHeight()
    5176             : {
    5177           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    5178           0 :   nsStyleCoord minHeight = StylePosition()->mMinHeight;
    5179             : 
    5180           0 :   if (eStyleUnit_Auto == minHeight.GetUnit() &&
    5181           0 :       !ShouldHonorMinSizeAutoInAxis(eAxisVertical)) {
    5182           0 :     minHeight.SetCoordValue(0);
    5183             :   }
    5184             : 
    5185           0 :   SetValueToCoord(val, minHeight, true, nullptr, nsCSSProps::kWidthKTable);
    5186           0 :   return val.forget();
    5187             : }
    5188             : 
    5189             : already_AddRefed<CSSValue>
    5190           0 : nsComputedDOMStyle::DoGetMinWidth()
    5191             : {
    5192           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    5193             : 
    5194           0 :   nsStyleCoord minWidth = StylePosition()->mMinWidth;
    5195             : 
    5196           0 :   if (eStyleUnit_Auto == minWidth.GetUnit() &&
    5197           0 :       !ShouldHonorMinSizeAutoInAxis(eAxisHorizontal)) {
    5198           0 :     minWidth.SetCoordValue(0);
    5199             :   }
    5200             : 
    5201           0 :   SetValueToCoord(val, minWidth, true, nullptr, nsCSSProps::kWidthKTable);
    5202           0 :   return val.forget();
    5203             : }
    5204             : 
    5205             : already_AddRefed<CSSValue>
    5206           0 : nsComputedDOMStyle::DoGetMixBlendMode()
    5207             : {
    5208           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    5209           0 :   val->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleEffects()->mMixBlendMode,
    5210           0 :                                                nsCSSProps::kBlendModeKTable));
    5211           0 :   return val.forget();
    5212             : }
    5213             : 
    5214             : already_AddRefed<CSSValue>
    5215           0 : nsComputedDOMStyle::DoGetIsolation()
    5216             : {
    5217           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    5218           0 :   val->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mIsolation,
    5219           0 :                                                nsCSSProps::kIsolationKTable));
    5220           0 :   return val.forget();
    5221             : }
    5222             : 
    5223             : already_AddRefed<CSSValue>
    5224           0 : nsComputedDOMStyle::DoGetObjectFit()
    5225             : {
    5226           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    5227           0 :   val->SetIdent(nsCSSProps::ValueToKeywordEnum(StylePosition()->mObjectFit,
    5228           0 :                                                nsCSSProps::kObjectFitKTable));
    5229           0 :   return val.forget();
    5230             : }
    5231             : 
    5232             : already_AddRefed<CSSValue>
    5233           0 : nsComputedDOMStyle::DoGetObjectPosition()
    5234             : {
    5235           0 :   RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false);
    5236           0 :   SetValueToPosition(StylePosition()->mObjectPosition, valueList);
    5237           0 :   return valueList.forget();
    5238             : }
    5239             : 
    5240             : already_AddRefed<CSSValue>
    5241           0 : nsComputedDOMStyle::DoGetLeft()
    5242             : {
    5243           0 :   return GetOffsetWidthFor(eSideLeft);
    5244             : }
    5245             : 
    5246             : already_AddRefed<CSSValue>
    5247           0 : nsComputedDOMStyle::DoGetRight()
    5248             : {
    5249           0 :   return GetOffsetWidthFor(eSideRight);
    5250             : }
    5251             : 
    5252             : already_AddRefed<CSSValue>
    5253           0 : nsComputedDOMStyle::DoGetTop()
    5254             : {
    5255           0 :   return GetOffsetWidthFor(eSideTop);
    5256             : }
    5257             : 
    5258             : already_AddRefed<CSSValue>
    5259           0 : nsComputedDOMStyle::GetOffsetWidthFor(mozilla::Side aSide)
    5260             : {
    5261           0 :   const nsStyleDisplay* display = StyleDisplay();
    5262             : 
    5263           0 :   AssertFlushedPendingReflows();
    5264             : 
    5265           0 :   uint8_t position = display->mPosition;
    5266           0 :   if (!mOuterFrame) {
    5267             :     // GetRelativeOffset and GetAbsoluteOffset don't handle elements
    5268             :     // without frames in any sensible way.  GetStaticOffset, however,
    5269             :     // is perfect for that case.
    5270           0 :     position = NS_STYLE_POSITION_STATIC;
    5271             :   }
    5272             : 
    5273           0 :   switch (position) {
    5274             :     case NS_STYLE_POSITION_STATIC:
    5275           0 :       return GetStaticOffset(aSide);
    5276             :     case NS_STYLE_POSITION_RELATIVE:
    5277           0 :       return GetRelativeOffset(aSide);
    5278             :     case NS_STYLE_POSITION_STICKY:
    5279           0 :       return GetStickyOffset(aSide);
    5280             :     case NS_STYLE_POSITION_ABSOLUTE:
    5281             :     case NS_STYLE_POSITION_FIXED:
    5282           0 :       return GetAbsoluteOffset(aSide);
    5283             :     default:
    5284           0 :       NS_ERROR("Invalid position");
    5285           0 :       return nullptr;
    5286             :   }
    5287             : }
    5288             : 
    5289             : already_AddRefed<CSSValue>
    5290           0 : nsComputedDOMStyle::GetAbsoluteOffset(mozilla::Side aSide)
    5291             : {
    5292           0 :   MOZ_ASSERT(mOuterFrame, "need a frame, so we can call GetContainingBlock()");
    5293             : 
    5294           0 :   nsIFrame* container = mOuterFrame->GetContainingBlock();
    5295           0 :   nsMargin margin = mOuterFrame->GetUsedMargin();
    5296           0 :   nsMargin border = container->GetUsedBorder();
    5297           0 :   nsMargin scrollbarSizes(0, 0, 0, 0);
    5298           0 :   nsRect rect = mOuterFrame->GetRect();
    5299           0 :   nsRect containerRect = container->GetRect();
    5300             : 
    5301           0 :   if (container->IsViewportFrame()) {
    5302             :     // For absolutely positioned frames scrollbars are taken into
    5303             :     // account by virtue of getting a containing block that does
    5304             :     // _not_ include the scrollbars.  For fixed positioned frames,
    5305             :     // the containing block is the viewport, which _does_ include
    5306             :     // scrollbars.  We have to do some extra work.
    5307             :     // the first child in the default frame list is what we want
    5308           0 :     nsIFrame* scrollingChild = container->PrincipalChildList().FirstChild();
    5309           0 :     nsIScrollableFrame *scrollFrame = do_QueryFrame(scrollingChild);
    5310           0 :     if (scrollFrame) {
    5311           0 :       scrollbarSizes = scrollFrame->GetActualScrollbarSizes();
    5312             :     }
    5313             :   }
    5314             : 
    5315           0 :   nscoord offset = 0;
    5316           0 :   switch (aSide) {
    5317             :     case eSideTop:
    5318           0 :       offset = rect.y - margin.top - border.top - scrollbarSizes.top;
    5319             : 
    5320           0 :       break;
    5321             :     case eSideRight:
    5322           0 :       offset = containerRect.width - rect.width -
    5323           0 :         rect.x - margin.right - border.right - scrollbarSizes.right;
    5324             : 
    5325           0 :       break;
    5326             :     case eSideBottom:
    5327           0 :       offset = containerRect.height - rect.height -
    5328           0 :         rect.y - margin.bottom - border.bottom - scrollbarSizes.bottom;
    5329             : 
    5330           0 :       break;
    5331             :     case eSideLeft:
    5332           0 :       offset = rect.x - margin.left - border.left - scrollbarSizes.left;
    5333             : 
    5334           0 :       break;
    5335             :     default:
    5336           0 :       NS_ERROR("Invalid side");
    5337           0 :       break;
    5338             :   }
    5339             : 
    5340           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    5341           0 :   val->SetAppUnits(offset);
    5342           0 :   return val.forget();
    5343             : }
    5344             : 
    5345             : static_assert(eSideTop == 0 && eSideRight == 1 &&
    5346             :               eSideBottom == 2 && eSideLeft == 3,
    5347             :               "box side constants not as expected for NS_OPPOSITE_SIDE");
    5348             : #define NS_OPPOSITE_SIDE(s_) mozilla::Side(((s_) + 2) & 3)
    5349             : 
    5350             : already_AddRefed<CSSValue>
    5351           0 : nsComputedDOMStyle::GetRelativeOffset(mozilla::Side aSide)
    5352             : {
    5353           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    5354             : 
    5355           0 :   const nsStylePosition* positionData = StylePosition();
    5356           0 :   int32_t sign = 1;
    5357           0 :   nsStyleCoord coord = positionData->mOffset.Get(aSide);
    5358             : 
    5359           0 :   NS_ASSERTION(coord.GetUnit() == eStyleUnit_Coord ||
    5360             :                coord.GetUnit() == eStyleUnit_Percent ||
    5361             :                coord.GetUnit() == eStyleUnit_Auto ||
    5362             :                coord.IsCalcUnit(),
    5363             :                "Unexpected unit");
    5364             : 
    5365           0 :   if (coord.GetUnit() == eStyleUnit_Auto) {
    5366           0 :     coord = positionData->mOffset.Get(NS_OPPOSITE_SIDE(aSide));
    5367           0 :     sign = -1;
    5368             :   }
    5369             :   PercentageBaseGetter baseGetter;
    5370           0 :   if (aSide == eSideLeft || aSide == eSideRight) {
    5371           0 :     baseGetter = &nsComputedDOMStyle::GetCBContentWidth;
    5372             :   } else {
    5373           0 :     baseGetter = &nsComputedDOMStyle::GetCBContentHeight;
    5374             :   }
    5375             : 
    5376           0 :   val->SetAppUnits(sign * StyleCoordToNSCoord(coord, baseGetter, 0, false));
    5377           0 :   return val.forget();
    5378             : }
    5379             : 
    5380             : already_AddRefed<CSSValue>
    5381           0 : nsComputedDOMStyle::GetStickyOffset(mozilla::Side aSide)
    5382             : {
    5383           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    5384             : 
    5385           0 :   const nsStylePosition* positionData = StylePosition();
    5386           0 :   nsStyleCoord coord = positionData->mOffset.Get(aSide);
    5387             : 
    5388           0 :   NS_ASSERTION(coord.GetUnit() == eStyleUnit_Coord ||
    5389             :                coord.GetUnit() == eStyleUnit_Percent ||
    5390             :                coord.GetUnit() == eStyleUnit_Auto ||
    5391             :                coord.IsCalcUnit(),
    5392             :                "Unexpected unit");
    5393             : 
    5394           0 :   if (coord.GetUnit() == eStyleUnit_Auto) {
    5395           0 :     val->SetIdent(eCSSKeyword_auto);
    5396           0 :     return val.forget();
    5397             :   }
    5398             :   PercentageBaseGetter baseGetter;
    5399           0 :   if (aSide == eSideLeft || aSide == eSideRight) {
    5400           0 :     baseGetter = &nsComputedDOMStyle::GetScrollFrameContentWidth;
    5401             :   } else {
    5402           0 :     baseGetter = &nsComputedDOMStyle::GetScrollFrameContentHeight;
    5403             :   }
    5404             : 
    5405           0 :   val->SetAppUnits(StyleCoordToNSCoord(coord, baseGetter, 0, false));
    5406           0 :   return val.forget();
    5407             : }
    5408             : 
    5409             : 
    5410             : already_AddRefed<CSSValue>
    5411           0 : nsComputedDOMStyle::GetStaticOffset(mozilla::Side aSide)
    5412             : 
    5413             : {
    5414           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    5415           0 :   SetValueToCoord(val, StylePosition()->mOffset.Get(aSide), false);
    5416           0 :   return val.forget();
    5417             : }
    5418             : 
    5419             : already_AddRefed<CSSValue>
    5420           0 : nsComputedDOMStyle::GetPaddingWidthFor(mozilla::Side aSide)
    5421             : {
    5422           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    5423             : 
    5424           0 :   if (!mInnerFrame) {
    5425           0 :     SetValueToCoord(val, StylePadding()->mPadding.Get(aSide), true);
    5426             :   } else {
    5427           0 :     AssertFlushedPendingReflows();
    5428             : 
    5429           0 :     val->SetAppUnits(mInnerFrame->GetUsedPadding().Side(aSide));
    5430             :   }
    5431             : 
    5432           0 :   return val.forget();
    5433             : }
    5434             : 
    5435             : bool
    5436           0 : nsComputedDOMStyle::GetLineHeightCoord(nscoord& aCoord)
    5437             : {
    5438           0 :   AssertFlushedPendingReflows();
    5439             : 
    5440           0 :   nscoord blockHeight = NS_AUTOHEIGHT;
    5441           0 :   if (StyleText()->mLineHeight.GetUnit() == eStyleUnit_Enumerated) {
    5442           0 :     if (!mInnerFrame)
    5443           0 :       return false;
    5444             : 
    5445           0 :     if (nsLayoutUtils::IsNonWrapperBlock(mInnerFrame)) {
    5446           0 :       blockHeight = mInnerFrame->GetContentRect().height;
    5447             :     } else {
    5448           0 :       GetCBContentHeight(blockHeight);
    5449             :     }
    5450             :   }
    5451             : 
    5452             :   // lie about font size inflation since we lie about font size (since
    5453             :   // the inflation only applies to text)
    5454           0 :   aCoord = ReflowInput::CalcLineHeight(mContent, mStyleContext,
    5455             :                                              blockHeight, 1.0f);
    5456             : 
    5457             :   // CalcLineHeight uses font->mFont.size, but we want to use
    5458             :   // font->mSize as the font size.  Adjust for that.  Also adjust for
    5459             :   // the text zoom, if any.
    5460           0 :   const nsStyleFont* font = StyleFont();
    5461           0 :   float fCoord = float(aCoord);
    5462           0 :   if (font->mAllowZoom) {
    5463           0 :     fCoord /= mPresShell->GetPresContext()->EffectiveTextZoom();
    5464             :   }
    5465           0 :   if (font->mFont.size != font->mSize) {
    5466           0 :     fCoord = fCoord * (float(font->mSize) / float(font->mFont.size));
    5467             :   }
    5468           0 :   aCoord = NSToCoordRound(fCoord);
    5469             : 
    5470           0 :   return true;
    5471             : }
    5472             : 
    5473             : already_AddRefed<CSSValue>
    5474           0 : nsComputedDOMStyle::GetBorderColorsFor(mozilla::Side aSide)
    5475             : {
    5476           0 :   const nsStyleBorder *border = StyleBorder();
    5477             : 
    5478           0 :   if (border->mBorderColors) {
    5479           0 :     nsBorderColors* borderColors = border->mBorderColors[aSide];
    5480           0 :     if (borderColors) {
    5481           0 :       RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false);
    5482             : 
    5483           0 :       do {
    5484           0 :         RefPtr<nsROCSSPrimitiveValue> primitive = new nsROCSSPrimitiveValue;
    5485             : 
    5486           0 :         SetToRGBAColor(primitive, borderColors->mColor);
    5487             : 
    5488           0 :         valueList->AppendCSSValue(primitive.forget());
    5489           0 :         borderColors = borderColors->mNext;
    5490           0 :       } while (borderColors);
    5491             : 
    5492           0 :       return valueList.forget();
    5493             :     }
    5494             :   }
    5495             : 
    5496           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    5497           0 :   val->SetIdent(eCSSKeyword_none);
    5498           0 :   return val.forget();
    5499             : }
    5500             : 
    5501             : already_AddRefed<CSSValue>
    5502           0 : nsComputedDOMStyle::GetBorderWidthFor(mozilla::Side aSide)
    5503             : {
    5504           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    5505             : 
    5506             :   nscoord width;
    5507           0 :   if (mInnerFrame) {
    5508           0 :     AssertFlushedPendingReflows();
    5509           0 :     width = mInnerFrame->GetUsedBorder().Side(aSide);
    5510             :   } else {
    5511           0 :     width = StyleBorder()->GetComputedBorderWidth(aSide);
    5512             :   }
    5513           0 :   val->SetAppUnits(width);
    5514             : 
    5515           0 :   return val.forget();
    5516             : }
    5517             : 
    5518             : already_AddRefed<CSSValue>
    5519           0 : nsComputedDOMStyle::GetBorderColorFor(mozilla::Side aSide)
    5520             : {
    5521           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    5522           0 :   SetValueFromComplexColor(val, StyleBorder()->mBorderColor[aSide]);
    5523           0 :   return val.forget();
    5524             : }
    5525             : 
    5526             : already_AddRefed<CSSValue>
    5527           0 : nsComputedDOMStyle::GetMarginWidthFor(mozilla::Side aSide)
    5528             : {
    5529           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    5530             : 
    5531           0 :   if (!mInnerFrame) {
    5532           0 :     SetValueToCoord(val, StyleMargin()->mMargin.Get(aSide), false);
    5533             :   } else {
    5534           0 :     AssertFlushedPendingReflows();
    5535             : 
    5536             :     // For tables, GetUsedMargin always returns an empty margin, so we
    5537             :     // should read the margin from the table wrapper frame instead.
    5538           0 :     val->SetAppUnits(mOuterFrame->GetUsedMargin().Side(aSide));
    5539           0 :     NS_ASSERTION(mOuterFrame == mInnerFrame ||
    5540             :                  mInnerFrame->GetUsedMargin() == nsMargin(0, 0, 0, 0),
    5541             :                  "Inner tables must have zero margins");
    5542             :   }
    5543             : 
    5544           0 :   return val.forget();
    5545             : }
    5546             : 
    5547             : already_AddRefed<CSSValue>
    5548           0 : nsComputedDOMStyle::GetBorderStyleFor(mozilla::Side aSide)
    5549             : {
    5550           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    5551           0 :   val->SetIdent(
    5552           0 :     nsCSSProps::ValueToKeywordEnum(StyleBorder()->GetBorderStyle(aSide),
    5553           0 :                                    nsCSSProps::kBorderStyleKTable));
    5554           0 :   return val.forget();
    5555             : }
    5556             : 
    5557             : void
    5558           0 : nsComputedDOMStyle::SetValueToCoord(nsROCSSPrimitiveValue* aValue,
    5559             :                                     const nsStyleCoord& aCoord,
    5560             :                                     bool aClampNegativeCalc,
    5561             :                                     PercentageBaseGetter aPercentageBaseGetter,
    5562             :                                     const KTableEntry aTable[],
    5563             :                                     nscoord aMinAppUnits,
    5564             :                                     nscoord aMaxAppUnits)
    5565             : {
    5566           0 :   NS_PRECONDITION(aValue, "Must have a value to work with");
    5567             : 
    5568           0 :   switch (aCoord.GetUnit()) {
    5569             :     case eStyleUnit_Normal:
    5570           0 :       aValue->SetIdent(eCSSKeyword_normal);
    5571           0 :       break;
    5572             : 
    5573             :     case eStyleUnit_Auto:
    5574           0 :       aValue->SetIdent(eCSSKeyword_auto);
    5575           0 :       break;
    5576             : 
    5577             :     case eStyleUnit_Percent:
    5578             :       {
    5579             :         nscoord percentageBase;
    5580           0 :         if (aPercentageBaseGetter &&
    5581           0 :             (this->*aPercentageBaseGetter)(percentageBase)) {
    5582           0 :           nscoord val = NSCoordSaturatingMultiply(percentageBase,
    5583           0 :                                                   aCoord.GetPercentValue());
    5584           0 :           aValue->SetAppUnits(std::max(aMinAppUnits, std::min(val, aMaxAppUnits)));
    5585             :         } else {
    5586           0 :           aValue->SetPercent(aCoord.GetPercentValue());
    5587             :         }
    5588             :       }
    5589           0 :       break;
    5590             : 
    5591             :     case eStyleUnit_Factor:
    5592           0 :       aValue->SetNumber(aCoord.GetFactorValue());
    5593           0 :       break;
    5594             : 
    5595             :     case eStyleUnit_Coord:
    5596             :       {
    5597           0 :         nscoord val = aCoord.GetCoordValue();
    5598           0 :         aValue->SetAppUnits(std::max(aMinAppUnits, std::min(val, aMaxAppUnits)));
    5599             :       }
    5600           0 :       break;
    5601             : 
    5602             :     case eStyleUnit_Integer:
    5603           0 :       aValue->SetNumber(aCoord.GetIntValue());
    5604           0 :       break;
    5605             : 
    5606             :     case eStyleUnit_Enumerated:
    5607           0 :       NS_ASSERTION(aTable, "Must have table to handle this case");
    5608           0 :       aValue->SetIdent(nsCSSProps::ValueToKeywordEnum(aCoord.GetIntValue(),
    5609           0 :                                                       aTable));
    5610           0 :       break;
    5611             : 
    5612             :     case eStyleUnit_None:
    5613           0 :       aValue->SetIdent(eCSSKeyword_none);
    5614           0 :       break;
    5615             : 
    5616             :     case eStyleUnit_Calc:
    5617             :       nscoord percentageBase;
    5618           0 :       if (!aCoord.CalcHasPercent()) {
    5619           0 :         nscoord val = nsRuleNode::ComputeCoordPercentCalc(aCoord, 0);
    5620           0 :         if (aClampNegativeCalc && val < 0) {
    5621           0 :           MOZ_ASSERT(aCoord.IsCalcUnit(),
    5622             :                      "parser should have rejected value");
    5623           0 :           val = 0;
    5624             :         }
    5625           0 :         aValue->SetAppUnits(std::max(aMinAppUnits, std::min(val, aMaxAppUnits)));
    5626           0 :       } else if (aPercentageBaseGetter &&
    5627           0 :                  (this->*aPercentageBaseGetter)(percentageBase)) {
    5628             :         nscoord val =
    5629           0 :           nsRuleNode::ComputeCoordPercentCalc(aCoord, percentageBase);
    5630           0 :         if (aClampNegativeCalc && val < 0) {
    5631           0 :           MOZ_ASSERT(aCoord.IsCalcUnit(),
    5632             :                      "parser should have rejected value");
    5633           0 :           val = 0;
    5634             :         }
    5635           0 :         aValue->SetAppUnits(std::max(aMinAppUnits, std::min(val, aMaxAppUnits)));
    5636             :       } else {
    5637           0 :         nsStyleCoord::Calc *calc = aCoord.GetCalcValue();
    5638           0 :         SetValueToCalc(calc, aValue);
    5639             :       }
    5640           0 :       break;
    5641             : 
    5642             :     case eStyleUnit_Degree:
    5643           0 :       aValue->SetDegree(aCoord.GetAngleValue());
    5644           0 :       break;
    5645             : 
    5646             :     case eStyleUnit_Grad:
    5647           0 :       aValue->SetGrad(aCoord.GetAngleValue());
    5648           0 :       break;
    5649             : 
    5650             :     case eStyleUnit_Radian:
    5651           0 :       aValue->SetRadian(aCoord.GetAngleValue());
    5652           0 :       break;
    5653             : 
    5654             :     case eStyleUnit_Turn:
    5655           0 :       aValue->SetTurn(aCoord.GetAngleValue());
    5656           0 :       break;
    5657             : 
    5658             :     case eStyleUnit_FlexFraction: {
    5659           0 :       nsAutoString tmpStr;
    5660           0 :       nsStyleUtil::AppendCSSNumber(aCoord.GetFlexFractionValue(), tmpStr);
    5661           0 :       tmpStr.AppendLiteral("fr");
    5662           0 :       aValue->SetString(tmpStr);
    5663           0 :       break;
    5664             :     }
    5665             : 
    5666             :     default:
    5667           0 :       NS_ERROR("Can't handle this unit");
    5668           0 :       break;
    5669             :   }
    5670           0 : }
    5671             : 
    5672             : nscoord
    5673           0 : nsComputedDOMStyle::StyleCoordToNSCoord(const nsStyleCoord& aCoord,
    5674             :                                         PercentageBaseGetter aPercentageBaseGetter,
    5675             :                                         nscoord aDefaultValue,
    5676             :                                         bool aClampNegativeCalc)
    5677             : {
    5678           0 :   NS_PRECONDITION(aPercentageBaseGetter, "Must have a percentage base getter");
    5679           0 :   if (aCoord.GetUnit() == eStyleUnit_Coord) {
    5680           0 :     return aCoord.GetCoordValue();
    5681             :   }
    5682           0 :   if (aCoord.GetUnit() == eStyleUnit_Percent || aCoord.IsCalcUnit()) {
    5683             :     nscoord percentageBase;
    5684           0 :     if ((this->*aPercentageBaseGetter)(percentageBase)) {
    5685             :       nscoord result =
    5686           0 :         nsRuleNode::ComputeCoordPercentCalc(aCoord, percentageBase);
    5687           0 :       if (aClampNegativeCalc && result < 0) {
    5688             :         // It's expected that we can get a negative value here with calc().
    5689             :         // We can also get a negative value with a percentage value if
    5690             :         // percentageBase is negative; this isn't expected, but can happen
    5691             :         // when large length values overflow.
    5692           0 :         NS_WARNING_ASSERTION(
    5693             :           percentageBase >= 0,
    5694             :           "percentage base value overflowed to become negative for a property "
    5695             :           "that disallows negative values");
    5696           0 :         MOZ_ASSERT(aCoord.IsCalcUnit() ||
    5697             :                    (aCoord.HasPercent() && percentageBase < 0),
    5698             :                    "parser should have rejected value");
    5699           0 :         result = 0;
    5700             :       }
    5701           0 :       return result;
    5702             :     }
    5703             :     // Fall through to returning aDefaultValue if we have no percentage base.
    5704             :   }
    5705             : 
    5706           0 :   return aDefaultValue;
    5707             : }
    5708             : 
    5709             : bool
    5710           0 : nsComputedDOMStyle::GetCBContentWidth(nscoord& aWidth)
    5711             : {
    5712           0 :   if (!mOuterFrame) {
    5713           0 :     return false;
    5714             :   }
    5715             : 
    5716           0 :   AssertFlushedPendingReflows();
    5717             : 
    5718           0 :   nsIFrame* container = mOuterFrame->GetContainingBlock();
    5719           0 :   aWidth = container->GetContentRect().width;
    5720           0 :   return true;
    5721             : }
    5722             : 
    5723             : bool
    5724           0 : nsComputedDOMStyle::GetCBContentHeight(nscoord& aHeight)
    5725             : {
    5726           0 :   if (!mOuterFrame) {
    5727           0 :     return false;
    5728             :   }
    5729             : 
    5730           0 :   AssertFlushedPendingReflows();
    5731             : 
    5732           0 :   nsIFrame* container = mOuterFrame->GetContainingBlock();
    5733           0 :   aHeight = container->GetContentRect().height;
    5734           0 :   return true;
    5735             : }
    5736             : 
    5737             : bool
    5738           0 : nsComputedDOMStyle::GetScrollFrameContentWidth(nscoord& aWidth)
    5739             : {
    5740           0 :   if (!mOuterFrame) {
    5741           0 :     return false;
    5742             :   }
    5743             : 
    5744           0 :   AssertFlushedPendingReflows();
    5745             : 
    5746             :   nsIScrollableFrame* scrollableFrame =
    5747           0 :     nsLayoutUtils::GetNearestScrollableFrame(mOuterFrame->GetParent(),
    5748             :       nsLayoutUtils::SCROLLABLE_SAME_DOC |
    5749           0 :       nsLayoutUtils::SCROLLABLE_INCLUDE_HIDDEN);
    5750             : 
    5751           0 :   if (!scrollableFrame) {
    5752           0 :     return false;
    5753             :   }
    5754           0 :   aWidth =
    5755           0 :     scrollableFrame->GetScrolledFrame()->GetContentRectRelativeToSelf().width;
    5756           0 :   return true;
    5757             : }
    5758             : 
    5759             : bool
    5760           0 : nsComputedDOMStyle::GetScrollFrameContentHeight(nscoord& aHeight)
    5761             : {
    5762           0 :   if (!mOuterFrame) {
    5763           0 :     return false;
    5764             :   }
    5765             : 
    5766           0 :   AssertFlushedPendingReflows();
    5767             : 
    5768             :   nsIScrollableFrame* scrollableFrame =
    5769           0 :     nsLayoutUtils::GetNearestScrollableFrame(mOuterFrame->GetParent(),
    5770             :       nsLayoutUtils::SCROLLABLE_SAME_DOC |
    5771           0 :       nsLayoutUtils::SCROLLABLE_INCLUDE_HIDDEN);
    5772             : 
    5773           0 :   if (!scrollableFrame) {
    5774           0 :     return false;
    5775             :   }
    5776           0 :   aHeight =
    5777           0 :     scrollableFrame->GetScrolledFrame()->GetContentRectRelativeToSelf().height;
    5778           0 :   return true;
    5779             : }
    5780             : 
    5781             : bool
    5782           0 : nsComputedDOMStyle::GetFrameBorderRectWidth(nscoord& aWidth)
    5783             : {
    5784           0 :   if (!mInnerFrame) {
    5785           0 :     return false;
    5786             :   }
    5787             : 
    5788           0 :   AssertFlushedPendingReflows();
    5789             : 
    5790           0 :   aWidth = mInnerFrame->GetSize().width;
    5791           0 :   return true;
    5792             : }
    5793             : 
    5794             : bool
    5795           0 : nsComputedDOMStyle::GetFrameBorderRectHeight(nscoord& aHeight)
    5796             : {
    5797           0 :   if (!mInnerFrame) {
    5798           0 :     return false;
    5799             :   }
    5800             : 
    5801           0 :   AssertFlushedPendingReflows();
    5802             : 
    5803           0 :   aHeight = mInnerFrame->GetSize().height;
    5804           0 :   return true;
    5805             : }
    5806             : 
    5807             : bool
    5808           0 : nsComputedDOMStyle::GetFrameBoundsWidthForTransform(nscoord& aWidth)
    5809             : {
    5810             :   // We need a frame to work with.
    5811           0 :   if (!mInnerFrame) {
    5812           0 :     return false;
    5813             :   }
    5814             : 
    5815           0 :   AssertFlushedPendingReflows();
    5816             : 
    5817           0 :   aWidth = nsStyleTransformMatrix::TransformReferenceBox(mInnerFrame).Width();
    5818           0 :   return true;
    5819             : }
    5820             : 
    5821             : bool
    5822           0 : nsComputedDOMStyle::GetFrameBoundsHeightForTransform(nscoord& aHeight)
    5823             : {
    5824             :   // We need a frame to work with.
    5825           0 :   if (!mInnerFrame) {
    5826           0 :     return false;
    5827             :   }
    5828             : 
    5829           0 :   AssertFlushedPendingReflows();
    5830             : 
    5831           0 :   aHeight = nsStyleTransformMatrix::TransformReferenceBox(mInnerFrame).Height();
    5832           0 :   return true;
    5833             : }
    5834             : 
    5835             : already_AddRefed<CSSValue>
    5836           0 : nsComputedDOMStyle::GetFallbackValue(const nsStyleSVGPaint* aPaint)
    5837             : {
    5838           0 :   RefPtr<nsROCSSPrimitiveValue> fallback = new nsROCSSPrimitiveValue;
    5839           0 :   if (aPaint->GetFallbackType() == eStyleSVGFallbackType_Color) {
    5840           0 :     SetToRGBAColor(fallback, aPaint->GetFallbackColor());
    5841             :   } else {
    5842           0 :     fallback->SetIdent(eCSSKeyword_none);
    5843             :   }
    5844           0 :   return fallback.forget();
    5845             : }
    5846             : 
    5847             : already_AddRefed<CSSValue>
    5848           0 : nsComputedDOMStyle::GetSVGPaintFor(bool aFill)
    5849             : {
    5850           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    5851             : 
    5852           0 :   const nsStyleSVG* svg = StyleSVG();
    5853           0 :   const nsStyleSVGPaint* paint = aFill ? &svg->mFill : &svg->mStroke;
    5854             : 
    5855           0 :   nsAutoString paintString;
    5856             : 
    5857           0 :   switch (paint->Type()) {
    5858             :     case eStyleSVGPaintType_None:
    5859           0 :       val->SetIdent(eCSSKeyword_none);
    5860           0 :       break;
    5861             :     case eStyleSVGPaintType_Color:
    5862           0 :       SetToRGBAColor(val, paint->GetColor());
    5863           0 :       break;
    5864             :     case eStyleSVGPaintType_Server: {
    5865           0 :       SetValueToURLValue(paint->GetPaintServer(), val);
    5866           0 :       if (paint->GetFallbackType() != eStyleSVGFallbackType_NotSet) {
    5867           0 :         RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false);
    5868           0 :         RefPtr<CSSValue> fallback = GetFallbackValue(paint);
    5869           0 :         valueList->AppendCSSValue(val.forget());
    5870           0 :         valueList->AppendCSSValue(fallback.forget());
    5871           0 :         return valueList.forget();
    5872             :       }
    5873           0 :       break;
    5874             :     }
    5875             :     case eStyleSVGPaintType_ContextFill:
    5876             :     case eStyleSVGPaintType_ContextStroke: {
    5877           0 :       val->SetIdent(paint->Type() == eStyleSVGPaintType_ContextFill ?
    5878           0 :                     eCSSKeyword_context_fill : eCSSKeyword_context_stroke);
    5879           0 :       if (paint->GetFallbackType() != eStyleSVGFallbackType_NotSet) {
    5880           0 :         RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false);
    5881           0 :         RefPtr<CSSValue> fallback = GetFallbackValue(paint);
    5882           0 :         valueList->AppendCSSValue(val.forget());
    5883           0 :         valueList->AppendCSSValue(fallback.forget());
    5884           0 :         return valueList.forget();
    5885             :       }
    5886           0 :       break;
    5887             :     }
    5888             :   }
    5889             : 
    5890           0 :   return val.forget();
    5891             : }
    5892             : 
    5893             : /* If the property is "none", hand back "none" wrapped in a value.
    5894             :  * Otherwise, compute the aggregate transform matrix and hands it back in a
    5895             :  * "matrix" wrapper.
    5896             :  */
    5897             : already_AddRefed<CSSValue>
    5898           0 : nsComputedDOMStyle::GetTransformValue(nsCSSValueSharedList* aSpecifiedTransform)
    5899             : {
    5900             :   /* If there are no transforms, then we should construct a single-element
    5901             :    * entry and hand it back.
    5902             :    */
    5903           0 :   if (!aSpecifiedTransform) {
    5904           0 :     RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    5905             : 
    5906             :     /* Set it to "none." */
    5907           0 :     val->SetIdent(eCSSKeyword_none);
    5908           0 :     return val.forget();
    5909             :   }
    5910             : 
    5911             :   /* Otherwise, we need to compute the current value of the transform matrix,
    5912             :    * store it in a string, and hand it back to the caller.
    5913             :    */
    5914             : 
    5915             :   /* Use the inner frame for the reference box.  If we don't have an inner
    5916             :    * frame we use empty dimensions to allow us to continue (and percentage
    5917             :    * values in the transform will simply give broken results).
    5918             :    * TODO: There is no good way for us to represent the case where there's no
    5919             :    * frame, which is problematic.  The reason is that when we have percentage
    5920             :    * transforms, there are a total of four stored matrix entries that influence
    5921             :    * the transform based on the size of the element.  However, this poses a
    5922             :    * problem, because only two of these values can be explicitly referenced
    5923             :    * using the named transforms.  Until a real solution is found, we'll just
    5924             :    * use this approach.
    5925             :    */
    5926           0 :   nsStyleTransformMatrix::TransformReferenceBox refBox(mInnerFrame,
    5927           0 :                                                        nsSize(0, 0));
    5928             : 
    5929           0 :    RuleNodeCacheConditions dummy;
    5930             :    bool dummyBool;
    5931             :    gfx::Matrix4x4 matrix =
    5932           0 :      nsStyleTransformMatrix::ReadTransforms(aSpecifiedTransform->mHead,
    5933             :                                             mStyleContext,
    5934             :                                             mStyleContext->PresContext(),
    5935             :                                             dummy,
    5936             :                                             refBox,
    5937           0 :                                             float(mozilla::AppUnitsPerCSSPixel()),
    5938           0 :                                             &dummyBool);
    5939             : 
    5940           0 :   return MatrixToCSSValue(matrix);
    5941             : }
    5942             : 
    5943             : already_AddRefed<CSSValue>
    5944           0 : nsComputedDOMStyle::DoGetFill()
    5945             : {
    5946           0 :   return GetSVGPaintFor(true);
    5947             : }
    5948             : 
    5949             : already_AddRefed<CSSValue>
    5950           0 : nsComputedDOMStyle::DoGetStroke()
    5951             : {
    5952           0 :   return GetSVGPaintFor(false);
    5953             : }
    5954             : 
    5955             : already_AddRefed<CSSValue>
    5956           0 : nsComputedDOMStyle::DoGetMarkerEnd()
    5957             : {
    5958           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    5959           0 :   SetValueToURLValue(StyleSVG()->mMarkerEnd, val);
    5960             : 
    5961           0 :   return val.forget();
    5962             : }
    5963             : 
    5964             : already_AddRefed<CSSValue>
    5965           0 : nsComputedDOMStyle::DoGetMarkerMid()
    5966             : {
    5967           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    5968           0 :   SetValueToURLValue(StyleSVG()->mMarkerMid, val);
    5969             : 
    5970           0 :   return val.forget();
    5971             : }
    5972             : 
    5973             : already_AddRefed<CSSValue>
    5974           0 : nsComputedDOMStyle::DoGetMarkerStart()
    5975             : {
    5976           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    5977           0 :   SetValueToURLValue(StyleSVG()->mMarkerStart, val);
    5978             : 
    5979           0 :   return val.forget();
    5980             : }
    5981             : 
    5982             : already_AddRefed<CSSValue>
    5983           0 : nsComputedDOMStyle::DoGetStrokeDasharray()
    5984             : {
    5985           0 :   const nsStyleSVG* svg = StyleSVG();
    5986             : 
    5987           0 :   if (svg->mStrokeDasharray.IsEmpty()) {
    5988           0 :     RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    5989           0 :     val->SetIdent(eCSSKeyword_none);
    5990           0 :     return val.forget();
    5991             :   }
    5992             : 
    5993           0 :   RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(true);
    5994             : 
    5995           0 :   for (uint32_t i = 0; i < svg->mStrokeDasharray.Length(); i++) {
    5996           0 :     RefPtr<nsROCSSPrimitiveValue> dash = new nsROCSSPrimitiveValue;
    5997           0 :     SetValueToCoord(dash, svg->mStrokeDasharray[i], true);
    5998           0 :     valueList->AppendCSSValue(dash.forget());
    5999             :   }
    6000             : 
    6001           0 :   return valueList.forget();
    6002             : }
    6003             : 
    6004             : already_AddRefed<CSSValue>
    6005           0 : nsComputedDOMStyle::DoGetStrokeDashoffset()
    6006             : {
    6007           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    6008           0 :   SetValueToCoord(val, StyleSVG()->mStrokeDashoffset, false);
    6009           0 :   return val.forget();
    6010             : }
    6011             : 
    6012             : already_AddRefed<CSSValue>
    6013           0 : nsComputedDOMStyle::DoGetStrokeWidth()
    6014             : {
    6015           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    6016           0 :   SetValueToCoord(val, StyleSVG()->mStrokeWidth, true);
    6017           0 :   return val.forget();
    6018             : }
    6019             : 
    6020             : already_AddRefed<CSSValue>
    6021           0 : nsComputedDOMStyle::DoGetVectorEffect()
    6022             : {
    6023           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    6024           0 :   val->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleSVGReset()->mVectorEffect,
    6025           0 :                                                nsCSSProps::kVectorEffectKTable));
    6026           0 :   return val.forget();
    6027             : }
    6028             : 
    6029             : already_AddRefed<CSSValue>
    6030           0 : nsComputedDOMStyle::DoGetFillOpacity()
    6031             : {
    6032           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    6033           0 :   val->SetNumber(StyleSVG()->mFillOpacity);
    6034           0 :   return val.forget();
    6035             : }
    6036             : 
    6037             : already_AddRefed<CSSValue>
    6038           0 : nsComputedDOMStyle::DoGetFloodOpacity()
    6039             : {
    6040           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    6041           0 :   val->SetNumber(StyleSVGReset()->mFloodOpacity);
    6042           0 :   return val.forget();
    6043             : }
    6044             : 
    6045             : already_AddRefed<CSSValue>
    6046           0 : nsComputedDOMStyle::DoGetStopOpacity()
    6047             : {
    6048           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    6049           0 :   val->SetNumber(StyleSVGReset()->mStopOpacity);
    6050           0 :   return val.forget();
    6051             : }
    6052             : 
    6053             : already_AddRefed<CSSValue>
    6054           0 : nsComputedDOMStyle::DoGetStrokeMiterlimit()
    6055             : {
    6056           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    6057           0 :   val->SetNumber(StyleSVG()->mStrokeMiterlimit);
    6058           0 :   return val.forget();
    6059             : }
    6060             : 
    6061             : already_AddRefed<CSSValue>
    6062           0 : nsComputedDOMStyle::DoGetStrokeOpacity()
    6063             : {
    6064           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    6065           0 :   val->SetNumber(StyleSVG()->mStrokeOpacity);
    6066           0 :   return val.forget();
    6067             : }
    6068             : 
    6069             : already_AddRefed<CSSValue>
    6070           0 : nsComputedDOMStyle::DoGetClipRule()
    6071             : {
    6072           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    6073           0 :   val->SetIdent(nsCSSProps::ValueToKeywordEnum(
    6074           0 :                   StyleSVG()->mClipRule, nsCSSProps::kFillRuleKTable));
    6075           0 :   return val.forget();
    6076             : }
    6077             : 
    6078             : already_AddRefed<CSSValue>
    6079           0 : nsComputedDOMStyle::DoGetFillRule()
    6080             : {
    6081           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    6082           0 :   val->SetIdent(nsCSSProps::ValueToKeywordEnum(
    6083           0 :                   StyleSVG()->mFillRule, nsCSSProps::kFillRuleKTable));
    6084           0 :   return val.forget();
    6085             : }
    6086             : 
    6087             : already_AddRefed<CSSValue>
    6088           0 : nsComputedDOMStyle::DoGetStrokeLinecap()
    6089             : {
    6090           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    6091           0 :   val->SetIdent(
    6092           0 :     nsCSSProps::ValueToKeywordEnum(StyleSVG()->mStrokeLinecap,
    6093           0 :                                    nsCSSProps::kStrokeLinecapKTable));
    6094           0 :   return val.forget();
    6095             : }
    6096             : 
    6097             : already_AddRefed<CSSValue>
    6098           0 : nsComputedDOMStyle::DoGetStrokeLinejoin()
    6099             : {
    6100           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    6101           0 :   val->SetIdent(
    6102           0 :     nsCSSProps::ValueToKeywordEnum(StyleSVG()->mStrokeLinejoin,
    6103           0 :                                    nsCSSProps::kStrokeLinejoinKTable));
    6104           0 :   return val.forget();
    6105             : }
    6106             : 
    6107             : already_AddRefed<CSSValue>
    6108           0 : nsComputedDOMStyle::DoGetTextAnchor()
    6109             : {
    6110           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    6111           0 :   val->SetIdent(
    6112           0 :     nsCSSProps::ValueToKeywordEnum(StyleSVG()->mTextAnchor,
    6113           0 :                                    nsCSSProps::kTextAnchorKTable));
    6114           0 :   return val.forget();
    6115             : }
    6116             : 
    6117             : already_AddRefed<CSSValue>
    6118           0 : nsComputedDOMStyle::DoGetColorInterpolation()
    6119             : {
    6120           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    6121           0 :   val->SetIdent(
    6122           0 :     nsCSSProps::ValueToKeywordEnum(StyleSVG()->mColorInterpolation,
    6123           0 :                                    nsCSSProps::kColorInterpolationKTable));
    6124           0 :   return val.forget();
    6125             : }
    6126             : 
    6127             : already_AddRefed<CSSValue>
    6128           0 : nsComputedDOMStyle::DoGetColorInterpolationFilters()
    6129             : {
    6130           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    6131           0 :   val->SetIdent(
    6132           0 :     nsCSSProps::ValueToKeywordEnum(StyleSVG()->mColorInterpolationFilters,
    6133           0 :                                    nsCSSProps::kColorInterpolationKTable));
    6134           0 :   return val.forget();
    6135             : }
    6136             : 
    6137             : already_AddRefed<CSSValue>
    6138           0 : nsComputedDOMStyle::DoGetDominantBaseline()
    6139             : {
    6140           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    6141           0 :   val->SetIdent(
    6142           0 :     nsCSSProps::ValueToKeywordEnum(StyleSVGReset()->mDominantBaseline,
    6143           0 :                                    nsCSSProps::kDominantBaselineKTable));
    6144           0 :   return val.forget();
    6145             : }
    6146             : 
    6147             : already_AddRefed<CSSValue>
    6148           0 : nsComputedDOMStyle::DoGetImageRendering()
    6149             : {
    6150           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    6151           0 :   val->SetIdent(
    6152           0 :     nsCSSProps::ValueToKeywordEnum(StyleVisibility()->mImageRendering,
    6153           0 :                                    nsCSSProps::kImageRenderingKTable));
    6154           0 :   return val.forget();
    6155             : }
    6156             : 
    6157             : already_AddRefed<CSSValue>
    6158           0 : nsComputedDOMStyle::DoGetShapeRendering()
    6159             : {
    6160           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    6161           0 :   val->SetIdent(
    6162           0 :     nsCSSProps::ValueToKeywordEnum(StyleSVG()->mShapeRendering,
    6163           0 :                                    nsCSSProps::kShapeRenderingKTable));
    6164           0 :   return val.forget();
    6165             : }
    6166             : 
    6167             : already_AddRefed<CSSValue>
    6168           0 : nsComputedDOMStyle::DoGetTextRendering()
    6169             : {
    6170           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    6171           0 :   val->SetIdent(
    6172           0 :     nsCSSProps::ValueToKeywordEnum(StyleText()->mTextRendering,
    6173           0 :                                    nsCSSProps::kTextRenderingKTable));
    6174           0 :   return val.forget();
    6175             : }
    6176             : 
    6177             : already_AddRefed<CSSValue>
    6178           0 : nsComputedDOMStyle::DoGetFloodColor()
    6179             : {
    6180           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    6181           0 :   SetToRGBAColor(val, StyleSVGReset()->mFloodColor);
    6182           0 :   return val.forget();
    6183             : }
    6184             : 
    6185             : already_AddRefed<CSSValue>
    6186           0 : nsComputedDOMStyle::DoGetLightingColor()
    6187             : {
    6188           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    6189           0 :   SetToRGBAColor(val, StyleSVGReset()->mLightingColor);
    6190           0 :   return val.forget();
    6191             : }
    6192             : 
    6193             : already_AddRefed<CSSValue>
    6194           0 : nsComputedDOMStyle::DoGetStopColor()
    6195             : {
    6196           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    6197           0 :   SetToRGBAColor(val, StyleSVGReset()->mStopColor);
    6198           0 :   return val.forget();
    6199             : }
    6200             : 
    6201             : void
    6202           0 : nsComputedDOMStyle::BoxValuesToString(nsAString& aString,
    6203             :                                       const nsTArray<nsStyleCoord>& aBoxValues)
    6204             : {
    6205           0 :   MOZ_ASSERT(aBoxValues.Length() == 4, "wrong number of box values");
    6206           0 :   nsAutoString value1, value2, value3, value4;
    6207           0 :   SetCssTextToCoord(value1, aBoxValues[0]);
    6208           0 :   SetCssTextToCoord(value2, aBoxValues[1]);
    6209           0 :   SetCssTextToCoord(value3, aBoxValues[2]);
    6210           0 :   SetCssTextToCoord(value4, aBoxValues[3]);
    6211             : 
    6212             :   // nsROCSSPrimitiveValue do not have binary comparison operators.
    6213             :   // Compare string results instead.
    6214           0 :   aString.Append(value1);
    6215           0 :   if (value1 != value2 || value1 != value3 || value1 != value4) {
    6216           0 :     aString.Append(' ');
    6217           0 :     aString.Append(value2);
    6218           0 :     if (value1 != value3 || value2 != value4) {
    6219           0 :       aString.Append(' ');
    6220           0 :       aString.Append(value3);
    6221           0 :       if (value2 != value4) {
    6222           0 :         aString.Append(' ');
    6223           0 :         aString.Append(value4);
    6224             :       }
    6225             :     }
    6226             :   }
    6227           0 : }
    6228             : 
    6229             : void
    6230           0 : nsComputedDOMStyle::BasicShapeRadiiToString(nsAString& aCssText,
    6231             :                                             const nsStyleCorners& aCorners)
    6232             : {
    6233           0 :   nsTArray<nsStyleCoord> horizontal, vertical;
    6234           0 :   nsAutoString horizontalString, verticalString;
    6235           0 :   NS_FOR_CSS_FULL_CORNERS(corner) {
    6236             :     horizontal.AppendElement(
    6237           0 :       aCorners.Get(FullToHalfCorner(corner, false)));
    6238             :     vertical.AppendElement(
    6239           0 :       aCorners.Get(FullToHalfCorner(corner, true)));
    6240             :   }
    6241           0 :   BoxValuesToString(horizontalString, horizontal);
    6242           0 :   BoxValuesToString(verticalString, vertical);
    6243           0 :   aCssText.Append(horizontalString);
    6244           0 :   if (horizontalString == verticalString) {
    6245           0 :     return;
    6246             :   }
    6247           0 :   aCssText.AppendLiteral(" / ");
    6248           0 :   aCssText.Append(verticalString);
    6249             : }
    6250             : 
    6251             : already_AddRefed<CSSValue>
    6252           0 : nsComputedDOMStyle::CreatePrimitiveValueForBasicShape(
    6253             :   const StyleBasicShape* aStyleBasicShape)
    6254             : {
    6255           0 :   MOZ_ASSERT(aStyleBasicShape, "Expect a valid basic shape pointer!");
    6256             : 
    6257           0 :   StyleBasicShapeType type = aStyleBasicShape->GetShapeType();
    6258             :   // Shape function name and opening parenthesis.
    6259           0 :   nsAutoString shapeFunctionString;
    6260           0 :   AppendASCIItoUTF16(nsCSSKeywords::GetStringValue(
    6261           0 :                        aStyleBasicShape->GetShapeTypeName()),
    6262           0 :                      shapeFunctionString);
    6263           0 :   shapeFunctionString.Append('(');
    6264           0 :   switch (type) {
    6265             :     case StyleBasicShapeType::Polygon: {
    6266           0 :       bool hasEvenOdd = aStyleBasicShape->GetFillRule() ==
    6267           0 :         StyleFillRule::Evenodd;
    6268           0 :       if (hasEvenOdd) {
    6269           0 :         shapeFunctionString.AppendLiteral("evenodd");
    6270             :       }
    6271           0 :       for (size_t i = 0;
    6272           0 :            i < aStyleBasicShape->Coordinates().Length(); i += 2) {
    6273           0 :         nsAutoString coordString;
    6274           0 :         if (i > 0 || hasEvenOdd) {
    6275           0 :           shapeFunctionString.AppendLiteral(", ");
    6276             :         }
    6277             :         SetCssTextToCoord(coordString,
    6278           0 :                           aStyleBasicShape->Coordinates()[i]);
    6279           0 :         shapeFunctionString.Append(coordString);
    6280           0 :         shapeFunctionString.Append(' ');
    6281             :         SetCssTextToCoord(coordString,
    6282           0 :                           aStyleBasicShape->Coordinates()[i + 1]);
    6283           0 :         shapeFunctionString.Append(coordString);
    6284             :       }
    6285           0 :       break;
    6286             :     }
    6287             :     case StyleBasicShapeType::Circle:
    6288             :     case StyleBasicShapeType::Ellipse: {
    6289           0 :       const nsTArray<nsStyleCoord>& radii = aStyleBasicShape->Coordinates();
    6290           0 :       MOZ_ASSERT(radii.Length() ==
    6291             :                  (type == StyleBasicShapeType::Circle ? 1 : 2),
    6292             :                  "wrong number of radii");
    6293           0 :       for (size_t i = 0; i < radii.Length(); ++i) {
    6294           0 :         nsAutoString radius;
    6295           0 :         RefPtr<nsROCSSPrimitiveValue> value = new nsROCSSPrimitiveValue;
    6296           0 :         bool clampNegativeCalc = true;
    6297           0 :         SetValueToCoord(value, radii[i], clampNegativeCalc, nullptr,
    6298           0 :                         nsCSSProps::kShapeRadiusKTable);
    6299           0 :         value->GetCssText(radius);
    6300           0 :         shapeFunctionString.Append(radius);
    6301           0 :         shapeFunctionString.Append(' ');
    6302             :       }
    6303           0 :       shapeFunctionString.AppendLiteral("at ");
    6304             : 
    6305           0 :       RefPtr<nsDOMCSSValueList> position = GetROCSSValueList(false);
    6306           0 :       nsAutoString positionString;
    6307           0 :       SetValueToPosition(aStyleBasicShape->GetPosition(), position);
    6308           0 :       position->GetCssText(positionString);
    6309           0 :       shapeFunctionString.Append(positionString);
    6310           0 :       break;
    6311             :     }
    6312             :     case StyleBasicShapeType::Inset: {
    6313           0 :       BoxValuesToString(shapeFunctionString, aStyleBasicShape->Coordinates());
    6314           0 :       if (aStyleBasicShape->HasRadius()) {
    6315           0 :         shapeFunctionString.AppendLiteral(" round ");
    6316           0 :         nsAutoString radiiString;
    6317           0 :         BasicShapeRadiiToString(radiiString, aStyleBasicShape->GetRadius());
    6318           0 :         shapeFunctionString.Append(radiiString);
    6319             :       }
    6320           0 :       break;
    6321             :     }
    6322             :     default:
    6323           0 :       NS_NOTREACHED("unexpected type");
    6324             :   }
    6325           0 :   shapeFunctionString.Append(')');
    6326           0 :   RefPtr<nsROCSSPrimitiveValue> functionValue = new nsROCSSPrimitiveValue;
    6327           0 :   functionValue->SetString(shapeFunctionString);
    6328           0 :   return functionValue.forget();
    6329             : }
    6330             : 
    6331             : template<typename ReferenceBox>
    6332             : already_AddRefed<CSSValue>
    6333           0 : nsComputedDOMStyle::CreatePrimitiveValueForShapeSource(
    6334             :   const StyleBasicShape* aStyleBasicShape,
    6335             :   ReferenceBox aReferenceBox,
    6336             :   const KTableEntry aBoxKeywordTable[])
    6337             : {
    6338           0 :   RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false);
    6339           0 :   if (aStyleBasicShape) {
    6340           0 :     valueList->AppendCSSValue(
    6341             :       CreatePrimitiveValueForBasicShape(aStyleBasicShape));
    6342             :   }
    6343             : 
    6344           0 :   if (aReferenceBox == ReferenceBox::NoBox) {
    6345           0 :     return valueList.forget();
    6346             :   }
    6347             : 
    6348           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    6349           0 :   val->SetIdent(nsCSSProps::ValueToKeywordEnum(aReferenceBox, aBoxKeywordTable));
    6350           0 :   valueList->AppendCSSValue(val.forget());
    6351             : 
    6352           0 :   return valueList.forget();
    6353             : }
    6354             : 
    6355             : already_AddRefed<CSSValue>
    6356           0 : nsComputedDOMStyle::GetShapeSource(
    6357             :   const StyleShapeSource& aShapeSource,
    6358             :   const KTableEntry aBoxKeywordTable[])
    6359             : {
    6360           0 :   switch (aShapeSource.GetType()) {
    6361             :     case StyleShapeSourceType::Shape:
    6362           0 :       return CreatePrimitiveValueForShapeSource(aShapeSource.GetBasicShape(),
    6363             :                                                 aShapeSource.GetReferenceBox(),
    6364           0 :                                                 aBoxKeywordTable);
    6365             :     case StyleShapeSourceType::Box:
    6366             :       return CreatePrimitiveValueForShapeSource(nullptr,
    6367             :                                                 aShapeSource.GetReferenceBox(),
    6368           0 :                                                 aBoxKeywordTable);
    6369             :     case StyleShapeSourceType::URL: {
    6370           0 :       RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    6371           0 :       SetValueToURLValue(aShapeSource.GetURL(), val);
    6372           0 :       return val.forget();
    6373             :     }
    6374             :     case StyleShapeSourceType::None: {
    6375           0 :       RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    6376           0 :       val->SetIdent(eCSSKeyword_none);
    6377           0 :       return val.forget();
    6378             :     }
    6379             :     default:
    6380           0 :       NS_NOTREACHED("unexpected type");
    6381             :   }
    6382           0 :   return nullptr;
    6383             : }
    6384             : 
    6385             : already_AddRefed<CSSValue>
    6386           0 : nsComputedDOMStyle::DoGetClipPath()
    6387             : {
    6388           0 :   return GetShapeSource(StyleSVGReset()->mClipPath,
    6389           0 :                         nsCSSProps::kClipPathGeometryBoxKTable);
    6390             : }
    6391             : 
    6392             : already_AddRefed<CSSValue>
    6393           0 : nsComputedDOMStyle::DoGetShapeOutside()
    6394             : {
    6395           0 :   return GetShapeSource(StyleDisplay()->mShapeOutside,
    6396           0 :                         nsCSSProps::kShapeOutsideShapeBoxKTable);
    6397             : }
    6398             : 
    6399             : void
    6400           0 : nsComputedDOMStyle::SetCssTextToCoord(nsAString& aCssText,
    6401             :                                       const nsStyleCoord& aCoord)
    6402             : {
    6403           0 :   RefPtr<nsROCSSPrimitiveValue> value = new nsROCSSPrimitiveValue;
    6404           0 :   bool clampNegativeCalc = true;
    6405           0 :   SetValueToCoord(value, aCoord, clampNegativeCalc);
    6406           0 :   value->GetCssText(aCssText);
    6407           0 : }
    6408             : 
    6409             : already_AddRefed<CSSValue>
    6410           0 : nsComputedDOMStyle::CreatePrimitiveValueForStyleFilter(
    6411             :   const nsStyleFilter& aStyleFilter)
    6412             : {
    6413           0 :   RefPtr<nsROCSSPrimitiveValue> value = new nsROCSSPrimitiveValue;
    6414             :   // Handle url().
    6415           0 :   if (aStyleFilter.GetType() == NS_STYLE_FILTER_URL) {
    6416           0 :     MOZ_ASSERT(aStyleFilter.GetURL() &&
    6417             :                aStyleFilter.GetURL()->GetURI());
    6418           0 :     SetValueToURLValue(aStyleFilter.GetURL(), value);
    6419           0 :     return value.forget();
    6420             :   }
    6421             : 
    6422             :   // Filter function name and opening parenthesis.
    6423           0 :   nsAutoString filterFunctionString;
    6424           0 :   AppendASCIItoUTF16(
    6425           0 :     nsCSSProps::ValueToKeyword(aStyleFilter.GetType(),
    6426           0 :                                nsCSSProps::kFilterFunctionKTable),
    6427           0 :                                filterFunctionString);
    6428           0 :   filterFunctionString.Append('(');
    6429             : 
    6430           0 :   nsAutoString argumentString;
    6431           0 :   if (aStyleFilter.GetType() == NS_STYLE_FILTER_DROP_SHADOW) {
    6432             :     // Handle drop-shadow()
    6433             :     RefPtr<CSSValue> shadowValue =
    6434           0 :       GetCSSShadowArray(aStyleFilter.GetDropShadow(),
    6435           0 :                         StyleColor()->mColor,
    6436           0 :                         false);
    6437           0 :     ErrorResult dummy;
    6438           0 :     shadowValue->GetCssText(argumentString, dummy);
    6439             :   } else {
    6440             :     // Filter function argument.
    6441           0 :     SetCssTextToCoord(argumentString, aStyleFilter.GetFilterParameter());
    6442             :   }
    6443           0 :   filterFunctionString.Append(argumentString);
    6444             : 
    6445             :   // Filter function closing parenthesis.
    6446           0 :   filterFunctionString.Append(')');
    6447             : 
    6448           0 :   value->SetString(filterFunctionString);
    6449           0 :   return value.forget();
    6450             : }
    6451             : 
    6452             : already_AddRefed<CSSValue>
    6453           0 : nsComputedDOMStyle::DoGetFilter()
    6454             : {
    6455           0 :   const nsTArray<nsStyleFilter>& filters = StyleEffects()->mFilters;
    6456             : 
    6457           0 :   if (filters.IsEmpty()) {
    6458           0 :     RefPtr<nsROCSSPrimitiveValue> value = new nsROCSSPrimitiveValue;
    6459           0 :     value->SetIdent(eCSSKeyword_none);
    6460           0 :     return value.forget();
    6461             :   }
    6462             : 
    6463           0 :   RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(false);
    6464           0 :   for(uint32_t i = 0; i < filters.Length(); i++) {
    6465           0 :     RefPtr<CSSValue> value = CreatePrimitiveValueForStyleFilter(filters[i]);
    6466           0 :     valueList->AppendCSSValue(value.forget());
    6467             :   }
    6468           0 :   return valueList.forget();
    6469             : }
    6470             : 
    6471             : already_AddRefed<CSSValue>
    6472           0 : nsComputedDOMStyle::DoGetMask()
    6473             : {
    6474           0 :   const nsStyleSVGReset* svg = StyleSVGReset();
    6475           0 :   const nsStyleImageLayers::Layer& firstLayer = svg->mMask.mLayers[0];
    6476             : 
    6477             :   // Mask is now a shorthand, but it used to be a longhand, so that we
    6478             :   // need to support computed style for the cases where it used to be
    6479             :   // a longhand.
    6480           0 :   if (svg->mMask.mImageCount > 1 ||
    6481           0 :       firstLayer.mClip != StyleGeometryBox::BorderBox ||
    6482           0 :       firstLayer.mOrigin != StyleGeometryBox::BorderBox ||
    6483           0 :       firstLayer.mComposite != NS_STYLE_MASK_COMPOSITE_ADD ||
    6484           0 :       firstLayer.mMaskMode != NS_STYLE_MASK_MODE_MATCH_SOURCE ||
    6485           0 :       !nsStyleImageLayers::IsInitialPositionForLayerType(
    6486           0 :         firstLayer.mPosition, nsStyleImageLayers::LayerType::Mask) ||
    6487           0 :       !firstLayer.mRepeat.IsInitialValue() ||
    6488           0 :       !firstLayer.mSize.IsInitialValue() ||
    6489           0 :       !(firstLayer.mImage.GetType() == eStyleImageType_Null ||
    6490           0 :         firstLayer.mImage.GetType() == eStyleImageType_Image ||
    6491           0 :         firstLayer.mImage.GetType() == eStyleImageType_URL)) {
    6492           0 :     return nullptr;
    6493             :   }
    6494             : 
    6495           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    6496             : 
    6497           0 :   SetValueToURLValue(firstLayer.mImage.GetURLValue(), val);
    6498             : 
    6499           0 :   return val.forget();
    6500             : }
    6501             : 
    6502             : #ifdef MOZ_ENABLE_MASK_AS_SHORTHAND
    6503             : already_AddRefed<CSSValue>
    6504           0 : nsComputedDOMStyle::DoGetMaskClip()
    6505             : {
    6506             :   return GetBackgroundList(&nsStyleImageLayers::Layer::mClip,
    6507             :                            &nsStyleImageLayers::mClipCount,
    6508           0 :                            StyleSVGReset()->mMask,
    6509           0 :                            nsCSSProps::kMaskClipKTable);
    6510             : }
    6511             : 
    6512             : already_AddRefed<CSSValue>
    6513           0 : nsComputedDOMStyle::DoGetMaskComposite()
    6514             : {
    6515             :   return GetBackgroundList(&nsStyleImageLayers::Layer::mComposite,
    6516             :                            &nsStyleImageLayers::mCompositeCount,
    6517           0 :                            StyleSVGReset()->mMask,
    6518           0 :                            nsCSSProps::kImageLayerCompositeKTable);
    6519             : }
    6520             : 
    6521             : already_AddRefed<CSSValue>
    6522           0 : nsComputedDOMStyle::DoGetMaskImage()
    6523             : {
    6524           0 :   const nsStyleImageLayers& layers = StyleSVGReset()->mMask;
    6525           0 :   return DoGetImageLayerImage(layers);
    6526             : }
    6527             : 
    6528             : already_AddRefed<CSSValue>
    6529           0 : nsComputedDOMStyle::DoGetMaskMode()
    6530             : {
    6531             :   return GetBackgroundList(&nsStyleImageLayers::Layer::mMaskMode,
    6532             :                            &nsStyleImageLayers::mMaskModeCount,
    6533           0 :                            StyleSVGReset()->mMask,
    6534           0 :                            nsCSSProps::kImageLayerModeKTable);
    6535             : }
    6536             : 
    6537             : already_AddRefed<CSSValue>
    6538           0 : nsComputedDOMStyle::DoGetMaskOrigin()
    6539             : {
    6540             :   return GetBackgroundList(&nsStyleImageLayers::Layer::mOrigin,
    6541             :                            &nsStyleImageLayers::mOriginCount,
    6542           0 :                            StyleSVGReset()->mMask,
    6543           0 :                            nsCSSProps::kMaskOriginKTable);
    6544             : }
    6545             : 
    6546             : already_AddRefed<CSSValue>
    6547           0 : nsComputedDOMStyle::DoGetMaskPosition()
    6548             : {
    6549           0 :   const nsStyleImageLayers& layers = StyleSVGReset()->mMask;
    6550           0 :   return DoGetImageLayerPosition(layers);
    6551             : }
    6552             : 
    6553             : already_AddRefed<CSSValue>
    6554           0 : nsComputedDOMStyle::DoGetMaskPositionX()
    6555             : {
    6556           0 :   const nsStyleImageLayers& layers = StyleSVGReset()->mMask;
    6557           0 :   return DoGetImageLayerPositionX(layers);
    6558             : }
    6559             : 
    6560             : already_AddRefed<CSSValue>
    6561           0 : nsComputedDOMStyle::DoGetMaskPositionY()
    6562             : {
    6563           0 :   const nsStyleImageLayers& layers = StyleSVGReset()->mMask;
    6564           0 :   return DoGetImageLayerPositionY(layers);
    6565             : }
    6566             : 
    6567             : already_AddRefed<CSSValue>
    6568           0 : nsComputedDOMStyle::DoGetMaskRepeat()
    6569             : {
    6570           0 :   const nsStyleImageLayers& layers = StyleSVGReset()->mMask;
    6571           0 :   return DoGetImageLayerRepeat(layers);
    6572             : }
    6573             : 
    6574             : already_AddRefed<CSSValue>
    6575           0 : nsComputedDOMStyle::DoGetMaskSize()
    6576             : {
    6577           0 :   const nsStyleImageLayers& layers = StyleSVGReset()->mMask;
    6578           0 :   return DoGetImageLayerSize(layers);
    6579             : }
    6580             : #endif
    6581             : 
    6582             : already_AddRefed<CSSValue>
    6583           0 : nsComputedDOMStyle::DoGetMaskType()
    6584             : {
    6585           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    6586           0 :   val->SetIdent(
    6587           0 :     nsCSSProps::ValueToKeywordEnum(StyleSVGReset()->mMaskType,
    6588           0 :                                    nsCSSProps::kMaskTypeKTable));
    6589           0 :   return val.forget();
    6590             : }
    6591             : 
    6592             : already_AddRefed<CSSValue>
    6593           0 : nsComputedDOMStyle::DoGetContextProperties()
    6594             : {
    6595           0 :   const nsTArray<nsCOMPtr<nsIAtom>>& contextProps = StyleSVG()->mContextProps;
    6596             : 
    6597           0 :   if (contextProps.IsEmpty()) {
    6598           0 :     RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    6599           0 :     val->SetIdent(eCSSKeyword_none);
    6600           0 :     return val.forget();
    6601             :   }
    6602             : 
    6603           0 :   RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(true);
    6604           0 :   for (const nsIAtom* ident : contextProps) {
    6605           0 :     RefPtr<nsROCSSPrimitiveValue> property = new nsROCSSPrimitiveValue;
    6606           0 :     property->SetString(nsDependentAtomString(ident));
    6607           0 :     valueList->AppendCSSValue(property.forget());
    6608             :   }
    6609             : 
    6610           0 :   return valueList.forget();
    6611             : }
    6612             : 
    6613             : already_AddRefed<CSSValue>
    6614           0 : nsComputedDOMStyle::DoGetPaintOrder()
    6615             : {
    6616           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    6617           0 :   nsAutoString string;
    6618           0 :   uint8_t paintOrder = StyleSVG()->mPaintOrder;
    6619           0 :   nsStyleUtil::AppendPaintOrderValue(paintOrder, string);
    6620           0 :   val->SetString(string);
    6621           0 :   return val.forget();
    6622             : }
    6623             : 
    6624             : already_AddRefed<CSSValue>
    6625           0 : nsComputedDOMStyle::DoGetTransitionDelay()
    6626             : {
    6627           0 :   const nsStyleDisplay* display = StyleDisplay();
    6628             : 
    6629           0 :   RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(true);
    6630             : 
    6631           0 :   MOZ_ASSERT(display->mTransitionDelayCount > 0,
    6632             :              "first item must be explicit");
    6633           0 :   uint32_t i = 0;
    6634           0 :   do {
    6635           0 :     const StyleTransition *transition = &display->mTransitions[i];
    6636           0 :     RefPtr<nsROCSSPrimitiveValue> delay = new nsROCSSPrimitiveValue;
    6637           0 :     delay->SetTime((float)transition->GetDelay() / (float)PR_MSEC_PER_SEC);
    6638           0 :     valueList->AppendCSSValue(delay.forget());
    6639           0 :   } while (++i < display->mTransitionDelayCount);
    6640             : 
    6641           0 :   return valueList.forget();
    6642             : }
    6643             : 
    6644             : already_AddRefed<CSSValue>
    6645           0 : nsComputedDOMStyle::DoGetTransitionDuration()
    6646             : {
    6647           0 :   const nsStyleDisplay* display = StyleDisplay();
    6648             : 
    6649           0 :   RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(true);
    6650             : 
    6651           0 :   MOZ_ASSERT(display->mTransitionDurationCount > 0,
    6652             :              "first item must be explicit");
    6653           0 :   uint32_t i = 0;
    6654           0 :   do {
    6655           0 :     const StyleTransition *transition = &display->mTransitions[i];
    6656           0 :     RefPtr<nsROCSSPrimitiveValue> duration = new nsROCSSPrimitiveValue;
    6657             : 
    6658           0 :     duration->SetTime((float)transition->GetDuration() / (float)PR_MSEC_PER_SEC);
    6659           0 :     valueList->AppendCSSValue(duration.forget());
    6660           0 :   } while (++i < display->mTransitionDurationCount);
    6661             : 
    6662           0 :   return valueList.forget();
    6663             : }
    6664             : 
    6665             : already_AddRefed<CSSValue>
    6666           0 : nsComputedDOMStyle::DoGetTransitionProperty()
    6667             : {
    6668           0 :   const nsStyleDisplay* display = StyleDisplay();
    6669             : 
    6670           0 :   RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(true);
    6671             : 
    6672           0 :   MOZ_ASSERT(display->mTransitionPropertyCount > 0,
    6673             :              "first item must be explicit");
    6674           0 :   uint32_t i = 0;
    6675           0 :   do {
    6676           0 :     const StyleTransition *transition = &display->mTransitions[i];
    6677           0 :     RefPtr<nsROCSSPrimitiveValue> property = new nsROCSSPrimitiveValue;
    6678           0 :     nsCSSPropertyID cssprop = transition->GetProperty();
    6679           0 :     if (cssprop == eCSSPropertyExtra_all_properties)
    6680           0 :       property->SetIdent(eCSSKeyword_all);
    6681           0 :     else if (cssprop == eCSSPropertyExtra_no_properties)
    6682           0 :       property->SetIdent(eCSSKeyword_none);
    6683           0 :     else if (cssprop == eCSSProperty_UNKNOWN ||
    6684             :              cssprop == eCSSPropertyExtra_variable)
    6685             :     {
    6686           0 :       nsAutoString escaped;
    6687             :       nsStyleUtil::AppendEscapedCSSIdent(
    6688           0 :         nsDependentAtomString(transition->GetUnknownProperty()), escaped);
    6689           0 :       property->SetString(escaped); // really want SetIdent
    6690             :     }
    6691             :     else
    6692           0 :       property->SetString(nsCSSProps::GetStringValue(cssprop));
    6693             : 
    6694           0 :     valueList->AppendCSSValue(property.forget());
    6695           0 :   } while (++i < display->mTransitionPropertyCount);
    6696             : 
    6697           0 :   return valueList.forget();
    6698             : }
    6699             : 
    6700             : void
    6701           0 : nsComputedDOMStyle::AppendTimingFunction(nsDOMCSSValueList *aValueList,
    6702             :                                          const nsTimingFunction& aTimingFunction)
    6703             : {
    6704           0 :   RefPtr<nsROCSSPrimitiveValue> timingFunction = new nsROCSSPrimitiveValue;
    6705             : 
    6706           0 :   nsAutoString tmp;
    6707           0 :   switch (aTimingFunction.mType) {
    6708             :     case nsTimingFunction::Type::CubicBezier:
    6709           0 :       nsStyleUtil::AppendCubicBezierTimingFunction(aTimingFunction.mFunc.mX1,
    6710           0 :                                                    aTimingFunction.mFunc.mY1,
    6711           0 :                                                    aTimingFunction.mFunc.mX2,
    6712           0 :                                                    aTimingFunction.mFunc.mY2,
    6713           0 :                                                    tmp);
    6714           0 :       break;
    6715             :     case nsTimingFunction::Type::StepStart:
    6716             :     case nsTimingFunction::Type::StepEnd:
    6717           0 :       nsStyleUtil::AppendStepsTimingFunction(aTimingFunction.mType,
    6718           0 :                                              aTimingFunction.mStepsOrFrames,
    6719           0 :                                              tmp);
    6720           0 :       break;
    6721             :     case nsTimingFunction::Type::Frames:
    6722           0 :       nsStyleUtil::AppendFramesTimingFunction(aTimingFunction.mStepsOrFrames,
    6723           0 :                                               tmp);
    6724           0 :       break;
    6725             :     default:
    6726           0 :       nsStyleUtil::AppendCubicBezierKeywordTimingFunction(aTimingFunction.mType,
    6727           0 :                                                           tmp);
    6728           0 :       break;
    6729             :   }
    6730           0 :   timingFunction->SetString(tmp);
    6731           0 :   aValueList->AppendCSSValue(timingFunction.forget());
    6732           0 : }
    6733             : 
    6734             : already_AddRefed<CSSValue>
    6735           0 : nsComputedDOMStyle::DoGetTransitionTimingFunction()
    6736             : {
    6737           0 :   const nsStyleDisplay* display = StyleDisplay();
    6738             : 
    6739           0 :   RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(true);
    6740             : 
    6741           0 :   MOZ_ASSERT(display->mTransitionTimingFunctionCount > 0,
    6742             :              "first item must be explicit");
    6743           0 :   uint32_t i = 0;
    6744           0 :   do {
    6745           0 :     AppendTimingFunction(valueList,
    6746           0 :                          display->mTransitions[i].GetTimingFunction());
    6747           0 :   } while (++i < display->mTransitionTimingFunctionCount);
    6748             : 
    6749           0 :   return valueList.forget();
    6750             : }
    6751             : 
    6752             : already_AddRefed<CSSValue>
    6753           0 : nsComputedDOMStyle::DoGetAnimationName()
    6754             : {
    6755           0 :   const nsStyleDisplay* display = StyleDisplay();
    6756             : 
    6757           0 :   RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(true);
    6758             : 
    6759           0 :   MOZ_ASSERT(display->mAnimationNameCount > 0,
    6760             :              "first item must be explicit");
    6761           0 :   uint32_t i = 0;
    6762           0 :   do {
    6763           0 :     const StyleAnimation *animation = &display->mAnimations[i];
    6764           0 :     RefPtr<nsROCSSPrimitiveValue> property = new nsROCSSPrimitiveValue;
    6765             : 
    6766           0 :     const nsString& name = animation->GetName();
    6767           0 :     if (name.IsEmpty()) {
    6768           0 :       property->SetIdent(eCSSKeyword_none);
    6769             :     } else {
    6770           0 :       nsAutoString escaped;
    6771           0 :       nsStyleUtil::AppendEscapedCSSIdent(animation->GetName(), escaped);
    6772           0 :       property->SetString(escaped); // really want SetIdent
    6773             :     }
    6774           0 :     valueList->AppendCSSValue(property.forget());
    6775           0 :   } while (++i < display->mAnimationNameCount);
    6776             : 
    6777           0 :   return valueList.forget();
    6778             : }
    6779             : 
    6780             : already_AddRefed<CSSValue>
    6781           0 : nsComputedDOMStyle::DoGetAnimationDelay()
    6782             : {
    6783           0 :   const nsStyleDisplay* display = StyleDisplay();
    6784             : 
    6785           0 :   RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(true);
    6786             : 
    6787           0 :   MOZ_ASSERT(display->mAnimationDelayCount > 0,
    6788             :              "first item must be explicit");
    6789           0 :   uint32_t i = 0;
    6790           0 :   do {
    6791           0 :     const StyleAnimation *animation = &display->mAnimations[i];
    6792           0 :     RefPtr<nsROCSSPrimitiveValue> delay = new nsROCSSPrimitiveValue;
    6793           0 :     delay->SetTime((float)animation->GetDelay() / (float)PR_MSEC_PER_SEC);
    6794           0 :     valueList->AppendCSSValue(delay.forget());
    6795           0 :   } while (++i < display->mAnimationDelayCount);
    6796             : 
    6797           0 :   return valueList.forget();
    6798             : }
    6799             : 
    6800             : already_AddRefed<CSSValue>
    6801           0 : nsComputedDOMStyle::DoGetAnimationDuration()
    6802             : {
    6803           0 :   const nsStyleDisplay* display = StyleDisplay();
    6804             : 
    6805           0 :   RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(true);
    6806             : 
    6807           0 :   MOZ_ASSERT(display->mAnimationDurationCount > 0,
    6808             :              "first item must be explicit");
    6809           0 :   uint32_t i = 0;
    6810           0 :   do {
    6811           0 :     const StyleAnimation *animation = &display->mAnimations[i];
    6812           0 :     RefPtr<nsROCSSPrimitiveValue> duration = new nsROCSSPrimitiveValue;
    6813             : 
    6814           0 :     duration->SetTime((float)animation->GetDuration() / (float)PR_MSEC_PER_SEC);
    6815           0 :     valueList->AppendCSSValue(duration.forget());
    6816           0 :   } while (++i < display->mAnimationDurationCount);
    6817             : 
    6818           0 :   return valueList.forget();
    6819             : }
    6820             : 
    6821             : already_AddRefed<CSSValue>
    6822           0 : nsComputedDOMStyle::DoGetAnimationTimingFunction()
    6823             : {
    6824           0 :   const nsStyleDisplay* display = StyleDisplay();
    6825             : 
    6826           0 :   RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(true);
    6827             : 
    6828           0 :   MOZ_ASSERT(display->mAnimationTimingFunctionCount > 0,
    6829             :              "first item must be explicit");
    6830           0 :   uint32_t i = 0;
    6831           0 :   do {
    6832           0 :     AppendTimingFunction(valueList,
    6833           0 :                          display->mAnimations[i].GetTimingFunction());
    6834           0 :   } while (++i < display->mAnimationTimingFunctionCount);
    6835             : 
    6836           0 :   return valueList.forget();
    6837             : }
    6838             : 
    6839             : already_AddRefed<CSSValue>
    6840           0 : nsComputedDOMStyle::DoGetAnimationDirection()
    6841             : {
    6842           0 :   const nsStyleDisplay* display = StyleDisplay();
    6843             : 
    6844           0 :   RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(true);
    6845             : 
    6846           0 :   MOZ_ASSERT(display->mAnimationDirectionCount > 0,
    6847             :              "first item must be explicit");
    6848           0 :   uint32_t i = 0;
    6849           0 :   do {
    6850           0 :     const StyleAnimation *animation = &display->mAnimations[i];
    6851           0 :     RefPtr<nsROCSSPrimitiveValue> direction = new nsROCSSPrimitiveValue;
    6852           0 :     direction->SetIdent(
    6853           0 :       nsCSSProps::ValueToKeywordEnum(
    6854           0 :         static_cast<int32_t>(animation->GetDirection()),
    6855           0 :         nsCSSProps::kAnimationDirectionKTable));
    6856             : 
    6857           0 :     valueList->AppendCSSValue(direction.forget());
    6858           0 :   } while (++i < display->mAnimationDirectionCount);
    6859             : 
    6860           0 :   return valueList.forget();
    6861             : }
    6862             : 
    6863             : already_AddRefed<CSSValue>
    6864           0 : nsComputedDOMStyle::DoGetAnimationFillMode()
    6865             : {
    6866           0 :   const nsStyleDisplay* display = StyleDisplay();
    6867             : 
    6868           0 :   RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(true);
    6869             : 
    6870           0 :   MOZ_ASSERT(display->mAnimationFillModeCount > 0,
    6871             :              "first item must be explicit");
    6872           0 :   uint32_t i = 0;
    6873           0 :   do {
    6874           0 :     const StyleAnimation *animation = &display->mAnimations[i];
    6875           0 :     RefPtr<nsROCSSPrimitiveValue> fillMode = new nsROCSSPrimitiveValue;
    6876           0 :     fillMode->SetIdent(
    6877           0 :       nsCSSProps::ValueToKeywordEnum(
    6878           0 :         static_cast<int32_t>(animation->GetFillMode()),
    6879           0 :         nsCSSProps::kAnimationFillModeKTable));
    6880             : 
    6881           0 :     valueList->AppendCSSValue(fillMode.forget());
    6882           0 :   } while (++i < display->mAnimationFillModeCount);
    6883             : 
    6884           0 :   return valueList.forget();
    6885             : }
    6886             : 
    6887             : already_AddRefed<CSSValue>
    6888           0 : nsComputedDOMStyle::DoGetAnimationIterationCount()
    6889             : {
    6890           0 :   const nsStyleDisplay* display = StyleDisplay();
    6891             : 
    6892           0 :   RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(true);
    6893             : 
    6894           0 :   MOZ_ASSERT(display->mAnimationIterationCountCount > 0,
    6895             :              "first item must be explicit");
    6896           0 :   uint32_t i = 0;
    6897           0 :   do {
    6898           0 :     const StyleAnimation *animation = &display->mAnimations[i];
    6899           0 :     RefPtr<nsROCSSPrimitiveValue> iterationCount = new nsROCSSPrimitiveValue;
    6900             : 
    6901           0 :     float f = animation->GetIterationCount();
    6902             :     /* Need a nasty hack here to work around an optimizer bug in gcc
    6903             :        4.2 on Mac, which somehow gets confused when directly comparing
    6904             :        a float to the return value of NS_IEEEPositiveInfinity when
    6905             :        building 32-bit builds. */
    6906             : #ifdef XP_MACOSX
    6907             :     volatile
    6908             : #endif
    6909           0 :       float inf = NS_IEEEPositiveInfinity();
    6910           0 :     if (f == inf) {
    6911           0 :       iterationCount->SetIdent(eCSSKeyword_infinite);
    6912             :     } else {
    6913           0 :       iterationCount->SetNumber(f);
    6914             :     }
    6915           0 :     valueList->AppendCSSValue(iterationCount.forget());
    6916           0 :   } while (++i < display->mAnimationIterationCountCount);
    6917             : 
    6918           0 :   return valueList.forget();
    6919             : }
    6920             : 
    6921             : already_AddRefed<CSSValue>
    6922           0 : nsComputedDOMStyle::DoGetAnimationPlayState()
    6923             : {
    6924           0 :   const nsStyleDisplay* display = StyleDisplay();
    6925             : 
    6926           0 :   RefPtr<nsDOMCSSValueList> valueList = GetROCSSValueList(true);
    6927             : 
    6928           0 :   MOZ_ASSERT(display->mAnimationPlayStateCount > 0,
    6929             :              "first item must be explicit");
    6930           0 :   uint32_t i = 0;
    6931           0 :   do {
    6932           0 :     const StyleAnimation *animation = &display->mAnimations[i];
    6933           0 :     RefPtr<nsROCSSPrimitiveValue> playState = new nsROCSSPrimitiveValue;
    6934           0 :     playState->SetIdent(
    6935           0 :       nsCSSProps::ValueToKeywordEnum(animation->GetPlayState(),
    6936           0 :                                      nsCSSProps::kAnimationPlayStateKTable));
    6937           0 :     valueList->AppendCSSValue(playState.forget());
    6938           0 :   } while (++i < display->mAnimationPlayStateCount);
    6939             : 
    6940           0 :   return valueList.forget();
    6941             : }
    6942             : 
    6943             : static void
    6944           0 : MarkComputedStyleMapDirty(const char* aPref, void* aData)
    6945             : {
    6946           0 :   static_cast<nsComputedStyleMap*>(aData)->MarkDirty();
    6947           0 : }
    6948             : 
    6949             : already_AddRefed<CSSValue>
    6950           0 : nsComputedDOMStyle::DoGetCustomProperty(const nsAString& aPropertyName)
    6951             : {
    6952           0 :   MOZ_ASSERT(nsCSSProps::IsCustomPropertyName(aPropertyName));
    6953             : 
    6954           0 :   nsString variableValue;
    6955             :   const nsAString& name = Substring(aPropertyName,
    6956           0 :                                     CSS_CUSTOM_NAME_PREFIX_LENGTH);
    6957           0 :   bool present = mStyleContext->IsServo()
    6958           0 :     ? Servo_GetCustomPropertyValue(mStyleContext->ComputedValues(),
    6959             :                                    &name, &variableValue)
    6960           0 :     : StyleVariables()->mVariables.Get(name, variableValue);
    6961           0 :   if (!present) {
    6962           0 :     return nullptr;
    6963             :   }
    6964             : 
    6965           0 :   RefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue;
    6966           0 :   val->SetString(variableValue);
    6967             : 
    6968           0 :   return val.forget();
    6969             : }
    6970             : 
    6971             : void
    6972           0 : nsComputedDOMStyle::ParentChainChanged(nsIContent* aContent)
    6973             : {
    6974           0 :   NS_ASSERTION(mContent == aContent, "didn't we register mContent?");
    6975           0 :   NS_ASSERTION(mResolvedStyleContext,
    6976             :                "should have only registered an observer when "
    6977             :                "mResolvedStyleContext is true");
    6978             : 
    6979           0 :   ClearStyleContext();
    6980           0 : }
    6981             : 
    6982             : /* static */ nsComputedStyleMap*
    6983           7 : nsComputedDOMStyle::GetComputedStyleMap()
    6984             : {
    6985             :   static nsComputedStyleMap map = {
    6986             :     {
    6987             : #define COMPUTED_STYLE_PROP(prop_, method_) \
    6988             :   { eCSSProperty_##prop_, &nsComputedDOMStyle::DoGet##method_ },
    6989             : #include "nsComputedDOMStylePropertyList.h"
    6990             : #undef COMPUTED_STYLE_PROP
    6991             :     }
    6992             :   };
    6993           7 :   return &map;
    6994             : }
    6995             : 
    6996             : /* static */ void
    6997           3 : nsComputedDOMStyle::RegisterPrefChangeCallbacks()
    6998             : {
    6999             :   // Note that this will register callbacks for all properties with prefs, not
    7000             :   // just those that are implemented on computed style objects, as it's not
    7001             :   // easy to grab specific property data from nsCSSPropList.h based on the
    7002             :   // entries iterated in nsComputedDOMStylePropertyList.h.
    7003           3 :   nsComputedStyleMap* data = GetComputedStyleMap();
    7004             : #define REGISTER_CALLBACK(pref_)                                             \
    7005             :   if (pref_[0]) {                                                            \
    7006             :     Preferences::RegisterCallback(MarkComputedStyleMapDirty, pref_, data);   \
    7007             :   }
    7008             : #define CSS_PROP(prop_, id_, method_, flags_, pref_, parsevariant_,          \
    7009             :                  kwtable_, stylestruct_, stylestructoffset_, animtype_)      \
    7010             :   REGISTER_CALLBACK(pref_)
    7011             : #define CSS_PROP_LIST_INCLUDE_LOGICAL
    7012             : #include "nsCSSPropList.h"
    7013             : #undef CSS_PROP_LIST_INCLUDE_LOGICAL
    7014             : #undef CSS_PROP
    7015             : #undef REGISTER_CALLBACK
    7016           3 : }
    7017             : 
    7018             : /* static */ void
    7019           0 : nsComputedDOMStyle::UnregisterPrefChangeCallbacks()
    7020             : {
    7021           0 :   nsComputedStyleMap* data = GetComputedStyleMap();
    7022             : #define UNREGISTER_CALLBACK(pref_)                                             \
    7023             :   if (pref_[0]) {                                                              \
    7024             :     Preferences::UnregisterCallback(MarkComputedStyleMapDirty, pref_, data);   \
    7025             :   }
    7026             : #define CSS_PROP(prop_, id_, method_, flags_, pref_, parsevariant_,            \
    7027             :                  kwtable_, stylestruct_, stylestructoffset_, animtype_)        \
    7028             :   UNREGISTER_CALLBACK(pref_)
    7029             : #define CSS_PROP_LIST_INCLUDE_LOGICAL
    7030             : #include "nsCSSPropList.h"
    7031             : #undef CSS_PROP_LIST_INCLUDE_LOGICAL
    7032             : #undef CSS_PROP
    7033             : #undef UNREGISTER_CALLBACK
    7034           0 : }

Generated by: LCOV version 1.13