mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-20 19:45:12 +00:00
LibWeb: Implement nagivator.serviceWorker.getRegistration()
This commit is contained in:
parent
8e410f959c
commit
37e1d6ece1
Notes:
github-actions[bot]
2025-01-30 22:19:44 +00:00
Author: https://github.com/F3n67u Commit: https://github.com/LadybirdBrowser/ladybird/commit/37e1d6ece10 Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/3110 Reviewed-by: https://github.com/ADKaster ✅
12 changed files with 280 additions and 36 deletions
|
@ -21,6 +21,8 @@
|
|||
#include <LibWeb/HTML/WorkerGlobalScope.h>
|
||||
#include <LibWeb/Page/Page.h>
|
||||
#include <LibWeb/SecureContexts/AbstractOperations.h>
|
||||
#include <LibWeb/ServiceWorker/ServiceWorker.h>
|
||||
#include <LibWeb/ServiceWorker/ServiceWorkerRegistration.h>
|
||||
#include <LibWeb/StorageAPI/StorageManager.h>
|
||||
|
||||
namespace Web::HTML {
|
||||
|
@ -61,6 +63,8 @@ void EnvironmentSettingsObject::visit_edges(Cell::Visitor& visitor)
|
|||
m_realm_execution_context->visit_edges(visitor);
|
||||
visitor.visit(m_fetch_group);
|
||||
visitor.visit(m_storage_manager);
|
||||
visitor.visit(m_service_worker_registration_object_map);
|
||||
visitor.visit(m_service_worker_object_map);
|
||||
}
|
||||
|
||||
JS::ExecutionContext& EnvironmentSettingsObject::realm_execution_context()
|
||||
|
@ -574,4 +578,63 @@ GC::Ref<StorageAPI::StorageManager> EnvironmentSettingsObject::storage_manager()
|
|||
return *m_storage_manager;
|
||||
}
|
||||
|
||||
// https://w3c.github.io/ServiceWorker/#get-the-service-worker-registration-object
|
||||
GC::Ref<ServiceWorker::ServiceWorkerRegistration> EnvironmentSettingsObject::get_service_worker_registration_object(ServiceWorker::Registration const& registration)
|
||||
{
|
||||
// 1. Let objectMap be environment’s service worker registration object map.
|
||||
auto& object_map = this->m_service_worker_registration_object_map;
|
||||
|
||||
// FIXME: File spec issue asking if this should be keyed on the registration's scope url only or on the url and the storage key
|
||||
auto const key = ServiceWorker::RegistrationKey { registration.storage_key(), registration.scope_url().serialize(URL::ExcludeFragment::Yes).to_byte_string() };
|
||||
|
||||
// 2. If objectMap[registration] does not exist, then:
|
||||
if (!object_map.contains(key)) {
|
||||
// 1. Let registrationObject be a new ServiceWorkerRegistration in environment’s Realm.
|
||||
// 2. Set registrationObject’s service worker registration to registration.
|
||||
// 3. Set registrationObject’s installing attribute to null.
|
||||
// 4. Set registrationObject’s waiting attribute to null.
|
||||
// 5. Set registrationObject’s active attribute to null.
|
||||
auto registration_object = ServiceWorker::ServiceWorkerRegistration::create(realm(), registration);
|
||||
|
||||
// 6. If registration’s installing worker is not null, then set registrationObject’s installing attribute to the result of getting the service worker object that represents registration’s installing worker in environment.
|
||||
if (registration.installing_worker())
|
||||
registration_object->set_installing(get_service_worker_object(registration.installing_worker()));
|
||||
|
||||
// 7. If registration’s waiting worker is not null, then set registrationObject’s waiting attribute to the result of getting the service worker object that represents registration’s waiting worker in environment.
|
||||
if (registration.waiting_worker())
|
||||
registration_object->set_waiting(get_service_worker_object(registration.waiting_worker()));
|
||||
|
||||
// 8. If registration’s active worker is not null, then set registrationObject’s active attribute to the result of getting the service worker object that represents registration’s active worker in environment.
|
||||
if (registration.active_worker())
|
||||
registration_object->set_active(get_service_worker_object(registration.active_worker()));
|
||||
|
||||
// 9. Set objectMap[registration] to registrationObject.
|
||||
object_map.set(key, registration_object);
|
||||
}
|
||||
|
||||
// 3. Return objectMap[registration].
|
||||
return *object_map.get(key);
|
||||
}
|
||||
|
||||
GC::Ref<ServiceWorker::ServiceWorker> EnvironmentSettingsObject::get_service_worker_object(ServiceWorker::ServiceWorkerRecord* service_worker)
|
||||
{
|
||||
// 1. Let objectMap be environment’s service worker object map.
|
||||
auto& object_map = this->m_service_worker_object_map;
|
||||
|
||||
// 2. If objectMap[serviceWorker] does not exist, then:
|
||||
if (!object_map.contains(service_worker)) {
|
||||
// 1. Let serviceWorkerObj be a new ServiceWorker in environment’s Realm, and associate it with serviceWorker.
|
||||
auto service_worker_obj = ServiceWorker::ServiceWorker::create(realm(), service_worker);
|
||||
|
||||
// 2. Set serviceWorkerObj’s state to serviceWorker’s state.
|
||||
service_worker_obj->set_service_worker_state(service_worker->state);
|
||||
|
||||
// 3. Set objectMap[serviceWorker] to serviceWorkerObj.
|
||||
object_map.set(service_worker, service_worker_obj);
|
||||
}
|
||||
|
||||
// 3. Return objectMap[serviceWorker].
|
||||
return *object_map.get(service_worker);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include <LibWeb/HTML/EventLoop/EventLoop.h>
|
||||
#include <LibWeb/HTML/Scripting/ModuleMap.h>
|
||||
#include <LibWeb/HTML/Scripting/SerializedEnvironmentSettingsObject.h>
|
||||
#include <LibWeb/ServiceWorker/Registration.h>
|
||||
|
||||
namespace Web::HTML {
|
||||
|
||||
|
@ -105,6 +106,12 @@ public:
|
|||
|
||||
GC::Ref<StorageAPI::StorageManager> storage_manager();
|
||||
|
||||
// https://w3c.github.io/ServiceWorker/#get-the-service-worker-registration-object
|
||||
GC::Ref<ServiceWorker::ServiceWorkerRegistration> get_service_worker_registration_object(ServiceWorker::Registration const&);
|
||||
|
||||
// https://w3c.github.io/ServiceWorker/#get-the-service-worker-object
|
||||
GC::Ref<ServiceWorker::ServiceWorker> get_service_worker_object(ServiceWorker::ServiceWorkerRecord*);
|
||||
|
||||
[[nodiscard]] bool discarded() const { return m_discarded; }
|
||||
void set_discarded(bool b) { m_discarded = b; }
|
||||
|
||||
|
@ -127,6 +134,16 @@ private:
|
|||
// Each environment settings object has an associated StorageManager object.
|
||||
GC::Ptr<StorageAPI::StorageManager> m_storage_manager;
|
||||
|
||||
// https://w3c.github.io/ServiceWorker/#environment-settings-object-service-worker-registration-object-map
|
||||
// An environment settings object has a service worker registration object map,
|
||||
// a map where the keys are service worker registrations and the values are ServiceWorkerRegistration objects.
|
||||
HashMap<ServiceWorker::RegistrationKey, GC::Ref<ServiceWorker::ServiceWorkerRegistration>> m_service_worker_registration_object_map;
|
||||
|
||||
// https://w3c.github.io/ServiceWorker/#environment-settings-object-service-worker-object-map
|
||||
// An environment settings object has a service worker object map,
|
||||
// a map where the keys are service workers and the values are ServiceWorker objects.
|
||||
HashMap<ServiceWorker::ServiceWorkerRecord*, GC::Ref<ServiceWorker::ServiceWorker>> m_service_worker_object_map;
|
||||
|
||||
// https://w3c.github.io/ServiceWorker/#service-worker-client-discarded-flag
|
||||
// A service worker client has an associated discarded flag. It is initially unset.
|
||||
bool m_discarded { false };
|
||||
|
|
|
@ -5,17 +5,12 @@
|
|||
*/
|
||||
|
||||
#include <AK/HashMap.h>
|
||||
#include <LibWeb/Crypto/Crypto.h>
|
||||
#include <LibWeb/DOMURL/DOMURL.h>
|
||||
#include <LibWeb/ServiceWorker/Registration.h>
|
||||
|
||||
namespace Web::ServiceWorker {
|
||||
|
||||
struct RegistrationKey {
|
||||
StorageAPI::StorageKey key;
|
||||
ByteString serialized_scope_url;
|
||||
|
||||
bool operator==(RegistrationKey const&) const = default;
|
||||
};
|
||||
|
||||
// FIXME: Surely this needs hooks to be cleared and manipulated at the UA level
|
||||
// Does this need to be serialized to disk as well?
|
||||
static HashMap<RegistrationKey, Registration> s_registrations;
|
||||
|
@ -84,6 +79,53 @@ Registration& Registration::set(StorageAPI::StorageKey const& storage_key, URL::
|
|||
return s_registrations.get(key).value();
|
||||
}
|
||||
|
||||
// https://w3c.github.io/ServiceWorker/#scope-match-algorithm
|
||||
Optional<Registration&> Registration::match(StorageAPI::StorageKey const& storage_key, URL::URL const& client_url)
|
||||
{
|
||||
// FIXME: 1. Run the following steps atomically.
|
||||
|
||||
// 2. Let clientURLString be serialized clientURL.
|
||||
auto client_url_string = client_url.serialize();
|
||||
|
||||
// 3. Let matchingScopeString be the empty string.
|
||||
ByteString matching_scope_string;
|
||||
|
||||
// 4. Let scopeStringSet be an empty list.
|
||||
Vector<ByteString> scope_string_set;
|
||||
|
||||
// 5. For each (entry storage key, entry scope) of registration map's keys:
|
||||
for (auto& [entry_storage_key, entry_scope] : s_registrations.keys()) {
|
||||
// 1. If storage key equals entry storage key, then append entry scope to the end of scopeStringSet.
|
||||
if (entry_storage_key == storage_key)
|
||||
scope_string_set.append(entry_scope);
|
||||
}
|
||||
|
||||
// 6. Set matchingScopeString to the longest value in scopeStringSet which the value of clientURLString starts with, if it exists.
|
||||
// NOTE: The URL string matching in this step is prefix-based rather than path-structural. E.g. a client
|
||||
// URL string with "https://example.com/prefix-of/resource.html" will match a registration for a
|
||||
// scope with "https://example.com/prefix". The URL string comparison is safe for the same-origin
|
||||
// security as HTTP(S) URLs are always serialized with a trailing slash at the end of the origin
|
||||
// part of the URLs.
|
||||
for (auto& scope_string : scope_string_set) {
|
||||
if (client_url_string.starts_with_bytes(scope_string) && scope_string.length() > matching_scope_string.length())
|
||||
matching_scope_string = scope_string;
|
||||
}
|
||||
|
||||
// 7. Let matchingScope be null.
|
||||
Optional<URL::URL> matching_scope;
|
||||
|
||||
// 8. If matchingScopeString is not the empty string, then:
|
||||
if (!matching_scope_string.is_empty()) {
|
||||
// 1. Let matchingScope be the result of parsing matchingScopeString.
|
||||
matching_scope = DOMURL::parse(matching_scope_string);
|
||||
// 2. Assert: matchingScope’s origin and clientURL’s origin are same origin.
|
||||
VERIFY(matching_scope.value().origin().is_same_origin(client_url.origin()));
|
||||
}
|
||||
|
||||
// 9. Return the result of running Get Registration given storage key and matchingScope.
|
||||
return get(storage_key, matching_scope);
|
||||
}
|
||||
|
||||
void Registration::remove(StorageAPI::StorageKey const& key, URL::URL const& scope)
|
||||
{
|
||||
(void)s_registrations.remove({ key, scope.serialize(URL::ExcludeFragment::Yes).to_byte_string() });
|
||||
|
@ -104,13 +146,3 @@ ServiceWorkerRecord* Registration::newest_worker() const
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
namespace AK {
|
||||
template<>
|
||||
struct Traits<Web::ServiceWorker::RegistrationKey> : public DefaultTraits<Web::ServiceWorker::RegistrationKey> {
|
||||
static unsigned hash(Web::ServiceWorker::RegistrationKey const& key)
|
||||
{
|
||||
return pair_int_hash(Traits<Web::StorageAPI::StorageKey>::hash(key.key), Traits<ByteString>::hash(key.serialized_scope_url));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -31,6 +31,9 @@ public:
|
|||
// https://w3c.github.io/ServiceWorker/#set-registration-algorithm
|
||||
static Registration& set(StorageAPI::StorageKey const&, URL::URL const&, Bindings::ServiceWorkerUpdateViaCache);
|
||||
|
||||
// https://w3c.github.io/ServiceWorker/#scope-match-algorithm
|
||||
static Optional<Registration&> match(StorageAPI::StorageKey const&, URL::URL const&);
|
||||
|
||||
static void remove(StorageAPI::StorageKey const&, URL::URL const&);
|
||||
|
||||
bool is_unregistered();
|
||||
|
@ -42,6 +45,10 @@ public:
|
|||
void set_last_update_check_time(MonotonicTime time) { m_last_update_check_time = time; }
|
||||
|
||||
ServiceWorkerRecord* newest_worker() const;
|
||||
ServiceWorkerRecord* installing_worker() const { return m_installing_worker; }
|
||||
ServiceWorkerRecord* waiting_worker() const { return m_waiting_worker; }
|
||||
ServiceWorkerRecord* active_worker() const { return m_active_worker; }
|
||||
|
||||
bool is_stale() const;
|
||||
|
||||
private:
|
||||
|
@ -65,4 +72,22 @@ private:
|
|||
ByteString m_navigation_preload_header_value; // https://w3c.github.io/ServiceWorker/#service-worker-registration-navigation-preload-header-value
|
||||
};
|
||||
|
||||
struct RegistrationKey {
|
||||
StorageAPI::StorageKey key;
|
||||
ByteString serialized_scope_url;
|
||||
|
||||
bool operator==(RegistrationKey const&) const = default;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace AK {
|
||||
template<>
|
||||
struct Traits<Web::ServiceWorker::RegistrationKey> : public DefaultTraits<Web::ServiceWorker::RegistrationKey> {
|
||||
static unsigned hash(Web::ServiceWorker::RegistrationKey const& key)
|
||||
{
|
||||
return pair_int_hash(Traits<Web::StorageAPI::StorageKey>::hash(key.key), Traits<ByteString>::hash(key.serialized_scope_url));
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -12,17 +12,17 @@
|
|||
|
||||
namespace Web::ServiceWorker {
|
||||
|
||||
ServiceWorker::ServiceWorker(JS::Realm& realm, String script_url)
|
||||
ServiceWorker::ServiceWorker(JS::Realm& realm, ServiceWorkerRecord* service_worker_record)
|
||||
: DOM::EventTarget(realm)
|
||||
, m_script_url(move(script_url))
|
||||
, m_service_worker_record(service_worker_record)
|
||||
{
|
||||
}
|
||||
|
||||
ServiceWorker::~ServiceWorker() = default;
|
||||
|
||||
GC::Ref<ServiceWorker> ServiceWorker::create(JS::Realm& realm)
|
||||
GC::Ref<ServiceWorker> ServiceWorker::create(JS::Realm& realm, ServiceWorkerRecord* service_worker_record)
|
||||
{
|
||||
return realm.create<ServiceWorker>(realm, ""_string);
|
||||
return realm.create<ServiceWorker>(realm, service_worker_record);
|
||||
}
|
||||
|
||||
void ServiceWorker::initialize(JS::Realm& realm)
|
||||
|
@ -31,6 +31,15 @@ void ServiceWorker::initialize(JS::Realm& realm)
|
|||
WEB_SET_PROTOTYPE_FOR_INTERFACE(ServiceWorker);
|
||||
}
|
||||
|
||||
// https://w3c.github.io/ServiceWorker/#dom-serviceworker-scripturl
|
||||
String ServiceWorker::script_url() const
|
||||
{
|
||||
if (!m_service_worker_record)
|
||||
return {};
|
||||
|
||||
return m_service_worker_record->script_url.serialize();
|
||||
}
|
||||
|
||||
#undef __ENUMERATE
|
||||
#define __ENUMERATE(attribute_name, event_name) \
|
||||
void ServiceWorker::set_##attribute_name(WebIDL::CallbackType* value) \
|
||||
|
|
|
@ -15,16 +15,18 @@
|
|||
|
||||
namespace Web::ServiceWorker {
|
||||
|
||||
// https://w3c.github.io/ServiceWorker/#serviceworker-interface
|
||||
class ServiceWorker : public DOM::EventTarget {
|
||||
WEB_PLATFORM_OBJECT(ServiceWorker, DOM::EventTarget);
|
||||
|
||||
public:
|
||||
[[nodiscard]] static GC::Ref<ServiceWorker> create(JS::Realm& realm);
|
||||
[[nodiscard]] static GC::Ref<ServiceWorker> create(JS::Realm& realm, ServiceWorkerRecord*);
|
||||
|
||||
virtual ~ServiceWorker() override;
|
||||
|
||||
String script_url() const { return m_script_url; }
|
||||
String script_url() const;
|
||||
Bindings::ServiceWorkerState service_worker_state() const { return m_state; }
|
||||
void set_service_worker_state(Bindings::ServiceWorkerState state) { m_state = state; }
|
||||
|
||||
#undef __ENUMERATE
|
||||
#define __ENUMERATE(attribute_name, event_name) \
|
||||
|
@ -34,12 +36,12 @@ public:
|
|||
#undef __ENUMERATE
|
||||
|
||||
private:
|
||||
ServiceWorker(JS::Realm&, String script_url);
|
||||
ServiceWorker(JS::Realm&, ServiceWorkerRecord*);
|
||||
|
||||
virtual void initialize(JS::Realm&) override;
|
||||
|
||||
String m_script_url;
|
||||
Bindings::ServiceWorkerState m_state { Bindings::ServiceWorkerState::Parsed };
|
||||
ServiceWorkerRecord* m_service_worker_record;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -10,9 +10,13 @@
|
|||
#include <LibWeb/Bindings/ServiceWorkerContainerPrototype.h>
|
||||
#include <LibWeb/DOMURL/DOMURL.h>
|
||||
#include <LibWeb/HTML/EventNames.h>
|
||||
#include <LibWeb/HTML/Scripting/TemporaryExecutionContext.h>
|
||||
#include <LibWeb/Platform/EventLoopPlugin.h>
|
||||
#include <LibWeb/ServiceWorker/Job.h>
|
||||
#include <LibWeb/ServiceWorker/Registration.h>
|
||||
#include <LibWeb/ServiceWorker/ServiceWorker.h>
|
||||
#include <LibWeb/ServiceWorker/ServiceWorkerContainer.h>
|
||||
#include <LibWeb/ServiceWorker/ServiceWorkerRegistration.h>
|
||||
#include <LibWeb/StorageAPI/StorageKey.h>
|
||||
|
||||
namespace Web::ServiceWorker {
|
||||
|
@ -80,6 +84,61 @@ GC::Ref<WebIDL::Promise> ServiceWorkerContainer::register_(String script_url, Re
|
|||
return p;
|
||||
}
|
||||
|
||||
// https://w3c.github.io/ServiceWorker/#navigator-service-worker-getRegistration
|
||||
GC::Ref<WebIDL::Promise> ServiceWorkerContainer::get_registration(String const& client_url)
|
||||
{
|
||||
auto& realm = this->realm();
|
||||
|
||||
// 1. Let client be this's service worker client.
|
||||
auto client = m_service_worker_client;
|
||||
|
||||
// 2. Let storage key be the result of running obtain a storage key given client.
|
||||
auto storage_key = StorageAPI::obtain_a_storage_key(client);
|
||||
|
||||
// FIXME: Ad-Hoc. Spec should handle this failure.
|
||||
if (!storage_key.has_value())
|
||||
return WebIDL::create_rejected_promise(realm, JS::TypeError::create(realm, "Failed to obtain a storage key"sv));
|
||||
|
||||
// 3. Let clientURL be the result of parsing clientURL with this's relevant settings object’s API base URL.
|
||||
auto base_url = HTML::relevant_settings_object(*this).api_base_url();
|
||||
auto parsed_client_url = DOMURL::parse(client_url, base_url);
|
||||
|
||||
// 4. If clientURL is failure, return a promise rejected with a TypeError.
|
||||
if (!parsed_client_url.has_value())
|
||||
return WebIDL::create_rejected_promise(realm, JS::TypeError::create(realm, "clientURL is not a valid URL"sv));
|
||||
|
||||
// 5. Set clientURL’s fragment to null.
|
||||
parsed_client_url->set_fragment({});
|
||||
|
||||
// 6. If the origin of clientURL is not client’s origin, return a promise rejected with a "SecurityError" DOMException.
|
||||
if (!parsed_client_url->origin().is_same_origin(client->origin()))
|
||||
return WebIDL::create_rejected_promise(realm, WebIDL::SecurityError::create(realm, "clientURL is not the same origin as the client's origin"_string));
|
||||
|
||||
// 7. Let promise be a new promise.
|
||||
auto promise = WebIDL::create_promise(realm);
|
||||
|
||||
// 8. Run the following substeps in parallel:
|
||||
Platform::EventLoopPlugin::the().deferred_invoke(GC::create_function(realm.heap(), [promise, storage_key, parsed_client_url = *parsed_client_url]() {
|
||||
auto& realm = HTML::relevant_realm(promise->promise());
|
||||
HTML::TemporaryExecutionContext const execution_context { realm, HTML::TemporaryExecutionContext::CallbacksEnabled::Yes };
|
||||
|
||||
// 1. Let registration be the result of running Match Service Worker Registration given storage key and clientURL.
|
||||
auto maybe_registration = Registration::match(storage_key.value(), parsed_client_url);
|
||||
|
||||
// 2. If registration is null, resolve promise with undefined and abort these steps.
|
||||
if (!maybe_registration.has_value()) {
|
||||
WebIDL::resolve_promise(realm, promise, JS::js_undefined());
|
||||
return;
|
||||
}
|
||||
|
||||
// 3. Resolve promise with the result of getting the service worker registration object that represents registration in promise’s relevant settings object.
|
||||
auto registration_object = HTML::relevant_settings_object(promise->promise()).get_service_worker_registration_object(maybe_registration.value());
|
||||
WebIDL::resolve_promise(realm, promise, registration_object);
|
||||
}));
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
||||
// https://w3c.github.io/ServiceWorker/#start-register-algorithm
|
||||
void ServiceWorkerContainer::start_register(Optional<URL::URL> scope_url, Optional<URL::URL> script_url, GC::Ref<WebIDL::Promise> promise, HTML::EnvironmentSettingsObject& client, URL::URL referrer, Bindings::WorkerType worker_type, Bindings::ServiceWorkerUpdateViaCache update_via_cache)
|
||||
{
|
||||
|
|
|
@ -36,6 +36,8 @@ public:
|
|||
|
||||
GC::Ref<WebIDL::Promise> register_(String script_url, RegistrationOptions const& options);
|
||||
|
||||
GC::Ref<WebIDL::Promise> get_registration(String const& client_url);
|
||||
|
||||
#undef __ENUMERATE
|
||||
#define __ENUMERATE(attribute_name, event_name) \
|
||||
void set_##attribute_name(WebIDL::CallbackType*); \
|
||||
|
|
|
@ -12,7 +12,7 @@ interface ServiceWorkerContainer : EventTarget {
|
|||
// FIXME: [NewObject] Promise<ServiceWorkerRegistration> register((TrustedScriptURL or USVString) scriptURL, optional RegistrationOptions options = {});
|
||||
[NewObject, ImplementedAs=register_] Promise<ServiceWorkerRegistration> register(USVString scriptURL, optional RegistrationOptions options = {});
|
||||
|
||||
[FIXME, NewObject] Promise<(ServiceWorkerRegistration or undefined)> getRegistration(optional USVString clientURL = "");
|
||||
[NewObject] Promise<(ServiceWorkerRegistration or undefined)> getRegistration(optional USVString clientURL = "");
|
||||
[FIXME, NewObject] Promise<FrozenArray<ServiceWorkerRegistration>> getRegistrations();
|
||||
|
||||
[FIXME] undefined startMessages();
|
||||
|
|
|
@ -7,14 +7,16 @@
|
|||
#include <LibJS/Runtime/Realm.h>
|
||||
#include <LibWeb/Bindings/Intrinsics.h>
|
||||
#include <LibWeb/Bindings/ServiceWorkerRegistrationPrototype.h>
|
||||
#include <LibWeb/ServiceWorker/ServiceWorker.h>
|
||||
#include <LibWeb/ServiceWorker/ServiceWorkerRegistration.h>
|
||||
|
||||
namespace Web::ServiceWorker {
|
||||
|
||||
GC_DEFINE_ALLOCATOR(ServiceWorkerRegistration);
|
||||
|
||||
ServiceWorkerRegistration::ServiceWorkerRegistration(JS::Realm& realm)
|
||||
ServiceWorkerRegistration::ServiceWorkerRegistration(JS::Realm& realm, Registration const& registration)
|
||||
: DOM::EventTarget(realm)
|
||||
, m_registration(registration)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -24,8 +26,16 @@ void ServiceWorkerRegistration::initialize(JS::Realm& realm)
|
|||
WEB_SET_PROTOTYPE_FOR_INTERFACE(ServiceWorkerRegistration);
|
||||
}
|
||||
|
||||
GC::Ref<ServiceWorkerRegistration> ServiceWorkerRegistration::create(JS::Realm& realm)
|
||||
void ServiceWorkerRegistration::visit_edges(Cell::Visitor& visitor)
|
||||
{
|
||||
return realm.create<ServiceWorkerRegistration>(realm);
|
||||
Base::visit_edges(visitor);
|
||||
visitor.visit(m_installing);
|
||||
visitor.visit(m_waiting);
|
||||
visitor.visit(m_active);
|
||||
}
|
||||
|
||||
GC::Ref<ServiceWorkerRegistration> ServiceWorkerRegistration::create(JS::Realm& realm, Registration const& registration)
|
||||
{
|
||||
return realm.create<ServiceWorkerRegistration>(realm, registration);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,17 +10,42 @@
|
|||
|
||||
namespace Web::ServiceWorker {
|
||||
|
||||
// https://w3c.github.io/ServiceWorker/#serviceworkerregistration-interface
|
||||
class ServiceWorkerRegistration : public DOM::EventTarget {
|
||||
WEB_PLATFORM_OBJECT(ServiceWorkerRegistration, DOM::EventTarget);
|
||||
GC_DECLARE_ALLOCATOR(ServiceWorkerRegistration);
|
||||
|
||||
public:
|
||||
[[nodiscard]] static GC::Ref<ServiceWorkerRegistration> create(JS::Realm& realm);
|
||||
[[nodiscard]] static GC::Ref<ServiceWorkerRegistration> create(JS::Realm& realm, Registration const& registration);
|
||||
|
||||
explicit ServiceWorkerRegistration(JS::Realm&);
|
||||
Registration const& registration() { return m_registration; }
|
||||
|
||||
GC::Ptr<ServiceWorker> installing() const { return m_installing; }
|
||||
void set_installing(GC::Ptr<ServiceWorker> installing) { m_installing = installing; }
|
||||
|
||||
GC::Ptr<ServiceWorker> waiting() const { return m_waiting; }
|
||||
void set_waiting(GC::Ptr<ServiceWorker> waiting) { m_waiting = waiting; }
|
||||
|
||||
GC::Ptr<ServiceWorker> active() const { return m_active; }
|
||||
void set_active(GC::Ptr<ServiceWorker> active) { m_active = active; }
|
||||
|
||||
// https://w3c.github.io/ServiceWorker/#dom-serviceworkerregistration-scope
|
||||
String scope() const { return m_registration.scope_url().serialize(); }
|
||||
|
||||
// https://w3c.github.io/ServiceWorker/#dom-serviceworkerregistration-updateviacache
|
||||
Bindings::ServiceWorkerUpdateViaCache update_via_cache() const { return m_registration.update_via_cache(); }
|
||||
|
||||
explicit ServiceWorkerRegistration(JS::Realm&, Registration const&);
|
||||
virtual ~ServiceWorkerRegistration() override = default;
|
||||
|
||||
private:
|
||||
virtual void initialize(JS::Realm&) override;
|
||||
virtual void visit_edges(JS::Cell::Visitor&) override;
|
||||
|
||||
Registration const& m_registration;
|
||||
GC::Ptr<ServiceWorker> m_installing;
|
||||
GC::Ptr<ServiceWorker> m_waiting;
|
||||
GC::Ptr<ServiceWorker> m_active;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -5,13 +5,13 @@
|
|||
// https://w3c.github.io/ServiceWorker/#serviceworkerregistration-interface
|
||||
[SecureContext, Exposed=(Window,Worker)]
|
||||
interface ServiceWorkerRegistration : EventTarget {
|
||||
[FIXME] readonly attribute ServiceWorker? installing;
|
||||
[FIXME] readonly attribute ServiceWorker? waiting;
|
||||
[FIXME] readonly attribute ServiceWorker? active;
|
||||
readonly attribute ServiceWorker? installing;
|
||||
readonly attribute ServiceWorker? waiting;
|
||||
readonly attribute ServiceWorker? active;
|
||||
[FIXME, SameObject] readonly attribute NavigationPreloadManager navigationPreload;
|
||||
|
||||
[FIXME] readonly attribute USVString scope;
|
||||
[FIXME] readonly attribute ServiceWorkerUpdateViaCache updateViaCache;
|
||||
readonly attribute USVString scope;
|
||||
readonly attribute ServiceWorkerUpdateViaCache updateViaCache;
|
||||
|
||||
[FIXME, NewObject] Promise<undefined> update();
|
||||
[FIXME, NewObject] Promise<boolean> unregister();
|
||||
|
|
Loading…
Add table
Reference in a new issue