| OLD | NEW |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "core/workers/ThreadedWorklet.h" | 5 #include "core/workers/ThreadedWorklet.h" |
| 6 | 6 |
| 7 #include "bindings/core/v8/ScriptSourceCode.h" | 7 #include "bindings/core/v8/ScriptSourceCode.h" |
| 8 #include "bindings/core/v8/V8BindingForCore.h" | 8 #include "bindings/core/v8/V8BindingForCore.h" |
| 9 #include "core/dom/DOMException.h" | 9 #include "core/dom/DOMException.h" |
| 10 #include "core/dom/Document.h" | 10 #include "core/dom/Document.h" |
| 11 #include "core/dom/ExceptionCode.h" | 11 #include "core/dom/ExceptionCode.h" |
| 12 #include "core/dom/TaskRunnerHelper.h" |
| 12 #include "core/frame/LocalFrame.h" | 13 #include "core/frame/LocalFrame.h" |
| 13 #include "core/workers/WorkletGlobalScopeProxy.h" | 14 #include "core/workers/WorkletGlobalScopeProxy.h" |
| 15 #include "core/workers/WorkletPendingTasks.h" |
| 16 #include "platform/WebTaskRunner.h" |
| 14 #include "platform/wtf/WTF.h" | 17 #include "platform/wtf/WTF.h" |
| 15 | 18 |
| 16 namespace blink { | 19 namespace blink { |
| 17 | 20 |
| 18 ThreadedWorklet::ThreadedWorklet(LocalFrame* frame) : Worklet(frame) {} | 21 ThreadedWorklet::ThreadedWorklet(LocalFrame* frame) : Worklet(frame) {} |
| 19 | 22 |
| 23 // Implementation of the second half of the "addModule(moduleURL, options)" |
| 24 // algorithm: |
| 25 // https://drafts.css-houdini.org/worklets/#dom-worklet-addmodule |
| 26 // TODO(nhiroki): MainThreadWorklet::FetchAndInvokeScript will be moved to the |
| 27 // parent class (i.e., Worklet) and this function will be replaced with it. |
| 28 // (https://crbug.com/727194) |
| 20 void ThreadedWorklet::FetchAndInvokeScript(const KURL& module_url_record, | 29 void ThreadedWorklet::FetchAndInvokeScript(const KURL& module_url_record, |
| 21 const WorkletOptions&, | 30 const WorkletOptions& options, |
| 22 ScriptPromiseResolver* resolver) { | 31 ScriptPromiseResolver* resolver) { |
| 23 DCHECK(IsMainThread()); | 32 DCHECK(IsMainThread()); |
| 24 if (!GetExecutionContext()) | 33 if (!GetExecutionContext()) |
| 25 return; | 34 return; |
| 26 | 35 |
| 27 if (!IsInitialized()) | 36 if (!IsInitialized()) |
| 28 Initialize(); | 37 Initialize(); |
| 29 | 38 |
| 30 WorkletScriptLoader* script_loader = WorkletScriptLoader::Create( | 39 // Step 6: "Let credentialOptions be the credentials member of options." |
| 31 ToDocument(GetExecutionContext())->Fetcher(), this); | 40 // TODO(nhiroki): Add tests for credentialOptions (https://crbug.com/710837). |
| 32 loader_to_resolver_map_.Set(script_loader, resolver); | 41 WebURLRequest::FetchCredentialsMode credentials_mode = |
| 33 script_loader->FetchScript(module_url_record); | 42 ParseCredentialsOption(options.credentials()); |
| 34 } | |
| 35 | 43 |
| 36 void ThreadedWorklet::NotifyWorkletScriptLoadingFinished( | 44 // Step 7: "Let outsideSettings be the relevant settings object of this." |
| 37 WorkletScriptLoader* script_loader, | 45 // In the specification, outsideSettings is used for posting a task to the |
| 38 const ScriptSourceCode& source_code) { | 46 // document's responsible event loop. In our implementation, we use the |
| 39 DCHECK(IsMainThread()); | 47 // document's UnspecedLoading task runner as that is what we commonly use for |
| 40 ScriptPromiseResolver* resolver = loader_to_resolver_map_.at(script_loader); | 48 // module loading. |
| 41 loader_to_resolver_map_.erase(script_loader); | 49 RefPtr<WebTaskRunner> outside_settings_task_runner = |
| 50 TaskRunnerHelper::Get(TaskType::kUnspecedLoading, GetExecutionContext()); |
| 42 | 51 |
| 43 if (!script_loader->WasScriptLoadSuccessful()) { | 52 // Step 8: "Let moduleResponsesMap be worklet's module responses map." |
| 44 resolver->Reject(DOMException::Create(kNetworkError)); | 53 // TODO(nhiroki): Implement moduleResponsesMap (https://crbug.com/627945). |
| 45 return; | |
| 46 } | |
| 47 | 54 |
| 48 GetWorkletGlobalScopeProxy()->EvaluateScript(source_code); | 55 // Step 9: "Let workletGlobalScopeType be worklet's worklet global scope |
| 49 resolver->Resolve(); | 56 // type." |
| 57 // workletGlobalScopeType is encoded into the class name (e.g., PaintWorklet). |
| 58 |
| 59 // Step 10: "If the worklet's WorkletGlobalScopes is empty, run the following |
| 60 // steps:" |
| 61 // 10.1: "Create a WorkletGlobalScope given workletGlobalScopeType, |
| 62 // moduleResponsesMap, and outsideSettings." |
| 63 // 10.2: "Add the WorkletGlobalScope to worklet's WorkletGlobalScopes." |
| 64 // "Depending on the type of worklet the user agent may create additional |
| 65 // WorkletGlobalScopes at this time." |
| 66 // TODO(nhiroki): These steps will be supported after MainThreadWorklet and |
| 67 // ThreadedWorklet are merged into Worklet (https://crbug.com/727194) |
| 68 |
| 69 // Step 11: "Let pendingTaskStruct be a new pending tasks struct with counter |
| 70 // initialized to the length of worklet's WorkletGlobalScopes." |
| 71 const int kNumberOfGlobalScopes = 1; |
| 72 WorkletPendingTasks* pending_tasks = |
| 73 new WorkletPendingTasks(kNumberOfGlobalScopes, resolver); |
| 74 |
| 75 // Step 12: "For each workletGlobalScope in the worklet's |
| 76 // WorkletGlobalScopes, queue a task on the workletGlobalScope to fetch and |
| 77 // invoke a worklet script given workletGlobalScope, moduleURLRecord, |
| 78 // moduleResponsesMap, credentialOptions, outsideSettings, pendingTaskStruct, |
| 79 // and promise." |
| 80 // TODO(nhiroki): Queue a task instead of executing this here. |
| 81 GetWorkletGlobalScopeProxy()->FetchAndInvokeScript( |
| 82 module_url_record, credentials_mode, |
| 83 std::move(outside_settings_task_runner), pending_tasks); |
| 50 } | 84 } |
| 51 | 85 |
| 52 void ThreadedWorklet::ContextDestroyed(ExecutionContext* execution_context) { | 86 void ThreadedWorklet::ContextDestroyed(ExecutionContext* execution_context) { |
| 53 DCHECK(IsMainThread()); | 87 DCHECK(IsMainThread()); |
| 54 for (const auto& script_loader : loader_to_resolver_map_.Keys()) | |
| 55 script_loader->Cancel(); | |
| 56 loader_to_resolver_map_.clear(); | |
| 57 if (IsInitialized()) | 88 if (IsInitialized()) |
| 58 GetWorkletGlobalScopeProxy()->TerminateWorkletGlobalScope(); | 89 GetWorkletGlobalScopeProxy()->TerminateWorkletGlobalScope(); |
| 59 } | 90 } |
| 60 | 91 |
| 61 DEFINE_TRACE(ThreadedWorklet) { | 92 DEFINE_TRACE(ThreadedWorklet) { |
| 62 visitor->Trace(loader_to_resolver_map_); | |
| 63 Worklet::Trace(visitor); | 93 Worklet::Trace(visitor); |
| 64 } | 94 } |
| 65 | 95 |
| 66 } // namespace blink | 96 } // namespace blink |
| OLD | NEW |