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 |