Browse Source

Follow xo style

pull/11/head
Luke Childs 8 years ago
parent
commit
3b568f7b2e
  1. 3
      controllers/error.js
  2. 2
      controllers/error404.js
  3. 9
      controllers/listing.js
  4. 8
      controllers/node.js
  5. 11
      index.js
  6. 16
      lib/bandwidth-chart.js
  7. 1
      lib/minify.js
  8. 32
      lib/nunjucks-filters.js
  9. 2
      lib/nunjucks-middleware.js
  10. 23
      lib/tor.js
  11. 105
      public/assets/enhancements.js
  12. 39
      public/sw.js

3
controllers/error.js

@ -1,6 +1,7 @@
/* eslint no-unused-vars: ["error", { "argsIgnorePattern": "next" }] */
module.exports = (err, req, res, next) => { module.exports = (err, req, res, next) => {
const statusCode = err.statusCode || 500; const statusCode = err.statusCode || 500;
const error = err.statusMessage || 'Something went wrong'; const error = err.statusMessage || 'Something went wrong';
console.error(err); console.error(err);
res.status(statusCode).render('error.html', { error }); res.status(statusCode).render('error.html', {error});
}; };

2
controllers/error404.js

@ -1,5 +1,5 @@
module.exports = (req, res) => { module.exports = (req, res) => {
const statusCode = 404; const statusCode = 404;
const error = '404 Not Found'; const error = '404 Not Found';
res.status(statusCode).render('error.html', { error }); res.status(statusCode).render('error.html', {error});
}; };

9
controllers/listing.js

@ -1,19 +1,18 @@
const tor = require('../lib/tor'); const tor = require('../lib/tor');
module.exports = (req, res, next) => { module.exports = (req, res, next) => {
let title = 'Top nodes by consensus weight'; let title = 'Top nodes by consensus weight';
const query = { const query = {
limit: 10 limit: 10
}; };
if(req.query.s) { if (req.query.s) {
title = `Search results for "${req.query.s}":`; title = `Search results for "${req.query.s}":`;
query.search = req.query.s; query.search = req.query.s;
} else { } else {
query.order = '-consensus_weight'; query.order = '-consensus_weight';
query.running = true; query.running = true;
} }
if(req.query.p) { if (req.query.p) {
query.offset = (query.limit * req.query.p) - query.limit; query.offset = (query.limit * req.query.p) - query.limit;
} }
@ -25,9 +24,9 @@ module.exports = (req, res, next) => {
numOfNodes: query.limit numOfNodes: query.limit
})) }))
.catch(err => { .catch(err => {
if(err.statusCode == 400 && req.query.s) { if (err.statusCode === 400 && req.query.s) {
err.statusMessage = 'Bad Search Query'; err.statusMessage = 'Bad Search Query';
} }
next(err); next(err);
}); });
} };

8
controllers/node.js

@ -8,7 +8,7 @@ module.exports = (req, res, next) => {
]) ])
.then(data => { .then(data => {
// Throw 404 if node doesn't exist // Throw 404 if node doesn't exist
if(!data[0]) { if (!data[0]) {
const err = new Error('Node doesn\'t exist'); const err = new Error('Node doesn\'t exist');
err.statusMessage = err.message; err.statusMessage = err.message;
err.statusCode = 404; err.statusCode = 404;
@ -19,12 +19,12 @@ module.exports = (req, res, next) => {
pageTitle: `${data[0].type}: ${data[0].nickname}`, pageTitle: `${data[0].type}: ${data[0].nickname}`,
node: data[0], node: data[0],
bandwidth: bandwidthChart(data[1]) bandwidth: bandwidthChart(data[1])
}) });
}) })
.catch(err => { .catch(err => {
if(err.statusCode == 400) { if (err.statusCode === 400) {
err.statusMessage = 'Invalid node'; err.statusMessage = 'Invalid node';
} }
next(err); next(err);
}); });
} };

11
index.js

@ -1,16 +1,17 @@
const express = require('express'); const express = require('express');
const anonlytics = require('anonlytics-express'); const anonlytics = require('anonlytics-express');
const nunjucks = require('nunjucks'); const nunjucks = require('nunjucks');
const compression = require('compression');
const nunjucksFilters = require('./lib/nunjucks-filters'); const nunjucksFilters = require('./lib/nunjucks-filters');
const nunjucksMiddleware = require('./lib/nunjucks-middleware'); const nunjucksMiddleware = require('./lib/nunjucks-middleware');
const compression = require('compression');
const minify = require('./lib/minify'); const minify = require('./lib/minify');
const controllers = require('./controllers'); const controllers = require('./controllers');
const app = express(); const app = express();
const port = process.env.port || 3000; const port = process.env.port || 3000;
// Trust proxy headers if we're deployed on now // Trust proxy headers if we're deployed on now
if(process.env.NOW) { if (process.env.NOW) {
app.enable('trust proxy'); app.enable('trust proxy');
} }
@ -18,7 +19,7 @@ if(process.env.NOW) {
app.use(anonlytics()); app.use(anonlytics());
// Setup nunjucks // Setup nunjucks
nunjucks.configure('views', { express: app }); nunjucks.configure('views', {express: app});
nunjucksFilters(app); nunjucksFilters(app);
app.use(nunjucksMiddleware); app.use(nunjucksMiddleware);
@ -35,8 +36,8 @@ app.get('/about', controllers.about);
app.get('/no-connection', controllers.noConnection); app.get('/no-connection', controllers.noConnection);
// Serve assets with cache headers // Serve assets with cache headers
app.use('/sw.js', express.static(`${__dirname}/public/sw.js`, { maxAge: '1 hour' })); app.use('/sw.js', express.static(`${__dirname}/public/sw.js`, {maxAge: '1 hour'}));
app.use(express.static(`${__dirname}/public`, { maxAge: '1 year' })); app.use(express.static(`${__dirname}/public`, {maxAge: '1 year'}));
// Errors // Errors
app.use(controllers.error404); app.use(controllers.error404);

16
lib/bandwidth-chart.js

@ -1,7 +1,6 @@
const chart = require('ascii-chart'); const chart = require('ascii-chart');
function pointsFromBandwidthData(values, numPoints) { function pointsFromBandwidthData(values, numPoints) {
// Define vars // Define vars
const len = values.length; const len = values.length;
const points = []; const points = [];
@ -9,10 +8,10 @@ function pointsFromBandwidthData(values, numPoints) {
let size; let size;
// Split values into n points // Split values into n points
if(numPoints < 2) { if (numPoints < 2) {
points.push(values); points.push(values);
} else { } else {
if(len % numPoints === 0) { if (len % numPoints === 0) {
size = Math.floor(len / numPoints); size = Math.floor(len / numPoints);
while (i < len) { while (i < len) {
points.push(values.slice(i, i += size)); points.push(values.slice(i, i += size));
@ -28,14 +27,16 @@ function pointsFromBandwidthData(values, numPoints) {
return points return points
// Calculate average value of each point // Calculate average value of each point
.map(point => Math.round(point.reduce((a,b) => a + b) / point.length)) .map(point => Math.round(point.reduce((a, b) => a + b) / point.length))
// Convert bytes to megabytes // Convert bytes to megabytes
.map(bytes => Number((bytes / 1000000).toPrecision(3))); .map(bytes => Number((bytes / 1000000).toPrecision(3)));
} }
module.exports = values => { module.exports = values => {
if(values && values.length) { if (!values || values.length < 1) {
return '';
}
const points = pointsFromBandwidthData(values, 57); const points = pointsFromBandwidthData(values, 57);
return chart(points, { return chart(points, {
width: 120, width: 120,
@ -45,7 +46,4 @@ module.exports = values => {
negativePointChar: '.', negativePointChar: '.',
axisChar: '.' axisChar: '.'
}); });
} else { };
return '';
}
}

1
lib/minify.js

@ -1,6 +1,7 @@
const minify = require('express-minify'); const minify = require('express-minify');
const minifyHTML = require('express-minify-html'); const minifyHTML = require('express-minify-html');
const CleanCSS = require('clean-css'); const CleanCSS = require('clean-css');
const cleanCSS = new CleanCSS(); const cleanCSS = new CleanCSS();
module.exports = [ module.exports = [

32
lib/nunjucks-filters.js

@ -1,6 +1,6 @@
const querystring = require('querystring');
const prettyBytes = require('pretty-bytes'); const prettyBytes = require('pretty-bytes');
const moment = require('moment'); const moment = require('moment');
const querystring = require('querystring');
function humanTimeAgo(utcDate) { function humanTimeAgo(utcDate) {
const diff = moment.utc().diff(moment.utc(utcDate)); const diff = moment.utc().diff(moment.utc(utcDate));
@ -18,7 +18,9 @@ function humanTimeAgo(utcDate) {
let readableUptime = ''; let readableUptime = '';
readableUptime += uptime.d ? ` ${uptime.d}d` : ''; readableUptime += uptime.d ? ` ${uptime.d}d` : '';
readableUptime += uptime.h ? ` ${uptime.h}h` : ''; readableUptime += uptime.h ? ` ${uptime.h}h` : '';
readableUptime += !uptime.d || !uptime.h && uptime.m ? ` ${uptime.m}m` : ''; if ((!uptime.d || !uptime.h) && uptime.m) {
readableUptime += ` ${uptime.m}m`;
}
return readableUptime.trim(); return readableUptime.trim();
} }
@ -26,9 +28,8 @@ function humanTimeAgo(utcDate) {
const filters = { const filters = {
bandwidth: node => `${prettyBytes(node.advertised_bandwidth)}/s`, bandwidth: node => `${prettyBytes(node.advertised_bandwidth)}/s`,
uptime: node => { uptime: node => {
// Check node is up // Check node is up
if(!node.running) { if (!node.running) {
return 'Down'; return 'Down';
} }
@ -36,7 +37,6 @@ const filters = {
return humanTimeAgo(node.last_restarted); return humanTimeAgo(node.last_restarted);
}, },
pagination: (req, direction) => { pagination: (req, direction) => {
// Clone query string // Clone query string
const query = Object.assign({}, req.query); const query = Object.assign({}, req.query);
@ -44,27 +44,35 @@ const filters = {
query.p = query.p ? query.p : 1; query.p = query.p ? query.p : 1;
// Update page // Update page
if(direction == 'next') { if (direction === 'next') {
query.p++; query.p++;
} else if(direction == 'prev') { } else if (direction === 'prev') {
query.p--; query.p--;
} }
// Don't add p var if it's page 1 // Don't add p var if it's page 1
query.p == 1 && delete query.p if (query.p === 1) {
delete query.p;
}
// Encode query string // Encode query string
const queryString = querystring.encode(query); const queryString = querystring.encode(query);
return queryString ? `/?${queryString}` : '/'; return queryString ? `/?${queryString}` : '/';
}, },
name: node => node.nickname name: node => {
|| node.fingerprint && node.fingerprint.slice(0, 8) let name = '';
|| node.hashed_fingerprint && node.hashed_fingerprint.slice(0, 8), if (node.nickname) {
name = node.nickname;
} else if (node.fingerprint || node.hashed_fingerprint) {
name = (node.fingerprint || node.hashed_fingerprint).slice(0, 8);
}
return name;
},
status: node => node.running ? status: node => node.running ?
`Up for ${humanTimeAgo(node.last_restarted)}` : `Up for ${humanTimeAgo(node.last_restarted)}` :
`Down for ${humanTimeAgo(node.last_seen)}` `Down for ${humanTimeAgo(node.last_seen)}`
}; };
module.exports = app => Object.keys(filters).forEach(filter => { module.exports = app => Object.keys(filters).forEach(filter => {
app.settings.nunjucksEnv.addFilter(filter, filters[filter]) app.settings.nunjucksEnv.addFilter(filter, filters[filter]);
}); });

2
lib/nunjucks-middleware.js

@ -2,4 +2,4 @@ module.exports = (req, res, next) => {
res.locals.req = req; res.locals.req = req;
res.locals.res = res; res.locals.res = res;
next(); next();
} };

23
lib/tor.js

@ -1,26 +1,32 @@
const Onionoo = require('onionoo'); const Onionoo = require('onionoo');
const onionoo = new Onionoo(); const onionoo = new Onionoo();
const setNodeType = type => node => {
node.type = type;
return node;
};
module.exports = { module.exports = {
listNodes: query => { listNodes: query => {
return onionoo return onionoo
.details(query) .details(query)
.then(response => { .then(response => {
const details = response.body; const details = response.body;
details.relays.forEach(node => node.type = 'relay'); details.relays.map(setNodeType('relay'));
details.bridges.forEach(node => node.type = 'bridge'); details.bridges.map(setNodeType('bridge'));
return details.relays.concat(details.bridges); return details.relays.concat(details.bridges);
}); });
}, },
node: id => { node: id => {
return onionoo return onionoo
.details({ lookup: id }) .details({lookup: id})
.then(response => { .then(response => {
const details = response.body; const details = response.body;
if(details.relays[0]) { if (details.relays[0]) {
details.relays[0].type = 'relay'; details.relays[0].type = 'relay';
return details.relays[0]; return details.relays[0];
} else if(details.bridges[0]) { } else if (details.bridges[0]) {
details.bridges[0].type = 'bridge'; details.bridges[0].type = 'bridge';
return details.bridges[0]; return details.bridges[0];
} }
@ -28,14 +34,13 @@ module.exports = {
}, },
bandwidth: id => { bandwidth: id => {
return onionoo return onionoo
.bandwidth({ lookup: id }) .bandwidth({lookup: id})
.then(response => { .then(response => {
const bandwidth = response.body; const bandwidth = response.body;
try { try {
const lastMonth = bandwidth.relays[0].write_history['1_month']; const lastMonth = bandwidth.relays[0].write_history['1_month'];
return lastMonth.values.map(value => value * lastMonth.factor) return lastMonth.values.map(value => value * lastMonth.factor);
} } catch (err) {
catch(e) {
return []; return [];
} }
}); });

105
public/assets/enhancements.js

@ -1,15 +1,14 @@
(function() { /* eslint-env browser */
(function () {
// Space optimisations // Space optimisations
var doc = document; var doc = document;
var find = doc.querySelector.bind(doc); var find = doc.querySelector.bind(doc);
var create = doc.createElement.bind(doc); var create = doc.createElement.bind(doc);
// Run callback when DOM is ready // Run callback when DOM is ready
function DOMReady(cb) { function domReady(cb) {
// Run now if DOM has already loaded as we're loading async // Run now if DOM has already loaded as we're loading async
if(['interactive', 'complete'].indexOf(doc.readyState) >= 0) { if (['interactive', 'complete'].indexOf(doc.readyState) >= 0) {
cb(); cb();
// Otherwise wait for DOM // Otherwise wait for DOM
@ -20,36 +19,36 @@
// Feature detection // Feature detection
var supports = { var supports = {
test: function(features) { test: function (features) {
var self = this; var self = this;
if(!features || !features.length) { if (!features || features.length < 1) {
return false; return false;
} }
return features.every(function(feature) { return features.every(function (feature) {
return self.tests[feature]; return self.tests[feature];
}); });
}, },
tests: { tests: {
localStorage: (function() { localStorage: (function () {
try { try {
localStorage.setItem('test', 'test'); localStorage.setItem('test', 'test');
localStorage.removeItem('test'); localStorage.removeItem('test');
return true; return true;
} catch (e) { } catch (err) {
return false; return false;
} }
})(), })(),
inlineSVG: (function() { inlineSVG: (function () {
var div = create('div'); var div = create('div');
div.innerHTML = '<svg/>'; div.innerHTML = '<svg/>';
return ( return (
typeof SVGRect != 'undefined' typeof SVGRect !== 'undefined' &&
&& div.firstChild div.firstChild &&
&& div.firstChild.namespaceURI div.firstChild.namespaceURI
) == 'http://www.w3.org/2000/svg'; ) === 'http://www.w3.org/2000/svg';
})(), })(),
querySelector: typeof doc.querySelector === 'function', querySelector: typeof doc.querySelector === 'function',
classList: (function() { classList: (function () {
var div = create('div'); var div = create('div');
div.innerHTML = '<svg/>'; div.innerHTML = '<svg/>';
return 'classList' in div.firstChild; return 'classList' in div.firstChild;
@ -71,33 +70,33 @@
activeClass: 'hearted', activeClass: 'hearted',
// Gets current node hash // Gets current node hash
getCurrentNode: function() { getCurrentNode: function () {
var node = /^\/node\/([a-zA-Z0-9]+)/.exec(window.location.pathname); var node = /^\/node\/([a-zA-Z0-9]+)/.exec(window.location.pathname);
return node ? node[1] : node; return node ? node[1] : node;
}, },
// Gets current node title // Gets current node title
getCurrentNodeTitle: function() { getCurrentNodeTitle: function () {
return find('h2.node-title .name').innerText; return find('h2.node-title .name').innerText;
}, },
// Gets hearted nodes // Gets hearted nodes
getHeartedNodes: function() { getHeartedNodes: function () {
return JSON.parse(localStorage.getItem(favouriteNodes.storageKey)) || {}; return JSON.parse(localStorage.getItem(favouriteNodes.storageKey)) || {};
}, },
// Saves hearted nodes // Saves hearted nodes
saveHeartedNodes: function(heartedNodes) { saveHeartedNodes: function (heartedNodes) {
return localStorage.setItem(favouriteNodes.storageKey, JSON.stringify(heartedNodes)); return localStorage.setItem(favouriteNodes.storageKey, JSON.stringify(heartedNodes));
}, },
// Checks if node is hearted // Checks if node is hearted
isHearted: function(node) { isHearted: function (node) {
return typeof favouriteNodes.getHeartedNodes()[node] !== 'undefined'; return typeof favouriteNodes.getHeartedNodes()[node] !== 'undefined';
}, },
// Heart node // Heart node
heart: function(node) { heart: function (node) {
var heartedNodes = favouriteNodes.getHeartedNodes(); var heartedNodes = favouriteNodes.getHeartedNodes();
heartedNodes[node] = favouriteNodes.getCurrentNodeTitle(); heartedNodes[node] = favouriteNodes.getCurrentNodeTitle();
favouriteNodes.saveHeartedNodes(heartedNodes); favouriteNodes.saveHeartedNodes(heartedNodes);
@ -106,7 +105,7 @@
}, },
// Unheart node // Unheart node
unHeart: function(node) { unHeart: function (node) {
var heartedNodes = favouriteNodes.getHeartedNodes(); var heartedNodes = favouriteNodes.getHeartedNodes();
delete heartedNodes[node]; delete heartedNodes[node];
favouriteNodes.saveHeartedNodes(heartedNodes); favouriteNodes.saveHeartedNodes(heartedNodes);
@ -115,44 +114,42 @@
}, },
// Get list of hearted nodes // Get list of hearted nodes
updateHeartedNodesList: function() { updateHeartedNodesList: function () {
var menu = find('.menu'); var menu = find('.menu');
if(!menu) { if (!menu) {
return false; return false;
} }
var menuHTML = ''; var menuHTML = '';
var heartedNodes = favouriteNodes.getHeartedNodes(); var heartedNodes = favouriteNodes.getHeartedNodes();
var nodeHashes = Object.keys(heartedNodes); var nodeHashes = Object.keys(heartedNodes);
if(nodeHashes.length) { if (nodeHashes.length > 0) {
menuHTML += '<ul>'; menuHTML += '<ul>';
nodeHashes.forEach(function(node) { nodeHashes.forEach(function (node) {
menuHTML += '<li><a href="/node/' + node + '">' + heartedNodes[node] + '</a></li>'; menuHTML += '<li><a href="/node/' + node + '">' + heartedNodes[node] + '</a></li>';
}); });
menuHTML += '</ul>'; menuHTML += '</ul>';
} else { } else {
menuHTML += '<div class="empty">Click the heart next to a node\'s title on it\'s own page to save it here for easy access :)</div>'; menuHTML += '<div class="empty">Click the heart next to a node\'s title on it\'s own page to save it here for easy access :)</div>';
} }
return menu.innerHTML = menuHTML; menu.innerHTML = menuHTML;
return menu.innerHTML;
}, },
// Load SVG, run callback when loaded // Load SVG, run callback when loaded
loadSVG: function(cb) { loadSVG: function (cb) {
// Get heart SVG // Get heart SVG
var xhr = new XMLHttpRequest(); var xhr = new XMLHttpRequest();
xhr.open('GET', favouriteNodes.heartPath); xhr.open('GET', favouriteNodes.heartPath);
xhr.addEventListener('load', function() { xhr.addEventListener('load', function () {
cb(xhr.responseText); cb(xhr.responseText);
}); });
xhr.send(); xhr.send();
}, },
// Initiate node favouriting // Initiate node favouriting
init: function() { init: function () {
// Start loading heart SVG before DOM // Start loading heart SVG before DOM
favouriteNodes.loadSVG(function(svg) { favouriteNodes.loadSVG(function (svg) {
// Create heart SVG elem // Create heart SVG elem
var div = create('div'); var div = create('div');
div.innerHTML = svg; div.innerHTML = svg;
@ -160,16 +157,15 @@
// Show heart as active if we've already hearted this node // Show heart as active if we've already hearted this node
var node = favouriteNodes.getCurrentNode(); var node = favouriteNodes.getCurrentNode();
if(favouriteNodes.isHearted(node)) { if (favouriteNodes.isHearted(node)) {
heartEl.classList.add(favouriteNodes.activeClass); heartEl.classList.add(favouriteNodes.activeClass);
} }
// Add click handler // Add click handler
heartEl.addEventListener('click', function() { heartEl.addEventListener('click', function () {
// Heart/unheart node // Heart/unheart node
var node = favouriteNodes.getCurrentNode(); var node = favouriteNodes.getCurrentNode();
if(favouriteNodes.isHearted(node)) { if (favouriteNodes.isHearted(node)) {
heartEl.classList.remove(favouriteNodes.activeClass); heartEl.classList.remove(favouriteNodes.activeClass);
favouriteNodes.unHeart(node); favouriteNodes.unHeart(node);
} else { } else {
@ -179,13 +175,13 @@
}); });
// Then inject into DOM when it's ready // Then inject into DOM when it's ready
DOMReady(function() { domReady(function () {
var headerHeight = find('.title').offsetHeight; var headerHeight = find('.title').offsetHeight;
var headerBoxShadow = 3; var headerBoxShadow = 3;
// Heart // Heart
var titleEl = find('h2.node-title'); var titleEl = find('h2.node-title');
if(titleEl) { if (titleEl) {
titleEl.insertBefore(heartEl, titleEl.firstChild); titleEl.insertBefore(heartEl, titleEl.firstChild);
} }
@ -194,7 +190,7 @@
menuButton.classList.add('menu-button'); menuButton.classList.add('menu-button');
menuButton.style.height = headerHeight + 'px'; menuButton.style.height = headerHeight + 'px';
menuButton.innerHTML = svg; menuButton.innerHTML = svg;
menuButton.addEventListener('click', function() { menuButton.addEventListener('click', function () {
favouriteNodes.updateHeartedNodesList(); favouriteNodes.updateHeartedNodesList();
find('.menu').classList.toggle('active'); find('.menu').classList.toggle('active');
}); });
@ -212,8 +208,7 @@
// If current node is hearted // If current node is hearted
var node = favouriteNodes.getCurrentNode(); var node = favouriteNodes.getCurrentNode();
if(favouriteNodes.isHearted(node)) { if (favouriteNodes.isHearted(node)) {
// Heart it again so we get the new name if it's updated // Heart it again so we get the new name if it's updated
favouriteNodes.heart(node); favouriteNodes.heart(node);
} }
@ -221,19 +216,18 @@
}; };
// Service worker // Service worker
if(supports.test(['serviceWorker', 'querySelector', 'classList'])) { if (supports.test(['serviceWorker', 'querySelector', 'classList'])) {
// Register service worker // Register service worker
navigator.serviceWorker.register('/sw.js'); navigator.serviceWorker.register('/sw.js');
// Show cache message on stale pages // Show cache message on stale pages
DOMReady(function() { domReady(function () {
if(window.cacheDate) { if (window.cacheDate) {
var offlineMessage = create('div'); var offlineMessage = create('div');
offlineMessage.classList.add('cache-message'); offlineMessage.classList.add('cache-message');
offlineMessage.innerText = '*There seems to be an issue connecting to the server. This data is cached from ' + window.cacheDate; offlineMessage.innerText = '*There seems to be an issue connecting to the server. This data is cached from ' + window.cacheDate;
var main = find('main'); var main = find('main');
if(main) { if (main) {
doc.body.classList.add('no-connection'); doc.body.classList.add('no-connection');
main.insertBefore(offlineMessage, main.firstChild); main.insertBefore(offlineMessage, main.firstChild);
} }
@ -242,20 +236,19 @@
} }
// Init favourite nodes // Init favourite nodes
if(supports.test(['localStorage', 'inlineSVG', 'querySelector', 'classList'])) { if (supports.test(['localStorage', 'inlineSVG', 'querySelector', 'classList'])) {
favouriteNodes.init(); favouriteNodes.init();
} }
// Add ios class to body on iOS devices // Add ios class to body on iOS devices
if(supports.test(['classList'])) { if (supports.test(['classList'])) {
DOMReady(function() { domReady(function () {
if( if (
/iPad|iPhone|iPod/.test(navigator.userAgent) /iPad|iPhone|iPod/.test(navigator.userAgent) &&
&& !window.MSStream !window.MSStream
) { ) {
doc.body.classList.add('ios'); doc.body.classList.add('ios');
} }
}); });
} }
})(); })();

39
public/sw.js

@ -1,13 +1,13 @@
/* eslint-env browser */
var cacheName = 'onionite-cache-v1'; var cacheName = 'onionite-cache-v1';
var offlineUrl = '/no-connection'; var offlineUrl = '/no-connection';
// Install // Install
self.addEventListener('install', function(event) { self.addEventListener('install', function (event) {
// Cache assets // Cache assets
event.waitUntil( event.waitUntil(
caches.open(cacheName) caches.open(cacheName)
.then(function(cache) { .then(function (cache) {
return cache.addAll([ return cache.addAll([
offlineUrl, offlineUrl,
'/', '/',
@ -22,24 +22,22 @@ self.addEventListener('install', function(event) {
}); });
// Fetch // Fetch
self.addEventListener('fetch', function(event) { self.addEventListener('fetch', function (event) {
var requestUrl = new URL(event.request.url); var requestUrl = new URL(event.request.url);
// Only do stuff with our own urls // Only do stuff with our own urls
if(requestUrl.origin !== location.origin) { if (requestUrl.origin !== location.origin) {
return; return;
} }
// Try cache first for assets // Try cache first for assets
if(requestUrl.pathname.startsWith('/assets/')) { if (requestUrl.pathname.startsWith('/assets/')) {
event.respondWith( event.respondWith(
caches.match(event.request) caches.match(event.request)
.then(function(response) { .then(function (response) {
// If we don't have it make the request // If we don't have it make the request
return response || fetch(event.request); return response || fetch(event.request);
} })
)
); );
return; return;
} }
@ -53,20 +51,17 @@ self.addEventListener('fetch', function(event) {
// Make the request // Make the request
fetch(event.request) fetch(event.request)
.then(function(response) { .then(function (response) {
// If it's the homepage or a node page // If it's the homepage or a node page
if(requestUrl.pathname === '/' || requestUrl.pathname.startsWith('/node/')) { if (requestUrl.pathname === '/' || requestUrl.pathname.startsWith('/node/')) {
// Clone the response and read the html // Clone the response and read the html
response.clone().text().then(function(html) { response.clone().text().then(function (html) {
// Modify the html so we know when it was cached // Modify the html so we know when it was cached
html = html.replace('window.cacheDate=false;', 'window.cacheDate="'+Date()+'";'); html = html.replace('window.cacheDate=false;', 'window.cacheDate="' + Date() + '";');
var modifiedResponse = new Response(new Blob([html]), { headers: response.headers }); var modifiedResponse = new Response(new Blob([html]), {headers: response.headers});
// Cache the modified response // Cache the modified response
caches.open(cacheName).then(function(cache) { caches.open(cacheName).then(function (cache) {
cache.put(event.request, modifiedResponse); cache.put(event.request, modifiedResponse);
}); });
}); });
@ -77,12 +72,10 @@ self.addEventListener('fetch', function(event) {
}) })
// If it fails // If it fails
.catch(function() { .catch(function () {
// Try and return a previously cached version // Try and return a previously cached version
return caches.match(event.request) return caches.match(event.request)
.then(function(response) { .then(function (response) {
// If we don't have a cached version show pretty offline page // If we don't have a cached version show pretty offline page
return response || caches.match(offlineUrl); return response || caches.match(offlineUrl);
}); });

Loading…
Cancel
Save