mirror of
https://github.com/jerryc127/hexo-theme-butterfly.git
synced 2026-04-12 22:17:06 +08:00
Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f9aca1cb86 | ||
|
|
0c7b406103 | ||
|
|
fb4ab20169 | ||
|
|
d10841f289 | ||
|
|
7b6a386a14 | ||
|
|
f91ce41a66 | ||
|
|
d7bfcf36c9 | ||
|
|
3704dae397 | ||
|
|
c72f8c41ec | ||
|
|
95ca6878f0 | ||
|
|
3d7a033721 | ||
|
|
90b4511193 | ||
|
|
e65481ecbd | ||
|
|
9398cf5190 | ||
|
|
0f87df3b3a | ||
|
|
f62d76046d | ||
|
|
975134fb14 |
@@ -86,7 +86,7 @@ npm i hexo-theme-butterfly
|
|||||||
- [x] Share (Sharejs/Addtoany)
|
- [x] Share (Sharejs/Addtoany)
|
||||||
- [X] Comment (Disqus/Disqusjs/Livere/Gitalk/Valine/Waline/Utterances/Facebook Comments/Twikoo/Giscus/Remark42/artalk)
|
- [X] Comment (Disqus/Disqusjs/Livere/Gitalk/Valine/Waline/Utterances/Facebook Comments/Twikoo/Giscus/Remark42/artalk)
|
||||||
- [x] Multiple Comment System Support
|
- [x] Multiple Comment System Support
|
||||||
- [x] Online Chats (Chatra/Tidio/Daovoice/Crisp)
|
- [x] Online Chats (Chatra/Tidio/Crisp)
|
||||||
- [x] Web analytics
|
- [x] Web analytics
|
||||||
- [x] Google AdSense
|
- [x] Google AdSense
|
||||||
- [x] Webmaster Verification
|
- [x] Webmaster Verification
|
||||||
@@ -98,6 +98,7 @@ npm i hexo-theme-butterfly
|
|||||||
- [x] Busuanzi visitor counter
|
- [x] Busuanzi visitor counter
|
||||||
- [x] Medium Zoom/Fancybox
|
- [x] Medium Zoom/Fancybox
|
||||||
- [x] Mermaid
|
- [x] Mermaid
|
||||||
|
- [x] Chart.js
|
||||||
- [x] Justified Gallery
|
- [x] Justified Gallery
|
||||||
- [x] Lazyload images
|
- [x] Lazyload images
|
||||||
- [x] Instantpage/Pangu/Snackbar notification toast/PWA......
|
- [x] Instantpage/Pangu/Snackbar notification toast/PWA......
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ theme: butterfly
|
|||||||
- [x] 多種分享系統(Sharejs/Addtoany)
|
- [x] 多種分享系統(Sharejs/Addtoany)
|
||||||
- [X] 多種評論系統(Disqus/Disqusjs/Livere/Gitalk/Valine/Waline/Utterances/Facebook Comments/Twikoo/Giscus/Remark42/artalk)
|
- [X] 多種評論系統(Disqus/Disqusjs/Livere/Gitalk/Valine/Waline/Utterances/Facebook Comments/Twikoo/Giscus/Remark42/artalk)
|
||||||
- [x] 支持雙評論部署
|
- [x] 支持雙評論部署
|
||||||
- [x] 多種在線聊天(Chatra/Tidio/Daovoice/Crisp)
|
- [x] 多種在線聊天(Chatra/Tidio/Crisp)
|
||||||
- [x] 多種分析系統
|
- [x] 多種分析系統
|
||||||
- [x] 谷歌廣告/手動廣告位置
|
- [x] 谷歌廣告/手動廣告位置
|
||||||
- [x] 各種站長驗證
|
- [x] 各種站長驗證
|
||||||
@@ -98,6 +98,7 @@ theme: butterfly
|
|||||||
- [x] 不蒜子訪問統計
|
- [x] 不蒜子訪問統計
|
||||||
- [x] 兩種大圖模式(Medium Zoom/Fancybox)
|
- [x] 兩種大圖模式(Medium Zoom/Fancybox)
|
||||||
- [x] Mermaid 圖表顯示
|
- [x] Mermaid 圖表顯示
|
||||||
|
- [x] Chart.js 圖表顯示
|
||||||
- [x] 照片牆
|
- [x] 照片牆
|
||||||
- [x] 圖片懶加載
|
- [x] 圖片懶加載
|
||||||
- [x] Instantpage/Pangu/Snackbar彈窗/PWA......
|
- [x] Instantpage/Pangu/Snackbar彈窗/PWA......
|
||||||
|
|||||||
28
_config.yml
28
_config.yml
@@ -602,7 +602,7 @@ facebook_comments:
|
|||||||
pageSize: 10
|
pageSize: 10
|
||||||
# Choose: social / time / reverse_time
|
# Choose: social / time / reverse_time
|
||||||
order_by: social
|
order_by: social
|
||||||
lang: zh_TW
|
lang: en_US
|
||||||
|
|
||||||
# Twikoo
|
# Twikoo
|
||||||
# https://github.com/imaegoo/twikoo
|
# https://github.com/imaegoo/twikoo
|
||||||
@@ -645,7 +645,7 @@ artalk:
|
|||||||
# --------------------------------------
|
# --------------------------------------
|
||||||
|
|
||||||
chat:
|
chat:
|
||||||
# Choose: chatra/tidio/daovoice/crisp
|
# Choose: chatra/tidio/crisp
|
||||||
# Leave it empty if you don't need chat
|
# Leave it empty if you don't need chat
|
||||||
use:
|
use:
|
||||||
# Chat Button [recommend]
|
# Chat Button [recommend]
|
||||||
@@ -662,10 +662,6 @@ chatra:
|
|||||||
tidio:
|
tidio:
|
||||||
public_key:
|
public_key:
|
||||||
|
|
||||||
# http://dashboard.daovoice.io/app
|
|
||||||
daovoice:
|
|
||||||
app_id:
|
|
||||||
|
|
||||||
# https://crisp.chat/en/
|
# https://crisp.chat/en/
|
||||||
crisp:
|
crisp:
|
||||||
website_id:
|
website_id:
|
||||||
@@ -924,6 +920,25 @@ mermaid:
|
|||||||
light: default
|
light: default
|
||||||
dark: dark
|
dark: dark
|
||||||
|
|
||||||
|
# chartjs
|
||||||
|
# see https://www.chartjs.org/docs/latest/
|
||||||
|
chartjs:
|
||||||
|
enable: false
|
||||||
|
# Do not modify unless you understand how they work.
|
||||||
|
# The default settings are only used when the MD syntax is not specified.
|
||||||
|
# General font color for the chart
|
||||||
|
fontColor:
|
||||||
|
light: 'rgba(0, 0, 0, 0.8)'
|
||||||
|
dark: 'rgba(255, 255, 255, 0.8)'
|
||||||
|
# General border color for the chart
|
||||||
|
borderColor:
|
||||||
|
light: 'rgba(0, 0, 0, 0.1)'
|
||||||
|
dark: 'rgba(255, 255, 255, 0.2)'
|
||||||
|
# Background color for scale labels on radar and polar area charts
|
||||||
|
scale_ticks_backdropColor:
|
||||||
|
light: 'transparent'
|
||||||
|
dark: 'transparent'
|
||||||
|
|
||||||
# Note - Bootstrap Callout
|
# Note - Bootstrap Callout
|
||||||
note:
|
note:
|
||||||
# Note tag style values:
|
# Note tag style values:
|
||||||
@@ -1050,6 +1065,7 @@ CDN:
|
|||||||
# canvas_fluttering_ribbon:
|
# canvas_fluttering_ribbon:
|
||||||
# canvas_nest:
|
# canvas_nest:
|
||||||
# canvas_ribbon:
|
# canvas_ribbon:
|
||||||
|
# chartjs:
|
||||||
# click_heart:
|
# click_heart:
|
||||||
# clickShowText:
|
# clickShowText:
|
||||||
# disqusjs:
|
# disqusjs:
|
||||||
|
|||||||
@@ -23,5 +23,6 @@ script#config-diff.
|
|||||||
isHome: !{is_home()},
|
isHome: !{is_home()},
|
||||||
isHighlightShrink: !{isHighlightShrink},
|
isHighlightShrink: !{isHighlightShrink},
|
||||||
isToc: !{showToc},
|
isToc: !{showToc},
|
||||||
postUpdate: '!{full_date(page.updated)}'
|
postUpdate: '!{full_date(page.updated)}',
|
||||||
|
isShuoshuo: !{page.type == 'shuoshuo'}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,47 +60,38 @@
|
|||||||
if block
|
if block
|
||||||
block
|
block
|
||||||
|
|
||||||
|
mixin otherPV()
|
||||||
|
if theme.umami_analytics.enable && theme.umami_analytics.UV_PV.page_pv
|
||||||
|
+pvBlock('', '', '')
|
||||||
|
span#umamiPV(data-path=url_for(page.path))
|
||||||
|
i.fa-solid.fa-spinner.fa-spin
|
||||||
|
else if theme.busuanzi.page_pv
|
||||||
|
+pvBlock('', 'post-meta-pv-cv', '')
|
||||||
|
span#busuanzi_value_page_pv
|
||||||
|
i.fa-solid.fa-spinner.fa-spin
|
||||||
|
|
||||||
- const commentUse = comments.use && comments.use[0]
|
- const commentUse = comments.use && comments.use[0]
|
||||||
if page.comments !== false && commentUse && !comments.lazyload
|
if page.comments !== false && commentUse && !comments.lazyload
|
||||||
case commentUse
|
if commentUse === 'Valine' && theme.valine.visitor
|
||||||
when 'Valine'
|
|
||||||
if theme.valine.visitor
|
|
||||||
+pvBlock(url_for(page.path), 'leancloud_visitors', page.title)
|
+pvBlock(url_for(page.path), 'leancloud_visitors', page.title)
|
||||||
span.leancloud-visitors-count
|
span.leancloud-visitors-count
|
||||||
i.fa-solid.fa-spinner.fa-spin
|
i.fa-solid.fa-spinner.fa-spin
|
||||||
when 'Waline'
|
else if commentUse === 'Waline' && theme.waline.pageview
|
||||||
if theme.waline.pageview
|
|
||||||
+pvBlock('', '', '')
|
+pvBlock('', '', '')
|
||||||
span.waline-pageview-count(data-path=url_for(page.path))
|
span.waline-pageview-count(data-path=url_for(page.path))
|
||||||
i.fa-solid.fa-spinner.fa-spin
|
i.fa-solid.fa-spinner.fa-spin
|
||||||
when 'Twikoo'
|
else if commentUse === 'Twikoo' && theme.twikoo.visitor
|
||||||
if theme.twikoo.visitor
|
|
||||||
+pvBlock('', '', '')
|
+pvBlock('', '', '')
|
||||||
span#twikoo_visitors
|
span#twikoo_visitors
|
||||||
i.fa-solid.fa-spinner.fa-spin
|
i.fa-solid.fa-spinner.fa-spin
|
||||||
when 'Artalk'
|
else if commentUse === 'Artalk' && theme.artalk.visitor
|
||||||
if theme.artalk.visitor
|
|
||||||
+pvBlock('', '', '')
|
+pvBlock('', '', '')
|
||||||
span#ArtalkPV
|
span#ArtalkPV
|
||||||
i.fa-solid.fa-spinner.fa-spin
|
i.fa-solid.fa-spinner.fa-spin
|
||||||
default
|
|
||||||
if theme.umami_analytics.enable && theme.umami_analytics.UV_PV.page_pv
|
|
||||||
+pvBlock('', '', '')
|
|
||||||
span#umamiPV(data-path=url_for(page.path))
|
|
||||||
i.fa-solid.fa-spinner.fa-spin
|
|
||||||
else if theme.busuanzi.page_pv
|
|
||||||
+pvBlock('', 'post-meta-pv-cv', '')
|
|
||||||
span#busuanzi_value_page_pv
|
|
||||||
i.fa-solid.fa-spinner.fa-spin
|
|
||||||
else
|
else
|
||||||
if theme.umami_analytics.enable && theme.umami_analytics.UV_PV.page_pv
|
+otherPV()
|
||||||
+pvBlock('', '', '')
|
else
|
||||||
span#umamiPV(data-path=url_for(page.path))
|
+otherPV()
|
||||||
i.fa-solid.fa-spinner.fa-spin
|
|
||||||
else if theme.busuanzi.page_pv
|
|
||||||
+pvBlock('', 'post-meta-pv-cv', '')
|
|
||||||
span#busuanzi_value_page_pv
|
|
||||||
i.fa-solid.fa-spinner.fa-spin
|
|
||||||
|
|
||||||
if comments.count && !comments.lazyload && page.comments !== false && comments.use
|
if comments.count && !comments.lazyload && page.comments !== false && comments.use
|
||||||
- var whichCount = comments.use[0]
|
- var whichCount = comments.use[0]
|
||||||
|
|||||||
@@ -105,15 +105,9 @@ mixin indexPostUI()
|
|||||||
i.fa-solid.fa-spinner.fa-spin
|
i.fa-solid.fa-spinner.fa-spin
|
||||||
|
|
||||||
//- Display the article introduction on homepage
|
//- Display the article introduction on homepage
|
||||||
case theme.index_post_content.method
|
- const content = postDesc(article)
|
||||||
when false
|
if content
|
||||||
- break
|
.content!=content
|
||||||
when 1
|
|
||||||
.content!= article.description
|
|
||||||
when 2
|
|
||||||
.content!= article.description || truncate(article.content, theme.index_post_content.length)
|
|
||||||
default
|
|
||||||
.content!= truncate(article.content, theme.index_post_content.length)
|
|
||||||
|
|
||||||
if theme.ad && theme.ad.index
|
if theme.ad && theme.ad.index
|
||||||
if (index + 1) % 3 === 0
|
if (index + 1) % 3 === 0
|
||||||
|
|||||||
@@ -6,27 +6,102 @@
|
|||||||
//- - tag1
|
//- - tag1
|
||||||
//- - tag2
|
//- - tag2
|
||||||
|
|
||||||
|
|
||||||
- page.comments = false
|
|
||||||
- page.toc = false
|
- page.toc = false
|
||||||
|
|
||||||
#article-container
|
#article-container
|
||||||
|
if page.comments !== false && theme.comments.use
|
||||||
|
- commentsJsLoad = true
|
||||||
|
|
||||||
|
script.
|
||||||
|
(() => {
|
||||||
|
const commentDiv = `!{partial('includes/third-party/comments/index', {}, {cache: true})}`
|
||||||
|
|
||||||
|
const runDestroy = (shuoshuoComment) => {
|
||||||
|
if (!shuoshuoComment) return
|
||||||
|
|
||||||
|
for (const [key, fn] of Object.entries(shuoshuoComment)) {
|
||||||
|
if (key.startsWith('destroy')) fn()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addCommentToShuoshuo = e => {
|
||||||
|
const btn = e.target.closest('.shuoshuo-comment-btn')
|
||||||
|
if (!btn) return
|
||||||
|
|
||||||
|
const ele = btn.parentNode.nextElementSibling
|
||||||
|
const { shuoshuoComment } = window
|
||||||
|
const isInclude = ele.classList.contains('no-comment')
|
||||||
|
runDestroy(shuoshuoComment)
|
||||||
|
if (isInclude) {
|
||||||
|
ele.classList.remove('no-comment')
|
||||||
|
ele.innerHTML = commentDiv
|
||||||
|
const key = `${location.pathname.replace(/\/$/, '')}?key=${ele.getAttribute('data-key')}`
|
||||||
|
btf.switchComments(ele, key)
|
||||||
|
shuoshuoComment.loadComment && shuoshuoComment.loadComment(ele, key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})()
|
||||||
|
|
||||||
if page.shuoshuo_url
|
if page.shuoshuo_url
|
||||||
script.
|
script.
|
||||||
(() => {
|
(() => {
|
||||||
|
const limitConfig = !{ JSON.stringify(page.limit || {}) }
|
||||||
|
|
||||||
|
const sortDataByDate = data => data.sort((a, b) => new Date(b.date) - new Date(a.date))
|
||||||
|
|
||||||
|
const filterDataByLimit = (data, limit) => {
|
||||||
|
if (!limit || !limit.type) return data
|
||||||
|
if (limit.type === 'num') return data.slice(0, limit.value)
|
||||||
|
if (limit.type === 'date') {
|
||||||
|
const limitDate = new Date(limit.value)
|
||||||
|
return data.filter(item => new Date(item.date) >= limitDate)
|
||||||
|
}
|
||||||
|
return data
|
||||||
|
};
|
||||||
|
|
||||||
|
const formatToTimeZone = (date) => {
|
||||||
|
const fullDate = date.length === 10 ? `${date} 00:00:00` : date
|
||||||
|
const visitorTimeZone = '#{config.timezone}' || Intl.DateTimeFormat().resolvedOptions().timeZone
|
||||||
|
const options = {
|
||||||
|
timeZone: visitorTimeZone,
|
||||||
|
year: 'numeric',
|
||||||
|
month: '2-digit',
|
||||||
|
day: '2-digit',
|
||||||
|
hour: '2-digit',
|
||||||
|
minute: '2-digit',
|
||||||
|
second: '2-digit',
|
||||||
|
hour12: false
|
||||||
|
}
|
||||||
|
const [day, month, year, hour, minute, second] = new Intl.DateTimeFormat('en-GB', options)
|
||||||
|
.format(new Date(fullDate))
|
||||||
|
.match(/\d+/g)
|
||||||
|
return `${year}-${month}-${day} ${hour}:${minute}:${second}`
|
||||||
|
}
|
||||||
|
|
||||||
const loadShuoshuo = async () => {
|
const loadShuoshuo = async () => {
|
||||||
try {
|
try {
|
||||||
const fetchContent = await fetch('!{url_for(page.shuoshuo_url)}')
|
const response = await fetch('!{url_for(page.shuoshuo_url)}')
|
||||||
const shuoshuo = await fetchContent.json()
|
let data = await response.json()
|
||||||
|
|
||||||
|
data = filterDataByLimit(sortDataByDate(data), limitConfig)
|
||||||
|
|
||||||
let start = 0
|
|
||||||
const container = document.getElementById('article-container')
|
const container = document.getElementById('article-container')
|
||||||
|
let start = 0
|
||||||
|
|
||||||
const addData = data => {
|
const renderData = (dataSlice) => {
|
||||||
const cLength = data.length
|
const content = dataSlice.map(item => {
|
||||||
const end = start + 10 > cLength ? cLength : start + 10
|
const formattedDate = formatToTimeZone(item.date)
|
||||||
let result = ''
|
const tags = item.tags && item.tags.map(tag => `<span class="shuoshuo-tag">${tag}</span>`).join('') || ''
|
||||||
data.slice(start, end).forEach((item) => {
|
const commentButton = item.key && !{commentsJsLoad}
|
||||||
result += `
|
? `<div class="shuoshuo-comment-btn" onclick="addCommentToShuoshuo(event)">
|
||||||
|
<i class="fa-solid fa-comments"></i>
|
||||||
|
</div>`
|
||||||
|
: ''
|
||||||
|
const commentContainer = item.key
|
||||||
|
? `<div class="shuoshuo-comment no-comment" data-key="${item.key}"></div>`
|
||||||
|
: ''
|
||||||
|
|
||||||
|
return `
|
||||||
<div class="shuoshuo-item">
|
<div class="shuoshuo-item">
|
||||||
<div class="shuoshuo-item-header">
|
<div class="shuoshuo-item-header">
|
||||||
<div class="shuoshuo-avatar">
|
<div class="shuoshuo-avatar">
|
||||||
@@ -34,70 +109,77 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="shuoshuo-info">
|
<div class="shuoshuo-info">
|
||||||
<div class="shuoshuo-author">${item.author || '!{config.author}'}</div>
|
<div class="shuoshuo-author">${item.author || '!{config.author}'}</div>
|
||||||
<div class="shuoshuo-date">${btf.diffDate(item.date, true)}</div>
|
<time class="shuoshuo-date" title="${formattedDate}">
|
||||||
|
${btf.diffDate(formattedDate, true)}
|
||||||
|
</time>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="shuoshuo-content">
|
<div class="shuoshuo-content">${item.content}</div>
|
||||||
${item.content}
|
<div class="shuoshuo-footer ${tags ? 'flex-between' : 'flex-end'}">
|
||||||
|
${tags ? `<div class="shuoshuo-tags">${tags}</div>` : ''}
|
||||||
|
${commentButton}
|
||||||
</div>
|
</div>
|
||||||
<div class="shuoshuo-footer">
|
${commentContainer}
|
||||||
<div class="shuoshuo-tags">
|
</div>`
|
||||||
${item.tags.map(tag => `<span class="shuoshuo-tag">${tag}</span>`).join('')}
|
}).join('')
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`
|
|
||||||
})
|
|
||||||
|
|
||||||
start = end
|
container.insertAdjacentHTML('beforeend', content)
|
||||||
container.insertAdjacentHTML('beforeend', result)
|
|
||||||
|
|
||||||
if (start >= cLength) {
|
|
||||||
observer.disconnect()
|
|
||||||
} else {
|
|
||||||
setTimeout(() => observer.observe(container.lastElementChild), 100)
|
|
||||||
}
|
|
||||||
|
|
||||||
window.lazyLoadInstance.update()
|
window.lazyLoadInstance.update()
|
||||||
btf.loadLightbox(document.querySelectorAll('#article-container img:not(.no-lightbox)'))
|
btf.loadLightbox(document.querySelectorAll('#article-container img:not(.no-lightbox)'))
|
||||||
}
|
}
|
||||||
|
|
||||||
addData(shuoshuo)
|
const handleIntersection = (entries) => {
|
||||||
|
if (!entries[0].isIntersecting) return
|
||||||
const observer = new IntersectionObserver((entries) => {
|
|
||||||
if (entries[0].isIntersecting) {
|
|
||||||
observer.unobserve(entries[0].target)
|
observer.unobserve(entries[0].target)
|
||||||
addData(shuoshuo)
|
|
||||||
|
const slice = data.slice(start, start + 10)
|
||||||
|
renderData(slice)
|
||||||
|
start += 10
|
||||||
|
|
||||||
|
if (start < data.length) {
|
||||||
|
setTimeout(() => observer.observe(container.lastElementChild), 100)
|
||||||
|
} else {
|
||||||
|
observer.disconnect()
|
||||||
}
|
}
|
||||||
}, {
|
};
|
||||||
|
|
||||||
|
const observer = new IntersectionObserver(handleIntersection, {
|
||||||
root: null,
|
root: null,
|
||||||
rootMargin: '0px',
|
rootMargin: '0px',
|
||||||
threshold: 1.0
|
threshold: 1.0
|
||||||
})
|
})
|
||||||
|
|
||||||
if (container.lastElementChild) {
|
renderData(data.slice(start, 10))
|
||||||
observer.observe(container.lastElementChild)
|
start += 10
|
||||||
}
|
|
||||||
} catch (e) {
|
if (container.lastElementChild) observer.observe(container.lastElementChild)
|
||||||
console.error(e)
|
} catch (error) {
|
||||||
}
|
console.error(error)
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
window.pjax ? loadShuoshuo() : window.addEventListener('load', loadShuoshuo)
|
window.pjax ? loadShuoshuo() : window.addEventListener('load', loadShuoshuo)
|
||||||
})()
|
})()
|
||||||
else
|
else
|
||||||
if site.data.shuoshuo
|
if site.data.shuoshuo
|
||||||
each i in site.data.shuoshuo
|
each i in shuoshuoFN(site.data.shuoshuo, page)
|
||||||
.shuoshuo-item
|
.shuoshuo-item
|
||||||
.shuoshuo-item-header
|
.shuoshuo-item-header
|
||||||
.shuoshuo-avatar
|
.shuoshuo-avatar
|
||||||
img.no-lightbox(src=i.avatar || url_for(theme.avatar.img))
|
img.no-lightbox(src=i.avatar || url_for(theme.avatar.img))
|
||||||
.shuoshuo-info
|
.shuoshuo-info
|
||||||
.shuoshuo-author=i.author || config.author
|
.shuoshuo-author=i.author || config.author
|
||||||
.shuoshuo-date=relative_date(i.date)
|
time.shuoshuo-date(title=i.date)=i.date
|
||||||
.shuoshuo-content
|
.shuoshuo-content
|
||||||
!=markdown(i.content)
|
!=markdown(i.content)
|
||||||
.shuoshuo-footer
|
.shuoshuo-footer(class=i.tags && i.tags.length ? 'flex-between' : 'flex-end')
|
||||||
|
if i.tags
|
||||||
.shuoshuo-tags
|
.shuoshuo-tags
|
||||||
each tag in i.tags
|
each tag in i.tags
|
||||||
span.shuoshuo-tag=tag
|
span.shuoshuo-tag=tag
|
||||||
|
if i.key && commentsJsLoad
|
||||||
|
.shuoshuo-comment-btn(onclick='addCommentToShuoshuo(event)')
|
||||||
|
i.fa-solid.fa-comments
|
||||||
|
if i.key && commentsJsLoad
|
||||||
|
.shuoshuo-comment.no-comment(data-key=i.key)
|
||||||
@@ -1,2 +1,2 @@
|
|||||||
.tag-cloud-list.is-center
|
.tag-cloud-list.text-center
|
||||||
!=cloudTags({source: site.tags, orderby: page.orderby || 'random', order: page.order || 1, minfontsize: 1.2, maxfontsize: 1.5, limit: 0, unit: 'em'})
|
!=cloudTags({source: site.tags, orderby: page.orderby || 'random', order: page.order || 1, minfontsize: 1.2, maxfontsize: 1.5, limit: 0, unit: 'em'})
|
||||||
@@ -7,30 +7,28 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
if is_post()
|
if is_post()
|
||||||
- let prev = theme.post_pagination === 1 ? page.prev : page.next
|
- let paginationOrder = theme.post_pagination === 1 ? { prev: page.prev, next: page.next } : { prev: page.next, next: page.prev }
|
||||||
- let next = theme.post_pagination === 1 ? page.next : page.prev
|
|
||||||
nav#pagination.pagination-post
|
|
||||||
if(prev)
|
|
||||||
- var hasPageNext = next ? 'pull-left' : 'pull-full'
|
|
||||||
a.prev-post(class=hasPageNext href=url_for(prev.path) title=prev.title)
|
|
||||||
if prev.cover_type === 'img'
|
|
||||||
img.cover(src=url_for(prev.cover) onerror=`onerror=null;src='${url_for(theme.error_img.post_page)}'` alt='cover of previous post')
|
|
||||||
else
|
|
||||||
.cover(style=`background: ${prev.cover || 'var(--default-bg-color)'}`)
|
|
||||||
.pagination-info
|
|
||||||
.label=_p('pagination.prev')
|
|
||||||
.prev_info=prev.title
|
|
||||||
|
|
||||||
if(next)
|
nav#pagination.pagination-post
|
||||||
- var hasPagePrev = prev ? 'pull-right' : 'pull-full'
|
each direction, key in paginationOrder
|
||||||
a.next-post(class=hasPagePrev href=url_for(next.path) title=next.title)
|
if direction
|
||||||
if next.cover_type === 'img'
|
- const getPostDesc = direction.postDesc || postDesc(direction)
|
||||||
img.cover(src=url_for(next.cover) onerror=`onerror=null;src='${url_for(theme.error_img.post_page)}'` alt='cover of next post')
|
- let className = key === 'prev' ? (paginationOrder.next ? '' : 'full-width') : (paginationOrder.prev ? '' : 'full-width')
|
||||||
|
- className = getPostDesc ? className : className + ' no-desc'
|
||||||
|
|
||||||
|
a.pagination-related(class=className href=url_for(direction.path) title=direction.title)
|
||||||
|
if direction.cover_type === 'img'
|
||||||
|
img.cover(src=url_for(direction.cover) onerror=`onerror=null;src='${url_for(theme.error_img.post_page)}'` alt=`cover of ${key === 'prev' ? 'previous' : 'next'} post`)
|
||||||
else
|
else
|
||||||
.cover(style=`background: ${next.cover || 'var(--default-bg-color)'}`)
|
.cover(style=`background: ${direction.cover || 'var(--default-bg-color)'}`)
|
||||||
.pagination-info
|
|
||||||
.label=_p('pagination.next')
|
.info(class=key === 'prev' ? '' : 'text-right')
|
||||||
.next_info=next.title
|
.info-1
|
||||||
|
.info-item-1=_p(`pagination.${key}`)
|
||||||
|
.info-item-2!=direction.title
|
||||||
|
if getPostDesc
|
||||||
|
.info-2
|
||||||
|
.info-item-1!=getPostDesc
|
||||||
else
|
else
|
||||||
nav#pagination
|
nav#pagination
|
||||||
.pagination
|
.pagination
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ if theme.menu
|
|||||||
#sidebar
|
#sidebar
|
||||||
#menu-mask
|
#menu-mask
|
||||||
#sidebar-menus
|
#sidebar-menus
|
||||||
.avatar-img.is-center
|
.avatar-img.text-center
|
||||||
img(src=url_for(theme.avatar.img) onerror=`onerror=null;src='${theme.error_img.flink}'` alt="avatar")
|
img(src=url_for(theme.avatar.img) onerror=`onerror=null;src='${theme.error_img.flink}'` alt="avatar")
|
||||||
.site-data.is-center
|
.site-data.text-center
|
||||||
a(href=url_for(config.archive_dir) + '/')
|
a(href=url_for(config.archive_dir) + '/')
|
||||||
.headline= _p('aside.articles')
|
.headline= _p('aside.articles')
|
||||||
.length-num= site.posts.length
|
.length-num= site.posts.length
|
||||||
|
|||||||
4
layout/includes/third-party/abcjs/abcjs.pug
vendored
4
layout/includes/third-party/abcjs/abcjs.pug
vendored
@@ -1,12 +1,12 @@
|
|||||||
script.
|
script.
|
||||||
(() => {
|
(() => {
|
||||||
const abcjsInit = () => {
|
const abcjsInit = () => {
|
||||||
const abcjsFn = () => {
|
const abcjsFn = () => setTimeout(() => {
|
||||||
document.querySelectorAll(".abc-music-sheet").forEach(ele => {
|
document.querySelectorAll(".abc-music-sheet").forEach(ele => {
|
||||||
if (ele.children.length > 0) return
|
if (ele.children.length > 0) return
|
||||||
ABCJS.renderAbc(ele, ele.innerHTML, {responsive: 'resize'})
|
ABCJS.renderAbc(ele, ele.innerHTML, {responsive: 'resize'})
|
||||||
})
|
})
|
||||||
}
|
}, 100)
|
||||||
|
|
||||||
typeof ABCJS === 'object' ? abcjsFn()
|
typeof ABCJS === 'object' ? abcjsFn()
|
||||||
: btf.getScript('!{url_for(theme.asset.abcjs_basic_js)}').then(abcjsFn)
|
: btf.getScript('!{url_for(theme.asset.abcjs_basic_js)}').then(abcjsFn)
|
||||||
|
|||||||
40
layout/includes/third-party/chat/daovoice.pug
vendored
40
layout/includes/third-party/chat/daovoice.pug
vendored
@@ -1,40 +0,0 @@
|
|||||||
//- https://guide.daocloud.io/daovoice/javascript-api-5869833.html
|
|
||||||
script.
|
|
||||||
(() => {
|
|
||||||
(function(i,s,o,g,r,a,m){i["DaoVoiceObject"]=r;i[r]=i[r]||function(){(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;a.charset="utf-8";m.parentNode.insertBefore(a,m)})(window,document,"script",('https:' == document.location.protocol ? 'https:' : 'http:') + "//widget.daovoice.io/widget/!{theme.daovoice.app_id}.js","daovoice")
|
|
||||||
|
|
||||||
const isChatBtn = !{theme.chat.rightside_button}
|
|
||||||
const isChatHideShow = !{theme.chat.button_hide_show}
|
|
||||||
|
|
||||||
daovoice('init', {
|
|
||||||
app_id: '!{theme.daovoice.app_id}',},{
|
|
||||||
launcher: {
|
|
||||||
disableLauncherIcon: isChatBtn
|
|
||||||
},
|
|
||||||
});
|
|
||||||
daovoice('update');
|
|
||||||
|
|
||||||
if (isChatBtn) {
|
|
||||||
window.chatBtnFn = () => {
|
|
||||||
const isShow = document.getElementById('daodream-messenger').classList.contains('daodream-messenger-active')
|
|
||||||
isShow ? daovoice('hide') : daovoice('show')
|
|
||||||
}
|
|
||||||
} else if (isChatHideShow) {
|
|
||||||
window.chatBtn = {
|
|
||||||
hide: () => {
|
|
||||||
daovoice('update', {},{
|
|
||||||
launcher: {
|
|
||||||
disableLauncherIcon: true
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
show: () => {
|
|
||||||
daovoice('update', {}, {
|
|
||||||
launcher: {
|
|
||||||
disableLauncherIcon: false
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})()
|
|
||||||
2
layout/includes/third-party/chat/index.pug
vendored
2
layout/includes/third-party/chat/index.pug
vendored
@@ -3,7 +3,5 @@ case theme.chat.use
|
|||||||
include ./chatra.pug
|
include ./chatra.pug
|
||||||
when 'tidio'
|
when 'tidio'
|
||||||
include ./tidio.pug
|
include ./tidio.pug
|
||||||
when 'daovoice'
|
|
||||||
include ./daovoice.pug
|
|
||||||
when 'crisp'
|
when 'crisp'
|
||||||
include ./crisp.pug
|
include ./crisp.pug
|
||||||
52
layout/includes/third-party/comments/artalk.pug
vendored
52
layout/includes/third-party/comments/artalk.pug
vendored
@@ -4,14 +4,27 @@
|
|||||||
script.
|
script.
|
||||||
(() => {
|
(() => {
|
||||||
let artalkItem = null
|
let artalkItem = null
|
||||||
const initArtalk = () => {
|
const option = !{JSON.stringify(option)}
|
||||||
artalkItem = Artalk.init(Object.assign({
|
const isShuoshuo = GLOBAL_CONFIG_SITE.isShuoshuo
|
||||||
el: '#artalk-wrap',
|
|
||||||
|
const destroyArtalk = () => {
|
||||||
|
if (artalkItem) {
|
||||||
|
artalkItem.destroy()
|
||||||
|
artalkItem = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const artalkChangeMode = theme => artalkItem && artalkItem.setDarkMode(theme === 'dark')
|
||||||
|
|
||||||
|
const initArtalk = (el = document, pageKey = location.pathname) => {
|
||||||
|
artalkItem = Artalk.init({
|
||||||
|
el: el.querySelector('#artalk-wrap'),
|
||||||
server: '!{server}',
|
server: '!{server}',
|
||||||
site: '!{site}',
|
site: '!{site}',
|
||||||
pageKey: location.pathname,
|
|
||||||
darkMode: document.documentElement.getAttribute('data-theme') === 'dark',
|
darkMode: document.documentElement.getAttribute('data-theme') === 'dark',
|
||||||
},!{JSON.stringify(option)}))
|
...option,
|
||||||
|
pageKey: isShuoshuo ? pageKey : (option && option.pageKey) || pageKey
|
||||||
|
})
|
||||||
|
|
||||||
if (GLOBAL_CONFIG.lightbox === 'null') return
|
if (GLOBAL_CONFIG.lightbox === 'null') return
|
||||||
artalkItem.on('list-loaded', () => {
|
artalkItem.on('list-loaded', () => {
|
||||||
@@ -21,31 +34,36 @@ script.
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
const destroyArtalk = () => {
|
if (isShuoshuo) {
|
||||||
artalkItem.destroy()
|
window.shuoshuoComment.destroyArtalk = () => {
|
||||||
|
destroyArtalk()
|
||||||
|
if (el.children.length) {
|
||||||
|
el.innerHTML = ''
|
||||||
|
el.classList.add('no-comment')
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
btf.addGlobalFn('pjaxSendOnce', destroyArtalk, 'destroyArtalk')
|
btf.addGlobalFn('pjaxSendOnce', destroyArtalk, 'destroyArtalk')
|
||||||
|
btf.addGlobalFn('themeChange', artalkChangeMode, 'artalk')
|
||||||
}
|
}
|
||||||
|
|
||||||
const loadArtalk = async () => {
|
const loadArtalk = async (el, pageKey) => {
|
||||||
if (typeof Artalk === 'object') initArtalk()
|
if (typeof Artalk === 'object') initArtalk(el, pageKey)
|
||||||
else {
|
else {
|
||||||
await btf.getCSS('!{theme.asset.artalk_css}')
|
await btf.getCSS('!{theme.asset.artalk_css}')
|
||||||
await btf.getScript('!{theme.asset.artalk_js}')
|
await btf.getScript('!{theme.asset.artalk_js}')
|
||||||
initArtalk()
|
initArtalk(el, pageKey)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const artalkChangeMode = theme => {
|
if (isShuoshuo) {
|
||||||
const artalkWrap = document.getElementById('artalk-wrap')
|
'!{use[0]}' === 'Artalk'
|
||||||
if (!(artalkWrap && artalkWrap.children.length)) return
|
? window.shuoshuoComment = { loadComment: loadArtalk }
|
||||||
const isDark = theme === 'dark'
|
: window.loadOtherComment = loadArtalk
|
||||||
artalkItem.setDarkMode(isDark)
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
btf.addGlobalFn('themeChange', artalkChangeMode, 'artalk')
|
|
||||||
|
|
||||||
if ('!{use[0]}' === 'Artalk' || !!{lazyload}) {
|
if ('!{use[0]}' === 'Artalk' || !!{lazyload}) {
|
||||||
if (!{lazyload}) btf.loadComment(document.getElementById('artalk-wrap'), loadArtalk)
|
if (!{lazyload}) btf.loadComment(document.getElementById('artalk-wrap'), loadArtalk)
|
||||||
else setTimeout(loadArtalk, 100)
|
else setTimeout(loadArtalk, 100)
|
||||||
|
|||||||
41
layout/includes/third-party/comments/disqus.pug
vendored
41
layout/includes/third-party/comments/disqus.pug
vendored
@@ -4,29 +4,43 @@
|
|||||||
|
|
||||||
script.
|
script.
|
||||||
(() => {
|
(() => {
|
||||||
const disqus_config = function () {
|
const isShuoshuo = GLOBAL_CONFIG_SITE.isShuoshuo
|
||||||
this.page.url = '!{ page.permalink }'
|
|
||||||
this.page.identifier = '!{ url_for(page.path) }'
|
|
||||||
this.page.title = '!{ disqusPageTitle }'
|
|
||||||
}
|
|
||||||
|
|
||||||
const disqusReset = () => {
|
const disqusReset = conf => {
|
||||||
window.DISQUS && window.DISQUS.reset({
|
window.DISQUS && window.DISQUS.reset({
|
||||||
reload: true,
|
reload: true,
|
||||||
config: disqus_config
|
config: conf
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
btf.addGlobalFn('themeChange', disqusReset, 'disqus')
|
const loadDisqus = (el, path) => {
|
||||||
|
if (isShuoshuo) {
|
||||||
|
window.shuoshuoComment.destroyDisqus = () => {
|
||||||
|
if (el.children.length) {
|
||||||
|
el.innerHTML = ''
|
||||||
|
el.classList.add('no-comment')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const loadDisqus = () =>{
|
window.disqus_identifier = isShuoshuo ? path : '!{ url_for(page.path) }'
|
||||||
if (window.DISQUS) disqusReset()
|
window.disqus_url = isShuoshuo ? location.origin + path : '!{ page.permalink }'
|
||||||
|
|
||||||
|
const disqus_config = function () {
|
||||||
|
this.page.url = disqus_url
|
||||||
|
this.page.identifier = disqus_identifier
|
||||||
|
this.page.title = '!{ disqusPageTitle }'
|
||||||
|
}
|
||||||
|
|
||||||
|
if (window.DISQUS) disqusReset(disqus_config)
|
||||||
else {
|
else {
|
||||||
const script = document.createElement('script')
|
const script = document.createElement('script')
|
||||||
script.src = 'https://!{shortname}.disqus.com/embed.js'
|
script.src = 'https://!{shortname}.disqus.com/embed.js'
|
||||||
script.setAttribute('data-timestamp', +new Date())
|
script.setAttribute('data-timestamp', +new Date())
|
||||||
document.head.appendChild(script)
|
document.head.appendChild(script)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
btf.addGlobalFn('themeChange', () => disqusReset(disqus_config), 'disqus')
|
||||||
}
|
}
|
||||||
|
|
||||||
const getCount = async() => {
|
const getCount = async() => {
|
||||||
@@ -47,6 +61,13 @@ script.
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isShuoshuo) {
|
||||||
|
'!{use[0]}' === 'Disqus'
|
||||||
|
? window.shuoshuoComment = { loadComment: loadDisqus }
|
||||||
|
: window.loadOtherComment = loadDisqus
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if ('!{use[0]}' === 'Disqus' || !!{lazyload}) {
|
if ('!{use[0]}' === 'Disqus' || !!{lazyload}) {
|
||||||
if (!{lazyload}) btf.loadComment(document.getElementById('disqus_thread'), loadDisqus)
|
if (!{lazyload}) btf.loadComment(document.getElementById('disqus_thread'), loadDisqus)
|
||||||
else {
|
else {
|
||||||
|
|||||||
@@ -1,36 +1,52 @@
|
|||||||
- let disqusjsPageTitle = page.title.replace(/'/ig,"\\'")
|
- let disqusjsPageTitle = page.title && page.title.replace(/'/ig,"\\'")
|
||||||
- const { shortname:dqShortname, apikey:dqApikey, option:dqOption } = theme.disqusjs
|
- const { shortname:dqShortname, apikey:dqApikey, option:dqOption } = theme.disqusjs
|
||||||
|
|
||||||
script.
|
script.
|
||||||
(() => {
|
(() => {
|
||||||
const initDisqusjs = () => {
|
const isShuoshuo = GLOBAL_CONFIG_SITE.isShuoshuo
|
||||||
|
const dqOption = !{JSON.stringify(dqOption)}
|
||||||
|
|
||||||
|
const destroyDisqusjs = () => {
|
||||||
|
disqusjs.destroy()
|
||||||
window.disqusjs = null
|
window.disqusjs = null
|
||||||
disqusjs = new DisqusJS(Object.assign({
|
}
|
||||||
|
|
||||||
|
const themeChange = (el, path) => {
|
||||||
|
destroyDisqusjs()
|
||||||
|
initDisqusjs(el, path)
|
||||||
|
}
|
||||||
|
|
||||||
|
const initDisqusjs = (el = document, path) => {
|
||||||
|
if (isShuoshuo) {
|
||||||
|
window.shuoshuoComment.destroyDisqusjs = () => {
|
||||||
|
destroyDisqusjs()
|
||||||
|
if (el.children.length) {
|
||||||
|
el.innerHTML = ''
|
||||||
|
el.classList.add('no-comment')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
disqusjs = new DisqusJS({
|
||||||
shortname: '!{dqShortname}',
|
shortname: '!{dqShortname}',
|
||||||
identifier: '!{ url_for(page.path) }',
|
|
||||||
url: '!{ page.permalink }',
|
|
||||||
title: '!{ disqusjsPageTitle }',
|
title: '!{ disqusjsPageTitle }',
|
||||||
apikey: '!{dqApikey}',
|
apikey: '!{dqApikey}',
|
||||||
},!{JSON.stringify(dqOption)}))
|
...dqOption,
|
||||||
|
identifier: isShuoshuo ? path : (dqOption && dqOption.identifier) || '!{ url_for(page.path) }',
|
||||||
|
url: isShuoshuo ? location.origin + path : (dqOption && dqOption.url) || '!{ page.permalink }'
|
||||||
|
})
|
||||||
|
|
||||||
disqusjs.render(document.getElementById('disqusjs-wrap'))
|
disqusjs.render(el.querySelector('#disqusjs-wrap'))
|
||||||
|
|
||||||
|
btf.addGlobalFn('themeChange', () => themeChange(el, path), 'disqusjs')
|
||||||
}
|
}
|
||||||
|
|
||||||
const themeChange = () => {
|
const loadDisqusjs = async(el, path) => {
|
||||||
const ele = document.getElementById('disqus_thread')
|
if (window.disqusJsLoad) initDisqusjs(el, path)
|
||||||
if(!ele) return
|
|
||||||
disqusjs.destroy()
|
|
||||||
initDisqusjs()
|
|
||||||
}
|
|
||||||
|
|
||||||
btf.addGlobalFn('themeChange', themeChange, 'disqusjs')
|
|
||||||
|
|
||||||
const loadDisqusjs = async() => {
|
|
||||||
if (window.disqusJsLoad) initDisqusjs()
|
|
||||||
else {
|
else {
|
||||||
await btf.getCSS('!{url_for(theme.asset.disqusjs_css)}')
|
await btf.getCSS('!{url_for(theme.asset.disqusjs_css)}')
|
||||||
await btf.getScript('!{url_for(theme.asset.disqusjs)}')
|
await btf.getScript('!{url_for(theme.asset.disqusjs)}')
|
||||||
initDisqusjs()
|
initDisqusjs(el, path)
|
||||||
window.disqusJsLoad = true
|
window.disqusJsLoad = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -52,6 +68,13 @@ script.
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isShuoshuo) {
|
||||||
|
'!{theme.comments.use[0]}' === 'Disqusjs'
|
||||||
|
? window.shuoshuoComment = { loadComment: loadDisqusjs }
|
||||||
|
: window.loadOtherComment = loadDisqusjs
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if ('!{theme.comments.use[0]}' === 'Disqusjs' || !!{theme.comments.lazyload}) {
|
if ('!{theme.comments.use[0]}' === 'Disqusjs' || !!{theme.comments.lazyload}) {
|
||||||
if (!{theme.comments.lazyload}) btf.loadComment(document.getElementById('disqusjs-wrap'), loadDisqusjs)
|
if (!{theme.comments.lazyload}) btf.loadComment(document.getElementById('disqusjs-wrap'), loadDisqusjs)
|
||||||
else {
|
else {
|
||||||
|
|||||||
@@ -3,17 +3,28 @@
|
|||||||
|
|
||||||
script.
|
script.
|
||||||
(()=>{
|
(()=>{
|
||||||
const loadFBComment = () => {
|
const isShuoshuo = GLOBAL_CONFIG_SITE.isShuoshuo
|
||||||
|
|
||||||
|
const loadFBComment = (el = document, path) => {
|
||||||
|
if (isShuoshuo) {
|
||||||
|
window.shuoshuoComment.destroyFB = () => {
|
||||||
|
if (el.children.length) {
|
||||||
|
el.innerHTML = ''
|
||||||
|
el.classList.add('no-comment')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
document.getElementById('fb-root') ? '' : document.body.insertAdjacentHTML('afterend', '<div id="fb-root"></div>')
|
document.getElementById('fb-root') ? '' : document.body.insertAdjacentHTML('afterend', '<div id="fb-root"></div>')
|
||||||
|
|
||||||
const themeNow = document.documentElement.getAttribute('data-theme') === 'dark' ? 'dark' : 'light'
|
const themeNow = document.documentElement.getAttribute('data-theme') === 'dark' ? 'dark' : 'light'
|
||||||
const $fbComment = document.getElementsByClassName('fb-comments')[0]
|
const $fbComment = el.getElementsByClassName('fb-comments')[0]
|
||||||
$fbComment.setAttribute('data-colorscheme',themeNow)
|
$fbComment.setAttribute('data-colorscheme',themeNow)
|
||||||
$fbComment.setAttribute('data-href', '!{urlNoIndex(page.permalink)}')
|
$fbComment.setAttribute('data-href', isShuoshuo ? '!{urlNoIndex(page.permalink)}' + '#' + path : '!{urlNoIndex(page.permalink)}')
|
||||||
|
|
||||||
if (typeof FB === 'object') {
|
if (typeof FB === 'object') {
|
||||||
FB.XFBML.parse(document.getElementsByClassName('post-meta-commentcount')[0])
|
FB.XFBML.parse(document.getElementsByClassName('post-meta-commentcount')[0])
|
||||||
FB.XFBML.parse(document.getElementById('post-comment'))
|
FB.XFBML.parse(el.querySelector('#post-comment'))
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
let ele = document.createElement('script')
|
let ele = document.createElement('script')
|
||||||
@@ -36,6 +47,13 @@ script.
|
|||||||
|
|
||||||
btf.addGlobalFn('themeChange', fbModeChange, 'facebook_comments')
|
btf.addGlobalFn('themeChange', fbModeChange, 'facebook_comments')
|
||||||
|
|
||||||
|
if (isShuoshuo) {
|
||||||
|
'!{theme.comments.use[0]}' === 'Facebook Comments'
|
||||||
|
? window.shuoshuoComment = { loadComment: loadFBComment }
|
||||||
|
: window.loadOtherComment = loadFBComment
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
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()
|
||||||
|
|||||||
54
layout/includes/third-party/comments/giscus.pug
vendored
54
layout/includes/third-party/comments/giscus.pug
vendored
@@ -4,27 +4,50 @@
|
|||||||
- const giscusOriginUrl = new URL(giscusUrl).origin
|
- const giscusOriginUrl = new URL(giscusUrl).origin
|
||||||
|
|
||||||
script.
|
script.
|
||||||
(()=>{
|
(() => {
|
||||||
|
const isShuoshuo = GLOBAL_CONFIG_SITE.isShuoshuo
|
||||||
|
const option = !{JSON.stringify(option)}
|
||||||
|
|
||||||
const getGiscusTheme = theme => theme === 'dark' ? '!{dark_theme}' : '!{light_theme}'
|
const getGiscusTheme = theme => theme === 'dark' ? '!{dark_theme}' : '!{light_theme}'
|
||||||
|
|
||||||
const loadGiscus = () => {
|
const createScriptElement = config => {
|
||||||
const config = Object.assign({
|
const ele = document.createElement('script')
|
||||||
|
Object.entries(config).forEach(([key, value]) => {
|
||||||
|
ele.setAttribute(key, value)
|
||||||
|
})
|
||||||
|
return ele
|
||||||
|
}
|
||||||
|
|
||||||
|
const loadGiscus = (el = document, key) => {
|
||||||
|
const mappingConfig = isShuoshuo
|
||||||
|
? { 'data-mapping': 'specific', 'data-term': key }
|
||||||
|
: { 'data-mapping': (option && option['data-mapping']) || 'pathname' }
|
||||||
|
|
||||||
|
const giscusConfig = {
|
||||||
src: '!{giscusUrl}',
|
src: '!{giscusUrl}',
|
||||||
'data-repo': '!{repo}',
|
'data-repo': '!{repo}',
|
||||||
'data-repo-id': '!{repo_id}',
|
'data-repo-id': '!{repo_id}',
|
||||||
'data-category-id': '!{category_id}',
|
'data-category-id': '!{category_id}',
|
||||||
'data-mapping': 'pathname',
|
|
||||||
'data-theme': getGiscusTheme(document.documentElement.getAttribute('data-theme')),
|
'data-theme': getGiscusTheme(document.documentElement.getAttribute('data-theme')),
|
||||||
'data-reactions-enabled': '1',
|
'data-reactions-enabled': '1',
|
||||||
crossorigin: 'anonymous',
|
crossorigin: 'anonymous',
|
||||||
async: true
|
async: true,
|
||||||
},!{JSON.stringify(option)})
|
...option,
|
||||||
|
...mappingConfig
|
||||||
const ele = document.createElement('script')
|
}
|
||||||
for (let key in config) {
|
|
||||||
ele.setAttribute(key, config[key])
|
const scriptElement = createScriptElement(giscusConfig)
|
||||||
|
|
||||||
|
el.querySelector('#giscus-wrap').appendChild(scriptElement)
|
||||||
|
|
||||||
|
if (isShuoshuo) {
|
||||||
|
window.shuoshuoComment.destroyGiscus = () => {
|
||||||
|
if (el.children.length) {
|
||||||
|
el.innerHTML = ''
|
||||||
|
el.classList.add('no-comment')
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
document.getElementById('giscus-wrap').appendChild(ele)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const changeGiscusTheme = theme => {
|
const changeGiscusTheme = theme => {
|
||||||
@@ -43,10 +66,17 @@ script.
|
|||||||
|
|
||||||
btf.addGlobalFn('themeChange', changeGiscusTheme, 'giscus')
|
btf.addGlobalFn('themeChange', changeGiscusTheme, 'giscus')
|
||||||
|
|
||||||
|
if (isShuoshuo) {
|
||||||
|
'!{use[0]}' === 'Giscus'
|
||||||
|
? window.shuoshuoComment = { loadComment: loadGiscus }
|
||||||
|
: window.loadOtherComment = loadGiscus
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if ('!{use[0]}' === 'Giscus' || !!{lazyload}) {
|
if ('!{use[0]}' === 'Giscus' || !!{lazyload}) {
|
||||||
if (!{lazyload}) btf.loadComment(document.getElementById('giscus-wrap'), loadGiscus)
|
if (!{lazyload}) btf.loadComment(document.getElementById('giscus-wrap'), loadGiscus)
|
||||||
else loadGiscus()
|
else loadGiscus()
|
||||||
} else {
|
} else {
|
||||||
window.loadOtherComment= loadGiscus
|
window.loadOtherComment = loadGiscus
|
||||||
}
|
}
|
||||||
})()
|
})()
|
||||||
|
|||||||
64
layout/includes/third-party/comments/gitalk.pug
vendored
64
layout/includes/third-party/comments/gitalk.pug
vendored
@@ -2,28 +2,8 @@
|
|||||||
|
|
||||||
script.
|
script.
|
||||||
(() => {
|
(() => {
|
||||||
const initGitalk = () => {
|
const isShuoshuo = GLOBAL_CONFIG_SITE.isShuoshuo
|
||||||
const gitalk = new Gitalk(Object.assign({
|
const option = !{JSON.stringify(option)}
|
||||||
clientID: '!{client_id}',
|
|
||||||
clientSecret: '!{client_secret}',
|
|
||||||
repo: '!{repo}',
|
|
||||||
owner: '!{owner}',
|
|
||||||
admin: ['!{admin}'],
|
|
||||||
id: '!{md5(page.path)}',
|
|
||||||
updateCountCallback: commentCount
|
|
||||||
},!{JSON.stringify(option)}))
|
|
||||||
|
|
||||||
gitalk.render('gitalk-container')
|
|
||||||
}
|
|
||||||
|
|
||||||
const loadGitalk = async() => {
|
|
||||||
if (typeof Gitalk === 'function') initGitalk()
|
|
||||||
else {
|
|
||||||
await btf.getCSS('!{url_for(theme.asset.gitalk_css)}')
|
|
||||||
await btf.getScript('!{url_for(theme.asset.gitalk)}')
|
|
||||||
initGitalk()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const commentCount = n => {
|
const commentCount = n => {
|
||||||
const isCommentCount = document.querySelector('#post-meta .gitalk-comment-count')
|
const isCommentCount = document.querySelector('#post-meta .gitalk-comment-count')
|
||||||
@@ -32,6 +12,46 @@ script.
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const initGitalk = (el, path) => {
|
||||||
|
if (isShuoshuo) {
|
||||||
|
window.shuoshuoComment.destroyGitalk = () => {
|
||||||
|
if (el.children.length) {
|
||||||
|
el.innerHTML = ''
|
||||||
|
el.classList.add('no-comment')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const gitalk = new Gitalk({
|
||||||
|
clientID: '!{client_id}',
|
||||||
|
clientSecret: '!{client_secret}',
|
||||||
|
repo: '!{repo}',
|
||||||
|
owner: '!{owner}',
|
||||||
|
admin: ['!{admin}'],
|
||||||
|
updateCountCallback: commentCount,
|
||||||
|
...option,
|
||||||
|
id: isShuoshuo ? path : (option && option.id) || '!{md5(page.path)}'
|
||||||
|
})
|
||||||
|
|
||||||
|
gitalk.render('gitalk-container')
|
||||||
|
}
|
||||||
|
|
||||||
|
const loadGitalk = async(el, path) => {
|
||||||
|
if (typeof Gitalk === 'function') initGitalk(el, path)
|
||||||
|
else {
|
||||||
|
await btf.getCSS('!{url_for(theme.asset.gitalk_css)}')
|
||||||
|
await btf.getScript('!{url_for(theme.asset.gitalk)}')
|
||||||
|
initGitalk(el, path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isShuoshuo) {
|
||||||
|
'!{theme.comments.use[0]}' === 'Gitalk'
|
||||||
|
? window.shuoshuoComment = { loadComment: loadGitalk }
|
||||||
|
: window.loadOtherComment = loadGitalk
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if ('!{theme.comments.use[0]}' === 'Gitalk' || !!{theme.comments.lazyload}) {
|
if ('!{theme.comments.use[0]}' === 'Gitalk' || !!{theme.comments.lazyload}) {
|
||||||
if (!{theme.comments.lazyload}) btf.loadComment(document.getElementById('gitalk-container'), loadGitalk)
|
if (!{theme.comments.lazyload}) btf.loadComment(document.getElementById('gitalk-container'), loadGitalk)
|
||||||
else loadGitalk()
|
else loadGitalk()
|
||||||
|
|||||||
26
layout/includes/third-party/comments/livere.pug
vendored
26
layout/includes/third-party/comments/livere.pug
vendored
@@ -1,8 +1,23 @@
|
|||||||
- const { use, lazyload } = theme.comments
|
- const { use, lazyload } = theme.comments
|
||||||
|
|
||||||
script.
|
script.
|
||||||
(()=>{
|
(() => {
|
||||||
const loadLivere = () => {
|
const isShuoshuo = GLOBAL_CONFIG_SITE.isShuoshuo
|
||||||
|
|
||||||
|
const loadLivere = (el, path) => {
|
||||||
|
window.livereOptions = {
|
||||||
|
refer: path || location.pathname
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isShuoshuo) {
|
||||||
|
window.shuoshuoComment.destroyLivere = () => {
|
||||||
|
if (el.children.length) {
|
||||||
|
el.innerHTML = ''
|
||||||
|
el.classList.add('no-comment')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (typeof LivereTower === 'object') window.LivereTower.init()
|
if (typeof LivereTower === 'object') window.LivereTower.init()
|
||||||
else {
|
else {
|
||||||
(function(d, s) {
|
(function(d, s) {
|
||||||
@@ -16,6 +31,13 @@ script.
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isShuoshuo) {
|
||||||
|
'!{use[0]}' === 'Livere'
|
||||||
|
? window.shuoshuoComment = { loadComment: loadLivere }
|
||||||
|
: window.loadOtherComment = loadLivere
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if ('!{use[0]}' === 'Livere' || !!{lazyload}) {
|
if ('!{use[0]}' === 'Livere' || !!{lazyload}) {
|
||||||
if (!{lazyload}) btf.loadComment(document.getElementById('lv-container'), loadLivere)
|
if (!{lazyload}) btf.loadComment(document.getElementById('lv-container'), loadLivere)
|
||||||
else loadLivere()
|
else loadLivere()
|
||||||
|
|||||||
@@ -1,68 +1,78 @@
|
|||||||
- const { host, siteId, option } = theme.remark42
|
- const { host, siteId, option } = theme.remark42
|
||||||
|
|
||||||
script.
|
script.
|
||||||
var remark_config = Object.assign({
|
(() => {
|
||||||
host: '!{host}',
|
const isShuoshuo = GLOBAL_CONFIG_SITE.isShuoshuo
|
||||||
site_id: '!{siteId}',
|
const option = !{JSON.stringify(option)}
|
||||||
components: ['embed'],
|
|
||||||
theme: document.documentElement.getAttribute('data-theme') === 'dark' ? 'dark' : 'light'
|
|
||||||
},!{JSON.stringify(option)})
|
|
||||||
|
|
||||||
function addRemark42(){
|
const loadScript = src => {
|
||||||
for (let i = 0; i < remark_config.components.length; i++) {
|
const script = document.createElement('script')
|
||||||
const s = document.createElement('script')
|
script.src = src
|
||||||
s.src = remark_config.host + '/web/' + remark_config.components[i] + '.js'
|
script.defer = true
|
||||||
s.defer = true
|
document.head.appendChild(script)
|
||||||
document.head.appendChild(s)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function initRemark42() {
|
const addRemark42 = () => loadScript('!{host}/web/embed.js')
|
||||||
|
|
||||||
|
const getCount = () => document.querySelector('.remark42__counter') && loadScript('!{host}/web/count.js')
|
||||||
|
|
||||||
|
const destroyRemark42 = () => window.remark42Instance && window.remark42Instance.destroy()
|
||||||
|
|
||||||
|
const initRemark42 = remark_config => {
|
||||||
if (window.REMARK42) {
|
if (window.REMARK42) {
|
||||||
if (this.remark42Instance) {
|
destroyRemark42()
|
||||||
this.remark42Instance.destroy()
|
window.remark42Instance = window.REMARK42.createInstance({
|
||||||
}
|
|
||||||
|
|
||||||
this.remark42Instance = window.REMARK42.createInstance({
|
|
||||||
...remark_config
|
...remark_config
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCount () {
|
const loadRemark42 = (el, path) => {
|
||||||
const ele = document.querySelector('.remark42__counter')
|
if (isShuoshuo) {
|
||||||
if (ele) {
|
window.shuoshuoComment.destroyRemark42 = () => {
|
||||||
const s = document.createElement('script')
|
destroyRemark42()
|
||||||
s.src = remark_config.host + '/web/counter.js'
|
if (el.children.length) {
|
||||||
s.defer = true
|
el.innerHTML = ''
|
||||||
document.head.appendChild(s)
|
el.classList.add('no-comment')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadRemark42 () {
|
window.remark_config = {
|
||||||
|
host: '!{host}',
|
||||||
|
site_id: '!{siteId}',
|
||||||
|
theme: document.documentElement.getAttribute('data-theme') === 'dark' ? 'dark' : 'light',
|
||||||
|
...option,
|
||||||
|
url: isShuoshuo ? window.location.origin + path : (option && option.url) || window.location.origin + window.location.pathname
|
||||||
|
}
|
||||||
|
|
||||||
if (window.REMARK42) {
|
if (window.REMARK42) {
|
||||||
this.initRemark42()
|
initRemark42(remark_config)
|
||||||
getCount()
|
getCount()
|
||||||
} else {
|
} else {
|
||||||
addRemark42()
|
addRemark42()
|
||||||
window.addEventListener('REMARK42::ready', () => {
|
window.addEventListener('REMARK42::ready', () => {
|
||||||
this.initRemark42()
|
initRemark42(remark_config)
|
||||||
getCount()
|
getCount()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function remarkChangeMode (theme) {
|
const remarkChangeMode = theme => window.REMARK42 && window.REMARK42.changeTheme(theme)
|
||||||
if (!window.REMARK42) return
|
|
||||||
window.REMARK42.changeTheme(theme)
|
|
||||||
}
|
|
||||||
|
|
||||||
btf.addGlobalFn('themeChange', remarkChangeMode, 'remark42')
|
btf.addGlobalFn('themeChange', remarkChangeMode, 'remark42')
|
||||||
|
|
||||||
|
if (isShuoshuo) {
|
||||||
|
'!{theme.comments.use[0]}' === 'Remark42'
|
||||||
|
? window.shuoshuoComment = { loadComment: loadRemark42 }
|
||||||
|
: window.loadOtherComment = loadRemark42
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
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)
|
||||||
else loadRemark42()
|
else loadRemark42()
|
||||||
} else {
|
} else {
|
||||||
function loadOtherComment () {
|
window.loadOtherComment = loadRemark42
|
||||||
loadRemark42()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
})()
|
||||||
35
layout/includes/third-party/comments/twikoo.pug
vendored
35
layout/includes/third-party/comments/twikoo.pug
vendored
@@ -3,6 +3,9 @@
|
|||||||
|
|
||||||
script.
|
script.
|
||||||
(() => {
|
(() => {
|
||||||
|
const isShuoshuo = GLOBAL_CONFIG_SITE.isShuoshuo
|
||||||
|
const option = !{JSON.stringify(option)}
|
||||||
|
|
||||||
const getCount = () => {
|
const getCount = () => {
|
||||||
const countELement = document.getElementById('twikoo-count')
|
const countELement = document.getElementById('twikoo-count')
|
||||||
if(!countELement) return
|
if(!countELement) return
|
||||||
@@ -18,22 +21,38 @@ script.
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const init = () => {
|
const init = (el = document, path = location.pathname) => {
|
||||||
twikoo.init(Object.assign({
|
twikoo.init({
|
||||||
el: '#twikoo-wrap',
|
el: el.querySelector('#twikoo-wrap'),
|
||||||
envId: '!{envId}',
|
envId: '!{envId}',
|
||||||
region: '!{region}',
|
region: '!{region}',
|
||||||
onCommentLoaded: () => {
|
onCommentLoaded: () => {
|
||||||
btf.loadLightbox(document.querySelectorAll('#twikoo .tk-content img:not(.tk-owo-emotion)'))
|
btf.loadLightbox(document.querySelectorAll('#twikoo .tk-content img:not(.tk-owo-emotion)'))
|
||||||
}
|
},
|
||||||
}, !{JSON.stringify(option)}))
|
...option,
|
||||||
|
path: isShuoshuo ? path : (option && option.path) || path
|
||||||
|
})
|
||||||
|
|
||||||
!{count ? 'GLOBAL_CONFIG_SITE.isPost && getCount()' : ''}
|
!{count ? 'GLOBAL_CONFIG_SITE.isPost && getCount()' : ''}
|
||||||
|
|
||||||
|
isShuoshuo && (window.shuoshuoComment.destroyTwikoo = () => {
|
||||||
|
if (el.children.length) {
|
||||||
|
el.innerHTML = ''
|
||||||
|
el.classList.add('no-comment')
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const loadTwikoo = () => {
|
const loadTwikoo = (el, path) => {
|
||||||
if (typeof twikoo === 'object') setTimeout(init,0)
|
if (typeof twikoo === 'object') setTimeout(() => init(el, path), 0)
|
||||||
else btf.getScript('!{url_for(theme.asset.twikoo)}').then(init)
|
else btf.getScript('!{url_for(theme.asset.twikoo)}').then(() => init(el, path))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isShuoshuo) {
|
||||||
|
'!{use[0]}' === 'Twikoo'
|
||||||
|
? window.shuoshuoComment = { loadComment: loadTwikoo }
|
||||||
|
: window.loadOtherComment = loadTwikoo
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('!{use[0]}' === 'Twikoo' || !!{lazyload}) {
|
if ('!{use[0]}' === 'Twikoo' || !!{lazyload}) {
|
||||||
|
|||||||
@@ -5,24 +5,33 @@
|
|||||||
|
|
||||||
script.
|
script.
|
||||||
(() => {
|
(() => {
|
||||||
|
const isShuoshuo = GLOBAL_CONFIG_SITE.isShuoshuo
|
||||||
|
const option = !{JSON.stringify(option)}
|
||||||
const getUtterancesTheme = theme => theme === 'dark' ? '#{dark_theme}' : '#{light_theme}'
|
const getUtterancesTheme = theme => theme === 'dark' ? '#{dark_theme}' : '#{light_theme}'
|
||||||
|
|
||||||
const loadUtterances = () => {
|
const loadUtterances = (el = document, key) => {
|
||||||
const config = Object.assign({
|
if (isShuoshuo) {
|
||||||
id: 'utterances_comment',
|
window.shuoshuoComment.destroyUtterances = () => {
|
||||||
|
if (el.children.length) {
|
||||||
|
el.innerHTML = ''
|
||||||
|
el.classList.add('no-comment')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const config = {
|
||||||
src: '!{utterancesUrl}',
|
src: '!{utterancesUrl}',
|
||||||
repo: '!{repo}',
|
repo: '!{repo}',
|
||||||
'issue-term': '!{issue_term}',
|
|
||||||
theme: getUtterancesTheme(document.documentElement.getAttribute('data-theme')),
|
theme: getUtterancesTheme(document.documentElement.getAttribute('data-theme')),
|
||||||
crossorigin: 'anonymous',
|
crossorigin: 'anonymous',
|
||||||
async: true
|
async: true,
|
||||||
},!{JSON.stringify(option)})
|
...option,
|
||||||
|
'issue-term': isShuoshuo ? key : (option && option['issue-term']) || '!{issue_term}'
|
||||||
|
}
|
||||||
|
|
||||||
const ele = document.createElement('script')
|
const ele = document.createElement('script')
|
||||||
for (let key in config) {
|
Object.entries(config).forEach(([key, value]) => ele.setAttribute(key, value))
|
||||||
ele.setAttribute(key, config[key])
|
el.querySelector('#utterances-wrap').appendChild(ele)
|
||||||
}
|
|
||||||
document.getElementById('utterances-wrap').appendChild(ele)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const changeUtterancesTheme = theme => {
|
const changeUtterancesTheme = theme => {
|
||||||
@@ -38,6 +47,13 @@ script.
|
|||||||
|
|
||||||
btf.addGlobalFn('themeChange', changeUtterancesTheme, 'utterances')
|
btf.addGlobalFn('themeChange', changeUtterancesTheme, 'utterances')
|
||||||
|
|
||||||
|
if (isShuoshuo) {
|
||||||
|
'!{use[0]}' === 'Utterances'
|
||||||
|
? window.shuoshuoComment = { loadComment: loadUtterances }
|
||||||
|
: window.loadOtherComment = loadUtterances
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if ('!{use[0]}' === 'Utterances' || !!{lazyload}) {
|
if ('!{use[0]}' === 'Utterances' || !!{lazyload}) {
|
||||||
if (!{lazyload}) btf.loadComment(document.getElementById('utterances-wrap'), loadUtterances)
|
if (!{lazyload}) btf.loadComment(document.getElementById('utterances-wrap'), loadUtterances)
|
||||||
else loadUtterances()
|
else loadUtterances()
|
||||||
|
|||||||
44
layout/includes/third-party/comments/valine.pug
vendored
44
layout/includes/third-party/comments/valine.pug
vendored
@@ -7,25 +7,48 @@ if site.data.valine
|
|||||||
|
|
||||||
script.
|
script.
|
||||||
(() => {
|
(() => {
|
||||||
const initValine = () => {
|
const isShuoshuo = GLOBAL_CONFIG_SITE.isShuoshuo
|
||||||
const valine = new Valine(Object.assign({
|
const option = !{JSON.stringify(option)}
|
||||||
|
|
||||||
|
const initValine = (el, path) => {
|
||||||
|
if (isShuoshuo) {
|
||||||
|
window.shuoshuoComment.destroyValine = () => {
|
||||||
|
if (el.children.length) {
|
||||||
|
el.innerHTML = ''
|
||||||
|
el.classList.add('no-comment')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const valineConfig = {
|
||||||
el: '#vcomment',
|
el: '#vcomment',
|
||||||
appId: '#{appId}',
|
appId: '#{appId}',
|
||||||
appKey: '#{appKey}',
|
appKey: '#{appKey}',
|
||||||
avatar: '#{avatar}',
|
avatar: '#{avatar}',
|
||||||
serverURLs: '#{serverURLs}',
|
serverURLs: '#{serverURLs}',
|
||||||
emojiMaps: !{emojiMaps},
|
emojiMaps: !{emojiMaps},
|
||||||
path: window.location.pathname,
|
visitor: #{visitor},
|
||||||
visitor: #{visitor}
|
...option,
|
||||||
}, !{JSON.stringify(option)}))
|
path: isShuoshuo ? path : (option && option.path) || window.location.pathname
|
||||||
}
|
}
|
||||||
|
|
||||||
const loadValine = async () => {
|
new Valine(valineConfig)
|
||||||
if (typeof Valine === 'function') initValine()
|
|
||||||
else {
|
|
||||||
await btf.getScript('!{url_for(theme.asset.valine)}')
|
|
||||||
initValine()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const loadValine = async (el, path) => {
|
||||||
|
if (typeof Valine === 'function') {
|
||||||
|
initValine(el, path)
|
||||||
|
} else {
|
||||||
|
await btf.getScript('!{url_for(theme.asset.valine)}')
|
||||||
|
initValine(el, path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isShuoshuo) {
|
||||||
|
'!{use[0]}' === 'Valine'
|
||||||
|
? window.shuoshuoComment = { loadComment: loadValine }
|
||||||
|
: window.loadOtherComment = loadValine
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('!{use[0]}' === 'Valine' || !!{lazyload}) {
|
if ('!{use[0]}' === 'Valine' || !!{lazyload}) {
|
||||||
@@ -35,4 +58,3 @@ script.
|
|||||||
window.loadOtherComment = loadValine
|
window.loadOtherComment = loadValine
|
||||||
}
|
}
|
||||||
})()
|
})()
|
||||||
|
|
||||||
|
|||||||
42
layout/includes/third-party/comments/waline.pug
vendored
42
layout/includes/third-party/comments/waline.pug
vendored
@@ -4,37 +4,53 @@
|
|||||||
script.
|
script.
|
||||||
(() => {
|
(() => {
|
||||||
let initFn = window.walineFn || null
|
let initFn = window.walineFn || null
|
||||||
|
const isShuoshuo = GLOBAL_CONFIG_SITE.isShuoshuo
|
||||||
|
const option = !{JSON.stringify(option)}
|
||||||
|
|
||||||
const initWaline = (Fn) => {
|
const destroyWaline = ele => ele.destroy()
|
||||||
const waline = Fn(Object.assign({
|
|
||||||
el: '#waline-wrap',
|
const initWaline = (Fn, el = document, path = window.location.pathname) => {
|
||||||
|
const waline = Fn({
|
||||||
|
el: el.querySelector('#waline-wrap'),
|
||||||
serverURL: '!{serverURL}',
|
serverURL: '!{serverURL}',
|
||||||
pageview: !{lazyload ? false : pageview},
|
pageview: !{lazyload ? false : pageview},
|
||||||
dark: 'html[data-theme="dark"]',
|
dark: 'html[data-theme="dark"]',
|
||||||
path: window.location.pathname,
|
|
||||||
comment: !{lazyload ? false : count},
|
comment: !{lazyload ? false : count},
|
||||||
}, !{JSON.stringify(option)}))
|
...option,
|
||||||
|
path: isShuoshuo ? path : (option && option.path) || path
|
||||||
|
})
|
||||||
|
|
||||||
const destroyWaline = () => {
|
if (isShuoshuo) {
|
||||||
waline.destroy()
|
window.shuoshuoComment.destroyWaline = () => {
|
||||||
|
destroyWaline(waline)
|
||||||
|
if (el.children.length) {
|
||||||
|
el.innerHTML = ''
|
||||||
|
el.classList.add('no-comment')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
btf.addGlobalFn('pjaxSendOnce', destroyWaline, 'destroyWaline')
|
const loadWaline = (el, path) => {
|
||||||
}
|
if (initFn) initWaline(initFn, el, path)
|
||||||
|
|
||||||
const loadWaline = () => {
|
|
||||||
if (initFn) initWaline(initFn)
|
|
||||||
else {
|
else {
|
||||||
btf.getCSS('!{url_for(theme.asset.waline_css)}')
|
btf.getCSS('!{url_for(theme.asset.waline_css)}')
|
||||||
.then(() => import('!{url_for(theme.asset.waline_js)}'))
|
.then(() => import('!{url_for(theme.asset.waline_js)}'))
|
||||||
.then(({ init }) => {
|
.then(({ init }) => {
|
||||||
initFn = init || Waline.init
|
initFn = init || Waline.init
|
||||||
initWaline(initFn)
|
initWaline(initFn, el, path)
|
||||||
window.walineFn = initFn
|
window.walineFn = initFn
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isShuoshuo) {
|
||||||
|
'!{use[0]}' === 'Waline'
|
||||||
|
? window.shuoshuoComment = { loadComment: loadWaline }
|
||||||
|
: window.loadOtherComment = loadWaline
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if ('!{use[0]}' === 'Waline' || !!{lazyload}) {
|
if ('!{use[0]}' === 'Waline' || !!{lazyload}) {
|
||||||
if (!{lazyload}) btf.loadComment(document.getElementById('waline-wrap'),loadWaline)
|
if (!{lazyload}) btf.loadComment(document.getElementById('waline-wrap'),loadWaline)
|
||||||
else setTimeout(loadWaline, 0)
|
else setTimeout(loadWaline, 0)
|
||||||
|
|||||||
91
layout/includes/third-party/math/chartjs.pug
vendored
Normal file
91
layout/includes/third-party/math/chartjs.pug
vendored
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
- const { fontColor, borderColor, scale_ticks_backdropColor } = theme.chartjs
|
||||||
|
|
||||||
|
script.
|
||||||
|
(() => {
|
||||||
|
const $chartjs = document.querySelectorAll('#article-container .chartjs-container')
|
||||||
|
if ($chartjs.length === 0) return
|
||||||
|
|
||||||
|
const applyThemeDefaultsConfig = theme => {
|
||||||
|
if (theme === 'dark-mode') {
|
||||||
|
Chart.defaults.color = "!{fontColor.dark}"
|
||||||
|
Chart.defaults.borderColor = "!{borderColor.dark}"
|
||||||
|
Chart.defaults.scale.ticks.backdropColor = "!{scale_ticks_backdropColor.dark}"
|
||||||
|
} else {
|
||||||
|
Chart.defaults.color = "!{fontColor.light}"
|
||||||
|
Chart.defaults.borderColor = "!{borderColor.light}"
|
||||||
|
Chart.defaults.scale.ticks.backdropColor = "!{scale_ticks_backdropColor.light}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recursively traverse the config object and automatically apply theme-specific color schemes
|
||||||
|
const applyThemeConfig = (obj, theme) => {
|
||||||
|
if (typeof obj !== 'object' || obj === null) return
|
||||||
|
|
||||||
|
Object.keys(obj).forEach(key => {
|
||||||
|
const value = obj[key]
|
||||||
|
// If the property is an object and has theme-specific options, apply them
|
||||||
|
if (typeof value === 'object' && value !== null) {
|
||||||
|
if (value[theme]) {
|
||||||
|
obj[key] = value[theme] // Apply the value for the current theme
|
||||||
|
} else {
|
||||||
|
// Recursively process child objects
|
||||||
|
applyThemeConfig(value, theme)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const runChartJS = () => {
|
||||||
|
window.loadChartJS = true
|
||||||
|
|
||||||
|
Array.from($chartjs).forEach((item, index) => {
|
||||||
|
const chartSrc = item.firstElementChild
|
||||||
|
const chartID = item.getAttribute('data-chartjs-id') || ('chartjs-' + index) // Use custom ID or default ID
|
||||||
|
const width = item.getAttribute('data-width')
|
||||||
|
const existingCanvas = document.getElementById(chartID)
|
||||||
|
|
||||||
|
// If a canvas already exists, remove it to avoid rendering duplicates
|
||||||
|
if (existingCanvas) {
|
||||||
|
existingCanvas.parentNode.remove()
|
||||||
|
}
|
||||||
|
|
||||||
|
const chartDefinition = chartSrc.textContent
|
||||||
|
const canvas = document.createElement('canvas')
|
||||||
|
canvas.id = chartID
|
||||||
|
|
||||||
|
const div = document.createElement('div')
|
||||||
|
div.className = 'chartjs-wrap'
|
||||||
|
|
||||||
|
if (width) {
|
||||||
|
div.style.width = width
|
||||||
|
}
|
||||||
|
|
||||||
|
div.appendChild(canvas)
|
||||||
|
chartSrc.insertAdjacentElement('afterend', div)
|
||||||
|
|
||||||
|
const ctx = document.getElementById(chartID).getContext('2d')
|
||||||
|
|
||||||
|
const config = JSON.parse(chartDefinition)
|
||||||
|
|
||||||
|
const theme = document.documentElement.getAttribute('data-theme') === 'dark' ? 'dark-mode' : 'light-mode'
|
||||||
|
|
||||||
|
// Set default styles (initial setup)
|
||||||
|
applyThemeDefaultsConfig(theme)
|
||||||
|
|
||||||
|
// Automatically traverse the config and apply dual-mode color schemes
|
||||||
|
applyThemeConfig(config, theme)
|
||||||
|
|
||||||
|
new Chart(ctx, config)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const loadChartJS = () => {
|
||||||
|
window.loadChartJS ? runChartJS() : btf.getScript('!{url_for(theme.asset.chartjs)}').then(runChartJS)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Listen for theme change events
|
||||||
|
btf.addGlobalFn('themeChange', runChartJS, 'chartjs')
|
||||||
|
btf.addGlobalFn('encrypt', runChartJS, 'chartjs')
|
||||||
|
|
||||||
|
window.pjax ? loadChartJS() : document.addEventListener('DOMContentLoaded', loadChartJS)
|
||||||
|
})()
|
||||||
3
layout/includes/third-party/math/index.pug
vendored
3
layout/includes/third-party/math/index.pug
vendored
@@ -9,3 +9,6 @@ case theme.math.use
|
|||||||
|
|
||||||
if theme.mermaid.enable
|
if theme.mermaid.enable
|
||||||
include ./mermaid.pug
|
include ./mermaid.pug
|
||||||
|
|
||||||
|
if theme.chartjs.enable
|
||||||
|
include ./chartjs.pug
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
- const { host, siteId } = theme.remark42
|
- const { host, siteId } = theme.remark42
|
||||||
|
!= partial("includes/third-party/newest-comments/common.pug", {}, { cache: true })
|
||||||
|
|
||||||
script.
|
script.
|
||||||
window.addEventListener('load', () => {
|
window.addEventListener('load', () => {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
button.search-close-button
|
button.search-close-button
|
||||||
i.fas.fa-times
|
i.fas.fa-times
|
||||||
|
|
||||||
#loading-database.is-center
|
#loading-database.text-center
|
||||||
i.fas.fa-spinner.fa-pulse
|
i.fas.fa-spinner.fa-pulse
|
||||||
span= ' ' + _p("search.load_data")
|
span= ' ' + _p("search.load_data")
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
if theme.aside.card_author.enable
|
if theme.aside.card_author.enable
|
||||||
.card-widget.card-info.is-center
|
.card-widget.card-info.text-center
|
||||||
.avatar-img
|
.avatar-img
|
||||||
img(src=url_for(theme.avatar.img) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt="avatar")
|
img(src=url_for(theme.avatar.img) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt="avatar")
|
||||||
.author-info-name= config.author
|
.author-info-name= config.author
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "hexo-theme-butterfly",
|
"name": "hexo-theme-butterfly",
|
||||||
"version": "5.0.0",
|
"version": "5.2.1",
|
||||||
"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": {
|
||||||
|
|||||||
18
plugins.yml
18
plugins.yml
@@ -1,15 +1,15 @@
|
|||||||
abcjs_basic_js:
|
abcjs_basic_js:
|
||||||
name: abcjs
|
name: abcjs
|
||||||
file: dist/abcjs-basic-min.js
|
file: dist/abcjs-basic-min.js
|
||||||
version: 6.4.3
|
version: 6.4.4
|
||||||
activate_power_mode:
|
activate_power_mode:
|
||||||
name: butterfly-extsrc
|
name: butterfly-extsrc
|
||||||
file: dist/activate-power-mode.min.js
|
file: dist/activate-power-mode.min.js
|
||||||
version: 1.1.4
|
version: 1.1.4
|
||||||
algolia_search:
|
algolia_search:
|
||||||
name: algoliasearch
|
name: algoliasearch
|
||||||
file: dist/algoliasearch-lite.umd.js
|
file: dist/lite/builds/browser.umd.js
|
||||||
version: 5.7.0
|
version: 5.12.0
|
||||||
aplayer_css:
|
aplayer_css:
|
||||||
name: aplayer
|
name: aplayer
|
||||||
file: dist/APlayer.min.css
|
file: dist/APlayer.min.css
|
||||||
@@ -42,6 +42,10 @@ canvas_ribbon:
|
|||||||
name: butterfly-extsrc
|
name: butterfly-extsrc
|
||||||
file: dist/canvas-ribbon.min.js
|
file: dist/canvas-ribbon.min.js
|
||||||
version: 1.1.4
|
version: 1.1.4
|
||||||
|
chartjs:
|
||||||
|
name: chart.js
|
||||||
|
file: dist/chart.umd.js
|
||||||
|
version: 4.4.6
|
||||||
clickShowText:
|
clickShowText:
|
||||||
name: butterfly-extsrc
|
name: butterfly-extsrc
|
||||||
file: dist/click-show-text.min.js
|
file: dist/click-show-text.min.js
|
||||||
@@ -62,12 +66,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: 3.6.2
|
version: 3.6.3
|
||||||
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: 3.6.2
|
version: 3.6.3
|
||||||
egjs_infinitegrid:
|
egjs_infinitegrid:
|
||||||
name: '@egjs/infinitegrid'
|
name: '@egjs/infinitegrid'
|
||||||
other_name: egjs-infinitegrid
|
other_name: egjs-infinitegrid
|
||||||
@@ -107,7 +111,7 @@ instantpage:
|
|||||||
instantsearch:
|
instantsearch:
|
||||||
name: instantsearch.js
|
name: instantsearch.js
|
||||||
file: dist/instantsearch.production.min.js
|
file: dist/instantsearch.production.min.js
|
||||||
version: 4.74.2
|
version: 4.75.3
|
||||||
katex:
|
katex:
|
||||||
name: katex
|
name: katex
|
||||||
file: dist/katex.min.css
|
file: dist/katex.min.css
|
||||||
@@ -133,7 +137,7 @@ medium_zoom:
|
|||||||
mermaid:
|
mermaid:
|
||||||
name: mermaid
|
name: mermaid
|
||||||
file: dist/mermaid.min.js
|
file: dist/mermaid.min.js
|
||||||
version: 11.2.1
|
version: 11.4.0
|
||||||
meting_js:
|
meting_js:
|
||||||
name: butterfly-extsrc
|
name: butterfly-extsrc
|
||||||
file: metingjs/dist/Meting.min.js
|
file: metingjs/dist/Meting.min.js
|
||||||
|
|||||||
36
scripts/common/postDesc.js
Normal file
36
scripts/common/postDesc.js
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
'use strict'
|
||||||
|
|
||||||
|
const { stripHTML, truncate } = require('hexo-util')
|
||||||
|
|
||||||
|
// Truncates the given content to a specified length, removing HTML tags and replacing newlines with spaces.
|
||||||
|
const truncateContent = (content, length) => {
|
||||||
|
return truncate(stripHTML(content), { length, separator: ' ' }).replace(/\n/g, ' ')
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generates a post description based on the provided data and theme configuration.
|
||||||
|
const postDesc = (data, hexo) => {
|
||||||
|
const { description, content, postDesc } = data
|
||||||
|
|
||||||
|
if (postDesc) return postDesc
|
||||||
|
|
||||||
|
const { length, method } = hexo.theme.config.index_post_content
|
||||||
|
|
||||||
|
if (method === false) return
|
||||||
|
|
||||||
|
let result
|
||||||
|
switch (method) {
|
||||||
|
case 1:
|
||||||
|
result = description
|
||||||
|
break
|
||||||
|
case 2:
|
||||||
|
result = description || truncateContent(content, length)
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
result = truncateContent(content, length)
|
||||||
|
}
|
||||||
|
|
||||||
|
data.postDesc = result
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { truncateContent, postDesc }
|
||||||
@@ -7,11 +7,18 @@ hexo.extend.filter.register('before_generate', () => {
|
|||||||
let { use } = themeConfig.comments
|
let { use } = themeConfig.comments
|
||||||
if (!use) return
|
if (!use) return
|
||||||
|
|
||||||
// 確保 use 是一個陣列
|
// Make sure use is an array
|
||||||
use = Array.isArray(use) ? use : use.split(',')
|
use = Array.isArray(use) ? use : use.split(',')
|
||||||
|
|
||||||
// 將每個項目轉換為小寫並將首字母大寫
|
// Capitalize the first letter of each comment name
|
||||||
themeConfig.comments.use = use.map(item =>
|
use = use.map(item =>
|
||||||
item.trim().toLowerCase().replace(/\b[a-z]/g, s => s.toUpperCase())
|
item.trim().toLowerCase().replace(/\b[a-z]/g, s => s.toUpperCase())
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Disqus and Disqusjs conflict, only keep the first one
|
||||||
|
if (use.includes('Disqus') && use.includes('Disqusjs')) {
|
||||||
|
use = [use[0]]
|
||||||
|
}
|
||||||
|
|
||||||
|
themeConfig.comments.use = use
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -341,7 +341,7 @@ hexo.extend.filter.register('before_generate', () => {
|
|||||||
user_id: null,
|
user_id: null,
|
||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
order_by: 'social',
|
order_by: 'social',
|
||||||
lang: 'zh_TW'
|
lang: 'en_US'
|
||||||
},
|
},
|
||||||
twikoo: {
|
twikoo: {
|
||||||
envId: null,
|
envId: null,
|
||||||
@@ -380,9 +380,6 @@ hexo.extend.filter.register('before_generate', () => {
|
|||||||
tidio: {
|
tidio: {
|
||||||
public_key: null
|
public_key: null
|
||||||
},
|
},
|
||||||
daovoice: {
|
|
||||||
app_id: null
|
|
||||||
},
|
|
||||||
crisp: {
|
crisp: {
|
||||||
website_id: null
|
website_id: null
|
||||||
},
|
},
|
||||||
@@ -512,6 +509,21 @@ hexo.extend.filter.register('before_generate', () => {
|
|||||||
dark: 'dark'
|
dark: 'dark'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
chartjs: {
|
||||||
|
enable: false,
|
||||||
|
fontColor: {
|
||||||
|
light: 'rgba(0, 0, 0, 0.8)',
|
||||||
|
dark: 'rgba(255, 255, 255, 0.8)'
|
||||||
|
},
|
||||||
|
borderColor: {
|
||||||
|
light: 'rgba(0, 0, 0, 0.1)',
|
||||||
|
dark: 'rgba(255, 255, 255, 0.2)'
|
||||||
|
},
|
||||||
|
scale_ticks_backdropColor: {
|
||||||
|
light: 'transparent',
|
||||||
|
dark: 'transparent'
|
||||||
|
}
|
||||||
|
},
|
||||||
note: {
|
note: {
|
||||||
style: 'flat',
|
style: 'flat',
|
||||||
icons: true,
|
icons: true,
|
||||||
|
|||||||
@@ -55,7 +55,6 @@ hexo.extend.helper.register('inject_head_js', function () {
|
|||||||
if (!${pjax.enable} && key.startsWith('pjax')) return
|
if (!${pjax.enable} && key.startsWith('pjax')) return
|
||||||
const globalFn = parent.globalFn || {}
|
const globalFn = parent.globalFn || {}
|
||||||
globalFn[key] = globalFn[key] || {}
|
globalFn[key] = globalFn[key] || {}
|
||||||
if (name && globalFn[key][name]) return
|
|
||||||
globalFn[key][name || Object.keys(globalFn[key]).length] = fn
|
globalFn[key][name || Object.keys(globalFn[key]).length] = fn
|
||||||
parent.globalFn = globalFn
|
parent.globalFn = globalFn
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,14 @@
|
|||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
const { stripHTML, prettyUrls, truncate } = require('hexo-util')
|
const { truncateContent, postDesc } = require('../common/postDesc')
|
||||||
|
const { prettyUrls } = require('hexo-util')
|
||||||
const crypto = require('crypto')
|
const crypto = require('crypto')
|
||||||
|
const moment = require('moment-timezone')
|
||||||
|
|
||||||
hexo.extend.helper.register('truncate', (content, length) => {
|
hexo.extend.helper.register('truncate', truncateContent)
|
||||||
return truncate(stripHTML(content), { length, separator: ' ' }).replace(/\n/g, ' ')
|
|
||||||
|
hexo.extend.helper.register('postDesc', data => {
|
||||||
|
return postDesc(data, hexo)
|
||||||
})
|
})
|
||||||
|
|
||||||
hexo.extend.helper.register('cloudTags', function (options = {}) {
|
hexo.extend.helper.register('cloudTags', function (options = {}) {
|
||||||
@@ -82,7 +86,7 @@ hexo.extend.helper.register('getBgPath', path => {
|
|||||||
|
|
||||||
const absoluteUrlPattern = /^(?:[a-z][a-z\d+.-]*:)?\/\//i
|
const absoluteUrlPattern = /^(?:[a-z][a-z\d+.-]*:)?\/\//i
|
||||||
const relativeUrlPattern = /^(\.\/|\.\.\/|\/|[^/]+\/).*$/
|
const relativeUrlPattern = /^(\.\/|\.\.\/|\/|[^/]+\/).*$/
|
||||||
const colorPattern = /^(#|rgb|rgba|hsl|hsla|linear-gradient|radial-gradient)/i
|
const colorPattern = /^(#|rgb|rgba|hsl|hsla)/i
|
||||||
|
|
||||||
if (colorPattern.test(path)) {
|
if (colorPattern.test(path)) {
|
||||||
return `background-color: ${path};`
|
return `background-color: ${path};`
|
||||||
@@ -92,3 +96,38 @@ hexo.extend.helper.register('getBgPath', path => {
|
|||||||
return `background: ${path};`
|
return `background: ${path};`
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
hexo.extend.helper.register('shuoshuoFN', (data, page) => {
|
||||||
|
const { limit } = page
|
||||||
|
let finalResult = ''
|
||||||
|
|
||||||
|
// Check if limit.value is a valid date
|
||||||
|
const isValidDate = date => !isNaN(Date.parse(date))
|
||||||
|
|
||||||
|
// order by date
|
||||||
|
const orderByDate = data => data.sort((a, b) => Date.parse(b.date) - Date.parse(a.date))
|
||||||
|
|
||||||
|
// Apply number limit or time limit conditionally
|
||||||
|
const limitData = data => {
|
||||||
|
if (limit && limit.type === 'num' && limit.value > 0) {
|
||||||
|
return data.slice(0, limit.value)
|
||||||
|
} else if (limit && limit.type === 'date' && isValidDate(limit.value)) {
|
||||||
|
const limitDate = Date.parse(limit.value)
|
||||||
|
return data.filter(item => Date.parse(item.date) >= limitDate)
|
||||||
|
}
|
||||||
|
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
orderByDate(data)
|
||||||
|
finalResult = limitData(data)
|
||||||
|
|
||||||
|
// This is a hack method, because hexo treats time as UTC time
|
||||||
|
// so you need to manually convert the time zone
|
||||||
|
finalResult.forEach(item => {
|
||||||
|
const utcDate = moment.utc(item.date).format('YYYY-MM-DD HH:mm:ss')
|
||||||
|
item.date = moment.tz(utcDate, hexo.config.timezone).format('YYYY-MM-DD HH:mm:ss')
|
||||||
|
})
|
||||||
|
|
||||||
|
return finalResult
|
||||||
|
})
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-disable camelcase */
|
||||||
/**
|
/**
|
||||||
* Butterfly
|
* Butterfly
|
||||||
* Related Posts
|
* Related Posts
|
||||||
@@ -6,12 +7,15 @@
|
|||||||
|
|
||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
|
const { postDesc } = require('../common/postDesc')
|
||||||
|
|
||||||
hexo.extend.helper.register('related_posts', function (currentPost, allPosts) {
|
hexo.extend.helper.register('related_posts', function (currentPost, allPosts) {
|
||||||
let relatedPosts = []
|
let relatedPosts = []
|
||||||
const tagsData = currentPost.tags
|
const tagsData = currentPost.tags
|
||||||
tagsData.length && tagsData.forEach(function (tag) {
|
tagsData.length && tagsData.forEach(function (tag) {
|
||||||
allPosts.forEach(function (post) {
|
allPosts.forEach(function (post) {
|
||||||
if (currentPost.path !== post.path && isTagRelated(tag.name, post.tags)) {
|
if (currentPost.path !== post.path && isTagRelated(tag.name, post.tags)) {
|
||||||
|
const getPostDesc = post.postDesc || postDesc(post, hexo)
|
||||||
const relatedPost = {
|
const relatedPost = {
|
||||||
title: post.title,
|
title: post.title,
|
||||||
path: post.path,
|
path: post.path,
|
||||||
@@ -19,7 +23,8 @@ hexo.extend.helper.register('related_posts', function (currentPost, allPosts) {
|
|||||||
cover_type: post.cover_type,
|
cover_type: post.cover_type,
|
||||||
weight: 1,
|
weight: 1,
|
||||||
updated: post.updated,
|
updated: post.updated,
|
||||||
created: post.date
|
created: post.date,
|
||||||
|
postDesc: getPostDesc
|
||||||
}
|
}
|
||||||
const index = findItem(relatedPosts, 'path', post.path)
|
const index = findItem(relatedPosts, 'path', post.path)
|
||||||
if (index !== -1) {
|
if (index !== -1) {
|
||||||
@@ -50,20 +55,27 @@ hexo.extend.helper.register('related_posts', function (currentPost, allPosts) {
|
|||||||
result += '<div class="relatedPosts-list">'
|
result += '<div class="relatedPosts-list">'
|
||||||
|
|
||||||
for (let i = 0; i < Math.min(relatedPosts.length, limitNum); i++) {
|
for (let i = 0; i < Math.min(relatedPosts.length, limitNum); i++) {
|
||||||
const cover = relatedPosts[i].cover || 'var(--default-bg-color)'
|
let { cover, title, path, cover_type, created, updated, postDesc } = relatedPosts[i]
|
||||||
const title = this.escape_html(relatedPosts[i].title)
|
const { escape_html, url_for, date } = this
|
||||||
result += `<a href="${this.url_for(relatedPosts[i].path)}" title="${title}">`
|
cover = cover || 'var(--default-bg-color)'
|
||||||
if (relatedPosts[i].cover_type === 'img') {
|
title = escape_html(title)
|
||||||
result += `<img class="cover" src="${this.url_for(cover)}" alt="cover">`
|
const className = postDesc ? 'pagination-related' : 'pagination-related no-desc'
|
||||||
|
result += `<a class="${className}" href="${url_for(path)}" title="${title}">`
|
||||||
|
if (cover_type === 'img') {
|
||||||
|
result += `<img class="cover" src="${url_for(cover)}" alt="cover">`
|
||||||
} else {
|
} else {
|
||||||
result += `<div class="cover" style="background: ${cover}"></div>`
|
result += `<div class="cover" style="background: ${cover}"></div>`
|
||||||
}
|
}
|
||||||
if (dateType === 'created') {
|
if (dateType === 'created') {
|
||||||
result += `<div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> ${this.date(relatedPosts[i].created, hexoConfig.date_format)}</div>`
|
result += `<div class="info text-center"><div class="info-1"><div class="info-item-1"><i class="far fa-calendar-alt fa-fw"></i> ${date(created, hexoConfig.date_format)}</div>`
|
||||||
} else {
|
} else {
|
||||||
result += `<div class="content is-center"><div class="date"><i class="fas fa-history fa-fw"></i> ${this.date(relatedPosts[i].updated, hexoConfig.date_format)}</div>`
|
result += `<div class="info text-center"><div class="info-1"><div class="info-item-1"><i class="fas fa-history fa-fw"></i> ${date(updated, hexoConfig.date_format)}</div>`
|
||||||
|
}
|
||||||
|
result += `<div class="info-item-2">${title}</div></div>`
|
||||||
|
|
||||||
|
if (postDesc) {
|
||||||
|
result += `<div class="info-2"><div class="info-item-1">${postDesc}</div></div>`
|
||||||
}
|
}
|
||||||
result += `<div class="title">${title}</div>`
|
|
||||||
result += '</div></a>'
|
result += '</div></a>'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
49
scripts/tag/chartjs.js
Normal file
49
scripts/tag/chartjs.js
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
/**
|
||||||
|
* Butterfly
|
||||||
|
* chartjs
|
||||||
|
* https://www.chartjs.org/
|
||||||
|
* {% chartjs [width, abreast, chartId] %}
|
||||||
|
* <!-- chart -->
|
||||||
|
* <!-- endchart -->
|
||||||
|
* <!-- desc -->
|
||||||
|
* <!-- enddesc -->
|
||||||
|
* {% endchartjs %}
|
||||||
|
*/
|
||||||
|
|
||||||
|
'use strict'
|
||||||
|
|
||||||
|
const { escapeHTML } = require('hexo-util')
|
||||||
|
|
||||||
|
const chartjs = (args, content) => {
|
||||||
|
if (!content) return
|
||||||
|
|
||||||
|
const chartRegex = /<!--\s*chart\s*-->\n([\w\W\s\S]*?)<!--\s*endchart\s*-->/
|
||||||
|
const descRegex = /<!--\s*desc\s*-->\n([\w\W\s\S]*?)<!--\s*enddesc\s*-->/
|
||||||
|
const selfConfig = args.join(' ').trim()
|
||||||
|
|
||||||
|
const [width = '', layout = false, chartId = ''] = selfConfig.split(',').map(s => s.trim())
|
||||||
|
|
||||||
|
const chartMatch = content.match(chartRegex)
|
||||||
|
const descMatch = content.match(descRegex)
|
||||||
|
|
||||||
|
if (!chartMatch) {
|
||||||
|
hexo.log.warn('chartjs tag: chart content is required!')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const chartConfig = chartMatch && chartMatch[1] ? chartMatch[1] : ''
|
||||||
|
const descContent = descMatch && descMatch[1] ? descMatch[1] : ''
|
||||||
|
|
||||||
|
const renderedDesc = descContent ? hexo.render.renderSync({ text: descContent, engine: 'markdown' }).trim() : ''
|
||||||
|
|
||||||
|
const descDOM = renderedDesc ? `<div class="chartjs-desc">${renderedDesc}</div>` : ''
|
||||||
|
const abreastClass = layout ? ' chartjs-abreast' : ''
|
||||||
|
const widthStyle = width ? `data-width="${width}%"` : ''
|
||||||
|
|
||||||
|
return `<div class="chartjs-container${abreastClass}" data-chartjs-id="${chartId}" ${widthStyle}>
|
||||||
|
<pre class="chartjs-src" hidden>${escapeHTML(chartConfig)}</pre>
|
||||||
|
${descDOM}
|
||||||
|
</div>`
|
||||||
|
}
|
||||||
|
|
||||||
|
hexo.extend.tag.register('chartjs', chartjs, { ends: true })
|
||||||
@@ -44,7 +44,7 @@ addBorderRadius(x = 6, hide = false)
|
|||||||
.postImgHover
|
.postImgHover
|
||||||
&:hover
|
&:hover
|
||||||
.cover
|
.cover
|
||||||
opacity: .7
|
opacity: .5
|
||||||
transform: scale(1.1)
|
transform: scale(1.1)
|
||||||
|
|
||||||
.cover
|
.cover
|
||||||
|
|||||||
@@ -179,14 +179,11 @@ if $site-name-font
|
|||||||
#aside-content .author-info-description
|
#aside-content .author-info-description
|
||||||
font-family: $site-name-font
|
font-family: $site-name-font
|
||||||
|
|
||||||
.is-center
|
.text-center
|
||||||
text-align: center
|
text-align: center
|
||||||
|
|
||||||
.pull-left
|
.text-right
|
||||||
float: left
|
text-align: right
|
||||||
|
|
||||||
.pull-right
|
|
||||||
float: right
|
|
||||||
|
|
||||||
img
|
img
|
||||||
&[src=''],
|
&[src=''],
|
||||||
|
|||||||
@@ -159,8 +159,8 @@
|
|||||||
a
|
a
|
||||||
display: flex
|
display: flex
|
||||||
flex-direction: row
|
flex-direction: row
|
||||||
padding: 2px 8px
|
|
||||||
margin: 2px 0
|
margin: 2px 0
|
||||||
|
padding: 2px 8px
|
||||||
color: var(--font-color)
|
color: var(--font-color)
|
||||||
transition: all .3s
|
transition: all .3s
|
||||||
addBorderRadius()
|
addBorderRadius()
|
||||||
@@ -354,11 +354,12 @@
|
|||||||
.headline
|
.headline
|
||||||
@extend .limit-one-line
|
@extend .limit-one-line
|
||||||
color: var(--font-color)
|
color: var(--font-color)
|
||||||
|
font-size: .95em
|
||||||
|
|
||||||
.length-num
|
.length-num
|
||||||
margin-top: -.32em
|
margin-top: -.45em
|
||||||
color: var(--text-highlight-color)
|
color: var(--text-highlight-color)
|
||||||
font-size: 1.4em
|
font-size: 1.2em
|
||||||
|
|
||||||
@keyframes more-btn-move
|
@keyframes more-btn-move
|
||||||
0%,
|
0%,
|
||||||
|
|||||||
@@ -146,10 +146,11 @@
|
|||||||
position: fixed
|
position: fixed
|
||||||
top: -60px
|
top: -60px
|
||||||
z-index: 91
|
z-index: 91
|
||||||
background: rgba(255, 255, 255, .8)
|
background: rgba(255, 255, 255, .7)
|
||||||
box-shadow: 0 5px 6px -5px alpha($grey, .6)
|
box-shadow: 0 5px 6px -5px alpha($grey, .6)
|
||||||
transition: transform .2s ease-in-out, opacity .2s ease-in-out
|
transition: transform .2s ease-in-out, opacity .2s ease-in-out
|
||||||
will-change: transform
|
will-change: transform
|
||||||
|
backdrop-filter: blur(7px)
|
||||||
|
|
||||||
#blog-info
|
#blog-info
|
||||||
color: var(--font-color)
|
color: var(--font-color)
|
||||||
@@ -430,6 +431,7 @@
|
|||||||
background-color: lighten($theme-color, 30%)
|
background-color: lighten($theme-color, 30%)
|
||||||
content: ''
|
content: ''
|
||||||
transition: all .3s ease-in-out
|
transition: all .3s ease-in-out
|
||||||
|
addBorderRadius()
|
||||||
|
|
||||||
&:hover
|
&:hover
|
||||||
&:after
|
&:after
|
||||||
|
|||||||
@@ -8,49 +8,28 @@
|
|||||||
background: $theme-paginator-color
|
background: $theme-paginator-color
|
||||||
color: var(--white)
|
color: var(--white)
|
||||||
|
|
||||||
.pagination-info
|
.full-width
|
||||||
position: absolute
|
|
||||||
top: 50%
|
|
||||||
padding: 20px 40px
|
|
||||||
width: 100%
|
|
||||||
transform: translate(0, -50%)
|
|
||||||
|
|
||||||
.prev_info,
|
|
||||||
.next_info
|
|
||||||
@extend .limit-one-line
|
|
||||||
color: var(--white)
|
|
||||||
font-weight: 500
|
|
||||||
|
|
||||||
.next-post
|
|
||||||
.pagination-info
|
|
||||||
text-align: right
|
|
||||||
|
|
||||||
.pull-full
|
|
||||||
width: 100% !important
|
width: 100% !important
|
||||||
|
|
||||||
.prev-post .label,
|
.pagination-related
|
||||||
.next-post .label
|
|
||||||
color: var(--light-grey)
|
|
||||||
text-transform: uppercase
|
|
||||||
font-size: 90%
|
|
||||||
|
|
||||||
.prev-post,
|
|
||||||
.next-post
|
|
||||||
@extend .postImgHover
|
|
||||||
position: relative
|
|
||||||
display: block
|
|
||||||
overflow: hidden
|
|
||||||
width: 50%
|
width: 50%
|
||||||
height: 150px
|
height: 150px
|
||||||
|
|
||||||
+maxWidth768()
|
+maxWidth768()
|
||||||
width: 100%
|
width: 100%
|
||||||
|
|
||||||
|
.info-1
|
||||||
|
.info-item-2
|
||||||
|
-webkit-line-clamp: 1
|
||||||
|
|
||||||
|
.info-2
|
||||||
|
.info-item-1
|
||||||
|
-webkit-line-clamp: 2
|
||||||
|
|
||||||
&.pagination-post
|
&.pagination-post
|
||||||
overflow: hidden
|
overflow: hidden
|
||||||
margin-top: 40px
|
margin-top: 40px
|
||||||
width: 100%
|
width: 100%
|
||||||
background: $dark-black
|
|
||||||
addBorderRadius()
|
addBorderRadius()
|
||||||
|
|
||||||
.layout
|
.layout
|
||||||
@@ -75,3 +54,50 @@
|
|||||||
|
|
||||||
& > *:not(.space)
|
& > *:not(.space)
|
||||||
box-shadow: none
|
box-shadow: none
|
||||||
|
|
||||||
|
.pagination-related
|
||||||
|
position: relative
|
||||||
|
display: inline-block
|
||||||
|
overflow: hidden
|
||||||
|
background: $dark-black
|
||||||
|
vertical-align: bottom
|
||||||
|
@extend .postImgHover
|
||||||
|
|
||||||
|
&.next-post
|
||||||
|
.info
|
||||||
|
text-align: right
|
||||||
|
|
||||||
|
.info
|
||||||
|
.info-1,
|
||||||
|
.info-2
|
||||||
|
@extend .verticalCenter
|
||||||
|
padding: 20px 40px
|
||||||
|
color: var(--white)
|
||||||
|
transition: transform .3s, opacity .3s
|
||||||
|
|
||||||
|
.info-1
|
||||||
|
.info-item-1
|
||||||
|
color: var(--light-grey)
|
||||||
|
text-transform: uppercase
|
||||||
|
font-size: 90%
|
||||||
|
|
||||||
|
.info-item-2
|
||||||
|
@extend .limit-more-line
|
||||||
|
color: var(--white)
|
||||||
|
font-weight: 500
|
||||||
|
|
||||||
|
.info-2
|
||||||
|
opacity: 0
|
||||||
|
transform: translate(0, 0)
|
||||||
|
|
||||||
|
.info-item-1
|
||||||
|
@extend .limit-more-line
|
||||||
|
|
||||||
|
&:not(.no-desc):hover
|
||||||
|
.info-1
|
||||||
|
opacity: 0
|
||||||
|
transform: translate(0, -100%)
|
||||||
|
|
||||||
|
.info-2
|
||||||
|
opacity: 1
|
||||||
|
transform: translate(0, -50%)
|
||||||
@@ -19,9 +19,9 @@ beautify()
|
|||||||
&:before
|
&:before
|
||||||
position: absolute
|
position: absolute
|
||||||
top: calc(50% - 7px)
|
top: calc(50% - 7px)
|
||||||
|
left: 0
|
||||||
color: $title-prefix-icon-color
|
color: $title-prefix-icon-color
|
||||||
content: $title-prefix-icon
|
content: $title-prefix-icon
|
||||||
left: 0
|
|
||||||
line-height: 1
|
line-height: 1
|
||||||
transition: all .2s ease-out
|
transition: all .2s ease-out
|
||||||
@extend .fontawesomeIcon
|
@extend .fontawesomeIcon
|
||||||
@@ -119,16 +119,16 @@ beautify()
|
|||||||
width: fit-content
|
width: fit-content
|
||||||
|
|
||||||
a:not(.headerlink)
|
a:not(.headerlink)
|
||||||
position relative
|
position: relative
|
||||||
z-index 10
|
z-index: 10
|
||||||
|
|
||||||
a.headerlink
|
a.headerlink
|
||||||
position: absolute
|
position: absolute
|
||||||
top: 0
|
top: 0
|
||||||
right: 0
|
right: 0
|
||||||
left 0
|
|
||||||
bottom: 0
|
bottom: 0
|
||||||
width 100%
|
left: 0
|
||||||
|
width: 100%
|
||||||
height: 100%
|
height: 100%
|
||||||
|
|
||||||
ol,
|
ol,
|
||||||
|
|||||||
@@ -8,15 +8,9 @@
|
|||||||
|
|
||||||
& > .relatedPosts-list
|
& > .relatedPosts-list
|
||||||
& > a
|
& > a
|
||||||
position: relative
|
|
||||||
display: inline-block
|
|
||||||
overflow: hidden
|
|
||||||
margin: 3px
|
margin: 3px
|
||||||
width: calc(33.333% - 6px)
|
width: calc(33.333% - 6px)
|
||||||
height: 200px
|
height: 200px
|
||||||
background: $dark-black
|
|
||||||
vertical-align: bottom
|
|
||||||
@extend .postImgHover
|
|
||||||
addBorderRadius()
|
addBorderRadius()
|
||||||
|
|
||||||
+maxWidth768()
|
+maxWidth768()
|
||||||
@@ -27,15 +21,11 @@
|
|||||||
+maxWidth600()
|
+maxWidth600()
|
||||||
width: calc(100% - 4px)
|
width: calc(100% - 4px)
|
||||||
|
|
||||||
.content
|
.info
|
||||||
padding: 0 20px
|
.info-1
|
||||||
@extend .verticalCenter
|
.info-item-2
|
||||||
|
|
||||||
.date
|
|
||||||
color: var(--light-grey)
|
|
||||||
font-size: 90%
|
|
||||||
|
|
||||||
.title
|
|
||||||
@extend .limit-more-line
|
|
||||||
color: var(--white)
|
|
||||||
-webkit-line-clamp: 2
|
-webkit-line-clamp: 2
|
||||||
|
|
||||||
|
.info-2
|
||||||
|
.info-item-1
|
||||||
|
-webkit-line-clamp: 3
|
||||||
@@ -75,6 +75,32 @@ if hexo-config('mermaid.enable')
|
|||||||
pre > code.mermaid
|
pre > code.mermaid
|
||||||
display: none
|
display: none
|
||||||
|
|
||||||
|
if hexo-config('chartjs.enable')
|
||||||
|
.chartjs-container
|
||||||
|
display: flex
|
||||||
|
flex-direction: column
|
||||||
|
justify-content: center
|
||||||
|
align-items: center
|
||||||
|
margin: 0 0 20px
|
||||||
|
text-align: center
|
||||||
|
gap: 20px
|
||||||
|
|
||||||
|
+maxWidth600()
|
||||||
|
.chartjs-wrap
|
||||||
|
width: 100% !important
|
||||||
|
|
||||||
|
&.chartjs-abreast
|
||||||
|
flex-direction: row
|
||||||
|
|
||||||
|
+maxWidth600()
|
||||||
|
flex-direction: column
|
||||||
|
|
||||||
|
.chartjs-wrap
|
||||||
|
width: -webkit-fill-available
|
||||||
|
|
||||||
|
canvas
|
||||||
|
display: inline-block !important
|
||||||
|
|
||||||
.utterances,
|
.utterances,
|
||||||
.fb-comments iframe
|
.fb-comments iframe
|
||||||
width: 100% !important
|
width: 100% !important
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
.shuoshuo-item-header
|
.shuoshuo-item-header
|
||||||
display: flex
|
display: flex
|
||||||
align-items: center
|
align-items: center
|
||||||
|
cursor: default
|
||||||
|
|
||||||
.shuoshuo-avatar
|
.shuoshuo-avatar
|
||||||
overflow: hidden
|
overflow: hidden
|
||||||
@@ -36,6 +37,16 @@
|
|||||||
& > *:last-child
|
& > *:last-child
|
||||||
margin-bottom: 0
|
margin-bottom: 0
|
||||||
|
|
||||||
|
.shuoshuo-footer
|
||||||
|
display: flex
|
||||||
|
align-items: center
|
||||||
|
|
||||||
|
&.flex-between
|
||||||
|
justify-content: space-between
|
||||||
|
|
||||||
|
&.flex-end
|
||||||
|
justify-content: flex-end
|
||||||
|
|
||||||
.shuoshuo-tag
|
.shuoshuo-tag
|
||||||
display: inline-block
|
display: inline-block
|
||||||
margin-right: 8px
|
margin-right: 8px
|
||||||
@@ -51,3 +62,17 @@
|
|||||||
&:hover
|
&:hover
|
||||||
background: $light-blue
|
background: $light-blue
|
||||||
color: var(--white)
|
color: var(--white)
|
||||||
|
|
||||||
|
.shuoshuo-comment-btn
|
||||||
|
padding: 2px
|
||||||
|
color: #90a4ae
|
||||||
|
cursor: pointer
|
||||||
|
|
||||||
|
&:hover
|
||||||
|
color: $light-blue
|
||||||
|
|
||||||
|
.shuoshuo-comment
|
||||||
|
padding-top: 10px
|
||||||
|
|
||||||
|
&.no-comment
|
||||||
|
display: none
|
||||||
|
|||||||
@@ -59,6 +59,7 @@
|
|||||||
height: 24px
|
height: 24px
|
||||||
text-align: center
|
text-align: center
|
||||||
line-height: 24px
|
line-height: 24px
|
||||||
|
addBorderRadius()
|
||||||
|
|
||||||
.ais-Pagination-item--selected
|
.ais-Pagination-item--selected
|
||||||
a
|
a
|
||||||
@@ -74,11 +75,11 @@
|
|||||||
overflow-y: overlay
|
overflow-y: overlay
|
||||||
margin: 0 -20px
|
margin: 0 -20px
|
||||||
padding: 0 22px
|
padding: 0 22px
|
||||||
max-height: calc(80vh - 240px)
|
max-height: calc(80vh - 220px)
|
||||||
|
|
||||||
+maxWidth768()
|
+maxWidth768()
|
||||||
max-height: none
|
max-height: none
|
||||||
height: calc(var(--search-height) - 265px)
|
height: calc(var(--search-height) - 235px)
|
||||||
|
|
||||||
#algolia-info
|
#algolia-info
|
||||||
div
|
div
|
||||||
|
|||||||
@@ -19,9 +19,6 @@
|
|||||||
height: 100%
|
height: 100%
|
||||||
border-radius: 0
|
border-radius: 0
|
||||||
|
|
||||||
hr
|
|
||||||
margin: 20px auto
|
|
||||||
|
|
||||||
.search-nav
|
.search-nav
|
||||||
margin: 0 0 14px
|
margin: 0 0 14px
|
||||||
color: $search-color
|
color: $search-color
|
||||||
@@ -40,7 +37,7 @@
|
|||||||
color: $search-color
|
color: $search-color
|
||||||
|
|
||||||
hr
|
hr
|
||||||
margin: 20px auto
|
margin: 15px auto
|
||||||
@extend .custom-hr
|
@extend .custom-hr
|
||||||
|
|
||||||
#search-mask
|
#search-mask
|
||||||
|
|||||||
@@ -19,30 +19,16 @@
|
|||||||
display: none
|
display: none
|
||||||
|
|
||||||
.local-search-hit-item
|
.local-search-hit-item
|
||||||
position: relative
|
margin-left: 24px
|
||||||
padding-left: 24px
|
padding-left: 3px
|
||||||
line-height: 1.7
|
line-height: 1.8
|
||||||
|
|
||||||
&:hover
|
&::marker
|
||||||
&:before
|
color: $search-color
|
||||||
border-color: var(--pseudo-hover)
|
font-weight: bold
|
||||||
|
font-style: italic
|
||||||
&:before
|
|
||||||
$w = .5em
|
|
||||||
position: absolute
|
|
||||||
top: .45em
|
|
||||||
left: 0
|
|
||||||
width: w = $w
|
|
||||||
height: h = w
|
|
||||||
border: 3px solid $search-color
|
|
||||||
border-radius: w
|
|
||||||
background: transparent
|
|
||||||
content: ''
|
|
||||||
line-height: h
|
|
||||||
transition: all .2s ease-in-out
|
|
||||||
|
|
||||||
a
|
a
|
||||||
display: block
|
|
||||||
color: var(--search-a-color)
|
color: var(--search-a-color)
|
||||||
|
|
||||||
&:hover
|
&:hover
|
||||||
@@ -53,17 +39,19 @@
|
|||||||
|
|
||||||
.search-result
|
.search-result
|
||||||
margin: 0 0 8px
|
margin: 0 0 8px
|
||||||
|
word-break: break-all
|
||||||
|
font-size: .9em
|
||||||
|
|
||||||
.search-result-list
|
.search-result-list
|
||||||
overflow-y: overlay
|
overflow-y: overlay
|
||||||
margin: 0 -20px
|
margin: 0 -20px
|
||||||
padding: 0 22px
|
padding: 0 22px
|
||||||
max-height: calc(80vh - 200px)
|
max-height: calc(80vh - 180px)
|
||||||
|
|
||||||
+maxWidth768()
|
+maxWidth768()
|
||||||
max-height: calc(var(--search-height) - 220px) !important
|
max-height: calc(var(--search-height) - 190px) !important
|
||||||
|
|
||||||
.search-keyword
|
.search-keyword
|
||||||
background: transparent
|
background: transparent
|
||||||
color: $search-keyword-highlight
|
color: $search-keyword-highlight
|
||||||
font-weight: bold
|
font-weight: 600
|
||||||
@@ -206,7 +206,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
const altValue = item.title || item.alt
|
const altValue = item.title || item.alt
|
||||||
if (!altValue) return
|
if (!altValue) return
|
||||||
const ele = document.createElement('div')
|
const ele = document.createElement('div')
|
||||||
ele.className = 'img-alt is-center'
|
ele.className = 'img-alt text-center'
|
||||||
ele.textContent = altValue
|
ele.textContent = altValue
|
||||||
item.insertAdjacentElement('afterend', ele)
|
item.insertAdjacentElement('afterend', ele)
|
||||||
})
|
})
|
||||||
@@ -806,22 +806,6 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
btf.addEventListenerPjax(cardCategory, 'click', handleToggleBtn, true)
|
btf.addEventListenerPjax(cardCategory, 'click', handleToggleBtn, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
const switchComments = () => {
|
|
||||||
const switchBtn = document.getElementById('switch-btn')
|
|
||||||
if (!switchBtn) return
|
|
||||||
|
|
||||||
let switchDone = false
|
|
||||||
const postComment = document.getElementById('post-comment')
|
|
||||||
const handleSwitchBtn = () => {
|
|
||||||
postComment.classList.toggle('move')
|
|
||||||
if (!switchDone && typeof loadOtherComment === 'function') {
|
|
||||||
switchDone = true
|
|
||||||
loadOtherComment()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
btf.addEventListenerPjax(switchBtn, 'click', handleSwitchBtn)
|
|
||||||
}
|
|
||||||
|
|
||||||
const addPostOutdateNotice = () => {
|
const addPostOutdateNotice = () => {
|
||||||
const { limitDay, messagePrev, messageNext, position } = GLOBAL_CONFIG.noticeOutdate
|
const { limitDay, messagePrev, messageNext, position } = GLOBAL_CONFIG.noticeOutdate
|
||||||
const diffDay = btf.diffDate(GLOBAL_CONFIG_SITE.postUpdate)
|
const diffDay = btf.diffDate(GLOBAL_CONFIG_SITE.postUpdate)
|
||||||
@@ -924,7 +908,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
scrollFn()
|
scrollFn()
|
||||||
|
|
||||||
forPostFn()
|
forPostFn()
|
||||||
switchComments()
|
!GLOBAL_CONFIG_SITE.isShuoshuo && btf.switchComments(document)
|
||||||
openMobileMenu()
|
openMobileMenu()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -85,9 +85,10 @@ window.addEventListener('load', () => {
|
|||||||
document.querySelector('#algolia-info .algolia-stats')
|
document.querySelector('#algolia-info .algolia-stats')
|
||||||
]
|
]
|
||||||
|
|
||||||
|
const searchClient = typeof algoliasearch === 'function' ? algoliasearch : window['algoliasearch/lite'].liteClient
|
||||||
const search = instantsearch({
|
const search = instantsearch({
|
||||||
indexName,
|
indexName,
|
||||||
searchClient: algoliasearch(appId, apiKey),
|
searchClient: searchClient(appId, apiKey),
|
||||||
searchFunction (helper) {
|
searchFunction (helper) {
|
||||||
disableDiv.forEach(item => {
|
disableDiv.forEach(item => {
|
||||||
item.style.display = helper.state.query ? '' : 'none'
|
item.style.display = helper.state.query ? '' : 'none'
|
||||||
|
|||||||
@@ -150,16 +150,16 @@ class LocalSearch {
|
|||||||
url.searchParams.append('highlight', keywords.join(' '))
|
url.searchParams.append('highlight', keywords.join(' '))
|
||||||
|
|
||||||
if (slicesOfTitle.length !== 0) {
|
if (slicesOfTitle.length !== 0) {
|
||||||
resultItem += `<div class="local-search-hit-item"><a href="${url.href}"><span class="search-result-title">${this.highlightKeyword(title, slicesOfTitle[0])}</span>`
|
resultItem += `<li class="local-search-hit-item"><a href="${url.href}"><span class="search-result-title">${this.highlightKeyword(title, slicesOfTitle[0])}</span>`
|
||||||
} else {
|
} else {
|
||||||
resultItem += `<div class="local-search-hit-item"><a href="${url.href}"><span class="search-result-title">${title}</span>`
|
resultItem += `<li class="local-search-hit-item"><a href="${url.href}"><span class="search-result-title">${title}</span>`
|
||||||
}
|
}
|
||||||
|
|
||||||
slicesOfContent.forEach(slice => {
|
slicesOfContent.forEach(slice => {
|
||||||
resultItem += `<p class="search-result">${this.highlightKeyword(content, slice)}...</p></a>`
|
resultItem += `<p class="search-result">${this.highlightKeyword(content, slice)}...</p></a>`
|
||||||
})
|
})
|
||||||
|
|
||||||
resultItem += '</div>'
|
resultItem += '</li>'
|
||||||
resultItems.push({
|
resultItems.push({
|
||||||
item: resultItem,
|
item: resultItem,
|
||||||
id: resultItems.length,
|
id: resultItems.length,
|
||||||
@@ -281,7 +281,7 @@ window.addEventListener('load', () => {
|
|||||||
|
|
||||||
const stats = languages.hits_stats.replace(/\$\{hits}/, resultItems.length)
|
const stats = languages.hits_stats.replace(/\$\{hits}/, resultItems.length)
|
||||||
|
|
||||||
container.innerHTML = `<div class="search-result-list">${resultItems.map(result => result.item).join('')}</div>`
|
container.innerHTML = `<ol class="search-result-list">${resultItems.map(result => result.item).join('')}</ol>`
|
||||||
statsItem.innerHTML = `<hr><div class="search-result-stats">${stats}</div>`
|
statsItem.innerHTML = `<hr><div class="search-result-stats">${stats}</div>`
|
||||||
window.pjax && window.pjax.refresh(container)
|
window.pjax && window.pjax.refresh(container)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -290,6 +290,22 @@
|
|||||||
Object.keys(keyObj).forEach(i => keyObj[i]())
|
Object.keys(keyObj).forEach(i => keyObj[i]())
|
||||||
|
|
||||||
delete globalFn[key]
|
delete globalFn[key]
|
||||||
|
},
|
||||||
|
|
||||||
|
switchComments: (el = document, path) => {
|
||||||
|
const switchBtn = el.querySelector('#switch-btn')
|
||||||
|
if (!switchBtn) return
|
||||||
|
|
||||||
|
let switchDone = false
|
||||||
|
const postComment = el.querySelector('#post-comment')
|
||||||
|
const handleSwitchBtn = () => {
|
||||||
|
postComment.classList.toggle('move')
|
||||||
|
if (!switchDone && typeof loadOtherComment === 'function') {
|
||||||
|
switchDone = true
|
||||||
|
loadOtherComment(el, path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
btf.addEventListenerPjax(switchBtn, 'click', handleSwitchBtn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user