mirror of
https://github.com/a2nt/silverstripe-progressivewebapp.git
synced 2024-10-22 11:05:45 +02:00
Service worker
This commit is contained in:
parent
a747fb2362
commit
b435128ac0
@ -3,6 +3,11 @@
|
||||
namespace MichelSteege\ProgressiveWebApp\Controllers;
|
||||
|
||||
use SilverStripe\Control\Controller;
|
||||
use SilverStripe\Control\Director;
|
||||
use SilverStripe\ORM\ArrayList;
|
||||
use SilverStripe\View\ArrayData;
|
||||
use SilverStripe\Core\ClassInfo;
|
||||
use MichelSteege\ProgressiveWebApp\Interfaces\ServiceWorkerCacheProvider;
|
||||
|
||||
class ServiceWorkerController extends Controller {
|
||||
|
||||
@ -13,6 +18,11 @@ class ServiceWorkerController extends Controller {
|
||||
'index'
|
||||
];
|
||||
|
||||
/**
|
||||
* @config
|
||||
*/
|
||||
private static $debug_mode = true;
|
||||
|
||||
/**
|
||||
* Default controller action for the service-worker.js file
|
||||
*
|
||||
@ -23,4 +33,43 @@ class ServiceWorkerController extends Controller {
|
||||
return $this->renderWith('ServiceWorker');
|
||||
}
|
||||
|
||||
/**
|
||||
* Base URL
|
||||
* @return varchar
|
||||
*/
|
||||
public function BaseUrl() {
|
||||
return Director::baseURL();
|
||||
}
|
||||
|
||||
/**
|
||||
* Debug mode
|
||||
* @return bool
|
||||
*/
|
||||
public function DebugMode() {
|
||||
if(Director::isDev()){
|
||||
return true;
|
||||
}
|
||||
return $this->config()->get('debug_mode');
|
||||
}
|
||||
|
||||
/**
|
||||
* A list with file to cache in the install event
|
||||
* @return ArrayList
|
||||
*/
|
||||
public function CacheOnInstall() {
|
||||
$paths = [];
|
||||
foreach(ClassInfo::implementorsOf(ServiceWorkerCacheProvider::class) as $class){
|
||||
foreach($class::getServiceWorkerCachedPaths() as $path){
|
||||
$paths[] = $path;
|
||||
}
|
||||
}
|
||||
$list = new ArrayList();
|
||||
foreach($paths as $path){
|
||||
$list->push(new ArrayData([
|
||||
'Path' => $path
|
||||
]));
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
|
||||
}
|
||||
|
9
src/Interfaces/ServiceWorkerCacheProvider.php
Normal file
9
src/Interfaces/ServiceWorkerCacheProvider.php
Normal file
@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace MichelSteege\ProgressiveWebApp\Interfaces;
|
||||
|
||||
interface ServiceWorkerCacheProvider {
|
||||
|
||||
public static function getServiceWorkerCachedPaths();
|
||||
|
||||
}
|
@ -1,26 +1,121 @@
|
||||
self.addEventListener('install', function(e) {
|
||||
console.log('Install');
|
||||
/*
|
||||
e.waitUntil(
|
||||
caches.open('airhorner').then(function(cache) {
|
||||
return cache.addAll([
|
||||
'/',
|
||||
'/index.html',
|
||||
'/index.html?homescreen=1',
|
||||
'/?homescreen=1',
|
||||
'/styles/main.css',
|
||||
'/scripts/main.min.js',
|
||||
'/sounds/airhorn.mp3'
|
||||
]);
|
||||
})
|
||||
);
|
||||
<%--<script>//Ugly fix for code highlights--%>
|
||||
var version = 'v1::';
|
||||
var debug = <% if $DebugMode %>true<% else %>false<% end_if %>;
|
||||
|
||||
/**
|
||||
* Console.log proxy for quick enabling/disabling
|
||||
*/
|
||||
});
|
||||
function log(msg){
|
||||
if(debug){
|
||||
console.log(msg);
|
||||
}
|
||||
}
|
||||
|
||||
self.addEventListener('fetch', function(event) {
|
||||
console.log(event.request.url);
|
||||
});
|
||||
/**
|
||||
* Service worker installation
|
||||
*/
|
||||
self.addEventListener('install', function (event) {
|
||||
log('Service worker: install start');
|
||||
event.waitUntil(caches.open(version + 'fundamentals').then(function (cache) {
|
||||
//Install all required pages/assets
|
||||
return cache.addAll([
|
||||
'$BaseUrl'<% if $CacheOnInstall %>,<% end_if %>
|
||||
<% if $CacheOnInstall %>
|
||||
<% loop $CacheOnInstall %>
|
||||
'$Path'<% if not $Last %>,<% end_if %>
|
||||
<% end_loop %>
|
||||
<% end_if %>
|
||||
]);
|
||||
}).then(function () {
|
||||
log('Service worker: install completed');
|
||||
}).catch(function(){
|
||||
log('Service worker: install failed');
|
||||
}));
|
||||
});
|
||||
|
||||
self.addEventListener('beforeinstallprompt', function(event) {
|
||||
console.log('beforeinstallprompt');
|
||||
});
|
||||
/**
|
||||
* Service worker activation
|
||||
*/
|
||||
self.addEventListener('activate', function (event) {
|
||||
log('Service worker: activate start');
|
||||
event.waitUntil(caches.keys().then(function (keys) {
|
||||
//Remove old cache entries
|
||||
return Promise.all(keys.filter(function (key) {
|
||||
return !key.startsWith(version);
|
||||
}).map(function (key) {
|
||||
return caches.delete(key);
|
||||
}));
|
||||
}).then(function () {
|
||||
log('Service worker: activate completed');
|
||||
}));
|
||||
});
|
||||
|
||||
/**
|
||||
* Fetch handler
|
||||
*/
|
||||
self.addEventListener('fetch', function (event) {
|
||||
//We are only interested in get requests
|
||||
if (event.request.method !== 'GET') {
|
||||
return;
|
||||
}
|
||||
|
||||
//Parse the url
|
||||
var requestURL = new URL(event.request.url);
|
||||
|
||||
//Test for images
|
||||
if (/\.(jpg|jpeg|png|gif|webp)$/.test(requestURL.pathname)) {
|
||||
log('Service worker: skip image ' + event.request.url);
|
||||
//For now we skip images but change this later to maybe some caching and/or an offline fallback
|
||||
return;
|
||||
}
|
||||
|
||||
//Check for our own urls
|
||||
if (requestURL.origin == location.origin) {
|
||||
//All our own urls are following this route:
|
||||
//-If there is cache serve from cache but also update the cache from the network
|
||||
//-If there is no cache then get from the network and put in the cache
|
||||
//-If both fail fallback to a generic offline message
|
||||
event.respondWith(caches.match(event.request).then(function (cached) {
|
||||
var networked = fetch(event.request).then(fetchedFromNetwork, unableToResolve).catch(unableToResolve);
|
||||
log('Service worker: fetch event ' + (cached ? '(cached)' : '(network)') + ' - ' + event.request.url);
|
||||
return cached || networked;
|
||||
|
||||
/**
|
||||
* Fetched from network handler
|
||||
*/
|
||||
function fetchedFromNetwork(response) {
|
||||
var cacheCopy = response.clone();
|
||||
log('Service worker fetch from network - ' + event.request.url);
|
||||
caches.open(version + 'pages').then(function add(cache) {
|
||||
cache.put(event.request, cacheCopy);
|
||||
}).then(function () {
|
||||
log('Service worker: fetch response stored in cache - ' + event.request.url);
|
||||
});
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* No internet and no cache handler
|
||||
*/
|
||||
function unableToResolve(error) {
|
||||
log('Service worker: fetch request failed in both cache and network ' + error);
|
||||
return new Response('<h1>Service Unavailable</h1>', {
|
||||
status: 503,
|
||||
statusText: 'Service Unavailable',
|
||||
headers: new Headers({
|
||||
'Content-Type': 'text/html'
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
}));
|
||||
return;
|
||||
}
|
||||
|
||||
//All others, nothing special here
|
||||
log('Service worker: other url - ' + event.request.url);
|
||||
event.respondWith(caches.match(event.request).then(function(response) {
|
||||
return response || fetch(event.request);
|
||||
}));
|
||||
});
|
||||
//<%--Ugly fix for code highlights</script>--%>
|
Loading…
Reference in New Issue
Block a user