Bug 1759881 - Part 7: Add a virtual method to get the module loader to use for the current global r=yulia,smaug

This adds a virtual method to  nsIGlobalObject and implements it for
nsGlobalWindowInner and SandboxPrivate. This means we don't have to put the
logic for dealing with all the different kinds of globals in once place.

Differential Revision: https://phabricator.services.mozilla.com/D141733
This commit is contained in:
Jon Coppeard 2022-03-28 12:38:27 +00:00
Родитель a19c8c37f2
Коммит 050bae2fd0
8 изменённых файлов: 61 добавлений и 32 удалений

Просмотреть файл

@ -7785,6 +7785,21 @@ already_AddRefed<nsGlobalWindowInner> nsGlobalWindowInner::Create(
return window.forget();
}
JS::loader::ModuleLoaderBase* nsGlobalWindowInner::GetModuleLoader(
JSContext* aCx) {
Document* document = GetDocument();
if (!document) {
return nullptr;
}
ScriptLoader* loader = document->ScriptLoader();
if (!loader) {
return nullptr;
}
return loader->GetModuleLoader();
}
nsIURI* nsPIDOMWindowInner::GetDocumentURI() const {
return mDoc ? mDoc->GetDocumentURI() : mDocumentURI.get();
}

Просмотреть файл

@ -1340,6 +1340,9 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
mStorageAllowedReasonCache = 0;
}
virtual JS::loader::ModuleLoaderBase* GetModuleLoader(
JSContext* aCx) override;
private:
RefPtr<mozilla::dom::ContentMediaController> mContentMediaController;

Просмотреть файл

@ -48,6 +48,12 @@ class ServiceWorkerRegistrationDescriptor;
} // namespace dom
} // namespace mozilla
namespace JS {
namespace loader {
class ModuleLoaderBase;
} // namespace loader
} // namespace JS
/**
* See <https://developer.mozilla.org/en-US/docs/Glossary/Global_object>.
*/
@ -242,6 +248,14 @@ class nsIGlobalObject : public nsISupports,
*/
virtual uint32_t GetPrincipalHashValue() const { return 0; }
/**
* Get the module loader to use for this global, if any. By default this
* returns null.
*/
virtual JS::loader::ModuleLoaderBase* GetModuleLoader(JSContext* aCx) {
return nullptr;
}
protected:
virtual ~nsIGlobalObject();

Просмотреть файл

@ -48,7 +48,7 @@ namespace mozilla::dom {
//////////////////////////////////////////////////////////////
// DOM module loader Helpers
//////////////////////////////////////////////////////////////
static ScriptLoader* GetCurrentScriptLoader(JSContext* aCx) {
static ModuleLoaderBase* GetCurrentModuleLoader(JSContext* aCx) {
auto reportError = mozilla::MakeScopeExit([aCx]() {
JS_ReportErrorASCII(aCx, "No ScriptLoader found for the current context");
});
@ -63,23 +63,7 @@ static ScriptLoader* GetCurrentScriptLoader(JSContext* aCx) {
return nullptr;
}
nsGlobalWindowInner* innerWindow = nullptr;
if (nsCOMPtr<nsPIDOMWindowInner> win = do_QueryInterface(global)) {
innerWindow = nsGlobalWindowInner::Cast(win);
} else {
innerWindow = xpc::SandboxWindowOrNull(object, aCx);
}
if (!innerWindow) {
return nullptr;
}
Document* document = innerWindow->GetDocument();
if (!document) {
return nullptr;
}
ScriptLoader* loader = document->ScriptLoader();
ModuleLoaderBase* loader = global->GetModuleLoader(aCx);
if (!loader) {
return nullptr;
}
@ -161,7 +145,7 @@ JSObject* HostResolveImportedModule(JSContext* aCx,
return nullptr;
}
RefPtr<ScriptLoader> loader = GetCurrentScriptLoader(aCx);
RefPtr<ModuleLoaderBase> loader = GetCurrentModuleLoader(aCx);
if (!loader) {
return nullptr;
}
@ -185,7 +169,7 @@ JSObject* HostResolveImportedModule(JSContext* aCx,
// Let resolved module script be moduleMap[url]. (This entry must exist for
// us to have gotten to this point.)
ModuleScript* ms = loader->GetModuleLoader()->GetFetchedModule(uri, global);
ModuleScript* ms = loader->GetFetchedModule(uri, global);
MOZ_ASSERT(ms, "Resolved module not found in module map");
MOZ_ASSERT(!ms->HasParseError());
MOZ_ASSERT(ms->ModuleRecord());
@ -236,7 +220,7 @@ bool HostImportModuleDynamically(JSContext* aCx,
return false;
}
RefPtr<ScriptLoader> loader = GetCurrentScriptLoader(aCx);
RefPtr<ModuleLoaderBase> loader = GetCurrentModuleLoader(aCx);
if (!loader) {
return false;
}
@ -271,7 +255,9 @@ bool HostImportModuleDynamically(JSContext* aCx,
// options from the document. This can happen when the user
// triggers an inline event handler, as there is no active script
// there.
Document* document = loader->GetDocument();
Document* document = static_cast<ModuleLoader*>(loader.get())
->GetScriptLoader()
->GetDocument();
// Use the document's principal for all loads, except WebExtension
// content-scripts.
@ -294,10 +280,10 @@ bool HostImportModuleDynamically(JSContext* aCx,
}
RefPtr<ModuleLoadRequest> request = ModuleLoader::CreateDynamicImport(
uri, options, baseURL, context, loader, aReferencingPrivate,
uri, options, baseURL, context, loader.get(), aReferencingPrivate,
specifierString, aPromise);
loader->GetModuleLoader()->StartDynamicImport(request);
loader->StartDynamicImport(request);
return true;
}
@ -580,7 +566,7 @@ already_AddRefed<ModuleLoadRequest> ModuleLoader::CreateStaticImport(
/* static */
already_AddRefed<ModuleLoadRequest> ModuleLoader::CreateDynamicImport(
nsIURI* aURI, ScriptFetchOptions* aFetchOptions, nsIURI* aBaseURL,
ScriptLoadContext* aContext, ScriptLoader* aLoader,
ScriptLoadContext* aContext, ModuleLoaderBase* aLoader,
JS::Handle<JS::Value> aReferencingPrivate, JS::Handle<JSString*> aSpecifier,
JS::Handle<JSObject*> aPromise) {
MOZ_ASSERT(aSpecifier);
@ -592,8 +578,8 @@ already_AddRefed<ModuleLoadRequest> ModuleLoader::CreateDynamicImport(
RefPtr<ModuleLoadRequest> request = new ModuleLoadRequest(
aURI, aFetchOptions, SRIMetadata(), aBaseURL, aContext, true,
/* is top level */ true, /* is dynamic import */
aLoader->GetModuleLoader(),
ModuleLoadRequest::NewVisitedSetForTopLevelImport(aURI), nullptr);
aLoader, ModuleLoadRequest::NewVisitedSetForTopLevelImport(aURI),
nullptr);
request->mDynamicReferencingPrivate = aReferencingPrivate;
request->mDynamicSpecifier = aSpecifier;

Просмотреть файл

@ -81,7 +81,7 @@ class ModuleLoader final : public JS::loader::ModuleLoaderBase {
// Create a module load request for dynamic module import.
static already_AddRefed<ModuleLoadRequest> CreateDynamicImport(
nsIURI* aURI, ScriptFetchOptions* aFetchOptions, nsIURI* aBaseURL,
ScriptLoadContext* aContext, ScriptLoader* aLoader,
ScriptLoadContext* aContext, ModuleLoaderBase* aLoader,
JS::Handle<JS::Value> aReferencingPrivate,
JS::Handle<JSString*> aSpecifier, JS::Handle<JSObject*> aPromise);
};

Просмотреть файл

@ -353,7 +353,7 @@ nsresult ModuleLoaderBase::HandleResolveFailure(
}
already_AddRefed<nsIURI> ModuleLoaderBase::ResolveModuleSpecifier(
ScriptLoaderInterface* aLoader, LoadedScript* aScript,
ModuleLoaderBase* aLoader, LoadedScript* aScript,
const nsAString& aSpecifier) {
// The following module specifiers are allowed by the spec:
// - a valid absolute URL
@ -383,7 +383,7 @@ already_AddRefed<nsIURI> ModuleLoaderBase::ResolveModuleSpecifier(
if (aScript) {
baseURL = aScript->BaseURL();
} else {
baseURL = aLoader->GetBaseURI();
baseURL = aLoader->mLoader->GetBaseURI();
}
rv = NS_NewURI(getter_AddRefs(uri), aSpecifier, nullptr, baseURL);
@ -432,7 +432,7 @@ nsresult ModuleLoaderBase::ResolveRequestedModules(
// and requested.
ModuleLoaderBase* requestModuleLoader = aRequest->mLoader;
nsCOMPtr<nsIURI> uri =
ResolveModuleSpecifier(requestModuleLoader->mLoader, ms, specifier);
ResolveModuleSpecifier(requestModuleLoader, ms, specifier);
if (!uri) {
uint32_t lineNumber = 0;
uint32_t columnNumber = 0;

Просмотреть файл

@ -138,7 +138,7 @@ class ModuleLoaderBase : public nsISupports {
#endif
static already_AddRefed<nsIURI> ResolveModuleSpecifier(
ScriptLoaderInterface* loader, LoadedScript* aScript,
ModuleLoaderBase* loader, LoadedScript* aScript,
const nsAString& aSpecifier);
static nsresult HandleResolveFailure(JSContext* aCx, LoadedScript* aScript,
const nsAString& aSpecifier,

Просмотреть файл

@ -14,6 +14,7 @@
#include "nsIGlobalObject.h"
#include "nsIScriptObjectPrincipal.h"
#include "nsIPrincipal.h"
#include "nsGlobalWindowInner.h"
#include "nsWeakReference.h"
#include "nsWrapperCache.h"
@ -81,6 +82,16 @@ class SandboxPrivate : public nsIGlobalObject,
MOZ_CRASH("SandboxPrivate doesn't use DOM bindings!");
}
JS::loader::ModuleLoaderBase* GetModuleLoader(JSContext* aCx) override {
JSObject* object = GetGlobalJSObject();
nsGlobalWindowInner* sandboxWindow = xpc::SandboxWindowOrNull(object, aCx);
if (!sandboxWindow) {
return nullptr;
}
return sandboxWindow->GetModuleLoader(aCx);
}
size_t ObjectMoved(JSObject* obj, JSObject* old) {
UpdateWrapper(obj, old);
return 0;