-
-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
LibWeb: Implement most of Service Worker registration
This approach will need some rework to be properly handled at the user agent level instead of per renderer process, but it's a start. (cherry picked from commit 7faebb2702a2a19fc401fde1856a0d90861d2904)
- Loading branch information
Showing
9 changed files
with
377 additions
and
13 deletions.
There are no files selected for viewing
6 changes: 5 additions & 1 deletion
6
Meta/gn/secondary/Userland/Libraries/LibWeb/ServiceWorker/BUILD.gn
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,9 @@ | ||
source_set("ServiceWorker") { | ||
configs += [ "//Userland/Libraries/LibWeb:configs" ] | ||
deps = [ "//Userland/Libraries/LibWeb:all_generated" ] | ||
sources = [ "Job.cpp" ] | ||
sources = [ | ||
"Job.cpp", | ||
"Registration.cpp", | ||
"ServiceWorker.cpp", | ||
] | ||
} |
2 changes: 1 addition & 1 deletion
2
Tests/LibWeb/Text/expected/ServiceWorker/service-worker-register.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
ServiceWorker registration failed: InternalError: TODO(Service Worker registration is not implemented in LibJS) | ||
ServiceWorker registration failed: InternalError: TODO(Service Worker update is not implemented in LibJS) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
/* | ||
* Copyright (c) 2024, Andrew Kaster <andrew@ladybird.org> | ||
* | ||
* SPDX-License-Identifier: BSD-2-Clause | ||
*/ | ||
|
||
#include <AK/HashMap.h> | ||
#include <LibWeb/ServiceWorker/Registration.h> | ||
|
||
namespace Web::ServiceWorker { | ||
|
||
struct RegistrationKey { | ||
StorageAPI::StorageKey key; | ||
ByteString serialized_scope_url; | ||
|
||
constexpr 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; | ||
|
||
Registration::Registration(StorageAPI::StorageKey storage_key, URL::URL scope, Bindings::ServiceWorkerUpdateViaCache update_via_cache) | ||
: m_storage_key(move(storage_key)) | ||
, m_scope_url(move(scope)) | ||
, m_update_via_cache_mode(update_via_cache) | ||
{ | ||
} | ||
|
||
// https://w3c.github.io/ServiceWorker/#dfn-service-worker-registration-unregistered | ||
bool Registration::is_unregistered() | ||
{ | ||
// A service worker registration is said to be unregistered if registration map[this service worker registration's (storage key, serialized scope url)] is not this service worker registration. | ||
// FIXME: Suspect that spec should say to serialize without fragment | ||
auto const key = RegistrationKey { m_storage_key, m_scope_url.serialize(URL::ExcludeFragment::Yes) }; | ||
return s_registrations.get(key).map([](auto& registration) { return ®istration; }).value_or(nullptr) != this; | ||
} | ||
|
||
// https://w3c.github.io/ServiceWorker/#get-registration-algorithm | ||
Optional<Registration&> Registration::get(StorageAPI::StorageKey const& key, Optional<URL::URL> scope) | ||
{ | ||
// 1. Run the following steps atomically. | ||
// FIXME: What does this mean? Do we need a mutex? does it need to be 'locked' at the UA level? | ||
|
||
// 2. Let scopeString be the empty string. | ||
ByteString scope_string; | ||
|
||
// 3. If scope is not null, set scopeString to serialized scope with the exclude fragment flag set. | ||
if (scope.has_value()) | ||
scope_string = scope.value().serialize(URL::ExcludeFragment::Yes); | ||
|
||
// 4. For each (entry storage key, entry scope) → registration of registration map: | ||
// 1. If storage key equals entry storage key and scopeString matches entry scope, then return registration. | ||
// 5. Return null. | ||
return s_registrations.get({ key, scope_string }); | ||
} | ||
|
||
// https://w3c.github.io/ServiceWorker/#set-registration-algorithm | ||
Registration& Registration::set(StorageAPI::StorageKey const& storage_key, URL::URL const& scope, Bindings::ServiceWorkerUpdateViaCache update_via_cache) | ||
{ | ||
// FIXME: 1. Run the following steps atomically. | ||
|
||
// 2. Let scopeString be serialized scope with the exclude fragment flag set. | ||
// 3. Let registration be a new service worker registration whose storage key is set to storage key, scope url is set to scope, and update via cache mode is set to updateViaCache. | ||
// 4. Set registration map[(storage key, scopeString)] to registration. | ||
// 5. Return registration. | ||
|
||
// FIXME: Is there a way to "ensure but always replace?" | ||
auto key = RegistrationKey { storage_key, scope.serialize(URL::ExcludeFragment::Yes) }; | ||
(void)s_registrations.set(key, Registration(storage_key, scope, update_via_cache)); | ||
return s_registrations.get(key).value(); | ||
} | ||
|
||
// https://w3c.github.io/ServiceWorker/#get-newest-worker | ||
ServiceWorker* Registration::newest_worker() const | ||
{ | ||
// FIXME: 1. Run the following steps atomically. | ||
|
||
// 2. Let newestWorker be null. | ||
// 3. If registration’s installing worker is not null, set newestWorker to registration’s installing worker. | ||
// 4. If registration’s waiting worker is not null, set newestWorker to registration’s waiting worker. | ||
// 5. If registration’s active worker is not null, set newestWorker to registration’s active worker. | ||
// 6. Return newestWorker. | ||
return m_installing_worker ? m_installing_worker : m_waiting_worker ? m_waiting_worker | ||
: m_active_worker; | ||
} | ||
|
||
} | ||
|
||
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)); | ||
} | ||
}; | ||
} |
Oops, something went wrong.