Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add service worker #399

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
25 changes: 25 additions & 0 deletions src/component/data/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,26 @@ data.remove = (key) => {
window.localStorage.removeItem(key);
};

data.clear_serviceWorker = () => {
if ('serviceWorker' in navigator) {
navigator.serviceWorker.getRegistrations().then((registrations) => {
registrations.forEach((registration) => {
registration.unregister();
});
});
}
};

data.clear_cache = () => {
if ('caches' in window) {
caches.keys().then((cacheNames) => {
cacheNames.forEach((cacheName) => {
caches.delete(cacheName);
});
});
}
};

data.backup = (dataToBackup) => {
if (dataToBackup) {
data.set(APP_NAME + 'Backup', JSON.stringify(dataToBackup));
Expand Down Expand Up @@ -315,11 +335,16 @@ data.load = () => {

data.wipe = {
all: () => {
data.clear_serviceWorker();
data.clear_cache();

data.remove(APP_NAME);

data.reload.render();
},
partial: () => {
data.clear_serviceWorker();
data.clear_cache();
bookmark.reset();

data.set(APP_NAME, JSON.stringify({
Expand Down
46 changes: 22 additions & 24 deletions src/component/version/index.js
Original file line number Diff line number Diff line change
@@ -1,38 +1,36 @@
export const version = {};
export const version = {
number: '7.5.0',
name: 'Delightful Komodo Dragon',
compare: (a, b) => {

version.number = '7.5.0';
let pa = a.split('.');

version.name = 'Delightful Komodo Dragon';
let pb = b.split('.');

version.compare = (a, b) => {
for (let i = 0; i < 3; i++) {

let pa = a.split('.');
let na = Number(pa[i]);

let pb = b.split('.');
let nb = Number(pb[i]);

for (let i = 0; i < 3; i++) {
if (na > nb) {
return 1;
}

let na = Number(pa[i]);
if (nb > na) {
return -1;
}

let nb = Number(pb[i]);
if (!isNaN(na) && isNaN(nb)) {
return 1;
}

if (na > nb) {
return 1;
}

if (nb > na) {
return -1;
}
if (isNaN(na) && !isNaN(nb)) {
return -1;
}

if (!isNaN(na) && isNaN(nb)) {
return 1;
}

if (isNaN(na) && !isNaN(nb)) {
return -1;
}

return 0;
}

return 0;
};
10 changes: 10 additions & 0 deletions src/initialBackground.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,13 @@ if (localStorage.getItem('nightTabStyle')) {
}
document.querySelector('head').appendChild(style);
}

// check if service worker is available
if ('serviceWorker' in navigator) {
// register service worker
navigator.serviceWorker.register('./service_worker.js').then(() => {
console.log('serviceWorker registered');
}).catch(error => {
console.log('serviceWorker registration failed', error);
});
}
65 changes: 65 additions & 0 deletions src/serviceWorker/cachingStrategy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// Caching strategies for service workers
// For more details refer
// https://web.dev/learn/pwa/caching/

export const cacheFirst = async function (cacheName, event) {
let cacheResponse = await caches.match(event.request);
let request = event.request;
if (cacheResponse !== undefined) {
// cache hit
return cacheResponse;
}
// miss
else {
const fetchResponse = await fetch(request);
const fetchResponseClone = fetchResponse.clone();
const cache = await caches.open(cacheName);
await cache.put(request, fetchResponseClone);
return fetchResponse;
}
};


export const networkFirst = async function (cacheName, event) {
let request = event.request;
try {
const fetchResponse = await fetch(request);
const fetchResponseClone = fetchResponse.clone();
const cache = await caches.open(cacheName);
await cache.put(request, fetchResponseClone);
return fetchResponse;
}
catch (err) {
return caches.match(event.request);
}
};

export const networkOnly = async function (cacheName, event) {
return fetch(event.request);
};

export const raceCacheNetwork = async function (cacheName, event) {
let request = event.request;

let cachePromise = caches.match(request).then(
response => {
if (response) {
return response;
}
else
throw Error('cache miss');
}
);

let networkPromise = fetch(request).then(
response => {
let responseClone = response.clone();
caches.open(cacheName).then(cache =>
cache.put(request, responseClone)
);
return response;
}
);

return Promise.any([cachePromise, networkPromise]);
};
49 changes: 49 additions & 0 deletions src/serviceWorker/policies.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { cacheFirst, networkFirst, networkOnly } from './cachingStrategy';

/* the various network policies for service workers
these are used to determine how to handle a request
based on the request's url
determine which policy to select is done based on the
first matching pattern */
export const policies = [
{
// chrome extension
url: /^chrome-extension:.*$/i,
handle: networkOnly
},
{
// github pages
url: /^https:\/\/\w*\.github\.io\/nightTab\/.*$/i,
handle: cacheFirst
},
{
// images
url: /^(ftp|https?):.*\.(jpe?g|png|gif|svg)($|\?.*)/i,
handle: cacheFirst
},
{
// audios & videos
url: /^(ftp|https?):.*\.(mp\d|webm|ogg|wav|flac)($|\?.*)/i,
handle: cacheFirst
},
{
// fonts
url: /^(ftp|https?):.*\.(ttf|otf|woff\d?)($|\?.*)/i,
handle: cacheFirst
},
{
// web content
url: /^(ftp|https?):.*\.([jt]sp?|css|html?)($|\?.*)/i,
handle: networkFirst
},
{
// web data
url: /^(ftp|https?):.*\.(csv|json|txt|xml)($|\?.*)/i,
handle: networkFirst
},
// fallback
{
url: /.+/i,
handle: cacheFirst
},
];
59 changes: 59 additions & 0 deletions src/serviceWorker/service_worker.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { policies } from './policies';
import {APP_NAME} from '../constant';

import { version } from '../component/version';

const CACHE_NAME = `${APP_NAME}-${version.number}`;

self.addEventListener('install', event => { // register
console.log('serviceWorker installing...');
event.waitUntil(async () => {

await caches.open(CACHE_NAME).then( cache => {
// check if running in chrome extension
if(chrome?.extension) {
console.log('running in chrome extension, nothing to cache');
}
else
cache.addAll([
'/', // alias for '/index.html'
'/index.html',
]);
});
console.log('serviceWorker installed...');
});
});

self.addEventListener('fetch', event => { // intercept

if(event.request.method !== 'GET')
event.respondWith(fetch(event.request));

// only cache GET requests
let policy = policies.find(
pattern => pattern.url.test(event.request.url)
);
event.respondWith(policy.handle(CACHE_NAME, event));
});

// Delete outdated caches
self.addEventListener('activate', function (e) {
e.waitUntil(
caches.keys().then(function (keyList) {
// filter out all caches that are not part of this app
let cacheWhitelist = keyList.filter(function (key) {
return key.indexOf(APP_NAME);
});
// add current latest cache to whitelist
cacheWhitelist.push(CACHE_NAME);

return Promise.all(keyList.map(function (key, i) {
if (cacheWhitelist.indexOf(key) === -1) {
console.log('deleting cache : ' + keyList[i]);
return caches.delete(keyList[i]);
}
}));
})
);
console.log('serviceWorker version ' + version.number + ' activated');
});
8 changes: 5 additions & 3 deletions webpack.common.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ const CopyPlugin = require('copy-webpack-plugin');

module.exports = {
entry: {
index: path.resolve(__dirname, 'src', 'index.js')
index: path.resolve(__dirname, 'src', 'index.js'),
service_worker: path.resolve(__dirname, 'src', 'serviceWorker', 'service_worker.js'),
},
output: {
filename: '[name].[contenthash].js',
filename: '[name].js',
path: path.resolve(__dirname, 'dist/web'),
clean: true
},
Expand Down Expand Up @@ -43,7 +44,8 @@ module.exports = {
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
template: './src/index.html',
chunks : ['index']
}),
new CopyPlugin({
patterns: [{
Expand Down