2023-11-08 11:47:41 -07:00
/*
* Copyright ( c ) 2023 , Andrew Kaster < akaster @ serenityos . org >
*
* SPDX - License - Identifier : BSD - 2 - Clause
*/
2024-10-26 21:02:28 +13:00
# include <LibWeb/Bindings/PrincipalHostDefined.h>
2026-02-11 07:33:58 +01:00
# include <LibWeb/DOM/Document.h>
2026-03-07 21:08:19 +01:00
# include <LibWeb/DOM/Event.h>
# include <LibWeb/DOM/EventTarget.h>
# include <LibWeb/HTML/EventLoop/EventLoop.h>
# include <LibWeb/HTML/EventNames.h>
2024-10-17 08:46:48 -04:00
# include <LibWeb/HTML/MessagePort.h>
2026-03-07 21:08:19 +01:00
# include <LibWeb/HTML/Scripting/Environments.h>
2026-01-04 22:20:18 -08:00
# include <LibWeb/HTML/Window.h>
2026-03-07 21:08:19 +01:00
# include <LibWeb/HTML/Worker.h>
2025-04-24 14:08:39 +12:00
# include <LibWeb/HTML/WorkerAgentParent.h>
2024-01-06 13:13:59 -07:00
# include <LibWeb/Page/Page.h>
2023-11-08 11:47:41 -07:00
# include <LibWeb/Worker/WebWorkerClient.h>
namespace Web : : HTML {
2025-04-24 14:08:39 +12:00
GC_DEFINE_ALLOCATOR ( WorkerAgentParent ) ;
2023-11-19 19:47:52 +01:00
2026-03-07 21:08:19 +01:00
WorkerAgentParent : : WorkerAgentParent ( URL : : URL url , WorkerOptions const & options , GC : : Ptr < MessagePort > outside_port , GC : : Ref < EnvironmentSettingsObject > outside_settings , GC : : Ref < DOM : : EventTarget > worker_event_target , Bindings : : AgentType agent_type )
2023-11-08 11:47:41 -07:00
: m_worker_options ( options )
2025-05-18 14:10:01 -06:00
, m_agent_type ( agent_type )
2023-11-08 11:47:41 -07:00
, m_url ( move ( url ) )
2023-12-20 13:47:01 -07:00
, m_outside_port ( outside_port )
2024-03-05 09:42:10 -07:00
, m_outside_settings ( outside_settings )
2026-03-07 21:08:19 +01:00
, m_worker_event_target ( worker_event_target )
2023-11-08 11:47:41 -07:00
{
2023-12-20 13:47:01 -07:00
}
2025-04-24 14:08:39 +12:00
void WorkerAgentParent : : initialize ( JS : : Realm & realm )
2023-12-20 13:47:01 -07:00
{
Base : : initialize ( realm ) ;
m_message_port = MessagePort : : create ( realm ) ;
m_message_port - > entangle_with ( * m_outside_port ) ;
2025-07-17 09:51:04 -04:00
TransferDataEncoder data_holder ;
2023-12-20 13:47:01 -07:00
MUST ( m_message_port - > transfer_steps ( data_holder ) ) ;
2023-11-22 09:57:22 -07:00
2025-06-07 23:57:17 +02:00
// FIXME: Specification says this supposed to happen in step 11 of onComplete handler defined in https://html.spec.whatwg.org/multipage/workers.html#run-a-worker
// but that would require introducing a new IPC message type to communicate this from WebWorker to WebContent process,
// so let's do it here for now.
m_outside_port - > start ( ) ;
2024-01-06 13:13:59 -07:00
// NOTE: This blocking IPC call may launch another process.
// If spinning the event loop for this can cause other javascript to execute, we're in trouble.
2026-03-12 14:17:41 +01:00
auto response = Bindings : : principal_host_defined_page ( realm ) . client ( ) . request_worker_agent ( m_agent_type ) ;
2024-01-06 13:13:59 -07:00
2026-03-12 14:17:41 +01:00
auto transport = MUST ( response . worker_handle . create_transport ( ) ) ;
2024-10-22 15:47:33 -06:00
m_worker_ipc = make_ref_counted < WebWorkerClient > ( move ( transport ) ) ;
2025-09-07 15:32:43 +01:00
setup_worker_ipc_callbacks ( realm ) ;
2024-01-06 13:13:59 -07:00
2026-03-12 14:17:41 +01:00
m_worker_ipc - > async_connect_to_request_server ( move ( response . request_server_handle ) ) ;
m_worker_ipc - > async_connect_to_image_decoder ( move ( response . image_decoder_handle ) ) ;
2026-01-04 22:20:18 -08:00
auto serialized_outside_settings = m_outside_settings - > serialize ( ) ;
2026-02-21 19:11:48 +01:00
m_worker_ipc - > async_start_worker ( m_url , m_worker_options . type , m_worker_options . credentials , m_worker_options . name , move ( data_holder ) , serialized_outside_settings , m_agent_type ) ;
2023-12-20 13:47:01 -07:00
}
2023-11-08 11:47:41 -07:00
2025-09-07 15:32:43 +01:00
void WorkerAgentParent : : setup_worker_ipc_callbacks ( JS : : Realm & realm )
{
// NOTE: As long as WorkerAgentParent is alive, realm and m_worker_ipc will be alive.
2026-02-07 11:13:47 -05:00
m_worker_ipc - > on_request_cookie = [ realm = GC : : RawRef { realm } ] ( URL : : URL const & url , HTTP : : Cookie : : Source source ) {
2025-09-07 15:32:43 +01:00
auto & client = Bindings : : principal_host_defined_page ( realm ) . client ( ) ;
return client . page_did_request_cookie ( url , source ) ;
} ;
2026-03-12 14:17:41 +01:00
m_worker_ipc - > on_request_worker_agent = [ realm = GC : : RawRef { realm } ] ( Web : : Bindings : : AgentType worker_type ) - > Messages : : WebWorkerClient : : RequestWorkerAgentResponse {
2026-01-06 13:33:34 -08:00
auto & client = Bindings : : principal_host_defined_page ( realm ) . client ( ) ;
2026-03-12 14:17:41 +01:00
auto response = client . request_worker_agent ( worker_type ) ;
return { move ( response . worker_handle ) , move ( response . request_server_handle ) , move ( response . image_decoder_handle ) } ;
2026-01-06 13:33:34 -08:00
} ;
2026-03-07 21:08:19 +01:00
m_worker_ipc - > on_worker_script_load_failure = [ self = GC : : Weak { * this } ] ( ) {
if ( ! self )
return ;
auto & outside_settings = * self - > m_outside_settings ;
auto & event_target = * self - > m_worker_event_target ;
// See: https://html.spec.whatwg.org/multipage/workers.html#worker-processing-model, onComplete handler for fetching script.
// 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.
queue_global_task ( Task : : Source : : DOMManipulation , outside_settings . global_object ( ) , GC : : create_function ( outside_settings . heap ( ) , [ & event_target , & outside_settings ] ( ) {
event_target . dispatch_event ( DOM : : Event : : create ( outside_settings . realm ( ) , EventNames : : error ) ) ;
} ) ) ;
} ;
2025-09-07 15:32:43 +01:00
}
2025-04-24 14:08:39 +12:00
void WorkerAgentParent : : visit_edges ( Cell : : Visitor & visitor )
2023-12-20 13:47:01 -07:00
{
Base : : visit_edges ( visitor ) ;
visitor . visit ( m_message_port ) ;
visitor . visit ( m_outside_port ) ;
2024-03-05 09:42:10 -07:00
visitor . visit ( m_outside_settings ) ;
2026-03-07 21:08:19 +01:00
visitor . visit ( m_worker_event_target ) ;
2023-11-08 11:47:41 -07:00
}
}