From 609f7aa65925294e6776ef6ddc106d8f4bee913c Mon Sep 17 00:00:00 2001 From: stelar7 Date: Sun, 1 Dec 2024 21:12:35 +0100 Subject: [PATCH] LibWeb: Implement IDBFactory::delete_database --- Libraries/LibWeb/IndexedDB/IDBFactory.cpp | 55 +++++++++++++++++++++++ Libraries/LibWeb/IndexedDB/IDBFactory.h | 2 + Libraries/LibWeb/IndexedDB/IDBFactory.idl | 2 +- 3 files changed, 58 insertions(+), 1 deletion(-) diff --git a/Libraries/LibWeb/IndexedDB/IDBFactory.cpp b/Libraries/LibWeb/IndexedDB/IDBFactory.cpp index 2c2ccbebe10..f7314ddaacc 100644 --- a/Libraries/LibWeb/IndexedDB/IDBFactory.cpp +++ b/Libraries/LibWeb/IndexedDB/IDBFactory.cpp @@ -115,4 +115,59 @@ WebIDL::ExceptionOr IDBFactory::cmp(JS::Value first, JS::Value second) return Key::compare_two_keys(a.release_value(), b.release_value()); } +// https://w3c.github.io/IndexedDB/#dom-idbfactory-deletedatabase +WebIDL::ExceptionOr> IDBFactory::delete_database(String const& name) +{ + auto& realm = this->realm(); + + // 1. Let environment be this's relevant settings object. + auto& environment = HTML::relevant_settings_object(*this); + + // 2. Let storageKey be the result of running obtain a storage key given environment. + // If failure is returned, then throw a "SecurityError" DOMException and abort these steps. + auto storage_key = StorageAPI::obtain_a_storage_key(environment); + if (!storage_key.has_value()) + return WebIDL::SecurityError::create(realm, "Failed to obtain a storage key"_string); + + // 3. Let request be a new open request. + auto request = IDBOpenDBRequest::create(realm); + + // 4. Run these steps in parallel: + Platform::EventLoopPlugin::the().deferred_invoke(GC::create_function(realm.heap(), [&realm, storage_key, name, request] { + HTML::TemporaryExecutionContext context(realm, HTML::TemporaryExecutionContext::CallbacksEnabled::Yes); + + // 1. Let result be the result of deleting a database, with storageKey, name, and request. + auto result = delete_a_database(realm, storage_key.value(), name, request); + + // 2. Set request’s processed flag to true. + request->set_processed(true); + + // 3. Queue a task to run these steps: + HTML::queue_a_task(HTML::Task::Source::DatabaseAccess, nullptr, nullptr, GC::create_function(realm.heap(), [&realm, request, result = move(result)]() mutable { + // 1. If result is an error, + if (result.is_error()) { + // set request’s error to result, + request->set_error(result.exception().get>()); + // set request’s done flag to true, + request->set_done(true); + // and fire an event named error at request with its bubbles and cancelable attributes initialized to true. + request->dispatch_event(DOM::Event::create(realm, HTML::EventNames::error, { .bubbles = true, .cancelable = true })); + } + // 2. Otherwise, + else { + // set request’s result to undefined, + request->set_result(JS::js_undefined()); + // set request’s done flag to true, + request->set_done(true); + // and fire a version change event named success at request with result and null. + auto value = result.release_value(); + fire_a_version_change_event(realm, HTML::EventNames::success, request, value, {}); + } + })); + })); + + // 5. Return a new IDBOpenDBRequest object for request. + return request; +} + } diff --git a/Libraries/LibWeb/IndexedDB/IDBFactory.h b/Libraries/LibWeb/IndexedDB/IDBFactory.h index b913672a1e2..ab7841b6e3a 100644 --- a/Libraries/LibWeb/IndexedDB/IDBFactory.h +++ b/Libraries/LibWeb/IndexedDB/IDBFactory.h @@ -21,6 +21,8 @@ public: virtual ~IDBFactory() override; WebIDL::ExceptionOr> open(String const& name, Optional version); + WebIDL::ExceptionOr> delete_database(String const& name); + WebIDL::ExceptionOr cmp(JS::Value first, JS::Value second); protected: diff --git a/Libraries/LibWeb/IndexedDB/IDBFactory.idl b/Libraries/LibWeb/IndexedDB/IDBFactory.idl index 5f57f2afb35..7edba81121d 100644 --- a/Libraries/LibWeb/IndexedDB/IDBFactory.idl +++ b/Libraries/LibWeb/IndexedDB/IDBFactory.idl @@ -2,7 +2,7 @@ [Exposed=(Window,Worker)] interface IDBFactory { [NewObject] IDBOpenDBRequest open(DOMString name, optional [EnforceRange] unsigned long long version); - [FIXME, NewObject] IDBOpenDBRequest deleteDatabase(DOMString name); + [NewObject] IDBOpenDBRequest deleteDatabase(DOMString name); [FIXME] Promise> databases();