-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathsw.js
More file actions
145 lines (127 loc) · 4.37 KB
/
sw.js
File metadata and controls
145 lines (127 loc) · 4.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
// https://brandonrozek.com/blog/2015-11-30-limiting-cache-service-workers-revisited3/
// https://developer.mozilla.org/en-US/docs/Web/API/Cache/match#ignoresearch
// Use {'ignoreSearch': true} to make the cache not choke on URLs with query strings
var version = 'v2.0.29:';
var offlineFundamentals = [
'.',
'index21.html',
'lexicon.xml',
'simple.css'
];
//Add core website files to cache during serviceworker installation
var updateStaticCache = function() {
return caches.open(version + 'fundamentals').then(function(cache) {
return Promise.all(offlineFundamentals.map(function(value) {
var request = new Request(value);
var url = new URL(request.url);
if (url.origin != location.origin) {
request = new Request(value, {mode: 'no-cors'});
}
return fetch(request).then(function(response) {
var cachedCopy = response.clone();
return cache.put(request, cachedCopy);
});
}))
})
};
//Clear caches with a different version number
var clearOldCaches = function() {
return caches.keys().then(function(keys) {
return Promise.all(
keys
.filter(function (key) {
return key.indexOf(version) != 0;
})
.map(function (key) {
return caches.delete(key);
})
);
})
}
/*
trims the cache
If cache has more than maxItems then it removes the excess items starting from the beginning
*/
var trimCache = function (cacheName, maxItems) {
caches.open(cacheName)
.then(function (cache) {
cache.keys()
.then(function (keys) {
if (keys.length > maxItems) {
cache.delete(keys[0])
.then(trimCache(cacheName, maxItems));
}
});
});
};
//When the service worker is first added to a computer
self.addEventListener("install", function(event) {
event.waitUntil(updateStaticCache()
.then(function() {
return self.skipWaiting();
})
);
})
self.addEventListener("message", function(event) {
var data = event.data;
//Send this command whenever many files are downloaded (ex: a page load)
if (data.command == "trimCache") {
trimCache(version + "pages", 25);
trimCache(version + "images", 10);
trimCache(version + "assets", 30);
}
});
//Service worker handles networking
self.addEventListener("fetch", function(event) {
//Fetch from network and cache
var fetchFromNetwork = function(response) {
var cacheCopy = response.clone();
if (event.request.headers.get('Accept').indexOf('text/html') != -1) {
caches.open(version + 'pages').then(function(cache) {
cache.put(event.request, cacheCopy);
});
} else if (event.request.headers.get('Accept').indexOf('image') != -1) {
caches.open(version + 'images').then(function(cache) {
cache.put(event.request, cacheCopy);
});
} else {
caches.open(version + 'assets').then(function add(cache) {
cache.put(event.request, cacheCopy);
});
}
return response;
}
//Fetch from network failed
var fallback = function() {
if (event.request.headers.get('Accept').indexOf('text/html') != -1) {
return caches.match(event.request, {'ignoreSearch': true}).then(function (response) {
return response || caches.match('/offline/');
})
} else if (event.request.headers.get('Accept').indexOf('image') != -1) {
return new Response('Offlineoffline', { headers: { 'Content-Type': 'image/svg+xml' }});
}
}
//This service worker won't touch non-get requests
if (event.request.method != 'GET') {
return;
}
//For HTML requests, look for file in network, then cache if network fails.
if (event.request.headers.get('Accept').indexOf('text/html') != -1) {
event.respondWith(fetch(event.request).then(fetchFromNetwork, fallback));
return;
}
//For non-HTML requests, look for file in cache, then network if no cache exists.
event.respondWith(
caches.match(event.request, {'ignoreSearch': true}).then(function(cached) {
return cached || fetch(event.request).then(fetchFromNetwork, fallback);
})
)
});
//After the install event
self.addEventListener("activate", function(event) {
event.waitUntil(clearOldCaches()
.then(function() {
return self.clients.claim();
})
);
});