1/* ÐокÑи â service worker. 2 * ÐадаÑи: (1) Ð´ÐµÐ»Ð°ÐµÑ ÑÐ°Ð¹Ñ ÑÑÑанавливаемÑм (PWA), (2) показÑÐ²Ð°ÐµÑ ÑÑÑаниÑÑ Â«ÐÐµÑ ÑоединениÑ» вмеÑÑо оÑибки бÑаÑзеÑа, 3 * (3) ÑÑкоÑÑÐµÑ Ð¿Ð¾Ð²ÑоÑнÑе визиÑÑ: каÑÑинки и ÑÑиÑÑÑ Ð±ÐµÑÑÑÑÑ Ð¸Ð· кÑÑа и ÑÐ¸Ñ Ð¾ обновлÑÑÑÑÑ; ÑÑили и ÑкÑипÑÑ â из ÑеÑи, кÑÑ ÑолÑко на ÑлÑÑай оÑÑÑÑÑÑÐ²Ð¸Ñ ÑвÑзи. 4 * СÑÑаниÑÑ (HTML), лиÑнÑе кабинеÑÑ, админка, запÑоÑÑ POST и лÑбÑе JSON/AJAX-оÑвеÑÑ ÐРкÑÑиÑÑÑÑÑÑ â 5 * ÑÑÐ¾Ð±Ñ Ð½Ð¸ÐºÐ¾Ð³Ð´Ð° не показÑваÑÑ ÑÑжие или ÑÑÑаÑевÑие даннÑе (в Ñом ÑиÑле на обÑем ÑÑÑÑойÑÑве). 6 * ÐÑи изменении логики поднимайÑе VERSION â ÑÑаÑÑе кÑÑи ÑдалÑÑÑÑ Ñами. */ 7const VERSION = 'v3'; 8const STATIC_CACHE = 'woxi-static-' + VERSION; 9const OFFLINE_URL = '/offline.html'; 10const PRECACHE = [OFFLINE_URL, '/pwa/icon-192.png', '/pwa/icon-512.png']; 11 12self.addEventListener('install', event => { 13 event.waitUntil(caches.open(STATIC_CACHE).then(cache => cache.addAll(PRECACHE)).then(() => self.skipWaiting())); 14}); 15 16self.addEventListener('activate', event => { 17 event.waitUntil( 18 caches.keys() 19 .then(keys => Promise.all(keys.filter(key => key !== STATIC_CACHE).map(key => caches.delete(key)))) 20 .then(() => self.clients.claim()) 21 ); 22}); 23 24// ÐаÑÑинки и ÑÑиÑÑÑ â из кÑÑа Ñ ÑÐ¸Ñ Ð¸Ð¼ обновлением; ÑÑили и ÑкÑипÑÑ â ÑнаÑала ÑеÑÑ (ÑÑÐ¾Ð±Ñ Ð½Ðµ оÑдаваÑÑ ÑÑÑаÑевÑий код поÑле Ð¾Ð±Ð½Ð¾Ð²Ð»ÐµÐ½Ð¸Ñ ÑайÑа), кÑÑ ÑолÑко как запаÑной ваÑÐ¸Ð°Ð½Ñ Ð±ÐµÐ· ÑеÑи 25function classify(url) { 26 if (url.origin !== self.location.origin) return null; 27 var ok = url.pathname.indexOf('/resources/') === 0 || url.pathname.indexOf('/storage/') === 0 || url.pathname.indexOf('/pwa/') === 0; 28 if (!ok) return null; 29 if (/\.(?:woff2?|ttf|svg|png|jpe?g|webp|gif|ico)$/i.test(url.pathname)) return 'media'; 30 if (/\.(?:css|js)$/i.test(url.pathname)) return 'code'; 31 return null; 32} 33 34self.addEventListener('fetch', event => { 35 const request = event.request; 36 37 if (request.method !== 'GET') return; 38 39 const url = new URL(request.url); 40 41 if (url.origin !== self.location.origin) return; 42 43 // ÐеÑÐµÑ Ð¾Ð´Ñ Ð¿Ð¾ ÑÑÑаниÑам: вÑегда из ÑеÑи; еÑли ÑеÑи Ð½ÐµÑ â ÑÑÑаниÑа «ÐÐµÑ ÑоединениÑ» 44 if (request.mode === 'navigate') { 45 event.respondWith( 46 fetch(request).catch(() => caches.match(OFFLINE_URL).then(r => r || Response.error())) 47 ); 48 return; 49 } 50 51 const kind = classify(url); 52 53 if (kind === 'media') { 54 event.respondWith( 55 caches.open(STATIC_CACHE).then(cache => 56 cache.match(request).then(cached => { 57 const network = fetch(request).then(response => { 58 if (response && response.ok && response.type === 'basic') cache.put(request, response.clone()); 59 return response; 60 }).catch(() => cached); 61 return cached || network; 62 }) 63 ) 64 ); 65 return; 66 } 67 68 if (kind === 'code') { 69 event.respondWith( 70 fetch(request).then(response => { 71 if (response && response.ok && response.type === 'basic') { 72 const copy = response.clone(); 73 caches.open(STATIC_CACHE).then(cache => cache.put(request, copy)); 74 } 75 return response; 76 }).catch(() => caches.match(request).then(r => r || Response.error())) 77 ); 78 } 79 // вÑÑ Ð¾ÑÑалÑное (AJAX, JSON, админка, ÑаÑ) â напÑÑмÑÑ Ð² ÑеÑÑ, без вмеÑаÑелÑÑÑва 80});
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.