hugo-theme-even/assets/js/even.js

280 lines
8.1 KiB
JavaScript
Raw Normal View History

'use strict';
2017-08-27 14:38:42 +00:00
const Even = {};
2017-08-27 14:38:42 +00:00
Even.backToTop = function() {
const $backToTop = $('#back-to-top');
2017-08-27 14:38:42 +00:00
$(window).scroll(function() {
2017-08-27 14:38:42 +00:00
if ($(window).scrollTop() > 100) {
$backToTop.fadeIn(1000);
2017-08-27 14:38:42 +00:00
} else {
$backToTop.fadeOut(1000);
2017-08-27 14:38:42 +00:00
}
});
2017-08-27 14:38:42 +00:00
$backToTop.click(function() {
$('body,html').animate({scrollTop: 0});
});
};
2017-08-27 14:38:42 +00:00
Even.mobileNavbar = function() {
const $mobileNav = $('#mobile-navbar');
const $mobileNavIcon = $('.mobile-navbar-icon');
const slideout = new Slideout({
2017-08-27 14:38:42 +00:00
'panel': document.getElementById('mobile-panel'),
'menu': document.getElementById('mobile-menu'),
'padding': 180,
'tolerance': 70,
});
slideout.disableTouch();
$mobileNavIcon.click(function() {
slideout.toggle();
});
slideout.on('beforeopen', function() {
$mobileNav.addClass('fixed-open');
$mobileNavIcon.addClass('icon-click').removeClass('icon-out');
});
slideout.on('beforeclose', function() {
$mobileNav.removeClass('fixed-open');
$mobileNavIcon.addClass('icon-out').removeClass('icon-click');
});
$('#mobile-panel').on('touchend', function() {
slideout.isOpen() && $mobileNavIcon.click();
});
};
Even._initToc = function() {
const SPACING = 20;
const $toc = $('.post-toc');
const $footer = $('.post-footer');
2017-08-27 14:38:42 +00:00
if ($toc.length) {
const minScrollTop = $toc.offset().top - SPACING;
const maxScrollTop = $footer.offset().top - $toc.height() - SPACING;
2017-08-27 14:38:42 +00:00
const tocState = {
2017-08-27 14:38:42 +00:00
start: {
'position': 'absolute',
'top': minScrollTop,
2017-08-27 14:38:42 +00:00
},
process: {
'position': 'fixed',
'top': SPACING,
2017-08-27 14:38:42 +00:00
},
end: {
'position': 'absolute',
'top': maxScrollTop,
},
};
2017-08-27 14:38:42 +00:00
$(window).scroll(function() {
const scrollTop = $(window).scrollTop();
2017-08-27 14:38:42 +00:00
if (scrollTop < minScrollTop) {
$toc.css(tocState.start);
2017-08-27 14:38:42 +00:00
} else if (scrollTop > maxScrollTop) {
$toc.css(tocState.end);
2017-08-27 14:38:42 +00:00
} else {
$toc.css(tocState.process);
2017-08-27 14:38:42 +00:00
}
});
2017-08-27 14:38:42 +00:00
}
const HEADERFIX = 30;
const $toclink = $('.toc-link');
const $headerlink = $('.headerlink');
const $tocLinkLis = $('.post-toc-content li');
2017-08-27 14:38:42 +00:00
const headerlinkTop = $.map($headerlink, function(link) {
return $(link).offset().top;
});
2017-08-27 14:38:42 +00:00
const headerLinksOffsetForSearch = $.map(headerlinkTop, function(offset) {
return offset - HEADERFIX;
});
2017-12-05 12:02:25 +00:00
const searchActiveTocIndex = function(array, target) {
2017-12-05 12:02:25 +00:00
for (let i = 0; i < array.length - 1; i++) {
if (target > array[i] && target <= array[i + 1]) return i;
2017-12-05 12:02:25 +00:00
}
if (target > array[array.length - 1]) return array.length - 1;
return -1;
};
2017-12-05 12:02:25 +00:00
$(window).scroll(function() {
const scrollTop = $(window).scrollTop();
const activeTocIndex = searchActiveTocIndex(headerLinksOffsetForSearch, scrollTop);
2017-08-27 14:38:42 +00:00
$($toclink).removeClass('active');
$($tocLinkLis).removeClass('has-active');
2017-08-27 14:38:42 +00:00
2017-12-05 12:02:25 +00:00
if (activeTocIndex !== -1) {
$($toclink[activeTocIndex]).addClass('active');
let ancestor = $toclink[activeTocIndex].parentNode;
2017-12-05 12:02:25 +00:00
while (ancestor.tagName !== 'NAV') {
$(ancestor).addClass('has-active');
ancestor = ancestor.parentNode.parentNode;
2017-08-27 14:38:42 +00:00
}
}
});
};
2017-08-27 14:38:42 +00:00
Even.fancybox = function() {
2017-08-27 14:38:42 +00:00
if ($.fancybox) {
$('.post-content').each(function() {
$(this).find('img').each(function() {
$(this).wrap(`<a class="fancybox" href="${this.src}" data-fancybox="gallery" data-caption="${this.title}"></a>`);
});
});
2017-08-27 14:38:42 +00:00
$('.fancybox').fancybox({
2017-09-06 09:20:16 +00:00
selector: '.fancybox',
protect: true,
});
2017-08-27 14:38:42 +00:00
}
};
2017-08-27 14:38:42 +00:00
Even.highlight = function() {
const blocks = document.querySelectorAll('pre code');
for (let i = 0; i < blocks.length; i++) {
const block = blocks[i];
const rootElement = block.parentElement;
const lineCodes = block.innerHTML.split(/\n/);
if (lineCodes[lineCodes.length - 1] === '') lineCodes.pop();
const lineLength = lineCodes.length;
2017-08-27 14:38:42 +00:00
let codeLineHtml = '';
2017-08-27 14:38:42 +00:00
for (let i = 0; i < lineLength; i++) {
codeLineHtml += `<div class="line">${i + 1}</div>`;
2017-08-27 14:38:42 +00:00
}
let codeHtml = '';
for (let i = 0; i < lineLength; i++) {
codeHtml += `<div class="line">${lineCodes[i]}</div>`;
2017-08-27 14:38:42 +00:00
}
block.className += ' highlight';
const figure = document.createElement('figure');
figure.className = block.className;
figure.innerHTML = `<table><tbody><tr><td class="gutter"><pre>${codeLineHtml}</pre></td><td class="code"><pre>${codeHtml}</pre></td></tr></tbody></table>`;
2017-08-27 14:38:42 +00:00
rootElement.parentElement.replaceChild(figure, rootElement);
2017-08-27 14:38:42 +00:00
}
};
2017-08-27 14:38:42 +00:00
Even.chroma = function() {
const blocks = document.querySelectorAll('.highlight > .chroma');
for (let i = 0; i < blocks.length; i++) {
const block = blocks[i];
const afterHighLight = block.querySelector('pre.chroma > code');
const lang = afterHighLight ? afterHighLight.className : '';
block.className += ' ' + lang;
}
};
Even.toc = function() {
const tocContainer = document.getElementById('post-toc');
if (tocContainer !== null) {
const toc = document.getElementById('TableOfContents');
if (toc === null) {
// toc = true, but there are no headings
tocContainer.parentNode.removeChild(tocContainer);
} else {
this._refactorToc(toc);
this._linkToc();
this._initToc();
}
}
};
Even._refactorToc = function(toc) {
// when headings do not start with `h1`
const oldTocList = toc.children[0];
let newTocList = oldTocList;
let temp;
while (newTocList.children.length === 1
&& (temp = newTocList.children[0].children[0]).tagName === 'UL') {
newTocList = temp;
}
if (newTocList !== oldTocList) toc.replaceChild(newTocList, oldTocList);
};
Even._linkToc = function() {
const links = document.querySelectorAll('#TableOfContents a:first-child');
for (let i = 0; i < links.length; i++) links[i].className += ' toc-link';
2017-08-27 14:38:42 +00:00
for (let num = 1; num <= 6; num++) {
const headers = document.querySelectorAll('.post-content>h' + num);
for (let i = 0; i < headers.length; i++) {
const header = headers[i];
2018-11-05 14:46:34 +00:00
header.innerHTML = `<a href="#${header.id}" class="headerlink anchor"><i class="iconfont icon-link"></i></a>${header.innerHTML}`;
2017-08-27 14:38:42 +00:00
}
}
};
2017-08-27 14:38:42 +00:00
Even.flowchart = function() {
if (!window.flowchart) return;
const blocks = document.querySelectorAll('pre code.language-flowchart, pre code.language-flow');
for (let i = 0; i < blocks.length; i++) {
if (!window.hljs && i % 2 === 0) continue;
const block = blocks[i];
const rootElement = window.hljs
? block.parentElement
: block.parentElement.parentElement.parentElement.parentElement.parentElement.parentElement.parentElement;
const container = document.createElement('div');
const id = `js-flowchart-diagrams-${i}`;
container.id = id;
container.className = 'align-center';
rootElement.parentElement.replaceChild(container, rootElement);
const diagram = flowchart.parse(block.childNodes[0].nodeValue);
diagram.drawSVG(id, window.flowchartDiagramsOptions ? window.flowchartDiagramsOptions : {});
}
};
Even.sequence = function() {
if (!window.Diagram) return;
const blocks = document.querySelectorAll('pre code.language-sequence');
for (let i = 0; i < blocks.length; i++) {
if (!window.hljs && i % 2 === 0) continue;
const block = blocks[i];
const rootElement = window.hljs
? block.parentElement
: block.parentElement.parentElement.parentElement.parentElement.parentElement.parentElement.parentElement;
const container = document.createElement('div');
const id = `js-sequence-diagrams-${i}`;
container.id = id;
container.className = 'align-center';
rootElement.parentElement.replaceChild(container, rootElement);
const diagram = Diagram.parse(block.childNodes[0].nodeValue);
diagram.drawSVG(id, window.sequenceDiagramsOptions
? window.sequenceDiagramsOptions
: {theme: 'simple'});
}
};
Even.responsiveTable = function() {
const tables = document.querySelectorAll('.post-content > table');
for (let i = 0; i < tables.length; i++) {
const table = tables[i];
const wrapper = document.createElement('div');
wrapper.className = 'table-wrapper';
table.parentElement.replaceChild(wrapper, table);
wrapper.appendChild(table);
}
};