🔍 搜索功能改進:

- 新增本地搜索分頁配置 (enablePagination, hitsPerPage)
- 重構 Algolia 搜索邏輯,支援多索引和更好的錯誤處理
- 優化搜索 UI 樣式,包括分頁按鈕和響應式設計
- 改進搜索結果顯示,新增編號和更好的高亮處理

📦 依賴項更新:
- 更新 plugins.yml 中的多個插件版本 (abcjs, algolia, aplayer 等)
- 更新 package.json 版本號為 5.5.0

🎨 UI/UX 優化:
- 改進側邊欄和目錄的動畫效果
- 優化樣式佈局,調整寬度百分比
- 新增說說頁面的分頁導航組件
- 改進右側邊欄按鈕樣式

🐛 錯誤處理和代碼優化:
- 修復 Umami Analytics 的錯誤處理和數據驗證
- 改進懶加載圖片的正則表達式,避免匹配腳本標籤
- 移除未使用的變數和改進代碼結構
- 新增說說內容的 Markdown 渲染支援

🔧 其他改進:
- 更新翻譯功能,移除箭頭函數語法以提升相容性
This commit is contained in:
Jerry
2025-09-09 15:40:08 +08:00
parent ec1a226774
commit 67c95cee0c
33 changed files with 1479 additions and 450 deletions

View File

@@ -274,6 +274,10 @@ module.exports = {
preload: false,
top_n_per_article: 1,
unescape: false,
pagination: {
enable: false,
hitsPerPage: 8
},
CDN: null
},
docsearch: {

View File

@@ -1,6 +1,5 @@
const { deepMerge } = require('hexo-util')
const path = require('path')
const fs = require('fs')
// Cache default config to avoid repeated file reads
let cachedDefaultConfig = null

View File

@@ -1,7 +1,7 @@
/**
* Butterfly
* lazyload
* replace src to data-lazy-src
* Lazyload filter
* Replace src with data-lazy-src for lazy loading
*/
'use strict'
@@ -10,11 +10,28 @@ const urlFor = require('hexo-util').url_for.bind(hexo)
const lazyload = htmlContent => {
if (hexo.theme.config.lazyload.native) {
return htmlContent.replace(/(<img.*?)(>)/ig, '$1 loading=\'lazy\'$2')
// Use more precise replacement: only replace img tags in HTML, not content inside script tags
return htmlContent.replace(/(<img(?![^>]*?\bloading=)(?:\s[^>]*?)?>)(?![^<]*<\/script>)/gi, match => {
return match.replace(/>$/, ' loading=\'lazy\'>')
})
}
const bg = hexo.theme.config.lazyload.placeholder ? urlFor(hexo.theme.config.lazyload.placeholder) : 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'
return htmlContent.replace(/(<img.*? src=)/ig, `$1 "${bg}" data-lazy-src=`)
// Use more precise replacement: handle src attributes with double and single quotes, but avoid replacing content inside script tags
let result = htmlContent
// Handle src attributes with double quotes
result = result.replace(/(<img(?![^>]*?\bdata-lazy-src=)(?:\s[^>]*?)?\ssrc="([^"]+)")(?![^<]*<\/script>)/gi, (match, tag, src) => {
return tag.replace(`src="${src}"`, `src="${bg}" data-lazy-src="${src}"`)
})
// Handle src attributes with single quotes
result = result.replace(/(<img(?![^>]*?\bdata-lazy-src=)(?:\s[^>]*?)?\ssrc='([^']+)')(?![^<]*<\/script>)/gi, (match, tag, src) => {
return tag.replace(`src='${src}'`, `src='${bg}' data-lazy-src='${src}'`)
})
return result
}
hexo.extend.filter.register('after_render:html', data => {

View File

@@ -53,7 +53,7 @@ hexo.extend.helper.register('urlNoIndex', function (url = null, trailingIndex =
})
hexo.extend.helper.register('md5', function (path) {
return crypto.createHash('md5').update(decodeURI(this.url_for(path, {relative: false}))).digest('hex')
return crypto.createHash('md5').update(decodeURI(this.url_for(path, { relative: false }))).digest('hex')
})
hexo.extend.helper.register('injectHtml', data => {
@@ -70,7 +70,7 @@ hexo.extend.helper.register('findArchivesTitle', function (page, menu, date) {
const defaultTitle = this._p('page.archives')
if (!menu) return defaultTitle
const loop = (m) => {
const loop = m => {
for (const key in m) {
if (typeof m[key] === 'object') {
const result = loop(m[key])
@@ -86,7 +86,7 @@ hexo.extend.helper.register('findArchivesTitle', function (page, menu, date) {
return loop(menu) || defaultTitle
})
hexo.extend.helper.register('getBgPath', function(path) {
hexo.extend.helper.register('getBgPath', function (path) {
if (!path) return ''
const absoluteUrlPattern = /^(?:[a-z][a-z\d+.-]*:)?\/\//i
@@ -132,6 +132,8 @@ hexo.extend.helper.register('shuoshuoFN', (data, page) => {
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')
// markdown
item.content = hexo.render.renderSync({ text: item.content, engine: 'markdown' })
})
return finalResult