1self.addEventListener("push", (event) => { 2 const payload = event.data ? event.data.json() : {}; 3 const title = payload.title || "New message"; 4 const body = payload.body || "You have a new chat message."; 5 const route = payload.route || "/dm"; 6 const tag = payload.tag || payload.messageId || undefined; 7 8 // Always show a notification for push events â browsers treat silent pushes 9 // as violations. Freshness is enforced by the server TTL instead. 10 event.waitUntil( 11 self.registration.showNotification(title, { 12 body, 13 icon: "/icons/icon-192.png", 14 badge: "/icons/icon-192.png", 15 tag, 16 renotify: false, 17 data: { 18 route, 19 messageId: payload.messageId, 20 sentAt: payload.sentAt, 21 }, 22 }) 23 ); 24}); 25 26self.addEventListener("pushsubscriptionchange", (event) => { 27 event.waitUntil( 28 clients.matchAll({ type: "window", includeUncontrolled: true }).then((windowClients) => { 29 for (const client of windowClients) { 30 client.postMessage({ type: "WEB_PUSH_RESUBSCRIBE" }); 31 } 32 }) 33 ); 34}); 35 36self.addEventListener("notificationclick", (event) => { 37 event.notification.close(); 38 const route = event.notification?.data?.route || "/dm"; 39 40 event.waitUntil( 41 clients.matchAll({ type: "window", includeUncontrolled: true }).then((windowClients) => { 42 for (const client of windowClients) { 43 if ("focus" in client) { 44 client.navigate(route); 45 return client.focus(); 46 } 47 } 48 return clients.openWindow(route); 49 }) 50 ); 51});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.