--- /dev/null
+/* global self, caches, fetch, URL, Response */
+'use strict';
+
+var config = {
+ version: 'v1',
+ staticCacheItems: [
+ 'index.html',
+ 'jquery.min.js',
+ 'nanofun.js',
+ 'nanofun.css'
+ ]
+};
+
+function cacheName (key, opts) {
+ return `${opts.version}-${key}`;
+}
+
+function addToCache (cacheKey, request, response) {
+ if (response.ok) {
+ var copy = response.clone();
+ caches.open(cacheKey).then( cache => {
+ cache.put(request, copy);
+ });
+ }
+ return response;
+}
+
+function fetchFromCache (event) {
+ return caches.match(event.request).then(response => {
+ if (!response) {
+ throw Error(`${event.request.url} not found in cache`);
+ }
+ return response;
+ });
+}
+
+function offlineResponse (resourceType, opts) {
+ return undefined;
+}
+
+self.addEventListener('install', event => {
+ function onInstall (event, opts) {
+ var cacheKey = cacheName('static', opts);
+ return caches.open(cacheKey)
+ .then(cache => cache.addAll(opts.staticCacheItems));
+ }
+
+ event.waitUntil(
+ onInstall(event, config).then( () => self.skipWaiting() )
+ );
+});
+
+self.addEventListener('activate', event => {
+ function onActivate (event, opts) {
+ return caches.keys()
+ .then(cacheKeys => {
+ var oldCacheKeys = cacheKeys.filter(key => key.indexOf(opts.version) !== 0);
+ var deletePromises = oldCacheKeys.map(oldKey => caches.delete(oldKey));
+ return Promise.all(deletePromises);
+ });
+ }
+
+ event.waitUntil(
+ onActivate(event, config)
+ .then( () => self.clients.claim() )
+ );
+});
+
+self.addEventListener('fetch', event => {
+
+ function shouldHandleFetch (event, opts) {
+ var request = event.request;
+ var url = new URL(request.url);
+ var criteria = {
+ isGETRequest : request.method === 'GET',
+ isFromMyOrigin : url.origin === self.location.origin
+ };
+ var failingCriteria = Object.keys(criteria)
+ .filter(criteriaKey => !criteria[criteriaKey]);
+ return !failingCriteria.length;
+ }
+
+ function onFetch (event, opts) {
+ var request = event.request;
+ var acceptHeader = request.headers.get('Accept');
+ var resourceType = 'static';
+ var cacheKey;
+
+ if (acceptHeader.indexOf('text/html') !== -1) {
+ resourceType = 'content';
+ } else if (acceptHeader.indexOf('image') !== -1) {
+ resourceType = 'image';
+ }
+
+ cacheKey = cacheName(resourceType, opts);
+
+ if (resourceType === 'content') {
+ event.respondWith(
+ fetch(request)
+ .then(response => addToCache(cacheKey, request, response))
+ .catch(() => fetchFromCache(event))
+ .catch(() => offlineResponse(resourceType, opts))
+ );
+ } else {
+ event.respondWith(
+ fetchFromCache(event)
+ .catch(() => fetch(request))
+ .then(response => addToCache(cacheKey, request, response))
+ .catch(() => offlineResponse(resourceType, opts))
+ );
+ }
+ }
+ if (shouldHandleFetch(event, config)) {
+ onFetch(event, config);
+ }
+
+});