1
0
mirror of https://github.com/cotes2020/jekyll-theme-chirpy.git synced 2025-12-18 05:41:31 +00:00

refactor(pwa): revert to JS and Liquid mixing

The gem package won't be able to pass `/sw.min.js` to the user end
This commit is contained in:
Cotes Chung
2024-02-13 23:35:32 +08:00
parent 90693ff95e
commit 6b34901d94
9 changed files with 25 additions and 51 deletions

54
assets/js/pwa/app.js Normal file
View File

@@ -0,0 +1,54 @@
---
layout: compress
permalink: /assets/js/dist/:basename.min.js
---
if ('serviceWorker' in navigator) {
const isEnabled = '{{ site.pwa.enabled }}' === 'true';
if (isEnabled) {
const swUrl = '{{ '/sw.min.js' | relative_url }}';
const $notification = $('#notification');
const $btnRefresh = $('#notification .toast-body>button');
navigator.serviceWorker.register(swUrl).then((registration) => {
{% comment %}In case the user ignores the notification{% endcomment %}
if (registration.waiting) {
$notification.toast('show');
}
registration.addEventListener('updatefound', () => {
registration.installing.addEventListener('statechange', () => {
if (registration.waiting) {
if (navigator.serviceWorker.controller) {
$notification.toast('show');
}
}
});
});
$btnRefresh.on('click', () => {
if (registration.waiting) {
registration.waiting.postMessage('SKIP_WAITING');
}
$notification.toast('hide');
});
});
let refreshing = false;
{% comment %}Detect controller change and refresh all the opened tabs{% endcomment %}
navigator.serviceWorker.addEventListener('controllerchange', () => {
if (!refreshing) {
window.location.reload();
refreshing = true;
}
});
} else {
navigator.serviceWorker.getRegistrations().then(function (registrations) {
for (let registration of registrations) {
registration.unregister();
}
});
}
}

101
assets/js/pwa/sw.js Normal file
View File

@@ -0,0 +1,101 @@
---
layout: compress
permalink: /:basename.min.js
# PWA service worker
---
const swconfUrl = '{{ '/assets/js/data/swconf.js' | relative_url }}';
importScripts(swconfUrl);
const purge = swconf.purge;
function verifyHost(url) {
for (const host of swconf.allowHosts) {
const regex = RegExp(`^http(s)?://${host}/`);
if (regex.test(url)) {
return true;
}
}
return false;
}
function verifyUrl(url) {
if (!verifyHost(url)) {
return false;
}
const requestPath = new URL(url).pathname;
for (const path of swconf.denyPaths) {
if (requestPath.startsWith(path)) {
return false;
}
}
return true;
}
if (!purge) {
swconf.allowHosts.push(location.host);
}
self.addEventListener('install', (event) => {
if (purge) {
return;
}
event.waitUntil(
caches.open(swconf.cacheName).then((cache) => {
return cache.addAll(swconf.resources);
})
);
});
self.addEventListener('activate', (event) => {
event.waitUntil(
caches.keys().then((keyList) => {
return Promise.all(
keyList.map((key) => {
if (purge) {
return caches.delete(key);
} else {
if (key !== swconf.cacheName) {
return caches.delete(key);
}
}
})
);
})
);
});
self.addEventListener('message', (event) => {
if (event.data === 'SKIP_WAITING') {
self.skipWaiting();
}
});
self.addEventListener('fetch', (event) => {
event.respondWith(
caches.match(event.request).then((response) => {
if (response) {
return response;
}
return fetch(event.request).then((response) => {
const url = event.request.url;
if (purge || event.request.method !== 'GET' || !verifyUrl(url)) {
return response;
}
{% comment %}See: <https://developers.google.com/web/fundamentals/primers/service-workers#cache_and_return_requests>{% endcomment %}
let responseToCache = response.clone();
caches.open(swconf.cacheName).then((cache) => {
cache.put(event.request, responseToCache);
});
return response;
});
})
);
});