11
11
#include < LibWeb/HTML/Scripting/Environments.h>
12
12
#include < LibWeb/HTML/Scripting/TemporaryExecutionContext.h>
13
13
#include < LibWeb/HTML/Worker.h>
14
- #include < LibWeb/HTML/WorkerDebugConsoleClient.h>
15
14
#include < LibWeb/WebIDL/ExceptionOr.h>
16
15
17
16
namespace Web ::HTML {
18
17
19
18
JS_DEFINE_ALLOCATOR (Worker);
20
19
21
20
// https://html.spec.whatwg.org/multipage/workers.html#dedicated-workers-and-the-worker-interface
22
- Worker::Worker (String const & script_url, WorkerOptions const options, DOM::Document& document)
21
+ Worker::Worker (String const & script_url, WorkerOptions const & options, DOM::Document& document)
23
22
: DOM::EventTarget(document.realm())
24
23
, m_script_url(script_url)
25
24
, m_options(options)
@@ -42,7 +41,7 @@ void Worker::visit_edges(Cell::Visitor& visitor)
42
41
}
43
42
44
43
// https://html.spec.whatwg.org/multipage/workers.html#dom-worker
45
- WebIDL::ExceptionOr<JS::NonnullGCPtr<Worker>> Worker::create (String const & script_url, WorkerOptions const options, DOM::Document& document)
44
+ WebIDL::ExceptionOr<JS::NonnullGCPtr<Worker>> Worker::create (String const & script_url, WorkerOptions const & options, DOM::Document& document)
46
45
{
47
46
dbgln_if (WEB_WORKER_DEBUG, " WebWorker: Creating worker with script_url = {}" , script_url);
48
47
@@ -79,6 +78,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Worker>> Worker::create(String const& scrip
79
78
80
79
// 8. Associate the outside port with worker
81
80
worker->m_outside_port = outside_port;
81
+ worker->m_outside_port ->set_worker_event_target (worker);
82
82
83
83
// 9. Run this step in parallel:
84
84
// 1. Run a worker given worker, worker URL, outside settings, outside port, and options.
@@ -89,7 +89,7 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Worker>> Worker::create(String const& scrip
89
89
}
90
90
91
91
// https://html.spec.whatwg.org/multipage/workers.html#run-a-worker
92
- void Worker::run_a_worker (AK::URL& url, EnvironmentSettingsObject& outside_settings, MessagePort& , WorkerOptions const & options)
92
+ void Worker::run_a_worker (AK::URL& url, EnvironmentSettingsObject& outside_settings, JS::GCPtr< MessagePort> port , WorkerOptions const & options)
93
93
{
94
94
// 1. Let is shared be true if worker is a SharedWorker object, and false otherwise.
95
95
// FIXME: SharedWorker support
@@ -110,55 +110,7 @@ void Worker::run_a_worker(AK::URL& url, EnvironmentSettingsObject& outside_setti
110
110
// and is shared. Run the rest of these steps in that agent.
111
111
112
112
// Note: This spawns a new process to act as the 'agent' for the worker.
113
- m_agent = heap ().allocate_without_realm <WorkerAgent>(url, options);
114
-
115
- auto & socket = m_agent->socket ();
116
- // FIXME: Hide this logic in MessagePort
117
- socket.set_notifications_enabled (true );
118
- socket.on_ready_to_read = [this ] {
119
- auto & socket = this ->m_agent ->socket ();
120
- auto & vm = this ->vm ();
121
- auto & realm = this ->realm ();
122
-
123
- auto num_bytes_ready = MUST (socket.pending_bytes ());
124
- switch (m_outside_port_state) {
125
- case PortState::Header: {
126
- if (num_bytes_ready < 8 )
127
- break ;
128
- auto const magic = MUST (socket.read_value <u32 >());
129
- if (magic != 0xDEADBEEF ) {
130
- m_outside_port_state = PortState::Error;
131
- break ;
132
- }
133
- m_outside_port_incoming_message_size = MUST (socket.read_value <u32 >());
134
- num_bytes_ready -= 8 ;
135
- m_outside_port_state = PortState::Data;
136
- }
137
- [[fallthrough]];
138
- case PortState::Data: {
139
- if (num_bytes_ready < m_outside_port_incoming_message_size)
140
- break ;
141
- SerializationRecord rec; // FIXME: Keep in class scope
142
- rec.resize (m_outside_port_incoming_message_size / sizeof (u32 ));
143
-
144
- MUST (socket.read_until_filled (to_bytes (rec.span ())));
145
-
146
- TemporaryExecutionContext cxt (relevant_settings_object (*this ));
147
- VERIFY (&realm == vm.current_realm ());
148
- MessageEventInit event_init {};
149
- event_init.data = MUST (structured_deserialize (vm, rec, realm, {}));
150
- // FIXME: Fill in the rest of the info from MessagePort
151
-
152
- this ->dispatch_event (MessageEvent::create (realm, EventNames::message, event_init));
153
-
154
- m_outside_port_state = PortState::Header;
155
- break ;
156
- }
157
- case PortState::Error:
158
- VERIFY_NOT_REACHED ();
159
- break ;
160
- }
161
- };
113
+ m_agent = heap ().allocate <WorkerAgent>(outside_settings.realm (), url, options, port);
162
114
}
163
115
164
116
// https://html.spec.whatwg.org/multipage/workers.html#dom-worker-terminate
@@ -170,29 +122,15 @@ WebIDL::ExceptionOr<void> Worker::terminate()
170
122
}
171
123
172
124
// https://html.spec.whatwg.org/multipage/workers.html#dom-worker-postmessage
173
- WebIDL::ExceptionOr<void > Worker::post_message (JS::Value message, JS::Value )
125
+ WebIDL::ExceptionOr<void > Worker::post_message (JS::Value message, StructuredSerializeOptions const & options )
174
126
{
175
127
dbgln_if (WEB_WORKER_DEBUG, " WebWorker: Post Message: {}" , message.to_string_without_side_effects ());
176
128
177
- // FIXME: 1. Let targetPort be the port with which this is entangled, if any; otherwise let it be null.
178
- // FIXME: 2. Let options be «[ "transfer" → transfer ]».
179
- // FIXME: 3. Run the message port post message steps providing this, targetPort, message and options .
129
+ // The postMessage(message, transfer) and postMessage(message, options) methods on Worker objects act as if,
130
+ // when invoked, they immediately invoked the respective postMessage(message, transfer) and
131
+ // postMessage(message, options) on the port, with the same arguments, and returned the same return value .
180
132
181
- auto & realm = this ->realm ();
182
- auto & vm = this ->vm ();
183
-
184
- // FIXME: Use the with-transfer variant, which should(?) prepend the magic + size at the front
185
- auto data = TRY (structured_serialize (vm, message));
186
-
187
- Array<u32 , 2 > header = { 0xDEADBEEF , static_cast <u32 >(data.size () * sizeof (u32 )) };
188
-
189
- if (auto const err = m_agent->socket ().write_until_depleted (to_readonly_bytes (header.span ())); err.is_error ())
190
- return WebIDL::DataCloneError::create (realm, TRY_OR_THROW_OOM (vm, String::formatted (" {}" , err.error ())));
191
-
192
- if (auto const err = m_agent->socket ().write_until_depleted (to_readonly_bytes (data.span ())); err.is_error ())
193
- return WebIDL::DataCloneError::create (realm, TRY_OR_THROW_OOM (vm, String::formatted (" {}" , err.error ())));
194
-
195
- return {};
133
+ return m_outside_port->post_message (message, options);
196
134
}
197
135
198
136
#undef __ENUMERATE
0 commit comments