hexo-theme-shokax 0.4.13 → 0.4.15
Sign up to get free protection for your applications and to get access to all the features.
- package/_config.yml +10 -4
- package/layout/_partials/head/head.pug +3 -0
- package/layout/_partials/layout.pug +19 -15
- package/layout/_partials/post/nav.pug +5 -1
- package/package.json +3 -4
- package/scripts/generaters/script.js +32 -4
- package/scripts/plugin/index.js +3 -0
- package/source/js/_app/components/cloudflare.ts +19 -0
- package/source/js/_app/library/declare.d.ts +3 -0
- package/source/js/_app/library/scriptPjax.ts +0 -18
- package/source/js/_app/page/post.ts +2 -2
- package/source/js/_app/page/search.ts +2 -3
package/_config.yml
CHANGED
@@ -27,6 +27,13 @@ experiments:
|
|
27
27
|
optimizeLongPosts: false # 优化长文章,这能让长文章的FPS提升70%-150%并解决假死问题,但存在一些副作用
|
28
28
|
# 具体见https://docs.kaitaku.xyz/guide/theme.html#%E9%95%BF%E6%96%87%E7%AB%A0%E4%BC%98%E5%8C%96
|
29
29
|
mobileWidth: 820px # 移动版和桌面版导航栏最短切换长度
|
30
|
+
# 使用 Cloudflare Rocket 或其他优化功能时需开启下列补丁,否则主题无法渲染
|
31
|
+
cloudflarePatch: false
|
32
|
+
coverConfig:
|
33
|
+
enableCover: true # 是否开启头图
|
34
|
+
enablePreload: true #是否开启预加载头图
|
35
|
+
enableNextGradientCover: false # 使用CSS渐变作为上/下一页封面
|
36
|
+
copyrightLength: 50 # 自定义复制时显示copyright的长度
|
30
37
|
|
31
38
|
homeConfig:
|
32
39
|
gradient: false # 使用CSS渐变作为文章封面
|
@@ -95,13 +102,13 @@ polyfill:
|
|
95
102
|
# 参阅 https://github.com/D-Sketon/mouse-firework
|
96
103
|
fireworks:
|
97
104
|
enable: true
|
98
|
-
options:
|
105
|
+
options:
|
99
106
|
excludeElements: ["a"]
|
100
107
|
particles:
|
101
108
|
- shape: circle
|
102
109
|
move: ["emit"]
|
103
110
|
easing: easeOutExpo
|
104
|
-
colors:
|
111
|
+
colors:
|
105
112
|
- "rgba(255,182,185,.9)"
|
106
113
|
- "rgba(250,227,217,.9)"
|
107
114
|
- "rgba(187,222,214,.9)"
|
@@ -221,7 +228,6 @@ summary:
|
|
221
228
|
remote: "https://api.openai.com"
|
222
229
|
apikey: "key"
|
223
230
|
|
224
|
-
|
225
231
|
# Social Links
|
226
232
|
# Usage: `Key: permalink || icon || color`
|
227
233
|
# Key is the link label showing to end users.
|
@@ -397,4 +403,4 @@ vendors:
|
|
397
403
|
justifiedGallery:
|
398
404
|
source: cdnjs
|
399
405
|
url: justifiedGallery/3.8.1/css/justifiedGallery.min.css
|
400
|
-
sri: "sha384-V/1Ew9pYm8xpy/L9i078ZXT6HSEOrGC6KNFYLbXOdtqb3+c6brpGqVzZtEPSQOiz"
|
406
|
+
sri: "sha384-V/1Ew9pYm8xpy/L9i078ZXT6HSEOrGC6KNFYLbXOdtqb3+c6brpGqVzZtEPSQOiz"
|
@@ -8,16 +8,19 @@ if (theme.quicklink.ignores)
|
|
8
8
|
|
9
9
|
- var covers = _cover_index(page, 6)
|
10
10
|
- var enableFixedCover = theme.homeConfig?.fixedCover
|
11
|
+
- var enablePreload = theme.experiments?.coverConfig?.enablePreload
|
12
|
+
- var enableCover = theme.experiments?.coverConfig?.enableCover
|
11
13
|
|
12
14
|
doctype html
|
13
15
|
html(lang=page.language?page.language:config.language, style=theme.grayMode ? 'filter: grayscale(1);':'' )
|
14
16
|
head
|
15
17
|
!= partial('_partials/head/head.pug', {}, {cache: true})
|
16
|
-
if
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
18
|
+
if enablePreload && enableCover
|
19
|
+
if enableFixedCover
|
20
|
+
link(rel="preload" href=theme.homeConfig.fixedCover as="image" fetchpriority="high")
|
21
|
+
else
|
22
|
+
each image in covers
|
23
|
+
link(rel="preload" href=image as="image" fetchpriority="high")
|
21
24
|
|
22
25
|
!= partial('_partials/head/head_com.pug')
|
23
26
|
!= shokax_inject('head')
|
@@ -44,17 +47,18 @@ html(lang=page.language?page.language:config.language, style=theme.grayMode ? 'f
|
|
44
47
|
|
45
48
|
!= partial('_partials/header.pug', {}, {cache: true})
|
46
49
|
div(id="imgs" class="pjax")
|
47
|
-
if
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
if covers.length === 6
|
53
|
-
ul
|
54
|
-
each image in covers
|
55
|
-
li(class="item" style=`background-image: url("${image}");`)
|
50
|
+
if enableCover
|
51
|
+
if theme.homeConfig.gradient || enableFixedCover
|
52
|
+
//- cover不可用时用Bing随机图片代替
|
53
|
+
- var coverImage = theme.homeConfig?.fixedCover || "https://7ed.net/bing/api"
|
54
|
+
img(src=coverImage loading="eager" decoding="async" fetchpriority="high" alt=title)
|
56
55
|
else
|
57
|
-
|
56
|
+
if covers.length === 6
|
57
|
+
ul
|
58
|
+
each image in covers
|
59
|
+
li(class="item" style=`background-image: url("${image}");`)
|
60
|
+
else
|
61
|
+
img(src=covers loading="eager" decoding="async" fetchpriority="high" alt=title)
|
58
62
|
div(id="waves")
|
59
63
|
svg(class="waves" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 24 150 28" preserveAspectRatio="none" shape-rendering="auto")
|
60
64
|
defs
|
@@ -1,8 +1,12 @@
|
|
1
1
|
mixin navpost(item, type)
|
2
|
+
- var enableNextGradientCover = theme?.experiments?.coverConfig?.enableNextGradientCover
|
2
3
|
- var postText = item.title || item.link || __('post.untitled')
|
3
4
|
- var lastcat = item.categories.last()
|
4
5
|
- var itemlink = `<span class="type">${__('post.' + type)}</span>${lastcat && lastcat.name ? `<span class="category"><i class="ic i-flag"></i>${lastcat.name}</span>` : ''}<h3>${postText}</h3>`
|
5
|
-
|
6
|
+
if enableNextGradientCover
|
7
|
+
!= _url(item.path, itemlink, {itemprop: 'url', rel: type, title: postText, style: `background-image: linear-gradient(to bottom right, ${random_color()}, ${random_color()});`})
|
8
|
+
else
|
9
|
+
!= _url(item.path, itemlink, {itemprop: 'url', rel: type, 'data-background-image': _cover(item), title: postText})
|
6
10
|
|
7
11
|
div(class="post-nav")
|
8
12
|
div(class="item left")
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "hexo-theme-shokax",
|
3
|
-
"version": "0.4.
|
3
|
+
"version": "0.4.15",
|
4
4
|
"description": "a hexo theme based on shoka",
|
5
5
|
"main": "index.js",
|
6
6
|
"repository": "https://github.com/theme-shoka-x/hexo-theme-shokaX",
|
@@ -30,7 +30,7 @@
|
|
30
30
|
"@algolia/client-search": "^5.5.3",
|
31
31
|
"@waline/client": "^3.3.2",
|
32
32
|
"algoliasearch": "5.5.3",
|
33
|
-
"esbuild": "^0.
|
33
|
+
"esbuild": "^0.24.0",
|
34
34
|
"hexo": "^7.3.0",
|
35
35
|
"hexo-algoliasearch": "^2.0.1",
|
36
36
|
"hexo-feed": "^1.1.2",
|
@@ -46,8 +46,7 @@
|
|
46
46
|
"theme-shokax-anime": "^0.0.7",
|
47
47
|
"theme-shokax-pjax": "^0.0.3",
|
48
48
|
"twikoo": "^1.6.39",
|
49
|
-
"unlazy": "^0.11.3"
|
50
|
-
"vue": "^3.5.7"
|
49
|
+
"unlazy": "^0.11.3"
|
51
50
|
},
|
52
51
|
"engines": {
|
53
52
|
"node": ">=18.0.0"
|
@@ -64,6 +64,9 @@ hexo.extend.generator.register("script", function(locals) {
|
|
64
64
|
priority: theme.quicklink.priority
|
65
65
|
},
|
66
66
|
playerAPI: theme.playerAPI,
|
67
|
+
experiments: {
|
68
|
+
copyrightLength: theme.experiments.copyrightLength
|
69
|
+
},
|
67
70
|
audio: void 0,
|
68
71
|
fireworks: theme.fireworks && theme.fireworks.enable && theme.fireworks.options ? theme.fireworks.options : void 0,
|
69
72
|
waline: {
|
@@ -93,10 +96,12 @@ hexo.extend.generator.register("script", function(locals) {
|
|
93
96
|
if (theme?.audio) {
|
94
97
|
siteConfig.audio = theme.audio;
|
95
98
|
}
|
96
|
-
let enterPoint;
|
99
|
+
let enterPoint, patchDir;
|
97
100
|
if (import_node_fs.default.existsSync("themes/shokaX/source/js/_app/pjax/siteInit.ts")) {
|
101
|
+
patchDir = "themes/shokaX/source/js/_app/components/cloudflare.ts";
|
98
102
|
enterPoint = "themes/shokaX/source/js/_app/pjax/siteInit.ts";
|
99
103
|
} else {
|
104
|
+
patchDir = "node_modules/hexo-theme-shokax/source/js/_app/components/cloudflare.ts";
|
100
105
|
enterPoint = "node_modules/hexo-theme-shokax/source/js/_app/pjax/siteInit.ts";
|
101
106
|
}
|
102
107
|
(0, import_esbuild.buildSync)({
|
@@ -134,9 +139,6 @@ hexo.extend.generator.register("script", function(locals) {
|
|
134
139
|
__shokax_twikoo__: theme.twikoo.enable ? "true" : "false",
|
135
140
|
shokax_CONFIG: JSON.stringify(siteConfig),
|
136
141
|
shokax_siteURL: "'" + config.url + "'"
|
137
|
-
},
|
138
|
-
alias: {
|
139
|
-
"algoliasearch/lite": "algoliasearch/dist/algoliasearch-lite.esm.browser.js"
|
140
142
|
}
|
141
143
|
});
|
142
144
|
const res = [];
|
@@ -167,5 +169,31 @@ hexo.extend.generator.register("script", function(locals) {
|
|
167
169
|
});
|
168
170
|
}
|
169
171
|
});
|
172
|
+
if (theme.experiments.cloudflarePatch) {
|
173
|
+
const result = (0, import_esbuild.buildSync)({
|
174
|
+
entryPoints: [patchDir],
|
175
|
+
bundle: true,
|
176
|
+
platform: "browser",
|
177
|
+
format: "iife",
|
178
|
+
tsconfigRaw: {
|
179
|
+
compilerOptions: {
|
180
|
+
target: "ES2022",
|
181
|
+
esModuleInterop: true,
|
182
|
+
module: "ESNext",
|
183
|
+
moduleResolution: "Node",
|
184
|
+
skipLibCheck: true
|
185
|
+
}
|
186
|
+
},
|
187
|
+
target: ["es2022"],
|
188
|
+
minify: true,
|
189
|
+
outfile: "cf-patch.js"
|
190
|
+
});
|
191
|
+
res.push({
|
192
|
+
path: theme.js + "/cf-patch.js",
|
193
|
+
data: function() {
|
194
|
+
return result;
|
195
|
+
}
|
196
|
+
});
|
197
|
+
}
|
170
198
|
return res;
|
171
199
|
});
|
package/scripts/plugin/index.js
CHANGED
@@ -31,6 +31,9 @@ var fs = __toESM(require("node:fs"));
|
|
31
31
|
hexo.on("generateBefore", () => {
|
32
32
|
(0, import_injects.default)(hexo);
|
33
33
|
fs.rmSync("./shokaxTemp", { force: true, recursive: true });
|
34
|
+
if (fs.existsSync("cf-patch.js")) {
|
35
|
+
fs.unlinkSync("cf-patch.js");
|
36
|
+
}
|
34
37
|
if (fs.existsSync("request.lock")) {
|
35
38
|
fs.unlinkSync("request.lock");
|
36
39
|
}
|
@@ -0,0 +1,19 @@
|
|
1
|
+
// rocket-loader & Auto minify(cloudflare) 补丁
|
2
|
+
// cloudflare 的上述功能会导致DOMContentLoaded事件无法触发,此补丁会将DOMContentLoaded重定向为load事件
|
3
|
+
function cloudflareInit () {
|
4
|
+
let inCloudFlare = true
|
5
|
+
window.addEventListener('DOMContentLoaded', function () {
|
6
|
+
inCloudFlare = false
|
7
|
+
})
|
8
|
+
|
9
|
+
if (document.readyState === 'loading') {
|
10
|
+
window.addEventListener('load', function () {
|
11
|
+
if (inCloudFlare) {
|
12
|
+
window.dispatchEvent(new Event('DOMContentLoaded'))
|
13
|
+
console.log('%c ☁️cloudflare patch ' + '%c running', 'color: white; background: #ff8c00; padding: 5px 3px;', 'padding: 4px;border:1px solid #ff8c00')
|
14
|
+
}
|
15
|
+
})
|
16
|
+
}
|
17
|
+
}
|
18
|
+
|
19
|
+
cloudflareInit()
|
@@ -1,21 +1,3 @@
|
|
1
|
-
// rocket-loader & Auto minify(cloudflare) 补丁
|
2
|
-
// cloudflare 的上述功能会导致DOMContentLoaded事件无法触发,此补丁会将DOMContentLoaded重定向为load事件
|
3
|
-
export function cloudflareInit () {
|
4
|
-
let inCloudFlare = true
|
5
|
-
window.addEventListener('DOMContentLoaded', function () {
|
6
|
-
inCloudFlare = false
|
7
|
-
})
|
8
|
-
|
9
|
-
if (document.readyState === 'loading') {
|
10
|
-
window.addEventListener('load', function () {
|
11
|
-
if (inCloudFlare) {
|
12
|
-
window.dispatchEvent(new Event('DOMContentLoaded'))
|
13
|
-
console.log('%c ☁️cloudflare patch ' + '%c running', 'color: white; background: #ff8c00; padding: 5px 3px;', 'padding: 4px;border:1px solid #ff8c00')
|
14
|
-
}
|
15
|
-
})
|
16
|
-
}
|
17
|
-
}
|
18
|
-
|
19
1
|
export const getScript = (url: string,sri: string, callback?: Function, condition?: string): void => {
|
20
2
|
// url: 脚本文件的URL地址
|
21
3
|
// callback: 当脚本加载完成时要执行的回调函数
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import { $dom } from '../library/dom'
|
2
2
|
import { postFancybox } from './fancybox'
|
3
3
|
import { clipBoard, showtip } from '../globals/tools'
|
4
|
-
import { BODY } from '../globals/globalVars'
|
4
|
+
import { CONFIG, BODY } from '../globals/globalVars'
|
5
5
|
import { pageScroll, transition } from '../library/anime'
|
6
6
|
import { mediaPlayer } from '../player'
|
7
7
|
import { getDisplay, setDisplay, wrapObject } from '../library/proto'
|
@@ -22,7 +22,7 @@ export const postBeauty = () => {
|
|
22
22
|
}
|
23
23
|
|
24
24
|
const copyright = document.getElementById('copyright')
|
25
|
-
if (window.getSelection().toString().length >
|
25
|
+
if (window.getSelection().toString().length > CONFIG.experiments.copyrightLength && copyright) {
|
26
26
|
event.preventDefault()
|
27
27
|
const author = '# ' + (copyright.querySelector('.author') as HTMLElement).innerText
|
28
28
|
const link = '# ' + (copyright.querySelector('.link') as HTMLElement).innerText
|
@@ -1,10 +1,9 @@
|
|
1
|
-
import {
|
1
|
+
import { CONFIG, siteSearch } from '../globals/globalVars'
|
2
2
|
import { transition } from '../library/anime'
|
3
|
-
import { $dom } from '../library/dom'
|
4
3
|
import { searchBox, configure, stats, hits, pagination } from 'instantsearch.js/es/widgets'
|
5
4
|
import type { HitHighlightResult } from 'instantsearch.js/es/types/results'
|
6
5
|
import instantsearch from 'instantsearch.js'
|
7
|
-
import algoliasearch from 'algoliasearch/lite'
|
6
|
+
import { liteClient as algoliasearch } from 'algoliasearch/lite'
|
8
7
|
|
9
8
|
export function algoliaSearch (pjax) {
|
10
9
|
const search = instantsearch({
|