diff --git a/Libraries/LibWeb/CMakeLists.txt b/Libraries/LibWeb/CMakeLists.txt index 72fcb36f1ef..d2e3585485e 100644 --- a/Libraries/LibWeb/CMakeLists.txt +++ b/Libraries/LibWeb/CMakeLists.txt @@ -80,6 +80,7 @@ set(SOURCES ContentSecurityPolicy/Violation.cpp Cookie/Cookie.cpp Cookie/ParsedCookie.cpp + CookieStore/CookieStore.cpp CredentialManagement/Credential.cpp CredentialManagement/CredentialsContainer.cpp CredentialManagement/FederatedCredential.cpp diff --git a/Libraries/LibWeb/CookieStore/CookieStore.cpp b/Libraries/LibWeb/CookieStore/CookieStore.cpp new file mode 100644 index 00000000000..b339f63bb09 --- /dev/null +++ b/Libraries/LibWeb/CookieStore/CookieStore.cpp @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2025, Idan Horowitz + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include + +namespace Web::CookieStore { + +GC_DEFINE_ALLOCATOR(CookieStore); + +CookieStore::CookieStore(JS::Realm& realm) + : DOM::EventTarget(realm) +{ +} + +void CookieStore::initialize(JS::Realm& realm) +{ + WEB_SET_PROTOTYPE_FOR_INTERFACE(CookieStore); + Base::initialize(realm); +} + +} diff --git a/Libraries/LibWeb/CookieStore/CookieStore.h b/Libraries/LibWeb/CookieStore/CookieStore.h new file mode 100644 index 00000000000..2ce834ea1f4 --- /dev/null +++ b/Libraries/LibWeb/CookieStore/CookieStore.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2025, Idan Horowitz + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include + +namespace Web::CookieStore { + +// https://cookiestore.spec.whatwg.org/#cookiestore +class CookieStore final : public DOM::EventTarget { + WEB_PLATFORM_OBJECT(CookieStore, DOM::EventTarget); + GC_DECLARE_ALLOCATOR(CookieStore); + +private: + CookieStore(JS::Realm&); + + virtual void initialize(JS::Realm&) override; +}; + +} diff --git a/Libraries/LibWeb/CookieStore/CookieStore.idl b/Libraries/LibWeb/CookieStore/CookieStore.idl new file mode 100644 index 00000000000..6c8edb119c8 --- /dev/null +++ b/Libraries/LibWeb/CookieStore/CookieStore.idl @@ -0,0 +1,21 @@ +#import +#import +#import +#import + +// https://cookiestore.spec.whatwg.org/#cookiestore +[Exposed=(ServiceWorker,Window), SecureContext] +interface CookieStore : EventTarget { + +}; + +// https://cookiestore.spec.whatwg.org/#Window +[SecureContext] +partial interface Window { + [SameObject] readonly attribute CookieStore cookieStore; +}; + +// https://cookiestore.spec.whatwg.org/#ServiceWorkerGlobalScope +partial interface ServiceWorkerGlobalScope { + [SameObject] readonly attribute CookieStore cookieStore; +}; diff --git a/Libraries/LibWeb/Forward.h b/Libraries/LibWeb/Forward.h index e6ee6709345..c32c44f4583 100644 --- a/Libraries/LibWeb/Forward.h +++ b/Libraries/LibWeb/Forward.h @@ -173,6 +173,12 @@ enum class Source; } +namespace Web::CookieStore { + +class CookieStore; + +} + namespace Web::CredentialManagement { class Credential; diff --git a/Libraries/LibWeb/HTML/Window.cpp b/Libraries/LibWeb/HTML/Window.cpp index 858aa7c4f4b..29f83417c30 100644 --- a/Libraries/LibWeb/HTML/Window.cpp +++ b/Libraries/LibWeb/HTML/Window.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -130,6 +131,7 @@ void Window::visit_edges(JS::Cell::Visitor& visitor) visitor.visit(m_pdf_viewer_plugin_objects); visitor.visit(m_pdf_viewer_mime_type_objects); visitor.visit(m_close_watcher_manager); + visitor.visit(m_cookie_store); visitor.visit(m_locationbar); visitor.visit(m_menubar); visitor.visit(m_personalbar); @@ -1121,6 +1123,17 @@ GC::Ref Window::close_watcher_manager() return GC::Ref { *m_close_watcher_manager }; } +// https://cookiestore.spec.whatwg.org/#Window +GC::Ref Window::cookie_store() +{ + auto& realm = this->realm(); + + // The cookieStore getter steps are to return this’s associated CookieStore. + if (!m_cookie_store) + m_cookie_store = realm.create(realm); + return *m_cookie_store; +} + // https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#dom-alert void Window::alert(String const& message) { diff --git a/Libraries/LibWeb/HTML/Window.h b/Libraries/LibWeb/HTML/Window.h index 71eae6495c0..05e4709f352 100644 --- a/Libraries/LibWeb/HTML/Window.h +++ b/Libraries/LibWeb/HTML/Window.h @@ -194,6 +194,7 @@ public: [[nodiscard]] GC::Ref navigator(); [[nodiscard]] GC::Ref close_watcher_manager(); + [[nodiscard]] GC::Ref cookie_store(); void alert(String const& message = {}); bool confirm(Optional const& message); @@ -310,6 +311,7 @@ private: GC::Ptr m_navigator; GC::Ptr m_location; GC::Ptr m_close_watcher_manager; + GC::Ptr m_cookie_store; // https://html.spec.whatwg.org/multipage/nav-history-apis.html#window-navigation-api GC::Ptr m_navigation; diff --git a/Libraries/LibWeb/HTML/Window.idl b/Libraries/LibWeb/HTML/Window.idl index 511a879d01b..84fffd9e615 100644 --- a/Libraries/LibWeb/HTML/Window.idl +++ b/Libraries/LibWeb/HTML/Window.idl @@ -1,3 +1,4 @@ +#import #import #import #import diff --git a/Libraries/LibWeb/HTML/WorkerGlobalScope.h b/Libraries/LibWeb/HTML/WorkerGlobalScope.h index 244ad54791a..d5cab471c90 100644 --- a/Libraries/LibWeb/HTML/WorkerGlobalScope.h +++ b/Libraries/LibWeb/HTML/WorkerGlobalScope.h @@ -109,6 +109,8 @@ public: protected: explicit WorkerGlobalScope(JS::Realm&, GC::Ref); + virtual void visit_edges(Cell::Visitor&) override; + virtual void initialize_web_interfaces_impl(); void close_a_worker(); @@ -120,8 +122,6 @@ protected: private: virtual bool is_window_or_worker_global_scope_mixin() const final { return true; } - virtual void visit_edges(Cell::Visitor&) override; - GC::Ptr m_location; GC::Ptr m_navigator; diff --git a/Libraries/LibWeb/ServiceWorker/ServiceWorkerGlobalScope.cpp b/Libraries/LibWeb/ServiceWorker/ServiceWorkerGlobalScope.cpp index e8cfc1154b4..a0116a25a98 100644 --- a/Libraries/LibWeb/ServiceWorker/ServiceWorkerGlobalScope.cpp +++ b/Libraries/LibWeb/ServiceWorker/ServiceWorkerGlobalScope.cpp @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include #include #include @@ -18,6 +19,13 @@ ServiceWorkerGlobalScope::ServiceWorkerGlobalScope(JS::Realm& realm, GC::Ref value) { @@ -78,4 +86,15 @@ GC::Ptr ServiceWorkerGlobalScope::onmessageerror() return event_handler_attribute(EventNames::messageerror); } +// https://cookiestore.spec.whatwg.org/#ServiceWorkerGlobalScope +GC::Ref ServiceWorkerGlobalScope::cookie_store() +{ + auto& realm = this->realm(); + + // The cookieStore getter steps are to return this’s associated CookieStore. + if (!m_cookie_store) + m_cookie_store = realm.create(realm); + return *m_cookie_store; +} + } diff --git a/Libraries/LibWeb/ServiceWorker/ServiceWorkerGlobalScope.h b/Libraries/LibWeb/ServiceWorker/ServiceWorkerGlobalScope.h index cded63f2611..7c1472abc7d 100644 --- a/Libraries/LibWeb/ServiceWorker/ServiceWorkerGlobalScope.h +++ b/Libraries/LibWeb/ServiceWorker/ServiceWorkerGlobalScope.h @@ -33,8 +33,15 @@ public: void set_onmessageerror(GC::Ptr); GC::Ptr onmessageerror(); + [[nodiscard]] GC::Ref cookie_store(); + protected: explicit ServiceWorkerGlobalScope(JS::Realm&, GC::Ref); + +private: + virtual void visit_edges(Cell::Visitor&) override; + + GC::Ptr m_cookie_store; }; } diff --git a/Libraries/LibWeb/ServiceWorker/ServiceWorkerGlobalScope.idl b/Libraries/LibWeb/ServiceWorker/ServiceWorkerGlobalScope.idl index 74a599aec05..187491ebc2f 100644 --- a/Libraries/LibWeb/ServiceWorker/ServiceWorkerGlobalScope.idl +++ b/Libraries/LibWeb/ServiceWorker/ServiceWorkerGlobalScope.idl @@ -1,3 +1,4 @@ +#import #import // https://w3c.github.io/ServiceWorker/#serviceworkerglobalscope diff --git a/Libraries/LibWeb/idl_files.cmake b/Libraries/LibWeb/idl_files.cmake index 7c415dd9eab..311837c3ea6 100644 --- a/Libraries/LibWeb/idl_files.cmake +++ b/Libraries/LibWeb/idl_files.cmake @@ -13,6 +13,7 @@ libweb_js_bindings(Clipboard/ClipboardItem) libweb_js_bindings(ContentSecurityPolicy/SecurityPolicyViolationEvent) libweb_js_bindings(Compression/CompressionStream) libweb_js_bindings(Compression/DecompressionStream) +libweb_js_bindings(CookieStore/CookieStore) libweb_js_bindings(CredentialManagement/Credential) libweb_js_bindings(CredentialManagement/CredentialsContainer) libweb_js_bindings(CredentialManagement/FederatedCredential) diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp b/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp index 32444f71bc3..6a91bc36a7f 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp @@ -4816,6 +4816,7 @@ static void generate_using_namespace_definitions(SourceGenerator& generator) using namespace Web::Animations; using namespace Web::Clipboard; using namespace Web::ContentSecurityPolicy; +using namespace Web::CookieStore; using namespace Web::CredentialManagement; using namespace Web::Crypto; using namespace Web::CSS; diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/Namespaces.h b/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/Namespaces.h index 1bcb7c4616e..01c3fcfaf15 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/Namespaces.h +++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/Namespaces.h @@ -17,6 +17,7 @@ static constexpr Array libweb_interface_namespaces = { "Clipboard"sv, "Compression"sv, "ContentSecurityPolicy"sv, + "CookieStore"sv, "Crypto"sv, "DOM"sv, "DOMURL"sv, diff --git a/Meta/gn/secondary/Userland/Libraries/LibWeb/BUILD.gn b/Meta/gn/secondary/Userland/Libraries/LibWeb/BUILD.gn index 4046f22a028..aca7872fc5a 100644 --- a/Meta/gn/secondary/Userland/Libraries/LibWeb/BUILD.gn +++ b/Meta/gn/secondary/Userland/Libraries/LibWeb/BUILD.gn @@ -333,6 +333,7 @@ shared_library("LibWeb") { "CSS", "Clipboard", "Cookie", + "CookieStore", "Crypto", "DOM", "DOMURL", diff --git a/Meta/gn/secondary/Userland/Libraries/LibWeb/CookieStore/BUILD.gn b/Meta/gn/secondary/Userland/Libraries/LibWeb/CookieStore/BUILD.gn new file mode 100644 index 00000000000..79ff6ce6f1a --- /dev/null +++ b/Meta/gn/secondary/Userland/Libraries/LibWeb/CookieStore/BUILD.gn @@ -0,0 +1,5 @@ +source_set("CookieStore") { + configs += [ "//Userland/Libraries/LibWeb:configs" ] + deps = [ "//Userland/Libraries/LibWeb:all_generated" ] + sources = [ "CookieStore.cpp" ] +} diff --git a/Meta/gn/secondary/Userland/Libraries/LibWeb/idl_files.gni b/Meta/gn/secondary/Userland/Libraries/LibWeb/idl_files.gni index e82f32e9952..141427aef59 100644 --- a/Meta/gn/secondary/Userland/Libraries/LibWeb/idl_files.gni +++ b/Meta/gn/secondary/Userland/Libraries/LibWeb/idl_files.gni @@ -30,6 +30,7 @@ standard_idl_files = [ "//Userland/Libraries/LibWeb/Animations/KeyframeEffect.idl", "//Userland/Libraries/LibWeb/Clipboard/Clipboard.idl", "//Userland/Libraries/LibWeb/Clipboard/ClipboardEvent.idl", + "//Userland/Libraries/LibWeb/CookieStore/CookieStore.idl", "//Userland/Libraries/LibWeb/Crypto/Crypto.idl", "//Userland/Libraries/LibWeb/Crypto/CryptoKey.idl", "//Userland/Libraries/LibWeb/Crypto/SubtleCrypto.idl", diff --git a/Tests/LibWeb/Text/expected/all-window-properties.txt b/Tests/LibWeb/Text/expected/all-window-properties.txt index 2559787d9d8..8e778ba5ccc 100644 --- a/Tests/LibWeb/Text/expected/all-window-properties.txt +++ b/Tests/LibWeb/Text/expected/all-window-properties.txt @@ -79,6 +79,7 @@ Comment CompositionEvent CompressionStream ConstantSourceNode +CookieStore CountQueuingStrategy Credential CredentialsContainer