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

Generated by: LCOV version 1.13-14-ga5dd952