diff --git a/_config.yml b/_config.yml index 8316d81..0f70126 100644 --- a/_config.yml +++ b/_config.yml @@ -158,7 +158,7 @@ subtitle: # Choose: false/1/2/3 # false - disable the function # 1 - hitokoto.cn - # 2 - yijuzhan.com + # 2 - https://api.aa1.cn/doc/yiyan.html # 3 - jinrishici.com source: false # If you close the typewriter effect, the subtitle will only show the first line of sub diff --git a/layout/includes/third-party/abcjs/abcjs.pug b/layout/includes/third-party/abcjs/abcjs.pug index 453f84b..9de2b97 100644 --- a/layout/includes/third-party/abcjs/abcjs.pug +++ b/layout/includes/third-party/abcjs/abcjs.pug @@ -1,17 +1,46 @@ script. - (() => { - const abcjsInit = () => { - const abcjsFn = () => setTimeout(() => { - document.querySelectorAll(".abc-music-sheet").forEach(ele => { - if (ele.children.length > 0) return - ABCJS.renderAbc(ele, ele.innerHTML, {responsive: 'resize'}) - }) - }, 100) - - typeof ABCJS === 'object' ? abcjsFn() - : btf.getScript('!{url_for(theme.asset.abcjs_basic_js)}').then(abcjsFn) + (function() { + const abcjsInit = function() { + const abcjsFn = function() { + setTimeout(function() { + const sheets = document.querySelectorAll(".abc-music-sheet") + for (let i = 0; i < sheets.length; i++) { + const ele = sheets[i] + if (ele.children.length > 0) continue + + // Parse parameters from data-params attribute + let params = {} + const dp = ele.getAttribute("data-params") + if (dp) { + try { + params = JSON.parse(dp) + } catch (e) { + console.error("Failed to parse data-params:", e) + } + } + + // Merge parsed parameters with the responsive option + // Ensures params content appears before responsive + const options = { ...params, responsive: "resize" } + + // Render the music score using ABCJS.renderAbc + ABCJS.renderAbc(ele, ele.innerHTML, options) + } + }, 100) + } + + if (typeof ABCJS === "object") { + abcjsFn() + } else { + btf.getScript("!{url_for(theme.asset.abcjs_basic_js)}").then(abcjsFn) + } } - window.pjax ? abcjsInit() : window.addEventListener('load', abcjsInit) - btf.addGlobalFn('encrypt', abcjsInit, 'abcjs') - })() \ No newline at end of file + if (window.pjax) { + abcjsInit() + } else { + window.addEventListener("load", abcjsInit) + } + + btf.addGlobalFn("encrypt", abcjsInit, "abcjs") + })() diff --git a/layout/includes/third-party/pjax.pug b/layout/includes/third-party/pjax.pug index a8094f1..94ec038 100644 --- a/layout/includes/third-party/pjax.pug +++ b/layout/includes/third-party/pjax.pug @@ -59,7 +59,10 @@ script. document.addEventListener('pjax:error', e => { if (e.request.status === 404) { - window.location.href = e.request.responseURL + const usePjax = !{theme.pjax && theme.pjax.enable} + !{theme.error_404 && theme.error_404.enable} + ? (usePjax ? pjax.loadUrl('!{url_for("/404.html")}') : window.location.href = '!{url_for("/404.html")}') + : window.location.href = e.request.responseURL } }) - })() \ No newline at end of file + })() diff --git a/layout/includes/third-party/subtitle.pug b/layout/includes/third-party/subtitle.pug index 3969604..0d0c523 100644 --- a/layout/includes/third-party/subtitle.pug +++ b/layout/includes/third-party/subtitle.pug @@ -1,4 +1,4 @@ -- const { effect,source,sub,typed_option } = theme.subtitle +- const { effect, source, sub, typed_option } = theme.subtitle - let subContent = sub || new Array() script. @@ -22,6 +22,26 @@ script. } else { subtitleType() } + }, + processSubtitle: (content, extraContents = []) => { + if (!{effect}) { + const sub = !{JSON.stringify(subContent)}.slice() + + if (extraContents.length > 0) { + sub.unshift(...extraContents) + } + + if (typeof content === 'string') { + sub.unshift(content) + } else if (Array.isArray(content)) { + sub.unshift(...content) + } + + sub.length > 0 && typedJSFn.init(sub) + } else { + document.getElementById('subtitle').textContent = typeof content === 'string' ? content : + (Array.isArray(content) && content.length > 0 ? content[0] : '') + } } } btf.addGlobalFn('pjaxSendOnce', () => { typed.destroy() }, 'typedDestroy') @@ -33,14 +53,12 @@ case source fetch('https://v1.hitokoto.cn') .then(response => response.json()) .then(data => { - if (!{effect}) { - const from = '出自 ' + data.from - const sub = !{JSON.stringify(subContent)} - sub.unshift(data.hitokoto, from) - typedJSFn.init(sub) - } else { - document.getElementById('subtitle').textContent = data.hitokoto - } + const from = '出自 ' + data.from + typedJSFn.processSubtitle(data.hitokoto, [from]) + }) + .catch(err => { + console.error('Failed to get the Hitokoto API:', err) + typedJSFn.processSubtitle(!{JSON.stringify(subContent)}) }) } typedJSFn.run(subtitleType) @@ -48,46 +66,48 @@ case source when 2 script. function subtitleType () { - btf.getScript('https://yijuzhan.com/api/word.php?m=js').then(() => { - const con = str[0] - if (!{effect}) { - const from = '出自 ' + str[1] - const sub = !{JSON.stringify(subContent)} - sub.unshift(con, from) - typedJSFn.init(sub) - } else { - document.getElementById('subtitle').textContent = con - } - }) + fetch('https://v.api.aa1.cn/api/yiyan/index.php') + .then(response => response.text()) + .then(data => { + const reg = /
(.*?)<\/p>/g + const result = reg.exec(data) + if (result && result[1]) { + typedJSFn.processSubtitle(result[1]) + } else { + throw new Error('Failed to parse the return value of the Yiyan API') + } + }) + .catch(err => { + console.error('Failed to get the Yiyan API:', err) + typedJSFn.processSubtitle(!{JSON.stringify(subContent.length)}) + }) } typedJSFn.run(subtitleType) when 3 script. function subtitleType () { - btf.getScript('https://sdk.jinrishici.com/v2/browser/jinrishici.js').then(() => { - jinrishici.load(result =>{ - if (!{effect}) { - const sub = !{JSON.stringify(subContent)} - const content = result.data.content - sub.unshift(content) - typedJSFn.init(sub) - } else { - document.getElementById('subtitle').textContent = result.data.content - } + btf.getScript('https://sdk.jinrishi8ci.com/v2/browser/jinrishici.js') + .then(() => { + jinrishici.load(result => { + if (result && result.data && result.data.content) { + typedJSFn.processSubtitle(result.data.content) + } else { + throw new Error('Failed to parse the return value of Jinrishici API') + } + }) + }) + .catch(err => { + console.error('Failed to get the Jinrishici API:', err) + typedJSFn.processSubtitle(!{JSON.stringify(subContent.length)}) }) - }) } typedJSFn.run(subtitleType) default - - subContent = subContent.length ? subContent : new Array(config.subtitle) - script. - function subtitleType () { - if (!{effect}) { - typedJSFn.init(!{JSON.stringify(subContent)}) - } else { - document.getElementById("subtitle").textContent = !{JSON.stringify(subContent[0])} + if subContent.length > 0 + script. + function subtitleType () { + typedJSFn.processSubtitle(!{JSON.stringify(subContent)}) } - } - typedJSFn.run(subtitleType) \ No newline at end of file + typedJSFn.run(subtitleType) \ No newline at end of file diff --git a/package.json b/package.json index 27543bf..4db56e4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "hexo-theme-butterfly", - "version": "5.3.3", + "version": "5.3.4", "description": "A Simple and Card UI Design theme for Hexo", "main": "package.json", "scripts": { diff --git a/plugins.yml b/plugins.yml index dd0e9d7..c79ad44 100644 --- a/plugins.yml +++ b/plugins.yml @@ -9,7 +9,7 @@ activate_power_mode: algolia_search: name: algoliasearch file: dist/lite/builds/browser.umd.js - version: 5.20.2 + version: 5.20.3 aplayer_css: name: aplayer file: dist/APlayer.min.css @@ -45,7 +45,7 @@ canvas_ribbon: chartjs: name: chart.js file: dist/chart.umd.js - version: 4.4.7 + version: 4.4.8 clickShowText: name: butterfly-extsrc file: dist/click-show-text.min.js @@ -66,12 +66,12 @@ docsearch_css: name: '@docsearch/css' other_name: docsearch-css file: dist/style.css - version: 3.8.3 + version: 3.9.0 docsearch_js: name: '@docsearch/js' other_name: docsearch-js file: dist/umd/index.js - version: 3.8.3 + version: 3.9.0 egjs_infinitegrid: name: '@egjs/infinitegrid' other_name: egjs-infinitegrid @@ -203,9 +203,9 @@ waline_css: name: '@waline/client' file: dist/waline.css other_name: waline - version: 3.5.2 + version: 3.5.5 waline_js: name: '@waline/client' file: dist/waline.js other_name: waline - version: 3.5.2 + version: 3.5.5 diff --git a/scripts/helpers/inject_head_js.js b/scripts/helpers/inject_head_js.js index 5598674..16e9b9a 100644 --- a/scripts/helpers/inject_head_js.js +++ b/scripts/helpers/inject_head_js.js @@ -89,7 +89,7 @@ hexo.extend.helper.register('inject_head_js', function () { darkmodeJs += ` const mediaQueryDark = window.matchMedia('(prefers-color-scheme: dark)') const mediaQueryLight = window.matchMedia('(prefers-color-scheme: light)') - + if (theme === undefined) { if (mediaQueryLight.matches) activateLightMode() else if (mediaQueryDark.matches) activateDarkMode() diff --git a/scripts/tag/score.js b/scripts/tag/score.js index dc380a5..df345e5 100644 --- a/scripts/tag/score.js +++ b/scripts/tag/score.js @@ -6,17 +6,45 @@ 'use strict' const score = (args, content) => { + // Escape HTML tags and some special characters, including curly braces const escapeHtmlTags = s => { const lookup = { '&': '&', '"': '"', - '\'': ''', + "'": ''', '<': '<', - '>': '>' + '>': '>', + '{': '{', + '}': '}' } - return s.replace(/[&"'<>]/g, c => lookup[c]) + return s.replace(/[&"'<>{}]/g, c => lookup[c]) } - return `