Browse Source

LibWeb: Implement PerformanceObserver.supportedEntryTypes

Luke Wilde 1 year ago
parent
commit
facece1a2a

+ 5 - 0
Tests/LibWeb/Text/expected/PerformanceObserver/PerformanceObserver-supportedEntryTypes.txt

@@ -0,0 +1,5 @@
+PerformanceObserver.supportedEntryTypes: mark,measure
+PerformanceObserver.supportedEntryTypes instanceof Array: true
+Object.isFrozen(PerformanceObserver.supportedEntryTypes): true
+PerformanceObserver.supportedEntryTypes === PerformanceObserver.supportedEntryTypes: true
+sorted alphabetically: true

+ 21 - 0
Tests/LibWeb/Text/input/PerformanceObserver/PerformanceObserver-supportedEntryTypes.html

@@ -0,0 +1,21 @@
+<script src="../include.js"></script>
+<script>
+    test(() => {
+        println(`PerformanceObserver.supportedEntryTypes: ${PerformanceObserver.supportedEntryTypes}`);
+        println(`PerformanceObserver.supportedEntryTypes instanceof Array: ${PerformanceObserver.supportedEntryTypes instanceof Array}`);
+        println(`Object.isFrozen(PerformanceObserver.supportedEntryTypes): ${Object.isFrozen(PerformanceObserver.supportedEntryTypes)}`);
+        println(`PerformanceObserver.supportedEntryTypes === PerformanceObserver.supportedEntryTypes: ${PerformanceObserver.supportedEntryTypes === PerformanceObserver.supportedEntryTypes}`);
+
+        const sorted = PerformanceObserver.supportedEntryTypes.toSorted((left, right) => {
+            if (left < right)
+                return -1;
+
+            if (left > right)
+                return 1;
+
+            return 0;
+        });
+
+        println(`sorted alphabetically: ${sorted.toString() === PerformanceObserver.supportedEntryTypes.toString()}`);
+    });
+</script>

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

@@ -12,6 +12,7 @@
 #include <AK/Utf8View.h>
 #include <AK/Vector.h>
 #include <LibJS/Heap/HeapFunction.h>
+#include <LibJS/Runtime/Array.h>
 #include <LibTextCodec/Decoder.h>
 #include <LibWeb/Bindings/MainThreadVM.h>
 #include <LibWeb/Fetch/FetchMethod.h>
@@ -59,6 +60,7 @@ void WindowOrWorkerGlobalScopeMixin::initialize(JS::Realm&)
 void WindowOrWorkerGlobalScopeMixin::visit_edges(JS::Cell::Visitor& visitor)
 {
     visitor.visit(m_performance);
+    visitor.visit(m_supported_entry_types_array);
     for (auto& it : m_timers)
         visitor.visit(it.value);
     for (auto& observer : m_registered_performance_observer_objects)
@@ -595,4 +597,28 @@ JS::NonnullGCPtr<HighResolutionTime::Performance> WindowOrWorkerGlobalScopeMixin
     return JS::NonnullGCPtr { *m_performance };
 }
 
+// https://w3c.github.io/performance-timeline/#dfn-frozen-array-of-supported-entry-types
+JS::NonnullGCPtr<JS::Object> WindowOrWorkerGlobalScopeMixin::supported_entry_types() const
+{
+    // Each global object has an associated frozen array of supported entry types, which is initialized to the
+    // FrozenArray created from the sequence of strings among the registry that are supported for the global
+    // object, in alphabetical order.
+    auto& vm = this_impl().vm();
+    auto& realm = this_impl().realm();
+
+    if (!m_supported_entry_types_array) {
+        Vector<JS::Value> supported_entry_types;
+
+#define __ENUMERATE_SUPPORTED_PERFORMANCE_ENTRY_TYPES(entry_type, cpp_class) \
+    supported_entry_types.append(JS::PrimitiveString::create(vm, entry_type));
+        ENUMERATE_SUPPORTED_PERFORMANCE_ENTRY_TYPES
+#undef __ENUMERATE_SUPPORTED_PERFORMANCE_ENTRY_TYPES
+
+        m_supported_entry_types_array = JS::Array::create_from(realm, supported_entry_types);
+        MUST(m_supported_entry_types_array->set_integrity_level(JS::Object::IntegrityLevel::Frozen));
+    }
+
+    return *m_supported_entry_types_array;
+}
+
 }

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

@@ -65,6 +65,8 @@ public:
 
     [[nodiscard]] JS::NonnullGCPtr<HighResolutionTime::Performance> performance();
 
+    JS::NonnullGCPtr<JS::Object> supported_entry_types() const;
+
 protected:
     void initialize(JS::Realm&);
     void visit_edges(JS::Cell::Visitor&);
@@ -95,6 +97,8 @@ private:
     OrderedHashMap<FlyString, PerformanceTimeline::PerformanceEntryTuple> m_performance_entry_buffer_map;
 
     JS::GCPtr<HighResolutionTime::Performance> m_performance;
+
+    mutable JS::GCPtr<JS::Object> m_supported_entry_types_array;
 };
 
 }

+ 11 - 0
Userland/Libraries/LibWeb/PerformanceTimeline/PerformanceObserver.cpp

@@ -218,6 +218,17 @@ Vector<JS::Handle<PerformanceTimeline::PerformanceEntry>> PerformanceObserver::t
     return records;
 }
 
+// https://w3c.github.io/performance-timeline/#dom-performanceobserver-supportedentrytypes
+JS::NonnullGCPtr<JS::Object> PerformanceObserver::supported_entry_types(JS::VM& vm)
+{
+    // 1. Let globalObject be the environment settings object's global object.
+    auto* window_or_worker = dynamic_cast<HTML::WindowOrWorkerGlobalScopeMixin*>(&vm.get_global_object());
+    VERIFY(window_or_worker);
+
+    // 2. Return globalObject's frozen array of supported entry types.
+    return window_or_worker->supported_entry_types();
+}
+
 void PerformanceObserver::unset_requires_dropped_entries(Badge<HTML::WindowOrWorkerGlobalScopeMixin>)
 {
     m_requires_dropped_entries = false;

+ 2 - 0
Userland/Libraries/LibWeb/PerformanceTimeline/PerformanceObserver.h

@@ -46,6 +46,8 @@ public:
 
     void append_to_observer_buffer(Badge<HTML::WindowOrWorkerGlobalScopeMixin>, JS::NonnullGCPtr<PerformanceTimeline::PerformanceEntry>);
 
+    static JS::NonnullGCPtr<JS::Object> supported_entry_types(JS::VM&);
+
 private:
     PerformanceObserver(JS::Realm&, JS::GCPtr<WebIDL::CallbackType>);
 

+ 2 - 1
Userland/Libraries/LibWeb/PerformanceTimeline/PerformanceObserver.idl

@@ -21,5 +21,6 @@ interface PerformanceObserver {
     undefined observe(optional PerformanceObserverInit options = {});
     undefined disconnect();
     PerformanceEntryList takeRecords();
-    //[SameObject] static readonly attribute sequence<DOMString> supportedEntryTypes;
+    // FIXME: [SameObject] static readonly attribute FrozenArray<DOMString> supportedEntryTypes;
+    [SameObject] static readonly attribute any supportedEntryTypes;
 };