diff --git a/Libraries/LibWeb/CMakeLists.txt b/Libraries/LibWeb/CMakeLists.txt index 7236656aa03..2c60a5d0070 100644 --- a/Libraries/LibWeb/CMakeLists.txt +++ b/Libraries/LibWeb/CMakeLists.txt @@ -738,6 +738,7 @@ set(SOURCES ResourceTiming/PerformanceResourceTiming.cpp SecureContexts/AbstractOperations.cpp Selection/Selection.cpp + ServiceWorker/CacheStorage.cpp ServiceWorker/EventNames.cpp ServiceWorker/Job.cpp ServiceWorker/Registration.cpp diff --git a/Libraries/LibWeb/HTML/WindowOrWorkerGlobalScope.cpp b/Libraries/LibWeb/HTML/WindowOrWorkerGlobalScope.cpp index 005bfc532fa..ea0af065499 100644 --- a/Libraries/LibWeb/HTML/WindowOrWorkerGlobalScope.cpp +++ b/Libraries/LibWeb/HTML/WindowOrWorkerGlobalScope.cpp @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -77,6 +78,7 @@ void WindowOrWorkerGlobalScopeMixin::visit_edges(JS::Cell::Visitor& visitor) entry.value.visit_edges(visitor); visitor.visit(m_registered_event_sources); visitor.visit(m_crypto); + visitor.visit(m_cache_storage); visitor.visit(m_resource_timing_secondary_buffer); } @@ -1020,4 +1022,15 @@ GC::Ref WindowOrWorkerGlobalScopeMixin::crypto() return GC::Ref { *m_crypto }; } +// https://w3c.github.io/ServiceWorker/#cache-storage-interface +GC::Ref WindowOrWorkerGlobalScopeMixin::caches() +{ + auto& platform_object = this_impl(); + auto& realm = platform_object.realm(); + + if (!m_cache_storage) + m_cache_storage = realm.create(realm); + return GC::Ref { *m_cache_storage }; +} + } diff --git a/Libraries/LibWeb/HTML/WindowOrWorkerGlobalScope.h b/Libraries/LibWeb/HTML/WindowOrWorkerGlobalScope.h index 782b8eda58f..fe5dcae1f6b 100644 --- a/Libraries/LibWeb/HTML/WindowOrWorkerGlobalScope.h +++ b/Libraries/LibWeb/HTML/WindowOrWorkerGlobalScope.h @@ -18,6 +18,7 @@ #include #include #include +#include #include namespace Web::HTML { @@ -100,6 +101,8 @@ public: [[nodiscard]] GC::Ref crypto(); + [[nodiscard]] GC::Ref caches(); + protected: void initialize(JS::Realm&); void visit_edges(JS::Cell::Visitor&); @@ -146,6 +149,8 @@ private: GC::Ptr m_crypto; + GC::Ptr m_cache_storage; + bool m_error_reporting_mode { false }; WebSockets::WebSocket::List m_registered_web_sockets; diff --git a/Libraries/LibWeb/HTML/WindowOrWorkerGlobalScope.idl b/Libraries/LibWeb/HTML/WindowOrWorkerGlobalScope.idl index 85ba3dbb3d3..c688c507339 100644 --- a/Libraries/LibWeb/HTML/WindowOrWorkerGlobalScope.idl +++ b/Libraries/LibWeb/HTML/WindowOrWorkerGlobalScope.idl @@ -5,6 +5,7 @@ #import #import #import +#import // https://html.spec.whatwg.org/multipage/webappapis.html#timerhandler typedef (DOMString or Function) TimerHandler; @@ -39,4 +40,7 @@ interface mixin WindowOrWorkerGlobalScope { // https://w3c.github.io/webcrypto/#crypto-interface [SameObject] readonly attribute Crypto crypto; + + // https://w3c.github.io/ServiceWorker/#cache-storage-interface + [SecureContext, SameObject] readonly attribute CacheStorage caches; }; diff --git a/Libraries/LibWeb/ServiceWorker/CacheStorage.cpp b/Libraries/LibWeb/ServiceWorker/CacheStorage.cpp new file mode 100644 index 00000000000..1d95b7a88b2 --- /dev/null +++ b/Libraries/LibWeb/ServiceWorker/CacheStorage.cpp @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2025, Aliaksandr Kalenik + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include + +namespace Web::ServiceWorker { + +GC_DEFINE_ALLOCATOR(CacheStorage); + +CacheStorage::CacheStorage(JS::Realm& realm) + : Bindings::PlatformObject(realm) +{ +} + +void CacheStorage::initialize(JS::Realm& realm) +{ + Base::initialize(realm); + WEB_SET_PROTOTYPE_FOR_INTERFACE(CacheStorage); +} + +// https://w3c.github.io/ServiceWorker/#cache-storage-open +GC::Ref CacheStorage::open(String const&) +{ + return WebIDL::create_rejected_promise(realm(), WebIDL::NotSupportedError::create(realm(), "CacheStorage.open() is not yet implemented"_string)); +} + +} diff --git a/Libraries/LibWeb/ServiceWorker/CacheStorage.h b/Libraries/LibWeb/ServiceWorker/CacheStorage.h new file mode 100644 index 00000000000..5b9af542ad8 --- /dev/null +++ b/Libraries/LibWeb/ServiceWorker/CacheStorage.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2025, Aliaksandr Kalenik + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include + +namespace Web::ServiceWorker { + +// https://w3c.github.io/ServiceWorker/#cachestorage-interface +class CacheStorage : public Bindings::PlatformObject { + WEB_PLATFORM_OBJECT(CacheStorage, Bindings::PlatformObject); + GC_DECLARE_ALLOCATOR(CacheStorage); + +public: + GC::Ref open(String const& cache_name); + +private: + explicit CacheStorage(JS::Realm&); + + virtual void initialize(JS::Realm&) override; +}; + +} diff --git a/Libraries/LibWeb/ServiceWorker/CacheStorage.idl b/Libraries/LibWeb/ServiceWorker/CacheStorage.idl new file mode 100644 index 00000000000..b214bab1c06 --- /dev/null +++ b/Libraries/LibWeb/ServiceWorker/CacheStorage.idl @@ -0,0 +1,15 @@ +#import + +// https://w3c.github.io/ServiceWorker/#cachestorage-interface +[SecureContext, Exposed=(Window,Worker)] +interface CacheStorage { + //[NewObject] Promise<(Response or undefined)> match(RequestInfo request, optional MultiCacheQueryOptions options = {}); + //[NewObject] Promise has(DOMString cacheName); + [NewObject] Promise open(DOMString cacheName); + //[NewObject] Promise delete(DOMString cacheName); + //[NewObject] Promise> keys(); +}; + +//dictionary MultiCacheQueryOptions : CacheQueryOptions { +// DOMString cacheName; +//}; diff --git a/Libraries/LibWeb/idl_files.cmake b/Libraries/LibWeb/idl_files.cmake index 2ffce4524df..b24ec81493d 100644 --- a/Libraries/LibWeb/idl_files.cmake +++ b/Libraries/LibWeb/idl_files.cmake @@ -297,6 +297,7 @@ libweb_js_bindings(ResizeObserver/ResizeObserver) libweb_js_bindings(ResizeObserver/ResizeObserverEntry) libweb_js_bindings(ResizeObserver/ResizeObserverSize) libweb_js_bindings(ResourceTiming/PerformanceResourceTiming) +libweb_js_bindings(ServiceWorker/CacheStorage) libweb_js_bindings(ServiceWorker/ServiceWorker) libweb_js_bindings(ServiceWorker/ServiceWorkerContainer) libweb_js_bindings(ServiceWorker/ServiceWorkerGlobalScope GLOBAL) diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp b/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp index dd1d8e77898..2d47ae30a7a 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp @@ -44,6 +44,7 @@ static bool is_platform_object(Type const& type) "AudioTrack"sv, "BaseAudioContext"sv, "Blob"sv, + "CacheStorage"sv, "CanvasGradient"sv, "CanvasPattern"sv, "CanvasRenderingContext2D"sv, diff --git a/Tests/LibWeb/Text/expected/all-window-properties.txt b/Tests/LibWeb/Text/expected/all-window-properties.txt index bcb262b15da..1a18cdce95c 100644 --- a/Tests/LibWeb/Text/expected/all-window-properties.txt +++ b/Tests/LibWeb/Text/expected/all-window-properties.txt @@ -61,6 +61,7 @@ CSSStyleRule CSSStyleSheet CSSSupportsRule CSSTransition +CacheStorage CanvasGradient CanvasPattern CanvasRenderingContext2D