LCOV - code coverage report
Current view: top level - layout/style - ServoBindings.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 333 1190 28.0 %
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             : #include "mozilla/ServoBindings.h"
       8             : 
       9             : #include "ChildIterator.h"
      10             : #include "ErrorReporter.h"
      11             : #include "GeckoProfiler.h"
      12             : #include "gfxFontFamilyList.h"
      13             : #include "gfxFontFeatures.h"
      14             : #include "nsAnimationManager.h"
      15             : #include "nsAttrValueInlines.h"
      16             : #include "nsCSSFrameConstructor.h"
      17             : #include "nsCSSProps.h"
      18             : #include "nsCSSPseudoElements.h"
      19             : #include "nsContentUtils.h"
      20             : #include "nsDOMTokenList.h"
      21             : #include "nsDeviceContext.h"
      22             : #include "nsIContentInlines.h"
      23             : #include "nsICrashReporter.h"
      24             : #include "nsIDocumentInlines.h"
      25             : #include "nsILoadContext.h"
      26             : #include "nsIFrame.h"
      27             : #include "nsIMemoryReporter.h"
      28             : #include "nsIMozBrowserFrame.h"
      29             : #include "nsINode.h"
      30             : #include "nsIPresShell.h"
      31             : #include "nsIPresShellInlines.h"
      32             : #include "nsIPrincipal.h"
      33             : #include "nsIURI.h"
      34             : #include "nsFontMetrics.h"
      35             : #include "nsHTMLStyleSheet.h"
      36             : #include "nsMappedAttributes.h"
      37             : #include "nsMediaFeatures.h"
      38             : #include "nsNameSpaceManager.h"
      39             : #include "nsNetUtil.h"
      40             : #include "nsProxyRelease.h"
      41             : #include "nsString.h"
      42             : #include "nsStyleStruct.h"
      43             : #include "nsStyleUtil.h"
      44             : #include "nsSVGElement.h"
      45             : #include "nsTArray.h"
      46             : #include "nsTransitionManager.h"
      47             : #include "nsWindowSizes.h"
      48             : 
      49             : #include "mozilla/CORSMode.h"
      50             : #include "mozilla/DeclarationBlock.h"
      51             : #include "mozilla/EffectCompositor.h"
      52             : #include "mozilla/EffectSet.h"
      53             : #include "mozilla/EventStates.h"
      54             : #include "mozilla/FontPropertyTypes.h"
      55             : #include "mozilla/Keyframe.h"
      56             : #include "mozilla/Mutex.h"
      57             : #include "mozilla/Preferences.h"
      58             : #include "mozilla/ServoElementSnapshot.h"
      59             : #include "mozilla/RestyleManager.h"
      60             : #include "mozilla/SizeOfState.h"
      61             : #include "mozilla/StyleAnimationValue.h"
      62             : #include "mozilla/SystemGroup.h"
      63             : #include "mozilla/ServoTraversalStatistics.h"
      64             : #include "mozilla/Telemetry.h"
      65             : #include "mozilla/RWLock.h"
      66             : #include "mozilla/dom/Element.h"
      67             : #include "mozilla/dom/ElementInlines.h"
      68             : #include "mozilla/dom/HTMLTableCellElement.h"
      69             : #include "mozilla/dom/HTMLBodyElement.h"
      70             : #include "mozilla/dom/HTMLSlotElement.h"
      71             : #include "mozilla/dom/MediaList.h"
      72             : #include "mozilla/LookAndFeel.h"
      73             : #include "mozilla/URLExtraData.h"
      74             : #include "mozilla/dom/CSSMozDocumentRule.h"
      75             : 
      76             : #if defined(MOZ_MEMORY)
      77             : # include "mozmemory.h"
      78             : #endif
      79             : 
      80             : using namespace mozilla;
      81             : using namespace mozilla::css;
      82             : using namespace mozilla::dom;
      83             : 
      84             : #define SERVO_ARC_TYPE(name_, type_) \
      85             :   already_AddRefed<type_>            \
      86             :   type_##Strong::Consume() {         \
      87             :     RefPtr<type_> result;            \
      88             :     result.swap(mPtr);               \
      89             :     return result.forget();          \
      90             :   }
      91             : #include "mozilla/ServoArcTypeList.h"
      92        5420 : SERVO_ARC_TYPE(ComputedStyle, ComputedStyle)
      93             : #undef SERVO_ARC_TYPE
      94             : 
      95             : // Definitions of the global traversal stats.
      96             : bool ServoTraversalStatistics::sActive = false;
      97             : ServoTraversalStatistics ServoTraversalStatistics::sSingleton;
      98             : 
      99             : static RWLock* sServoFFILock = nullptr;
     100             : 
     101             : static
     102             : const nsFont*
     103         163 : ThreadSafeGetDefaultFontHelper(const nsPresContext* aPresContext,
     104             :                                nsAtom* aLanguage, uint8_t aGenericId)
     105             : {
     106         163 :   bool needsCache = false;
     107             :   const nsFont* retval;
     108             : 
     109             :   {
     110           0 :     AutoReadLock guard(*sServoFFILock);
     111         163 :     retval = aPresContext->GetDefaultFont(aGenericId, aLanguage, &needsCache);
     112             :   }
     113         163 :   if (!needsCache) {
     114             :     return retval;
     115             :   }
     116             :   {
     117           0 :     AutoWriteLock guard(*sServoFFILock);
     118           0 :     retval = aPresContext->GetDefaultFont(aGenericId, aLanguage, nullptr);
     119             :   }
     120           0 :   return retval;
     121             : }
     122             : 
     123             : void
     124         110 : AssertIsMainThreadOrServoLangFontPrefsCacheLocked()
     125             : {
     126           0 :   MOZ_ASSERT(NS_IsMainThread() || sServoFFILock->LockedForWritingByCurrentThread());
     127         110 : }
     128             : 
     129             : 
     130             : /*
     131             :  * Does this child count as significant for selector matching?
     132             :  *
     133             :  * See nsStyleUtil::IsSignificantChild for details.
     134             :  */
     135             : bool
     136          12 : Gecko_IsSignificantChild(RawGeckoNodeBorrowed aNode,
     137             :                          bool aWhitespaceIsSignificant)
     138             : {
     139           0 :   return nsStyleUtil::ThreadSafeIsSignificantChild(aNode->AsContent(),
     140          12 :                                                    aWhitespaceIsSignificant);
     141             : }
     142             : 
     143             : RawGeckoNodeBorrowedOrNull
     144           0 : Gecko_GetLastChild(RawGeckoNodeBorrowed aNode)
     145             : {
     146           0 :   return aNode->GetLastChild();
     147             : }
     148             : 
     149             : RawGeckoNodeBorrowedOrNull
     150       12463 : Gecko_GetFlattenedTreeParentNode(RawGeckoNodeBorrowed aNode)
     151             : {
     152       12461 :   return aNode->GetFlattenedTreeParentNodeForStyle();
     153             : }
     154             : 
     155             : RawGeckoElementBorrowedOrNull
     156          48 : Gecko_GetBeforeOrAfterPseudo(RawGeckoElementBorrowed aElement, bool aIsBefore)
     157             : {
     158           0 :   MOZ_ASSERT(aElement);
     159          48 :   MOZ_ASSERT(aElement->HasProperties());
     160             : 
     161             :   return aIsBefore
     162             :     ? nsLayoutUtils::GetBeforePseudo(aElement)
     163          48 :     : nsLayoutUtils::GetAfterPseudo(aElement);
     164             : }
     165             : 
     166             : nsTArray<nsIContent*>*
     167         146 : Gecko_GetAnonymousContentForElement(RawGeckoElementBorrowed aElement)
     168             : {
     169           0 :   nsIAnonymousContentCreator* ac = do_QueryFrame(aElement->GetPrimaryFrame());
     170         146 :   if (!ac) {
     171             :     return nullptr;
     172             :   }
     173             : 
     174           0 :   auto* array = new nsTArray<nsIContent*>();
     175           0 :   nsContentUtils::AppendNativeAnonymousChildren(aElement, *array, 0);
     176           8 :   return array;
     177             : }
     178             : 
     179             : void
     180           8 : Gecko_DestroyAnonymousContentList(nsTArray<nsIContent*>* aAnonContent)
     181             : {
     182           0 :   MOZ_ASSERT(aAnonContent);
     183           0 :   delete aAnonContent;
     184           8 : }
     185             : 
     186             : const nsTArray<RefPtr<nsINode>>*
     187           0 : Gecko_GetAssignedNodes(RawGeckoElementBorrowed aElement)
     188             : {
     189           0 :   MOZ_ASSERT(HTMLSlotElement::FromNode(aElement));
     190           0 :   return &static_cast<const HTMLSlotElement*>(aElement)->AssignedNodes();
     191             : }
     192             : 
     193             : void
     194           0 : Gecko_ComputedStyle_Init(
     195             :     mozilla::ComputedStyle* aStyle,
     196             :     const mozilla::ComputedStyle* aParentContext,
     197             :     RawGeckoPresContextBorrowed aPresContext,
     198             :     const ServoComputedData* aValues,
     199             :     mozilla::CSSPseudoElementType aPseudoType,
     200             :     nsAtom* aPseudoTag)
     201             : {
     202        1156 :   auto* presContext = const_cast<nsPresContext*>(aPresContext);
     203             :   new (KnownNotNull, aStyle) mozilla::ComputedStyle(
     204             :       presContext, aPseudoTag, aPseudoType,
     205        1156 :       ServoComputedDataForgotten(aValues));
     206           0 : }
     207             : 
     208        1156 : ServoComputedData::ServoComputedData(
     209           0 :     const ServoComputedDataForgotten aValue)
     210             : {
     211        1156 :   PodAssign(this, aValue.mPtr);
     212        1156 : }
     213             : 
     214         884 : MOZ_DEFINE_MALLOC_ENCLOSING_SIZE_OF(ServoStyleStructsMallocEnclosingSizeOf)
     215             : 
     216             : void
     217         104 : ServoComputedData::AddSizeOfExcludingThis(nsWindowSizes& aSizes) const
     218             : {
     219             :   // Note: GetStyleFoo() returns a pointer to an nsStyleFoo that sits within a
     220             :   // servo_arc::Arc, i.e. it is preceded by a word-sized refcount. So we need
     221             :   // to measure it with a function that can handle an interior pointer. We use
     222             :   // ServoStyleStructsEnclosingMallocSizeOf to clearly identify in DMD's
     223             :   // output the memory measured here.
     224             : #define STYLE_STRUCT(name_) \
     225             :   static_assert(alignof(nsStyle##name_) <= sizeof(size_t), \
     226             :                 "alignment will break AddSizeOfExcludingThis()"); \
     227             :   const void* p##name_ = GetStyle##name_(); \
     228             :   if (!aSizes.mState.HaveSeenPtr(p##name_)) { \
     229             :     aSizes.mStyleSizes.NS_STYLE_SIZES_FIELD(name_) += \
     230             :       ServoStyleStructsMallocEnclosingSizeOf(p##name_); \
     231             :   }
     232             : #include "nsStyleStructList.h"
     233             : #undef STYLE_STRUCT
     234             : 
     235         104 :   if (visited_style.mPtr && !aSizes.mState.HaveSeenPtr(visited_style.mPtr)) {
     236           0 :     visited_style.mPtr->AddSizeOfIncludingThis(
     237           0 :       aSizes, &aSizes.mLayoutComputedValuesVisited);
     238             :   }
     239             : 
     240             :   // Measurement of the following members may be added later if DMD finds it is
     241             :   // worthwhile:
     242             :   // - custom_properties
     243             :   // - writing_mode
     244             :   // - rules
     245             :   // - font_computation_data
     246         104 : }
     247             : 
     248             : void
     249         574 : Gecko_ComputedStyle_Destroy(mozilla::ComputedStyle* aStyle)
     250             : {
     251           0 :   aStyle->~ComputedStyle();
     252           0 : }
     253             : 
     254             : void
     255       26689 : Gecko_ConstructStyleChildrenIterator(
     256             :   RawGeckoElementBorrowed aElement,
     257             :   RawGeckoStyleChildrenIteratorBorrowedMut aIterator)
     258             : {
     259       26689 :   MOZ_ASSERT(aElement);
     260           0 :   MOZ_ASSERT(aIterator);
     261       26689 :   new (aIterator) StyleChildrenIterator(aElement);
     262           0 : }
     263             : 
     264             : void
     265       26689 : Gecko_DestroyStyleChildrenIterator(
     266             :   RawGeckoStyleChildrenIteratorBorrowedMut aIterator)
     267             : {
     268           0 :   MOZ_ASSERT(aIterator);
     269             : 
     270       26689 :   aIterator->~StyleChildrenIterator();
     271       26689 : }
     272             : 
     273             : RawGeckoNodeBorrowed
     274       67370 : Gecko_GetNextStyleChild(RawGeckoStyleChildrenIteratorBorrowedMut aIterator)
     275             : {
     276           0 :   MOZ_ASSERT(aIterator);
     277       67370 :   return aIterator->GetNextChild();
     278             : }
     279             : 
     280             : bool
     281         543 : Gecko_IsPrivateBrowsingEnabled(const nsIDocument* aDoc)
     282             : {
     283           0 :   MOZ_ASSERT(aDoc);
     284         543 :   MOZ_ASSERT(NS_IsMainThread());
     285             : 
     286         543 :   nsILoadContext* loadContext = aDoc->GetLoadContext();
     287         543 :   return loadContext && loadContext->UsePrivateBrowsing();
     288             : }
     289             : 
     290             : EventStates::ServoType
     291           0 : Gecko_ElementState(RawGeckoElementBorrowed aElement)
     292             : {
     293           0 :   return aElement->StyleState().ServoValue();
     294             : }
     295             : 
     296             : bool
     297        3076 : Gecko_IsRootElement(RawGeckoElementBorrowed aElement)
     298             : {
     299           0 :   return aElement->OwnerDoc()->GetRootElement() == aElement;
     300             : }
     301             : 
     302             : // Dirtiness tracking.
     303             : void
     304           0 : Gecko_SetNodeFlags(RawGeckoNodeBorrowed aNode, uint32_t aFlags)
     305             : {
     306         235 :   const_cast<nsINode*>(aNode)->SetFlags(aFlags);
     307         235 : }
     308             : 
     309             : void
     310           0 : Gecko_UnsetNodeFlags(RawGeckoNodeBorrowed aNode, uint32_t aFlags)
     311             : {
     312           0 :   const_cast<nsINode*>(aNode)->UnsetFlags(aFlags);
     313         348 : }
     314             : 
     315             : void
     316           1 : Gecko_NoteDirtyElement(RawGeckoElementBorrowed aElement)
     317             : {
     318           0 :   MOZ_ASSERT(NS_IsMainThread());
     319           0 :   const_cast<Element*>(aElement)->NoteDirtyForServo();
     320           1 : }
     321             : 
     322             : void
     323           2 : Gecko_NoteDirtySubtreeForInvalidation(RawGeckoElementBorrowed aElement)
     324             : {
     325           0 :   MOZ_ASSERT(NS_IsMainThread());
     326           0 :   const_cast<Element*>(aElement)->NoteDirtySubtreeForServo();
     327           2 : }
     328             : 
     329             : void
     330          10 : Gecko_NoteAnimationOnlyDirtyElement(RawGeckoElementBorrowed aElement)
     331             : {
     332           0 :   MOZ_ASSERT(NS_IsMainThread());
     333           0 :   const_cast<Element*>(aElement)->NoteAnimationOnlyDirtyForServo();
     334          10 : }
     335             : 
     336           5 : bool Gecko_AnimationNameMayBeReferencedFromStyle(
     337             :   RawGeckoPresContextBorrowed aPresContext,
     338             :   nsAtom* aName)
     339             : {
     340           5 :   MOZ_ASSERT(aPresContext);
     341          15 :   return aPresContext->AnimationManager()->AnimationMayBeReferenced(aName);
     342             : }
     343             : 
     344             : CSSPseudoElementType
     345         949 : Gecko_GetImplementedPseudo(RawGeckoElementBorrowed aElement)
     346             : {
     347         949 :   return aElement->GetPseudoElementType();
     348             : }
     349             : 
     350             : uint32_t
     351          45 : Gecko_CalcStyleDifference(ComputedStyleBorrowed aOldStyle,
     352             :                           ComputedStyleBorrowed aNewStyle,
     353             :                           bool* aAnyStyleStructChanged,
     354             :                           bool* aOnlyResetStructsChanged)
     355             : {
     356           0 :   MOZ_ASSERT(aOldStyle);
     357          45 :   MOZ_ASSERT(aNewStyle);
     358             : 
     359             :   uint32_t equalStructs;
     360             :   nsChangeHint result = const_cast<ComputedStyle*>(aOldStyle)->
     361          45 :     CalcStyleDifference(const_cast<ComputedStyle*>(aNewStyle), &equalStructs);
     362             : 
     363          45 :   *aAnyStyleStructChanged =
     364          45 :     equalStructs != StyleStructConstants::kAllStructsMask;
     365             : 
     366           0 :   const auto kInheritedStructsMask = StyleStructConstants::kInheritedStructsMask;
     367          45 :   *aOnlyResetStructsChanged =
     368          45 :     (equalStructs & kInheritedStructsMask) == kInheritedStructsMask;
     369             : 
     370           0 :   return result;
     371             : }
     372             : 
     373             : const ServoElementSnapshot*
     374          78 : Gecko_GetElementSnapshot(const ServoElementSnapshotTable* aTable,
     375             :                          const Element* aElement)
     376             : {
     377          78 :   MOZ_ASSERT(aTable);
     378           1 :   MOZ_ASSERT(aElement);
     379             : 
     380          78 :   return aTable->Get(const_cast<Element*>(aElement));
     381             : }
     382             : 
     383             : bool
     384           0 : Gecko_HaveSeenPtr(SeenPtrs* aTable, const void* aPtr)
     385             : {
     386           0 :   MOZ_ASSERT(NS_IsMainThread());
     387           0 :   MOZ_ASSERT(aTable);
     388             :   // Empty Rust allocations are indicated by small values up to the alignment
     389             :   // of the relevant type. We shouldn't see anything like that here.
     390           0 :   MOZ_ASSERT(uintptr_t(aPtr) > 16);
     391             : 
     392           0 :   return aTable->HaveSeenPtr(aPtr);
     393             : }
     394             : 
     395             : RawServoDeclarationBlockStrongBorrowedOrNull
     396          31 : Gecko_GetStyleAttrDeclarationBlock(RawGeckoElementBorrowed aElement)
     397             : {
     398           0 :   DeclarationBlock* decl = aElement->GetInlineStyleDeclaration();
     399          31 :   if (!decl) {
     400             :     return nullptr;
     401             :   }
     402           8 :   return decl->RefRawStrong();
     403             : }
     404             : 
     405             : void
     406          31 : Gecko_UnsetDirtyStyleAttr(RawGeckoElementBorrowed aElement)
     407             : {
     408          31 :   DeclarationBlock* decl = aElement->GetInlineStyleDeclaration();
     409          31 :   if (!decl) {
     410             :     return;
     411             :   }
     412           8 :   decl->UnsetDirty();
     413             : }
     414             : 
     415             : static const RawServoDeclarationBlockStrong*
     416             : AsRefRawStrong(const RefPtr<RawServoDeclarationBlock>& aDecl)
     417             : {
     418             :   static_assert(sizeof(RefPtr<RawServoDeclarationBlock>) ==
     419             :                 sizeof(RawServoDeclarationBlockStrong),
     420             :                 "RefPtr should just be a pointer");
     421             :   return reinterpret_cast<const RawServoDeclarationBlockStrong*>(&aDecl);
     422             : }
     423             : 
     424             : RawServoDeclarationBlockStrongBorrowedOrNull
     425        1030 : Gecko_GetHTMLPresentationAttrDeclarationBlock(RawGeckoElementBorrowed aElement)
     426             : {
     427        1030 :   const nsMappedAttributes* attrs = aElement->GetMappedAttributes();
     428        1030 :   if (!attrs) {
     429        1004 :     auto* svg = nsSVGElement::FromNodeOrNull(aElement);
     430           0 :     if (svg) {
     431          41 :       if (auto decl = svg->GetContentDeclarationBlock()) {
     432          38 :         return decl->RefRawStrong();
     433             :       }
     434             :     }
     435             :     return nullptr;
     436             :   }
     437             : 
     438          26 :   return AsRefRawStrong(attrs->GetServoStyle());
     439             : }
     440             : 
     441             : RawServoDeclarationBlockStrongBorrowedOrNull
     442        1030 : Gecko_GetExtraContentStyleDeclarations(RawGeckoElementBorrowed aElement)
     443             : {
     444        1030 :   if (!aElement->IsAnyOfHTMLElements(nsGkAtoms::td, nsGkAtoms::th)) {
     445             :     return nullptr;
     446             :   }
     447           0 :   const HTMLTableCellElement* cell = static_cast<const HTMLTableCellElement*>(aElement);
     448           0 :   if (nsMappedAttributes* attrs = cell->GetMappedAttributesInheritedFromTable()) {
     449           0 :     return AsRefRawStrong(attrs->GetServoStyle());
     450             :   }
     451             :   return nullptr;
     452             : }
     453             : 
     454             : RawServoDeclarationBlockStrongBorrowedOrNull
     455           0 : Gecko_GetUnvisitedLinkAttrDeclarationBlock(RawGeckoElementBorrowed aElement)
     456             : {
     457           0 :   nsHTMLStyleSheet* sheet = aElement->OwnerDoc()->GetAttributeStyleSheet();
     458           0 :   if (!sheet) {
     459             :     return nullptr;
     460             :   }
     461             : 
     462           0 :   return AsRefRawStrong(sheet->GetServoUnvisitedLinkDecl());
     463             : }
     464             : 
     465           0 : StyleSheet* Gecko_StyleSheet_Clone(
     466             :     const StyleSheet* aSheet,
     467             :     const StyleSheet* aNewParentSheet)
     468             : {
     469           0 :   MOZ_ASSERT(aSheet);
     470           0 :   MOZ_ASSERT(aSheet->GetParentSheet(), "Should only be used for @import");
     471           0 :   MOZ_ASSERT(aNewParentSheet, "Wat");
     472             : 
     473             :   RefPtr<StyleSheet> newSheet =
     474           0 :     aSheet->Clone(nullptr, nullptr, nullptr, nullptr);
     475             : 
     476             :   // NOTE(emilio): This code runs in the StylesheetInner constructor, which
     477             :   // means that the inner pointer of `aNewParentSheet` still points to the old
     478             :   // one.
     479             :   //
     480             :   // So we _don't_ update neither the parent pointer of the stylesheet, nor the
     481             :   // child list (yet). This is fixed up in that same constructor.
     482           0 :   return static_cast<StyleSheet*>(newSheet.forget().take());
     483             : }
     484             : 
     485             : void
     486         199 : Gecko_StyleSheet_AddRef(const StyleSheet* aSheet)
     487             : {
     488           0 :   MOZ_ASSERT(NS_IsMainThread());
     489           0 :   const_cast<StyleSheet*>(aSheet)->AddRef();
     490         199 : }
     491             : 
     492             : void
     493         102 : Gecko_StyleSheet_Release(const StyleSheet* aSheet)
     494             : {
     495           0 :   MOZ_ASSERT(NS_IsMainThread());
     496         102 :   const_cast<StyleSheet*>(aSheet)->Release();
     497         102 : }
     498             : 
     499             : RawServoDeclarationBlockStrongBorrowedOrNull
     500           0 : Gecko_GetVisitedLinkAttrDeclarationBlock(RawGeckoElementBorrowed aElement)
     501             : {
     502           0 :   nsHTMLStyleSheet* sheet = aElement->OwnerDoc()->GetAttributeStyleSheet();
     503           0 :   if (!sheet) {
     504             :     return nullptr;
     505             :   }
     506             : 
     507           0 :   return AsRefRawStrong(sheet->GetServoVisitedLinkDecl());
     508             : }
     509             : 
     510             : RawServoDeclarationBlockStrongBorrowedOrNull
     511           0 : Gecko_GetActiveLinkAttrDeclarationBlock(RawGeckoElementBorrowed aElement)
     512             : {
     513           0 :   nsHTMLStyleSheet* sheet = aElement->OwnerDoc()->GetAttributeStyleSheet();
     514           0 :   if (!sheet) {
     515             :     return nullptr;
     516             :   }
     517             : 
     518           0 :   return AsRefRawStrong(sheet->GetServoActiveLinkDecl());
     519             : }
     520             : 
     521             : static CSSPseudoElementType
     522           0 : GetPseudoTypeFromElementForAnimation(const Element*& aElementOrPseudo) {
     523          14 :   if (aElementOrPseudo->IsGeneratedContentContainerForBefore()) {
     524           0 :     aElementOrPseudo = aElementOrPseudo->GetParent()->AsElement();
     525           0 :     return CSSPseudoElementType::before;
     526             :   }
     527             : 
     528          14 :   if (aElementOrPseudo->IsGeneratedContentContainerForAfter()) {
     529           0 :     aElementOrPseudo = aElementOrPseudo->GetParent()->AsElement();
     530           0 :     return CSSPseudoElementType::after;
     531             :   }
     532             : 
     533             :   return CSSPseudoElementType::NotPseudo;
     534             : }
     535             : 
     536             : bool
     537           6 : Gecko_GetAnimationRule(RawGeckoElementBorrowed aElement,
     538             :                        EffectCompositor::CascadeLevel aCascadeLevel,
     539             :                        RawServoAnimationValueMapBorrowedMut aAnimationValues)
     540             : {
     541           6 :   MOZ_ASSERT(aElement);
     542             : 
     543           6 :   nsIDocument* doc = aElement->GetComposedDoc();
     544           6 :   if (!doc) {
     545             :     return false;
     546             :   }
     547           6 :   nsPresContext* presContext = doc->GetPresContext();
     548          12 :   if (!presContext || !presContext->IsDynamic()) {
     549             :     // For print or print preview, ignore animations.
     550             :     return false;
     551             :   }
     552             : 
     553             :   CSSPseudoElementType pseudoType =
     554           6 :     GetPseudoTypeFromElementForAnimation(aElement);
     555             : 
     556             :   return presContext->EffectCompositor()
     557          12 :     ->GetServoAnimationRule(aElement,
     558             :                             pseudoType,
     559             :                             aCascadeLevel,
     560           6 :                             aAnimationValues);
     561             : }
     562             : 
     563             : bool
     564          39 : Gecko_StyleAnimationsEquals(RawGeckoStyleAnimationListBorrowed aA,
     565             :                             RawGeckoStyleAnimationListBorrowed aB)
     566             : {
     567           0 :   return *aA == *aB;
     568             : }
     569             : 
     570             : void
     571           0 : Gecko_CopyAnimationNames(RawGeckoStyleAnimationListBorrowedMut aDest,
     572             :                          RawGeckoStyleAnimationListBorrowed aSrc)
     573             : {
     574           0 :   size_t srcLength = aSrc->Length();
     575           0 :   aDest->EnsureLengthAtLeast(srcLength);
     576             : 
     577           0 :   for (size_t index = 0; index < srcLength; index++) {
     578           0 :     (*aDest)[index].SetName((*aSrc)[index].GetName());
     579             :   }
     580           0 : }
     581             : 
     582             : void
     583           1 : Gecko_SetAnimationName(StyleAnimation* aStyleAnimation,
     584             :                        nsAtom* aAtom)
     585             : {
     586           1 :   MOZ_ASSERT(aStyleAnimation);
     587             : 
     588           2 :   aStyleAnimation->SetName(already_AddRefed<nsAtom>(aAtom));
     589           0 : }
     590             : 
     591             : void
     592           0 : Gecko_UpdateAnimations(RawGeckoElementBorrowed aElement,
     593             :                        ComputedStyleBorrowedOrNull aOldComputedData,
     594             :                        ComputedStyleBorrowedOrNull aComputedData,
     595             :                        UpdateAnimationsTasks aTasks)
     596             : {
     597           0 :   MOZ_ASSERT(NS_IsMainThread());
     598           3 :   MOZ_ASSERT(aElement);
     599             : 
     600           3 :   if (!aElement->IsInComposedDoc()) {
     601           0 :     return;
     602             :   }
     603             : 
     604           0 :   nsPresContext* presContext = nsContentUtils::GetContextForContent(aElement);
     605           6 :   if (!presContext || !presContext->IsDynamic()) {
     606             :     return;
     607             :   }
     608             : 
     609           0 :   nsAutoAnimationMutationBatch mb(aElement->OwnerDoc());
     610             : 
     611             :   CSSPseudoElementType pseudoType =
     612           3 :     GetPseudoTypeFromElementForAnimation(aElement);
     613             : 
     614           3 :   if (aTasks & UpdateAnimationsTasks::CSSAnimations) {
     615             :     presContext->AnimationManager()->
     616           2 :       UpdateAnimations(const_cast<dom::Element*>(aElement), pseudoType,
     617           1 :                        aComputedData);
     618             :   }
     619             : 
     620             :   // aComputedData might be nullptr if the target element is now in a
     621             :   // display:none subtree. We still call Gecko_UpdateAnimations in this case
     622             :   // because we need to stop CSS animations in the display:none subtree.
     623             :   // However, we don't need to update transitions since they are stopped by
     624             :   // RestyleManager::AnimationsWithDestroyedFrame so we just return early
     625             :   // here.
     626           3 :   if (!aComputedData) {
     627           0 :     return;
     628             :   }
     629             : 
     630           0 :   if (aTasks & UpdateAnimationsTasks::CSSTransitions) {
     631           0 :     MOZ_ASSERT(aOldComputedData);
     632             :     presContext->TransitionManager()->
     633           4 :       UpdateTransitions(const_cast<dom::Element*>(aElement), pseudoType,
     634             :                         *aOldComputedData,
     635           0 :                         *aComputedData);
     636             :   }
     637             : 
     638           3 :   if (aTasks & UpdateAnimationsTasks::EffectProperties) {
     639           0 :     presContext->EffectCompositor()->UpdateEffectProperties(
     640           0 :       aComputedData, const_cast<dom::Element*>(aElement), pseudoType);
     641             :   }
     642             : 
     643           3 :   if (aTasks & UpdateAnimationsTasks::CascadeResults) {
     644           0 :     EffectSet* effectSet = EffectSet::GetEffectSet(aElement, pseudoType);
     645             :     // CSS animations/transitions might have been destroyed as part of the above
     646             :     // steps so before updating cascade results, we check if there are still any
     647             :     // animations to update.
     648           0 :     if (effectSet) {
     649             :       // We call UpdateCascadeResults directly (intead of
     650             :       // MaybeUpdateCascadeResults) since we know for sure that the cascade has
     651             :       // changed, but we were unable to call MarkCascadeUpdated when we noticed
     652             :       // it since we avoid mutating state as part of the Servo parallel
     653             :       // traversal.
     654           0 :       presContext->EffectCompositor()
     655             :                  ->UpdateCascadeResults(*effectSet,
     656             :                                         const_cast<Element*>(aElement),
     657           0 :                                         pseudoType);
     658             :     }
     659             :   }
     660             : 
     661           3 :   if (aTasks & UpdateAnimationsTasks::DisplayChangedFromNone) {
     662             :     presContext->EffectCompositor()
     663           0 :                ->RequestRestyle(const_cast<Element*>(aElement),
     664             :                                 pseudoType,
     665             :                                 EffectCompositor::RestyleType::Standard,
     666           0 :                                 EffectCompositor::CascadeLevel::Animations);
     667             :   }
     668             : }
     669             : 
     670             : bool
     671           0 : Gecko_ElementHasAnimations(RawGeckoElementBorrowed aElement)
     672             : {
     673             :   CSSPseudoElementType pseudoType =
     674           0 :     GetPseudoTypeFromElementForAnimation(aElement);
     675             : 
     676           0 :   return !!EffectSet::GetEffectSet(aElement, pseudoType);
     677             : }
     678             : 
     679             : bool
     680           0 : Gecko_ElementHasCSSAnimations(RawGeckoElementBorrowed aElement)
     681             : {
     682             :   CSSPseudoElementType pseudoType =
     683           0 :     GetPseudoTypeFromElementForAnimation(aElement);
     684             :   nsAnimationManager::CSSAnimationCollection* collection =
     685             :     nsAnimationManager::CSSAnimationCollection
     686           0 :                       ::GetAnimationCollection(aElement, pseudoType);
     687             : 
     688           0 :   return collection && !collection->mAnimations.IsEmpty();
     689             : }
     690             : 
     691             : bool
     692           0 : Gecko_ElementHasCSSTransitions(RawGeckoElementBorrowed aElement)
     693             : {
     694             :   CSSPseudoElementType pseudoType =
     695           0 :     GetPseudoTypeFromElementForAnimation(aElement);
     696             :   nsTransitionManager::CSSTransitionCollection* collection =
     697             :     nsTransitionManager::CSSTransitionCollection
     698           0 :                        ::GetAnimationCollection(aElement, pseudoType);
     699             : 
     700           0 :   return collection && !collection->mAnimations.IsEmpty();
     701             : }
     702             : 
     703             : size_t
     704           0 : Gecko_ElementTransitions_Length(RawGeckoElementBorrowed aElement)
     705             : {
     706             :   CSSPseudoElementType pseudoType =
     707           5 :     GetPseudoTypeFromElementForAnimation(aElement);
     708             :   nsTransitionManager::CSSTransitionCollection* collection =
     709             :     nsTransitionManager::CSSTransitionCollection
     710           5 :                        ::GetAnimationCollection(aElement, pseudoType);
     711             : 
     712           5 :   return collection ? collection->mAnimations.Length() : 0;
     713             : }
     714             : 
     715             : static CSSTransition*
     716           0 : GetCurrentTransitionAt(RawGeckoElementBorrowed aElement, size_t aIndex)
     717             : {
     718             :   CSSPseudoElementType pseudoType =
     719           0 :     GetPseudoTypeFromElementForAnimation(aElement);
     720             :   nsTransitionManager::CSSTransitionCollection* collection =
     721             :     nsTransitionManager::CSSTransitionCollection
     722           0 :                        ::GetAnimationCollection(aElement, pseudoType);
     723           0 :   if (!collection) {
     724             :     return nullptr;
     725             :   }
     726           0 :   nsTArray<RefPtr<CSSTransition>>& transitions = collection->mAnimations;
     727           0 :   return aIndex < transitions.Length()
     728           0 :          ? transitions[aIndex].get()
     729             :          : nullptr;
     730             : }
     731             : 
     732             : nsCSSPropertyID
     733           0 : Gecko_ElementTransitions_PropertyAt(RawGeckoElementBorrowed aElement,
     734             :                                     size_t aIndex)
     735             : {
     736           0 :   CSSTransition* transition = GetCurrentTransitionAt(aElement, aIndex);
     737           0 :   return transition ? transition->TransitionProperty()
     738           0 :                     : nsCSSPropertyID::eCSSProperty_UNKNOWN;
     739             : }
     740             : 
     741             : RawServoAnimationValueBorrowedOrNull
     742           0 : Gecko_ElementTransitions_EndValueAt(RawGeckoElementBorrowed aElement,
     743             :                                     size_t aIndex)
     744             : {
     745             :   CSSTransition* transition = GetCurrentTransitionAt(aElement,
     746           0 :                                                      aIndex);
     747           0 :   return transition ? transition->ToValue().mServo.get() : nullptr;
     748             : }
     749             : 
     750             : double
     751           4 : Gecko_GetProgressFromComputedTiming(RawGeckoComputedTimingBorrowed aComputedTiming)
     752             : {
     753           0 :   return aComputedTiming->mProgress.Value();
     754             : }
     755             : 
     756             : double
     757           4 : Gecko_GetPositionInSegment(RawGeckoAnimationPropertySegmentBorrowed aSegment,
     758             :                            double aProgress,
     759             :                            ComputedTimingFunction::BeforeFlag aBeforeFlag)
     760             : {
     761           4 :   MOZ_ASSERT(aSegment->mFromKey < aSegment->mToKey,
     762             :              "The segment from key should be less than to key");
     763             : 
     764           0 :   double positionInSegment = (aProgress - aSegment->mFromKey) /
     765             :                              // To avoid floating precision inaccuracies, make
     766             :                              // sure we calculate both the numerator and
     767             :                              // denominator using double precision.
     768           0 :                              (double(aSegment->mToKey) - aSegment->mFromKey);
     769             : 
     770           4 :   return ComputedTimingFunction::GetPortion(aSegment->mTimingFunction,
     771             :                                             positionInSegment,
     772           0 :                                             aBeforeFlag);
     773             : }
     774             : 
     775             : RawServoAnimationValueBorrowedOrNull
     776           0 : Gecko_AnimationGetBaseStyle(void* aBaseStyles, nsCSSPropertyID aProperty)
     777             : {
     778             :   auto base =
     779             :     static_cast<nsRefPtrHashtable<nsUint32HashKey, RawServoAnimationValue>*>
     780           0 :       (aBaseStyles);
     781           0 :   return base->GetWeak(aProperty);
     782             : }
     783             : 
     784             : void
     785         280 : Gecko_FillAllImageLayers(nsStyleImageLayers* aLayers, uint32_t aMaxLen)
     786             : {
     787         280 :   aLayers->FillAllLayers(aMaxLen);
     788           0 : }
     789             : 
     790             : bool
     791           0 : Gecko_IsDocumentBody(RawGeckoElementBorrowed aElement)
     792             : {
     793           0 :   nsIDocument* doc = aElement->GetUncomposedDoc();
     794           0 :   return doc && doc->GetBodyElement() == aElement;
     795             : }
     796             : 
     797             : nscolor
     798         384 : Gecko_GetLookAndFeelSystemColor(int32_t aId,
     799             :                                 RawGeckoPresContextBorrowed aPresContext)
     800             : {
     801         768 :   bool useStandinsForNativeColors = aPresContext && !aPresContext->IsChrome();
     802             :   nscolor result;
     803         384 :   LookAndFeel::ColorID colorId = static_cast<LookAndFeel::ColorID>(aId);
     804           0 :   AutoWriteLock guard(*sServoFFILock);
     805         384 :   LookAndFeel::GetColor(colorId, useStandinsForNativeColors, &result);
     806         768 :   return result;
     807             : }
     808             : 
     809             : bool
     810           0 : Gecko_MatchLang(RawGeckoElementBorrowed aElement,
     811             :                 nsAtom* aOverrideLang,
     812             :                 bool aHasOverrideLang,
     813             :                 const char16_t* aValue)
     814             : {
     815           0 :   MOZ_ASSERT(!(aOverrideLang && !aHasOverrideLang),
     816             :              "aHasOverrideLang should only be set when aOverrideLang is null");
     817           0 :   MOZ_ASSERT(aValue, "null lang parameter");
     818           0 :   if (!aValue || !*aValue) {
     819             :     return false;
     820             :   }
     821             : 
     822             :   // We have to determine the language of the current element.  Since
     823             :   // this is currently no property and since the language is inherited
     824             :   // from the parent we have to be prepared to look at all parent
     825             :   // nodes.  The language itself is encoded in the LANG attribute.
     826           0 :   if (auto* language = aHasOverrideLang ? aOverrideLang : aElement->GetLang()) {
     827           0 :     return nsStyleUtil::DashMatchCompare(nsDependentAtomString(language),
     828           0 :                                          nsDependentString(aValue),
     829           0 :                                          nsASCIICaseInsensitiveStringComparator());
     830             :   }
     831             : 
     832             :   // Try to get the language from the HTTP header or if this
     833             :   // is missing as well from the preferences.
     834             :   // The content language can be a comma-separated list of
     835             :   // language codes.
     836           0 :   nsAutoString language;
     837           0 :   aElement->OwnerDoc()->GetContentLanguage(language);
     838             : 
     839           0 :   nsDependentString langString(aValue);
     840           0 :   language.StripWhitespace();
     841           0 :   for (auto const& lang : language.Split(char16_t(','))) {
     842           0 :     if (nsStyleUtil::DashMatchCompare(lang,
     843             :                                       langString,
     844           0 :                                       nsASCIICaseInsensitiveStringComparator())) {
     845           0 :       return true;
     846             :     }
     847             :   }
     848           0 :   return false;
     849             : }
     850             : 
     851             : nsAtom*
     852        1030 : Gecko_GetXMLLangValue(RawGeckoElementBorrowed aElement)
     853             : {
     854             :   const nsAttrValue* attr =
     855        2062 :     aElement->GetParsedAttr(nsGkAtoms::lang, kNameSpaceID_XML);
     856             : 
     857        1032 :   if (!attr) {
     858             :     return nullptr;
     859             :   }
     860             : 
     861           0 :   MOZ_ASSERT(attr->Type() == nsAttrValue::eAtom);
     862             : 
     863           0 :   RefPtr<nsAtom> atom = attr->GetAtomValue();
     864           0 :   return atom.forget().take();
     865             : }
     866             : 
     867             : nsIDocument::DocumentTheme
     868         775 : Gecko_GetDocumentLWTheme(const nsIDocument* aDocument)
     869             : {
     870           0 :   return aDocument->ThreadSafeGetDocumentLWTheme();
     871             : }
     872             : 
     873             : bool
     874           0 : Gecko_IsTableBorderNonzero(RawGeckoElementBorrowed aElement)
     875             : {
     876           0 :   if (!aElement->IsHTMLElement(nsGkAtoms::table)) {
     877             :     return false;
     878             :   }
     879           0 :   const nsAttrValue *val = aElement->GetParsedAttr(nsGkAtoms::border);
     880           0 :   return val && (val->Type() != nsAttrValue::eInteger ||
     881           0 :                  val->GetIntegerValue() != 0);
     882             : }
     883             : 
     884             : bool
     885           0 : Gecko_IsBrowserFrame(RawGeckoElementBorrowed aElement)
     886             : {
     887             :   nsIMozBrowserFrame* browserFrame =
     888           0 :     const_cast<Element*>(aElement)->GetAsMozBrowserFrame();
     889           0 :   return browserFrame && browserFrame->GetReallyIsBrowser();
     890             : }
     891             : 
     892             : template <typename Implementor>
     893             : static nsAtom*
     894           0 : AtomAttrValue(Implementor* aElement, nsAtom* aName)
     895             : {
     896       10764 :   const nsAttrValue* attr = aElement->GetParsedAttr(aName);
     897       10766 :   return attr ? attr->GetAtomValue() : nullptr;
     898             : }
     899             : 
     900             : template <typename Implementor>
     901             : static nsAtom*
     902           0 : LangValue(Implementor* aElement)
     903             : {
     904             :   // TODO(emilio): Deduplicate a bit with nsIContent::GetLang().
     905             :   const nsAttrValue* attr =
     906           0 :     aElement->GetParsedAttr(nsGkAtoms::lang, kNameSpaceID_XML);
     907           0 :   if (!attr && aElement->SupportsLangAttr()) {
     908           0 :     attr = aElement->GetParsedAttr(nsGkAtoms::lang);
     909             :   }
     910             : 
     911           0 :   if (!attr) {
     912             :     return nullptr;
     913             :   }
     914             : 
     915           0 :   MOZ_ASSERT(attr->Type() == nsAttrValue::eAtom);
     916           0 :   RefPtr<nsAtom> atom = attr->GetAtomValue();
     917           0 :   return atom.forget().take();
     918             : }
     919             : 
     920             : template <typename Implementor, typename MatchFn>
     921             : static bool
     922           0 : DoMatch(Implementor* aElement, nsAtom* aNS, nsAtom* aName, MatchFn aMatch)
     923             : {
     924       30783 :   if (MOZ_LIKELY(aNS)) {
     925       30783 :     int32_t ns = aNS == nsGkAtoms::_empty
     926       30824 :       ? kNameSpaceID_None
     927             :       : nsContentUtils::NameSpaceManager()->GetNameSpaceID(
     928           0 :           aNS, aElement->IsInChromeDocument());
     929             : 
     930           0 :     MOZ_ASSERT(ns == nsContentUtils::NameSpaceManager()->GetNameSpaceID(
     931             :                        aNS, aElement->IsInChromeDocument()));
     932           0 :     NS_ENSURE_TRUE(ns != kNameSpaceID_Unknown, false);
     933       30741 :     const nsAttrValue* value = aElement->GetParsedAttr(aName, ns);
     934           0 :     return value && aMatch(value);
     935             :   }
     936             : 
     937             :   // No namespace means any namespace - we have to check them all. :-(
     938             :   BorrowedAttrInfo attrInfo;
     939           0 :   for (uint32_t i = 0; (attrInfo = aElement->GetAttrInfoAt(i)); ++i) {
     940           0 :     if (attrInfo.mName->LocalName() != aName) {
     941             :       continue;
     942             :     }
     943           0 :     if (aMatch(attrInfo.mValue)) {
     944             :       return true;
     945             :     }
     946             :   }
     947             :   return false;
     948             : }
     949             : 
     950             : template <typename Implementor>
     951             : static bool
     952             : HasAttr(Implementor* aElement, nsAtom* aNS, nsAtom* aName)
     953             : {
     954             :   auto match = [](const nsAttrValue* aValue) { return true; };
     955        5656 :   return DoMatch(aElement, aNS, aName, match);
     956             : }
     957             : 
     958             : template <typename Implementor>
     959             : static bool
     960       24507 : AttrEquals(Implementor* aElement, nsAtom* aNS, nsAtom* aName, nsAtom* aStr,
     961             :            bool aIgnoreCase)
     962             : {
     963        3732 :   auto match = [aStr, aIgnoreCase](const nsAttrValue* aValue) {
     964        1866 :     return aValue->Equals(aStr, aIgnoreCase ? eIgnoreCase : eCaseMatters);
     965       26373 :   };
     966           0 :   return DoMatch(aElement, aNS, aName, match);
     967             : }
     968             : 
     969             : #define WITH_COMPARATOR(ignore_case_, c_, expr_)    \
     970             :     if (ignore_case_) {                             \
     971             :       const nsCaseInsensitiveStringComparator c_    \
     972             :           = nsCaseInsensitiveStringComparator();    \
     973             :       return expr_;                                 \
     974             :     } else {                                        \
     975             :       const nsDefaultStringComparator c_;           \
     976             :       return expr_;                                 \
     977             :     }
     978             : 
     979             : 
     980             : template <typename Implementor>
     981             : static bool
     982           0 : AttrDashEquals(Implementor* aElement, nsAtom* aNS, nsAtom* aName,
     983             :                nsAtom* aStr, bool aIgnoreCase)
     984             : {
     985           0 :   auto match = [aStr, aIgnoreCase](const nsAttrValue* aValue) {
     986           0 :     nsAutoString str;
     987           0 :     aValue->ToString(str);
     988           0 :     WITH_COMPARATOR(aIgnoreCase, c,
     989             :                     nsStyleUtil::DashMatchCompare(str, nsDependentAtomString(aStr), c))
     990           0 :   };
     991           0 :   return DoMatch(aElement, aNS, aName, match);
     992             : }
     993             : 
     994             : template <typename Implementor>
     995             : static bool
     996           0 : AttrIncludes(Implementor* aElement, nsAtom* aNS, nsAtom* aName,
     997             :              nsAtom* aStr, bool aIgnoreCase)
     998             : {
     999         237 :   auto match = [aStr, aIgnoreCase](const nsAttrValue* aValue) {
    1000         158 :     nsAutoString str;
    1001          79 :     aValue->ToString(str);
    1002           0 :     WITH_COMPARATOR(aIgnoreCase, c,
    1003             :                     nsStyleUtil::ValueIncludes(str, nsDependentAtomString(aStr), c))
    1004         602 :   };
    1005           0 :   return DoMatch(aElement, aNS, aName, match);
    1006             : }
    1007             : 
    1008             : template <typename Implementor>
    1009             : static bool
    1010           0 : AttrHasSubstring(Implementor* aElement, nsAtom* aNS, nsAtom* aName,
    1011             :                  nsAtom* aStr, bool aIgnoreCase)
    1012             : {
    1013           0 :   auto match = [aStr, aIgnoreCase](const nsAttrValue* aValue) {
    1014           0 :     nsAutoString str;
    1015           0 :     aValue->ToString(str);
    1016           0 :     WITH_COMPARATOR(aIgnoreCase, c,
    1017             :                     FindInReadable(nsDependentAtomString(aStr), str, c))
    1018           0 :   };
    1019           0 :   return DoMatch(aElement, aNS, aName, match);
    1020             : }
    1021             : 
    1022             : template <typename Implementor>
    1023             : static bool
    1024           0 : AttrHasPrefix(Implementor* aElement, nsAtom* aNS, nsAtom* aName,
    1025             :               nsAtom* aStr, bool aIgnoreCase)
    1026             : {
    1027          36 :   auto match = [aStr, aIgnoreCase](const nsAttrValue* aValue) {
    1028          24 :     nsAutoString str;
    1029          12 :     aValue->ToString(str);
    1030           0 :     WITH_COMPARATOR(aIgnoreCase, c,
    1031             :                     StringBeginsWith(str, nsDependentAtomString(aStr), c))
    1032          17 :   };
    1033           0 :   return DoMatch(aElement, aNS, aName, match);
    1034             : }
    1035             : 
    1036             : template <typename Implementor>
    1037             : static bool
    1038           0 : AttrHasSuffix(Implementor* aElement, nsAtom* aNS, nsAtom* aName,
    1039             :               nsAtom* aStr, bool aIgnoreCase)
    1040             : {
    1041           0 :   auto match = [aStr, aIgnoreCase](const nsAttrValue* aValue) {
    1042           0 :     nsAutoString str;
    1043           0 :     aValue->ToString(str);
    1044           0 :     WITH_COMPARATOR(aIgnoreCase, c,
    1045             :                     StringEndsWith(str, nsDependentAtomString(aStr), c))
    1046           1 :   };
    1047           0 :   return DoMatch(aElement, aNS, aName, match);
    1048             : }
    1049             : 
    1050             : /**
    1051             :  * Returns whether an element contains a class in its class list or not.
    1052             :  */
    1053             : template <typename Implementor>
    1054             : static bool
    1055        4745 : HasClass(Implementor* aElement, nsAtom* aClass, bool aIgnoreCase)
    1056             : {
    1057        4745 :   const nsAttrValue* attr = aElement->DoGetClasses();
    1058        4745 :   if (!attr) {
    1059             :     return false;
    1060             :   }
    1061             : 
    1062        4745 :   return attr->Contains(aClass, aIgnoreCase ? eIgnoreCase : eCaseMatters);
    1063             : }
    1064             : 
    1065             : /**
    1066             :  * Gets the class or class list (if any) of the implementor. The calling
    1067             :  * convention here is rather hairy, and is optimized for getting Servo the
    1068             :  * information it needs for hot calls.
    1069             :  *
    1070             :  * The return value indicates the number of classes. If zero, neither outparam
    1071             :  * is valid. If one, the class_ outparam is filled with the atom of the class.
    1072             :  * If two or more, the classList outparam is set to point to an array of atoms
    1073             :  * representing the class list.
    1074             :  *
    1075             :  * The array is borrowed and the atoms are not addrefed. These values can be
    1076             :  * invalidated by any DOM mutation. Use them in a tight scope.
    1077             :  */
    1078             : template <typename Implementor>
    1079             : static uint32_t
    1080        3022 : ClassOrClassList(Implementor* aElement, nsAtom** aClass, nsAtom*** aClassList)
    1081             : {
    1082        3022 :   const nsAttrValue* attr = aElement->DoGetClasses();
    1083        3022 :   if (!attr) {
    1084             :     return 0;
    1085             :   }
    1086             : 
    1087             :   // For class values with only whitespace, Gecko just stores a string. For the
    1088             :   // purposes of the style system, there is no class in this case.
    1089           0 :   nsAttrValue::ValueType type = attr->Type();
    1090        3022 :   if (MOZ_UNLIKELY(type == nsAttrValue::eString)) {
    1091           0 :     MOZ_ASSERT(nsContentUtils::TrimWhitespace<nsContentUtils::IsHTMLWhitespace>(
    1092             :                  attr->GetStringValue()).IsEmpty());
    1093             :     return 0;
    1094             :   }
    1095             : 
    1096             :   // Single tokens are generally stored as an atom. Check that case.
    1097           0 :   if (type == nsAttrValue::eAtom) {
    1098        2369 :     *aClass = attr->GetAtomValue();
    1099        2369 :     return 1;
    1100             :   }
    1101             : 
    1102             :   // At this point we should have an atom array. It is likely, but not
    1103             :   // guaranteed, that we have two or more elements in the array.
    1104           0 :   MOZ_ASSERT(type == nsAttrValue::eAtomArray);
    1105           0 :   nsTArray<RefPtr<nsAtom>>* atomArray = attr->GetAtomArrayValue();
    1106        1306 :   uint32_t length = atomArray->Length();
    1107             : 
    1108             :   // Special case: zero elements.
    1109         653 :   if (length == 0) {
    1110             :     return 0;
    1111             :   }
    1112             : 
    1113             :   // Special case: one element.
    1114         653 :   if (length == 1) {
    1115           0 :     *aClass = atomArray->ElementAt(0);
    1116           0 :     return 1;
    1117             :   }
    1118             : 
    1119             :   // General case: Two or more elements.
    1120             :   //
    1121             :   // Note: We could also expose this array as an array of nsCOMPtrs, since
    1122             :   // bindgen knows what those look like, and eliminate the reinterpret_cast.
    1123             :   // But it's not obvious that that would be preferable.
    1124             :   static_assert(sizeof(RefPtr<nsAtom>) == sizeof(nsAtom*), "Bad simplification");
    1125             :   static_assert(alignof(RefPtr<nsAtom>) == alignof(nsAtom*), "Bad simplification");
    1126             : 
    1127        1306 :   RefPtr<nsAtom>* elements = atomArray->Elements();
    1128         653 :   nsAtom** rawElements = reinterpret_cast<nsAtom**>(elements);
    1129         653 :   *aClassList = rawElements;
    1130        1306 :   return atomArray->Length();
    1131             : }
    1132             : 
    1133             : #define SERVO_IMPL_ELEMENT_ATTR_MATCHING_FUNCTIONS(prefix_, implementor_)        \
    1134             :   nsAtom* prefix_##AtomAttrValue(implementor_ aElement, nsAtom* aName)           \
    1135             :   {                                                                              \
    1136             :     return AtomAttrValue(aElement, aName);                                       \
    1137             :   }                                                                              \
    1138             :   nsAtom* prefix_##LangValue(implementor_ aElement)                              \
    1139             :   {                                                                              \
    1140             :     return LangValue(aElement);                                                  \
    1141             :   }                                                                              \
    1142             :   bool prefix_##HasAttr(implementor_ aElement, nsAtom* aNS, nsAtom* aName)       \
    1143             :   {                                                                              \
    1144             :     return HasAttr(aElement, aNS, aName);                                        \
    1145             :   }                                                                              \
    1146             :   bool prefix_##AttrEquals(implementor_ aElement, nsAtom* aNS,                   \
    1147             :                            nsAtom* aName, nsAtom* aStr, bool aIgnoreCase)        \
    1148             :   {                                                                              \
    1149             :     return AttrEquals(aElement, aNS, aName, aStr, aIgnoreCase);                  \
    1150             :   }                                                                              \
    1151             :   bool prefix_##AttrDashEquals(implementor_ aElement, nsAtom* aNS,               \
    1152             :                                nsAtom* aName, nsAtom* aStr, bool aIgnoreCase)    \
    1153             :   {                                                                              \
    1154             :     return AttrDashEquals(aElement, aNS, aName, aStr, aIgnoreCase);              \
    1155             :   }                                                                              \
    1156             :   bool prefix_##AttrIncludes(implementor_ aElement, nsAtom* aNS,                 \
    1157             :                              nsAtom* aName, nsAtom* aStr, bool aIgnoreCase)      \
    1158             :   {                                                                              \
    1159             :     return AttrIncludes(aElement, aNS, aName, aStr, aIgnoreCase);                \
    1160             :   }                                                                              \
    1161             :   bool prefix_##AttrHasSubstring(implementor_ aElement, nsAtom* aNS,             \
    1162             :                                  nsAtom* aName, nsAtom* aStr, bool aIgnoreCase)  \
    1163             :   {                                                                              \
    1164             :     return AttrHasSubstring(aElement, aNS, aName, aStr, aIgnoreCase);            \
    1165             :   }                                                                              \
    1166             :   bool prefix_##AttrHasPrefix(implementor_ aElement, nsAtom* aNS,                \
    1167             :                               nsAtom* aName, nsAtom* aStr, bool aIgnoreCase)     \
    1168             :   {                                                                              \
    1169             :     return AttrHasPrefix(aElement, aNS, aName, aStr, aIgnoreCase);               \
    1170             :   }                                                                              \
    1171             :   bool prefix_##AttrHasSuffix(implementor_ aElement, nsAtom* aNS,                \
    1172             :                               nsAtom* aName, nsAtom* aStr, bool aIgnoreCase)     \
    1173             :   {                                                                              \
    1174             :     return AttrHasSuffix(aElement, aNS, aName, aStr, aIgnoreCase);               \
    1175             :   }                                                                              \
    1176             :   uint32_t prefix_##ClassOrClassList(implementor_ aElement, nsAtom** aClass,     \
    1177             :                                      nsAtom*** aClassList)                       \
    1178             :   {                                                                              \
    1179             :     return ClassOrClassList(aElement, aClass, aClassList);                       \
    1180             :   }                                                                              \
    1181             :   bool prefix_##HasClass(implementor_ aElement, nsAtom* aClass, bool aIgnoreCase)\
    1182             :   {                                                                              \
    1183             :     return HasClass(aElement, aClass, aIgnoreCase);                              \
    1184             :   }                                                                              \
    1185             : 
    1186             : 
    1187       53558 : SERVO_IMPL_ELEMENT_ATTR_MATCHING_FUNCTIONS(Gecko_, RawGeckoElementBorrowed)
    1188        1409 : SERVO_IMPL_ELEMENT_ATTR_MATCHING_FUNCTIONS(Gecko_Snapshot, const ServoElementSnapshot*)
    1189             : 
    1190             : #undef SERVO_IMPL_ELEMENT_ATTR_MATCHING_FUNCTIONS
    1191             : 
    1192             : nsAtom*
    1193           0 : Gecko_Atomize(const char* aString, uint32_t aLength)
    1194             : {
    1195       52026 :   return NS_Atomize(nsDependentCSubstring(aString, aLength)).take();
    1196             : }
    1197             : 
    1198             : nsAtom*
    1199           0 : Gecko_Atomize16(const nsAString* aString)
    1200             : {
    1201           0 :   return NS_Atomize(*aString).take();
    1202             : }
    1203             : 
    1204             : void
    1205           0 : Gecko_AddRefAtom(nsAtom* aAtom)
    1206             : {
    1207           0 :   NS_ADDREF(aAtom);
    1208       41775 : }
    1209             : 
    1210             : void
    1211           0 : Gecko_ReleaseAtom(nsAtom* aAtom)
    1212             : {
    1213           0 :   NS_RELEASE(aAtom);
    1214           0 : }
    1215             : 
    1216             : void
    1217           0 : Gecko_nsTArray_FontFamilyName_AppendNamed(nsTArray<FontFamilyName>* aNames,
    1218             :                                           nsAtom* aName,
    1219             :                                           bool aQuoted)
    1220             : {
    1221           6 :   FontFamilyName family;
    1222           3 :   aName->ToString(family.mName);
    1223           0 :   if (aQuoted) {
    1224           0 :     family.mType = eFamily_named_quoted;
    1225             :   }
    1226             : 
    1227           0 :   aNames->AppendElement(family);
    1228           0 : }
    1229             : 
    1230             : void
    1231          10 : Gecko_nsTArray_FontFamilyName_AppendGeneric(nsTArray<FontFamilyName>* aNames,
    1232             :                                             FontFamilyType aType)
    1233             : {
    1234           0 :   aNames->AppendElement(FontFamilyName(aType));
    1235          10 : }
    1236             : 
    1237             : SharedFontList*
    1238          10 : Gecko_SharedFontList_Create()
    1239             : {
    1240           0 :   RefPtr<SharedFontList> fontlist = new SharedFontList();
    1241           0 :   return fontlist.forget().take();
    1242             : }
    1243             : 
    1244           0 : MOZ_DEFINE_MALLOC_SIZE_OF(GeckoSharedFontListMallocSizeOf)
    1245             : 
    1246             : size_t
    1247           0 : Gecko_SharedFontList_SizeOfIncludingThisIfUnshared(SharedFontList* aFontlist)
    1248             : {
    1249           0 :   MOZ_ASSERT(NS_IsMainThread());
    1250           0 :   return aFontlist->SizeOfIncludingThisIfUnshared(GeckoSharedFontListMallocSizeOf);
    1251             : }
    1252             : 
    1253             : size_t
    1254           0 : Gecko_SharedFontList_SizeOfIncludingThis(SharedFontList* aFontlist)
    1255             : {
    1256           0 :   MOZ_ASSERT(NS_IsMainThread());
    1257           0 :   return aFontlist->SizeOfIncludingThis(GeckoSharedFontListMallocSizeOf);
    1258             : }
    1259             : 
    1260           0 : NS_IMPL_THREADSAFE_FFI_REFCOUNTING(mozilla::SharedFontList, SharedFontList);
    1261             : 
    1262             : void
    1263           0 : Gecko_CopyFontFamilyFrom(nsFont* dst, const nsFont* src)
    1264             : {
    1265           1 :   dst->fontlist = src->fontlist;
    1266           0 : }
    1267             : 
    1268             : void
    1269           0 : Gecko_nsFont_InitSystem(nsFont* aDest, int32_t aFontId,
    1270             :                         const nsStyleFont* aFont, RawGeckoPresContextBorrowed aPresContext)
    1271             : {
    1272           0 :   const nsFont* defaultVariableFont = ThreadSafeGetDefaultFontHelper(aPresContext, aFont->mLanguage,
    1273          81 :                                                                      kPresContext_DefaultVariableFont_ID);
    1274             : 
    1275             :   // We have passed uninitialized memory to this function,
    1276             :   // initialize it. We can't simply return an nsFont because then
    1277             :   // we need to know its size beforehand. Servo cannot initialize nsFont
    1278             :   // itself, so this will do.
    1279           0 :   nsFont* system = new (aDest) nsFont(*defaultVariableFont);
    1280             : 
    1281          81 :   MOZ_RELEASE_ASSERT(system);
    1282             : 
    1283          81 :   *aDest = *defaultVariableFont;
    1284          81 :   LookAndFeel::FontID fontID = static_cast<LookAndFeel::FontID>(aFontId);
    1285             : 
    1286         162 :   AutoWriteLock guard(*sServoFFILock);
    1287             :   nsLayoutUtils::ComputeSystemFont(aDest, fontID, aPresContext,
    1288          81 :                                    defaultVariableFont);
    1289           0 : }
    1290             : 
    1291             : void
    1292           0 : Gecko_nsFont_Destroy(nsFont* aDest)
    1293             : {
    1294           0 :   aDest->~nsFont();
    1295           0 : }
    1296             : 
    1297             : gfxFontFeatureValueSet*
    1298           0 : Gecko_ConstructFontFeatureValueSet()
    1299             : {
    1300           0 :   return new gfxFontFeatureValueSet();
    1301             : }
    1302             : 
    1303             : nsTArray<unsigned int>*
    1304           0 : Gecko_AppendFeatureValueHashEntry(gfxFontFeatureValueSet* aFontFeatureValues,
    1305             :                                   nsAtom* aFamily, uint32_t aAlternate, nsAtom* aName)
    1306             : {
    1307           0 :   MOZ_ASSERT(NS_IsMainThread());
    1308             :   static_assert(sizeof(unsigned int) == sizeof(uint32_t),
    1309             :                 "sizeof unsigned int and uint32_t must be the same");
    1310             :   return aFontFeatureValues->AppendFeatureValueHashEntry(
    1311           0 :     nsDependentAtomString(aFamily),
    1312           0 :     nsDependentAtomString(aName),
    1313             :     aAlternate
    1314           0 :   );
    1315             : }
    1316             : 
    1317             : void
    1318           0 : Gecko_nsFont_SetFontFeatureValuesLookup(nsFont* aFont,
    1319             :                                         const RawGeckoPresContext* aPresContext)
    1320             : {
    1321           0 :   aFont->featureValueLookup = aPresContext->GetFontFeatureValuesLookup();
    1322           0 : }
    1323             : 
    1324             : float
    1325          81 : Gecko_FontStretch_ToFloat(mozilla::FontStretch aStretch)
    1326             : {
    1327             :   // Servo represents percentages with 1. being 100%.
    1328           0 :   return aStretch.Percentage() / 100.0f;
    1329             : }
    1330             : 
    1331             : void
    1332          81 : Gecko_FontStretch_SetFloat(mozilla::FontStretch* aStretch, float aFloat)
    1333             : {
    1334             :   // Servo represents percentages with 1. being 100%.
    1335             :   //
    1336             :   // Also, the font code assumes a given maximum that style doesn't really need
    1337             :   // to know about. So clamp here at the boundary.
    1338           0 :   *aStretch = FontStretch(std::min(aFloat * 100.0f, float(FontStretch::kMax)));
    1339          81 : }
    1340             : 
    1341             : void
    1342          81 : Gecko_FontSlantStyle_SetNormal(mozilla::FontSlantStyle* aStyle)
    1343             : {
    1344           0 :   *aStyle = mozilla::FontSlantStyle::Normal();
    1345           0 : }
    1346             : 
    1347             : void
    1348           0 : Gecko_FontSlantStyle_SetItalic(mozilla::FontSlantStyle* aStyle)
    1349             : {
    1350           0 :   *aStyle = mozilla::FontSlantStyle::Italic();
    1351           0 : }
    1352             : 
    1353             : void
    1354           0 : Gecko_FontSlantStyle_SetOblique(mozilla::FontSlantStyle* aStyle,
    1355             :                                 float aAngleInDegrees)
    1356             : {
    1357           0 :   *aStyle = mozilla::FontSlantStyle::Oblique(aAngleInDegrees);
    1358           0 : }
    1359             : 
    1360             : void
    1361          81 : Gecko_FontSlantStyle_Get(mozilla::FontSlantStyle aStyle,
    1362             :                          bool* aNormal,
    1363             :                          bool* aItalic,
    1364             :                          float* aObliqueAngle)
    1365             : {
    1366          81 :   *aNormal = aStyle.IsNormal();
    1367           0 :   *aItalic = aStyle.IsItalic();
    1368          81 :   if (aStyle.IsOblique()) {
    1369           0 :     *aObliqueAngle = aStyle.ObliqueAngle();
    1370             :   }
    1371          81 : }
    1372             : 
    1373             : float
    1374           0 : Gecko_FontWeight_ToFloat(mozilla::FontWeight aWeight)
    1375             : {
    1376          84 :   return aWeight.ToFloat();
    1377             : }
    1378             : 
    1379             : void
    1380           0 : Gecko_FontWeight_SetFloat(mozilla::FontWeight* aWeight,
    1381             :                           float aFloat)
    1382             : {
    1383          86 :   *aWeight = mozilla::FontWeight(aFloat);
    1384          86 : }
    1385             : 
    1386             : void
    1387          81 : Gecko_nsFont_ResetFontFeatureValuesLookup(nsFont* aFont)
    1388             : {
    1389           0 :   aFont->featureValueLookup = nullptr;
    1390           0 : }
    1391             : 
    1392             : 
    1393             : void
    1394          81 : Gecko_ClearAlternateValues(nsFont* aFont, size_t aLength)
    1395             : {
    1396           0 :   aFont->alternateValues.Clear();
    1397          81 :   aFont->alternateValues.SetCapacity(aLength);
    1398          81 : }
    1399             : 
    1400             : void
    1401           0 : Gecko_AppendAlternateValues(nsFont* aFont, uint32_t aAlternateName, nsAtom* aAtom)
    1402             : {
    1403           0 :   aFont->alternateValues.AppendElement(gfxAlternateValue {
    1404             :     aAlternateName,
    1405           0 :     nsDependentAtomString(aAtom)
    1406           0 :   });
    1407           0 : }
    1408             : 
    1409             : void
    1410           1 : Gecko_CopyAlternateValuesFrom(nsFont* aDest, const nsFont* aSrc)
    1411             : {
    1412           0 :   aDest->alternateValues.Clear();
    1413           0 :   aDest->alternateValues.AppendElements(aSrc->alternateValues);
    1414           1 :   aDest->featureValueLookup = aSrc->featureValueLookup;
    1415           1 : }
    1416             : 
    1417             : void
    1418           0 : Gecko_SetImageOrientation(nsStyleVisibility* aVisibility,
    1419             :                           uint8_t aOrientation, bool aFlip)
    1420             : {
    1421             :   aVisibility->mImageOrientation =
    1422           0 :     nsStyleImageOrientation::CreateAsOrientationAndFlip(aOrientation, aFlip);
    1423           0 : }
    1424             : 
    1425             : void
    1426           0 : Gecko_SetImageOrientationAsFromImage(nsStyleVisibility* aVisibility)
    1427             : {
    1428           0 :   aVisibility->mImageOrientation = nsStyleImageOrientation::CreateAsFromImage();
    1429           0 : }
    1430             : 
    1431             : void
    1432           0 : Gecko_CopyImageOrientationFrom(nsStyleVisibility* aDst,
    1433             :                                const nsStyleVisibility* aSrc)
    1434             : {
    1435           0 :   aDst->mImageOrientation = aSrc->mImageOrientation;
    1436           0 : }
    1437             : 
    1438             : void
    1439           0 : Gecko_SetCounterStyleToName(CounterStylePtr* aPtr, nsAtom* aName,
    1440             :                             RawGeckoPresContextBorrowed aPresContext)
    1441             : {
    1442             :   // Try resolving the counter style if possible, and keep it unresolved
    1443             :   // otherwise.
    1444           0 :   CounterStyleManager* manager = aPresContext->CounterStyleManager();
    1445           0 :   RefPtr<nsAtom> name = already_AddRefed<nsAtom>(aName);
    1446           0 :   if (CounterStyle* style = manager->GetCounterStyle(name)) {
    1447           0 :     *aPtr = style;
    1448             :   } else {
    1449           0 :     *aPtr = name.forget();
    1450             :   }
    1451           0 : }
    1452             : 
    1453             : void
    1454           0 : Gecko_SetCounterStyleToSymbols(CounterStylePtr* aPtr, uint8_t aSymbolsType,
    1455             :                                nsACString const* const* aSymbols,
    1456             :                                uint32_t aSymbolsCount)
    1457             : {
    1458           0 :   nsTArray<nsString> symbols(aSymbolsCount);
    1459           0 :   for (uint32_t i = 0; i < aSymbolsCount; i++) {
    1460           0 :     symbols.AppendElement(NS_ConvertUTF8toUTF16(*aSymbols[i]));
    1461             :   }
    1462           0 :   *aPtr = new AnonymousCounterStyle(aSymbolsType, std::move(symbols));
    1463           0 : }
    1464             : 
    1465             : void
    1466           0 : Gecko_SetCounterStyleToString(CounterStylePtr* aPtr, const nsACString* aSymbol)
    1467             : {
    1468           0 :   *aPtr = new AnonymousCounterStyle(NS_ConvertUTF8toUTF16(*aSymbol));
    1469           0 : }
    1470             : 
    1471             : void
    1472           0 : Gecko_CopyCounterStyle(CounterStylePtr* aDst, const CounterStylePtr* aSrc)
    1473             : {
    1474           0 :   *aDst = *aSrc;
    1475           0 : }
    1476             : 
    1477             : nsAtom*
    1478           0 : Gecko_CounterStyle_GetName(const CounterStylePtr* aPtr)
    1479             : {
    1480           0 :   if (!aPtr->IsResolved()) {
    1481           0 :     return aPtr->AsAtom();
    1482             :   }
    1483           0 :   return (*aPtr)->GetStyleName();
    1484             : }
    1485             : 
    1486             : const AnonymousCounterStyle*
    1487           0 : Gecko_CounterStyle_GetAnonymous(const CounterStylePtr* aPtr)
    1488             : {
    1489           0 :   return aPtr->AsAnonymous();
    1490             : }
    1491             : 
    1492             : already_AddRefed<css::URLValue>
    1493           0 : ServoBundledURI::IntoCssUrl()
    1494             : {
    1495           0 :   MOZ_ASSERT(mExtraData->GetReferrer());
    1496         280 :   MOZ_ASSERT(mExtraData->GetPrincipal());
    1497             : 
    1498             :   RefPtr<css::URLValue> urlValue =
    1499           0 :     new css::URLValue(mURLString, do_AddRef(mExtraData));
    1500         280 :   return urlValue.forget();
    1501             : }
    1502             : 
    1503             : already_AddRefed<css::ImageValue>
    1504         394 : ServoBundledURI::IntoCssImage(mozilla::CORSMode aCorsMode)
    1505             : {
    1506             :   RefPtr<css::ImageValue> urlValue =
    1507        1182 :     new css::ImageValue(mURLString, do_AddRef(mExtraData), aCorsMode);
    1508         788 :   return urlValue.forget();
    1509             : }
    1510             : 
    1511             : void
    1512         112 : Gecko_SetNullImageValue(nsStyleImage* aImage)
    1513             : {
    1514           0 :   MOZ_ASSERT(aImage);
    1515         112 :   aImage->SetNull();
    1516         112 : }
    1517             : 
    1518             : void
    1519          33 : Gecko_SetGradientImageValue(nsStyleImage* aImage, nsStyleGradient* aGradient)
    1520             : {
    1521           0 :   MOZ_ASSERT(aImage);
    1522           0 :   aImage->SetGradientData(aGradient);
    1523          33 : }
    1524             : 
    1525           0 : NS_IMPL_THREADSAFE_FFI_REFCOUNTING(mozilla::css::ImageValue, ImageValue);
    1526             : 
    1527             : static already_AddRefed<nsStyleImageRequest>
    1528           0 : CreateStyleImageRequest(nsStyleImageRequest::Mode aModeFlags,
    1529             :                         mozilla::css::ImageValue* aImageValue)
    1530             : {
    1531             :   RefPtr<nsStyleImageRequest> req =
    1532         158 :     new nsStyleImageRequest(aModeFlags, aImageValue);
    1533         158 :   return req.forget();
    1534             : }
    1535             : 
    1536             : mozilla::css::ImageValue*
    1537         394 : Gecko_ImageValue_Create(ServoBundledURI aURI)
    1538             : {
    1539             :   // Bug 1434963: Change this to accept a CORS mode from the caller.
    1540         788 :   return aURI.IntoCssImage(mozilla::CORSMode::CORS_NONE).take();
    1541             : }
    1542             : 
    1543           0 : MOZ_DEFINE_MALLOC_SIZE_OF(GeckoImageValueMallocSizeOf)
    1544             : 
    1545             : size_t
    1546           0 : Gecko_ImageValue_SizeOfIncludingThis(mozilla::css::ImageValue* aImageValue)
    1547             : {
    1548           0 :   MOZ_ASSERT(NS_IsMainThread());
    1549           0 :   return aImageValue->SizeOfIncludingThis(GeckoImageValueMallocSizeOf);
    1550             : }
    1551             : 
    1552             : void
    1553           9 : Gecko_SetLayerImageImageValue(nsStyleImage* aImage,
    1554             :                               mozilla::css::ImageValue* aImageValue)
    1555             : {
    1556           9 :   MOZ_ASSERT(aImage && aImageValue);
    1557             : 
    1558             :   RefPtr<nsStyleImageRequest> req =
    1559           0 :     CreateStyleImageRequest(nsStyleImageRequest::Mode::Track, aImageValue);
    1560           9 :   aImage->SetImageRequest(req.forget());
    1561           9 : }
    1562             : 
    1563             : void
    1564           0 : Gecko_SetImageElement(nsStyleImage* aImage, nsAtom* aAtom) {
    1565           0 :   MOZ_ASSERT(aImage);
    1566           0 :   aImage->SetElementId(do_AddRef(aAtom));
    1567           0 : }
    1568             : 
    1569             : void
    1570           0 : Gecko_CopyImageValueFrom(nsStyleImage* aImage, const nsStyleImage* aOther)
    1571             : {
    1572           0 :   MOZ_ASSERT(aImage);
    1573           0 :   MOZ_ASSERT(aOther);
    1574             : 
    1575           0 :   *aImage = *aOther;
    1576           0 : }
    1577             : 
    1578             : void
    1579           0 : Gecko_InitializeImageCropRect(nsStyleImage* aImage)
    1580             : {
    1581           0 :   MOZ_ASSERT(aImage);
    1582           0 :   aImage->SetCropRect(MakeUnique<nsStyleSides>());
    1583           0 : }
    1584             : 
    1585             : void
    1586          77 : Gecko_SetCursorArrayLength(nsStyleUserInterface* aStyleUI, size_t aLen)
    1587             : {
    1588           0 :   aStyleUI->mCursorImages.Clear();
    1589           0 :   aStyleUI->mCursorImages.SetLength(aLen);
    1590          77 : }
    1591             : 
    1592             : void
    1593           0 : Gecko_SetCursorImageValue(nsCursorImage* aCursor,
    1594             :                           mozilla::css::ImageValue* aImageValue)
    1595             : {
    1596           0 :   MOZ_ASSERT(aCursor && aImageValue);
    1597             : 
    1598             :   aCursor->mImage =
    1599           0 :     CreateStyleImageRequest(nsStyleImageRequest::Mode::Discard, aImageValue);
    1600           0 : }
    1601             : 
    1602             : void
    1603           0 : Gecko_CopyCursorArrayFrom(nsStyleUserInterface* aDest,
    1604             :                           const nsStyleUserInterface* aSrc)
    1605             : {
    1606           0 :   aDest->mCursorImages = aSrc->mCursorImages;
    1607           0 : }
    1608             : 
    1609             : void
    1610           2 : Gecko_SetContentDataImageValue(nsStyleContentData* aContent,
    1611             :                                mozilla::css::ImageValue* aImageValue)
    1612             : {
    1613           0 :   MOZ_ASSERT(aContent && aImageValue);
    1614             : 
    1615             :   RefPtr<nsStyleImageRequest> req =
    1616           0 :     CreateStyleImageRequest(nsStyleImageRequest::Mode::Track, aImageValue);
    1617           2 :   aContent->SetImageRequest(req.forget());
    1618           2 : }
    1619             : 
    1620             : nsStyleContentData::CounterFunction*
    1621           0 : Gecko_SetCounterFunction(nsStyleContentData* aContent, nsStyleContentType aType)
    1622             : {
    1623             :   RefPtr<nsStyleContentData::CounterFunction>
    1624           0 :     counterFunc = new nsStyleContentData::CounterFunction();
    1625           0 :   nsStyleContentData::CounterFunction* ptr = counterFunc;
    1626           0 :   aContent->SetCounters(aType, counterFunc.forget());
    1627           0 :   return ptr;
    1628             : }
    1629             : 
    1630             : nsStyleGradient*
    1631           0 : Gecko_CreateGradient(uint8_t aShape,
    1632             :                      uint8_t aSize,
    1633             :                      bool aRepeating,
    1634             :                      bool aLegacySyntax,
    1635             :                      bool aMozLegacySyntax,
    1636             :                      uint32_t aStopCount)
    1637             : {
    1638          33 :   nsStyleGradient* result = new nsStyleGradient();
    1639             : 
    1640          33 :   result->mShape = aShape;
    1641          33 :   result->mSize = aSize;
    1642          33 :   result->mRepeating = aRepeating;
    1643          33 :   result->mLegacySyntax = aLegacySyntax;
    1644           0 :   result->mMozLegacySyntax = aMozLegacySyntax;
    1645             : 
    1646           0 :   result->mAngle.SetNoneValue();
    1647           0 :   result->mBgPosX.SetNoneValue();
    1648           0 :   result->mBgPosY.SetNoneValue();
    1649           0 :   result->mRadiusX.SetNoneValue();
    1650           0 :   result->mRadiusY.SetNoneValue();
    1651             : 
    1652           0 :   nsStyleGradientStop dummyStop = {
    1653           0 :     nsStyleCoord(eStyleUnit_None),
    1654           0 :     StyleComplexColor::FromColor(NS_RGB(0, 0, 0)),
    1655           0 :     0
    1656             :   };
    1657         109 : 
    1658           0 :   for (uint32_t i = 0; i < aStopCount; i++) {
    1659             :     result->mStops.AppendElement(dummyStop);
    1660             :   }
    1661           0 : 
    1662             :   return result;
    1663             : }
    1664             : 
    1665           0 : const nsStyleImageRequest*
    1666             : Gecko_GetImageRequest(const nsStyleImage* aImage)
    1667           0 : {
    1668           0 :   MOZ_ASSERT(aImage);
    1669             :   return aImage->ImageRequest();
    1670             : }
    1671             : 
    1672           0 : nsAtom*
    1673             : Gecko_GetImageElement(const nsStyleImage* aImage)
    1674           0 : {
    1675           0 :   MOZ_ASSERT(aImage && aImage->GetType() == eStyleImageType_Element);
    1676             :   return const_cast<nsAtom*>(aImage->GetElementId());
    1677             : }
    1678             : 
    1679           0 : const nsStyleGradient*
    1680             : Gecko_GetGradientImageValue(const nsStyleImage* aImage)
    1681           0 : {
    1682           0 :   MOZ_ASSERT(aImage && aImage->GetType() == eStyleImageType_Gradient);
    1683             :   return aImage->GetGradientData();
    1684             : }
    1685             : 
    1686          52 : void
    1687             : Gecko_SetListStyleImageNone(nsStyleList* aList)
    1688           0 : {
    1689          52 :   aList->mListStyleImage = nullptr;
    1690             : }
    1691             : 
    1692           0 : void
    1693             : Gecko_SetListStyleImageImageValue(nsStyleList* aList,
    1694             :                              mozilla::css::ImageValue* aImageValue)
    1695           0 : {
    1696             :   MOZ_ASSERT(aList && aImageValue);
    1697             : 
    1698           0 :   aList->mListStyleImage =
    1699          68 :     CreateStyleImageRequest(nsStyleImageRequest::Mode(0), aImageValue);
    1700             : }
    1701             : 
    1702           6 : void
    1703             : Gecko_CopyListStyleImageFrom(nsStyleList* aList, const nsStyleList* aSource)
    1704           0 : {
    1705           0 :   aList->mListStyleImage = aSource->mListStyleImage;
    1706             : }
    1707             : 
    1708           0 : void
    1709             : Gecko_EnsureTArrayCapacity(void* aArray, size_t aCapacity, size_t aElemSize)
    1710             : {
    1711             :   auto base =
    1712         119 :     reinterpret_cast<nsTArray_base<nsTArrayInfallibleAllocator,
    1713             :                                    nsTArray_CopyWithMemutils>*>(aArray);
    1714           0 : 
    1715         119 :   base->EnsureCapacity<nsTArrayInfallibleAllocator>(aCapacity, aElemSize);
    1716             : }
    1717             : 
    1718           0 : void
    1719             : Gecko_ClearPODTArray(void* aArray, size_t aElementSize, size_t aElementAlign)
    1720             : {
    1721             :   auto base =
    1722           0 :     reinterpret_cast<nsTArray_base<nsTArrayInfallibleAllocator,
    1723             :                                    nsTArray_CopyWithMemutils>*>(aArray);
    1724           0 : 
    1725           0 :   base->template ShiftData<nsTArrayInfallibleAllocator>(0, base->Length(), 0,
    1726           0 :                                                         aElementSize, aElementAlign);
    1727             : }
    1728           0 : 
    1729             : void Gecko_ResizeTArrayForStrings(nsTArray<nsString>* aArray, uint32_t aLength)
    1730           0 : {
    1731           0 :   aArray->SetLength(aLength);
    1732             : }
    1733             : 
    1734           0 : void
    1735             : Gecko_SetStyleGridTemplate(UniquePtr<nsStyleGridTemplate>* aGridTemplate,
    1736             :                            nsStyleGridTemplate* aValue)
    1737           0 : {
    1738           0 :   aGridTemplate->reset(aValue);
    1739             : }
    1740             : 
    1741           0 : nsStyleGridTemplate*
    1742             : Gecko_CreateStyleGridTemplate(uint32_t aTrackSizes, uint32_t aNameSize)
    1743           0 : {
    1744           0 :   nsStyleGridTemplate* result = new nsStyleGridTemplate;
    1745           0 :   result->mMinTrackSizingFunctions.SetLength(aTrackSizes);
    1746           0 :   result->mMaxTrackSizingFunctions.SetLength(aTrackSizes);
    1747           0 :   result->mLineNameLists.SetLength(aNameSize);
    1748             :   return result;
    1749             : }
    1750             : 
    1751           0 : void
    1752             : Gecko_CopyStyleGridTemplateValues(UniquePtr<nsStyleGridTemplate>* aGridTemplate,
    1753             :                                   const nsStyleGridTemplate* aOther)
    1754          34 : {
    1755           0 :   if (aOther) {
    1756             :     *aGridTemplate = MakeUnique<nsStyleGridTemplate>(*aOther);
    1757           0 :   } else {
    1758             :     *aGridTemplate = nullptr;
    1759          34 :   }
    1760             : }
    1761             : 
    1762           0 : mozilla::css::GridTemplateAreasValue*
    1763             : Gecko_NewGridTemplateAreasValue(uint32_t aAreas, uint32_t aTemplates, uint32_t aColumns)
    1764           0 : {
    1765           0 :   RefPtr<mozilla::css::GridTemplateAreasValue> value = new mozilla::css::GridTemplateAreasValue;
    1766           0 :   value->mNamedAreas.SetLength(aAreas);
    1767           0 :   value->mTemplates.SetLength(aTemplates);
    1768           0 :   value->mNColumns = aColumns;
    1769             :   return value.forget().take();
    1770             : }
    1771           0 : 
    1772             : NS_IMPL_THREADSAFE_FFI_REFCOUNTING(mozilla::css::GridTemplateAreasValue, GridTemplateAreasValue);
    1773             : 
    1774           0 : void
    1775             : Gecko_ClearAndResizeStyleContents(nsStyleContent* aContent, uint32_t aHowMany)
    1776           9 : {
    1777           0 :   aContent->AllocateContents(aHowMany);
    1778             : }
    1779             : 
    1780           0 : void
    1781             : Gecko_CopyStyleContentsFrom(nsStyleContent* aContent, const nsStyleContent* aOther)
    1782           0 : {
    1783             :   uint32_t count = aOther->ContentCount();
    1784           0 : 
    1785             :   aContent->AllocateContents(count);
    1786           0 : 
    1787           0 :   for (uint32_t i = 0; i < count; ++i) {
    1788             :     aContent->ContentAt(i) = aOther->ContentAt(i);
    1789           0 :   }
    1790             : }
    1791             : 
    1792           0 : void
    1793             : Gecko_ClearAndResizeCounterIncrements(nsStyleContent* aContent, uint32_t aHowMany)
    1794           0 : {
    1795           0 :   aContent->AllocateCounterIncrements(aHowMany);
    1796             : }
    1797             : 
    1798           0 : void
    1799             : Gecko_CopyCounterIncrementsFrom(nsStyleContent* aContent, const nsStyleContent* aOther)
    1800           0 : {
    1801             :   uint32_t count = aOther->CounterIncrementCount();
    1802           0 : 
    1803             :   aContent->AllocateCounterIncrements(count);
    1804           0 : 
    1805           0 :   for (uint32_t i = 0; i < count; ++i) {
    1806           0 :     const nsStyleCounterData& data = aOther->CounterIncrementAt(i);
    1807             :     aContent->SetCounterIncrementAt(i, data.mCounter, data.mValue);
    1808           0 :   }
    1809             : }
    1810             : 
    1811           0 : void
    1812             : Gecko_ClearAndResizeCounterResets(nsStyleContent* aContent, uint32_t aHowMany)
    1813           0 : {
    1814           0 :   aContent->AllocateCounterResets(aHowMany);
    1815             : }
    1816             : 
    1817           0 : void
    1818             : Gecko_CopyCounterResetsFrom(nsStyleContent* aContent, const nsStyleContent* aOther)
    1819           0 : {
    1820             :   uint32_t count = aOther->CounterResetCount();
    1821           0 : 
    1822             :   aContent->AllocateCounterResets(count);
    1823           0 : 
    1824           0 :   for (uint32_t i = 0; i < count; ++i) {
    1825           0 :     const nsStyleCounterData& data = aOther->CounterResetAt(i);
    1826             :     aContent->SetCounterResetAt(i, data.mCounter, data.mValue);
    1827           0 :   }
    1828             : }
    1829             : 
    1830           0 : void
    1831             : Gecko_EnsureImageLayersLength(nsStyleImageLayers* aLayers, size_t aLen,
    1832             :                               nsStyleImageLayers::LayerType aLayerType)
    1833           0 : {
    1834             :   size_t oldLength = aLayers->mLayers.Length();
    1835         322 : 
    1836             :   aLayers->mLayers.EnsureLengthAtLeast(aLen);
    1837         322 : 
    1838           0 :   for (size_t i = oldLength; i < aLen; ++i) {
    1839             :     aLayers->mLayers[i].Initialize(aLayerType);
    1840         322 :   }
    1841             : }
    1842             : 
    1843             : template <typename StyleType>
    1844           0 : static void
    1845             : EnsureStyleAutoArrayLength(StyleType* aArray, size_t aLen)
    1846           0 : {
    1847             :   size_t oldLength = aArray->Length();
    1848         139 : 
    1849             :   aArray->EnsureLengthAtLeast(aLen);
    1850           0 : 
    1851           4 :   for (size_t i = oldLength; i < aLen; ++i) {
    1852             :     (*aArray)[i].SetInitialValues();
    1853         139 :   }
    1854             : }
    1855             : 
    1856           0 : void
    1857             : Gecko_EnsureStyleAnimationArrayLength(void* aArray, size_t aLen)
    1858             : {
    1859           0 :   auto base =
    1860          16 :     static_cast<nsStyleAutoArray<StyleAnimation>*>(aArray);
    1861          16 :   EnsureStyleAutoArrayLength(base, aLen);
    1862             : }
    1863             : 
    1864         123 : void
    1865             : Gecko_EnsureStyleTransitionArrayLength(void* aArray, size_t aLen)
    1866             : {
    1867           0 :   auto base =
    1868         123 :     reinterpret_cast<nsStyleAutoArray<StyleTransition>*>(aArray);
    1869         123 :   EnsureStyleAutoArrayLength(base, aLen);
    1870             : }
    1871             : 
    1872           0 : void
    1873             : Gecko_ClearWillChange(nsStyleDisplay* aDisplay, size_t aLength)
    1874           0 : {
    1875           0 :   aDisplay->mWillChange.Clear();
    1876           0 :   aDisplay->mWillChange.SetCapacity(aLength);
    1877             : }
    1878             : 
    1879           0 : void
    1880             : Gecko_AppendWillChange(nsStyleDisplay* aDisplay, nsAtom* aAtom)
    1881           0 : {
    1882           0 :   aDisplay->mWillChange.AppendElement(aAtom);
    1883             : }
    1884             : 
    1885           0 : void
    1886             : Gecko_CopyWillChangeFrom(nsStyleDisplay* aDest, nsStyleDisplay* aSrc)
    1887           0 : {
    1888           0 :   aDest->mWillChange.Clear();
    1889           0 :   aDest->mWillChange.AppendElements(aSrc->mWillChange);
    1890             : }
    1891             : 
    1892             : enum class KeyframeSearchDirection {
    1893             :   Forwards,
    1894             :   Backwards,
    1895             : };
    1896             : 
    1897             : enum class KeyframeInsertPosition {
    1898             :   Prepend,
    1899             :   LastForOffset,
    1900             : };
    1901             : 
    1902           0 : static Keyframe*
    1903             : GetOrCreateKeyframe(nsTArray<Keyframe>* aKeyframes,
    1904             :                     float aOffset,
    1905             :                     const nsTimingFunction* aTimingFunction,
    1906             :                     KeyframeSearchDirection aSearchDirection,
    1907             :                     KeyframeInsertPosition aInsertPosition)
    1908           0 : {
    1909           0 :   MOZ_ASSERT(aKeyframes, "The keyframe array should be valid");
    1910           0 :   MOZ_ASSERT(aTimingFunction, "The timing function should be valid");
    1911             :   MOZ_ASSERT(aOffset >= 0. && aOffset <= 1.,
    1912             :              "The offset should be in the range of [0.0, 1.0]");
    1913             : 
    1914           0 :   size_t keyframeIndex;
    1915             :   switch (aSearchDirection) {
    1916           0 :     case KeyframeSearchDirection::Forwards:
    1917             :       if (nsAnimationManager::FindMatchingKeyframe(*aKeyframes,
    1918             :                                                    aOffset,
    1919             :                                                    *aTimingFunction,
    1920           0 :                                                    keyframeIndex)) {
    1921             :         return &(*aKeyframes)[keyframeIndex];
    1922             :       }
    1923             :       break;
    1924           0 :     case KeyframeSearchDirection::Backwards:
    1925             :       if (nsAnimationManager::FindMatchingKeyframe(Reversed(*aKeyframes),
    1926             :                                                    aOffset,
    1927             :                                                    *aTimingFunction,
    1928           0 :                                                    keyframeIndex)) {
    1929             :         return &(*aKeyframes)[aKeyframes->Length() - 1 - keyframeIndex];
    1930           0 :       }
    1931           0 :       keyframeIndex = aKeyframes->Length() - 1;
    1932             :       break;
    1933             :   }
    1934             : 
    1935           0 :   Keyframe* keyframe =
    1936             :     aKeyframes->InsertElementAt(
    1937             :       aInsertPosition == KeyframeInsertPosition::Prepend
    1938           0 :                          ? 0
    1939           0 :                          : keyframeIndex);
    1940           0 :   keyframe->mOffset.emplace(aOffset);
    1941           0 :   if (aTimingFunction->mType != nsTimingFunction::Type::Linear) {
    1942           0 :     keyframe->mTimingFunction.emplace();
    1943             :     keyframe->mTimingFunction->Init(*aTimingFunction);
    1944             :   }
    1945             : 
    1946             :   return keyframe;
    1947             : }
    1948             : 
    1949           0 : Keyframe*
    1950             : Gecko_GetOrCreateKeyframeAtStart(nsTArray<Keyframe>* aKeyframes,
    1951             :                                  float aOffset,
    1952             :                                  const nsTimingFunction* aTimingFunction)
    1953           0 : {
    1954             :   MOZ_ASSERT(aKeyframes->IsEmpty() ||
    1955             :              aKeyframes->ElementAt(0).mOffset.value() >= aOffset,
    1956             :              "The offset should be less than or equal to the first keyframe's "
    1957             :              "offset if there are exisiting keyframes");
    1958             : 
    1959             :   return GetOrCreateKeyframe(aKeyframes,
    1960             :                              aOffset,
    1961             :                              aTimingFunction,
    1962           0 :                              KeyframeSearchDirection::Forwards,
    1963             :                              KeyframeInsertPosition::Prepend);
    1964             : }
    1965             : 
    1966           0 : Keyframe*
    1967             : Gecko_GetOrCreateInitialKeyframe(nsTArray<Keyframe>* aKeyframes,
    1968             :                                  const nsTimingFunction* aTimingFunction)
    1969             : {
    1970             :   return GetOrCreateKeyframe(aKeyframes,
    1971             :                              0.,
    1972             :                              aTimingFunction,
    1973           0 :                              KeyframeSearchDirection::Forwards,
    1974             :                              KeyframeInsertPosition::LastForOffset);
    1975             : }
    1976             : 
    1977           0 : Keyframe*
    1978             : Gecko_GetOrCreateFinalKeyframe(nsTArray<Keyframe>* aKeyframes,
    1979             :                                const nsTimingFunction* aTimingFunction)
    1980             : {
    1981             :   return GetOrCreateKeyframe(aKeyframes,
    1982             :                              1.,
    1983             :                              aTimingFunction,
    1984           0 :                              KeyframeSearchDirection::Backwards,
    1985             :                              KeyframeInsertPosition::LastForOffset);
    1986             : }
    1987             : 
    1988           0 : PropertyValuePair*
    1989             : Gecko_AppendPropertyValuePair(nsTArray<PropertyValuePair>* aProperties,
    1990             :                               nsCSSPropertyID aProperty)
    1991           0 : {
    1992           0 :   MOZ_ASSERT(aProperties);
    1993             :   return aProperties->AppendElement(PropertyValuePair {aProperty});
    1994             : }
    1995             : 
    1996           0 : void
    1997             : Gecko_ResetStyleCoord(nsStyleUnit* aUnit, nsStyleUnion* aValue)
    1998           0 : {
    1999           0 :   nsStyleCoord::Reset(*aUnit, *aValue);
    2000             : }
    2001             : 
    2002           0 : void
    2003             : Gecko_SetStyleCoordCalcValue(nsStyleUnit* aUnit, nsStyleUnion* aValue, nsStyleCoord::CalcValue aCalc)
    2004             : {
    2005           0 :   // Calc units should be cleaned up first
    2006         136 :   MOZ_ASSERT(*aUnit != nsStyleUnit::eStyleUnit_Calc);
    2007          68 :   nsStyleCoord::Calc* calcRef = new nsStyleCoord::Calc();
    2008           0 :   calcRef->mLength = aCalc.mLength;
    2009          68 :   calcRef->mPercent = aCalc.mPercent;
    2010          68 :   calcRef->mHasPercent = aCalc.mHasPercent;
    2011           0 :   *aUnit = nsStyleUnit::eStyleUnit_Calc;
    2012           0 :   aValue->mPointer = calcRef;
    2013           0 :   calcRef->AddRef();
    2014             : }
    2015             : 
    2016           0 : void
    2017             : Gecko_CopyShapeSourceFrom(mozilla::StyleShapeSource* aDst, const mozilla::StyleShapeSource* aSrc)
    2018           0 : {
    2019           0 :   MOZ_ASSERT(aDst);
    2020             :   MOZ_ASSERT(aSrc);
    2021           0 : 
    2022           0 :   *aDst = *aSrc;
    2023             : }
    2024             : 
    2025           0 : void
    2026             : Gecko_DestroyShapeSource(mozilla::StyleShapeSource* aShape)
    2027           0 : {
    2028           0 :   aShape->~StyleShapeSource();
    2029             : }
    2030             : 
    2031           0 : void
    2032             : Gecko_StyleShapeSource_SetURLValue(StyleShapeSource* aShape, URLValue* aURL)
    2033           0 : {
    2034           0 :   aShape->SetURL(aURL);
    2035             : }
    2036             : 
    2037           0 : void
    2038             : Gecko_NewBasicShape(mozilla::StyleShapeSource* aShape,
    2039             :                     mozilla::StyleBasicShapeType aType)
    2040           0 : {
    2041           0 :   aShape->SetBasicShape(MakeUnique<mozilla::StyleBasicShape>(aType),
    2042           0 :                         StyleGeometryBox::NoBox);
    2043             : }
    2044             : 
    2045           0 : void
    2046             : Gecko_NewShapeImage(mozilla::StyleShapeSource* aShape)
    2047           0 : {
    2048           0 :   aShape->SetShapeImage(MakeUnique<nsStyleImage>());
    2049             : }
    2050             : 
    2051           0 : void
    2052             : Gecko_ResetFilters(nsStyleEffects* effects, size_t new_len)
    2053           0 : {
    2054           0 :   effects->mFilters.Clear();
    2055           0 :   effects->mFilters.SetLength(new_len);
    2056             : }
    2057             : 
    2058           0 : void
    2059             : Gecko_CopyFiltersFrom(nsStyleEffects* aSrc, nsStyleEffects* aDest)
    2060           0 : {
    2061           0 :   aDest->mFilters = aSrc->mFilters;
    2062             : }
    2063             : 
    2064           0 : void
    2065             : Gecko_nsStyleFilter_SetURLValue(nsStyleFilter* aEffects, URLValue* aURL)
    2066           0 : {
    2067           0 :   aEffects->SetURL(aURL);
    2068             : }
    2069             : 
    2070           0 : void
    2071             : Gecko_nsStyleSVGPaint_CopyFrom(nsStyleSVGPaint* aDest, const nsStyleSVGPaint* aSrc)
    2072           0 : {
    2073           0 :   *aDest = *aSrc;
    2074             : }
    2075             : 
    2076           0 : void
    2077             : Gecko_nsStyleSVGPaint_SetURLValue(nsStyleSVGPaint* aPaint, URLValue* aURL)
    2078           0 : {
    2079           0 :   aPaint->SetPaintServer(aURL);
    2080             : }
    2081          89 : 
    2082             : void Gecko_nsStyleSVGPaint_Reset(nsStyleSVGPaint* aPaint)
    2083          89 : {
    2084           0 :   aPaint->SetNone();
    2085             : }
    2086             : 
    2087           0 : void
    2088             : Gecko_nsStyleSVG_SetDashArrayLength(nsStyleSVG* aSvg, uint32_t aLen)
    2089           0 : {
    2090           0 :   aSvg->mStrokeDasharray.Clear();
    2091           0 :   aSvg->mStrokeDasharray.SetLength(aLen);
    2092             : }
    2093             : 
    2094           0 : void
    2095             : Gecko_nsStyleSVG_CopyDashArray(nsStyleSVG* aDst, const nsStyleSVG* aSrc)
    2096           0 : {
    2097           0 :   aDst->mStrokeDasharray = aSrc->mStrokeDasharray;
    2098             : }
    2099             : 
    2100           0 : void
    2101             : Gecko_nsStyleSVG_SetContextPropertiesLength(nsStyleSVG* aSvg, uint32_t aLen)
    2102           0 : {
    2103           0 :   aSvg->mContextProps.Clear();
    2104          75 :   aSvg->mContextProps.SetLength(aLen);
    2105             : }
    2106             : 
    2107           0 : void
    2108             : Gecko_nsStyleSVG_CopyContextProperties(nsStyleSVG* aDst, const nsStyleSVG* aSrc)
    2109           0 : {
    2110           0 :   aDst->mContextProps = aSrc->mContextProps;
    2111           0 :   aDst->mContextPropsBits = aSrc->mContextPropsBits;
    2112             : }
    2113             : 
    2114             : 
    2115           0 : css::URLValue*
    2116             : Gecko_NewURLValue(ServoBundledURI aURI)
    2117           0 : {
    2118         396 :   RefPtr<css::URLValue> url = aURI.IntoCssUrl();
    2119             :   return url.forget().take();
    2120             : }
    2121           0 : 
    2122             : MOZ_DEFINE_MALLOC_SIZE_OF(GeckoURLValueMallocSizeOf)
    2123             : 
    2124           0 : size_t
    2125             : Gecko_URLValue_SizeOfIncludingThis(URLValue* aURL)
    2126           0 : {
    2127           0 :   MOZ_ASSERT(NS_IsMainThread());
    2128             :   return aURL->SizeOfIncludingThis(GeckoURLValueMallocSizeOf);
    2129             : }
    2130             : 
    2131           0 : void
    2132             : Gecko_GetComputedURLSpec(const URLValueData* aURL, nsCString* aOut)
    2133           0 : {
    2134           0 :   MOZ_ASSERT(aURL);
    2135           0 :   MOZ_ASSERT(aOut);
    2136           0 :   if (aURL->IsLocalRef()) {
    2137           0 :     aOut->Assign(aURL->GetString());
    2138             :     return;
    2139           0 :   }
    2140           0 :   if (nsIURI* uri = aURL->GetURI()) {
    2141           0 :     nsresult rv = uri->GetSpec(*aOut);
    2142             :     if (NS_SUCCEEDED(rv)) {
    2143             :       return;
    2144             :     }
    2145             :   }
    2146           0 : 
    2147             :   aOut->AssignLiteral("about:invalid");
    2148             : }
    2149        1008 : 
    2150             : NS_IMPL_THREADSAFE_FFI_REFCOUNTING(css::URLValue, CSSURLValue);
    2151        1847 : 
    2152             : NS_IMPL_THREADSAFE_FFI_REFCOUNTING(URLExtraData, URLExtraData);
    2153           0 : 
    2154             : NS_IMPL_THREADSAFE_FFI_REFCOUNTING(nsStyleCoord::Calc, Calc);
    2155             : 
    2156          37 : nsCSSShadowArray*
    2157             : Gecko_NewCSSShadowArray(uint32_t aLen)
    2158          74 : {
    2159           0 :   RefPtr<nsCSSShadowArray> arr = new(aLen) nsCSSShadowArray(aLen);
    2160             :   return arr.forget().take();
    2161             : }
    2162           0 : 
    2163             : NS_IMPL_THREADSAFE_FFI_REFCOUNTING(nsCSSShadowArray, CSSShadowArray);
    2164             : 
    2165           0 : nsStyleQuoteValues*
    2166             : Gecko_NewStyleQuoteValues(uint32_t aLen)
    2167           0 : {
    2168           0 :   RefPtr<nsStyleQuoteValues> values = new nsStyleQuoteValues;
    2169           0 :   values->mQuotePairs.SetLength(aLen);
    2170             :   return values.forget().take();
    2171             : }
    2172           0 : 
    2173             : NS_IMPL_THREADSAFE_FFI_REFCOUNTING(nsStyleQuoteValues, QuoteValues);
    2174             : 
    2175           0 : nsCSSValueSharedList*
    2176             : Gecko_NewCSSValueSharedList(uint32_t aLen)
    2177          39 : {
    2178           0 :   RefPtr<nsCSSValueSharedList> list = new nsCSSValueSharedList;
    2179           0 :   if (aLen == 0) {
    2180             :     return list.forget().take();
    2181             :   }
    2182          13 : 
    2183           0 :   list->mHead = new nsCSSValueList;
    2184           0 :   nsCSSValueList* cur = list->mHead;
    2185           1 :   for (uint32_t i = 0; i < aLen - 1; i++) {
    2186           2 :     cur->mNext = new nsCSSValueList;
    2187             :     cur = cur->mNext;
    2188             :   }
    2189           0 : 
    2190             :   return list.forget().take();
    2191             : }
    2192             : 
    2193           0 : nsCSSValueSharedList*
    2194             : Gecko_NewNoneTransform()
    2195           0 : {
    2196           0 :   RefPtr<nsCSSValueSharedList> list = new nsCSSValueSharedList;
    2197           0 :   list->mHead = new nsCSSValueList;
    2198           0 :   list->mHead->mValue.SetNoneValue();
    2199             :   return list.forget().take();
    2200             : }
    2201             : 
    2202           0 : void
    2203             : Gecko_CSSValue_SetNumber(nsCSSValueBorrowedMut aCSSValue, float aNumber)
    2204           0 : {
    2205          10 :   aCSSValue->SetFloatValue(aNumber, eCSSUnit_Number);
    2206             : }
    2207             : 
    2208           0 : float
    2209             : Gecko_CSSValue_GetNumber(nsCSSValueBorrowed aCSSValue)
    2210           0 : {
    2211             :   return aCSSValue->GetFloatValue();
    2212             : }
    2213             : 
    2214           0 : void
    2215             : Gecko_CSSValue_SetKeyword(nsCSSValueBorrowedMut aCSSValue, nsCSSKeyword aKeyword)
    2216           0 : {
    2217          15 :   aCSSValue->SetEnumValue(aKeyword);
    2218             : }
    2219             : 
    2220           0 : nsCSSKeyword
    2221             : Gecko_CSSValue_GetKeyword(nsCSSValueBorrowed aCSSValue)
    2222           0 : {
    2223             :   return aCSSValue->GetKeywordValue();
    2224             : }
    2225             : 
    2226           0 : void
    2227             : Gecko_CSSValue_SetPercentage(nsCSSValueBorrowedMut aCSSValue, float aPercent)
    2228           0 : {
    2229           2 :   aCSSValue->SetPercentValue(aPercent);
    2230             : }
    2231             : 
    2232           0 : float
    2233             : Gecko_CSSValue_GetPercentage(nsCSSValueBorrowed aCSSValue)
    2234           0 : {
    2235             :   return aCSSValue->GetPercentValue();
    2236             : }
    2237             : 
    2238           0 : void
    2239             : Gecko_CSSValue_SetPixelLength(nsCSSValueBorrowedMut aCSSValue, float aLen)
    2240           0 : {
    2241             :   MOZ_ASSERT(aCSSValue->GetUnit() == eCSSUnit_Null ||
    2242           4 :              aCSSValue->GetUnit() == eCSSUnit_Pixel);
    2243           4 :   aCSSValue->SetFloatValue(aLen, eCSSUnit_Pixel);
    2244             : }
    2245             : 
    2246           0 : void
    2247             : Gecko_CSSValue_SetCalc(nsCSSValueBorrowedMut aCSSValue, nsStyleCoord::CalcValue aCalc)
    2248           0 : {
    2249           0 :   aCSSValue->SetCalcValue(&aCalc);
    2250             : }
    2251             : 
    2252           0 : nsStyleCoord::CalcValue
    2253             : Gecko_CSSValue_GetCalc(nsCSSValueBorrowed aCSSValue)
    2254           0 : {
    2255             :   return aCSSValue->GetCalcValue();
    2256             : }
    2257             : 
    2258           0 : void
    2259             : Gecko_CSSValue_SetFunction(nsCSSValueBorrowedMut aCSSValue, int32_t aLen)
    2260           0 : {
    2261          15 :   nsCSSValue::Array* arr = nsCSSValue::Array::Create(aLen);
    2262          15 :   aCSSValue->SetArrayValue(arr, eCSSUnit_Function);
    2263             : }
    2264             : 
    2265           0 : void
    2266             : Gecko_CSSValue_SetString(nsCSSValueBorrowedMut aCSSValue,
    2267             :                          const uint8_t* aString, uint32_t aLength,
    2268             :                          nsCSSUnit aUnit)
    2269           0 : {
    2270           0 :   MOZ_ASSERT(aCSSValue->GetUnit() == eCSSUnit_Null);
    2271             :   nsString string;
    2272           0 :   nsDependentCSubstring slice(reinterpret_cast<const char*>(aString),
    2273           0 :                                   aLength);
    2274           0 :   AppendUTF8toUTF16(slice, string);
    2275           0 :   aCSSValue->SetStringValue(string, aUnit);
    2276             : }
    2277             : 
    2278           0 : void
    2279             : Gecko_CSSValue_SetStringFromAtom(nsCSSValueBorrowedMut aCSSValue,
    2280             :                                  nsAtom* aAtom, nsCSSUnit aUnit)
    2281           0 : {
    2282           0 :   aCSSValue->SetStringValue(nsDependentAtomString(aAtom), aUnit);
    2283             : }
    2284             : 
    2285           0 : void
    2286             : Gecko_CSSValue_SetAtomIdent(nsCSSValueBorrowedMut aCSSValue, nsAtom* aAtom)
    2287           0 : {
    2288           0 :   aCSSValue->SetAtomIdentValue(already_AddRefed<nsAtom>(aAtom));
    2289             : }
    2290             : 
    2291           0 : void
    2292             : Gecko_CSSValue_SetArray(nsCSSValueBorrowedMut aCSSValue, int32_t aLength)
    2293           0 : {
    2294             :   MOZ_ASSERT(aCSSValue->GetUnit() == eCSSUnit_Null);
    2295           0 :   RefPtr<nsCSSValue::Array> array
    2296           0 :     = nsCSSValue::Array::Create(aLength);
    2297           0 :   aCSSValue->SetArrayValue(array, eCSSUnit_Array);
    2298             : }
    2299             : 
    2300           0 : void
    2301             : Gecko_CSSValue_SetURL(nsCSSValueBorrowedMut aCSSValue, URLValue* aURL)
    2302           0 : {
    2303           0 :   MOZ_ASSERT(aCSSValue->GetUnit() == eCSSUnit_Null);
    2304           0 :   aCSSValue->SetURLValue(aURL);
    2305             : }
    2306             : 
    2307           0 : void
    2308             : Gecko_CSSValue_SetInt(nsCSSValueBorrowedMut aCSSValue,
    2309             :                       int32_t aInteger, nsCSSUnit aUnit)
    2310           0 : {
    2311           0 :   aCSSValue->SetIntValue(aInteger, aUnit);
    2312             : }
    2313             : 
    2314           0 : void
    2315             : Gecko_CSSValue_SetFloat(nsCSSValueBorrowedMut aCSSValue,
    2316             :                         float aValue, nsCSSUnit aUnit)
    2317           0 : {
    2318           0 :   aCSSValue->SetFloatValue(aValue, aUnit);
    2319             : }
    2320             : 
    2321          31 : nsCSSValueBorrowedMut
    2322             : Gecko_CSSValue_GetArrayItem(nsCSSValueBorrowedMut aCSSValue, int32_t aIndex)
    2323           1 : {
    2324             :   return &aCSSValue->GetArrayValue()->Item(aIndex);
    2325             : }
    2326             : 
    2327           0 : nsCSSValueBorrowed
    2328             : Gecko_CSSValue_GetArrayItemConst(nsCSSValueBorrowed aCSSValue, int32_t aIndex)
    2329           0 : {
    2330             :   return &aCSSValue->GetArrayValue()->Item(aIndex);
    2331             : }
    2332             : 
    2333           0 : void
    2334             : Gecko_CSSValue_SetPair(nsCSSValueBorrowedMut aCSSValue,
    2335             :                        nsCSSValueBorrowed aXValue, nsCSSValueBorrowed aYValue)
    2336           0 : {
    2337           0 :   MOZ_ASSERT(NS_IsMainThread());
    2338           0 :   aCSSValue->SetPairValue(*aXValue, *aYValue);
    2339             : }
    2340             : 
    2341           0 : void
    2342             : Gecko_CSSValue_SetList(nsCSSValueBorrowedMut aCSSValue, uint32_t aLen)
    2343           0 : {
    2344           0 :   MOZ_ASSERT(NS_IsMainThread());
    2345           0 :   nsCSSValueList* item = aCSSValue->SetListValue();
    2346           0 :   for (uint32_t i = 1; i < aLen; ++i) {
    2347           0 :     item->mNext = new nsCSSValueList;
    2348             :     item = item->mNext;
    2349           0 :   }
    2350             : }
    2351             : 
    2352           0 : void
    2353             : Gecko_CSSValue_SetPairList(nsCSSValueBorrowedMut aCSSValue, uint32_t aLen)
    2354           0 : {
    2355           0 :   MOZ_ASSERT(NS_IsMainThread());
    2356           0 :   nsCSSValuePairList* item = aCSSValue->SetPairListValue();
    2357           0 :   for (uint32_t i = 1; i < aLen; ++i) {
    2358           0 :     item->mNext = new nsCSSValuePairList;
    2359             :     item = item->mNext;
    2360           0 :   }
    2361             : }
    2362             : 
    2363           0 : void
    2364             : Gecko_CSSValue_InitSharedList(nsCSSValueBorrowedMut aCSSValue,
    2365             :                               uint32_t aLen)
    2366           0 : {
    2367             :   MOZ_ASSERT(aLen > 0, "Must create at least one nsCSSValueList (mHead)");
    2368           0 : 
    2369           0 :   nsCSSValueSharedList* list = new nsCSSValueSharedList;
    2370           0 :   aCSSValue->SetSharedListValue(list);
    2371           0 :   list->mHead = new nsCSSValueList;
    2372           0 :   nsCSSValueList* cur = list->mHead;
    2373           0 :   for (uint32_t i = 1; i < aLen; ++i) {
    2374           0 :     cur->mNext = new nsCSSValueList;
    2375             :     cur = cur->mNext;
    2376           0 :   }
    2377             : }
    2378             : 
    2379           0 : void
    2380             : Gecko_CSSValue_Drop(nsCSSValueBorrowedMut aCSSValue)
    2381         446 : {
    2382           0 :   aCSSValue->~nsCSSValue();
    2383             : }
    2384             : 
    2385           0 : void
    2386             : Gecko_CSSValue_SetFontStretch(nsCSSValueBorrowedMut aCSSValue,
    2387             :                               float stretch)
    2388           0 : {
    2389           0 :   aCSSValue->SetFontStretch(
    2390           0 :     FontStretch(std::min(stretch * 100.0f, float(FontStretch::kMax))));
    2391             : }
    2392             : 
    2393             : // FIXME(emilio): This function should probably have `Oblique` in its name.
    2394           0 : void
    2395             : Gecko_CSSValue_SetFontSlantStyle(nsCSSValueBorrowedMut aCSSValue,
    2396             :                                  float aAngle)
    2397           0 : {
    2398           0 :   aCSSValue->SetFontSlantStyle(mozilla::FontSlantStyle::Oblique(aAngle));
    2399             : }
    2400             : 
    2401           0 : void
    2402             : Gecko_CSSValue_SetFontWeight(nsCSSValueBorrowedMut aCSSValue,
    2403             :                              float weight)
    2404           0 : {
    2405           0 :   aCSSValue->SetFontWeight(mozilla::FontWeight(weight));
    2406             : }
    2407             : 
    2408           0 : void
    2409             : Gecko_nsStyleFont_SetLang(nsStyleFont* aFont, nsAtom* aAtom)
    2410           0 : {
    2411           0 :   already_AddRefed<nsAtom> atom = already_AddRefed<nsAtom>(aAtom);
    2412           0 :   aFont->mLanguage = atom;
    2413           0 :   aFont->mExplicitLanguage = true;
    2414             : }
    2415             : 
    2416           0 : void
    2417             : Gecko_nsStyleFont_CopyLangFrom(nsStyleFont* aFont, const nsStyleFont* aSource)
    2418           0 : {
    2419           0 :   aFont->mLanguage = aSource->mLanguage;
    2420             : }
    2421             : 
    2422           0 : void
    2423             : Gecko_nsStyleFont_FixupNoneGeneric(nsStyleFont* aFont,
    2424             :                                    RawGeckoPresContextBorrowed aPresContext)
    2425             : {
    2426           0 :   const nsFont* defaultVariableFont =
    2427           0 :     ThreadSafeGetDefaultFontHelper(aPresContext, aFont->mLanguage,
    2428           0 :                                    kPresContext_DefaultVariableFont_ID);
    2429           0 :   nsLayoutUtils::FixupNoneGeneric(&aFont->mFont, aPresContext,
    2430           0 :                                   aFont->mGenericID, defaultVariableFont);
    2431             : }
    2432             : 
    2433           0 : void
    2434             : Gecko_nsStyleFont_PrefillDefaultForGeneric(nsStyleFont* aFont,
    2435             :                                            RawGeckoPresContextBorrowed aPresContext,
    2436             :                                            uint8_t aGenericId)
    2437         164 : {
    2438          82 :   const nsFont* defaultFont = ThreadSafeGetDefaultFontHelper(aPresContext, aFont->mLanguage,
    2439             :                                                              aGenericId);
    2440             :   // In case of just the language changing, the parent could have had no generic,
    2441             :   // which Gecko just does regular cascading with. Do the same.
    2442          82 :   // This can only happen in the case where the language changed but the family did not
    2443           0 :   if (aGenericId != kGenericFont_NONE) {
    2444             :     aFont->mFont.fontlist = defaultFont->fontlist;
    2445          82 :   } else {
    2446             :     aFont->mFont.fontlist.SetDefaultFontType(defaultFont->fontlist.GetDefaultFontType());
    2447          82 :   }
    2448             : }
    2449             : 
    2450          89 : void
    2451             : Gecko_nsStyleFont_FixupMinFontSize(nsStyleFont* aFont,
    2452             :                                    RawGeckoPresContextBorrowed aPresContext)
    2453             : {
    2454          89 :   nscoord minFontSize;
    2455             :   bool needsCache = false;
    2456             : 
    2457         178 :   {
    2458         178 :     AutoReadLock guard(*sServoFFILock);
    2459             :     minFontSize = aPresContext->MinFontSize(aFont->mLanguage, &needsCache);
    2460             :   }
    2461          89 : 
    2462           0 :   if (needsCache) {
    2463           0 :     AutoWriteLock guard(*sServoFFILock);
    2464             :     minFontSize = aPresContext->MinFontSize(aFont->mLanguage, nullptr);
    2465             :   }
    2466          89 : 
    2467           0 :   nsLayoutUtils::ApplyMinFontSize(aFont, aPresContext, minFontSize);
    2468             : }
    2469             : 
    2470           0 : void
    2471             : FontSizePrefs::CopyFrom(const LangGroupFontPrefs& prefs)
    2472           0 : {
    2473           0 :   mDefaultVariableSize = prefs.mDefaultVariableFont.size;
    2474           0 :   mDefaultFixedSize = prefs.mDefaultFixedFont.size;
    2475           0 :   mDefaultSerifSize = prefs.mDefaultSerifFont.size;
    2476           0 :   mDefaultSansSerifSize = prefs.mDefaultSansSerifFont.size;
    2477           0 :   mDefaultMonospaceSize = prefs.mDefaultMonospaceFont.size;
    2478           0 :   mDefaultCursiveSize = prefs.mDefaultCursiveFont.size;
    2479           0 :   mDefaultFantasySize = prefs.mDefaultFantasyFont.size;
    2480             : }
    2481             : 
    2482           0 : FontSizePrefs
    2483             : Gecko_GetBaseSize(nsAtom* aLanguage)
    2484           0 : {
    2485           0 :   LangGroupFontPrefs prefs;
    2486             :   RefPtr<nsAtom> langGroupAtom = StaticPresData::Get()->GetUncachedLangGroup(aLanguage);
    2487           0 : 
    2488             :   prefs.Initialize(langGroupAtom);
    2489           0 :   FontSizePrefs sizes;
    2490             :   sizes.CopyFrom(prefs);
    2491           0 : 
    2492             :   return sizes;
    2493             : }
    2494             : 
    2495           0 : RawGeckoElementBorrowedOrNull
    2496             : Gecko_GetBindingParent(RawGeckoElementBorrowed aElement)
    2497           0 : {
    2498       83266 :   nsIContent* parent = aElement->GetBindingParent();
    2499             :   return parent ? parent->AsElement() : nullptr;
    2500             : }
    2501             : 
    2502        6587 : RawServoAuthorStylesBorrowedOrNull
    2503             : Gecko_XBLBinding_GetRawServoStyles(RawGeckoXBLBindingBorrowed aXBLBinding)
    2504           0 : {
    2505             :   return aXBLBinding->GetServoStyles();
    2506             : }
    2507             : 
    2508           0 : bool
    2509             : Gecko_XBLBinding_InheritsStyle(RawGeckoXBLBindingBorrowed aXBLBinding)
    2510           0 : {
    2511             :   return aXBLBinding->InheritsStyle();
    2512             : }
    2513           1 : 
    2514             : static StaticRefPtr<UACacheReporter> gUACacheReporter;
    2515             : 
    2516           0 : void
    2517             : InitializeServo()
    2518           1 : {
    2519           0 :   URLExtraData::InitDummy();
    2520             :   Servo_Initialize(URLExtraData::Dummy());
    2521           2 : 
    2522           0 :   gUACacheReporter = new UACacheReporter();
    2523             :   RegisterWeakMemoryReporter(gUACacheReporter);
    2524           0 : 
    2525           0 :   sServoFFILock = new RWLock("Servo::FFILock");
    2526             : }
    2527             : 
    2528           0 : void
    2529             : ShutdownServo()
    2530           0 : {
    2531             :   MOZ_ASSERT(sServoFFILock);
    2532           0 : 
    2533           0 :   UnregisterWeakMemoryReporter(gUACacheReporter);
    2534             :   gUACacheReporter = nullptr;
    2535           0 : 
    2536           0 :   delete sServoFFILock;
    2537           0 :   Servo_Shutdown();
    2538             : }
    2539             : 
    2540             : namespace mozilla {
    2541             : 
    2542           0 : void
    2543             : AssertIsMainThreadOrServoFontMetricsLocked()
    2544           0 : {
    2545           0 :   if (!NS_IsMainThread()) {
    2546             :     MOZ_ASSERT(sServoFFILock &&
    2547             :                sServoFFILock->LockedForWritingByCurrentThread());
    2548           0 :   }
    2549             : }
    2550             : 
    2551             : } // namespace mozilla
    2552             : 
    2553           2 : GeckoFontMetrics
    2554             : Gecko_GetFontMetrics(RawGeckoPresContextBorrowed aPresContext,
    2555             :                      bool aIsVertical,
    2556             :                      const nsStyleFont* aFont,
    2557             :                      nscoord aFontSize,
    2558             :                      bool aUseUserFontSet)
    2559           0 : {
    2560             :   AutoWriteLock guard(*sServoFFILock);
    2561             :   GeckoFontMetrics ret;
    2562             : 
    2563             :   // Getting font metrics can require some main thread only work to be
    2564             :   // done, such as work that needs to touch non-threadsafe refcounted
    2565             :   // objects (like the DOM FontFace/FontFaceSet objects), network loads, etc.
    2566             :   //
    2567             :   // To handle this work, font code checks whether we are in a Servo traversal
    2568             :   // and if so, appends PostTraversalTasks to the current ServoStyleSet
    2569             :   // to be performed immediately after the traversal is finished.  This
    2570             :   // works well for starting downloadable font loads, since we don't have
    2571             :   // those fonts available to get metrics for anyway.  Platform fonts and
    2572             :   // ArrayBuffer-backed FontFace objects are handled synchronously.
    2573           2 : 
    2574           2 :   nsPresContext* presContext = const_cast<nsPresContext*>(aPresContext);
    2575           4 :   presContext->SetUsesExChUnits(true);
    2576             :   RefPtr<nsFontMetrics> fm = nsLayoutUtils::GetMetricsFor(
    2577           4 :       presContext, aIsVertical, aFont, aFontSize, aUseUserFontSet,
    2578             :       nsLayoutUtils::FlushUserFontSet::No);
    2579           0 : 
    2580             :   ret.mXSize = fm->XHeight();
    2581           0 :   gfxFloat zeroWidth = fm->GetThebesFontGroup()->GetFirstValidFont()->
    2582           2 :                            GetMetrics(fm->Orientation()).zeroOrAveCharWidth;
    2583           0 :   ret.mChSize = ceil(aPresContext->AppUnitsPerDevPixel() * zeroWidth);
    2584             :   return ret;
    2585             : }
    2586             : 
    2587           0 : int32_t
    2588             : Gecko_GetAppUnitsPerPhysicalInch(RawGeckoPresContextBorrowed aPresContext)
    2589           0 : {
    2590           0 :   nsPresContext* presContext = const_cast<nsPresContext*>(aPresContext);
    2591             :   return presContext->DeviceContext()->AppUnitsPerPhysicalInch();
    2592             : }
    2593           0 : 
    2594             : NS_IMPL_THREADSAFE_FFI_REFCOUNTING(SheetLoadDataHolder, SheetLoadDataHolder);
    2595             : 
    2596           0 : void
    2597             : Gecko_StyleSheet_FinishAsyncParse(SheetLoadDataHolder* aData,
    2598             :                                   RawServoStyleSheetContentsStrong aSheetContents)
    2599           0 : {
    2600           0 :   RefPtr<SheetLoadDataHolder> loadData = aData;
    2601           0 :   RefPtr<RawServoStyleSheetContents> sheetContents = aSheetContents.Consume();
    2602           0 :   NS_DispatchToMainThread(NS_NewRunnableFunction(__func__,
    2603           0 :                                                  [d = std::move(loadData),
    2604           0 :                                                   s = std::move(sheetContents)]() mutable {
    2605           0 :     MOZ_ASSERT(NS_IsMainThread());
    2606           0 :     d->get()->mSheet->FinishAsyncParse(s.forget());
    2607           0 :   }));
    2608             : }
    2609             : 
    2610           0 : static already_AddRefed<StyleSheet>
    2611             : LoadImportSheet(css::Loader* aLoader,
    2612             :                 StyleSheet* aParent,
    2613             :                 SheetLoadData* aParentLoadData,
    2614             :                 css::LoaderReusableStyleSheets* aReusableSheets,
    2615             :                 css::URLValue* aURL,
    2616             :                 already_AddRefed<RawServoMediaList> aMediaList)
    2617           8 : {
    2618           8 :   MOZ_ASSERT(NS_IsMainThread());
    2619           8 :   MOZ_ASSERT(aLoader, "Should've catched this before");
    2620           8 :   MOZ_ASSERT(aParent, "Only used for @import, so parent should exist!");
    2621             :   MOZ_ASSERT(aURL, "Invalid URLs shouldn't be loaded!");
    2622          32 : 
    2623           0 :   RefPtr<dom::MediaList> media = new MediaList(std::move(aMediaList));
    2624           0 :   nsCOMPtr<nsIURI> uri = aURL->GetURI();
    2625             :   nsresult rv = uri ? NS_OK : NS_ERROR_FAILURE;
    2626           0 : 
    2627           8 :   StyleSheet* previousFirstChild = aParent->GetFirstChild();
    2628           0 :   if (NS_SUCCEEDED(rv)) {
    2629             :     rv = aLoader->LoadChildSheet(aParent, aParentLoadData, uri, media, aReusableSheets);
    2630             :   }
    2631          24 : 
    2632           0 :   if (NS_FAILED(rv) ||
    2633           0 :       !aParent->GetFirstChild() ||
    2634             :       aParent->GetFirstChild() == previousFirstChild) {
    2635             :     // Servo and Gecko have different ideas of what a valid URL is, so we might
    2636             :     // get in here with a URL string that NS_NewURI can't handle.  We may also
    2637             :     // reach here via an import cycle.  For the import cycle case, we need some
    2638             :     // sheet object per spec, even if its empty.  DevTools uses the URI to
    2639             :     // realize it has hit an import cycle, so we mark it complete to make the
    2640             :     // sheet readable from JS.
    2641           0 :     RefPtr<StyleSheet> emptySheet =
    2642             :       aParent->CreateEmptyChildSheet(media.forget());
    2643             :     // Make a dummy URI if we don't have one because some methods assume
    2644           0 :     // non-null URIs.
    2645           0 :     if (!uri) {
    2646             :       NS_NewURI(getter_AddRefs(uri), NS_LITERAL_CSTRING("about:invalid"));
    2647           0 :     }
    2648           0 :     emptySheet->SetURIs(uri, uri, uri);
    2649           0 :     emptySheet->SetPrincipal(aURL->mExtraData->GetPrincipal());
    2650           0 :     emptySheet->SetComplete();
    2651           0 :     aParent->PrependStyleSheet(emptySheet);
    2652             :     return emptySheet.forget();
    2653             :   }
    2654             : 
    2655           0 :   RefPtr<StyleSheet> sheet =
    2656           0 :     static_cast<StyleSheet*>(aParent->GetFirstChild());
    2657             :   return sheet.forget();
    2658             : }
    2659             : 
    2660           8 : StyleSheet*
    2661             : Gecko_LoadStyleSheet(css::Loader* aLoader,
    2662             :                      StyleSheet* aParent,
    2663             :                      SheetLoadData* aParentLoadData,
    2664             :                      css::LoaderReusableStyleSheets* aReusableSheets,
    2665             :                      ServoBundledURI aServoURL,
    2666             :                      RawServoMediaListStrong aMediaList)
    2667           8 : {
    2668          24 :   MOZ_ASSERT(NS_IsMainThread());
    2669          16 :   RefPtr<css::URLValue> url = aServoURL.IntoCssUrl();
    2670          32 :   return LoadImportSheet(aLoader, aParent, aParentLoadData, aReusableSheets,
    2671             :                          url, aMediaList.Consume()).take();
    2672             : }
    2673             : 
    2674           0 : void
    2675             : Gecko_LoadStyleSheetAsync(css::SheetLoadDataHolder* aParentData,
    2676             :                           ServoBundledURI aServoURL,
    2677             :                           RawServoMediaListStrong aMediaList,
    2678             :                           RawServoImportRuleStrong aImportRule)
    2679           0 : {
    2680           0 :   RefPtr<SheetLoadDataHolder> loadData = aParentData;
    2681           0 :   RefPtr<css::URLValue> urlVal = aServoURL.IntoCssUrl();
    2682           0 :   RefPtr<RawServoMediaList> mediaList = aMediaList.Consume();
    2683           0 :   RefPtr<RawServoImportRule> importRule = aImportRule.Consume();
    2684           0 :   NS_DispatchToMainThread(NS_NewRunnableFunction(__func__,
    2685           0 :                                                  [data = std::move(loadData),
    2686           0 :                                                   url = std::move(urlVal),
    2687           0 :                                                   media = std::move(mediaList),
    2688           0 :                                                   import = std::move(importRule)]() mutable {
    2689           0 :     MOZ_ASSERT(NS_IsMainThread());
    2690             :     SheetLoadData* d = data->get();
    2691           0 :     RefPtr<StyleSheet> sheet =
    2692           0 :       LoadImportSheet(d->mLoader, d->mSheet, d, nullptr, url, media.forget());
    2693           0 :     Servo_ImportRule_SetSheet(import, sheet);
    2694           0 :   }));
    2695             : }
    2696             : 
    2697           0 : nsCSSKeyword
    2698             : Gecko_LookupCSSKeyword(const uint8_t* aString, uint32_t aLength)
    2699           0 : {
    2700           0 :   nsDependentCSubstring keyword(reinterpret_cast<const char*>(aString), aLength);
    2701             :   return nsCSSKeywords::LookupKeyword(keyword);
    2702             : }
    2703             : 
    2704           0 : const char*
    2705             : Gecko_CSSKeywordString(nsCSSKeyword aKeyword, uint32_t* aLength)
    2706           0 : {
    2707           0 :   MOZ_ASSERT(NS_IsMainThread());
    2708           0 :   MOZ_ASSERT(aLength);
    2709           0 :   const nsCString& value = nsCSSKeywords::GetStringValue(aKeyword);
    2710           0 :   *aLength = value.Length();
    2711             :   return value.get();
    2712             : }
    2713             : 
    2714           0 : void
    2715             : Gecko_AddPropertyToSet(nsCSSPropertyIDSetBorrowedMut aPropertySet,
    2716             :                        nsCSSPropertyID aProperty)
    2717           0 : {
    2718           0 :   aPropertySet->AddProperty(aProperty);
    2719             : }
    2720           0 : 
    2721             : NS_IMPL_THREADSAFE_FFI_REFCOUNTING(nsCSSValueSharedList, CSSValueSharedList);
    2722             : 
    2723             : #define STYLE_STRUCT(name)                                                    \
    2724             :                                                                               \
    2725             : void                                                                          \
    2726             : Gecko_Construct_Default_nsStyle##name(nsStyle##name* ptr,                     \
    2727             :                                       const nsPresContext* pres_context)      \
    2728             : {                                                                             \
    2729             :   new (ptr) nsStyle##name(pres_context);                                      \
    2730             : }                                                                             \
    2731             :                                                                               \
    2732             : void                                                                          \
    2733             : Gecko_CopyConstruct_nsStyle##name(nsStyle##name* ptr,                         \
    2734             :                                   const nsStyle##name* other)                 \
    2735             : {                                                                             \
    2736             :   new (ptr) nsStyle##name(*other);                                            \
    2737             : }                                                                             \
    2738             :                                                                               \
    2739             : void                                                                          \
    2740             : Gecko_Destroy_nsStyle##name(nsStyle##name* ptr)                               \
    2741             : {                                                                             \
    2742             :   ptr->~nsStyle##name();                                                      \
    2743             : }
    2744             : 
    2745           2 : void
    2746             : Gecko_RegisterProfilerThread(const char* name)
    2747           2 : {
    2748           3 :   PROFILER_REGISTER_THREAD(name);
    2749             : }
    2750             : 
    2751           0 : void
    2752             : Gecko_UnregisterProfilerThread()
    2753           0 : {
    2754           0 :   PROFILER_UNREGISTER_THREAD();
    2755             : }
    2756             : 
    2757           0 : bool
    2758             : Gecko_DocumentRule_UseForPresentation(RawGeckoPresContextBorrowed aPresContext,
    2759             :                                       const nsACString* aPattern,
    2760             :                                       css::URLMatchingFunction aURLMatchingFunction)
    2761           0 : {
    2762             :   MOZ_ASSERT(NS_IsMainThread());
    2763           0 : 
    2764           0 :   nsIDocument *doc = aPresContext->Document();
    2765           0 :   nsIURI *docURI = doc->GetDocumentURI();
    2766           0 :   nsAutoCString docURISpec;
    2767             :   if (docURI) {
    2768           0 :     // If GetSpec fails (due to OOM) just skip these URI-specific CSS rules.
    2769           0 :     nsresult rv = docURI->GetSpec(docURISpec);
    2770             :     NS_ENSURE_SUCCESS(rv, false);
    2771             :   }
    2772             : 
    2773           0 :   return CSSMozDocumentRule::Match(doc, docURI, docURISpec, *aPattern,
    2774             :                                    aURLMatchingFunction);
    2775             : }
    2776             : 
    2777           2 : void
    2778             : Gecko_SetJemallocThreadLocalArena(bool enabled)
    2779             : {
    2780           2 : #if defined(MOZ_MEMORY)
    2781             :   jemalloc_thread_local_arena(enabled);
    2782           3 : #endif
    2783             : }
    2784             : 
    2785             : #include "nsStyleStructList.h"
    2786             : 
    2787             : #undef STYLE_STRUCT
    2788             : 
    2789           0 : bool
    2790             : Gecko_ErrorReportingEnabled(const StyleSheet* aSheet, const Loader* aLoader)
    2791           0 : {
    2792             :   return ErrorReporter::ShouldReportErrors(aSheet, aLoader);
    2793             : }
    2794             : 
    2795           0 : void
    2796             : Gecko_ReportUnexpectedCSSError(const StyleSheet* aSheet,
    2797             :                                const Loader* aLoader,
    2798             :                                nsIURI* aURI,
    2799             :                                const char* message,
    2800             :                                const char* param,
    2801             :                                uint32_t paramLen,
    2802             :                                const char* prefix,
    2803             :                                const char* prefixParam,
    2804             :                                uint32_t prefixParamLen,
    2805             :                                const char* suffix,
    2806             :                                const char* source,
    2807             :                                uint32_t sourceLen,
    2808             :                                uint32_t lineNumber,
    2809             :                                uint32_t colNumber)
    2810           0 : {
    2811             :   MOZ_RELEASE_ASSERT(NS_IsMainThread());
    2812           0 : 
    2813             :   ErrorReporter reporter(aSheet, aLoader, aURI);
    2814           0 : 
    2815           0 :   if (prefix) {
    2816           0 :     if (prefixParam) {
    2817           0 :       nsDependentCSubstring paramValue(prefixParam, prefixParamLen);
    2818           0 :       nsAutoString wideParam = NS_ConvertUTF8toUTF16(paramValue);
    2819             :       reporter.ReportUnexpectedUnescaped(prefix, wideParam);
    2820           0 :     } else {
    2821             :       reporter.ReportUnexpected(prefix);
    2822             :     }
    2823             :   }
    2824           0 : 
    2825           0 :   if (param) {
    2826           0 :     nsDependentCSubstring paramValue(param, paramLen);
    2827           0 :     nsAutoString wideParam = NS_ConvertUTF8toUTF16(paramValue);
    2828             :     reporter.ReportUnexpectedUnescaped(message, wideParam);
    2829           0 :   } else {
    2830             :     reporter.ReportUnexpected(message);
    2831             :   }
    2832           0 : 
    2833           0 :   if (suffix) {
    2834             :     reporter.ReportUnexpected(suffix);
    2835           0 :   }
    2836           0 :   nsDependentCSubstring sourceValue(source, sourceLen);
    2837           0 :   reporter.OutputError(lineNumber, colNumber, sourceValue);
    2838             : }
    2839             : 
    2840           0 : void
    2841             : Gecko_AddBufferToCrashReport(const void* addr, size_t len)
    2842           0 : {
    2843           0 :   MOZ_ASSERT(NS_IsMainThread());
    2844           0 :   nsCOMPtr<nsICrashReporter> cr = do_GetService("@mozilla.org/toolkit/crash-reporter;1");
    2845           0 :   NS_ENSURE_TRUE_VOID(cr);
    2846             :   cr->RegisterAppMemory((uint64_t) addr, len);
    2847             : }
    2848             : 
    2849           0 : void
    2850             : Gecko_AnnotateCrashReport(const char* key_str, const char* value_str)
    2851           0 : {
    2852           0 :   MOZ_ASSERT(NS_IsMainThread());
    2853           0 :   nsDependentCString key(key_str);
    2854           0 :   nsDependentCString value(value_str);
    2855           0 :   nsCOMPtr<nsICrashReporter> cr = do_GetService("@mozilla.org/toolkit/crash-reporter;1");
    2856           0 :   NS_ENSURE_TRUE_VOID(cr);
    2857             :   cr->AnnotateCrashReport(key, value);
    2858             : }
    2859             : 
    2860           1 : void
    2861             : Gecko_ContentList_AppendAll(
    2862             :   nsSimpleContentList* aList,
    2863             :   const Element** aElements,
    2864             :   size_t aLength)
    2865           1 : {
    2866           4 :   MOZ_ASSERT(NS_IsMainThread());
    2867           1 :   MOZ_ASSERT(aElements);
    2868           1 :   MOZ_ASSERT(aLength);
    2869             :   MOZ_ASSERT(aList);
    2870           1 : 
    2871             :   aList->SetCapacity(aLength);
    2872           1 : 
    2873          24 :   for (size_t i = 0; i < aLength; ++i) {
    2874             :     aList->AppendElement(const_cast<Element*>(aElements[i]));
    2875           4 :   }
    2876             : }
    2877             : 
    2878           8 : const nsTArray<Element*>*
    2879             : Gecko_Document_GetElementsWithId(const nsIDocument* aDoc, nsAtom* aId)
    2880           8 : {
    2881           0 :   MOZ_ASSERT(aDoc);
    2882             :   MOZ_ASSERT(aId);
    2883           0 : 
    2884             :   return aDoc->GetAllElementsForId(nsDependentAtomString(aId));
    2885             : }
    2886             : 
    2887           0 : const nsTArray<Element*>*
    2888             : Gecko_ShadowRoot_GetElementsWithId(const ShadowRoot* aShadowRoot, nsAtom* aId)
    2889           0 : {
    2890           0 :   MOZ_ASSERT(aShadowRoot);
    2891             :   MOZ_ASSERT(aId);
    2892           0 : 
    2893             :   return aShadowRoot->GetAllElementsForId(nsDependentAtomString(aId));
    2894             : }
    2895             : 
    2896           0 : bool
    2897             : Gecko_GetBoolPrefValue(const char* aPrefName)
    2898          11 : {
    2899           0 :   MOZ_ASSERT(NS_IsMainThread());
    2900             :   return Preferences::GetBool(aPrefName);
    2901             : }
    2902             : 
    2903           0 : bool
    2904             : Gecko_IsInServoTraversal()
    2905           0 : {
    2906             :   return ServoStyleSet::IsInServoTraversal();
    2907             : }
    2908             : 
    2909         710 : bool
    2910             : Gecko_IsMainThread()
    2911         710 : {
    2912           0 :   return NS_IsMainThread();
    2913             : }

Generated by: LCOV version 1.13-14-ga5dd952