6
6
7
7
#include < LibIPC/File.h>
8
8
#include < LibJS/Runtime/ConsoleObject.h>
9
+ #include < LibWeb/Fetch/Enums.h>
9
10
#include < LibWeb/Fetch/Fetching/Fetching.h>
10
11
#include < LibWeb/Fetch/Infrastructure/FetchAlgorithms.h>
11
12
#include < LibWeb/HTML/DedicatedWorkerGlobalScope.h>
13
+ #include < LibWeb/HTML/MessageEvent.h>
12
14
#include < LibWeb/HTML/MessagePort.h>
13
15
#include < LibWeb/HTML/Scripting/ClassicScript.h>
14
16
#include < LibWeb/HTML/Scripting/EnvironmentSettingsSnapshot.h>
15
17
#include < LibWeb/HTML/Scripting/Fetching.h>
18
+ #include < LibWeb/HTML/Scripting/TemporaryExecutionContext.h>
16
19
#include < LibWeb/HTML/Scripting/WorkerEnvironmentSettingsObject.h>
20
+ #include < LibWeb/HTML/SharedWorkerGlobalScope.h>
17
21
#include < LibWeb/HTML/WorkerDebugConsoleClient.h>
18
22
#include < LibWeb/HTML/WorkerGlobalScope.h>
19
23
#include < LibWeb/HighResolutionTime/TimeOrigin.h>
20
24
#include < LibWeb/Loader/ResourceLoader.h>
21
- #include < WebWorker/DedicatedWorkerHost .h>
25
+ #include < WebWorker/WorkerHost .h>
22
26
23
27
namespace WebWorker {
24
28
25
- DedicatedWorkerHost::DedicatedWorkerHost (URL::URL url, Web::Bindings::WorkerType type, String name)
29
+ WorkerHost::WorkerHost (URL::URL url, Web::Bindings::WorkerType type, String name)
26
30
: m_url(move(url))
27
31
, m_type(type)
28
32
, m_name(move(name))
29
33
{
30
34
}
31
35
32
- DedicatedWorkerHost ::~DedicatedWorkerHost () = default ;
36
+ WorkerHost ::~WorkerHost () = default ;
33
37
34
38
// https://html.spec.whatwg.org/multipage/workers.html#run-a-worker
35
- // FIXME: Extract out into a helper for both shared and dedicated workers
36
- void DedicatedWorkerHost::run (GC::Ref<Web::Page> page, Web::HTML::TransferDataHolder message_port_data, Web::HTML::SerializedEnvironmentSettingsObject const & outside_settings_snapshot)
39
+ void WorkerHost::run (GC::Ref<Web::Page> page, Web::HTML::TransferDataHolder message_port_data, Web::HTML::SerializedEnvironmentSettingsObject const & outside_settings_snapshot, Web::Bindings::RequestCredentials credentials, bool is_shared)
37
40
{
38
- bool const is_shared = false ;
39
-
40
41
// 3. Let unsafeWorkerCreationTime be the unsafe shared current time.
41
42
auto unsafe_worker_creation_time = Web::HighResolutionTime::unsafe_shared_current_time ();
42
43
43
44
// 7. Let realm execution context be the result of creating a new JavaScript realm given agent and the following customizations:
44
45
auto realm_execution_context = Web::Bindings::create_a_new_javascript_realm (
45
46
Web::Bindings::main_thread_vm (),
46
- [page](JS::Realm& realm) -> JS::Object* {
47
+ [page, is_shared ](JS::Realm& realm) -> JS::Object* {
47
48
// 7a. For the global object, if is shared is true, create a new SharedWorkerGlobalScope object.
48
49
// 7b. Otherwise, create a new DedicatedWorkerGlobalScope object.
49
- // FIXME: Proper support for both SharedWorkerGlobalScope and DedicatedWorkerGlobalScope
50
50
if (is_shared)
51
- TODO ( );
51
+ return Web::Bindings::main_thread_vm (). heap (). allocate <Web::HTML::SharedWorkerGlobalScope>(realm, page );
52
52
return Web::Bindings::main_thread_vm ().heap ().allocate <Web::HTML::DedicatedWorkerGlobalScope>(realm, page);
53
53
},
54
54
nullptr );
@@ -67,10 +67,7 @@ void DedicatedWorkerHost::run(GC::Ref<Web::Page> page, Web::HTML::TransferDataHo
67
67
console_object.console ().set_client (*m_console);
68
68
69
69
// 10. Set worker global scope's name to the value of options's name member.
70
- if (is_shared)
71
- TODO ();
72
- else
73
- static_cast <Web::HTML::DedicatedWorkerGlobalScope&>(*worker_global_scope).set_name (m_name);
70
+ worker_global_scope->set_name (m_name);
74
71
75
72
// 11. Append owner to worker global scope's owner set.
76
73
// FIXME: support for 'owner' set on WorkerGlobalScope
@@ -80,19 +77,26 @@ void DedicatedWorkerHost::run(GC::Ref<Web::Page> page, Web::HTML::TransferDataHo
80
77
81
78
// 12. If is shared is true, then:
82
79
if (is_shared) {
83
- // FIXME: Shared worker support
80
+ auto & shared_global_scope = static_cast <Web::HTML::SharedWorkerGlobalScope&>(*worker_global_scope);
84
81
// 1. Set worker global scope's constructor origin to outside settings's origin.
82
+ shared_global_scope.set_constructor_origin (outside_settings->origin ());
83
+
85
84
// 2. Set worker global scope's constructor url to url.
85
+ shared_global_scope.set_constructor_url (m_url);
86
+
86
87
// 3. Set worker global scope's type to the value of options's type member.
88
+ shared_global_scope.set_type (m_type);
89
+
87
90
// 4. Set worker global scope's credentials to the value of options's credentials member.
91
+ shared_global_scope.set_credentials (Web::Fetch::from_bindings_enum (credentials));
88
92
}
89
93
90
94
// 13. Let destination be "sharedworker" if is shared is true, and "worker" otherwise.
91
95
auto destination = is_shared ? Web::Fetch::Infrastructure::Request::Destination::SharedWorker
92
96
: Web::Fetch::Infrastructure::Request::Destination::Worker;
93
97
94
98
// In both cases, let performFetch be the following perform the fetch hook given request, isTopLevel and processCustomFetchResponse:
95
- auto perform_fetch_function = [inside_settings, worker_global_scope](GC::Ref<Web::Fetch::Infrastructure::Request> request, Web::HTML::TopLevelModule is_top_level, Web::Fetch::Infrastructure::FetchAlgorithms::ProcessResponseConsumeBodyFunction process_custom_fetch_response) -> Web::WebIDL::ExceptionOr<void > {
99
+ auto perform_fetch_function = [inside_settings, worker_global_scope, is_shared ](GC::Ref<Web::Fetch::Infrastructure::Request> request, Web::HTML::TopLevelModule is_top_level, Web::Fetch::Infrastructure::FetchAlgorithms::ProcessResponseConsumeBodyFunction process_custom_fetch_response) -> Web::WebIDL::ExceptionOr<void > {
96
100
auto & realm = inside_settings->realm ();
97
101
auto & vm = realm.vm ();
98
102
@@ -112,7 +116,7 @@ void DedicatedWorkerHost::run(GC::Ref<Web::Page> page, Web::HTML::TransferDataHo
112
116
auto process_custom_fetch_response_function = GC::create_function (vm.heap (), move (process_custom_fetch_response));
113
117
114
118
// 3. Fetch request with processResponseConsumeBody set to the following steps given response response and null, failure, or a byte sequence bodyBytes:
115
- fetch_algorithms_input.process_response_consume_body = [worker_global_scope, process_custom_fetch_response_function, inside_settings](auto response, auto body_bytes) {
119
+ fetch_algorithms_input.process_response_consume_body = [worker_global_scope, process_custom_fetch_response_function, inside_settings, is_shared ](auto response, auto body_bytes) {
116
120
auto & vm = inside_settings->vm ();
117
121
118
122
// 1. Set worker global scope's url to response's url.
@@ -127,6 +131,7 @@ void DedicatedWorkerHost::run(GC::Ref<Web::Page> page, Web::HTML::TransferDataHo
127
131
response = Web::Fetch::Infrastructure::Response::network_error (vm, " Blocked by Content Security Policy" _string);
128
132
}
129
133
134
+ // FIXME: Use worker global scope's policy container's embedder policy
130
135
// FIXME: 4. If worker global scope's embedder policy's value is compatible with cross-origin isolation and is shared is true,
131
136
// then set agent's agent cluster's cross-origin isolation mode to "logical" or "concrete".
132
137
// The one chosen is implementation-defined.
@@ -150,7 +155,7 @@ void DedicatedWorkerHost::run(GC::Ref<Web::Page> page, Web::HTML::TransferDataHo
150
155
};
151
156
auto perform_fetch = Web::HTML::create_perform_the_fetch_hook (inside_settings->heap (), move (perform_fetch_function));
152
157
153
- auto on_complete_function = [inside_settings, worker_global_scope, message_port_data = move (message_port_data), url = m_url](GC::Ptr<Web::HTML::Script> script) mutable {
158
+ auto on_complete_function = [inside_settings, worker_global_scope, message_port_data = move (message_port_data), url = m_url, is_shared ](GC::Ptr<Web::HTML::Script> script) mutable {
154
159
auto & realm = inside_settings->realm ();
155
160
// 1. If script is null or if script's error to rethrow is non-null, then:
156
161
if (!script || !script->error_to_rethrow ().is_null ()) {
@@ -206,10 +211,25 @@ void DedicatedWorkerHost::run(GC::Ref<Web::Page> page, Web::HTML::TransferDataHo
206
211
inside_port->start ();
207
212
}
208
213
209
- // FIXME: 13. If is shared is true, then queue a global task on DOM manipulation task source given worker
214
+ // 13. If is shared is true, then queue a global task on DOM manipulation task source given worker
210
215
// global scope to fire an event named connect at worker global scope, using MessageEvent,
211
216
// with the data attribute initialized to the empty string, the ports attribute initialized
212
217
// to a new frozen array containing inside port, and the source attribute initialized to inside port.
218
+ if (is_shared) {
219
+ Web::HTML::queue_global_task (Web::HTML::Task::Source::DOMManipulation, *worker_global_scope, GC::create_function (realm.heap (), [worker_global_scope, inside_port] {
220
+ auto & realm = worker_global_scope->realm ();
221
+ auto & vm = realm.vm ();
222
+ Web::HTML::TemporaryExecutionContext const context (realm);
223
+
224
+ Web::HTML::MessageEventInit event_init {};
225
+ event_init.data = GC::Ref { vm.empty_string () };
226
+ event_init.ports = { inside_port };
227
+ event_init.source = inside_port;
228
+
229
+ auto message_event = Web::HTML::MessageEvent::create (realm, Web::HTML::EventNames::connect, event_init);
230
+ worker_global_scope->dispatch_event (message_event);
231
+ }));
232
+ }
213
233
214
234
// FIXME: 14. Enable the client message queue of the ServiceWorkerContainer object whose associated service
215
235
// worker client is worker global scope's relevant settings object.
0 commit comments