mirror of
https://github.com/lexmount/moli.git
synced 2026-10-13 08:01:14 +00:00
fix(renderer): replace the Service Worker client on initial Document commit
This commit is contained in:
+25
-2
@@ -170,7 +170,17 @@ async fn initial_popup_commit_keeps_window_timers_and_service_worker_completion(
|
||||
let response = Arc::clone(&response);
|
||||
async move {
|
||||
if uri.path() == "/worker.js" {
|
||||
return ([("content-type", "text/javascript")], "self.addEventListener('install',e=>e.waitUntil(self.skipWaiting()));self.addEventListener('activate',e=>e.waitUntil(self.clients.claim()));");
|
||||
return (
|
||||
[("content-type", "text/javascript")],
|
||||
r#"
|
||||
self.addEventListener('install', e => e.waitUntil(self.skipWaiting()));
|
||||
self.addEventListener('activate', e => e.waitUntil(self.clients.claim()));
|
||||
self.addEventListener('message', e => e.waitUntil(
|
||||
self.clients.matchAll({includeUncontrolled:true, type:'window'})
|
||||
.then(clients => e.source.postMessage(clients.map(c => c.url)))
|
||||
));
|
||||
"#,
|
||||
);
|
||||
}
|
||||
if uri.path() == "/child" {
|
||||
response.notified().await;
|
||||
@@ -218,8 +228,21 @@ async fn initial_popup_commit_keeps_window_timers_and_service_worker_completion(
|
||||
json!({"autoAttach":false,"waitForDebuggerOnStart":false,"flatten":true}),
|
||||
)
|
||||
.await;
|
||||
evaluate_window_name_probe(&mut child, 4, "window.registered='pending';navigator.serviceWorker.register('/worker.js').then(()=>registered='success',e=>registered=e.name);true").await;
|
||||
evaluate_window_name_probe(&mut child, 4, "window.registered='pending';window.controllerChanges=0;navigator.serviceWorker.oncontrollerchange=()=>controllerChanges++;navigator.serviceWorker.register('/worker.js').then(()=>registered='success',e=>registered=e.name);true").await;
|
||||
wait_for_value(&mut child, "registered", json!("success")).await;
|
||||
wait_for_value(
|
||||
&mut child,
|
||||
"[navigator.serviceWorker.controller?.scriptURL,controllerChanges]",
|
||||
json!([format!("{base}/worker.js"), 1]),
|
||||
)
|
||||
.await;
|
||||
evaluate_window_name_probe(&mut child, 6, "window.clientURLs=null;navigator.serviceWorker.onmessage=e=>clientURLs=e.data;navigator.serviceWorker.controller.postMessage('clients');true").await;
|
||||
wait_for_value(
|
||||
&mut child,
|
||||
"clientURLs?.sort()",
|
||||
json!([format!("{base}/child"), format!("{base}/opener")]),
|
||||
)
|
||||
.await;
|
||||
assert_eq!(
|
||||
evaluate_window_name_probe(&mut child, 5, "clearInterval(intervalId);typeof timeoutId")
|
||||
.await,
|
||||
|
||||
@@ -315,26 +315,14 @@ impl JsContextHost {
|
||||
.unwrap_or_else(|| {
|
||||
super::service_workers::service_worker_first_party_storage_key(&document_url)
|
||||
});
|
||||
let service_worker_client_id = reserved_service_worker_client_id
|
||||
.filter(|client_id| {
|
||||
browser_context_runtime.update_service_worker_client_document_and_page_endpoint(
|
||||
*client_id,
|
||||
document_url.clone(),
|
||||
service_worker_storage_key.clone(),
|
||||
crate::service_worker_runtime::ServiceWorkerClientFrameType::TopLevel,
|
||||
Some(super::WindowDocumentOwner::Frame(main_document_owner)),
|
||||
service_worker_task_tx.clone(),
|
||||
)
|
||||
})
|
||||
.unwrap_or_else(|| {
|
||||
browser_context_runtime.register_service_worker_client(
|
||||
document_url,
|
||||
service_worker_storage_key,
|
||||
crate::service_worker_runtime::ServiceWorkerClientFrameType::TopLevel,
|
||||
Some(super::WindowDocumentOwner::Frame(main_document_owner)),
|
||||
service_worker_task_tx.clone(),
|
||||
)
|
||||
});
|
||||
let service_worker_client_id = Self::register_main_service_worker_client(
|
||||
&browser_context_runtime,
|
||||
document_url,
|
||||
service_worker_storage_key,
|
||||
main_document_owner,
|
||||
service_worker_task_tx.clone(),
|
||||
reserved_service_worker_client_id,
|
||||
);
|
||||
assert!(
|
||||
frame_owner_store
|
||||
.set_current_main_service_worker_client_id(Some(service_worker_client_id,)),
|
||||
|
||||
@@ -103,6 +103,65 @@ pub(crate) struct PendingServiceWorkerClientsOpenWindowPopup {
|
||||
}
|
||||
|
||||
impl JsContextHost {
|
||||
pub(in crate::native_bridge::context_host) fn register_main_service_worker_client(
|
||||
browser_context_runtime: &crate::runtime::RendererBrowserContextRuntime,
|
||||
document_url: Url,
|
||||
storage_key: String,
|
||||
document_owner: FrameDocumentTaskOwner,
|
||||
completion_tx: crate::page_task_queue::RendererPageServiceWorkerTaskSender,
|
||||
reserved_client_id: Option<ServiceWorkerClientId>,
|
||||
) -> ServiceWorkerClientId {
|
||||
reserved_client_id
|
||||
.filter(|client_id| {
|
||||
browser_context_runtime.update_service_worker_client_document_and_page_endpoint(
|
||||
*client_id,
|
||||
document_url.clone(),
|
||||
storage_key.clone(),
|
||||
ServiceWorkerClientFrameType::TopLevel,
|
||||
Some(WindowDocumentOwner::Frame(document_owner)),
|
||||
completion_tx.clone(),
|
||||
)
|
||||
})
|
||||
.unwrap_or_else(|| {
|
||||
browser_context_runtime.register_service_worker_client(
|
||||
document_url,
|
||||
storage_key,
|
||||
ServiceWorkerClientFrameType::TopLevel,
|
||||
Some(WindowDocumentOwner::Frame(document_owner)),
|
||||
completion_tx,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn adopt_initial_document_service_worker_client(
|
||||
&mut self,
|
||||
transition: crate::frame_owner_model::MainDocumentOwnerTransition,
|
||||
reserved_client_id: Option<ServiceWorkerClientId>,
|
||||
) {
|
||||
let document_url = self.document_url().clone();
|
||||
let storage_key = self.service_worker_document_storage_key();
|
||||
let client_id = Self::register_main_service_worker_client(
|
||||
&self.browser_context_runtime,
|
||||
document_url,
|
||||
storage_key,
|
||||
transition.current_owner(),
|
||||
self.service_worker_task_sender(),
|
||||
reserved_client_id,
|
||||
);
|
||||
let retired_client_id = std::mem::replace(&mut self.service_worker_client_id, client_id);
|
||||
if retired_client_id != client_id {
|
||||
self.browser_context_runtime
|
||||
.unregister_service_worker_client(retired_client_id);
|
||||
}
|
||||
self.service_worker_control = None;
|
||||
assert!(
|
||||
self.frame_owner_store
|
||||
.set_current_main_service_worker_client_id(Some(client_id)),
|
||||
"initial Document commit requires a current service worker client owner"
|
||||
);
|
||||
self.apply_main_service_worker_document_owner_transition(transition);
|
||||
}
|
||||
|
||||
fn allocate_service_worker_request_id(&mut self) -> u64 {
|
||||
let request_id = self.next_service_worker_request_id;
|
||||
self.next_service_worker_request_id = request_id
|
||||
|
||||
@@ -116,6 +116,10 @@ impl ScriptVm {
|
||||
page_task_tx.top_level_navigation_handoff_sender(),
|
||||
page_task_tx.service_worker_task_sender(),
|
||||
);
|
||||
host.adopt_initial_document_service_worker_client(
|
||||
transition,
|
||||
env.reserved_service_worker_client_id,
|
||||
);
|
||||
host.retire_document_resource_loader(
|
||||
crate::native_bridge::WindowDocumentOwner::Frame(
|
||||
transition.retired_owner(),
|
||||
|
||||
Reference in New Issue
Block a user