js/offline.js

/**
* @file Defines a client-side script for offline visits to pages not `CacheStorage`
* @author Reuben L. Lillie <reubenlillie@gmail.com>
* @since 0.3.0
* @see {@link https://github.com/cferdinandi/go-make-things/blob/master/content/offline.md Example offline landing page by Chris Ferdinandi}
*/


// Immediately invoked function expression to enclose scope
(function () {
// Client supports service workers
if(navigator && navigator.serviceWorker) {
// Immediately invoked asynchronous function to enclose scope
(async () => {
/**
* Define markup for listing cached pages
* @since 0.1.0
* @param {Promise<Request[]>} pages `Request` objects in pages cache
* @return {String} HTML
*/

var html = pages => {
/**
* DOM object with `data-offline attribute
* @type {Object}
*/

var offline = document.querySelector('[data-offline]');

// Only create the markup when there are pages to list
offline.innerHTML = `<!-- ./js/offline.js -->
<p>You can still access these pages you’ve already viewed:</p>
<ul>
${pages.map(page => `<li>
<a href="
${page.url}">${page.url}</a>
</li>
`
).join('\n')}

</ul>
`

return
}

/**
* Display pages from the `CacheStorage` API
* @since 0.1.0
* @param {String} key `cacheName` to request from `CacheStorage`
* @return {Function} cachedPages
*/

var displayCachedPages = async key => {
/**
* `Cache` obejct matching the `key` paramater
* @type {Promise<Cache>}
*/

var cache = await caches.open(key)

/**
* `Request` objects
* @type {Promise<Request[]>}
*/

var keys = await cache.keys()

/**
* `Request` objects that are pages, not including the offline landing page
* @type {Request[]}
*/

var pages = keys.filter(key => key.url.endsWith('/') && !key.url.includes('/offline/'))

return pages.length > 0
? html(pages)
: console.warn('No pages to display in CacheStorage')
}

/**
* Get pages from the `CacheStorage` API
* @since 0.1.0
* @return {string[]} From the page cache
*/

var getCachedPages = async () => {
/**
* Names of `Cache` objects
* @type {Promise<string[]>}
*/

var keys = await caches.keys()
return keys.filter(key => key.includes('_pages'))
}

var cachedPages = await getCachedPages()
return cachedPages.forEach(key => displayCachedPages(key))
})()
}
return
}())