LibWeb/IDB: Fillout IDBIndex attributes

This commit is contained in:
stelar7 2025-04-01 18:36:39 +02:00
commit f16dfe720a
3 changed files with 101 additions and 10 deletions

View file

@ -4,6 +4,7 @@
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
#include <LibJS/Runtime/Array.h>
#include <LibWeb/Bindings/IDBIndexPrototype.h> #include <LibWeb/Bindings/IDBIndexPrototype.h>
#include <LibWeb/Bindings/Intrinsics.h> #include <LibWeb/Bindings/Intrinsics.h>
#include <LibWeb/HTML/EventNames.h> #include <LibWeb/HTML/EventNames.h>
@ -15,14 +16,17 @@ GC_DEFINE_ALLOCATOR(IDBIndex);
IDBIndex::~IDBIndex() = default; IDBIndex::~IDBIndex() = default;
IDBIndex::IDBIndex(JS::Realm& realm) IDBIndex::IDBIndex(JS::Realm& realm, GC::Ref<Index> index, GC::Ref<IDBObjectStore> object_store)
: PlatformObject(realm) : PlatformObject(realm)
, m_index(index)
, m_object_store_handle(object_store)
, m_name(index->name())
{ {
} }
GC::Ref<IDBIndex> IDBIndex::create(JS::Realm& realm) GC::Ref<IDBIndex> IDBIndex::create(JS::Realm& realm, GC::Ref<Index> index, GC::Ref<IDBObjectStore> object_store)
{ {
return realm.create<IDBIndex>(realm); return realm.create<IDBIndex>(realm, index, object_store);
} }
void IDBIndex::initialize(JS::Realm& realm) void IDBIndex::initialize(JS::Realm& realm)
@ -31,4 +35,68 @@ void IDBIndex::initialize(JS::Realm& realm)
WEB_SET_PROTOTYPE_FOR_INTERFACE(IDBIndex); WEB_SET_PROTOTYPE_FOR_INTERFACE(IDBIndex);
} }
void IDBIndex::visit_edges(Visitor& visitor)
{
Base::visit_edges(visitor);
visitor.visit(m_index);
visitor.visit(m_object_store_handle);
}
// https://w3c.github.io/IndexedDB/#dom-idbindex-name
WebIDL::ExceptionOr<void> IDBIndex::set_name(String const& value)
{
auto& realm = this->realm();
// 1. Let name be the given value.
auto const& name = value;
// 2. Let transaction be thiss transaction.
auto transaction = this->transaction();
// 3. Let index be thiss index.
auto index = this->index();
// 4. If transaction is not an upgrade transaction, throw an "InvalidStateError" DOMException.
if (!transaction->is_upgrade_transaction())
return WebIDL::InvalidStateError::create(realm, "Transaction is not an upgrade transaction"_string);
// 5. If transactions state is not active, then throw a "TransactionInactiveError" DOMException.
if (transaction->state() != IDBTransaction::TransactionState::Active)
return WebIDL::TransactionInactiveError::create(realm, "Transaction is not active"_string);
// FIXME: 6. If index or indexs object store has been deleted, throw an "InvalidStateError" DOMException.
// 7. If indexs name is equal to name, terminate these steps.
if (index->name() == name)
return {};
// 8. If an index named name already exists in indexs object store, throw a "ConstraintError" DOMException.
for (auto const& existing_index : m_object_store_handle->index_set()) {
if (existing_index->name() == name)
return WebIDL::ConstraintError::create(realm, "An index with the given name already exists"_string);
}
// 9. Set indexs name to name.
index->set_name(name);
// 10. Set thiss name to name.
m_name = name;
return {};
}
// https://w3c.github.io/IndexedDB/#dom-idbindex-keypath
JS::Value IDBIndex::key_path() const
{
return m_index->key_path().visit(
[&](String const& value) -> JS::Value {
return JS::PrimitiveString::create(realm().vm(), value);
},
[&](Vector<String> const& value) -> JS::Value {
return JS::Array::create_from<String>(realm(), value.span(), [&](auto const& entry) -> JS::Value {
return JS::PrimitiveString::create(realm().vm(), entry);
});
});
}
} }

View file

@ -8,6 +8,8 @@
#include <LibGC/Heap.h> #include <LibGC/Heap.h>
#include <LibWeb/Bindings/PlatformObject.h> #include <LibWeb/Bindings/PlatformObject.h>
#include <LibWeb/IndexedDB/IDBObjectStore.h>
#include <LibWeb/IndexedDB/Internal/Index.h>
namespace Web::IndexedDB { namespace Web::IndexedDB {
@ -18,11 +20,32 @@ class IDBIndex : public Bindings::PlatformObject {
public: public:
virtual ~IDBIndex() override; virtual ~IDBIndex() override;
[[nodiscard]] static GC::Ref<IDBIndex> create(JS::Realm&); [[nodiscard]] static GC::Ref<IDBIndex> create(JS::Realm&, GC::Ref<Index>, GC::Ref<IDBObjectStore>);
WebIDL::ExceptionOr<void> set_name(String const& value);
String name() const { return m_name; }
GC::Ref<IDBObjectStore> object_store() { return m_object_store_handle; }
JS::Value key_path() const;
bool multi_entry() const { return m_index->multi_entry(); }
bool unique() const { return m_index->unique(); }
// The transaction of an index handle is the transaction of its associated object store handle.
GC::Ref<IDBTransaction> transaction() { return m_object_store_handle->transaction(); }
GC::Ref<Index> index() { return m_index; }
GC::Ref<IDBObjectStore> store() { return m_object_store_handle; }
protected: protected:
explicit IDBIndex(JS::Realm&); explicit IDBIndex(JS::Realm&, GC::Ref<Index>, GC::Ref<IDBObjectStore>);
virtual void initialize(JS::Realm&) override; virtual void initialize(JS::Realm&) override;
virtual void visit_edges(Visitor& visitor) override;
private:
// An index handle has an associated index and an associated object store handle.
GC::Ref<Index> m_index;
GC::Ref<IDBObjectStore> m_object_store_handle;
// An index handle has a name, which is initialized to the name of the associated index when the index handle is created.
String m_name;
}; };
} }

View file

@ -2,11 +2,11 @@
[Exposed=(Window,Worker)] [Exposed=(Window,Worker)]
interface IDBIndex { interface IDBIndex {
[FIXME] attribute DOMString name; attribute DOMString name;
[FIXME, SameObject] readonly attribute IDBObjectStore objectStore; [SameObject] readonly attribute IDBObjectStore objectStore;
[FIXME] readonly attribute any keyPath; readonly attribute any keyPath;
[FIXME] readonly attribute boolean multiEntry; readonly attribute boolean multiEntry;
[FIXME] readonly attribute boolean unique; readonly attribute boolean unique;
[FIXME, NewObject] IDBRequest get(any query); [FIXME, NewObject] IDBRequest get(any query);
[FIXME, NewObject] IDBRequest getKey(any query); [FIXME, NewObject] IDBRequest getKey(any query);
[FIXME, NewObject] IDBRequest getAll(optional any query, optional [EnforceRange] unsigned long count); [FIXME, NewObject] IDBRequest getAll(optional any query, optional [EnforceRange] unsigned long count);