LibWeb: Implement CacheStorage.open
This commit is contained in:
parent
80b612b789
commit
0d2f0a6ed9
6 changed files with 127 additions and 3 deletions
|
|
@ -905,6 +905,7 @@ set(SOURCES
|
|||
ServiceWorker/CacheStorage.cpp
|
||||
ServiceWorker/EventNames.cpp
|
||||
ServiceWorker/Job.cpp
|
||||
ServiceWorker/NameToCacheMap.cpp
|
||||
ServiceWorker/Registration.cpp
|
||||
ServiceWorker/ServiceWorker.cpp
|
||||
ServiceWorker/ServiceWorkerContainer.cpp
|
||||
|
|
|
|||
|
|
@ -1,11 +1,15 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
|
||||
* Copyright (c) 2026, Tim Flynn <trflynn89@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibWeb/Bindings/CacheStoragePrototype.h>
|
||||
#include <LibWeb/Bindings/Intrinsics.h>
|
||||
#include <LibWeb/HTML/Scripting/TemporaryExecutionContext.h>
|
||||
#include <LibWeb/Platform/EventLoopPlugin.h>
|
||||
#include <LibWeb/ServiceWorker/Cache.h>
|
||||
#include <LibWeb/ServiceWorker/CacheStorage.h>
|
||||
#include <LibWeb/WebIDL/Promise.h>
|
||||
|
||||
|
|
@ -24,10 +28,10 @@ void CacheStorage::initialize(JS::Realm& realm)
|
|||
WEB_SET_PROTOTYPE_FOR_INTERFACE(CacheStorage);
|
||||
}
|
||||
|
||||
// https://w3c.github.io/ServiceWorker/#cache-storage-open
|
||||
GC::Ref<WebIDL::Promise> CacheStorage::open(String const&)
|
||||
void CacheStorage::visit_edges(Visitor& visitor)
|
||||
{
|
||||
return WebIDL::create_rejected_promise(realm(), WebIDL::NotSupportedError::create(realm(), "CacheStorage.open() is not yet implemented"_utf16));
|
||||
Base::visit_edges(visitor);
|
||||
visitor.visit(m_relevant_name_to_cache_map);
|
||||
}
|
||||
|
||||
// https://w3c.github.io/ServiceWorker/#cache-storage-has
|
||||
|
|
@ -37,4 +41,54 @@ GC::Ref<WebIDL::Promise> CacheStorage::has(String const&)
|
|||
return WebIDL::create_rejected_promise(realm(), JS::Value(false));
|
||||
}
|
||||
|
||||
// https://w3c.github.io/ServiceWorker/#cache-storage-open
|
||||
GC::Ref<WebIDL::Promise> CacheStorage::open(String const& cache_name)
|
||||
{
|
||||
auto& realm = HTML::relevant_realm(*this);
|
||||
|
||||
// 1. Let promise be a new promise.
|
||||
auto promise = WebIDL::create_promise(realm);
|
||||
|
||||
// 2. Run the following substeps in parallel:
|
||||
Platform::EventLoopPlugin::the().deferred_invoke(GC::create_function(realm.heap(), [this, &realm, promise, cache_name]() {
|
||||
HTML::TemporaryExecutionContext context { realm, HTML::TemporaryExecutionContext::CallbacksEnabled::Yes };
|
||||
auto& relevant_name_to_cache_map = this->relevant_name_to_cache_map();
|
||||
|
||||
// 1. For each key → value of the relevant name to cache map:
|
||||
// 1. If cacheName matches key, then:
|
||||
if (auto value = relevant_name_to_cache_map.get(cache_name); value.has_value()) {
|
||||
// 1. Resolve promise with a new Cache object that represents value.
|
||||
WebIDL::resolve_promise(realm, promise, realm.create<Cache>(realm, value.release_value()));
|
||||
|
||||
// 2. Abort these steps.
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. Let cache be a new request response list.
|
||||
auto cache = realm.heap().allocate<RequestResponseList>();
|
||||
|
||||
// 3. Set the relevant name to cache map[cacheName] to cache. If this cache write operation failed due to
|
||||
// exceeding the granted quota limit, reject promise with a QuotaExceededError and abort these steps.
|
||||
// FIXME: Handle cache quotas.
|
||||
relevant_name_to_cache_map.set(cache_name, cache);
|
||||
|
||||
// 4. Resolve promise with a new Cache object that represents cache.
|
||||
WebIDL::resolve_promise(realm, promise, realm.create<Cache>(realm, cache));
|
||||
}));
|
||||
|
||||
// 3. Return promise.
|
||||
return promise;
|
||||
}
|
||||
|
||||
// https://w3c.github.io/ServiceWorker/#relevant-name-to-cache-map
|
||||
NameToCacheMap& CacheStorage::relevant_name_to_cache_map()
|
||||
{
|
||||
// The relevant name to cache map for a CacheStorage object is the name to cache map associated with the result of
|
||||
// running obtain a local storage bottle map with the object’s relevant settings object and "caches".
|
||||
|
||||
// FIXME: We don't yet have a way to serialize request/response pairs for storage in the UI process. For now, we
|
||||
// use an ephemeral name to cache map.
|
||||
return m_relevant_name_to_cache_map;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
|
||||
* Copyright (c) 2026, Tim Flynn <trflynn89@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
|
@ -7,6 +8,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <LibWeb/Bindings/PlatformObject.h>
|
||||
#include <LibWeb/ServiceWorker/NameToCacheMap.h>
|
||||
#include <LibWeb/WebIDL/Promise.h>
|
||||
|
||||
namespace Web::ServiceWorker {
|
||||
|
|
@ -24,6 +26,11 @@ private:
|
|||
explicit CacheStorage(JS::Realm&);
|
||||
|
||||
virtual void initialize(JS::Realm&) override;
|
||||
virtual void visit_edges(Visitor&) override;
|
||||
|
||||
NameToCacheMap& relevant_name_to_cache_map();
|
||||
|
||||
NameToCacheMap m_relevant_name_to_cache_map;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#import <Fetch/Request.idl>
|
||||
#import <ServiceWorker/Cache.idl>
|
||||
|
||||
// https://w3c.github.io/ServiceWorker/#cachestorage-interface
|
||||
[SecureContext, Exposed=(Window,Worker), Experimental]
|
||||
|
|
|
|||
22
Libraries/LibWeb/ServiceWorker/NameToCacheMap.cpp
Normal file
22
Libraries/LibWeb/ServiceWorker/NameToCacheMap.cpp
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* Copyright (c) 2026, Tim Flynn <trflynn89@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibWeb/Fetch/Infrastructure/HTTP/Requests.h>
|
||||
#include <LibWeb/Fetch/Infrastructure/HTTP/Responses.h>
|
||||
#include <LibWeb/ServiceWorker/NameToCacheMap.h>
|
||||
|
||||
namespace Web::ServiceWorker {
|
||||
|
||||
GC_DEFINE_ALLOCATOR(RequestResponse);
|
||||
|
||||
void RequestResponse::visit_edges(Visitor& visitor)
|
||||
{
|
||||
Base::visit_edges(visitor);
|
||||
visitor.visit(request);
|
||||
visitor.visit(response);
|
||||
}
|
||||
|
||||
}
|
||||
39
Libraries/LibWeb/ServiceWorker/NameToCacheMap.h
Normal file
39
Libraries/LibWeb/ServiceWorker/NameToCacheMap.h
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright (c) 2026, Tim Flynn <trflynn89@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibGC/Cell.h>
|
||||
#include <LibGC/CellAllocator.h>
|
||||
#include <LibGC/HeapVector.h>
|
||||
#include <LibWeb/Forward.h>
|
||||
|
||||
namespace Web::ServiceWorker {
|
||||
|
||||
// https://w3c.github.io/ServiceWorker/#dfn-request-response-list
|
||||
struct RequestResponse : public GC::Cell {
|
||||
GC_CELL(RequestResponse, GC::Cell);
|
||||
GC_DECLARE_ALLOCATOR(RequestResponse);
|
||||
|
||||
RequestResponse(GC::Ref<Fetch::Infrastructure::Request> request, GC::Ref<Fetch::Infrastructure::Response> response)
|
||||
: request(request)
|
||||
, response(response)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void visit_edges(Visitor&) override;
|
||||
|
||||
GC::Ref<Fetch::Infrastructure::Request> request;
|
||||
GC::Ref<Fetch::Infrastructure::Response> response;
|
||||
};
|
||||
|
||||
// https://w3c.github.io/ServiceWorker/#dfn-request-response-list
|
||||
using RequestResponseList = GC::HeapVector<GC::Ref<RequestResponse>>;
|
||||
|
||||
// https://w3c.github.io/ServiceWorker/#dfn-name-to-cache-map
|
||||
using NameToCacheMap = OrderedHashMap<String, GC::Ref<RequestResponseList>>;
|
||||
|
||||
}
|
||||
Loading…
Reference in a new issue