LibWeb/IDB: Fillout IDBIndex attributes

This commit is contained in:
stelar7 2025-04-01 18:36:39 +02:00 committed by Andrew Kaster
parent 9321ad04c0
commit a235dd4300
Notes: github-actions[bot] 2025-04-09 17:50:51 +00:00
3 changed files with 101 additions and 10 deletions

View file

@ -4,6 +4,7 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibJS/Runtime/Array.h>
#include <LibWeb/Bindings/IDBIndexPrototype.h>
#include <LibWeb/Bindings/Intrinsics.h>
#include <LibWeb/HTML/EventNames.h>
@ -15,14 +16,17 @@ GC_DEFINE_ALLOCATOR(IDBIndex);
IDBIndex::~IDBIndex() = default;
IDBIndex::IDBIndex(JS::Realm& realm)
IDBIndex::IDBIndex(JS::Realm& realm, GC::Ref<Index> index, GC::Ref<IDBObjectStore> object_store)
: 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)
@ -31,4 +35,68 @@ void IDBIndex::initialize(JS::Realm& realm)
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 <LibWeb/Bindings/PlatformObject.h>
#include <LibWeb/IndexedDB/IDBObjectStore.h>
#include <LibWeb/IndexedDB/Internal/Index.h>
namespace Web::IndexedDB {
@ -18,11 +20,32 @@ class IDBIndex : public Bindings::PlatformObject {
public:
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:
explicit IDBIndex(JS::Realm&);
explicit IDBIndex(JS::Realm&, GC::Ref<Index>, GC::Ref<IDBObjectStore>);
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)]
interface IDBIndex {
[FIXME] attribute DOMString name;
[FIXME, SameObject] readonly attribute IDBObjectStore objectStore;
[FIXME] readonly attribute any keyPath;
[FIXME] readonly attribute boolean multiEntry;
[FIXME] readonly attribute boolean unique;
attribute DOMString name;
[SameObject] readonly attribute IDBObjectStore objectStore;
readonly attribute any keyPath;
readonly attribute boolean multiEntry;
readonly attribute boolean unique;
[FIXME, NewObject] IDBRequest get(any query);
[FIXME, NewObject] IDBRequest getKey(any query);
[FIXME, NewObject] IDBRequest getAll(optional any query, optional [EnforceRange] unsigned long count);