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
--- 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;