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
commit 40a2bb32c3
Notes: sideshowbarker 2024-07-17 02:08:15 +09:00
13 changed files with 179 additions and 43 deletions

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;