LibWeb/IDB: Implement IDBIndex::openKeyCursor

This commit is contained in:
stelar7 2025-05-13 22:59:45 +02:00 committed by Jelle Raaijmakers
parent 852323009f
commit c73b8d1fa0
Notes: github-actions[bot] 2025-05-14 15:19:07 +00:00
3 changed files with 41 additions and 1 deletions

View file

@ -296,4 +296,43 @@ WebIDL::ExceptionOr<GC::Ref<IDBRequest>> IDBIndex::count(JS::Value query)
return result;
}
// https://w3c.github.io/IndexedDB/#dom-idbindex-openkeycursor
WebIDL::ExceptionOr<GC::Ref<IDBRequest>> IDBIndex::open_key_cursor(JS::Value query, Bindings::IDBCursorDirection direction)
{
auto& realm = this->realm();
// 1. Let transaction be thiss transaction.
auto transaction = this->transaction();
// 2. Let index be thiss index.
[[maybe_unused]] auto index = this->index();
// FIXME: 3. If index or indexs object store has been deleted, throw an "InvalidStateError" DOMException.
// 4. 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 while opening key cursor"_string);
// 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, query));
// 6. Let cursor be a new cursor with its source handle set to this, undefined position, direction set to direction, got value flag set to false, undefined key and value, range set to range, and key only flag set to true.
auto cursor = IDBCursor::create(realm, GC::Ref(*this), {}, direction, IDBCursor::GotValue::No, {}, {}, range, IDBCursor::KeyOnly::Yes);
// 7. Let operation be an algorithm to run iterate a cursor with the current Realm record and cursor.
auto operation = GC::Function<WebIDL::ExceptionOr<JS::Value>()>::create(realm.heap(), [&realm, cursor] -> WebIDL::ExceptionOr<JS::Value> {
return WebIDL::ExceptionOr<JS::Value>(iterate_a_cursor(realm, cursor));
});
// 8. Let request be the result of running asynchronously execute a request with this and operation.
auto request = asynchronously_execute_a_request(realm, GC::Ref(*this), operation);
dbgln_if(IDB_DEBUG, "Executing request for open key cursor with uuid {}", request->uuid());
// 9. Set cursors request to request.
cursor->set_request(request);
// 10. Return request.
return request;
}
}