hexo-theme-shokax 0.5.0-dev-f787465 → 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.
Files changed (44) hide show
  1. package/README.md +2 -2
  2. package/UsageRestrictions.md +1 -1
  3. package/_config.yml +14 -15
  4. package/languages/en.yml +2 -0
  5. package/languages/ja.yml +2 -0
  6. package/languages/zh-CN.yml +2 -0
  7. package/languages/zh-HK.yml +2 -0
  8. package/languages/zh-TW.yml +2 -0
  9. package/layout/_partials/layout.pug +10 -5
  10. package/layout/_partials/post/footer.pug +8 -5
  11. package/package.json +31 -21
  12. package/scripts/generaters/config.js +12 -7
  13. package/scripts/generaters/images.js +9 -8
  14. package/scripts/generaters/script.js +21 -33
  15. package/scripts/generaters/summary_ai.js +130 -0
  16. package/scripts/helpers/summary_ai.js +1 -108
  17. package/scripts/plugin/index.js +32 -69
  18. package/source/css/_common/outline/sidebar/quick.styl +1 -1
  19. package/source/css/_common/outline/sidebar/sidebar.styl +2 -0
  20. package/source/js/_app/components/comments.ts +0 -2
  21. package/source/js/_app/components/sidebar.ts +37 -36
  22. package/source/js/_app/globals/globalVars.ts +0 -3
  23. package/source/js/_app/globals/handles.ts +9 -9
  24. package/source/js/_app/globals/themeColor.ts +5 -6
  25. package/source/js/_app/globals/thirdparty.ts +2 -2
  26. package/source/js/_app/globals/tools.ts +4 -6
  27. package/source/js/_app/library/anime.ts +30 -19
  28. package/source/js/_app/library/declare.d.ts +1 -0
  29. package/source/js/_app/library/proto.ts +0 -67
  30. package/source/js/_app/library/vue.ts +6 -7
  31. package/source/js/_app/page/common.ts +8 -10
  32. package/source/js/_app/page/fancybox.ts +13 -13
  33. package/source/js/_app/page/post.ts +42 -44
  34. package/source/js/_app/page/search.ts +0 -1
  35. package/source/js/_app/page/tab.ts +8 -9
  36. package/source/js/_app/pjax/domInit.ts +2 -5
  37. package/source/js/_app/pjax/refresh.ts +9 -0
  38. package/source/js/_app/pjax/siteInit.ts +18 -14
  39. package/source/js/_app/player.ts +26 -27
  40. package/toolbox/compiler.mjs +20 -48
  41. package/scripts/plugin/lib/injects-point.js +0 -41
  42. package/scripts/plugin/lib/injects.js +0 -105
  43. package/source/js/_app/library/dom.ts +0 -28
  44. package/source/js/_app/library/storage.ts +0 -12
@@ -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;
@@ -23,7 +23,6 @@ export const walineComment = function () {
23
23
  }
24
24
 
25
25
  export const walinePageview = function () {
26
- // TODO waline 上游此模块存在问题
27
26
  pageviewCount({
28
27
  serverURL: CONFIG.waline.serverURL,
29
28
  path: window.location.pathname
@@ -37,7 +36,6 @@ export const walineRecentComments = async function () {
37
36
  serverURL: CONFIG.waline.serverURL.replace(/\/+$/, ''),
38
37
  count: 10
39
38
  })
40
- // TODO 疑似 waline API 返回格式与文档不一致,需要确认是否为上游问题
41
39
  // @ts-ignore
42
40
  comments.data.forEach(function (item) {
43
41
  let cText = (item.orig.length > 50) ? item.orig.substring(0, 50) + '...' : item.orig
@@ -3,14 +3,12 @@
3
3
  import { CONFIG, Container, diffY, menuToggle, showContents, sideBar } from '../globals/globalVars'
4
4
  import { clipBoard } from '../globals/tools'
5
5
  import { pageScroll, transition } from '../library/anime'
6
- import { $dom } from '../library/dom'
7
- import initProto, { getHeight, setDisplay } from '../library/proto'
6
+ import { getHeight, setDisplay } from '../library/proto'
8
7
 
9
- initProto()
10
8
  export const sideBarToggleHandle = (event:Event, force?:number) => {
11
- if (sideBar.hasClass('on')) {
12
- sideBar.removeClass('on')
13
- menuToggle.removeClass('close')
9
+ if (sideBar.classList.contains('on')) {
10
+ sideBar.classList.remove('on')
11
+ menuToggle.classList.remove('close')
14
12
  if (force) {
15
13
  // @ts-ignore
16
14
  // noinspection JSConstantReassignment
@@ -25,8 +23,8 @@ export const sideBarToggleHandle = (event:Event, force?:number) => {
25
23
  sideBar.style = ''
26
24
  } else {
27
25
  transition(sideBar, 'slideRightIn', () => {
28
- sideBar.addClass('on')
29
- menuToggle.addClass('close')
26
+ sideBar.classList.add('on')
27
+ menuToggle.classList.add('close')
30
28
  })
31
29
  }
32
30
  }
@@ -61,29 +59,29 @@ export const sideBarTab = () => {
61
59
  const text = document.createTextNode(element.getAttribute('data-title'))
62
60
  span.appendChild(text)
63
61
  tab.appendChild(span)
64
- tab.addClass(item + ' item')
62
+ tab.classList.add(item + ' item')
65
63
 
66
64
  if (active) {
67
- element.addClass(active)
68
- tab.addClass(active)
65
+ element.classList.add(active)
66
+ tab.classList.add(active)
69
67
  } else {
70
- element.removeClass('active')
68
+ element.classList.remove('active')
71
69
  }
72
70
  tab.addEventListener('click', (event) => {
73
71
  const target = event.currentTarget as HTMLElement
74
- if (target.hasClass('active')) return
72
+ if (target.classList.contains('active')) return
75
73
 
76
- sideBar.find('.tab .item').forEach((element) => {
77
- element.removeClass('active')
74
+ sideBar.querySelectorAll('.tab .item').forEach((element) => {
75
+ element.classList.remove('active')
78
76
  })
79
77
 
80
- sideBar.find('.panel').forEach((element) => {
81
- element.removeClass('active')
78
+ sideBar.querySelectorAll('.panel').forEach((element) => {
79
+ element.classList.remove('active')
82
80
  })
83
81
 
84
- sideBar.querySelector('.panel.' + target.className.replace(' item', '')).addClass('active')
82
+ sideBar.querySelector('.panel.' + target.className.replace(' item', '')).classList.add('active')
85
83
 
86
- target.addClass('active')
84
+ target.classList.add('active')
87
85
  })
88
86
 
89
87
  list.appendChild(tab)
@@ -104,39 +102,39 @@ export const sidebarTOC = () => {
104
102
 
105
103
  if (!target) return
106
104
 
107
- if (target.hasClass('current')) {
105
+ if (target.classList.contains('current')) {
108
106
  return
109
107
  }
110
108
 
111
- $dom.each('.toc .active', (element) => {
112
- element && element.removeClass('active current')
109
+ document.querySelectorAll('.toc .active').forEach((element) => {
110
+ element && element.classList.remove('active current')
113
111
  })
114
112
 
115
113
  sections.forEach((element) => {
116
- element && element.removeClass('active')
114
+ element && element.classList.remove('active')
117
115
  })
118
116
 
119
- target.addClass('active current')
120
- sections[index] && sections[index].addClass('active')
117
+ target.classList.add('active current')
118
+ sections[index] && sections[index].classList.add('active')
121
119
 
122
120
  let parent = <Element> target.parentNode
123
121
 
124
122
  while (!parent.matches('.contents')) {
125
123
  if (parent.matches('li')) {
126
- parent.addClass('active')
124
+ parent.classList.add('active')
127
125
  const t = document.getElementById(decodeURIComponent(parent.querySelector('a.toc-link').getAttribute('href').replace('#', '')))
128
126
  if (t) {
129
- t.addClass('active')
127
+ t.classList.add('active')
130
128
  }
131
129
  }
132
130
  parent = <Element> parent.parentNode
133
131
  }
134
132
  // Scrolling to center active TOC element if TOC content is taller than viewport.
135
- if (getComputedStyle(sideBar).display !== 'none' && tocElement.hasClass('active')) {
133
+ if (getComputedStyle(sideBar).display !== 'none' && tocElement.classList.contains('active')) {
136
134
  pageScroll((tocElement as HTMLElement), target.offsetTop - ((tocElement as HTMLElement).offsetHeight / 4))
137
135
  }
138
136
  }
139
- const navItems = $dom.all('.contents li')
137
+ const navItems = document.querySelectorAll<HTMLElement>('.contents li')
140
138
 
141
139
  if (navItems.length < 1) {
142
140
  return
@@ -147,7 +145,9 @@ export const sidebarTOC = () => {
147
145
 
148
146
  sections = sections.map((element, index) => {
149
147
  const link = element.querySelector('a.toc-link')
150
- 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('#', '')))
151
151
  if (!anchor) return null
152
152
  const alink = anchor.querySelector('a.anchor')
153
153
 
@@ -222,18 +222,19 @@ export const goToCommentHandle = () => {
222
222
  }
223
223
 
224
224
  export const menuActive = () => {
225
- $dom.each('.menu .item:not(.title)', (element) => {
225
+ document.querySelectorAll('.menu .item:not(.title)').forEach((element) => {
226
226
  const target = <HTMLAnchorElement> element.querySelector('a[href]')
227
- const parentItem = element.parentNode.parentNode
227
+ const parentItem = element.parentNode.parentNode as HTMLElement
228
228
  if (!target) return
229
229
  const isSamePath = target.pathname === location.pathname || target.pathname === location.pathname.replace('index.html', '')
230
230
  const isSubPath = !CONFIG.root.startsWith(target.pathname) && location.pathname.startsWith(target.pathname)
231
231
  const active = !target.onclick && target.hostname === location.hostname && (isSamePath || isSubPath)
232
- element.toggleClass('active', active)
233
- if (element.parentNode.querySelector('.active') && parentItem.hasClass('dropdown')) {
234
- parentItem.removeClass('active').addClass('expand')
232
+ element.classList.toggle('active', active)
233
+ if (element.parentNode.querySelector('.active') && parentItem.classList.contains('dropdown')) {
234
+ parentItem.classList.remove('active')
235
+ parentItem.classList.add('expand')
235
236
  } else {
236
- parentItem.removeClass('expand')
237
+ parentItem.classList.remove('expand')
237
238
  }
238
239
  })
239
240
  }
@@ -1,7 +1,4 @@
1
- import initProto from '../library/proto'
2
-
3
1
  export const CONFIG = shokax_CONFIG
4
- initProto()
5
2
  export const statics = CONFIG.statics.indexOf('//') > 0 ? CONFIG.statics : CONFIG.root
6
3
  export const scrollAction: { x: number, y: number } = { x: 0, y: 0 }
7
4
  export let diffY = 0
@@ -63,12 +63,12 @@ export const scrollHandle = () => {
63
63
  }
64
64
 
65
65
  // 控制导航栏的显示隐藏
66
- siteNav.toggleClass('show', SHOW)
66
+ siteNav.classList.toggle('show', SHOW)
67
67
  // 控制网站 logo 的显示隐藏
68
- toolBtn.toggleClass('affix', startScroll)
68
+ toolBtn.classList.toggle('affix', startScroll)
69
69
  // 控制侧边栏的显示隐藏,当滚动高度大于 headerHight 且窗口宽度大于 991px 时显示
70
- siteBrand.toggleClass('affix', startScroll)
71
- sideBar.toggleClass('affix', window.scrollY > headerHight && document.body.offsetWidth >= 991)
70
+ siteBrand.classList.toggle('affix', startScroll)
71
+ sideBar.classList.toggle('affix', window.scrollY > headerHight && document.body.offsetWidth >= 991)
72
72
  // 初始化滚动时导航栏的显示方向
73
73
  if (typeof scrollAction.y === 'undefined') {
74
74
  scrollAction.y = window.scrollY
@@ -77,11 +77,11 @@ export const scrollHandle = () => {
77
77
 
78
78
  // 控制滑动时导航栏显示
79
79
  if (diffY < 0) {
80
- siteNav.removeClass('up')
81
- siteNav.toggleClass('down', SHOW)
80
+ siteNav.classList.remove('up')
81
+ siteNav.classList.toggle('down', SHOW)
82
82
  } else if (diffY > 0) {
83
- siteNav.removeClass('down')
84
- siteNav.toggleClass('up', SHOW)
83
+ siteNav.classList.remove('down')
84
+ siteNav.classList.toggle('up', SHOW)
85
85
  } else { /* empty */ }
86
86
  scrollAction.y = window.scrollY
87
87
  // 计算滚动百分比
@@ -91,7 +91,7 @@ export const scrollHandle = () => {
91
91
  backToTop.querySelector('span').innerText = scrollPercent
92
92
  }
93
93
  // 更新百分比进度条的宽度
94
- if (document.getElementById('sidebar').hasClass('affix') || document.getElementById('sidebar').hasClass('on')) {
94
+ if (document.getElementById('sidebar').classList.contains('affix') || document.getElementById('sidebar').classList.contains('on')) {
95
95
  setWidth(document.querySelector('.percent'), scrollPercent)
96
96
  }
97
97
  }
@@ -1,4 +1,3 @@
1
- import { $storage } from '../library/storage'
2
1
  import { CONFIG, HTML } from './globalVars'
3
2
 
4
3
  /**
@@ -8,12 +7,12 @@ export const changeTheme = (type?: string) => {
8
7
  const btn = document.querySelector('.theme .ic')
9
8
  if (type === 'dark') {
10
9
  HTML.setAttribute('data-theme', type)
11
- btn.removeClass('i-sun')
12
- btn.addClass('i-moon')
10
+ btn.classList.remove('i-sun')
11
+ btn.classList.add('i-moon')
13
12
  } else {
14
13
  HTML.removeAttribute('data-theme')
15
- btn.removeClass('i-moon')
16
- btn.addClass('i-sun')
14
+ btn.classList.remove('i-moon')
15
+ btn.classList.add('i-sun')
17
16
  }
18
17
  }
19
18
 
@@ -52,7 +51,7 @@ export const themeColorListener = () => {
52
51
  }
53
52
  })
54
53
 
55
- const t = $storage.get('theme')
54
+ const t = localStorage.getItem('theme')
56
55
  if (t) {
57
56
  changeTheme(t)
58
57
  } else {
@@ -9,7 +9,7 @@ export const Loader = {
9
9
  lock: false,
10
10
  show () {
11
11
  clearTimeout(this.timer)
12
- document.body.removeClass('loaded')
12
+ document.body.classList.remove('loaded')
13
13
  loadCat.setAttribute('style', 'display:block')
14
14
  Loader.lock = false
15
15
  },
@@ -26,7 +26,7 @@ export const Loader = {
26
26
  if (CONFIG.loader.start) {
27
27
  transition(loadCat, 0)
28
28
  }
29
- document.body.addClass('loaded')
29
+ document.body.classList.add('loaded')
30
30
  Loader.lock = true
31
31
  }
32
32
  }
@@ -1,6 +1,4 @@
1
1
  import { pageScroll } from '../library/anime'
2
- import { $dom } from '../library/dom'
3
- import { $storage } from '../library/storage'
4
2
  import { BODY, CONFIG, LOCAL_HASH, LOCAL_URL, scrollAction, setLocalHash } from './globalVars'
5
3
  import { createChild } from '../library/proto'
6
4
 
@@ -16,7 +14,7 @@ export const showtip = (msg: string): void | never => {
16
14
  })
17
15
 
18
16
  setTimeout(() => {
19
- tipbox.addClass('hide')
17
+ tipbox.classList.add('hide')
20
18
  setTimeout(() => {
21
19
  BODY.removeChild(tipbox)
22
20
  }, 300)
@@ -27,7 +25,7 @@ export const pagePosition = () => {
27
25
  // 判断配置项是否开启了自动记录滚动位置
28
26
  if (CONFIG.auto_scroll) {
29
27
  // 将当前页面的滚动位置存入本地缓存
30
- $storage.set(LOCAL_URL, String(scrollAction.y))
28
+ localStorage.setItem(LOCAL_URL, String(scrollAction.y))
31
29
  }
32
30
  }
33
31
 
@@ -37,14 +35,14 @@ export const positionInit = (comment?: boolean) => {
37
35
 
38
36
  let target = null
39
37
  if (LOCAL_HASH) {
40
- $storage.del(LOCAL_URL)
38
+ localStorage.removeItem(LOCAL_URL)
41
39
  return
42
40
  }
43
41
 
44
42
  if (anchor) {
45
43
  target = document.querySelector(decodeURI(anchor))
46
44
  } else {
47
- target = CONFIG.auto_scroll ? parseInt($storage.get(LOCAL_URL)) : 0
45
+ target = CONFIG.auto_scroll ? parseInt(localStorage.getItem(LOCAL_URL)) : 0
48
46
  }
49
47
 
50
48
  if (target) {
@@ -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