feat: artalk 支持點擊打開大圖

feat: 設置了隨系統而切換淺色和深色模式後,評論和 mermaind 也會跟隨切換顏色
feat: artalk 最新評論,從 artalk 配置讀取頭像 CDN 和默認頭像
fix: 修復代碼塊在未展開時,點擊複製按鈕,無法複製的 bug
improvement: 代碼和性能優化
improvement: artalk 獲取評論數,由 LoadCountWidget 改為 loadCountWidget
This commit is contained in:
Jerry 2023-05-09 00:36:00 +08:00
parent 52441b6bf5
commit 28d1744b9b
30 changed files with 214 additions and 165 deletions

View File

@ -88,7 +88,7 @@
} }
script. script.
const GLOBAL_CONFIG = { const GLOBAL_CONFIG = {
root: '!{config.root}', root: '!{config.root}',
algolia: !{algolia}, algolia: !{algolia},
localSearch: !{localSearch}, localSearch: !{localSearch},
@ -127,5 +127,6 @@ script.
percent: { percent: {
toc: !{theme.toc.scroll_percent}, toc: !{theme.toc.scroll_percent},
rightside: !{theme.rightside_scroll_percent}, rightside: !{theme.rightside_scroll_percent},
} },
autoDarkmode: !{theme.darkmode.enable && theme.darkmode.autoChangeMode === 1}
} }

View File

@ -1,4 +1,4 @@
if theme.abcjs.enable if theme.abcjs && theme.abcjs.enable
if theme.abcjs.per_page if theme.abcjs.per_page
if is_post() || is_page() if is_post() || is_page()
include ./abcjs.pug include ./abcjs.pug

View File

@ -4,7 +4,7 @@ script.
(() => { (() => {
const getArtalkCount = () => { const getArtalkCount = () => {
const runWidget = () => { const runWidget = () => {
Artalk.LoadCountWidget({ Artalk.loadCountWidget({
server: '!{server}', server: '!{server}',
site: '!{site}', site: '!{site}',
countEl: '.artalk-count' countEl: '.artalk-count'

View File

@ -18,7 +18,7 @@ script.
includeReply: false includeReply: false
}).then(function (res) { }).then(function (res) {
document.querySelectorAll('#recent-posts .twikoo-count').forEach((item,index) => { document.querySelectorAll('#recent-posts .twikoo-count').forEach((item,index) => {
item.innerText = res[index].count item.textContent = res[index].count
}) })
}).catch(function (err) { }).catch(function (err) {
console.log(err) console.log(err)

View File

@ -11,22 +11,35 @@ script.
darkMode: document.documentElement.getAttribute('data-theme') === 'dark', darkMode: document.documentElement.getAttribute('data-theme') === 'dark',
countEl: '.artalk-count' countEl: '.artalk-count'
},!{JSON.stringify(option)})) },!{JSON.stringify(option)}))
if (GLOBAL_CONFIG.lightbox === 'null') return
window.artalkItem.use(ctx => {
ctx.on('list-loaded', () => {
ctx.getCommentList().forEach(comment => {
const $content = comment.getRender().$content
btf.loadLightbox($content.querySelectorAll('img:not([atk-emoticon])'))
})
})
})
} }
if (typeof window.artalkItem === 'object') setTimeout(()=>{initArtalk()},200) if (typeof window.artalkItem === 'object') setTimeout(()=>{initArtalk()},200)
else { else {
getCSS('!{theme.asset.artalk_css}') getCSS('!{theme.asset.artalk_css}').then(()=>{
typeof Artalk !== 'function' ? getScript('!{theme.asset.artalk_js}').then(initArtalk) typeof Artalk !== 'function' ? getScript('!{theme.asset.artalk_js}').then(initArtalk)
: setTimeout(()=>{initArtalk()},200) : setTimeout(()=>{initArtalk()},200)
})
} }
} }
document.getElementById('darkmode').addEventListener('click',()=> { function artalkChangeMode (theme) {
if (typeof window.artalkItem !== 'object') return const artalkWrap = document.getElementById('artalk-wrap')
let isDark = document.documentElement.getAttribute('data-theme') === 'dark' if (!(artalkWrap && artalkWrap.children.length)) return
window.artalkItem.setDarkMode(!isDark) const isDark = theme === 'dark'
}) window.artalkItem.setDarkMode(isDark)
}
btf.addModeChange('artalk', artalkChangeMode)
if ('!{theme.comments.use[0]}' === 'Artalk' || !!{theme.comments.lazyload}) { if ('!{theme.comments.use[0]}' === 'Artalk' || !!{theme.comments.lazyload}) {
if (!{theme.comments.lazyload}) btf.loadComment(document.getElementById('artalk-wrap'), loadArtalk) if (!{theme.comments.lazyload}) btf.loadComment(document.getElementById('artalk-wrap'), loadArtalk)

View File

@ -2,19 +2,21 @@
script. script.
function loadDisqus () { function loadDisqus () {
var disqus_config = function () { const disqus_config = function () {
this.page.url = '!{ page.permalink }' this.page.url = '!{ page.permalink }'
this.page.identifier = '!{ url_for(page.path) }' this.page.identifier = '!{ url_for(page.path) }'
this.page.title = '!{ disqusPageTitle }' this.page.title = '!{ disqusPageTitle }'
}; }
window.disqusReset = () => { const disqusReset = () => {
DISQUS.reset({ DISQUS.reset({
reload: true, reload: true,
config: disqus_config config: disqus_config
}) })
} }
btf.addModeChange('disqus', disqusReset)
if (window.DISQUS) disqusReset() if (window.DISQUS) disqusReset()
else { else {
(function() { (function() {
@ -24,10 +26,6 @@ script.
(d.head || d.body).appendChild(s); (d.head || d.body).appendChild(s);
})(); })();
} }
document.getElementById('darkmode').addEventListener('click', () => {
setTimeout(() => window.disqusReset(), 200)
})
} }
if ('!{theme.comments.use[0]}' === 'Disqus' || !!{theme.comments.lazyload}) { if ('!{theme.comments.use[0]}' === 'Disqus' || !!{theme.comments.lazyload}) {

View File

@ -23,7 +23,7 @@ script.
} }
document.getElementById('darkmode').addEventListener('click', themeChange) btf.addModeChange('disqusjs', themeChange)
if (window.disqusJsLoad) initDisqusjs() if (window.disqusJsLoad) initDisqusjs()
else { else {

View File

@ -22,9 +22,19 @@ script.
ele.setAttribute('crossorigin', 'anonymous') ele.setAttribute('crossorigin', 'anonymous')
ele.setAttribute('id', 'facebook-jssdk') ele.setAttribute('id', 'facebook-jssdk')
document.getElementById('fb-root').insertAdjacentElement('afterbegin',ele) document.getElementById('fb-root').insertAdjacentElement('afterbegin',ele)
} }
} }
function fbModeChange (theme) {
const $fbComment = document.getElementsByClassName('fb-comments')[0]
if ($fbComment && typeof FB === 'object') {
$fbComment.setAttribute('data-colorscheme',theme)
FB.XFBML.parse(document.getElementById('post-comment'))
}
}
btf.addModeChange('facebook_comments', fbModeChange)
if ('!{theme.comments.use[0]}' === 'Facebook Comments' || !!{theme.comments.lazyload}) { if ('!{theme.comments.use[0]}' === 'Facebook Comments' || !!{theme.comments.lazyload}) {
if (!{theme.comments.lazyload}) btf.loadComment(document.querySelector('#post-comment .fb-comments'), loadFBComment) if (!{theme.comments.lazyload}) btf.loadComment(document.querySelector('#post-comment .fb-comments'), loadFBComment)
else loadFBComment() else loadFBComment()

View File

@ -3,8 +3,8 @@
- const giscusOriginUrl = new URL(giscusUrl).origin - const giscusOriginUrl = new URL(giscusUrl).origin
script. script.
function getGiscusTheme () { function getGiscusTheme (theme) {
return document.documentElement.getAttribute('data-theme') === 'dark' ? '!{themes.dark}' : '!{themes.light}' return theme === 'dark' ? '!{themes.dark}' : '!{themes.light}'
} }
function loadGiscus () { function loadGiscus () {
@ -14,7 +14,7 @@ script.
'data-repo-id': '!{repo_id}', 'data-repo-id': '!{repo_id}',
'data-category-id': '!{category_id}', 'data-category-id': '!{category_id}',
'data-mapping': 'pathname', 'data-mapping': 'pathname',
'data-theme': getGiscusTheme(), 'data-theme': getGiscusTheme(document.documentElement.getAttribute('data-theme')),
'data-reactions-enabled': '1', 'data-reactions-enabled': '1',
crossorigin: 'anonymous', crossorigin: 'anonymous',
async: true async: true
@ -27,7 +27,7 @@ script.
document.getElementById('giscus-wrap').insertAdjacentElement('afterbegin',ele) document.getElementById('giscus-wrap').insertAdjacentElement('afterbegin',ele)
} }
function changeGiscusTheme () { function changeGiscusTheme (theme) {
function sendMessage(message) { function sendMessage(message) {
const iframe = document.querySelector('iframe.giscus-frame') const iframe = document.querySelector('iframe.giscus-frame')
if (!iframe) return if (!iframe) return
@ -36,11 +36,13 @@ script.
sendMessage({ sendMessage({
setConfig: { setConfig: {
theme: getGiscusTheme() theme: getGiscusTheme(theme)
} }
}); });
} }
btf.addModeChange('giscus', changeGiscusTheme)
if ('!{theme.comments.use[0]}' === 'Giscus' || !!{theme.comments.lazyload}) { if ('!{theme.comments.use[0]}' === 'Giscus' || !!{theme.comments.lazyload}) {
if (!{theme.comments.lazyload}) btf.loadComment(document.getElementById('giscus-wrap'), loadGiscus) if (!{theme.comments.lazyload}) btf.loadComment(document.getElementById('giscus-wrap'), loadGiscus)
else loadGiscus() else loadGiscus()

View File

@ -24,7 +24,7 @@ script.
function commentCount(n){ function commentCount(n){
let isCommentCount = document.querySelector('#post-meta .gitalk-comment-count') let isCommentCount = document.querySelector('#post-meta .gitalk-comment-count')
if (isCommentCount) { if (isCommentCount) {
isCommentCount.innerHTML= n isCommentCount.textContent= n
} }
} }

View File

@ -51,11 +51,12 @@ script.
} }
} }
document.getElementById('darkmode').addEventListener('click',()=>{ function remarkChangeMode (theme) {
if (!window.REMARK42) return if (!window.REMARK42) return
let theme = document.documentElement.getAttribute('data-theme') === 'dark' ? 'light' : 'dark'
window.REMARK42.changeTheme(theme) window.REMARK42.changeTheme(theme)
}) }
btf.addModeChange('remark42', remarkChangeMode)
if ('!{theme.comments.use[0]}' === 'Remark42' || !!{theme.comments.lazyload}) { if ('!{theme.comments.use[0]}' === 'Remark42' || !!{theme.comments.lazyload}) {
if (!{theme.comments.lazyload}) btf.loadComment(document.getElementById('remark42'), loadRemark42) if (!{theme.comments.lazyload}) btf.loadComment(document.getElementById('remark42'), loadRemark42)

View File

@ -23,7 +23,7 @@ script.
urls: [window.location.pathname], urls: [window.location.pathname],
includeReply: false includeReply: false
}).then(function (res) { }).then(function (res) {
countELement.innerText = res[0].count countELement.textContent = res[0].count
}).catch(function (err) { }).catch(function (err) {
console.error(err); console.error(err);
}); });

View File

@ -12,10 +12,10 @@ script.
document.getElementById('utterances-wrap').insertAdjacentElement('afterbegin',ele) document.getElementById('utterances-wrap').insertAdjacentElement('afterbegin',ele)
} }
function utterancesTheme () { function utterancesTheme (theme) {
const iframe = document.querySelector('.utterances-frame') const iframe = document.querySelector('.utterances-frame')
if (iframe) { if (iframe) {
const theme = document.documentElement.getAttribute('data-theme') === 'dark' ? '#{theme.utterances.dark_theme}' : '#{theme.utterances.light_theme}' const theme = theme === 'dark' ? '#{theme.utterances.dark_theme}' : '#{theme.utterances.light_theme}'
const message = { const message = {
type: 'set-theme', type: 'set-theme',
theme: theme theme: theme
@ -24,6 +24,8 @@ script.
} }
} }
btf.addModeChange('utterances', utterancesTheme)
if ('!{theme.comments.use[0]}' === 'Utterances' || !!{theme.comments.lazyload}) { if ('!{theme.comments.use[0]}' === 'Utterances' || !!{theme.comments.lazyload}) {
if (!{theme.comments.lazyload}) btf.loadComment(document.getElementById('utterances-wrap'), loadUtterances) if (!{theme.comments.lazyload}) btf.loadComment(document.getElementById('utterances-wrap'), loadUtterances)
else loadUtterances() else loadUtterances()

View File

@ -21,6 +21,10 @@ script.
window.loadMermaid ? runMermaid() : getScript('!{url_for(theme.asset.mermaid)}').then(runMermaid) window.loadMermaid ? runMermaid() : getScript('!{url_for(theme.asset.mermaid)}').then(runMermaid)
} }
btf.addModeChange('mermaid', () => {
window.runMermaid()
})
window.pjax ? loadMermaid() : document.addEventListener('DOMContentLoaded', loadMermaid) window.pjax ? loadMermaid() : document.addEventListener('DOMContentLoaded', loadMermaid)
} }
})() })()

View File

@ -1,6 +1,6 @@
- const { server, site, option } = theme.artalk - const { server, site, option } = theme.artalk
- const avatarCdn = option !== null && option.gravatar ? option.gravatar.mirror : 'https://sdn.geekzu.org/avatar/' - const avatarCdn = option !== null && option.gravatar && option.gravatar.mirror
- const avatarDefault = option !== null && option.gravatar ? option.gravatar.default : 'mp' - const avatarDefault = option !== null && option.gravatar && option.gravatar.default
script. script.
window.addEventListener('load', () => { window.addEventListener('load', () => {
@ -45,6 +45,15 @@ script.
window.pjax && window.pjax.refresh($dom) window.pjax && window.pjax.refresh($dom)
} }
const getSetting = async () => {
try {
const res = await fetch('!{server}/api/conf', { method: 'GET' })
return await res.json()
} catch (e) {
console.log(e)
}
}
const headerList = { const headerList = {
method: 'POST', method: 'POST',
headers: { headers: {
@ -58,25 +67,29 @@ script.
}) })
} }
const getComment = () => { const getComment = async () => {
fetch('!{server}/api/stat', headerList) try {
.then(response => response.json()) const res = await fetch('!{server}/api/stat', headerList)
.then(d => { const result = await res.json()
const artalk = d.data.map(function (e) { const avatarStr = await getSetting()
return { const avatarCdn = !{avatarCdn} || avatarStr.data.frontend_conf.gravatar.mirror
'avatar': '!{avatarCdn}' + e.email_encrypted + '?d=!{avatarDefault}', const avatarDefault = !{avatarDefault} || avatarStr.data.frontend_conf.gravatar.default
'content': changeContent(e.content_marked), const artalk = result.data.map(function (e) {
'nick': e.nick, return {
'url': e.page_url, 'avatar': `${avatarCdn}${e.email_encrypted}?d=${avatarDefault}`,
'date': e.date, 'content': changeContent(e.content_marked),
} 'nick': e.nick,
}) 'url': e.page_url,
saveToLocal.set('artalk-newest-comments', JSON.stringify(artalk), !{theme.newest_comments.storage}/(60*24)) 'date': e.date,
generateHtml(artalk) }
}).catch(e => {
const $dom = document.querySelector('#card-newest-comments .aside-list')
$dom.innerHTML= "!{_p('aside.card_newest_comments.error')}"
}) })
saveToLocal.set('artalk-newest-comments', JSON.stringify(artalk), !{theme.newest_comments.storage}/(60*24))
generateHtml(artalk)
} catch (e) {
console.log(e)
const $dom = document.querySelector('#card-newest-comments .aside-list')
$dom.innerHTML= "!{_p('aside.card_newest_comments.error')}"
}
} }
const newestCommentInit = () => { const newestCommentInit = () => {

View File

@ -32,7 +32,7 @@ script.
generateHtml(disqusArray) generateHtml(disqusArray)
}).catch(e => { }).catch(e => {
const $dom = document.querySelector('#card-newest-comments .aside-list') const $dom = document.querySelector('#card-newest-comments .aside-list')
$dom.innerHTML= "!{_p('aside.card_newest_comments.error')}" $dom.textContent= "!{_p('aside.card_newest_comments.error')}"
}) })
} }

View File

@ -58,7 +58,7 @@ script.
findTrueUrl(githubArray) findTrueUrl(githubArray)
}).catch(e => { }).catch(e => {
const $dom = document.querySelector('#card-newest-comments .aside-list') const $dom = document.querySelector('#card-newest-comments .aside-list')
$dom.innerHTML= "!{_p('aside.card_newest_comments.error')}" $dom.textContent= "!{_p('aside.card_newest_comments.error')}"
}) })
} }

View File

@ -60,7 +60,7 @@ script.
generateHtml(remark42) generateHtml(remark42)
}).catch(e => { }).catch(e => {
const $dom = document.querySelector('#card-newest-comments .aside-list') const $dom = document.querySelector('#card-newest-comments .aside-list')
$dom.innerHTML= "!{_p('aside.card_newest_comments.error')}" $dom.textContent= "!{_p('aside.card_newest_comments.error')}"
}) })
} }

View File

@ -36,7 +36,7 @@ script.
generateHtml(twikooArray) generateHtml(twikooArray)
}).catch(function (err) { }).catch(function (err) {
const $dom = document.querySelector('#card-newest-comments .aside-list') const $dom = document.querySelector('#card-newest-comments .aside-list')
$dom.innerHTML= "!{_p('aside.card_newest_comments.error')}" $dom.textContent= "!{_p('aside.card_newest_comments.error')}"
}) })
} }

View File

@ -79,7 +79,7 @@ script.
generateHtml(valineArray) generateHtml(valineArray)
}).catch(e => { }).catch(e => {
const $dom = document.querySelector('#card-newest-comments .aside-list') const $dom = document.querySelector('#card-newest-comments .aside-list')
$dom.innerHTML= "!{_p('aside.card_newest_comments.error')}" $dom.textContent= "!{_p('aside.card_newest_comments.error')}"
}) })
} }

View File

@ -60,7 +60,7 @@ script.
generateHtml(walineArray) generateHtml(walineArray)
}).catch(e => { }).catch(e => {
const $dom = document.querySelector('#card-newest-comments .aside-list') const $dom = document.querySelector('#card-newest-comments .aside-list')
$dom.innerHTML= "!{_p('aside.card_newest_comments.error')}" $dom.textContent= "!{_p('aside.card_newest_comments.error')}"
}) })
} }

View File

@ -38,7 +38,7 @@ case source
sub.unshift(data.hitokoto, from) sub.unshift(data.hitokoto, from)
typedJSFn.init(sub) typedJSFn.init(sub)
} else { } else {
document.getElementById('subtitle').innerHTML = data.hitokoto document.getElementById('subtitle').textContent = data.hitokoto
} }
}) })
} }
@ -55,7 +55,7 @@ case source
sub.unshift(con, from) sub.unshift(con, from)
typedJSFn.init(sub) typedJSFn.init(sub)
} else { } else {
document.getElementById('subtitle').innerHTML = con document.getElementById('subtitle').textContent = con
} }
}) })
} }
@ -72,7 +72,7 @@ case source
sub.unshift(content) sub.unshift(content)
typedJSFn.init(sub) typedJSFn.init(sub)
} else { } else {
document.getElementById('subtitle').innerHTML = result.data.content document.getElementById('subtitle').textContent = result.data.content
} }
}) })
}) })
@ -86,7 +86,7 @@ case source
if (!{effect}) { if (!{effect}) {
typedJSFn.init(!{JSON.stringify(subContent)}) typedJSFn.init(!{JSON.stringify(subContent)})
} else { } else {
document.getElementById("subtitle").innerHTML = '!{subContent[0]}' document.getElementById("subtitle").textContent = '!{subContent[0]}'
} }
} }
typedJSFn.run(subtitleType) typedJSFn.run(subtitleType)

View File

@ -1,6 +1,6 @@
{ {
"name": "hexo-theme-butterfly", "name": "hexo-theme-butterfly",
"version": "4.8.1", "version": "4.8.5",
"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": {

View File

@ -5,7 +5,7 @@ algolia_search:
instantsearch: instantsearch:
name: instantsearch.js name: instantsearch.js
file: dist/instantsearch.production.min.js file: dist/instantsearch.production.min.js
version: 4.54.0 version: 4.55.0
pjax: pjax:
name: pjax name: pjax
file: pjax.min.js file: pjax.min.js
@ -37,17 +37,17 @@ disqusjs_css:
twikoo: twikoo:
name: twikoo name: twikoo
file: dist/twikoo.all.min.js file: dist/twikoo.all.min.js
version: 1.6.14 version: 1.6.16
waline_js: waline_js:
name: '@waline/client' name: '@waline/client'
file: dist/waline.js file: dist/waline.js
other_name: waline other_name: waline
version: 2.14.9 version: 2.15.4
waline_css: waline_css:
name: '@waline/client' name: '@waline/client'
file: dist/waline.css file: dist/waline.css
other_name: waline other_name: waline
version: 2.14.9 version: 2.15.4
sharejs: sharejs:
name: butterfly-extsrc name: butterfly-extsrc
file: sharejs/dist/js/social-share.min.js file: sharejs/dist/js/social-share.min.js
@ -64,12 +64,12 @@ katex:
name: katex name: katex
file: dist/katex.min.css file: dist/katex.min.css
other_name: KaTeX other_name: KaTeX
version: 0.16.4 version: 0.16.7
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.16.4 version: 0.16.7
mermaid: mermaid:
name: mermaid name: mermaid
file: dist/mermaid.min.js file: dist/mermaid.min.js
@ -113,7 +113,7 @@ instantpage:
typed: typed:
name: typed.js name: typed.js
file: dist/typed.umd.js file: dist/typed.umd.js
version: 2.0.15 version: 2.0.16
pangu: pangu:
name: pangu name: pangu
file: dist/browser/pangu.min.js file: dist/browser/pangu.min.js
@ -121,12 +121,12 @@ pangu:
fancybox_css: fancybox_css:
name: '@fancyapps/ui' name: '@fancyapps/ui'
file: dist/fancybox/fancybox.css file: dist/fancybox/fancybox.css
version: 5.0.15 version: 5.0.17
other_name: fancyapps-ui other_name: fancyapps-ui
fancybox: fancybox:
name: '@fancyapps/ui' name: '@fancyapps/ui'
file: dist/fancybox/fancybox.umd.js file: dist/fancybox/fancybox.umd.js
version: 5.0.15 version: 5.0.17
other_name: fancyapps-ui other_name: fancyapps-ui
medium_zoom: medium_zoom:
name: medium-zoom name: medium-zoom
@ -202,13 +202,13 @@ 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: 3.3.3 version: 3.3.4
docsearch_css: 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: 3.3.3 version: 3.3.4
abcjs_basic_js: abcjs_basic_js:
name: abcjs name: abcjs
file: dist/abcjs-basic-min.js file: dist/abcjs-basic-min.js
version: 6.2.0 version: 6.2.2

View File

@ -174,9 +174,6 @@ if $site-name-font
.is-center .is-center
text-align: center text-align: center
.copy-true
user-select: all
.pull-left .pull-left
float: left float: left

View File

@ -75,6 +75,14 @@ $code-block
&:hover &:hover
border-bottom-color: var(--hl-color) border-bottom-color: var(--hl-color)
&.copy-true
user-select: all
& > table,
& > pre
display: block !important
opacity: 0
.highlight-tools .highlight-tools
position: relative position: relative
display: flex display: flex

View File

@ -70,28 +70,17 @@ document.addEventListener('DOMContentLoaded', function () {
const highLight = GLOBAL_CONFIG.highlight const highLight = GLOBAL_CONFIG.highlight
if (!highLight) return if (!highLight) return
const isHighlightCopy = highLight.highlightCopy const { highlightCopy, highlightLang, highlightHeightLimit, plugin } = highLight
const isHighlightLang = highLight.highlightLang
const isHighlightShrink = GLOBAL_CONFIG_SITE.isHighlightShrink const isHighlightShrink = GLOBAL_CONFIG_SITE.isHighlightShrink
const highlightHeightLimit = highLight.highlightHeightLimit const isShowTool = highlightCopy || highlightLang || isHighlightShrink !== undefined
const isShowTool = isHighlightCopy || isHighlightLang || isHighlightShrink !== undefined const $figureHighlight = plugin === 'highlighjs' ? document.querySelectorAll('figure.highlight') : document.querySelectorAll('pre[class*="language-"]')
const $figureHighlight = highLight.plugin === 'highlighjs' ? document.querySelectorAll('figure.highlight') : document.querySelectorAll('pre[class*="language-"]')
if (!((isShowTool || highlightHeightLimit) && $figureHighlight.length)) return if (!((isShowTool || highlightHeightLimit) && $figureHighlight.length)) return
const isPrismjs = highLight.plugin === 'prismjs' const isPrismjs = plugin === 'prismjs'
let highlightShrinkEle = ''
let highlightCopyEle = ''
const highlightShrinkClass = isHighlightShrink === true ? 'closed' : '' const highlightShrinkClass = isHighlightShrink === true ? 'closed' : ''
const highlightShrinkEle = isHighlightShrink !== undefined ? `<i class="fas fa-angle-down expand ${highlightShrinkClass}"></i>` : ''
if (isHighlightShrink !== undefined) { const highlightCopyEle = highlightCopy ? '<div class="copy-notice"></div><i class="fas fa-paste copy-button"></i>' : ''
highlightShrinkEle = `<i class="fas fa-angle-down expand ${highlightShrinkClass}"></i>`
}
if (isHighlightCopy) {
highlightCopyEle = '<div class="copy-notice"></div><i class="fas fa-paste copy-button"></i>'
}
const copy = (text, ctx) => { const copy = (text, ctx) => {
if (document.queryCommandSupported && document.queryCommandSupported('copy')) { if (document.queryCommandSupported && document.queryCommandSupported('copy')) {
@ -100,7 +89,7 @@ document.addEventListener('DOMContentLoaded', function () {
btf.snackbarShow(GLOBAL_CONFIG.copy.success) btf.snackbarShow(GLOBAL_CONFIG.copy.success)
} else { } else {
const prevEle = ctx.previousElementSibling const prevEle = ctx.previousElementSibling
prevEle.innerText = GLOBAL_CONFIG.copy.success prevEle.textContent = GLOBAL_CONFIG.copy.success
prevEle.style.opacity = 1 prevEle.style.opacity = 1
setTimeout(() => { prevEle.style.opacity = 0 }, 700) setTimeout(() => { prevEle.style.opacity = 0 }, 700)
} }
@ -108,7 +97,7 @@ document.addEventListener('DOMContentLoaded', function () {
if (GLOBAL_CONFIG.Snackbar !== undefined) { if (GLOBAL_CONFIG.Snackbar !== undefined) {
btf.snackbarShow(GLOBAL_CONFIG.copy.noSupport) btf.snackbarShow(GLOBAL_CONFIG.copy.noSupport)
} else { } else {
ctx.previousElementSibling.innerText = GLOBAL_CONFIG.copy.noSupport ctx.previousElementSibling.textContent = GLOBAL_CONFIG.copy.noSupport
} }
} }
} }
@ -119,8 +108,8 @@ document.addEventListener('DOMContentLoaded', function () {
$buttonParent.classList.add('copy-true') $buttonParent.classList.add('copy-true')
const selection = window.getSelection() const selection = window.getSelection()
const range = document.createRange() const range = document.createRange()
if (isPrismjs) range.selectNodeContents($buttonParent.querySelectorAll('pre code')[0]) const preCodeSelector = isPrismjs ? 'pre code' : 'table .code pre'
else range.selectNodeContents($buttonParent.querySelectorAll('table .code pre')[0]) range.selectNodeContents($buttonParent.querySelectorAll(`${preCodeSelector}`)[0])
selection.removeAllRanges() selection.removeAllRanges()
selection.addRange(range) selection.addRange(range)
const text = selection.toString() const text = selection.toString()
@ -175,33 +164,29 @@ document.addEventListener('DOMContentLoaded', function () {
} }
} }
if (isHighlightLang) { if (isPrismjs) {
if (isPrismjs) { $figureHighlight.forEach(item => {
$figureHighlight.forEach(function (item) { if (highlightLang) {
const langName = item.getAttribute('data-language') ? item.getAttribute('data-language') : 'Code' const langName = item.getAttribute('data-language') || 'Code'
const highlightLangEle = `<div class="code-lang">${langName}</div>` const highlightLangEle = `<div class="code-lang">${langName}</div>`
btf.wrap(item, 'figure', { class: 'highlight' }) btf.wrap(item, 'figure', { class: 'highlight' })
createEle(highlightLangEle, item) createEle(highlightLangEle, item)
}) } else {
} else { btf.wrap(item, 'figure', { class: 'highlight' })
$figureHighlight.forEach(function (item) { createEle('', item)
}
})
} else {
$figureHighlight.forEach(function (item) {
if (highlightLang) {
let langName = item.getAttribute('class').split(' ')[1] let langName = item.getAttribute('class').split(' ')[1]
if (langName === 'plain' || langName === undefined) langName = 'Code' if (langName === 'plain' || langName === undefined) langName = 'Code'
const highlightLangEle = `<div class="code-lang">${langName}</div>` const highlightLangEle = `<div class="code-lang">${langName}</div>`
createEle(highlightLangEle, item, 'hl') createEle(highlightLangEle, item, 'hl')
}) } else {
}
} else {
if (isPrismjs) {
$figureHighlight.forEach(function (item) {
btf.wrap(item, 'figure', { class: 'highlight' })
createEle('', item)
})
} else {
$figureHighlight.forEach(function (item) {
createEle('', item, 'hl') createEle('', item, 'hl')
}) }
} })
} }
} }
@ -313,6 +298,12 @@ document.addEventListener('DOMContentLoaded', function () {
const scrollFn = function () { const scrollFn = function () {
const $rightside = document.getElementById('rightside') const $rightside = document.getElementById('rightside')
const innerHeight = window.innerHeight + 56 const innerHeight = window.innerHeight + 56
let initTop = 0
let isChatShow = true
const $header = document.getElementById('page-header')
const isChatBtnHide = typeof chatBtnHide === 'function'
const isChatBtnShow = typeof chatBtnShow === 'function'
const isShowPercent = GLOBAL_CONFIG.percent.rightside
// 當滾動條小于 56 的時候 // 當滾動條小于 56 的時候
if (document.body.scrollHeight <= innerHeight) { if (document.body.scrollHeight <= innerHeight) {
@ -321,19 +312,12 @@ document.addEventListener('DOMContentLoaded', function () {
} }
// find the scroll direction // find the scroll direction
function scrollDirection (currentTop) { const scrollDirection = currentTop => {
const result = currentTop > initTop // true is down & false is up const result = currentTop > initTop // true is down & false is up
initTop = currentTop initTop = currentTop
return result return result
} }
let initTop = 0
let isChatShow = true
const $header = document.getElementById('page-header')
const isChatBtnHide = typeof chatBtnHide === 'function'
const isChatBtnShow = typeof chatBtnShow === 'function'
const isShowPercent = GLOBAL_CONFIG.percent.rightside
const scrollTask = btf.throttle(() => { const scrollTask = btf.throttle(() => {
const currentTop = window.scrollY || document.documentElement.scrollTop const currentTop = window.scrollY || document.documentElement.scrollTop
const isDown = scrollDirection(currentTop) const isDown = scrollDirection(currentTop)
@ -492,6 +476,22 @@ document.addEventListener('DOMContentLoaded', function () {
window.addEventListener('scroll', tocScrollFn) window.addEventListener('scroll', tocScrollFn)
} }
const modeChangeFn = mode => {
if (!window.themeChange) {
return
}
const turnMode = item => window.themeChange[item](mode)
Object.keys(window.themeChange).forEach(item => {
if (['disqus', 'disqusjs'].includes(item)) {
setTimeout(() => turnMode(item), 300)
} else {
turnMode(item)
}
})
}
/** /**
* Rightside * Rightside
*/ */
@ -504,7 +504,7 @@ document.addEventListener('DOMContentLoaded', function () {
newEle.className = 'fas fa-sign-out-alt exit-readmode' newEle.className = 'fas fa-sign-out-alt exit-readmode'
$body.appendChild(newEle) $body.appendChild(newEle)
function clickFn () { const clickFn = () => {
$body.classList.remove('read-mode') $body.classList.remove('read-mode')
newEle.remove() newEle.remove()
newEle.removeEventListener('click', clickFn) newEle.removeEventListener('click', clickFn)
@ -513,8 +513,8 @@ document.addEventListener('DOMContentLoaded', function () {
newEle.addEventListener('click', clickFn) newEle.addEventListener('click', clickFn)
}, },
switchDarkMode: () => { // Switch Between Light And Dark Mode switchDarkMode: () => { // Switch Between Light And Dark Mode
const nowMode = document.documentElement.getAttribute('data-theme') === 'dark' ? 'dark' : 'light' const willChangeMode = document.documentElement.getAttribute('data-theme') === 'dark' ? 'light' : 'dark'
if (nowMode === 'light') { if (willChangeMode === 'dark') {
activateDarkMode() activateDarkMode()
saveToLocal.set('theme', 'dark', 2) saveToLocal.set('theme', 'dark', 2)
GLOBAL_CONFIG.Snackbar !== undefined && btf.snackbarShow(GLOBAL_CONFIG.Snackbar.day_to_night) GLOBAL_CONFIG.Snackbar !== undefined && btf.snackbarShow(GLOBAL_CONFIG.Snackbar.day_to_night)
@ -523,11 +523,7 @@ document.addEventListener('DOMContentLoaded', function () {
saveToLocal.set('theme', 'light', 2) saveToLocal.set('theme', 'light', 2)
GLOBAL_CONFIG.Snackbar !== undefined && btf.snackbarShow(GLOBAL_CONFIG.Snackbar.night_to_day) GLOBAL_CONFIG.Snackbar !== undefined && btf.snackbarShow(GLOBAL_CONFIG.Snackbar.night_to_day)
} }
// handle some cases modeChangeFn(willChangeMode)
typeof utterancesTheme === 'function' && utterancesTheme()
typeof changeGiscusTheme === 'function' && changeGiscusTheme()
typeof FB === 'object' && window.loadFBComment && window.loadFBComment()
typeof runMermaid === 'function' && window.runMermaid()
}, },
showOrHideBtn: (e) => { // rightside 點擊設置 按鈕 展開 showOrHideBtn: (e) => { // rightside 點擊設置 按鈕 展開
const rightsideHideClassList = document.getElementById('rightside-config-hide').classList const rightsideHideClassList = document.getElementById('rightside-config-hide').classList
@ -545,9 +541,8 @@ document.addEventListener('DOMContentLoaded', function () {
}, },
hideAsideBtn: () => { // Hide aside hideAsideBtn: () => { // Hide aside
const $htmlDom = document.documentElement.classList const $htmlDom = document.documentElement.classList
$htmlDom.contains('hide-aside') const saveStatus = $htmlDom.contains('hide-aside') ? 'show' : 'hide'
? saveToLocal.set('aside-status', 'show', 2) saveToLocal.set('aside-status', saveStatus, 2)
: saveToLocal.set('aside-status', 'hide', 2)
$htmlDom.toggle('hide-aside') $htmlDom.toggle('hide-aside')
}, },
@ -596,21 +591,16 @@ document.addEventListener('DOMContentLoaded', function () {
} }
/** /**
* 複製時加上版權信息 * 複製時加上版權信息
*/ */
const addCopyright = () => { const addCopyright = () => {
const copyright = GLOBAL_CONFIG.copyright const copyright = GLOBAL_CONFIG.copyright
document.body.oncopy = (e) => { document.body.oncopy = (e) => {
e.preventDefault() e.preventDefault()
let textFont; const copyFont = window.getSelection(0).toString() const copyFont = window.getSelection(0).toString()
let textFont = copyFont
if (copyFont.length > copyright.limitCount) { if (copyFont.length > copyright.limitCount) {
textFont = copyFont + '\n' + '\n' + '\n' + textFont = `${copyFont}\n\n\n${copyright.languages.author}\n${copyright.languages.link}${window.location.href}\n${copyright.languages.source}\n${copyright.languages.info}`
copyright.languages.author + '\n' +
copyright.languages.link + window.location.href + '\n' +
copyright.languages.source + '\n' +
copyright.languages.info
} else {
textFont = copyFont
} }
if (e.clipboardData) { if (e.clipboardData) {
return e.clipboardData.setData('text', textFont) return e.clipboardData.setData('text', textFont)
@ -627,7 +617,7 @@ document.addEventListener('DOMContentLoaded', function () {
const $runtimeCount = document.getElementById('runtimeshow') const $runtimeCount = document.getElementById('runtimeshow')
if ($runtimeCount) { if ($runtimeCount) {
const publishDate = $runtimeCount.getAttribute('data-publishDate') const publishDate = $runtimeCount.getAttribute('data-publishDate')
$runtimeCount.innerText = btf.diffDate(publishDate) + ' ' + GLOBAL_CONFIG.runtime $runtimeCount.textContent = `${btf.diffDate(publishDate)} ${GLOBAL_CONFIG.runtime}`
} }
} }
@ -638,7 +628,7 @@ document.addEventListener('DOMContentLoaded', function () {
const $lastPushDateItem = document.getElementById('last-push-date') const $lastPushDateItem = document.getElementById('last-push-date')
if ($lastPushDateItem) { if ($lastPushDateItem) {
const lastPushDate = $lastPushDateItem.getAttribute('data-lastPushDate') const lastPushDate = $lastPushDateItem.getAttribute('data-lastPushDate')
$lastPushDateItem.innerText = btf.diffDate(lastPushDate, true) $lastPushDateItem.textContent = btf.diffDate(lastPushDate, true)
} }
} }
@ -771,10 +761,9 @@ document.addEventListener('DOMContentLoaded', function () {
const relativeDate = function (selector) { const relativeDate = function (selector) {
selector.forEach(item => { selector.forEach(item => {
const $this = item const timeVal = item.getAttribute('datetime')
const timeVal = $this.getAttribute('datetime') item.textContent = btf.diffDate(timeVal, true)
$this.innerText = btf.diffDate(timeVal, true) item.style.display = 'inline'
$this.style.display = 'inline'
}) })
} }
@ -789,6 +778,13 @@ document.addEventListener('DOMContentLoaded', function () {
clickFnOfSubMenu() clickFnOfSubMenu()
GLOBAL_CONFIG.islazyload && lazyloadImg() GLOBAL_CONFIG.islazyload && lazyloadImg()
GLOBAL_CONFIG.copyright !== undefined && addCopyright() GLOBAL_CONFIG.copyright !== undefined && addCopyright()
if (GLOBAL_CONFIG.autoDarkmode) {
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => {
if (saveToLocal.get('theme') !== undefined) return
e.matches ? modeChangeFn('dark') : modeChangeFn('light')
})
}
} }
window.refreshFn = function () { window.refreshFn = function () {

View File

@ -282,7 +282,7 @@ window.addEventListener('load', () => {
window.pjax && window.pjax.refresh(container) window.pjax && window.pjax.refresh(container)
} }
$loadingStatus.innerHTML = '' $loadingStatus.textContent = ''
} }
let loadFlag = false let loadFlag = false

View File

@ -1,10 +1,6 @@
document.addEventListener('DOMContentLoaded', function () { document.addEventListener('DOMContentLoaded', function () {
const translate = GLOBAL_CONFIG.translate const { defaultEncoding, translateDelay, msgToTraditionalChinese, msgToSimplifiedChinese } = GLOBAL_CONFIG.translate
const snackbarData = GLOBAL_CONFIG.Snackbar const snackbarData = GLOBAL_CONFIG.Snackbar
const defaultEncoding = translate.defaultEncoding // 網站默認語言1: 繁體中文, 2: 簡體中文
const translateDelay = translate.translateDelay // 延遲時間,若不在前, 要設定延遲翻譯時間, 如100表示100ms,默認為0
const msgToTraditionalChinese = translate.msgToTraditionalChinese // 此處可以更改為你想要顯示的文字
const msgToSimplifiedChinese = translate.msgToSimplifiedChinese // 同上,但兩處均不建議更改
let currentEncoding = defaultEncoding let currentEncoding = defaultEncoding
const targetEncodingCookie = 'translate-chn-cht' const targetEncodingCookie = 'translate-chn-cht'
let targetEncoding = let targetEncoding =
@ -12,7 +8,7 @@ document.addEventListener('DOMContentLoaded', function () {
? defaultEncoding ? defaultEncoding
: Number(saveToLocal.get('translate-chn-cht')) : Number(saveToLocal.get('translate-chn-cht'))
let translateButtonObject let translateButtonObject
const isSnackbar = GLOBAL_CONFIG.Snackbar !== undefined const isSnackbar = snackbarData !== undefined
function setLang () { function setLang () {
document.documentElement.lang = targetEncoding === 1 ? 'zh-TW' : 'zh-CN' document.documentElement.lang = targetEncoding === 1 ? 'zh-TW' : 'zh-CN'
@ -58,12 +54,12 @@ document.addEventListener('DOMContentLoaded', function () {
if (targetEncoding === 1) { if (targetEncoding === 1) {
currentEncoding = 1 currentEncoding = 1
targetEncoding = 2 targetEncoding = 2
translateButtonObject.innerHTML = msgToTraditionalChinese translateButtonObject.textContent = msgToTraditionalChinese
isSnackbar && btf.snackbarShow(snackbarData.cht_to_chs) isSnackbar && btf.snackbarShow(snackbarData.cht_to_chs)
} else if (targetEncoding === 2) { } else if (targetEncoding === 2) {
currentEncoding = 2 currentEncoding = 2
targetEncoding = 1 targetEncoding = 1
translateButtonObject.innerHTML = msgToSimplifiedChinese translateButtonObject.textContent = msgToSimplifiedChinese
isSnackbar && btf.snackbarShow(snackbarData.chs_to_cht) isSnackbar && btf.snackbarShow(snackbarData.chs_to_cht)
} }
saveToLocal.set(targetEncodingCookie, targetEncoding, 2) saveToLocal.set(targetEncodingCookie, targetEncoding, 2)
@ -104,7 +100,7 @@ document.addEventListener('DOMContentLoaded', function () {
translateButtonObject = document.getElementById('translateLink') translateButtonObject = document.getElementById('translateLink')
if (translateButtonObject) { if (translateButtonObject) {
if (currentEncoding !== targetEncoding) { if (currentEncoding !== targetEncoding) {
translateButtonObject.innerHTML = translateButtonObject.textContent =
targetEncoding === 1 targetEncoding === 1
? msgToSimplifiedChinese ? msgToSimplifiedChinese
: msgToTraditionalChinese : msgToTraditionalChinese

View File

@ -302,5 +302,13 @@ const btf = {
const scrollPercentRounded = Math.round(scrollPercent * 100) const scrollPercentRounded = Math.round(scrollPercent * 100)
const percentage = (scrollPercentRounded > 100) ? 100 : (scrollPercentRounded <= 0) ? 0 : scrollPercentRounded const percentage = (scrollPercentRounded > 100) ? 100 : (scrollPercentRounded <= 0) ? 0 : scrollPercentRounded
return percentage return percentage
},
addModeChange: (name, fn) => {
if (window.themeChange && window.themeChange[name]) return
window.themeChange = {
...window.themeChange,
[name]: fn
}
} }
} }