LCOV - code coverage report
Current view: top level - layout/style - ServoBindings.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 3 1112 0.3 %
Date: 2017-07-14 16:53:18 Functions: 1 311 0.3 %
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 "nsAnimationManager.h"
      14             : #include "nsAttrValueInlines.h"
      15             : #include "nsCSSCounterStyleRule.h"
      16             : #include "nsCSSFontFaceRule.h"
      17             : #include "nsCSSFrameConstructor.h"
      18             : #include "nsCSSProps.h"
      19             : #include "nsCSSParser.h"
      20             : #include "nsCSSPseudoElements.h"
      21             : #include "nsCSSRuleProcessor.h"
      22             : #include "nsCSSRules.h"
      23             : #include "nsContentUtils.h"
      24             : #include "nsDOMTokenList.h"
      25             : #include "nsDeviceContext.h"
      26             : #include "nsIContentInlines.h"
      27             : #include "nsIDOMNode.h"
      28             : #include "nsIDocumentInlines.h"
      29             : #include "nsIFrame.h"
      30             : #include "nsINode.h"
      31             : #include "nsIPresShell.h"
      32             : #include "nsIPresShellInlines.h"
      33             : #include "nsIPrincipal.h"
      34             : #include "nsIURI.h"
      35             : #include "nsFontMetrics.h"
      36             : #include "nsHTMLStyleSheet.h"
      37             : #include "nsMappedAttributes.h"
      38             : #include "nsMediaFeatures.h"
      39             : #include "nsNameSpaceManager.h"
      40             : #include "nsNetUtil.h"
      41             : #include "nsRuleNode.h"
      42             : #include "nsString.h"
      43             : #include "nsStyleStruct.h"
      44             : #include "nsStyleUtil.h"
      45             : #include "nsSVGElement.h"
      46             : #include "nsTArray.h"
      47             : #include "nsTransitionManager.h"
      48             : 
      49             : #include "mozilla/DeclarationBlockInlines.h"
      50             : #include "mozilla/EffectCompositor.h"
      51             : #include "mozilla/EffectSet.h"
      52             : #include "mozilla/EventStates.h"
      53             : #include "mozilla/GeckoStyleContext.h"
      54             : #include "mozilla/Keyframe.h"
      55             : #include "mozilla/Mutex.h"
      56             : #include "mozilla/Preferences.h"
      57             : #include "mozilla/ServoElementSnapshot.h"
      58             : #include "mozilla/ServoRestyleManager.h"
      59             : #include "mozilla/StyleAnimationValue.h"
      60             : #include "mozilla/SystemGroup.h"
      61             : #include "mozilla/ServoMediaList.h"
      62             : #include "mozilla/RWLock.h"
      63             : #include "mozilla/dom/Element.h"
      64             : #include "mozilla/dom/ElementInlines.h"
      65             : #include "mozilla/dom/HTMLTableCellElement.h"
      66             : #include "mozilla/dom/HTMLBodyElement.h"
      67             : #include "mozilla/LookAndFeel.h"
      68             : #include "mozilla/URLExtraData.h"
      69             : 
      70             : #if defined(MOZ_MEMORY)
      71             : # include "mozmemory.h"
      72             : #endif
      73             : 
      74             : using namespace mozilla;
      75             : using namespace mozilla::css;
      76             : using namespace mozilla::dom;
      77             : 
      78             : #define SERVO_ARC_TYPE(name_, type_) \
      79             :   already_AddRefed<type_>            \
      80             :   type_##Strong::Consume() {         \
      81             :     RefPtr<type_> result;            \
      82             :     result.swap(mPtr);               \
      83             :     return result.forget();          \
      84             :   }
      85             : #include "mozilla/ServoArcTypeList.h"
      86             : #undef SERVO_ARC_TYPE
      87             : 
      88             : 
      89             : static Mutex* sServoFontMetricsLock = nullptr;
      90             : static RWLock* sServoLangFontPrefsLock = nullptr;
      91             : 
      92             : static bool sFramesTimingFunctionEnabled;
      93             : 
      94             : static
      95             : const nsFont*
      96           0 : ThreadSafeGetDefaultFontHelper(const nsPresContext* aPresContext,
      97             :                                nsIAtom* aLanguage, uint8_t aGenericId)
      98             : {
      99           0 :   bool needsCache = false;
     100             :   const nsFont* retval;
     101             : 
     102             :   {
     103           0 :     AutoReadLock guard(*sServoLangFontPrefsLock);
     104           0 :     retval = aPresContext->GetDefaultFont(aGenericId, aLanguage, &needsCache);
     105             :   }
     106           0 :   if (!needsCache) {
     107           0 :     return retval;
     108             :   }
     109             :   {
     110           0 :     AutoWriteLock guard(*sServoLangFontPrefsLock);
     111           0 :   retval = aPresContext->GetDefaultFont(aGenericId, aLanguage, nullptr);
     112             :   }
     113           0 :   return retval;
     114             : }
     115             : 
     116             : void
     117          12 : AssertIsMainThreadOrServoLangFontPrefsCacheLocked()
     118             : {
     119          12 :   MOZ_ASSERT(NS_IsMainThread() || sServoLangFontPrefsLock->LockedForWritingByCurrentThread());
     120          12 : }
     121             : 
     122             : uint32_t
     123           0 : Gecko_ChildrenCount(RawGeckoNodeBorrowed aNode)
     124             : {
     125           0 :   return aNode->GetChildCount();
     126             : }
     127             : 
     128             : bool
     129           0 : Gecko_NodeIsElement(RawGeckoNodeBorrowed aNode)
     130             : {
     131           0 :   return aNode->IsElement();
     132             : }
     133             : 
     134             : bool
     135           0 : Gecko_IsInDocument(RawGeckoNodeBorrowed aNode)
     136             : {
     137           0 :   return aNode->IsInComposedDoc();
     138             : }
     139             : 
     140             : #ifdef MOZ_DEBUG_RUST
     141             : bool
     142           0 : Gecko_FlattenedTreeParentIsParent(RawGeckoNodeBorrowed aNode)
     143             : {
     144             :   // Servo calls this in debug builds to verify the result of its own
     145             :   // flattened_tree_parent_is_parent() function.
     146           0 :   return FlattenedTreeParentIsParent<nsIContent::eForStyle>(aNode);
     147             : }
     148             : #endif
     149             : 
     150             : /*
     151             :  * Does this child count as significant for selector matching?
     152             :  *
     153             :  * See nsStyleUtil::IsSignificantChild for details.
     154             :  */
     155             : bool
     156           0 : Gecko_IsSignificantChild(RawGeckoNodeBorrowed aNode, bool aTextIsSignificant,
     157             :                          bool aWhitespaceIsSignificant)
     158             : {
     159           0 :   return nsStyleUtil::ThreadSafeIsSignificantChild(aNode->AsContent(),
     160             :                                                    aTextIsSignificant,
     161           0 :                                                    aWhitespaceIsSignificant);
     162             : }
     163             : 
     164             : RawGeckoNodeBorrowedOrNull
     165           0 : Gecko_GetLastChild(RawGeckoNodeBorrowed aNode)
     166             : {
     167           0 :   return aNode->GetLastChild();
     168             : }
     169             : 
     170             : RawGeckoNodeBorrowedOrNull
     171           0 : Gecko_GetFlattenedTreeParentNode(RawGeckoNodeBorrowed aNode)
     172             : {
     173           0 :   MOZ_ASSERT(!FlattenedTreeParentIsParent<nsIContent::eForStyle>(aNode),
     174             :              "Should have taken the inline path");
     175           0 :   MOZ_ASSERT(aNode->IsContent(), "Slow path only applies to content");
     176           0 :   const nsIContent* c = aNode->AsContent();
     177           0 :   return c->GetFlattenedTreeParentNodeInternal(nsIContent::eForStyle);
     178             : }
     179             : 
     180             : RawGeckoElementBorrowedOrNull
     181           0 : Gecko_GetBeforeOrAfterPseudo(RawGeckoElementBorrowed aElement, bool aIsBefore)
     182             : {
     183           0 :   MOZ_ASSERT(aElement);
     184           0 :   MOZ_ASSERT(aElement->HasProperties());
     185             : 
     186             :   return aIsBefore
     187             :     ? nsLayoutUtils::GetBeforePseudo(aElement)
     188           0 :     : nsLayoutUtils::GetAfterPseudo(aElement);
     189             : }
     190             : 
     191             : nsTArray<nsIContent*>*
     192           0 : Gecko_GetAnonymousContentForElement(RawGeckoElementBorrowed aElement)
     193             : {
     194           0 :   nsIAnonymousContentCreator* ac = do_QueryFrame(aElement->GetPrimaryFrame());
     195           0 :   if (!ac) {
     196           0 :     return nullptr;
     197             :   }
     198             : 
     199           0 :   auto* array = new nsTArray<nsIContent*>();
     200           0 :   nsContentUtils::AppendNativeAnonymousChildren(aElement, *array, 0);
     201           0 :   return array;
     202             : }
     203             : 
     204             : void
     205           0 : Gecko_DestroyAnonymousContentList(nsTArray<nsIContent*>* aAnonContent)
     206             : {
     207           0 :   MOZ_ASSERT(aAnonContent);
     208           0 :   delete aAnonContent;
     209           0 : }
     210             : 
     211             : void
     212           0 : Gecko_ConstructStyleChildrenIterator(
     213             :   RawGeckoElementBorrowed aElement,
     214             :   RawGeckoStyleChildrenIteratorBorrowedMut aIterator)
     215             : {
     216           0 :   MOZ_ASSERT(aElement);
     217           0 :   MOZ_ASSERT(aIterator);
     218           0 :   new (aIterator) StyleChildrenIterator(aElement);
     219           0 : }
     220             : 
     221             : void
     222           0 : Gecko_DestroyStyleChildrenIterator(
     223             :   RawGeckoStyleChildrenIteratorBorrowedMut aIterator)
     224             : {
     225           0 :   MOZ_ASSERT(aIterator);
     226             : 
     227           0 :   aIterator->~StyleChildrenIterator();
     228           0 : }
     229             : 
     230             : nsIContent*
     231           0 : Gecko_ElementBindingAnonymousContent(RawGeckoElementBorrowed aElement)
     232             : {
     233           0 :   MOZ_ASSERT(aElement->HasFlag(NODE_MAY_BE_IN_BINDING_MNGR));
     234           0 :   nsBindingManager* manager = aElement->OwnerDoc()->BindingManager();
     235           0 :   if (nsXBLBinding* binding = manager->GetBindingWithContent(aElement)) {
     236           0 :     return binding->GetAnonymousContent();
     237             :   }
     238           0 :   return nullptr;
     239             : }
     240             : 
     241             : RawGeckoNodeBorrowed
     242           0 : Gecko_GetNextStyleChild(RawGeckoStyleChildrenIteratorBorrowedMut aIterator)
     243             : {
     244           0 :   MOZ_ASSERT(aIterator);
     245           0 :   return aIterator->GetNextChild();
     246             : }
     247             : 
     248             : EventStates::ServoType
     249           0 : Gecko_ElementState(RawGeckoElementBorrowed aElement)
     250             : {
     251           0 :   return aElement->StyleState().ServoValue();
     252             : }
     253             : 
     254             : EventStates::ServoType
     255           0 : Gecko_DocumentState(const nsIDocument* aDocument)
     256             : {
     257           0 :   return aDocument->ThreadSafeGetDocumentState().ServoValue();
     258             : }
     259             : 
     260             : bool
     261           0 : Gecko_IsTextNode(RawGeckoNodeBorrowed aNode)
     262             : {
     263           0 :   return aNode->NodeInfo()->NodeType() == nsIDOMNode::TEXT_NODE;
     264             : }
     265             : 
     266             : bool
     267           0 : Gecko_IsRootElement(RawGeckoElementBorrowed aElement)
     268             : {
     269           0 :   return aElement->OwnerDoc()->GetRootElement() == aElement;
     270             : }
     271             : 
     272             : bool
     273           0 : Gecko_MatchesElement(CSSPseudoClassType aType,
     274             :                      RawGeckoElementBorrowed aElement)
     275             : {
     276           0 :   return nsCSSPseudoClasses::MatchesElement(aType, aElement).value();
     277             : }
     278             : 
     279             : nsIAtom*
     280           0 : Gecko_LocalName(RawGeckoElementBorrowed aElement)
     281             : {
     282           0 :   return aElement->NodeInfo()->NameAtom();
     283             : }
     284             : 
     285             : nsIAtom*
     286           0 : Gecko_Namespace(RawGeckoElementBorrowed aElement)
     287             : {
     288           0 :   int32_t id = aElement->NodeInfo()->NamespaceID();
     289           0 :   return nsContentUtils::NameSpaceManager()->NameSpaceURIAtomForServo(id);
     290             : }
     291             : 
     292             : nsIAtom*
     293           0 : Gecko_GetElementId(RawGeckoElementBorrowed aElement)
     294             : {
     295           0 :   const nsAttrValue* attr = aElement->GetParsedAttr(nsGkAtoms::id);
     296           0 :   if (attr && attr->Type() == nsAttrValue::eAtom) {
     297           0 :     return attr->GetAtomValue();
     298             :   }
     299             :   // The only case in which we should have a non-atom value here is if it's the
     300             :   // empty string value.
     301           0 :   MOZ_ASSERT(!attr || attr->IsEmptyString());
     302           0 :   return nullptr;
     303             : }
     304             : 
     305             : // Dirtiness tracking.
     306             : uint32_t
     307           0 : Gecko_GetNodeFlags(RawGeckoNodeBorrowed aNode)
     308             : {
     309           0 :   return aNode->GetFlags();
     310             : }
     311             : 
     312             : void
     313           0 : Gecko_SetNodeFlags(RawGeckoNodeBorrowed aNode, uint32_t aFlags)
     314             : {
     315           0 :   const_cast<nsINode*>(aNode)->SetFlags(aFlags);
     316           0 : }
     317             : 
     318             : void
     319           0 : Gecko_UnsetNodeFlags(RawGeckoNodeBorrowed aNode, uint32_t aFlags)
     320             : {
     321           0 :   const_cast<nsINode*>(aNode)->UnsetFlags(aFlags);
     322           0 : }
     323             : 
     324             : void
     325           0 : Gecko_SetOwnerDocumentNeedsStyleFlush(RawGeckoElementBorrowed aElement)
     326             : {
     327           0 :   MOZ_ASSERT(NS_IsMainThread());
     328             : 
     329           0 :   if (nsIPresShell* shell = aElement->OwnerDoc()->GetShell()) {
     330           0 :     shell->EnsureStyleFlush();
     331             :   }
     332           0 : }
     333             : 
     334             : nsStyleContext*
     335           0 : Gecko_GetStyleContext(RawGeckoElementBorrowed aElement,
     336             :                       nsIAtom* aPseudoTagOrNull)
     337             : {
     338             :   nsIFrame* relevantFrame =
     339           0 :     ServoRestyleManager::FrameForPseudoElement(aElement, aPseudoTagOrNull);
     340           0 :   if (relevantFrame) {
     341           0 :     return relevantFrame->StyleContext();
     342             :   }
     343             : 
     344           0 :   if (aPseudoTagOrNull) {
     345           0 :     return nullptr;
     346             :   }
     347             : 
     348             :   // FIXME(emilio): Is there a shorter path?
     349           0 :   nsIPresShell* shell = aElement->OwnerDoc()->GetShell();
     350           0 :   NS_ENSURE_TRUE(shell, nullptr);
     351           0 :   nsCSSFrameConstructor* fc = shell->GetPresContext()->FrameConstructor();
     352             : 
     353             :   // NB: This is only called for CalcStyleDifference, and we handle correctly
     354             :   // the display: none case since Servo still has the older style.
     355           0 :   return fc->GetDisplayContentsStyleFor(aElement);
     356             : }
     357             : 
     358             : CSSPseudoElementType
     359           0 : Gecko_GetImplementedPseudo(RawGeckoElementBorrowed aElement)
     360             : {
     361           0 :   return aElement->GetPseudoElementType();
     362             : }
     363             : 
     364             : nsChangeHint
     365           0 : Gecko_CalcStyleDifference(nsStyleContext* aOldStyleContext,
     366             :                           ServoComputedValuesBorrowed aComputedValues,
     367             :                           bool* aAnyStyleChanged)
     368             : {
     369           0 :   MOZ_ASSERT(aOldStyleContext);
     370           0 :   MOZ_ASSERT(aComputedValues);
     371             : 
     372             :   uint32_t equalStructs, samePointerStructs;
     373             :   nsChangeHint result =
     374             :     aOldStyleContext->CalcStyleDifference(aComputedValues,
     375             :                                           &equalStructs,
     376           0 :                                           &samePointerStructs);
     377           0 :   *aAnyStyleChanged = equalStructs != NS_STYLE_INHERIT_MASK;
     378           0 :   return result;
     379             : }
     380             : 
     381             : nsChangeHint
     382           0 : Gecko_HintsHandledForDescendants(nsChangeHint aHint)
     383             : {
     384           0 :   return aHint & ~NS_HintsNotHandledForDescendantsIn(aHint);
     385             : }
     386             : 
     387             : const ServoElementSnapshot*
     388           0 : Gecko_GetElementSnapshot(const ServoElementSnapshotTable* aTable,
     389             :                          const Element* aElement)
     390             : {
     391           0 :   MOZ_ASSERT(aTable);
     392           0 :   MOZ_ASSERT(aElement);
     393             : 
     394           0 :   return aTable->Get(const_cast<Element*>(aElement));
     395             : }
     396             : 
     397             : RawServoDeclarationBlockStrongBorrowedOrNull
     398           0 : Gecko_GetStyleAttrDeclarationBlock(RawGeckoElementBorrowed aElement)
     399             : {
     400           0 :   DeclarationBlock* decl = aElement->GetInlineStyleDeclaration();
     401           0 :   if (!decl) {
     402           0 :     return nullptr;
     403             :   }
     404           0 :   if (decl->IsGecko()) {
     405             :     // XXX This can happen when nodes are adopted from a Gecko-style-backend
     406             :     //     document into a Servo-style-backend document.  See bug 1330051.
     407           0 :     NS_WARNING("stylo: requesting a Gecko declaration block?");
     408           0 :     return nullptr;
     409             :   }
     410           0 :   return decl->AsServo()->RefRawStrong();
     411             : }
     412             : 
     413             : void
     414           0 : Gecko_UnsetDirtyStyleAttr(RawGeckoElementBorrowed aElement)
     415             : {
     416           0 :   DeclarationBlock* decl = aElement->GetInlineStyleDeclaration();
     417           0 :   if (!decl) {
     418           0 :     return;
     419             :   }
     420           0 :   if (decl->IsGecko()) {
     421             :     // XXX This can happen when nodes are adopted from a Gecko-style-backend
     422             :     //     document into a Servo-style-backend document.  See bug 1330051.
     423           0 :     NS_WARNING("stylo: requesting a Gecko declaration block?");
     424           0 :     return;
     425             :   }
     426           0 :   decl->UnsetDirty();
     427             : }
     428             : 
     429             : RawServoDeclarationBlockStrongBorrowedOrNull
     430           0 : Gecko_GetSMILOverrideDeclarationBlock(RawGeckoElementBorrowed aElement)
     431             : {
     432             :   // This function duplicates a lot of the code in
     433             :   // Gecko_GetStyleAttrDeclarationBlock above because I haven't worked out a way
     434             :   // to persuade hazard analysis that a pointer-to-lambda is ok yet.
     435           0 :   MOZ_ASSERT(aElement, "Invalid GeckoElement");
     436             : 
     437             :   DeclarationBlock* decl =
     438           0 :     const_cast<dom::Element*>(aElement)->GetSMILOverrideStyleDeclaration();
     439           0 :   if (!decl) {
     440           0 :     return nullptr;
     441             :   }
     442           0 :   if (decl->IsGecko()) {
     443             :     // XXX This can happen when nodes are adopted from a Gecko-style-backend
     444             :     //     document into a Servo-style-backend document.  See bug 1330051.
     445           0 :     NS_WARNING("stylo: requesting a Gecko declaration block?");
     446           0 :     return nullptr;
     447             :   }
     448           0 :   return decl->AsServo()->RefRawStrong();
     449             : }
     450             : 
     451             : const RawServoDeclarationBlockStrong*
     452           0 : AsRefRawStrong(const RefPtr<RawServoDeclarationBlock>& aDecl)
     453             : {
     454             :   static_assert(sizeof(RefPtr<RawServoDeclarationBlock>) ==
     455             :                 sizeof(RawServoDeclarationBlockStrong),
     456             :                 "RefPtr should just be a pointer");
     457           0 :   return reinterpret_cast<const RawServoDeclarationBlockStrong*>(&aDecl);
     458             : }
     459             : 
     460             : RawServoDeclarationBlockStrongBorrowedOrNull
     461           0 : Gecko_GetHTMLPresentationAttrDeclarationBlock(RawGeckoElementBorrowed aElement)
     462             : {
     463           0 :   const nsMappedAttributes* attrs = aElement->GetMappedAttributes();
     464           0 :   if (!attrs) {
     465           0 :     auto* svg = nsSVGElement::FromContentOrNull(aElement);
     466           0 :     if (svg) {
     467           0 :       if (auto decl = svg->GetContentDeclarationBlock()) {
     468           0 :         return decl->AsServo()->RefRawStrong();
     469             :       }
     470             :     }
     471           0 :     return nullptr;
     472             :   }
     473             : 
     474           0 :   return AsRefRawStrong(attrs->GetServoStyle());
     475             : }
     476             : 
     477             : RawServoDeclarationBlockStrongBorrowedOrNull
     478           0 : Gecko_GetExtraContentStyleDeclarations(RawGeckoElementBorrowed aElement)
     479             : {
     480           0 :   if (!aElement->IsAnyOfHTMLElements(nsGkAtoms::td, nsGkAtoms::th)) {
     481           0 :     return nullptr;
     482             :   }
     483           0 :   const HTMLTableCellElement* cell = static_cast<const HTMLTableCellElement*>(aElement);
     484           0 :   if (nsMappedAttributes* attrs = cell->GetMappedAttributesInheritedFromTable()) {
     485           0 :     return AsRefRawStrong(attrs->GetServoStyle());
     486             :   }
     487           0 :   return nullptr;
     488             : }
     489             : 
     490             : RawServoDeclarationBlockStrongBorrowedOrNull
     491           0 : Gecko_GetUnvisitedLinkAttrDeclarationBlock(RawGeckoElementBorrowed aElement)
     492             : {
     493           0 :   nsHTMLStyleSheet* sheet = aElement->OwnerDoc()->GetAttributeStyleSheet();
     494           0 :   if (!sheet) {
     495           0 :     return nullptr;
     496             :   }
     497             : 
     498           0 :   return AsRefRawStrong(sheet->GetServoUnvisitedLinkDecl());
     499             : }
     500             : 
     501           0 : ServoStyleSheet* Gecko_StyleSheet_Clone(
     502             :     const ServoStyleSheet* aSheet,
     503             :     const ServoStyleSheet* aNewParentSheet)
     504             : {
     505           0 :   MOZ_ASSERT(aSheet);
     506           0 :   MOZ_ASSERT(aSheet->GetParentSheet(), "Should only be used for @import");
     507           0 :   MOZ_ASSERT(aNewParentSheet, "Wat");
     508             : 
     509             :   RefPtr<StyleSheet> newSheet =
     510           0 :     aSheet->Clone(nullptr, nullptr, nullptr, nullptr);
     511             : 
     512             :   // NOTE(emilio): This code runs in the StylesheetInner constructor, which
     513             :   // means that the inner pointer of `aNewParentSheet` still points to the old
     514             :   // one.
     515             :   //
     516             :   // So we _don't_ update neither the parent pointer of the stylesheet, nor the
     517             :   // child list (yet). This is fixed up in that same constructor.
     518           0 :   return static_cast<ServoStyleSheet*>(newSheet.forget().take());
     519             : }
     520             : 
     521             : void
     522           0 : Gecko_StyleSheet_AddRef(const ServoStyleSheet* aSheet)
     523             : {
     524           0 :   MOZ_ASSERT(NS_IsMainThread());
     525           0 :   const_cast<ServoStyleSheet*>(aSheet)->AddRef();
     526           0 : }
     527             : 
     528             : void
     529           0 : Gecko_StyleSheet_Release(const ServoStyleSheet* aSheet)
     530             : {
     531           0 :   MOZ_ASSERT(NS_IsMainThread());
     532           0 :   const_cast<ServoStyleSheet*>(aSheet)->Release();
     533           0 : }
     534             : 
     535             : RawServoDeclarationBlockStrongBorrowedOrNull
     536           0 : Gecko_GetVisitedLinkAttrDeclarationBlock(RawGeckoElementBorrowed aElement)
     537             : {
     538           0 :   nsHTMLStyleSheet* sheet = aElement->OwnerDoc()->GetAttributeStyleSheet();
     539           0 :   if (!sheet) {
     540           0 :     return nullptr;
     541             :   }
     542             : 
     543           0 :   return AsRefRawStrong(sheet->GetServoVisitedLinkDecl());
     544             : }
     545             : 
     546             : RawServoDeclarationBlockStrongBorrowedOrNull
     547           0 : Gecko_GetActiveLinkAttrDeclarationBlock(RawGeckoElementBorrowed aElement)
     548             : {
     549           0 :   nsHTMLStyleSheet* sheet = aElement->OwnerDoc()->GetAttributeStyleSheet();
     550           0 :   if (!sheet) {
     551           0 :     return nullptr;
     552             :   }
     553             : 
     554           0 :   return AsRefRawStrong(sheet->GetServoActiveLinkDecl());
     555             : }
     556             : 
     557             : static CSSPseudoElementType
     558           0 : GetPseudoTypeFromElementForAnimation(const Element*& aElementOrPseudo) {
     559           0 :   if (aElementOrPseudo->IsGeneratedContentContainerForBefore()) {
     560           0 :     aElementOrPseudo = aElementOrPseudo->GetParent()->AsElement();
     561           0 :     return CSSPseudoElementType::before;
     562             :   }
     563             : 
     564           0 :   if (aElementOrPseudo->IsGeneratedContentContainerForAfter()) {
     565           0 :     aElementOrPseudo = aElementOrPseudo->GetParent()->AsElement();
     566           0 :     return CSSPseudoElementType::after;
     567             :   }
     568             : 
     569           0 :   return CSSPseudoElementType::NotPseudo;
     570             : }
     571             : 
     572             : bool
     573           0 : Gecko_GetAnimationRule(RawGeckoElementBorrowed aElement,
     574             :                        EffectCompositor::CascadeLevel aCascadeLevel,
     575             :                        RawServoAnimationValueMapBorrowedMut aAnimationValues)
     576             : {
     577           0 :   MOZ_ASSERT(aElement);
     578             : 
     579           0 :   nsIDocument* doc = aElement->GetComposedDoc();
     580           0 :   if (!doc || !doc->GetShell()) {
     581           0 :     return false;
     582             :   }
     583           0 :   nsPresContext* presContext = doc->GetShell()->GetPresContext();
     584           0 :   if (!presContext || !presContext->IsDynamic()) {
     585             :     // For print or print preview, ignore animations.
     586           0 :     return false;
     587             :   }
     588             : 
     589             :   CSSPseudoElementType pseudoType =
     590           0 :     GetPseudoTypeFromElementForAnimation(aElement);
     591             : 
     592             :   return presContext->EffectCompositor()
     593           0 :     ->GetServoAnimationRule(aElement,
     594             :                             pseudoType,
     595             :                             aCascadeLevel,
     596           0 :                             aAnimationValues);
     597             : }
     598             : 
     599             : bool
     600           0 : Gecko_StyleAnimationsEquals(RawGeckoStyleAnimationListBorrowed aA,
     601             :                             RawGeckoStyleAnimationListBorrowed aB)
     602             : {
     603           0 :   return *aA == *aB;
     604             : }
     605             : 
     606             : void
     607           0 : Gecko_UpdateAnimations(RawGeckoElementBorrowed aElement,
     608             :                        ServoComputedValuesBorrowedOrNull aOldComputedValues,
     609             :                        ServoComputedValuesBorrowedOrNull aComputedValues,
     610             :                        UpdateAnimationsTasks aTasks)
     611             : {
     612           0 :   MOZ_ASSERT(NS_IsMainThread());
     613           0 :   MOZ_ASSERT(aElement);
     614             : 
     615           0 :   if (!aElement->IsInComposedDoc()) {
     616           0 :     return;
     617             :   }
     618             : 
     619           0 :   nsPresContext* presContext = nsContentUtils::GetContextForContent(aElement);
     620           0 :   if (!presContext || !presContext->IsDynamic()) {
     621           0 :     return;
     622             :   }
     623             : 
     624             :   CSSPseudoElementType pseudoType =
     625           0 :     GetPseudoTypeFromElementForAnimation(aElement);
     626             : 
     627           0 :   if (aTasks & UpdateAnimationsTasks::CSSAnimations) {
     628             :     presContext->AnimationManager()->
     629           0 :       UpdateAnimations(const_cast<dom::Element*>(aElement), pseudoType,
     630           0 :                        aComputedValues);
     631             :   }
     632             : 
     633             :   // aComputedValues might be nullptr if the target element is now in a
     634             :   // display:none subtree. We still call Gecko_UpdateAnimations in this case
     635             :   // because we need to stop CSS animations in the display:none subtree.
     636             :   // However, we don't need to update transitions since they are stopped by
     637             :   // RestyleManager::AnimationsWithDestroyedFrame so we just return early
     638             :   // here.
     639           0 :   if (!aComputedValues) {
     640           0 :     return;
     641             :   }
     642             : 
     643           0 :   if (aTasks & UpdateAnimationsTasks::CSSTransitions) {
     644           0 :     MOZ_ASSERT(aOldComputedValues);
     645             :     presContext->TransitionManager()->
     646           0 :       UpdateTransitions(const_cast<dom::Element*>(aElement), pseudoType,
     647           0 :                         aOldComputedValues, aComputedValues);
     648             :   }
     649             : 
     650           0 :   if (aTasks & UpdateAnimationsTasks::EffectProperties) {
     651           0 :     presContext->EffectCompositor()->UpdateEffectProperties(
     652           0 :       aComputedValues, const_cast<dom::Element*>(aElement), pseudoType);
     653             :   }
     654             : 
     655           0 :   if (aTasks & UpdateAnimationsTasks::CascadeResults) {
     656             :     // This task will be scheduled if we detected any changes to !important
     657             :     // rules. We post a restyle here so that we can update the cascade
     658             :     // results in the pre-traversal of the next restyle.
     659             :     presContext->EffectCompositor()
     660           0 :                ->RequestRestyle(const_cast<Element*>(aElement),
     661             :                                 pseudoType,
     662             :                                 EffectCompositor::RestyleType::Standard,
     663           0 :                                 EffectCompositor::CascadeLevel::Animations);
     664             :   }
     665             : }
     666             : 
     667             : bool
     668           0 : Gecko_ElementHasAnimations(RawGeckoElementBorrowed aElement)
     669             : {
     670             :   CSSPseudoElementType pseudoType =
     671           0 :     GetPseudoTypeFromElementForAnimation(aElement);
     672             : 
     673           0 :   return !!EffectSet::GetEffectSet(aElement, pseudoType);
     674             : }
     675             : 
     676             : bool
     677           0 : Gecko_ElementHasCSSAnimations(RawGeckoElementBorrowed aElement)
     678             : {
     679             :   CSSPseudoElementType pseudoType =
     680           0 :     GetPseudoTypeFromElementForAnimation(aElement);
     681             :   nsAnimationManager::CSSAnimationCollection* collection =
     682             :     nsAnimationManager::CSSAnimationCollection
     683           0 :                       ::GetAnimationCollection(aElement, pseudoType);
     684             : 
     685           0 :   return collection && !collection->mAnimations.IsEmpty();
     686             : }
     687             : 
     688             : bool
     689           0 : Gecko_ElementHasCSSTransitions(RawGeckoElementBorrowed aElement)
     690             : {
     691             :   CSSPseudoElementType pseudoType =
     692           0 :     GetPseudoTypeFromElementForAnimation(aElement);
     693             :   nsTransitionManager::CSSTransitionCollection* collection =
     694             :     nsTransitionManager::CSSTransitionCollection
     695           0 :                        ::GetAnimationCollection(aElement, pseudoType);
     696             : 
     697           0 :   return collection && !collection->mAnimations.IsEmpty();
     698             : }
     699             : 
     700             : size_t
     701           0 : Gecko_ElementTransitions_Length(RawGeckoElementBorrowed aElement)
     702             : {
     703             :   CSSPseudoElementType pseudoType =
     704           0 :     GetPseudoTypeFromElementForAnimation(aElement);
     705             :   nsTransitionManager::CSSTransitionCollection* collection =
     706             :     nsTransitionManager::CSSTransitionCollection
     707           0 :                        ::GetAnimationCollection(aElement, pseudoType);
     708             : 
     709           0 :   return collection ? collection->mAnimations.Length() : 0;
     710             : }
     711             : 
     712             : static CSSTransition*
     713           0 : GetCurrentTransitionAt(RawGeckoElementBorrowed aElement, size_t aIndex)
     714             : {
     715             :   CSSPseudoElementType pseudoType =
     716           0 :     GetPseudoTypeFromElementForAnimation(aElement);
     717             :   nsTransitionManager::CSSTransitionCollection* collection =
     718             :     nsTransitionManager::CSSTransitionCollection
     719           0 :                        ::GetAnimationCollection(aElement, pseudoType);
     720           0 :   if (!collection) {
     721           0 :     return nullptr;
     722             :   }
     723           0 :   nsTArray<RefPtr<CSSTransition>>& transitions = collection->mAnimations;
     724           0 :   return aIndex < transitions.Length()
     725           0 :          ? transitions[aIndex].get()
     726           0 :          : nullptr;
     727             : }
     728             : 
     729             : nsCSSPropertyID
     730           0 : Gecko_ElementTransitions_PropertyAt(RawGeckoElementBorrowed aElement,
     731             :                                     size_t aIndex)
     732             : {
     733           0 :   CSSTransition* transition = GetCurrentTransitionAt(aElement, aIndex);
     734           0 :   return transition ? transition->TransitionProperty()
     735           0 :                     : nsCSSPropertyID::eCSSProperty_UNKNOWN;
     736             : }
     737             : 
     738             : RawServoAnimationValueBorrowedOrNull
     739           0 : Gecko_ElementTransitions_EndValueAt(RawGeckoElementBorrowed aElement,
     740             :                                     size_t aIndex)
     741             : {
     742             :   CSSTransition* transition = GetCurrentTransitionAt(aElement,
     743           0 :                                                      aIndex);
     744           0 :   return transition ? transition->ToValue().mServo.get() : nullptr;
     745             : }
     746             : 
     747             : double
     748           0 : Gecko_GetProgressFromComputedTiming(RawGeckoComputedTimingBorrowed aComputedTiming)
     749             : {
     750           0 :   return aComputedTiming->mProgress.Value();
     751             : }
     752             : 
     753             : double
     754           0 : Gecko_GetPositionInSegment(RawGeckoAnimationPropertySegmentBorrowed aSegment,
     755             :                           double aProgress,
     756             :                           ComputedTimingFunction::BeforeFlag aBeforeFlag)
     757             : {
     758           0 :   MOZ_ASSERT(aSegment->mFromKey < aSegment->mToKey,
     759             :              "The segment from key should be less than to key");
     760             : 
     761             :   double positionInSegment =
     762           0 :     (aProgress - aSegment->mFromKey) / (aSegment->mToKey - aSegment->mFromKey);
     763             : 
     764           0 :   return ComputedTimingFunction::GetPortion(aSegment->mTimingFunction,
     765             :                                             positionInSegment,
     766           0 :                                             aBeforeFlag);
     767             : }
     768             : 
     769             : bool
     770           0 : Gecko_IsFramesTimingEnabled() {
     771           0 :   return sFramesTimingFunctionEnabled;
     772             : }
     773             : 
     774             : RawServoAnimationValueBorrowedOrNull
     775           0 : Gecko_AnimationGetBaseStyle(void* aBaseStyles, nsCSSPropertyID aProperty)
     776             : {
     777             :   auto base =
     778             :     static_cast<nsRefPtrHashtable<nsUint32HashKey, RawServoAnimationValue>*>
     779           0 :       (aBaseStyles);
     780           0 :   return base->GetWeak(aProperty);
     781             : }
     782             : 
     783             : void
     784           0 : Gecko_StyleTransition_SetUnsupportedProperty(StyleTransition* aTransition,
     785             :                                              nsIAtom* aAtom)
     786             : {
     787             :   nsCSSPropertyID id =
     788           0 :     nsCSSProps::LookupProperty(nsDependentAtomString(aAtom),
     789           0 :                                CSSEnabledState::eForAllContent);
     790           0 :   if (id == eCSSProperty_UNKNOWN || id == eCSSPropertyExtra_variable) {
     791           0 :     aTransition->SetUnknownProperty(id, aAtom);
     792             :   } else {
     793           0 :     aTransition->SetProperty(id);
     794             :   }
     795           0 : }
     796             : 
     797             : void
     798           0 : Gecko_FillAllBackgroundLists(nsStyleImageLayers* aLayers, uint32_t aMaxLen)
     799             : {
     800           0 :   nsRuleNode::FillAllBackgroundLists(*aLayers, aMaxLen);
     801           0 : }
     802             : 
     803             : void
     804           0 : Gecko_FillAllMaskLists(nsStyleImageLayers* aLayers, uint32_t aMaxLen)
     805             : {
     806           0 :   nsRuleNode::FillAllMaskLists(*aLayers, aMaxLen);
     807           0 : }
     808             : 
     809             : RawGeckoElementBorrowedOrNull
     810           0 : Gecko_GetBody(RawGeckoPresContextBorrowed aPresContext)
     811             : {
     812           0 :   return aPresContext->Document()->GetBodyElement();
     813             : }
     814             : 
     815           0 : nscolor Gecko_GetLookAndFeelSystemColor(int32_t aId,
     816             :                                         RawGeckoPresContextBorrowed aPresContext)
     817             : {
     818           0 :   bool useStandinsForNativeColors = aPresContext && !aPresContext->IsChrome();
     819             :   nscolor result;
     820           0 :   LookAndFeel::ColorID colorId = static_cast<LookAndFeel::ColorID>(aId);
     821           0 :   LookAndFeel::GetColor(colorId, useStandinsForNativeColors, &result);
     822           0 :   return result;
     823             : }
     824             : 
     825             : bool
     826           0 : Gecko_MatchStringArgPseudo(RawGeckoElementBorrowed aElement,
     827             :                            CSSPseudoClassType aType,
     828             :                            const char16_t* aIdent,
     829             :                            bool* aSetSlowSelectorFlag)
     830             : {
     831           0 :   EventStates dummyMask; // mask is never read because we pass aDependence=nullptr
     832             :   return nsCSSRuleProcessor::StringPseudoMatches(aElement, aType, aIdent,
     833           0 :                                                  aElement->OwnerDoc(), true,
     834           0 :                                                  dummyMask, aSetSlowSelectorFlag, nullptr);
     835             : }
     836             : 
     837             : bool
     838           0 : Gecko_MatchLang(RawGeckoElementBorrowed aElement,
     839             :                 nsIAtom* aOverrideLang,
     840             :                 bool aHasOverrideLang,
     841             :                 const char16_t* aValue)
     842             : {
     843           0 :   MOZ_ASSERT(!(aOverrideLang && !aHasOverrideLang),
     844             :              "aHasOverrideLang should only be set when aOverrideLang is null");
     845             : 
     846           0 :   if (!aHasOverrideLang) {
     847             :     return nsCSSRuleProcessor::LangPseudoMatches(aElement, nullptr, false,
     848           0 :                                                  aValue, aElement->OwnerDoc());
     849             :   }
     850             : 
     851             :   return nsCSSRuleProcessor::LangPseudoMatches(aElement, aOverrideLang, true,
     852           0 :                                                aValue, aElement->OwnerDoc());
     853             : }
     854             : 
     855             : nsIAtom*
     856           0 : Gecko_GetXMLLangValue(RawGeckoElementBorrowed aElement)
     857             : {
     858             :   const nsAttrValue* attr =
     859           0 :     aElement->GetParsedAttr(nsGkAtoms::lang, kNameSpaceID_XML);
     860             : 
     861           0 :   if (!attr) {
     862           0 :     return nullptr;
     863             :   }
     864             : 
     865           0 :   MOZ_ASSERT(attr->Type() == nsAttrValue::eAtom);
     866             : 
     867           0 :   nsCOMPtr<nsIAtom> atom = attr->GetAtomValue();
     868           0 :   return atom.forget().take();
     869             : }
     870             : 
     871             : nsIDocument::DocumentTheme
     872           0 : Gecko_GetDocumentLWTheme(const nsIDocument* aDocument)
     873             : {
     874           0 :   return aDocument->ThreadSafeGetDocumentLWTheme();
     875             : }
     876             : 
     877             : template <typename Implementor>
     878             : static nsIAtom*
     879           0 : AtomAttrValue(Implementor* aElement, nsIAtom* aName)
     880             : {
     881           0 :   const nsAttrValue* attr = aElement->GetParsedAttr(aName);
     882           0 :   return attr ? attr->GetAtomValue() : nullptr;
     883             : }
     884             : 
     885             : template <typename Implementor>
     886             : static nsIAtom*
     887           0 : LangValue(Implementor* aElement)
     888             : {
     889             :   // TODO(emilio): Deduplicate a bit with nsIContent::GetLang().
     890             :   const nsAttrValue* attr =
     891           0 :     aElement->GetParsedAttr(nsGkAtoms::lang, kNameSpaceID_XML);
     892           0 :   if (!attr && aElement->SupportsLangAttr()) {
     893           0 :     attr = aElement->GetParsedAttr(nsGkAtoms::lang);
     894             :   }
     895             : 
     896           0 :   if (!attr) {
     897           0 :     return nullptr;
     898             :   }
     899             : 
     900           0 :   MOZ_ASSERT(attr->Type() == nsAttrValue::eAtom);
     901           0 :   nsCOMPtr<nsIAtom> atom = attr->GetAtomValue();
     902           0 :   return atom.forget().take();
     903             : }
     904             : 
     905             : template <typename Implementor, typename MatchFn>
     906             : static bool
     907           0 : DoMatch(Implementor* aElement, nsIAtom* aNS, nsIAtom* aName, MatchFn aMatch)
     908             : {
     909           0 :   if (aNS) {
     910             :     int32_t ns = nsContentUtils::NameSpaceManager()->GetNameSpaceID(aNS,
     911           0 :                                                                     aElement->IsInChromeDocument());
     912           0 :     NS_ENSURE_TRUE(ns != kNameSpaceID_Unknown, false);
     913           0 :     const nsAttrValue* value = aElement->GetParsedAttr(aName, ns);
     914           0 :     return value && aMatch(value);
     915             :   }
     916             :   // No namespace means any namespace - we have to check them all. :-(
     917           0 :   BorrowedAttrInfo attrInfo;
     918           0 :   for (uint32_t i = 0; (attrInfo = aElement->GetAttrInfoAt(i)); ++i) {
     919           0 :     if (attrInfo.mName->LocalName() != aName) {
     920           0 :       continue;
     921             :     }
     922           0 :     if (aMatch(attrInfo.mValue)) {
     923           0 :       return true;
     924             :     }
     925             :   }
     926           0 :   return false;
     927             : }
     928             : 
     929             : template <typename Implementor>
     930             : static bool
     931           0 : HasAttr(Implementor* aElement, nsIAtom* aNS, nsIAtom* aName)
     932             : {
     933           0 :   auto match = [](const nsAttrValue* aValue) { return true; };
     934           0 :   return DoMatch(aElement, aNS, aName, match);
     935             : }
     936             : 
     937             : template <typename Implementor>
     938             : static bool
     939           0 : AttrEquals(Implementor* aElement, nsIAtom* aNS, nsIAtom* aName, nsIAtom* aStr,
     940             :            bool aIgnoreCase)
     941             : {
     942           0 :   auto match = [aStr, aIgnoreCase](const nsAttrValue* aValue) {
     943           0 :     return aValue->Equals(aStr, aIgnoreCase ? eIgnoreCase : eCaseMatters);
     944           0 :   };
     945           0 :   return DoMatch(aElement, aNS, aName, match);
     946             : }
     947             : 
     948             : #define WITH_COMPARATOR(ignore_case_, c_, expr_)    \
     949             :     if (ignore_case_) {                             \
     950             :       const nsCaseInsensitiveStringComparator c_    \
     951             :           = nsCaseInsensitiveStringComparator();    \
     952             :       return expr_;                                 \
     953             :     } else {                                        \
     954             :       const nsDefaultStringComparator c_;           \
     955             :       return expr_;                                 \
     956             :     }
     957             : 
     958             : 
     959             : template <typename Implementor>
     960             : static bool
     961           0 : AttrDashEquals(Implementor* aElement, nsIAtom* aNS, nsIAtom* aName,
     962             :                nsIAtom* aStr, bool aIgnoreCase)
     963             : {
     964           0 :   auto match = [aStr, aIgnoreCase](const nsAttrValue* aValue) {
     965           0 :     nsAutoString str;
     966           0 :     aValue->ToString(str);
     967           0 :     WITH_COMPARATOR(aIgnoreCase, c,
     968             :                     nsStyleUtil::DashMatchCompare(str, nsDependentAtomString(aStr), c))
     969           0 :   };
     970           0 :   return DoMatch(aElement, aNS, aName, match);
     971             : }
     972             : 
     973             : template <typename Implementor>
     974             : static bool
     975           0 : AttrIncludes(Implementor* aElement, nsIAtom* aNS, nsIAtom* aName,
     976             :              nsIAtom* aStr, bool aIgnoreCase)
     977             : {
     978           0 :   auto match = [aStr, aIgnoreCase](const nsAttrValue* aValue) {
     979           0 :     nsAutoString str;
     980           0 :     aValue->ToString(str);
     981           0 :     WITH_COMPARATOR(aIgnoreCase, c,
     982             :                     nsStyleUtil::ValueIncludes(str, nsDependentAtomString(aStr), c))
     983           0 :   };
     984           0 :   return DoMatch(aElement, aNS, aName, match);
     985             : }
     986             : 
     987             : template <typename Implementor>
     988             : static bool
     989           0 : AttrHasSubstring(Implementor* aElement, nsIAtom* aNS, nsIAtom* aName,
     990             :                  nsIAtom* aStr, bool aIgnoreCase)
     991             : {
     992           0 :   auto match = [aStr, aIgnoreCase](const nsAttrValue* aValue) {
     993           0 :     nsAutoString str;
     994           0 :     aValue->ToString(str);
     995           0 :     WITH_COMPARATOR(aIgnoreCase, c,
     996             :                     FindInReadable(nsDependentAtomString(aStr), str, c))
     997           0 :   };
     998           0 :   return DoMatch(aElement, aNS, aName, match);
     999             : }
    1000             : 
    1001             : template <typename Implementor>
    1002             : static bool
    1003           0 : AttrHasPrefix(Implementor* aElement, nsIAtom* aNS, nsIAtom* aName,
    1004             :               nsIAtom* aStr, bool aIgnoreCase)
    1005             : {
    1006           0 :   auto match = [aStr, aIgnoreCase](const nsAttrValue* aValue) {
    1007           0 :     nsAutoString str;
    1008           0 :     aValue->ToString(str);
    1009           0 :     WITH_COMPARATOR(aIgnoreCase, c,
    1010             :                     StringBeginsWith(str, nsDependentAtomString(aStr), c))
    1011           0 :   };
    1012           0 :   return DoMatch(aElement, aNS, aName, match);
    1013             : }
    1014             : 
    1015             : template <typename Implementor>
    1016             : static bool
    1017           0 : AttrHasSuffix(Implementor* aElement, nsIAtom* aNS, nsIAtom* aName,
    1018             :               nsIAtom* aStr, bool aIgnoreCase)
    1019             : {
    1020           0 :   auto match = [aStr, aIgnoreCase](const nsAttrValue* aValue) {
    1021           0 :     nsAutoString str;
    1022           0 :     aValue->ToString(str);
    1023           0 :     WITH_COMPARATOR(aIgnoreCase, c,
    1024             :                     StringEndsWith(str, nsDependentAtomString(aStr), c))
    1025           0 :   };
    1026           0 :   return DoMatch(aElement, aNS, aName, match);
    1027             : }
    1028             : 
    1029             : /**
    1030             :  * Gets the class or class list (if any) of the implementor. The calling
    1031             :  * convention here is rather hairy, and is optimized for getting Servo the
    1032             :  * information it needs for hot calls.
    1033             :  *
    1034             :  * The return value indicates the number of classes. If zero, neither outparam
    1035             :  * is valid. If one, the class_ outparam is filled with the atom of the class.
    1036             :  * If two or more, the classList outparam is set to point to an array of atoms
    1037             :  * representing the class list.
    1038             :  *
    1039             :  * The array is borrowed and the atoms are not addrefed. These values can be
    1040             :  * invalidated by any DOM mutation. Use them in a tight scope.
    1041             :  */
    1042             : template <typename Implementor>
    1043             : static uint32_t
    1044           0 : ClassOrClassList(Implementor* aElement, nsIAtom** aClass, nsIAtom*** aClassList)
    1045             : {
    1046           0 :   const nsAttrValue* attr = aElement->GetClasses();
    1047           0 :   if (!attr) {
    1048           0 :     return 0;
    1049             :   }
    1050             : 
    1051             :   // For class values with only whitespace, Gecko just stores a string. For the
    1052             :   // purposes of the style system, there is no class in this case.
    1053           0 :   if (attr->Type() == nsAttrValue::eString) {
    1054           0 :     MOZ_ASSERT(nsContentUtils::TrimWhitespace<nsContentUtils::IsHTMLWhitespace>(
    1055             :                  attr->GetStringValue()).IsEmpty());
    1056           0 :     return 0;
    1057             :   }
    1058             : 
    1059             :   // Single tokens are generally stored as an atom. Check that case.
    1060           0 :   if (attr->Type() == nsAttrValue::eAtom) {
    1061           0 :     *aClass = attr->GetAtomValue();
    1062           0 :     return 1;
    1063             :   }
    1064             : 
    1065             :   // At this point we should have an atom array. It is likely, but not
    1066             :   // guaranteed, that we have two or more elements in the array.
    1067           0 :   MOZ_ASSERT(attr->Type() == nsAttrValue::eAtomArray);
    1068           0 :   nsTArray<nsCOMPtr<nsIAtom>>* atomArray = attr->GetAtomArrayValue();
    1069           0 :   uint32_t length = atomArray->Length();
    1070             : 
    1071             :   // Special case: zero elements.
    1072           0 :   if (length == 0) {
    1073           0 :     return 0;
    1074             :   }
    1075             : 
    1076             :   // Special case: one element.
    1077           0 :   if (length == 1) {
    1078           0 :     *aClass = atomArray->ElementAt(0);
    1079           0 :     return 1;
    1080             :   }
    1081             : 
    1082             :   // General case: Two or more elements.
    1083             :   //
    1084             :   // Note: We could also expose this array as an array of nsCOMPtrs, since
    1085             :   // bindgen knows what those look like, and eliminate the reinterpret_cast.
    1086             :   // But it's not obvious that that would be preferable.
    1087             :   static_assert(sizeof(nsCOMPtr<nsIAtom>) == sizeof(nsIAtom*), "Bad simplification");
    1088             :   static_assert(alignof(nsCOMPtr<nsIAtom>) == alignof(nsIAtom*), "Bad simplification");
    1089             : 
    1090           0 :   nsCOMPtr<nsIAtom>* elements = atomArray->Elements();
    1091           0 :   nsIAtom** rawElements = reinterpret_cast<nsIAtom**>(elements);
    1092           0 :   *aClassList = rawElements;
    1093           0 :   return atomArray->Length();
    1094             : }
    1095             : 
    1096             : #define SERVO_IMPL_ELEMENT_ATTR_MATCHING_FUNCTIONS(prefix_, implementor_)        \
    1097             :   nsIAtom* prefix_##AtomAttrValue(implementor_ aElement, nsIAtom* aName)         \
    1098             :   {                                                                              \
    1099             :     return AtomAttrValue(aElement, aName);                                       \
    1100             :   }                                                                              \
    1101             :   nsIAtom* prefix_##LangValue(implementor_ aElement)                             \
    1102             :   {                                                                              \
    1103             :     return LangValue(aElement);                                                  \
    1104             :   }                                                                              \
    1105             :   bool prefix_##HasAttr(implementor_ aElement, nsIAtom* aNS, nsIAtom* aName)     \
    1106             :   {                                                                              \
    1107             :     return HasAttr(aElement, aNS, aName);                                        \
    1108             :   }                                                                              \
    1109             :   bool prefix_##AttrEquals(implementor_ aElement, nsIAtom* aNS,                  \
    1110             :                            nsIAtom* aName, nsIAtom* aStr, bool aIgnoreCase)      \
    1111             :   {                                                                              \
    1112             :     return AttrEquals(aElement, aNS, aName, aStr, aIgnoreCase);                  \
    1113             :   }                                                                              \
    1114             :   bool prefix_##AttrDashEquals(implementor_ aElement, nsIAtom* aNS,              \
    1115             :                                nsIAtom* aName, nsIAtom* aStr, bool aIgnoreCase)  \
    1116             :   {                                                                              \
    1117             :     return AttrDashEquals(aElement, aNS, aName, aStr, aIgnoreCase);              \
    1118             :   }                                                                              \
    1119             :   bool prefix_##AttrIncludes(implementor_ aElement, nsIAtom* aNS,                \
    1120             :                              nsIAtom* aName, nsIAtom* aStr, bool aIgnoreCase)    \
    1121             :   {                                                                              \
    1122             :     return AttrIncludes(aElement, aNS, aName, aStr, aIgnoreCase);                \
    1123             :   }                                                                              \
    1124             :   bool prefix_##AttrHasSubstring(implementor_ aElement, nsIAtom* aNS,            \
    1125             :                                  nsIAtom* aName, nsIAtom* aStr, bool aIgnoreCase)\
    1126             :   {                                                                              \
    1127             :     return AttrHasSubstring(aElement, aNS, aName, aStr, aIgnoreCase);            \
    1128             :   }                                                                              \
    1129             :   bool prefix_##AttrHasPrefix(implementor_ aElement, nsIAtom* aNS,               \
    1130             :                               nsIAtom* aName, nsIAtom* aStr, bool aIgnoreCase)   \
    1131             :   {                                                                              \
    1132             :     return AttrHasPrefix(aElement, aNS, aName, aStr, aIgnoreCase);               \
    1133             :   }                                                                              \
    1134             :   bool prefix_##AttrHasSuffix(implementor_ aElement, nsIAtom* aNS,               \
    1135             :                               nsIAtom* aName, nsIAtom* aStr, bool aIgnoreCase)   \
    1136             :   {                                                                              \
    1137             :     return AttrHasSuffix(aElement, aNS, aName, aStr, aIgnoreCase);               \
    1138             :   }                                                                              \
    1139             :   uint32_t prefix_##ClassOrClassList(implementor_ aElement, nsIAtom** aClass,    \
    1140             :                                      nsIAtom*** aClassList)                      \
    1141             :   {                                                                              \
    1142             :     return ClassOrClassList(aElement, aClass, aClassList);                       \
    1143             :   }
    1144             : 
    1145           0 : SERVO_IMPL_ELEMENT_ATTR_MATCHING_FUNCTIONS(Gecko_, RawGeckoElementBorrowed)
    1146           0 : SERVO_IMPL_ELEMENT_ATTR_MATCHING_FUNCTIONS(Gecko_Snapshot, const ServoElementSnapshot*)
    1147             : 
    1148             : #undef SERVO_IMPL_ELEMENT_ATTR_MATCHING_FUNCTIONS
    1149             : 
    1150             : nsIAtom*
    1151           0 : Gecko_Atomize(const char* aString, uint32_t aLength)
    1152             : {
    1153           0 :   return NS_Atomize(nsDependentCSubstring(aString, aLength)).take();
    1154             : }
    1155             : 
    1156             : nsIAtom*
    1157           0 : Gecko_Atomize16(const nsAString* aString)
    1158             : {
    1159           0 :   return NS_Atomize(*aString).take();
    1160             : }
    1161             : 
    1162             : void
    1163           0 : Gecko_AddRefAtom(nsIAtom* aAtom)
    1164             : {
    1165           0 :   NS_ADDREF(aAtom);
    1166           0 : }
    1167             : 
    1168             : void
    1169           0 : Gecko_ReleaseAtom(nsIAtom* aAtom)
    1170             : {
    1171           0 :   NS_RELEASE(aAtom);
    1172           0 : }
    1173             : 
    1174             : const uint16_t*
    1175           0 : Gecko_GetAtomAsUTF16(nsIAtom* aAtom, uint32_t* aLength)
    1176             : {
    1177             :   static_assert(sizeof(char16_t) == sizeof(uint16_t), "Servo doesn't know what a char16_t is");
    1178           0 :   MOZ_ASSERT(aAtom);
    1179           0 :   *aLength = aAtom->GetLength();
    1180             : 
    1181             :   // We need to manually cast from char16ptr_t to const char16_t* to handle the
    1182             :   // MOZ_USE_CHAR16_WRAPPER we use on WIndows.
    1183           0 :   return reinterpret_cast<const uint16_t*>(static_cast<const char16_t*>(aAtom->GetUTF16String()));
    1184             : }
    1185             : 
    1186             : bool
    1187           0 : Gecko_AtomEqualsUTF8(nsIAtom* aAtom, const char* aString, uint32_t aLength)
    1188             : {
    1189             :   // XXXbholley: We should be able to do this without converting, I just can't
    1190             :   // find the right thing to call.
    1191           0 :   nsDependentAtomString atomStr(aAtom);
    1192           0 :   NS_ConvertUTF8toUTF16 inStr(nsDependentCSubstring(aString, aLength));
    1193           0 :   return atomStr.Equals(inStr);
    1194             : }
    1195             : 
    1196             : bool
    1197           0 : Gecko_AtomEqualsUTF8IgnoreCase(nsIAtom* aAtom, const char* aString, uint32_t aLength)
    1198             : {
    1199             :   // XXXbholley: We should be able to do this without converting, I just can't
    1200             :   // find the right thing to call.
    1201           0 :   nsDependentAtomString atomStr(aAtom);
    1202           0 :   NS_ConvertUTF8toUTF16 inStr(nsDependentCSubstring(aString, aLength));
    1203           0 :   return nsContentUtils::EqualsIgnoreASCIICase(atomStr, inStr);
    1204             : }
    1205             : 
    1206             : void
    1207           0 : Gecko_EnsureMozBorderColors(nsStyleBorder* aBorder)
    1208             : {
    1209           0 :   aBorder->EnsureBorderColors();
    1210           0 : }
    1211             : 
    1212           0 : void Gecko_ClearMozBorderColors(nsStyleBorder* aBorder, mozilla::Side aSide)
    1213             : {
    1214           0 :   aBorder->ClearBorderColors(aSide);
    1215           0 : }
    1216             : 
    1217             : void
    1218           0 : Gecko_AppendMozBorderColors(nsStyleBorder* aBorder, mozilla::Side aSide,
    1219             :                             nscolor aColor)
    1220             : {
    1221           0 :   aBorder->AppendBorderColor(aSide, aColor);
    1222           0 : }
    1223             : 
    1224             : void
    1225           0 : Gecko_CopyMozBorderColors(nsStyleBorder* aDest, const nsStyleBorder* aSrc,
    1226             :                           mozilla::Side aSide)
    1227             : {
    1228           0 :   if (aSrc->mBorderColors) {
    1229           0 :     aDest->CopyBorderColorsFrom(aSrc->mBorderColors[aSide], aSide);
    1230             :   }
    1231           0 : }
    1232             : 
    1233             : const nsBorderColors*
    1234           0 : Gecko_GetMozBorderColors(const nsStyleBorder* aBorder, mozilla::Side aSide)
    1235             : {
    1236           0 :   MOZ_ASSERT(aBorder);
    1237           0 :   return aBorder->mBorderColors ? aBorder->mBorderColors[aSide] : nullptr;
    1238             : }
    1239             : 
    1240             : void
    1241           0 : Gecko_FontFamilyList_Clear(FontFamilyList* aList) {
    1242           0 :   aList->Clear();
    1243           0 : }
    1244             : 
    1245             : void
    1246           0 : Gecko_FontFamilyList_AppendNamed(FontFamilyList* aList, nsIAtom* aName, bool aQuoted)
    1247             : {
    1248           0 :   FontFamilyName family;
    1249           0 :   aName->ToString(family.mName);
    1250           0 :   if (aQuoted) {
    1251           0 :     family.mType = eFamily_named_quoted;
    1252             :   }
    1253             : 
    1254           0 :   aList->Append(family);
    1255           0 : }
    1256             : 
    1257             : void
    1258           0 : Gecko_FontFamilyList_AppendGeneric(FontFamilyList* aList, FontFamilyType aType)
    1259             : {
    1260           0 :   aList->Append(FontFamilyName(aType));
    1261           0 : }
    1262             : 
    1263             : void
    1264           0 : Gecko_CopyFontFamilyFrom(nsFont* dst, const nsFont* src)
    1265             : {
    1266           0 :   dst->fontlist = src->fontlist;
    1267           0 : }
    1268             : 
    1269             : void
    1270           0 : Gecko_nsFont_InitSystem(nsFont* aDest, int32_t aFontId,
    1271             :                         const nsStyleFont* aFont, RawGeckoPresContextBorrowed aPresContext)
    1272             : {
    1273           0 :   const nsFont* defaultVariableFont = ThreadSafeGetDefaultFontHelper(aPresContext, aFont->mLanguage,
    1274           0 :                                                                      kPresContext_DefaultVariableFont_ID);
    1275             : 
    1276             :   // We have passed uninitialized memory to this function,
    1277             :   // initialize it. We can't simply return an nsFont because then
    1278             :   // we need to know its size beforehand. Servo cannot initialize nsFont
    1279             :   // itself, so this will do.
    1280           0 :   nsFont* system = new (aDest) nsFont(*defaultVariableFont);
    1281             : 
    1282           0 :   MOZ_RELEASE_ASSERT(system);
    1283             : 
    1284           0 :   *aDest = *defaultVariableFont;
    1285           0 :   LookAndFeel::FontID fontID = static_cast<LookAndFeel::FontID>(aFontId);
    1286             : 
    1287           0 :   MutexAutoLock lock(*sServoFontMetricsLock);
    1288           0 :   nsRuleNode::ComputeSystemFont(aDest, fontID, aPresContext, defaultVariableFont);
    1289           0 : }
    1290             : 
    1291             : void
    1292           0 : Gecko_nsFont_Destroy(nsFont* aDest)
    1293             : {
    1294           0 :   aDest->~nsFont();
    1295           0 : }
    1296             : 
    1297             : 
    1298             : void
    1299           0 : Gecko_ClearAlternateValues(nsFont* aFont, size_t aLength)
    1300             : {
    1301           0 :   aFont->alternateValues.Clear();
    1302           0 :   aFont->alternateValues.SetCapacity(aLength);
    1303           0 : }
    1304             : 
    1305             : void
    1306           0 : Gecko_AppendAlternateValues(nsFont* aFont, uint32_t aAlternateName, nsIAtom* aAtom)
    1307             : {
    1308           0 :   aFont->alternateValues.AppendElement(gfxAlternateValue {
    1309             :     aAlternateName,
    1310           0 :     nsDependentAtomString(aAtom)
    1311           0 :   });
    1312           0 : }
    1313             : 
    1314             : void
    1315           0 : Gecko_CopyAlternateValuesFrom(nsFont* aDest, const nsFont* aSrc)
    1316             : {
    1317           0 :   aDest->alternateValues.Clear();
    1318           0 :   aDest->alternateValues.AppendElements(aSrc->alternateValues);
    1319           0 : }
    1320             : 
    1321             : void
    1322           0 : Gecko_SetImageOrientation(nsStyleVisibility* aVisibility,
    1323             :                           double aRadians, bool aFlip)
    1324             : {
    1325             :   aVisibility->mImageOrientation =
    1326           0 :     nsStyleImageOrientation::CreateAsAngleAndFlip(aRadians, aFlip);
    1327           0 : }
    1328             : 
    1329             : void
    1330           0 : Gecko_SetImageOrientationAsFromImage(nsStyleVisibility* aVisibility)
    1331             : {
    1332           0 :   aVisibility->mImageOrientation = nsStyleImageOrientation::CreateAsFromImage();
    1333           0 : }
    1334             : 
    1335             : void
    1336           0 : Gecko_CopyImageOrientationFrom(nsStyleVisibility* aDst,
    1337             :                                const nsStyleVisibility* aSrc)
    1338             : {
    1339           0 :   aDst->mImageOrientation = aSrc->mImageOrientation;
    1340           0 : }
    1341             : 
    1342             : void
    1343           0 : Gecko_SetCounterStyleToName(CounterStylePtr* aPtr, nsIAtom* aName,
    1344             :                             RawGeckoPresContextBorrowed aPresContext)
    1345             : {
    1346             :   // Try resolving the counter style if possible, and keep it unresolved
    1347             :   // otherwise.
    1348           0 :   CounterStyleManager* manager = aPresContext->CounterStyleManager();
    1349           0 :   nsCOMPtr<nsIAtom> name = already_AddRefed<nsIAtom>(aName);
    1350           0 :   if (CounterStyle* style = manager->GetCounterStyle(name)) {
    1351           0 :     *aPtr = style;
    1352             :   } else {
    1353           0 :     *aPtr = name.forget();
    1354             :   }
    1355           0 : }
    1356             : 
    1357             : void
    1358           0 : Gecko_SetCounterStyleToSymbols(CounterStylePtr* aPtr, uint8_t aSymbolsType,
    1359             :                                nsACString const* const* aSymbols,
    1360             :                                uint32_t aSymbolsCount)
    1361             : {
    1362           0 :   nsTArray<nsString> symbols(aSymbolsCount);
    1363           0 :   for (uint32_t i = 0; i < aSymbolsCount; i++) {
    1364           0 :     symbols.AppendElement(NS_ConvertUTF8toUTF16(*aSymbols[i]));
    1365             :   }
    1366           0 :   *aPtr = new AnonymousCounterStyle(aSymbolsType, Move(symbols));
    1367           0 : }
    1368             : 
    1369             : void
    1370           0 : Gecko_SetCounterStyleToString(CounterStylePtr* aPtr, const nsACString* aSymbol)
    1371             : {
    1372           0 :   *aPtr = new AnonymousCounterStyle(NS_ConvertUTF8toUTF16(*aSymbol));
    1373           0 : }
    1374             : 
    1375             : void
    1376           0 : Gecko_CopyCounterStyle(CounterStylePtr* aDst, const CounterStylePtr* aSrc)
    1377             : {
    1378           0 :   *aDst = *aSrc;
    1379           0 : }
    1380             : 
    1381             : already_AddRefed<css::URLValue>
    1382           0 : ServoBundledURI::IntoCssUrl()
    1383             : {
    1384           0 :   if (!mURLString) {
    1385           0 :     return nullptr;
    1386             :   }
    1387             : 
    1388           0 :   MOZ_ASSERT(mExtraData->GetReferrer());
    1389           0 :   MOZ_ASSERT(mExtraData->GetPrincipal());
    1390             : 
    1391           0 :   NS_ConvertUTF8toUTF16 url(reinterpret_cast<const char*>(mURLString),
    1392           0 :                             mURLStringLength);
    1393             : 
    1394             :   RefPtr<css::URLValue> urlValue =
    1395           0 :     new css::URLValue(url, do_AddRef(mExtraData));
    1396           0 :   return urlValue.forget();
    1397             : }
    1398             : 
    1399             : void
    1400           0 : Gecko_SetNullImageValue(nsStyleImage* aImage)
    1401             : {
    1402           0 :   MOZ_ASSERT(aImage);
    1403           0 :   aImage->SetNull();
    1404           0 : }
    1405             : 
    1406             : void
    1407           0 : Gecko_SetGradientImageValue(nsStyleImage* aImage, nsStyleGradient* aGradient)
    1408             : {
    1409           0 :   MOZ_ASSERT(aImage);
    1410           0 :   aImage->SetGradientData(aGradient);
    1411           0 : }
    1412             : 
    1413           0 : NS_IMPL_THREADSAFE_FFI_REFCOUNTING(mozilla::css::ImageValue, ImageValue);
    1414             : 
    1415             : static already_AddRefed<nsStyleImageRequest>
    1416           0 : CreateStyleImageRequest(nsStyleImageRequest::Mode aModeFlags,
    1417             :                         mozilla::css::ImageValue* aImageValue)
    1418             : {
    1419             :   RefPtr<nsStyleImageRequest> req =
    1420           0 :     new nsStyleImageRequest(aModeFlags, aImageValue);
    1421           0 :   return req.forget();
    1422             : }
    1423             : 
    1424             : mozilla::css::ImageValue*
    1425           0 : Gecko_ImageValue_Create(ServoBundledURI aURI)
    1426             : {
    1427           0 :   NS_ConvertUTF8toUTF16 url(reinterpret_cast<const char*>(aURI.mURLString),
    1428           0 :                             aURI.mURLStringLength);
    1429             : 
    1430             :   RefPtr<css::ImageValue> value(
    1431           0 :     new css::ImageValue(url, do_AddRef(aURI.mExtraData)));
    1432           0 :   return value.forget().take();
    1433             : }
    1434             : 
    1435             : void
    1436           0 : Gecko_SetLayerImageImageValue(nsStyleImage* aImage,
    1437             :                               mozilla::css::ImageValue* aImageValue)
    1438             : {
    1439           0 :   MOZ_ASSERT(aImage && aImageValue);
    1440             : 
    1441             :   RefPtr<nsStyleImageRequest> req =
    1442           0 :     CreateStyleImageRequest(nsStyleImageRequest::Mode::Track, aImageValue);
    1443           0 :   aImage->SetImageRequest(req.forget());
    1444           0 : }
    1445             : 
    1446             : void
    1447           0 : Gecko_SetImageElement(nsStyleImage* aImage, nsIAtom* aAtom) {
    1448           0 :   MOZ_ASSERT(aImage);
    1449           0 :   aImage->SetElementId(do_AddRef(aAtom));
    1450           0 : }
    1451             : 
    1452             : void
    1453           0 : Gecko_CopyImageValueFrom(nsStyleImage* aImage, const nsStyleImage* aOther)
    1454             : {
    1455           0 :   MOZ_ASSERT(aImage);
    1456           0 :   MOZ_ASSERT(aOther);
    1457             : 
    1458           0 :   *aImage = *aOther;
    1459           0 : }
    1460             : 
    1461             : void
    1462           0 : Gecko_InitializeImageCropRect(nsStyleImage* aImage)
    1463             : {
    1464           0 :   MOZ_ASSERT(aImage);
    1465           0 :   aImage->SetCropRect(MakeUnique<nsStyleSides>());
    1466           0 : }
    1467             : 
    1468             : void
    1469           0 : Gecko_SetCursorArrayLength(nsStyleUserInterface* aStyleUI, size_t aLen)
    1470             : {
    1471           0 :   aStyleUI->mCursorImages.Clear();
    1472           0 :   aStyleUI->mCursorImages.SetLength(aLen);
    1473           0 : }
    1474             : 
    1475             : void
    1476           0 : Gecko_SetCursorImageValue(nsCursorImage* aCursor,
    1477             :                           mozilla::css::ImageValue* aImageValue)
    1478             : {
    1479           0 :   MOZ_ASSERT(aCursor && aImageValue);
    1480             : 
    1481             :   aCursor->mImage =
    1482           0 :     CreateStyleImageRequest(nsStyleImageRequest::Mode::Discard, aImageValue);
    1483           0 : }
    1484             : 
    1485             : void
    1486           0 : Gecko_CopyCursorArrayFrom(nsStyleUserInterface* aDest,
    1487             :                           const nsStyleUserInterface* aSrc)
    1488             : {
    1489           0 :   aDest->mCursorImages = aSrc->mCursorImages;
    1490           0 : }
    1491             : 
    1492             : void
    1493           0 : Gecko_SetContentDataImageValue(nsStyleContentData* aContent,
    1494             :                                mozilla::css::ImageValue* aImageValue)
    1495             : {
    1496           0 :   MOZ_ASSERT(aContent && aImageValue);
    1497             : 
    1498             :   RefPtr<nsStyleImageRequest> req =
    1499           0 :     CreateStyleImageRequest(nsStyleImageRequest::Mode::Track, aImageValue);
    1500           0 :   aContent->SetImageRequest(req.forget());
    1501           0 : }
    1502             : 
    1503             : nsStyleContentData::CounterFunction*
    1504           0 : Gecko_SetCounterFunction(nsStyleContentData* aContent, nsStyleContentType aType)
    1505             : {
    1506             :   RefPtr<nsStyleContentData::CounterFunction>
    1507           0 :     counterFunc = new nsStyleContentData::CounterFunction();
    1508           0 :   nsStyleContentData::CounterFunction* ptr = counterFunc;
    1509           0 :   aContent->SetCounters(aType, counterFunc.forget());
    1510           0 :   return ptr;
    1511             : }
    1512             : 
    1513             : nsStyleGradient*
    1514           0 : Gecko_CreateGradient(uint8_t aShape,
    1515             :                      uint8_t aSize,
    1516             :                      bool aRepeating,
    1517             :                      bool aLegacySyntax,
    1518             :                      bool aMozLegacySyntax,
    1519             :                      uint32_t aStopCount)
    1520             : {
    1521           0 :   nsStyleGradient* result = new nsStyleGradient();
    1522             : 
    1523           0 :   result->mShape = aShape;
    1524           0 :   result->mSize = aSize;
    1525           0 :   result->mRepeating = aRepeating;
    1526           0 :   result->mLegacySyntax = aLegacySyntax;
    1527           0 :   result->mMozLegacySyntax = aMozLegacySyntax;
    1528             : 
    1529           0 :   result->mAngle.SetNoneValue();
    1530           0 :   result->mBgPosX.SetNoneValue();
    1531           0 :   result->mBgPosY.SetNoneValue();
    1532           0 :   result->mRadiusX.SetNoneValue();
    1533           0 :   result->mRadiusY.SetNoneValue();
    1534             : 
    1535           0 :   nsStyleGradientStop dummyStop;
    1536           0 :   dummyStop.mLocation.SetNoneValue();
    1537           0 :   dummyStop.mColor = NS_RGB(0, 0, 0);
    1538           0 :   dummyStop.mIsInterpolationHint = 0;
    1539             : 
    1540           0 :   for (uint32_t i = 0; i < aStopCount; i++) {
    1541           0 :     result->mStops.AppendElement(dummyStop);
    1542             :   }
    1543             : 
    1544           0 :   return result;
    1545             : }
    1546             : 
    1547             : const mozilla::css::URLValueData*
    1548           0 : Gecko_GetURLValue(const nsStyleImage* aImage)
    1549             : {
    1550           0 :   MOZ_ASSERT(aImage && aImage->GetType() == eStyleImageType_Image);
    1551           0 :   return aImage->GetURLValue();
    1552             : }
    1553             : 
    1554             : nsIAtom*
    1555           0 : Gecko_GetImageElement(const nsStyleImage* aImage)
    1556             : {
    1557           0 :   MOZ_ASSERT(aImage && aImage->GetType() == eStyleImageType_Element);
    1558           0 :   return const_cast<nsIAtom*>(aImage->GetElementId());
    1559             : }
    1560             : 
    1561             : const nsStyleGradient*
    1562           0 : Gecko_GetGradientImageValue(const nsStyleImage* aImage)
    1563             : {
    1564           0 :   MOZ_ASSERT(aImage && aImage->GetType() == eStyleImageType_Gradient);
    1565           0 :   return aImage->GetGradientData();
    1566             : }
    1567             : 
    1568             : void
    1569           0 : Gecko_SetListStyleImageNone(nsStyleList* aList)
    1570             : {
    1571           0 :   aList->mListStyleImage = nullptr;
    1572           0 : }
    1573             : 
    1574             : void
    1575           0 : Gecko_SetListStyleImageImageValue(nsStyleList* aList,
    1576             :                              mozilla::css::ImageValue* aImageValue)
    1577             : {
    1578           0 :   MOZ_ASSERT(aList && aImageValue);
    1579             : 
    1580             :   aList->mListStyleImage =
    1581           0 :     CreateStyleImageRequest(nsStyleImageRequest::Mode(0), aImageValue);
    1582           0 : }
    1583             : 
    1584             : void
    1585           0 : Gecko_CopyListStyleImageFrom(nsStyleList* aList, const nsStyleList* aSource)
    1586             : {
    1587           0 :   aList->mListStyleImage = aSource->mListStyleImage;
    1588           0 : }
    1589             : 
    1590             : void
    1591           0 : Gecko_EnsureTArrayCapacity(void* aArray, size_t aCapacity, size_t aElemSize)
    1592             : {
    1593             :   auto base =
    1594             :     reinterpret_cast<nsTArray_base<nsTArrayInfallibleAllocator,
    1595           0 :                                    nsTArray_CopyWithMemutils>*>(aArray);
    1596             : 
    1597           0 :   base->EnsureCapacity<nsTArrayInfallibleAllocator>(aCapacity, aElemSize);
    1598           0 : }
    1599             : 
    1600             : void
    1601           0 : Gecko_ClearPODTArray(void* aArray, size_t aElementSize, size_t aElementAlign)
    1602             : {
    1603             :   auto base =
    1604             :     reinterpret_cast<nsTArray_base<nsTArrayInfallibleAllocator,
    1605           0 :                                    nsTArray_CopyWithMemutils>*>(aArray);
    1606             : 
    1607           0 :   base->template ShiftData<nsTArrayInfallibleAllocator>(0, base->Length(), 0,
    1608           0 :                                                         aElementSize, aElementAlign);
    1609           0 : }
    1610             : 
    1611           0 : void Gecko_SetStyleGridTemplateArrayLengths(nsStyleGridTemplate* aValue,
    1612             :                                             uint32_t aTrackSizes)
    1613             : {
    1614           0 :   aValue->mMinTrackSizingFunctions.SetLength(aTrackSizes);
    1615           0 :   aValue->mMaxTrackSizingFunctions.SetLength(aTrackSizes);
    1616           0 :   aValue->mLineNameLists.SetLength(aTrackSizes + 1);
    1617           0 : }
    1618             : 
    1619           0 : void Gecko_SetGridTemplateLineNamesLength(nsStyleGridTemplate* aValue,
    1620             :                                           uint32_t aNames)
    1621             : {
    1622           0 :   aValue->mLineNameLists.SetLength(aNames);
    1623           0 : }
    1624             : 
    1625           0 : void Gecko_ResizeTArrayForStrings(nsTArray<nsString>* aArray, uint32_t aLength)
    1626             : {
    1627           0 :   aArray->SetLength(aLength);
    1628           0 : }
    1629             : 
    1630             : void
    1631           0 : Gecko_CopyStyleGridTemplateValues(nsStyleGridTemplate* aGridTemplate,
    1632             :                                   const nsStyleGridTemplate* aOther)
    1633             : {
    1634           0 :   *aGridTemplate = *aOther;
    1635           0 : }
    1636             : 
    1637             : mozilla::css::GridTemplateAreasValue*
    1638           0 : Gecko_NewGridTemplateAreasValue(uint32_t aAreas, uint32_t aTemplates, uint32_t aColumns)
    1639             : {
    1640           0 :   RefPtr<mozilla::css::GridTemplateAreasValue> value = new mozilla::css::GridTemplateAreasValue;
    1641           0 :   value->mNamedAreas.SetLength(aAreas);
    1642           0 :   value->mTemplates.SetLength(aTemplates);
    1643           0 :   value->mNColumns = aColumns;
    1644           0 :   return value.forget().take();
    1645             : }
    1646             : 
    1647           0 : NS_IMPL_THREADSAFE_FFI_REFCOUNTING(mozilla::css::GridTemplateAreasValue, GridTemplateAreasValue);
    1648             : 
    1649             : void
    1650           0 : Gecko_ClearAndResizeStyleContents(nsStyleContent* aContent, uint32_t aHowMany)
    1651             : {
    1652           0 :   aContent->AllocateContents(aHowMany);
    1653           0 : }
    1654             : 
    1655             : void
    1656           0 : Gecko_CopyStyleContentsFrom(nsStyleContent* aContent, const nsStyleContent* aOther)
    1657             : {
    1658           0 :   uint32_t count = aOther->ContentCount();
    1659             : 
    1660           0 :   aContent->AllocateContents(count);
    1661             : 
    1662           0 :   for (uint32_t i = 0; i < count; ++i) {
    1663           0 :     aContent->ContentAt(i) = aOther->ContentAt(i);
    1664             :   }
    1665           0 : }
    1666             : 
    1667             : void
    1668           0 : Gecko_ClearAndResizeCounterIncrements(nsStyleContent* aContent, uint32_t aHowMany)
    1669             : {
    1670           0 :   aContent->AllocateCounterIncrements(aHowMany);
    1671           0 : }
    1672             : 
    1673             : void
    1674           0 : Gecko_CopyCounterIncrementsFrom(nsStyleContent* aContent, const nsStyleContent* aOther)
    1675             : {
    1676           0 :   uint32_t count = aOther->CounterIncrementCount();
    1677             : 
    1678           0 :   aContent->AllocateCounterIncrements(count);
    1679             : 
    1680           0 :   for (uint32_t i = 0; i < count; ++i) {
    1681           0 :     const nsStyleCounterData& data = aOther->CounterIncrementAt(i);
    1682           0 :     aContent->SetCounterIncrementAt(i, data.mCounter, data.mValue);
    1683             :   }
    1684           0 : }
    1685             : 
    1686             : void
    1687           0 : Gecko_ClearAndResizeCounterResets(nsStyleContent* aContent, uint32_t aHowMany)
    1688             : {
    1689           0 :   aContent->AllocateCounterResets(aHowMany);
    1690           0 : }
    1691             : 
    1692             : void
    1693           0 : Gecko_CopyCounterResetsFrom(nsStyleContent* aContent, const nsStyleContent* aOther)
    1694             : {
    1695           0 :   uint32_t count = aOther->CounterResetCount();
    1696             : 
    1697           0 :   aContent->AllocateCounterResets(count);
    1698             : 
    1699           0 :   for (uint32_t i = 0; i < count; ++i) {
    1700           0 :     const nsStyleCounterData& data = aOther->CounterResetAt(i);
    1701           0 :     aContent->SetCounterResetAt(i, data.mCounter, data.mValue);
    1702             :   }
    1703           0 : }
    1704             : 
    1705             : void
    1706           0 : Gecko_EnsureImageLayersLength(nsStyleImageLayers* aLayers, size_t aLen,
    1707             :                               nsStyleImageLayers::LayerType aLayerType)
    1708             : {
    1709           0 :   size_t oldLength = aLayers->mLayers.Length();
    1710             : 
    1711           0 :   aLayers->mLayers.EnsureLengthAtLeast(aLen);
    1712             : 
    1713           0 :   for (size_t i = oldLength; i < aLen; ++i) {
    1714           0 :     aLayers->mLayers[i].Initialize(aLayerType);
    1715             :   }
    1716           0 : }
    1717             : 
    1718             : void
    1719           0 : Gecko_EnsureStyleAnimationArrayLength(void* aArray, size_t aLen)
    1720             : {
    1721             :   auto base =
    1722           0 :     static_cast<nsStyleAutoArray<StyleAnimation>*>(aArray);
    1723             : 
    1724           0 :   size_t oldLength = base->Length();
    1725             : 
    1726           0 :   base->EnsureLengthAtLeast(aLen);
    1727             : 
    1728           0 :   for (size_t i = oldLength; i < aLen; ++i) {
    1729           0 :     (*base)[i].SetInitialValues();
    1730             :   }
    1731           0 : }
    1732             : 
    1733             : void
    1734           0 : Gecko_EnsureStyleTransitionArrayLength(void* aArray, size_t aLen)
    1735             : {
    1736             :   auto base =
    1737           0 :     reinterpret_cast<nsStyleAutoArray<StyleTransition>*>(aArray);
    1738             : 
    1739           0 :   size_t oldLength = base->Length();
    1740             : 
    1741           0 :   base->EnsureLengthAtLeast(aLen);
    1742             : 
    1743           0 :   for (size_t i = oldLength; i < aLen; ++i) {
    1744           0 :     (*base)[i].SetInitialValues();
    1745             :   }
    1746           0 : }
    1747             : 
    1748             : void
    1749           0 : Gecko_ClearWillChange(nsStyleDisplay* aDisplay, size_t aLength)
    1750             : {
    1751           0 :   aDisplay->mWillChange.Clear();
    1752           0 :   aDisplay->mWillChange.SetCapacity(aLength);
    1753           0 : }
    1754             : 
    1755             : void
    1756           0 : Gecko_AppendWillChange(nsStyleDisplay* aDisplay, nsIAtom* aAtom)
    1757             : {
    1758           0 :   aDisplay->mWillChange.AppendElement(aAtom);
    1759           0 : }
    1760             : 
    1761             : void
    1762           0 : Gecko_CopyWillChangeFrom(nsStyleDisplay* aDest, nsStyleDisplay* aSrc)
    1763             : {
    1764           0 :   aDest->mWillChange.Clear();
    1765           0 :   aDest->mWillChange.AppendElements(aSrc->mWillChange);
    1766           0 : }
    1767             : 
    1768             : enum class KeyframeSearchDirection {
    1769             :   Forwards,
    1770             :   Backwards,
    1771             : };
    1772             : 
    1773             : enum class KeyframeInsertPosition {
    1774             :   Prepend,
    1775             :   LastForOffset,
    1776             : };
    1777             : 
    1778             : static Keyframe*
    1779           0 : GetOrCreateKeyframe(nsTArray<Keyframe>* aKeyframes,
    1780             :                     float aOffset,
    1781             :                     const nsTimingFunction* aTimingFunction,
    1782             :                     KeyframeSearchDirection aSearchDirection,
    1783             :                     KeyframeInsertPosition aInsertPosition)
    1784             : {
    1785           0 :   MOZ_ASSERT(aKeyframes, "The keyframe array should be valid");
    1786           0 :   MOZ_ASSERT(aTimingFunction, "The timing function should be valid");
    1787           0 :   MOZ_ASSERT(aOffset >= 0. && aOffset <= 1.,
    1788             :              "The offset should be in the range of [0.0, 1.0]");
    1789             : 
    1790             :   size_t keyframeIndex;
    1791           0 :   switch (aSearchDirection) {
    1792             :     case KeyframeSearchDirection::Forwards:
    1793           0 :       if (nsAnimationManager::FindMatchingKeyframe(*aKeyframes,
    1794             :                                                    aOffset,
    1795             :                                                    *aTimingFunction,
    1796             :                                                    keyframeIndex)) {
    1797           0 :         return &(*aKeyframes)[keyframeIndex];
    1798             :       }
    1799           0 :       break;
    1800             :     case KeyframeSearchDirection::Backwards:
    1801           0 :       if (nsAnimationManager::FindMatchingKeyframe(Reversed(*aKeyframes),
    1802             :                                                    aOffset,
    1803             :                                                    *aTimingFunction,
    1804             :                                                    keyframeIndex)) {
    1805           0 :         return &(*aKeyframes)[aKeyframes->Length() - 1 - keyframeIndex];
    1806             :       }
    1807           0 :       keyframeIndex = aKeyframes->Length() - 1;
    1808           0 :       break;
    1809             :   }
    1810             : 
    1811             :   Keyframe* keyframe =
    1812           0 :     aKeyframes->InsertElementAt(
    1813             :       aInsertPosition == KeyframeInsertPosition::Prepend
    1814             :                          ? 0
    1815           0 :                          : keyframeIndex);
    1816           0 :   keyframe->mOffset.emplace(aOffset);
    1817           0 :   if (aTimingFunction->mType != nsTimingFunction::Type::Linear) {
    1818           0 :     keyframe->mTimingFunction.emplace();
    1819           0 :     keyframe->mTimingFunction->Init(*aTimingFunction);
    1820             :   }
    1821             : 
    1822           0 :   return keyframe;
    1823             : }
    1824             : 
    1825             : Keyframe*
    1826           0 : Gecko_GetOrCreateKeyframeAtStart(nsTArray<Keyframe>* aKeyframes,
    1827             :                                  float aOffset,
    1828             :                                  const nsTimingFunction* aTimingFunction)
    1829             : {
    1830           0 :   MOZ_ASSERT(aKeyframes->IsEmpty() ||
    1831             :              aKeyframes->ElementAt(0).mOffset.value() >= aOffset,
    1832             :              "The offset should be less than or equal to the first keyframe's "
    1833             :              "offset if there are exisiting keyframes");
    1834             : 
    1835             :   return GetOrCreateKeyframe(aKeyframes,
    1836             :                              aOffset,
    1837             :                              aTimingFunction,
    1838             :                              KeyframeSearchDirection::Forwards,
    1839           0 :                              KeyframeInsertPosition::Prepend);
    1840             : }
    1841             : 
    1842             : Keyframe*
    1843           0 : Gecko_GetOrCreateInitialKeyframe(nsTArray<Keyframe>* aKeyframes,
    1844             :                                  const nsTimingFunction* aTimingFunction)
    1845             : {
    1846             :   return GetOrCreateKeyframe(aKeyframes,
    1847             :                              0.,
    1848             :                              aTimingFunction,
    1849             :                              KeyframeSearchDirection::Forwards,
    1850           0 :                              KeyframeInsertPosition::LastForOffset);
    1851             : }
    1852             : 
    1853             : Keyframe*
    1854           0 : Gecko_GetOrCreateFinalKeyframe(nsTArray<Keyframe>* aKeyframes,
    1855             :                                const nsTimingFunction* aTimingFunction)
    1856             : {
    1857             :   return GetOrCreateKeyframe(aKeyframes,
    1858             :                              1.,
    1859             :                              aTimingFunction,
    1860             :                              KeyframeSearchDirection::Backwards,
    1861           0 :                              KeyframeInsertPosition::LastForOffset);
    1862             : }
    1863             : 
    1864             : void
    1865           0 : Gecko_ResetStyleCoord(nsStyleUnit* aUnit, nsStyleUnion* aValue)
    1866             : {
    1867           0 :   nsStyleCoord::Reset(*aUnit, *aValue);
    1868           0 : }
    1869             : 
    1870             : void
    1871           0 : Gecko_SetStyleCoordCalcValue(nsStyleUnit* aUnit, nsStyleUnion* aValue, nsStyleCoord::CalcValue aCalc)
    1872             : {
    1873             :   // Calc units should be cleaned up first
    1874           0 :   MOZ_ASSERT(*aUnit != nsStyleUnit::eStyleUnit_Calc);
    1875           0 :   nsStyleCoord::Calc* calcRef = new nsStyleCoord::Calc();
    1876           0 :   calcRef->mLength = aCalc.mLength;
    1877           0 :   calcRef->mPercent = aCalc.mPercent;
    1878           0 :   calcRef->mHasPercent = aCalc.mHasPercent;
    1879           0 :   *aUnit = nsStyleUnit::eStyleUnit_Calc;
    1880           0 :   aValue->mPointer = calcRef;
    1881           0 :   calcRef->AddRef();
    1882           0 : }
    1883             : 
    1884             : void
    1885           0 : Gecko_CopyShapeSourceFrom(mozilla::StyleShapeSource* aDst, const mozilla::StyleShapeSource* aSrc)
    1886             : {
    1887           0 :   MOZ_ASSERT(aDst);
    1888           0 :   MOZ_ASSERT(aSrc);
    1889             : 
    1890           0 :   *aDst = *aSrc;
    1891           0 : }
    1892             : 
    1893             : void
    1894           0 : Gecko_DestroyShapeSource(mozilla::StyleShapeSource* aShape)
    1895             : {
    1896           0 :   aShape->~StyleShapeSource();
    1897           0 : }
    1898             : 
    1899             : void
    1900           0 : Gecko_StyleShapeSource_SetURLValue(mozilla::StyleShapeSource* aShape, ServoBundledURI aURI)
    1901             : {
    1902           0 :   RefPtr<css::URLValue> url = aURI.IntoCssUrl();
    1903           0 :   aShape->SetURL(url.get());
    1904           0 : }
    1905             : 
    1906             : mozilla::StyleBasicShape*
    1907           0 : Gecko_NewBasicShape(mozilla::StyleBasicShapeType aType)
    1908             : {
    1909           0 :   RefPtr<StyleBasicShape> ptr = new mozilla::StyleBasicShape(aType);
    1910           0 :   return ptr.forget().take();
    1911             : }
    1912             : 
    1913             : void
    1914           0 : Gecko_ResetFilters(nsStyleEffects* effects, size_t new_len)
    1915             : {
    1916           0 :   effects->mFilters.Clear();
    1917           0 :   effects->mFilters.SetLength(new_len);
    1918           0 : }
    1919             : 
    1920             : void
    1921           0 : Gecko_CopyFiltersFrom(nsStyleEffects* aSrc, nsStyleEffects* aDest)
    1922             : {
    1923           0 :   aDest->mFilters = aSrc->mFilters;
    1924           0 : }
    1925             : 
    1926             : void
    1927           0 : Gecko_nsStyleFilter_SetURLValue(nsStyleFilter* aEffects, ServoBundledURI aURI)
    1928             : {
    1929           0 :   RefPtr<css::URLValue> url = aURI.IntoCssUrl();
    1930           0 :   aEffects->SetURL(url.get());
    1931           0 : }
    1932             : 
    1933             : void
    1934           0 : Gecko_nsStyleSVGPaint_CopyFrom(nsStyleSVGPaint* aDest, const nsStyleSVGPaint* aSrc)
    1935             : {
    1936           0 :   *aDest = *aSrc;
    1937           0 : }
    1938             : 
    1939             : void
    1940           0 : Gecko_nsStyleSVGPaint_SetURLValue(nsStyleSVGPaint* aPaint, ServoBundledURI aURI)
    1941             : {
    1942           0 :   RefPtr<css::URLValue> url = aURI.IntoCssUrl();
    1943           0 :   aPaint->SetPaintServer(url.get());
    1944           0 : }
    1945             : 
    1946           0 : void Gecko_nsStyleSVGPaint_Reset(nsStyleSVGPaint* aPaint)
    1947             : {
    1948           0 :   aPaint->SetNone();
    1949           0 : }
    1950             : 
    1951             : void
    1952           0 : Gecko_nsStyleSVG_SetDashArrayLength(nsStyleSVG* aSvg, uint32_t aLen)
    1953             : {
    1954           0 :   aSvg->mStrokeDasharray.Clear();
    1955           0 :   aSvg->mStrokeDasharray.SetLength(aLen);
    1956           0 : }
    1957             : 
    1958             : void
    1959           0 : Gecko_nsStyleSVG_CopyDashArray(nsStyleSVG* aDst, const nsStyleSVG* aSrc)
    1960             : {
    1961           0 :   aDst->mStrokeDasharray = aSrc->mStrokeDasharray;
    1962           0 : }
    1963             : 
    1964             : void
    1965           0 : Gecko_nsStyleSVG_SetContextPropertiesLength(nsStyleSVG* aSvg, uint32_t aLen)
    1966             : {
    1967           0 :   aSvg->mContextProps.Clear();
    1968           0 :   aSvg->mContextProps.SetLength(aLen);
    1969           0 : }
    1970             : 
    1971             : void
    1972           0 : Gecko_nsStyleSVG_CopyContextProperties(nsStyleSVG* aDst, const nsStyleSVG* aSrc)
    1973             : {
    1974           0 :   aDst->mContextProps = aSrc->mContextProps;
    1975           0 :   aDst->mContextPropsBits = aSrc->mContextPropsBits;
    1976           0 : }
    1977             : 
    1978             : 
    1979             : css::URLValue*
    1980           0 : Gecko_NewURLValue(ServoBundledURI aURI)
    1981             : {
    1982           0 :   RefPtr<css::URLValue> url = aURI.IntoCssUrl();
    1983           0 :   return url.forget().take();
    1984             : }
    1985             : 
    1986           0 : NS_IMPL_THREADSAFE_FFI_REFCOUNTING(css::URLValue, CSSURLValue);
    1987             : 
    1988           0 : NS_IMPL_THREADSAFE_FFI_REFCOUNTING(URLExtraData, URLExtraData);
    1989             : 
    1990           0 : NS_IMPL_THREADSAFE_FFI_REFCOUNTING(nsStyleCoord::Calc, Calc);
    1991             : 
    1992             : nsCSSShadowArray*
    1993           0 : Gecko_NewCSSShadowArray(uint32_t aLen)
    1994             : {
    1995           0 :   RefPtr<nsCSSShadowArray> arr = new(aLen) nsCSSShadowArray(aLen);
    1996           0 :   return arr.forget().take();
    1997             : }
    1998             : 
    1999           0 : NS_IMPL_THREADSAFE_FFI_REFCOUNTING(nsCSSShadowArray, CSSShadowArray);
    2000             : 
    2001             : nsStyleQuoteValues*
    2002           0 : Gecko_NewStyleQuoteValues(uint32_t aLen)
    2003             : {
    2004           0 :   RefPtr<nsStyleQuoteValues> values = new nsStyleQuoteValues;
    2005           0 :   values->mQuotePairs.SetLength(aLen);
    2006           0 :   return values.forget().take();
    2007             : }
    2008             : 
    2009           0 : NS_IMPL_THREADSAFE_FFI_REFCOUNTING(nsStyleQuoteValues, QuoteValues);
    2010             : 
    2011             : nsCSSValueSharedList*
    2012           0 : Gecko_NewCSSValueSharedList(uint32_t aLen)
    2013             : {
    2014           0 :   RefPtr<nsCSSValueSharedList> list = new nsCSSValueSharedList;
    2015           0 :   if (aLen == 0) {
    2016           0 :     return list.forget().take();
    2017             :   }
    2018             : 
    2019           0 :   list->mHead = new nsCSSValueList;
    2020           0 :   nsCSSValueList* cur = list->mHead;
    2021           0 :   for (uint32_t i = 0; i < aLen - 1; i++) {
    2022           0 :     cur->mNext = new nsCSSValueList;
    2023           0 :     cur = cur->mNext;
    2024             :   }
    2025             : 
    2026           0 :   return list.forget().take();
    2027             : }
    2028             : 
    2029             : nsCSSValueSharedList*
    2030           0 : Gecko_NewNoneTransform()
    2031             : {
    2032           0 :   RefPtr<nsCSSValueSharedList> list = new nsCSSValueSharedList;
    2033           0 :   list->mHead = new nsCSSValueList;
    2034           0 :   list->mHead->mValue.SetNoneValue();
    2035           0 :   return list.forget().take();
    2036             : }
    2037             : 
    2038             : void
    2039           0 : Gecko_CSSValue_SetAbsoluteLength(nsCSSValueBorrowedMut aCSSValue, nscoord aLen)
    2040             : {
    2041           0 :   MOZ_ASSERT(aCSSValue->GetUnit() == eCSSUnit_Null || aCSSValue->IsLengthUnit());
    2042             :   // The call below could trigger refcounting if aCSSValue were a
    2043             :   // FontFamilyList, but we just asserted that it's not. So we can
    2044             :   // whitelist this for static analysis.
    2045           0 :   aCSSValue->SetIntegerCoordValue(aLen);
    2046           0 : }
    2047             : 
    2048             : nscoord
    2049           0 : Gecko_CSSValue_GetAbsoluteLength(nsCSSValueBorrowed aCSSValue)
    2050             : {
    2051             :   // SetIntegerCoordValue() which is used in Gecko_CSSValue_SetAbsoluteLength()
    2052             :   // converts values by nsPresContext::AppUnitsToFloatCSSPixels() and stores
    2053             :   // values in eCSSUnit_Pixel unit. We need to convert the values back to app
    2054             :   // units by GetPixelLength().
    2055           0 :   MOZ_ASSERT(aCSSValue->GetUnit() == eCSSUnit_Pixel,
    2056             :              "The unit should be eCSSUnit_Pixel");
    2057           0 :   return aCSSValue->GetPixelLength();
    2058             : }
    2059             : 
    2060             : void
    2061           0 : Gecko_CSSValue_SetNumber(nsCSSValueBorrowedMut aCSSValue, float aNumber)
    2062             : {
    2063           0 :   aCSSValue->SetFloatValue(aNumber, eCSSUnit_Number);
    2064           0 : }
    2065             : 
    2066             : float
    2067           0 : Gecko_CSSValue_GetNumber(nsCSSValueBorrowed aCSSValue)
    2068             : {
    2069           0 :   return aCSSValue->GetFloatValue();
    2070             : }
    2071             : 
    2072             : void
    2073           0 : Gecko_CSSValue_SetKeyword(nsCSSValueBorrowedMut aCSSValue, nsCSSKeyword aKeyword)
    2074             : {
    2075           0 :   aCSSValue->SetEnumValue(aKeyword);
    2076           0 : }
    2077             : 
    2078             : nsCSSKeyword
    2079           0 : Gecko_CSSValue_GetKeyword(nsCSSValueBorrowed aCSSValue)
    2080             : {
    2081           0 :   return aCSSValue->GetKeywordValue();
    2082             : }
    2083             : 
    2084             : void
    2085           0 : Gecko_CSSValue_SetPercentage(nsCSSValueBorrowedMut aCSSValue, float aPercent)
    2086             : {
    2087           0 :   aCSSValue->SetPercentValue(aPercent);
    2088           0 : }
    2089             : 
    2090             : float
    2091           0 : Gecko_CSSValue_GetPercentage(nsCSSValueBorrowed aCSSValue)
    2092             : {
    2093           0 :   return aCSSValue->GetPercentValue();
    2094             : }
    2095             : 
    2096             : void
    2097           0 : Gecko_CSSValue_SetCalc(nsCSSValueBorrowedMut aCSSValue, nsStyleCoord::CalcValue aCalc)
    2098             : {
    2099           0 :   aCSSValue->SetCalcValue(&aCalc);
    2100           0 : }
    2101             : 
    2102             : nsStyleCoord::CalcValue
    2103           0 : Gecko_CSSValue_GetCalc(nsCSSValueBorrowed aCSSValue)
    2104             : {
    2105           0 :   return aCSSValue->GetCalcValue();
    2106             : }
    2107             : 
    2108             : void
    2109           0 : Gecko_CSSValue_SetFunction(nsCSSValueBorrowedMut aCSSValue, int32_t aLen)
    2110             : {
    2111           0 :   nsCSSValue::Array* arr = nsCSSValue::Array::Create(aLen);
    2112           0 :   aCSSValue->SetArrayValue(arr, eCSSUnit_Function);
    2113           0 : }
    2114             : 
    2115             : void
    2116           0 : Gecko_CSSValue_SetString(nsCSSValueBorrowedMut aCSSValue,
    2117             :                          const uint8_t* aString, uint32_t aLength,
    2118             :                          nsCSSUnit aUnit)
    2119             : {
    2120           0 :   MOZ_ASSERT(aCSSValue->GetUnit() == eCSSUnit_Null);
    2121           0 :   nsString string;
    2122             :   nsDependentCSubstring slice(reinterpret_cast<const char*>(aString),
    2123           0 :                                   aLength);
    2124           0 :   AppendUTF8toUTF16(slice, string);
    2125           0 :   aCSSValue->SetStringValue(string, aUnit);
    2126           0 : }
    2127             : 
    2128             : void
    2129           0 : Gecko_CSSValue_SetStringFromAtom(nsCSSValueBorrowedMut aCSSValue,
    2130             :                                  nsIAtom* aAtom, nsCSSUnit aUnit)
    2131             : {
    2132           0 :   aCSSValue->SetStringValue(nsDependentAtomString(aAtom), aUnit);
    2133           0 : }
    2134             : 
    2135             : void
    2136           0 : Gecko_CSSValue_SetAtomIdent(nsCSSValueBorrowedMut aCSSValue, nsIAtom* aAtom)
    2137             : {
    2138           0 :   aCSSValue->SetAtomIdentValue(already_AddRefed<nsIAtom>(aAtom));
    2139           0 : }
    2140             : 
    2141             : void
    2142           0 : Gecko_CSSValue_SetArray(nsCSSValueBorrowedMut aCSSValue, int32_t aLength)
    2143             : {
    2144           0 :   MOZ_ASSERT(aCSSValue->GetUnit() == eCSSUnit_Null);
    2145             :   RefPtr<nsCSSValue::Array> array
    2146           0 :     = nsCSSValue::Array::Create(aLength);
    2147           0 :   aCSSValue->SetArrayValue(array, eCSSUnit_Array);
    2148           0 : }
    2149             : 
    2150             : void
    2151           0 : Gecko_CSSValue_SetURL(nsCSSValueBorrowedMut aCSSValue,
    2152             :                       ServoBundledURI aURI)
    2153             : {
    2154           0 :   MOZ_ASSERT(aCSSValue->GetUnit() == eCSSUnit_Null);
    2155           0 :   RefPtr<css::URLValue> url = aURI.IntoCssUrl();
    2156           0 :   aCSSValue->SetURLValue(url.get());
    2157           0 : }
    2158             : 
    2159             : void
    2160           0 : Gecko_CSSValue_SetInt(nsCSSValueBorrowedMut aCSSValue,
    2161             :                       int32_t aInteger, nsCSSUnit aUnit)
    2162             : {
    2163           0 :   aCSSValue->SetIntValue(aInteger, aUnit);
    2164           0 : }
    2165             : 
    2166             : nsCSSValueBorrowedMut
    2167           0 : Gecko_CSSValue_GetArrayItem(nsCSSValueBorrowedMut aCSSValue, int32_t aIndex)
    2168             : {
    2169           0 :   return &aCSSValue->GetArrayValue()->Item(aIndex);
    2170             : }
    2171             : 
    2172             : nsCSSValueBorrowed
    2173           0 : Gecko_CSSValue_GetArrayItemConst(nsCSSValueBorrowed aCSSValue, int32_t aIndex)
    2174             : {
    2175           0 :   return &aCSSValue->GetArrayValue()->Item(aIndex);
    2176             : }
    2177             : 
    2178             : void
    2179           0 : Gecko_CSSValue_SetPair(nsCSSValueBorrowedMut aCSSValue,
    2180             :                        nsCSSValueBorrowed aXValue, nsCSSValueBorrowed aYValue)
    2181             : {
    2182           0 :   MOZ_ASSERT(NS_IsMainThread());
    2183           0 :   aCSSValue->SetPairValue(*aXValue, *aYValue);
    2184           0 : }
    2185             : 
    2186             : void
    2187           0 : Gecko_CSSValue_SetList(nsCSSValueBorrowedMut aCSSValue, uint32_t aLen)
    2188             : {
    2189           0 :   MOZ_ASSERT(NS_IsMainThread());
    2190           0 :   nsCSSValueList* item = aCSSValue->SetListValue();
    2191           0 :   for (uint32_t i = 1; i < aLen; ++i) {
    2192           0 :     item->mNext = new nsCSSValueList;
    2193           0 :     item = item->mNext;
    2194             :   }
    2195           0 : }
    2196             : 
    2197             : void
    2198           0 : Gecko_CSSValue_SetPairList(nsCSSValueBorrowedMut aCSSValue, uint32_t aLen)
    2199             : {
    2200           0 :   MOZ_ASSERT(NS_IsMainThread());
    2201           0 :   nsCSSValuePairList* item = aCSSValue->SetPairListValue();
    2202           0 :   for (uint32_t i = 1; i < aLen; ++i) {
    2203           0 :     item->mNext = new nsCSSValuePairList;
    2204           0 :     item = item->mNext;
    2205             :   }
    2206           0 : }
    2207             : 
    2208             : void
    2209           0 : Gecko_CSSValue_InitSharedList(nsCSSValueBorrowedMut aCSSValue,
    2210             :                               uint32_t aLen)
    2211             : {
    2212           0 :   MOZ_ASSERT(aLen > 0, "Must create at least one nsCSSValueList (mHead)");
    2213             : 
    2214           0 :   nsCSSValueSharedList* list = new nsCSSValueSharedList;
    2215           0 :   aCSSValue->SetSharedListValue(list);
    2216           0 :   list->mHead = new nsCSSValueList;
    2217           0 :   nsCSSValueList* cur = list->mHead;
    2218           0 :   for (uint32_t i = 1; i < aLen; ++i) {
    2219           0 :     cur->mNext = new nsCSSValueList;
    2220           0 :     cur = cur->mNext;
    2221             :   }
    2222           0 : }
    2223             : 
    2224             : bool
    2225           0 : Gecko_PropertyId_IsPrefEnabled(nsCSSPropertyID id)
    2226             : {
    2227           0 :   return nsCSSProps::IsEnabled(id);
    2228             : }
    2229             : 
    2230             : void
    2231           0 : Gecko_CSSValue_Drop(nsCSSValueBorrowedMut aCSSValue)
    2232             : {
    2233           0 :   aCSSValue->~nsCSSValue();
    2234           0 : }
    2235             : 
    2236             : void
    2237           0 : Gecko_nsStyleFont_SetLang(nsStyleFont* aFont, nsIAtom* aAtom)
    2238             : {
    2239           0 :   already_AddRefed<nsIAtom> atom = already_AddRefed<nsIAtom>(aAtom);
    2240           0 :   aFont->mLanguage = atom;
    2241           0 :   aFont->mExplicitLanguage = true;
    2242           0 : }
    2243             : 
    2244             : void
    2245           0 : Gecko_nsStyleFont_CopyLangFrom(nsStyleFont* aFont, const nsStyleFont* aSource)
    2246             : {
    2247           0 :   aFont->mLanguage = aSource->mLanguage;
    2248           0 : }
    2249             : 
    2250             : void
    2251           0 : Gecko_nsStyleFont_FixupNoneGeneric(nsStyleFont* aFont,
    2252             :                                    RawGeckoPresContextBorrowed aPresContext)
    2253             : {
    2254           0 :   const nsFont* defaultVariableFont = ThreadSafeGetDefaultFontHelper(aPresContext, aFont->mLanguage,
    2255           0 :                                                                      kPresContext_DefaultVariableFont_ID);
    2256           0 :   nsRuleNode::FixupNoneGeneric(&aFont->mFont, aPresContext,
    2257           0 :                                aFont->mGenericID, defaultVariableFont);
    2258           0 : }
    2259             : 
    2260             : void
    2261           0 : Gecko_nsStyleFont_PrefillDefaultForGeneric(nsStyleFont* aFont,
    2262             :                                            RawGeckoPresContextBorrowed aPresContext,
    2263             :                                            uint8_t aGenericId)
    2264             : {
    2265           0 :   const nsFont* defaultFont = ThreadSafeGetDefaultFontHelper(aPresContext, aFont->mLanguage,
    2266           0 :                                                              aGenericId);
    2267           0 :    aFont->mFont.fontlist = defaultFont->fontlist;
    2268           0 : }
    2269             : 
    2270             : void
    2271           0 : Gecko_nsStyleFont_FixupMinFontSize(nsStyleFont* aFont,
    2272             :                                    RawGeckoPresContextBorrowed aPresContext)
    2273             : {
    2274             :   nscoord minFontSize;
    2275           0 :   bool needsCache = false;
    2276             : 
    2277             :   {
    2278           0 :     AutoReadLock guard(*sServoLangFontPrefsLock);
    2279           0 :     minFontSize = aPresContext->MinFontSize(aFont->mLanguage, &needsCache);
    2280             :   }
    2281             : 
    2282           0 :   if (needsCache) {
    2283           0 :     AutoWriteLock guard(*sServoLangFontPrefsLock);
    2284           0 :     minFontSize = aPresContext->MinFontSize(aFont->mLanguage, nullptr);
    2285             :   }
    2286             : 
    2287           0 :   nsRuleNode::ApplyMinFontSize(aFont, aPresContext, minFontSize);
    2288           0 : }
    2289             : 
    2290             : void
    2291           0 : FontSizePrefs::CopyFrom(const LangGroupFontPrefs& prefs)
    2292             : {
    2293           0 :   mDefaultVariableSize = prefs.mDefaultVariableFont.size;
    2294           0 :   mDefaultFixedSize = prefs.mDefaultFixedFont.size;
    2295           0 :   mDefaultSerifSize = prefs.mDefaultSerifFont.size;
    2296           0 :   mDefaultSansSerifSize = prefs.mDefaultSansSerifFont.size;
    2297           0 :   mDefaultMonospaceSize = prefs.mDefaultMonospaceFont.size;
    2298           0 :   mDefaultCursiveSize = prefs.mDefaultCursiveFont.size;
    2299           0 :   mDefaultFantasySize = prefs.mDefaultFantasyFont.size;
    2300           0 : }
    2301             : 
    2302             : FontSizePrefs
    2303           0 : Gecko_GetBaseSize(nsIAtom* aLanguage)
    2304             : {
    2305           0 :   LangGroupFontPrefs prefs;
    2306           0 :   nsCOMPtr<nsIAtom> langGroupAtom = StaticPresData::Get()->GetUncachedLangGroup(aLanguage);
    2307             : 
    2308           0 :   prefs.Initialize(langGroupAtom);
    2309             :   FontSizePrefs sizes;
    2310           0 :   sizes.CopyFrom(prefs);
    2311             : 
    2312           0 :   return sizes;
    2313             : }
    2314             : 
    2315             : RawGeckoElementBorrowedOrNull
    2316           0 : Gecko_GetBindingParent(RawGeckoElementBorrowed aElement)
    2317             : {
    2318           0 :   nsIContent* parent = aElement->GetBindingParent();
    2319           0 :   return parent ? parent->AsElement() : nullptr;
    2320             : }
    2321             : 
    2322             : RawGeckoXBLBindingBorrowedOrNull
    2323           0 : Gecko_GetXBLBinding(RawGeckoElementBorrowed aElement)
    2324             : {
    2325           0 :   return aElement->GetXBLBinding();
    2326             : }
    2327             : 
    2328             : RawServoStyleSetBorrowedOrNull
    2329           0 : Gecko_XBLBinding_GetRawServoStyleSet(RawGeckoXBLBindingBorrowed aXBLBinding)
    2330             : {
    2331           0 :   const ServoStyleSet* set = aXBLBinding->GetServoStyleSet();
    2332           0 :   return set ? set->RawSet() : nullptr;
    2333             : }
    2334             : 
    2335             : bool
    2336           0 : Gecko_XBLBinding_InheritsStyle(RawGeckoXBLBindingBorrowed aXBLBinding)
    2337             : {
    2338           0 :   return aXBLBinding->InheritsStyle();
    2339             : }
    2340             : 
    2341             : void
    2342           0 : InitializeServo()
    2343             : {
    2344           0 :   URLExtraData::InitDummy();
    2345           0 :   Servo_Initialize(URLExtraData::Dummy());
    2346             : 
    2347           0 :   sServoFontMetricsLock = new Mutex("Gecko_GetFontMetrics");
    2348           0 :   sServoLangFontPrefsLock = new RWLock("nsPresContext::GetDefaultFont");
    2349             : 
    2350             :   Preferences::AddBoolVarCache(&sFramesTimingFunctionEnabled,
    2351           0 :                                "layout.css.frames-timing.enabled");
    2352           0 : }
    2353             : 
    2354             : void
    2355           0 : ShutdownServo()
    2356             : {
    2357           0 :   delete sServoFontMetricsLock;
    2358           0 :   delete sServoLangFontPrefsLock;
    2359           0 :   Servo_Shutdown();
    2360           0 : }
    2361             : 
    2362             : namespace mozilla {
    2363             : 
    2364             : void
    2365           0 : AssertIsMainThreadOrServoFontMetricsLocked()
    2366             : {
    2367           0 :   if (!NS_IsMainThread()) {
    2368           0 :     MOZ_ASSERT(sServoFontMetricsLock);
    2369           0 :     sServoFontMetricsLock->AssertCurrentThreadOwns();
    2370             :   }
    2371           0 : }
    2372             : 
    2373             : } // namespace mozilla
    2374             : 
    2375             : GeckoFontMetrics
    2376           0 : Gecko_GetFontMetrics(RawGeckoPresContextBorrowed aPresContext,
    2377             :                      bool aIsVertical,
    2378             :                      const nsStyleFont* aFont,
    2379             :                      nscoord aFontSize,
    2380             :                      bool aUseUserFontSet)
    2381             : {
    2382           0 :   MutexAutoLock lock(*sServoFontMetricsLock);
    2383             :   GeckoFontMetrics ret;
    2384             : 
    2385             :   // Getting font metrics can require some main thread only work to be
    2386             :   // done, such as work that needs to touch non-threadsafe refcounted
    2387             :   // objects (like the DOM FontFace/FontFaceSet objects), network loads, etc.
    2388             :   //
    2389             :   // To handle this work, font code checks whether we are in a Servo traversal
    2390             :   // and if so, appends PostTraversalTasks to the current ServoStyleSet
    2391             :   // to be performed immediately after the traversal is finished.  This
    2392             :   // works well for starting downloadable font loads, since we don't have
    2393             :   // those fonts available to get metrics for anyway.  Platform fonts and
    2394             :   // ArrayBuffer-backed FontFace objects are handled synchronously.
    2395             : 
    2396           0 :   nsPresContext* presContext = const_cast<nsPresContext*>(aPresContext);
    2397           0 :   presContext->SetUsesExChUnits(true);
    2398           0 :   RefPtr<nsFontMetrics> fm = nsRuleNode::GetMetricsFor(presContext, aIsVertical,
    2399             :                                                        aFont, aFontSize,
    2400           0 :                                                        aUseUserFontSet);
    2401           0 :   ret.mXSize = fm->XHeight();
    2402             :   gfxFloat zeroWidth = fm->GetThebesFontGroup()->GetFirstValidFont()->
    2403           0 :                            GetMetrics(fm->Orientation()).zeroOrAveCharWidth;
    2404           0 :   ret.mChSize = ceil(aPresContext->AppUnitsPerDevPixel() * zeroWidth);
    2405           0 :   return ret;
    2406             : }
    2407             : 
    2408             : int32_t
    2409           0 : Gecko_GetAppUnitsPerPhysicalInch(RawGeckoPresContextBorrowed aPresContext)
    2410             : {
    2411           0 :   nsPresContext* presContext = const_cast<nsPresContext*>(aPresContext);
    2412           0 :   return presContext->DeviceContext()->AppUnitsPerPhysicalInch();
    2413             : }
    2414             : 
    2415             : ServoStyleSheet*
    2416           0 : Gecko_LoadStyleSheet(css::Loader* aLoader,
    2417             :                      ServoStyleSheet* aParent,
    2418             :                      css::LoaderReusableStyleSheets* aReusableSheets,
    2419             :                      RawGeckoURLExtraData* aBaseURLData,
    2420             :                      const uint8_t* aURLString,
    2421             :                      uint32_t aURLStringLength,
    2422             :                      RawServoMediaListStrong aMediaList)
    2423             : {
    2424           0 :   MOZ_ASSERT(NS_IsMainThread());
    2425           0 :   MOZ_ASSERT(aLoader, "Should've catched this before");
    2426           0 :   MOZ_ASSERT(aParent, "Only used for @import, so parent should exist!");
    2427           0 :   MOZ_ASSERT(aURLString, "Invalid URLs shouldn't be loaded!");
    2428           0 :   MOZ_ASSERT(aBaseURLData, "Need base URL data");
    2429             : 
    2430           0 :   RefPtr<dom::MediaList> media = new ServoMediaList(aMediaList.Consume());
    2431             :   nsDependentCSubstring urlSpec(reinterpret_cast<const char*>(aURLString),
    2432           0 :                                 aURLStringLength);
    2433           0 :   nsCOMPtr<nsIURI> uri;
    2434           0 :   nsresult rv = NS_NewURI(getter_AddRefs(uri), urlSpec, nullptr,
    2435           0 :                           aBaseURLData->BaseURI());
    2436             : 
    2437           0 :   StyleSheet* previousFirstChild = aParent->GetFirstChild();
    2438           0 :   if (NS_SUCCEEDED(rv)) {
    2439           0 :     rv = aLoader->LoadChildSheet(aParent, uri, media, nullptr, aReusableSheets);
    2440             :   }
    2441             : 
    2442           0 :   if (NS_FAILED(rv) ||
    2443           0 :       !aParent->GetFirstChild() ||
    2444           0 :       aParent->GetFirstChild() == previousFirstChild) {
    2445             :     // Servo and Gecko have different ideas of what a valid URL is, so we might
    2446             :     // get in here with a URL string that NS_NewURI can't handle.  If so,
    2447             :     // silently do nothing.  Eventually we should be able to assert that the
    2448             :     // NS_NewURI succeeds, here.
    2449             :     RefPtr<ServoStyleSheet> emptySheet =
    2450           0 :       aParent->CreateEmptyChildSheet(media.forget());
    2451           0 :     aParent->PrependStyleSheet(emptySheet);
    2452           0 :     return emptySheet.forget().take();
    2453             :   }
    2454             : 
    2455             :   RefPtr<ServoStyleSheet> sheet =
    2456           0 :     static_cast<ServoStyleSheet*>(aParent->GetFirstChild());
    2457           0 :   return sheet.forget().take();
    2458             : }
    2459             : 
    2460             : const nsMediaFeature*
    2461           0 : Gecko_GetMediaFeatures()
    2462             : {
    2463           0 :   return nsMediaFeatures::features;
    2464             : }
    2465             : 
    2466             : nsCSSKeyword
    2467           0 : Gecko_LookupCSSKeyword(const uint8_t* aString, uint32_t aLength)
    2468             : {
    2469           0 :   MOZ_ASSERT(NS_IsMainThread());
    2470             : 
    2471           0 :   nsDependentCSubstring keyword(reinterpret_cast<const char*>(aString), aLength);
    2472           0 :   return nsCSSKeywords::LookupKeyword(keyword);
    2473             : }
    2474             : 
    2475             : const char*
    2476           0 : Gecko_CSSKeywordString(nsCSSKeyword aKeyword, uint32_t* aLength)
    2477             : {
    2478           0 :   MOZ_ASSERT(NS_IsMainThread());
    2479           0 :   MOZ_ASSERT(aLength);
    2480           0 :   const nsCString& value = nsCSSKeywords::GetStringValue(aKeyword);
    2481           0 :   *aLength = value.Length();
    2482           0 :   return value.get();
    2483             : }
    2484             : 
    2485             : nsCSSFontFaceRule*
    2486           0 : Gecko_CSSFontFaceRule_Create(uint32_t aLine, uint32_t aColumn)
    2487             : {
    2488           0 :   RefPtr<nsCSSFontFaceRule> rule = new nsCSSFontFaceRule(aLine, aColumn);
    2489           0 :   return rule.forget().take();
    2490             : }
    2491             : 
    2492             : nsCSSFontFaceRule*
    2493           0 : Gecko_CSSFontFaceRule_Clone(const nsCSSFontFaceRule* aRule)
    2494             : {
    2495           0 :   RefPtr<css::Rule> rule = aRule->Clone();
    2496           0 :   return static_cast<nsCSSFontFaceRule*>(rule.forget().take());
    2497             : }
    2498             : 
    2499             : void
    2500           0 : Gecko_CSSFontFaceRule_GetCssText(const nsCSSFontFaceRule* aRule,
    2501             :                                  nsAString* aResult)
    2502             : {
    2503             :   // GetCSSText serializes nsCSSValues, which have a heap write
    2504             :   // hazard when dealing with color values (nsCSSKeywords::AddRefTable)
    2505             :   // We only serialize on the main thread; assert to convince the analysis
    2506             :   // and prevent accidentally calling this elsewhere
    2507           0 :   MOZ_ASSERT(NS_IsMainThread());
    2508             : 
    2509           0 :   aRule->GetCssText(*aResult);
    2510           0 : }
    2511             : 
    2512             : void
    2513           0 : Gecko_AddPropertyToSet(nsCSSPropertyIDSetBorrowedMut aPropertySet,
    2514             :                        nsCSSPropertyID aProperty)
    2515             : {
    2516           0 :   aPropertySet->AddProperty(aProperty);
    2517           0 : }
    2518             : 
    2519             : int32_t
    2520           0 : Gecko_RegisterNamespace(nsIAtom* aNamespace)
    2521             : {
    2522             :   int32_t id;
    2523             : 
    2524           0 :   MOZ_ASSERT(NS_IsMainThread());
    2525             : 
    2526           0 :   nsAutoString str;
    2527           0 :   aNamespace->ToString(str);
    2528           0 :   nsresult rv = nsContentUtils::NameSpaceManager()->RegisterNameSpace(str, id);
    2529             : 
    2530           0 :   if (NS_FAILED(rv)) {
    2531           0 :     return -1;
    2532             :   }
    2533           0 :   return id;
    2534             : }
    2535             : 
    2536           0 : NS_IMPL_FFI_REFCOUNTING(nsCSSFontFaceRule, CSSFontFaceRule);
    2537             : 
    2538             : nsCSSCounterStyleRule*
    2539           0 : Gecko_CSSCounterStyle_Create(nsIAtom* aName)
    2540             : {
    2541           0 :   RefPtr<nsCSSCounterStyleRule> rule = new nsCSSCounterStyleRule(aName, 0, 0);
    2542           0 :   return rule.forget().take();
    2543             : }
    2544             : 
    2545             : nsCSSCounterStyleRule*
    2546           0 : Gecko_CSSCounterStyle_Clone(const nsCSSCounterStyleRule* aRule)
    2547             : {
    2548           0 :   RefPtr<css::Rule> rule = aRule->Clone();
    2549           0 :   return static_cast<nsCSSCounterStyleRule*>(rule.forget().take());
    2550             : }
    2551             : 
    2552             : void
    2553           0 : Gecko_CSSCounterStyle_GetCssText(const nsCSSCounterStyleRule* aRule,
    2554             :                                  nsAString* aResult)
    2555             : {
    2556           0 :   MOZ_ASSERT(NS_IsMainThread());
    2557           0 :   aRule->GetCssText(*aResult);
    2558           0 : }
    2559             : 
    2560           0 : NS_IMPL_FFI_REFCOUNTING(nsCSSCounterStyleRule, CSSCounterStyleRule);
    2561             : 
    2562           0 : NS_IMPL_THREADSAFE_FFI_REFCOUNTING(nsCSSValueSharedList, CSSValueSharedList);
    2563             : 
    2564             : #define STYLE_STRUCT(name, checkdata_cb)                                      \
    2565             :                                                                               \
    2566             : void                                                                          \
    2567             : Gecko_Construct_Default_nsStyle##name(nsStyle##name* ptr,                     \
    2568             :                                       const nsPresContext* pres_context)      \
    2569             : {                                                                             \
    2570             :   new (ptr) nsStyle##name(pres_context);                                      \
    2571             : }                                                                             \
    2572             :                                                                               \
    2573             : void                                                                          \
    2574             : Gecko_CopyConstruct_nsStyle##name(nsStyle##name* ptr,                         \
    2575             :                                   const nsStyle##name* other)                 \
    2576             : {                                                                             \
    2577             :   new (ptr) nsStyle##name(*other);                                            \
    2578             : }                                                                             \
    2579             :                                                                               \
    2580             : void                                                                          \
    2581             : Gecko_Destroy_nsStyle##name(nsStyle##name* ptr)                               \
    2582             : {                                                                             \
    2583             :   ptr->~nsStyle##name();                                                      \
    2584             : }
    2585             : 
    2586             : void
    2587           0 : Gecko_Construct_nsStyleVariables(nsStyleVariables* ptr)
    2588             : {
    2589           0 :   new (ptr) nsStyleVariables();
    2590           0 : }
    2591             : 
    2592             : void
    2593           0 : Gecko_RegisterProfilerThread(const char* name)
    2594             : {
    2595             :   char stackTop;
    2596           0 :   profiler_register_thread(name, &stackTop);
    2597           0 : }
    2598             : 
    2599             : void
    2600           0 : Gecko_UnregisterProfilerThread()
    2601             : {
    2602           0 :   profiler_unregister_thread();
    2603           0 : }
    2604             : 
    2605             : bool
    2606           0 : Gecko_DocumentRule_UseForPresentation(RawGeckoPresContextBorrowed aPresContext,
    2607             :                                       const nsACString* aPattern,
    2608             :                                       css::URLMatchingFunction aURLMatchingFunction)
    2609             : {
    2610           0 :   MOZ_ASSERT(NS_IsMainThread());
    2611             : 
    2612           0 :   nsIDocument *doc = aPresContext->Document();
    2613           0 :   nsIURI *docURI = doc->GetDocumentURI();
    2614           0 :   nsAutoCString docURISpec;
    2615           0 :   if (docURI) {
    2616             :     // If GetSpec fails (due to OOM) just skip these URI-specific CSS rules.
    2617           0 :     nsresult rv = docURI->GetSpec(docURISpec);
    2618           0 :     NS_ENSURE_SUCCESS(rv, false);
    2619             :   }
    2620             : 
    2621             :   return css::DocumentRule::UseForPresentation(doc, docURI, docURISpec,
    2622           0 :                                                *aPattern, aURLMatchingFunction);
    2623             : }
    2624             : 
    2625             : void
    2626           0 : Gecko_SetJemallocThreadLocalArena(bool enabled)
    2627             : {
    2628             : #if defined(MOZ_MEMORY)
    2629             :   // At this point we convert |enabled| from a plain C++ bool to a
    2630             :   // |jemalloc_bool|, so be on the safe side.
    2631           0 :   jemalloc_thread_local_arena(!!enabled);
    2632             : #endif
    2633           0 : }
    2634             : 
    2635             : #include "nsStyleStructList.h"
    2636             : 
    2637             : #undef STYLE_STRUCT
    2638             : 
    2639             : #ifndef MOZ_STYLO
    2640             : #define SERVO_BINDING_FUNC(name_, return_, ...)                               \
    2641             :   return_ name_(__VA_ARGS__) {                                                \
    2642             :     MOZ_CRASH("stylo: shouldn't be calling " #name_ "in a non-stylo build");  \
    2643             :   }
    2644             : #include "ServoBindingList.h"
    2645             : #undef SERVO_BINDING_FUNC
    2646             : #endif
    2647             : 
    2648             : ErrorReporter*
    2649           0 : Gecko_CreateCSSErrorReporter(ServoStyleSheet* sheet,
    2650             :                              Loader* loader,
    2651             :                              nsIURI* uri)
    2652             : {
    2653           0 :   MOZ_ASSERT(NS_IsMainThread());
    2654           0 :   return new ErrorReporter(sheet, loader, uri);
    2655             : }
    2656             : 
    2657             : void
    2658           0 : Gecko_DestroyCSSErrorReporter(ErrorReporter* reporter)
    2659             : {
    2660           0 :   delete reporter;
    2661           0 : }
    2662             : 
    2663             : void
    2664           0 : Gecko_ReportUnexpectedCSSError(ErrorReporter* reporter,
    2665             :                                const char* message,
    2666             :                                const char* param,
    2667             :                                uint32_t paramLen,
    2668             :                                const char* source,
    2669             :                                uint32_t sourceLen,
    2670             :                                uint32_t lineNumber,
    2671             :                                uint32_t colNumber,
    2672             :                                nsIURI* uri)
    2673             : {
    2674           0 :   MOZ_ASSERT(NS_IsMainThread());
    2675             : 
    2676           0 :   nsDependentCSubstring paramValue(param, paramLen);
    2677           0 :   nsAutoString wideParam = NS_ConvertUTF8toUTF16(paramValue);
    2678           0 :   reporter->ReportUnexpectedUnescaped(message, wideParam);
    2679           0 :   nsDependentCSubstring sourceValue(source, sourceLen);
    2680           0 :   reporter->OutputError(lineNumber, colNumber, sourceValue);
    2681           0 : }

Generated by: LCOV version 1.13