diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp b/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp
index a7b3406f1e2..e61b86a50c9 100644
--- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp
+++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp
@@ -74,6 +74,7 @@ static bool is_platform_object(Type const& type)
"Path2D"sv,
"PerformanceEntry"sv,
"PerformanceMark"sv,
+ "PerformanceNavigation"sv,
"PeriodicWave"sv,
"PointerEvent"sv,
"ReadableStreamBYOBReader"sv,
diff --git a/Tests/LibWeb/Text/expected/all-window-properties.txt b/Tests/LibWeb/Text/expected/all-window-properties.txt
index d83c69f63ff..1521f134eae 100644
--- a/Tests/LibWeb/Text/expected/all-window-properties.txt
+++ b/Tests/LibWeb/Text/expected/all-window-properties.txt
@@ -237,6 +237,7 @@ Performance
PerformanceEntry
PerformanceMark
PerformanceMeasure
+PerformanceNavigation
PerformanceObserver
PerformanceObserverEntryList
PerformanceTiming
diff --git a/Tests/LibWeb/Text/expected/performance-navigation.txt b/Tests/LibWeb/Text/expected/performance-navigation.txt
new file mode 100644
index 00000000000..470034c8a5e
--- /dev/null
+++ b/Tests/LibWeb/Text/expected/performance-navigation.txt
@@ -0,0 +1,3 @@
+0
+0
+true
diff --git a/Tests/LibWeb/Text/input/performance-navigation.html b/Tests/LibWeb/Text/input/performance-navigation.html
new file mode 100644
index 00000000000..4e69d67f3ba
--- /dev/null
+++ b/Tests/LibWeb/Text/input/performance-navigation.html
@@ -0,0 +1,8 @@
+
+
diff --git a/Userland/Libraries/LibWeb/CMakeLists.txt b/Userland/Libraries/LibWeb/CMakeLists.txt
index ed8b49992a9..6fa79bcfe2b 100644
--- a/Userland/Libraries/LibWeb/CMakeLists.txt
+++ b/Userland/Libraries/LibWeb/CMakeLists.txt
@@ -538,6 +538,7 @@ set(SOURCES
MixedContent/AbstractOperations.cpp
Namespace.cpp
NavigationTiming/EntryNames.cpp
+ NavigationTiming/PerformanceNavigation.cpp
NavigationTiming/PerformanceTiming.cpp
Page/EditEventHandler.cpp
Page/EventHandler.cpp
diff --git a/Userland/Libraries/LibWeb/Forward.h b/Userland/Libraries/LibWeb/Forward.h
index fc6ca353f73..909c4d400cb 100644
--- a/Userland/Libraries/LibWeb/Forward.h
+++ b/Userland/Libraries/LibWeb/Forward.h
@@ -582,6 +582,7 @@ class MimeType;
}
namespace Web::NavigationTiming {
+class PerformanceNavigation;
class PerformanceTiming;
}
diff --git a/Userland/Libraries/LibWeb/HighResolutionTime/Performance.cpp b/Userland/Libraries/LibWeb/HighResolutionTime/Performance.cpp
index 15cd6522c2f..ba8e5eb8b4f 100644
--- a/Userland/Libraries/LibWeb/HighResolutionTime/Performance.cpp
+++ b/Userland/Libraries/LibWeb/HighResolutionTime/Performance.cpp
@@ -14,6 +14,7 @@
#include
#include
#include
+#include
#include
#include
@@ -50,6 +51,19 @@ JS::GCPtr Performance::timing()
return m_timing;
}
+JS::GCPtr Performance::navigation()
+{
+ auto& realm = this->realm();
+ if (!m_navigation) {
+ // FIXME actually determine values for these
+ u16 type = 0;
+ u16 redirect_count = 0;
+
+ m_navigation = heap().allocate(realm, realm, type, redirect_count);
+ }
+ return m_navigation;
+}
+
double Performance::time_origin() const
{
return static_cast(m_timer.origin_time().nanoseconds()) / 1e6;
diff --git a/Userland/Libraries/LibWeb/HighResolutionTime/Performance.h b/Userland/Libraries/LibWeb/HighResolutionTime/Performance.h
index d301bbee98a..95f990ff723 100644
--- a/Userland/Libraries/LibWeb/HighResolutionTime/Performance.h
+++ b/Userland/Libraries/LibWeb/HighResolutionTime/Performance.h
@@ -25,8 +25,6 @@ public:
double now() const { return static_cast(m_timer.elapsed_time().to_nanoseconds()) / 1e6; }
double time_origin() const;
- JS::GCPtr timing();
-
WebIDL::ExceptionOr> mark(String const& mark_name, UserTiming::PerformanceMarkOptions const& mark_options = {});
void clear_marks(Optional mark_name);
WebIDL::ExceptionOr> measure(String const& measure_name, Variant const& start_or_measure_options, Optional end_mark);
@@ -36,6 +34,9 @@ public:
WebIDL::ExceptionOr>> get_entries_by_type(String const& type) const;
WebIDL::ExceptionOr>> get_entries_by_name(String const& name, Optional type) const;
+ JS::GCPtr timing();
+ JS::GCPtr navigation();
+
private:
explicit Performance(JS::Realm&);
@@ -48,6 +49,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::GCPtr m_navigation;
JS::GCPtr m_timing;
Core::ElapsedTimer m_timer;
diff --git a/Userland/Libraries/LibWeb/HighResolutionTime/Performance.idl b/Userland/Libraries/LibWeb/HighResolutionTime/Performance.idl
index bd92ebc2cb2..e619f01f337 100644
--- a/Userland/Libraries/LibWeb/HighResolutionTime/Performance.idl
+++ b/Userland/Libraries/LibWeb/HighResolutionTime/Performance.idl
@@ -1,5 +1,6 @@
#import
#import
+#import
#import
#import
#import
@@ -15,8 +16,6 @@ interface Performance : EventTarget {
readonly attribute DOMHighResTimeStamp timeOrigin;
[Default] object toJSON();
- readonly attribute PerformanceTiming timing;
-
// https://w3c.github.io/user-timing/#extensions-performance-interface
// "User Timing" extensions to the Performance interface
PerformanceMark mark(DOMString markName, optional PerformanceMarkOptions markOptions = {});
@@ -29,4 +28,11 @@ interface Performance : EventTarget {
PerformanceEntryList getEntries();
PerformanceEntryList getEntriesByType(DOMString type);
PerformanceEntryList getEntriesByName(DOMString name, optional DOMString type);
+
+ // https://w3c.github.io/navigation-timing/#extensions-to-the-performance-interface
+ // Obsolete "Navigation Timing" extensions to the Performance interface
+ [SameObject]
+ readonly attribute PerformanceTiming timing;
+ [SameObject]
+ readonly attribute PerformanceNavigation navigation;
};
diff --git a/Userland/Libraries/LibWeb/NavigationTiming/PerformanceNavigation.cpp b/Userland/Libraries/LibWeb/NavigationTiming/PerformanceNavigation.cpp
new file mode 100644
index 00000000000..cb41677bba5
--- /dev/null
+++ b/Userland/Libraries/LibWeb/NavigationTiming/PerformanceNavigation.cpp
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2024, Colin Reeder
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include
+#include
+#include
+
+namespace Web::NavigationTiming {
+
+JS_DEFINE_ALLOCATOR(PerformanceNavigation);
+
+PerformanceNavigation::PerformanceNavigation(JS::Realm& realm, u16 type, u16 redirect_count)
+ : PlatformObject(realm)
+ , m_type(type)
+ , m_redirect_count(redirect_count)
+{
+}
+PerformanceNavigation::~PerformanceNavigation() = default;
+
+void PerformanceNavigation::initialize(JS::Realm& realm)
+{
+ Base::initialize(realm);
+ WEB_SET_PROTOTYPE_FOR_INTERFACE(PerformanceNavigation);
+}
+
+u16 PerformanceNavigation::type() const
+{
+ return m_type;
+}
+
+u16 PerformanceNavigation::redirect_count() const
+{
+ return m_redirect_count;
+}
+
+}
diff --git a/Userland/Libraries/LibWeb/NavigationTiming/PerformanceNavigation.h b/Userland/Libraries/LibWeb/NavigationTiming/PerformanceNavigation.h
new file mode 100644
index 00000000000..50c4f4b347e
--- /dev/null
+++ b/Userland/Libraries/LibWeb/NavigationTiming/PerformanceNavigation.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2024, Colin Reeder
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include
+
+namespace Web::NavigationTiming {
+
+class PerformanceNavigation final : public Bindings::PlatformObject {
+ WEB_PLATFORM_OBJECT(PerformanceNavigation, Bindings::PlatformObject);
+ JS_DECLARE_ALLOCATOR(PerformanceNavigation);
+
+public:
+ ~PerformanceNavigation();
+
+ u16 type() const;
+ u16 redirect_count() const;
+
+private:
+ explicit PerformanceNavigation(JS::Realm&, u16 type, u16 redirect_count);
+
+ void initialize(JS::Realm&) override;
+
+ u16 m_type;
+ u16 m_redirect_count;
+};
+
+}
diff --git a/Userland/Libraries/LibWeb/NavigationTiming/PerformanceNavigation.idl b/Userland/Libraries/LibWeb/NavigationTiming/PerformanceNavigation.idl
new file mode 100644
index 00000000000..12f9bbe9ada
--- /dev/null
+++ b/Userland/Libraries/LibWeb/NavigationTiming/PerformanceNavigation.idl
@@ -0,0 +1,10 @@
+[Exposed=Window]
+interface PerformanceNavigation {
+ const unsigned short TYPE_NAVIGATE = 0;
+ const unsigned short TYPE_RELOAD = 1;
+ const unsigned short TYPE_BACK_FORWARD = 2;
+ const unsigned short TYPE_RESERVED = 255;
+ readonly attribute unsigned short type;
+ readonly attribute unsigned short redirectCount;
+ [Default] object toJSON();
+};
\ No newline at end of file
diff --git a/Userland/Libraries/LibWeb/idl_files.cmake b/Userland/Libraries/LibWeb/idl_files.cmake
index cab7aef9449..14714cd140c 100644
--- a/Userland/Libraries/LibWeb/idl_files.cmake
+++ b/Userland/Libraries/LibWeb/idl_files.cmake
@@ -236,6 +236,7 @@ libweb_js_bindings(Internals/Internals)
libweb_js_bindings(IntersectionObserver/IntersectionObserver)
libweb_js_bindings(IntersectionObserver/IntersectionObserverEntry)
libweb_js_bindings(MathML/MathMLElement)
+libweb_js_bindings(NavigationTiming/PerformanceNavigation)
libweb_js_bindings(NavigationTiming/PerformanceTiming)
libweb_js_bindings(PerformanceTimeline/PerformanceEntry)
libweb_js_bindings(PerformanceTimeline/PerformanceObserver)