Commit 5dd9513f authored by Hiroshige Hayashizaki's avatar Hiroshige Hayashizaki Committed by Commit Bot

[Layered API] Implement origin trials: BuiltInModuleKvStorage

This CL adds origin_trial_feature_name to
- "BuiltInModuleInfra"
- "BuiltInModuleKvStorage"
While "BuiltInModuleInfra" origin trial is not needed for
end users, this is needed in terms of implementation, because
"BuiltInModuleInfra" should be enabled if "BuiltInModuleKvStorage"
is enabled, and thus "BuiltInModuleInfra" flag should also depend
on origin trials.
By adding origin_trial_feature_name to "BuiltInModuleInfra",
origin_trials::BuiltInModuleInfraEnabled() takes care of
the dependency.

As origin trials requires ExecutionContext, this CL associates
built-in module feature control with Modulator, by introducing
- Modulator::BuiltInModuleInfraEnabled()
- Modulator::BuiltInModuleEnabled()
This CL plumbs Modulator via ModuleScriptFetcher::Fetch() and
ImportMap, to plumb Modulator::BuiltInModule*Enabled() to
layered_api.cc.

It seems a little confusing that ModuleScriptFetcher takes
both Modulator and ResourceFetcher that refer
module map settings object and fetch client settings object,
respectively.
This is actually consistent, because built-in modules are
associated with module map settings object and the current
implementation of import maps is also associated with
Modulator (crbug/928435), while fetching should refer to
fetch client settings object.
This apparent inconsistency should be resolved by
- Fixing Issue 928435, or
- Enabling Built-in modules by default (which will remove
  dependencies to ExecutionContext/Modulator again), or
- Refactoring ModuleScriptFetcher.

This CL implements individual control over built-in modules
in ModulatorImplBase::BuiltInModuleEnabled().
After this CL,
- "BuiltInModuleKvStorage" enables "kv-storage" and "blank" only, and
- "BuiltInModuleInfra" flag enables "blank" only,
while they enabled all built-in modules before this CL.

Bug: 829084, 928435
Change-Id: I0ee2838c0981192e9a993cb784bc39d866682836
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1497468
Commit-Queue: Hiroshige Hayashizaki <hiroshige@chromium.org>
Reviewed-by: default avatarKouhei Ueno <kouhei@chromium.org>
Cr-Commit-Position: refs/heads/master@{#638289}
parent 999fbba8
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
#include "third_party/blink/renderer/core/inspector/console_message.h" #include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/core/script/layered_api.h" #include "third_party/blink/renderer/core/script/layered_api.h"
#include "third_party/blink/renderer/platform/bindings/parkable_string.h" #include "third_party/blink/renderer/platform/bindings/parkable_string.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/wtf/vector.h" #include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink { namespace blink {
...@@ -15,13 +14,15 @@ namespace blink { ...@@ -15,13 +14,15 @@ namespace blink {
void DocumentModuleScriptFetcher::Fetch( void DocumentModuleScriptFetcher::Fetch(
FetchParameters& fetch_params, FetchParameters& fetch_params,
ResourceFetcher* fetch_client_settings_object_fetcher, ResourceFetcher* fetch_client_settings_object_fetcher,
const Modulator* modulator_for_built_in_modules,
ModuleGraphLevel level, ModuleGraphLevel level,
ModuleScriptFetcher::Client* client) { ModuleScriptFetcher::Client* client) {
DCHECK(fetch_client_settings_object_fetcher); DCHECK(fetch_client_settings_object_fetcher);
DCHECK(!client_); DCHECK(!client_);
client_ = client; client_ = client;
if (FetchIfLayeredAPI(fetch_params)) if (modulator_for_built_in_modules &&
FetchIfLayeredAPI(*modulator_for_built_in_modules, fetch_params))
return; return;
ScriptResource::Fetch(fetch_params, fetch_client_settings_object_fetcher, ScriptResource::Fetch(fetch_params, fetch_client_settings_object_fetcher,
...@@ -52,8 +53,9 @@ void DocumentModuleScriptFetcher::Trace(blink::Visitor* visitor) { ...@@ -52,8 +53,9 @@ void DocumentModuleScriptFetcher::Trace(blink::Visitor* visitor) {
} }
bool DocumentModuleScriptFetcher::FetchIfLayeredAPI( bool DocumentModuleScriptFetcher::FetchIfLayeredAPI(
const Modulator& modulator_for_built_in_modules,
FetchParameters& fetch_params) { FetchParameters& fetch_params) {
if (!RuntimeEnabledFeatures::BuiltInModuleInfraEnabled()) if (!modulator_for_built_in_modules.BuiltInModuleInfraEnabled())
return false; return false;
KURL layered_api_url = blink::layered_api::GetInternalURL(fetch_params.Url()); KURL layered_api_url = blink::layered_api::GetInternalURL(fetch_params.Url());
...@@ -61,7 +63,8 @@ bool DocumentModuleScriptFetcher::FetchIfLayeredAPI( ...@@ -61,7 +63,8 @@ bool DocumentModuleScriptFetcher::FetchIfLayeredAPI(
if (layered_api_url.IsNull()) if (layered_api_url.IsNull())
return false; return false;
String source_text = blink::layered_api::GetSourceText(layered_api_url); String source_text = blink::layered_api::GetSourceText(
modulator_for_built_in_modules, layered_api_url);
if (source_text.IsNull()) { if (source_text.IsNull()) {
HeapVector<Member<ConsoleMessage>> error_messages; HeapVector<Member<ConsoleMessage>> error_messages;
......
...@@ -27,6 +27,7 @@ class CORE_EXPORT DocumentModuleScriptFetcher final ...@@ -27,6 +27,7 @@ class CORE_EXPORT DocumentModuleScriptFetcher final
// Implements ModuleScriptFetcher. // Implements ModuleScriptFetcher.
void Fetch(FetchParameters&, void Fetch(FetchParameters&,
ResourceFetcher*, ResourceFetcher*,
const Modulator* modulator_for_built_in_modules,
ModuleGraphLevel, ModuleGraphLevel,
Client*) override; Client*) override;
...@@ -37,7 +38,8 @@ class CORE_EXPORT DocumentModuleScriptFetcher final ...@@ -37,7 +38,8 @@ class CORE_EXPORT DocumentModuleScriptFetcher final
void Trace(blink::Visitor*) override; void Trace(blink::Visitor*) override;
private: private:
bool FetchIfLayeredAPI(FetchParameters&); bool FetchIfLayeredAPI(const Modulator& modulator_for_built_in_modules,
FetchParameters&);
Member<Client> client_; Member<Client> client_;
}; };
......
...@@ -18,6 +18,7 @@ InstalledServiceWorkerModuleScriptFetcher:: ...@@ -18,6 +18,7 @@ InstalledServiceWorkerModuleScriptFetcher::
void InstalledServiceWorkerModuleScriptFetcher::Fetch( void InstalledServiceWorkerModuleScriptFetcher::Fetch(
FetchParameters& fetch_params, FetchParameters& fetch_params,
ResourceFetcher*, ResourceFetcher*,
const Modulator* modulator_for_built_in_modules,
ModuleGraphLevel level, ModuleGraphLevel level,
ModuleScriptFetcher::Client* client) { ModuleScriptFetcher::Client* client) {
DCHECK(global_scope_->IsContextThread()); DCHECK(global_scope_->IsContextThread());
......
...@@ -26,6 +26,7 @@ class CORE_EXPORT InstalledServiceWorkerModuleScriptFetcher final ...@@ -26,6 +26,7 @@ class CORE_EXPORT InstalledServiceWorkerModuleScriptFetcher final
// Implements ModuleScriptFetcher. // Implements ModuleScriptFetcher.
void Fetch(FetchParameters&, void Fetch(FetchParameters&,
ResourceFetcher*, ResourceFetcher*,
const Modulator* modulator_for_built_in_modules,
ModuleGraphLevel, ModuleGraphLevel,
ModuleScriptFetcher::Client*) override; ModuleScriptFetcher::Client*) override;
......
...@@ -37,8 +37,15 @@ class CORE_EXPORT ModuleScriptFetcher : public ResourceClient { ...@@ -37,8 +37,15 @@ class CORE_EXPORT ModuleScriptFetcher : public ResourceClient {
// Takes a non-const reference to FetchParameters because // Takes a non-const reference to FetchParameters because
// ScriptResource::Fetch() requires it. // ScriptResource::Fetch() requires it.
//
// Do not use |modulator_for_built_in_modules| other than for built-in
// modules. Fetching should depend sorely on the ResourceFetcher that
// represents fetch client settings object. https://crbug.com/928435
// |modulator_for_built_in_modules| can be nullptr in unit tests, and
// in such cases built-in modules are not loaded at all.
virtual void Fetch(FetchParameters&, virtual void Fetch(FetchParameters&,
ResourceFetcher*, ResourceFetcher*,
const Modulator* modulator_for_built_in_modules,
ModuleGraphLevel, ModuleGraphLevel,
Client*) = 0; Client*) = 0;
......
...@@ -222,7 +222,7 @@ void ModuleScriptLoader::FetchInternal( ...@@ -222,7 +222,7 @@ void ModuleScriptLoader::FetchInternal(
// [spec text] // [spec text]
module_fetcher_ = modulator_->CreateModuleScriptFetcher(custom_fetch_type); module_fetcher_ = modulator_->CreateModuleScriptFetcher(custom_fetch_type);
module_fetcher_->Fetch(fetch_params, fetch_client_settings_object_fetcher, module_fetcher_->Fetch(fetch_params, fetch_client_settings_object_fetcher,
level, this); modulator_, level, this);
} }
void ModuleScriptLoader::NotifyFetchFinished( void ModuleScriptLoader::NotifyFetchFinished(
......
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
#include "third_party/blink/renderer/platform/bindings/v8_throw_exception.h" #include "third_party/blink/renderer/platform/bindings/v8_throw_exception.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_loading_log.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_loading_log.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/weborigin/security_policy.h" #include "third_party/blink/renderer/platform/weborigin/security_policy.h"
#include "third_party/blink/renderer/platform/wtf/vector.h" #include "third_party/blink/renderer/platform/wtf/vector.h"
#include "v8/include/v8.h" #include "v8/include/v8.h"
...@@ -170,8 +169,8 @@ void ModuleTreeLinker::FetchRoot(const KURL& original_url, ...@@ -170,8 +169,8 @@ void ModuleTreeLinker::FetchRoot(const KURL& original_url,
// href="https://github.com/drufball/layered-apis/blob/master/spec.md#fetch-a-module-script-graph" // href="https://github.com/drufball/layered-apis/blob/master/spec.md#fetch-a-module-script-graph"
// step="1">Set url to the layered API fetching URL given url and the current // step="1">Set url to the layered API fetching URL given url and the current
// settings object's API base URL.</spec> // settings object's API base URL.</spec>
if (RuntimeEnabledFeatures::BuiltInModuleInfraEnabled()) if (modulator_->BuiltInModuleInfraEnabled())
url = blink::layered_api::ResolveFetchingURL(url); url = blink::layered_api::ResolveFetchingURL(*modulator_, url);
#if DCHECK_IS_ON() #if DCHECK_IS_ON()
url_ = url; url_ = url;
......
...@@ -21,6 +21,7 @@ WorkerModuleScriptFetcher::WorkerModuleScriptFetcher( ...@@ -21,6 +21,7 @@ WorkerModuleScriptFetcher::WorkerModuleScriptFetcher(
void WorkerModuleScriptFetcher::Fetch( void WorkerModuleScriptFetcher::Fetch(
FetchParameters& fetch_params, FetchParameters& fetch_params,
ResourceFetcher* fetch_client_settings_object_fetcher, ResourceFetcher* fetch_client_settings_object_fetcher,
const Modulator* modulator_for_built_in_modules,
ModuleGraphLevel level, ModuleGraphLevel level,
ModuleScriptFetcher::Client* client) { ModuleScriptFetcher::Client* client) {
DCHECK(global_scope_->IsContextThread()); DCHECK(global_scope_->IsContextThread());
......
...@@ -27,6 +27,7 @@ class CORE_EXPORT WorkerModuleScriptFetcher final ...@@ -27,6 +27,7 @@ class CORE_EXPORT WorkerModuleScriptFetcher final
// Implements ModuleScriptFetcher. // Implements ModuleScriptFetcher.
void Fetch(FetchParameters&, void Fetch(FetchParameters&,
ResourceFetcher*, ResourceFetcher*,
const Modulator* modulator_for_built_in_modules,
ModuleGraphLevel, ModuleGraphLevel,
ModuleScriptFetcher::Client*) override; ModuleScriptFetcher::Client*) override;
......
...@@ -15,6 +15,7 @@ WorkletModuleScriptFetcher::WorkletModuleScriptFetcher( ...@@ -15,6 +15,7 @@ WorkletModuleScriptFetcher::WorkletModuleScriptFetcher(
void WorkletModuleScriptFetcher::Fetch( void WorkletModuleScriptFetcher::Fetch(
FetchParameters& fetch_params, FetchParameters& fetch_params,
ResourceFetcher* fetch_client_settings_object_fetcher, ResourceFetcher* fetch_client_settings_object_fetcher,
const Modulator* modulator_for_built_in_modules,
ModuleGraphLevel level, ModuleGraphLevel level,
ModuleScriptFetcher::Client* client) { ModuleScriptFetcher::Client* client) {
if (module_responses_map_->GetEntry( if (module_responses_map_->GetEntry(
......
...@@ -33,6 +33,7 @@ class CORE_EXPORT WorkletModuleScriptFetcher final ...@@ -33,6 +33,7 @@ class CORE_EXPORT WorkletModuleScriptFetcher final
// Implements ModuleScriptFetcher. // Implements ModuleScriptFetcher.
void Fetch(FetchParameters&, void Fetch(FetchParameters&,
ResourceFetcher*, ResourceFetcher*,
const Modulator* modulator_for_built_in_modules,
ModuleGraphLevel, ModuleGraphLevel,
ModuleScriptFetcher::Client*) override; ModuleScriptFetcher::Client*) override;
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <memory> #include <memory>
#include <utility> #include <utility>
#include "third_party/blink/renderer/core/script/layered_api.h" #include "third_party/blink/renderer/core/script/layered_api.h"
#include "third_party/blink/renderer/core/script/modulator.h"
#include "third_party/blink/renderer/core/script/parsed_specifier.h" #include "third_party/blink/renderer/core/script/parsed_specifier.h"
#include "third_party/blink/renderer/platform/json/json_parser.h" #include "third_party/blink/renderer/platform/json/json_parser.h"
#include "third_party/blink/renderer/platform/json/json_values.h" #include "third_party/blink/renderer/platform/json/json_values.h"
...@@ -92,7 +93,8 @@ KURL GetValue(const String& key, ...@@ -92,7 +93,8 @@ KURL GetValue(const String& key,
// ignored, except that they are reported to the console |logger|. // ignored, except that they are reported to the console |logger|.
// TODO(hiroshige): Handle errors in a spec-conformant way once specified. // TODO(hiroshige): Handle errors in a spec-conformant way once specified.
// https://github.com/WICG/import-maps/issues/100 // https://github.com/WICG/import-maps/issues/100
ImportMap* ImportMap::Create(const String& text, ImportMap* ImportMap::Create(const Modulator& modulator_for_built_in_modules,
const String& text,
const KURL& base_url, const KURL& base_url,
ConsoleLogger& logger) { ConsoleLogger& logger) {
HashMap<String, Vector<KURL>> modules_map; HashMap<String, Vector<KURL>> modules_map;
...@@ -101,21 +103,24 @@ ImportMap* ImportMap::Create(const String& text, ...@@ -101,21 +103,24 @@ ImportMap* ImportMap::Create(const String& text,
if (!root) { if (!root) {
logger.AddErrorMessage(ConsoleLogger::Source::kOther, logger.AddErrorMessage(ConsoleLogger::Source::kOther,
"Failed to parse import map: invalid JSON"); "Failed to parse import map: invalid JSON");
return MakeGarbageCollected<ImportMap>(modules_map); return MakeGarbageCollected<ImportMap>(modulator_for_built_in_modules,
modules_map);
} }
std::unique_ptr<JSONObject> root_object = JSONObject::From(std::move(root)); std::unique_ptr<JSONObject> root_object = JSONObject::From(std::move(root));
if (!root_object) { if (!root_object) {
logger.AddErrorMessage(ConsoleLogger::Source::kOther, logger.AddErrorMessage(ConsoleLogger::Source::kOther,
"Failed to parse import map: not an object"); "Failed to parse import map: not an object");
return MakeGarbageCollected<ImportMap>(modules_map); return MakeGarbageCollected<ImportMap>(modulator_for_built_in_modules,
modules_map);
} }
JSONObject* modules = root_object->GetJSONObject("imports"); JSONObject* modules = root_object->GetJSONObject("imports");
if (!modules) { if (!modules) {
logger.AddErrorMessage(ConsoleLogger::Source::kOther, logger.AddErrorMessage(ConsoleLogger::Source::kOther,
"Failed to parse import map: no \"imports\" entry."); "Failed to parse import map: no \"imports\" entry.");
return MakeGarbageCollected<ImportMap>(modules_map); return MakeGarbageCollected<ImportMap>(modulator_for_built_in_modules,
modules_map);
} }
for (wtf_size_t i = 0; i < modules->size(); ++i) { for (wtf_size_t i = 0; i < modules->size(); ++i) {
...@@ -196,9 +201,15 @@ ImportMap* ImportMap::Create(const String& text, ...@@ -196,9 +201,15 @@ ImportMap* ImportMap::Create(const String& text,
// TODO(crbug.com/927181): Process "scopes" entry. // TODO(crbug.com/927181): Process "scopes" entry.
return MakeGarbageCollected<ImportMap>(modules_map); return MakeGarbageCollected<ImportMap>(modulator_for_built_in_modules,
modules_map);
} }
ImportMap::ImportMap(const Modulator& modulator_for_built_in_modules,
const HashMap<String, Vector<KURL>>& imports)
: imports_(imports),
modulator_for_built_in_modules_(&modulator_for_built_in_modules) {}
base::Optional<KURL> ImportMap::Resolve(const ParsedSpecifier& parsed_specifier, base::Optional<KURL> ImportMap::Resolve(const ParsedSpecifier& parsed_specifier,
String* debug_message) const { String* debug_message) const {
DCHECK(debug_message); DCHECK(debug_message);
...@@ -211,7 +222,9 @@ base::Optional<KURL> ImportMap::Resolve(const ParsedSpecifier& parsed_specifier, ...@@ -211,7 +222,9 @@ base::Optional<KURL> ImportMap::Resolve(const ParsedSpecifier& parsed_specifier,
} }
for (const auto& candidate_url : it->value) { for (const auto& candidate_url : it->value) {
if (blink::layered_api::ResolveFetchingURL(candidate_url).IsValid()) { if (blink::layered_api::ResolveFetchingURL(*modulator_for_built_in_modules_,
candidate_url)
.IsValid()) {
*debug_message = "Import Map: \"" + key + "\" matches with \"" + it->key + *debug_message = "Import Map: \"" + key + "\" matches with \"" + it->key +
"\" and is mapped to " + candidate_url.ElidedString(); "\" and is mapped to " + candidate_url.ElidedString();
return candidate_url; return candidate_url;
...@@ -241,4 +254,8 @@ String ImportMap::ToString() const { ...@@ -241,4 +254,8 @@ String ImportMap::ToString() const {
return builder.ToString(); return builder.ToString();
} }
void ImportMap::Trace(Visitor* visitor) {
visitor->Trace(modulator_for_built_in_modules_);
}
} // namespace blink } // namespace blink
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
namespace blink { namespace blink {
class ConsoleLogger; class ConsoleLogger;
class Modulator;
class ParsedSpecifier; class ParsedSpecifier;
// Import maps. // Import maps.
...@@ -22,12 +23,12 @@ class ParsedSpecifier; ...@@ -22,12 +23,12 @@ class ParsedSpecifier;
// https://github.com/WICG/import-maps/blob/master/spec.md // https://github.com/WICG/import-maps/blob/master/spec.md
class ImportMap final : public GarbageCollectedFinalized<ImportMap> { class ImportMap final : public GarbageCollectedFinalized<ImportMap> {
public: public:
static ImportMap* Create(const String& text, static ImportMap* Create(const Modulator& modulator_for_built_in_modules,
const String& text,
const KURL& base_url, const KURL& base_url,
ConsoleLogger& logger); ConsoleLogger& logger);
explicit ImportMap(const HashMap<String, Vector<KURL>>& imports) ImportMap(const Modulator&, const HashMap<String, Vector<KURL>>& imports);
: imports_(imports) {}
// Returns nullopt when not mapped by |this| import map (i.e. the import map // Returns nullopt when not mapped by |this| import map (i.e. the import map
// doesn't have corresponding keys). // doesn't have corresponding keys).
...@@ -37,10 +38,11 @@ class ImportMap final : public GarbageCollectedFinalized<ImportMap> { ...@@ -37,10 +38,11 @@ class ImportMap final : public GarbageCollectedFinalized<ImportMap> {
String ToString() const; String ToString() const;
void Trace(Visitor*) {} void Trace(Visitor*);
private: private:
HashMap<String, Vector<KURL>> imports_; HashMap<String, Vector<KURL>> imports_;
Member<const Modulator> modulator_for_built_in_modules_;
}; };
} // namespace blink } // namespace blink
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include "base/stl_util.h" #include "base/stl_util.h"
#include "third_party/blink/renderer/core/script/layered_api_resources.h" #include "third_party/blink/renderer/core/script/layered_api_resources.h"
#include "third_party/blink/renderer/core/script/modulator.h"
#include "third_party/blink/renderer/platform/data_resource_helper.h" #include "third_party/blink/renderer/platform/data_resource_helper.h"
#include "third_party/blink/renderer/platform/wtf/text/string_builder.h" #include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
...@@ -22,17 +23,18 @@ static const char kImportScheme[] = "import"; ...@@ -22,17 +23,18 @@ static const char kImportScheme[] = "import";
constexpr char kBuiltinSpecifierPrefix[] = "@std/"; constexpr char kBuiltinSpecifierPrefix[] = "@std/";
int GetResourceIDFromPath(const String& path) { int GetResourceIDFromPath(const Modulator& modulator, const String& path) {
for (size_t i = 0; i < base::size(kLayeredAPIResources); ++i) { for (size_t i = 0; i < base::size(kLayeredAPIResources); ++i) {
if (path == kLayeredAPIResources[i].path) { if (modulator.BuiltInModuleEnabled(kLayeredAPIResources[i].module) &&
path == kLayeredAPIResources[i].path) {
return kLayeredAPIResources[i].resource_id; return kLayeredAPIResources[i].resource_id;
} }
} }
return -1; return -1;
} }
bool IsImplemented(const String& name) { bool IsImplemented(const Modulator& modulator, const String& name) {
return GetResourceIDFromPath(name + "/index.js") >= 0; return GetResourceIDFromPath(modulator, name + "/index.js") >= 0;
} }
} // namespace } // namespace
...@@ -49,7 +51,7 @@ String GetBuiltinPath(const KURL& url) { ...@@ -49,7 +51,7 @@ String GetBuiltinPath(const KURL& url) {
} }
// https://github.com/drufball/layered-apis/blob/master/spec.md#user-content-layered-api-fetching-url // https://github.com/drufball/layered-apis/blob/master/spec.md#user-content-layered-api-fetching-url
KURL ResolveFetchingURL(const KURL& url) { KURL ResolveFetchingURL(const Modulator& modulator, const KURL& url) {
// <spec step="1">If url's scheme is not "std", return url.</spec> // <spec step="1">If url's scheme is not "std", return url.</spec>
// <spec step="2">Let path be url's path[0].</spec> // <spec step="2">Let path be url's path[0].</spec>
// Note: Also accepts "import:@std/x". // Note: Also accepts "import:@std/x".
...@@ -61,7 +63,7 @@ KURL ResolveFetchingURL(const KURL& url) { ...@@ -61,7 +63,7 @@ KURL ResolveFetchingURL(const KURL& url) {
// <spec step="5">If the layered API identified by path is implemented by this // <spec step="5">If the layered API identified by path is implemented by this
// user agent, return the result of parsing the concatenation of "std:" with // user agent, return the result of parsing the concatenation of "std:" with
// identifier.</spec> // identifier.</spec>
if (IsImplemented(path)) { if (IsImplemented(modulator, path)) {
StringBuilder url_string; StringBuilder url_string;
url_string.Append(kStdScheme); url_string.Append(kStdScheme);
url_string.Append(":"); url_string.Append(":");
...@@ -90,7 +92,7 @@ KURL GetInternalURL(const KURL& url) { ...@@ -90,7 +92,7 @@ KURL GetInternalURL(const KURL& url) {
return NullURL(); return NullURL();
} }
String GetSourceText(const KURL& url) { String GetSourceText(const Modulator& modulator, const KURL& url) {
if (!url.ProtocolIs(kInternalScheme)) if (!url.ProtocolIs(kInternalScheme))
return String(); return String();
...@@ -102,7 +104,7 @@ String GetSourceText(const KURL& url) { ...@@ -102,7 +104,7 @@ String GetSourceText(const KURL& url) {
path = path.Substring(2); path = path.Substring(2);
} }
int resource_id = GetResourceIDFromPath(path); int resource_id = GetResourceIDFromPath(modulator, path);
if (resource_id < 0) if (resource_id < 0)
return String(); return String();
......
...@@ -11,10 +11,21 @@ ...@@ -11,10 +11,21 @@
namespace blink { namespace blink {
class Modulator;
// Implements Layered API. // Implements Layered API.
// Spec: https://github.com/drufball/layered-apis/blob/master/spec.md // Spec: https://github.com/drufball/layered-apis/blob/master/spec.md
// Implementation Design Doc: // Implementation Design Doc:
// https://docs.google.com/document/d/1V-WaCZQbBcQJRSYSYBb8Y6p0DOdDpiNDSmD41ui_73s/edit // https://docs.google.com/document/d/1V-WaCZQbBcQJRSYSYBb8Y6p0DOdDpiNDSmD41ui_73s/edit
// Some methods takes Modulator as an argument, to support origin trials
// (which depends on ExecutionContext).
// TODO(hiroshige): Using Modulator here means Layered API fetching and
// import maps fallback depends on module map settings object. Currently
// this is consistent throughout Blink implementation, but this might cause
// problems when we support built-in modules around workers
// (https://crbug.com/927477), and we might switch to fetch client settings
// object in the future (https://crbug.com/928435).
namespace layered_api { namespace layered_api {
// Returns the path part (`x`) for std:x or import:@std/x URLs. // Returns the path part (`x`) for std:x or import:@std/x URLs.
...@@ -30,14 +41,14 @@ CORE_EXPORT String GetBuiltinPath(const KURL&); ...@@ -30,14 +41,14 @@ CORE_EXPORT String GetBuiltinPath(const KURL&);
// //
// Currently fallback syntax is disabled and only "std:x" (not "std:x|y") is // Currently fallback syntax is disabled and only "std:x" (not "std:x|y") is
// accepted. https://crbug.com/864748 // accepted. https://crbug.com/864748
CORE_EXPORT KURL ResolveFetchingURL(const KURL&); CORE_EXPORT KURL ResolveFetchingURL(const Modulator&, const KURL&);
// Returns std-internal://x/index.js if the URL is Layered API, or null URL // Returns std-internal://x/index.js if the URL is Layered API, or null URL
// otherwise (not specced). // otherwise (not specced).
CORE_EXPORT KURL GetInternalURL(const KURL&); CORE_EXPORT KURL GetInternalURL(const KURL&);
// Gets source text for std-internal://x/index.js. // Gets source text for std-internal://x/index.js.
CORE_EXPORT String GetSourceText(const KURL&); CORE_EXPORT String GetSourceText(const Modulator&, const KURL&);
} // namespace layered_api } // namespace layered_api
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "third_party/blink/renderer/core/script/layered_api.h" #include "third_party/blink/renderer/core/script/layered_api.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/core/testing/dummy_modulator.h"
namespace blink { namespace blink {
...@@ -12,23 +13,43 @@ namespace layered_api { ...@@ -12,23 +13,43 @@ namespace layered_api {
namespace { namespace {
TEST(LayeredAPITest, ResolveFetchingURL) { class LayeredAPITestModulator final : public DummyModulator {
public:
bool BuiltInModuleInfraEnabled() const override { return true; }
bool BuiltInModuleEnabled(blink::layered_api::Module) const override {
return true;
}
};
class LayeredAPITest : public testing::Test {
public:
LayeredAPITest()
: modulator_(MakeGarbageCollected<LayeredAPITestModulator>()) {}
const Modulator& GetModulator() const { return *modulator_; }
private:
Persistent<LayeredAPITestModulator> modulator_;
};
TEST_F(LayeredAPITest, ResolveFetchingURL) {
KURL base_url("https://example.com/base/path/"); KURL base_url("https://example.com/base/path/");
EXPECT_EQ(ResolveFetchingURL(KURL("https://example.com/")), EXPECT_EQ(ResolveFetchingURL(GetModulator(), KURL("https://example.com/")),
KURL("https://example.com/")); KURL("https://example.com/"));
EXPECT_EQ(ResolveFetchingURL(KURL("std:blank")), KURL("std:blank")); EXPECT_EQ(ResolveFetchingURL(GetModulator(), KURL("std:blank")),
KURL("std:blank"));
EXPECT_EQ(ResolveFetchingURL(KURL("std:none")), NullURL()); EXPECT_EQ(ResolveFetchingURL(GetModulator(), KURL("std:none")), NullURL());
// Fallback syntax is currently disabled and rejected. // Fallback syntax is currently disabled and rejected.
// https://crbug.com/864748 // https://crbug.com/864748
EXPECT_EQ(ResolveFetchingURL(KURL("std:blank|https://example.com/")), EXPECT_EQ(ResolveFetchingURL(GetModulator(),
KURL("std:blank|https://example.com/")),
NullURL()); NullURL());
} }
TEST(LayeredAPITest, GetInternalURL) { TEST_F(LayeredAPITest, GetInternalURL) {
EXPECT_EQ(GetInternalURL(KURL("https://example.com/")), NullURL()); EXPECT_EQ(GetInternalURL(KURL("https://example.com/")), NullURL());
EXPECT_EQ(GetInternalURL(KURL("std:blank")), EXPECT_EQ(GetInternalURL(KURL("std:blank")),
...@@ -40,7 +61,7 @@ TEST(LayeredAPITest, GetInternalURL) { ...@@ -40,7 +61,7 @@ TEST(LayeredAPITest, GetInternalURL) {
KURL("std-internal://blank/foo/bar.js")); KURL("std-internal://blank/foo/bar.js"));
} }
TEST(LayeredAPITest, InternalURLRelativeResolution) { TEST_F(LayeredAPITest, InternalURLRelativeResolution) {
EXPECT_EQ(KURL(KURL("std-internal://blank/index.js"), "./sub.js"), EXPECT_EQ(KURL(KURL("std-internal://blank/index.js"), "./sub.js"),
KURL("std-internal://blank/sub.js")); KURL("std-internal://blank/sub.js"));
EXPECT_EQ(KURL(KURL("std-internal://blank/index.js"), "/sub.js"), EXPECT_EQ(KURL(KURL("std-internal://blank/index.js"), "/sub.js"),
...@@ -51,13 +72,19 @@ TEST(LayeredAPITest, InternalURLRelativeResolution) { ...@@ -51,13 +72,19 @@ TEST(LayeredAPITest, InternalURLRelativeResolution) {
KURL("std-internal://blank/baz.js")); KURL("std-internal://blank/baz.js"));
} }
TEST(LayeredAPITest, GetSourceText) { TEST_F(LayeredAPITest, GetSourceText) {
EXPECT_EQ(GetSourceText(KURL("std-internal://blank/index.js")), String("")); EXPECT_EQ(
GetSourceText(GetModulator(), KURL("std-internal://blank/index.js")),
String(""));
EXPECT_EQ(GetSourceText(KURL("std-internal://blank/not-found.js")), String()); EXPECT_EQ(
EXPECT_EQ(GetSourceText(KURL("std-internal://none/index.js")), String()); GetSourceText(GetModulator(), KURL("std-internal://blank/not-found.js")),
String());
EXPECT_EQ(GetSourceText(GetModulator(), KURL("std-internal://none/index.js")),
String());
EXPECT_EQ(GetSourceText(KURL("https://example.com/")), String()); EXPECT_EQ(GetSourceText(GetModulator(), KURL("https://example.com/")),
String());
} }
} // namespace } // namespace
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "third_party/blink/renderer/bindings/core/v8/script_module.h" #include "third_party/blink/renderer/bindings/core/v8/script_module.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_code_cache.h" #include "third_party/blink/renderer/bindings/core/v8/v8_code_cache.h"
#include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/script/layered_api_module.h"
#include "third_party/blink/renderer/core/script/module_import_meta.h" #include "third_party/blink/renderer/core/script/module_import_meta.h"
#include "third_party/blink/renderer/platform/bindings/name_client.h" #include "third_party/blink/renderer/platform/bindings/name_client.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
...@@ -120,6 +121,9 @@ class CORE_EXPORT Modulator : public GarbageCollectedFinalized<Modulator>, ...@@ -120,6 +121,9 @@ class CORE_EXPORT Modulator : public GarbageCollectedFinalized<Modulator>,
// "scripting is disabled for settings's responsible browsing context" // "scripting is disabled for settings's responsible browsing context"
virtual bool IsScriptingDisabled() const = 0; virtual bool IsScriptingDisabled() const = 0;
virtual bool BuiltInModuleInfraEnabled() const = 0;
virtual bool BuiltInModuleEnabled(blink::layered_api::Module) const = 0;
// https://html.spec.whatwg.org/C/#fetch-a-module-script-tree // https://html.spec.whatwg.org/C/#fetch-a-module-script-tree
// https://html.spec.whatwg.org/C/#fetch-a-module-worker-script-tree // https://html.spec.whatwg.org/C/#fetch-a-module-worker-script-tree
// Note that |this| is the "module map settings object" and // Note that |this| is the "module map settings object" and
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "third_party/blink/renderer/core/loader/modulescript/module_script_fetch_request.h" #include "third_party/blink/renderer/core/loader/modulescript/module_script_fetch_request.h"
#include "third_party/blink/renderer/core/loader/modulescript/module_tree_linker.h" #include "third_party/blink/renderer/core/loader/modulescript/module_tree_linker.h"
#include "third_party/blink/renderer/core/loader/modulescript/module_tree_linker_registry.h" #include "third_party/blink/renderer/core/loader/modulescript/module_tree_linker_registry.h"
#include "third_party/blink/renderer/core/origin_trials/origin_trials.h"
#include "third_party/blink/renderer/core/script/dynamic_module_resolver.h" #include "third_party/blink/renderer/core/script/dynamic_module_resolver.h"
#include "third_party/blink/renderer/core/script/import_map.h" #include "third_party/blink/renderer/core/script/import_map.h"
#include "third_party/blink/renderer/core/script/module_map.h" #include "third_party/blink/renderer/core/script/module_map.h"
...@@ -45,6 +46,25 @@ bool ModulatorImplBase::IsScriptingDisabled() const { ...@@ -45,6 +46,25 @@ bool ModulatorImplBase::IsScriptingDisabled() const {
return !GetExecutionContext()->CanExecuteScripts(kAboutToExecuteScript); return !GetExecutionContext()->CanExecuteScripts(kAboutToExecuteScript);
} }
bool ModulatorImplBase::BuiltInModuleInfraEnabled() const {
return origin_trials::BuiltInModuleInfraEnabled(GetExecutionContext());
}
bool ModulatorImplBase::BuiltInModuleEnabled(
blink::layered_api::Module module) const {
DCHECK(BuiltInModuleInfraEnabled());
switch (module) {
case blink::layered_api::Module::kBlank:
return true;
case blink::layered_api::Module::kVirtualScroller:
return RuntimeEnabledFeatures::BuiltInModuleAllEnabled();
case blink::layered_api::Module::kKvStorage:
return RuntimeEnabledFeatures::BuiltInModuleAllEnabled() ||
origin_trials::BuiltInModuleKvStorageEnabled(
GetExecutionContext());
}
}
// <specdef label="fetch-a-module-script-tree" // <specdef label="fetch-a-module-script-tree"
// href="https://html.spec.whatwg.org/C/#fetch-a-module-script-tree"> // href="https://html.spec.whatwg.org/C/#fetch-a-module-script-tree">
// <specdef label="fetch-a-module-worker-script-tree" // <specdef label="fetch-a-module-worker-script-tree"
...@@ -161,7 +181,7 @@ KURL ModulatorImplBase::ResolveModuleSpecifier(const String& specifier, ...@@ -161,7 +181,7 @@ KURL ModulatorImplBase::ResolveModuleSpecifier(const String& specifier,
case ParsedSpecifier::Type::kBare: case ParsedSpecifier::Type::kBare:
// Allow |@std/x| specifiers if Layered API is enabled. // Allow |@std/x| specifiers if Layered API is enabled.
if (RuntimeEnabledFeatures::BuiltInModuleInfraEnabled()) { if (BuiltInModuleInfraEnabled()) {
if (parsed_specifier.GetImportMapKeyString().StartsWith("@std/")) { if (parsed_specifier.GetImportMapKeyString().StartsWith("@std/")) {
return KURL("import:" + parsed_specifier.GetImportMapKeyString()); return KURL("import:" + parsed_specifier.GetImportMapKeyString());
} }
...@@ -190,7 +210,7 @@ void ModulatorImplBase::RegisterImportMap(const ImportMap* import_map) { ...@@ -190,7 +210,7 @@ void ModulatorImplBase::RegisterImportMap(const ImportMap* import_map) {
return; return;
} }
if (!RuntimeEnabledFeatures::BuiltInModuleInfraEnabled()) { if (!BuiltInModuleInfraEnabled()) {
GetExecutionContext()->AddErrorMessage( GetExecutionContext()->AddErrorMessage(
ConsoleLogger::Source::kOther, ConsoleLogger::Source::kOther,
"Import maps are disabled when Layered API Infra is disabled."); "Import maps are disabled when Layered API Infra is disabled.");
......
...@@ -42,6 +42,9 @@ class ModulatorImplBase : public Modulator { ...@@ -42,6 +42,9 @@ class ModulatorImplBase : public Modulator {
bool IsScriptingDisabled() const override; bool IsScriptingDisabled() const override;
bool BuiltInModuleInfraEnabled() const override;
bool BuiltInModuleEnabled(blink::layered_api::Module) const override;
ScriptModuleResolver* GetScriptModuleResolver() override { ScriptModuleResolver* GetScriptModuleResolver() override {
return script_module_resolver_.Get(); return script_module_resolver_.Get();
} }
......
...@@ -111,6 +111,7 @@ class ModuleMapTestModulator final : public DummyModulator { ...@@ -111,6 +111,7 @@ class ModuleMapTestModulator final : public DummyModulator {
: modulator_(modulator) {} : modulator_(modulator) {}
void Fetch(FetchParameters& request, void Fetch(FetchParameters& request,
ResourceFetcher*, ResourceFetcher*,
const Modulator* modulator_for_built_in_modules,
ModuleGraphLevel, ModuleGraphLevel,
ModuleScriptFetcher::Client* client) override { ModuleScriptFetcher::Client* client) override {
TestRequest* test_request = MakeGarbageCollected<TestRequest>( TestRequest* test_request = MakeGarbageCollected<TestRequest>(
......
...@@ -180,7 +180,7 @@ ShouldFireErrorEvent ParseAndRegisterImportMap(ScriptElementBase& element) { ...@@ -180,7 +180,7 @@ ShouldFireErrorEvent ParseAndRegisterImportMap(ScriptElementBase& element) {
// If import maps are not enabled, we do nothing and return here, and also // If import maps are not enabled, we do nothing and return here, and also
// do not fire error events. // do not fire error events.
if (!RuntimeEnabledFeatures::BuiltInModuleInfraEnabled()) if (!modulator->BuiltInModuleInfraEnabled())
return ShouldFireErrorEvent::kDoNotFire; return ShouldFireErrorEvent::kDoNotFire;
if (!modulator->IsAcquiringImportMaps()) { if (!modulator->IsAcquiringImportMaps()) {
...@@ -199,8 +199,8 @@ ShouldFireErrorEvent ParseAndRegisterImportMap(ScriptElementBase& element) { ...@@ -199,8 +199,8 @@ ShouldFireErrorEvent ParseAndRegisterImportMap(ScriptElementBase& element) {
} }
KURL base_url = element_document.BaseURL(); KURL base_url = element_document.BaseURL();
ImportMap* import_map = ImportMap* import_map = ImportMap::Create(
ImportMap::Create(element.TextFromChildren(), base_url, element_document); *modulator, element.TextFromChildren(), base_url, element_document);
if (!import_map) if (!import_map)
return ShouldFireErrorEvent::kShouldFire; return ShouldFireErrorEvent::kShouldFire;
......
...@@ -58,6 +58,14 @@ bool DummyModulator::IsScriptingDisabled() const { ...@@ -58,6 +58,14 @@ bool DummyModulator::IsScriptingDisabled() const {
return false; return false;
} }
bool DummyModulator::BuiltInModuleInfraEnabled() const {
return false;
}
bool DummyModulator::BuiltInModuleEnabled(blink::layered_api::Module) const {
return false;
}
ScriptModuleResolver* DummyModulator::GetScriptModuleResolver() { ScriptModuleResolver* DummyModulator::GetScriptModuleResolver() {
return resolver_.Get(); return resolver_.Get();
} }
......
...@@ -35,6 +35,9 @@ class DummyModulator : public Modulator { ...@@ -35,6 +35,9 @@ class DummyModulator : public Modulator {
V8CacheOptions GetV8CacheOptions() const override; V8CacheOptions GetV8CacheOptions() const override;
bool IsScriptingDisabled() const override; bool IsScriptingDisabled() const override;
bool BuiltInModuleInfraEnabled() const override;
bool BuiltInModuleEnabled(blink::layered_api::Module) const override;
void FetchTree(const KURL&, void FetchTree(const KURL&,
ResourceFetcher*, ResourceFetcher*,
mojom::RequestContextType destination, mojom::RequestContextType destination,
......
...@@ -43,6 +43,7 @@ class WorkletModuleResponsesMapTest : public testing::Test { ...@@ -43,6 +43,7 @@ class WorkletModuleResponsesMapTest : public testing::Test {
WorkletModuleScriptFetcher* module_fetcher = WorkletModuleScriptFetcher* module_fetcher =
MakeGarbageCollected<WorkletModuleScriptFetcher>(map_.Get()); MakeGarbageCollected<WorkletModuleScriptFetcher>(map_.Get());
module_fetcher->Fetch(fetch_params, fetcher_.Get(), module_fetcher->Fetch(fetch_params, fetcher_.Get(),
nullptr /* modulator_for_built_in_modules */,
ModuleGraphLevel::kTopLevelModuleFetch, client); ModuleGraphLevel::kTopLevelModuleFetch, client);
} }
......
...@@ -187,12 +187,14 @@ ...@@ -187,12 +187,14 @@
}, },
{ {
name: "BuiltInModuleInfra", name: "BuiltInModuleInfra",
origin_trial_feature_name: "BuiltInModuleInfra",
implied_by: ["ExperimentalProductivityFeatures", implied_by: ["ExperimentalProductivityFeatures",
"BuiltInModuleAll", "BuiltInModuleAll",
"BuiltInModuleKvStorage"], "BuiltInModuleKvStorage"],
}, },
{ {
name: "BuiltInModuleKvStorage", name: "BuiltInModuleKvStorage",
origin_trial_feature_name: "BuiltInModuleKvStorage",
implied_by: ["ExperimentalProductivityFeatures"], implied_by: ["ExperimentalProductivityFeatures"],
}, },
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment