Bug 1384542: Move GetParent and IsLinkContext to GeckoStyleContext. r?heycam draft
authorEmilio Cobos Álvarez <emilio@crisal.io>
Wed, 26 Jul 2017 18:21:35 +0200
changeset 618418 338b18c8c9741fc74dce2506ea16b4cd694cab74
parent 618417 983c6ce26cee78668a5693b1a563b8ca56618f8d
child 618419 2f5421250d7e45439d83826c34552150e0c41f0e
push id71323
push userbmo:emilio+bugs@crisal.io
push dateMon, 31 Jul 2017 12:35:01 +0000
reviewersheycam
bugs1384542
milestone56.0a1
Bug 1384542: Move GetParent and IsLinkContext to GeckoStyleContext. r?heycam MozReview-Commit-ID: C19yGcphixX
dom/animation/AnimValuesStyleRule.cpp
layout/base/GeckoRestyleManager.cpp
layout/base/RestyleManager.cpp
layout/base/nsCSSFrameConstructor.cpp
layout/base/nsPresContext.cpp
layout/generic/nsFrame.cpp
layout/generic/nsTextFrame.cpp
layout/style/GeckoStyleContext.cpp
layout/style/GeckoStyleContext.h
layout/style/nsComputedDOMStyle.cpp
layout/style/nsRuleData.cpp
layout/style/nsRuleData.h
layout/style/nsRuleNode.cpp
layout/style/nsRuleNode.h
layout/style/nsStyleContext.h
layout/style/nsStyleContextInlines.h
layout/tables/nsTableColGroupFrame.cpp
layout/xul/nsSplitterFrame.cpp
--- a/dom/animation/AnimValuesStyleRule.cpp
+++ b/dom/animation/AnimValuesStyleRule.cpp
@@ -1,26 +1,26 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "AnimValuesStyleRule.h"
+#include "mozilla/GeckoStyleContext.h"
 #include "nsRuleData.h"
-#include "mozilla/GeckoStyleContext.h"
 
 namespace mozilla {
 
 NS_IMPL_ISUPPORTS(AnimValuesStyleRule, nsIStyleRule)
 
 void
 AnimValuesStyleRule::MapRuleInfoInto(nsRuleData* aRuleData)
 {
-  GeckoStyleContext *contextParent = aRuleData->mStyleContext->GetParent();
+  GeckoStyleContext* contextParent = aRuleData->mStyleContext->GetParent();
   if (contextParent && contextParent->HasPseudoElementData()) {
     // Don't apply transitions or animations to things inside of
     // pseudo-elements.
     // FIXME (Bug 522599): Add tests for this.
 
     // Prevent structs from being cached on the rule node since we're inside
     // a pseudo-element, as we could determine cacheability differently
     // when walking the rule tree for a style context that is not inside
--- a/layout/base/GeckoRestyleManager.cpp
+++ b/layout/base/GeckoRestyleManager.cpp
@@ -136,17 +136,17 @@ GetNextBlockInInlineSibling(nsIFrame* aF
  * Since this is used when deciding to copy the new style context, it
  * takes as an argument the old style context to check if the style is
  * the same.  When it is used in other contexts (i.e., where the next
  * continuation would already have the new style context), the current
  * style context should be passed.
  */
 static nsIFrame*
 GetNextContinuationWithSameStyle(nsIFrame* aFrame,
-                                 nsStyleContext* aOldStyleContext,
+                                 GeckoStyleContext* aOldStyleContext,
                                  bool* aHaveMoreContinuations = nullptr)
 {
   // See GetPrevContinuationWithSameStyle about {ib} splits.
 
   nsIFrame* nextContinuation = aFrame->GetNextContinuation();
   if (!nextContinuation &&
       (aFrame->GetStateBits() & NS_FRAME_PART_OF_IBSPLIT)) {
     // We're the last continuation, so we have to hop back to the first
@@ -161,17 +161,17 @@ GetNextContinuationWithSameStyle(nsIFram
 
   if (!nextContinuation) {
     return nullptr;
   }
 
   NS_ASSERTION(nextContinuation->GetContent() == aFrame->GetContent(),
                "unexpected content mismatch");
 
-  nsStyleContext* nextStyle = nextContinuation->StyleContext();
+  GeckoStyleContext* nextStyle = nextContinuation->StyleContext()->AsGecko();
   if (nextStyle != aOldStyleContext) {
     NS_ASSERTION(aOldStyleContext->GetPseudo() != nextStyle->GetPseudo() ||
                  aOldStyleContext->GetParent() != nextStyle->GetParent(),
                  "continuations should have the same style context");
     nextContinuation = nullptr;
     if (aHaveMoreContinuations) {
       *aHaveMoreContinuations = true;
     }
@@ -917,18 +917,18 @@ GetPrevContinuationWithPossiblySameStyle
 static nsIFrame*
 GetPrevContinuationWithSameStyle(nsIFrame* aFrame)
 {
   nsIFrame* prevContinuation = GetPrevContinuationWithPossiblySameStyle(aFrame);
   if (!prevContinuation) {
     return nullptr;
   }
 
-  nsStyleContext* prevStyle = prevContinuation->StyleContext();
-  nsStyleContext* selfStyle = aFrame->StyleContext();
+  GeckoStyleContext* prevStyle = prevContinuation->StyleContext()->AsGecko();
+  GeckoStyleContext* selfStyle = aFrame->StyleContext()->AsGecko();
   if (prevStyle != selfStyle) {
     NS_ASSERTION(prevStyle->GetPseudo() != selfStyle->GetPseudo() ||
                  prevStyle->GetParent() != selfStyle->GetParent(),
                  "continuations should have the same style context");
     prevContinuation = nullptr;
   }
   return prevContinuation;
 }
@@ -976,18 +976,18 @@ GeckoRestyleManager::ReparentStyleContex
     // same style context is valid before the reresolution.  (We need
     // to check the pseudo-type and style context parent because of
     // :first-letter and :first-line, where we create styled and
     // unstyled letter/line frames distinguished by pseudo-type, and
     // then need to distinguish their descendants based on having
     // different parents.)
     nsIFrame* nextContinuation = aFrame->GetNextContinuation();
     if (nextContinuation) {
-      nsStyleContext* nextContinuationContext =
-        nextContinuation->StyleContext();
+      GeckoStyleContext* nextContinuationContext =
+        nextContinuation->StyleContext()->AsGecko();
       NS_ASSERTION(oldContext == nextContinuationContext ||
                    oldContext->GetPseudo() !=
                      nextContinuationContext->GetPseudo() ||
                    oldContext->GetParent() !=
                      nextContinuationContext->GetParent(),
                    "continuations should have the same style context");
     }
   }
@@ -1453,17 +1453,17 @@ ElementRestyler::ConditionallyRestyleCon
   MOZ_ASSERT(aFrame->GetContent()->IsElement());
   MOZ_ASSERT(!aFrame->GetContent()->IsStyledByServo());
 
   if (aFrame->GetContent()->HasFlag(mRestyleTracker.RootBit())) {
     aRestyleRoot = aFrame->GetContent()->AsElement();
   }
 
   for (nsIFrame* f = aFrame; f;
-       f = GetNextContinuationWithSameStyle(f, f->StyleContext())) {
+       f = GetNextContinuationWithSameStyle(f, f->StyleContext()->AsGecko())) {
     nsIFrame::ChildListIterator lists(f);
     for (; !lists.IsDone(); lists.Next()) {
       for (nsIFrame* child : lists.CurrentList()) {
         // Out-of-flows are reached through their placeholders.  Continuations
         // and block-in-inline splits are reached through those chains.
         if (!(child->GetStateBits() & NS_FRAME_OUT_OF_FLOW) &&
             !GetPrevContinuationWithSameStyle(child)) {
           // only do frames that are in flow
@@ -1733,17 +1733,17 @@ ElementRestyler::MoveStyleContextsForChi
   nsTArray<GeckoStyleContext*> contextsToMove;
 
   MOZ_ASSERT(!MustReframeForBeforePseudo(),
              "shouldn't need to reframe ::before as we would have had "
              "eRestyle_Subtree and wouldn't get in here");
 
   DebugOnly<nsIFrame*> lastContinuation;
   for (nsIFrame* f = mFrame; f;
-       f = GetNextContinuationWithSameStyle(f, f->StyleContext())) {
+       f = GetNextContinuationWithSameStyle(f, f->StyleContext()->AsGecko())) {
     lastContinuation = f;
     if (!MoveStyleContextsForContentChildren(f, aOldContext, contextsToMove)) {
       return false;
     }
   }
 
   MOZ_ASSERT(!MustReframeForAfterPseudo(lastContinuation),
              "shouldn't need to reframe ::after as we would have had "
@@ -2996,17 +2996,17 @@ ElementRestyler::RestyleChildren(nsResty
   // kids would use mFrame->StyleContext(), which is out of date if
   // mHintsHandledBySelf has a ReconstructFrame hint; doing this could
   // trigger assertions about mismatched rule trees.
   nsIFrame* lastContinuation;
   if (!(mHintsHandledBySelf & nsChangeHint_ReconstructFrame)) {
     InitializeAccessibilityNotifications(mFrame->StyleContext());
 
     for (nsIFrame* f = mFrame; f;
-         f = GetNextContinuationWithSameStyle(f, f->StyleContext())) {
+         f = GetNextContinuationWithSameStyle(f, f->StyleContext()->AsGecko())) {
       lastContinuation = f;
       RestyleContentChildren(f, aChildRestyleHint);
     }
 
     SendAccessibilityNotifications();
   }
 
   // Check whether we might need to create a new ::after frame.
--- a/layout/base/RestyleManager.cpp
+++ b/layout/base/RestyleManager.cpp
@@ -528,21 +528,21 @@ DumpContext(nsIFrame* aFrame, nsStyleCon
       fputs(NS_LossyConvertUTF16toASCII(buffer).get(), stdout);
       fputs(" ", stdout);
     }
     fputs("{}\n", stdout);
   }
 }
 
 static void
-VerifySameTree(nsStyleContext* aContext1, nsStyleContext* aContext2)
+VerifySameTree(GeckoStyleContext* aContext1, GeckoStyleContext* aContext2)
 {
-  nsStyleContext* top1 = aContext1;
-  nsStyleContext* top2 = aContext2;
-  nsStyleContext* parent;
+  GeckoStyleContext* top1 = aContext1;
+  GeckoStyleContext* top2 = aContext2;
+  GeckoStyleContext* parent;
   for (;;) {
     parent = top1->GetParent();
     if (!parent)
       break;
     top1 = parent;
   }
   for (;;) {
     parent = top2->GetParent();
@@ -550,32 +550,33 @@ VerifySameTree(nsStyleContext* aContext1
       break;
     top2 = parent;
   }
   NS_ASSERTION(top1 == top2,
                "Style contexts are not in the same style context tree");
 }
 
 static void
-VerifyContextParent(nsIFrame* aFrame, nsStyleContext* aContext,
-                    nsStyleContext* aParentContext)
+VerifyContextParent(nsIFrame* aFrame, GeckoStyleContext* aContext,
+                    GeckoStyleContext* aParentContext)
 {
   // get the contexts not provided
   if (!aContext) {
-    aContext = aFrame->StyleContext();
+    aContext = aFrame->StyleContext()->AsGecko();
   }
 
   if (!aParentContext) {
     nsIFrame* providerFrame;
-    aParentContext = aFrame->GetParentStyleContext(&providerFrame);
+    nsStyleContext* parent = aFrame->GetParentStyleContext(&providerFrame);
+    aParentContext = parent ? parent->AsGecko() : nullptr;
     // aParentContext could still be null
   }
 
   NS_ASSERTION(aContext, "Failure to get required contexts");
-  nsStyleContext* actualParentContext = aContext->GetParent();
+  GeckoStyleContext* actualParentContext = aContext->GetParent();
 
   if (aParentContext) {
     if (aParentContext != actualParentContext) {
       DumpContext(aFrame, aContext);
       if (aContext == aParentContext) {
         NS_ERROR("Using parent's style context");
       } else {
         NS_ERROR("Wrong parent style context");
@@ -593,17 +594,17 @@ VerifyContextParent(nsIFrame* aFrame, ns
       NS_ERROR("Have parent context and shouldn't");
       DumpContext(aFrame, aContext);
       fputs("Has parent context: ", stdout);
       DumpContext(nullptr, actualParentContext);
       fputs("Should be null\n\n", stdout);
     }
   }
 
-  nsStyleContext* childStyleIfVisited = aContext->GetStyleIfVisited();
+  GeckoStyleContext* childStyleIfVisited = aContext->GetStyleIfVisited();
   // Either childStyleIfVisited has aContext->GetParent()->GetStyleIfVisited()
   // as the parent or it has a different rulenode from aContext _and_ has
   // aContext->GetParent() as the parent.
   if (childStyleIfVisited &&
       !((childStyleIfVisited->RuleNode() != aContext->RuleNode() &&
          childStyleIfVisited->GetParent() == aContext->GetParent()) ||
         childStyleIfVisited->GetParent() ==
           aContext->GetParent()->GetStyleIfVisited())) {
@@ -611,17 +612,17 @@ VerifyContextParent(nsIFrame* aFrame, ns
     DumpContext(aFrame, aContext);
     fputs("\n", stdout);
   }
 }
 
 static void
 VerifyStyleTree(nsIFrame* aFrame)
 {
-  nsStyleContext* context = aFrame->StyleContext();
+  GeckoStyleContext* context = aFrame->StyleContext()->AsGecko();
   VerifyContextParent(aFrame, context, nullptr);
 
   nsIFrame::ChildListIterator lists(aFrame);
   for (; !lists.IsDone(); lists.Next()) {
     for (nsIFrame* child : lists.CurrentList()) {
       if (!(child->GetStateBits() & NS_FRAME_OUT_OF_FLOW)) {
         // only do frames that are in flow
         if (child->IsPlaceholderFrame()) {
@@ -645,17 +646,17 @@ VerifyStyleTree(nsIFrame* aFrame)
     }
   }
 
   // do additional contexts
   int32_t contextIndex = 0;
   for (nsStyleContext* extraContext;
        (extraContext = aFrame->GetAdditionalStyleContext(contextIndex));
        ++contextIndex) {
-    VerifyContextParent(aFrame, extraContext, context);
+    VerifyContextParent(aFrame, extraContext->AsGecko(), context);
   }
 }
 
 void
 RestyleManager::DebugVerifyStyleTree(nsIFrame* aFrame)
 {
   if (IsServo()) {
     // XXXheycam For now, we know that we don't use the same inheritance
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -5880,17 +5880,17 @@ nsCSSFrameConstructor::AddFrameConstruct
 
       if (newPendingBinding->mBinding) {
         pendingBinding = newPendingBinding;
         // aState takes over owning newPendingBinding
         aState.AddPendingBinding(newPendingBinding.forget());
       }
 
       if (resolveStyle) {
-        if (aContent->IsStyledByServo()) {
+        if (styleContext->IsServo()) {
           Element* element = aContent->AsElement();
           ServoStyleSet* styleSet = mPresShell->StyleSet()->AsServo();
 
           // XXX: We should have a better way to restyle ourselves.
           ServoRestyleManager::ClearServoDataFromSubtree(element);
           styleSet->StyleNewSubtree(element);
 
           // Servo's should_traverse_children() in traversal.rs skips
@@ -5900,17 +5900,18 @@ nsCSSFrameConstructor::AddFrameConstruct
 
           // Because of LazyComputeBehavior::Assert we never create a style
           // context here, so it's fine to pass a null parent.
           styleContext =
             styleSet->ResolveStyleFor(element, nullptr,
                                       LazyComputeBehavior::Assert);
         } else {
           styleContext =
-            ResolveStyleContext(styleContext->GetParent(), aContent, &aState);
+            ResolveStyleContext(styleContext->AsGecko()->GetParent(),
+                                aContent, &aState);
         }
 
         display = styleContext->StyleDisplay();
         aStyleContext = styleContext;
       }
 
       aTag = mDocument->BindingManager()->ResolveTag(aContent, &aNameSpaceID);
     } else if (display->mBinding.ForceGet()) {
@@ -9642,17 +9643,17 @@ nsCSSFrameConstructor::MaybeRecreateFram
     if (!oldContext) {
       return nullptr;
     }
     oldDisplay = StyleDisplay::Contents;
   }
 
   // The parent has a frame, so try resolving a new context.
   RefPtr<nsStyleContext> newContext = mPresShell->StyleSet()->
-    ResolveStyleFor(aElement, oldContext->GetParent(),
+    ResolveStyleFor(aElement, oldContext->AsGecko()->GetParent(),
                     LazyComputeBehavior::Assert);
 
   if (oldDisplay == StyleDisplay::None) {
     ChangeUndisplayedContent(aElement, newContext);
   } else {
     ChangeDisplayContents(aElement, newContext);
   }
 
--- a/layout/base/nsPresContext.cpp
+++ b/layout/base/nsPresContext.cpp
@@ -2257,19 +2257,19 @@ nsPresContext::UpdateIsChrome()
   mIsChrome = mContainer &&
               nsIDocShellTreeItem::typeChrome == mContainer->ItemType();
 }
 
 bool
 nsPresContext::HasAuthorSpecifiedRules(const nsIFrame* aFrame,
                                        uint32_t aRuleTypeMask) const
 {
-  if (mShell->StyleSet()->IsGecko()) {
+  if (auto* geckoStyleContext = aFrame->StyleContext()->GetAsGecko()) {
     return
-      nsRuleNode::HasAuthorSpecifiedRules(aFrame->StyleContext(),
+      nsRuleNode::HasAuthorSpecifiedRules(geckoStyleContext,
                                           aRuleTypeMask,
                                           UseDocumentColors());
   }
   Element* elem = aFrame->GetContent()->AsElement();
 
   MOZ_ASSERT(elem->GetPseudoElementType() ==
              aFrame->StyleContext()->GetPseudoType());
   MOZ_ASSERT(elem->HasServoData());
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -7196,24 +7196,24 @@ nsIFrame::ListGeneric(nsACString& aTo, c
   aTo += nsPrintfCString(" [sc=%p", static_cast<void*>(mStyleContext));
   if (mStyleContext) {
     nsIAtom* pseudoTag = mStyleContext->GetPseudo();
     if (pseudoTag) {
       nsAutoString atomString;
       pseudoTag->ToString(atomString);
       aTo += nsPrintfCString("%s", NS_LossyConvertUTF16toASCII(atomString).get());
     }
-    if (mStyleContext->IsGecko()) {
-      if (!mStyleContext->GetParent() ||
-          (GetParent() && GetParent()->StyleContext() != mStyleContext->GetParent())) {
-        aTo += nsPrintfCString("^%p", mStyleContext->GetParent());
-        if (mStyleContext->GetParent()) {
-          aTo += nsPrintfCString("^%p", mStyleContext->GetParent()->GetParent());
-          if (mStyleContext->GetParent()->GetParent()) {
-            aTo += nsPrintfCString("^%p", mStyleContext->GetParent()->GetParent()->GetParent());
+    if (auto* geckoContext = mStyleContext->GetAsGecko()) {
+      if (!geckoContext->GetParent() ||
+          (GetParent() && GetParent()->StyleContext() != geckoContext->GetParent())) {
+        aTo += nsPrintfCString("^%p", geckoContext->GetParent());
+        if (geckoContext->GetParent()) {
+          aTo += nsPrintfCString("^%p", geckoContext->GetParent()->GetParent());
+          if (geckoContext->GetParent()->GetParent()) {
+            aTo += nsPrintfCString("^%p", geckoContext->GetParent()->GetParent()->GetParent());
           }
         }
       }
     }
   }
   aTo += "]";
 }
 
--- a/layout/generic/nsTextFrame.cpp
+++ b/layout/generic/nsTextFrame.cpp
@@ -4091,31 +4091,40 @@ nsTextPaintStyle::InitSelectionColorsAnd
   mInitSelectionColorsAndShadow = true;
 
   nsIFrame* nonGeneratedAncestor = nsLayoutUtils::GetNonGeneratedAncestor(mFrame);
   Element* selectionElement =
     FindElementAncestorForMozSelection(nonGeneratedAncestor->GetContent());
 
   if (selectionElement &&
       selectionStatus == nsISelectionController::SELECTION_ON) {
-    RefPtr<nsStyleContext> sc = nullptr;
-    sc = mPresContext->StyleSet()->
-      ProbePseudoElementStyle(selectionElement,
-                              CSSPseudoElementType::mozSelection,
-                              mFrame->StyleContext());
+    RefPtr<nsStyleContext> sc =
+      mPresContext->StyleSet()->
+        ProbePseudoElementStyle(selectionElement,
+                                CSSPseudoElementType::mozSelection,
+                                mFrame->StyleContext());
     // Use -moz-selection pseudo class.
     if (sc) {
       mSelectionBGColor =
         sc->GetVisitedDependentColor(&nsStyleBackground::mBackgroundColor);
       mSelectionTextColor =
         sc->GetVisitedDependentColor(&nsStyleText::mWebkitTextFillColor);
-      mHasSelectionShadow =
-        nsRuleNode::HasAuthorSpecifiedRules(sc,
-                                            NS_AUTHOR_SPECIFIED_TEXT_SHADOW,
-                                            true);
+      if (auto* geckoStyleContext = sc->GetAsGecko()) {
+        mHasSelectionShadow =
+          nsRuleNode::HasAuthorSpecifiedRules(geckoStyleContext,
+                                              NS_AUTHOR_SPECIFIED_TEXT_SHADOW,
+                                              true);
+      } else {
+        NS_WARNING("stylo: Need a way to get HasAuthorSpecifiedRules from a "
+                   "raw style context");
+        // Or at least an element and a pseudo-style, which is probably a bit
+        // more doable, since we know that, at least when not in the presence of
+        // first-line / first-letter, we're inheriting from selectionElement.
+        mHasSelectionShadow = true;
+      }
       if (mHasSelectionShadow) {
         mSelectionShadow = sc->StyleText()->mTextShadow;
       }
       return true;
     }
   }
 
   nscolor selectionBGColor =
--- a/layout/style/GeckoStyleContext.cpp
+++ b/layout/style/GeckoStyleContext.cpp
@@ -771,17 +771,17 @@ GeckoStyleContext::ApplyStyleFixups(bool
 
   // CSS Inline Layout Level 3 - 3.5 Sizing Initial Letters:
   // For an N-line drop initial in a Western script, the cap-height of the
   // letter needs to be (N – 1) times the line-height, plus the cap-height
   // of the surrounding text.
   if (mPseudoTag == nsCSSPseudoElements::firstLetter) {
     const nsStyleTextReset* textReset = StyleTextReset();
     if (textReset->mInitialLetterSize != 0.0f) {
-      nsStyleContext* containerSC = mParent;
+      GeckoStyleContext* containerSC = GetParent();
       const nsStyleDisplay* containerDisp = containerSC->StyleDisplay();
       while (containerDisp->mDisplay == mozilla::StyleDisplay::Contents) {
         if (!containerSC->GetParent()) {
           break;
         }
         containerSC = containerSC->GetParent();
         containerDisp = containerSC->StyleDisplay();
       }
@@ -933,17 +933,17 @@ GeckoStyleContext::ApplyStyleFixups(bool
   // Any block-level element directly contained by elements with ruby display
   // values are converted to their inline-level equivalents.
   if (!aSkipParentDisplayBasedStyleFixup && mParent) {
     // Skip display:contents ancestors to reach the potential container.
     // (If there are only display:contents ancestors between this node and
     // a flex/grid container ancestor, then this node is a flex/grid item, since
     // its parent *in the frame tree* will be the flex/grid container. So we treat
     // it like a flex/grid item here.)
-    nsStyleContext* containerContext = mParent;
+    GeckoStyleContext* containerContext = GetParent();
     const nsStyleDisplay* containerDisp = containerContext->StyleDisplay();
     while (containerDisp->mDisplay == mozilla::StyleDisplay::Contents) {
       if (!containerContext->GetParent()) {
         break;
       }
       containerContext = containerContext->GetParent();
       containerDisp = containerContext->StyleDisplay();
     }
--- a/layout/style/GeckoStyleContext.h
+++ b/layout/style/GeckoStyleContext.h
@@ -32,16 +32,25 @@ public:
 
   nsPresContext* PresContext() const {
     return RuleNode()->PresContext();
   }
 
   void AddChild(GeckoStyleContext* aChild);
   void RemoveChild(GeckoStyleContext* aChild);
 
+  GeckoStyleContext* GetParent() const {
+    return mParent ? mParent->AsGecko() : nullptr;
+  }
+
+  bool IsLinkContext() const {
+    return GetStyleIfVisited() &&
+           GetStyleIfVisited()->GetParent() == GetParent();
+  }
+
   /**
    * Moves this style context to a new parent.
    *
    * This function violates style context tree immutability, and
    * is a very low-level function and should only be used after verifying
    * many conditions that make it safe to call.
    */
   void MoveTo(GeckoStyleContext* aNewParent);
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -563,18 +563,18 @@ MustReresolveStyle(const nsStyleContext*
   if (aContext->HasPseudoElementData()) {
     if (!aContext->GetPseudo() ||
         aContext->IsServo()) {
       // TODO(emilio): When ::first-line is supported in Servo, we may want to
       // fix this to avoid re-resolving pseudo-element styles.
       return true;
     }
 
-    return aContext->GetParent() &&
-           aContext->GetParent()->HasPseudoElementData();
+    return aContext->AsGecko()->GetParent() &&
+           aContext->HasPseudoElementData();
   }
 
   return false;
 }
 
 already_AddRefed<nsStyleContext>
 nsComputedDOMStyle::DoGetStyleContextNoFlush(Element* aElement,
                                              nsIAtom* aPseudo,
@@ -890,17 +890,17 @@ nsComputedDOMStyle::UpdateCurrentStyleSo
 #ifdef DEBUG
     if (mStyleContext && mStyleContext->IsGecko()) {
       // We want to check that going through this path because of
       // HasPseudoElementData is rare, because it slows us down a good
       // bit.  So check that we're really inside something associated
       // with a pseudo-element that contains elements.  (We also allow
       // the element to be NAC, just in case some chrome JS calls
       // getComputedStyle on a NAC-implemented pseudo.)
-      nsStyleContext* topWithPseudoElementData = mStyleContext;
+      GeckoStyleContext* topWithPseudoElementData = mStyleContext->AsGecko();
       while (topWithPseudoElementData->GetParent()->HasPseudoElementData()) {
         topWithPseudoElementData = topWithPseudoElementData->GetParent();
       }
       CSSPseudoElementType pseudo = topWithPseudoElementData->GetPseudoType();
       nsIAtom* pseudoAtom = nsCSSPseudoElements::GetPseudoAtom(pseudo);
       nsAutoString assertMsg(
         NS_LITERAL_STRING("we should be in a pseudo-element that is expected to contain elements ("));
       assertMsg.Append(nsDependentString(pseudoAtom->GetUTF16String()));
--- a/layout/style/nsRuleData.cpp
+++ b/layout/style/nsRuleData.cpp
@@ -26,17 +26,17 @@ nsRuleData::GetPoisonOffset()
   uintptr_t framePoisonValue = mozPoisonValue();
   return size_t(framePoisonValue - uintptr_t(mValueStorage)) /
          sizeof(nsCSSValue);
 }
 
 nsRuleData::nsRuleData(uint32_t aSIDs,
                        nsCSSValue* aValueStorage,
                        nsPresContext* aContext,
-                       nsStyleContext* aStyleContext)
+                       GeckoStyleContext* aStyleContext)
   : GenericSpecifiedValues(StyleBackendType::Gecko, aContext, aSIDs)
   , mStyleContext(aStyleContext)
   , mValueStorage(aValueStorage)
 {
 #ifndef MOZ_VALGRIND
   size_t framePoisonOffset = GetPoisonOffset();
   for (size_t i = 0; i < nsStyleStructID_Length; ++i) {
     mValueOffsets[i] = framePoisonOffset;
--- a/layout/style/nsRuleData.h
+++ b/layout/style/nsRuleData.h
@@ -16,27 +16,30 @@
 #include "mozilla/RuleNodeCacheConditions.h"
 #include "mozilla/SheetType.h"
 #include "nsAutoPtr.h"
 #include "nsCSSProps.h"
 #include "nsCSSValue.h"
 #include "nsStyleStructFwd.h"
 
 class nsPresContext;
-class nsStyleContext;
 struct nsRuleData;
 
+namespace mozilla {
+class GeckoStyleContext;
+} // namespace mozilla
+
 typedef void (*nsPostResolveFunc)(void* aStyleStruct, nsRuleData* aData);
 
 struct nsRuleData final : mozilla::GenericSpecifiedValues
 {
   mozilla::RuleNodeCacheConditions mConditions;
   bool mIsImportantRule;
   mozilla::SheetType mLevel;
-  nsStyleContext* const mStyleContext;
+  mozilla::GeckoStyleContext* const mStyleContext;
 
   // We store nsCSSValues needed to compute the data for one or more
   // style structs (specified by the bitfield mSIDs).  These are stored
   // in a single array allocation (which our caller allocates; see
   // AutoCSSValueArray)   The offset of each property |prop| in
   // mValueStorage is the sum of
   // mValueOffsets[nsCSSProps::kSIDTable[prop]] and
   // nsCSSProps::PropertyIndexInStruct(prop).  The only place we gather
@@ -47,17 +50,17 @@ struct nsRuleData final : mozilla::Gener
   nsCSSValue* const mValueStorage; // our user owns this array
   size_t mValueOffsets[nsStyleStructID_Length];
 
   nsAutoPtr<mozilla::CSSVariableDeclarations> mVariables;
 
   nsRuleData(uint32_t aSIDs,
              nsCSSValue* aValueStorage,
              nsPresContext* aContext,
-             nsStyleContext* aStyleContext);
+             mozilla::GeckoStyleContext* aStyleContext);
 
 #ifdef DEBUG
   ~nsRuleData();
 #else
   ~nsRuleData() {}
 #endif
 
   /**
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -624,30 +624,31 @@ static nscoord CalcLengthWith(const nsCS
         // the root element, in which case aFontSize is already the
         // value we want.
         if (aFontSize == -1) {
           // XXX Should this be styleFont->mSize instead to avoid taking
           // minfontsize prefs into account?
           aFontSize = styleFont->mFont.size;
         }
         rootFontSize = aFontSize;
-      } else if (aStyleContext && !aStyleContext->GetParent()) {
+      // FIXME(emilio, bug 1384656): We can reach this from servo right now...
+      } else if (aStyleContext && !aStyleContext->AsGecko()->GetParent()) {
         // This is the root element (XXX we don't really know this, but
         // nsRuleNode::SetFont makes the same assumption!), so we should
         // use StyleFont on this context to get the root element's
         // font size.
         rootFontSize = styleFont->mFont.size;
       } else {
         // This is not the root element or we are calculating something other
         // than font size, so rem is relative to the root element's font size.
         // Find the root style context by walking up the style context tree.
         // NOTE: We should not call ResolveStyleFor() against the root element
         // to obtain the root style here because it may lead to reentrant call
         // of nsStyleSet::GetContext().
-        nsStyleContext* rootStyle = aStyleContext;
+        GeckoStyleContext* rootStyle = aStyleContext->AsGecko();
         while (rootStyle->GetParent()) {
           rootStyle = rootStyle->GetParent();
         }
         const nsStyleFont *rootStyleFont = rootStyle->StyleFont();
         rootFontSize = rootStyleFont->mFont.size;
       }
 
       return ScaleCoordRound(aValue, float(rootFontSize));
@@ -1105,17 +1106,17 @@ SetPairCoords(const nsCSSValue& aValue,
                        aPresContext, aConditions);
   mozilla::DebugOnly<bool> cY = SetCoord(valY, aCoordY, aParentY, aMask,
                        aStyleContext, aPresContext, aConditions);
   MOZ_ASSERT(cX == cY, "changed one but not the other");
   return cX;
 }
 
 static bool SetColor(const nsCSSValue& aValue, const nscolor aParentColor,
-                       nsPresContext* aPresContext, nsStyleContext *aContext,
+                       nsPresContext* aPresContext, nsStyleContext* aContext,
                        nscolor& aResult, RuleNodeCacheConditions& aConditions)
 {
   bool    result = false;
   nsCSSUnit unit = aValue.GetUnit();
 
   if (aValue.IsNumericColorUnit()) {
     aResult = aValue.GetColorValue();
     result = true;
@@ -10503,28 +10504,21 @@ nsRuleNode::GetDiscretelyAnimatedCSSValu
     }
     if (rule->GetDiscretelyAnimatedCSSValue(aProperty, aValue)) {
       return;
     }
   }
 }
 
 /* static */ bool
-nsRuleNode::HasAuthorSpecifiedRules(nsStyleContext* aStyleContext,
+nsRuleNode::HasAuthorSpecifiedRules(GeckoStyleContext* aStyleContext,
                                     uint32_t ruleTypeMask,
                                     bool aAuthorColorsAllowed)
 {
-#ifdef MOZ_STYLO
-  if (aStyleContext->IsServo()) {
-    NS_WARNING("stylo: nsRuleNode::HasAuthorSpecifiedRules not implemented");
-    return true;
-  }
-#endif
-
-  RefPtr<GeckoStyleContext> styleContext = aStyleContext->AsGecko();
+  RefPtr<GeckoStyleContext> styleContext = aStyleContext;
 
   uint32_t inheritBits = 0;
   if (ruleTypeMask & NS_AUTHOR_SPECIFIED_BACKGROUND)
     inheritBits |= NS_STYLE_INHERIT_BIT(Background);
 
   if (ruleTypeMask & NS_AUTHOR_SPECIFIED_BORDER)
     inheritBits |= NS_STYLE_INHERIT_BIT(Border);
 
--- a/layout/style/nsRuleNode.h
+++ b/layout/style/nsRuleNode.h
@@ -27,18 +27,18 @@ class nsFontMetrics;
 class nsIStyleRule;
 class nsStyleCoord;
 struct nsCSSRect;
 struct nsCSSValueList;
 struct nsCSSValuePairList;
 struct nsRuleData;
 
 namespace mozilla {
-  class GeckoStyleContext;
-}
+class GeckoStyleContext;
+} // namespace mozilla
 
 struct nsInheritedStyleData
 {
   mozilla::RangedArray<void*,
                        nsStyleStructID_Inherited_Start,
                        nsStyleStructID_Inherited_Count> mStyleStructs;
 
   void* operator new(size_t sz, nsPresContext* aContext) {
@@ -987,17 +987,17 @@ public:
   }
 
   #include "nsStyleStructList.h"
 
   #undef STYLE_STRUCT_RESET
   #undef STYLE_STRUCT_INHERITED
 
   static bool
-    HasAuthorSpecifiedRules(nsStyleContext* aStyleContext,
+    HasAuthorSpecifiedRules(mozilla::GeckoStyleContext* aStyleContext,
                             uint32_t ruleTypeMask,
                             bool aAuthorColorsAllowed);
 
   /**
    * Fill in to aPropertiesOverridden all of the properties in aProperties
    * that, for this rule node, have a declaration that is higher than the
    * animation level in the CSS Cascade.
    */
@@ -1005,17 +1005,23 @@ public:
   ComputePropertiesOverridingAnimation(
                               const nsTArray<nsCSSPropertyID>& aProperties,
                               mozilla::GeckoStyleContext* aStyleContext,
                               nsCSSPropertyIDSet& aPropertiesOverridden);
 
   // Expose this so media queries can use it
   static nscoord CalcLengthWithInitialFont(nsPresContext* aPresContext,
                                            const nsCSSValue& aValue);
+
   // Expose this so nsTransformFunctions can use it.
+  //
+  // FIXME(emilio): This can enter here with a Servo style context, which will
+  // mostly be fine except for our handling of rem units, I think.
+  //
+  // Ditto in SpecifiedCalcToComputedCalc.
   static nscoord CalcLength(const nsCSSValue& aValue,
                             nsStyleContext* aStyleContext,
                             nsPresContext* aPresContext,
                             mozilla::RuleNodeCacheConditions& aConditions);
 
   struct ComputedCalc {
     nscoord mLength;
     float mPercent;
--- a/layout/style/nsStyleContext.h
+++ b/layout/style/nsStyleContext.h
@@ -86,22 +86,16 @@ public:
 
   uint32_t FrameRefCnt() const {
     return mFrameRefCnt;
   }
 #endif
 
   inline nsPresContext* PresContext() const;
 
-  inline mozilla::GeckoStyleContext* GetParent() const;
-
-  nsStyleContext* GetParentAllowServo() const {
-    return mParent;
-  }
-
   nsIAtom* GetPseudo() const { return mPseudoTag; }
   mozilla::CSSPseudoElementType GetPseudoType() const {
     return static_cast<mozilla::CSSPseudoElementType>(
              mBits >> NS_STYLE_CONTEXT_TYPE_SHIFT);
   }
 
   bool IsAnonBox() const {
     return
--- a/layout/style/nsStyleContextInlines.h
+++ b/layout/style/nsStyleContextInlines.h
@@ -186,34 +186,16 @@ nsStyleContext::PresContext() const
 
 
 nsStyleContext*
 nsStyleContext::GetStyleIfVisited() const
 {
   MOZ_STYLO_FORWARD(GetStyleIfVisited, ())
 }
 
-mozilla::GeckoStyleContext*
-nsStyleContext::GetParent() const
-{
-  MOZ_ASSERT(IsGecko(),
-             "This should be used only in Gecko-backed style system!");
-  if (mParent) {
-    return mParent->AsGecko();
-  } else {
-    return nullptr;
-  }
-}
-
-bool
-nsStyleContext::IsLinkContext() const
-{
-  return GetStyleIfVisited() && GetStyleIfVisited()->GetParent() == GetParent();
-}
-
 void
 nsStyleContext::StartBackgroundImageLoads()
 {
   // Just get our background struct; that should do the trick
   StyleBackground();
 }
 
 #endif // nsStyleContextInlines_h
--- a/layout/tables/nsTableColGroupFrame.cpp
+++ b/layout/tables/nsTableColGroupFrame.cpp
@@ -294,17 +294,17 @@ nsTableColGroupFrame::RemoveFrame(ChildL
       nsTableColFrame* col = colFrame->GetNextCol();
       nsTableColFrame* nextCol;
       while (col && col->GetColType() == eColAnonymousCol) {
 #ifdef DEBUG
         nsIFrame* providerFrame;
         nsStyleContext* psc = colFrame->GetParentStyleContext(&providerFrame);
         if (psc->IsGecko()) {
           // This check code is useful only in Gecko-backed style system.
-          if (static_cast<nsStyleContext*>(colFrame->StyleContext()->GetParent()) == psc) {
+          if (colFrame->StyleContext()->AsGecko()->GetParent() == psc->AsGecko()) {
             NS_ASSERTION(col->StyleContext() == colFrame->StyleContext() &&
                          col->GetContent() == colFrame->GetContent(),
                          "How did that happen??");
           }
           // else colFrame is being removed because of a frame
           // reconstruct on it, and its style context is still the old
           // one, so we can't assert anything about how it compares to
           // col's style context.
--- a/layout/xul/nsSplitterFrame.cpp
+++ b/layout/xul/nsSplitterFrame.cpp
@@ -280,21 +280,26 @@ nsSplitterFrame::Init(nsIContent*       
   // XXXbz this is pretty messed up, since this can change whether we should
   // have a frame at all.  This really needs a better solution.
   if (aParent && aParent->IsXULBoxFrame()) {
     if (!aParent->IsXULHorizontal()) {
       if (!nsContentUtils::HasNonEmptyAttr(aContent, kNameSpaceID_None,
                                            nsGkAtoms::orient)) {
         aContent->SetAttr(kNameSpaceID_None, nsGkAtoms::orient,
                           NS_LITERAL_STRING("vertical"), false);
-        GeckoStyleContext* parentStyleContext = StyleContext()->GetParent();
-        RefPtr<nsStyleContext> newContext = PresContext()->StyleSet()->
-          ResolveStyleFor(aContent->AsElement(), parentStyleContext,
-                          LazyComputeBehavior::Allow);
-        SetStyleContextWithoutNotification(newContext);
+        if (StyleContext()->IsGecko()) {
+          // FIXME(emilio): Even if we did this in Servo, this just won't
+          // work, and we'd need a specific "really re-resolve the style" API...
+          GeckoStyleContext* parentStyleContext =
+            StyleContext()->AsGecko()->GetParent();
+          RefPtr<nsStyleContext> newContext = PresContext()->StyleSet()->
+            ResolveStyleFor(aContent->AsElement(), parentStyleContext,
+                            LazyComputeBehavior::Allow);
+          SetStyleContextWithoutNotification(newContext);
+        }
       }
     }
   }
 
   nsBoxFrame::Init(aContent, aParent, aPrevInFlow);
 
   mInner->mState = nsSplitterFrameInner::Open;
   mInner->AddListener();