mirror of
https://github.com/jerryc127/hexo-theme-butterfly.git
synced 2026-08-08 11:38:42 +08:00
feat(shuoshuo): render hexo tag plugins and defer post features via event
This commit is contained in:
@@ -161,7 +161,7 @@
|
|||||||
container.innerHTML = content
|
container.innerHTML = content
|
||||||
|
|
||||||
window.lazyLoadInstance && window.lazyLoadInstance.update()
|
window.lazyLoadInstance && window.lazyLoadInstance.update()
|
||||||
btf.loadLightbox(document.querySelectorAll('#article-container img:not(.no-lightbox)'))
|
document.dispatchEvent(new Event('shuoshuo:rendered'))
|
||||||
}
|
}
|
||||||
|
|
||||||
const setupNavEvents = (nav) => {
|
const setupNavEvents = (nav) => {
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "hexo-theme-butterfly",
|
"name": "hexo-theme-butterfly",
|
||||||
"version": "5.6.1",
|
"version": "5.6.2",
|
||||||
"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": {
|
||||||
|
|||||||
+20
-1
@@ -157,8 +157,27 @@ hexo.extend.helper.register('shuoshuoFN', (data, page) => {
|
|||||||
processedData.forEach(item => {
|
processedData.forEach(item => {
|
||||||
const parsed = moment.utc(item.date)
|
const parsed = moment.utc(item.date)
|
||||||
item.date = moment.tz(parsed.format('YYYY-MM-DD HH:mm:ss'), timezone).format('YYYY-MM-DD HH:mm:ss')
|
item.date = moment.tz(parsed.format('YYYY-MM-DD HH:mm:ss'), timezone).format('YYYY-MM-DD HH:mm:ss')
|
||||||
// markdown
|
|
||||||
|
// Render the content using Hexo's rendering engine to process any tags or markdown
|
||||||
|
const mockPost = { content: item.content }
|
||||||
|
hexo.execFilterSync('before_post_render', mockPost, { context: hexo })
|
||||||
|
item.content = mockPost.content
|
||||||
|
|
||||||
|
const codeBlocks = []
|
||||||
|
item.content = item.content.replace(/<hexoPostRenderCodeBlock>([\s\S]*?)<\/hexoPostRenderCodeBlock>/g, (_, c) => {
|
||||||
|
codeBlocks.push(c)
|
||||||
|
return `<!--CODEBLOCK_${codeBlocks.length - 1}-->`
|
||||||
|
})
|
||||||
|
|
||||||
|
try {
|
||||||
|
item.content = hexo.extend.tag.env.renderString(item.content, {})
|
||||||
|
} catch (e) {
|
||||||
|
// ignore tag plugin errors, fallback to markdown-only rendering
|
||||||
|
}
|
||||||
|
|
||||||
item.content = hexo.render.renderSync({ text: item.content, engine: 'markdown' })
|
item.content = hexo.render.renderSync({ text: item.content, engine: 'markdown' })
|
||||||
|
|
||||||
|
item.content = item.content.replace(/<!--CODEBLOCK_(\d+)-->/g, (_, i) => codeBlocks[+i])
|
||||||
})
|
})
|
||||||
|
|
||||||
return processedData
|
return processedData
|
||||||
|
|||||||
+43
-38
@@ -267,23 +267,23 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
const fetchUrl = async url => {
|
const fetchUrl = async url => {
|
||||||
try {
|
try {
|
||||||
const response = await fetch(url)
|
const response = await fetch(url)
|
||||||
if (!response.ok) throw new Error(`HTTP ${response.status}`)
|
if (!response.ok) throw new Error(`HTTP ${response.status}`)
|
||||||
return await response.json()
|
return await response.json()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to fetch URL:', error)
|
console.error('Failed to fetch URL:', error)
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const runJustifiedGallery = (container, data, config) => {
|
const runJustifiedGallery = (container, data, config) => {
|
||||||
const { isButton, tabs } = config
|
const { isButton, tabs } = config
|
||||||
const limit = Math.max(1, Number(config.limit) || 20)
|
const limit = Math.max(1, Number(config.limit) || 20)
|
||||||
const firstLimit = Math.max(1, Number(config.firstLimit) || limit)
|
const firstLimit = Math.max(1, Number(config.firstLimit) || limit)
|
||||||
|
|
||||||
const dataLength = data.length
|
const dataLength = data.length
|
||||||
const maxGroupKey = dataLength
|
const maxGroupKey = dataLength
|
||||||
? Math.ceil(Math.max(0, dataLength - firstLimit) / limit) + 1
|
? Math.ceil(Math.max(0, dataLength - firstLimit) / limit) + 1
|
||||||
: 0
|
: 0
|
||||||
|
|
||||||
// Gallery configuration
|
// Gallery configuration
|
||||||
const igConfig = {
|
const igConfig = {
|
||||||
@@ -300,19 +300,19 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
let isLayoutHidden = false
|
let isLayoutHidden = false
|
||||||
|
|
||||||
// Utility functions
|
// Utility functions
|
||||||
const sanitizeString = str => String(str ?? '')
|
const sanitizeString = str => String(str ?? '')
|
||||||
.replace(/&/g, '&')
|
.replace(/&/g, '&')
|
||||||
.replace(/"/g, '"')
|
.replace(/"/g, '"')
|
||||||
.replace(/'/g, ''')
|
.replace(/'/g, ''')
|
||||||
.replace(/</g, '<')
|
.replace(/</g, '<')
|
||||||
.replace(/>/g, '>')
|
.replace(/>/g, '>')
|
||||||
|
|
||||||
const createImageItem = item => {
|
const createImageItem = item => {
|
||||||
const alt = item.alt ? `alt="${sanitizeString(item.alt)}"` : ''
|
const alt = item.alt ? `alt="${sanitizeString(item.alt)}"` : ''
|
||||||
const title = item.title ? `title="${sanitizeString(item.title)}"` : ''
|
const title = item.title ? `title="${sanitizeString(item.title)}"` : ''
|
||||||
const url = item.url ? sanitizeString(item.url) : ''
|
const url = item.url ? sanitizeString(item.url) : ''
|
||||||
return `<div class="item">
|
return `<div class="item">
|
||||||
<img src="${url}" data-grid-maintained-target="true" ${alt} ${title} />
|
<img src="${url}" data-grid-maintained-target="true" ${alt} ${title} />
|
||||||
</div>`
|
</div>`
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -381,13 +381,13 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
btf.setLoading.add(container)
|
btf.setLoading.add(container)
|
||||||
ig.on('renderComplete', handleRenderComplete)
|
ig.on('renderComplete', handleRenderComplete)
|
||||||
|
|
||||||
if (isButton && dataLength) {
|
if (isButton && dataLength) {
|
||||||
appendItems(1, firstLimit, true)
|
appendItems(1, firstLimit, true)
|
||||||
} else if (dataLength) {
|
} else if (dataLength) {
|
||||||
ig.on('requestAppend', handleRequestAppend)
|
ig.on('requestAppend', handleRequestAppend)
|
||||||
ig.renderItems()
|
ig.renderItems()
|
||||||
} else {
|
} else {
|
||||||
btf.setLoading.remove(container)
|
btf.setLoading.remove(container)
|
||||||
}
|
}
|
||||||
|
|
||||||
btf.addGlobalFn('pjaxSendOnce', () => ig.destroy())
|
btf.addGlobalFn('pjaxSendOnce', () => ig.destroy())
|
||||||
@@ -412,9 +412,9 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
container.textContent = ''
|
container.textContent = ''
|
||||||
try {
|
try {
|
||||||
const data = element.getAttribute('data-type') === 'url' ? await fetchUrl(content) : JSON.parse(content)
|
const data = element.getAttribute('data-type') === 'url' ? await fetchUrl(content) : JSON.parse(content)
|
||||||
if (!Array.isArray(data)) throw new TypeError('Gallery data must be an array')
|
if (!Array.isArray(data)) throw new TypeError('Gallery data must be an array')
|
||||||
runJustifiedGallery(container, data, config)
|
runJustifiedGallery(container, data, config)
|
||||||
element.classList.add('loaded')
|
element.classList.add('loaded')
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Gallery data parsing failed:', error)
|
console.error('Gallery data parsing failed:', error)
|
||||||
}
|
}
|
||||||
@@ -456,7 +456,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
|
|
||||||
// 檢查文檔高度是否小於視窗高度
|
// 檢查文檔高度是否小於視窗高度
|
||||||
const checkDocumentHeight = () => {
|
const checkDocumentHeight = () => {
|
||||||
if (document.body.scrollHeight <= window.innerHeight + 56) {
|
if (document.body.scrollHeight <= window.innerHeight + 56) {
|
||||||
$rightside.classList.add('rightside-show')
|
$rightside.classList.add('rightside-show')
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -472,8 +472,8 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
|
|
||||||
let flag = ''
|
let flag = ''
|
||||||
const scrollTask = btf.rafThrottle(() => {
|
const scrollTask = btf.rafThrottle(() => {
|
||||||
if (checkDocumentHeight()) return
|
if (checkDocumentHeight()) return
|
||||||
|
|
||||||
const currentTop = window.scrollY || document.documentElement.scrollTop
|
const currentTop = window.scrollY || document.documentElement.scrollTop
|
||||||
const isDown = scrollDirection(currentTop)
|
const isDown = scrollDirection(currentTop)
|
||||||
if (currentTop > 56) {
|
if (currentTop > 56) {
|
||||||
@@ -501,14 +501,14 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
$header.classList.remove('nav-fixed', 'nav-visible')
|
$header.classList.remove('nav-fixed', 'nav-visible')
|
||||||
}
|
}
|
||||||
$rightside.classList.remove('rightside-show')
|
$rightside.classList.remove('rightside-show')
|
||||||
}
|
}
|
||||||
|
|
||||||
isShowPercent && rightsideScrollPercent(currentTop)
|
isShowPercent && rightsideScrollPercent(currentTop)
|
||||||
})
|
})
|
||||||
|
|
||||||
checkDocumentHeight()
|
checkDocumentHeight()
|
||||||
btf.addEventListenerPjax(window, 'scroll', scrollTask, { passive: true })
|
btf.addEventListenerPjax(window, 'scroll', scrollTask, { passive: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* toc, anchor
|
* toc, anchor
|
||||||
@@ -995,8 +995,11 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
GLOBAL_CONFIG_SITE.pageType === 'home' && scrollDownInIndex()
|
GLOBAL_CONFIG_SITE.pageType === 'home' && scrollDownInIndex()
|
||||||
scrollFn()
|
scrollFn()
|
||||||
|
|
||||||
forPostFn()
|
if (GLOBAL_CONFIG_SITE.pageType !== 'shuoshuo') {
|
||||||
GLOBAL_CONFIG_SITE.pageType !== 'shuoshuo' && btf.switchComments(document)
|
forPostFn()
|
||||||
|
btf.switchComments(document)
|
||||||
|
}
|
||||||
|
|
||||||
openMobileMenu()
|
openMobileMenu()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1012,4 +1015,6 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
fn()
|
fn()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
document.addEventListener('shuoshuo:rendered', forPostFn)
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user