Files
xmrpay.link/sw.js
Alexander Schmidt 6a9a5b6a75 perf: self-host fonts, eliminate CLS, a11y and contrast fixes
- Self-host Inter and JetBrains Mono (woff2, 69KB total)
- Remove Google Fonts dependency entirely (no external requests)
- Service Worker pre-caches font files
- Eliminate font-swap layout shifts
- WCAG contrast fix: disabled button uses solid color instead of opacity
- Footer link always underlined for distinguishability
- Translated aria-labels via data-i18n-aria
- Dimmed QR with "Bezahlt" stamp on paid invoices
- Hide wallet/address buttons when invoice is paid
2026-03-25 16:56:10 +01:00

62 lines
1.5 KiB
JavaScript

var CACHE_NAME = 'xmrpay-v3';
var ASSETS = [
'/',
'/index.html',
'/app.js',
'/i18n.js',
'/style.css',
'/lib/qrcode.min.js',
'/fonts/inter-400.woff2',
'/fonts/jetbrains-400.woff2'
// xmr-crypto.bundle.js and jspdf.min.js are lazy-loaded and runtime-cached
];
self.addEventListener('install', function (e) {
e.waitUntil(
caches.open(CACHE_NAME).then(function (cache) {
return cache.addAll(ASSETS);
})
);
self.skipWaiting();
});
self.addEventListener('activate', function (e) {
e.waitUntil(
caches.keys().then(function (names) {
return Promise.all(
names.filter(function (n) { return n !== CACHE_NAME; })
.map(function (n) { return caches.delete(n); })
);
})
);
self.clients.claim();
});
self.addEventListener('fetch', function (e) {
var url = new URL(e.request.url);
// External APIs and RPC proxy — network only, don't cache
if (url.hostname !== location.hostname || url.pathname.startsWith('/api/')) {
e.respondWith(fetch(e.request));
return;
}
// App assets — cache first, fallback to network
e.respondWith(
caches.match(e.request).then(function (cached) {
var networkFetch = fetch(e.request).then(function (response) {
if (response.ok) {
var clone = response.clone();
caches.open(CACHE_NAME).then(function (cache) {
cache.put(e.request, clone);
});
}
return response;
}).catch(function () {
return cached;
});
return cached || networkFetch;
})
);
});