Bug 1338446 Part 3 - Label SheetLoadData in Loader::PostLoadEvent. draft
authorTing-Yu Lin <tlin@mozilla.com>
Mon, 13 Mar 2017 17:00:57 +0800
changeset 501448 d938012ea8d1651104e1c5e5459cf892b9c061f9
parent 501447 1018a755d49ecad1ce89ad3f4f45e5a08e2b9265
child 501449 62879f361491d0f9714c47262f651b7a3ccd406e
push id49988
push userbmo:tlin@mozilla.com
push dateMon, 20 Mar 2017 10:12:33 +0000
bugs1338446
milestone55.0a1
Bug 1338446 Part 3 - Label SheetLoadData in Loader::PostLoadEvent. When constructing a Loader without passing a document, we added a DocGroup parameter so that we could still use it to dispatch events to the DocGroup. Delete NS_ENSURE_TRUE because new() is infallable. Use another runnable pointer for calling dispatching because forget() will nuke the pointer and we need to use evt afterwards. MozReview-Commit-ID: Ce2K6j4pUhA
dom/base/nsDocument.cpp
layout/base/nsDocumentViewer.cpp
layout/base/nsStyleSheetService.cpp
layout/style/CSSStyleSheet.cpp
layout/style/Loader.cpp
layout/style/Loader.h
layout/style/PreloadedStyleSheet.cpp
layout/style/nsLayoutStylesheetCache.cpp
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -4401,17 +4401,18 @@ nsDocument::LoadAdditionalStyleSheet(add
 {
   NS_PRECONDITION(aSheetURI, "null arg");
 
   // Checking if we have loaded this one already.
   if (FindSheet(mAdditionalSheets[aType], aSheetURI) >= 0)
     return NS_ERROR_INVALID_ARG;
 
   // Loading the sheet sync.
-  RefPtr<css::Loader> loader = new css::Loader(GetStyleBackendType());
+  RefPtr<css::Loader> loader =
+    new css::Loader(GetStyleBackendType(), GetDocGroup());
 
   css::SheetParsingMode parsingMode;
   switch (aType) {
     case nsIDocument::eAgentSheet:
       parsingMode = css::eAgentSheetFeatures;
       break;
 
     case nsIDocument::eUserSheet:
--- a/layout/base/nsDocumentViewer.cpp
+++ b/layout/base/nsDocumentViewer.cpp
@@ -2289,18 +2289,18 @@ nsDocumentViewer::CreateStyleSet(nsIDocu
     nsCOMPtr<nsIDOMElement> elt(do_QueryInterface(chromeHandler));
     nsCOMPtr<nsIContent> content(do_QueryInterface(elt));
     if (elt && content) {
       nsCOMPtr<nsIURI> baseURI = content->GetBaseURI();
 
       nsAutoString sheets;
       elt->GetAttribute(NS_LITERAL_STRING("usechromesheets"), sheets);
       if (!sheets.IsEmpty() && baseURI) {
-        RefPtr<mozilla::css::Loader> cssLoader =
-          new mozilla::css::Loader(backendType);
+        RefPtr<css::Loader> cssLoader =
+          new css::Loader(backendType, aDocument->GetDocGroup());
 
         char *str = ToNewCString(sheets);
         char *newStr = str;
         char *token;
         while ( (token = nsCRT::strtok(newStr, ", ", &newStr)) ) {
           NS_NewURI(getter_AddRefs(uri), nsDependentCString(token), nullptr,
                     baseURI);
           if (!uri) continue;
--- a/layout/base/nsStyleSheetService.cpp
+++ b/layout/base/nsStyleSheetService.cpp
@@ -213,17 +213,17 @@ nsStyleSheetService::LoadAndRegisterShee
 }
 
 static nsresult
 LoadSheet(nsIURI* aURI,
           css::SheetParsingMode aParsingMode,
           StyleBackendType aType,
           RefPtr<StyleSheet>* aResult)
 {
-  RefPtr<css::Loader> loader = new css::Loader(aType);
+  RefPtr<css::Loader> loader = new css::Loader(aType, nullptr);
   return loader->LoadSheetSync(aURI, aParsingMode, true, aResult);
 }
 
 nsresult
 nsStyleSheetService::LoadAndRegisterSheetInternal(nsIURI *aSheetURI,
                                                   uint32_t aSheetType)
 {
   NS_ENSURE_ARG_POINTER(aSheetURI);
--- a/layout/style/CSSStyleSheet.cpp
+++ b/layout/style/CSSStyleSheet.cpp
@@ -983,17 +983,17 @@ CSSStyleSheet::ReparseSheet(const nsAStr
 
   // Hold strong ref to the CSSLoader in case the document update
   // kills the document
   RefPtr<css::Loader> loader;
   if (mDocument) {
     loader = mDocument->CSSLoader();
     NS_ASSERTION(loader, "Document with no CSS loader!");
   } else {
-    loader = new css::Loader(StyleBackendType::Gecko);
+    loader = new css::Loader(StyleBackendType::Gecko, nullptr);
   }
 
   mozAutoDocUpdate updateBatch(mDocument, UPDATE_STYLE, true);
 
   WillDirty();
 
   // detach existing rules (including child sheets via import rules)
   css::LoaderReusableStyleSheets reusableSheets;
--- a/layout/style/Loader.cpp
+++ b/layout/style/Loader.cpp
@@ -14,21 +14,22 @@
  * 04/20/2000       IBM Corp.      OS/2 VisualAge build.
  */
 
 /* loading of CSS style sheets using the network APIs */
 
 #include "mozilla/css/Loader.h"
 
 #include "mozilla/ArrayUtils.h"
+#include "mozilla/dom/DocGroup.h"
 #include "mozilla/IntegerPrintfMacros.h"
 #include "mozilla/LoadInfo.h"
 #include "mozilla/MemoryReporting.h"
-
 #include "mozilla/StyleSheetInlines.h"
+#include "mozilla/SystemGroup.h"
 #include "nsIRunnable.h"
 #include "nsIUnicharStreamLoader.h"
 #include "nsSyncLoadService.h"
 #include "nsCOMPtr.h"
 #include "nsString.h"
 #include "nsIContent.h"
 #include "nsIDocument.h"
 #include "nsIDOMNode.h"
@@ -514,18 +515,19 @@ LoaderReusableStyleSheets::FindReusableS
   }
   return false;
 }
 
 /*************************
  * Loader Implementation *
  *************************/
 
-Loader::Loader(StyleBackendType aType)
+Loader::Loader(StyleBackendType aType, DocGroup* aDocGroup)
   : mDocument(nullptr)
+  , mDocGroup(aDocGroup)
   , mDatasToNotifyOn(0)
   , mCompatMode(eCompatibility_FullStandards)
   , mStyleBackendType(Some(aType))
   , mEnabled(true)
   , mReporter(new ConsoleReportCollector())
 #ifdef DEBUG
   , mSyncCallback(false)
 #endif
@@ -537,16 +539,18 @@ Loader::Loader(nsIDocument* aDocument)
   , mDatasToNotifyOn(0)
   , mCompatMode(eCompatibility_FullStandards)
   , mEnabled(true)
   , mReporter(new ConsoleReportCollector())
 #ifdef DEBUG
   , mSyncCallback(false)
 #endif
 {
+  MOZ_ASSERT(mDocument, "We should get a valid document from the caller!");
+
   // We can just use the preferred set, since there are no sheets in the
   // document yet (if there are, how did they get there? _we_ load the sheets!)
   // and hence the selected set makes no sense at this time.
   nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(mDocument);
   if (domDoc) {
     domDoc->GetPreferredStyleSheetSet(mPreferredSheet);
   }
 }
@@ -2466,23 +2470,34 @@ Loader::PostLoadEvent(nsIURI* aURI,
     new SheetLoadData(this, EmptyString(), // title doesn't matter here
                       aURI,
                       aSheet,
                       aElement,
                       aWasAlternate,
                       aObserver,
                       nullptr,
                       mDocument);
-  NS_ENSURE_TRUE(evt, NS_ERROR_OUT_OF_MEMORY);
 
   if (!mPostedEvents.AppendElement(evt)) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
-  nsresult rv = NS_DispatchToCurrentThread(evt);
+  nsresult rv;
+  RefPtr<SheetLoadData> runnable(evt);
+  if (mDocument) {
+    rv = mDocument->Dispatch("SheetLoadData", TaskCategory::Other,
+                             runnable.forget());
+  } else if (mDocGroup) {
+    rv = mDocGroup->Dispatch("SheetLoadData", TaskCategory::Other,
+                             runnable.forget());
+  } else {
+    rv = SystemGroup::Dispatch("SheetLoadData", TaskCategory::Other,
+                               runnable.forget());
+  }
+
   if (NS_FAILED(rv)) {
     NS_WARNING("failed to dispatch stylesheet load event");
     mPostedEvents.RemoveElement(evt);
   } else {
     // We'll unblock onload when we handle the event.
     if (mDocument) {
       mDocument->BlockOnload();
     }
--- a/layout/style/Loader.h
+++ b/layout/style/Loader.h
@@ -31,16 +31,17 @@ class nsICSSLoaderObserver;
 class nsIConsoleReportCollector;
 class nsIContent;
 class nsIDocument;
 class nsMediaList;
 class nsIStyleSheetLinkingElement;
 
 namespace mozilla {
 namespace dom {
+class DocGroup;
 class Element;
 } // namespace dom
 } // namespace mozilla
 
 namespace mozilla {
 
 class URIPrincipalReferrerPolicyAndCORSModeHashKey : public nsURIHashKey
 {
@@ -186,17 +187,21 @@ enum StyleSheetState {
   eSheetLoading,
   eSheetComplete
 };
 
 class Loader final {
   typedef mozilla::net::ReferrerPolicy ReferrerPolicy;
 
 public:
-  explicit Loader(StyleBackendType aType);
+  // aDocGroup is used for dispatching SheetLoadData in PostLoadEvent(). It
+  // can be null if you want to use this constructor, and there's no
+  // document when the Loader is constructed.
+  Loader(StyleBackendType aType, mozilla::dom::DocGroup* aDocGroup);
+
   explicit Loader(nsIDocument*);
 
  private:
   // Private destructor, to discourage deletion outside of Release():
   ~Loader();
 
  public:
   NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(Loader)
@@ -569,16 +574,18 @@ private:
 
   // Our array of "global" observers
   nsTObserverArray<nsCOMPtr<nsICSSLoaderObserver> > mObservers;
 
   // This reference is nulled by the Document in it's destructor through
   // DropDocumentReference().
   nsIDocument* MOZ_NON_OWNING_REF mDocument;  // the document we live for
 
+  // For dispatching events via DocGroup::Dispatch() when mDocument is nullptr.
+  RefPtr<mozilla::dom::DocGroup> mDocGroup;
 
   // Number of datas still waiting to be notified on if we're notifying on a
   // whole bunch at once (e.g. in one of the stop methods).  This is used to
   // make sure that HasPendingLoads() won't return false until we're notifying
   // on the last data we're working with.
   uint32_t          mDatasToNotifyOn;
 
   nsCompatibility   mCompatMode;
--- a/layout/style/PreloadedStyleSheet.cpp
+++ b/layout/style/PreloadedStyleSheet.cpp
@@ -66,17 +66,17 @@ nsresult
 PreloadedStyleSheet::GetSheet(StyleBackendType aType, StyleSheet** aResult)
 {
   *aResult = nullptr;
 
   RefPtr<StyleSheet>& sheet =
     aType == StyleBackendType::Gecko ? mGecko : mServo;
 
   if (!sheet) {
-    RefPtr<css::Loader> loader = new css::Loader(aType);
+    RefPtr<css::Loader> loader = new css::Loader(aType, nullptr);
     nsresult rv = loader->LoadSheetSync(mURI, mParsingMode, true, &sheet);
     NS_ENSURE_SUCCESS(rv, rv);
     MOZ_ASSERT(sheet);
   }
 
   *aResult = sheet;
   return NS_OK;
 }
--- a/layout/style/nsLayoutStylesheetCache.cpp
+++ b/layout/style/nsLayoutStylesheetCache.cpp
@@ -768,17 +768,17 @@ nsLayoutStylesheetCache::LoadSheet(nsIUR
     return;
   }
 
   auto& loader = mBackendType == StyleBackendType::Gecko ?
     gCSSLoader_Gecko :
     gCSSLoader_Servo;
 
   if (!loader) {
-    loader = new mozilla::css::Loader(mBackendType);
+    loader = new Loader(mBackendType, nullptr);
     if (!loader) {
       ErrorLoadingSheet(aURI, "no Loader", eCrash);
       return;
     }
   }
 
 #ifdef MOZ_CRASHREPORTER
   nsZipArchive::sFileCorruptedReason = nullptr;