LibWeb/IDB: Update IDBObjectStore::get_all_keys to spec

This commit is contained in:
stelar7 2025-07-09 15:54:13 +02:00 committed by Jelle Raaijmakers
commit 6f756f7f6c
Notes: github-actions[bot] 2025-08-27 14:15:24 +00:00

View file

@ -666,9 +666,10 @@ WebIDL::ExceptionOr<GC::Ref<IDBRequest>> IDBObjectStore::open_key_cursor(JS::Val
}
// https://w3c.github.io/IndexedDB/#dom-idbobjectstore-getallkeys
WebIDL::ExceptionOr<GC::Ref<IDBRequest>> IDBObjectStore::get_all_keys(Optional<JS::Value> query, Optional<WebIDL::UnsignedLong> count)
WebIDL::ExceptionOr<GC::Ref<IDBRequest>> IDBObjectStore::get_all_keys(Optional<JS::Value> query_or_options, Optional<WebIDL::UnsignedLong> count)
{
auto& realm = this->realm();
auto& vm = realm.vm();
// 1. Let transaction be thiss transaction.
auto transaction = this->transaction();
@ -682,15 +683,49 @@ WebIDL::ExceptionOr<GC::Ref<IDBRequest>> IDBObjectStore::get_all_keys(Optional<J
if (!transaction->is_active())
return WebIDL::TransactionInactiveError::create(realm, "Transaction is not active while getting all keys"_utf16);
// 5. Let range be the result of converting a value to a key range with query. Rethrow any exceptions.
auto range = TRY(convert_a_value_to_a_key_range(realm, move(query)));
// 5. Let range be a key range.
GC::Ptr<IDBKeyRange> range;
// 6. Let operation be an algorithm to run retrieve multiple keys from an object store with store, range, and count if given.
auto operation = GC::Function<WebIDL::ExceptionOr<JS::Value>()>::create(realm.heap(), [&realm, store, range, count] -> WebIDL::ExceptionOr<JS::Value> {
return retrieve_multiple_keys_from_an_object_store(realm, store, range, count);
// 6. Let direction be a cursor direction.
Bindings::IDBCursorDirection direction = Bindings::IDBCursorDirection::Next;
// 7. If running is a potentially valid key range with query_or_options is true, then:
if (is_a_potentially_valid_key_range(realm, *query_or_options)) {
// 1. Set range to the result of converting a value to a key range with query_or_options. Rethrow any exceptions.
range = TRY(convert_a_value_to_a_key_range(realm, query_or_options));
// 2. Set direction to "next".
direction = Bindings::IDBCursorDirection::Next;
}
// 8. Else:
else {
// 1. Set range to the result of converting a value to a key range with query_or_options["query"]. Rethrow any exceptions.
range = TRY(convert_a_value_to_a_key_range(realm, TRY(query_or_options->get(vm, "query"_utf16))));
// 2. Set count to query_or_options["count"].
count = TRY(TRY(query_or_options->get(vm, "count"_utf16)).to_u32(vm));
// 3. Set direction to query_or_options["direction"].
auto direction_value = TRY(TRY(query_or_options->get(vm, "direction"_utf16)).to_string(vm));
if (direction_value == "next")
direction = Bindings::IDBCursorDirection::Next;
else if (direction_value == "nextunique")
direction = Bindings::IDBCursorDirection::Nextunique;
else if (direction_value == "prev")
direction = Bindings::IDBCursorDirection::Prev;
else if (direction_value == "prevunique")
direction = Bindings::IDBCursorDirection::Prevunique;
else
return WebIDL::SimpleException { WebIDL::SimpleExceptionType::TypeError, "Invalid direction value"_string };
}
// 9. Let operation be an algorithm to run retrieve multiple items from an object store with the current Realm record, store, range, "key", direction, and count if given.
auto operation = GC::Function<WebIDL::ExceptionOr<JS::Value>()>::create(realm.heap(), [&realm, store, range, direction, count] -> WebIDL::ExceptionOr<JS::Value> {
return retrieve_multiple_items_from_an_object_store(realm, store, GC::Ref(*range), RecordKind::Key, direction, count);
});
// 7. Return the result (an IDBRequest) of running asynchronously execute a request with this and operation.
// 10. Return the result (an IDBRequest) of running asynchronously execute a request with this and operation.
auto result = asynchronously_execute_a_request(realm, GC::Ref(*this), operation);
dbgln_if(IDB_DEBUG, "Executing request for get all keys with uuid {}", result->uuid());
return result;