<%# Use the hash of the application.js file as cache name or 'app' if not running in production %> <%# This ensures that the cache is always updated if the hash of the application.js file changes %> const cacheName = '<%= javascript_path('application', asset_host: false).scan(/application-([^\.]+)\.js/).last&.first || 'app' %>'; <%# Paths to cache when the service worker is installed %> const cachePaths = [ '/', '/favicon.ico', '/manifest.json', '/images/webapp-icon-32.png', '/images/webapp-icon-60.png', '/images/webapp-icon-80.png', '/images/webapp-icon-128.png', '/images/webapp-icon-256.png', '/images/webapp-icon-512.png', '<%= service_worker_asset_urls.join "',\n '" %>', '<%= doc_index_urls.join "',\n '" %>', ]; <%# Set-up the cache %> self.addEventListener('install', event => { self.skipWaiting(); event.waitUntil( caches.open(cacheName).then(cache => cache.addAll(cachePaths)), ); }); <%# Remove old caches %> self.addEventListener('activate', event => { event.waitUntil((async () => { const keys = await caches.keys(); const jobs = keys.map(key => key !== cacheName ? caches.delete(key) : Promise.resolve()); return Promise.all(jobs); })()); }); <%# Handle HTTP requests %> self.addEventListener('fetch', event => { event.respondWith((async () => { <% if bypass_cache? %> return fetch(event.request); <% else %> const cachedResponse = await caches.match(event.request); if (cachedResponse) return cachedResponse; try { const response = await fetch(event.request); return response; } catch (err) { const url = new URL(event.request.url); <%# Attempt to return the index page from the cache if the user is visiting a url like devdocs.io/javascript/global_objects/array/find %> <%# The index page will make sure the correct documentation or a proper offline page is shown %> if (url.origin === location.origin && !url.pathname.includes('.')) { const cachedIndex = await caches.match('/'); if (cachedIndex) return cachedIndex; } throw err; } <% end %> })()); });