mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-07-31 21:29:06 +00:00
LibWeb/IDB: Implement IDBCursor::continue
This commit is contained in:
parent
f5eb7928d9
commit
64c4bea189
Notes:
github-actions[bot]
2025-05-06 09:17:37 +00:00
Author: https://github.com/stelar7
Commit: 64c4bea189
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/4524
Reviewed-by: https://github.com/gmta ✅
4 changed files with 82 additions and 15 deletions
|
@ -66,4 +66,70 @@ JS::Value IDBCursor::key()
|
|||
return convert_a_key_to_a_value(realm(), *m_key);
|
||||
}
|
||||
|
||||
// https://w3c.github.io/IndexedDB/#dom-idbcursor-continue
|
||||
WebIDL::ExceptionOr<void> IDBCursor::continue_(JS::Value key)
|
||||
{
|
||||
auto& realm = this->realm();
|
||||
|
||||
// 1. Let transaction be this's transaction.
|
||||
auto transaction = this->transaction();
|
||||
|
||||
// 2. If transaction’s 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 continuing cursor"_string);
|
||||
|
||||
// FIXME: 3. If this's source or effective object store has been deleted, throw an "InvalidStateError" DOMException
|
||||
|
||||
// 4. If this's got value flag is false, indicating that the cursor is being iterated or has iterated past its end, throw an "InvalidStateError" DOMException.
|
||||
if (!m_got_value)
|
||||
return WebIDL::InvalidStateError::create(realm, "Cursor is active or EOL"_string);
|
||||
|
||||
// 5. If key is given, then:
|
||||
GC::Ptr<Key> key_value;
|
||||
if (!key.is_undefined()) {
|
||||
// 1. Let r be the result of converting a value to a key with key. Rethrow any exceptions.
|
||||
auto r = TRY(convert_a_value_to_a_key(realm, key));
|
||||
|
||||
// 2. If r is invalid, throw a "DataError" DOMException.
|
||||
if (r->is_invalid())
|
||||
return WebIDL::DataError::create(realm, r->value_as_string());
|
||||
|
||||
// 3. Let key be r.
|
||||
key_value = r;
|
||||
|
||||
// 4. If key is less than or equal to this's position and this's direction is "next" or "nextunique", then throw a "DataError" DOMException.
|
||||
auto is_less_than_or_equal_to = Key::less_than(*key_value, *this->position()) || Key::equals(*key_value, *this->position());
|
||||
if (is_less_than_or_equal_to && (m_direction == Bindings::IDBCursorDirection::Next || m_direction == Bindings::IDBCursorDirection::Nextunique))
|
||||
return WebIDL::DataError::create(realm, "Key is less than or equal to cursor's position"_string);
|
||||
|
||||
// 5. If key is greater than or equal to this's position and this's direction is "prev" or "prevunique", then throw a "DataError" DOMException.
|
||||
auto is_greater_than_or_equal_to = Key::greater_than(*key_value, *this->position()) || Key::equals(*key_value, *this->position());
|
||||
if (is_greater_than_or_equal_to && (m_direction == Bindings::IDBCursorDirection::Prev || m_direction == Bindings::IDBCursorDirection::Prevunique))
|
||||
return WebIDL::DataError::create(realm, "Key is greater than or equal to cursor's position"_string);
|
||||
}
|
||||
|
||||
// 6. Set this's got value flag to false.
|
||||
m_got_value = false;
|
||||
|
||||
// 7. Let request be this's request.
|
||||
auto request = this->request();
|
||||
|
||||
// 8. Set request’s processed flag to false.
|
||||
request->set_processed(false);
|
||||
|
||||
// 9. Set request’s done flag to false.
|
||||
request->set_done(false);
|
||||
|
||||
// 10. Let operation be an algorithm to run iterate a cursor with the current Realm record, this, and key (if given).
|
||||
auto operation = GC::Function<WebIDL::ExceptionOr<JS::Value>()>::create(realm.heap(), [this, &realm, key_value] -> WebIDL::ExceptionOr<JS::Value> {
|
||||
return WebIDL::ExceptionOr<JS::Value>(iterate_a_cursor(realm, *this, key_value));
|
||||
});
|
||||
|
||||
// 11. Run asynchronously execute a request with this's source, operation, and request.
|
||||
asynchronously_execute_a_request(realm, GC::Ref(*this), operation, request);
|
||||
dbgln_if(IDB_DEBUG, "Executing request for cursor continue with uuid {}", request->uuid());
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -47,6 +47,8 @@ public:
|
|||
void set_value(JS::Value value) { m_value = value; }
|
||||
void set_object_store_position(GC::Ptr<Key> object_store_position) { m_object_store_position = object_store_position; }
|
||||
|
||||
WebIDL::ExceptionOr<void> continue_(JS::Value);
|
||||
|
||||
protected:
|
||||
explicit IDBCursor(JS::Realm&, GC::Ref<IDBTransaction>, GC::Ptr<Key>, Bindings::IDBCursorDirection, bool, GC::Ptr<Key>, JS::Value, CursorSource, GC::Ref<IDBKeyRange>, bool);
|
||||
virtual void initialize(JS::Realm&) override;
|
||||
|
|
|
@ -8,7 +8,7 @@ interface IDBCursor {
|
|||
[FIXME] readonly attribute any primaryKey;
|
||||
[SameObject] readonly attribute IDBRequest request;
|
||||
[FIXME] undefined advance([EnforceRange] unsigned long count);
|
||||
[FIXME] undefined continue(optional any key);
|
||||
undefined continue(optional any key);
|
||||
[FIXME] undefined continuePrimaryKey(any key, any primaryKey);
|
||||
[FIXME, NewObject] IDBRequest update(any value);
|
||||
[FIXME, NewObject] IDBRequest delete();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue