LibWeb: Create separate DedicatedWorkerGlobalScope class

This is how it's supposed to have been from the beginning, we were just
lazy :).
This commit is contained in:
Andrew Kaster 2024-07-09 15:54:22 -06:00 committed by Andreas Kling
parent f99c7ad85d
commit 40a2bb32c3
Notes: sideshowbarker 2024-07-17 02:08:15 +09:00
13 changed files with 179 additions and 43 deletions

View file

@ -428,6 +428,12 @@ static ErrorOr<ExposedTo> parse_exposure_set(IDL::Interface& interface)
return ExposedTo::Window;
if (exposed == "Worker"sv)
return ExposedTo::AllWorkers;
if (exposed == "DedicatedWorker"sv)
return ExposedTo::DedicatedWorker;
if (exposed == "SharedWorker"sv)
return ExposedTo::SharedWorker;
if (exposed == "ServiceWorker"sv)
return ExposedTo::ServiceWorker;
if (exposed == "AudioWorklet"sv)
return ExposedTo::AudioWorklet;

View file

@ -270,6 +270,7 @@ set(SOURCES
HTML/DataTransfer.cpp
HTML/Dates.cpp
HTML/DecodedImageData.cpp
HTML/DedicatedWorkerGlobalScope.cpp
HTML/DocumentState.cpp
HTML/DOMParser.cpp
HTML/DOMStringMap.cpp

View file

@ -0,0 +1,73 @@
/*
* Copyright (c) 2024, Andrew Kaster <akaster@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibWeb/Bindings/DedicatedWorkerExposedInterfaces.h>
#include <LibWeb/Bindings/DedicatedWorkerGlobalScopePrototype.h>
#include <LibWeb/Bindings/Intrinsics.h>
#include <LibWeb/HTML/DedicatedWorkerGlobalScope.h>
#include <LibWeb/HTML/EventHandler.h>
#include <LibWeb/HTML/EventNames.h>
#include <LibWeb/HTML/MessageEvent.h>
namespace Web::HTML {
JS_DEFINE_ALLOCATOR(DedicatedWorkerGlobalScope);
DedicatedWorkerGlobalScope::DedicatedWorkerGlobalScope(JS::Realm& realm, JS::NonnullGCPtr<Web::Page> page)
: WorkerGlobalScope(realm, page)
{
m_legacy_platform_object_flags = LegacyPlatformObjectFlags { .has_global_interface_extended_attribute = true };
}
DedicatedWorkerGlobalScope::~DedicatedWorkerGlobalScope() = default;
void DedicatedWorkerGlobalScope::initialize_web_interfaces_impl()
{
auto& realm = this->realm();
add_dedicated_worker_exposed_interfaces(*this);
WEB_SET_PROTOTYPE_FOR_INTERFACE(DedicatedWorkerGlobalScope);
DedicatedWorkerGlobalScopeGlobalMixin::initialize(realm, *this);
Base::initialize_web_interfaces_impl();
}
// https://html.spec.whatwg.org/multipage/workers.html#dom-dedicatedworkerglobalscope-close
void DedicatedWorkerGlobalScope::close()
{
// The close() method steps are to close a worker given this.
close_a_worker();
}
void DedicatedWorkerGlobalScope::finalize()
{
Base::finalize();
WindowOrWorkerGlobalScopeMixin::finalize();
}
WebIDL::ExceptionOr<void> DedicatedWorkerGlobalScope::post_message(JS::Value message, StructuredSerializeOptions const& options)
{
// The postMessage(message, transfer) and postMessage(message, options) methods on DedicatedWorkerGlobalScope objects act as if,
// when invoked, it immediately invoked the respective postMessage(message, transfer) and postMessage(message, options)
// on the port, with the same arguments, and returned the same return value.
return m_internal_port->post_message(message, options);
}
#undef __ENUMERATE
#define __ENUMERATE(attribute_name, event_name) \
void DedicatedWorkerGlobalScope::set_##attribute_name(WebIDL::CallbackType* value) \
{ \
set_event_handler_attribute(event_name, move(value)); \
} \
WebIDL::CallbackType* DedicatedWorkerGlobalScope::attribute_name() \
{ \
return event_handler_attribute(event_name); \
}
ENUMERATE_DEDICATED_WORKER_GLOBAL_SCOPE_EVENT_HANDLERS(__ENUMERATE)
#undef __ENUMERATE
}

View file

@ -0,0 +1,52 @@
/*
* Copyright (c) 2024, Andrew Kaster <akaster@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <LibWeb/Bindings/DedicatedWorkerGlobalScopeGlobalMixin.h>
#include <LibWeb/Bindings/WorkerGlobalScopePrototype.h>
#include <LibWeb/HTML/WorkerGlobalScope.h>
#define ENUMERATE_DEDICATED_WORKER_GLOBAL_SCOPE_EVENT_HANDLERS(E) \
E(onmessage, HTML::EventNames::message) \
E(onmessageerror, HTML::EventNames::messageerror)
namespace Web::HTML {
class DedicatedWorkerGlobalScope
: public WorkerGlobalScope
, public Bindings::DedicatedWorkerGlobalScopeGlobalMixin {
WEB_PLATFORM_OBJECT(DedicatedWorkerGlobalScope, WorkerGlobalScope);
JS_DECLARE_ALLOCATOR(DedicatedWorkerGlobalScope);
public:
virtual ~DedicatedWorkerGlobalScope() override;
WebIDL::ExceptionOr<void> post_message(JS::Value message, StructuredSerializeOptions const&);
void set_name(String name) { m_name = move(name); }
String name() const { return m_name; }
void close();
#undef __ENUMERATE
#define __ENUMERATE(attribute_name, event_name) \
void set_##attribute_name(WebIDL::CallbackType*); \
WebIDL::CallbackType* attribute_name();
ENUMERATE_DEDICATED_WORKER_GLOBAL_SCOPE_EVENT_HANDLERS(__ENUMERATE)
#undef __ENUMERATE
virtual void finalize() override;
private:
DedicatedWorkerGlobalScope(JS::Realm&, JS::NonnullGCPtr<Web::Page>);
virtual void initialize_web_interfaces_impl() override;
String m_name;
};
}

View file

@ -0,0 +1,15 @@
#import <HTML/WorkerGlobalScope.idl>
// https://html.spec.whatwg.org/multipage/workers.html#dedicatedworkerglobalscope
[Global=(Worker,DedicatedWorker),Exposed=DedicatedWorker]
interface DedicatedWorkerGlobalScope : WorkerGlobalScope {
[Replaceable] readonly attribute DOMString name;
// FIXME: IDL overload issue here
// FIXME: undefined postMessage(any message, sequence<object> transfer);
undefined postMessage(any message, optional StructuredSerializeOptions options = {});
undefined close();
attribute EventHandler onmessage;
attribute EventHandler onmessageerror;
};

View file

@ -5,7 +5,6 @@
*/
#include <AK/Vector.h>
#include <LibWeb/Bindings/DedicatedWorkerExposedInterfaces.h>
#include <LibWeb/Bindings/Intrinsics.h>
#include <LibWeb/Bindings/WorkerGlobalScopePrototype.h>
#include <LibWeb/CSS/FontFaceSet.h>
@ -31,16 +30,11 @@ WorkerGlobalScope::WorkerGlobalScope(JS::Realm& realm, JS::NonnullGCPtr<Web::Pag
WorkerGlobalScope::~WorkerGlobalScope() = default;
void WorkerGlobalScope::initialize_web_interfaces(Badge<WorkerEnvironmentSettingsObject>)
void WorkerGlobalScope::initialize_web_interfaces_impl()
{
auto& realm = this->realm();
Base::initialize(realm);
// FIXME: Handle shared worker
add_dedicated_worker_exposed_interfaces(*this);
WEB_SET_PROTOTYPE_FOR_INTERFACE(WorkerGlobalScope);
WindowOrWorkerGlobalScopeMixin::initialize(realm);
m_navigator = WorkerNavigator::create(*this);
@ -71,7 +65,7 @@ void WorkerGlobalScope::set_internal_port(JS::NonnullGCPtr<MessagePort> port)
}
// https://html.spec.whatwg.org/multipage/workers.html#close-a-worker
void WorkerGlobalScope::close()
void WorkerGlobalScope::close_a_worker()
{
// 1. Discard any tasks that have been added to workerGlobal's relevant agent's event loop's task queues.
relevant_settings_object(*this).responsible_event_loop().task_queue().remove_tasks_matching([](HTML::Task const&) {
@ -147,11 +141,6 @@ JS::NonnullGCPtr<WorkerNavigator> WorkerGlobalScope::navigator() const
return *m_navigator;
}
WebIDL::ExceptionOr<void> WorkerGlobalScope::post_message(JS::Value message, StructuredSerializeOptions const& options)
{
return m_internal_port->post_message(message, options);
}
#undef __ENUMERATE
#define __ENUMERATE(attribute_name, event_name) \
void WorkerGlobalScope::set_##attribute_name(WebIDL::CallbackType* value) \

View file

@ -18,16 +18,13 @@
#include <LibWeb/HTML/WorkerNavigator.h>
#include <LibWeb/WebIDL/ExceptionOr.h>
// FIXME: message/messageerror belong on subclasses only
#define ENUMERATE_WORKER_GLOBAL_SCOPE_EVENT_HANDLERS(E) \
E(onerror, HTML::EventNames::error) \
E(onlanguagechange, HTML::EventNames::languagechange) \
E(ononline, HTML::EventNames::online) \
E(onoffline, HTML::EventNames::offline) \
E(onrejectionhandled, HTML::EventNames::rejectionhandled) \
E(onunhandledrejection, HTML::EventNames::unhandledrejection) \
E(onmessage, HTML::EventNames::message) \
E(onmessageerror, HTML::EventNames::messageerror)
#define ENUMERATE_WORKER_GLOBAL_SCOPE_EVENT_HANDLERS(E) \
E(onerror, HTML::EventNames::error) \
E(onlanguagechange, HTML::EventNames::languagechange) \
E(ononline, HTML::EventNames::online) \
E(onoffline, HTML::EventNames::offline) \
E(onrejectionhandled, HTML::EventNames::rejectionhandled) \
E(onunhandledrejection, HTML::EventNames::unhandledrejection)
namespace Web::HTML {
@ -76,8 +73,6 @@ public:
ENUMERATE_WORKER_GLOBAL_SCOPE_EVENT_HANDLERS(__ENUMERATE)
#undef __ENUMERATE
WebIDL::ExceptionOr<void> post_message(JS::Value message, StructuredSerializeOptions const&);
JS::NonnullGCPtr<CSS::FontFaceSet> fonts();
// Non-IDL public methods
@ -91,7 +86,7 @@ public:
void set_internal_port(JS::NonnullGCPtr<MessagePort> port);
void initialize_web_interfaces(Badge<WorkerEnvironmentSettingsObject>);
void initialize_web_interfaces(Badge<WorkerEnvironmentSettingsObject>) { initialize_web_interfaces_impl(); }
Web::Page* page() { return m_page.ptr(); }
@ -99,20 +94,24 @@ public:
bool is_closing() const { return m_closing; }
void close();
protected:
explicit WorkerGlobalScope(JS::Realm&, JS::NonnullGCPtr<Web::Page>);
virtual void initialize_web_interfaces_impl();
void close_a_worker();
virtual void finalize() override;
JS::GCPtr<MessagePort> m_internal_port;
private:
virtual void visit_edges(Cell::Visitor&) override;
virtual void finalize() override;
JS::GCPtr<WorkerLocation> m_location;
JS::GCPtr<WorkerNavigator> m_navigator;
JS::NonnullGCPtr<Web::Page> m_page;
JS::GCPtr<MessagePort> m_internal_port;
// FIXME: Add all these internal slots

View file

@ -20,12 +20,6 @@ interface WorkerGlobalScope : EventTarget {
attribute EventHandler ononline;
attribute EventHandler onrejectionhandled;
attribute EventHandler onunhandledrejection;
// FIXME: IDL overload issue here
// FIXME: undefined postMessage(any message, sequence<object> transfer);
undefined postMessage(any message, optional StructuredSerializeOptions options = {});
attribute EventHandler onmessage;
attribute EventHandler onmessageerror;
};
WorkerGlobalScope includes WindowOrWorkerGlobalScope;

View file

@ -101,6 +101,7 @@ libweb_js_bindings(HTML/CloseEvent)
libweb_js_bindings(HTML/CloseWatcher)
libweb_js_bindings(HTML/CustomElements/CustomElementRegistry)
libweb_js_bindings(HTML/DataTransfer)
libweb_js_bindings(HTML/DedicatedWorkerGlobalScope GLOBAL)
libweb_js_bindings(HTML/DOMParser)
libweb_js_bindings(HTML/DOMStringMap)
libweb_js_bindings(HTML/DragEvent)

View file

@ -63,9 +63,9 @@ Web::Page const& ConnectionFromClient::page() const
return m_page_host->page();
}
void ConnectionFromClient::start_dedicated_worker(URL::URL const& url, String const& type, String const&, String const&, Web::HTML::TransferDataHolder const& implicit_port, Web::HTML::SerializedEnvironmentSettingsObject const& outside_settings)
void ConnectionFromClient::start_dedicated_worker(URL::URL const& url, String const& type, String const&, String const& name, Web::HTML::TransferDataHolder const& implicit_port, Web::HTML::SerializedEnvironmentSettingsObject const& outside_settings)
{
m_worker_host = make_ref_counted<DedicatedWorkerHost>(url, type);
m_worker_host = make_ref_counted<DedicatedWorkerHost>(url, type, name);
// FIXME: Yikes, const_cast to move? Feels like a LibIPC bug.
// We should be able to move non-copyable types from a Message type.
m_worker_host->run(page(), move(const_cast<Web::HTML::TransferDataHolder&>(implicit_port)), outside_settings);

View file

@ -41,7 +41,7 @@ private:
Web::Page& page();
Web::Page const& page() const;
virtual void start_dedicated_worker(URL::URL const& url, String const&, String const&, String const&, Web::HTML::TransferDataHolder const&, Web::HTML::SerializedEnvironmentSettingsObject const&) override;
virtual void start_dedicated_worker(URL::URL const& url, String const& type, String const&, String const& name, Web::HTML::TransferDataHolder const&, Web::HTML::SerializedEnvironmentSettingsObject const&) override;
virtual void handle_file_return(i32 error, Optional<IPC::File> const& file, i32 request_id) override;
JS::Handle<PageHost> m_page_host;

View file

@ -8,6 +8,7 @@
#include <LibJS/Runtime/ConsoleObject.h>
#include <LibWeb/Fetch/Fetching/Fetching.h>
#include <LibWeb/Fetch/Infrastructure/FetchAlgorithms.h>
#include <LibWeb/HTML/DedicatedWorkerGlobalScope.h>
#include <LibWeb/HTML/Scripting/ClassicScript.h>
#include <LibWeb/HTML/Scripting/EnvironmentSettingsSnapshot.h>
#include <LibWeb/HTML/Scripting/Fetching.h>
@ -20,9 +21,10 @@
namespace WebWorker {
DedicatedWorkerHost::DedicatedWorkerHost(URL::URL url, String type)
DedicatedWorkerHost::DedicatedWorkerHost(URL::URL url, String type, String name)
: m_url(move(url))
, m_type(move(type))
, m_name(move(name))
{
}
@ -46,7 +48,7 @@ void DedicatedWorkerHost::run(JS::NonnullGCPtr<Web::Page> page, Web::HTML::Trans
// FIXME: Proper support for both SharedWorkerGlobalScope and DedicatedWorkerGlobalScope
if (is_shared)
TODO();
return Web::Bindings::main_thread_vm().heap().allocate_without_realm<Web::HTML::WorkerGlobalScope>(realm, page);
return Web::Bindings::main_thread_vm().heap().allocate_without_realm<Web::HTML::DedicatedWorkerGlobalScope>(realm, page);
},
nullptr);
@ -64,7 +66,10 @@ void DedicatedWorkerHost::run(JS::NonnullGCPtr<Web::Page> page, Web::HTML::Trans
console_object.console().set_client(*m_console);
// 10. Set worker global scope's name to the value of options's name member.
// FIXME: name property requires the SharedWorkerGlobalScope or DedicatedWorkerGlobalScope child class to be used
if (is_shared)
TODO();
else
static_cast<Web::HTML::DedicatedWorkerGlobalScope&>(*worker_global_scope).set_name(m_name);
// 11. Append owner to worker global scope's owner set.
// FIXME: support for 'owner' set on WorkerGlobalScope

View file

@ -17,7 +17,7 @@ namespace WebWorker {
class DedicatedWorkerHost : public RefCounted<DedicatedWorkerHost> {
public:
explicit DedicatedWorkerHost(URL::URL url, String type);
explicit DedicatedWorkerHost(URL::URL url, String type, String name);
~DedicatedWorkerHost();
void run(JS::NonnullGCPtr<Web::Page>, Web::HTML::TransferDataHolder message_port_data, Web::HTML::SerializedEnvironmentSettingsObject const&);
@ -27,6 +27,7 @@ private:
URL::URL m_url;
String m_type;
String m_name;
};
}