Initial commit: KGV-PWA plugin with manifest, service worker and install prompt

This commit is contained in:
Ronny Grobel
2026-04-20 21:12:48 +02:00
commit e6930011ab
5 changed files with 891 additions and 0 deletions

117
assets/js/service-worker.js Normal file
View File

@@ -0,0 +1,117 @@
/**
* KGV PWA Service Worker
*
* Strategie:
* - HTML-Seiten: Network-first (frische Inhalte, Fallback auf Cache)
* - Statische Assets (CSS/JS/Bilder/Fonts): Cache-first
*/
'use strict';
const CACHE_NAME = 'kgv-pwa-v1';
const OFFLINE_PAGE = '/';
const PRECACHE_URLS = [
'/',
];
// -----------------------------------------------------------------------
// Install: Precache-Ressourcen laden
// -----------------------------------------------------------------------
self.addEventListener( 'install', function ( event ) {
event.waitUntil(
caches.open( CACHE_NAME ).then( function ( cache ) {
return cache.addAll( PRECACHE_URLS );
} )
);
self.skipWaiting();
} );
// -----------------------------------------------------------------------
// Activate: Alte Caches löschen
// -----------------------------------------------------------------------
self.addEventListener( 'activate', function ( event ) {
event.waitUntil(
caches.keys().then( function ( keys ) {
return Promise.all(
keys
.filter( function ( key ) { return key !== CACHE_NAME; } )
.map( function ( key ) { return caches.delete( key ); } )
);
} )
);
self.clients.claim();
} );
// -----------------------------------------------------------------------
// Fetch: Anfragen abfangen
// -----------------------------------------------------------------------
self.addEventListener( 'fetch', function ( event ) {
var request = event.request;
// Nur GET-Anfragen behandeln
if ( request.method !== 'GET' ) {
return;
}
// Nur Anfragen gleichen Ursprungs behandeln
if ( ! request.url.startsWith( self.location.origin ) ) {
return;
}
var url = new URL( request.url );
// Admin-Bereich und WP-Cron ausschließen
if (
url.pathname.startsWith( '/wp-admin' ) ||
url.pathname.startsWith( '/wp-cron' ) ||
url.pathname.includes( 'wp-login' )
) {
return;
}
// HTML-Navigation: Network-first
if ( request.mode === 'navigate' ) {
event.respondWith(
fetch( request )
.then( function ( response ) {
// Erfolgreiche Antwort im Cache speichern
if ( response && response.status === 200 ) {
var clone = response.clone();
caches.open( CACHE_NAME ).then( function ( cache ) {
cache.put( request, clone );
} );
}
return response;
} )
.catch( function () {
// Offline-Fallback: gecachte Startseite
return caches.match( request ).then( function ( cached ) {
return cached || caches.match( OFFLINE_PAGE );
} );
} )
);
return;
}
// Statische Assets: Cache-first
if ( /\.(css|js|png|jpg|jpeg|gif|svg|webp|woff2?|ttf|eot|ico)(\?.*)?$/.test( url.pathname ) ) {
event.respondWith(
caches.match( request ).then( function ( cached ) {
if ( cached ) {
return cached;
}
return fetch( request ).then( function ( response ) {
if ( response && response.status === 200 ) {
var clone = response.clone();
caches.open( CACHE_NAME ).then( function ( cache ) {
cache.put( request, clone );
} );
}
return response;
} );
} )
);
return;
}
} );