blob: 7a8f21b85570d7b1988dcca8f51b574280206a76 [file] [log] [blame]
// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
/* jshint newcap: false */
var _ = require('lodash');
var domready = require('domready');
var React = require('react');
var ReactDOM = require('react-dom');
var dom = require('./dom');
var Sidebar = React.createFactory(require('./sidebar'));
var Toc = React.createFactory(require('./toc'));
domready(function() {
var sidebarEl = dom.find('.sidebar');
ReactDOM.render(Sidebar({
items: parseSidebarProps(dom.find('.sidebar-data'))
}), sidebarEl);
// Menu toggle, for small screens.
var obfuscatorEl = dom.element('div');
obfuscatorEl.classList.add('mdl-layout__obfuscator');
dom.find('body').appendChild(obfuscatorEl);
function showSidebar() {
sidebarEl.classList.add('is-visible');
obfuscatorEl.classList.add('is-visible');
}
function hideSidebar() {
sidebarEl.classList.remove('is-visible');
obfuscatorEl.classList.remove('is-visible');
}
obfuscatorEl.addEventListener('click', hideSidebar);
dom.find('header .icon').addEventListener('click', showSidebar);
// Render table of contents if requested and there are headings.
var el = dom.find('.toc');
if (el) {
var props = parseTocProps();
if ((props.headings || []).length > 0) {
ReactDOM.render(Toc(props), el);
} else {
el.parentNode.removeChild(el);
}
}
// Init syntax highlighting.
require('./highlight')();
// Add copy-to-clipboard buttons to code blocks, but only for certain sections
// of the site.
var pathname = window.location.pathname;
if (pathname.match(/(tutorials|installation|contributing)/)) {
require('./clipboard')();
}
// Update img elements to display alt text in a figcaption.
dom.all('main img').forEach(function(img) {
var figure = dom.element('figure');
figure.appendChild(img.cloneNode());
figure.appendChild(dom.element('figcaption', img.alt));
img.parentNode.replaceChild(figure, img);
});
// Open external links in a new tab.
var links = document.links;
for (var i = 0; i < links.length; i++) {
if (links[i].hostname !== window.location.hostname) {
links[i].target = '_blank';
}
}
});
function parseSidebarProps(el) {
return _.map(_.filter(dom.all(el, 'a'), function(a) {
return a.parentNode === el;
}), function(a) {
var text = a.innerText;
if (a.className !== 'nav') {
return {text: text, href: a.href};
}
var nav = a.nextElementSibling;
console.assert(nav.tagName === 'NAV');
return {text: text, items: parseSidebarProps(nav)};
});
}
function parseTocProps() {
// Note, we ignore nested headers such as those inside info boxes.
var hs = dom.all('main > h1, main > h2, main > h3, main > h4');
var titleEl = _.find(hs, function(el) {
return el.classList.contains('title');
});
var headings = [];
_.forEach(hs, function(el) {
if (el === titleEl || !el.id) {
return;
}
headings.push({
id: el.id,
text: el.innerText,
level: parseInt(el.tagName.split('')[1]),
isAboveWindow: function() {
return el.getBoundingClientRect().top < 0;
},
isBelowWindow: function() {
return el.getBoundingClientRect().bottom > window.innerHeight;
}
});
});
return {
title: titleEl.innerText,
headings: headings
};
}