hexo-theme-particlex 2.4.11 → 2.5.0
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 +15 -4
- package/_config.yml +6 -4
- package/layout/archives.ejs +42 -35
- package/layout/card.ejs +4 -2
- package/layout/categories.ejs +7 -1
- package/layout/{script.ejs → comment.ejs} +0 -10
- package/layout/footer.ejs +6 -3
- package/layout/import.ejs +44 -0
- package/layout/index.ejs +3 -3
- package/layout/layout.ejs +25 -28
- package/layout/menu.ejs +5 -5
- package/layout/post.ejs +23 -7
- package/layout/posts.ejs +7 -1
- package/layout/tags.ejs +7 -1
- package/package.json +1 -1
- package/source/css/{particlex.css → main.css} +121 -98
- package/source/js/lib/crypto.js +41 -0
- package/source/js/lib/highlight.js +32 -0
- package/source/js/lib/math.js +15 -0
- package/source/js/lib/preview.js +26 -0
- package/source/js/lib/search.js +28 -0
- package/source/js/main.js +47 -0
- package/layout/loading.ejs +0 -9
- package/source/js/functions.js +0 -71
- package/source/js/particlex.js +0 -98
package/README.md
CHANGED
@@ -69,7 +69,6 @@ theme: particlex
|
|
69
69
|
avatar: # Avatar image
|
70
70
|
headBlockEnable: true # Home page info block
|
71
71
|
background: # Home page background image
|
72
|
-
highlightStyle: github # Highlight style
|
73
72
|
```
|
74
73
|
|
75
74
|
- 导航栏
|
@@ -170,9 +169,21 @@ highlightStyle: github # Highlight style
|
|
170
169
|
- default
|
171
170
|
```
|
172
171
|
|
173
|
-
-
|
172
|
+
- 代码高亮
|
174
173
|
|
175
|
-
使用
|
174
|
+
使用 Highlight.js 代码高亮
|
175
|
+
|
176
|
+
样式可以在[这里](https://highlightjs.org/static/demo)选择,默认为 GitHub
|
177
|
+
|
178
|
+
```yaml
|
179
|
+
highlight:
|
180
|
+
enable: false
|
181
|
+
style: github
|
182
|
+
```
|
183
|
+
|
184
|
+
- 数学渲染
|
185
|
+
|
186
|
+
使用 KaTeX 渲染数学公式
|
176
187
|
|
177
188
|
```yaml
|
178
189
|
math:
|
@@ -194,7 +205,7 @@ highlightStyle: github # Highlight style
|
|
194
205
|
|
195
206
|
- 搜索
|
196
207
|
|
197
|
-
嵌入到 Archives
|
208
|
+
嵌入到 Archives 中的搜索
|
198
209
|
|
199
210
|
目前只支持搜索文档标题(我太弱了)
|
200
211
|
|
package/_config.yml
CHANGED
@@ -10,10 +10,6 @@ headBlockEnable: true
|
|
10
10
|
# Home page background image
|
11
11
|
background:
|
12
12
|
|
13
|
-
# Highlight style
|
14
|
-
# https://highlightjs.org
|
15
|
-
highlightStyle: github
|
16
|
-
|
17
13
|
# ParticleX theme icon is adopts the Font Awesome 6
|
18
14
|
# https://fontawesome.com/search
|
19
15
|
|
@@ -76,6 +72,12 @@ polyfill:
|
|
76
72
|
features:
|
77
73
|
- default
|
78
74
|
|
75
|
+
# Highlight.js
|
76
|
+
# https://highlightjs.org
|
77
|
+
highlight:
|
78
|
+
enable: true
|
79
|
+
style: github
|
80
|
+
|
79
81
|
# Rendering math with KaTeX
|
80
82
|
math:
|
81
83
|
enable: false
|
package/layout/archives.ejs
CHANGED
@@ -4,46 +4,53 @@
|
|
4
4
|
%>
|
5
5
|
<div id="archives">
|
6
6
|
<% if (theme.search.enable) { %>
|
7
|
-
<
|
8
|
-
<input id="search-bar" class="input" placeholder="搜索" style="z-index: <%- posts.length + 2 %>">
|
7
|
+
<input id="search-bar" class="input" placeholder="搜索" v-model="rawSearch" />
|
9
8
|
<% } %>
|
10
|
-
|
11
|
-
|
12
|
-
<div class="timeline-
|
13
|
-
|
14
|
-
<div class="
|
15
|
-
|
16
|
-
<
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
<
|
9
|
+
<div id="timeline-wrap" ref="timeline">
|
10
|
+
<% posts.reverse().forEach((post, id) => { %>
|
11
|
+
<div class="timeline" data-title="<%- post.title.toLowerCase().replace(/\s+/gm, "") %>">
|
12
|
+
<div class="timeline-tail"></div>
|
13
|
+
<div class="timeline-content">
|
14
|
+
<div class="item-time"><%= date(post.date, "YYYY/M/D") %></div>
|
15
|
+
<a href="<%- url_for(post.path) %>">
|
16
|
+
<h3><%= post.title %></h3>
|
17
|
+
</a>
|
18
|
+
<div class="info">
|
19
|
+
<% if (post.categories && post.categories.data.length !== 0) { %>
|
20
|
+
<span class="category">
|
21
|
+
<a href="<%- url_for(post.categories.data[0].path) %>">
|
22
|
+
<span class="icon">
|
23
|
+
<i class="fa-solid fa-bookmark fa-fw"></i>
|
24
|
+
</span>
|
25
|
+
<%= post.categories.data[0].name %>
|
26
|
+
</a>
|
27
|
+
</span>
|
28
|
+
<% } %>
|
29
|
+
<% if (post.tags && post.tags.data.length !== 0) { %>
|
30
|
+
<span class="tags">
|
22
31
|
<span class="icon">
|
23
|
-
<i class="fa-solid fa-
|
32
|
+
<i class="fa-solid fa-tags fa-fw"></i>
|
24
33
|
</span>
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
%>
|
40
|
-
<a href="<%- url_for(data.path) %>" style="<%- color[num] %>"><%= data.name %></a>
|
34
|
+
<% post.tags.data.forEach(data => { %>
|
35
|
+
<span class="tag">
|
36
|
+
<%
|
37
|
+
const color = [
|
38
|
+
"color: #ffa2c4",
|
39
|
+
"color: #00bcd4",
|
40
|
+
"color: #03a9f4",
|
41
|
+
"color: #00a596",
|
42
|
+
"color: #ff7d73",
|
43
|
+
];
|
44
|
+
let num = Math.floor(Math.random() * color.length);
|
45
|
+
%>
|
46
|
+
<a href="<%- url_for(data.path) %>" style="<%- color[num] %>"><%= data.name %></a>
|
47
|
+
</span>
|
48
|
+
<% }); %>
|
41
49
|
</span>
|
42
|
-
<% }
|
43
|
-
</
|
44
|
-
<% } %>
|
50
|
+
<% } %>
|
51
|
+
</div>
|
45
52
|
</div>
|
46
53
|
</div>
|
54
|
+
<% }); %>
|
47
55
|
</div>
|
48
|
-
<% }); %>
|
49
56
|
</div>
|
package/layout/card.ejs
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
<div id="card-div">
|
2
2
|
<div class="card-style" style="width: 300px">
|
3
3
|
<div class="avatar">
|
4
|
-
<img src="<%- url_for(theme.avatar) %>" alt="avatar"
|
4
|
+
<img src="<%- url_for(theme.avatar) %>" alt="avatar" />
|
5
5
|
</div>
|
6
6
|
<div class="name"><%= config.author %></div>
|
7
7
|
<div class="description">
|
@@ -12,7 +12,9 @@
|
|
12
12
|
<% Object.keys(theme.card.iconLinks).forEach(key => { %>
|
13
13
|
<span class="icon-link">
|
14
14
|
<a href="<%- url_for(theme.card.iconLinks[key].link) %>">
|
15
|
-
<i
|
15
|
+
<i
|
16
|
+
class="fa-<%- theme.card.iconLinks[key].theme %> fa-<%- theme.card.iconLinks[key].name %> fa-fw"
|
17
|
+
></i>
|
16
18
|
</a>
|
17
19
|
</span>
|
18
20
|
<% }); %>
|
package/layout/categories.ejs
CHANGED
@@ -51,7 +51,13 @@
|
|
51
51
|
<% post.tags.data.forEach(data => { %>
|
52
52
|
<span class="tag">
|
53
53
|
<%
|
54
|
-
const color = [
|
54
|
+
const color = [
|
55
|
+
"color: #ffa2c4",
|
56
|
+
"color: #00bcd4",
|
57
|
+
"color: #03a9f4",
|
58
|
+
"color: #00a596",
|
59
|
+
"color: #ff7d73",
|
60
|
+
];
|
55
61
|
let num = Math.floor(Math.random() * color.length);
|
56
62
|
%>
|
57
63
|
<a href="<%- url_for(data.path) %>" style="<%- color[num] %>"><%= data.name %></a>
|
@@ -1,9 +1,4 @@
|
|
1
|
-
<script src="<%- url_for("/js/functions.js") %>"></script>
|
2
|
-
<script src="<%- url_for("/js/particlex.js") %>"></script>
|
3
|
-
<% if (type === "post" && page.comments) { %>
|
4
1
|
<% if (theme.gitalk.enable) { %>
|
5
|
-
<script src="https://cdn.staticfile.org/gitalk/1.8.0/gitalk.min.js"></script>
|
6
|
-
<link rel="stylesheet" href="https://cdn.staticfile.org/gitalk/1.8.0/gitalk.min.css">
|
7
2
|
<script>
|
8
3
|
let clientID = "<%- theme.gitalk.clientID %>",
|
9
4
|
clientSecret = "<%- theme.gitalk.clientSecret %>";
|
@@ -48,9 +43,6 @@
|
|
48
43
|
></script>
|
49
44
|
<% } %>
|
50
45
|
<% if (theme.waline.enable) { %>
|
51
|
-
<script src="https://cdn.staticfile.org/waline/2.14.7/waline.min.js"></script>
|
52
|
-
<link rel="stylesheet" href="https://cdn.staticfile.org/waline/2.14.7/waline.min.css">
|
53
|
-
<link rel="stylesheet" href="https://cdn.staticfile.org/waline/2.14.7/waline-meta.min.css">
|
54
46
|
<script>
|
55
47
|
Waline.init({
|
56
48
|
el: "#waline-container",
|
@@ -69,7 +61,6 @@
|
|
69
61
|
</script>
|
70
62
|
<% } %>
|
71
63
|
<% if (theme.twikoo.enable) { %>
|
72
|
-
<script src="https://cdn.staticfile.org/twikoo/1.6.8/twikoo.all.min.js"></script>
|
73
64
|
<script>
|
74
65
|
twikoo.init({
|
75
66
|
el: "#twikoo-container",
|
@@ -80,4 +71,3 @@
|
|
80
71
|
})
|
81
72
|
</script>
|
82
73
|
<% } %>
|
83
|
-
<% } %>
|
package/layout/footer.ejs
CHANGED
@@ -1,14 +1,17 @@
|
|
1
1
|
<footer id="footer">
|
2
|
-
<div
|
2
|
+
<div id="footer-wrap">
|
3
3
|
<div>
|
4
4
|
©
|
5
5
|
<%= theme.footer.since %> - <%= date(Date.now(), "YYYY") %> <%= config.title %>
|
6
|
-
<span
|
6
|
+
<span id="footer-icon">
|
7
7
|
<i class="fa-solid fa-font-awesome fa-fw"></i>
|
8
8
|
</span>
|
9
9
|
@<%= config.author %>
|
10
10
|
</div>
|
11
|
-
<div>
|
11
|
+
<div>
|
12
|
+
Based on the <a href="https://hexo.io">Hexo Engine</a> &
|
13
|
+
<a href="https://github.com/argvchs/hexo-theme-particlex">ParticleX Theme</a>
|
14
|
+
</div>
|
12
15
|
<% if (theme.footer.ICP.enable) { %>
|
13
16
|
<div>
|
14
17
|
备案号:
|
@@ -0,0 +1,44 @@
|
|
1
|
+
<script src="https://cdn.staticfile.org/vue/3.2.45/vue.global.prod.min.js"></script>
|
2
|
+
<link rel="stylesheet" href="https://cdn.staticfile.org/font-awesome/6.2.1/css/all.min.css" />
|
3
|
+
<link rel="stylesheet" href="<%- url_for("/css/fonts.min.css") %>" />
|
4
|
+
<script>const mixins = [];</script>
|
5
|
+
<% if (theme.highlight.enable) { %>
|
6
|
+
<script src="https://cdn.staticfile.org/highlight.js/11.7.0/highlight.min.js"></script>
|
7
|
+
<link
|
8
|
+
rel="stylesheet"
|
9
|
+
href="https://cdn.staticfile.org/highlight.js/11.7.0/styles/<%- theme.highlight.style %>.min.css"
|
10
|
+
/>
|
11
|
+
<script src="<%- url_for("/js/lib/highlight.js") %>"></script>
|
12
|
+
<% } %>
|
13
|
+
<% if (theme.polyfill.enable) { %>
|
14
|
+
<script src="https://polyfill.io/v3/polyfill.min.js?features=<%- theme.polyfill.features.join(",") %>"></script>
|
15
|
+
<% } %>
|
16
|
+
<% if (theme.math.enable) { %>
|
17
|
+
<script src="https://cdn.staticfile.org/KaTeX/0.16.4/katex.min.js"></script>
|
18
|
+
<script src="https://cdn.staticfile.org/KaTeX/0.16.4/contrib/auto-render.min.js"></script>
|
19
|
+
<link rel="stylesheet" href="https://cdn.staticfile.org/KaTeX/0.16.4/katex.min.css" />
|
20
|
+
<script src="<%- url_for("/js/lib/math.js") %>"></script>
|
21
|
+
<% } %>
|
22
|
+
<% if (theme.crypto.enable && typeof page.secret !== "undefined") { %>
|
23
|
+
<script src="https://cdn.staticfile.org/crypto-js/4.1.1/crypto-js.min.js"></script>
|
24
|
+
<script src="<%- url_for("/js/lib/crypto.js") %>"></script>
|
25
|
+
<% } %>
|
26
|
+
<% if (theme.search.enable && type === "archives") { %>
|
27
|
+
<script src="<%- url_for("/js/lib/search.js") %>"></script>
|
28
|
+
<% } %>
|
29
|
+
<% if (page.comments && type === "post") { %>
|
30
|
+
<% if (theme.gitalk.enable) { %>
|
31
|
+
<script src="https://cdn.staticfile.org/gitalk/1.8.0/gitalk.min.js"></script>
|
32
|
+
<link rel="stylesheet" href="https://cdn.staticfile.org/gitalk/1.8.0/gitalk.min.css" />
|
33
|
+
<% } %>
|
34
|
+
<% if (theme.waline.enable) { %>
|
35
|
+
<script src="https://cdn.staticfile.org/waline/2.14.7/waline.min.js"></script>
|
36
|
+
<link rel="stylesheet" href="https://cdn.staticfile.org/waline/2.14.7/waline.min.css" />
|
37
|
+
<link rel="stylesheet" href="https://cdn.staticfile.org/waline/2.14.7/waline-meta.min.css" />
|
38
|
+
<% } %>
|
39
|
+
<% if (theme.twikoo.enable) { %>
|
40
|
+
<script src="https://cdn.staticfile.org/twikoo/1.6.8/twikoo.all.min.js"></script>
|
41
|
+
<% } %>
|
42
|
+
<% } %>
|
43
|
+
<script src="<%- url_for("/js/lib/preview.js") %>"></script>
|
44
|
+
<link rel="stylesheet" href="<%- url_for("/css/main.css") %>" />
|
package/layout/index.ejs
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
<div id="home-head">
|
1
|
+
<div id="home-head" ref="head">
|
2
2
|
<div id="home-background" style="background-image: url(<%- theme.background %>)"></div>
|
3
3
|
<% if (theme.headBlockEnable) { %>
|
4
|
-
<div id="home-info" @click="
|
4
|
+
<div id="home-info" @click="homeClick">
|
5
5
|
<span class="loop"></span>
|
6
6
|
<span class="loop"></span>
|
7
7
|
<span class="loop"></span>
|
@@ -16,7 +16,7 @@
|
|
16
16
|
</div>
|
17
17
|
<% } %>
|
18
18
|
</div>
|
19
|
-
<div id="home-posts-wrap"
|
19
|
+
<div id="home-posts-wrap" <%- theme.card.enable ? "" : 'class="home-posts-wrap-no-card"' %> ref="wrap">
|
20
20
|
<div id="home-posts">
|
21
21
|
<div id="posts">
|
22
22
|
<%- partial("posts") %>
|
package/layout/layout.ejs
CHANGED
@@ -24,45 +24,42 @@
|
|
24
24
|
<!DOCTYPE html>
|
25
25
|
<html lang="<%- config.language %>">
|
26
26
|
<head>
|
27
|
-
<meta charset="UTF-8"
|
27
|
+
<meta charset="UTF-8" />
|
28
28
|
<title><%= title %></title>
|
29
|
-
<meta name="author" content="<%- config.author %>"
|
30
|
-
<meta name="description" content="<%- config.description %>"
|
31
|
-
<meta name="keywords" content="<%- config.keywords %>"
|
32
|
-
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0"
|
33
|
-
<link rel="icon" href="<%- url_for(theme.avatar) %>"
|
34
|
-
|
35
|
-
<script src="https://cdn.staticfile.org/highlight.js/11.7.0/highlight.min.js"></script>
|
36
|
-
<link rel="stylesheet" href="https://cdn.staticfile.org/highlight.js/11.7.0/styles/<%- theme.highlightStyle %>.min.css">
|
37
|
-
<link rel="stylesheet" href="https://cdn.staticfile.org/font-awesome/6.2.1/css/all.min.css">
|
38
|
-
<% if (theme.polyfill.enable) { %>
|
39
|
-
<script src="https://polyfill.io/v3/polyfill.min.js?features=<%- theme.polyfill.features.join(",") %>"></script>
|
40
|
-
<% } %>
|
41
|
-
<% if (theme.math.enable) { %>
|
42
|
-
<script src="https://cdn.staticfile.org/KaTeX/0.16.4/katex.min.js"></script>
|
43
|
-
<script src="https://cdn.staticfile.org/KaTeX/0.16.4/contrib/auto-render.min.js"></script>
|
44
|
-
<link rel="stylesheet" href="https://cdn.staticfile.org/KaTeX/0.16.4/katex.min.css">
|
45
|
-
<% } %>
|
46
|
-
<% if (theme.crypto.enable && typeof page.secret !== "undefined") { %>
|
47
|
-
<script src="https://cdn.staticfile.org/crypto-js/4.1.1/crypto-js.min.js"></script>
|
48
|
-
<% } %>
|
49
|
-
<link rel="stylesheet" href="<%- url_for("/css/fonts.min.css") %>">
|
50
|
-
<link rel="stylesheet" href="<%- url_for("/css/particlex.css") %>">
|
29
|
+
<meta name="author" content="<%- config.author %>" />
|
30
|
+
<meta name="description" content="<%- config.description %>" />
|
31
|
+
<meta name="keywords" content="<%- config.keywords %>" />
|
32
|
+
<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0" />
|
33
|
+
<link rel="icon" href="<%- url_for(theme.avatar) %>" />
|
34
|
+
<%- partial("import", { type }) %>
|
51
35
|
</head>
|
52
36
|
<body>
|
53
|
-
<%- partial("loading") %>
|
54
37
|
<div id="layout">
|
38
|
+
<transition name="fade">
|
39
|
+
<div id="loading" v-show="loading">
|
40
|
+
<div id="loading-circle">
|
41
|
+
<h2>LOADING</h2>
|
42
|
+
<p>加载过慢请开启缓存 浏览器默认开启</p>
|
43
|
+
<img src="<%- url_for("/images/loading.gif") %>" />
|
44
|
+
</div>
|
45
|
+
</div>
|
46
|
+
</transition>
|
55
47
|
<transition name="into">
|
56
|
-
<div id="main" v-show="
|
48
|
+
<div id="main" v-show="!loading">
|
57
49
|
<%- partial("menu") %>
|
58
50
|
<%- partial(type) %>
|
59
51
|
<%- partial("footer") %>
|
60
52
|
</div>
|
61
53
|
</transition>
|
62
|
-
<
|
63
|
-
|
54
|
+
<transition name="fade">
|
55
|
+
<div id="preview" ref="preview" v-show="previewShow">
|
56
|
+
<img id="preview-content" ref="previewContent" />
|
64
57
|
</div>
|
58
|
+
</transition>
|
65
59
|
</div>
|
66
|
-
<%-
|
60
|
+
<script src="<%- url_for("/js/main.js") %>"></script>
|
61
|
+
<% if (type === "post" && page.comments) { %>
|
62
|
+
<%- partial("comment") %>
|
63
|
+
<% } %>
|
67
64
|
</body>
|
68
65
|
</html>
|
package/layout/menu.ejs
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
<nav id="menu">
|
1
|
+
<nav id="menu" ref="menu">
|
2
2
|
<div class="desktop-menu">
|
3
3
|
<a class="title" href="<%- config.root %>">
|
4
4
|
<span><%= config.title.toUpperCase() %></span>
|
@@ -10,14 +10,14 @@
|
|
10
10
|
</a>
|
11
11
|
<% }); %>
|
12
12
|
</div>
|
13
|
-
<div
|
14
|
-
<div class="curtain" @click="
|
15
|
-
<div class="title" @click="
|
13
|
+
<div id="mobile-menu">
|
14
|
+
<div class="curtain" v-show="showMenu" @click="showMenu = !showMenu"></div>
|
15
|
+
<div class="title" @click="showMenu = !showMenu">
|
16
16
|
<i class="fa-solid fa-bars fa-fw"></i>
|
17
17
|
<span> <%= config.title.toUpperCase() %></span>
|
18
18
|
</div>
|
19
19
|
<transition name="slide">
|
20
|
-
<div class="items" v-show="
|
20
|
+
<div class="items" v-show="showMenu">
|
21
21
|
<% Object.keys(theme.menu).forEach(key => { %>
|
22
22
|
<a href="<%- url_for(theme.menu[key].src) %>">
|
23
23
|
<div class="item">
|
package/layout/post.ejs
CHANGED
@@ -27,7 +27,13 @@
|
|
27
27
|
<% page.tags.data.forEach(data => { %>
|
28
28
|
<span class="tag">
|
29
29
|
<%
|
30
|
-
const color = [
|
30
|
+
const color = [
|
31
|
+
"color: #ffa2c4",
|
32
|
+
"color: #00bcd4",
|
33
|
+
"color: #03a9f4",
|
34
|
+
"color: #00a596",
|
35
|
+
"color: #ff7d73",
|
36
|
+
];
|
31
37
|
let num = Math.floor(Math.random() * color.length);
|
32
38
|
%>
|
33
39
|
<a href="<%- url_for(data.path) %>" style="<%- color[num] %>"><%= data.name %></a>
|
@@ -39,15 +45,25 @@
|
|
39
45
|
<% if (theme.crypto.enable && typeof page.secret !== "undefined") { %>
|
40
46
|
<%
|
41
47
|
const CryptoJS = crypto();
|
42
|
-
function
|
43
|
-
return CryptoJS.SHA256(
|
48
|
+
function SHA(word) {
|
49
|
+
return CryptoJS.SHA256(word).toString();
|
44
50
|
}
|
45
|
-
function encrypt(
|
46
|
-
return CryptoJS.AES.encrypt(
|
51
|
+
function encrypt(word, secret) {
|
52
|
+
return CryptoJS.AES.encrypt(word, secret).toString();
|
47
53
|
}
|
48
54
|
%>
|
49
|
-
<input
|
50
|
-
|
55
|
+
<input
|
56
|
+
id="crypto"
|
57
|
+
class="input"
|
58
|
+
ref="crypto"
|
59
|
+
placeholder="文章被加密,请输入密码"
|
60
|
+
data-encrypted="<%- encrypt(page.content, page.secret) %>"
|
61
|
+
data-shasum="<%- SHA(page.content) %>"
|
62
|
+
v-model="crypto"
|
63
|
+
/>
|
64
|
+
<transition name="fade">
|
65
|
+
<div class="content" ref="content" v-show="check"></div>
|
66
|
+
</transition>
|
51
67
|
<% } else { %>
|
52
68
|
<div class="content" v-pre>
|
53
69
|
<%- page.content %>
|
package/layout/posts.ejs
CHANGED
@@ -61,7 +61,13 @@
|
|
61
61
|
<% post.tags.data.forEach(data => { %>
|
62
62
|
<span class="tag">
|
63
63
|
<%
|
64
|
-
const color = [
|
64
|
+
const color = [
|
65
|
+
"color: #ffa2c4",
|
66
|
+
"color: #00bcd4",
|
67
|
+
"color: #03a9f4",
|
68
|
+
"color: #00a596",
|
69
|
+
"color: #ff7d73",
|
70
|
+
];
|
65
71
|
let num = Math.floor(Math.random() * color.length);
|
66
72
|
%>
|
67
73
|
<a href="<%- url_for(data.path) %>" style="<%- color[num] %>">
|
package/layout/tags.ejs
CHANGED
@@ -51,7 +51,13 @@
|
|
51
51
|
<% post.tags.data.forEach(data => { %>
|
52
52
|
<span class="tag">
|
53
53
|
<%
|
54
|
-
const color = [
|
54
|
+
const color = [
|
55
|
+
"color: #ffa2c4",
|
56
|
+
"color: #00bcd4",
|
57
|
+
"color: #03a9f4",
|
58
|
+
"color: #00a596",
|
59
|
+
"color: #ff7d73",
|
60
|
+
];
|
55
61
|
let num = Math.floor(Math.random() * color.length);
|
56
62
|
%>
|
57
63
|
<a href="<%- url_for(data.path) %>" style="<%- color[num] %>"><%= data.name %></a>
|
package/package.json
CHANGED
@@ -1,53 +1,3 @@
|
|
1
|
-
@keyframes into {
|
2
|
-
from {
|
3
|
-
opacity: 0;
|
4
|
-
transform: scale(1.1);
|
5
|
-
}
|
6
|
-
to {
|
7
|
-
opacity: 1;
|
8
|
-
transform: scale(1);
|
9
|
-
}
|
10
|
-
}
|
11
|
-
@keyframes loading {
|
12
|
-
from {
|
13
|
-
opacity: 0;
|
14
|
-
}
|
15
|
-
to {
|
16
|
-
opacity: 1;
|
17
|
-
}
|
18
|
-
}
|
19
|
-
@keyframes loop1 {
|
20
|
-
from {
|
21
|
-
transform: rotate(30deg);
|
22
|
-
}
|
23
|
-
to {
|
24
|
-
transform: rotate(390deg);
|
25
|
-
}
|
26
|
-
}
|
27
|
-
@keyframes loop2 {
|
28
|
-
from {
|
29
|
-
transform: rotate(60deg);
|
30
|
-
}
|
31
|
-
to {
|
32
|
-
transform: rotate(420deg);
|
33
|
-
}
|
34
|
-
}
|
35
|
-
@keyframes loop3 {
|
36
|
-
from {
|
37
|
-
transform: rotate(90deg);
|
38
|
-
}
|
39
|
-
to {
|
40
|
-
transform: rotate(450deg);
|
41
|
-
}
|
42
|
-
}
|
43
|
-
@keyframes loop4 {
|
44
|
-
from {
|
45
|
-
transform: rotate(120deg);
|
46
|
-
}
|
47
|
-
to {
|
48
|
-
transform: rotate(480deg);
|
49
|
-
}
|
50
|
-
}
|
51
1
|
#archives {
|
52
2
|
margin: auto;
|
53
3
|
margin-top: 100px;
|
@@ -117,19 +67,19 @@
|
|
117
67
|
text-align: center;
|
118
68
|
width: 100%;
|
119
69
|
}
|
120
|
-
#footer
|
70
|
+
#footer #footer-icon {
|
121
71
|
color: #66afef;
|
122
72
|
display: inline-block;
|
123
73
|
font-size: 18px;
|
124
74
|
margin: 0 10px;
|
125
75
|
}
|
126
|
-
#footer
|
76
|
+
#footer #footer-wrap {
|
127
77
|
border-top: 1px solid #aaa;
|
128
78
|
color: #5c6b72;
|
129
79
|
margin: auto;
|
130
80
|
width: 900px;
|
131
81
|
}
|
132
|
-
#footer
|
82
|
+
#footer #footer-wrap div {
|
133
83
|
margin: 15px;
|
134
84
|
}
|
135
85
|
#home-card {
|
@@ -376,9 +326,42 @@
|
|
376
326
|
#home-posts-wrap,
|
377
327
|
#archives,
|
378
328
|
.article,
|
379
|
-
#footer
|
329
|
+
#footer #footer-wrap {
|
380
330
|
box-sizing: border-box;
|
381
331
|
}
|
332
|
+
#loading {
|
333
|
+
align-items: center;
|
334
|
+
background: #fff;
|
335
|
+
display: flex;
|
336
|
+
flex-direction: column;
|
337
|
+
height: 100vh;
|
338
|
+
justify-content: center;
|
339
|
+
left: 0;
|
340
|
+
position: fixed;
|
341
|
+
top: 0;
|
342
|
+
width: 100vw;
|
343
|
+
z-index: 2147483647;
|
344
|
+
}
|
345
|
+
#loading h2,
|
346
|
+
#loading p,
|
347
|
+
#loading img {
|
348
|
+
margin: 10px;
|
349
|
+
}
|
350
|
+
#loading img {
|
351
|
+
border-radius: 0;
|
352
|
+
height: 50px;
|
353
|
+
}
|
354
|
+
#loading-circle {
|
355
|
+
align-items: center;
|
356
|
+
border: 10px solid #a3ddfb;
|
357
|
+
border-radius: 50%;
|
358
|
+
display: flex;
|
359
|
+
flex-direction: column;
|
360
|
+
height: 50vmin;
|
361
|
+
justify-content: center;
|
362
|
+
padding: 50px;
|
363
|
+
width: 50vmin;
|
364
|
+
}
|
382
365
|
#main {
|
383
366
|
margin-right: calc(100% - 100vw);
|
384
367
|
overflow: auto;
|
@@ -391,8 +374,8 @@
|
|
391
374
|
position: fixed;
|
392
375
|
top: 0;
|
393
376
|
transition: background 0.25s ease-out, top 0.25s ease-out;
|
394
|
-
width:
|
395
|
-
z-index:
|
377
|
+
width: 100vw;
|
378
|
+
z-index: 10004;
|
396
379
|
}
|
397
380
|
#menu .desktop-menu {
|
398
381
|
height: 50px;
|
@@ -408,11 +391,11 @@
|
|
408
391
|
display: inline-block;
|
409
392
|
margin-left: 30px;
|
410
393
|
}
|
411
|
-
#menu
|
394
|
+
#menu #mobile-menu {
|
412
395
|
min-height: 50px;
|
413
396
|
text-align: center;
|
414
397
|
}
|
415
|
-
#menu
|
398
|
+
#menu #mobile-menu .curtain {
|
416
399
|
height: 100%;
|
417
400
|
left: 0;
|
418
401
|
position: fixed;
|
@@ -420,26 +403,26 @@
|
|
420
403
|
width: 100%;
|
421
404
|
z-index: -1;
|
422
405
|
}
|
423
|
-
#menu
|
406
|
+
#menu #mobile-menu .items {
|
424
407
|
padding: 10px 0 20px;
|
425
|
-
z-index:
|
408
|
+
z-index: 10002;
|
426
409
|
}
|
427
|
-
#menu
|
410
|
+
#menu #mobile-menu .items .item {
|
428
411
|
display: flex;
|
429
412
|
justify-content: center;
|
430
413
|
margin: auto;
|
431
414
|
min-width: 200px;
|
432
415
|
width: 80%;
|
433
416
|
}
|
434
|
-
#menu
|
417
|
+
#menu #mobile-menu .items a {
|
435
418
|
color: #555;
|
436
419
|
}
|
437
|
-
#menu
|
420
|
+
#menu #mobile-menu .title {
|
438
421
|
color: #555;
|
439
422
|
cursor: pointer;
|
440
|
-
z-index:
|
423
|
+
z-index: 10003;
|
441
424
|
}
|
442
|
-
#menu.hidden
|
425
|
+
#menu.hidden {
|
443
426
|
top: -70px !important;
|
444
427
|
}
|
445
428
|
#menu.menu-color {
|
@@ -450,38 +433,32 @@
|
|
450
433
|
#menu.menu-color a {
|
451
434
|
color: #fff !important;
|
452
435
|
}
|
453
|
-
#
|
454
|
-
margin: 0 auto 50px;
|
455
|
-
}
|
456
|
-
#search-mask {
|
457
|
-
background: #f6f8fa;
|
458
|
-
height: 150px;
|
459
|
-
margin: auto;
|
460
|
-
margin-bottom: -25px;
|
461
|
-
margin-top: -125px;
|
462
|
-
width: 100%;
|
463
|
-
}
|
464
|
-
#showimg {
|
436
|
+
#preview {
|
465
437
|
align-items: center;
|
466
438
|
background-color: #fffc;
|
467
439
|
display: flex;
|
468
440
|
height: 100vh;
|
469
441
|
justify-content: center;
|
470
442
|
left: 0;
|
471
|
-
opacity: 0;
|
472
443
|
position: fixed;
|
473
444
|
top: 0;
|
474
|
-
transition: opacity 0.25s, visibility 0.25s;
|
475
|
-
visibility: hidden;
|
476
445
|
width: 100vw;
|
477
|
-
z-index:
|
446
|
+
z-index: 10005;
|
478
447
|
}
|
479
|
-
#
|
448
|
+
#preview-content {
|
480
449
|
box-shadow: 0 0 50px 10px #d9d9d980;
|
481
450
|
margin: auto;
|
482
451
|
max-height: 95%;
|
483
452
|
max-width: 95%;
|
484
453
|
}
|
454
|
+
#search-bar {
|
455
|
+
margin: 0 auto 50px;
|
456
|
+
z-index: 10001;
|
457
|
+
}
|
458
|
+
#timeline-wrap {
|
459
|
+
display: flex;
|
460
|
+
flex-direction: column-reverse;
|
461
|
+
}
|
485
462
|
* {
|
486
463
|
margin: 0;
|
487
464
|
padding: 0;
|
@@ -547,6 +524,14 @@ body::-webkit-scrollbar-track {
|
|
547
524
|
.copycode:not(.copied) i:last-child {
|
548
525
|
opacity: 0;
|
549
526
|
}
|
527
|
+
.fade-enter-active,
|
528
|
+
.fade-leave-active {
|
529
|
+
transition: opacity 0.3s;
|
530
|
+
}
|
531
|
+
.fade-enter-from,
|
532
|
+
.fade-leave-to {
|
533
|
+
opacity: 0;
|
534
|
+
}
|
550
535
|
.icon {
|
551
536
|
color: #5c6b72;
|
552
537
|
margin-right: 5px;
|
@@ -575,7 +560,15 @@ body::-webkit-scrollbar-track {
|
|
575
560
|
}
|
576
561
|
.into-enter-active,
|
577
562
|
.into-leave-active {
|
578
|
-
|
563
|
+
transition: opacity 0.5s, transform 0.5s;
|
564
|
+
}
|
565
|
+
.into-enter-from,
|
566
|
+
.into-leave-to {
|
567
|
+
opacity: 0;
|
568
|
+
transform: scale(1.1);
|
569
|
+
}
|
570
|
+
.katex {
|
571
|
+
overflow: auto;
|
579
572
|
}
|
580
573
|
.language {
|
581
574
|
background: linear-gradient(to right, #ed6ea0 0%, #ec8c69 100%);
|
@@ -589,14 +582,18 @@ body::-webkit-scrollbar-track {
|
|
589
582
|
position: absolute;
|
590
583
|
top: 0;
|
591
584
|
}
|
592
|
-
.katex {
|
593
|
-
overflow: auto;
|
594
|
-
}
|
595
585
|
.page-num,
|
596
586
|
.icon-link a,
|
597
587
|
.friend-link a {
|
598
588
|
transition: background 0.25s, color 0.25s;
|
599
589
|
}
|
590
|
+
.page-num:hover,
|
591
|
+
.icon-link a:hover,
|
592
|
+
.friend-link a:hover,
|
593
|
+
.categories-tags a:hover,
|
594
|
+
.go-post:hover {
|
595
|
+
opacity: 1;
|
596
|
+
}
|
600
597
|
.slide-enter-active,
|
601
598
|
.slide-leave-active {
|
602
599
|
transition: margin-top 0.3s, opacity 0.3s;
|
@@ -608,7 +605,7 @@ body::-webkit-scrollbar-track {
|
|
608
605
|
}
|
609
606
|
.timeline {
|
610
607
|
margin-bottom: 30px;
|
611
|
-
transition: margin-top 0.5s, opacity 0.
|
608
|
+
transition: margin-top 0.5s, opacity 0.3s, visibility 0.3s;
|
612
609
|
}
|
613
610
|
.timeline-content {
|
614
611
|
background: #fff;
|
@@ -690,6 +687,7 @@ audio,
|
|
690
687
|
iframe,
|
691
688
|
#home-head,
|
692
689
|
#menu,
|
690
|
+
#loading,
|
693
691
|
.katex,
|
694
692
|
.go-post,
|
695
693
|
.page-current,
|
@@ -720,13 +718,6 @@ h6 {
|
|
720
718
|
font-weight: bold;
|
721
719
|
margin: 15px 0;
|
722
720
|
}
|
723
|
-
.page-num:hover,
|
724
|
-
.icon-link a:hover,
|
725
|
-
.friend-link a:hover,
|
726
|
-
.categories-tags a:hover,
|
727
|
-
.go-post:hover {
|
728
|
-
opacity: 1;
|
729
|
-
}
|
730
721
|
h2 {
|
731
722
|
font-size: 27px;
|
732
723
|
}
|
@@ -801,6 +792,38 @@ ul li,
|
|
801
792
|
ol li {
|
802
793
|
margin: 8px 0;
|
803
794
|
}
|
795
|
+
@keyframes loop1 {
|
796
|
+
from {
|
797
|
+
transform: rotate(30deg);
|
798
|
+
}
|
799
|
+
to {
|
800
|
+
transform: rotate(390deg);
|
801
|
+
}
|
802
|
+
}
|
803
|
+
@keyframes loop2 {
|
804
|
+
from {
|
805
|
+
transform: rotate(60deg);
|
806
|
+
}
|
807
|
+
to {
|
808
|
+
transform: rotate(420deg);
|
809
|
+
}
|
810
|
+
}
|
811
|
+
@keyframes loop3 {
|
812
|
+
from {
|
813
|
+
transform: rotate(90deg);
|
814
|
+
}
|
815
|
+
to {
|
816
|
+
transform: rotate(450deg);
|
817
|
+
}
|
818
|
+
}
|
819
|
+
@keyframes loop4 {
|
820
|
+
from {
|
821
|
+
transform: rotate(120deg);
|
822
|
+
}
|
823
|
+
to {
|
824
|
+
transform: rotate(480deg);
|
825
|
+
}
|
826
|
+
}
|
804
827
|
@media (min-width: 900px) {
|
805
828
|
#home-card {
|
806
829
|
margin-right: auto;
|
@@ -851,12 +874,12 @@ ol li {
|
|
851
874
|
#menu .desktop-menu {
|
852
875
|
display: block;
|
853
876
|
}
|
854
|
-
#menu
|
877
|
+
#menu #mobile-menu {
|
855
878
|
display: none;
|
856
879
|
}
|
857
880
|
.article,
|
858
881
|
#archives,
|
859
|
-
#footer
|
882
|
+
#footer #footer-wrap {
|
860
883
|
width: 900px;
|
861
884
|
}
|
862
885
|
.home-posts-wrap-no-card #home-posts {
|
@@ -932,14 +955,14 @@ ol li {
|
|
932
955
|
#home-posts-wrap,
|
933
956
|
.article,
|
934
957
|
#archives,
|
935
|
-
#footer
|
958
|
+
#footer #footer-wrap {
|
936
959
|
width: 100%;
|
937
960
|
}
|
938
961
|
#menu .desktop-menu,
|
939
962
|
#home-card {
|
940
963
|
display: none;
|
941
964
|
}
|
942
|
-
#menu
|
965
|
+
#menu #mobile-menu {
|
943
966
|
display: block;
|
944
967
|
}
|
945
968
|
ul,
|
@@ -0,0 +1,41 @@
|
|
1
|
+
const cryptoMixin = {
|
2
|
+
data() {
|
3
|
+
return {
|
4
|
+
crypto: "",
|
5
|
+
check: false,
|
6
|
+
};
|
7
|
+
},
|
8
|
+
methods: {
|
9
|
+
SHA(word) {
|
10
|
+
return CryptoJS.SHA256(word).toString();
|
11
|
+
},
|
12
|
+
decrypt(word, secret, shasum) {
|
13
|
+
try {
|
14
|
+
let res = CryptoJS.AES.decrypt(word, secret).toString(CryptoJS.enc.Utf8);
|
15
|
+
return { check: this.SHA(res) === shasum, decrypted: res };
|
16
|
+
} catch {
|
17
|
+
return { check: false };
|
18
|
+
}
|
19
|
+
},
|
20
|
+
},
|
21
|
+
watch: {
|
22
|
+
crypto(value) {
|
23
|
+
let input = this.$refs.crypto,
|
24
|
+
content = this.$refs.content;
|
25
|
+
let { decrypted, check } = this.decrypt(
|
26
|
+
input.dataset.encrypted,
|
27
|
+
value,
|
28
|
+
input.dataset.shasum
|
29
|
+
);
|
30
|
+
this.check = check;
|
31
|
+
if (check) {
|
32
|
+
input.classList.remove("fail");
|
33
|
+
input.classList.add("success");
|
34
|
+
input.disabled = true;
|
35
|
+
content.innerHTML = decrypted;
|
36
|
+
this.render();
|
37
|
+
} else input.classList.add("fail");
|
38
|
+
},
|
39
|
+
},
|
40
|
+
};
|
41
|
+
mixins.push(cryptoMixin);
|
@@ -0,0 +1,32 @@
|
|
1
|
+
const highlightMixin = {
|
2
|
+
data() {
|
3
|
+
return { copying: false };
|
4
|
+
},
|
5
|
+
mounted() {
|
6
|
+
hljs.configure({ ignoreUnescapedHTML: true });
|
7
|
+
},
|
8
|
+
methods: {
|
9
|
+
highlight() {
|
10
|
+
let that = this;
|
11
|
+
let codes = document.getElementsByTagName("pre");
|
12
|
+
for (let i of codes) {
|
13
|
+
let lang = [...i.classList, ...i.firstChild.classList][0] || "plaintext";
|
14
|
+
let code = i.innerText;
|
15
|
+
i.innerHTML = `<div class="code-content">${code}</div><div class="language">${lang}</div><div class="copycode"><i class="fa-solid fa-copy fa-fw"></i><i class="fa-solid fa-clone fa-fw"></i></div>`;
|
16
|
+
let copycode = i.getElementsByClassName("copycode")[0];
|
17
|
+
copycode.addEventListener("click", async function () {
|
18
|
+
if (that.copying) return;
|
19
|
+
that.copying = true;
|
20
|
+
this.classList.add("copied");
|
21
|
+
await navigator.clipboard.writeText(code);
|
22
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
23
|
+
this.classList.remove("copied");
|
24
|
+
that.copying = false;
|
25
|
+
});
|
26
|
+
let content = i.getElementsByClassName("code-content")[0];
|
27
|
+
hljs.highlightElement(content);
|
28
|
+
}
|
29
|
+
},
|
30
|
+
},
|
31
|
+
};
|
32
|
+
mixins.push(highlightMixin);
|
@@ -0,0 +1,15 @@
|
|
1
|
+
const mathMixin = {
|
2
|
+
methods: {
|
3
|
+
math() {
|
4
|
+
renderMathInElement(document.body, {
|
5
|
+
delimiters: [
|
6
|
+
{ left: "$$", right: "$$", display: true },
|
7
|
+
{ left: "$", right: "$", display: false },
|
8
|
+
{ left: "\\(", right: "\\)", display: false },
|
9
|
+
{ left: "\\[", right: "\\]", display: true },
|
10
|
+
],
|
11
|
+
});
|
12
|
+
},
|
13
|
+
},
|
14
|
+
};
|
15
|
+
mixins.push(mathMixin);
|
@@ -0,0 +1,26 @@
|
|
1
|
+
const previewMixin = {
|
2
|
+
data() {
|
3
|
+
return { previewShow: false };
|
4
|
+
},
|
5
|
+
methods: {
|
6
|
+
preview() {
|
7
|
+
let that = this;
|
8
|
+
let preview = this.$refs.preview,
|
9
|
+
content = this.$refs.previewContent,
|
10
|
+
images = document.getElementsByTagName("img");
|
11
|
+
for (let i of images)
|
12
|
+
i.addEventListener("click", function () {
|
13
|
+
content.alt = this.alt;
|
14
|
+
content.src = this.src;
|
15
|
+
that.previewShow = true;
|
16
|
+
});
|
17
|
+
preview.addEventListener("click", () => {
|
18
|
+
this.previewShow = false;
|
19
|
+
});
|
20
|
+
window.addEventListener("resize", () => {
|
21
|
+
this.previewShow = false;
|
22
|
+
});
|
23
|
+
},
|
24
|
+
},
|
25
|
+
};
|
26
|
+
mixins.push(previewMixin);
|
@@ -0,0 +1,28 @@
|
|
1
|
+
const searchMixin = {
|
2
|
+
data() {
|
3
|
+
return {
|
4
|
+
rawSearch: "",
|
5
|
+
};
|
6
|
+
},
|
7
|
+
watch: {
|
8
|
+
search(value) {
|
9
|
+
let timeline = this.$refs.timeline.childNodes;
|
10
|
+
for (let i of timeline)
|
11
|
+
if (!value || i.dataset.title.includes(value)) {
|
12
|
+
i.style.opacity = 1;
|
13
|
+
i.style.visibility = "visible";
|
14
|
+
i.style.marginTop = 0;
|
15
|
+
} else {
|
16
|
+
i.style.opacity = 0;
|
17
|
+
i.style.visibility = "hidden";
|
18
|
+
i.style.marginTop = -i.offsetHeight - 30 + "px";
|
19
|
+
}
|
20
|
+
},
|
21
|
+
},
|
22
|
+
computed: {
|
23
|
+
search() {
|
24
|
+
return this.rawSearch.toLowerCase().replace(/s+/gm, "");
|
25
|
+
},
|
26
|
+
},
|
27
|
+
};
|
28
|
+
mixins.push(searchMixin);
|
@@ -0,0 +1,47 @@
|
|
1
|
+
const app = Vue.createApp({
|
2
|
+
mixins,
|
3
|
+
data() {
|
4
|
+
return {
|
5
|
+
loading: true,
|
6
|
+
showMenu: false,
|
7
|
+
barLocal: 0,
|
8
|
+
};
|
9
|
+
},
|
10
|
+
created() {
|
11
|
+
window.addEventListener("load", () => {
|
12
|
+
this.loading = false;
|
13
|
+
});
|
14
|
+
},
|
15
|
+
mounted() {
|
16
|
+
if (this.$refs.head) this.$refs.menu.classList.add("menu-color");
|
17
|
+
window.addEventListener("scroll", this.handleScroll, true);
|
18
|
+
this.render();
|
19
|
+
},
|
20
|
+
methods: {
|
21
|
+
homeClick() {
|
22
|
+
window.scrollTo({ top: window.innerHeight, behavior: "smooth" });
|
23
|
+
},
|
24
|
+
handleScroll() {
|
25
|
+
let menu = this.$refs.menu,
|
26
|
+
wrap = this.$refs.wrap;
|
27
|
+
let newlocal = document.documentElement.scrollTop;
|
28
|
+
if (this.barLocal < newlocal) {
|
29
|
+
this.showMenu = false;
|
30
|
+
menu.classList.add("hidden");
|
31
|
+
} else menu.classList.remove("hidden");
|
32
|
+
if (wrap) {
|
33
|
+
if (newlocal <= window.innerHeight - 100) menu.classList.add("menu-color");
|
34
|
+
else menu.classList.remove("menu-color");
|
35
|
+
if (newlocal <= 400) wrap.style.marginTop = -newlocal / 5 + "px";
|
36
|
+
else wrap.style.marginTop = "-80px";
|
37
|
+
}
|
38
|
+
this.barLocal = newlocal;
|
39
|
+
},
|
40
|
+
render() {
|
41
|
+
if (typeof this.highlight !== "undefined") this.highlight();
|
42
|
+
if (typeof this.math !== "undefined") this.math();
|
43
|
+
this.preview();
|
44
|
+
},
|
45
|
+
},
|
46
|
+
});
|
47
|
+
app.mount("#layout");
|
package/layout/loading.ejs
DELETED
@@ -1,9 +0,0 @@
|
|
1
|
-
<div id="loading" style="height: 100vh; width: 100vw; left: 0; top: 0; position: fixed; display: flex; z-index: 2147483647; background: #fff; transition: opacity 0.3s ease-out; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; pointer-events: none">
|
2
|
-
<div style="width: 50vmin; height: 50vmin; margin: auto; padding: 50px; border-radius: 50%; display: flex; border: solid 10px #a3ddfb">
|
3
|
-
<div style="margin: auto; text-align: center">
|
4
|
-
<h2>LOADING</h2>
|
5
|
-
<p>加载过慢请开启缓存,浏览器默认开启</p>
|
6
|
-
<img src="<%- url_for("/images/loading.gif") %>" style="height: 50px; border-radius: 0">
|
7
|
-
</div>
|
8
|
-
</div>
|
9
|
-
</div>
|
package/source/js/functions.js
DELETED
@@ -1,71 +0,0 @@
|
|
1
|
-
function sleep(ms) {
|
2
|
-
return new Promise(resolve => setTimeout(resolve, ms));
|
3
|
-
}
|
4
|
-
let copying = false;
|
5
|
-
function highlight() {
|
6
|
-
hljs.configure({ ignoreUnescapedHTML: true });
|
7
|
-
let codes = document.getElementsByTagName("pre");
|
8
|
-
for (let i of codes) {
|
9
|
-
let lang = [...i.classList, ...i.firstChild.classList][0] || "plaintext";
|
10
|
-
i.innerHTML = `<div class="code-content">${i.innerHTML}</div><div class="language">${lang}</div><div class="copycode"><i class="fa-solid fa-copy fa-fw"></i><i class="fa-solid fa-clone fa-fw"></i></div>`;
|
11
|
-
let copycode = i.getElementsByClassName("copycode")[0];
|
12
|
-
copycode.addEventListener("click", async function () {
|
13
|
-
if (copying) return;
|
14
|
-
copying = true;
|
15
|
-
this.classList.add("copied");
|
16
|
-
await navigator.clipboard.writeText(this.parentElement.firstChild.innerText);
|
17
|
-
await sleep(1000);
|
18
|
-
this.classList.remove("copied");
|
19
|
-
copying = false;
|
20
|
-
});
|
21
|
-
hljs.highlightElement(i.getElementsByClassName("code-content")[0]);
|
22
|
-
}
|
23
|
-
}
|
24
|
-
function showimg() {
|
25
|
-
let wrap = document.getElementById("showimg"),
|
26
|
-
content = document.getElementById("showimg-content"),
|
27
|
-
images = document.querySelectorAll(".article .content img");
|
28
|
-
function show(image) {
|
29
|
-
content.alt = image.alt;
|
30
|
-
content.src = image.src;
|
31
|
-
wrap.style.opacity = 1;
|
32
|
-
wrap.style.visibility = "visible";
|
33
|
-
}
|
34
|
-
function hide() {
|
35
|
-
wrap.style.opacity = 0;
|
36
|
-
wrap.style.visibility = "hidden";
|
37
|
-
}
|
38
|
-
for (let i of images)
|
39
|
-
i.addEventListener("click", function () {
|
40
|
-
show(this);
|
41
|
-
});
|
42
|
-
wrap.addEventListener("click", hide);
|
43
|
-
window.addEventListener("resize", hide);
|
44
|
-
}
|
45
|
-
function rendermath() {
|
46
|
-
if (typeof renderMathInElement !== "undefined")
|
47
|
-
renderMathInElement(document.body, {
|
48
|
-
delimiters: [
|
49
|
-
{ left: "$$", right: "$$", display: true },
|
50
|
-
{ left: "$", right: "$", display: false },
|
51
|
-
{ left: "\\(", right: "\\)", display: false },
|
52
|
-
{ left: "\\[", right: "\\]", display: true },
|
53
|
-
],
|
54
|
-
});
|
55
|
-
}
|
56
|
-
function renderall() {
|
57
|
-
highlight();
|
58
|
-
showimg();
|
59
|
-
rendermath();
|
60
|
-
}
|
61
|
-
function sha(str) {
|
62
|
-
return CryptoJS.SHA256(str).toString();
|
63
|
-
}
|
64
|
-
function decrypt(str, key, shasum) {
|
65
|
-
try {
|
66
|
-
let res = CryptoJS.AES.decrypt(str, key).toString(CryptoJS.enc.Utf8);
|
67
|
-
return { decrypt: res, check: sha(res) === shasum };
|
68
|
-
} catch {
|
69
|
-
return { check: false };
|
70
|
-
}
|
71
|
-
}
|
package/source/js/particlex.js
DELETED
@@ -1,98 +0,0 @@
|
|
1
|
-
const app = Vue.createApp({
|
2
|
-
data() {
|
3
|
-
return {
|
4
|
-
showpage: false,
|
5
|
-
menushow: false,
|
6
|
-
cardtop: 100,
|
7
|
-
barlocal: 0,
|
8
|
-
composition: false,
|
9
|
-
};
|
10
|
-
},
|
11
|
-
created() {
|
12
|
-
window.addEventListener("load", () => {
|
13
|
-
this.showpage = true;
|
14
|
-
document.getElementById("loading").style.opacity = 0;
|
15
|
-
});
|
16
|
-
},
|
17
|
-
mounted() {
|
18
|
-
if (document.getElementById("home-head"))
|
19
|
-
document.getElementById("menu").className += " menu-color";
|
20
|
-
if (document.getElementById("crypto")) {
|
21
|
-
let input = document.getElementById("crypto");
|
22
|
-
input.addEventListener("input", () => {
|
23
|
-
if (!this.composition) this.handlecrypto();
|
24
|
-
});
|
25
|
-
input.addEventListener("compositionstart", () => {
|
26
|
-
this.composition = true;
|
27
|
-
});
|
28
|
-
input.addEventListener("compositionend", () => {
|
29
|
-
this.handlecrypto();
|
30
|
-
this.composition = false;
|
31
|
-
});
|
32
|
-
}
|
33
|
-
if (document.getElementById("search-bar")) {
|
34
|
-
let input = document.getElementById("search-bar");
|
35
|
-
input.addEventListener("input", () => {
|
36
|
-
if (!this.composition) this.handlesearch();
|
37
|
-
});
|
38
|
-
input.addEventListener("compositionstart", () => {
|
39
|
-
this.composition = true;
|
40
|
-
});
|
41
|
-
input.addEventListener("compositionend", () => {
|
42
|
-
this.handlesearch();
|
43
|
-
this.composition = false;
|
44
|
-
});
|
45
|
-
}
|
46
|
-
window.addEventListener("scroll", this.handlescroll, true);
|
47
|
-
renderall();
|
48
|
-
},
|
49
|
-
methods: {
|
50
|
-
homeclick() {
|
51
|
-
window.scrollTo({ top: window.innerHeight, behavior: "smooth" });
|
52
|
-
},
|
53
|
-
handlescroll() {
|
54
|
-
let newlocal = document.documentElement.scrollTop;
|
55
|
-
let menu = document.getElementById("menu");
|
56
|
-
let wrap = document.getElementById("home-posts-wrap");
|
57
|
-
if (this.barlocal < newlocal) {
|
58
|
-
menu.className = "hidden-menu";
|
59
|
-
this.menushow = false;
|
60
|
-
} else menu.className = "show-menu";
|
61
|
-
if (wrap) {
|
62
|
-
if (newlocal <= window.innerHeight - 100) menu.className += " menu-color";
|
63
|
-
if (newlocal <= 400) wrap.style.marginTop = newlocal / -5 + "px";
|
64
|
-
else wrap.style.marginTop = "-80px";
|
65
|
-
}
|
66
|
-
this.barlocal = newlocal;
|
67
|
-
},
|
68
|
-
handlecrypto() {
|
69
|
-
let input = document.getElementById("crypto"),
|
70
|
-
content = document.getElementsByClassName("content")[0];
|
71
|
-
let res = decrypt(input.dataset.encrypt, input.value, input.dataset.shasum);
|
72
|
-
if (res.check) {
|
73
|
-
input.disabled = true;
|
74
|
-
input.classList.remove("fail");
|
75
|
-
input.classList.add("success");
|
76
|
-
content.innerHTML = res.decrypt;
|
77
|
-
content.style.opacity = 1;
|
78
|
-
renderall();
|
79
|
-
} else input.classList.add("fail");
|
80
|
-
},
|
81
|
-
handlesearch() {
|
82
|
-
let input = document.getElementById("search-bar"),
|
83
|
-
timeline = document.getElementsByClassName("timeline"),
|
84
|
-
key = input.value.toLowerCase().replace(/s+/gm, "");
|
85
|
-
for (let i of timeline)
|
86
|
-
if (!key || i.dataset.title.includes(key)) {
|
87
|
-
i.style.opacity = 1;
|
88
|
-
i.style.pointerEvents = "";
|
89
|
-
i.style.marginTop = "";
|
90
|
-
} else {
|
91
|
-
i.style.opacity = 0;
|
92
|
-
i.style.pointerEvents = "none";
|
93
|
-
i.style.marginTop = -i.offsetHeight - 30 + "px";
|
94
|
-
}
|
95
|
-
},
|
96
|
-
},
|
97
|
-
});
|
98
|
-
app.mount("#layout");
|