diff --git a/views/index.html b/views/index.html
index c13584043bf..dbff801392f 100644
--- a/views/index.html
+++ b/views/index.html
@@ -729,29 +729,11 @@
console.log('Service worker registered');
reg.addEventListener('updatefound', () => {
console.log('Service worker update detected');
+ reg.update();
const newWorker = reg.installing;
- var reloaded;
-
- newWorker.addEventListener('statechange', (stateEvent) => {
- console.log('New worker state change', stateEvent.currentTarget.state, stateEvent);
-
- if (stateEvent.currentTarget.state == 'installed') {
- // `controller` should be assigned if an active worker already exists
- if (navigator.serviceWorker.controller) {
- // a new worker was activated, so refresh the page
- if (reloaded) {
- // needed to prevent reload loops with `update on reload` option in dev tools
- return;
- }
-
- console.log('New service worker installed, refreshing');
- reloaded = true;
- window.location.reload(true);
- } else {
- // there was no active worker, so it was cached and no refresh is necessary
- console.log('Service worker cached');
- }
- }
+ newWorker.addEventListener('statechange', (state) => {
+ console.log('New worker state change', state);
+ window.location.reload(true);
});
});
}).catch(function(error) {
diff --git a/views/service-worker.js b/views/service-worker.js
index ef28360abaf..41b5043897e 100644
--- a/views/service-worker.js
+++ b/views/service-worker.js
@@ -38,10 +38,57 @@ const CACHE_LIST = [
'/images/logo2.png'
];
-// Open a cache and use `addAll()` with an array of assets to add all of them
-// to the cache. Return a promise resolving when all the assets are added.
+function returnRangeRequest(request) {
+ return caches
+ .open(CACHE)
+ .then((cache) => {
+ return cache.match(request.url);
+ })
+ .then((res) => {
+ if (!res) {
+ return fetch(request)
+ .then(res => {
+ const clonedRes = res.clone();
+ return caches
+ .open(CACHE)
+ .then(cache => cache.put(request, clonedRes))
+ .then(() => res);
+ })
+ .then(res => {
+ return res.arrayBuffer();
+ });
+ }
+ return res.arrayBuffer();
+ })
+ .then((arrayBuffer) => {
+ const bytes = /^bytes=(\d+)-(\d+)?$/g.exec(
+ request.headers.get('range')
+ );
+ if (bytes) {
+ const start = Number(bytes[1]);
+ const end = Number(bytes[2]) || arrayBuffer.byteLength - 1;
+ return new Response(arrayBuffer.slice(start, end + 1), {
+ status: 206,
+ statusText: 'Partial Content',
+ headers: [
+ ['Content-Range', `bytes ${start}-${end}/${arrayBuffer.byteLength}`]
+ ]
+ });
+ } else {
+ return new Response(null, {
+ status: 416,
+ statusText: 'Range Not Satisfiable',
+ headers: [['Content-Range', `*/${arrayBuffer.byteLength}`]]
+ });
+ }
+ });
+}
+
+// Open a cache and `put()` the assets to the cache.
+// Return a promise resolving when all the assets are added.
function precache() {
- return caches.open(CACHE).then(function (cache) {
+ return caches.open(CACHE)
+ .then((cache) => {
// if any cache requests fail, don't interrupt other requests in progress
return Promise.allSettled(
CACHE_LIST.map((url) => {
@@ -59,50 +106,43 @@ function precache() {
});
}
-// Open the cache where the assets were stored and search for the requested
-// resource. Notice that in case of no matching, the promise still resolves
-// but it does with `undefined` as value.
-function fromCache(request) {
- return caches.open(CACHE).then(function (cache) {
- return cache.match(request).then(function (matching) {
- return matching || Promise.reject('no-match');
- });
- });
-}
-
-// Update consists in opening the cache, performing a network request and
-// storing the new response data.
-function update(request) {
- return caches.open(CACHE).then(function (cache) {
- return fetch(request).then(function (response) {
- return cache.put(request, response);
- });
- });
-}
-
// Try to read the requested resource from cache.
// If the requested resource does not exist in the cache, fetch it from
// network and cache the response.
-function fromCacheOrUpdate(request) {
- return caches.open(CACHE).then(function (cache) {
- return cache.match(request).then(function (cacheResponse) {
- return cacheResponse || fetch(request).then(function (netResponse) {
- cache.put(request, netResponse.clone());
- return netResponse;
+function fromCache(request) {
+ return caches.open(CACHE).then((cache) => {
+ return cache.match(request).then((matching) => {
+ console.log(matching);
+ if(matching){
+ return matching;
+ }
+
+ return fetch(request).then((response) => {
+ // console.log('Response from network is:', response);
+ cache.put(request, response.clone());
+ return response;
+ }).catch((error) => {
+ // This catch() will handle exceptions thrown from the fetch() operation.
+ // Note that a HTTP error response (e.g. 404) will NOT trigger an exception.
+ // It will return a normal response object that has the appropriate error code set.
+ console.error('Fetching failed:', error);
+
+ throw error;
});
});
});
}
// On install, cache some resources.
-self.addEventListener('install', function(evt) {
- console.log('The service worker is being installed.');
+self.addEventListener('install', (evt) => {
+ // console.log('The service worker is being installed.');
+ self.skipWaiting();
evt.waitUntil(precache());
});
function inCache(request) {
let found = false;
- CACHE_LIST.forEach( function (e) {
+ CACHE_LIST.forEach((e) => {
if (request.url.endsWith(e)) {
found = true;
}
@@ -110,38 +150,29 @@ function inCache(request) {
return found;
}
-self.addEventListener('fetch', function(evt) {
+self.addEventListener('fetch', (evt) => {
if (!evt.request.url.startsWith(self.location.origin) || CACHE === 'developmentMode' || !inCache(evt.request) || evt.request.method !== 'GET') {
- // console.log('Skipping cache for', evt.request.url);
- evt.respondWith(fetch(evt.request));
+ //console.log('Skipping cache for ', evt.request.url);
+ return void evt.respondWith(fetch(evt.request));
+ }
+ if (evt.request.headers.get('range')) {
+ evt.respondWith(returnRangeRequest(evt.request));
} else {
- var request = evt.request;
- if (evt.request.headers.has('Range')) {
- // Firefox will give an error if it tries to store partial content (206) responses in the cache.
- // To mitigate this, strip the `Range` header from the request so a full document (200) is returned.
- var strippedHeaders = new Headers(evt.request.headers).delete('Range');
- request = new Request(evt.request, { headers: strippedHeaders });
- }
- // console.log('Using cache for', evt.request);
- evt.respondWith(fromCacheOrUpdate(request));
+ evt.respondWith(fromCache(evt.request));
}
});
self.addEventListener('activate', (event) => {
event.waitUntil(
caches.keys().then((cacheNames) => {
- if (!cacheNames) {
- // Fallback to an empty array if cache is empty.
- // This can occur if the prefetch fails.
- return [];
- }
+ return Promise.all(
+ cacheNames.map((cacheName) => {
+ if (cacheName !== CACHE) {
+ // console.log('Deleting out of date cache:', cacheName);
+ return caches.delete(cacheName);
+ }
+ })
+ );
+ }));
- return cacheNames.filter((cacheName) => CACHE !== cacheName);
- }).then((unusedCaches) => {
- // console.log('DESTROYING CACHE', unusedCaches.join(','));
- return Promise.all(unusedCaches.map((unusedCache) => {
- return caches.delete(unusedCache);
- }));
- }).then(() => self.clients.claim())
- );
-});
\ No newline at end of file
+});