Bug 1379148: Part 1 - Allow blocking only non-script-created parsers. r?hsivonen
MozReview-Commit-ID: 8cGxywiUzWj
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -10888,21 +10888,22 @@ nsIDocument::ObsoleteSheet(const nsAStri
}
class UnblockParsingPromiseHandler final : public PromiseNativeHandler
{
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS(UnblockParsingPromiseHandler)
- explicit UnblockParsingPromiseHandler(nsIDocument* aDocument, Promise* aPromise)
+ explicit UnblockParsingPromiseHandler(nsIDocument* aDocument, Promise* aPromise,
+ const BlockParsingOptions& aOptions)
: mPromise(aPromise)
{
nsCOMPtr<nsIParser> parser = aDocument->CreatorParserOrNull();
- if (parser) {
+ if (parser && (aOptions.mBlockScriptCreated || !parser->IsScriptCreated())) {
parser->BlockParser();
mParser = do_GetWeakReference(parser);
mDocument = aDocument;
}
}
void
ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue) override
@@ -10955,24 +10956,25 @@ NS_IMPL_CYCLE_COLLECTION(UnblockParsingP
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(UnblockParsingPromiseHandler)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(UnblockParsingPromiseHandler)
NS_IMPL_CYCLE_COLLECTING_RELEASE(UnblockParsingPromiseHandler)
already_AddRefed<Promise>
-nsIDocument::BlockParsing(Promise& aPromise, ErrorResult& aRv)
+nsIDocument::BlockParsing(Promise& aPromise, const BlockParsingOptions& aOptions, ErrorResult& aRv)
{
RefPtr<Promise> resultPromise = Promise::Create(aPromise.GetParentObject(), aRv);
if (aRv.Failed()) {
return nullptr;
}
- RefPtr<PromiseNativeHandler> promiseHandler = new UnblockParsingPromiseHandler(this, resultPromise);
+ RefPtr<PromiseNativeHandler> promiseHandler = new UnblockParsingPromiseHandler(this, resultPromise,
+ aOptions);
aPromise.AppendNativeHandler(promiseHandler);
return resultPromise.forget();
}
already_AddRefed<nsIURI>
nsIDocument::GetMozDocumentURIIfNotForErrorPages()
{
--- a/dom/base/nsIDocument.h
+++ b/dom/base/nsIDocument.h
@@ -2947,16 +2947,17 @@ public:
return mStyleSheetChangeEventsEnabled;
}
void ObsoleteSheet(nsIURI *aSheetURI, mozilla::ErrorResult& rv);
void ObsoleteSheet(const nsAString& aSheetURI, mozilla::ErrorResult& rv);
already_AddRefed<mozilla::dom::Promise> BlockParsing(mozilla::dom::Promise& aPromise,
+ const mozilla::dom::BlockParsingOptions& aOptions,
mozilla::ErrorResult& aRv);
already_AddRefed<nsIURI> GetMozDocumentURIIfNotForErrorPages();
// ParentNode
nsIHTMLCollection* Children();
uint32_t ChildElementCount();
--- a/dom/webidl/Document.webidl
+++ b/dom/webidl/Document.webidl
@@ -380,23 +380,32 @@ partial interface Document {
[ChromeOnly] readonly attribute nsIDocShell? docShell;
[ChromeOnly] readonly attribute DOMString contentLanguage;
[ChromeOnly] readonly attribute nsILoadGroup? documentLoadGroup;
// Blocks the initial document parser until the given promise is settled.
[ChromeOnly, Throws]
- Promise<any> blockParsing(Promise<any> promise);
+ Promise<any> blockParsing(Promise<any> promise,
+ optional BlockParsingOptions options);
// like documentURI, except that for error pages, it returns the URI we were
// trying to load when we hit an error, rather than the error page's own URI.
[ChromeOnly] readonly attribute URI? mozDocumentURIIfNotForErrorPages;
};
+dictionary BlockParsingOptions {
+ /**
+ * If true, blocks script-created parsers (created via document.open()) in
+ * addition to network-created parsers.
+ */
+ boolean blockScriptCreated = true;
+};
+
// Extension to give chrome JS the ability to determine when a document was
// created to satisfy an iframe with srcdoc attribute.
partial interface Document {
[ChromeOnly] readonly attribute boolean isSrcdocDocument;
};
// Extension to give chrome JS the ability to get the underlying