Differential Revision: https://phabricator.services.mozilla.com/D310337
143 lines
4.7 KiB
C++
143 lines
4.7 KiB
C++
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#ifndef js_loader_ImportMap_h
|
|
#define js_loader_ImportMap_h
|
|
|
|
#include "mozilla/Logging.h"
|
|
#include "mozilla/RefPtr.h"
|
|
#include "mozilla/UniquePtr.h"
|
|
|
|
#include <functional>
|
|
#include <map>
|
|
|
|
#include "nsStringFwd.h"
|
|
#include "nsTArray.h"
|
|
#include "ResolveResult.h"
|
|
#include "ScriptLoaderInterface.h"
|
|
|
|
#include "js/SourceText.h"
|
|
|
|
struct JSContext;
|
|
class nsIScriptElement;
|
|
class nsIURI;
|
|
|
|
namespace JS::loader {
|
|
class ModuleLoaderBase;
|
|
class ScriptFetchInfo;
|
|
class ScriptLoadRequest;
|
|
|
|
/**
|
|
* A helper class to report warning to ScriptLoaderInterface.
|
|
*/
|
|
class ReportWarningHelper {
|
|
public:
|
|
ReportWarningHelper(ScriptLoaderInterface* aLoader,
|
|
ScriptLoadRequest* aRequest)
|
|
: mLoader(aLoader), mRequest(aRequest) {}
|
|
|
|
template <typename... Args>
|
|
void Report(const char* aMessageName, Args&&... aArgs) const;
|
|
|
|
private:
|
|
RefPtr<ScriptLoaderInterface> mLoader;
|
|
ScriptLoadRequest* mRequest;
|
|
};
|
|
|
|
// Specifier map from import maps.
|
|
// https://html.spec.whatwg.org/multipage/webappapis.html#module-specifier-map
|
|
using SpecifierMap = std::map<nsString, nsCOMPtr<nsIURI>, std::greater<>>;
|
|
|
|
// Scope map from import maps.
|
|
// https://html.spec.whatwg.org/multipage/webappapis.html#concept-import-map-scopes
|
|
using ScopeMap =
|
|
std::map<nsCString, mozilla::UniquePtr<SpecifierMap>, std::greater<>>;
|
|
|
|
// Integrity map from import maps.
|
|
// https://html.spec.whatwg.org/multipage/webappapis.html#concept-import-map-integrity
|
|
using IntegrityMap = std::map<nsCString, nsString, std::greater<>>;
|
|
|
|
/**
|
|
* Implementation of Import maps.
|
|
* https://html.spec.whatwg.org/multipage/webappapis.html#import-maps
|
|
*/
|
|
class ImportMap {
|
|
public:
|
|
ImportMap(mozilla::UniquePtr<SpecifierMap> aImports,
|
|
mozilla::UniquePtr<ScopeMap> aScopes,
|
|
mozilla::UniquePtr<IntegrityMap> aIntegrity)
|
|
: mImports(aImports ? std::move(aImports)
|
|
: mozilla::MakeUnique<SpecifierMap>()),
|
|
mScopes(aScopes ? std::move(aScopes) : mozilla::MakeUnique<ScopeMap>()),
|
|
mIntegrity(aIntegrity ? std::move(aIntegrity)
|
|
: mozilla::MakeUnique<IntegrityMap>()) {}
|
|
|
|
static mozilla::UniquePtr<ImportMap> CreateEmpty() {
|
|
return mozilla::MakeUnique<ImportMap>(nullptr, nullptr, nullptr);
|
|
}
|
|
|
|
/**
|
|
* A helper function to get the "dom.multiple_import_maps.enabled" pref.
|
|
* The pref's type is of non-atomic, which can be only accessed on the main
|
|
* thread.
|
|
* If this function is called from a non-main thread, it safely returns false.
|
|
*/
|
|
static bool IsMultipleImportMapsSupported();
|
|
|
|
/**
|
|
* Parse the JSON string from the Import map script.
|
|
* This function will throw a TypeError if there's any invalid key or value in
|
|
* the JSON text according to the spec.
|
|
*
|
|
* https://html.spec.whatwg.org/multipage/webappapis.html#parse-an-import-map-string
|
|
*/
|
|
static mozilla::UniquePtr<ImportMap> ParseString(
|
|
JSContext* aCx, SourceText<char16_t>& aInput, nsIURI* aBaseURL,
|
|
const ReportWarningHelper& aWarning);
|
|
|
|
/**
|
|
* This implements "Resolve a module specifier" algorithm defined in the
|
|
* Import maps spec.
|
|
*
|
|
* See
|
|
* https://html.spec.whatwg.org/multipage/webappapis.html#resolve-a-module-specifier
|
|
*/
|
|
static ResolveResult ResolveModuleSpecifier(ImportMap* aImportMap,
|
|
ScriptLoaderInterface* aLoader,
|
|
ScriptFetchInfo* aFetchInfo,
|
|
const nsAString& aSpecifier);
|
|
|
|
static mozilla::Maybe<nsString> LookupIntegrity(ImportMap* aImportMap,
|
|
nsIURI* aURL);
|
|
|
|
/**
|
|
* Merge the new import map with the existing one.
|
|
*
|
|
* https://html.spec.whatwg.org/#merge-existing-and-new-import-maps
|
|
*/
|
|
static void Merge(ModuleLoaderBase* aModuleLoader,
|
|
mozilla::UniquePtr<ImportMap> aNewMap,
|
|
const ReportWarningHelper& aWarning);
|
|
|
|
// Logging
|
|
static mozilla::LazyLogModule gImportMapLog;
|
|
|
|
private:
|
|
/**
|
|
* https://html.spec.whatwg.org/multipage/webappapis.html#import-map-processing-model
|
|
*
|
|
* Formally, an import map is a struct with three items:
|
|
* 1. imports, a module specifier map, and
|
|
* 2. scopes, an ordered map of URLs to module specifier maps.
|
|
* 3. integrity, a module integrity map.
|
|
*/
|
|
mozilla::UniquePtr<SpecifierMap> mImports;
|
|
mozilla::UniquePtr<ScopeMap> mScopes;
|
|
mozilla::UniquePtr<IntegrityMap> mIntegrity;
|
|
};
|
|
|
|
} // namespace JS::loader
|
|
|
|
#endif // js_loader_ImportMap_h
|