Bug 1467722: Don't return null for getComputedStyle when there's no pres shell. r?heycam draft
authorEmilio Cobos Álvarez <emilio@crisal.io>
Fri, 08 Jun 2018 11:15:34 +0200
changeset 805711 8d6c47f51ca813967a5b196f2465857b633abb2b
parent 805708 1f8c48a3cab132dd8a32ce8ca3e5375bdea20809
child 805712 4a3c6220c337fff962dc1020334a966a0d837851
push id112752
push userbmo:emilio@crisal.io
push dateFri, 08 Jun 2018 12:08:30 +0000
reviewersheycam
bugs1467722
milestone62.0a1
Bug 1467722: Don't return null for getComputedStyle when there's no pres shell. r?heycam We need to deal with this case regardless from getPropertyValue, and this causes pain and webcompat issues. MozReview-Commit-ID: Gbpzq0N4O2T
dom/base/AnonymousContent.cpp
dom/base/nsGlobalWindowOuter.cpp
editor/libeditor/CSSEditUtils.cpp
layout/style/nsComputedDOMStyle.cpp
layout/style/nsComputedDOMStyle.h
--- a/dom/base/AnonymousContent.cpp
+++ b/dom/base/AnonymousContent.cpp
@@ -223,15 +223,17 @@ AnonymousContent::GetComputedStyleProper
 
   nsIPresShell* shell = element->OwnerDoc()->GetShell();
   if (!shell) {
     aRv.Throw(NS_ERROR_NOT_AVAILABLE);
     return;
   }
 
   RefPtr<nsComputedDOMStyle> cs =
-    new nsComputedDOMStyle(element, NS_LITERAL_STRING(""), shell,
+    new nsComputedDOMStyle(element,
+                           NS_LITERAL_STRING(""),
+                           element->OwnerDoc(),
                            nsComputedDOMStyle::eAll);
   aRv = cs->GetPropertyValue(aPropertyName, aResult);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/base/nsGlobalWindowOuter.cpp
+++ b/dom/base/nsGlobalWindowOuter.cpp
@@ -6686,45 +6686,22 @@ nsGlobalWindowOuter::PageHidden()
   FORWARD_TO_INNER_VOID(PageHidden, ());
 }
 
 already_AddRefed<nsICSSDeclaration>
 nsGlobalWindowOuter::GetComputedStyleHelperOuter(Element& aElt,
                                                  const nsAString& aPseudoElt,
                                                  bool aDefaultStylesOnly)
 {
-  if (!mDocShell) {
+  if (!mDoc) {
     return nullptr;
   }
 
-  nsCOMPtr<nsIPresShell> presShell = mDocShell->GetPresShell();
-
-  if (!presShell) {
-    // Try flushing frames on our parent in case there's a pending
-    // style change that will create the presshell.
-    auto* parent = nsGlobalWindowOuter::Cast(GetPrivateParent());
-    if (!parent) {
-      return nullptr;
-    }
-
-    parent->FlushPendingNotifications(FlushType::Frames);
-
-    // Might have killed mDocShell
-    if (!mDocShell) {
-      return nullptr;
-    }
-
-    presShell = mDocShell->GetPresShell();
-    if (!presShell) {
-      return nullptr;
-    }
-  }
-
   RefPtr<nsICSSDeclaration> compStyle =
-    NS_NewComputedDOMStyle(&aElt, aPseudoElt, presShell,
+    NS_NewComputedDOMStyle(&aElt, aPseudoElt, mDoc,
                            aDefaultStylesOnly ? nsComputedDOMStyle::eDefaultOnly :
                                                 nsComputedDOMStyle::eAll);
 
   return compStyle.forget();
 }
 
 //*****************************************************************************
 // nsGlobalWindowOuter::nsIInterfaceRequestor
--- a/editor/libeditor/CSSEditUtils.cpp
+++ b/editor/libeditor/CSSEditUtils.cpp
@@ -551,21 +551,18 @@ CSSEditUtils::GetCSSInlinePropertyBase(n
 already_AddRefed<nsComputedDOMStyle>
 CSSEditUtils::GetComputedStyle(Element* aElement)
 {
   MOZ_ASSERT(aElement);
 
   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);
+    NS_NewComputedDOMStyle(aElement, EmptyString(), doc);
 
   return style.forget();
 }
 
 // remove the CSS style "aProperty : aPropertyValue" and possibly remove the whole node
 // if it is a span and if its only attribute is _moz_dirty
 nsresult
 CSSEditUtils::RemoveCSSInlineStyle(nsINode& aNode,
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -62,22 +62,23 @@ using namespace mozilla::dom;
 #endif
 
 /*
  * This is the implementation of the readonly CSSStyleDeclaration that is
  * returned by the getComputedStyle() function.
  */
 
 already_AddRefed<nsComputedDOMStyle>
-NS_NewComputedDOMStyle(dom::Element* aElement, const nsAString& aPseudoElt,
-                       nsIPresShell* aPresShell,
+NS_NewComputedDOMStyle(dom::Element* aElement,
+                       const nsAString& aPseudoElt,
+                       nsIDocument* aDocument,
                        nsComputedDOMStyle::StyleType aStyleType)
 {
   RefPtr<nsComputedDOMStyle> computedStyle =
-    new nsComputedDOMStyle(aElement, aPseudoElt, aPresShell, aStyleType);
+    new nsComputedDOMStyle(aElement, aPseudoElt, aDocument, aStyleType);
   return computedStyle.forget();
 }
 
 static nsDOMCSSValueList*
 GetROCSSValueList(bool aCommaDelimited)
 {
   return new nsDOMCSSValueList(aCommaDelimited, true);
 }
@@ -306,31 +307,31 @@ ComputedStyleMap::Update()
       mIndexMap[index++] = i;
     }
   }
   mExposedPropertyCount = index;
 }
 
 nsComputedDOMStyle::nsComputedDOMStyle(dom::Element* aElement,
                                        const nsAString& aPseudoElt,
-                                       nsIPresShell* aPresShell,
+                                       nsIDocument* aDocument,
                                        StyleType aStyleType)
   : mDocumentWeak(nullptr)
   , mOuterFrame(nullptr)
   , mInnerFrame(nullptr)
   , mPresShell(nullptr)
   , mStyleType(aStyleType)
   , mComputedStyleGeneration(0)
   , mExposeVisitedStyle(false)
   , mResolvedComputedStyle(false)
 {
-  MOZ_ASSERT(aElement && aPresShell);
-  MOZ_ASSERT(aPresShell->GetPresContext());
-
-  mDocumentWeak = do_GetWeakReference(aPresShell->GetDocument());
+  MOZ_ASSERT(aElement);
+  // TODO(emilio, bug 548397, https://github.com/w3c/csswg-drafts/issues/2403):
+  // Should use aElement->OwnerDoc() instead.
+  mDocumentWeak = do_GetWeakReference(aDocument);
   mContent = aElement;
   mPseudo = nsCSSPseudoElements::GetPseudoAtom(aPseudoElt);
 }
 
 nsComputedDOMStyle::~nsComputedDOMStyle()
 {
   ClearComputedStyle();
 }
--- a/layout/style/nsComputedDOMStyle.h
+++ b/layout/style/nsComputedDOMStyle.h
@@ -75,17 +75,17 @@ public:
 
   enum StyleType {
     eDefaultOnly, // Only includes UA and user sheets
     eAll // Includes all stylesheets
   };
 
   nsComputedDOMStyle(mozilla::dom::Element* aElement,
                      const nsAString& aPseudoElt,
-                     nsIPresShell* aPresShell,
+                     nsIDocument* aPresShell,
                      StyleType aStyleType);
 
   virtual nsINode *GetParentObject() override
   {
     return mContent;
   }
 
   static already_AddRefed<mozilla::ComputedStyle>
@@ -784,13 +784,13 @@ private:
 #ifdef DEBUG
   bool mFlushedPendingReflows;
 #endif
 };
 
 already_AddRefed<nsComputedDOMStyle>
 NS_NewComputedDOMStyle(mozilla::dom::Element* aElement,
                        const nsAString& aPseudoElt,
-                       nsIPresShell* aPresShell,
+                       nsIDocument* aDocument,
                        nsComputedDOMStyle::StyleType aStyleType =
                          nsComputedDOMStyle::eAll);
 
 #endif /* nsComputedDOMStyle_h__ */