浏览代码

LibWeb: Wire up UniversalGlobalScopeMixin to ShadowRealmGlobalScope

Shannon Booth 8 月之前
父节点
当前提交
457cdd0cc3

+ 1 - 0
Tests/LibWeb/Text/expected/HTML/shadow-realm-btoa.txt

@@ -0,0 +1 @@
+Shadow realm evaluation returned: SGVsbG8sIHdvcmxkIQ==

+ 1 - 0
Tests/LibWeb/Text/expected/HTML/shadow-realm-url.txt

@@ -0,0 +1 @@
+Shadow realm evaluation returned: example.com

+ 8 - 0
Tests/LibWeb/Text/input/HTML/shadow-realm-btoa.html

@@ -0,0 +1,8 @@
+<script src="../include.js"></script>
+<script>
+    test(() => {
+        const realm = new ShadowRealm();
+        const result = realm.evaluate(`() => self.btoa('Hello, world!')`)();
+        println(`Shadow realm evaluation returned: ${result}`);
+    });
+</script>

+ 8 - 0
Tests/LibWeb/Text/input/HTML/shadow-realm-url.html

@@ -0,0 +1,8 @@
+<script src="../include.js"></script>
+<script>
+    test(() => {
+        const realm = new ShadowRealm();
+        const result = realm.evaluate(`() => new URL('https://example.com/path?name=value').hostname`)();
+        println(`Shadow realm evaluation returned: ${result}`);
+    });
+</script>

+ 1 - 0
Userland/Libraries/LibWeb/CMakeLists.txt

@@ -483,6 +483,7 @@ set(SOURCES
     HTML/TokenizedFeatures.cpp
     HTML/TrackEvent.cpp
     HTML/TraversableNavigable.cpp
+    HTML/UniversalGlobalScope.cpp
     HTML/UserActivation.cpp
     HTML/VideoTrack.cpp
     HTML/VideoTrackList.cpp

+ 5 - 3
Userland/Libraries/LibWeb/HTML/ShadowRealmGlobalScope.cpp

@@ -26,14 +26,16 @@ JS::NonnullGCPtr<ShadowRealmGlobalScope> ShadowRealmGlobalScope::create(JS::Real
 
 void ShadowRealmGlobalScope::initialize(JS::Realm&)
 {
-    // FIXME: This does not work as we do not have any intrinsics in the [HostDefined] of a shadow realm. Figure out how this _should_ work.
-    // Base::initialize(realm);
-    // WEB_SET_PROTOTYPE_FOR_INTERFACE(ShadowRealmGlobalScope);
 }
 
 void ShadowRealmGlobalScope::initialize_web_interfaces()
 {
+    auto& realm = this->realm();
+
+    WEB_SET_PROTOTYPE_FOR_INTERFACE(ShadowRealmGlobalScope);
+
     add_shadow_realm_exposed_interfaces(*this);
+    Bindings::ShadowRealmGlobalScopeGlobalMixin::initialize(realm, *this);
 }
 
 void ShadowRealmGlobalScope::visit_edges(Cell::Visitor& visitor)

+ 14 - 1
Userland/Libraries/LibWeb/HTML/ShadowRealmGlobalScope.h

@@ -7,12 +7,17 @@
 #pragma once
 
 #include <LibWeb/Bindings/Intrinsics.h>
+#include <LibWeb/Bindings/ShadowRealmGlobalScopeGlobalMixin.h>
 #include <LibWeb/DOM/EventTarget.h>
+#include <LibWeb/HTML/UniversalGlobalScope.h>
 
 namespace Web::HTML {
 
 // https://whatpr.org/html/9893/webappapis.html#shadowrealmglobalscope
-class ShadowRealmGlobalScope : public DOM::EventTarget {
+class ShadowRealmGlobalScope
+    : public DOM::EventTarget
+    , public UniversalGlobalScopeMixin
+    , public Bindings::ShadowRealmGlobalScopeGlobalMixin {
     WEB_PLATFORM_OBJECT(ShadowRealmGlobalScope, DOM::EventTarget);
     JS_DECLARE_ALLOCATOR(ShadowRealmGlobalScope);
 
@@ -21,6 +26,9 @@ public:
 
     static JS::NonnullGCPtr<ShadowRealmGlobalScope> create(JS::Realm&);
 
+    virtual Bindings::PlatformObject& this_impl() override { return *this; }
+    virtual Bindings::PlatformObject const& this_impl() const override { return *this; }
+
     // https://whatpr.org/html/9893/webappapis.html#dom-shadowrealmglobalscope-self
     JS::NonnullGCPtr<ShadowRealmGlobalScope> self()
     {
@@ -28,6 +36,11 @@ public:
         return *this;
     }
 
+    using UniversalGlobalScopeMixin::atob;
+    using UniversalGlobalScopeMixin::btoa;
+    using UniversalGlobalScopeMixin::queue_microtask;
+    using UniversalGlobalScopeMixin::structured_clone;
+
     void initialize_web_interfaces();
 
 protected:

+ 4 - 0
Userland/Libraries/LibWeb/HTML/ShadowRealmGlobalScope.idl

@@ -1,5 +1,9 @@
+#import <HTML/UniversalGlobalScope.idl>
+
 // https://whatpr.org/html/9893/webappapis.html#shadowrealmglobalscope
 [Global, Exposed=ShadowRealm]
 interface ShadowRealmGlobalScope : EventTarget {
     readonly attribute ShadowRealmGlobalScope self;
 };
+
+ShadowRealmGlobalScope includes UniversalGlobalScope;

+ 104 - 0
Userland/Libraries/LibWeb/HTML/UniversalGlobalScope.cpp

@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2022, Andrew Kaster <akaster@serenityos.org>
+ * Copyright (c) 2023, Linus Groh <linusg@serenityos.org>
+ * Copyright (c) 2023, Luke Wilde <lukew@serenityos.org>
+ * Copyright (c) 2024, Shannon Booth <shannon@serenityos.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <AK/Base64.h>
+#include <AK/String.h>
+#include <AK/Utf8View.h>
+#include <AK/Vector.h>
+#include <LibJS/Heap/HeapFunction.h>
+#include <LibWeb/HTML/Scripting/ExceptionReporter.h>
+#include <LibWeb/HTML/StructuredSerialize.h>
+#include <LibWeb/HTML/StructuredSerializeOptions.h>
+#include <LibWeb/HTML/UniversalGlobalScope.h>
+#include <LibWeb/HTML/Window.h>
+#include <LibWeb/Infra/Strings.h>
+#include <LibWeb/WebIDL/AbstractOperations.h>
+#include <LibWeb/WebIDL/DOMException.h>
+#include <LibWeb/WebIDL/ExceptionOr.h>
+#include <LibWeb/WebIDL/Types.h>
+
+namespace Web::HTML {
+
+UniversalGlobalScopeMixin::~UniversalGlobalScopeMixin() = default;
+
+// https://html.spec.whatwg.org/multipage/webappapis.html#dom-btoa
+WebIDL::ExceptionOr<String> UniversalGlobalScopeMixin::btoa(String const& data) const
+{
+    auto& vm = this_impl().vm();
+    auto& realm = *vm.current_realm();
+
+    // The btoa(data) method must throw an "InvalidCharacterError" DOMException if data contains any character whose code point is greater than U+00FF.
+    Vector<u8> byte_string;
+    byte_string.ensure_capacity(data.bytes().size());
+    for (u32 code_point : Utf8View(data)) {
+        if (code_point > 0xff)
+            return WebIDL::InvalidCharacterError::create(realm, "Data contains characters outside the range U+0000 and U+00FF"_string);
+        byte_string.append(code_point);
+    }
+
+    // Otherwise, the user agent must convert data to a byte sequence whose nth byte is the eight-bit representation of the nth code point of data,
+    // and then must apply forgiving-base64 encode to that byte sequence and return the result.
+    return TRY_OR_THROW_OOM(vm, encode_base64(byte_string.span()));
+}
+
+// https://html.spec.whatwg.org/multipage/webappapis.html#dom-atob
+WebIDL::ExceptionOr<String> UniversalGlobalScopeMixin::atob(String const& data) const
+{
+    auto& vm = this_impl().vm();
+    auto& realm = *vm.current_realm();
+
+    // 1. Let decodedData be the result of running forgiving-base64 decode on data.
+    auto decoded_data = decode_base64(data);
+
+    // 2. If decodedData is failure, then throw an "InvalidCharacterError" DOMException.
+    if (decoded_data.is_error())
+        return WebIDL::InvalidCharacterError::create(realm, "Input string is not valid base64 data"_string);
+
+    // 3. Return decodedData.
+    // decode_base64() returns a byte buffer. LibJS uses UTF-8 for strings. Use isomorphic decoding to convert bytes to UTF-8.
+    return Infra::isomorphic_decode(decoded_data.value());
+}
+
+// https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#dom-queuemicrotask
+void UniversalGlobalScopeMixin::queue_microtask(WebIDL::CallbackType& callback)
+{
+    auto& vm = this_impl().vm();
+    auto& realm = *vm.current_realm();
+
+    JS::GCPtr<DOM::Document> document;
+    if (is<Window>(this_impl()))
+        document = &static_cast<Window&>(this_impl()).associated_document();
+
+    // The queueMicrotask(callback) method must queue a microtask to invoke callback, and if callback throws an exception, report the exception.
+    HTML::queue_a_microtask(document, JS::create_heap_function(realm.heap(), [&callback, &realm] {
+        auto result = WebIDL::invoke_callback(callback, {});
+        if (result.is_error())
+            HTML::report_exception(result, realm);
+    }));
+}
+
+// https://html.spec.whatwg.org/multipage/structured-data.html#dom-structuredclone
+WebIDL::ExceptionOr<JS::Value> UniversalGlobalScopeMixin::structured_clone(JS::Value value, StructuredSerializeOptions const& options) const
+{
+    auto& vm = this_impl().vm();
+    (void)options;
+
+    // 1. Let serialized be ? StructuredSerializeWithTransfer(value, options["transfer"]).
+    // FIXME: Use WithTransfer variant of the AO
+    auto serialized = TRY(structured_serialize(vm, value));
+
+    // 2. Let deserializeRecord be ? StructuredDeserializeWithTransfer(serialized, this's relevant realm).
+    // FIXME: Use WithTransfer variant of the AO
+    auto deserialized = TRY(structured_deserialize(vm, serialized, relevant_realm(this_impl()), {}));
+
+    // 3. Return deserializeRecord.[[Deserialized]].
+    return deserialized;
+}
+
+}

+ 33 - 0
Userland/Libraries/LibWeb/HTML/UniversalGlobalScope.h

@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2023, Linus Groh <linusg@serenityos.org>
+ * Copyright (c) 2023, Luke Wilde <lukew@serenityos.org>
+ * Copyright (c) 2024, Shannon Booth <shannon@serenityos.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include <AK/Forward.h>
+#include <AK/String.h>
+#include <LibJS/Runtime/Value.h>
+#include <LibWeb/Forward.h>
+#include <LibWeb/WebIDL/ExceptionOr.h>
+
+namespace Web::HTML {
+
+// https://whatpr.org/html/9893/webappapis.html#universalglobalscope-mixin
+class UniversalGlobalScopeMixin {
+public:
+    virtual ~UniversalGlobalScopeMixin();
+
+    virtual Bindings::PlatformObject& this_impl() = 0;
+    virtual Bindings::PlatformObject const& this_impl() const = 0;
+
+    WebIDL::ExceptionOr<String> btoa(String const& data) const;
+    WebIDL::ExceptionOr<String> atob(String const& data) const;
+    void queue_microtask(WebIDL::CallbackType&);
+    WebIDL::ExceptionOr<JS::Value> structured_clone(JS::Value, StructuredSerializeOptions const&) const;
+};
+
+}

+ 17 - 0
Userland/Libraries/LibWeb/HTML/UniversalGlobalScope.idl

@@ -0,0 +1,17 @@
+#import <HTML/MessagePort.idl>
+
+// FIXME: Support VoidFunction in the IDL parser
+callback VoidFunction = undefined ();
+
+// https://whatpr.org/html/9893/webappapis.html#universalglobalscope-mixin
+interface mixin UniversalGlobalScope {
+    // base64 utility methods
+    DOMString btoa(DOMString data);
+    ByteString atob(DOMString data);
+
+    // microtask queuing
+    undefined queueMicrotask(VoidFunction callback);
+
+    // structured cloning
+    any structuredClone(any value, optional StructuredSerializeOptions options = {});
+};

+ 6 - 4
Userland/Libraries/LibWeb/HTML/Window.h

@@ -24,6 +24,7 @@
 #include <LibWeb/HTML/Scripting/ImportMap.h>
 #include <LibWeb/HTML/ScrollOptions.h>
 #include <LibWeb/HTML/StructuredSerializeOptions.h>
+#include <LibWeb/HTML/UniversalGlobalScope.h>
 #include <LibWeb/HTML/WindowEventHandlers.h>
 #include <LibWeb/HTML/WindowOrWorkerGlobalScope.h>
 #include <LibWeb/RequestIdleCallback/IdleRequest.h>
@@ -49,6 +50,7 @@ class Window final
     , public GlobalEventHandlers
     , public WindowEventHandlers
     , public WindowOrWorkerGlobalScopeMixin
+    , public UniversalGlobalScopeMixin
     , public Bindings::WindowGlobalMixin {
     WEB_PLATFORM_OBJECT(Window, DOM::EventTarget);
     JS_DECLARE_ALLOCATOR(Window);
@@ -58,17 +60,17 @@ public:
 
     ~Window();
 
-    using WindowOrWorkerGlobalScopeMixin::atob;
-    using WindowOrWorkerGlobalScopeMixin::btoa;
+    using UniversalGlobalScopeMixin::atob;
+    using UniversalGlobalScopeMixin::btoa;
+    using UniversalGlobalScopeMixin::queue_microtask;
+    using UniversalGlobalScopeMixin::structured_clone;
     using WindowOrWorkerGlobalScopeMixin::clear_interval;
     using WindowOrWorkerGlobalScopeMixin::clear_timeout;
     using WindowOrWorkerGlobalScopeMixin::create_image_bitmap;
     using WindowOrWorkerGlobalScopeMixin::fetch;
-    using WindowOrWorkerGlobalScopeMixin::queue_microtask;
     using WindowOrWorkerGlobalScopeMixin::report_error;
     using WindowOrWorkerGlobalScopeMixin::set_interval;
     using WindowOrWorkerGlobalScopeMixin::set_timeout;
-    using WindowOrWorkerGlobalScopeMixin::structured_clone;
 
     // ^DOM::EventTarget
     virtual bool dispatch_event(DOM::Event&) override;

+ 2 - 0
Userland/Libraries/LibWeb/HTML/Window.idl

@@ -9,6 +9,7 @@
 #import <HTML/History.idl>
 #import <HTML/Navigation.idl>
 #import <HTML/Navigator.idl>
+#import <HTML/UniversalGlobalScope.idl>
 #import <HTML/WindowLocalStorage.idl>
 #import <HTML/WindowOrWorkerGlobalScope.idl>
 #import <HTML/WindowSessionStorage.idl>
@@ -115,6 +116,7 @@ interface Window : EventTarget {
 };
 Window includes AnimationFrameProvider;
 Window includes GlobalEventHandlers;
+Window includes UniversalGlobalScope;
 Window includes WindowEventHandlers;
 Window includes WindowLocalStorage;
 Window includes WindowSessionStorage;

+ 0 - 77
Userland/Libraries/LibWeb/HTML/WindowOrWorkerGlobalScope.cpp

@@ -6,7 +6,6 @@
  * SPDX-License-Identifier: BSD-2-Clause
  */
 
-#include <AK/Base64.h>
 #include <AK/QuickSort.h>
 #include <AK/String.h>
 #include <AK/Utf8View.h>
@@ -27,8 +26,6 @@
 #include <LibWeb/HTML/Scripting/ExceptionReporter.h>
 #include <LibWeb/HTML/Scripting/Fetching.h>
 #include <LibWeb/HTML/Scripting/TemporaryExecutionContext.h>
-#include <LibWeb/HTML/StructuredSerialize.h>
-#include <LibWeb/HTML/StructuredSerializeOptions.h>
 #include <LibWeb/HTML/Timer.h>
 #include <LibWeb/HTML/Window.h>
 #include <LibWeb/HTML/WindowOrWorkerGlobalScope.h>
@@ -108,62 +105,6 @@ bool WindowOrWorkerGlobalScopeMixin::cross_origin_isolated() const
     return relevant_settings_object(this_impl()).cross_origin_isolated_capability() == CanUseCrossOriginIsolatedAPIs::Yes;
 }
 
-// https://html.spec.whatwg.org/multipage/webappapis.html#dom-btoa
-WebIDL::ExceptionOr<String> WindowOrWorkerGlobalScopeMixin::btoa(String const& data) const
-{
-    auto& vm = this_impl().vm();
-    auto& realm = *vm.current_realm();
-
-    // The btoa(data) method must throw an "InvalidCharacterError" DOMException if data contains any character whose code point is greater than U+00FF.
-    Vector<u8> byte_string;
-    byte_string.ensure_capacity(data.bytes().size());
-    for (u32 code_point : Utf8View(data)) {
-        if (code_point > 0xff)
-            return WebIDL::InvalidCharacterError::create(realm, "Data contains characters outside the range U+0000 and U+00FF"_string);
-        byte_string.append(code_point);
-    }
-
-    // Otherwise, the user agent must convert data to a byte sequence whose nth byte is the eight-bit representation of the nth code point of data,
-    // and then must apply forgiving-base64 encode to that byte sequence and return the result.
-    return TRY_OR_THROW_OOM(vm, encode_base64(byte_string.span()));
-}
-
-// https://html.spec.whatwg.org/multipage/webappapis.html#dom-atob
-WebIDL::ExceptionOr<String> WindowOrWorkerGlobalScopeMixin::atob(String const& data) const
-{
-    auto& vm = this_impl().vm();
-    auto& realm = *vm.current_realm();
-
-    // 1. Let decodedData be the result of running forgiving-base64 decode on data.
-    auto decoded_data = decode_base64(data);
-
-    // 2. If decodedData is failure, then throw an "InvalidCharacterError" DOMException.
-    if (decoded_data.is_error())
-        return WebIDL::InvalidCharacterError::create(realm, "Input string is not valid base64 data"_string);
-
-    // 3. Return decodedData.
-    // decode_base64() returns a byte buffer. LibJS uses UTF-8 for strings. Use isomorphic decoding to convert bytes to UTF-8.
-    return Infra::isomorphic_decode(decoded_data.value());
-}
-
-// https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#dom-queuemicrotask
-void WindowOrWorkerGlobalScopeMixin::queue_microtask(WebIDL::CallbackType& callback)
-{
-    auto& vm = this_impl().vm();
-    auto& realm = *vm.current_realm();
-
-    JS::GCPtr<DOM::Document> document;
-    if (is<Window>(this_impl()))
-        document = &static_cast<Window&>(this_impl()).associated_document();
-
-    // The queueMicrotask(callback) method must queue a microtask to invoke callback, and if callback throws an exception, report the exception.
-    HTML::queue_a_microtask(document, JS::create_heap_function(realm.heap(), [&callback, &realm] {
-        auto result = WebIDL::invoke_callback(callback, {});
-        if (result.is_error())
-            HTML::report_exception(result, realm);
-    }));
-}
-
 // https://html.spec.whatwg.org/multipage/imagebitmap-and-animations.html#dom-createimagebitmap
 JS::NonnullGCPtr<WebIDL::Promise> WindowOrWorkerGlobalScopeMixin::create_image_bitmap(ImageBitmapSource image, Optional<ImageBitmapOptions> options) const
 {
@@ -261,24 +202,6 @@ JS::NonnullGCPtr<WebIDL::Promise> WindowOrWorkerGlobalScopeMixin::create_image_b
     return p;
 }
 
-// https://html.spec.whatwg.org/multipage/structured-data.html#dom-structuredclone
-WebIDL::ExceptionOr<JS::Value> WindowOrWorkerGlobalScopeMixin::structured_clone(JS::Value value, StructuredSerializeOptions const& options) const
-{
-    auto& vm = this_impl().vm();
-    (void)options;
-
-    // 1. Let serialized be ? StructuredSerializeWithTransfer(value, options["transfer"]).
-    // FIXME: Use WithTransfer variant of the AO
-    auto serialized = TRY(structured_serialize(vm, value));
-
-    // 2. Let deserializeRecord be ? StructuredDeserializeWithTransfer(serialized, this's relevant realm).
-    // FIXME: Use WithTransfer variant of the AO
-    auto deserialized = TRY(structured_deserialize(vm, serialized, relevant_realm(this_impl()), {}));
-
-    // 3. Return deserializeRecord.[[Deserialized]].
-    return deserialized;
-}
-
 JS::NonnullGCPtr<WebIDL::Promise> WindowOrWorkerGlobalScopeMixin::fetch(Fetch::RequestInfo const& input, Fetch::RequestInit const& init) const
 {
     auto& vm = this_impl().vm();

+ 0 - 4
Userland/Libraries/LibWeb/HTML/WindowOrWorkerGlobalScope.h

@@ -36,12 +36,8 @@ public:
     WebIDL::ExceptionOr<String> origin() const;
     bool is_secure_context() const;
     bool cross_origin_isolated() const;
-    WebIDL::ExceptionOr<String> btoa(String const& data) const;
-    WebIDL::ExceptionOr<String> atob(String const& data) const;
-    void queue_microtask(WebIDL::CallbackType&);
     JS::NonnullGCPtr<WebIDL::Promise> create_image_bitmap(ImageBitmapSource image, Optional<ImageBitmapOptions> options = {}) const;
     JS::NonnullGCPtr<WebIDL::Promise> create_image_bitmap(ImageBitmapSource image, WebIDL::Long sx, WebIDL::Long sy, WebIDL::Long sw, WebIDL::Long sh, Optional<ImageBitmapOptions> options = {}) const;
-    WebIDL::ExceptionOr<JS::Value> structured_clone(JS::Value, StructuredSerializeOptions const&) const;
     JS::NonnullGCPtr<WebIDL::Promise> fetch(Fetch::RequestInfo const&, Fetch::RequestInit const&) const;
 
     i32 set_timeout(TimerHandler, i32 timeout, JS::MarkedVector<JS::Value> arguments);

+ 0 - 13
Userland/Libraries/LibWeb/HTML/WindowOrWorkerGlobalScope.idl

@@ -6,9 +6,6 @@
 #import <HTML/MessagePort.idl>
 #import <IndexedDB/IDBFactory.idl>
 
-// FIXME: Support VoidFunction in the IDL parser
-callback VoidFunction = undefined ();
-
 // https://html.spec.whatwg.org/#timerhandler
 typedef (DOMString or Function) TimerHandler;
 
@@ -21,26 +18,16 @@ interface mixin WindowOrWorkerGlobalScope {
     // https://html.spec.whatwg.org/multipage/webappapis.html#dom-reporterror
     undefined reportError(any e);
 
-    // base64 utility methods
-    DOMString btoa(DOMString data);
-    ByteString atob(DOMString data);
-
     // timers
     long setTimeout(TimerHandler handler, optional long timeout = 0, any... arguments);
     undefined clearTimeout(optional long id = 0);
     long setInterval(TimerHandler handler, optional long timeout = 0, any... arguments);
     undefined clearInterval(optional long id = 0);
 
-    // microtask queuing
-    undefined queueMicrotask(VoidFunction callback);
-
     // ImageBitmap
     Promise<ImageBitmap> createImageBitmap(ImageBitmapSource image, optional ImageBitmapOptions options = {});
     Promise<ImageBitmap> createImageBitmap(ImageBitmapSource image, long sx, long sy, long sw, long sh, optional ImageBitmapOptions options = {});
 
-    // structured cloning
-    any structuredClone(any value, optional StructuredSerializeOptions options = {});
-
     // https://fetch.spec.whatwg.org/#fetch-method
     [NewObject] Promise<Response> fetch(RequestInfo input, optional RequestInit init = {});
 

+ 7 - 5
Userland/Libraries/LibWeb/HTML/WorkerGlobalScope.h

@@ -13,6 +13,7 @@
 #include <LibWeb/DOM/EventTarget.h>
 #include <LibWeb/Forward.h>
 #include <LibWeb/HTML/Scripting/Fetching.h>
+#include <LibWeb/HTML/UniversalGlobalScope.h>
 #include <LibWeb/HTML/WindowOrWorkerGlobalScope.h>
 #include <LibWeb/HTML/WorkerLocation.h>
 #include <LibWeb/HTML/WorkerNavigator.h>
@@ -33,7 +34,8 @@ namespace Web::HTML {
 // user agent runs the run a worker algorithm.
 class WorkerGlobalScope
     : public DOM::EventTarget
-    , public WindowOrWorkerGlobalScopeMixin {
+    , public WindowOrWorkerGlobalScopeMixin
+    , public UniversalGlobalScopeMixin {
     WEB_PLATFORM_OBJECT(WorkerGlobalScope, DOM::EventTarget);
     JS_DECLARE_ALLOCATOR(WorkerGlobalScope);
 
@@ -44,17 +46,17 @@ public:
     virtual Bindings::PlatformObject& this_impl() override { return *this; }
     virtual Bindings::PlatformObject const& this_impl() const override { return *this; }
 
-    using WindowOrWorkerGlobalScopeMixin::atob;
-    using WindowOrWorkerGlobalScopeMixin::btoa;
+    using UniversalGlobalScopeMixin::atob;
+    using UniversalGlobalScopeMixin::btoa;
+    using UniversalGlobalScopeMixin::queue_microtask;
+    using UniversalGlobalScopeMixin::structured_clone;
     using WindowOrWorkerGlobalScopeMixin::clear_interval;
     using WindowOrWorkerGlobalScopeMixin::clear_timeout;
     using WindowOrWorkerGlobalScopeMixin::create_image_bitmap;
     using WindowOrWorkerGlobalScopeMixin::fetch;
     using WindowOrWorkerGlobalScopeMixin::performance;
-    using WindowOrWorkerGlobalScopeMixin::queue_microtask;
     using WindowOrWorkerGlobalScopeMixin::set_interval;
     using WindowOrWorkerGlobalScopeMixin::set_timeout;
-    using WindowOrWorkerGlobalScopeMixin::structured_clone;
 
     // Following methods are from the WorkerGlobalScope IDL definition
     // https://html.spec.whatwg.org/multipage/workers.html#the-workerglobalscope-common-interface

+ 4 - 2
Userland/Libraries/LibWeb/HTML/WorkerGlobalScope.idl

@@ -1,10 +1,11 @@
 #import <CSS/FontFaceSet.idl>
 #import <DOM/EventTarget.idl>
 #import <DOM/EventHandler.idl>
+#import <HTML/MessagePort.idl>
+#import <HTML/UniversalGlobalScope.idl>
 #import <HTML/WindowOrWorkerGlobalScope.idl>
 #import <HTML/WorkerLocation.idl>
 #import <HTML/WorkerNavigator.idl>
-#import <HTML/MessagePort.idl>
 
 // https://html.spec.whatwg.org/multipage/workers.html#workerglobalscope
 [Exposed=Worker]
@@ -22,5 +23,6 @@ interface WorkerGlobalScope : EventTarget {
     attribute EventHandler onunhandledrejection;
 };
 
-WorkerGlobalScope includes WindowOrWorkerGlobalScope;
 WorkerGlobalScope includes FontFaceSource;
+WorkerGlobalScope includes UniversalGlobalScope;
+WorkerGlobalScope includes WindowOrWorkerGlobalScope;

+ 1 - 1
Userland/Libraries/LibWeb/idl_files.cmake

@@ -222,7 +222,7 @@ libweb_js_bindings(HTML/RadioNodeList)
 libweb_js_bindings(HTML/ServiceWorker)
 libweb_js_bindings(HTML/ServiceWorkerContainer)
 libweb_js_bindings(HTML/ServiceWorkerRegistration)
-libweb_js_bindings(HTML/ShadowRealmGlobalScope)
+libweb_js_bindings(HTML/ShadowRealmGlobalScope GLOBAL)
 libweb_js_bindings(HTML/Storage)
 libweb_js_bindings(HTML/SubmitEvent)
 libweb_js_bindings(HTML/TextMetrics)