diff --git a/Tests/LibWeb/Text/expected/Worker/Worker-performance.txt b/Tests/LibWeb/Text/expected/Worker/Worker-performance.txt
new file mode 100644
index 00000000000..d60021025e0
--- /dev/null
+++ b/Tests/LibWeb/Text/expected/Worker/Worker-performance.txt
@@ -0,0 +1 @@
+performance global object is available: true
diff --git a/Tests/LibWeb/Text/input/Worker/Worker-performance.html b/Tests/LibWeb/Text/input/Worker/Worker-performance.html
new file mode 100644
index 00000000000..fe82ace0cc2
--- /dev/null
+++ b/Tests/LibWeb/Text/input/Worker/Worker-performance.html
@@ -0,0 +1,10 @@
+
+
diff --git a/Tests/LibWeb/Text/input/Worker/worker-performance.js b/Tests/LibWeb/Text/input/Worker/worker-performance.js
new file mode 100644
index 00000000000..5c3d61c02a2
--- /dev/null
+++ b/Tests/LibWeb/Text/input/Worker/worker-performance.js
@@ -0,0 +1 @@
+postMessage(performance !== undefined);
diff --git a/Userland/Libraries/LibWeb/Animations/DocumentTimeline.cpp b/Userland/Libraries/LibWeb/Animations/DocumentTimeline.cpp
index 08d51b5a9c7..291251069aa 100644
--- a/Userland/Libraries/LibWeb/Animations/DocumentTimeline.cpp
+++ b/Userland/Libraries/LibWeb/Animations/DocumentTimeline.cpp
@@ -19,7 +19,9 @@ JS_DEFINE_ALLOCATOR(DocumentTimeline);
JS::NonnullGCPtr DocumentTimeline::create(JS::Realm& realm, DOM::Document& document, HighResolutionTime::DOMHighResTimeStamp origin_time)
{
auto timeline = realm.heap().allocate(realm, realm, document, origin_time);
- timeline->set_current_time(document.window()->performance()->now());
+ auto* window_or_worker = dynamic_cast(&realm.global_object());
+ VERIFY(window_or_worker);
+ timeline->set_current_time(window_or_worker->performance()->now());
return timeline;
}
diff --git a/Userland/Libraries/LibWeb/HTML/Window.cpp b/Userland/Libraries/LibWeb/HTML/Window.cpp
index 63708b28ea4..d05553c099c 100644
--- a/Userland/Libraries/LibWeb/HTML/Window.cpp
+++ b/Userland/Libraries/LibWeb/HTML/Window.cpp
@@ -58,7 +58,6 @@
#include
#include
#include
-#include
#include
#include
#include
@@ -121,7 +120,6 @@ void Window::visit_edges(JS::Cell::Visitor& visitor)
visitor.visit(m_associated_document);
visitor.visit(m_current_event);
- visitor.visit(m_performance);
visitor.visit(m_screen);
visitor.visit(m_location);
visitor.visit(m_crypto);
@@ -1572,14 +1570,6 @@ JS::GCPtr Window::get_selection() const
return associated_document().get_selection();
}
-// https://w3c.github.io/hr-time/#dom-windoworworkerglobalscope-performance
-JS::NonnullGCPtr Window::performance()
-{
- if (!m_performance)
- m_performance = heap().allocate(realm(), *this);
- return JS::NonnullGCPtr { *m_performance };
-}
-
// https://w3c.github.io/webcrypto/#dom-windoworworkerglobalscope-crypto
JS::NonnullGCPtr Window::crypto()
{
diff --git a/Userland/Libraries/LibWeb/HTML/Window.h b/Userland/Libraries/LibWeb/HTML/Window.h
index c5811ff8e98..ba0a4a1ceed 100644
--- a/Userland/Libraries/LibWeb/HTML/Window.h
+++ b/Userland/Libraries/LibWeb/HTML/Window.h
@@ -196,8 +196,6 @@ public:
JS::GCPtr get_selection() const;
- [[nodiscard]] JS::NonnullGCPtr performance();
-
[[nodiscard]] JS::NonnullGCPtr crypto();
[[nodiscard]] JS::NonnullGCPtr custom_elements();
@@ -246,7 +244,6 @@ private:
// https://html.spec.whatwg.org/multipage/webappapis.html#import-maps-allowed
bool m_import_maps_allowed { true };
- JS::GCPtr m_performance;
JS::GCPtr m_crypto;
JS::GCPtr m_screen;
JS::GCPtr m_navigator;
diff --git a/Userland/Libraries/LibWeb/HTML/Window.idl b/Userland/Libraries/LibWeb/HTML/Window.idl
index 48d89696480..9de543783a9 100644
--- a/Userland/Libraries/LibWeb/HTML/Window.idl
+++ b/Userland/Libraries/LibWeb/HTML/Window.idl
@@ -5,7 +5,6 @@
#import
#import
#import
-#import
#import
#import
#import
@@ -106,10 +105,6 @@ interface Window : EventTarget {
// https://w3c.github.io/selection-api/#extensions-to-window-interface
Selection? getSelection();
- // FIXME: Everything from here on should be shared through WindowOrWorkerGlobalScope
- // https://w3c.github.io/hr-time/#the-performance-attribute
- [Replaceable] readonly attribute Performance performance;
-
// https://w3c.github.io/webcrypto/#crypto-interface
[SameObject] readonly attribute Crypto crypto;
};
diff --git a/Userland/Libraries/LibWeb/HTML/WindowOrWorkerGlobalScope.cpp b/Userland/Libraries/LibWeb/HTML/WindowOrWorkerGlobalScope.cpp
index c930cc9f261..b55f66b2694 100644
--- a/Userland/Libraries/LibWeb/HTML/WindowOrWorkerGlobalScope.cpp
+++ b/Userland/Libraries/LibWeb/HTML/WindowOrWorkerGlobalScope.cpp
@@ -25,6 +25,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -57,6 +58,7 @@ void WindowOrWorkerGlobalScopeMixin::initialize(JS::Realm&)
void WindowOrWorkerGlobalScopeMixin::visit_edges(JS::Cell::Visitor& visitor)
{
+ visitor.visit(m_performance);
for (auto& it : m_timers)
visitor.visit(it.value);
for (auto& observer : m_registered_performance_observer_objects)
@@ -585,4 +587,12 @@ void WindowOrWorkerGlobalScopeMixin::run_steps_after_a_timeout_impl(i32 timeout,
timer->start();
}
+// https://w3c.github.io/hr-time/#dom-windoworworkerglobalscope-performance
+JS::NonnullGCPtr WindowOrWorkerGlobalScopeMixin::performance()
+{
+ if (!m_performance)
+ m_performance = this_impl().heap().allocate(this_impl().realm(), *this);
+ return JS::NonnullGCPtr { *m_performance };
+}
+
}
diff --git a/Userland/Libraries/LibWeb/HTML/WindowOrWorkerGlobalScope.h b/Userland/Libraries/LibWeb/HTML/WindowOrWorkerGlobalScope.h
index 6074b8160ec..4071e859cc6 100644
--- a/Userland/Libraries/LibWeb/HTML/WindowOrWorkerGlobalScope.h
+++ b/Userland/Libraries/LibWeb/HTML/WindowOrWorkerGlobalScope.h
@@ -63,6 +63,8 @@ public:
void run_steps_after_a_timeout(i32 timeout, Function completion_step);
+ [[nodiscard]] JS::NonnullGCPtr performance();
+
protected:
void initialize(JS::Realm&);
void visit_edges(JS::Cell::Visitor&);
@@ -91,6 +93,8 @@ private:
// a performance entry buffer map map, keyed on a DOMString, representing the entry type to which the buffer belongs. The map's value is the following tuple:
// NOTE: See the PerformanceEntryTuple struct above for the map's value tuple.
OrderedHashMap m_performance_entry_buffer_map;
+
+ JS::GCPtr m_performance;
};
}
diff --git a/Userland/Libraries/LibWeb/HTML/WindowOrWorkerGlobalScope.idl b/Userland/Libraries/LibWeb/HTML/WindowOrWorkerGlobalScope.idl
index fda12c65dd2..9dd6938ae8c 100644
--- a/Userland/Libraries/LibWeb/HTML/WindowOrWorkerGlobalScope.idl
+++ b/Userland/Libraries/LibWeb/HTML/WindowOrWorkerGlobalScope.idl
@@ -1,5 +1,6 @@
#import
#import
+#import
#import
// FIXME: Support VoidFunction in the IDL parser
@@ -38,4 +39,7 @@ interface mixin WindowOrWorkerGlobalScope {
// https://fetch.spec.whatwg.org/#fetch-method
[NewObject] Promise fetch(RequestInfo input, optional RequestInit init = {});
+
+ // https://w3c.github.io/hr-time/#the-performance-attribute
+ [Replaceable] readonly attribute Performance performance;
};
diff --git a/Userland/Libraries/LibWeb/HTML/WorkerGlobalScope.h b/Userland/Libraries/LibWeb/HTML/WorkerGlobalScope.h
index 3fc8ac5f555..e5263e49ee4 100644
--- a/Userland/Libraries/LibWeb/HTML/WorkerGlobalScope.h
+++ b/Userland/Libraries/LibWeb/HTML/WorkerGlobalScope.h
@@ -51,6 +51,7 @@ public:
using WindowOrWorkerGlobalScopeMixin::clear_interval;
using WindowOrWorkerGlobalScopeMixin::clear_timeout;
using WindowOrWorkerGlobalScopeMixin::fetch;
+ using WindowOrWorkerGlobalScopeMixin::performance;
using WindowOrWorkerGlobalScopeMixin::queue_microtask;
using WindowOrWorkerGlobalScopeMixin::set_interval;
using WindowOrWorkerGlobalScopeMixin::set_timeout;
diff --git a/Userland/Libraries/LibWeb/HighResolutionTime/Performance.cpp b/Userland/Libraries/LibWeb/HighResolutionTime/Performance.cpp
index bd208624e76..9e54cd96a18 100644
--- a/Userland/Libraries/LibWeb/HighResolutionTime/Performance.cpp
+++ b/Userland/Libraries/LibWeb/HighResolutionTime/Performance.cpp
@@ -20,9 +20,9 @@ namespace Web::HighResolutionTime {
JS_DEFINE_ALLOCATOR(Performance);
-Performance::Performance(HTML::Window& window)
- : DOM::EventTarget(window.realm())
- , m_window(window)
+Performance::Performance(HTML::WindowOrWorkerGlobalScopeMixin& window_or_worker)
+ : DOM::EventTarget(window_or_worker.this_impl().realm())
+ , m_window_or_worker(window_or_worker)
, m_timer(Core::TimerType::Precise)
{
m_timer.start();
@@ -39,14 +39,14 @@ void Performance::initialize(JS::Realm& realm)
void Performance::visit_edges(Cell::Visitor& visitor)
{
Base::visit_edges(visitor);
- visitor.visit(m_window);
visitor.visit(m_timing);
+ visitor.visit(m_window_or_worker->this_impl());
}
JS::GCPtr Performance::timing()
{
if (!m_timing)
- m_timing = heap().allocate(realm(), *m_window);
+ m_timing = heap().allocate(realm(), *m_window_or_worker);
return m_timing;
}
diff --git a/Userland/Libraries/LibWeb/HighResolutionTime/Performance.h b/Userland/Libraries/LibWeb/HighResolutionTime/Performance.h
index 213dbeeef30..df748126837 100644
--- a/Userland/Libraries/LibWeb/HighResolutionTime/Performance.h
+++ b/Userland/Libraries/LibWeb/HighResolutionTime/Performance.h
@@ -9,6 +9,7 @@
#include
#include
+#include
#include
#include
@@ -36,7 +37,7 @@ public:
WebIDL::ExceptionOr>> get_entries_by_name(String const& name, Optional type) const;
private:
- explicit Performance(HTML::Window&);
+ explicit Performance(HTML::WindowOrWorkerGlobalScopeMixin&);
virtual void initialize(JS::Realm&) override;
virtual void visit_edges(Cell::Visitor&) override;
@@ -44,7 +45,7 @@ private:
WebIDL::ExceptionOr convert_name_to_timestamp(JS::Realm& realm, String const& name);
WebIDL::ExceptionOr convert_mark_to_timestamp(JS::Realm& realm, Variant mark);
- JS::NonnullGCPtr m_window;
+ JS::NonnullGCPtr m_window_or_worker;
JS::GCPtr m_timing;
Core::ElapsedTimer m_timer;
diff --git a/Userland/Libraries/LibWeb/NavigationTiming/PerformanceTiming.cpp b/Userland/Libraries/LibWeb/NavigationTiming/PerformanceTiming.cpp
index c3a4260c6f9..705be16612e 100644
--- a/Userland/Libraries/LibWeb/NavigationTiming/PerformanceTiming.cpp
+++ b/Userland/Libraries/LibWeb/NavigationTiming/PerformanceTiming.cpp
@@ -10,9 +10,9 @@ namespace Web::NavigationTiming {
JS_DEFINE_ALLOCATOR(PerformanceTiming);
-PerformanceTiming::PerformanceTiming(HTML::Window& window)
- : PlatformObject(window.realm())
- , m_window(window)
+PerformanceTiming::PerformanceTiming(HTML::WindowOrWorkerGlobalScopeMixin& window_or_worker)
+ : PlatformObject(window_or_worker.this_impl().realm())
+ , m_window_or_worker(window_or_worker)
{
}
@@ -27,7 +27,8 @@ void PerformanceTiming::initialize(JS::Realm& realm)
void PerformanceTiming::visit_edges(Cell::Visitor& visitor)
{
Base::visit_edges(visitor);
- visitor.visit(m_window);
+ if (m_window_or_worker)
+ visitor.visit(m_window_or_worker->this_impl());
}
}
diff --git a/Userland/Libraries/LibWeb/NavigationTiming/PerformanceTiming.h b/Userland/Libraries/LibWeb/NavigationTiming/PerformanceTiming.h
index 0c9798d9e07..c92db2e8d2f 100644
--- a/Userland/Libraries/LibWeb/NavigationTiming/PerformanceTiming.h
+++ b/Userland/Libraries/LibWeb/NavigationTiming/PerformanceTiming.h
@@ -42,12 +42,12 @@ public:
u64 load_event_end() { return 0; }
private:
- explicit PerformanceTiming(HTML::Window&);
+ explicit PerformanceTiming(HTML::WindowOrWorkerGlobalScopeMixin&);
virtual void initialize(JS::Realm&) override;
virtual void visit_edges(Cell::Visitor&) override;
- JS::GCPtr m_window;
+ JS::GCPtr m_window_or_worker;
};
}