mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-10-22 16:09:23 +00:00
LibWeb: Implement CookieStore::get(name)
This commit is contained in:
parent
dc1b7b1925
commit
5545d38d7a
Notes:
github-actions[bot]
2025-08-08 17:12:25 +00:00
Author: https://github.com/IdanHo
Commit: 5545d38d7a
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/5766
Reviewed-by: https://github.com/trflynn89 ✅
14 changed files with 174 additions and 17 deletions
|
@ -7,13 +7,20 @@
|
|||
#include <LibWeb/Bindings/CookieStorePrototype.h>
|
||||
#include <LibWeb/Bindings/Intrinsics.h>
|
||||
#include <LibWeb/CookieStore/CookieStore.h>
|
||||
#include <LibWeb/HTML/Scripting/Environments.h>
|
||||
#include <LibWeb/HTML/Scripting/TemporaryExecutionContext.h>
|
||||
#include <LibWeb/Page/Page.h>
|
||||
#include <LibWeb/Platform/EventLoopPlugin.h>
|
||||
#include <LibWeb/WebIDL/DOMException.h>
|
||||
#include <LibWeb/WebIDL/Promise.h>
|
||||
|
||||
namespace Web::CookieStore {
|
||||
|
||||
GC_DEFINE_ALLOCATOR(CookieStore);
|
||||
|
||||
CookieStore::CookieStore(JS::Realm& realm)
|
||||
CookieStore::CookieStore(JS::Realm& realm, PageClient& client)
|
||||
: DOM::EventTarget(realm)
|
||||
, m_client(client)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -23,4 +30,103 @@ void CookieStore::initialize(JS::Realm& realm)
|
|||
Base::initialize(realm);
|
||||
}
|
||||
|
||||
void CookieStore::visit_edges(Cell::Visitor& visitor)
|
||||
{
|
||||
Base::visit_edges(visitor);
|
||||
|
||||
visitor.visit(m_client);
|
||||
}
|
||||
|
||||
// https://cookiestore.spec.whatwg.org/#create-a-cookielistitem
|
||||
static CookieListItem create_a_cookie_list_item(Cookie::Cookie const& cookie)
|
||||
{
|
||||
// 1. Let name be the result of running UTF-8 decode without BOM on cookie’s name.
|
||||
// 2. Let value be the result of running UTF-8 decode without BOM on cookie’s value.
|
||||
// 3. Return «[ "name" → name, "value" → value ]»
|
||||
return CookieListItem {
|
||||
.name = cookie.name,
|
||||
.value = cookie.value,
|
||||
};
|
||||
}
|
||||
|
||||
// https://cookiestore.spec.whatwg.org/#query-cookies
|
||||
static Vector<CookieListItem> query_cookies(PageClient& client, URL::URL const& url, Optional<String> const& name)
|
||||
{
|
||||
// 1. Perform the steps defined in Cookies § Retrieval Model to compute the "cookie-string from a given cookie store"
|
||||
// with url as request-uri. The cookie-string itself is ignored, but the intermediate cookie-list is used in subsequent steps.
|
||||
// For the purposes of the steps, the cookie-string is being generated for a "non-HTTP" API.
|
||||
auto cookie_list = client.page_did_request_all_cookies_cookiestore(url);
|
||||
|
||||
// 2. Let list be a new list.
|
||||
Vector<CookieListItem> list;
|
||||
|
||||
// 3. For each cookie in cookie-list, run these steps:
|
||||
for (auto const& cookie : cookie_list) {
|
||||
// 1. Assert: cookie’s http-only-flag is false.
|
||||
VERIFY(!cookie.http_only);
|
||||
|
||||
// 2. If name is given, then run these steps:
|
||||
if (name.has_value()) {
|
||||
// 1. Let cookieName be the result of running UTF-8 decode without BOM on cookie’s name.
|
||||
// 2. If cookieName does not equal name, then continue.
|
||||
if (cookie.name != name.value())
|
||||
continue;
|
||||
}
|
||||
// 3. Let item be the result of running create a CookieListItem from cookie.
|
||||
auto item = create_a_cookie_list_item(cookie);
|
||||
|
||||
// 4. Append item to list.
|
||||
list.append(move(item));
|
||||
}
|
||||
|
||||
// 4. Return list.
|
||||
return list;
|
||||
}
|
||||
|
||||
// https://cookiestore.spec.whatwg.org/#dom-cookiestore-get
|
||||
GC::Ref<WebIDL::Promise> CookieStore::get(String name)
|
||||
{
|
||||
auto& realm = this->realm();
|
||||
|
||||
// 1. Let settings be this’s relevant settings object.
|
||||
auto const& settings = HTML::relevant_settings_object(*this);
|
||||
|
||||
// 2. Let origin be settings’s 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 settings’s 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. If list is empty, then resolve p with null.
|
||||
if (list.is_empty())
|
||||
WebIDL::resolve_promise(realm, promise, JS::js_null());
|
||||
|
||||
// 4. Otherwise, resolve p with the first item of list.
|
||||
else
|
||||
WebIDL::resolve_promise(realm, promise, Bindings::cookie_list_item_to_value(realm, list[0]));
|
||||
}));
|
||||
}));
|
||||
|
||||
// 7. Return p.
|
||||
return promise;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue