From bb31b682a58a2c2f9dca6966957b8658b85df0e5 Mon Sep 17 00:00:00 2001 From: stelar7 Date: Thu, 7 Nov 2024 20:33:25 +0100 Subject: [PATCH] LibWeb: Implement IDBDatabase::close() --- Libraries/LibWeb/IndexedDB/IDBDatabase.h | 9 +++++++++ Libraries/LibWeb/IndexedDB/IDBDatabase.idl | 2 +- .../LibWeb/IndexedDB/Internal/Algorithms.cpp | 16 ++++++++++++++++ Libraries/LibWeb/IndexedDB/Internal/Algorithms.h | 1 + 4 files changed, 27 insertions(+), 1 deletion(-) diff --git a/Libraries/LibWeb/IndexedDB/IDBDatabase.h b/Libraries/LibWeb/IndexedDB/IDBDatabase.h index cc02d21c4ed..e1085f890d2 100644 --- a/Libraries/LibWeb/IndexedDB/IDBDatabase.h +++ b/Libraries/LibWeb/IndexedDB/IDBDatabase.h @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -35,6 +36,7 @@ public: void set_version(u64 version) { m_version = version; } void set_close_pending(bool close_pending) { m_close_pending = close_pending; } + void set_state(ConnectionState state) { m_state = state; } [[nodiscard]] GC::Ref object_store_names() { return m_object_store_names; } [[nodiscard]] String name() const { return m_name; } @@ -43,6 +45,13 @@ public: [[nodiscard]] ConnectionState state() const { return m_state; } [[nodiscard]] GC::Ref associated_database() { return m_associated_database; } + // https://w3c.github.io/IndexedDB/#dom-idbdatabase-close + void close() + { + // 1. Run close a database connection with this connection. + close_a_database_connection(*this); + } + void set_onabort(WebIDL::CallbackType*); WebIDL::CallbackType* onabort(); void set_onclose(WebIDL::CallbackType*); diff --git a/Libraries/LibWeb/IndexedDB/IDBDatabase.idl b/Libraries/LibWeb/IndexedDB/IDBDatabase.idl index 2b396057514..917441e482f 100644 --- a/Libraries/LibWeb/IndexedDB/IDBDatabase.idl +++ b/Libraries/LibWeb/IndexedDB/IDBDatabase.idl @@ -8,7 +8,7 @@ interface IDBDatabase : EventTarget { readonly attribute DOMStringList objectStoreNames; [FIXME, NewObject] IDBTransaction transaction((DOMString or sequence) storeNames, optional IDBTransactionMode mode = "readonly", optional IDBTransactionOptions options = {}); - [FIXME] undefined close(); + undefined close(); [FIXME, NewObject] IDBObjectStore createObjectStore(DOMString name, optional IDBObjectStoreParameters options = {}); [FIXME] undefined deleteObjectStore(DOMString name); diff --git a/Libraries/LibWeb/IndexedDB/Internal/Algorithms.cpp b/Libraries/LibWeb/IndexedDB/Internal/Algorithms.cpp index 097a822eb05..9a35879d97f 100644 --- a/Libraries/LibWeb/IndexedDB/Internal/Algorithms.cpp +++ b/Libraries/LibWeb/IndexedDB/Internal/Algorithms.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -266,4 +267,19 @@ ErrorOr convert_a_value_to_a_key(JS::Realm& realm, JS::Value input, Vector< return Error::from_string_literal("Unknown key type"); } +// https://w3c.github.io/IndexedDB/#close-a-database-connection +void close_a_database_connection(IDBDatabase& connection, bool forced) +{ + // 1. Set connection’s close pending flag to true. + connection.set_close_pending(true); + + // FIXME: 2. If the forced flag is true, then for each transaction created using connection run abort a transaction with transaction and newly created "AbortError" DOMException. + // FIXME: 3. Wait for all transactions created using connection to complete. Once they are complete, connection is closed. + connection.set_state(IDBDatabase::ConnectionState::Closed); + + // 4. If the forced flag is true, then fire an event named close at connection. + if (forced) + connection.dispatch_event(DOM::Event::create(connection.realm(), HTML::EventNames::close)); +} + } diff --git a/Libraries/LibWeb/IndexedDB/Internal/Algorithms.h b/Libraries/LibWeb/IndexedDB/Internal/Algorithms.h index 22562eafa84..175ba0311fb 100644 --- a/Libraries/LibWeb/IndexedDB/Internal/Algorithms.h +++ b/Libraries/LibWeb/IndexedDB/Internal/Algorithms.h @@ -16,5 +16,6 @@ namespace Web::IndexedDB { WebIDL::ExceptionOr> open_a_database_connection(JS::Realm&, StorageAPI::StorageKey, String, Optional, GC::Ref); bool fire_a_version_change_event(JS::Realm&, FlyString const&, GC::Ref, u64, Optional); ErrorOr convert_a_value_to_a_key(JS::Realm&, JS::Value, Vector = {}); +void close_a_database_connection(IDBDatabase&, bool forced = false); }