diff options
author | panda-z <panda.hust@gmail.com> | 2020-04-13 21:18:35 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-04-13 21:18:35 +0800 |
commit | 5657112dfb0e6eac2faa2ae1dc0978ed29030709 (patch) | |
tree | f22279cb587444b0649f95da647b60daf1f370e9 /assets/js | |
parent | d39d3e443953caea05510b19fdd7a259c71a0ab3 (diff) |
chore(build): drop webpack and use Hugo Pipes (#130)
Diffstat (limited to 'assets/js')
-rw-r--r-- | assets/js/even.js | 279 | ||||
-rw-r--r-- | assets/js/main.js | 18 |
2 files changed, 297 insertions, 0 deletions
diff --git a/assets/js/even.js b/assets/js/even.js new file mode 100644 index 0000000..01b9200 --- /dev/null +++ b/assets/js/even.js @@ -0,0 +1,279 @@ +'use strict'; + +const Even = {}; + +Even.backToTop = function() { + const $backToTop = $('#back-to-top'); + + $(window).scroll(function() { + if ($(window).scrollTop() > 100) { + $backToTop.fadeIn(1000); + } else { + $backToTop.fadeOut(1000); + } + }); + + $backToTop.click(function() { + $('body,html').animate({scrollTop: 0}); + }); +}; + +Even.mobileNavbar = function() { + const $mobileNav = $('#mobile-navbar'); + const $mobileNavIcon = $('.mobile-navbar-icon'); + const slideout = new Slideout({ + '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'); + + if ($toc.length) { + const minScrollTop = $toc.offset().top - SPACING; + const maxScrollTop = $footer.offset().top - $toc.height() - SPACING; + + const tocState = { + start: { + 'position': 'absolute', + 'top': minScrollTop, + }, + process: { + 'position': 'fixed', + 'top': SPACING, + }, + end: { + 'position': 'absolute', + 'top': maxScrollTop, + }, + }; + + $(window).scroll(function() { + const scrollTop = $(window).scrollTop(); + + if (scrollTop < minScrollTop) { + $toc.css(tocState.start); + } else if (scrollTop > maxScrollTop) { + $toc.css(tocState.end); + } else { + $toc.css(tocState.process); + } + }); + } + + const HEADERFIX = 30; + const $toclink = $('.toc-link'); + const $headerlink = $('.headerlink'); + const $tocLinkLis = $('.post-toc-content li'); + + const headerlinkTop = $.map($headerlink, function(link) { + return $(link).offset().top; + }); + + const headerLinksOffsetForSearch = $.map(headerlinkTop, function(offset) { + return offset - HEADERFIX; + }); + + const searchActiveTocIndex = function(array, target) { + for (let i = 0; i < array.length - 1; i++) { + if (target > array[i] && target <= array[i + 1]) return i; + } + if (target > array[array.length - 1]) return array.length - 1; + return -1; + }; + + $(window).scroll(function() { + const scrollTop = $(window).scrollTop(); + const activeTocIndex = searchActiveTocIndex(headerLinksOffsetForSearch, scrollTop); + + $($toclink).removeClass('active'); + $($tocLinkLis).removeClass('has-active'); + + if (activeTocIndex !== -1) { + $($toclink[activeTocIndex]).addClass('active'); + let ancestor = $toclink[activeTocIndex].parentNode; + while (ancestor.tagName !== 'NAV') { + $(ancestor).addClass('has-active'); + ancestor = ancestor.parentNode.parentNode; + } + } + }); +}; + +Even.fancybox = function() { + 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>`); + }); + }); + + $('.fancybox').fancybox({ + selector: '.fancybox', + protect: true, + }); + } +}; + +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; + + let codeLineHtml = ''; + for (let i = 0; i < lineLength; i++) { + codeLineHtml += `<div class="line">${i + 1}</div>`; + } + + let codeHtml = ''; + for (let i = 0; i < lineLength; i++) { + codeHtml += `<div class="line">${lineCodes[i]}</div>`; + } + + 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>`; + + rootElement.parentElement.replaceChild(figure, rootElement); + } +}; + +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'; + + 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]; + header.innerHTML = `<a href="#${header.id}" class="headerlink anchor"><i class="iconfont icon-link"></i></a>${header.innerHTML}`; + } + } +}; + +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); + } +}; + diff --git a/assets/js/main.js b/assets/js/main.js new file mode 100644 index 0000000..96db5db --- /dev/null +++ b/assets/js/main.js @@ -0,0 +1,18 @@ +$(document).ready(function () { + Even.backToTop(); + Even.mobileNavbar(); + Even.toc(); + Even.fancybox(); +}); + +Even.responsiveTable(); +Even.flowchart(); +Even.sequence(); + +if (window.hljs) { + hljs.initHighlighting(); + Even.highlight(); +} else { + Even.chroma(); +} + |