@@ -27,7 +27,7 @@ GC_DEFINE_ALLOCATOR(SharedWorker);
2727// https://html.spec.whatwg.org/multipage/workers.html#dom-sharedworker
2828WebIDL::ExceptionOr<GC::Ref<SharedWorker>> SharedWorker::construct_impl (JS::Realm& realm, TrustedTypes::TrustedScriptURLOrString const & script_url, Variant<String, WorkerOptions>& options_value)
2929{
30- // 1. Let compliantScriptURL be the result of invoking the Get Trusted Type compliant string algorithm with
30+ // 1. Let compliantScriptURL be the result of invoking the get trusted type compliant string algorithm with
3131 // TrustedScriptURL, this's relevant global object, scriptURL, "SharedWorker constructor", and "script".
3232 auto const compliant_script_url = TRY (get_trusted_type_compliant_string (
3333 TrustedTypes::TrustedTypeName::TrustedScriptURL,
@@ -36,8 +36,8 @@ WebIDL::ExceptionOr<GC::Ref<SharedWorker>> SharedWorker::construct_impl(JS::Real
3636 TrustedTypes::InjectionSink::SharedWorker_constructor,
3737 TrustedTypes::Script.to_string ()));
3838
39- // 2. If options is a DOMString, set options to a new WorkerOptions dictionary whose name member is set to the value
40- // of options and whose other members are set to their default values.
39+ // 2. If options is a DOMString, set options to a new WorkerOptions dictionary whose name member is set to the
40+ // value of options and whose other members are set to their default values.
4141 auto options = options_value.visit (
4242 [&](String& options) {
4343 return WorkerOptions { .name = move (options) };
@@ -46,122 +46,125 @@ WebIDL::ExceptionOr<GC::Ref<SharedWorker>> SharedWorker::construct_impl(JS::Real
4646 return move (options);
4747 });
4848
49- // 3. Let outside settings be the current settings object.
49+ // 3. Let outside settings be this's relevant settings object.
50+ // FIXME: We don't have a `this` yet, so use the current principal settings object, as the previous spec did.
5051 auto & outside_settings = current_principal_settings_object ();
5152
52- // 4. Let urlRecord be the result of encoding-parsing a URL given compliantScriptURL, relative to outside settings .
53+ // 4. Let urlRecord be the result of encoding-parsing a URL given compliantScriptURL, relative to outsideSettings .
5354 auto url = outside_settings.encoding_parse_url (compliant_script_url.to_utf8_but_should_be_ported_to_utf16 ());
5455
5556 // 5. If urlRecord is failure, then throw a "SyntaxError" DOMException.
5657 if (!url.has_value ())
5758 return WebIDL::SyntaxError::create (realm, " SharedWorker constructed with invalid URL" _utf16);
5859
59- // 7. Let outside port be a new MessagePort in outside settings's realm.
60- // NOTE: We do this first so that we can store the port as a GC::Ref.
60+ // 6. Let outsidePort be a new MessagePort in outsideSettings's realm.
6161 auto outside_port = MessagePort::create (outside_settings.realm ());
6262
63- // 6. Let worker be a new SharedWorker object.
64- // 8. Assign outside port to the port attribute of worker.
63+ // 10. Let worker be this.
64+ // AD-HOC: We do this first so that we can use `this`.
65+
66+ // 7. Set this's port to outsidePort.
6567 auto worker = realm.create <SharedWorker>(realm, url.release_value (), options, outside_port);
6668
67- // 9 . Let callerIsSecureContext be true if outside settings is a secure context; otherwise, false.
69+ // 8 . Let callerIsSecureContext be true if outside settings is a secure context; otherwise, false.
6870 auto caller_is_secure_context = HTML::is_secure_context (outside_settings);
6971
70- // 10 . Let outside storage key be the result of running obtain a storage key for non-storage purposes given outside settings .
72+ // 9 . Let outsideStorageKey be the result of running obtain a storage key for non-storage purposes given outsideSettings .
7173 auto outside_storage_key = StorageAPI::obtain_a_storage_key_for_non_storage_purposes (outside_settings);
7274
75+ // 10. Let worker be this.
76+ // NB: This is done earlier.
77+
7378 // 11. Enqueue the following steps to the shared worker manager:
7479 // FIXME: "A user agent has an associated shared worker manager which is the result of starting a new parallel queue."
7580 // We just use the singular global event loop for now.
7681 Platform::EventLoopPlugin::the ().deferred_invoke (GC::create_function (realm.heap (), [worker, outside_port, &outside_settings, caller_is_secure_context, outside_storage_key = move (outside_storage_key)]() mutable {
77- // 1. Let worker global scope be null.
82+ // 1. Let workerGlobalScope be null.
7883 GC::Ptr<SharedWorkerGlobalScope> worker_global_scope;
7984
8085 // 2. For each scope in the list of all SharedWorkerGlobalScope objects:
8186 for (auto & scope : all_shared_worker_global_scopes ()) {
82- // 1. Let worker storage key be the result of running obtain a storage key for non-storage purposes given
87+ // 1. Let workerStorageKey be the result of running obtain a storage key for non-storage purposes given
8388 // scope's relevant settings object.
8489 auto worker_storage_key = StorageAPI::obtain_a_storage_key_for_non_storage_purposes (HTML::relevant_settings_object (scope));
8590
8691 // 2. If all of the following are true:
8792 if (
88- // * worker storage key equals outside storage key ;
93+ // * workerStorageKey equals outsideStorageKey ;
8994 worker_storage_key == outside_storage_key
9095
9196 // * scope's closing flag is false;
9297 && !scope->is_closing ()
9398
94- // * scope's constructor url equals urlRecord; and
99+ // * scope's constructor URL equals urlRecord; and
95100 && scope->url () == worker->m_script_url
96101
97- // * scope's name equals the value of options's name member ,
102+ // * scope's name equals options[" name"] ,
98103 && scope->name () == worker->m_options .name )
99104 // then:
100105 {
101- // 1. Set worker global scope to scope.
106+ // 1. Set workerGlobalScope to scope.
102107 worker_global_scope = scope;
103108
104109 // 2. Break.
105110 break ;
106111 }
107112 }
108113
109- // FIXME: 3. If worker global scope is not null, but the user agent has been configured to disallow communication
110- // between the worker represented by the worker global scope and the scripts whose settings object is outside
111- // settings, then set worker global scope to null.
112- // FIXME: 4. If worker global scope is not null, then check if worker global scope's type and credentials match the
113- // options values. If not, queue a task to fire an event named error and abort these steps.
114+ // FIXME: 3. If workerGlobalScope is not null, but the user agent has been configured to disallow communication between the worker represented by the workerGlobalScope and the scripts whose settings object is outsideSettings, then set workerGlobalScope to null.
115+ // FIXME: 4. If workerGlobalScope is not null, and any of the following are true: ...
114116
115- // 5. If worker global scope is not null, then run these subsubsteps :
117+ // 5. If workerGlobalScope is not null:
116118 if (worker_global_scope) {
117- // 1. Let settings object be the relevant settings object for worker global scope .
118- auto & settings_object = HTML:: relevant_settings_object (*worker_global_scope);
119+ // 1. Let insideSettings be workerGlobalScope's relevant settings object.
120+ auto & inside_settings = relevant_settings_object (*worker_global_scope);
119121
120- // 2. Let workerIsSecureContext be true if settings object is a secure context; otherwise, false.
121- auto worker_is_secure_context = HTML:: is_secure_context (settings_object );
122+ // 2. Let workerIsSecureContext be true if insideSettings is a secure context; otherwise, false.
123+ auto worker_is_secure_context = is_secure_context (inside_settings );
122124
123- // 3. If workerIsSecureContext is not callerIsSecureContext, then queue a task to fire an event named error
124- // at worker and abort these steps. [SECURE-CONTEXTS]
125+ // 3. If workerIsSecureContext is not callerIsSecureContext:
125126 if (worker_is_secure_context != caller_is_secure_context) {
126- queue_a_task (HTML::Task::Source::Unspecified, nullptr , nullptr , GC::create_function (worker->heap (), [worker]() {
127- worker->dispatch_event (DOM::Event::create (worker->realm (), HTML::EventNames::error));
127+ // 1. Queue a global task on the DOM manipulation task source given worker's relevant global object to fire an event named error at worker.
128+ queue_global_task (Task::Source::DOMManipulation, relevant_global_object (worker), GC::create_function (worker->heap (), [worker]() {
129+ worker->dispatch_event (DOM::Event::create (worker->realm (), EventNames::error));
128130 }));
129131
132+ // 2. Abort these steps.
130133 return ;
131134 }
132135
133- // FIXME: 4. Associate worker with worker global scope .
136+ // FIXME: 4. Associate worker with workerGlobalScope .
134137
135- // 5. Let inside port be a new MessagePort in settings object 's realm.
136- auto inside_port = HTML::MessagePort::create (settings_object .realm ());
138+ // 5. Let insidePort be a new MessagePort in insideSettings 's realm.
139+ auto inside_port = HTML::MessagePort::create (inside_settings .realm ());
137140
138- // 6. Entangle outside port and inside port .
141+ // 6. Entangle outsidePort and insidePort .
139142 outside_port->entangle_with (inside_port);
140143
141- // 7. Queue a task, using the DOM manipulation task source, to fire an event named connect at worker global
142- // scope , using MessageEvent, with the data attribute initialized to the empty string, the ports attribute
143- // initialized to a new frozen array containing only inside port , and the source attribute initialized to
144- // inside port .
145- queue_a_task (HTML:: Task::Source::DOMManipulation, nullptr , nullptr , GC::create_function (worker->heap (), [worker_global_scope, inside_port]() {
144+ // 7. Queue a global task on the DOM manipulation task source given workerGlobalScope to fire an event
145+ // named connect at workerGlobalScope , using MessageEvent, with the data attribute initialized to the
146+ // empty string, the ports attribute initialized to a new frozen array containing only insidePort , and
147+ // the source attribute initialized to insidePort .
148+ queue_global_task ( Task::Source::DOMManipulation, *worker_global_scope , GC::create_function (worker->heap (), [worker_global_scope, inside_port]() {
146149 auto & realm = worker_global_scope->realm ();
147150
148151 MessageEventInit init;
149152 init.data = JS::PrimitiveString::create (realm.vm (), String {});
150153 init.ports .append (inside_port);
151154 init.source = inside_port;
152155
153- worker_global_scope->dispatch_event (MessageEvent::create (realm, HTML:: EventNames::connect, init));
156+ worker_global_scope->dispatch_event (MessageEvent::create (realm, EventNames::connect, init));
154157 }));
155158
156- // FIXME: 8. Append the relevant owner to add given outside settings to worker global scope's owner set.
159+ // FIXME: 8. Append the relevant owner to add given outsideSettings to workerGlobalScope's owner set.
160+
157161 }
158- // 6. Otherwise, in parallel, run a worker given worker, urlRecord, outside settings, outside port , and options.
162+ // 6. Otherwise, in parallel, run a worker given worker, urlRecord, outsideSettings, outsidePort , and options.
159163 else {
160164 run_a_worker (worker, worker->m_script_url , outside_settings, outside_port, worker->m_options );
161165 }
162166 }));
163167
164- // 12. Return worker.
165168 return worker;
166169}
167170
0 commit comments