LibWeb: Implement CookieStore::getAll(name)

This commit is contained in:
Idan Horowitz 2025-08-05 23:52:27 +03:00 committed by Tim Flynn
parent 5545d38d7a
commit 536158878d
3 changed files with 55 additions and 0 deletions

View File

@ -4,6 +4,7 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibJS/Runtime/Array.h>
#include <LibWeb/Bindings/CookieStorePrototype.h>
#include <LibWeb/Bindings/Intrinsics.h>
#include <LibWeb/CookieStore/CookieStore.h>
@ -129,4 +130,52 @@ GC::Ref<WebIDL::Promise> CookieStore::get(String name)
return promise;
}
static JS::Value cookie_list_to_value(JS::Realm& realm, Vector<CookieListItem> const& cookie_list)
{
return JS::Array::create_from<CookieListItem>(realm, cookie_list, [&](auto const& cookie) {
return Bindings::cookie_list_item_to_value(realm, cookie);
});
}
// https://cookiestore.spec.whatwg.org/#dom-cookiestore-getall
GC::Ref<WebIDL::Promise> CookieStore::get_all(String name)
{
auto& realm = this->realm();
// 1. Let settings be thiss relevant settings object.
auto const& settings = HTML::relevant_settings_object(*this);
// 2. Let origin be settingss origin.
auto const& origin = settings.origin();
// 3. If origin is an opaque origin, then return a promise rejected with a "SecurityError" DOMException.
if (origin.is_opaque())
return WebIDL::create_rejected_promise(realm, WebIDL::SecurityError::create(realm, "Document origin is opaque"_string));
// 4. Let url be settingss creation URL.
auto url = settings.creation_url;
// 5. Let p be a new promise.
auto promise = WebIDL::create_promise(realm);
// 6. Run the following steps in parallel:
Platform::EventLoopPlugin::the().deferred_invoke(GC::create_function(realm.heap(), [&realm, client = m_client, promise, url = move(url), name = move(name)]() {
// 1. Let list be the results of running query cookies with url and name.
auto list = query_cookies(client, url, name);
// AD-HOC: Queue a global task to perform the next steps
// Spec issue: https://github.com/whatwg/cookiestore/issues/239
queue_global_task(HTML::Task::Source::Unspecified, realm.global_object(), GC::create_function(realm.heap(), [&realm, promise, list = move(list)]() {
HTML::TemporaryExecutionContext execution_context { realm };
// 2. If list is failure, then reject p with a TypeError and abort these steps.
// 3. Otherwise, resolve p with list.
WebIDL::resolve_promise(realm, promise, cookie_list_to_value(realm, list));
}));
}));
// 7. Return p.
return promise;
}
}

View File

@ -27,6 +27,8 @@ class CookieStore final : public DOM::EventTarget {
public:
GC::Ref<WebIDL::Promise> get(String name);
GC::Ref<WebIDL::Promise> get_all(String name);
private:
CookieStore(JS::Realm&, PageClient&);

View File

@ -9,10 +9,14 @@ dictionary CookieListItem {
USVString value;
};
typedef sequence<CookieListItem> CookieList;
// https://cookiestore.spec.whatwg.org/#cookiestore
[Exposed=(ServiceWorker,Window), SecureContext]
interface CookieStore : EventTarget {
Promise<CookieListItem?> get(USVString name);
Promise<CookieList> getAll(USVString name);
};
// https://cookiestore.spec.whatwg.org/#Window