aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/globalscope.rs
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/dom/globalscope.rs')
-rw-r--r--components/script/dom/globalscope.rs78
1 files changed, 78 insertions, 0 deletions
diff --git a/components/script/dom/globalscope.rs b/components/script/dom/globalscope.rs
index e578f31c190..8e067e75de1 100644
--- a/components/script/dom/globalscope.rs
+++ b/components/script/dom/globalscope.rs
@@ -41,6 +41,8 @@ use crate::dom::paintworkletglobalscope::PaintWorkletGlobalScope;
use crate::dom::performance::Performance;
use crate::dom::performanceobserver::VALID_ENTRY_TYPES;
use crate::dom::promise::Promise;
+use crate::dom::serviceworker::ServiceWorker;
+use crate::dom::serviceworkerregistration::ServiceWorkerRegistration;
use crate::dom::window::Window;
use crate::dom::workerglobalscope::WorkerGlobalScope;
use crate::dom::workletglobalscope::WorkletGlobalScope;
@@ -81,6 +83,7 @@ use js::rust::{HandleValue, MutableHandleValue};
use js::{JSCLASS_IS_DOMJSCLASS, JSCLASS_IS_GLOBAL};
use msg::constellation_msg::{
BlobId, BroadcastChannelRouterId, MessagePortId, MessagePortRouterId, PipelineId,
+ ServiceWorkerId, ServiceWorkerRegistrationId,
};
use net_traits::blob_url_store::{get_blob_origin, BlobBuf};
use net_traits::filemanager_thread::{
@@ -135,6 +138,13 @@ pub struct GlobalScope {
/// The blobs managed by this global, if any.
blob_state: DomRefCell<BlobState>,
+ /// <https://w3c.github.io/ServiceWorker/#environment-settings-object-service-worker-registration-object-map>
+ registration_map:
+ DomRefCell<HashMap<ServiceWorkerRegistrationId, Dom<ServiceWorkerRegistration>>>,
+
+ /// <https://w3c.github.io/ServiceWorker/#environment-settings-object-service-worker-object-map>
+ worker_map: DomRefCell<HashMap<ServiceWorkerId, Dom<ServiceWorker>>>,
+
/// Pipeline id associated with this global.
pipeline_id: PipelineId,
@@ -567,6 +577,8 @@ impl GlobalScope {
blob_state: DomRefCell::new(BlobState::UnManaged),
eventtarget: EventTarget::new_inherited(),
crypto: Default::default(),
+ registration_map: DomRefCell::new(HashMap::new()),
+ worker_map: DomRefCell::new(HashMap::new()),
pipeline_id,
devtools_wants_updates: Default::default(),
console_timers: DomRefCell::new(Default::default()),
@@ -645,6 +657,72 @@ impl GlobalScope {
);
}
+ /// <https://w3c.github.io/ServiceWorker/#get-the-service-worker-registration-object>
+ pub fn get_serviceworker_registration(
+ &self,
+ script_url: &ServoUrl,
+ scope: &ServoUrl,
+ registration_id: ServiceWorkerRegistrationId,
+ installing_worker: Option<ServiceWorkerId>,
+ _waiting_worker: Option<ServiceWorkerId>,
+ _active_worker: Option<ServiceWorkerId>,
+ ) -> DomRoot<ServiceWorkerRegistration> {
+ // Step 1
+ let mut registrations = self.registration_map.borrow_mut();
+
+ if let Some(registration) = registrations.get(&registration_id) {
+ // Step 3
+ return DomRoot::from_ref(&**registration);
+ }
+
+ // Step 2.1 -> 2.5
+ let new_registration =
+ ServiceWorkerRegistration::new(self, scope.clone(), registration_id.clone());
+
+ // Step 2.6
+ if let Some(worker_id) = installing_worker {
+ let worker = self.get_serviceworker(script_url, scope, worker_id);
+ new_registration.set_installing(&*worker);
+ }
+
+ // TODO: 2.7 (waiting worker)
+
+ // TODO: 2.8 (active worker)
+
+ // Step 2.9
+ registrations.insert(registration_id, Dom::from_ref(&*new_registration));
+
+ // Step 3
+ new_registration
+ }
+
+ /// <https://w3c.github.io/ServiceWorker/#get-the-service-worker-object>
+ pub fn get_serviceworker(
+ &self,
+ script_url: &ServoUrl,
+ scope: &ServoUrl,
+ worker_id: ServiceWorkerId,
+ ) -> DomRoot<ServiceWorker> {
+ // Step 1
+ let mut workers = self.worker_map.borrow_mut();
+
+ if let Some(worker) = workers.get(&worker_id) {
+ // Step 3
+ DomRoot::from_ref(&**worker)
+ } else {
+ // Step 2.1
+ // TODO: step 2.2, worker state.
+ let new_worker =
+ ServiceWorker::new(self, script_url.clone(), scope.clone(), worker_id.clone());
+
+ // Step 2.3
+ workers.insert(worker_id, Dom::from_ref(&*new_worker));
+
+ // Step 3
+ new_worker
+ }
+ }
+
/// Complete the transfer of a message-port.
fn complete_port_transfer(&self, port_id: MessagePortId, tasks: VecDeque<PortMessageTask>) {
let should_start = if let MessagePortState::Managed(_id, message_ports) =