diff --git a/Libraries/LibWeb/Forward.h b/Libraries/LibWeb/Forward.h index 6793b94da5e..a9fd5a7e5f6 100644 --- a/Libraries/LibWeb/Forward.h +++ b/Libraries/LibWeb/Forward.h @@ -624,6 +624,7 @@ class Performance; namespace Web::IndexedDB { class Database; class IDBCursor; +class IDBCursorWithValue; class IDBDatabase; class IDBFactory; class IDBIndex; diff --git a/Libraries/LibWeb/IndexedDB/IDBCursor.cpp b/Libraries/LibWeb/IndexedDB/IDBCursor.cpp index f58e8c67e0b..dfa7cd58264 100644 --- a/Libraries/LibWeb/IndexedDB/IDBCursor.cpp +++ b/Libraries/LibWeb/IndexedDB/IDBCursor.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include namespace Web::IndexedDB { @@ -18,11 +19,11 @@ IDBCursor::~IDBCursor() = default; IDBCursor::IDBCursor(JS::Realm& realm, CursorSourceHandle source_handle, GC::Ptr position, Bindings::IDBCursorDirection direction, GotValue got_value, GC::Ptr key, JS::Value value, GC::Ref range, KeyOnly key_only) : PlatformObject(realm) + , m_value(value) , m_position(position) , m_direction(direction) , m_got_value(got_value == GotValue::Yes) , m_key(key) - , m_value(value) , m_source_handle(source_handle) , m_range(range) , m_key_only(key_only == KeyOnly::Yes) @@ -31,6 +32,10 @@ IDBCursor::IDBCursor(JS::Realm& realm, CursorSourceHandle source_handle, GC::Ptr GC::Ref IDBCursor::create(JS::Realm& realm, CursorSourceHandle source_handle, GC::Ptr position, Bindings::IDBCursorDirection direction, GotValue got_value, GC::Ptr key, JS::Value value, GC::Ref range, KeyOnly key_only) { + // A cursor that has its key only flag set to false implements the IDBCursorWithValue interface as well. + if (key_only == KeyOnly::No) + return realm.create(realm, source_handle, position, direction, got_value, key, value, range, key_only); + return realm.create(realm, source_handle, position, direction, got_value, key, value, range, key_only); } @@ -54,6 +59,26 @@ void IDBCursor::visit_edges(Visitor& visitor) }); } +GC_DEFINE_ALLOCATOR(IDBCursorWithValue); + +IDBCursorWithValue::~IDBCursorWithValue() = default; + +IDBCursorWithValue::IDBCursorWithValue(JS::Realm& realm, CursorSourceHandle source_handle, GC::Ptr position, Bindings::IDBCursorDirection direction, GotValue got_value, GC::Ptr key, JS::Value value, GC::Ref range, KeyOnly key_only) + : IDBCursor(realm, source_handle, position, direction, got_value, key, value, range, key_only) +{ +} + +void IDBCursorWithValue::initialize(JS::Realm& realm) +{ + WEB_SET_PROTOTYPE_FOR_INTERFACE(IDBCursorWithValue); + Base::initialize(realm); +} + +void IDBCursorWithValue::visit_edges(Visitor& visitor) +{ + Base::visit_edges(visitor); +} + // https://w3c.github.io/IndexedDB/#cursor-transaction GC::Ref IDBCursor::transaction() { diff --git a/Libraries/LibWeb/IndexedDB/IDBCursor.h b/Libraries/LibWeb/IndexedDB/IDBCursor.h index 1d3efccad4b..79ee1cf29bc 100644 --- a/Libraries/LibWeb/IndexedDB/IDBCursor.h +++ b/Libraries/LibWeb/IndexedDB/IDBCursor.h @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -52,7 +53,6 @@ public: WebIDL::ExceptionOr> update(JS::Value); WebIDL::ExceptionOr> delete_(); - [[nodiscard]] JS::Value value() { return m_value.value_or(JS::js_undefined()); } [[nodiscard]] GC::Ref range() { return m_range; } [[nodiscard]] GC::Ptr position() { return m_position; } [[nodiscard]] GC::Ptr object_store_position() { return m_object_store_position; } @@ -75,6 +75,9 @@ protected: virtual void initialize(JS::Realm&) override; virtual void visit_edges(Visitor& visitor) override; + // A cursor has a value which represent the value of the last iterated record. + Optional m_value; + private: // A cursor has a position within its range. GC::Ptr m_position; @@ -88,9 +91,8 @@ private: // A cursor has a got value flag. bool m_got_value { false }; - // A cursor has a key and a value which represent the key and the value of the last iterated record. + // A cursor has a key which represent the key the last iterated record. GC::Ptr m_key; - Optional m_value; // A cursor has a source handle, which is the index handle or the object store handle that opened the cursor. CursorSourceHandle m_source_handle; @@ -104,4 +106,5 @@ private: // A cursor also has a key only flag, that indicates whether the cursor’s value is exposed via the API. bool m_key_only { false }; }; + } diff --git a/Libraries/LibWeb/IndexedDB/IDBCursorWithValue.h b/Libraries/LibWeb/IndexedDB/IDBCursorWithValue.h new file mode 100644 index 00000000000..8a9d6f9af0a --- /dev/null +++ b/Libraries/LibWeb/IndexedDB/IDBCursorWithValue.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2025, stelar7 + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include + +namespace Web::IndexedDB { + +// https://w3c.github.io/IndexedDB/#idbcursorwithvalue +class IDBCursorWithValue : public IDBCursor { + WEB_PLATFORM_OBJECT(IDBCursorWithValue, IDBCursor); + GC_DECLARE_ALLOCATOR(IDBCursorWithValue); + +public: + virtual ~IDBCursorWithValue() override; + + // https://w3c.github.io/IndexedDB/#dom-idbcursorwithvalue-value + [[nodiscard]] JS::Value value() { return m_value.value_or(JS::js_undefined()); } + +private: + explicit IDBCursorWithValue(JS::Realm&, CursorSourceHandle, GC::Ptr, Bindings::IDBCursorDirection, GotValue, GC::Ptr, JS::Value, GC::Ref, KeyOnly); + virtual void initialize(JS::Realm&) override; + virtual void visit_edges(Visitor& visitor) override; +}; + +} diff --git a/Libraries/LibWeb/IndexedDB/IDBCursorWithValue.idl b/Libraries/LibWeb/IndexedDB/IDBCursorWithValue.idl new file mode 100644 index 00000000000..52ff47ea31d --- /dev/null +++ b/Libraries/LibWeb/IndexedDB/IDBCursorWithValue.idl @@ -0,0 +1,6 @@ +#import + +[Exposed=(Window,Worker)] +interface IDBCursorWithValue : IDBCursor { + readonly attribute any value; +}; diff --git a/Libraries/LibWeb/IndexedDB/IDBIndex.cpp b/Libraries/LibWeb/IndexedDB/IDBIndex.cpp index d63ec66a34c..75095c2ab08 100644 --- a/Libraries/LibWeb/IndexedDB/IDBIndex.cpp +++ b/Libraries/LibWeb/IndexedDB/IDBIndex.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include namespace Web::IndexedDB { diff --git a/Libraries/LibWeb/IndexedDB/IDBObjectStore.cpp b/Libraries/LibWeb/IndexedDB/IDBObjectStore.cpp index 3a1528e5339..c0ec08f73b7 100644 --- a/Libraries/LibWeb/IndexedDB/IDBObjectStore.cpp +++ b/Libraries/LibWeb/IndexedDB/IDBObjectStore.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include diff --git a/Libraries/LibWeb/idl_files.cmake b/Libraries/LibWeb/idl_files.cmake index aadb593fe66..ef222993eb9 100644 --- a/Libraries/LibWeb/idl_files.cmake +++ b/Libraries/LibWeb/idl_files.cmake @@ -260,6 +260,7 @@ libweb_js_bindings(HTML/WorkletGlobalScope) libweb_js_bindings(HTML/XMLSerializer) libweb_js_bindings(HighResolutionTime/Performance) libweb_js_bindings(IndexedDB/IDBCursor) +libweb_js_bindings(IndexedDB/IDBCursorWithValue) libweb_js_bindings(IndexedDB/IDBDatabase) libweb_js_bindings(IndexedDB/IDBFactory) libweb_js_bindings(IndexedDB/IDBIndex) diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp b/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp index bdf842dbab0..7ced49c6673 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp @@ -66,6 +66,7 @@ static bool is_platform_object(Type const& type) "FormData"sv, "HTMLCollection"sv, "IDBCursor"sv, + "IDBCursorWithValue"sv, "IDBIndex"sv, "IDBKeyRange"sv, "IDBObjectStore"sv, diff --git a/Tests/LibWeb/Text/expected/all-window-properties.txt b/Tests/LibWeb/Text/expected/all-window-properties.txt index 54650c6120a..1c18d2b324c 100644 --- a/Tests/LibWeb/Text/expected/all-window-properties.txt +++ b/Tests/LibWeb/Text/expected/all-window-properties.txt @@ -213,6 +213,7 @@ HashChangeEvent Headers History IDBCursor +IDBCursorWithValue IDBDatabase IDBFactory IDBIndex