diff options
author | Andreas Kling <kling@serenityos.org> | 2022-09-05 12:19:41 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-09-06 00:27:09 +0200 |
commit | e97cc671eaff2830fc1481f932378727c4136f55 (patch) | |
tree | 8d399cfd4026ec02f681b9323f548829427d1da0 /Userland | |
parent | ddc018fb757e59f09adac88fc6f98e2c6425c4af (diff) | |
download | serenity-e97cc671eaff2830fc1481f932378727c4136f55.zip |
LibWeb: Give web workers a (totally hacky) Window object
This is *not* according to spec, however we currently store prototypes
and constructors on Window, so the only way for objects in a worker
context to become fully formed is to make a Window.
Long-term we should clean this up and remove the worker window object,
but for now it allows workers to exist without asserting.
Diffstat (limited to 'Userland')
-rw-r--r-- | Userland/Libraries/LibWeb/HTML/Scripting/WorkerEnvironmentSettingsObject.h | 21 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/HTML/Worker.cpp | 15 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/HTML/Worker.h | 9 |
3 files changed, 25 insertions, 20 deletions
diff --git a/Userland/Libraries/LibWeb/HTML/Scripting/WorkerEnvironmentSettingsObject.h b/Userland/Libraries/LibWeb/HTML/Scripting/WorkerEnvironmentSettingsObject.h index 0a39f64eaf..8631a88cd8 100644 --- a/Userland/Libraries/LibWeb/HTML/Scripting/WorkerEnvironmentSettingsObject.h +++ b/Userland/Libraries/LibWeb/HTML/Scripting/WorkerEnvironmentSettingsObject.h @@ -12,23 +12,20 @@ namespace Web::HTML { -// FIXME: This is a bit ugly, this implementation is basically a 1:1 copy of what is in ESO -// just modified to use DOM::Document instead of HTML::Window since workers have no window class WorkerEnvironmentSettingsObject final : public EnvironmentSettingsObject , public Weakable<WorkerEnvironmentSettingsObject> { public: - WorkerEnvironmentSettingsObject(DOM::Document& document, NonnullOwnPtr<JS::ExecutionContext> execution_context) + WorkerEnvironmentSettingsObject(NonnullOwnPtr<JS::ExecutionContext> execution_context) : EnvironmentSettingsObject(move(execution_context)) - , m_document(JS::make_handle(document)) { } - static WeakPtr<WorkerEnvironmentSettingsObject> setup(DOM::Document& document, NonnullOwnPtr<JS::ExecutionContext> execution_context /* FIXME: null or an environment reservedEnvironment, a URL topLevelCreationURL, and an origin topLevelOrigin */) + static WeakPtr<WorkerEnvironmentSettingsObject> setup(NonnullOwnPtr<JS::ExecutionContext> execution_context /* FIXME: null or an environment reservedEnvironment, a URL topLevelCreationURL, and an origin topLevelOrigin */) { auto* realm = execution_context->realm; VERIFY(realm); - auto settings_object = adopt_own(*new WorkerEnvironmentSettingsObject(document, move(execution_context))); + auto settings_object = adopt_own(*new WorkerEnvironmentSettingsObject(move(execution_context))); settings_object->target_browsing_context = nullptr; realm->set_host_defined(move(settings_object)); @@ -37,14 +34,16 @@ public: virtual ~WorkerEnvironmentSettingsObject() override = default; - JS::GCPtr<DOM::Document> responsible_document() override { return m_document.ptr(); } - String api_url_character_encoding() override { return m_document->encoding_or_default(); } - AK::URL api_base_url() override { return m_document->url(); } - Origin origin() override { return m_document->origin(); } + JS::GCPtr<DOM::Document> responsible_document() override { return nullptr; } + String api_url_character_encoding() override { return m_api_url_character_encoding; } + AK::URL api_base_url() override { return m_url; } + Origin origin() override { return m_origin; } CanUseCrossOriginIsolatedAPIs cross_origin_isolated_capability() override { TODO(); } private: - JS::Handle<DOM::Document> m_document; + String m_api_url_character_encoding; + AK::URL m_url; + HTML::Origin m_origin; }; } diff --git a/Userland/Libraries/LibWeb/HTML/Worker.cpp b/Userland/Libraries/LibWeb/HTML/Worker.cpp index 74abb3d1ea..aab54be5d5 100644 --- a/Userland/Libraries/LibWeb/HTML/Worker.cpp +++ b/Userland/Libraries/LibWeb/HTML/Worker.cpp @@ -34,8 +34,6 @@ void Worker::visit_edges(Cell::Visitor& visitor) { Base::visit_edges(visitor); visitor.visit(m_document.ptr()); - visitor.visit(m_worker_realm.ptr()); - visitor.visit(m_worker_scope.ptr()); visitor.visit(m_implicit_port.ptr()); visitor.visit(m_outside_port.ptr()); } @@ -129,6 +127,11 @@ void Worker::run_a_worker(AK::URL& url, EnvironmentSettingsObject& outside_setti auto& console_object = *realm_execution_context->realm->intrinsics().console_object(); m_worker_realm = realm_execution_context->realm; + + // FIXME: Remove this once we don't need a hack Window (for prototypes and constructors) in workers anymore. + m_worker_window = HTML::Window::create(*m_worker_realm); + m_worker_realm->set_global_object(m_worker_scope, nullptr); + m_console = adopt_ref(*new WorkerDebugConsoleClient(console_object.console())); console_object.console().set_client(*m_console); @@ -159,8 +162,7 @@ void Worker::run_a_worker(AK::URL& url, EnvironmentSettingsObject& outside_setti MessageEventInit event_init {}; event_init.data = message; event_init.origin = "<origin>"; - // FIXME: The cast here is totally bogus, since workers don't have a Window object.. - dispatch_event(*MessageEvent::create(verify_cast<HTML::Window>(*m_worker_scope), HTML::EventNames::message, event_init)); + dispatch_event(*MessageEvent::create(*m_worker_window, HTML::EventNames::message, event_init)); })); return JS::js_undefined(); @@ -172,7 +174,7 @@ void Worker::run_a_worker(AK::URL& url, EnvironmentSettingsObject& outside_setti // 9. Set up a worker environment settings object with realm execution context, // outside settings, and unsafeWorkerCreationTime, and let inside settings be the result. - m_inner_settings = WorkerEnvironmentSettingsObject::setup(*m_document, move(realm_execution_context)); + m_inner_settings = WorkerEnvironmentSettingsObject::setup(move(realm_execution_context)); // 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 @@ -257,8 +259,7 @@ void Worker::run_a_worker(AK::URL& url, EnvironmentSettingsObject& outside_setti // FIXME: Global scope association // 16. Let inside port be a new MessagePort object in inside settings's Realm. - // FIXME: The cast here is totally bogus, since workers don't have a Window object.. - auto inside_port = MessagePort::create(verify_cast<HTML::Window>(*m_worker_scope)); + auto inside_port = MessagePort::create(*m_worker_window); // 17. Associate inside port with worker global scope. // FIXME: Global scope association diff --git a/Userland/Libraries/LibWeb/HTML/Worker.h b/Userland/Libraries/LibWeb/HTML/Worker.h index 833796d31c..5f7b892841 100644 --- a/Userland/Libraries/LibWeb/HTML/Worker.h +++ b/Userland/Libraries/LibWeb/HTML/Worker.h @@ -80,13 +80,18 @@ private: NonnullOwnPtr<JS::Interpreter> m_interpreter; WeakPtr<WorkerEnvironmentSettingsObject> m_inner_settings; JS::VM::InterpreterExecutionScope m_interpreter_scope; - JS::GCPtr<JS::Realm> m_worker_realm; RefPtr<WorkerDebugConsoleClient> m_console; - JS::GCPtr<JS::Object> m_worker_scope; JS::NonnullGCPtr<MessagePort> m_implicit_port; JS::GCPtr<MessagePort> m_outside_port; + // NOTE: These are inside the worker VM. + JS::GCPtr<JS::Realm> m_worker_realm; + JS::GCPtr<JS::Object> m_worker_scope; + // FIXME: This is a mega-hack but necessary because HTML::Window holds all the prototypes and constructors. + // There should be *no* Window object in a Worker context. + JS::GCPtr<HTML::Window> m_worker_window; + void run_a_worker(AK::URL& url, EnvironmentSettingsObject& outside_settings, MessagePort& outside_port, WorkerOptions const options); }; |