diff options
Diffstat (limited to 'chromium/third_party/blink/renderer/core/script')
46 files changed, 1159 insertions, 679 deletions
diff --git a/chromium/third_party/blink/renderer/core/script/BUILD.gn b/chromium/third_party/blink/renderer/core/script/BUILD.gn index ff592b2f241..b02fb078836 100644 --- a/chromium/third_party/blink/renderer/core/script/BUILD.gn +++ b/chromium/third_party/blink/renderer/core/script/BUILD.gn @@ -26,6 +26,7 @@ blink_core_sources("script") { "ignore_destructive_write_count_incrementer.h", "layered_api.cc", "layered_api.h", + "layered_api_resources.h", "modulator.cc", "modulator.h", "modulator_impl_base.cc", diff --git a/chromium/third_party/blink/renderer/core/script/classic_pending_script.cc b/chromium/third_party/blink/renderer/core/script/classic_pending_script.cc index 8a92a60c654..65e1def936b 100644 --- a/chromium/third_party/blink/renderer/core/script/classic_pending_script.cc +++ b/chromium/third_party/blink/renderer/core/script/classic_pending_script.cc @@ -11,7 +11,6 @@ #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/scriptable_document_parser.h" #include "third_party/blink/renderer/core/frame/local_frame.h" -#include "third_party/blink/renderer/core/loader/allowed_by_nosniff.h" #include "third_party/blink/renderer/core/loader/document_loader.h" #include "third_party/blink/renderer/core/loader/resource/script_resource.h" #include "third_party/blink/renderer/core/loader/subresource_integrity_helper.h" @@ -19,10 +18,12 @@ #include "third_party/blink/renderer/core/script/script_loader.h" #include "third_party/blink/renderer/platform/bindings/script_state.h" #include "third_party/blink/renderer/platform/histogram.h" +#include "third_party/blink/renderer/platform/loader/allowed_by_nosniff.h" #include "third_party/blink/renderer/platform/loader/fetch/cached_metadata.h" #include "third_party/blink/renderer/platform/loader/fetch/memory_cache.h" #include "third_party/blink/renderer/platform/loader/fetch/raw_resource.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_client.h" +#include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h" #include "third_party/blink/renderer/platform/loader/fetch/source_keyed_cached_metadata_handler.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/wtf/functional.h" @@ -41,9 +42,10 @@ ClassicPendingScript* ClassicPendingScript::Fetch( FetchParameters params = options.CreateFetchParameters( url, element_document.GetSecurityOrigin(), cross_origin, encoding, defer); - ClassicPendingScript* pending_script = new ClassicPendingScript( - element, TextPosition(), ScriptSourceLocationType::kExternalFile, options, - true /* is_external */); + ClassicPendingScript* pending_script = + MakeGarbageCollected<ClassicPendingScript>( + element, TextPosition(), ScriptSourceLocationType::kExternalFile, + options, true /* is_external */); // [Intervention] // For users on slow connections, we want to avoid blocking the parser in @@ -72,8 +74,9 @@ ClassicPendingScript* ClassicPendingScript::CreateInline( ScriptSourceLocationType source_location_type, const ScriptFetchOptions& options) { ClassicPendingScript* pending_script = - new ClassicPendingScript(element, starting_position, source_location_type, - options, false /* is_external */); + MakeGarbageCollected<ClassicPendingScript>(element, starting_position, + source_location_type, options, + false /* is_external */); pending_script->CheckState(); return pending_script; } @@ -93,8 +96,7 @@ ClassicPendingScript::ClassicPendingScript( source_location_type_(source_location_type), is_external_(is_external), ready_state_(is_external ? kWaitingForResource : kReady), - integrity_failure_(false), - is_currently_streaming_(false) { + integrity_failure_(false) { CHECK(GetElement()); MemoryCoordinator::Instance().RegisterClient(this); } @@ -297,6 +299,7 @@ ClassicScript* ClassicPendingScript::GetSource(const KURL& document_url) const { if (ready_state_ == kErrorOccurred) return nullptr; + TRACE_EVENT0("blink", "ClassicPendingScript::GetSource"); if (!is_external_) { SingleCachedMetadataHandler* cache_handler = nullptr; // We only create an inline cache handler for html-embedded scripts, not @@ -327,10 +330,12 @@ ClassicScript* ClassicPendingScript::GetSource(const KURL& document_url) const { DCHECK(GetResource()->IsLoaded()); ScriptResource* resource = ToScriptResource(GetResource()); + auto* fetcher = GetElement()->GetDocument().ContextDocument()->Fetcher(); // If the MIME check fails, which is considered as load failure. if (!AllowedByNosniff::MimeTypeAsScript( - GetElement()->GetDocument().ContextDocument(), - resource->GetResponse(), AllowedByNosniff::MimeTypeCheck::kLax)) { + fetcher->Context(), fetcher->GetConsoleLogger(), + resource->GetResponse(), AllowedByNosniff::MimeTypeCheck::kLax, + false)) { return nullptr; } @@ -390,42 +395,9 @@ void ClassicPendingScript::AdvanceReadyState(ReadyState new_ready_state) { bool old_is_ready = IsReady(); ready_state_ = new_ready_state; - ScriptResource* resource = ToScriptResource(GetResource()); - // Did we transition into a 'ready' state? if (IsReady() && !old_is_ready && IsWatchingForLoad()) PendingScriptFinished(); - - // Did we finish streaming? - if (IsCurrentlyStreaming()) { - if (ready_state_ == kReady || ready_state_ == kErrorOccurred) { - // Call the streamer_done_ callback. Ensure that is_currently_streaming_ - // is reset only after the callback returns, to prevent accidentally - // start streaming by work done within the callback. (crbug.com/754360) - base::OnceClosure done = std::move(streamer_done_); - if (done) - std::move(done).Run(); - is_currently_streaming_ = false; - } - } - - // Streaming-related post conditions: - - // To help diagnose crbug.com/78426, we'll temporarily add some DCHECKs - // that are a subset of the DCHECKs below: - if (IsCurrentlyStreaming()) { - DCHECK(resource->HasStreamer()); - DCHECK(!resource->HasFinishedStreamer()); - } - - // IsCurrentlyStreaming should match what streamer_ thinks. - DCHECK_EQ(IsCurrentlyStreaming(), - resource->HasStreamer() && !resource->HasFinishedStreamer()); - // IsCurrentlyStreaming should match the ready_state_. - DCHECK_EQ(IsCurrentlyStreaming(), - resource->HasStreamer() && ready_state_ == kWaitingForResource); - // We can only have a streamer_done_ callback if we are actually streaming. - DCHECK(IsCurrentlyStreaming() || !streamer_done_); } void ClassicPendingScript::OnPurgeMemory() { @@ -435,19 +407,15 @@ void ClassicPendingScript::OnPurgeMemory() { // here. } -bool ClassicPendingScript::StartStreamingIfPossible( - base::OnceClosure done) { - if (IsCurrentlyStreaming()) - return false; - +void ClassicPendingScript::StartStreamingIfPossible() { // We can start streaming in two states: While still loading // (kWaitingForResource), or after having loaded (kReady). if (ready_state_ != kWaitingForResource && ready_state_ != kReady) - return false; + return; Document* document = &GetElement()->GetDocument(); if (!document || !document->GetFrame()) - return false; + return; // Parser blocking scripts tend to do a lot of work in the 'finished' // callbacks, while async + in-order scripts all do control-like activities @@ -457,26 +425,14 @@ bool ClassicPendingScript::StartStreamingIfPossible( ? TaskType::kNetworking : TaskType::kNetworkingControl; - DCHECK(!IsCurrentlyStreaming()); - DCHECK(!streamer_done_); - ReadyState ready_state_before_stream = ready_state_; - bool success = ToScriptResource(GetResource()) - ->StartStreaming(document->GetTaskRunner(task_type)); + ToScriptResource(GetResource()) + ->StartStreaming(document->GetTaskRunner(task_type)); // We have to make sure that the ready state is not changed by starting // streaming, just in case we're relying on IsReady being false. CHECK_EQ(ready_state_before_stream, ready_state_); - // If we have successfully started streaming, we are required to call the - // callback. - is_currently_streaming_ = success; - if (success) - streamer_done_ = std::move(done); - return success; -} - -bool ClassicPendingScript::IsCurrentlyStreaming() const { - return is_currently_streaming_; + return; } bool ClassicPendingScript::WasCanceled() const { diff --git a/chromium/third_party/blink/renderer/core/script/classic_pending_script.h b/chromium/third_party/blink/renderer/core/script/classic_pending_script.h index 45faa0a04e0..5860329ffb2 100644 --- a/chromium/third_party/blink/renderer/core/script/classic_pending_script.h +++ b/chromium/third_party/blink/renderer/core/script/classic_pending_script.h @@ -47,6 +47,11 @@ class CORE_EXPORT ClassicPendingScript final : public PendingScript, ScriptSourceLocationType, const ScriptFetchOptions&); + ClassicPendingScript(ScriptElementBase*, + const TextPosition&, + ScriptSourceLocationType, + const ScriptFetchOptions&, + bool is_external); ~ClassicPendingScript() override; // ScriptStreamer callbacks. @@ -65,8 +70,7 @@ class CORE_EXPORT ClassicPendingScript final : public PendingScript, bool IsReady() const override; bool IsExternal() const override { return is_external_; } bool WasCanceled() const override; - bool StartStreamingIfPossible(base::OnceClosure) override; - bool IsCurrentlyStreaming() const override; + void StartStreamingIfPossible() override; KURL UrlForTracing() const override; void DisposeInternal() override; @@ -84,11 +88,6 @@ class CORE_EXPORT ClassicPendingScript final : public PendingScript, kErrorOccurred, }; - ClassicPendingScript(ScriptElementBase*, - const TextPosition&, - ScriptSourceLocationType, - const ScriptFetchOptions&, - bool is_external); ClassicPendingScript() = delete; // Advances the current state of the script, reporting to the client if @@ -129,22 +128,6 @@ class CORE_EXPORT ClassicPendingScript final : public PendingScript, // The request is intervened by document.write() intervention. bool intervened_ = false; - base::OnceClosure streamer_done_; - - // This flag tracks whether streamer_ is currently streaming. It is used - // mainly to prevent re-streaming a script while it is being streamed. - // - // ReadyState unfortunately doesn't contain this information, because - // 1, the WaitingFor* states can occur with or without streaming, and - // 2, during the state transition, we need to first transition ready_state_, - // then run callbacks, and only then consider the streaming done. So - // during AdvanceReadyState and callback processing, the ready state - // and is_currently_streaming_ are temporarily different. (They must - // be consistent before and after AdvanceReadyState.) - // - // (See also: crbug.com/754360) - bool is_currently_streaming_; - // Specifies the reason that script was never streamed. ScriptStreamer::NotStreamingReason not_streamed_reason_; }; diff --git a/chromium/third_party/blink/renderer/core/script/classic_script.h b/chromium/third_party/blink/renderer/core/script/classic_script.h index b645f6bf413..25e5e43ab4e 100644 --- a/chromium/third_party/blink/renderer/core/script/classic_script.h +++ b/chromium/third_party/blink/renderer/core/script/classic_script.h @@ -20,17 +20,10 @@ class CORE_EXPORT ClassicScript final : public Script { const KURL& base_url, const ScriptFetchOptions& fetch_options, SanitizeScriptErrors sanitize_script_errors) { - return new ClassicScript(script_source_code, base_url, fetch_options, - sanitize_script_errors); + return MakeGarbageCollected<ClassicScript>( + script_source_code, base_url, fetch_options, sanitize_script_errors); } - void Trace(blink::Visitor*) override; - - const ScriptSourceCode& GetScriptSourceCode() const { - return script_source_code_; - } - - private: ClassicScript(const ScriptSourceCode& script_source_code, const KURL& base_url, const ScriptFetchOptions& fetch_options, @@ -39,6 +32,13 @@ class CORE_EXPORT ClassicScript final : public Script { script_source_code_(script_source_code), sanitize_script_errors_(sanitize_script_errors) {} + void Trace(blink::Visitor*) override; + + const ScriptSourceCode& GetScriptSourceCode() const { + return script_source_code_; + } + + private: mojom::ScriptType GetScriptType() const override { return mojom::ScriptType::kClassic; } diff --git a/chromium/third_party/blink/renderer/core/script/document_modulator_impl.cc b/chromium/third_party/blink/renderer/core/script/document_modulator_impl.cc index f8518d64bff..42c7286a4b4 100644 --- a/chromium/third_party/blink/renderer/core/script/document_modulator_impl.cc +++ b/chromium/third_party/blink/renderer/core/script/document_modulator_impl.cc @@ -9,28 +9,17 @@ namespace blink { -ModulatorImplBase* DocumentModulatorImpl::Create( - ScriptState* script_state, - ResourceFetcher* resource_fetcher) { - return MakeGarbageCollected<DocumentModulatorImpl>(script_state, - resource_fetcher); +ModulatorImplBase* DocumentModulatorImpl::Create(ScriptState* script_state) { + return MakeGarbageCollected<DocumentModulatorImpl>(script_state); } +DocumentModulatorImpl::DocumentModulatorImpl(ScriptState* script_state) + : ModulatorImplBase(script_state) {} + ModuleScriptFetcher* DocumentModulatorImpl::CreateModuleScriptFetcher( ModuleScriptCustomFetchType custom_fetch_type) { DCHECK_EQ(ModuleScriptCustomFetchType::kNone, custom_fetch_type); - return MakeGarbageCollected<DocumentModuleScriptFetcher>(fetcher_); -} - -void DocumentModulatorImpl::Trace(blink::Visitor* visitor) { - visitor->Trace(fetcher_); - ModulatorImplBase::Trace(visitor); -} - -DocumentModulatorImpl::DocumentModulatorImpl(ScriptState* script_state, - ResourceFetcher* resource_fetcher) - : ModulatorImplBase(script_state), fetcher_(resource_fetcher) { - DCHECK(fetcher_); + return MakeGarbageCollected<DocumentModuleScriptFetcher>(); } bool DocumentModulatorImpl::IsDynamicImportForbidden(String* reason) { diff --git a/chromium/third_party/blink/renderer/core/script/document_modulator_impl.h b/chromium/third_party/blink/renderer/core/script/document_modulator_impl.h index 5c34db9ddd4..a090c5d6c3c 100644 --- a/chromium/third_party/blink/renderer/core/script/document_modulator_impl.h +++ b/chromium/third_party/blink/renderer/core/script/document_modulator_impl.h @@ -12,7 +12,6 @@ namespace blink { class ModuleScriptFetcher; -class ResourceFetcher; class ScriptState; // DocumentModulatorImpl is the Modulator implementation used in main documents @@ -21,21 +20,17 @@ class ScriptState; // ModulatorImplBase. class DocumentModulatorImpl final : public ModulatorImplBase { public: - static ModulatorImplBase* Create(ScriptState*, ResourceFetcher*); + static ModulatorImplBase* Create(ScriptState*); - DocumentModulatorImpl(ScriptState*, ResourceFetcher*); + explicit DocumentModulatorImpl(ScriptState*); // Implements Modulator. ModuleScriptFetcher* CreateModuleScriptFetcher( ModuleScriptCustomFetchType) override; - void Trace(blink::Visitor*) override; - private: // Implements ModulatorImplBase. bool IsDynamicImportForbidden(String* reason) override; - - Member<ResourceFetcher> fetcher_; }; } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/script/document_write_intervention.cc b/chromium/third_party/blink/renderer/core/script/document_write_intervention.cc index ed287c4f29f..28896971a6a 100644 --- a/chromium/third_party/blink/renderer/core/script/document_write_intervention.cc +++ b/chromium/third_party/blink/renderer/core/script/document_write_intervention.cc @@ -4,7 +4,7 @@ #include "third_party/blink/renderer/core/script/document_write_intervention.h" -#include "third_party/blink/public/platform/modules/fetch/fetch_api_request.mojom-shared.h" +#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-shared.h" #include "third_party/blink/public/platform/web_effective_connection_type.h" #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/frame/local_frame_client.h" diff --git a/chromium/third_party/blink/renderer/core/script/dynamic_module_resolver.cc b/chromium/third_party/blink/renderer/core/script/dynamic_module_resolver.cc index f7353d1230e..2f5e27fded4 100644 --- a/chromium/third_party/blink/renderer/core/script/dynamic_module_resolver.cc +++ b/chromium/third_party/blink/renderer/core/script/dynamic_module_resolver.cc @@ -10,6 +10,7 @@ #include "third_party/blink/renderer/core/loader/modulescript/module_script_fetch_request.h" #include "third_party/blink/renderer/core/script/modulator.h" #include "third_party/blink/renderer/core/script/module_script.h" +#include "third_party/blink/renderer/core/workers/worker_global_scope.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/bindings/v8_throw_exception.h" #include "third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object_snapshot.h" @@ -25,17 +26,18 @@ class DynamicImportTreeClient final : public ModuleTreeClient { const KURL& url, Modulator* modulator, ScriptPromiseResolver* promise_resolver) { - return new DynamicImportTreeClient(url, modulator, promise_resolver); + return MakeGarbageCollected<DynamicImportTreeClient>(url, modulator, + promise_resolver); } - void Trace(blink::Visitor*) override; - - private: DynamicImportTreeClient(const KURL& url, Modulator* modulator, ScriptPromiseResolver* promise_resolver) : url_(url), modulator_(modulator), promise_resolver_(promise_resolver) {} + void Trace(blink::Visitor*) override; + + private: // Implements ModuleTreeClient: void NotifyModuleTreeLoadFinished(ModuleScript*) final; @@ -239,10 +241,11 @@ void DynamicModuleResolver::ResolveDynamically( // highly discouraged since it breaks layering. Rewrite this. auto* execution_context = ExecutionContext::From(modulator_->GetScriptState()); - modulator_->FetchTree( - url, execution_context->CreateFetchClientSettingsObjectSnapshot(), - mojom::RequestContextType::SCRIPT, options, - ModuleScriptCustomFetchType::kNone, tree_client); + if (auto* scope = DynamicTo<WorkerGlobalScope>(*execution_context)) + scope->EnsureFetcher(); + modulator_->FetchTree(url, execution_context->Fetcher(), + mojom::RequestContextType::SCRIPT, options, + ModuleScriptCustomFetchType::kNone, tree_client); // Steps 2.[5-8] are implemented at // DynamicImportTreeClient::NotifyModuleLoadFinished. diff --git a/chromium/third_party/blink/renderer/core/script/dynamic_module_resolver_test.cc b/chromium/third_party/blink/renderer/core/script/dynamic_module_resolver_test.cc index 46f86410254..f9b1995fd40 100644 --- a/chromium/third_party/blink/renderer/core/script/dynamic_module_resolver_test.cc +++ b/chromium/third_party/blink/renderer/core/script/dynamic_module_resolver_test.cc @@ -70,7 +70,7 @@ class DynamicModuleResolverTestModulator final : public DummyModulator { } void FetchTree(const KURL& url, - FetchClientSettingsObjectSnapshot*, + ResourceFetcher*, mojom::RequestContextType, const ScriptFetchOptions&, ModuleScriptCustomFetchType custom_fetch_type, @@ -131,7 +131,8 @@ class CaptureExportedStringFunction final : public ScriptFunction { v8::Local<v8::Value> exported_value = module_namespace->Get(context, V8String(isolate, export_name_)) .ToLocalChecked(); - captured_value_ = ToCoreString(exported_value->ToString(isolate)); + captured_value_ = + ToCoreString(exported_value->ToString(context).ToLocalChecked()); return ScriptValue(); } @@ -165,11 +166,11 @@ class CaptureErrorFunction final : public ScriptFunction { v8::Local<v8::Value> name = error_object->Get(context, V8String(isolate, "name")).ToLocalChecked(); - name_ = ToCoreString(name->ToString(isolate)); + name_ = ToCoreString(name->ToString(context).ToLocalChecked()); v8::Local<v8::Value> message = error_object->Get(context, V8String(isolate, "message")) .ToLocalChecked(); - message_ = ToCoreString(message->ToString(isolate)); + message_ = ToCoreString(message->ToString(context).ToLocalChecked()); return ScriptValue(); } @@ -182,14 +183,15 @@ class CaptureErrorFunction final : public ScriptFunction { class DynamicModuleResolverTestNotReached final : public ScriptFunction { public: static v8::Local<v8::Function> CreateFunction(ScriptState* script_state) { - auto* not_reached = new DynamicModuleResolverTestNotReached(script_state); + auto* not_reached = + MakeGarbageCollected<DynamicModuleResolverTestNotReached>(script_state); return not_reached->BindToV8Function(); } - private: explicit DynamicModuleResolverTestNotReached(ScriptState* script_state) : ScriptFunction(script_state) {} + private: ScriptValue Call(ScriptValue) override { ADD_FAILURE(); return ScriptValue(); @@ -200,16 +202,16 @@ class DynamicModuleResolverTestNotReached final : public ScriptFunction { TEST(DynamicModuleResolverTest, ResolveSuccess) { V8TestingScope scope; - auto* modulator = - new DynamicModuleResolverTestModulator(scope.GetScriptState()); + auto* modulator = MakeGarbageCollected<DynamicModuleResolverTestModulator>( + scope.GetScriptState()); modulator->SetExpectedFetchTreeURL(TestDependencyURL()); auto* promise_resolver = ScriptPromiseResolver::Create(scope.GetScriptState()); ScriptPromise promise = promise_resolver->Promise(); - auto* capture = - new CaptureExportedStringFunction(scope.GetScriptState(), "foo"); + auto* capture = MakeGarbageCollected<CaptureExportedStringFunction>( + scope.GetScriptState(), "foo"); promise.Then(capture->Bind(), DynamicModuleResolverTestNotReached::CreateFunction( scope.GetScriptState())); @@ -237,15 +239,16 @@ TEST(DynamicModuleResolverTest, ResolveSuccess) { TEST(DynamicModuleResolverTest, ResolveSpecifierFailure) { V8TestingScope scope; - auto* modulator = - new DynamicModuleResolverTestModulator(scope.GetScriptState()); + auto* modulator = MakeGarbageCollected<DynamicModuleResolverTestModulator>( + scope.GetScriptState()); modulator->SetExpectedFetchTreeURL(TestDependencyURL()); auto* promise_resolver = ScriptPromiseResolver::Create(scope.GetScriptState()); ScriptPromise promise = promise_resolver->Promise(); - auto* capture = new CaptureErrorFunction(scope.GetScriptState()); + auto* capture = + MakeGarbageCollected<CaptureErrorFunction>(scope.GetScriptState()); promise.Then(DynamicModuleResolverTestNotReached::CreateFunction( scope.GetScriptState()), capture->Bind()); @@ -262,15 +265,16 @@ TEST(DynamicModuleResolverTest, ResolveSpecifierFailure) { TEST(DynamicModuleResolverTest, FetchFailure) { V8TestingScope scope; - auto* modulator = - new DynamicModuleResolverTestModulator(scope.GetScriptState()); + auto* modulator = MakeGarbageCollected<DynamicModuleResolverTestModulator>( + scope.GetScriptState()); modulator->SetExpectedFetchTreeURL(TestDependencyURL()); auto* promise_resolver = ScriptPromiseResolver::Create(scope.GetScriptState()); ScriptPromise promise = promise_resolver->Promise(); - auto* capture = new CaptureErrorFunction(scope.GetScriptState()); + auto* capture = + MakeGarbageCollected<CaptureErrorFunction>(scope.GetScriptState()); promise.Then(DynamicModuleResolverTestNotReached::CreateFunction( scope.GetScriptState()), capture->Bind()); @@ -291,15 +295,16 @@ TEST(DynamicModuleResolverTest, FetchFailure) { TEST(DynamicModuleResolverTest, ExceptionThrown) { V8TestingScope scope; - auto* modulator = - new DynamicModuleResolverTestModulator(scope.GetScriptState()); + auto* modulator = MakeGarbageCollected<DynamicModuleResolverTestModulator>( + scope.GetScriptState()); modulator->SetExpectedFetchTreeURL(TestDependencyURL()); auto* promise_resolver = ScriptPromiseResolver::Create(scope.GetScriptState()); ScriptPromise promise = promise_resolver->Promise(); - auto* capture = new CaptureErrorFunction(scope.GetScriptState()); + auto* capture = + MakeGarbageCollected<CaptureErrorFunction>(scope.GetScriptState()); promise.Then(DynamicModuleResolverTestNotReached::CreateFunction( scope.GetScriptState()), capture->Bind()); @@ -329,16 +334,16 @@ TEST(DynamicModuleResolverTest, ResolveWithNullReferrerScriptSuccess) { V8TestingScope scope; scope.GetDocument().SetURL(KURL("https://example.com")); - auto* modulator = - new DynamicModuleResolverTestModulator(scope.GetScriptState()); + auto* modulator = MakeGarbageCollected<DynamicModuleResolverTestModulator>( + scope.GetScriptState()); modulator->SetExpectedFetchTreeURL(TestDependencyURL()); auto* promise_resolver = ScriptPromiseResolver::Create(scope.GetScriptState()); ScriptPromise promise = promise_resolver->Promise(); - auto* capture = - new CaptureExportedStringFunction(scope.GetScriptState(), "foo"); + auto* capture = MakeGarbageCollected<CaptureExportedStringFunction>( + scope.GetScriptState(), "foo"); promise.Then(capture->Bind(), DynamicModuleResolverTestNotReached::CreateFunction( scope.GetScriptState())); @@ -368,8 +373,8 @@ TEST(DynamicModuleResolverTest, ResolveWithReferrerScriptInfoBaseURL) { V8TestingScope scope; scope.GetDocument().SetURL(KURL("https://example.com")); - auto* modulator = - new DynamicModuleResolverTestModulator(scope.GetScriptState()); + auto* modulator = MakeGarbageCollected<DynamicModuleResolverTestModulator>( + scope.GetScriptState()); modulator->SetExpectedFetchTreeURL( KURL("https://example.com/correct/dependency.js")); diff --git a/chromium/third_party/blink/renderer/core/script/fetch_client_settings_object_impl.cc b/chromium/third_party/blink/renderer/core/script/fetch_client_settings_object_impl.cc index 15af66c2727..461d9172c2f 100644 --- a/chromium/third_party/blink/renderer/core/script/fetch_client_settings_object_impl.cc +++ b/chromium/third_party/blink/renderer/core/script/fetch_client_settings_object_impl.cc @@ -40,6 +40,27 @@ HttpsState FetchClientSettingsObjectImpl::GetHttpsState() const { return execution_context_->GetHttpsState(); } +AllowedByNosniff::MimeTypeCheck +FetchClientSettingsObjectImpl::MimeTypeCheckForClassicWorkerScript() const { + if (execution_context_->IsDocument()) { + // For worker creation on a document, don't impose strict MIME-type checks + // on the top-level worker script for backward compatibility. Note that + // there is a plan to deprecate legacy mime types for workers. See + // https://crbug.com/794548. + // + // For worker creation on a document with off-the-main-thread top-level + // worker classic script loading, this value is propagated to + // outsideSettings FCSO. + return AllowedByNosniff::MimeTypeCheck::kLax; + } + + // For importScripts() and nested worker top-level scripts impose the strict + // MIME-type checks. + // Nested workers is a new feature (enabled by default in M69) and there is no + // backward compatibility issue. + return AllowedByNosniff::MimeTypeCheck::kStrict; +} + void FetchClientSettingsObjectImpl::Trace(Visitor* visitor) { visitor->Trace(execution_context_); FetchClientSettingsObject::Trace(visitor); diff --git a/chromium/third_party/blink/renderer/core/script/fetch_client_settings_object_impl.h b/chromium/third_party/blink/renderer/core/script/fetch_client_settings_object_impl.h index 8ea794e2e87..d79ee309500 100644 --- a/chromium/third_party/blink/renderer/core/script/fetch_client_settings_object_impl.h +++ b/chromium/third_party/blink/renderer/core/script/fetch_client_settings_object_impl.h @@ -38,6 +38,9 @@ class CORE_EXPORT FetchClientSettingsObjectImpl final HttpsState GetHttpsState() const override; + AllowedByNosniff::MimeTypeCheck MimeTypeCheckForClassicWorkerScript() + const override; + void Trace(Visitor* visitor) override; private: diff --git a/chromium/third_party/blink/renderer/core/script/generate_lapi_grdp.py b/chromium/third_party/blink/renderer/core/script/generate_lapi_grdp.py new file mode 100755 index 00000000000..99eff1f6377 --- /dev/null +++ b/chromium/third_party/blink/renderer/core/script/generate_lapi_grdp.py @@ -0,0 +1,101 @@ +#!/usr/bin/env python +# Copyright (c) 2019 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +import sys +import os + + +def main(): + core_script_path = os.path.dirname(sys.argv[0]) + + # The path to the directory containing layered API files. + input_path = os.path.join(core_script_path, 'resources/layered_api') + + # Relative path from the main grd file; in this case, + # third_party/blink/public/blink_resources.grd. + input_relative_path = '../renderer/core/script/resources/layered_api' + + # Output .grdp file. + output_grdp_file = open( + os.path.join(core_script_path, 'resources/layered_api/resources.grdp'), + 'w') + + # Output .h file. + output_header_file = open( + os.path.join(core_script_path, 'layered_api_resources.h'), 'w') + + print >> output_grdp_file, '''<?xml version="1.0" encoding="utf-8"?> +<grit-part> + <!-- Layered API scripts. This file is generated by + core/script/generate_lapi_grdp.py and shouldn't modified manually. + A corresponding header file (layered_api_resources.h) is also generated. + The paths are relative to the main grd file, i.e. + third_party/blink/public/blink_resources.grd. + -->''' + + print >> output_header_file, '''// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/public/resources/grit/blink_resources.h" +#include "third_party/blink/renderer/core/script/layered_api.h" + +#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_SCRIPT_LAYERED_API_RESOURCES_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_SCRIPT_LAYERED_API_RESOURCES_H_ + +// This file is generated by +// core/script/generate_lapi_grdp.py and shouldn't modified manually. +// A corresponding grdp file (layered_api_resources.grdp) is also generated. + +// This file should be included only once from core/script/layered_api.cc. + +namespace blink { + +namespace layered_api { + +namespace { + +const LayeredAPIResource kLayeredAPIResources[] = {''' + + for root, _, filenames in sorted(os.walk(input_path)): + if root == 'resources/layered_api': + # We don't include top-level files under resources/layered_api, + # including generated resources.grdp. + continue + for filename in sorted(filenames): + if filename.startswith('.') or filename.startswith( + 'README') or filename.startswith('OWNERS'): + continue + relpath = os.path.relpath(os.path.join(root, filename), input_path) + relpath = relpath.replace('\\', '/') + resource_id = relpath + resource_id = resource_id.replace('/', '_') + resource_id = resource_id.replace('-', '_') + resource_id = resource_id.replace('.', '_') + resource_id = resource_id.upper() + resource_id = "IDR_LAYERED_API_" + resource_id + print >> output_header_file, ( + ' {"%s",\n %s},' % (relpath, resource_id)) + print >> output_grdp_file, ( + ' <include name="%s" file="%s/%s" type="BINDATA" skip_minify="true" compress="gzip"/>' + % (resource_id, input_relative_path, relpath)) + print >> output_header_file, '' + print >> output_grdp_file, '</grit-part>' + + print >> output_header_file, '''}; + +} // namespace + +} // namespace layered_api + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_SCRIPT_LAYERED_API_RESOURCES_H_''' + output_grdp_file.close() + output_header_file.close() + + +if __name__ == '__main__': + main() diff --git a/chromium/third_party/blink/renderer/core/script/html_parser_script_runner.cc b/chromium/third_party/blink/renderer/core/script/html_parser_script_runner.cc index 563c7e4a9ac..ca737a21b99 100644 --- a/chromium/third_party/blink/renderer/core/script/html_parser_script_runner.cc +++ b/chromium/third_party/blink/renderer/core/script/html_parser_script_runner.cc @@ -478,7 +478,7 @@ void HTMLParserScriptRunner::RequestParsingBlockingScript( // Callers will attempt to run the m_parserBlockingScript if possible before // returning control to the parser. if (!ParserBlockingScript()->IsReady()) { - parser_blocking_script_->StartStreamingIfPossible(base::OnceClosure()); + parser_blocking_script_->StartStreamingIfPossible(); parser_blocking_script_->WatchForLoad(this); } } @@ -491,7 +491,7 @@ void HTMLParserScriptRunner::RequestDeferredScript( return; if (!pending_script->IsReady()) { - pending_script->StartStreamingIfPossible(base::OnceClosure()); + pending_script->StartStreamingIfPossible(); } DCHECK(pending_script->IsExternalOrModule()); diff --git a/chromium/third_party/blink/renderer/core/script/layered_api.cc b/chromium/third_party/blink/renderer/core/script/layered_api.cc index 7b406f0fff6..859662023f5 100644 --- a/chromium/third_party/blink/renderer/core/script/layered_api.cc +++ b/chromium/third_party/blink/renderer/core/script/layered_api.cc @@ -5,7 +5,7 @@ #include "third_party/blink/renderer/core/script/layered_api.h" #include "base/stl_util.h" -#include "third_party/blink/public/resources/grit/blink_resources.h" +#include "third_party/blink/renderer/core/script/layered_api_resources.h" #include "third_party/blink/renderer/platform/data_resource_helper.h" #include "third_party/blink/renderer/platform/wtf/text/string_builder.h" @@ -18,32 +18,6 @@ namespace { static const char kStdScheme[] = "std"; static const char kInternalScheme[] = "std-internal"; -struct LayeredAPIResource { - const char* path; - int resource_id; -}; - -const LayeredAPIResource kLayeredAPIResources[] = { - {"blank/index.js", IDR_LAYERED_API_BLANK_INDEX_JS}, - - {"async-local-storage/index.js", - IDR_LAYERED_API_ASYNC_LOCAL_STORAGE_INDEX_JS}, - - {"virtual-scroller/index.js", IDR_LAYERED_API_VIRTUAL_SCROLLER_INDEX_JS}, - {"virtual-scroller/item-source.js", - IDR_LAYERED_API_VIRTUAL_SCROLLER_ITEM_SOURCE_JS}, - {"virtual-scroller/layouts/layout-1d-base.js", - IDR_LAYERED_API_VIRTUAL_SCROLLER_LAYOUTS_LAYOUT_1D_BASE_JS}, - {"virtual-scroller/layouts/layout-1d-grid.js", - IDR_LAYERED_API_VIRTUAL_SCROLLER_LAYOUTS_LAYOUT_1D_GRID_JS}, - {"virtual-scroller/layouts/layout-1d.js", - IDR_LAYERED_API_VIRTUAL_SCROLLER_LAYOUTS_LAYOUT_1D_JS}, - {"virtual-scroller/virtual-scroller.js", - IDR_LAYERED_API_VIRTUAL_SCROLLER_VIRTUAL_SCROLLER_JS}, - {"virtual-scroller/virtual-repeater.js", - IDR_LAYERED_API_VIRTUAL_SCROLLER_VIRTUAL_REPEATER_JS}, -}; - int GetResourceIDFromPath(const String& path) { for (size_t i = 0; i < base::size(kLayeredAPIResources); ++i) { if (path == kLayeredAPIResources[i].path) { @@ -115,7 +89,7 @@ String GetSourceText(const KURL& url) { if (resource_id < 0) return String(); - return GetResourceAsString(resource_id); + return UncompressResourceAsString(resource_id); } } // namespace layered_api diff --git a/chromium/third_party/blink/renderer/core/script/layered_api.h b/chromium/third_party/blink/renderer/core/script/layered_api.h index 37f948c0b93..91977362c6b 100644 --- a/chromium/third_party/blink/renderer/core/script/layered_api.h +++ b/chromium/third_party/blink/renderer/core/script/layered_api.h @@ -30,6 +30,11 @@ CORE_EXPORT KURL GetInternalURL(const KURL&); // Gets source text for std-internal://x/index.js. CORE_EXPORT String GetSourceText(const KURL&); +struct LayeredAPIResource { + const char* path; + int resource_id; +}; + } // namespace layered_api } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/script/layered_api_resources.h b/chromium/third_party/blink/renderer/core/script/layered_api_resources.h new file mode 100644 index 00000000000..cfd04355a00 --- /dev/null +++ b/chromium/third_party/blink/renderer/core/script/layered_api_resources.h @@ -0,0 +1,54 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "third_party/blink/public/resources/grit/blink_resources.h" +#include "third_party/blink/renderer/core/script/layered_api.h" + +#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_SCRIPT_LAYERED_API_RESOURCES_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_SCRIPT_LAYERED_API_RESOURCES_H_ + +// This file is generated by +// core/script/generate_lapi_grdp.py and shouldn't modified manually. +// A corresponding grdp file (layered_api_resources.grdp) is also generated. + +// This file should be included only once from core/script/layered_api.cc. + +namespace blink { + +namespace layered_api { + +namespace { + +const LayeredAPIResource kLayeredAPIResources[] = { + {"blank/index.js", IDR_LAYERED_API_BLANK_INDEX_JS}, + + {"kv-storage/async_iterator.js", + IDR_LAYERED_API_KV_STORAGE_ASYNC_ITERATOR_JS}, + {"kv-storage/idb_utils.js", IDR_LAYERED_API_KV_STORAGE_IDB_UTILS_JS}, + {"kv-storage/index.js", IDR_LAYERED_API_KV_STORAGE_INDEX_JS}, + + {"virtual-scroller/index.js", IDR_LAYERED_API_VIRTUAL_SCROLLER_INDEX_JS}, + {"virtual-scroller/item-source.js", + IDR_LAYERED_API_VIRTUAL_SCROLLER_ITEM_SOURCE_JS}, + {"virtual-scroller/virtual-repeater.js", + IDR_LAYERED_API_VIRTUAL_SCROLLER_VIRTUAL_REPEATER_JS}, + {"virtual-scroller/virtual-scroller.js", + IDR_LAYERED_API_VIRTUAL_SCROLLER_VIRTUAL_SCROLLER_JS}, + + {"virtual-scroller/layouts/layout-1d-base.js", + IDR_LAYERED_API_VIRTUAL_SCROLLER_LAYOUTS_LAYOUT_1D_BASE_JS}, + {"virtual-scroller/layouts/layout-1d-grid.js", + IDR_LAYERED_API_VIRTUAL_SCROLLER_LAYOUTS_LAYOUT_1D_GRID_JS}, + {"virtual-scroller/layouts/layout-1d.js", + IDR_LAYERED_API_VIRTUAL_SCROLLER_LAYOUTS_LAYOUT_1D_JS}, + +}; + +} // namespace + +} // namespace layered_api + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_SCRIPT_LAYERED_API_RESOURCES_H_ diff --git a/chromium/third_party/blink/renderer/core/script/mock_script_element_base.h b/chromium/third_party/blink/renderer/core/script/mock_script_element_base.h index 27a94b14d3f..bb7fea10b0e 100644 --- a/chromium/third_party/blink/renderer/core/script/mock_script_element_base.h +++ b/chromium/third_party/blink/renderer/core/script/mock_script_element_base.h @@ -19,7 +19,7 @@ class MockScriptElementBase public: static MockScriptElementBase* Create() { - return new testing::StrictMock<MockScriptElementBase>(); + return MakeGarbageCollected<testing::StrictMock<MockScriptElementBase>>(); } virtual ~MockScriptElementBase() {} @@ -33,6 +33,7 @@ class MockScriptElementBase MOCK_CONST_METHOD0(ForAttributeValue, String()); MOCK_CONST_METHOD0(IntegrityAttributeValue, String()); MOCK_CONST_METHOD0(ReferrerPolicyAttributeValue, String()); + MOCK_CONST_METHOD0(ImportanceAttributeValue, String()); MOCK_CONST_METHOD0(LanguageAttributeValue, String()); MOCK_CONST_METHOD0(NomoduleAttributeValue, bool()); MOCK_CONST_METHOD0(SourceAttributeValue, String()); diff --git a/chromium/third_party/blink/renderer/core/script/modulator.cc b/chromium/third_party/blink/renderer/core/script/modulator.cc index dfaba2eac1d..b0561f36349 100644 --- a/chromium/third_party/blink/renderer/core/script/modulator.cc +++ b/chromium/third_party/blink/renderer/core/script/modulator.cc @@ -36,8 +36,7 @@ Modulator* Modulator::From(ScriptState* script_state) { return modulator; ExecutionContext* execution_context = ExecutionContext::From(script_state); if (auto* document = DynamicTo<Document>(execution_context)) { - modulator = - DocumentModulatorImpl::Create(script_state, document->Fetcher()); + modulator = DocumentModulatorImpl::Create(script_state); Modulator::SetModulator(script_state, modulator); // See comment in LocalDOMWindow::modulator_ for this workaround. diff --git a/chromium/third_party/blink/renderer/core/script/modulator.h b/chromium/third_party/blink/renderer/core/script/modulator.h index 5bfa557f487..591b7787496 100644 --- a/chromium/third_party/blink/renderer/core/script/modulator.h +++ b/chromium/third_party/blink/renderer/core/script/modulator.h @@ -23,11 +23,11 @@ namespace blink { -class FetchClientSettingsObjectSnapshot; class ModuleScript; class ModuleScriptFetchRequest; class ModuleScriptFetcher; class ReferrerScriptInfo; +class ResourceFetcher; class ScriptModuleResolver; class ScriptPromiseResolver; class ScriptState; @@ -118,30 +118,33 @@ class CORE_EXPORT Modulator : public GarbageCollectedFinalized<Modulator>, // https://html.spec.whatwg.org/multipage/webappapis.html#fetch-a-module-script-tree // https://html.spec.whatwg.org/multipage/webappapis.html#fetch-a-module-worker-script-tree - // Note that |this| is the "module map settings object" used in the "fetch a - // module worker script graph" algorithm. - virtual void FetchTree( - const KURL&, - FetchClientSettingsObjectSnapshot* fetch_client_settings_object, - mojom::RequestContextType destination, - const ScriptFetchOptions&, - ModuleScriptCustomFetchType, - ModuleTreeClient*) = 0; + // Note that |this| is the "module map settings object" and + // ResourceFetcher represents "fetch client settings object" + // used in the "fetch a module worker script graph" algorithm. + virtual void FetchTree(const KURL&, + ResourceFetcher* fetch_client_settings_object_fetcher, + mojom::RequestContextType destination, + const ScriptFetchOptions&, + ModuleScriptCustomFetchType, + ModuleTreeClient*) = 0; // Asynchronously retrieve a module script from the module map, or fetch it // and put it in the map if it's not there already. // https://html.spec.whatwg.org/multipage/webappapis.html#fetch-a-single-module-script - // Note that |this| is the "module map settings object". + // Note that |this| is the "module map settings object" and + // |fetch_client_settings_object_fetcher| represents + // "fetch client settings object", which can be different from the + // ResourceFetcher associated with |this|. virtual void FetchSingle( const ModuleScriptFetchRequest&, - FetchClientSettingsObjectSnapshot* fetch_client_settings_object, + ResourceFetcher* fetch_client_settings_object_fetcher, ModuleGraphLevel, ModuleScriptCustomFetchType, SingleModuleClient*) = 0; virtual void FetchDescendantsForInlineScript( ModuleScript*, - FetchClientSettingsObjectSnapshot* fetch_client_settings_object, + ResourceFetcher* fetch_client_settings_object_fetcher, mojom::RequestContextType destination, ModuleTreeClient*) = 0; diff --git a/chromium/third_party/blink/renderer/core/script/modulator_impl_base.cc b/chromium/third_party/blink/renderer/core/script/modulator_impl_base.cc index bbb206dcf4f..c30ee5d431e 100644 --- a/chromium/third_party/blink/renderer/core/script/modulator_impl_base.cc +++ b/chromium/third_party/blink/renderer/core/script/modulator_impl_base.cc @@ -17,7 +17,6 @@ #include "third_party/blink/renderer/core/script/module_script.h" #include "third_party/blink/renderer/core/script/script_module_resolver_impl.h" #include "third_party/blink/renderer/platform/bindings/v8_throw_exception.h" -#include "third_party/blink/renderer/platform/loader/fetch/fetch_client_settings_object_snapshot.h" namespace blink { @@ -51,7 +50,7 @@ bool ModulatorImplBase::IsScriptingDisabled() const { // href="https://html.spec.whatwg.org/multipage/webappapis.html#fetch-a-module-worker-script-tree"> void ModulatorImplBase::FetchTree( const KURL& url, - FetchClientSettingsObjectSnapshot* fetch_client_settings_object, + ResourceFetcher* fetch_client_settings_object_fetcher, mojom::RequestContextType destination, const ScriptFetchOptions& options, ModuleScriptCustomFetchType custom_fetch_type, @@ -69,8 +68,8 @@ void ModulatorImplBase::FetchTree( // of this algorithm specified custom perform the fetch steps, pass those // along as well.</spec> - ModuleTreeLinker::Fetch(url, fetch_client_settings_object, destination, - options, this, custom_fetch_type, + ModuleTreeLinker::Fetch(url, fetch_client_settings_object_fetcher, + destination, options, this, custom_fetch_type, tree_linker_registry_, client); // <spec label="fetch-a-module-script-tree" step="3">When the internal module @@ -86,22 +85,22 @@ void ModulatorImplBase::FetchTree( void ModulatorImplBase::FetchDescendantsForInlineScript( ModuleScript* module_script, - FetchClientSettingsObjectSnapshot* fetch_client_settings_object, + ResourceFetcher* fetch_client_settings_object_fetcher, mojom::RequestContextType destination, ModuleTreeClient* client) { ModuleTreeLinker::FetchDescendantsForInlineScript( - module_script, fetch_client_settings_object, destination, this, + module_script, fetch_client_settings_object_fetcher, destination, this, ModuleScriptCustomFetchType::kNone, tree_linker_registry_, client); } void ModulatorImplBase::FetchSingle( const ModuleScriptFetchRequest& request, - FetchClientSettingsObjectSnapshot* fetch_client_settings_object, + ResourceFetcher* fetch_client_settings_object_fetcher, ModuleGraphLevel level, ModuleScriptCustomFetchType custom_fetch_type, SingleModuleClient* client) { - map_->FetchSingleModuleScript(request, fetch_client_settings_object, level, - custom_fetch_type, client); + map_->FetchSingleModuleScript(request, fetch_client_settings_object_fetcher, + level, custom_fetch_type, client); } ModuleScript* ModulatorImplBase::GetFetchedModuleScript(const KURL& url) { diff --git a/chromium/third_party/blink/renderer/core/script/modulator_impl_base.h b/chromium/third_party/blink/renderer/core/script/modulator_impl_base.h index a4fe715b94f..8a71af5dcf0 100644 --- a/chromium/third_party/blink/renderer/core/script/modulator_impl_base.h +++ b/chromium/third_party/blink/renderer/core/script/modulator_impl_base.h @@ -49,24 +49,22 @@ class ModulatorImplBase : public Modulator { return task_runner_.get(); } - void FetchTree( - const KURL&, - FetchClientSettingsObjectSnapshot* fetch_client_settings_object, - mojom::RequestContextType destination, - const ScriptFetchOptions&, - ModuleScriptCustomFetchType, - ModuleTreeClient*) override; + void FetchTree(const KURL&, + ResourceFetcher* fetch_client_settings_object_fetcher, + mojom::RequestContextType destination, + const ScriptFetchOptions&, + ModuleScriptCustomFetchType, + ModuleTreeClient*) override; void FetchDescendantsForInlineScript( ModuleScript*, - FetchClientSettingsObjectSnapshot* fetch_client_settings_object, + ResourceFetcher* fetch_client_settings_object_fetcher, mojom::RequestContextType destination, ModuleTreeClient*) override; - void FetchSingle( - const ModuleScriptFetchRequest&, - FetchClientSettingsObjectSnapshot* fetch_client_settings_object, - ModuleGraphLevel, - ModuleScriptCustomFetchType, - SingleModuleClient*) override; + void FetchSingle(const ModuleScriptFetchRequest&, + ResourceFetcher* fetch_client_settings_object_fetcher, + ModuleGraphLevel, + ModuleScriptCustomFetchType, + SingleModuleClient*) override; ModuleScript* GetFetchedModuleScript(const KURL&) override; bool HasValidContext() override; KURL ResolveModuleSpecifier(const String& module_request, diff --git a/chromium/third_party/blink/renderer/core/script/module_map.cc b/chromium/third_party/blink/renderer/core/script/module_map.cc index 4399cb898e8..e8ba2e8ddbf 100644 --- a/chromium/third_party/blink/renderer/core/script/module_map.cc +++ b/chromium/third_party/blink/renderer/core/script/module_map.cc @@ -113,7 +113,7 @@ void ModuleMap::Trace(blink::Visitor* visitor) { // <specdef href="https://html.spec.whatwg.org/#fetch-a-single-module-script"> void ModuleMap::FetchSingleModuleScript( const ModuleScriptFetchRequest& request, - FetchClientSettingsObjectSnapshot* fetch_client_settings_object, + ResourceFetcher* fetch_client_settings_object_fetcher, ModuleGraphLevel level, ModuleScriptCustomFetchType custom_fetch_type, SingleModuleClient* client) { @@ -132,9 +132,9 @@ void ModuleMap::FetchSingleModuleScript( // Steps 4-9 loads a new single module script. // Delegates to ModuleScriptLoader via Modulator. - ModuleScriptLoader::Fetch(request, fetch_client_settings_object, level, - modulator_, custom_fetch_type, loader_registry_, - entry); + ModuleScriptLoader::Fetch(request, fetch_client_settings_object_fetcher, + level, modulator_, custom_fetch_type, + loader_registry_, entry); } DCHECK(entry); diff --git a/chromium/third_party/blink/renderer/core/script/module_map.h b/chromium/third_party/blink/renderer/core/script/module_map.h index 5c5c341fa22..3949ceba032 100644 --- a/chromium/third_party/blink/renderer/core/script/module_map.h +++ b/chromium/third_party/blink/renderer/core/script/module_map.h @@ -16,11 +16,11 @@ namespace blink { -class FetchClientSettingsObjectSnapshot; class Modulator; class ModuleScript; class ModuleScriptFetchRequest; class ModuleScriptLoaderRegistry; +class ResourceFetcher; class SingleModuleClient; enum class ModuleGraphLevel; enum class ModuleScriptCustomFetchType; @@ -44,7 +44,7 @@ class CORE_EXPORT ModuleMap final : public GarbageCollected<ModuleMap>, // https://html.spec.whatwg.org/multipage/webappapis.html#fetch-a-single-module-script void FetchSingleModuleScript( const ModuleScriptFetchRequest&, - FetchClientSettingsObjectSnapshot* fetch_client_settings_object, + ResourceFetcher* fetch_client_settings_object_fetcher, ModuleGraphLevel, ModuleScriptCustomFetchType, SingleModuleClient*); diff --git a/chromium/third_party/blink/renderer/core/script/module_map_test.cc b/chromium/third_party/blink/renderer/core/script/module_map_test.cc index 6b5f0054de8..9497735ba62 100644 --- a/chromium/third_party/blink/renderer/core/script/module_map_test.cc +++ b/chromium/third_party/blink/renderer/core/script/module_map_test.cc @@ -110,6 +110,7 @@ class ModuleMapTestModulator final : public DummyModulator { explicit TestModuleScriptFetcher(ModuleMapTestModulator* modulator) : modulator_(modulator) {} void Fetch(FetchParameters& request, + ResourceFetcher*, ModuleGraphLevel, ModuleScriptFetcher::Client* client) override { TestRequest* test_request = MakeGarbageCollected<TestRequest>( @@ -163,7 +164,8 @@ class ModuleMapTestModulator final : public DummyModulator { }; ModuleMapTestModulator::ModuleMapTestModulator(ScriptState* script_state) - : script_state_(script_state), resolver_(new TestScriptModuleResolver) {} + : script_state_(script_state), + resolver_(MakeGarbageCollected<TestScriptModuleResolver>()) {} void ModuleMapTestModulator::Trace(blink::Visitor* visitor) { visitor->Trace(test_requests_); @@ -208,13 +210,12 @@ TEST_F(ModuleMapTest, sequentialRequests) { platform->AdvanceClockSeconds(1.); // For non-zero DocumentParserTimings KURL url(NullURL(), "https://example.com/foo.js"); - auto* settings_object = - GetDocument().CreateFetchClientSettingsObjectSnapshot(); // First request - TestSingleModuleClient* client = new TestSingleModuleClient; + TestSingleModuleClient* client = + MakeGarbageCollected<TestSingleModuleClient>(); Map()->FetchSingleModuleScript(ModuleScriptFetchRequest::CreateForTest(url), - settings_object, + GetDocument().Fetcher(), ModuleGraphLevel::kTopLevelModuleFetch, ModuleScriptCustomFetchType::kNone, client); Modulator()->ResolveFetches(); @@ -230,9 +231,10 @@ TEST_F(ModuleMapTest, sequentialRequests) { EXPECT_TRUE(client->GetModuleScript()); // Secondary request - TestSingleModuleClient* client2 = new TestSingleModuleClient; + TestSingleModuleClient* client2 = + MakeGarbageCollected<TestSingleModuleClient>(); Map()->FetchSingleModuleScript(ModuleScriptFetchRequest::CreateForTest(url), - settings_object, + GetDocument().Fetcher(), ModuleGraphLevel::kTopLevelModuleFetch, ModuleScriptCustomFetchType::kNone, client2); Modulator()->ResolveFetches(); @@ -255,20 +257,20 @@ TEST_F(ModuleMapTest, concurrentRequestsShouldJoin) { platform->AdvanceClockSeconds(1.); // For non-zero DocumentParserTimings KURL url(NullURL(), "https://example.com/foo.js"); - auto* settings_object = - GetDocument().CreateFetchClientSettingsObjectSnapshot(); // First request - TestSingleModuleClient* client = new TestSingleModuleClient; + TestSingleModuleClient* client = + MakeGarbageCollected<TestSingleModuleClient>(); Map()->FetchSingleModuleScript(ModuleScriptFetchRequest::CreateForTest(url), - settings_object, + GetDocument().Fetcher(), ModuleGraphLevel::kTopLevelModuleFetch, ModuleScriptCustomFetchType::kNone, client); // Secondary request (which should join the first request) - TestSingleModuleClient* client2 = new TestSingleModuleClient; + TestSingleModuleClient* client2 = + MakeGarbageCollected<TestSingleModuleClient>(); Map()->FetchSingleModuleScript(ModuleScriptFetchRequest::CreateForTest(url), - settings_object, + GetDocument().Fetcher(), ModuleGraphLevel::kTopLevelModuleFetch, ModuleScriptCustomFetchType::kNone, client2); diff --git a/chromium/third_party/blink/renderer/core/script/module_pending_script.h b/chromium/third_party/blink/renderer/core/script/module_pending_script.h index 518bafa16ab..d1c1576448c 100644 --- a/chromium/third_party/blink/renderer/core/script/module_pending_script.h +++ b/chromium/third_party/blink/renderer/core/script/module_pending_script.h @@ -79,8 +79,7 @@ class CORE_EXPORT ModulePendingScript : public PendingScript { bool IsExternal() const override { return is_external_; } bool WasCanceled() const override { return false; } - bool StartStreamingIfPossible(base::OnceClosure) override { return false; } - bool IsCurrentlyStreaming() const override { return false; } + void StartStreamingIfPossible() override {} KURL UrlForTracing() const override { return NullURL(); } diff --git a/chromium/third_party/blink/renderer/core/script/module_script.h b/chromium/third_party/blink/renderer/core/script/module_script.h index 071d0cee791..02c3e13682b 100644 --- a/chromium/third_party/blink/renderer/core/script/module_script.h +++ b/chromium/third_party/blink/renderer/core/script/module_script.h @@ -54,8 +54,14 @@ class CORE_EXPORT ModuleScript final : public Script, public NameClient { ScriptModule Record() const; bool HasEmptyRecord() const; + // Note: ParseError-related methods should only be used from ModuleTreeLinker + // or unit tests. You probably want to check |*ErrorToRethrow*()| + // instead. + void SetParseErrorAndClearRecord(ScriptValue error); bool HasParseError() const { return !parse_error_.IsEmpty(); } + + // CreateParseError() retrieves |parse_error_| as a ScriptValue. ScriptValue CreateParseError() const; void SetErrorToRethrow(ScriptValue error); @@ -93,6 +99,9 @@ class CORE_EXPORT ModuleScript final : public Script, public NameClient { Member<Modulator> settings_object_; // https://html.spec.whatwg.org/multipage/webappapis.html#concept-script-record + // TODO(keishi): Visitor only defines a trace method for v8::Value so this + // needs to be cast. + GC_PLUGIN_IGNORE("757708") TraceWrapperV8Reference<v8::Module> record_; // https://html.spec.whatwg.org/multipage/webappapis.html#concept-script-parse-error diff --git a/chromium/third_party/blink/renderer/core/script/pending_script.cc b/chromium/third_party/blink/renderer/core/script/pending_script.cc index 617d7c8d890..9f23c80d4f1 100644 --- a/chromium/third_party/blink/renderer/core/script/pending_script.cc +++ b/chromium/third_party/blink/renderer/core/script/pending_script.cc @@ -126,6 +126,7 @@ void PendingScript::MarkParserBlockingLoadStartTime() { // <specdef href="https://html.spec.whatwg.org/#execute-the-script-block"> void PendingScript::ExecuteScriptBlock(const KURL& document_url) { + TRACE_EVENT0("blink", "PendingScript::ExecuteScriptBlock"); Document* context_document = element_->GetDocument().ContextDocument(); if (!context_document) { Dispose(); diff --git a/chromium/third_party/blink/renderer/core/script/pending_script.h b/chromium/third_party/blink/renderer/core/script/pending_script.h index 0ab981568b8..31663d11807 100644 --- a/chromium/third_party/blink/renderer/core/script/pending_script.h +++ b/chromium/third_party/blink/renderer/core/script/pending_script.h @@ -97,8 +97,7 @@ class CORE_EXPORT PendingScript virtual bool WasCanceled() const = 0; // Support for script streaming. - virtual bool StartStreamingIfPossible(base::OnceClosure) = 0; - virtual bool IsCurrentlyStreaming() const = 0; + virtual void StartStreamingIfPossible() = 0; // Used only for tracing, and can return a null URL. // TODO(hiroshige): It's preferable to return the base URL consistently diff --git a/chromium/third_party/blink/renderer/core/script/resources/layered_api/README.md b/chromium/third_party/blink/renderer/core/script/resources/layered_api/README.md new file mode 100644 index 00000000000..270d8117aa5 --- /dev/null +++ b/chromium/third_party/blink/renderer/core/script/resources/layered_api/README.md @@ -0,0 +1,32 @@ +# Layered API resources directory + +This directory stores module JavaScript implementation files of +[Layered APIs](https://github.com/drufball/layered-apis), +that are to be bundled with the browser. + +## Adding/removing files + +When adding/removing files, execute + +- `core/script/generate_lapi_grdp.py` +- `git cl format` + +to update the following files: + +- `core/script/layered_api_resources.h` +- `core/script/resources/layered_api/resources.grdp` + +and commit these files together with the changes under resources/layered_api/. + +(This is not needed when the content of the files are modified) + +## Which files are bundled + +All files under this directory will be included in the grdp and thus bundled +in the Chromium binary, except for + +- Files directly under `core/script/resources/layered_api`, or +- Files starting with '.', 'README', or 'OWNERS'. + +So be careful about binary size increase when you add new files or add more +contents to existing files. diff --git a/chromium/third_party/blink/renderer/core/script/resources/layered_api/async-local-storage/README.chromium b/chromium/third_party/blink/renderer/core/script/resources/layered_api/async-local-storage/README.chromium deleted file mode 100644 index 4119a8375c5..00000000000 --- a/chromium/third_party/blink/renderer/core/script/resources/layered_api/async-local-storage/README.chromium +++ /dev/null @@ -1,12 +0,0 @@ -Name: async-local-storage Layered API -URL: https://github.com/valdrinkoshi/virtual-list -Version: 4bfe22c2d424e3451acfcf809585336f389f6397 -Security Critical: no - -Description: -Temporarily, the files under this directory are authored by Chromium Authors -on a github repository, and then imported to Chromium repository directly here, -until a long-term Layered API development plan is settled. - -Local Modifications: -None (except for renaming to index.js) diff --git a/chromium/third_party/blink/renderer/core/script/resources/layered_api/async-local-storage/index.js b/chromium/third_party/blink/renderer/core/script/resources/layered_api/async-local-storage/index.js deleted file mode 100644 index b3971d06895..00000000000 --- a/chromium/third_party/blink/renderer/core/script/resources/layered_api/async-local-storage/index.js +++ /dev/null @@ -1,253 +0,0 @@ -// TODOs/spec-noncompliances: -// - Susceptible to tampering of built-in prototypes and globals. We want to -// work on tooling to ameliorate that. - -// TODO: Use private fields when those ship. -const databaseName = new WeakMap(); -const databasePromise = new WeakMap(); - -if (!self.isSecureContext) { - throw new DOMException( - 'Async local storage is only available in secure contexts', - 'SecurityError'); -} - -export class StorageArea { - constructor(name) { - databasePromise.set(this, null); - databaseName.set(this, `async-local-storage:${name}`); - } - - async set(key, value) { - throwForDisallowedKey(key); - - return performDatabaseOperation(this, 'readwrite', (transaction, store) => { - store.put(value, key); - - return new Promise((resolve, reject) => { - transaction.oncomplete = () => resolve(); - transaction.onabort = () => reject(transaction.error); - transaction.onerror = () => reject(transaction.error); - }); - }); - } - - async get(key) { - throwForDisallowedKey(key); - - return performDatabaseOperation(this, 'readonly', (transaction, store) => { - const request = store.get(key); - - return new Promise((resolve, reject) => { - request.onsuccess = () => resolve(request.result); - request.onerror = () => reject(request.error); - }); - }); - } - - async has(key) { - throwForDisallowedKey(key); - - return performDatabaseOperation(this, 'readonly', (transaction, store) => { - const request = store.count(key); - - return new Promise((resolve, reject) => { - request.onsuccess = () => resolve(request.result === 0 ? false : true); - request.onerror = () => reject(request.error); - }); - }); - } - - async delete(key) { - throwForDisallowedKey(key); - - return performDatabaseOperation(this, 'readwrite', (transaction, store) => { - store.delete(key); - - return new Promise((resolve, reject) => { - transaction.oncomplete = () => resolve(); - transaction.onabort = () => reject(transaction.error); - transaction.onerror = () => reject(transaction.error); - }); - }); - } - - async clear() { - if (!databasePromise.has(this)) { - return Promise.reject(new TypeError('Invalid this value')); - } - - if (databasePromise.get(this) !== null) { - return databasePromise.get(this).then( - () => { - databasePromise.set(this, null); - return deleteDatabase(databaseName.get(this)); - }, - () => { - databasePromise.set(this, null); - return deleteDatabase(databaseName.get(this)); - }); - } - - return deleteDatabase(databaseName.get(this)); - } - - async keys() { - return performDatabaseOperation(this, 'readonly', (transaction, store) => { - const request = store.getAllKeys(undefined); - - return new Promise((resolve, reject) => { - request.onsuccess = () => resolve(request.result); - request.onerror = () => reject(request.error); - }); - }); - } - - async values() { - return performDatabaseOperation(this, 'readonly', (transaction, store) => { - const request = store.getAll(undefined); - - return new Promise((resolve, reject) => { - request.onsuccess = () => resolve(request.result); - request.onerror = () => reject(request.error); - }); - }); - } - - async entries() { - return performDatabaseOperation(this, 'readonly', (transaction, store) => { - const keysRequest = store.getAllKeys(undefined); - const valuesRequest = store.getAll(undefined); - - return new Promise((resolve, reject) => { - keysRequest.onerror = () => reject(keysRequest.error); - valuesRequest.onerror = () => reject(valuesRequest.error); - - valuesRequest.onsuccess = () => { - resolve(zip(keysRequest.result, valuesRequest.result)); - }; - }); - }); - } - - get backingStore() { - if (!databasePromise.has(this)) { - throw new TypeError('Invalid this value'); - } - - return {database: databaseName.get(this), store: 'store', version: 1}; - } -} - -export const storage = new StorageArea('default'); - -function performDatabaseOperation(area, mode, steps) { - if (!databasePromise.has(area)) { - return Promise.reject(new TypeError('Invalid this value')); - } - - if (databasePromise.get(area) === null) { - initializeDatabasePromise(area); - } - - return databasePromise.get(area).then(database => { - const transaction = database.transaction('store', mode); - const store = transaction.objectStore('store'); - - return steps(transaction, store); - }); -} - -function initializeDatabasePromise(area) { - databasePromise.set(area, new Promise((resolve, reject) => { - const request = self.indexedDB.open(databaseName.get(area), 1); - - request.onsuccess = () => { - const database = request.result; - database.onclose = () => databasePromise.set(area, null); - database.onversionchange = () => { - database.close(); - databasePromise.set(area, null); - }; - resolve(database); - }; - - request.onerror = () => reject(request.error); - - request.onupgradeneeded = () => { - try { - request.result.createObjectStore('store'); - } catch (e) { - reject(e); - } - }; - })); -} - -function isAllowedAsAKey(value) { - if (typeof value === 'number' || typeof value === 'string') { - return true; - } - - if (Array.isArray(value)) { - return true; - } - - if (isDate(value)) { - return true; - } - - if (ArrayBuffer.isView(value)) { - return true; - } - - if (isArrayBuffer(value)) { - return true; - } - - return false; -} - -function isDate(value) { - try { - Date.prototype.getTime.call(value); - return true; - } catch { - return false; - } -} - -const byteLengthGetter = - Object.getOwnPropertyDescriptor(ArrayBuffer.prototype, 'byteLength').get; -function isArrayBuffer(value) { - try { - byteLengthGetter.call(value); - return true; - } catch { - return false; - } -} - -function throwForDisallowedKey(key) { - if (!isAllowedAsAKey(key)) { - throw new DOMException( - 'The given value is not allowed as a key', 'DataError'); - } -} - -function zip(a, b) { - const result = []; - for (let i = 0; i < a.length; ++i) { - result.push([a[i], b[i]]); - } - - return result; -} - -function deleteDatabase(name) { - return new Promise((resolve, reject) => { - const request = self.indexedDB.deleteDatabase(name); - request.onsuccess = () => resolve(); - request.onerror = () => reject(request.error); - }); -} diff --git a/chromium/third_party/blink/renderer/core/script/resources/layered_api/kv-storage/.eslintrc.js b/chromium/third_party/blink/renderer/core/script/resources/layered_api/kv-storage/.eslintrc.js new file mode 100644 index 00000000000..7b8fea0b3bf --- /dev/null +++ b/chromium/third_party/blink/renderer/core/script/resources/layered_api/kv-storage/.eslintrc.js @@ -0,0 +1,337 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +module.exports = { + root: true, + env: { + es6: true, + browser: true + }, + parserOptions: { + sourceType: 'module', + ecmaVersion: 2019 + }, + rules: { + 'for-direction': 'error', + 'getter-return': 'error', + 'no-async-promise-executor': 'error', + 'no-await-in-loop': 'error', + 'no-compare-neg-zero': 'error', + 'no-cond-assign': ['error', 'except-parens'], + 'no-console': 'error', + 'no-constant-condition': ['error', {checkLoops: false}], + 'no-control-regex': 'error', + 'no-debugger': 'error', + 'no-dupe-args': 'error', + 'no-dupe-keys': 'error', + 'no-duplicate-case': 'error', + 'no-empty': 'error', + 'no-empty-character-class': 'error', + 'no-ex-assign': 'error', + 'no-extra-boolean-cast': 'error', + 'no-extra-parens': [ + 'error', + 'all', + { + conditionalAssign: false, + nestedBinaryExpressions: false, + returnAssign: false + } + ], + 'no-extra-semi': 'error', + 'no-func-assign': 'error', + 'no-inner-declarations': 'off', + 'no-invalid-regexp': 'error', + 'no-irregular-whitespace': 'error', + 'no-misleading-character-class': 'error', + 'no-obj-calls': 'error', + 'no-prototype-builtins': 'error', + 'no-regex-spaces': 'error', + 'no-sparse-arrays': 'error', + 'no-template-curly-in-string': 'error', + 'no-unexpected-multiline': 'error', + 'no-unreachable': 'error', + 'no-unsafe-finally': 'off', + 'no-unsafe-negation': 'error', + 'use-isnan': 'error', + 'valid-typeof': 'error', + 'accessor-pairs': 'error', + 'array-callback-return': 'error', + 'block-scoped-var': 'off', + 'class-methods-use-this': 'off', + 'complexity': 'off', + 'consistent-return': 'error', + 'curly': ['error', 'all'], + 'default-case': 'off', + 'dot-location': ['error', 'property'], + 'dot-notation': 'error', + 'eqeqeq': 'error', + 'guard-for-in': 'off', + 'no-alert': 'error', + 'no-caller': 'error', + 'no-case-declarations': 'error', + 'no-div-regex': 'off', + 'no-else-return': 'error', + 'no-empty-function': 'off', + 'no-empty-pattern': 'error', + 'no-eq-null': 'error', + 'no-eval': 'error', + 'no-extend-native': 'error', + 'no-extra-bind': 'error', + 'no-extra-label': 'error', + 'no-fallthrough': 'error', + 'no-floating-decimal': 'error', + 'no-global-assign': 'error', + 'no-implicit-coercion': 'error', + 'no-implicit-globals': 'error', + 'no-implied-eval': 'error', + 'no-invalid-this': 'error', + 'no-iterator': 'error', + 'no-labels': ['error', {allowLoop: true}], + 'no-lone-blocks': 'error', + 'no-loop-func': 'error', + 'no-magic-numbers': ['error', {ignore: [0, 1]}], + 'no-multi-spaces': ['error', {ignoreEOLComments: true}], + 'no-multi-str': 'error', + 'no-new': 'error', + 'no-new-func': 'error', + 'no-new-wrappers': 'error', + 'no-octal': 'error', + 'no-octal-escape': 'error', + 'no-param-reassign': 'off', + 'no-process-env': 'error', + 'no-proto': 'error', + 'no-redeclare': 'error', + 'no-restricted-properties': 'off', + 'no-return-assign': ['error', 'except-parens'], + 'no-return-await': 'error', + 'no-script-url': 'off', + 'no-self-assign': 'error', + 'no-self-compare': 'error', + 'no-sequences': 'error', + 'no-throw-literal': 'error', + 'no-unmodified-loop-condition': 'error', + 'no-unused-expressions': 'error', + 'no-unused-labels': 'error', + 'no-useless-call': 'error', + 'no-useless-concat': 'error', + 'no-useless-escape': 'error', + 'no-useless-return': 'error', + 'no-void': 'error', + 'no-warning-comments': 'off', + 'no-with': 'error', + 'prefer-promise-reject-errors': 'error', + 'radix': ['error', 'as-needed'], + 'require-await': 'off', + 'vars-on-top': 'off', + 'wrap-iife': ['error', 'outside'], + 'yoda': ['error', 'never'], + 'strict': ['error', 'global'], + 'init-declarations': 'off', + 'no-delete-var': 'error', + 'no-label-var': 'error', + 'no-restricted-globals': 'off', + 'no-shadow': 'error', + 'no-shadow-restricted-names': 'error', + 'no-undef': 'error', + 'no-undef-init': 'error', + 'no-undefined': 'off', + 'no-unused-vars': 'error', + 'no-use-before-define': ['error', 'nofunc'], + 'callback-return': 'off', + 'global-require': 'error', + 'handle-callback-err': 'error', + 'no-buffer-constructor': 'error', + 'no-mixed-requires': ['error', true], + 'no-new-require': 'error', + 'no-path-concat': 'error', + 'no-process-exit': 'error', + 'no-restricted-modules': 'off', + 'no-sync': 'off', + 'array-bracket-newline': ['error', {multiline: true}], + 'array-bracket-spacing': ['error', 'never'], + 'array-element-newline': 'off', + 'block-spacing': ['error', 'always'], + 'brace-style': [ + 'error', + '1tbs', + {allowSingleLine: false} + ], + camelcase: ['error', {properties: 'always'}], + 'capitalized-comments': 'off', + 'comma-dangle': ['error', 'always-multiline'], + 'comma-spacing': [ + 'error', + { + before: false, + after: true + } + ], + 'comma-style': ['error', 'last'], + 'computed-property-spacing': ['error', 'never'], + 'consistent-this': 'off', + 'eol-last': 'error', + 'func-call-spacing': ['error', 'never'], + 'func-name-matching': 'error', + 'func-names': 'off', + 'func-style': ['error', 'declaration'], + 'function-paren-newline': 'off', + 'id-blacklist': 'off', + 'id-length': 'off', + 'id-match': 'off', + indent: 'off', // not really compatible with clang-format + 'jsx-quotes': 'off', + 'key-spacing': [ + 'error', + { + beforeColon: false, + afterColon: true, + mode: 'strict' + } + ], + 'keyword-spacing': [ + 'error', + { + before: true, + after: true + } + ], + 'line-comment-position': 'off', + 'linebreak-style': ['error', 'unix'], + 'lines-around-comment': 'off', + 'max-depth': 'off', + 'max-len': 'off', + 'max-lines': 'off', + 'max-nested-callbacks': 'off', + 'max-params': 'off', + 'max-statements': 'off', + 'max-statements-per-line': ['error', {max: 1}], + 'multiline-ternary': ['error', 'always-multiline'], + 'new-cap': 'error', + 'new-parens': 'error', + 'newline-per-chained-call': 'off', + 'no-array-constructor': 'error', + 'no-bitwise': 'off', + 'no-continue': 'off', + 'no-inline-comments': 'off', + 'no-lonely-if': 'error', + 'no-mixed-operators': [ + 'error', + { + groups: [ + ['&', '|', '^', '~', '<<', '>>', '>>>'], + ['==', '!=', '===', '!==', '>', '>=', '<', '<='], + ['&&', '||'], + ['in', 'instanceof'] + ] + } + ], + 'no-mixed-spaces-and-tabs': 'error', + 'no-multi-assign': 'off', + 'no-multiple-empty-lines': 'error', + 'no-negated-condition': 'off', + 'no-nested-ternary': 'error', + 'no-new-object': 'error', + 'no-plusplus': 'off', + 'no-restricted-syntax': 'off', + 'no-tabs': 'error', + 'no-ternary': 'off', + 'no-trailing-spaces': 'error', + 'no-underscore-dangle': 'off', + 'no-unneeded-ternary': 'error', + 'no-whitespace-before-property': 'error', + 'nonblock-statement-body-position': 'error', + 'object-curly-newline': ['error', {consistent: true}], + 'object-curly-spacing': ['error', 'never'], + 'object-property-newline': 'off', + 'one-var': ['error', 'never'], + 'one-var-declaration-per-line': ['error', 'initializations'], + 'operator-assignment': ['error', 'always'], + 'operator-linebreak': ['error', 'after'], + 'padded-blocks': ['error', 'never'], + 'padding-line-between-statements': 'off', + 'quote-props': ['error', 'as-needed'], + quotes: [ + 'error', + 'single', + { + avoidEscape: true, + allowTemplateLiterals: true + } + ], + semi: ['error', 'always'], + 'semi-spacing': 'error', + 'semi-style': 'error', + 'sort-keys': 'off', + 'sort-vars': 'off', + 'space-before-blocks': ['error', 'always'], + 'space-before-function-paren': [ + 'error', + { + anonymous: 'always', + named: 'never' + } + ], + 'space-in-parens': ['error', 'never'], + 'space-infix-ops': 'error', + 'space-unary-ops': [ + 'error', + { + words: true, + nonwords: false + } + ], + 'spaced-comment': ['error', 'always'], + 'switch-colon-spacing': 'error', + 'template-tag-spacing': 'error', + 'unicode-bom': 'error', + 'wrap-regex': 'off', + 'arrow-body-style': 'off', + 'arrow-parens': ['error', 'as-needed'], + 'arrow-spacing': 'error', + 'constructor-super': 'error', + 'generator-star-spacing': ['error', 'neither'], + 'no-class-assign': 'error', + 'no-confusing-arrow': 'off', + 'no-const-assign': 'error', + 'no-dupe-class-members': 'error', + 'no-duplicate-imports': 'error', + 'no-new-symbol': 'error', + 'no-restricted-imports': 'off', + 'no-this-before-super': 'error', + 'no-useless-computed-key': 'error', + 'no-useless-constructor': 'error', + 'no-useless-rename': 'error', + 'no-var': 'error', + 'object-shorthand': 'error', + 'prefer-arrow-callback': 'error', + 'prefer-const': ['error', {ignoreReadBeforeAssign: true}], + 'prefer-destructuring': [ + 'error', + { + VariableDeclarator: { + array: false, + object: true + }, + AssignmentExpression: { + array: false, + object: false + } + }, + { + enforceForRenamedProperties: false + } + ], + 'prefer-numeric-literals': 'error', + 'prefer-rest-params': 'error', + 'prefer-spread': 'error', + 'prefer-template': 'off', + 'require-yield': 'error', + 'rest-spread-spacing': 'error', + 'sort-imports': 'off', + 'symbol-description': 'error', + 'template-curly-spacing': ['error', 'never'], + 'yield-star-spacing': ['error', 'after'] + } +}; diff --git a/chromium/third_party/blink/renderer/core/script/resources/layered_api/kv-storage/OWNERS b/chromium/third_party/blink/renderer/core/script/resources/layered_api/kv-storage/OWNERS new file mode 100644 index 00000000000..b891d42816e --- /dev/null +++ b/chromium/third_party/blink/renderer/core/script/resources/layered_api/kv-storage/OWNERS @@ -0,0 +1,5 @@ +jsbell@chromium.org +pwnall@chromium.org + +# TEAM: storage-dev@chromium.org +# COMPONENT: Blink>Storage>IndexedDB diff --git a/chromium/third_party/blink/renderer/core/script/resources/layered_api/kv-storage/async_iterator.js b/chromium/third_party/blink/renderer/core/script/resources/layered_api/kv-storage/async_iterator.js new file mode 100644 index 00000000000..79f35f28fb3 --- /dev/null +++ b/chromium/third_party/blink/renderer/core/script/resources/layered_api/kv-storage/async_iterator.js @@ -0,0 +1,88 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import {getNextKey, getNextKeyValuePair, HASNT_STARTED_YET} from './idb_utils.js'; + +const _performDatabaseOperation = new WeakMap(); +const _lastKey = new WeakMap(); // undefined = got to the end; + // HASNT_STARTED_YET = not yet started +const _ongoingPromise = new WeakMap(); +const _mode = new WeakMap(); + +const AsyncIteratorPrototype = Object.getPrototypeOf( + Object.getPrototypeOf(async function*() {}).prototype); + +const StorageAreaAsyncIteratorPrototype = { + __proto__: AsyncIteratorPrototype, + + next() { + const performDatabaseOperation = _performDatabaseOperation.get(this); + if (!performDatabaseOperation) { + return Promise.reject(new TypeError('Invalid this value')); + } + + // We need to avoid multiple concurrent calls into the main logic of next(), + // which can happen if you manually manipulate the async iterator, i.e. + // `iter.next(); iter.next()` with no `await`s. This is because until we + // actually have the last key set correctly, such concurrent calls will use + // the wrong value for lastKey. + + const currentOngoingPromise = _ongoingPromise.get(this); + let thisNextPromise; + if (currentOngoingPromise !== undefined) { + thisNextPromise = currentOngoingPromise.then( + () => getNextIterResult(this, performDatabaseOperation)); + } else { + thisNextPromise = getNextIterResult(this, performDatabaseOperation); + } + + _ongoingPromise.set(this, thisNextPromise); + return thisNextPromise; + }, +}; + +function getNextIterResult(iter, performDatabaseOperation) { + return performDatabaseOperation(async (transaction, store) => { + const lastKey = _lastKey.get(iter); + if (lastKey === undefined) { + return {value: undefined, done: true}; + } + + const mode = _mode.get(iter); + let key; + let value; + let iterResultValue; + switch (mode) { + case 'keys': { + key = await getNextKey(store, lastKey); + iterResultValue = key; + break; + } + case 'values': { + [key, value] = await getNextKeyValuePair(store, lastKey); + iterResultValue = value; + break; + } + case 'entries': { + [key, value] = await getNextKeyValuePair(store, lastKey); + iterResultValue = key === undefined ? undefined : [key, value]; + break; + } + } + + _lastKey.set(iter, key); + _ongoingPromise.set(iter, undefined); + + return {value: iterResultValue, done: key === undefined}; + }); +} + +export function createStorageAreaAsyncIterator(mode, performDatabaseOperation) { + const iter = Object.create(StorageAreaAsyncIteratorPrototype); + _mode.set(iter, mode); + _performDatabaseOperation.set(iter, performDatabaseOperation); + _lastKey.set(iter, HASNT_STARTED_YET); + _ongoingPromise.set(iter, undefined); + return iter; +} diff --git a/chromium/third_party/blink/renderer/core/script/resources/layered_api/kv-storage/idb_utils.js b/chromium/third_party/blink/renderer/core/script/resources/layered_api/kv-storage/idb_utils.js new file mode 100644 index 00000000000..6c66ab95a02 --- /dev/null +++ b/chromium/third_party/blink/renderer/core/script/resources/layered_api/kv-storage/idb_utils.js @@ -0,0 +1,107 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +export function promiseForRequest(request) { + return new Promise((resolve, reject) => { + request.onsuccess = () => resolve(request.result); + request.onerror = () => reject(request.error); + }); +} + +export function keyValuePairPromise(store, range) { + const keyRequest = store.getKey(range); + const valueRequest = store.get(range); + + return new Promise((resolve, reject) => { + keyRequest.onerror = () => reject(keyRequest.error); + valueRequest.onerror = () => reject(valueRequest.error); + valueRequest.onsuccess = () => + resolve([keyRequest.result, valueRequest.result]); + }); +} + +export function promiseForTransaction(transaction) { + return new Promise((resolve, reject) => { + transaction.oncomplete = () => resolve(); + transaction.onabort = () => reject(transaction.error); + transaction.onerror = () => reject(transaction.error); + }); +} + +export function throwForDisallowedKey(key) { + if (!isAllowedAsAKey(key)) { + throw new DOMException( + 'The given value is not allowed as a key', 'DataError'); + } +} + +export const HASNT_STARTED_YET = {}; + +export function getNextKey(store, lastKey) { + const range = getRangeForKey(lastKey); + return promiseForRequest(store.getKey(range)); +} + +export function getNextKeyValuePair(store, lastKey) { + const range = getRangeForKey(lastKey); + return keyValuePairPromise(store, range); +} + +function getRangeForKey(key) { + if (key === HASNT_STARTED_YET) { + // This is a stand-in for the spec's "unbounded" range, which isn't exposed + // to JS currently. If we ever get keys that sort below -Infinity, e.g. per + // https://github.com/w3c/IndexedDB/issues/76, then this needs to change. + // Alternately, if we add better primitives to IDB for getting the first + // key, per + // https://github.com/WICG/kv-storage/issues/6#issuecomment-452054944, then + // we could use those. + return IDBKeyRange.lowerBound(-Infinity); + } + return IDBKeyRange.lowerBound(key, true); +} + +function isAllowedAsAKey(value) { + if (typeof value === 'number' || typeof value === 'string') { + return true; + } + + if (Array.isArray(value)) { + return true; + } + + if (isDate(value)) { + return true; + } + + if (ArrayBuffer.isView(value)) { + return true; + } + + if (isArrayBuffer(value)) { + return true; + } + + return false; +} + +function isDate(value) { + try { + Date.prototype.getTime.call(value); + return true; + } catch { + return false; + } +} + +const byteLengthGetter = + Object.getOwnPropertyDescriptor(ArrayBuffer.prototype, 'byteLength').get; +function isArrayBuffer(value) { + try { + byteLengthGetter.call(value); + return true; + } catch { + return false; + } +} diff --git a/chromium/third_party/blink/renderer/core/script/resources/layered_api/kv-storage/index.js b/chromium/third_party/blink/renderer/core/script/resources/layered_api/kv-storage/index.js new file mode 100644 index 00000000000..b35752d1021 --- /dev/null +++ b/chromium/third_party/blink/renderer/core/script/resources/layered_api/kv-storage/index.js @@ -0,0 +1,176 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import {createStorageAreaAsyncIterator} from './async_iterator.js'; +import {promiseForRequest, promiseForTransaction, throwForDisallowedKey} from './idb_utils.js'; + +// TODOs/spec-noncompliances: +// - Susceptible to tampering of built-in prototypes and globals. We want to +// work on tooling to ameliorate that. + +// TODO: Use private fields when those ship. +// In the meantime we use this hard-to-understand, but effective, pattern: +// http://2ality.com/2016/01/private-data-classes.html#keeping-private-data-in-weakmaps +// Of note, the weak map entries will live only as long as the corresponding StorageArea instances. +// +// Cheatsheet: +// x.#y <---> _y.get(x) +// x.#y = z <---> _y.set(x, z) + +const _databaseName = new WeakMap(); +const _databasePromise = new WeakMap(); + +const DEFAULT_STORAGE_AREA_NAME = 'default'; +const DEFAULT_IDB_STORE_NAME = 'store'; + +if (!self.isSecureContext) { + throw new DOMException( + 'KV Storage is only available in secure contexts', + 'SecurityError'); +} + +export class StorageArea { + constructor(name) { + _databasePromise.set(this, null); + _databaseName.set(this, `kv-storage:${name}`); + } + + async set(key, value) { + throwForDisallowedKey(key); + + return performDatabaseOperation(this, 'readwrite', (transaction, store) => { + if (value === undefined) { + store.delete(key); + } else { + store.put(value, key); + } + + return promiseForTransaction(transaction); + }); + } + + async get(key) { + throwForDisallowedKey(key); + + return performDatabaseOperation(this, 'readonly', (transaction, store) => { + return promiseForRequest(store.get(key)); + }); + } + + async delete(key) { + throwForDisallowedKey(key); + + return performDatabaseOperation(this, 'readwrite', (transaction, store) => { + store.delete(key); + return promiseForTransaction(transaction); + }); + } + + async clear() { + if (!_databasePromise.has(this)) { + throw new TypeError('Invalid this value'); + } + + const databasePromise = _databasePromise.get(this); + if (databasePromise !== null) { + // Don't try to delete, and clear the promise, while we're opening the database; wait for that + // first. + try { + await databasePromise; + } catch { + // If the database failed to initialize, then that's fine, we'll still try to delete it. + } + + _databasePromise.set(this, null); + } + + return promiseForRequest(self.indexedDB.deleteDatabase(_databaseName.get(this))); + } + + keys() { + if (!_databasePromise.has(this)) { + throw new TypeError('Invalid this value'); + } + + return createStorageAreaAsyncIterator( + 'keys', steps => performDatabaseOperation(this, 'readonly', steps)); + } + + values() { + if (!_databasePromise.has(this)) { + throw new TypeError('Invalid this value'); + } + + return createStorageAreaAsyncIterator( + 'values', steps => performDatabaseOperation(this, 'readonly', steps)); + } + + entries() { + if (!_databasePromise.has(this)) { + throw new TypeError('Invalid this value'); + } + + return createStorageAreaAsyncIterator( + 'entries', steps => performDatabaseOperation(this, 'readonly', steps)); + } + + get backingStore() { + if (!_databasePromise.has(this)) { + throw new TypeError('Invalid this value'); + } + + return { + database: _databaseName.get(this), + store: DEFAULT_IDB_STORE_NAME, + version: 1, + }; + } +} + +StorageArea.prototype[Symbol.asyncIterator] = StorageArea.prototype.entries; + +export const storage = new StorageArea(DEFAULT_STORAGE_AREA_NAME); + +async function performDatabaseOperation(area, mode, steps) { + if (!_databasePromise.has(area)) { + throw new TypeError('Invalid this value'); + } + + if (_databasePromise.get(area) === null) { + initializeDatabasePromise(area); + } + + const database = await _databasePromise.get(area); + const transaction = database.transaction(DEFAULT_IDB_STORE_NAME, mode); + const store = transaction.objectStore(DEFAULT_IDB_STORE_NAME); + + return steps(transaction, store); +} + +function initializeDatabasePromise(area) { + _databasePromise.set( + area, new Promise((resolve, reject) => { + const request = self.indexedDB.open(_databaseName.get(area), 1); + + request.onsuccess = () => { + const database = request.result; + database.onclose = () => _databasePromise.set(area, null); + database.onversionchange = () => { + database.close(); + _databasePromise.set(area, null); + }; + resolve(database); + }; + + request.onerror = () => reject(request.error); + + request.onupgradeneeded = () => { + try { + request.result.createObjectStore(DEFAULT_IDB_STORE_NAME); + } catch (e) { + reject(e); + } + }; + })); +} diff --git a/chromium/third_party/blink/renderer/core/script/resources/layered_api/resources.grdp b/chromium/third_party/blink/renderer/core/script/resources/layered_api/resources.grdp new file mode 100644 index 00000000000..c16d09783b3 --- /dev/null +++ b/chromium/third_party/blink/renderer/core/script/resources/layered_api/resources.grdp @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="utf-8"?> +<grit-part> + <!-- Layered API scripts. This file is generated by + core/script/generate_lapi_grdp.py and shouldn't modified manually. + A corresponding header file (layered_api_resources.h) is also generated. + The paths are relative to the main grd file, i.e. + third_party/blink/public/blink_resources.grd. + --> + <include name="IDR_LAYERED_API_BLANK_INDEX_JS" file="../renderer/core/script/resources/layered_api/blank/index.js" type="BINDATA" skip_minify="true" compress="gzip"/> + <include name="IDR_LAYERED_API_KV_STORAGE_ASYNC_ITERATOR_JS" file="../renderer/core/script/resources/layered_api/kv-storage/async_iterator.js" type="BINDATA" skip_minify="true" compress="gzip"/> + <include name="IDR_LAYERED_API_KV_STORAGE_IDB_UTILS_JS" file="../renderer/core/script/resources/layered_api/kv-storage/idb_utils.js" type="BINDATA" skip_minify="true" compress="gzip"/> + <include name="IDR_LAYERED_API_KV_STORAGE_INDEX_JS" file="../renderer/core/script/resources/layered_api/kv-storage/index.js" type="BINDATA" skip_minify="true" compress="gzip"/> + <include name="IDR_LAYERED_API_VIRTUAL_SCROLLER_INDEX_JS" file="../renderer/core/script/resources/layered_api/virtual-scroller/index.js" type="BINDATA" skip_minify="true" compress="gzip"/> + <include name="IDR_LAYERED_API_VIRTUAL_SCROLLER_ITEM_SOURCE_JS" file="../renderer/core/script/resources/layered_api/virtual-scroller/item-source.js" type="BINDATA" skip_minify="true" compress="gzip"/> + <include name="IDR_LAYERED_API_VIRTUAL_SCROLLER_VIRTUAL_REPEATER_JS" file="../renderer/core/script/resources/layered_api/virtual-scroller/virtual-repeater.js" type="BINDATA" skip_minify="true" compress="gzip"/> + <include name="IDR_LAYERED_API_VIRTUAL_SCROLLER_VIRTUAL_SCROLLER_JS" file="../renderer/core/script/resources/layered_api/virtual-scroller/virtual-scroller.js" type="BINDATA" skip_minify="true" compress="gzip"/> + <include name="IDR_LAYERED_API_VIRTUAL_SCROLLER_LAYOUTS_LAYOUT_1D_BASE_JS" file="../renderer/core/script/resources/layered_api/virtual-scroller/layouts/layout-1d-base.js" type="BINDATA" skip_minify="true" compress="gzip"/> + <include name="IDR_LAYERED_API_VIRTUAL_SCROLLER_LAYOUTS_LAYOUT_1D_GRID_JS" file="../renderer/core/script/resources/layered_api/virtual-scroller/layouts/layout-1d-grid.js" type="BINDATA" skip_minify="true" compress="gzip"/> + <include name="IDR_LAYERED_API_VIRTUAL_SCROLLER_LAYOUTS_LAYOUT_1D_JS" file="../renderer/core/script/resources/layered_api/virtual-scroller/layouts/layout-1d.js" type="BINDATA" skip_minify="true" compress="gzip"/> +</grit-part> diff --git a/chromium/third_party/blink/renderer/core/script/script_element_base.h b/chromium/third_party/blink/renderer/core/script/script_element_base.h index 7f6e6fa21c4..23e974d07a0 100644 --- a/chromium/third_party/blink/renderer/core/script/script_element_base.h +++ b/chromium/third_party/blink/renderer/core/script/script_element_base.h @@ -51,6 +51,7 @@ class CORE_EXPORT ScriptElementBase : public GarbageCollectedMixin { virtual String SourceAttributeValue() const = 0; virtual String TypeAttributeValue() const = 0; virtual String ReferrerPolicyAttributeValue() const = 0; + virtual String ImportanceAttributeValue() const = 0; virtual String TextFromChildren() = 0; virtual bool HasSourceAttribute() const = 0; diff --git a/chromium/third_party/blink/renderer/core/script/script_loader.cc b/chromium/third_party/blink/renderer/core/script/script_loader.cc index c058625bbcf..c58812ff1d7 100644 --- a/chromium/third_party/blink/renderer/core/script/script_loader.cc +++ b/chromium/third_party/blink/renderer/core/script/script_loader.cc @@ -38,6 +38,7 @@ #include "third_party/blink/renderer/core/html/parser/html_parser_idioms.h" #include "third_party/blink/renderer/core/html_names.h" #include "third_party/blink/renderer/core/inspector/console_message.h" +#include "third_party/blink/renderer/core/loader/importance_attribute.h" #include "third_party/blink/renderer/core/loader/modulescript/module_script_fetch_request.h" #include "third_party/blink/renderer/core/loader/subresource_integrity_helper.h" #include "third_party/blink/renderer/core/script/classic_pending_script.h" @@ -140,8 +141,8 @@ bool IsValidClassicScriptTypeAndLanguage( const String& type, const String& language, ScriptLoader::LegacyTypeSupport support_legacy_types) { - // FIXME: isLegacySupportedJavaScriptLanguage() is not valid HTML5. It is used - // here to maintain backwards compatibility with existing layout tests. The + // FIXME: IsLegacySupportedJavaScriptLanguage() is not valid HTML5. It is used + // here to maintain backwards compatibility with existing web tests. The // specific violations are: // - Allowing type=javascript. type= should only support MIME types, such as // text/javascript. @@ -382,6 +383,14 @@ bool ScriptLoader::PrepareScript(const TextPosition& script_start_position, &referrer_policy); } + // Priority Hints is currently a non-standard feature, but we can assume the + // following (see https://crbug.com/821464): + // <spec step="21">Let importance be the current state of the element's + // importance content attribute.</spec> + String importance_attr = element_->ImportanceAttributeValue(); + mojom::FetchImportanceMode importance = + GetFetchImportanceAttributeValue(importance_attr); + // <spec step="21">Let parser metadata be "parser-inserted" if the script // element has been flagged as "parser-inserted", and "not-parser-inserted" // otherwise.</spec> @@ -411,14 +420,17 @@ bool ScriptLoader::PrepareScript(const TextPosition& script_start_position, // parser metadata is parser metadata, credentials mode is module script // credentials mode, and referrer policy is referrer policy.</spec> ScriptFetchOptions options(nonce, integrity_metadata, integrity_attr, - parser_state, credentials_mode, referrer_policy); + parser_state, credentials_mode, referrer_policy, + importance); // <spec step="23">Let settings object be the element's node document's // relevant settings object.</spec> // - // Note: We use |element_document| as "settings object" in the steps below. - auto* settings_object = - element_document.CreateFetchClientSettingsObjectSnapshot(); + // In some cases (mainly for classic scripts) |element_document| is used as + // the "settings object", while in other cases (mainly for module scripts) + // |content_document| is used. + // TODO(hiroshige): Use a consistent Document everywhere. + auto* fetch_client_settings_object_fetcher = context_document->Fetcher(); // <spec step="24">If the element has a src content attribute, then:</spec> if (element_->HasSourceAttribute()) { @@ -490,7 +502,8 @@ bool ScriptLoader::PrepareScript(const TextPosition& script_start_position, // options.</spec> Modulator* modulator = Modulator::From( ToScriptStateForMainWorld(context_document->GetFrame())); - FetchModuleScriptTree(url, settings_object, modulator, options); + FetchModuleScriptTree(url, fetch_client_settings_object_fetcher, + modulator, options); } // <spec step="24.6">When the chosen algorithm asynchronously completes, set // the script's script to the result. At that time, the script is ready. @@ -575,8 +588,8 @@ bool ScriptLoader::PrepareScript(const TextPosition& script_start_position, // that time, the script is ready.</spec> auto* module_tree_client = ModulePendingScriptTreeClient::Create(); modulator->FetchDescendantsForInlineScript( - module_script, settings_object, mojom::RequestContextType::SCRIPT, - module_tree_client); + module_script, fetch_client_settings_object_fetcher, + mojom::RequestContextType::SCRIPT, module_tree_client); prepared_pending_script_ = ModulePendingScript::Create( element_, module_tree_client, is_external_script_); break; @@ -756,7 +769,7 @@ void ScriptLoader::FetchClassicScript(const KURL& url, // <specdef href="https://html.spec.whatwg.org/#prepare-a-script"> void ScriptLoader::FetchModuleScriptTree( const KURL& url, - FetchClientSettingsObjectSnapshot* settings_object, + ResourceFetcher* fetch_client_settings_object_fetcher, Modulator* modulator, const ScriptFetchOptions& options) { // <spec step="24.6.B">"module" @@ -764,9 +777,9 @@ void ScriptLoader::FetchModuleScriptTree( // Fetch a module script graph given url, settings object, "script", and // options.</spec> auto* module_tree_client = ModulePendingScriptTreeClient::Create(); - modulator->FetchTree(url, settings_object, mojom::RequestContextType::SCRIPT, - options, ModuleScriptCustomFetchType::kNone, - module_tree_client); + modulator->FetchTree(url, fetch_client_settings_object_fetcher, + mojom::RequestContextType::SCRIPT, options, + ModuleScriptCustomFetchType::kNone, module_tree_client); prepared_pending_script_ = ModulePendingScript::Create( element_, module_tree_client, is_external_script_); } diff --git a/chromium/third_party/blink/renderer/core/script/script_loader.h b/chromium/third_party/blink/renderer/core/script/script_loader.h index 95a3a3d70d6..689d62b12a0 100644 --- a/chromium/third_party/blink/renderer/core/script/script_loader.h +++ b/chromium/third_party/blink/renderer/core/script/script_loader.h @@ -41,8 +41,8 @@ namespace blink { -class FetchClientSettingsObjectSnapshot; class Resource; +class ResourceFetcher; class ScriptElementBase; class Script; class ScriptResource; @@ -131,7 +131,7 @@ class CORE_EXPORT ScriptLoader final const WTF::TextEncoding&); // https://html.spec.whatwg.org/multipage/webappapis.html#fetch-a-module-script-tree void FetchModuleScriptTree(const KURL&, - FetchClientSettingsObjectSnapshot*, + ResourceFetcher*, Modulator*, const ScriptFetchOptions&); diff --git a/chromium/third_party/blink/renderer/core/script/script_module_resolver_impl_test.cc b/chromium/third_party/blink/renderer/core/script/script_module_resolver_impl_test.cc index 9fbfae71b0a..5cc43ce7b99 100644 --- a/chromium/third_party/blink/renderer/core/script/script_module_resolver_impl_test.cc +++ b/chromium/third_party/blink/renderer/core/script/script_module_resolver_impl_test.cc @@ -120,7 +120,7 @@ class ScriptModuleResolverImplTest : public testing::Test { void ScriptModuleResolverImplTest::SetUp() { platform_->AdvanceClockSeconds(1.); // For non-zero DocumentParserTimings - modulator_ = new ScriptModuleResolverImplTestModulator(); + modulator_ = MakeGarbageCollected<ScriptModuleResolverImplTestModulator>(); } TEST_F(ScriptModuleResolverImplTest, RegisterResolveSuccess) { diff --git a/chromium/third_party/blink/renderer/core/script/script_runner.cc b/chromium/third_party/blink/renderer/core/script/script_runner.cc index 9f5f0b87626..95d55e55f42 100644 --- a/chromium/third_party/blink/renderer/core/script/script_runner.cc +++ b/chromium/third_party/blink/renderer/core/script/script_runner.cc @@ -49,7 +49,9 @@ void ScriptRunner::QueueScriptForExecution(PendingScript* pending_script) { switch (pending_script->GetSchedulingType()) { case ScriptSchedulingType::kAsync: pending_async_scripts_.insert(pending_script); - TryStream(pending_script); + if (!is_suspended_) { + pending_script->StartStreamingIfPossible(); + } break; case ScriptSchedulingType::kInOrder: @@ -116,7 +118,6 @@ void ScriptRunner::NotifyScriptReady(PendingScript* pending_script) { async_scripts_to_execute_soon_.push_back(pending_script); PostTask(FROM_HERE); - TryStreamAny(); break; case ScriptSchedulingType::kInOrder: @@ -144,11 +145,6 @@ bool ScriptRunner::RemovePendingInOrderScript(PendingScript* pending_script) { return true; } -void ScriptRunner::NotifyScriptStreamerFinished() { - PostTask(FROM_HERE); - TryStreamAny(); -} - void ScriptRunner::MovePendingScript(Document& old_document, Document& new_document, ScriptLoader* script_loader) { @@ -206,6 +202,7 @@ void ScriptRunner::MovePendingScript(ScriptRunner* new_runner, } bool ScriptRunner::ExecuteInOrderTask() { + TRACE_EVENT0("blink", "ScriptRunner::ExecuteInOrderTask"); if (in_order_scripts_to_execute_soon_.IsEmpty()) return false; @@ -221,20 +218,12 @@ bool ScriptRunner::ExecuteInOrderTask() { } bool ScriptRunner::ExecuteAsyncTask() { - // Find an async script loader which is not currently streaming. - auto it = std::find_if(async_scripts_to_execute_soon_.begin(), - async_scripts_to_execute_soon_.end(), - [](PendingScript* pending_script) { - DCHECK(pending_script); - return !pending_script->IsCurrentlyStreaming(); - }); - if (it == async_scripts_to_execute_soon_.end()) { + TRACE_EVENT0("blink", "ScriptRunner::ExecuteAsyncTask"); + if (async_scripts_to_execute_soon_.IsEmpty()) return false; - } // Remove the async script loader from the ready-to-exec set and execute. - PendingScript* pending_script = *it; - async_scripts_to_execute_soon_.erase(it); + PendingScript* pending_script = async_scripts_to_execute_soon_.TakeFirst(); DCHECK_EQ(pending_script->GetSchedulingType(), ScriptSchedulingType::kAsync) << "Async scripts queue should not contain any in-order script."; @@ -256,70 +245,12 @@ void ScriptRunner::ExecuteTask() { return; #ifndef NDEBUG - // Extra tasks should be posted only when we resume after suspending, - // or when we stream a script. These should all be accounted for in - // number_of_extra_tasks_. + // Extra tasks should be posted only when we resume after suspending. These + // should all be accounted for in number_of_extra_tasks_. DCHECK_GT(number_of_extra_tasks_--, 0); #endif } -void ScriptRunner::TryStreamAny() { - if (is_suspended_) - return; - - if (!RuntimeEnabledFeatures::WorkStealingInScriptRunnerEnabled()) - return; - - // Look through async_scripts_to_execute_soon_, and stream any one of them. - for (auto pending_script : async_scripts_to_execute_soon_) { - if (DoTryStream(pending_script)) - return; - } -} - -void ScriptRunner::TryStream(PendingScript* pending_script) { - if (!is_suspended_) - DoTryStream(pending_script); -} - -bool ScriptRunner::DoTryStream(PendingScript* pending_script) { - // Checks that all callers should have already done. - DCHECK(!is_suspended_); - DCHECK(pending_script); - - // Currently, we stream only async scripts in this function. - // Note: HTMLParserScriptRunner kicks streaming for deferred or blocking - // scripts. - DCHECK(pending_async_scripts_.find(pending_script) != - pending_async_scripts_.end() || - std::find(async_scripts_to_execute_soon_.begin(), - async_scripts_to_execute_soon_.end(), - pending_script) != async_scripts_to_execute_soon_.end()); - - if (!pending_script) - return false; - - DCHECK_EQ(pending_script->GetSchedulingType(), ScriptSchedulingType::kAsync); - -#ifndef NDEBUG - bool was_already_streaming = pending_script->IsCurrentlyStreaming(); -#endif - - bool success = pending_script->StartStreamingIfPossible( - WTF::Bind(&ScriptRunner::NotifyScriptStreamerFinished, - WrapWeakPersistent(this))); -#ifndef NDEBUG - if (was_already_streaming) { - DCHECK(!success); - } else { - DCHECK_EQ(success, pending_script->IsCurrentlyStreaming()); - } - if (success) - number_of_extra_tasks_++; -#endif - return success; -} - void ScriptRunner::Trace(blink::Visitor* visitor) { visitor->Trace(document_); visitor->Trace(pending_in_order_scripts_); diff --git a/chromium/third_party/blink/renderer/core/script/script_runner.h b/chromium/third_party/blink/renderer/core/script/script_runner.h index 9a4608e4495..9f44f22abc5 100644 --- a/chromium/third_party/blink/renderer/core/script/script_runner.h +++ b/chromium/third_party/blink/renderer/core/script/script_runner.h @@ -60,7 +60,6 @@ class CORE_EXPORT ScriptRunner final void Suspend(); void Resume(); void NotifyScriptReady(PendingScript*); - void NotifyScriptStreamerFinished(); static void MovePendingScript(Document&, Document&, ScriptLoader*); @@ -86,11 +85,6 @@ class CORE_EXPORT ScriptRunner final void ExecuteTask(); - // Try to start streaming a specific script or any available script. - void TryStream(PendingScript*); - void TryStreamAny(); - bool DoTryStream(PendingScript*); // Implementation for both Try* methods. - Member<Document> document_; HeapDeque<TraceWrapperMember<PendingScript>> pending_in_order_scripts_; @@ -110,9 +104,8 @@ class CORE_EXPORT ScriptRunner final #ifndef NDEBUG // We expect to have one posted task in flight for each script in either // .._to_be_executed_soon_ queue. This invariant will be temporarily violated - // when the ScriptRunner is suspended, or when we take a Script out the - // async_scripts_to_be_executed_soon_ queue for streaming. We'll use this - // variable to account & check this invariant for debugging. + // when the ScriptRunner is suspended. We'll use this variable to account & + // check this invariant for debugging. int number_of_extra_tasks_ = 0; #endif DISALLOW_COPY_AND_ASSIGN(ScriptRunner); diff --git a/chromium/third_party/blink/renderer/core/script/script_runner_test.cc b/chromium/third_party/blink/renderer/core/script/script_runner_test.cc index 7fab1aa0bec..657d8c610f6 100644 --- a/chromium/third_party/blink/renderer/core/script/script_runner_test.cc +++ b/chromium/third_party/blink/renderer/core/script/script_runner_test.cc @@ -49,40 +49,9 @@ class MockPendingScript : public PendingScript { MOCK_METHOD0(RemoveFromMemoryCache, void()); MOCK_METHOD1(ExecuteScriptBlock, void(const KURL&)); - enum class State { - kStreamingNotReady, - kReadyToBeStreamed, - kStreaming, - kStreamingFinished, - }; - - bool IsCurrentlyStreaming() const override { - return state_ == State::kStreaming; - } - - void PrepareForStreaming() { - DCHECK_EQ(state_, State::kStreamingNotReady); - state_ = State::kReadyToBeStreamed; - } - - bool StartStreamingIfPossible(base::OnceClosure closure) override { - if (state_ != State::kReadyToBeStreamed) - return false; - - state_ = State::kStreaming; - streaming_finished_callback_ = std::move(closure); - return true; - } + void StartStreamingIfPossible() override {} - void SimulateStreamingEnd() { - DCHECK_EQ(state_, State::kStreaming); - state_ = State::kStreamingFinished; - std::move(streaming_finished_callback_).Run(); - } - - State state() const { return state_; } - - bool IsReady() const { return is_ready_; } + bool IsReady() const override { return is_ready_; } void SetIsReady(bool is_ready) { is_ready_ = is_ready; } protected: @@ -101,7 +70,6 @@ class MockPendingScript : public PendingScript { return pending_script; } - State state_ = State::kStreamingNotReady; bool is_ready_ = false; base::OnceClosure streaming_finished_callback_; }; @@ -449,30 +417,4 @@ TEST_F(ScriptRunnerTest, TryStreamWhenEnqueingScript) { QueueScriptForExecution(pending_script1); } -TEST_F(ScriptRunnerTest, DontExecuteWhileStreaming) { - auto* pending_script = MockPendingScript::CreateAsync(document_); - - // Enqueue script. - QueueScriptForExecution(pending_script); - - // Simulate script load and mark the pending script as streaming ready. - pending_script->SetIsReady(true); - pending_script->PrepareForStreaming(); - NotifyScriptReady(pending_script); - - // ScriptLoader should have started streaming by now. - EXPECT_EQ(pending_script->state(), MockPendingScript::State::kStreaming); - - // Note that there is no expectation for ScriptLoader::Execute() yet, - // so the mock will fail if it's called anyway. - platform_->RunUntilIdle(); - - // Finish streaming. - pending_script->SimulateStreamingEnd(); - - // Now that streaming is finished, expect Execute() to be called. - EXPECT_CALL(*pending_script, ExecuteScriptBlock(_)).Times(1); - platform_->RunUntilIdle(); -} - } // namespace blink diff --git a/chromium/third_party/blink/renderer/core/script/worker_modulator_impl.cc b/chromium/third_party/blink/renderer/core/script/worker_modulator_impl.cc index 09f3c14c895..78135bdb98d 100644 --- a/chromium/third_party/blink/renderer/core/script/worker_modulator_impl.cc +++ b/chromium/third_party/blink/renderer/core/script/worker_modulator_impl.cc @@ -26,14 +26,14 @@ ModuleScriptFetcher* WorkerModulatorImpl::CreateModuleScriptFetcher( auto* global_scope = To<WorkerGlobalScope>(GetExecutionContext()); switch (custom_fetch_type) { case ModuleScriptCustomFetchType::kNone: - return MakeGarbageCollected<DocumentModuleScriptFetcher>( - global_scope->EnsureFetcher()); + return MakeGarbageCollected<DocumentModuleScriptFetcher>(); case ModuleScriptCustomFetchType::kWorkerConstructor: return MakeGarbageCollected<WorkerModuleScriptFetcher>(global_scope); case ModuleScriptCustomFetchType::kWorkletAddModule: break; case ModuleScriptCustomFetchType::kInstalledServiceWorker: - return new InstalledServiceWorkerModuleScriptFetcher(global_scope); + return MakeGarbageCollected<InstalledServiceWorkerModuleScriptFetcher>( + global_scope); } NOTREACHED(); return nullptr; diff --git a/chromium/third_party/blink/renderer/core/script/worklet_modulator_impl.cc b/chromium/third_party/blink/renderer/core/script/worklet_modulator_impl.cc index cee9449e2a5..932fc41526a 100644 --- a/chromium/third_party/blink/renderer/core/script/worklet_modulator_impl.cc +++ b/chromium/third_party/blink/renderer/core/script/worklet_modulator_impl.cc @@ -22,7 +22,7 @@ ModuleScriptFetcher* WorkletModulatorImpl::CreateModuleScriptFetcher( WorkletGlobalScope* global_scope = To<WorkletGlobalScope>(GetExecutionContext()); return MakeGarbageCollected<WorkletModuleScriptFetcher>( - global_scope->EnsureFetcher(), global_scope->GetModuleResponsesMap()); + global_scope->GetModuleResponsesMap()); } bool WorkletModulatorImpl::IsDynamicImportForbidden(String* reason) { |