Click the heart next to a node\'s title on it\'s own page to save it here for easy access :)
';
}
menu.innerHTML = menuHTML;
return menu.innerHTML;
},
// Load SVG, run callback when loaded
loadSVG: function (cb) {
// Get heart SVG
var xhr = new XMLHttpRequest();
xhr.open('GET', favouriteNodes.heartPath);
xhr.addEventListener('load', function () {
cb(xhr.responseText);
});
xhr.send();
},
// Initiate node favouriting
init: function () {
// Start loading heart SVG before DOM
favouriteNodes.loadSVG(function (svg) {
// Create heart SVG elem
var div = create('div');
div.innerHTML = svg;
var heartEl = div.firstChild;
// Show heart as active if we've already hearted this node
var node = favouriteNodes.getCurrentNode();
if (favouriteNodes.isHearted(node)) {
heartEl.classList.add(favouriteNodes.activeClass);
}
// Add click handler
heartEl.addEventListener('click', function () {
// Heart/unheart node
var node = favouriteNodes.getCurrentNode();
if (favouriteNodes.isHearted(node)) {
heartEl.classList.remove(favouriteNodes.activeClass);
favouriteNodes.unHeart(node);
} else {
heartEl.classList.add(favouriteNodes.activeClass);
favouriteNodes.heart(node);
}
});
// Then inject into DOM when it's ready
domReady(function () {
var headerHeight = find('.title').offsetHeight;
var headerBoxShadow = 3;
// Heart
var titleEl = find('h2.node-title');
if (titleEl) {
titleEl.insertBefore(heartEl, titleEl.firstChild);
}
// Menu button
var menuButton = create('div');
menuButton.classList.add('menu-button');
menuButton.style.height = headerHeight + 'px';
menuButton.innerHTML = svg;
menuButton.addEventListener('click', function () {
favouriteNodes.updateHeartedNodesList();
find('.menu').classList.toggle('active');
});
find('header .wrapper').appendChild(menuButton);
// Menu
var menu = create('div');
menu.classList.add('menu');
menu.style.top = (headerHeight + headerBoxShadow) + 'px';
menu.style.height = 'calc(100% - ' + (headerHeight + headerBoxShadow) + 'px)';
document.body.appendChild(menu);
favouriteNodes.updateHeartedNodesList();
});
});
// If current node is hearted
var node = favouriteNodes.getCurrentNode();
if (favouriteNodes.isHearted(node)) {
// Heart it again so we get the new name if it's updated
favouriteNodes.heart(node);
}
}
};
// Service worker
if (supports.test(['serviceWorker', 'querySelector', 'classList'])) {
// Register service worker
navigator.serviceWorker.register('/sw.js');
// Show cache message on stale pages
domReady(function () {
if (window.cacheDate) {
var offlineMessage = create('div');
offlineMessage.classList.add('cache-message');
offlineMessage.innerText = '*There seems to be an issue connecting to the server. This data is cached from ' + window.cacheDate;
var main = find('main');
if (main) {
doc.body.classList.add('no-connection');
main.insertBefore(offlineMessage, main.firstChild);
}
}
});
}
// Init favourite nodes
if (supports.test(['localStorage', 'inlineSVG', 'querySelector', 'classList'])) {
favouriteNodes.init();
}
// Add ios class to body on iOS devices
if (supports.test(['classList'])) {
domReady(function () {
if (
/iPad|iPhone|iPod/.test(navigator.userAgent) &&
!window.MSStream
) {
doc.body.classList.add('ios');
}
});
}
})();