Bug 1432490: Make nsComputedDOMStyle::GetStyleContext / GetStyleContextNoFlush not take a presShell. r=bz
authorEmilio Cobos Álvarez <emilio@crisal.io>
Tue, 23 Jan 2018 15:49:00 +0100
changeset 460213 01dbdfc733d262f13a10b205d9b725b071737abc
parent 460212 b636251b75ab5280b1f473b0e8cf57853f846d83
child 460214 319210e2f742b3935869ed06f76a27c49b011c5d
push id1683
push usersfraser@mozilla.com
push dateThu, 26 Apr 2018 16:43:40 +0000
treeherdermozilla-release@5af6cb21869d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs1432490
milestone60.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1432490: Make nsComputedDOMStyle::GetStyleContext / GetStyleContextNoFlush not take a presShell. r=bz Everyone calls them with the shell of the current composed document, and this allows the multi-presShell stuff to just be in UpdateCurrentStyleSources / DoGetStyleContextNoFlush. The only reason we need to use OwnerDoc()->GetShell() instead of the composed doc in GetStyleContext / GetStyleContextNoFlush is Element::GetBindingURL, which does expect to get the binding URL for stuff outside of the composed doc (and changing that gave me a useless browser). That's technically a behavior change on the cases that used to pass nullptr, but I think all callers are fine with that. I could also just add a special function for that particular case, it may be worth it. MozReview-Commit-ID: 2XlnkgdgDCK
accessible/base/StyleInfo.cpp
accessible/base/StyleInfo.h
accessible/generic/Accessible.cpp
dom/animation/KeyframeEffectReadOnly.cpp
dom/base/Element.cpp
dom/base/nsDOMWindowUtils.cpp
dom/base/nsPlainTextSerializer.cpp
dom/base/nsRange.cpp
dom/base/nsXHTMLContentSerializer.cpp
dom/canvas/CanvasRenderingContext2D.cpp
dom/html/nsGenericHTMLElement.cpp
dom/smil/nsSMILCSSValueType.cpp
dom/smil/nsSMILCompositor.cpp
dom/svg/SVGContentUtils.cpp
dom/svg/SVGGeometryElement.cpp
dom/svg/SVGPathElement.cpp
editor/libeditor/CSSEditUtils.cpp
editor/libeditor/EditorBase.cpp
layout/inspector/InspectorUtils.cpp
layout/style/StyleAnimationValue.cpp
layout/style/nsComputedDOMStyle.cpp
layout/style/nsComputedDOMStyle.h
--- a/accessible/base/StyleInfo.cpp
+++ b/accessible/base/StyleInfo.cpp
@@ -9,21 +9,21 @@
 #include "mozilla/dom/Element.h"
 #include "nsComputedDOMStyle.h"
 #include "nsCSSProps.h"
 #include "nsIFrame.h"
 
 using namespace mozilla;
 using namespace mozilla::a11y;
 
-StyleInfo::StyleInfo(dom::Element* aElement, nsIPresShell* aPresShell) :
+StyleInfo::StyleInfo(dom::Element* aElement) :
   mElement(aElement)
 {
   mStyleContext =
-    nsComputedDOMStyle::GetStyleContextNoFlush(aElement, nullptr, aPresShell);
+    nsComputedDOMStyle::GetStyleContextNoFlush(aElement, nullptr);
 }
 
 void
 StyleInfo::Display(nsAString& aValue)
 {
   aValue.Truncate();
   AppendASCIItoUTF16(
     nsCSSProps::ValueToKeyword(mStyleContext->StyleDisplay()->mDisplay,
--- a/accessible/base/StyleInfo.h
+++ b/accessible/base/StyleInfo.h
@@ -11,17 +11,17 @@
 #include "nsStyleContext.h"
 
 namespace mozilla {
 namespace a11y {
 
 class StyleInfo
 {
 public:
-  StyleInfo(dom::Element* aElement, nsIPresShell* aPresShell);
+  explicit StyleInfo(dom::Element* aElement);
   ~StyleInfo() { }
 
   void Display(nsAString& aValue);
   void TextAlign(nsAString& aValue);
   void TextIndent(nsAString& aValue);
   void MarginLeft(nsAString& aValue) { Margin(eSideLeft, aValue); }
   void MarginRight(nsAString& aValue) { Margin(eSideRight, aValue); }
   void MarginTop(nsAString& aValue) { Margin(eSideTop, aValue); }
--- a/accessible/generic/Accessible.cpp
+++ b/accessible/generic/Accessible.cpp
@@ -1080,17 +1080,17 @@ Accessible::NativeAttributes()
 
   // Don't calculate CSS-based object attributes when no frame (i.e.
   // the accessible is unattached from the tree).
   if (!mContent->GetPrimaryFrame())
     return attributes.forget();
 
   // CSS style based object attributes.
   nsAutoString value;
-  StyleInfo styleInfo(mContent->AsElement(), mDoc->PresShell());
+  StyleInfo styleInfo(mContent->AsElement());
 
   // Expose 'display' attribute.
   styleInfo.Display(value);
   nsAccUtils::SetAccAttr(attributes, nsGkAtoms::display, value);
 
   // Expose 'text-align' attribute.
   styleInfo.TextAlign(value);
   nsAccUtils::SetAccAttr(attributes, nsGkAtoms::textAlign, value);
--- a/dom/animation/KeyframeEffectReadOnly.cpp
+++ b/dom/animation/KeyframeEffectReadOnly.cpp
@@ -1090,29 +1090,28 @@ KeyframeEffectReadOnly::RequestRestyle(
       RequestRestyle(mTarget->mElement, mTarget->mPseudoType,
                      aRestyleType, mAnimation->CascadeLevel());
   }
 }
 
 already_AddRefed<nsStyleContext>
 KeyframeEffectReadOnly::GetTargetStyleContext()
 {
-  nsIPresShell* shell = GetPresShell();
-  if (!shell) {
+  if (!GetRenderedDocument()) {
     return nullptr;
   }
 
   MOZ_ASSERT(mTarget,
-             "Should only have a presshell when we have a target element");
+             "Should only have a document when we have a target element");
 
   nsAtom* pseudo = mTarget->mPseudoType < CSSPseudoElementType::Count
                     ? nsCSSPseudoElements::GetPseudoAtom(mTarget->mPseudoType)
                     : nullptr;
 
-  return nsComputedDOMStyle::GetStyleContext(mTarget->mElement, pseudo, shell);
+  return nsComputedDOMStyle::GetStyleContext(mTarget->mElement, pseudo);
 }
 
 #ifdef DEBUG
 void
 DumpAnimationProperties(nsTArray<AnimationProperty>& aAnimationProperties)
 {
   for (auto& p : aAnimationProperties) {
     printf("%s\n", nsCSSProps::GetStringValue(p.mProperty).get());
--- a/dom/base/Element.cpp
+++ b/dom/base/Element.cpp
@@ -531,47 +531,40 @@ Element::GetBindingURL(nsIDocument *aDoc
 {
   // If we have a frame the frame has already loaded the binding.  And
   // otherwise, don't do anything else here unless we're dealing with
   // XUL or an HTML element that may have a plugin-related overlay
   // (i.e. object or embed).
   bool isXULorPluginElement = (IsXULElement() ||
                                IsHTMLElement(nsGkAtoms::object) ||
                                IsHTMLElement(nsGkAtoms::embed));
-  nsIPresShell* shell = aDocument->GetShell();
-  if (!shell || GetPrimaryFrame() || !isXULorPluginElement) {
+  if (!aDocument->GetShell() || GetPrimaryFrame() || !isXULorPluginElement) {
     *aResult = nullptr;
     return true;
   }
 
   // Get the computed -moz-binding directly from the style context
   RefPtr<nsStyleContext> sc =
-    nsComputedDOMStyle::GetStyleContextNoFlush(this, nullptr, shell);
+    nsComputedDOMStyle::GetStyleContextNoFlush(this, nullptr);
   NS_ENSURE_TRUE(sc, false);
 
   NS_IF_ADDREF(*aResult = sc->StyleDisplay()->mBinding);
   return true;
 }
 
 JSObject*
 Element::WrapObject(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
 {
   JS::Rooted<JSObject*> obj(aCx, nsINode::WrapObject(aCx, aGivenProto));
   if (!obj) {
     return nullptr;
   }
 
-  nsIDocument* doc;
-  if (HasFlag(NODE_FORCE_XBL_BINDINGS)) {
-    doc = OwnerDoc();
-  }
-  else {
-    doc = GetComposedDoc();
-  }
-
+  nsIDocument* doc =
+    HasFlag(NODE_FORCE_XBL_BINDINGS) ? OwnerDoc() : GetComposedDoc();
   if (!doc) {
     // There's no baseclass that cares about this call so we just
     // return here.
     return obj;
   }
 
   // We must ensure that the XBL Binding is installed before we hand
   // back this object.
@@ -1530,17 +1523,17 @@ void
 Element::GetElementsWithGrid(nsTArray<RefPtr<Element>>& aElements)
 {
   // This helper function is passed to GetElementsByMatching()
   // to identify elements with styling which will cause them to
   // generate a nsGridContainerFrame during layout.
   auto IsDisplayGrid = [](Element* aElement) -> bool
   {
     RefPtr<nsStyleContext> styleContext =
-      nsComputedDOMStyle::GetStyleContext(aElement, nullptr, nullptr);
+      nsComputedDOMStyle::GetStyleContext(aElement, nullptr);
     if (styleContext) {
       const nsStyleDisplay* display = styleContext->StyleDisplay();
       return (display->mDisplay == StyleDisplay::Grid ||
               display->mDisplay == StyleDisplay::InlineGrid);
     }
     return false;
   };
 
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -2722,22 +2722,18 @@ nsDOMWindowUtils::ComputeAnimationDistan
 
   Element* element = content->AsElement();
   AnimationValue v1 = AnimationValue::FromString(property, aValue1, element);
   AnimationValue v2 = AnimationValue::FromString(property, aValue2, element);
   if (v1.IsNull() || v2.IsNull()) {
     return NS_ERROR_ILLEGAL_VALUE;
   }
 
-  RefPtr<nsStyleContext> styleContext;
-  nsIDocument* doc = element->GetComposedDoc();
-  if (doc && doc->GetShell()) {
-    styleContext =
-      nsComputedDOMStyle::GetStyleContext(element, nullptr, doc->GetShell());
-  }
+  RefPtr<nsStyleContext> styleContext =
+    nsComputedDOMStyle::GetStyleContext(element, nullptr);
   *aResult = v1.ComputeDistance(property, v2, styleContext);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMWindowUtils::GetAnimationTypeForLonghand(const nsAString& aProperty,
                                               nsAString& aResult)
 {
@@ -2809,35 +2805,33 @@ nsDOMWindowUtils::GetUnanimatedComputedS
       nsCSSProps::IsShorthand(propertyID)) {
     return NS_ERROR_INVALID_ARG;
   }
 
   switch (aFlushType) {
     case FLUSH_NONE:
       break;
     case FLUSH_STYLE: {
-      nsIDocument* doc = element->GetComposedDoc();
-      if (doc) {
+      if (nsIDocument* doc = element->GetComposedDoc()) {
         doc->FlushPendingNotifications(FlushType::Style);
       }
       break;
     }
     default:
       return NS_ERROR_INVALID_ARG;
   }
 
   nsIPresShell* shell = GetPresShell();
   if (!shell) {
     return NS_ERROR_FAILURE;
   }
 
   RefPtr<nsAtom> pseudo = nsCSSPseudoElements::GetPseudoAtom(aPseudoElement);
   RefPtr<nsStyleContext> styleContext =
-    nsComputedDOMStyle::GetUnanimatedStyleContextNoFlush(element,
-                                                         pseudo, shell);
+    nsComputedDOMStyle::GetUnanimatedStyleContextNoFlush(element, pseudo);
   if (!styleContext) {
     return NS_ERROR_FAILURE;
   }
 
   if (styleContext->IsServo()) {
     RefPtr<RawServoAnimationValue> value =
       Servo_ComputedValues_ExtractAnimationValue(styleContext->AsServo(),
                                                  propertyID).Consume();
--- a/dom/base/nsPlainTextSerializer.cpp
+++ b/dom/base/nsPlainTextSerializer.cpp
@@ -1847,30 +1847,30 @@ nsPlainTextSerializer::IsInPre()
 {
   return !mPreformatStack.empty() && mPreformatStack.top();
 }
 
 bool
 nsPlainTextSerializer::IsElementPreformatted(Element* aElement)
 {
   RefPtr<nsStyleContext> styleContext =
-    nsComputedDOMStyle::GetStyleContextNoFlush(aElement, nullptr, nullptr);
+    nsComputedDOMStyle::GetStyleContextNoFlush(aElement, nullptr);
   if (styleContext) {
     const nsStyleText* textStyle = styleContext->StyleText();
     return textStyle->WhiteSpaceOrNewlineIsSignificant();
   }
   // Fall back to looking at the tag, in case there is no style information.
   return GetIdForContent(aElement) == nsGkAtoms::pre;
 }
 
 bool
 nsPlainTextSerializer::IsElementBlock(Element* aElement)
 {
   RefPtr<nsStyleContext> styleContext =
-    nsComputedDOMStyle::GetStyleContextNoFlush(aElement, nullptr, nullptr);
+    nsComputedDOMStyle::GetStyleContextNoFlush(aElement, nullptr);
   if (styleContext) {
     const nsStyleDisplay* displayStyle = styleContext->StyleDisplay();
     return displayStyle->IsBlockOutsideStyle();
   }
   // Fall back to looking at the tag, in case there is no style information.
   return nsContentUtils::IsHTMLBlock(aElement);
 }
 
--- a/dom/base/nsRange.cpp
+++ b/dom/base/nsRange.cpp
@@ -3761,17 +3761,17 @@ IsVisibleAndNotInReplacedElement(nsIFram
 
 static bool
 ElementIsVisibleNoFlush(Element* aElement)
 {
   if (!aElement) {
     return false;
   }
   RefPtr<nsStyleContext> sc =
-    nsComputedDOMStyle::GetStyleContextNoFlush(aElement, nullptr, nullptr);
+    nsComputedDOMStyle::GetStyleContextNoFlush(aElement, nullptr);
   return sc && sc->StyleVisibility()->IsVisible();
 }
 
 static void
 AppendTransformedText(InnerTextAccumulator& aResult, nsIContent* aContainer)
 {
   auto textNode = static_cast<nsGenericDOMDataNode*>(aContainer);
 
--- a/dom/base/nsXHTMLContentSerializer.cpp
+++ b/dom/base/nsXHTMLContentSerializer.cpp
@@ -716,18 +716,17 @@ bool
 nsXHTMLContentSerializer::IsElementPreformatted(nsIContent* aNode)
 {
   MOZ_ASSERT(ShouldMaintainPreLevel(), "We should not be calling this needlessly");
 
   if (!aNode->IsElement()) {
     return false;
   }
   RefPtr<nsStyleContext> styleContext =
-    nsComputedDOMStyle::GetStyleContextNoFlush(aNode->AsElement(),
-                                               nullptr, nullptr);
+    nsComputedDOMStyle::GetStyleContextNoFlush(aNode->AsElement(), nullptr);
   if (styleContext) {
     const nsStyleText* textStyle = styleContext->StyleText();
     return textStyle->WhiteSpaceOrNewlineIsSignificant();
   }
   return false;
 }
 
 bool
--- a/dom/canvas/CanvasRenderingContext2D.cpp
+++ b/dom/canvas/CanvasRenderingContext2D.cpp
@@ -1196,17 +1196,17 @@ CanvasRenderingContext2D::ParseColor(con
                                       &wasCurrentColor, loader)) {
       return false;
     }
 
     if (wasCurrentColor && mCanvasElement) {
       // Otherwise, get the value of the color property, flushing style
       // if necessary.
       RefPtr<nsStyleContext> canvasStyle =
-        nsComputedDOMStyle::GetStyleContext(mCanvasElement, nullptr, presShell);
+        nsComputedDOMStyle::GetStyleContext(mCanvasElement, nullptr);
       if (canvasStyle) {
         *aColor = canvasStyle->StyleColor()->mColor;
       }
       // Beware that the presShell could be gone here.
     }
     return true;
   }
 
@@ -1223,19 +1223,18 @@ CanvasRenderingContext2D::ParseColor(con
     // if we already have a color we can just use it directly
     *aColor = value.GetColorValue();
   } else {
     // otherwise resolve it
     nsCOMPtr<nsIPresShell> presShell = GetPresShell();
     RefPtr<nsStyleContext> parentContext;
     if (mCanvasElement && mCanvasElement->IsInUncomposedDoc()) {
       // Inherit from the canvas element.
-      parentContext = nsComputedDOMStyle::GetStyleContext(mCanvasElement,
-                                                          nullptr,
-                                                          presShell);
+      parentContext =
+        nsComputedDOMStyle::GetStyleContext(mCanvasElement, nullptr);
     }
 
     Unused << nsRuleNode::ComputeColor(
       value, presShell ? presShell->GetPresContext() : nullptr, parentContext,
       *aColor);
   }
   return true;
 #else
@@ -1998,30 +1997,28 @@ void
 CanvasRenderingContext2D::ClearTarget()
 {
   Reset();
 
   mResetLayer = true;
 
   SetInitialState();
 
+  if (!mCanvasElement || !mCanvasElement->IsInUncomposedDoc()) {
+    return;
+  }
+
   // For vertical writing-mode, unless text-orientation is sideways,
   // we'll modify the initial value of textBaseline to 'middle'.
-  RefPtr<nsStyleContext> canvasStyle;
-  if (mCanvasElement && mCanvasElement->IsInUncomposedDoc()) {
-    nsCOMPtr<nsIPresShell> presShell = GetPresShell();
-    if (presShell) {
-      canvasStyle =
-        nsComputedDOMStyle::GetStyleContext(mCanvasElement, nullptr, presShell);
-      if (canvasStyle) {
-        WritingMode wm(canvasStyle);
-        if (wm.IsVertical() && !wm.IsSideways()) {
-          CurrentState().textBaseline = TextBaseline::MIDDLE;
-        }
-      }
+  RefPtr<nsStyleContext> canvasStyle =
+    nsComputedDOMStyle::GetStyleContext(mCanvasElement, nullptr);
+  if (canvasStyle) {
+    WritingMode wm(canvasStyle);
+    if (wm.IsVertical() && !wm.IsSideways()) {
+      CurrentState().textBaseline = TextBaseline::MIDDLE;
     }
   }
 }
 
 void
 CanvasRenderingContext2D::ReturnTarget(bool aForceReset)
 {
   if (mTarget && mBufferProvider && mTarget != sErrorTarget) {
@@ -2733,28 +2730,29 @@ CreateFontDeclaration(const nsAString& a
 {
   bool lineHeightChanged;
   return CreateDeclaration(aNode,
     eCSSProperty_font, aFont, aOutFontChanged,
     eCSSProperty_line_height, NS_LITERAL_STRING("normal"), &lineHeightChanged);
 }
 
 static already_AddRefed<GeckoStyleContext>
-GetFontParentStyleContext(Element* aElement, nsIPresShell* aPresShell,
+GetFontParentStyleContext(Element* aElement,
+                          nsIPresShell* aPresShell,
                           ErrorResult& aError)
 {
   if (aElement && aElement->IsInUncomposedDoc()) {
     // Inherit from the canvas element.
     RefPtr<nsStyleContext> result =
-      nsComputedDOMStyle::GetStyleContext(aElement, nullptr, aPresShell);
+      nsComputedDOMStyle::GetStyleContext(aElement, nullptr);
     if (!result) {
       aError.Throw(NS_ERROR_FAILURE);
       return nullptr;
     }
-    return already_AddRefed<GeckoStyleContext>(result.forget().take()->AsGecko());
+    return GeckoStyleContext::TakeRef(result.forget());
   }
 
   // otherwise inherit from default (10px sans-serif)
 
   bool changed;
   RefPtr<css::Declaration> parentRule =
     CreateFontDeclaration(NS_LITERAL_STRING("10px sans-serif"),
                           aPresShell->GetDocument(), &changed);
@@ -2913,51 +2911,44 @@ GetFontStyleForServo(Element* aElement, 
   // at font-size-adjust, which the font shorthand resets to 'none'.
   if (Servo_DeclarationBlock_HasCSSWideKeyword(declarations,
                                                eCSSProperty_font_size_adjust)) {
     return nullptr;
   }
 
   ServoStyleSet* styleSet = aPresShell->StyleSet()->AsServo();
 
-  RefPtr<ServoStyleContext> parentStyle;
+  RefPtr<nsStyleContext> parentStyle;
   // have to get a parent style context for inherit-like relative
   // values (2em, bolder, etc.)
   if (aElement && aElement->IsInUncomposedDoc()) {
-    // Inherit from the canvas element.
-    aPresShell->FlushPendingNotifications(FlushType::Style);
-    // We need to use ResolveStyleLazily, which involves traversal,
-    // instead of ResolvestyleFor() because we need up-to-date style even if
-    // the canvas element is display:none.
-    parentStyle =
-      styleSet->ResolveStyleLazily(aElement, CSSPseudoElementType::NotPseudo);
+    parentStyle = nsComputedDOMStyle::GetStyleContext(aElement, nullptr);
   } else {
     RefPtr<RawServoDeclarationBlock> declarations =
       CreateFontDeclarationForServo(NS_LITERAL_STRING("10px sans-serif"),
                                     aPresShell->GetDocument());
     MOZ_ASSERT(declarations);
 
     parentStyle = aPresShell->StyleSet()->AsServo()->
       ResolveForDeclarations(nullptr, declarations);
   }
 
   MOZ_RELEASE_ASSERT(parentStyle, "Should have a valid parent style");
 
   MOZ_ASSERT(!aPresShell->IsDestroying(),
              "GetFontParentStyleContext should have returned an error if the presshell is being destroyed.");
 
   RefPtr<ServoStyleContext> sc =
-    styleSet->ResolveForDeclarations(parentStyle, declarations);
+    styleSet->ResolveForDeclarations(parentStyle->AsServo(), declarations);
 
   // The font getter is required to be reserialized based on what we
   // parsed (including having line-height removed).  (Older drafts of
   // the spec required font sizes be converted to pixels, but that no
   // longer seems to be required.)
   Servo_SerializeFontValueForCanvas(declarations, &aOutUsedFont);
-
   return sc.forget();
 }
 
 #ifdef MOZ_OLD_STYLE
 static already_AddRefed<Declaration>
 CreateFilterDeclaration(const nsAString& aFilter,
                         nsINode* aNode,
                         bool* aOutFilterChanged)
@@ -4583,17 +4574,17 @@ CanvasRenderingContext2D::DrawOrMeasureT
 
   // for now, default to ltr if not in doc
   bool isRTL = false;
 
   RefPtr<nsStyleContext> canvasStyle;
   if (mCanvasElement && mCanvasElement->IsInUncomposedDoc()) {
     // try to find the closest context
     canvasStyle =
-      nsComputedDOMStyle::GetStyleContext(mCanvasElement, nullptr, presShell);
+      nsComputedDOMStyle::GetStyleContext(mCanvasElement, nullptr);
     if (!canvasStyle) {
       return NS_ERROR_FAILURE;
     }
 
     isRTL = canvasStyle->StyleVisibility()->mDirection ==
       NS_STYLE_DIRECTION_RTL;
   } else {
     isRTL = GET_BIDI_OPTION_DIRECTION(document->GetBidiOptions()) == IBMBIDI_TEXTDIRECTION_RTL;
--- a/dom/html/nsGenericHTMLElement.cpp
+++ b/dom/html/nsGenericHTMLElement.cpp
@@ -2970,16 +2970,21 @@ nsGenericHTMLElement::NewURIFromString(c
   }
 
   return NS_OK;
 }
 
 static bool
 IsOrHasAncestorWithDisplayNone(Element* aElement, nsIPresShell* aPresShell)
 {
+  // FIXME(emilio): In the servo case it should suffice to do something like:
+  //
+  // return !aElement->HasServoData() || Servo_Element_IsDisplayNone(aElement);
+  //
+  // at least in the case the element is part of the flattened tree...
   AutoTArray<Element*, 10> elementsToCheck;
   // Style and layout work on the flattened tree, so this is what we need to
   // check in order to figure out whether we're in a display: none subtree.
   for (Element* e = aElement; e; e = e->GetFlattenedTreeParentElement()) {
     if (e->GetPrimaryFrame()) {
       // e definitely isn't display:none and doesn't have a display:none
       // ancestor.
       break;
@@ -3000,18 +3005,17 @@ IsOrHasAncestorWithDisplayNone(Element* 
                                        LazyComputeBehavior::Assert);
       } else {
         // Call ResolveStyleLazily to protect against stale element data in
         // the tree when styled by Servo.
         sc = styleSet->AsServo()->ResolveStyleLazily(
             element, CSSPseudoElementType::NotPseudo);
       }
     } else {
-      sc = nsComputedDOMStyle::GetStyleContextNoFlush(element,
-                                                      nullptr, aPresShell);
+      sc = nsComputedDOMStyle::GetStyleContextNoFlush(element, nullptr);
     }
     if (sc->StyleDisplay()->mDisplay == StyleDisplay::None) {
       return true;
     }
   }
 
   return false;
 }
--- a/dom/smil/nsSMILCSSValueType.cpp
+++ b/dom/smil/nsSMILCSSValueType.cpp
@@ -782,18 +782,17 @@ nsSMILCSSValueType::ValueFromString(nsCS
                                                 doc->NodePrincipal(),
                                                 nullptr,
                                                 doc->GetDocumentURI(),
                                                 0, aString, nullptr)) {
     return;
   }
 
   RefPtr<nsStyleContext> styleContext =
-    nsComputedDOMStyle::GetStyleContext(aTargetElement, nullptr,
-                                        presContext->PresShell());
+    nsComputedDOMStyle::GetStyleContext(aTargetElement, nullptr);
   if (!styleContext) {
     return;
   }
 
   if (styleContext->IsServo()) {
     ServoAnimationValues parsedValues =
       ValueFromStringHelper(aPropID, aTargetElement, presContext,
                             styleContext, aString);
--- a/dom/smil/nsSMILCompositor.cpp
+++ b/dom/smil/nsSMILCompositor.cpp
@@ -56,17 +56,17 @@ nsSMILCompositor::ComposeAttribute(bool&
     return;
 
   // If we might need to resolve base styles, grab a suitable style context
   // for initializing our nsISMILAttr with.
   RefPtr<nsStyleContext> baseStyleContext;
   if (MightNeedBaseStyle()) {
     baseStyleContext =
       nsComputedDOMStyle::GetUnanimatedStyleContextNoFlush(mKey.mElement,
-                                                           nullptr, nullptr);
+                                                           nullptr);
   }
 
   // FIRST: Get the nsISMILAttr (to grab base value from, and to eventually
   // give animated value to)
   UniquePtr<nsISMILAttr> smilAttr = CreateSMILAttr(baseStyleContext);
   if (!smilAttr) {
     // Target attribute not found (or, out of memory)
     return;
--- a/dom/svg/SVGContentUtils.cpp
+++ b/dom/svg/SVGContentUtils.cpp
@@ -175,17 +175,17 @@ SVGContentUtils::GetStrokeOptions(AutoSt
                                   SVGContextPaint* aContextPaint,
                                   StrokeOptionFlags aFlags)
 {
   RefPtr<nsStyleContext> styleContext;
   if (aStyleContext) {
     styleContext = aStyleContext;
   } else {
     styleContext =
-      nsComputedDOMStyle::GetStyleContextNoFlush(aElement, nullptr, nullptr);
+      nsComputedDOMStyle::GetStyleContextNoFlush(aElement, nullptr);
   }
 
   if (!styleContext) {
     return;
   }
 
   const nsStyleSVG* styleSVG = styleContext->StyleSVG();
 
@@ -248,17 +248,17 @@ SVGContentUtils::GetStrokeWidth(nsSVGEle
                                 nsStyleContext* aStyleContext,
                                 SVGContextPaint* aContextPaint)
 {
   RefPtr<nsStyleContext> styleContext;
   if (aStyleContext) {
     styleContext = aStyleContext;
   } else {
     styleContext =
-      nsComputedDOMStyle::GetStyleContextNoFlush(aElement, nullptr, nullptr);
+      nsComputedDOMStyle::GetStyleContextNoFlush(aElement, nullptr);
   }
 
   if (!styleContext) {
     return 0.0f;
   }
 
   const nsStyleSVG* styleSVG = styleContext->StyleSVG();
 
@@ -271,17 +271,17 @@ SVGContentUtils::GetStrokeWidth(nsSVGEle
 
 float
 SVGContentUtils::GetFontSize(Element *aElement)
 {
   if (!aElement)
     return 1.0f;
 
   RefPtr<nsStyleContext> styleContext =
-    nsComputedDOMStyle::GetStyleContextNoFlush(aElement, nullptr, nullptr);
+    nsComputedDOMStyle::GetStyleContextNoFlush(aElement, nullptr);
   if (!styleContext) {
     // ReportToConsole
     NS_WARNING("Couldn't get style context for content in GetFontStyle");
     return 1.0f;
   }
 
   return GetFontSize(styleContext);
 }
@@ -308,17 +308,17 @@ SVGContentUtils::GetFontSize(nsStyleCont
 
 float
 SVGContentUtils::GetFontXHeight(Element *aElement)
 {
   if (!aElement)
     return 1.0f;
 
   RefPtr<nsStyleContext> styleContext =
-    nsComputedDOMStyle::GetStyleContextNoFlush(aElement, nullptr, nullptr);
+    nsComputedDOMStyle::GetStyleContextNoFlush(aElement, nullptr);
   if (!styleContext) {
     // ReportToConsole
     NS_WARNING("Couldn't get style context for content in GetFontStyle");
     return 1.0f;
   }
 
   return GetFontXHeight(styleContext);
 }
--- a/dom/svg/SVGGeometryElement.cpp
+++ b/dom/svg/SVGGeometryElement.cpp
@@ -129,17 +129,17 @@ SVGGeometryElement::GetOrBuildPathForMea
 }
 
 FillRule
 SVGGeometryElement::GetFillRule()
 {
   FillRule fillRule = FillRule::FILL_WINDING; // Equivalent to StyleFillRule::Nonzero
 
   RefPtr<nsStyleContext> styleContext =
-    nsComputedDOMStyle::GetStyleContextNoFlush(this, nullptr, nullptr);
+    nsComputedDOMStyle::GetStyleContextNoFlush(this, nullptr);
 
   if (styleContext) {
     MOZ_ASSERT(styleContext->StyleSVG()->mFillRule == StyleFillRule::Nonzero ||
                styleContext->StyleSVG()->mFillRule == StyleFillRule::Evenodd);
 
     if (styleContext->StyleSVG()->mFillRule == StyleFillRule::Evenodd) {
       fillRule = FillRule::FILL_EVEN_ODD;
     }
--- a/dom/svg/SVGPathElement.cpp
+++ b/dom/svg/SVGPathElement.cpp
@@ -325,17 +325,17 @@ SVGPathElement::BuildPath(PathBuilder* a
   // SVGPathData needs to know our stroke-linecap style and, if "square", then
   // also our stroke width. See the comment for
   // ApproximateZeroLengthSubpathSquareCaps for more info.
 
   uint8_t strokeLineCap = NS_STYLE_STROKE_LINECAP_BUTT;
   Float strokeWidth = 0;
 
   RefPtr<nsStyleContext> styleContext =
-    nsComputedDOMStyle::GetStyleContextNoFlush(this, nullptr, nullptr);
+    nsComputedDOMStyle::GetStyleContextNoFlush(this, nullptr);
   if (styleContext) {
     const nsStyleSVG* style = styleContext->StyleSVG();
     // Note: the path that we return may be used for hit-testing, and SVG
     // exposes hit-testing of strokes that are not actually painted. For that
     // reason we do not check for eStyleSVGPaintType_None or check the stroke
     // opacity here.
     if (style->mStrokeLinecap != NS_STYLE_STROKE_LINECAP_BUTT) {
       strokeLineCap = style->mStrokeLinecap;
--- a/editor/libeditor/CSSEditUtils.cpp
+++ b/editor/libeditor/CSSEditUtils.cpp
@@ -551,17 +551,17 @@ CSSEditUtils::GetCSSInlinePropertyBase(n
 }
 
 // static
 already_AddRefed<nsComputedDOMStyle>
 CSSEditUtils::GetComputedStyle(Element* aElement)
 {
   MOZ_ASSERT(aElement);
 
-  nsIDocument* doc = aElement->GetUncomposedDoc();
+  nsIDocument* doc = aElement->GetComposedDoc();
   NS_ENSURE_TRUE(doc, nullptr);
 
   nsIPresShell* presShell = doc->GetShell();
   NS_ENSURE_TRUE(presShell, nullptr);
 
   RefPtr<nsComputedDOMStyle> style =
     NS_NewComputedDOMStyle(aElement, EmptyString(), presShell);
 
--- a/editor/libeditor/EditorBase.cpp
+++ b/editor/libeditor/EditorBase.cpp
@@ -4249,18 +4249,17 @@ EditorBase::IsPreformatted(nsIDOMNode* a
 
   // Look at the node (and its parent if it's not an element), and grab its style context
   RefPtr<nsStyleContext> elementStyle;
   if (!content->IsElement()) {
     content = content->GetParent();
   }
   if (content && content->IsElement()) {
     elementStyle =
-      nsComputedDOMStyle::GetStyleContextNoFlush(content->AsElement(),
-                                                 nullptr, ps);
+      nsComputedDOMStyle::GetStyleContextNoFlush(content->AsElement(), nullptr);
   }
 
   if (!elementStyle) {
     // Consider nodes without a style context to be NOT preformatted:
     // For instance, this is true of JS tags inside the body (which show
     // up as #text nodes but have no style context).
     *aResult = false;
     return NS_OK;
--- a/layout/inspector/InspectorUtils.cpp
+++ b/layout/inspector/InspectorUtils.cpp
@@ -1018,17 +1018,17 @@ InspectorUtils::GetCleanStyleContextForE
   nsPresContext *presContext = presShell->GetPresContext();
   if (!presContext) {
     return nullptr;
   }
 
   presContext->EnsureSafeToHandOutCSSRules();
 
   RefPtr<nsStyleContext> styleContext =
-    nsComputedDOMStyle::GetStyleContext(aElement, aPseudo, presShell);
+    nsComputedDOMStyle::GetStyleContext(aElement, aPseudo);
   return styleContext.forget();
 }
 
 /* static */ void
 InspectorUtils::GetUsedFontFaces(GlobalObject& aGlobalObject,
                                  nsRange& aRange,
                                  uint32_t aMaxRanges,
                                  nsTArray<nsAutoPtr<InspectorFontFace>>& aResult,
--- a/layout/style/StyleAnimationValue.cpp
+++ b/layout/style/StyleAnimationValue.cpp
@@ -5536,37 +5536,32 @@ AnimationValue::FromString(nsCSSProperty
   nsCOMPtr<nsIPresShell> shell = doc->GetShell();
   if (!shell) {
     return result;
   }
 
   // GetStyleContext() flushes style, so we shouldn't assume that any
   // non-owning references we have are still valid.
   RefPtr<nsStyleContext> styleContext =
-    nsComputedDOMStyle::GetStyleContext(aElement, nullptr, shell);
-
-  if (auto servoContext = styleContext->GetAsServo()) {
-    nsPresContext* presContext = shell->GetPresContext();
-    if (!presContext) {
-      return result;
-    }
-
+    nsComputedDOMStyle::GetStyleContext(aElement, nullptr);
+  MOZ_ASSERT(styleContext);
+
+  if (auto* servoContext = styleContext->GetAsServo()) {
     RefPtr<RawServoDeclarationBlock> declarations =
       ServoCSSParser::ParseProperty(aProperty, aValue,
                                     ServoCSSParser::GetParsingEnvironment(doc));
 
     if (!declarations) {
       return result;
     }
 
-    result.mServo = presContext->StyleSet()
-                               ->AsServo()
-                               ->ComputeAnimationValue(aElement,
-                                                       declarations,
-                                                       servoContext);
+    result.mServo =
+      shell->StyleSet()->AsServo()->ComputeAnimationValue(aElement,
+                                                          declarations,
+                                                          servoContext);
     return result;
   }
 
 #ifdef MOZ_OLD_STYLE
   if (!StyleAnimationValue::ComputeValue(aProperty, aElement,
                                          styleContext->AsGecko(),
                                          aValue, false /* |aUseSVGMode| */,
                                          result.mGecko)) {
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -373,22 +373,21 @@ nsComputedDOMStyle::nsComputedDOMStyle(d
   , mPresShell(nullptr)
   , mStyleType(aStyleType)
   , mStyleContextGeneration(0)
   , mExposeVisitedStyle(false)
   , mResolvedStyleContext(false)
   , mAnimationFlag(aFlag)
 {
   MOZ_ASSERT(aElement && aPresShell);
+  MOZ_ASSERT(aPresShell->GetPresContext());
 
   mDocumentWeak = do_GetWeakReference(aPresShell->GetDocument());
   mContent = aElement;
   mPseudo = nsCSSPseudoElements::GetPseudoAtom(aPseudoElt);
-
-  MOZ_ASSERT(aPresShell->GetPresContext());
 }
 
 nsComputedDOMStyle::~nsComputedDOMStyle()
 {
   ClearStyleContext();
 }
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsComputedDOMStyle)
@@ -513,35 +512,22 @@ nsComputedDOMStyle::GetPropertyValue(con
 
   return NS_OK;
 }
 
 /* static */
 already_AddRefed<nsStyleContext>
 nsComputedDOMStyle::GetStyleContext(Element* aElement,
                                     nsAtom* aPseudo,
-                                    nsIPresShell* aPresShell,
                                     StyleType aStyleType)
 {
-  // If the content has a pres shell, we must use it.  Otherwise we'd
-  // potentially mix rule trees by using the wrong pres shell's style
-  // set.  Using the pres shell from the content also means that any
-  // content that's actually *in* a document will get the style from the
-  // correct document.
-  nsCOMPtr<nsIPresShell> presShell =
-    nsContentUtils::GetPresShellForContent(aElement);
-  if (!presShell) {
-    presShell = aPresShell;
-    if (!presShell)
-      return nullptr;
-  }
-
-  presShell->FlushPendingNotifications(FlushType::Style);
-
-  return GetStyleContextNoFlush(aElement, aPseudo, presShell, aStyleType);
+  if (nsIDocument* doc = aElement->GetComposedDoc()) {
+    doc->FlushPendingNotifications(FlushType::Style);
+  }
+  return GetStyleContextNoFlush(aElement, aPseudo, aStyleType);
 }
 
 #ifdef MOZ_OLD_STYLE
 namespace {
 class MOZ_STACK_CLASS StyleResolver final
 {
 public:
   StyleResolver(nsPresContext* aPresContext,
@@ -829,18 +815,18 @@ nsComputedDOMStyle::DoGetStyleContextNoF
   }
 
 #ifdef MOZ_OLD_STYLE
   RefPtr<GeckoStyleContext> parentContext;
   nsIContent* parent = aPseudo ? aElement : aElement->GetParent();
   // Don't resolve parent context for document fragments.
   if (parent && parent->IsElement()) {
     RefPtr<nsStyleContext> p =
-      GetStyleContextNoFlush(parent->AsElement(), nullptr,
-                             aPresShell, aStyleType);
+      DoGetStyleContextNoFlush(parent->AsElement(), nullptr,
+                               aPresShell, aStyleType, eWithAnimation);
     MOZ_ASSERT(p && p->IsGecko());
     parentContext = GeckoStyleContext::TakeRef(p.forget());
   }
 
   StyleResolver styleResolver(presContext, aAnimationFlag);
 
   if (aAnimationFlag == eWithAnimation) {
     return styleResolver.ResolveWithAnimation(styleSet->AsGecko(),
@@ -973,16 +959,21 @@ void
 nsComputedDOMStyle::UpdateCurrentStyleSources(bool aNeedsLayoutFlush)
 {
   nsCOMPtr<nsIDocument> document = do_QueryReferent(mDocumentWeak);
   if (!document) {
     ClearStyleContext();
     return;
   }
 
+  // TODO(emilio): We may want to handle a few special-cases here:
+  //
+  //  * https://github.com/w3c/csswg-drafts/issues/1964
+  //  * https://github.com/w3c/csswg-drafts/issues/1548
+
   // If the property we are computing relies on layout, then we must flush.
   FlushTarget target = aNeedsLayoutFlush ? FlushTarget::Normal : GetFlushTarget(document);
 
   // Flush _before_ getting the presshell, since that could create a new
   // presshell.  Also note that we want to flush the style on the document
   // we're computing style in, not on the document mContent is in -- the two
   // may be different.
   document->FlushPendingNotifications(
@@ -1092,33 +1083,33 @@ nsComputedDOMStyle::UpdateCurrentStyleSo
                    NS_LossyConvertUTF16toASCII(assertMsg).get());
 #else
       MOZ_CRASH("old style system disabled");
 #endif
     }
 #endif
     // Need to resolve a style context
     RefPtr<nsStyleContext> resolvedStyleContext =
-      nsComputedDOMStyle::GetStyleContextNoFlush(
+      DoGetStyleContextNoFlush(
           mContent->AsElement(),
           mPseudo,
           presShellForContent ? presShellForContent.get() : mPresShell,
-          mStyleType);
+          mStyleType,
+          eWithAnimation);
     if (!resolvedStyleContext) {
       ClearStyleContext();
       return;
     }
 
     // No need to re-get the generation, even though GetStyleContext
     // will flush, since we flushed style at the top of this function.
     // We don't need to check this if we only flushed the parent.
     NS_ASSERTION(target == FlushTarget::ParentOnly ||
-                 (mPresShell &&
-                   currentGeneration ==
-                     mPresShell->GetPresContext()->GetUndisplayedRestyleGeneration()),
+                 currentGeneration ==
+                     mPresShell->GetPresContext()->GetUndisplayedRestyleGeneration(),
                    "why should we have flushed style again?");
 
     SetResolvedStyleContext(Move(resolvedStyleContext), currentGeneration);
     NS_ASSERTION(mPseudo || !mStyleContext->HasPseudoElementData(),
                  "should not have pseudo-element data");
   }
 
   if (mAnimationFlag == eWithoutAnimation) {
--- a/layout/style/nsComputedDOMStyle.h
+++ b/layout/style/nsComputedDOMStyle.h
@@ -93,41 +93,38 @@ public:
 
   virtual nsINode *GetParentObject() override
   {
     return mContent;
   }
 
   static already_AddRefed<nsStyleContext>
   GetStyleContext(mozilla::dom::Element* aElement, nsAtom* aPseudo,
-                  nsIPresShell* aPresShell,
                   StyleType aStyleType = eAll);
 
   static already_AddRefed<nsStyleContext>
   GetStyleContextNoFlush(mozilla::dom::Element* aElement,
                          nsAtom* aPseudo,
-                         nsIPresShell* aPresShell,
                          StyleType aStyleType = eAll)
   {
     return DoGetStyleContextNoFlush(aElement,
                                     aPseudo,
-                                    aPresShell,
+                                    aElement->OwnerDoc()->GetShell(),
                                     aStyleType,
                                     eWithAnimation);
   }
 
   static already_AddRefed<nsStyleContext>
   GetUnanimatedStyleContextNoFlush(mozilla::dom::Element* aElement,
                                    nsAtom* aPseudo,
-                                   nsIPresShell* aPresShell,
                                    StyleType aStyleType = eAll)
   {
     return DoGetStyleContextNoFlush(aElement,
                                     aPseudo,
-                                    aPresShell,
+                                    aElement->OwnerDoc()->GetShell(),
                                     aStyleType,
                                     eWithoutAnimation);
   }
 
   // Helper for nsDOMWindowUtils::GetVisitedDependentComputedStyle
   void SetExposeVisitedStyle(bool aExpose) {
     NS_ASSERTION(aExpose != mExposeVisitedStyle, "should always be changing");
     mExposeVisitedStyle = aExpose;