You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

196 lines
6.7 KiB

const OFFLINE_URL = 'lib/pwa/offline.html';
importScripts("vendor/npm-asset/dexie/dist/dexie.min.js")
const staticAssets = [
'.',
'themes/base_files/css/tiki_base.css',
'vendor_bundled/vendor/bower-asset/fontawesome/css/all.css',
'themes/default/css/default.css',
'img/tiki/Tiki_WCG.png',
'tiki-index.php',
'lib/jquery_tiki/iconsets.js',
'lib/tiki-js.js',
'lib/jquery_tiki/tiki-jquery.js',
'tiki-listpages.php',
'vendor/npm-asset/dexie/dist/dexie.min.js',
'lib/jquery_tiki/tiki-trackers.js',
OFFLINE_URL,
];
const cacheName = 'pages-cache-v1';
var db = new Dexie("post_cache");
db.version(1).stores({
messages: 'name,value',
post_cache: 'key,request,timestamp',
});
self.addEventListener('install', event => {
event.waitUntil(
caches.open(cacheName)
.then(cache => cache.addAll(staticAssets))
.then(self.skipWaiting())
);
});
self.addEventListener('activate', event => {
const currentCaches = [cacheName];
event.waitUntil(
caches.keys().then(cacheNames => {
return cacheNames.filter(cacheName => !currentCaches.includes(cacheName));
}).then(cachesToDelete => {
return Promise.all(cachesToDelete.map(cacheToDelete => {
return caches.delete(cacheToDelete);
}));
}).then(() => self.clients.claim())
);
});
// The fetch handler serves responses for same-origin resources from a cache.
// If no response is found, it populates the runtime cache with the response
// from the network before returning it to the page.
self.addEventListener('fetch', event => {
function normalizeRequest(url) {
if (url.includes("tiki-view_tracker_item.php") || url.includes("tiki-ajax_services.php")) {
url = url.replace(/&from=.*/, "");
}
return url;
}
// Skip cross-origin requests, like those for Google Analytics.
if (event.request.url.startsWith(self.location.origin) && event.request.method === "GET" && event.request.url.indexOf("logout") === -1) {
let request = event.request;
let url = normalizeRequest(request.url);
event.respondWith(
caches.match(url).then(cachedResponse => {
return caches.open(cacheName).then(cache => {
return fetch(event.request).then(response => {
// Put a copy of the response in the runtime cache.
return cache.put(event.request, response.clone()).then(() => {
return response;
});
}).catch(error => {
console.warn(cachedResponse, url)
if (cachedResponse) {
return cachedResponse;
}
return caches.match(OFFLINE_URL);
});
}).catch(error => {
return caches.match(OFFLINE_URL);
});
}).catch(error => {
return caches.match(OFFLINE_URL);
})
);
} else if ((event.request.method === "POST" || event.request.method === "PUT") && event.request.url.indexOf("logout") === -1) {
event.respondWith(
fetch(event.request.clone())
.then(function (response) {
return response;
})
.catch(function () {
return cachePut(event, db.post_cache).then(function (resp) { //save request to be done later
return caches.match(event.request.url).then(cachedResponse => {
return db.messages.put({"name": "show-warning", "value": true}).then(function () {
let body;
var init = {
"status": 200, "statusText": "You are offline"
};
if (cachedResponse) {
console.warn("fetch", event.request.url)
body = cachedResponse.body
} else {
let url = normalizeRequest(event.request.referrer);
console.warn("fetch", url)
return caches.match(url).then(cachedResponse => {
console.warn("cache", cachedResponse)
if (cachedResponse)
body = cachedResponse.body
return new Response(body, init);
})
}
return new Response(body, init);
});
});
});
})
);
} else {
console.error(event.request);
}
});
/**
* Serializes a Request into a plain JS object.
*
* @param request
* @returns Promise
*/
function serializeRequest(request) {
var serialized = {
url: request.url,
headers: serializeHeaders(request.headers),
method: request.method,
mode: request.mode,
credentials: request.credentials,
cache: request.cache,
redirect: request.redirect,
referrer: request.referrer
};
// Only if method is not `GET` or `HEAD` is the request allowed to have body.
if (request.method !== 'GET' && request.method !== 'HEAD') {
return request.clone().text().then(function (body) {
serialized.body = body;
return Promise.resolve(serialized);
});
}
return Promise.resolve(serialized);
}
/**
* Saves the response for the given request eventually overriding the previous version
*
* @param data
* @returns Promise
*/
function cachePut(event, store) {
var request = event.request.clone();
return serializeRequest(request.clone()).then(function (data) {
var entry = {
key: Date.now(),
request: data,
timestamp: Date.now()
};
return store.put(entry).then(value => {
return store.get(entry.key).then(function () {
})
})
});
}
/**
* Serializes headers into a plain JS object
*
* @param headers
* @returns object
*/
function serializeHeaders(headers) {
var serialized = {};
// `for(... of ...)` is ES6 notation but current browsers supporting SW, support this
// notation as well and this is the only way of retrieving all the headers.
for (var entry of headers.entries()) {
serialized[entry[0]] = entry[1];
}
return serialized;
}