diff --git a/Libraries/LibWeb/IndexedDB/IDBCursor.cpp b/Libraries/LibWeb/IndexedDB/IDBCursor.cpp index ec52f9de8a0..f58e8c67e0b 100644 --- a/Libraries/LibWeb/IndexedDB/IDBCursor.cpp +++ b/Libraries/LibWeb/IndexedDB/IDBCursor.cpp @@ -381,4 +381,43 @@ WebIDL::ExceptionOr> IDBCursor::update(JS::Value value) return request; } +// https://w3c.github.io/IndexedDB/#dom-idbcursor-update +WebIDL::ExceptionOr> IDBCursor::delete_() +{ + 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 deleting cursor"_string); + + // 3. If transaction is a read-only transaction, throw a "ReadOnlyError" DOMException. + if (transaction->is_readonly()) + return WebIDL::ReadOnlyError::create(realm, "Transaction is read-only while deleting cursor"_string); + + // FIXME: 4. If this’s source or effective object store has been deleted, throw an "InvalidStateError" DOMException. + + // 5. 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 while deleting"_string); + + // 6. If this’s key only flag is true, throw an "InvalidStateError" DOMException. + if (m_key_only) + return WebIDL::InvalidStateError::create(realm, "Cursor is key-only while deleting"_string); + + // 7. Let operation be an algorithm to run delete records from an object store with this’s effective object store and this’s effective key. + auto operation = GC::Function()>::create(realm.heap(), [this, &realm] -> WebIDL::ExceptionOr { + auto effective_key = this->effective_key(); + auto range = IDBKeyRange::create(realm, effective_key, effective_key, IDBKeyRange::LowerOpen::No, IDBKeyRange::UpperOpen::No); + return delete_records_from_an_object_store(*this->effective_object_store(), range); + }); + + // 8. Return the result (an IDBRequest) 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 cursor delete with uuid {}", request->uuid()); + return request; +} + } diff --git a/Libraries/LibWeb/IndexedDB/IDBCursor.h b/Libraries/LibWeb/IndexedDB/IDBCursor.h index 74840171455..1d3efccad4b 100644 --- a/Libraries/LibWeb/IndexedDB/IDBCursor.h +++ b/Libraries/LibWeb/IndexedDB/IDBCursor.h @@ -50,6 +50,7 @@ public: WebIDL::ExceptionOr continue_primary_key(JS::Value, JS::Value); WebIDL::ExceptionOr> update(JS::Value); + WebIDL::ExceptionOr> delete_(); [[nodiscard]] JS::Value value() { return m_value.value_or(JS::js_undefined()); } [[nodiscard]] GC::Ref range() { return m_range; } diff --git a/Libraries/LibWeb/IndexedDB/IDBCursor.idl b/Libraries/LibWeb/IndexedDB/IDBCursor.idl index 314660e03c0..54aeb7c46c0 100644 --- a/Libraries/LibWeb/IndexedDB/IDBCursor.idl +++ b/Libraries/LibWeb/IndexedDB/IDBCursor.idl @@ -11,7 +11,7 @@ interface IDBCursor { undefined continue(optional any key); undefined continuePrimaryKey(any key, any primaryKey); [NewObject] IDBRequest update(any value); - [FIXME, NewObject] IDBRequest delete(); + [NewObject] IDBRequest delete(); }; enum IDBCursorDirection {