hexo-theme-shokax 0.5.0-dev-5c5076b → 0.5.0-dev-36bb58f

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -5,12 +5,11 @@
5
5
  - [x] 移除 pjax
6
6
  - [x] 移除 quicklink
7
7
  - [x] 移除 assetUrl 为基的动态 Vendor 机制
8
- - [ ] 移除 ShokaX Inject
8
+ - [x] 移除 ShokaX Inject
9
9
  - [ ] 引入新的 Inject 类技术 (长期)
10
10
  - [ ] 引入新的工作流程
11
- - [ ] 引入 CI 自动测试
12
- - [ ] 进行组件化重构 & 引入 Vue
13
11
  - [ ] 重构 player (暂时移除)
12
+ - [ ] 重构并修改代码块
14
13
  - [ ] 优化 menu 配置格式
15
14
  - [ ] 优化和异步化 Smart Bundle 技术
16
15
  - [ ] 优化 CSS 结构和加载
package/_config.yml CHANGED
@@ -34,6 +34,7 @@ experiments:
34
34
  enablePreload: true #是否开启预加载头图
35
35
  enableNextGradientCover: false # 使用CSS渐变作为上/下一页封面
36
36
  copyrightLength: 50 # 自定义复制时显示copyright的长度
37
+ antiFakeWebsite: true # 防止恶意网站伪装
37
38
 
38
39
  homeConfig:
39
40
  gradient: false # 使用CSS渐变作为文章封面
@@ -202,12 +203,12 @@ waline:
202
203
  lang: "zh-CN"
203
204
  locale: {} # https://waline.js.org/guide/features/i18n.html#%E8%87%AA%E5%AE%9A%E4%B9%89%E8%AF%AD%E8%A8%80
204
205
  emoji: # 表情包
205
- - https://unpkg.com/@waline/emojis@1.0.1/weibo
206
- - https://unpkg.com/@waline/emojis@1.0.1/alus
207
- - https://unpkg.com/@waline/emojis@1.0.1/bilibili
208
- - https://unpkg.com/@waline/emojis@1.0.1/qq
209
- - https://unpkg.com/@waline/emojis@1.0.1/tieba
210
- - https://unpkg.com/@waline/emojis@1.0.1/tw-emoji
206
+ # - https://unpkg.com/@waline/emojis@1.0.1/weibo
207
+ # - https://unpkg.com/@waline/emojis@1.0.1/alus
208
+ # - https://unpkg.com/@waline/emojis@1.0.1/bilibili
209
+ # - https://unpkg.com/@waline/emojis@1.0.1/qq
210
+ # - https://unpkg.com/@waline/emojis@1.0.1/tieba
211
+ # - https://unpkg.com/@waline/emojis@1.0.1/tw-emoji
211
212
  meta: # 可以填写的内容
212
213
  - nick
213
214
  - mail
@@ -221,12 +222,13 @@ waline:
221
222
 
222
223
  summary:
223
224
  enable: false
224
- introduce: "我是基于ChatGPT-turbo-3.5实现的AI助手,在此网站上负责整理和概括文章" # AI自我介绍
225
- mode: openai # openai/custom
226
- pricing: "trial" # trial为试用模板(3 RPM);pay为即用即付模板(60 RPM)
227
- openai:
228
- remote: "https://api.openai.com"
229
- apikey: "key"
225
+ introduce: "" # AI自我介绍
226
+ model:
227
+ apiKey:
228
+ apiUrl:
229
+ temperature:
230
+ initalPrompt:
231
+ concurrency: 5
230
232
 
231
233
  # Social Links
232
234
  # Usage: `Key: permalink || icon || color`
package/languages/en.yml CHANGED
@@ -67,6 +67,7 @@ footer:
67
67
  powered: "Powered by %s"
68
68
  total_views: Total Views
69
69
  total_visitors: Total Visitors
70
+ loading: "Loading..."
70
71
 
71
72
  counter:
72
73
  index:
@@ -109,6 +110,7 @@ symbol:
109
110
  comma: ", "
110
111
  period: ". "
111
112
  colon: ": "
113
+ space: " "
112
114
  year: "Y"
113
115
  month: "M"
114
116
 
package/languages/ja.yml CHANGED
@@ -67,6 +67,7 @@ footer:
67
67
  powered: "Powered by %s"
68
68
  total_views: 閲覧合計数
69
69
  total_visitors: 合計閲覧者数
70
+ loading: "ローディング..."
70
71
 
71
72
  counter:
72
73
  index:
@@ -109,6 +110,7 @@ symbol:
109
110
  comma: "、"
110
111
  period: "。"
111
112
  colon: ":"
113
+ space: " "
112
114
  year: 年
113
115
  month: 月
114
116
 
@@ -67,6 +67,7 @@ footer:
67
67
  powered: "基于 %s"
68
68
  total_views: 总访问量
69
69
  total_visitors: 总访客量
70
+ loading: "加载中..."
70
71
 
71
72
  counter:
72
73
  index:
@@ -109,6 +110,7 @@ symbol:
109
110
  comma: ","
110
111
  period: "。"
111
112
  colon: ":"
113
+ space: " "
112
114
  year: 年
113
115
  month: 月
114
116
 
@@ -67,6 +67,7 @@ footer:
67
67
  powered: "基於 %s"
68
68
  total_views: 總瀏覽次數
69
69
  total_visitors: 訪客總數
70
+ loading: "載入中..."
70
71
 
71
72
  counter:
72
73
  index:
@@ -109,6 +110,7 @@ symbol:
109
110
  comma: ","
110
111
  period: "。"
111
112
  colon: ":"
113
+ space: " "
112
114
  year: 年
113
115
  month: 月
114
116
 
@@ -67,6 +67,7 @@ footer:
67
67
  powered: "基於 %s"
68
68
  total_views: 總瀏覽次數
69
69
  total_visitors: 訪客總數
70
+ loading: "載入中..."
70
71
 
71
72
  counter:
72
73
  index:
@@ -109,6 +110,7 @@ symbol:
109
110
  comma: ","
110
111
  period: "。"
111
112
  colon: ":"
113
+ space: " "
112
114
  year: 年
113
115
  month: 月
114
116
 
@@ -14,9 +14,11 @@ html(lang=page.language?page.language:config.language, style=theme.grayMode ? 'f
14
14
  if enablePreload && enableCover
15
15
  if enableFixedCover
16
16
  link(rel="preload" href=theme.homeConfig.fixedCover as="image" fetchpriority="high")
17
- else
17
+ else if Array.isArray(covers)
18
18
  each image in covers
19
- link(rel="preload" href=image as="image" fetchpriority="high")
19
+ link(rel="preload" href!=image as="image" fetchpriority="high")
20
+ else
21
+ link(rel="preload" href!=covers as="image" fetchpriority="high")
20
22
 
21
23
  != partial('_partials/head/head_com.pug')
22
24
  != shokax_inject('head')
@@ -89,11 +91,13 @@ html(lang=page.language?page.language:config.language, style=theme.grayMode ? 'f
89
91
  else
90
92
  - audioValue = "undefined"
91
93
 
94
+ - var ccIcon = '<i class="ic i-creative-commons"></i>'
95
+ - var ccText = theme.creative_commons.license.toUpperCase()
92
96
  script(data-config type="text/javascript").
93
97
  var LOCAL = {
94
98
  ispost: !{is_post()},
95
- path: `#{_permapath(page.path)}`,
96
- favicon: {
99
+ path: `#{_permapath(page.path)}`,
100
+ favicon: {
97
101
  show: `#{__('favicon.show')}`,
98
102
  hide: `#{__('favicon.hide')}`
99
103
  },
@@ -102,6 +106,8 @@ html(lang=page.language?page.language:config.language, style=theme.grayMode ? 'f
102
106
  empty: "!{__('search.empty')}",
103
107
  stats: "!{__('search.stats')}"
104
108
  },
109
+ nocopy: "!{!!page.nocopy}",
110
+ copyright: `!{page.copyright !== false ? (page.nocopy === true ? __("tips.nocopy") : __("tips.copyright", ccIcon + ccText)) : undefined}`,
105
111
  copy_tex: #{!!page.math},
106
112
  katex: #{!!page.math},
107
113
  mermaid: #{!!page.mermaid},
@@ -137,4 +143,3 @@ html(lang=page.language?page.language:config.language, style=theme.grayMode ? 'f
137
143
  != shokax_inject('bodyEnd')
138
144
 
139
145
 
140
-
@@ -1,16 +1,19 @@
1
1
  div(class="meta")
2
- if date(post.date) !== date(post.updated) || time(post.date) !== time(post.updated)
3
- if theme.twikoo.enable || theme.waline.pageview
2
+ if theme.twikoo.enable || theme.waline.pageview
3
+ span(class="item")
4
4
  span(class="icon")
5
5
  i(class="ic i-eye")
6
- span 此文章已被阅读次数:
6
+ span(class="text")
7
+ !=__('footer.total_views') + __('symbol.colon')
7
8
  - var prefixedPath = post.path.startsWith('/') ? post.path : '/' + post.path
8
- span(id="twikoo_visitors" class="waline-pageview-count" data-path=prefixedPath) 正在加载...
9
+ span(id="twikoo_visitors" class="waline-pageview-count" data-path=prefixedPath)
10
+ !=__('footer.loading')
11
+ if date(post.date) !== date(post.updated) || time(post.date) !== time(post.updated)
9
12
  span(class="item")
10
13
  span(class="icon")
11
14
  i(class="ic i-calendar-check")
12
15
  span(class="text")
13
- != __('post.edited')
16
+ != __('post.edited') + __('symbol.space')
14
17
  time(title=__('post.modified') + __('symbol.colon') + full_date(post.updated) itemprop="dateModified" datetime=moment(post.updated).format())
15
18
  != date(post.updated)
16
19
 
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "hexo-theme-shokax",
3
- "version": "0.5.0-dev-5c5076b",
3
+ "version": "0.5.0-dev-36bb58f",
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",
7
7
  "author": "zkz098",
8
8
  "license": "AGPL-3.0-or-later",
9
- "packageManager": "pnpm@9.5.0",
9
+ "packageManager": "pnpm@10.6.5",
10
10
  "scripts": {
11
11
  "test": "tsc --build --verbose",
12
12
  "build": "node ./toolbox/compiler.mjs"
@@ -16,34 +16,40 @@
16
16
  "@types/jquery": "^3.5.32",
17
17
  "@types/js-yaml": "^4.0.9",
18
18
  "@types/katex": "^0.16.7",
19
- "@types/node": "^22.8.6",
20
- "@typescript-eslint/eslint-plugin": "^8.12.2",
21
- "@typescript-eslint/parser": "^8.12.2",
22
- "eslint": "^9.13.0",
19
+ "@types/node": "^22.13.10",
20
+ "@types/quicklink": "^2.3.4",
21
+ "@typescript-eslint/eslint-plugin": "^8.27.0",
22
+ "@typescript-eslint/parser": "^8.27.0",
23
+ "eslint": "^9.22.0",
23
24
  "eslint-config-standard": "~17",
24
- "eslint-plugin-vue": "^9.30.0",
25
- "glob": "^11.0.0",
26
- "typescript": "^5.6.3"
25
+ "eslint-plugin-vue": "^10.0.0",
26
+ "glob": "^11.0.1",
27
+ "typescript": "^5.8.2"
27
28
  },
28
29
  "dependencies": {
29
- "@algolia/client-search": "^5.12.0",
30
- "@waline/client": "^3.3.2",
31
- "algoliasearch": "5.12.0",
32
- "esbuild": "^0.24.0",
30
+ "@algolia/client-search": "^5.21.0",
31
+ "@common.js/p-limit": "^6.1.0",
32
+ "@waline/client": "^3.5.6",
33
+ "algoliasearch": "5.21.0",
34
+ "dompurify": "^3.2.4",
35
+ "es-toolkit": "^1.33.0",
36
+ "esbuild": "^0.25.1",
33
37
  "hexo": "^7.3.0",
34
38
  "hexo-algoliasearch": "^2.0.1",
35
39
  "hexo-feed": "^1.1.2",
36
- "hexo-fs": "^4.1.3",
40
+ "hexo-fs": "^5.0.0",
37
41
  "hexo-pagination": "^4.0.0",
38
42
  "hexo-renderer-pug": "^3.0.0",
39
43
  "hexo-util": "^3.3.0",
40
- "instantsearch.js": "^4.75.3",
44
+ "instantsearch.js": "^4.78.0",
41
45
  "js-yaml": "^4.1.0",
42
- "katex": "^0.16.11",
43
- "mouse-firework": "^0.0.6",
44
- "theme-shokax-anime": "^0.0.7",
45
- "twikoo": "^1.6.39",
46
- "unlazy": "^0.11.3"
46
+ "katex": "^0.16.21",
47
+ "mouse-firework": "^0.1.1",
48
+ "quicklink": "^2.3.0",
49
+ "theme-shokax-anime": "^0.0.8",
50
+ "theme-shokax-pjax": "^0.0.3",
51
+ "twikoo": "^1.6.41",
52
+ "unlazy": "^0.12.3"
47
53
  },
48
54
  "engines": {
49
55
  "node": ">=20.0.0"
@@ -60,6 +66,10 @@
60
66
  "object.fromentries": "npm:@nolyfill/object.fromentries@latest",
61
67
  "object.groupby": "npm:@nolyfill/object.groupby@latest",
62
68
  "object.values": "npm:@nolyfill/object.values@latest"
63
- }
69
+ },
70
+ "onlyBuiltDependencies": [
71
+ "esbuild",
72
+ "hexo-util"
73
+ ]
64
74
  }
65
75
  }
@@ -22,10 +22,10 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
22
22
  mod
23
23
  ));
24
24
  var import_hexo_util = require("hexo-util");
25
- var import_node_fs = __toESM(require("node:fs"));
25
+ var import_promises = __toESM(require("node:fs/promises"));
26
26
  var import_path = __toESM(require("path"));
27
27
  var import_js_yaml = __toESM(require("js-yaml"));
28
- hexo.extend.filter.register("before_generate", () => {
28
+ hexo.extend.filter.register("before_generate", async () => {
29
29
  if (hexo.config.theme_config) {
30
30
  hexo.theme.config = (0, import_hexo_util.deepMerge)(hexo.theme.config, hexo.config.theme_config);
31
31
  }
@@ -44,20 +44,25 @@ hexo.extend.filter.register("before_generate", () => {
44
44
  hexo.theme.config.style = {};
45
45
  for (const style of ["iconfont", "colors", "custom"]) {
46
46
  const custom_file = "source/_data/" + style + ".styl";
47
- if (import_node_fs.default.existsSync(custom_file)) {
47
+ try {
48
+ await import_promises.default.readFile(custom_file);
48
49
  hexo.theme.config.style[style] = import_path.default.resolve(hexo.base_dir, custom_file);
50
+ } catch {
49
51
  }
50
52
  }
51
53
  if (data.images && data.images.length > 0) {
52
54
  hexo.theme.config.image_list = data.images;
53
55
  } else {
54
- hexo.theme.config.image_list = import_js_yaml.default.load(import_node_fs.default.readFileSync(import_path.default.join(__dirname, "../../_images.yml"), { encoding: "utf-8" }));
56
+ hexo.theme.config.image_list = import_js_yaml.default.load(await import_promises.default.readFile(import_path.default.join(__dirname, "../../_images.yml"), { encoding: "utf-8" }));
55
57
  }
56
58
  if (data.images_index && data.images_index.length > 0) {
57
59
  hexo.theme.config.index_images = data.images_index;
58
- } else if (import_node_fs.default.existsSync(import_path.default.join(__dirname, "../../_images_index.yml"))) {
59
- hexo.theme.config.index_images = import_js_yaml.default.load(import_node_fs.default.readFileSync(import_path.default.join(__dirname, "../../_images_index.yml"), { encoding: "utf-8" }));
60
60
  } else {
61
- hexo.theme.config.index_images = data.index_images || [];
61
+ try {
62
+ const fileContent = await import_promises.default.readFile(import_path.default.join(__dirname, "../../_images_index.yml"), "utf-8");
63
+ hexo.theme.config.index_images = import_js_yaml.default.load(fileContent);
64
+ } catch (e) {
65
+ hexo.theme.config.index_images = data.index_images || [];
66
+ }
62
67
  }
63
68
  });
@@ -1,19 +1,20 @@
1
1
  "use strict";
2
- const fs = require("hexo-fs");
3
- hexo.extend.generator.register("images", function(locals) {
2
+ var import_promises = require("node:fs/promises");
3
+ hexo.extend.generator.register("images", async function(locals) {
4
4
  const theme = hexo.theme.config;
5
5
  const dir = "source/_data/" + theme.assets + "/";
6
- if (!fs.existsSync(dir)) {
6
+ try {
7
+ await (0, import_promises.readdir)(dir);
8
+ } catch (e) {
7
9
  return;
8
10
  }
9
11
  const result = [];
10
- const files = fs.listDirSync(dir);
11
- files.forEach((file) => {
12
+ const files = await (0, import_promises.readdir)(dir);
13
+ files.forEach(async (file) => {
14
+ const fileContent = await (0, import_promises.readFile)(dir + file);
12
15
  result.push({
13
16
  path: theme.assets + "/" + file,
14
- data: function() {
15
- return fs.createReadStream(dir + file);
16
- }
17
+ data: fileContent
17
18
  });
18
19
  });
19
20
  return result;
@@ -21,10 +21,10 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
21
21
  mod
22
22
  ));
23
23
  var import_package = __toESM(require("../../package.json"));
24
- var import_node_fs = __toESM(require("node:fs"));
24
+ var import_promises = __toESM(require("node:fs/promises"));
25
25
  var import_esbuild = require("esbuild");
26
26
  var import_utils = require("../utils");
27
- hexo.extend.generator.register("script", function(locals) {
27
+ hexo.extend.generator.register("script", async function(locals) {
28
28
  const config = hexo.config;
29
29
  const theme = hexo.theme.config;
30
30
  const siteConfig = {
@@ -39,10 +39,6 @@ hexo.extend.generator.register("script", function(locals) {
39
39
  darkmode: theme.darkmode,
40
40
  auto_dark: theme.auto_dark,
41
41
  auto_scroll: theme.auto_scroll,
42
- js: {
43
- copy_tex: (0, import_utils.getVendorLink)(hexo, theme.vendors.async_js.copy_tex),
44
- fancybox: (0, import_utils.getVendorLink)(hexo, theme.vendors.async_js.fancybox)
45
- },
46
42
  css: {
47
43
  katex: (0, import_utils.getVendorLink)(hexo, theme.vendors.css.katex),
48
44
  mermaid: {
@@ -93,14 +89,15 @@ hexo.extend.generator.register("script", function(locals) {
93
89
  siteConfig.audio = theme.audio;
94
90
  }
95
91
  let enterPoint, patchDir;
96
- if (import_node_fs.default.existsSync("themes/shokaX/source/js/_app/pjax/siteInit.ts")) {
97
- patchDir = "themes/shokaX/source/js/_app/components/cloudflare.ts";
92
+ try {
93
+ await import_promises.default.readFile("themes/shokaX/source/js/_app/pjax/siteInit.ts", "utf-8");
98
94
  enterPoint = "themes/shokaX/source/js/_app/pjax/siteInit.ts";
99
- } else {
100
- patchDir = "node_modules/hexo-theme-shokax/source/js/_app/components/cloudflare.ts";
95
+ patchDir = "themes/shokaX/source/js/_app/components/cloudflare.ts";
96
+ } catch (e) {
101
97
  enterPoint = "node_modules/hexo-theme-shokax/source/js/_app/pjax/siteInit.ts";
98
+ patchDir = "node_modules/hexo-theme-shokax/source/js/_app/components/cloudflare.ts";
102
99
  }
103
- (0, import_esbuild.buildSync)({
100
+ const result = await (0, import_esbuild.build)({
104
101
  entryPoints: [enterPoint],
105
102
  bundle: true,
106
103
  outdir: "shokaxTemp",
@@ -133,40 +130,33 @@ hexo.extend.generator.register("script", function(locals) {
133
130
  __shokax_fancybox__: theme.modules.fancybox ? "true" : "false",
134
131
  __shokax_waline__: theme.waline.enable ? "true" : "false",
135
132
  __shokax_twikoo__: theme.twikoo.enable ? "true" : "false",
133
+ __shokax_antiFakeWebsite__: theme.experiments.antiFakeWebsite ? "true" : "false",
136
134
  shokax_CONFIG: JSON.stringify(siteConfig),
137
135
  shokax_siteURL: "'" + config.url + "'"
138
136
  }
139
137
  });
140
138
  const res = [];
141
- import_node_fs.default.readdirSync("./shokaxTemp").forEach((file) => {
142
- const fileText = import_node_fs.default.readFileSync(`./shokaxTemp/${file}`, { encoding: "utf-8" });
143
- if (file.endsWith("js")) {
144
- const result = hexo.render.renderSync({ text: fileText, engine: "js" });
139
+ result.outputFiles.forEach((file) => {
140
+ const fileName = file.path.split("/").pop();
141
+ if (fileName.endsWith(".js")) {
145
142
  res.push({
146
- path: theme.js + "/" + file,
147
- data: function() {
148
- return result;
149
- }
143
+ path: theme.js + "/" + fileName,
144
+ data: file.text
150
145
  });
151
- } else if (file.endsWith("css")) {
152
- const result = hexo.render.renderSync({ text: fileText, engine: "css" });
146
+ } else if (fileName.endsWith(".css")) {
153
147
  res.push({
154
- path: theme.css + "/" + file,
155
- data: function() {
156
- return result;
157
- }
148
+ path: theme.css + "/" + fileName,
149
+ data: file.text
158
150
  });
159
151
  } else {
160
152
  res.push({
161
- path: theme.js + "/" + file,
162
- data: function() {
163
- return fileText;
164
- }
153
+ path: theme.js + "/" + fileName,
154
+ data: file.text
165
155
  });
166
156
  }
167
157
  });
168
158
  if (theme.experiments.cloudflarePatch) {
169
- const result = (0, import_esbuild.buildSync)({
159
+ const patchRes = await (0, import_esbuild.build)({
170
160
  entryPoints: [patchDir],
171
161
  bundle: true,
172
162
  platform: "browser",
@@ -186,9 +176,7 @@ hexo.extend.generator.register("script", function(locals) {
186
176
  });
187
177
  res.push({
188
178
  path: theme.js + "/cf-patch.js",
189
- data: function() {
190
- return import_node_fs.default.readFileSync("./cf-patch.js", { encoding: "utf-8" });
191
- }
179
+ data: patchRes.outputFiles[0].text
192
180
  });
193
181
  }
194
182
  return res;
@@ -0,0 +1,130 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __copyProps = (to, from, except, desc) => {
8
+ if (from && typeof from === "object" || typeof from === "function") {
9
+ for (let key of __getOwnPropNames(from))
10
+ if (!__hasOwnProp.call(to, key) && key !== except)
11
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
12
+ }
13
+ return to;
14
+ };
15
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
16
+ // If the importer is in node compatibility mode or this is not an ESM
17
+ // file that has been converted to a CommonJS file using a Babel-
18
+ // compatible transform (i.e. "__esModule" has not been set), then set
19
+ // "default" to the CommonJS "module.exports" for node compatibility.
20
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
21
+ mod
22
+ ));
23
+ var import_node_crypto = require("node:crypto");
24
+ var import_promises = __toESM(require("node:fs/promises"));
25
+ async function getSummaryByAPI(content) {
26
+ const apiKey = hexo.theme.config.summary.apiKey;
27
+ const apiUrl = hexo.theme.config.summary.apiUrl;
28
+ const model = hexo.theme.config.summary.model;
29
+ const temperature = hexo.theme.config.summary.temperature ?? 1.3;
30
+ const initalPrompt = hexo.theme.config.summary.initalPrompt;
31
+ const res = await fetch(apiUrl, {
32
+ method: "POST",
33
+ headers: {
34
+ "Content-Type": "application/json",
35
+ "Authorization": `Bearer ${apiKey}`
36
+ },
37
+ body: JSON.stringify({
38
+ model,
39
+ messages: [{
40
+ role: "system",
41
+ content: `${initalPrompt}`
42
+ }, {
43
+ role: "user",
44
+ content: `${content}`
45
+ }],
46
+ temperature
47
+ })
48
+ });
49
+ if (!res.ok) {
50
+ throw new Error(`Error: ${res.status} ${res.statusText}`);
51
+ }
52
+ const data = await res.json();
53
+ if (data.error) {
54
+ throw new Error(`Error: ${data.error.message}`);
55
+ }
56
+ const summary = data.choices[0].message.content;
57
+ return summary;
58
+ }
59
+ class SummaryDatabase {
60
+ fileChanged;
61
+ data;
62
+ constructor() {
63
+ this.fileChanged = false;
64
+ this.data = {
65
+ version: 2,
66
+ features: {
67
+ incremental: false
68
+ },
69
+ summaries: {}
70
+ };
71
+ }
72
+ async readDB() {
73
+ try {
74
+ await import_promises.default.access("summary.json");
75
+ this.data = JSON.parse(await import_promises.default.readFile("summary.json", "utf-8"));
76
+ } catch (error) {
77
+ }
78
+ if (this.data.version !== 2) {
79
+ throw new Error(`Incompatible version of summary database: ${this.data.version}`);
80
+ }
81
+ }
82
+ async writeDB() {
83
+ if (this.fileChanged) {
84
+ await import_promises.default.writeFile("summary.json", JSON.stringify(this.data));
85
+ }
86
+ }
87
+ async getPostSummary(path, content) {
88
+ const pathHash = (0, import_node_crypto.createHash)("sha256").update(path).digest("hex");
89
+ const contentHash = (0, import_node_crypto.createHash)("sha256").update(content).digest("hex");
90
+ if (this.data.summaries[pathHash]?.sha256 === contentHash) {
91
+ return this.data.summaries[pathHash].summary;
92
+ } else {
93
+ const summaryContent = await getSummaryByAPI(content);
94
+ this.data.summaries[pathHash] = {
95
+ summary: summaryContent,
96
+ sha256: contentHash
97
+ };
98
+ this.fileChanged = true;
99
+ return summaryContent;
100
+ }
101
+ }
102
+ }
103
+ hexo.extend.generator.register("summary_ai", async function(locals) {
104
+ const posts = locals.posts;
105
+ if (!hexo.theme.config.summary.enable) {
106
+ return;
107
+ }
108
+ const db = new SummaryDatabase();
109
+ await db.readDB();
110
+ const postArray = posts.toArray();
111
+ const pLimit = require("@common.js/p-limit").default;
112
+ const concurrencyLimit = pLimit(hexo.theme.config.summary?.concurrency || 5);
113
+ const processingPromises = postArray.map((post) => concurrencyLimit(async () => {
114
+ const content = post.content;
115
+ const path = post.path;
116
+ const published = post.published;
117
+ if (content && path && published && content.length > 0) {
118
+ try {
119
+ const summary = await db.getPostSummary(path, content);
120
+ post.summary = summary;
121
+ } catch (error) {
122
+ hexo.log.error(`[ShokaX Summary AI] \u5904\u7406\u6587\u7AE0 ${path} \u65F6\u51FA\u9519:`, error.message);
123
+ post.summary = `${error.message}`;
124
+ }
125
+ }
126
+ }));
127
+ await Promise.all(processingPromises);
128
+ await db.writeDB();
129
+ hexo.log.info(`[ShokaX Summary AI] \u6240\u6709\u6587\u7AE0\u6458\u8981\u5904\u7406\u5B8C\u6210\uFF0C\u5DF2\u4FDD\u5B58\u5230\u6570\u636E\u5E93`);
130
+ });
@@ -1,112 +1,5 @@
1
- var __create = Object.create;
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __getProtoOf = Object.getPrototypeOf;
6
- var __hasOwnProp = Object.prototype.hasOwnProperty;
7
- var __copyProps = (to, from, except, desc) => {
8
- if (from && typeof from === "object" || typeof from === "function") {
9
- for (let key of __getOwnPropNames(from))
10
- if (!__hasOwnProp.call(to, key) && key !== except)
11
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
12
- }
13
- return to;
14
- };
15
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
16
- // If the importer is in node compatibility mode or this is not an ESM
17
- // file that has been converted to a CommonJS file using a Babel-
18
- // compatible transform (i.e. "__esModule" has not been set), then set
19
- // "default" to the CommonJS "module.exports" for node compatibility.
20
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
21
- mod
22
- ));
23
- var import_node_fs = __toESM(require("node:fs"));
24
- function getContent(post) {
25
- return post?.raw ?? post?._content ?? post.content;
26
- }
27
- let db;
28
- function postMessage(path, content, dbPath, startMessage) {
29
- if (import_node_fs.default.existsSync("summary.json")) {
30
- db = JSON.parse(import_node_fs.default.readFileSync("summary.json", { encoding: "utf-8" }));
31
- } else {
32
- db = {};
33
- }
34
- const config = hexo.theme.config.summary;
35
- if (config.enable) {
36
- if (typeof db?.[path] !== "undefined" && typeof db?.[path]?.[dbPath] !== "undefined") {
37
- return db[path][dbPath];
38
- } else {
39
- if (typeof db?.[path] === "undefined") {
40
- db[path] = {};
41
- } else {
42
- db[path][dbPath] = "";
43
- }
44
- }
45
- if (config.mode === "openai") {
46
- const request = () => {
47
- fetch(`${config.openai.remote}/v1/chat/completions`, {
48
- method: "POST",
49
- headers: requestHeaders,
50
- body: JSON.stringify(requestBody)
51
- }).then((response) => {
52
- if (!response.ok) {
53
- throw Error("ERROR: Failed to get summary from Openai API");
54
- }
55
- response.json().then((data) => {
56
- const summary = data.choices[0].message.content;
57
- try {
58
- db[path][dbPath] = summary;
59
- } catch (e) {
60
- db ??= {};
61
- db[path] ??= {};
62
- db[path][dbPath] ??= "";
63
- db[path][dbPath] = summary;
64
- }
65
- import_node_fs.default.writeFileSync("summary.json", JSON.stringify(db));
66
- if (import_node_fs.default.existsSync("requested.lock")) {
67
- import_node_fs.default.unlinkSync("requested.lock");
68
- }
69
- return summary;
70
- });
71
- });
72
- };
73
- const checkTime = (waitTime) => {
74
- if (import_node_fs.default.existsSync("request.lock")) {
75
- if (import_node_fs.default.existsSync("requested.lock")) {
76
- setTimeout(checkTime, 1e3 * waitTime);
77
- return;
78
- }
79
- import_node_fs.default.writeFileSync("requested.lock", "");
80
- setTimeout(request, 1e3 * 2.5 * waitTime);
81
- import_node_fs.default.unlinkSync("request.lock");
82
- } else {
83
- import_node_fs.default.writeFileSync("request.lock", "");
84
- request();
85
- }
86
- };
87
- const requestHeaders = {
88
- "Content-Type": "application/json",
89
- Authorization: `Bearer ${config.openai.apikey}`
90
- };
91
- const requestBody = {
92
- model: "gpt-3.5-turbo",
93
- messages: [{ role: "user", content: `${startMessage} ${content}` }],
94
- temperature: 0.7
95
- };
96
- if (config.pricing === "trial") {
97
- hexo.log.info("Requesting OpenAI API... (3 RPM mode)");
98
- hexo.log.info("It may take 20 minutes or more (depending on the number of articles, each one takes 25 seconds)");
99
- checkTime(10);
100
- } else {
101
- hexo.log.info("Requesting OpenAI API... (60 RPM mode)");
102
- checkTime(0.5);
103
- }
104
- } else {
105
- }
106
- }
107
- }
108
1
  hexo.extend.helper.register("get_summary", (post) => {
109
- return postMessage(post.path, getContent(post), "summary", "\u8BF7\u4E3A\u4E0B\u8FF0\u6587\u7AE0\u63D0\u4F9B\u4E00\u4EFD200\u5B57\u4EE5\u5185\u7684\u6982\u62EC\uFF0C\u4F7F\u7528\u4E2D\u6587\u56DE\u7B54\u4E14\u5C3D\u53EF\u80FD\u7B80\u6D01: ");
2
+ return post.summary;
110
3
  });
111
4
  hexo.extend.helper.register("get_introduce", () => {
112
5
  return hexo.theme.config.summary.introduce;
@@ -1,75 +1,38 @@
1
- var __create = Object.create;
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __getProtoOf = Object.getPrototypeOf;
6
- var __hasOwnProp = Object.prototype.hasOwnProperty;
7
- var __copyProps = (to, from, except, desc) => {
8
- if (from && typeof from === "object" || typeof from === "function") {
9
- for (let key of __getOwnPropNames(from))
10
- if (!__hasOwnProp.call(to, key) && key !== except)
11
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
12
- }
13
- return to;
14
- };
15
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
16
- // If the importer is in node compatibility mode or this is not an ESM
17
- // file that has been converted to a CommonJS file using a Babel-
18
- // compatible transform (i.e. "__esModule" has not been set), then set
19
- // "default" to the CommonJS "module.exports" for node compatibility.
20
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
21
- mod
22
- ));
23
- var import_injects = __toESM(require("./lib/injects"));
24
1
  var import_package = require("../../package.json");
25
- var fs = __toESM(require("node:fs"));
26
- /*!
27
- index.js in next-theme/hexo-theme-next by next-theme
28
- under GNU AFFERO GENERAL PUBLIC LICENSE v3.0 OR LATER
29
- https://github.com/next-theme/hexo-theme-next/blob/master/LICENSE.md
30
- */
31
- hexo.on("generateBefore", () => {
32
- (0, import_injects.default)(hexo);
33
- fs.rmSync("./shokaxTemp", { force: true, recursive: true });
34
- if (fs.existsSync("cf-patch.js")) {
35
- fs.unlinkSync("cf-patch.js");
36
- }
37
- if (fs.existsSync("request.lock")) {
38
- fs.unlinkSync("request.lock");
39
- }
40
- if (fs.existsSync("requested.lock")) {
41
- fs.unlinkSync("requested.lock");
2
+ var import_promises = require("node:fs/promises");
3
+ hexo.on("generateBefore", async () => {
4
+ await (0, import_promises.rm)("./shokaxTemp", { force: true, recursive: true });
5
+ try {
6
+ (0, import_promises.unlink)("cf-patch.js");
7
+ } catch (e) {
42
8
  }
43
9
  });
44
- hexo.on("generateAfter", () => {
45
- fetch("https://api.shokax.top/version/hexo", { headers: {
46
- "User-Agent": "Mozilla/5.0 ShokaX Client (hexo-theme-shokax)"
47
- } }).then((res) => {
48
- res.json().then((resp) => {
49
- try {
50
- const latest = resp["version"];
51
- const current = import_package.version.split(".");
52
- let isOutdated = false;
53
- for (let i = 0; i < Math.max(latest.length, current.length); i++) {
54
- if (!current[i] || latest[i] > current[i]) {
55
- isOutdated = true;
56
- break;
57
- }
58
- if (latest[i] < current[i]) {
59
- break;
60
- }
61
- }
62
- if (isOutdated) {
63
- hexo.log.warn(`Your theme ShokaX is outdated. Current version: v${current.join(".")}, latest version: v${latest.join(".")}`);
64
- hexo.log.warn("Visit https://github.com/theme-shoka-x/hexo-theme-shokaX/releases for more information.");
65
- }
66
- } catch (e) {
67
- hexo.log.warn("Failed to detect version info. Error message:");
68
- hexo.log.warn(e);
10
+ hexo.on("generateAfter", async () => {
11
+ try {
12
+ const res = await fetch("https://registry.npmmirror.com/hexo-theme-shokax/latest", {
13
+ headers: {
14
+ "User-Agent": "ShokaX Client (hexo-theme-shokax)"
69
15
  }
70
- }).catch((e) => {
71
- hexo.log.warn("Failed to detect version info. Error message:");
72
- hexo.log.warn(e);
73
16
  });
74
- });
17
+ const resp = await res.json();
18
+ const latest = resp.version;
19
+ const current = import_package.version.split(".");
20
+ let isOutdated = false;
21
+ for (let i = 0; i < Math.max(latest.length, current.length); i++) {
22
+ if (!current[i] || latest[i] > current[i]) {
23
+ isOutdated = true;
24
+ break;
25
+ }
26
+ if (latest[i] < current[i]) {
27
+ break;
28
+ }
29
+ }
30
+ if (isOutdated) {
31
+ hexo.log.warn(`Your theme ShokaX is outdated. Current version: v${current.join(".")}, latest version: v${latest.join(".")}`);
32
+ hexo.log.warn("Visit https://github.com/theme-shoka-x/hexo-theme-shokaX/releases for more information.");
33
+ }
34
+ } catch (e) {
35
+ hexo.log.warn("Failed to detect version info. Error message:");
36
+ hexo.log.warn(e);
37
+ }
75
38
  });
@@ -5,7 +5,7 @@
5
5
  width: $sidebar-desktop;
6
6
  margin: 0;
7
7
  padding: 0;
8
- position: fixed;
8
+ position: sticky;
9
9
  bottom: .125rem;
10
10
 
11
11
  li {
@@ -1,5 +1,6 @@
1
1
  #sidebar {
2
2
  position: static;
3
+ overflow: scroll;
3
4
  width: $sidebar-desktop;
4
5
  top: 0;
5
6
  bottom: 0;
@@ -42,6 +43,7 @@
42
43
  padding: 4.6875rem 0 2rem;
43
44
  width: 100%;
44
45
  overflow: hidden;
46
+ min-height: 100vh;
45
47
 
46
48
  .inner {
47
49
  margin-top: 2.5rem;
@@ -145,7 +145,9 @@ export const sidebarTOC = () => {
145
145
 
146
146
  sections = sections.map((element, index) => {
147
147
  const link = element.querySelector('a.toc-link')
148
- const anchor = document.getElementById(decodeURI(link.getAttribute('href').replace('#', '')))
148
+ const linkHref = link.getAttribute('href')
149
+ if (!linkHref) return null
150
+ const anchor = document.getElementById(decodeURI(linkHref.replace('#', '')))
149
151
  if (!anchor) return null
150
152
  const alink = anchor.querySelector('a.anchor')
151
153
 
@@ -89,22 +89,33 @@ export const transition = (target: HTMLElement, type: number|string|Function, co
89
89
  }, animation)).play()
90
90
  }
91
91
 
92
- export const pageScroll = (target: HTMLElement|number, offset?: number, complete?: Function) => {
93
- // target: 滚动到的目标元素或坐标(number)
94
- // offset: 可选的偏移量
95
- // complete: 可选的回调函数,在动画完成时调用
96
- anime({
97
- // 动画目标
98
- targets: typeof offset === 'number' && typeof target !== 'number' ? target.parentNode : document.scrollingElement,
99
- // 动画持续时间
100
- duration: 500,
101
- // 动画缓动函数
102
- easing: 'easeInOutQuad',
103
- // 如果 offset 存在,则滚动到 offset,如果 target 是数字,则滚动到 target,如果 target 是 DOM 元素,则滚动到下述表达式
104
- scrollTop: offset || (typeof target === 'number' ? target : (target ? getTop(target) + document.documentElement.scrollTop - siteNavHeight : 0)),
105
- // 完成回调函数
106
- complete () {
107
- complete && complete()
108
- }
109
- }).play()
110
- }
92
+ export const pageScroll = (target: HTMLElement | number, offset?: number, complete?: Function) => {
93
+ // 确定滚动容器
94
+ const scrollContainer = (typeof offset === 'number' && typeof target !== 'number')
95
+ ? target.parentNode as HTMLElement
96
+ : document.scrollingElement || document.documentElement;
97
+
98
+ // 计算目标滚动位置
99
+ let scrollTop: number;
100
+ if (typeof offset !== 'undefined') {
101
+ scrollTop = offset;
102
+ } else if (typeof target === 'number') {
103
+ scrollTop = target;
104
+ } else if (target) {
105
+ const rect = target.getBoundingClientRect();
106
+ scrollTop = rect.top + window.scrollY - siteNavHeight;
107
+ } else {
108
+ scrollTop = 0;
109
+ }
110
+
111
+ // 执行平滑滚动
112
+ scrollContainer.scrollTo({
113
+ top: scrollTop,
114
+ behavior: 'smooth'
115
+ });
116
+
117
+ // 处理完成回调(模拟动画持续时间)
118
+ if (complete) {
119
+ setTimeout(() => complete(), 500); // 与原动画持续时间保持一致
120
+ }
121
+ };
@@ -127,3 +127,4 @@ declare const __shokax_waline__:boolean
127
127
  declare const __shokax_twikoo__:boolean
128
128
  declare const shokax_CONFIG:configType
129
129
  declare const shokax_siteURL:string
130
+ declare const __shokax_antiFakeWebsite__:boolean
@@ -1,10 +1,11 @@
1
1
  import { insertAfter } from '../library/proto'
2
+ import DOMPurify from 'dompurify';
2
3
 
3
4
  // TODO 使用PhotoSwipe替换Fancybox
4
5
  export const postFancybox = (p:string) => {
5
6
  if (document.querySelector(p + ' .md img')) {
6
- const q = jQuery.noConflict()
7
-
7
+ // vendorCss('fancybox')
8
+ // vendorCss('justifiedGallery')
8
9
  document.querySelectorAll(p + ' p.gallery').forEach((element) => {
9
10
  const box = document.createElement('div')
10
11
  box.className = 'gallery'
@@ -17,8 +18,8 @@ export const postFancybox = (p:string) => {
17
18
  })
18
19
 
19
20
  document.querySelectorAll(p + ' .md img:not(.emoji):not(.vemoji)').forEach((element) => {
20
- const $image = q(element)
21
- const imageLink = $image.attr('data-src') || $image.attr('src') // 替换
21
+ const $image = $(element)
22
+ const imageLink = DOMPurify.sanitize($image.attr('data-src') || $image.attr('src')) // 替换
22
23
  const $imageWrapLink = $image.wrap('<a class="fancybox" href="' + imageLink + '" itemscope itemtype="https://schema.org/ImageObject" itemprop="url"></a>').parent('a')
23
24
  let info; let captionClass = 'image-info'
24
25
  if (!$image.is('a img')) {
@@ -34,25 +35,25 @@ export const postFancybox = (p:string) => {
34
35
  const para = document.createElement('span')
35
36
  const txt = document.createTextNode(info)
36
37
  para.appendChild(txt)
37
- para.classList.add(captionClass)
38
+ para.addClass(captionClass)
38
39
  insertAfter(element, para)
39
40
  }
40
41
  })
41
42
 
42
43
  document.querySelectorAll(p + ' div.gallery').forEach((el, i) => {
43
44
  // @ts-ignore
44
- q(el).justifiedGallery({
45
- rowHeight: q(el).data('height') || 120,
45
+ $(el).justifiedGallery({
46
+ rowHeight: $(el).data('height') || 120,
46
47
  rel: 'gallery-' + i
47
48
  }).on('jg.complete', function () {
48
- q(this).find('a').each((k, ele) => {
49
+ $(this).find('a').each((k, ele) => {
49
50
  ele.setAttribute('data-fancybox', 'gallery-' + i)
50
51
  })
51
52
  })
52
53
  })
53
54
 
54
- q.fancybox.defaults.hash = false
55
- q(p + ' .fancybox').fancybox({
55
+ $.fancybox.defaults.hash = false
56
+ $(p + ' .fancybox').fancybox({
56
57
  loop: true,
57
58
  // @ts-ignore
58
59
  helpers: {
@@ -1,6 +1,7 @@
1
1
  import { cardActive } from '../page/common'
2
2
  import { resizeHandle } from '../globals/handles'
3
3
  import {
4
+ CONFIG,
4
5
  setLocalHash, setLocalUrl, setOriginTitle,
5
6
  } from '../globals/globalVars'
6
7
  import { positionInit } from '../globals/tools'
@@ -10,6 +11,14 @@ import { tabFormat } from '../page/tab'
10
11
  import { lazyLoad } from 'unlazy'
11
12
 
12
13
  export const siteRefresh = async (reload) => {
14
+ if (__shokax_antiFakeWebsite__) {
15
+ if (window.location.origin !== CONFIG.hostname && window.location.origin !== "http://localhost:4000") {
16
+ window.location.href = CONFIG.hostname
17
+ /*! 我知道你正在试图去除这段代码,虽然我无法阻止你,但我劝你好自为之 */
18
+ alert('检测到非法仿冒网站,已自动跳转回正确首页;\nWe have detected a fake website, and you have been redirected to the correct homepage.')
19
+ }
20
+ }
21
+
13
22
  setLocalHash(0)
14
23
  setLocalUrl(window.location.href)
15
24
 
@@ -70,6 +70,14 @@ const siteInit = async () => {
70
70
 
71
71
  cloudflareInit()
72
72
 
73
+ if (__shokax_antiFakeWebsite__) {
74
+ if (window.location.origin !== CONFIG.hostname && window.location.origin !== "http://localhost:4000") {
75
+ window.location.href = CONFIG.hostname
76
+ /*! 我知道你正在试图去除这段代码,虽然我无法阻止你,但我劝你好自为之 */
77
+ alert('检测到非法仿冒网站,已自动跳转回正确首页;\nWe have detected a fake website, and you have been redirected to the correct homepage.')
78
+ }
79
+ }
80
+
73
81
  window.addEventListener('DOMContentLoaded', siteInit, {
74
82
  passive: true
75
83
  })
@@ -1,41 +0,0 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
- var injects_point_exports = {};
20
- __export(injects_point_exports, {
21
- default: () => injects_point_default
22
- });
23
- module.exports = __toCommonJS(injects_point_exports);
24
- var injects_point_default = {
25
- views: [
26
- "head",
27
- "sidebar",
28
- "rightNav",
29
- "postMeta",
30
- "postBodyEnd",
31
- "footer",
32
- "bodyEnd",
33
- "comment",
34
- "status"
35
- ],
36
- styles: [
37
- "variable",
38
- "mixin",
39
- "style"
40
- ]
41
- };
@@ -1,105 +0,0 @@
1
- var __create = Object.create;
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __getProtoOf = Object.getPrototypeOf;
6
- var __hasOwnProp = Object.prototype.hasOwnProperty;
7
- var __export = (target, all) => {
8
- for (var name in all)
9
- __defProp(target, name, { get: all[name], enumerable: true });
10
- };
11
- var __copyProps = (to, from, except, desc) => {
12
- if (from && typeof from === "object" || typeof from === "function") {
13
- for (let key of __getOwnPropNames(from))
14
- if (!__hasOwnProp.call(to, key) && key !== except)
15
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
- }
17
- return to;
18
- };
19
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
20
- // If the importer is in node compatibility mode or this is not an ESM
21
- // file that has been converted to a CommonJS file using a Babel-
22
- // compatible transform (i.e. "__esModule" has not been set), then set
23
- // "default" to the CommonJS "module.exports" for node compatibility.
24
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
25
- mod
26
- ));
27
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
28
- var injects_exports = {};
29
- __export(injects_exports, {
30
- default: () => injects_default
31
- });
32
- module.exports = __toCommonJS(injects_exports);
33
- var import_node_fs = __toESM(require("node:fs"));
34
- var import_node_path = __toESM(require("node:path"));
35
- var import_injects_point = __toESM(require("./injects-point"));
36
- /*!
37
- inject.js in next-theme/hexo-theme-next by next-theme
38
- under GNU AFFERO GENERAL PUBLIC LICENSE v3.0 OR LATER
39
- https://github.com/next-theme/hexo-theme-next/blob/master/LICENSE.md
40
- */
41
- const defaultExtname = ".pug";
42
- class StylusInject {
43
- files;
44
- base_dir;
45
- constructor(base_dir) {
46
- this.base_dir = base_dir;
47
- this.files = [];
48
- }
49
- push(file) {
50
- this.files.push(import_node_path.default.resolve(this.base_dir, file));
51
- }
52
- }
53
- class ViewInject {
54
- base_dir;
55
- raws;
56
- constructor(base_dir) {
57
- this.base_dir = base_dir;
58
- this.raws = [];
59
- }
60
- raw(name, raw, ...args) {
61
- if (import_node_path.default.extname(name) === "") {
62
- name += defaultExtname;
63
- }
64
- this.raws.push({ name, raw, args });
65
- }
66
- file(name, file, ...args) {
67
- if (import_node_path.default.extname(name) === "") {
68
- name += import_node_path.default.extname(file);
69
- }
70
- this.raw(name, import_node_fs.default.readFileSync(import_node_path.default.resolve(this.base_dir, file), "utf8"), ...args);
71
- }
72
- }
73
- function initInject(base_dir) {
74
- const injects = {};
75
- import_injects_point.default.styles.forEach((item) => {
76
- injects[item] = new StylusInject(base_dir);
77
- });
78
- import_injects_point.default.views.forEach((item) => {
79
- injects[item] = new ViewInject(base_dir);
80
- });
81
- return injects;
82
- }
83
- var injects_default = (hexo) => {
84
- const injects = initInject(hexo.base_dir);
85
- hexo.execFilterSync("theme_inject", injects);
86
- hexo.theme.config.injects = {};
87
- import_injects_point.default.styles.forEach((type) => {
88
- hexo.theme.config.injects[type] = injects[type].files;
89
- });
90
- import_injects_point.default.views.forEach((type) => {
91
- const configs = /* @__PURE__ */ Object.create(null);
92
- hexo.theme.config.injects[type] = [];
93
- injects[type].raws.forEach((injectObj, index) => {
94
- const name = `inject/${type}/${injectObj.name}`;
95
- hexo.theme.setView(name, injectObj.raw);
96
- configs[name] = {
97
- layout: name,
98
- locals: injectObj.args[0],
99
- options: injectObj.args[1],
100
- order: injectObj.args[2] || index
101
- };
102
- });
103
- hexo.theme.config.injects[type] = Object.values(configs).sort((x, y) => x.order - y.order);
104
- });
105
- };