feat(shuoshuo): render hexo tag plugins and defer post features via event

This commit is contained in:
myw
2026-07-21 21:46:58 +08:00 Unverified
parent 77ec898737
commit 85a1412b94
4 changed files with 65 additions and 41 deletions
+43 -38
View File
@@ -267,23 +267,23 @@ document.addEventListener('DOMContentLoaded', () => {
const fetchUrl = async url => {
try {
const response = await fetch(url)
if (!response.ok) throw new Error(`HTTP ${response.status}`)
if (!response.ok) throw new Error(`HTTP ${response.status}`)
return await response.json()
} catch (error) {
console.error('Failed to fetch URL:', error)
throw error
}
} catch (error) {
console.error('Failed to fetch URL:', error)
throw error
}
}
const runJustifiedGallery = (container, data, config) => {
const { isButton, tabs } = config
const limit = Math.max(1, Number(config.limit) || 20)
const firstLimit = Math.max(1, Number(config.firstLimit) || limit)
const { isButton, tabs } = config
const limit = Math.max(1, Number(config.limit) || 20)
const firstLimit = Math.max(1, Number(config.firstLimit) || limit)
const dataLength = data.length
const maxGroupKey = dataLength
? Math.ceil(Math.max(0, dataLength - firstLimit) / limit) + 1
: 0
const maxGroupKey = dataLength
? Math.ceil(Math.max(0, dataLength - firstLimit) / limit) + 1
: 0
// Gallery configuration
const igConfig = {
@@ -300,19 +300,19 @@ document.addEventListener('DOMContentLoaded', () => {
let isLayoutHidden = false
// Utility functions
const sanitizeString = str => String(str ?? '')
.replace(/&/g, '&')
.replace(/"/g, '"')
.replace(/'/g, ''')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
const sanitizeString = str => String(str ?? '')
.replace(/&/g, '&amp;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#39;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
const createImageItem = item => {
const alt = item.alt ? `alt="${sanitizeString(item.alt)}"` : ''
const title = item.title ? `title="${sanitizeString(item.title)}"` : ''
const url = item.url ? sanitizeString(item.url) : ''
const url = item.url ? sanitizeString(item.url) : ''
return `<div class="item">
<img src="${url}" data-grid-maintained-target="true" ${alt} ${title} />
<img src="${url}" data-grid-maintained-target="true" ${alt} ${title} />
</div>`
}
@@ -381,13 +381,13 @@ document.addEventListener('DOMContentLoaded', () => {
btf.setLoading.add(container)
ig.on('renderComplete', handleRenderComplete)
if (isButton && dataLength) {
if (isButton && dataLength) {
appendItems(1, firstLimit, true)
} else if (dataLength) {
} else if (dataLength) {
ig.on('requestAppend', handleRequestAppend)
ig.renderItems()
} else {
btf.setLoading.remove(container)
} else {
btf.setLoading.remove(container)
}
btf.addGlobalFn('pjaxSendOnce', () => ig.destroy())
@@ -412,9 +412,9 @@ document.addEventListener('DOMContentLoaded', () => {
container.textContent = ''
try {
const data = element.getAttribute('data-type') === 'url' ? await fetchUrl(content) : JSON.parse(content)
if (!Array.isArray(data)) throw new TypeError('Gallery data must be an array')
if (!Array.isArray(data)) throw new TypeError('Gallery data must be an array')
runJustifiedGallery(container, data, config)
element.classList.add('loaded')
element.classList.add('loaded')
} catch (error) {
console.error('Gallery data parsing failed:', error)
}
@@ -456,7 +456,7 @@ document.addEventListener('DOMContentLoaded', () => {
// 檢查文檔高度是否小於視窗高度
const checkDocumentHeight = () => {
if (document.body.scrollHeight <= window.innerHeight + 56) {
if (document.body.scrollHeight <= window.innerHeight + 56) {
$rightside.classList.add('rightside-show')
return true
}
@@ -472,8 +472,8 @@ document.addEventListener('DOMContentLoaded', () => {
let flag = ''
const scrollTask = btf.rafThrottle(() => {
if (checkDocumentHeight()) return
if (checkDocumentHeight()) return
const currentTop = window.scrollY || document.documentElement.scrollTop
const isDown = scrollDirection(currentTop)
if (currentTop > 56) {
@@ -501,14 +501,14 @@ document.addEventListener('DOMContentLoaded', () => {
$header.classList.remove('nav-fixed', 'nav-visible')
}
$rightside.classList.remove('rightside-show')
}
isShowPercent && rightsideScrollPercent(currentTop)
})
checkDocumentHeight()
btf.addEventListenerPjax(window, 'scroll', scrollTask, { passive: true })
}
}
isShowPercent && rightsideScrollPercent(currentTop)
})
checkDocumentHeight()
btf.addEventListenerPjax(window, 'scroll', scrollTask, { passive: true })
}
/**
* toc, anchor
@@ -995,8 +995,11 @@ document.addEventListener('DOMContentLoaded', () => {
GLOBAL_CONFIG_SITE.pageType === 'home' && scrollDownInIndex()
scrollFn()
forPostFn()
GLOBAL_CONFIG_SITE.pageType !== 'shuoshuo' && btf.switchComments(document)
if (GLOBAL_CONFIG_SITE.pageType !== 'shuoshuo') {
forPostFn()
btf.switchComments(document)
}
openMobileMenu()
}
@@ -1012,4 +1015,6 @@ document.addEventListener('DOMContentLoaded', () => {
fn()
})
})
document.addEventListener('shuoshuo:rendered', forPostFn)
})