asd
This commit is contained in:
commit
3e4a056b14
67 files changed
+13926
No files matched your search
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Offline copy of the public calculator (field staff often have weak signal).
|
||||
* - The calculator page: network first (fresh parameters), stored copy when
|
||||
* offline or slow. Responses marked no-store (admin views) are never kept.
|
||||
* - Versioned assets (assets/...?v=): stored copy first.
|
||||
* - calc.php, admin/ and everything else: network only, never stored.
|
||||
*/
|
||||
'use strict';
|
||||
var CACHE = 'serubi-v1';
|
||||
var PAGE_TIMEOUT_MS = 4000;
|
||||
var SCOPE = self.registration.scope; // e.g. https://host/ or http://localhost/calcserubi-prod/
|
||||
var PAGE_KEY = SCOPE; // one stored copy of the calculator, whatever the query string
|
||||
|
||||
self.addEventListener('install', function () { self.skipWaiting(); });
|
||||
|
||||
self.addEventListener('activate', function (event) {
|
||||
event.waitUntil(caches.keys().then(function (keys) {
|
||||
return Promise.all(keys.filter(function (k) { return k !== CACHE; }).map(function (k) { return caches.delete(k); }));
|
||||
}).then(function () { return self.clients.claim(); }));
|
||||
});
|
||||
|
||||
function isCalculatorPage(url) {
|
||||
var rel = url.href.slice(SCOPE.length).split('?')[0];
|
||||
return rel === '' || rel === 'index.php';
|
||||
}
|
||||
|
||||
function storable(res) {
|
||||
return res && res.ok && res.type === 'basic' && !/no-store/i.test(res.headers.get('Cache-Control') || '');
|
||||
}
|
||||
|
||||
function pageNetworkFirst(request) {
|
||||
return caches.open(CACHE).then(function (cache) {
|
||||
var network = fetch(request).then(function (res) {
|
||||
if (storable(res)) cache.put(PAGE_KEY, res.clone());
|
||||
return res;
|
||||
});
|
||||
network.catch(function () { /* handled below */ });
|
||||
var timeout = new Promise(function (resolve) { setTimeout(resolve, PAGE_TIMEOUT_MS); });
|
||||
// slow network: answer from the stored copy after the timeout, if there is one
|
||||
return Promise.race([network, timeout.then(function () { return cache.match(PAGE_KEY).then(function (c) { return c || network; }); })])
|
||||
.catch(function () { return cache.match(PAGE_KEY).then(function (c) { if (c) return c; throw new Error('offline'); }); });
|
||||
});
|
||||
}
|
||||
|
||||
function assetCacheFirst(request) {
|
||||
return caches.open(CACHE).then(function (cache) {
|
||||
return cache.match(request).then(function (hit) {
|
||||
if (hit) return hit;
|
||||
return fetch(request).then(function (res) {
|
||||
if (storable(res)) {
|
||||
// keep only the newest version (?v=) of each asset
|
||||
var path = new URL(request.url).pathname;
|
||||
cache.keys().then(function (keys) {
|
||||
keys.forEach(function (k) { if (new URL(k.url).pathname === path && k.url !== request.url) cache.delete(k); });
|
||||
});
|
||||
cache.put(request, res.clone());
|
||||
}
|
||||
return res;
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
self.addEventListener('fetch', function (event) {
|
||||
var req = event.request;
|
||||
if (req.method !== 'GET') return;
|
||||
var url = new URL(req.url);
|
||||
if (url.origin !== self.location.origin || req.url.indexOf(SCOPE) !== 0) return;
|
||||
if (req.mode === 'navigate' && isCalculatorPage(url)) {
|
||||
event.respondWith(pageNetworkFirst(req));
|
||||
} else if (url.pathname.indexOf('/assets/') !== -1) {
|
||||
event.respondWith(assetCacheFirst(req));
|
||||
}
|
||||
// anything else (calc.php, admin/, ...) goes straight to the network
|
||||
});
|
||||
Reference in new issue
Block a user