Serenity Operating System
at master 97 lines 3.4 kB view raw
1/* 2 * Copyright (c) 2022, Ben Abraham <ben.d.abraham@gmail.com> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#pragma once 8 9#include <AK/RefCounted.h> 10#include <AK/URLParser.h> 11#include <LibJS/Interpreter.h> 12#include <LibWeb/Bindings/MainThreadVM.h> 13#include <LibWeb/Forward.h> 14#include <LibWeb/HTML/MessageEvent.h> 15#include <LibWeb/HTML/MessagePort.h> 16#include <LibWeb/HTML/Scripting/ClassicScript.h> 17#include <LibWeb/HTML/Scripting/WindowEnvironmentSettingsObject.h> 18#include <LibWeb/HTML/Scripting/WorkerEnvironmentSettingsObject.h> 19#include <LibWeb/HTML/WorkerDebugConsoleClient.h> 20#include <LibWeb/Loader/ResourceLoader.h> 21 22#define ENUMERATE_WORKER_EVENT_HANDLERS(E) \ 23 E(onmessage, HTML::EventNames::message) \ 24 E(onmessageerror, HTML::EventNames::messageerror) 25 26namespace Web::HTML { 27 28struct WorkerOptions { 29 String type { "classic"_string.release_value_but_fixme_should_propagate_errors() }; 30 String credentials { "same-origin"_string.release_value_but_fixme_should_propagate_errors() }; 31 String name { String {} }; 32}; 33 34// https://html.spec.whatwg.org/multipage/workers.html#dedicated-workers-and-the-worker-interface 35class Worker : public DOM::EventTarget { 36 WEB_PLATFORM_OBJECT(Worker, DOM::EventTarget); 37 38public: 39 static WebIDL::ExceptionOr<JS::NonnullGCPtr<Worker>> create(String const& script_url, WorkerOptions const options, DOM::Document& document); 40 static WebIDL::ExceptionOr<JS::NonnullGCPtr<Worker>> construct_impl(JS::Realm& realm, String const& script_url, WorkerOptions const options) 41 { 42 auto& window = verify_cast<HTML::Window>(realm.global_object()); 43 return Worker::create(script_url, options, window.associated_document()); 44 } 45 46 WebIDL::ExceptionOr<void> terminate(); 47 48 void post_message(JS::Value message, JS::Value transfer); 49 50 virtual ~Worker() = default; 51 52 MessagePort* implicit_message_port() { return m_implicit_port.ptr(); } 53 JS::GCPtr<MessagePort> outside_message_port() { return m_outside_port; } 54 55#undef __ENUMERATE 56#define __ENUMERATE(attribute_name, event_name) \ 57 void set_##attribute_name(WebIDL::CallbackType*); \ 58 WebIDL::CallbackType* attribute_name(); 59 ENUMERATE_WORKER_EVENT_HANDLERS(__ENUMERATE) 60#undef __ENUMERATE 61 62protected: 63 Worker(String const&, const WorkerOptions, DOM::Document&); 64 65private: 66 static HTML::EventLoop& get_vm_event_loop(JS::VM& target_vm) 67 { 68 return static_cast<Bindings::WebEngineCustomData*>(target_vm.custom_data())->event_loop; 69 } 70 71 virtual JS::ThrowCompletionOr<void> initialize(JS::Realm&) override; 72 virtual void visit_edges(Cell::Visitor&) override; 73 74 String m_script_url; 75 WorkerOptions m_options; 76 77 JS::GCPtr<DOM::Document> m_document; 78 79 Bindings::WebEngineCustomData m_custom_data; 80 81 NonnullRefPtr<JS::VM> m_worker_vm; 82 NonnullOwnPtr<JS::Interpreter> m_interpreter; 83 JS::GCPtr<WorkerEnvironmentSettingsObject> m_inner_settings; 84 JS::VM::InterpreterExecutionScope m_interpreter_scope; 85 RefPtr<WorkerDebugConsoleClient> m_console; 86 87 JS::NonnullGCPtr<MessagePort> m_implicit_port; 88 JS::GCPtr<MessagePort> m_outside_port; 89 90 // NOTE: These are inside the worker VM. 91 JS::GCPtr<JS::Realm> m_worker_realm; 92 JS::GCPtr<JS::Object> m_worker_scope; 93 94 void run_a_worker(AK::URL& url, EnvironmentSettingsObject& outside_settings, MessagePort& outside_port, WorkerOptions const& options); 95}; 96 97}