rastrillo / pwa Public

Clone
git clone https://amadan.net/rastrillo/pwa

Plain git — no account needed to clone.

Download

Download this file

1// The app calls install once in its classic worker, alongside aviso's handlers.
2// Keeping the fallback in the worker avoids caching a login redirect or a page
3// rendered for the account that happened to install it.
4(function (root) {
5 "use strict";
6 const fallback = `<!doctype html><html lang="en"><meta charset="utf-8">
7<meta name="viewport" content="width=device-width,initial-scale=1">
8<title>You're offline</title><style>body{font:1.1rem system-ui;margin:4rem auto;padding:0 1.5rem;max-width:32rem;line-height:1.6}a{color:inherit}</style>
9<main><h1>You're offline</h1><p>Connect to the internet, then try again.</p><a href="">Try again</a></main></html>`;
10 let installed = false;
11
12 function install({ offlineHTML = fallback } = {}) {
13 if (installed) throw new Error("pwa: install may only be called once per worker");
14 if (typeof offlineHTML !== "string" || !offlineHTML.trim()) {
15 throw new Error("pwa: offlineHTML must be a non-empty public HTML document");
16 }
17 installed = true;
18 const scope = new URL(root.registration.scope);
19 function inScope(raw) {
20 const url = new URL(raw);
21 return url.origin === scope.origin && url.pathname.startsWith(scope.pathname);
22 }
23
24 root.addEventListener("fetch", (event) => {
25 const request = event.request;
26 if (request.method !== "GET" || request.mode !== "navigate" || !inScope(request.url)) return;
27 // Never turn HTTP errors into offline successes, and never persist the
28 // network response: it may contain a signed-in person's data.
29 event.respondWith(root.fetch(request, { cache: "no-store" }).catch(() => new Response(offlineHTML, {
30 status: 503,
31 headers: {
32 "Content-Type": "text/html; charset=utf-8",
33 "Cache-Control": "no-store",
34 "Content-Security-Policy": "default-src 'none'; style-src 'unsafe-inline'; base-uri 'none'; form-action 'none'; frame-ancestors 'none'",
35 },
36 })));
37 });
38
39 root.addEventListener("message", (event) => {
40 if (event.data?.type !== "rastrillo:pwa:activate" || !event.source?.url || !inScope(event.source.url)) return;
41 event.waitUntil(root.skipWaiting());
42 });
43 // No unconditional skipWaiting or clients.claim: an older tab may still
44 // have unsaved edits. The app chooses when all tabs can accept an update.
45 }
46
47 root.RastrilloPWA = { install };
48})(self);
49