Merge pull request #73 from dillonzq/feature/custom_fixed_header

Feature/custom fixed header
This commit is contained in:
Dillon 2020-02-16 22:43:58 +08:00 committed by GitHub
commit 34cc26b94a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
28 changed files with 434 additions and 469 deletions

32
.circleci/config.yml Normal file
View file

@ -0,0 +1,32 @@
version: 2.1
jobs:
build-check:
parameters:
example-site-path:
type: string
theme-path:
type: string
docker:
- image: cibuilds/hugo:0.64
working_directory: ~/LoveIt
steps:
- checkout
- run: git submodule sync
- run: git submodule update --init
- run:
command: |
cd << parameters.example-site-path >>
pwd
HUGO_ENV=production hugo --themesDir << parameters.theme-path >> -v --minify --gc
htmlproofer public --allow-hash-href --empty-alt-ignore --disable-external
workflows:
build-check-exampleSite:
jobs:
- build-check:
example-site-path: exampleSite
theme-path: ../..
build-check-exampleSite-zh:
jobs:
- build-check:
example-site-path: exampleSite/zh
theme-path: ../../..

View file

@ -91,7 +91,6 @@ I hope you will LoveIt ❤️!
* Kinds of admonitions shortcode support
* Custom align and float style shortcodes support
* Animated typing support by [TypeIt](https://typeitjs.com/)
* Animated coutdown support by [jQuery.countdown](https://github.com/hilios/jQuery.countdown)
* Dynamic to top support by [Smooth Scroll](https://github.com/cferdinandi/smooth-scroll)
* ...
@ -200,8 +199,6 @@ Thanks to the authors of following resources included in the theme:
* [lazysizes](https://github.com/aFarkas/lazysizes)
* [Smooth Scroll](https://github.com/cferdinandi/smooth-scroll)
* [TypeIt](https://typeitjs.com/)
* [jQuery](https://github.com/jquery/jquery)
* [jQuery.countdown](https://github.com/hilios/jQuery.countdown)
* [Katex](https://katex.org/)
* [mermaid](https://github.com/knsv/mermaid)
* [APlayer](https://github.com/MoePlayer/APlayer)

View file

@ -86,7 +86,6 @@
* 支持多种提醒样式的 shortcode
* 支持自定义对齐和浮动方式的 shortcode
* 支持基于 [TypeIt](https://typeitjs.com/) 的打字动画
* 支持基于 [jQuery.countdown](https://github.com/hilios/jQuery.countdown) 的倒计时动画
* 支持基于 [Smooth Scroll](https://github.com/cferdinandi/smooth-scroll) 的回到顶部动画
* ...
@ -135,7 +134,7 @@
* `assets/css/_varibales.scss` 你可以覆盖 `_variables.scss` 中的变量来自定义样式
* `assets/css/_custom.scss` 你可以把自定义的样式放在这个文件
* 需要使用hugo extended版本编译sass否则修改css无法生效
* 需要使用hugo extended版本编译sass否则修改css无法生效
## 网站图标、浏览器配置、网站清单
@ -195,8 +194,6 @@ LoveIt 根据 MIT 许可协议授权。 更多信息请查看 [LICENSE 文件](h
* [lazysizes](https://github.com/aFarkas/lazysizes)
* [Smooth Scroll](https://github.com/cferdinandi/smooth-scroll)
* [TypeIt](https://typeitjs.com/)
* [jQuery](https://github.com/jquery/jquery)
* [jQuery.countdown](https://github.com/hilios/jQuery.countdown)
* [Katex](https://katex.org/)
* [mermaid](https://github.com/knsv/mermaid)
* [APlayer](https://github.com/MoePlayer/APlayer)

View file

@ -1,5 +1,6 @@
html {
font-family: $global-font-family;
font-size: 16px;
}
/* scrollbar, only support webkit */
@ -25,7 +26,6 @@ html {
}
body {
font-size: 16px;
font-weight: 400;
line-height: 1.5rem;
background-color: $global-background-color;

View file

@ -32,7 +32,7 @@
}
@media only screen and (max-width: 960px) {
header.desktop {
#header-desktop {
.header-wrapper {
margin: 0 1rem;
}
@ -52,16 +52,17 @@
}
@media only screen and (max-width: 560px) {
header.desktop {
#header-desktop {
display: none;
}
header.mobile {
#header-mobile {
display: block;
}
.page {
max-width: 100%;
padding-top: $page-padding-top-mobile;
.categories-card {
.card-item {
@ -80,8 +81,4 @@
}
}
}
.dynamic-to-top {
display: none !important;
}
}

View file

@ -3,7 +3,7 @@
width: 100%;
max-width: 980px;
margin: 0 auto;
padding-top: 6rem;
padding-top: $page-padding-top-desktop;
}
@import "_single";

View file

@ -54,13 +54,6 @@
@import "../_partial/_single/toc";
.content {
.post-dummy-target:target {
display: inline-block;
position: relative;
top: -5.6rem;
visibility: hidden;
}
h1,
h2,
h3,
@ -68,22 +61,14 @@
h5,
h6 {
font-weight: bold;
margin: 1.2rem 0;
.dark-theme & {
font-weight: bolder;
}
}
h2,
h3,
h4,
h5,
h6 {
padding-top: .8rem;
padding-bottom: .3rem;
}
h2::before {
h2 > a:first-child::before {
content: "#";
margin-right: .3125rem;
color: $single-link-color;
@ -93,16 +78,18 @@
}
}
h3::before,
h4::before,
h5::before,
h6::before {
content: "|";
margin-right: .3125rem;
color: $single-link-color;
h3,
h4,
h5,
h6 {
& > a:first-child::before {
content: "|";
margin-right: .3125rem;
color: $single-link-color;
.dark-theme & {
color: $single-link-color-dark;
.dark-theme & {
color: $single-link-color-dark;
}
}
}

View file

@ -1,15 +1,18 @@
header.desktop {
display: block;
position: fixed;
header {
width: 100%;
z-index: 100;
height: 4rem;
line-height: 4rem;
background-color: $header-background-color;
.dark-theme & {
background-color: $header-background-color-dark;
}
}
#header-desktop {
display: block;
position: $header-position-desktop;
height: $header-height-desktop;
line-height: $header-height-desktop;
.header-wrapper {
width: auto;
@ -42,19 +45,16 @@ header.desktop {
}
}
header.mobile {
#header-mobile {
display: none;
position: fixed;
width: 100%;
z-index: 100;
transition: all 0.3s ease 0s;
position: $header-position-mobile;
height: $header-height-mobile;
line-height: $header-height-mobile;
.header-wrapper {
padding: 0;
margin: 0;
height: 4.5rem;
line-height: 4.5rem;
background: $global-background-color;
transition: all 0.3s ease 0s;
.header-container {
display: flex;
@ -72,19 +72,19 @@ header.mobile {
.menu-toggle {
cursor: pointer;
line-height: 4.5rem;
line-height: 4rem;
span {
display: block;
background: #000;
width: 24px;
background: $global-font-color;
width: 1.5rem;
height: 2px;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
-webkit-transition: .2s margin .2s, .2s transform;
-moz-transition: .2s margin .2s, .2s transform;
transition: .2s margin .2s, .2s transform;
-webkit-transition: .1s margin .1s, .1s transform;
-moz-transition: .1s margin .1s, .1s transform;
transition: .1s margin .1s, .1s transform;
.dark-theme & {
background: $global-font-color-dark;
@ -92,25 +92,25 @@ header.mobile {
}
span:nth-child(1) {
margin-bottom: 8px;
margin-bottom: .5rem;
}
span:nth-child(3) {
margin-top: 8px;
margin-top: .5rem;
}
&.active {
span {
-webkit-transition: .2s margin, .2s transform .2s;
-moz-transition: .2s margin, .2s transform .2s;
transition: .2s margin, .2s transform .2s;
-webkit-transition: .1s margin, .1s transform .1s;
-moz-transition: .1s margin, .1s transform .1s;
transition: .1s margin, .1s transform .1s;
}
span:nth-child(1) {
-moz-transform: rotate(45deg) translate(4px, 6px);
-ms-transform: rotate(45deg) translate(4px, 6px);
-webkit-transform: rotate(45deg) translate(4px, 6px);
transform: rotate(45deg) translate(4px, 6px);
-moz-transform: rotate(45deg) translate(.4rem, .5rem);
-ms-transform: rotate(45deg) translate(.4rem, .5rem);
-webkit-transform: rotate(45deg) translate(.4rem, .5rem);
transform: rotate(45deg) translate(.4rem, .5rem);
}
span:nth-child(2) {
@ -118,10 +118,10 @@ header.mobile {
}
span:nth-child(3) {
-moz-transform: rotate(-45deg) translate(8px, -10px);
-ms-transform: rotate(-45deg) translate(8px, -10px);
-webkit-transform: rotate(-45deg) translate(8px, -10px);
transform: rotate(-45deg) translate(8px, -10px);
-moz-transform: rotate(-45deg) translate(.4rem, -.5rem);
-ms-transform: rotate(-45deg) translate(.4rem, -.5rem);
-webkit-transform: rotate(-45deg) translate(.4rem, -.5rem);
transform: rotate(-45deg) translate(.4rem, -.5rem);
}
}
}
@ -148,9 +148,5 @@ header.mobile {
border-top: 2px solid $global-font-color-dark;
}
}
.dark-theme & {
background: $global-background-color-dark;
}
}
}

View file

@ -7,7 +7,7 @@
border-left: 1px solid $global-border-color;
overflow-wrap: break-word;
box-sizing: border-box;
top: 12rem;
top: $post-toc-top;
.dark-theme & {
border-left: 1px solid $global-border-color-dark;
@ -54,16 +54,15 @@
}
}
.toc-link.active {
a.active {
font-weight: bold;
color: $single-link-hover-color;
color: $single-link-color;
.dark-theme & {
color: $single-link-hover-color-dark;
color: $single-link-color-dark;
}
&::before {
font-weight: bolder;
color: $single-link-hover-color;
.dark-theme & {

View file

@ -1,5 +1,3 @@
@charset 'utf-8';
// ==============================
// Variables
// ==============================
@ -48,6 +46,10 @@ $selection-color-dark: rgba(38, 139, 211, 0.3) !default;
// ========== Selection ========== //
// ========== Header ========== //
// Height of the header
$header-height-desktop: 4rem !default;
$header-height-mobile: 4rem !default;
// Color of the header background
$header-background-color: #fafafa !default;
$header-background-color-dark: #252627 !default;

View file

@ -1,3 +1,5 @@
@charset 'utf-8';
{{- if eq .Site.Params.home_mode "post" -}}
$home-profile: true;
$home-posts: true;
@ -6,6 +8,24 @@
$home-posts: false;
{{- end -}}
{{- if eq .Site.Params.desktopHeaderMode "normal" -}}
$header-position-desktop: static;
$page-padding-top-desktop: 1rem;
$post-toc-top: 7rem;
{{- else -}}
$header-position-desktop: fixed;
$page-padding-top-desktop: 6rem;
$post-toc-top: 12rem;
{{- end -}}
{{- if eq .Site.Params.mobileHeaderMode "normal" -}}
$header-position-mobile: static;
$page-padding-top-mobile: 1rem;
{{- else -}}
$header-position-mobile: fixed;
$page-padding-top-mobile: 6rem;
{{- end -}}
@import "_variables";
{{- if fileExists "config/css/_custom.scss" -}}

View file

@ -1,12 +1,10 @@
gitalk@1.5.0
valine@1.3.10
jquery@3.4.1
lazysizes@5.1.2
katex@0.11.1
mermaid@8.4.2
echarts@4.5.0
typeit@6.0.3
jquery-countdown@2.2.0
typeit@6.5.1
aplayer@1.10.1
meting@2.0.1
smooth-scroll@16.1.0
smooth-scroll@16.1.2

View file

@ -1,22 +0,0 @@
/*!
* The Final Countdown for jQuery v2.2.0 (http://hilios.github.io/jQuery.countdown/)
* Copyright (c) 2016 Edson Hilios
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
!function(a){"use strict";"function"==typeof define&&define.amd?define(["jquery"],a):a(jQuery)}(function(a){"use strict";function b(a){if(a instanceof Date)return a;if(String(a).match(g))return String(a).match(/^[0-9]*$/)&&(a=Number(a)),String(a).match(/\-/)&&(a=String(a).replace(/\-/g,"/")),new Date(a);throw new Error("Couldn't cast `"+a+"` to a date object.")}function c(a){var b=a.toString().replace(/([.?*+^$[\]\\(){}|-])/g,"\\$1");return new RegExp(b)}function d(a){return function(b){var d=b.match(/%(-|!)?[A-Z]{1}(:[^;]+;)?/gi);if(d)for(var f=0,g=d.length;f<g;++f){var h=d[f].match(/%(-|!)?([a-zA-Z]{1})(:[^;]+;)?/),j=c(h[0]),k=h[1]||"",l=h[3]||"",m=null;h=h[2],i.hasOwnProperty(h)&&(m=i[h],m=Number(a[m])),null!==m&&("!"===k&&(m=e(l,m)),""===k&&m<10&&(m="0"+m.toString()),b=b.replace(j,m.toString()))}return b=b.replace(/%%/,"%")}}function e(a,b){var c="s",d="";return a&&(a=a.replace(/(:|;|\s)/gi,"").split(/\,/),1===a.length?c=a[0]:(d=a[0],c=a[1])),Math.abs(b)>1?c:d}var f=[],g=[],h={precision:100,elapse:!1,defer:!1};g.push(/^[0-9]*$/.source),g.push(/([0-9]{1,2}\/){2}[0-9]{4}( [0-9]{1,2}(:[0-9]{2}){2})?/.source),g.push(/[0-9]{4}([\/\-][0-9]{1,2}){2}( [0-9]{1,2}(:[0-9]{2}){2})?/.source),g=new RegExp(g.join("|"));var i={Y:"years",m:"months",n:"daysToMonth",d:"daysToWeek",w:"weeks",W:"weeksToMonth",H:"hours",M:"minutes",S:"seconds",D:"totalDays",I:"totalHours",N:"totalMinutes",T:"totalSeconds"},j=function(b,c,d){this.el=b,this.$el=a(b),this.interval=null,this.offset={},this.options=a.extend({},h),this.instanceNumber=f.length,f.push(this),this.$el.data("countdown-instance",this.instanceNumber),d&&("function"==typeof d?(this.$el.on("update.countdown",d),this.$el.on("stoped.countdown",d),this.$el.on("finish.countdown",d)):this.options=a.extend({},h,d)),this.setFinalDate(c),this.options.defer===!1&&this.start()};a.extend(j.prototype,{start:function(){null!==this.interval&&clearInterval(this.interval);var a=this;this.update(),this.interval=setInterval(function(){a.update.call(a)},this.options.precision)},stop:function(){clearInterval(this.interval),this.interval=null,this.dispatchEvent("stoped")},toggle:function(){this.interval?this.stop():this.start()},pause:function(){this.stop()},resume:function(){this.start()},remove:function(){this.stop.call(this),f[this.instanceNumber]=null,delete this.$el.data().countdownInstance},setFinalDate:function(a){this.finalDate=b(a)},update:function(){if(0===this.$el.closest("html").length)return void this.remove();var b,c=void 0!==a._data(this.el,"events"),d=new Date;b=this.finalDate.getTime()-d.getTime(),b=Math.ceil(b/1e3),b=!this.options.elapse&&b<0?0:Math.abs(b),this.totalSecsLeft!==b&&c&&(this.totalSecsLeft=b,this.elapsed=d>=this.finalDate,this.offset={seconds:this.totalSecsLeft%60,minutes:Math.floor(this.totalSecsLeft/60)%60,hours:Math.floor(this.totalSecsLeft/60/60)%24,days:Math.floor(this.totalSecsLeft/60/60/24)%7,daysToWeek:Math.floor(this.totalSecsLeft/60/60/24)%7,daysToMonth:Math.floor(this.totalSecsLeft/60/60/24%30.4368),weeks:Math.floor(this.totalSecsLeft/60/60/24/7),weeksToMonth:Math.floor(this.totalSecsLeft/60/60/24/7)%4,months:Math.floor(this.totalSecsLeft/60/60/24/30.4368),years:Math.abs(this.finalDate.getFullYear()-d.getFullYear()),totalDays:Math.floor(this.totalSecsLeft/60/60/24),totalHours:Math.floor(this.totalSecsLeft/60/60),totalMinutes:Math.floor(this.totalSecsLeft/60),totalSeconds:this.totalSecsLeft},this.options.elapse||0!==this.totalSecsLeft?this.dispatchEvent("update"):(this.stop(),this.dispatchEvent("finish")))},dispatchEvent:function(b){var c=a.Event(b+".countdown");c.finalDate=this.finalDate,c.elapsed=this.elapsed,c.offset=a.extend({},this.offset),c.strftime=d(this.offset),this.$el.trigger(c)}}),a.fn.countdown=function(){var b=Array.prototype.slice.call(arguments,0);return this.each(function(){var c=a(this).data("countdown-instance");if(void 0!==c){var d=f[c],e=b[0];j.prototype.hasOwnProperty(e)?d[e].apply(d,b.slice(1)):null===String(e).match(/^[$A-Z_][0-9A-Z_$]*$/i)?(d.setFinalDate.call(d,e),d.start()):a.error("Method %s does not exist on jQuery.countdown".replace(/\%s/gi,e))}else new j(this,b[0],b[1])})}});

File diff suppressed because one or more lines are too long

4
assets/js/lib/smooth-scroll/smooth-scroll.polyfills.min.js vendored Normal file → Executable file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,313 +1,320 @@
jQuery(function($) {
(() => {
'use strict';
var _Theme = window._Theme || {};
class Util {
forEach(elements, handler) {
elements = elements || [];
for (let i = 0; i < elements.length; i++) {
handler(elements[i]);
}
}
_Theme.scroll = function () {
window.scroll = new SmoothScroll('[data-scroll]', {speed: 300, speedAsDuration: true});
getScrollTop() {
return (document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop;
}
}
_Theme.toggleMobileMenu = function () {
$('#menu-toggle').on('click', () => {
$('#menu-toggle').toggleClass('active');
$('#menu-mobile').toggleClass('active');
});
};
class Theme {
constructor() {
this.util = new Util();
this.scrollTop = 0;
this.scrollEvents = [];
}
_Theme.toggleTheme = function () {
$('.theme-switch').on('click', () => {
$('body').toggleClass('dark-theme');
window.isDark = !window.isDark;
window.localStorage && window.localStorage.setItem('theme', window.isDark ? 'dark' : 'light');
this.echarts();
});
};
initMobileMenu() {
document.getElementById('menu-toggle').onclick = () => {
document.getElementById('menu-toggle').classList.toggle('active');
document.getElementById('menu-mobile').classList.toggle('active');
};
}
_Theme.dynamicToTop = function () {
const min = 300;
var $toTop = $('#dynamic-to-top');
$(window).scroll(() => {
var scrollTop = $(window).scrollTop();
if (typeof document.body.style.maxHeight === 'undefined') {
$toTop.css({
'position': 'absolute',
'top': scrollTop + $(window).height() - 20,
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}`;
});
}
if (scrollTop > min) {
(function fadeIn(el, display){
display = display || "block";
if (el.style.display !== display) {
el.style.opacity = 0;
el.style.display = display;
(function fade() {
var val = parseFloat(el.style.opacity);
if (!((val += .1) > 1)) {
el.style.opacity = val;
requestAnimationFrame(fade);
}
})();
}
})(document.getElementById('dynamic-to-top'));
} else {
(function fadeOut(el){
if (el.style.display !== "none") {
el.style.opacity = 1;
(function fade() {
if ((el.style.opacity -= .1) < 0) {
el.style.display = "none";
} else {
requestAnimationFrame(fade);
}
})();
}
})(document.getElementById('dynamic-to-top'));
}
_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;
}
});
};
_Theme.chroma = function () {
const blocks = document.querySelectorAll('.highlight > .chroma');
for (let i = 0; i < blocks.length; i++) {
const block = blocks[i];
const codes = block.querySelectorAll('pre.chroma > code');
const code = codes[codes.length - 1];
const lang = code ? code.className.toLowerCase() : '';
block.className += ' ' + lang;
if (newTocList !== oldTocList) toc.replaceChild(newTocList, oldTocList);
}
const nolinenosBlocks = document.querySelectorAll('.highlight > pre.chroma');
for (let i = 0; i < nolinenosBlocks.length; i++) {
const block = nolinenosBlocks[i];
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);
}
};
_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);
_Theme.responsiveTable = function () {
const tables = document.querySelectorAll('.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);
}
};
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`;
}
_Theme._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);
};
_Theme._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('.content>h' + num);
for (let i = 0; i < headers.length; i++) {
const header = headers[i];
header.innerHTML = `<a href="#${header.id}" class="headerlink"></a>${header.innerHTML}`;
}
}
};
_Theme._initToc = function () {
const $toc = $('#post-toc');
if ($toc.length && $toc.css('display') !== 'none') {
const SPACING = 80;
const $footer = $('#post-footer');
const minTop = $toc.position().top;;
const mainTop = $('main').position().top;
const minScrollTop = minTop + mainTop - SPACING;
const changeTocState = function () {
const scrollTop = $(window).scrollTop();
const maxTop = $footer.position().top - $toc.height();
const maxScrollTop = maxTop + mainTop - SPACING;
const tocState = {
start: {
'position': 'absolute',
'top': minTop,
},
process: {
'position': 'fixed',
'top': SPACING,
},
end: {
'position': 'absolute',
'top': maxTop,
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 (scrollTop < minScrollTop) {
$toc.css(tocState.start);
} else if (scrollTop > maxScrollTop) {
$toc.css(tocState.end);
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 {
$toc.css(tocState.process);
this._refactorToc(toc);
this._initTocState(tocContainer);
window.addEventListener('resize', () => {
window.setTimeout(() => {
this._initTocState(tocContainer);
}, 0);
}, false);
}
};
changeTocState();
const $toclink = $('.toc-link');
const $headerDummyLink = $('.post-dummy-target');
const $tocLinkLis = $('.post-toc-content li');
const activeIndex = function () {
const scrollTop = $(window).scrollTop();
const headerlinkTop = $.map($headerDummyLink, function(link) {
return $(link).offset().top;
});
const searchActiveTocIndex = function(array, target) {
for (let i = 0; i < array.length - 1; i++) {
if ( target < array[i + 1]) return i;
}
return array.length - 1;
};
const activeTocIndex = searchActiveTocIndex(headerlinkTop, 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;
}
}
};
activeIndex();
if (!this._initTocOnce) {
$(window).scroll(changeTocState);
$(window).scroll(activeIndex);
this._initTocOnce = true;
}
}
};
_Theme.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();
// Listen for orientation changes
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(_Theme._initToc, 0);
this.setTimeout(() => {
for (let i = 0; i < echartsArr.length; i++) {
echartsArr[i].resize();
}
}, 0);
}, false);
}
}
};
_Theme.mermaid = function () {
if (window.mermaidMap) {
mermaid.initialize({startOnLoad: false, theme: null});
const mermaidAPI = mermaid.mermaidAPI
Object.keys(mermaidMap).forEach((id) => {
const element = document.getElementById(id);
mermaidAPI.render("d" + id, mermaidMap[id], (svgCode) => {
element.innerHTML = svgCode;
const svg = element.firstChild;
svg.style.width = "100%"
}, element);
});
}
}
_Theme.echarts = function () {
if (window.echartsMap) {
for (let i = 0; i < echartsArr.length; i++) {
echartsArr[i].dispose();
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);
}
}
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();
}
}
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();
}
}
_Theme.countdown = function () {
if (window.countdownMap) {
Object.keys(countdownMap).forEach(function(id) {
$(`#${id}`).countdown(countdownMap[id]['date'], {elapse: true})
.on('update.countdown', function(event) {
$(this).html(event.strftime(countdownMap[id]['pattern']));
});
});
}
const themeInit = () => {
const theme = new Theme();
theme.init();
};
_Theme.typeit = function () {
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);
}
}
};
$(document).ready(() => {
_Theme.scroll();
_Theme.toggleMobileMenu();
_Theme.toggleTheme();
_Theme.dynamicToTop();
_Theme.chroma();
_Theme.responsiveTable();
_Theme.mermaid();
_Theme.echarts();
_Theme.countdown();
_Theme.typeit();
_Theme.toc();
});
});
if (document.readyState !== 'loading') {
themeInit();
} else {
document.addEventListener('DOMContentLoaded', themeInit, false);
}
})();

View file

@ -112,6 +112,10 @@ dateFormatToUse = "2006-01-02"
keywords = ["Theme", "Hugo"]
# site default theme ("light", "dark", "auto")
defaultTheme = "auto"
# desktop header mode ("fixed", "normal", "auto")
desktopHeaderMode = "fixed"
# mobile header mode ("fixed", "normal", "auto")
mobileHeaderMode = "auto"
# Home Page Info
##home mode ("post", "other")
@ -167,7 +171,6 @@ dateFormatToUse = "2006-01-02"
gitalk_css = ''
gitalk_js = ''
valine_js = ''
jquery_js = ''
lazysizes_js = ''
smooth_scroll_js = ''
katex_css = ''
@ -180,7 +183,6 @@ dateFormatToUse = "2006-01-02"
echarts_js = ''
echarts_macarons_js = ''
typeit_js = ''
jquery_countdown_js = ''
aplayer_css = ''
aplayer_js = ''
meting_js = ''

View file

@ -52,7 +52,6 @@ It is based on the original [LeaveIt Theme](https://github.com/liuzc/LeaveIt/) a
* :(far fa-bell): Kinds of admonitions shortcode support
* :(fas fa-align-left): Custom align and float style shortcodes support
* :(fas fa-i-cursor): Animated typing support by [TypeIt](https://typeitjs.com/)
* :(far fa-clock): Animated coutdown support by [jQuery.countdown](https://github.com/hilios/jQuery.countdown)
* :(fas fa-arrow-up): Dynamic to top support by [Smooth Scroll](https://github.com/cferdinandi/smooth-scroll)
* ...
@ -69,8 +68,6 @@ Thanks to the authors of following resources included in the theme:
* [lazysizes](https://github.com/aFarkas/lazysizes)
* [Smooth Scroll](https://github.com/cferdinandi/smooth-scroll)
* [TypeIt](https://typeitjs.com/)
* [jQuery](https://github.com/jquery/jquery)
* [jQuery.countdown](https://github.com/hilios/jQuery.countdown)
* [Katex](https://katex.org/)
* [mermaid](https://github.com/knsv/mermaid)
* [APlayer](https://github.com/MoePlayer/APlayer)

View file

@ -112,6 +112,10 @@ dateFormatToUse = "2006-01-02"
keywords = ["Theme", "Hugo"]
# 网站默认主题 ("light", "dark", "auto")
defaultTheme = "auto"
# 桌面端导航栏模式 ("fixed", "normal", "auto")
desktopHeaderMode = "fixed"
# 移动端导航栏模式 ("fixed", "normal", "auto")
mobileHeaderMode = "auto"
# 主页信息设置
## 主页模式 ("post", "other")
@ -167,7 +171,6 @@ dateFormatToUse = "2006-01-02"
gitalk_css = ''
gitalk_js = ''
valine_js = ''
jquery_js = ''
lazysizes_js = ''
smooth_scroll_js = ''
katex_css = ''
@ -180,7 +183,6 @@ dateFormatToUse = "2006-01-02"
echarts_js = ''
echarts_macarons_js = ''
typeit_js = ''
jquery_countdown_js = ''
aplayer_css = ''
aplayer_js = ''
meting_js = ''

View file

@ -52,7 +52,6 @@ draft: false
* :(far fa-bell): 支持多种提醒样式的 shortcode
* :(fas fa-align-left): 支持自定义对齐和浮动方式的 shortcode
* :(fas fa-i-cursor): 支持基于 [TypeIt](https://typeitjs.com/) 的打字动画
* :(far fa-clock): 支持基于 [jQuery.countdown](https://github.com/hilios/jQuery.countdown) 的倒计时动画
* :(fas fa-arrow-up): 支持基于 [Smooth Scroll](https://github.com/cferdinandi/smooth-scroll) 的回到顶部动画
* ...
@ -69,8 +68,6 @@ LoveIt 根据 MIT 许可协议授权。
* [lazysizes](https://github.com/aFarkas/lazysizes)
* [Smooth Scroll](https://github.com/cferdinandi/smooth-scroll)
* [TypeIt](https://typeitjs.com/)
* [jQuery](https://github.com/jquery/jquery)
* [jQuery.countdown](https://github.com/hilios/jQuery.countdown)
* [Katex](https://katex.org/)
* [mermaid](https://github.com/knsv/mermaid)
* [APlayer](https://github.com/MoePlayer/APlayer)

View file

@ -176,20 +176,20 @@ func main() {
### 3.5 引用链接的定义
```markdown
[foo]: /url "title"
[foo]: / "title"
[foo]
[bar]: /url
[bar]: /
[bar]
```
[foo]: /url "title"
[foo]: / "title"
[foo]
[bar]: /url
[bar]: /
[bar]
@ -683,14 +683,14 @@ function doIt() {
```
| _颜色_ | 水果 | 蔬菜 |
| ------------- |:---------------:| -----------------:|
| red | *苹果* | [辣椒](#Tables) |
| red | *苹果* | [辣椒](#) |
| ~~橙色~~ | 橘子 | **胡萝卜** |
| 绿色 | ~~***梨子***~~ | 菠菜 |
```
| _颜色_ | 水果 | 蔬菜 |
| ------------- |:---------------:| ------------:|
| red | *苹果* | [辣椒](#Tables) |
| red | *苹果* | [辣椒](#) |
| ~~橙色~~ | 橘子 | **胡萝卜** |
| 绿色 | ~~***梨子***~~ | 菠菜 |

View file

@ -52,7 +52,7 @@
</div>
{{- /* Dynamic to top button */ -}}
<a href="#" class="dynamic-to-top" id="dynamic-to-top" data-scroll>
<a href="#" class="dynamic-to-top animated faster" id="dynamic-to-top">
<span>&nbsp;</span>
</a>

View file

@ -1,5 +1,5 @@
{{- /* Desktop header */ -}}
<header class="desktop">
<header class="desktop" id="header-desktop">
<div class="header-wrapper">
<div class="header-title animated bounceIn">
<a href="{{ .Site.BaseURL }}">
@ -19,7 +19,7 @@
</header>
{{- /* Mobile header */ -}}
<header class="mobile">
<header class="mobile" id="header-mobile">
<div class="header-wrapper">
<div class="header-container">
<div class="header-title animated bounceIn">
@ -42,3 +42,8 @@
</div>
</div>
</header>
<script>
window.desktopHeaderMode = {{ .Site.Params.desktopHeaderMode }};
window.mobileHeaderMode = {{ .Site.Params.mobileHeaderMode }};
</script>

View file

@ -25,19 +25,4 @@
{{- $REout = `↩︎` -}}
{{- $content = replaceRE $REin $REout $content -}}
{{- /* Dummy target */ -}}
{{- $REin = `<(h[23456]) (id=".+?")>` -}}
{{- $REout = `<a class="post-dummy-target" $2></a><$1>` -}}
{{- $content = replaceRE $REin $REout $content -}}
{{- /* Dummy target */ -}}
{{- $REin = `<(.+) (id="fnref:.+?")>` -}}
{{- $REout = `<a class="post-dummy-target" $2></a><$1>` -}}
{{- $content = replaceRE $REin $REout $content -}}
{{- /* Dummy target */ -}}
{{- $REin = `<li (id="fn:.+?")(.*?)>\s?<p>` -}}
{{- $REout = `<li $2><p><a class="post-dummy-target" $1></a>` -}}
{{- $content = replaceRE $REin $REout $content -}}
{{- return $content -}}

View file

@ -5,13 +5,6 @@
{{- template "_internal/google_analytics_async.html" . -}}
{{- end -}}
{{- /* jQuery https://github.com/jquery/jquery */ -}}
{{- with $CDN.jquery_js -}}
{{- slice . | $.Scratch.Add "scriptCDN" -}}
{{- else -}}
{{- slice "js/lib/jquery/jquery.slim.min.js" | .Scratch.Add "scriptLocal" -}}
{{- end -}}
{{- /* lazysizes https://github.com/aFarkas/lazysizes */ -}}
{{- with $CDN.lazysizes_js -}}
{{- slice . | $.Scratch.Add "scriptCDN" -}}
@ -133,18 +126,6 @@
{{- end -}}
{{- end -}}
{{- /* jQuery.countdown https://github.com/hilios/jQuery.countdown */ -}}
{{- with .Scratch.Get "countdownMap" -}}
{{- with $CDN.jquery_countdown_js -}}
{{- slice . | $.Scratch.Add "scriptCDN" -}}
{{- else -}}
{{- slice "js/lib/jquery-countdown/jquery.countdown.min.js" | $.Scratch.Add "scriptLocal" -}}
{{- end -}}
<script>
window.countdownMap = {{ jsonify . | safeJS }};
</script>
{{- end -}}
{{- /* dev feature */ -}}
{{- if .Params.dev -}}
{{- /* ECharts https://github.com/apache/incubator-echarts */ -}}

View file

@ -1,12 +0,0 @@
{{- if .Get "date" -}}
{{- $date := .Get "date" -}}
{{- $id := delimit (split (md5 $date) "" | shuffle) "" | printf "countdown-%s" -}}
{{- $defaultPattern := printf "%%D %s %%H %s %%M %s %%S %s" (T "day") (T "hour") (T "minute") (T "second") -}}
{{- $new := dict $id (dict "date" $date "pattern" (.Get "pattern" | default $defaultPattern)) -}}
{{- with .Page.Scratch.Get "countdownMap" -}}
{{- .Page.Scratch.Set "countdownMap" (merge . $new) -}}
{{- else -}}
{{- .Page.Scratch.Set "countdownMap" $new -}}
{{- end -}}
<div id="{{ $id }}" style={{ .Get "style" | safeCSS }}></div>
{{- end -}}