Bug 1432490: Make nsComputedDOMStyle::GetStyleContext / GetStyleContextNoFlush not take a presShell. r?bz draft
authorEmilio Cobos Álvarez <emilio@crisal.io>
Tue, 23 Jan 2018 15:49:00 +0100
changeset 724057 ee408ca42b3227e6ba3103b0a2fb507eb0249691
parent 723788 c5461973d6ee7845b3f560c05e1502429fd63184
child 747033 00f56a3fd393679e6f1d2ec5f099fd15b50f5a0e
push id96621
push userbmo:emilio@crisal.io
push dateWed, 24 Jan 2018 10:01:40 +0000
reviewersbz
bugs1432490
milestone60.0a1
Bug 1432490: Make nsComputedDOMStyle::GetStyleContext / GetStyleContextNoFlush not take a presShell. r?bz Everyone calls them from 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. Also it changes a few very suspicious usages GetUncomposedDoc. 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
@@ -1085,17 +1085,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
@@ -1056,29 +1056,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
@@ -533,47 +533,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.
@@ -1532,17 +1525,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
@@ -2756,22 +2756,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)
 {
@@ -2843,35 +2839,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
@@ -3756,17 +3756,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
@@ -1177,17 +1177,17 @@ CanvasRenderingContext2D::ParseColor(con
                                       &wasCurrentColor, loader)) {
       return false;
     }
 
     if (wasCurrentColor) {
       // Otherwise, get the value of the color property, flushing style
       // if necessary.
       RefPtr<nsStyleContext> canvasStyle =
-        nsComputedDOMStyle::GetStyleContext(mCanvasElement, nullptr, presShell);
+        nsComputedDOMStyle::GetStyleContext(mCanvasElement, nullptr);
       *aColor = canvasStyle->StyleColor()->mColor;
     }
     return true;
   }
 
   // Pass the CSS Loader object to the parser, to allow parser error
   // reports to include the outer window ID.
   nsCSSParser parser(loader);
@@ -1198,21 +1198,20 @@ CanvasRenderingContext2D::ParseColor(con
 
   if (value.IsNumericColorUnit()) {
     // 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()) {
+    if (mCanvasElement && mCanvasElement->IsInComposedDoc()) {
       // 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;
 }
@@ -1972,30 +1971,28 @@ void
 CanvasRenderingContext2D::ClearTarget()
 {
   Reset();
 
   mResetLayer = true;
 
   SetInitialState();
 
+  if (!mCanvasElement || !mCanvasElement->IsInComposedDoc()) {
+    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) {
@@ -2706,28 +2703,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()) {
+  if (aElement && aElement->IsInComposedDoc()) {
     // 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);
@@ -2885,51 +2883,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);
+  if (aElement && aElement->IsInComposedDoc()) {
+    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();
 }
 
 static already_AddRefed<Declaration>
 CreateFilterDeclaration(const nsAString& aFilter,
                         nsINode* aNode,
                         bool* aOutFilterChanged)
 {
@@ -4541,20 +4532,20 @@ CanvasRenderingContext2D::DrawOrMeasureT
   if (aMaxWidth.WasPassed() && (aMaxWidth.Value() <= 0 || IsNaN(aMaxWidth.Value()))) {
     textToDraw.Truncate();
   }
 
   // for now, default to ltr if not in doc
   bool isRTL = false;
 
   RefPtr<nsStyleContext> canvasStyle;
-  if (mCanvasElement && mCanvasElement->IsInUncomposedDoc()) {
+  if (mCanvasElement && mCanvasElement->IsInComposedDoc()) {
     // 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
@@ -3024,16 +3024,21 @@ nsGenericHTMLElement::NewURIFromString(c
   }
 
   return NS_OK;
 }
 
 static bool
 IsOrHasAncestorWithDisplayNone(Element* aElement, nsIPresShell* aPresShell)
 {
+  // FIXME(emilio): In the servo case it should suffice with 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;
@@ -3054,18 +3059,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
@@ -624,17 +624,17 @@ nsSMILCSSValueType::Interpolate(const ns
                              aUnitDistance,
                              aResult);
 }
 
 // Helper function to extract presContext
 static nsPresContext*
 GetPresContextForElement(Element* aElem)
 {
-  nsIDocument* doc = aElem->GetUncomposedDoc();
+  nsIDocument* doc = aElem->GetComposedDoc();
   if (!doc) {
     // This can happen if we process certain types of restyles mid-sample
     // and remove anonymous animated content from the document as a result.
     // See bug 534975.
     return nullptr;
   }
   nsIPresShell* shell = doc->GetShell();
   return shell ? shell->GetPresContext() : nullptr;
@@ -742,28 +742,27 @@ nsSMILCSSValueType::ValueFromString(nsCS
 {
   MOZ_ASSERT(aValue.IsNull(), "Outparam should be null-typed");
   nsPresContext* presContext = GetPresContextForElement(aTargetElement);
   if (!presContext) {
     NS_WARNING("Not parsing animation value; unable to get PresContext");
     return;
   }
 
-  nsIDocument* doc = aTargetElement->GetUncomposedDoc();
+  nsIDocument* doc = aTargetElement->GetComposedDoc();
   if (doc && !nsStyleUtil::CSPAllowsInlineStyle(nullptr,
                                                 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
@@ -174,17 +174,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();
 
@@ -247,17 +247,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();
 
@@ -270,17 +270,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);
 }
@@ -307,17 +307,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
@@ -126,17 +126,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
@@ -544,17 +544,17 @@ CSSEditUtils::GetCSSInlinePropertyBase(n
   return NS_OK;
 }
 
 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
@@ -4169,18 +4169,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
@@ -976,17 +976,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,
                                  nsTArray<nsAutoPtr<InspectorFontFace>>& aResult,
                                  ErrorResult& aRv)
--- a/layout/style/StyleAnimationValue.cpp
+++ b/layout/style/StyleAnimationValue.cpp
@@ -5463,37 +5463,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;
   }
 
   if (!StyleAnimationValue::ComputeValue(aProperty, aElement,
                                          styleContext->AsGecko(),
                                          aValue, false /* |aUseSVGMode| */,
                                          result.mGecko)) {
     MOZ_ASSERT(result.IsNull());
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -351,22 +351,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)
@@ -490,34 +489,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 = 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);
 }
 
 namespace {
 class MOZ_STACK_CLASS StyleResolver final
 {
 public:
   StyleResolver(nsPresContext* aPresContext,
                 nsComputedDOMStyle::AnimationFlag aAnimationFlag)
@@ -793,18 +780,18 @@ nsComputedDOMStyle::DoGetStyleContextNoF
                                               result);
   }
 
   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(),
@@ -835,18 +822,19 @@ nsComputedDOMStyle::GetAdjustedValuesFor
   return adjustment;
 }
 
 /* static */
 nsIPresShell*
 nsComputedDOMStyle::GetPresShellForContent(const nsIContent* aContent)
 {
   nsIDocument* composedDoc = aContent->GetComposedDoc();
-  if (!composedDoc)
+  if (!composedDoc) {
     return nullptr;
+  }
 
   return composedDoc->GetShell();
 }
 
 // nsDOMCSSDeclaration abstract methods which should never be called
 // on a nsComputedDOMStyle object, but must be defined to avoid
 // compile errors.
 DeclarationBlock*
@@ -945,16 +933,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(
@@ -1059,33 +1052,33 @@ nsComputedDOMStyle::UpdateCurrentStyleSo
       assertMsg.Append(')');
       NS_ASSERTION(nsCSSPseudoElements::PseudoElementContainsElements(pseudo) ||
                    mContent->IsNativeAnonymous(),
                    NS_LossyConvertUTF16toASCII(assertMsg).get());
     }
 #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
@@ -95,41 +95,38 @@ public:
 
   virtual mozilla::dom::DocGroup* GetDocGroup() const override
   {
     return mContent ? mContent->GetDocGroup() : nullptr;
   }
 
   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);
   }
 
   static nsIPresShell*
   GetPresShellForContent(const nsIContent* aContent);
 
   // Helper for nsDOMWindowUtils::GetVisitedDependentComputedStyle