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.
- package/README.md +2 -2
- package/UsageRestrictions.md +1 -1
- package/_config.yml +14 -15
- package/languages/en.yml +2 -0
- package/languages/ja.yml +2 -0
- package/languages/zh-CN.yml +2 -0
- package/languages/zh-HK.yml +2 -0
- package/languages/zh-TW.yml +2 -0
- package/layout/_partials/layout.pug +10 -5
- package/layout/_partials/post/footer.pug +8 -5
- package/package.json +31 -21
- package/scripts/generaters/config.js +12 -7
- package/scripts/generaters/images.js +9 -8
- package/scripts/generaters/script.js +21 -33
- package/scripts/generaters/summary_ai.js +130 -0
- package/scripts/helpers/summary_ai.js +1 -108
- package/scripts/plugin/index.js +32 -69
- package/source/css/_common/outline/sidebar/quick.styl +1 -1
- package/source/css/_common/outline/sidebar/sidebar.styl +2 -0
- package/source/js/_app/components/comments.ts +0 -2
- package/source/js/_app/components/sidebar.ts +37 -36
- package/source/js/_app/globals/globalVars.ts +0 -3
- package/source/js/_app/globals/handles.ts +9 -9
- package/source/js/_app/globals/themeColor.ts +5 -6
- package/source/js/_app/globals/thirdparty.ts +2 -2
- package/source/js/_app/globals/tools.ts +4 -6
- package/source/js/_app/library/anime.ts +30 -19
- package/source/js/_app/library/declare.d.ts +1 -0
- package/source/js/_app/library/proto.ts +0 -67
- package/source/js/_app/library/vue.ts +6 -7
- package/source/js/_app/page/common.ts +8 -10
- package/source/js/_app/page/fancybox.ts +13 -13
- package/source/js/_app/page/post.ts +42 -44
- package/source/js/_app/page/search.ts +0 -1
- package/source/js/_app/page/tab.ts +8 -9
- package/source/js/_app/pjax/domInit.ts +2 -5
- package/source/js/_app/pjax/refresh.ts +9 -0
- package/source/js/_app/pjax/siteInit.ts +18 -14
- package/source/js/_app/player.ts +26 -27
- package/toolbox/compiler.mjs +20 -48
- package/scripts/plugin/lib/injects-point.js +0 -41
- package/scripts/plugin/lib/injects.js +0 -105
- package/source/js/_app/library/dom.ts +0 -28
- 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
|
2
|
+
return post.summary;
|
110
3
|
});
|
111
4
|
hexo.extend.helper.register("get_introduce", () => {
|
112
5
|
return hexo.theme.config.summary.introduce;
|
package/scripts/plugin/index.js
CHANGED
@@ -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
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
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
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
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
|
});
|
@@ -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 {
|
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.
|
12
|
-
sideBar.
|
13
|
-
menuToggle.
|
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.
|
29
|
-
menuToggle.
|
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.
|
62
|
+
tab.classList.add(item + ' item')
|
65
63
|
|
66
64
|
if (active) {
|
67
|
-
element.
|
68
|
-
tab.
|
65
|
+
element.classList.add(active)
|
66
|
+
tab.classList.add(active)
|
69
67
|
} else {
|
70
|
-
element.
|
68
|
+
element.classList.remove('active')
|
71
69
|
}
|
72
70
|
tab.addEventListener('click', (event) => {
|
73
71
|
const target = event.currentTarget as HTMLElement
|
74
|
-
if (target.
|
72
|
+
if (target.classList.contains('active')) return
|
75
73
|
|
76
|
-
sideBar.
|
77
|
-
element.
|
74
|
+
sideBar.querySelectorAll('.tab .item').forEach((element) => {
|
75
|
+
element.classList.remove('active')
|
78
76
|
})
|
79
77
|
|
80
|
-
sideBar.
|
81
|
-
element.
|
78
|
+
sideBar.querySelectorAll('.panel').forEach((element) => {
|
79
|
+
element.classList.remove('active')
|
82
80
|
})
|
83
81
|
|
84
|
-
sideBar.querySelector('.panel.' + target.className.replace(' item', '')).
|
82
|
+
sideBar.querySelector('.panel.' + target.className.replace(' item', '')).classList.add('active')
|
85
83
|
|
86
|
-
target.
|
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.
|
105
|
+
if (target.classList.contains('current')) {
|
108
106
|
return
|
109
107
|
}
|
110
108
|
|
111
|
-
|
112
|
-
element && element.
|
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.
|
114
|
+
element && element.classList.remove('active')
|
117
115
|
})
|
118
116
|
|
119
|
-
target.
|
120
|
-
sections[index] && sections[index].
|
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.
|
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.
|
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.
|
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 =
|
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
|
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
|
-
|
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.
|
233
|
-
if (element.parentNode.querySelector('.active') && parentItem.
|
234
|
-
parentItem.
|
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.
|
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.
|
66
|
+
siteNav.classList.toggle('show', SHOW)
|
67
67
|
// 控制网站 logo 的显示隐藏
|
68
|
-
toolBtn.
|
68
|
+
toolBtn.classList.toggle('affix', startScroll)
|
69
69
|
// 控制侧边栏的显示隐藏,当滚动高度大于 headerHight 且窗口宽度大于 991px 时显示
|
70
|
-
siteBrand.
|
71
|
-
sideBar.
|
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.
|
81
|
-
siteNav.
|
80
|
+
siteNav.classList.remove('up')
|
81
|
+
siteNav.classList.toggle('down', SHOW)
|
82
82
|
} else if (diffY > 0) {
|
83
|
-
siteNav.
|
84
|
-
siteNav.
|
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').
|
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.
|
12
|
-
btn.
|
10
|
+
btn.classList.remove('i-sun')
|
11
|
+
btn.classList.add('i-moon')
|
13
12
|
} else {
|
14
13
|
HTML.removeAttribute('data-theme')
|
15
|
-
btn.
|
16
|
-
btn.
|
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 =
|
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.
|
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.
|
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.
|
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
|
-
|
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
|
-
|
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(
|
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
|
-
//
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
}
|
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
|
+
};
|