mirror of
https://github.com/jerryc127/hexo-theme-butterfly.git
synced 2026-08-08 11:38:42 +08:00
update
This commit is contained in:
@@ -124,7 +124,6 @@ npm install hexo-renderer-pug hexo-renderer-stylus --save
|
|||||||
- [x] **Theme Customization** - Custom site color schemes
|
- [x] **Theme Customization** - Custom site color schemes
|
||||||
- [x] **Chart Support** - Mermaid flowcharts/Chart.js data charts
|
- [x] **Chart Support** - Mermaid flowcharts/Chart.js data charts
|
||||||
- [x] **Music Notation** - ABCJS music notation support
|
- [x] **Music Notation** - ABCJS music notation support
|
||||||
- [x] **Music Player** - APlayer/Meting music playback
|
|
||||||
- [x] **Article Series** - Series article organization
|
- [x] **Article Series** - Series article organization
|
||||||
- [x] **Instantpage** - Page preloading acceleration
|
- [x] **Instantpage** - Page preloading acceleration
|
||||||
- [x] **Snackbar** - Elegant notification messages
|
- [x] **Snackbar** - Elegant notification messages
|
||||||
|
|||||||
@@ -124,7 +124,6 @@ npm install hexo-renderer-pug hexo-renderer-stylus --save
|
|||||||
- [x] **主題定製** - 自訂網站配色方案
|
- [x] **主題定製** - 自訂網站配色方案
|
||||||
- [x] **圖表支援** - Mermaid 流程圖/Chart.js 數據圖表
|
- [x] **圖表支援** - Mermaid 流程圖/Chart.js 數據圖表
|
||||||
- [x] **音樂符號** - ABCJS 音樂記譜法支援
|
- [x] **音樂符號** - ABCJS 音樂記譜法支援
|
||||||
- [x] **音樂播放器** - APlayer/Meting 音樂播放功能
|
|
||||||
- [x] **系列文章** - 系列文章組織功能
|
- [x] **系列文章** - 系列文章組織功能
|
||||||
- [x] **Instantpage** - 頁面預載入加速
|
- [x] **Instantpage** - 頁面預載入加速
|
||||||
- [x] **Snackbar** - 優雅的提示訊息
|
- [x] **Snackbar** - 優雅的提示訊息
|
||||||
|
|||||||
@@ -993,11 +993,6 @@ pjax:
|
|||||||
exclude:
|
exclude:
|
||||||
# - /xxxxxx/
|
# - /xxxxxx/
|
||||||
|
|
||||||
# Inject the css and script (aplayer/meting)
|
|
||||||
aplayerInject:
|
|
||||||
enable: false
|
|
||||||
per_page: true
|
|
||||||
|
|
||||||
# Snackbar - Toast Notification
|
# Snackbar - Toast Notification
|
||||||
# https://github.com/polonel/SnackBar
|
# https://github.com/polonel/SnackBar
|
||||||
# position: top-left / top-center / top-right / bottom-left / bottom-center / bottom-right
|
# position: top-left / top-center / top-right / bottom-left / bottom-center / bottom-right
|
||||||
@@ -1088,8 +1083,6 @@ CDN:
|
|||||||
# activate_power_mode:
|
# activate_power_mode:
|
||||||
# algolia_js:
|
# algolia_js:
|
||||||
# algolia_search:
|
# algolia_search:
|
||||||
# aplayer_css:
|
|
||||||
# aplayer_js:
|
|
||||||
# artalk_css:
|
# artalk_css:
|
||||||
# artalk_js:
|
# artalk_js:
|
||||||
# blueimp_md5:
|
# blueimp_md5:
|
||||||
@@ -1122,7 +1115,6 @@ CDN:
|
|||||||
# mathjax:
|
# mathjax:
|
||||||
# medium_zoom:
|
# medium_zoom:
|
||||||
# mermaid:
|
# mermaid:
|
||||||
# meting_js:
|
|
||||||
# prismjs_autoloader:
|
# prismjs_autoloader:
|
||||||
# prismjs_js:
|
# prismjs_js:
|
||||||
# prismjs_lineNumber_js:
|
# prismjs_lineNumber_js:
|
||||||
|
|||||||
@@ -41,10 +41,6 @@ div
|
|||||||
!= partial("includes/third-party/effect", {}, { cache: true })
|
!= partial("includes/third-party/effect", {}, { cache: true })
|
||||||
!= partial("includes/third-party/chat/index", {}, { cache: true })
|
!= partial("includes/third-party/chat/index", {}, { cache: true })
|
||||||
|
|
||||||
if theme.aplayerInject && theme.aplayerInject.enable
|
|
||||||
if theme.pjax.enable || theme.aplayerInject.per_page || page.aplayer
|
|
||||||
include ./third-party/aplayer.pug
|
|
||||||
|
|
||||||
if theme.pjax.enable
|
if theme.pjax.enable
|
||||||
!= partial("includes/third-party/pjax", {}, { cache: true })
|
!= partial("includes/third-party/pjax", {}, { cache: true })
|
||||||
|
|
||||||
|
|||||||
@@ -161,7 +161,7 @@
|
|||||||
container.innerHTML = content
|
container.innerHTML = content
|
||||||
|
|
||||||
window.lazyLoadInstance && window.lazyLoadInstance.update()
|
window.lazyLoadInstance && window.lazyLoadInstance.update()
|
||||||
btf.loadLightbox(document.querySelectorAll('#article-container img:not(.no-lightbox)'))
|
document.dispatchEvent(new Event('shuoshuo:rendered'))
|
||||||
}
|
}
|
||||||
|
|
||||||
const setupNavEvents = (nav) => {
|
const setupNavEvents = (nav) => {
|
||||||
|
|||||||
-23
@@ -1,23 +0,0 @@
|
|||||||
link(rel='stylesheet' href=url_for(theme.asset.aplayer_css) media="print" onload="this.media='all'")
|
|
||||||
script(src=url_for(theme.asset.aplayer_js))
|
|
||||||
script(src=url_for(theme.asset.meting_js))
|
|
||||||
if theme.pjax.enable
|
|
||||||
script.
|
|
||||||
(() => {
|
|
||||||
const destroyAplayer = () => {
|
|
||||||
if (window.aplayers) {
|
|
||||||
for (let i = 0; i < window.aplayers.length; i++) {
|
|
||||||
if (!window.aplayers[i].options.fixed) {
|
|
||||||
window.aplayers[i].destroy()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const runMetingJS = () => {
|
|
||||||
typeof loadMeting === 'function' && document.getElementsByClassName('aplayer').length && loadMeting()
|
|
||||||
}
|
|
||||||
|
|
||||||
btf.addGlobalFn('pjaxSend', destroyAplayer, 'destroyAplayer')
|
|
||||||
btf.addGlobalFn('pjaxComplete', loadMeting, 'runMetingJS')
|
|
||||||
})()
|
|
||||||
@@ -43,4 +43,13 @@ hr.custom-hr
|
|||||||
when 'Remark42'
|
when 'Remark42'
|
||||||
#remark42
|
#remark42
|
||||||
when 'Artalk'
|
when 'Artalk'
|
||||||
|
if theme.artalk.vote
|
||||||
|
.artalk-vote
|
||||||
|
span.artalk-page-vote-up
|
||||||
|
i.fas.fa-thumbs-up
|
||||||
|
span.artalk-page-vote-up-count
|
||||||
|
span.artalk-page-vote-down
|
||||||
|
i.fas.fa-thumbs-down
|
||||||
|
span.artalk-page-vote-down-count
|
||||||
#artalk-wrap
|
#artalk-wrap
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "hexo-theme-butterfly",
|
"name": "hexo-theme-butterfly",
|
||||||
"version": "5.6.1",
|
"version": "5.7.0",
|
||||||
"description": "A Simple and Card UI Design theme for Hexo",
|
"description": "A Simple and Card UI Design theme for Hexo",
|
||||||
"main": "package.json",
|
"main": "package.json",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@@ -26,7 +26,7 @@
|
|||||||
"hexo-renderer-pug": "^3.0.0",
|
"hexo-renderer-pug": "^3.0.0",
|
||||||
"hexo-renderer-stylus": "^3.0.1",
|
"hexo-renderer-stylus": "^3.0.1",
|
||||||
"hexo-util": "^4.0.0",
|
"hexo-util": "^4.0.0",
|
||||||
"moment-timezone": "^0.6.2"
|
"moment-timezone": "^0.6.3"
|
||||||
},
|
},
|
||||||
"homepage": "https://butterfly.js.org/",
|
"homepage": "https://butterfly.js.org/",
|
||||||
"author": "Jerry <my@crazywong.com>",
|
"author": "Jerry <my@crazywong.com>",
|
||||||
|
|||||||
+9
-21
@@ -10,22 +10,14 @@ algolia_search:
|
|||||||
name: algoliasearch
|
name: algoliasearch
|
||||||
file: dist/lite/builds/browser.umd.js
|
file: dist/lite/builds/browser.umd.js
|
||||||
version: 5.56.0
|
version: 5.56.0
|
||||||
aplayer_css:
|
|
||||||
name: aplayer
|
|
||||||
file: dist/APlayer.min.css
|
|
||||||
version: 1.10.1
|
|
||||||
aplayer_js:
|
|
||||||
name: aplayer
|
|
||||||
file: dist/APlayer.min.js
|
|
||||||
version: 1.10.1
|
|
||||||
artalk_css:
|
artalk_css:
|
||||||
name: artalk
|
name: artalk
|
||||||
file: dist/Artalk.css
|
file: dist/Artalk.css
|
||||||
version: 2.9.1
|
version: 2.10.0
|
||||||
artalk_js:
|
artalk_js:
|
||||||
name: artalk
|
name: artalk
|
||||||
file: dist/Artalk.js
|
file: dist/Artalk.js
|
||||||
version: 2.9.1
|
version: 2.10.0
|
||||||
blueimp_md5:
|
blueimp_md5:
|
||||||
name: blueimp-md5
|
name: blueimp-md5
|
||||||
file: js/md5.min.js
|
file: js/md5.min.js
|
||||||
@@ -66,12 +58,12 @@ docsearch_css:
|
|||||||
name: '@docsearch/css'
|
name: '@docsearch/css'
|
||||||
other_name: docsearch-css
|
other_name: docsearch-css
|
||||||
file: dist/style.css
|
file: dist/style.css
|
||||||
version: 4.6.3
|
version: 4.7.0
|
||||||
docsearch_js:
|
docsearch_js:
|
||||||
name: '@docsearch/js'
|
name: '@docsearch/js'
|
||||||
other_name: docsearch-js
|
other_name: docsearch-js
|
||||||
file: dist/umd/index.js
|
file: dist/umd/index.js
|
||||||
version: 4.6.3
|
version: 4.7.0
|
||||||
egjs_infinitegrid:
|
egjs_infinitegrid:
|
||||||
name: '@egjs/infinitegrid'
|
name: '@egjs/infinitegrid'
|
||||||
other_name: egjs-infinitegrid
|
other_name: egjs-infinitegrid
|
||||||
@@ -80,13 +72,13 @@ egjs_infinitegrid:
|
|||||||
fancybox:
|
fancybox:
|
||||||
name: '@fancyapps/ui'
|
name: '@fancyapps/ui'
|
||||||
file: dist/fancybox/fancybox.umd.js
|
file: dist/fancybox/fancybox.umd.js
|
||||||
version: 6.1.14
|
|
||||||
other_name: fancyapps-ui
|
other_name: fancyapps-ui
|
||||||
|
version: 6.1.14
|
||||||
fancybox_css:
|
fancybox_css:
|
||||||
name: '@fancyapps/ui'
|
name: '@fancyapps/ui'
|
||||||
file: dist/fancybox/fancybox.css
|
file: dist/fancybox/fancybox.css
|
||||||
version: 6.1.14
|
|
||||||
other_name: fancyapps-ui
|
other_name: fancyapps-ui
|
||||||
|
version: 6.1.14
|
||||||
fireworks:
|
fireworks:
|
||||||
name: butterfly-extsrc
|
name: butterfly-extsrc
|
||||||
file: dist/fireworks.min.js
|
file: dist/fireworks.min.js
|
||||||
@@ -112,12 +104,12 @@ katex:
|
|||||||
name: katex
|
name: katex
|
||||||
file: dist/katex.min.css
|
file: dist/katex.min.css
|
||||||
other_name: KaTeX
|
other_name: KaTeX
|
||||||
version: 0.17.0
|
version: 0.18.1
|
||||||
katex_copytex:
|
katex_copytex:
|
||||||
name: katex
|
name: katex
|
||||||
file: dist/contrib/copy-tex.min.js
|
file: dist/contrib/copy-tex.min.js
|
||||||
other_name: KaTeX
|
other_name: KaTeX
|
||||||
version: 0.17.0
|
version: 0.18.1
|
||||||
lazyload:
|
lazyload:
|
||||||
name: vanilla-lazyload
|
name: vanilla-lazyload
|
||||||
file: dist/lazyload.iife.min.js
|
file: dist/lazyload.iife.min.js
|
||||||
@@ -134,10 +126,6 @@ mermaid:
|
|||||||
name: mermaid
|
name: mermaid
|
||||||
file: dist/mermaid.min.js
|
file: dist/mermaid.min.js
|
||||||
version: 11.16.0
|
version: 11.16.0
|
||||||
meting_js:
|
|
||||||
name: butterfly-extsrc
|
|
||||||
file: metingjs/dist/Meting.min.js
|
|
||||||
version: 1.1.6
|
|
||||||
pace_default_css:
|
pace_default_css:
|
||||||
name: pace-js
|
name: pace-js
|
||||||
other_name: pace
|
other_name: pace
|
||||||
@@ -186,7 +174,7 @@ snackbar_css:
|
|||||||
twikoo:
|
twikoo:
|
||||||
name: twikoo
|
name: twikoo
|
||||||
file: dist/twikoo.all.min.js
|
file: dist/twikoo.all.min.js
|
||||||
version: 1.7.14
|
version: 1.7.15
|
||||||
typed:
|
typed:
|
||||||
name: typed.js
|
name: typed.js
|
||||||
file: dist/typed.umd.js
|
file: dist/typed.umd.js
|
||||||
|
|||||||
@@ -378,6 +378,7 @@ module.exports = {
|
|||||||
server: null,
|
server: null,
|
||||||
site: null,
|
site: null,
|
||||||
visitor: false,
|
visitor: false,
|
||||||
|
vote: false,
|
||||||
option: null
|
option: null
|
||||||
},
|
},
|
||||||
chat: {
|
chat: {
|
||||||
@@ -555,10 +556,6 @@ module.exports = {
|
|||||||
enable: false,
|
enable: false,
|
||||||
exclude: null
|
exclude: null
|
||||||
},
|
},
|
||||||
aplayerInject: {
|
|
||||||
enable: false,
|
|
||||||
per_page: true
|
|
||||||
},
|
|
||||||
snackbar: {
|
snackbar: {
|
||||||
enable: false,
|
enable: false,
|
||||||
position: 'bottom-left',
|
position: 'bottom-left',
|
||||||
|
|||||||
@@ -6,7 +6,8 @@
|
|||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
hexo.extend.generator.register('404', function (locals) {
|
hexo.extend.generator.register('404', function (locals) {
|
||||||
if (!hexo.theme.config.error_404.enable) return
|
const error404 = hexo.theme.config.error_404 || {}
|
||||||
|
if (!error404.enable) return
|
||||||
return {
|
return {
|
||||||
path: '404.html',
|
path: '404.html',
|
||||||
layout: ['page'],
|
layout: ['page'],
|
||||||
|
|||||||
@@ -8,11 +8,19 @@
|
|||||||
const { version } = require('../../package.json')
|
const { version } = require('../../package.json')
|
||||||
const path = require('path')
|
const path = require('path')
|
||||||
|
|
||||||
|
// Cache plugins.yml to avoid re-rendering on every generate
|
||||||
|
let cachedPlugins = null
|
||||||
|
const loadPlugins = hexo => {
|
||||||
|
if (cachedPlugins) return cachedPlugins
|
||||||
|
cachedPlugins = hexo.render.renderSync({ path: path.join(hexo.theme_dir, '/plugins.yml'), engine: 'yaml' })
|
||||||
|
return cachedPlugins
|
||||||
|
}
|
||||||
|
|
||||||
hexo.extend.filter.register('before_generate', () => {
|
hexo.extend.filter.register('before_generate', () => {
|
||||||
const themeConfig = hexo.theme.config
|
const themeConfig = hexo.theme.config
|
||||||
const { CDN } = themeConfig
|
const { CDN } = themeConfig
|
||||||
|
|
||||||
const thirdPartySrc = hexo.render.renderSync({ path: path.join(hexo.theme_dir, '/plugins.yml'), engine: 'yaml' })
|
const thirdPartySrc = loadPlugins(hexo)
|
||||||
const internalSrc = {
|
const internalSrc = {
|
||||||
main: {
|
main: {
|
||||||
name: 'hexo-theme-butterfly',
|
name: 'hexo-theme-butterfly',
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
hexo.extend.filter.register('stylus:renderer', style => {
|
hexo.extend.filter.register('stylus:renderer', style => {
|
||||||
const { syntax_highlighter: syntaxHighlighter, highlight, prismjs } = hexo.config
|
const { syntax_highlighter: syntaxHighlighter, highlight = {}, prismjs = {} } = hexo.config
|
||||||
let { enable: highlightEnable, line_number: highlightLineNumber } = highlight
|
let { enable: highlightEnable, line_number: highlightLineNumber } = highlight
|
||||||
let { enable: prismjsEnable, line_number: prismjsLineNumber } = prismjs
|
let { enable: prismjsEnable, line_number: prismjsLineNumber } = prismjs
|
||||||
|
|
||||||
|
|||||||
@@ -69,18 +69,14 @@ hexo.extend.helper.register('aside_archives', function (options = {}) {
|
|||||||
|
|
||||||
// Use template literal for better readability
|
// Use template literal for better readability
|
||||||
const archiveHeader = `
|
const archiveHeader = `
|
||||||
<div class="item-headline">
|
<div class="item-headline"><i class="fas fa-archive"></i><span>${_p('aside.card_archives')}</span>${
|
||||||
<i class="fas fa-archive"></i>
|
data.length > limitedData.length
|
||||||
<span>${_p('aside.card_archives')}</span>
|
? `<a class="card-more-btn" href="${urlFor(archiveDir)}/"
|
||||||
${
|
|
||||||
data.length > limitedData.length
|
|
||||||
? `<a class="card-more-btn" href="${urlFor(archiveDir)}/"
|
|
||||||
title="${_p('aside.more_button')}">
|
title="${_p('aside.more_button')}">
|
||||||
<i class="fas fa-angle-right"></i>
|
<i class="fas fa-angle-right"></i>
|
||||||
</a>`
|
</a>`
|
||||||
: ''
|
: ''
|
||||||
}
|
}</div>
|
||||||
</div>
|
|
||||||
`
|
`
|
||||||
|
|
||||||
// Use map for generating list items, join for performance
|
// Use map for generating list items, join for performance
|
||||||
|
|||||||
@@ -89,11 +89,7 @@ hexo.extend.helper.register('aside_categories', function (categories, options =
|
|||||||
<i class="fas fa-angle-right"></i></a>`
|
<i class="fas fa-angle-right"></i></a>`
|
||||||
: ''
|
: ''
|
||||||
|
|
||||||
return `<div class="item-headline">
|
return `<div class="item-headline"><i class="fas fa-folder-open"></i><span>${this._p('aside.card_categories')}</span>${moreButton}</div>
|
||||||
<i class="fas fa-folder-open"></i>
|
|
||||||
<span>${this._p('aside.card_categories')}</span>
|
|
||||||
${moreButton}
|
|
||||||
</div>
|
|
||||||
<ul class="card-category-list${isExpand && list.result ? ' expandBtn' : ''}" id="aside-cat-list">
|
<ul class="card-category-list${isExpand && list.result ? ' expandBtn' : ''}" id="aside-cat-list">
|
||||||
${list.result}
|
${list.result}
|
||||||
</ul>`
|
</ul>`
|
||||||
|
|||||||
+33
-1
@@ -157,8 +157,40 @@ hexo.extend.helper.register('shuoshuoFN', (data, page) => {
|
|||||||
processedData.forEach(item => {
|
processedData.forEach(item => {
|
||||||
const parsed = moment.utc(item.date)
|
const parsed = moment.utc(item.date)
|
||||||
item.date = moment.tz(parsed.format('YYYY-MM-DD HH:mm:ss'), timezone).format('YYYY-MM-DD HH:mm:ss')
|
item.date = moment.tz(parsed.format('YYYY-MM-DD HH:mm:ss'), timezone).format('YYYY-MM-DD HH:mm:ss')
|
||||||
// markdown
|
|
||||||
|
// Render the content using Hexo's rendering engine to process any tags or markdown
|
||||||
|
const mockPost = {
|
||||||
|
content: item.content,
|
||||||
|
source: item.source || page.source || '',
|
||||||
|
full_source: page.full_source || '',
|
||||||
|
path: page.path || '',
|
||||||
|
layout: item.layout || page.layout || 'post',
|
||||||
|
raw: item.raw || item.content,
|
||||||
|
draft: false,
|
||||||
|
published: true
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
hexo.execFilterSync('before_post_render', mockPost, { context: hexo })
|
||||||
|
} catch (e) {
|
||||||
|
// ignore third-party plugin errors, fallback to markdown-only rendering
|
||||||
|
}
|
||||||
|
item.content = mockPost.content
|
||||||
|
|
||||||
|
const codeBlocks = []
|
||||||
|
item.content = item.content.replace(/<hexoPostRenderCodeBlock>([\s\S]*?)<\/hexoPostRenderCodeBlock>/g, (_, c) => {
|
||||||
|
codeBlocks.push(c)
|
||||||
|
return `<!--CODEBLOCK_${codeBlocks.length - 1}-->`
|
||||||
|
})
|
||||||
|
|
||||||
|
try {
|
||||||
|
item.content = hexo.extend.tag.env.renderString(item.content, {})
|
||||||
|
} catch (e) {
|
||||||
|
// ignore tag plugin errors, fallback to markdown-only rendering
|
||||||
|
}
|
||||||
|
|
||||||
item.content = hexo.render.renderSync({ text: item.content, engine: 'markdown' })
|
item.content = hexo.render.renderSync({ text: item.content, engine: 'markdown' })
|
||||||
|
|
||||||
|
item.content = item.content.replace(/<!--CODEBLOCK_(\d+)-->/g, (_, i) => codeBlocks[+i])
|
||||||
})
|
})
|
||||||
|
|
||||||
return processedData
|
return processedData
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ function buildSeriesGroups () {
|
|||||||
groups[p.series].push({
|
groups[p.series].push({
|
||||||
title: p.title,
|
title: p.title,
|
||||||
path: p.path,
|
path: p.path,
|
||||||
date: p.date.unix()
|
date: p.date.valueOf()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -131,6 +131,10 @@ body
|
|||||||
*::-webkit-scrollbar-track
|
*::-webkit-scrollbar-track
|
||||||
background-color: transparent
|
background-color: transparent
|
||||||
|
|
||||||
|
// make the scrollbar transparent when fancybox is open
|
||||||
|
html.with-fancybox
|
||||||
|
--scrollbar-color: transparent
|
||||||
|
|
||||||
input::placeholder
|
input::placeholder
|
||||||
color: var(--font-color)
|
color: var(--font-color)
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,107 @@
|
|||||||
.wl-comment-actions > button:not(last-child)
|
.wl-comment-actions > button:not(last-child)
|
||||||
padding-right: 4px
|
padding-right: 4px
|
||||||
|
|
||||||
|
if hexo-config('artalk.vote')
|
||||||
|
.artalk-vote
|
||||||
|
display: flex
|
||||||
|
justify-content: center
|
||||||
|
align-items: center
|
||||||
|
margin: 4px 0 20px
|
||||||
|
gap: 10px
|
||||||
|
|
||||||
|
.artalk-page-vote-up,
|
||||||
|
.artalk-page-vote-down
|
||||||
|
position: relative
|
||||||
|
display: inline-flex
|
||||||
|
align-items: center
|
||||||
|
overflow: hidden
|
||||||
|
padding: 5px 16px
|
||||||
|
border: 1px solid alpha($theme-color, .15)
|
||||||
|
gap: 6px
|
||||||
|
addBorderRadius(8)
|
||||||
|
background: var(--card-bg)
|
||||||
|
color: var(--font-color)
|
||||||
|
font-weight: 500
|
||||||
|
font-size: .95em
|
||||||
|
cursor: pointer
|
||||||
|
transition: all .2s ease
|
||||||
|
user-select: none
|
||||||
|
|
||||||
|
i,
|
||||||
|
.artalk-page-vote-up-count,
|
||||||
|
.artalk-page-vote-down-count
|
||||||
|
position: relative
|
||||||
|
z-index: 1
|
||||||
|
|
||||||
|
i
|
||||||
|
font-size: 1em
|
||||||
|
line-height: 1
|
||||||
|
|
||||||
|
.artalk-page-vote-up-count,
|
||||||
|
.artalk-page-vote-down-count
|
||||||
|
min-width: 1em
|
||||||
|
text-align: center
|
||||||
|
font-weight: 600
|
||||||
|
font-size: .9em
|
||||||
|
font-variant-numeric: tabular-nums
|
||||||
|
|
||||||
|
&::after
|
||||||
|
position: absolute
|
||||||
|
top: 50%
|
||||||
|
left: 50%
|
||||||
|
z-index: 0
|
||||||
|
width: 8px
|
||||||
|
height: 8px
|
||||||
|
border-radius: 50%
|
||||||
|
content: ''
|
||||||
|
opacity: 0
|
||||||
|
pointer-events: none
|
||||||
|
|
||||||
|
&:hover
|
||||||
|
border-color: $theme-color
|
||||||
|
|
||||||
|
&:active
|
||||||
|
transform: scale(.95)
|
||||||
|
|
||||||
|
&::after
|
||||||
|
animation: artalkVoteRipple .6s ease-out forwards
|
||||||
|
|
||||||
|
.artalk-page-vote-up
|
||||||
|
&:hover,
|
||||||
|
&.active
|
||||||
|
border-color: $theme-color
|
||||||
|
background: alpha($theme-color, .1)
|
||||||
|
color: $theme-color
|
||||||
|
|
||||||
|
&::after
|
||||||
|
background: alpha($theme-color, .5)
|
||||||
|
|
||||||
|
.artalk-page-vote-down
|
||||||
|
&:hover,
|
||||||
|
&.active
|
||||||
|
border-color: $light-red
|
||||||
|
background: alpha($light-red, .1)
|
||||||
|
color: $light-red
|
||||||
|
|
||||||
|
&::after
|
||||||
|
background: alpha($light-red, .5)
|
||||||
|
|
||||||
|
+maxWidth600()
|
||||||
|
gap: 8px
|
||||||
|
|
||||||
|
.artalk-page-vote-up,
|
||||||
|
.artalk-page-vote-down
|
||||||
|
padding: 4px 12px
|
||||||
|
|
||||||
|
@keyframes artalkVoteRipple
|
||||||
|
0%
|
||||||
|
opacity: .8
|
||||||
|
transform: translate(-50%, -50%) scale(0)
|
||||||
|
|
||||||
|
100%
|
||||||
|
opacity: 0
|
||||||
|
transform: translate(-50%, -50%) scale(20)
|
||||||
|
|
||||||
if hexo-config('valine.bg')
|
if hexo-config('valine.bg')
|
||||||
#vcomment
|
#vcomment
|
||||||
textarea
|
textarea
|
||||||
@@ -193,26 +294,6 @@ if hexo-config('math.use')
|
|||||||
right: 0
|
right: 0
|
||||||
bottom: 0
|
bottom: 0
|
||||||
|
|
||||||
.aplayer
|
|
||||||
color: $font-black
|
|
||||||
|
|
||||||
.container
|
|
||||||
.aplayer
|
|
||||||
margin: 0 0 20px
|
|
||||||
|
|
||||||
if hexo-config('beautify.enable')
|
|
||||||
ol,
|
|
||||||
ul
|
|
||||||
margin: 0
|
|
||||||
padding: 0
|
|
||||||
|
|
||||||
li
|
|
||||||
margin: 0
|
|
||||||
padding: 0 15px
|
|
||||||
|
|
||||||
&:before
|
|
||||||
content: none
|
|
||||||
|
|
||||||
.snackbar-container.snackbar-css
|
.snackbar-container.snackbar-css
|
||||||
addBorderRadius(5)
|
addBorderRadius(5)
|
||||||
opacity: .85 !important
|
opacity: .85 !important
|
||||||
|
|||||||
@@ -105,9 +105,6 @@ if hexo-config('darkmode.enable') || hexo-config('display_mode') == 'dark'
|
|||||||
code
|
code
|
||||||
background: $code-background
|
background: $code-background
|
||||||
|
|
||||||
.aplayer
|
|
||||||
filter: brightness(.8)
|
|
||||||
|
|
||||||
kbd
|
kbd
|
||||||
border-color: #696969
|
border-color: #696969
|
||||||
background-color: #525252
|
background-color: #525252
|
||||||
|
|||||||
+43
-38
@@ -267,23 +267,23 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
const fetchUrl = async url => {
|
const fetchUrl = async url => {
|
||||||
try {
|
try {
|
||||||
const response = await fetch(url)
|
const response = await fetch(url)
|
||||||
if (!response.ok) throw new Error(`HTTP ${response.status}`)
|
if (!response.ok) throw new Error(`HTTP ${response.status}`)
|
||||||
return await response.json()
|
return await response.json()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to fetch URL:', error)
|
console.error('Failed to fetch URL:', error)
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const runJustifiedGallery = (container, data, config) => {
|
const runJustifiedGallery = (container, data, config) => {
|
||||||
const { isButton, tabs } = config
|
const { isButton, tabs } = config
|
||||||
const limit = Math.max(1, Number(config.limit) || 20)
|
const limit = Math.max(1, Number(config.limit) || 20)
|
||||||
const firstLimit = Math.max(1, Number(config.firstLimit) || limit)
|
const firstLimit = Math.max(1, Number(config.firstLimit) || limit)
|
||||||
|
|
||||||
const dataLength = data.length
|
const dataLength = data.length
|
||||||
const maxGroupKey = dataLength
|
const maxGroupKey = dataLength
|
||||||
? Math.ceil(Math.max(0, dataLength - firstLimit) / limit) + 1
|
? Math.ceil(Math.max(0, dataLength - firstLimit) / limit) + 1
|
||||||
: 0
|
: 0
|
||||||
|
|
||||||
// Gallery configuration
|
// Gallery configuration
|
||||||
const igConfig = {
|
const igConfig = {
|
||||||
@@ -300,19 +300,19 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
let isLayoutHidden = false
|
let isLayoutHidden = false
|
||||||
|
|
||||||
// Utility functions
|
// Utility functions
|
||||||
const sanitizeString = str => String(str ?? '')
|
const sanitizeString = str => String(str ?? '')
|
||||||
.replace(/&/g, '&')
|
.replace(/&/g, '&')
|
||||||
.replace(/"/g, '"')
|
.replace(/"/g, '"')
|
||||||
.replace(/'/g, ''')
|
.replace(/'/g, ''')
|
||||||
.replace(/</g, '<')
|
.replace(/</g, '<')
|
||||||
.replace(/>/g, '>')
|
.replace(/>/g, '>')
|
||||||
|
|
||||||
const createImageItem = item => {
|
const createImageItem = item => {
|
||||||
const alt = item.alt ? `alt="${sanitizeString(item.alt)}"` : ''
|
const alt = item.alt ? `alt="${sanitizeString(item.alt)}"` : ''
|
||||||
const title = item.title ? `title="${sanitizeString(item.title)}"` : ''
|
const title = item.title ? `title="${sanitizeString(item.title)}"` : ''
|
||||||
const url = item.url ? sanitizeString(item.url) : ''
|
const url = item.url ? sanitizeString(item.url) : ''
|
||||||
return `<div class="item">
|
return `<div class="item">
|
||||||
<img src="${url}" data-grid-maintained-target="true" ${alt} ${title} />
|
<img src="${url}" data-grid-maintained-target="true" ${alt} ${title} />
|
||||||
</div>`
|
</div>`
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -381,13 +381,13 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
btf.setLoading.add(container)
|
btf.setLoading.add(container)
|
||||||
ig.on('renderComplete', handleRenderComplete)
|
ig.on('renderComplete', handleRenderComplete)
|
||||||
|
|
||||||
if (isButton && dataLength) {
|
if (isButton && dataLength) {
|
||||||
appendItems(1, firstLimit, true)
|
appendItems(1, firstLimit, true)
|
||||||
} else if (dataLength) {
|
} else if (dataLength) {
|
||||||
ig.on('requestAppend', handleRequestAppend)
|
ig.on('requestAppend', handleRequestAppend)
|
||||||
ig.renderItems()
|
ig.renderItems()
|
||||||
} else {
|
} else {
|
||||||
btf.setLoading.remove(container)
|
btf.setLoading.remove(container)
|
||||||
}
|
}
|
||||||
|
|
||||||
btf.addGlobalFn('pjaxSendOnce', () => ig.destroy())
|
btf.addGlobalFn('pjaxSendOnce', () => ig.destroy())
|
||||||
@@ -412,9 +412,9 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
container.textContent = ''
|
container.textContent = ''
|
||||||
try {
|
try {
|
||||||
const data = element.getAttribute('data-type') === 'url' ? await fetchUrl(content) : JSON.parse(content)
|
const data = element.getAttribute('data-type') === 'url' ? await fetchUrl(content) : JSON.parse(content)
|
||||||
if (!Array.isArray(data)) throw new TypeError('Gallery data must be an array')
|
if (!Array.isArray(data)) throw new TypeError('Gallery data must be an array')
|
||||||
runJustifiedGallery(container, data, config)
|
runJustifiedGallery(container, data, config)
|
||||||
element.classList.add('loaded')
|
element.classList.add('loaded')
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Gallery data parsing failed:', error)
|
console.error('Gallery data parsing failed:', error)
|
||||||
}
|
}
|
||||||
@@ -456,7 +456,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
|
|
||||||
// 檢查文檔高度是否小於視窗高度
|
// 檢查文檔高度是否小於視窗高度
|
||||||
const checkDocumentHeight = () => {
|
const checkDocumentHeight = () => {
|
||||||
if (document.body.scrollHeight <= window.innerHeight + 56) {
|
if (document.body.scrollHeight <= window.innerHeight + 56) {
|
||||||
$rightside.classList.add('rightside-show')
|
$rightside.classList.add('rightside-show')
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -472,8 +472,8 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
|
|
||||||
let flag = ''
|
let flag = ''
|
||||||
const scrollTask = btf.rafThrottle(() => {
|
const scrollTask = btf.rafThrottle(() => {
|
||||||
if (checkDocumentHeight()) return
|
if (checkDocumentHeight()) return
|
||||||
|
|
||||||
const currentTop = window.scrollY || document.documentElement.scrollTop
|
const currentTop = window.scrollY || document.documentElement.scrollTop
|
||||||
const isDown = scrollDirection(currentTop)
|
const isDown = scrollDirection(currentTop)
|
||||||
if (currentTop > 56) {
|
if (currentTop > 56) {
|
||||||
@@ -501,14 +501,14 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
$header.classList.remove('nav-fixed', 'nav-visible')
|
$header.classList.remove('nav-fixed', 'nav-visible')
|
||||||
}
|
}
|
||||||
$rightside.classList.remove('rightside-show')
|
$rightside.classList.remove('rightside-show')
|
||||||
}
|
}
|
||||||
|
|
||||||
isShowPercent && rightsideScrollPercent(currentTop)
|
isShowPercent && rightsideScrollPercent(currentTop)
|
||||||
})
|
})
|
||||||
|
|
||||||
checkDocumentHeight()
|
checkDocumentHeight()
|
||||||
btf.addEventListenerPjax(window, 'scroll', scrollTask, { passive: true })
|
btf.addEventListenerPjax(window, 'scroll', scrollTask, { passive: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* toc, anchor
|
* toc, anchor
|
||||||
@@ -995,8 +995,11 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
GLOBAL_CONFIG_SITE.pageType === 'home' && scrollDownInIndex()
|
GLOBAL_CONFIG_SITE.pageType === 'home' && scrollDownInIndex()
|
||||||
scrollFn()
|
scrollFn()
|
||||||
|
|
||||||
forPostFn()
|
if (GLOBAL_CONFIG_SITE.pageType !== 'shuoshuo') {
|
||||||
GLOBAL_CONFIG_SITE.pageType !== 'shuoshuo' && btf.switchComments(document)
|
forPostFn()
|
||||||
|
btf.switchComments(document)
|
||||||
|
}
|
||||||
|
|
||||||
openMobileMenu()
|
openMobileMenu()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1012,4 +1015,6 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
fn()
|
fn()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
document.addEventListener('shuoshuo:rendered', forPostFn)
|
||||||
})
|
})
|
||||||
|
|||||||
+5
-3
@@ -243,9 +243,10 @@
|
|||||||
],
|
],
|
||||||
right: ['slideshow', 'thumbs', 'close']
|
right: ['slideshow', 'thumbs', 'close']
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
hideScrollbar: false
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
options = {
|
options = {
|
||||||
Hash: false,
|
Hash: false,
|
||||||
Carousel: {
|
Carousel: {
|
||||||
@@ -274,7 +275,8 @@
|
|||||||
maxScale: 4
|
maxScale: 4
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
hideScrollbar: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user