1/** 2 * Copyright 2016-2023 The Cotonic Authors. All Rights Reserved. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS-IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17"use strict"; 18 19self.addEventListener('install', (event) => { 20 event.waitUntil( self.skipWaiting() ); 21}); 22 23self.addEventListener('activate', (event) => { 24 event.waitUntil( self.clients.claim() ); 25}); 26 27self.addEventListener('fetch', (event) => { 28 // Firefox 88 is failing downloads for large requests over slower 29 // connections if the service worker handles the fetch event. 30 // Temporarily disabled the code below to fix this issue. 31 // 32 // if ( !event.request.headers.get('range') 33 // && !event.request.headers.get('x-no-cache')) { 34 // // fetch drops the 'range' header, which is used 35 // // with video and audio requests. 36 // event.respondWith( fetch( event.request ) ); 37 // } 38}); 39 40self.addEventListener('message', (event) => { 41 switch (event.data.type) { 42 case "broadcast": 43 // Relay broadcast messages 44 const message = event.data; 45 message.sender_id = event.source.id; 46 47 event.waitUntil(messageClients(message)); 48 break; 49 default: 50 console.info("Service Worker: unknown message", event); 51 } 52}); 53 54self.addEventListener('push', (event) => { 55 const message = event.data.json(); 56 57 switch(message.type) { 58 case "notification": 59 const data = message.data; 60 self.registration.showNotification(data.title, data.options); 61 break; 62 default: 63 console.info("Service Worker: unknown push message", event); 64 } 65}); 66 67self.addEventListener("notificationclick", (event) => { 68 const notification = event.notification; 69 const localURL = ensureLocalURL(notification.data?notification.data.url:undefined); 70 event.waitUntil(focusWindow(localURL)); 71}); 72 73 74// Try to focus a tab with the given url. When such a tab is not found, 75// a new one will be opened. 76function focusWindow(url) { 77 return clients.matchAll({ type: "window" }) 78 .then((clientList) => { 79 // Check if there already is a tab with has this url open. 80 for(const client of clientList) { 81 if((client.url === url) && ('focus' in client)) { 82 return client.focus(); 83 } 84 } 85 86 if (clients.openWindow) { 87 return clients.openWindow(url); 88 } 89 }); 90} 91 92// Relay a message to all clients (including the sender) 93function messageClients( message ) { 94 return self.clients.matchAll() 95 .then((clientList) => { 96 clientList.forEach((client) => { 97 client.postMessage(message); 98 }) 99 }); 100} 101 102// Ensure that a local url is returned to prevent cross 103// origin navigations from a notification. 104function ensureLocalURL(url) { 105 let parsed; 106 107 if(url) { 108 parsed = new URL(url, self.origin); 109 } 110 111 if((parsed === undefined) || (parsed.origin !== self.origin)) { 112 parsed = new URL("/", self.origin); 113 } 114 115 return parsed.toJSON(); 116}
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.