Improved www.ttss.krakow.pl
Jacek Kowalski
2017-05-14 4d882e6d16036c99055cfb8df0bf8c25bcbb8d8c
commit | author | age
537471 1 'use strict';
JK 2
3 var CACHE = 'ttss-app-v1';
4 var CACHE_RESOURCES = [
5     '/version.php',
6     '/',
7     '/common.js',
8     '/index.css',
9     '/index.html',
10     '/index.js',
11     '/lang_en.js',
12     '/lang_pl.js',
13     '/map.css',
14     '/map.html',
15     '/map.js',
16     '/serviceworker-install.js',
17     'https://code.jquery.com/jquery-3.1.1.min.js',
18     'https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList',
19     'https://openlayers.org/en/v4.1.0/build/ol.js'
20 ];
21
22 var self = this;
23
24 this.addEventListener('install', event => {
25     event.waitUntil(
26         caches.open(CACHE).then(cache => {
27             return cache.addAll(CACHE_RESOURCES);
28         })
29     );
30 });
31
32 this.addEventListener('fetch', event => {
33     event.respondWith(
34         caches.match(event.request).then(response => response || fetch(event.request))
35     );
36     
37     if(event.request.url.endsWith('/version.php')) {
38         event.waitUntil(
39             Promise.all([
40                 caches.open(CACHE),
41                 fetch(event.request)
42             ]).then(results => {
43                 var cache = results[0];
44                 var v2 = results[1];
45                 var v2copy = v2.clone();
46                 
47                 return Promise.all([
48                     cache.match(event.request).then(v1 => v1.json()),
49                     v2copy.json()
50                 ]).then(results => {
51                     var v1json = results[0];
52                     var v2json = results[1];
53                     
54                     return updateCache(cache, v1json, v2json).then(_ => cache.put(event.request, v2)).then(function() {
55                         console.log('Service Worker: update successful!');
56                         self.skipWaiting();
57                         postMessage({action: 'updated'});
58                     });
59                 });
60             }).catch(function(error) {
61                 console.log('Service Worker: update failed: ', error);
62                 postMessage({action: 'updateFailed'});
63             })
64         );
65     }
66 });
67
68 this.addEventListener('activate', event => {
69     event.waitUntil(
70         caches.keys().then(keyList => Promise.all(
71             keyList.map(key => {
72                 if (key != CACHE) {
73                     return caches.delete(key);
74                 }
75             })
76         )).then(caches.open(CACHE)).then(cache => cache.keys()).then(keys => 
77             console.log(keys)
78         
79             /*Promise.all(
80             keys.map(key => {
81                 console.log(key);
82                 if(!(key in CACHE_RESOURCES)) {
83                     //return cache.delete(key);
84                 }
85             })*/
86         )
87     );
88 });
89
90 function postMessage(message) {
91     self.clients.matchAll().then(clients => {
92         clients.forEach(client => {
93             client.postMessage(message);
94         });
95     });
96 }
97
98 function updateCache(cache, cachedVersion, currentVersion) {
99     var remove = [];
100     var add = [];
101     
102     for(var cachedFile in cachedVersion) {
103         if(!currentVersion[cachedFile]) {
104             remove.push('/' + cachedFile);
105         } else if(cachedVersion[cachedFile] != currentVersion[cachedFile]) {
106             add.push('/' + cachedFile);
107         }
108     }
109     for(var currentFile in currentVersion) {
110         if(CACHE_RESOURCES.indexOf('/' + currentFile) === -1) {
111             continue;
112         } else if(!cachedVersion[currentFile]) {
113             add.push('/' + currentFile);
114         }
115     }
116     
117     console.log('Service Worker: updating files: ', add);
118     console.log('Service Worker: deleting files: ', remove);
119     
120     return cache.addAll(add).then(function() {
121         return Promise.all(
122             remove.map(filename => {
123                 return caches.delete(filename)
124             })
125         );
126     });
127 }
128
129 this.addEventListener('message', function(event) {
130     switch(event.data.action) {
131         case 'skipWaiting':
132             self.skipWaiting();
133         break;
134     }
135 });