Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/uPagge/uBlogger.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDillon <dillonzq@outlook.com>2020-02-16 19:41:08 +0300
committerDillon <dillonzq@outlook.com>2020-02-16 19:41:08 +0300
commitd87af711761d0ea8b2fc173407b45299e3314138 (patch)
tree30f42db3c1c22a36f8cd77ed6984e69d1afb80b8 /src
parent34cc26b94af4ccbc217c130f7f37a2d13ba292e1 (diff)
chore(hook): add babel pre-commit hook
Diffstat (limited to 'src')
-rw-r--r--src/js/theme.js320
1 files changed, 320 insertions, 0 deletions
diff --git a/src/js/theme.js b/src/js/theme.js
new file mode 100644
index 0000000..7629260
--- /dev/null
+++ b/src/js/theme.js
@@ -0,0 +1,320 @@
+(() => {
+ 'use strict';
+
+ class Util {
+ forEach(elements, handler) {
+ elements = elements || [];
+ for (let i = 0; i < elements.length; i++) {
+ handler(elements[i]);
+ }
+ }
+
+ getScrollTop() {
+ return (document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop;
+ }
+ }
+
+ class Theme {
+ constructor() {
+ this.util = new Util();
+ this.scrollTop = 0;
+ this.scrollEvents = [];
+ }
+
+ initMobileMenu() {
+ document.getElementById('menu-toggle').onclick = () => {
+ document.getElementById('menu-toggle').classList.toggle('active');
+ document.getElementById('menu-mobile').classList.toggle('active');
+ };
+ }
+
+ initSwitchTheme() {
+ this.util.forEach(document.getElementsByClassName('theme-switch'), (button) => {
+ button.onclick = () => {
+ document.body.classList.toggle('dark-theme');
+ window.isDark = !window.isDark;
+ window.localStorage && window.localStorage.setItem('theme', window.isDark ? 'dark' : 'light');
+ this.initEcharts();
+ };
+ });
+ }
+
+ initHighlight() {
+ this.util.forEach(document.querySelectorAll('.highlight > .chroma'), (block) => {
+ const codes = block.querySelectorAll('pre.chroma > code');
+ const code = codes[codes.length - 1];
+ const lang = code ? code.className.toLowerCase() : '';
+ block.className += ' ' + lang;
+ });
+ this.util.forEach(document.querySelectorAll('.highlight > pre.chroma'), (block) => {
+ const chroma = document.createElement('div');
+ chroma.className = block.className;
+ const table = document.createElement('table');
+ chroma.appendChild(table);
+ const tbody = document.createElement('tbody');
+ table.appendChild(tbody);
+ const tr = document.createElement('tr');
+ tbody.appendChild(tr);
+ const td = document.createElement('td');
+ tr.appendChild(td);
+ block.parentElement.replaceChild(chroma, block);
+ td.appendChild(block);
+ });
+ }
+
+ initTable() {
+ this.util.forEach(document.querySelectorAll('.content table'), (table) => {
+ const wrapper = document.createElement('div');
+ wrapper.className = 'table-wrapper';
+ table.parentElement.replaceChild(wrapper, table);
+ wrapper.appendChild(table);
+ });
+ }
+
+ initHeaderLink() {
+ for (let num = 1; num <= 6; num++) {
+ this.util.forEach(document.querySelectorAll('.content > h' + num), (header) => {
+ header.classList.add('headerLink');
+ header.innerHTML = `<a href="#${header.id}"></a>${header.innerHTML}`;
+ });
+ }
+ }
+
+ _refactorToc(toc) {
+ this.util.forEach(toc.querySelectorAll('a:first-child'), (link) => {
+ link.classList.add('toc-link');
+ });
+
+ // 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);
+ }
+
+ _initTocState(tocContainer) {
+ if (window.getComputedStyle(tocContainer, null).display !== 'none') {
+ const fixed = window.desktopHeaderMode !== 'normal';
+ const fixedHeight = document.getElementById('header-desktop').getBoundingClientRect().height;
+ const TOP_SPACING = 20 + (fixed ? fixedHeight : 0);
+ const minTop = tocContainer.offsetTop;
+ const minScrollTop = minTop - TOP_SPACING + (fixed ? 0 : fixedHeight);
+ const footerTop = document.getElementById('post-footer').offsetTop;
+ const toclinks = tocContainer.getElementsByClassName('toc-link');
+ const headerLinks = document.getElementsByClassName('headerLink') || [];
+ const tocLinkLis = tocContainer.querySelectorAll('.post-toc-content li');
+ const INDEX_SPACING = 5 + (fixed ? fixedHeight : 0);
+
+ const changeTocState = () => {
+ const scrollTop = this.util.getScrollTop();
+ const maxTop = footerTop - tocContainer.getBoundingClientRect().height;
+ const maxScrollTop = maxTop - TOP_SPACING + (fixed ? 0 : fixedHeight);
+ if (scrollTop < minScrollTop) {
+ tocContainer.style.position = 'absolute';
+ tocContainer.style.top = `${minTop}px`;
+ } else if (scrollTop > maxScrollTop) {
+ tocContainer.style.position = 'absolute';
+ tocContainer.style.top = `${maxTop}px`;
+ } else {
+ tocContainer.style.position = 'fixed';
+ tocContainer.style.top = `${TOP_SPACING}px`;
+ }
+
+ this.util.forEach(toclinks, (link) => { link.classList.remove('active'); });
+ this.util.forEach(tocLinkLis, (link) => { link.classList.remove('has-active'); });
+ let activeTocIndex = headerLinks.length - 1;
+ for (let i = 0; i < headerLinks.length - 1; i++) {
+ const thisTop = headerLinks[i].getBoundingClientRect().top;
+ const nextTop = headerLinks[i + 1].getBoundingClientRect().top;
+ if ((i == 0 && thisTop > INDEX_SPACING)
+ || (thisTop <= INDEX_SPACING && nextTop > INDEX_SPACING)) {
+ activeTocIndex = i;
+ break;
+ }
+ }
+ if (activeTocIndex !== -1) {
+ toclinks[activeTocIndex].classList.add('active');
+ let parent = toclinks[activeTocIndex].parentElement;
+ while (parent.tagName !== 'NAV') {
+ parent.classList.add('has-active');
+ parent = parent.parentElement.parentElement;
+ }
+ }
+ };
+ changeTocState();
+
+ if (!this._initTocOnce) {
+ this.scrollEvents.push(changeTocState);
+ this._initTocOnce = true;
+ }
+ }
+ }
+
+ initToc() {
+ const tocContainer = document.getElementById('post-toc');
+ if (tocContainer !== null) {
+ const toc = document.getElementById('TableOfContents');
+ if (toc === null) {
+ tocContainer.parentElement.removeChild(tocContainer);
+ } else {
+ this._refactorToc(toc);
+ this._initTocState(tocContainer);
+ window.addEventListener('resize', () => {
+ window.setTimeout(() => {
+ this._initTocState(tocContainer);
+ }, 0);
+ }, false);
+ }
+ }
+ }
+
+ initMermaid() {
+ if (window.mermaidMap) {
+ mermaid.initialize({startOnLoad: false, theme: null});
+ Object.keys(mermaidMap).forEach((id) => {
+ const element = document.getElementById(id);
+ mermaid.mermaidAPI.render("d" + id, mermaidMap[id], (svgCode) => {
+ element.innerHTML = svgCode;
+ const svg = element.firstChild;
+ svg.style.width = "100%"
+ }, element);
+ });
+ }
+ }
+
+ initEcharts() {
+ if (window.echartsMap) {
+ for (let i = 0; i < echartsArr.length; i++) {
+ echartsArr[i].dispose();
+ }
+ echartsArr = [];
+ Object.keys(echartsMap).forEach((id) => {
+ let myChart = echarts.init(document.getElementById(id), window.isDark ? 'dark' : 'macarons', {renderer: 'svg'});
+ myChart.setOption(echartsMap[id]);
+ echartsArr.push(myChart);
+ });
+ window.addEventListener("resize", function () {
+ this.setTimeout(() => {
+ for (let i = 0; i < echartsArr.length; i++) {
+ echartsArr[i].resize();
+ }
+ }, 0);
+ }, false);
+ }
+ }
+
+ initTypeit() {
+ if (window.typeitArr) {
+ for (let i = 0; i < typeitArr.length; i++) {
+ const group = typeitArr[i];
+ (function typeone(i) {
+ const content = document.getElementById(`r${group[i]}`).innerHTML;
+ if (i === group.length - 1) {
+ new TypeIt(`#${group[i]}`, {
+ strings: content,
+ }).go();
+ return;
+ }
+ let instance = new TypeIt(`#${group[i]}`, {
+ strings: content,
+ afterComplete: () => {
+ instance.destroy();
+ typeone(i + 1);
+ },
+ }).go();
+ })(0);
+ }
+ }
+ }
+
+ initScroll() {
+ for (let i = 0; i < this.scrollEvents.length; i++) {
+ document.addEventListener('scroll', this.scrollEvents[i], false);
+ }
+ const initSmoothScroll = () => {
+ const isMobile = window.matchMedia('only screen and (max-width: 560px)').matches;
+ if ((!isMobile && window.desktopHeaderMode === 'normal')
+ || (isMobile && window.mobileHeaderMode === 'normal')) {
+ new SmoothScroll('[href^="#"]', {speed: 300, speedAsDuration: true});
+ } else {
+ new SmoothScroll('[href^="#"]', {speed: 300, speedAsDuration: true, header: '#header-desktop'});
+ }
+ };
+ initSmoothScroll();
+ window.addEventListener('resize', () => {
+ window.setTimeout(() => {
+ initSmoothScroll();
+ }, 0);
+ }, false);
+ const headers = [];
+ if (window.desktopHeaderMode === 'auto') headers.push(document.getElementById('header-desktop'));
+ if (window.mobileHeaderMode === 'auto') headers.push(document.getElementById('header-mobile'));
+ this.util.forEach(headers, (header) => {
+ header.classList.add('animated');
+ header.classList.add('faster');
+ });
+ const toTopButton = document.getElementById('dynamic-to-top');
+ document.addEventListener('scroll', () => {
+ const scrollTop = this.util.getScrollTop();
+ this.util.forEach(headers, (header) => {
+ if (this.scrollTop < scrollTop) {
+ if (!header.classList.contains('fadeOutUp')) {
+ header.classList.remove('fadeInDown');
+ header.classList.add('fadeOutUp');
+ }
+ } else {
+ if (!header.classList.contains('fadeInDown')) {
+ header.classList.remove('fadeOutUp');
+ header.classList.add('fadeInDown');
+ }
+ }
+ if (scrollTop > 600) {
+ if (this.scrollTop < scrollTop) {
+ if (!toTopButton.classList.contains('fadeOut')) {
+ toTopButton.classList.remove('fadeIn');
+ toTopButton.classList.add('fadeOut');
+ }
+ } else {
+ toTopButton.style.display = 'block';
+ if (!toTopButton.classList.contains('fadeIn')) {
+ toTopButton.classList.remove('fadeOut');
+ toTopButton.classList.add('fadeIn');
+ }
+ }
+ } else {
+ toTopButton.style.display = 'none';
+ }
+ });
+ this.scrollTop = scrollTop;
+ }, false);
+ }
+
+ init() {
+ this.initMobileMenu();
+ this.initSwitchTheme();
+ this.initHighlight();
+ this.initTable();
+ this.initHeaderLink();
+ this.initMermaid();
+ this.initEcharts();
+ this.initTypeit();
+ this.initToc();
+ this.initScroll();
+ }
+ }
+
+ const themeInit = () => {
+ const theme = new Theme();
+ theme.init();
+ };
+
+ if (document.readyState !== 'loading') {
+ themeInit();
+ } else {
+ document.addEventListener('DOMContentLoaded', themeInit, false);
+ }
+})();