hexo-theme-particlex 2.1.0 → 2.1.2
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +8 -15
- package/_config.yml +0 -1
- package/layout/archives.ejs +3 -5
- package/layout/categories.ejs +11 -1
- package/layout/layout.ejs +5 -1
- package/layout/post.ejs +4 -6
- package/layout/tags.ejs +11 -1
- package/package.json +1 -2
- package/source/css/particlex.css +30 -76
- package/source/js/functions.js +28 -11
- package/source/js/particlex.js +62 -14
- package/source/js/cryptor.js +0 -44
- package/source/js/searcher.js +0 -43
package/README.md
CHANGED
@@ -139,7 +139,7 @@ highlightStyle: github # Highlight style
|
|
139
139
|
|
140
140
|
一般来说,缩略展示文档只需要在文档中添加 `<!-- more -->` 即可,缩略内容在显示全文中也会出现
|
141
141
|
|
142
|
-
但考虑到不想把缩略内容放在正文里,就添加了此参数,在 Front-Matter 里设置
|
142
|
+
但考虑到不想把缩略内容放在正文里,就添加了此参数,在 [Front-Matter](https://hexo.io/zh-cn/docs/front-matter) 里设置
|
143
143
|
|
144
144
|
支持 Markdown 格式
|
145
145
|
|
@@ -184,9 +184,13 @@ highlightStyle: github # Highlight style
|
|
184
184
|
enable: false
|
185
185
|
```
|
186
186
|
|
187
|
+
- 文章置顶
|
188
|
+
|
189
|
+
在 [Front-Matter](https://hexo.io/zh-cn/docs/front-matter) 里设置 `top` 作为置顶参数,越大越靠前,默认为 0
|
190
|
+
|
187
191
|
- 文章加密
|
188
192
|
|
189
|
-
使用 AES 加密算法,在 Front-Matter 里设置 `password` 作为密码,**使用请安装插件 [Hexo-Helper-Crypto](https://github.com/argvchs/hexo-helper-crypto)**
|
193
|
+
使用 AES 加密算法,在 [Front-Matter](https://hexo.io/zh-cn/docs/front-matter) 里设置 `password` 作为密码,**使用请安装插件 [Hexo-Helper-Crypto](https://github.com/argvchs/hexo-helper-crypto)**
|
190
194
|
|
191
195
|
```yaml
|
192
196
|
crypto:
|
@@ -195,24 +199,13 @@ highlightStyle: github # Highlight style
|
|
195
199
|
|
196
200
|
- 搜索
|
197
201
|
|
198
|
-
嵌入到 Archives
|
202
|
+
嵌入到 Archives 中的搜索,默认关闭
|
199
203
|
|
200
|
-
|
201
|
-
|
202
|
-
要同时在主题和根目录的两个 `_config.yml` 添加配置
|
204
|
+
目前只支持搜索文档标题(我太弱了)
|
203
205
|
|
204
206
|
```yaml
|
205
|
-
# Theme config
|
206
207
|
search:
|
207
208
|
enable: false
|
208
|
-
path: /search.json
|
209
|
-
```
|
210
|
-
|
211
|
-
```yaml
|
212
|
-
# Site config
|
213
|
-
search:
|
214
|
-
path: /search.json
|
215
|
-
optimize: true
|
216
209
|
```
|
217
210
|
|
218
211
|
- Gitalk
|
package/_config.yml
CHANGED
package/layout/archives.ejs
CHANGED
@@ -1,12 +1,10 @@
|
|
1
1
|
<div id="archives">
|
2
2
|
<% if (theme.search.enable) { %>
|
3
|
-
<div
|
4
|
-
<input
|
5
|
-
<script src="<%- url_for("/js/searcher.js") %>"></script>
|
6
|
-
<script>searcher.init("<%- url_for(theme.search.path) %>");</script>
|
3
|
+
<div id="search-mask" style="z-index: <%= site.posts.length + 1 %>"></div>
|
4
|
+
<input id="search-bar" class="ipt" placeholder="搜索" style="z-index: <%= site.posts.length + 2 %>">
|
7
5
|
<% } %>
|
8
6
|
<% site.posts.forEach((post, id) => { %>
|
9
|
-
<div class="timeline"
|
7
|
+
<div class="timeline" style="z-index: <%= site.posts.length - id %>" data-title="<%- post.title.toLowerCase().replace(/\s+/gm, "") %>">
|
10
8
|
<div class="timeline-tail"></div>
|
11
9
|
<div class="timeline-content">
|
12
10
|
<div class="item-time"><%- date(post.date, "YYYY/M/D") %></div>
|
package/layout/categories.ejs
CHANGED
@@ -16,7 +16,17 @@
|
|
16
16
|
<%= category.name %>
|
17
17
|
</a>
|
18
18
|
</span>
|
19
|
-
<% if (is_category(category.name)) {
|
19
|
+
<% if (is_category(category.name)) { %>
|
20
|
+
<%
|
21
|
+
posts = category.posts;
|
22
|
+
posts.data.sort((a, b) => {
|
23
|
+
if (typeof a.top === "undefined") a.top = 0;
|
24
|
+
if (typeof b.top === "undefined") b.top = 0;
|
25
|
+
return a.top == b.top ? b.date - a.date : b.top - a.top
|
26
|
+
});
|
27
|
+
%>
|
28
|
+
<% } %>
|
29
|
+
<% }); %>
|
20
30
|
</div>
|
21
31
|
<% posts.forEach(post => { %>
|
22
32
|
<div class="timeline">
|
package/layout/layout.ejs
CHANGED
@@ -20,7 +20,11 @@
|
|
20
20
|
else if (is_archive() || is_year() || is_month())
|
21
21
|
title = "Archives | ";
|
22
22
|
title += config.title;
|
23
|
-
site.posts.data.sort((a, b) =>
|
23
|
+
site.posts.data.sort((a, b) => {
|
24
|
+
if (typeof a.top === "undefined") a.top = 0;
|
25
|
+
if (typeof b.top === "undefined") b.top = 0;
|
26
|
+
return a.top == b.top ? b.date - a.date : b.top - a.top;
|
27
|
+
});
|
24
28
|
%>
|
25
29
|
<!DOCTYPE html>
|
26
30
|
<html lang="<%- config.language %>">
|
package/layout/post.ejs
CHANGED
@@ -41,21 +41,19 @@
|
|
41
41
|
<% if (typeof page.password !== "undefined" && theme.crypto.enable) { %>
|
42
42
|
<%
|
43
43
|
const CryptoJS = crypto();
|
44
|
-
function
|
44
|
+
function sha(str) {
|
45
45
|
return CryptoJS.SHA256(str).toString(CryptoJS.enc.Base64);
|
46
46
|
}
|
47
47
|
function encrypt(str, key) {
|
48
|
-
return CryptoJS.AES.encrypt(str,
|
48
|
+
return CryptoJS.AES.encrypt(str, sha(key), {
|
49
49
|
mode: CryptoJS.mode.ECB,
|
50
50
|
padding: CryptoJS.pad.Pkcs7,
|
51
51
|
}).toString();
|
52
52
|
}
|
53
53
|
%>
|
54
|
-
<input class="ipt crypto" placeholder="文章被加密,请输入密码">
|
55
|
-
<div class="content" v-pre></div>
|
56
54
|
<script src="https://cdn.staticfile.org/crypto-js/4.1.1/crypto-js.min.js"></script>
|
57
|
-
<
|
58
|
-
<
|
55
|
+
<input id="crypto" class="ipt" placeholder="文章被加密,请输入密码" data-encrypt="<%- encrypt(page.content, page.password.toString()) %>" data-check="<%- sha(page.content) %>">
|
56
|
+
<div class="content" style="opacity: 0" v-pre></div>
|
59
57
|
<% } else { %>
|
60
58
|
<div class="content" v-pre>
|
61
59
|
<%- page.content %>
|
package/layout/tags.ejs
CHANGED
@@ -16,7 +16,17 @@
|
|
16
16
|
<%= tag.name %>
|
17
17
|
</a>
|
18
18
|
</span>
|
19
|
-
<% if (is_tag(tag.name)) {
|
19
|
+
<% if (is_tag(tag.name)) { %>
|
20
|
+
<%
|
21
|
+
posts = tag.posts;
|
22
|
+
posts.data.sort((a, b) => {
|
23
|
+
if (typeof a.top === "undefined") a.top = 0;
|
24
|
+
if (typeof b.top === "undefined") b.top = 0;
|
25
|
+
return a.top == b.top ? b.date - a.date : b.top - a.top;
|
26
|
+
});
|
27
|
+
%>
|
28
|
+
<% } %>
|
29
|
+
<% }); %>
|
20
30
|
</div>
|
21
31
|
<% posts.forEach(post => { %>
|
22
32
|
<div class="timeline">
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "hexo-theme-particlex",
|
3
|
-
"version": "2.1.
|
3
|
+
"version": "2.1.2",
|
4
4
|
"description": "A concise Hexo theme, based on Particle.",
|
5
5
|
"scripts": {
|
6
6
|
"test": "echo \"Error: no test specified\" && exit 1"
|
@@ -24,7 +24,6 @@
|
|
24
24
|
},
|
25
25
|
"homepage": "https://github.com/argvchs/hexo-theme-particlex#readme",
|
26
26
|
"dependencies": {
|
27
|
-
"hexo-generator-search-lite": "^1.0.8",
|
28
27
|
"hexo-helper-crypto": "^1.0.4",
|
29
28
|
"hexo-renderer-babeljs": "^1.0.7",
|
30
29
|
"hexo-renderer-ejs": "^2.0.0"
|
package/source/css/particlex.css
CHANGED
@@ -61,6 +61,7 @@ body {
|
|
61
61
|
margin: 0;
|
62
62
|
padding: 0;
|
63
63
|
word-wrap: break-word;
|
64
|
+
word-break: keep-all;
|
64
65
|
scrollbar-width: thin;
|
65
66
|
scrollbar-color: #8ab5ff #e6efff;
|
66
67
|
}
|
@@ -200,9 +201,6 @@ footer .footer-wrap {
|
|
200
201
|
color: #333;
|
201
202
|
border-radius: 50%;
|
202
203
|
}
|
203
|
-
#home-head .home-info .info h1 {
|
204
|
-
word-break: keep-all;
|
205
|
-
}
|
206
204
|
#home-head .home-info .loop:nth-child(1) {
|
207
205
|
border-radius: 38% 62% 63% 37%/41% 44% 56% 59%;
|
208
206
|
background: #fff;
|
@@ -292,8 +290,10 @@ footer .footer-wrap {
|
|
292
290
|
#home-posts .post .excerpt {
|
293
291
|
color: #1e3e3f;
|
294
292
|
}
|
293
|
+
#home-posts .post .post-tags {
|
294
|
+
line-height: 1.5;
|
295
|
+
}
|
295
296
|
#home-posts .post .post-tags a {
|
296
|
-
color: #ffbbf4;
|
297
297
|
font-size: 14px;
|
298
298
|
}
|
299
299
|
#home-posts .post .post-tags .tag {
|
@@ -477,7 +477,6 @@ footer .footer-wrap {
|
|
477
477
|
#menu .desktop-menu .title {
|
478
478
|
display: inline-block;
|
479
479
|
margin-left: 30px;
|
480
|
-
margin-right: 20px;
|
481
480
|
font-family: "Lexend", "Noto Sans SC", sans-serif;
|
482
481
|
text-transform: uppercase;
|
483
482
|
color: #555;
|
@@ -718,16 +717,24 @@ footer .footer-icon {
|
|
718
717
|
color: #5c6b72;
|
719
718
|
text-decoration: none;
|
720
719
|
}
|
721
|
-
#archives .
|
722
|
-
|
723
|
-
text-decoration: none;
|
720
|
+
#archives .info {
|
721
|
+
line-height: 1.5;
|
724
722
|
}
|
725
723
|
#archives .category {
|
726
|
-
|
724
|
+
display: inline-block;
|
725
|
+
margin-right: 10px;
|
726
|
+
}
|
727
|
+
#archives .tags {
|
728
|
+
display: inline-block;
|
727
729
|
}
|
728
730
|
#archives .tags .tag {
|
731
|
+
display: inline-block;
|
729
732
|
margin-right: 10px;
|
730
733
|
}
|
734
|
+
#archives .tag-icon {
|
735
|
+
color: #5c6b72;
|
736
|
+
text-decoration: none;
|
737
|
+
}
|
731
738
|
#archives h3 {
|
732
739
|
margin: 10px 0;
|
733
740
|
}
|
@@ -778,6 +785,9 @@ footer .footer-icon {
|
|
778
785
|
font-weight: bold;
|
779
786
|
margin: 20px 0;
|
780
787
|
}
|
788
|
+
.article .info {
|
789
|
+
line-height: 1.5;
|
790
|
+
}
|
781
791
|
.article .info a {
|
782
792
|
color: #5c6b72;
|
783
793
|
text-decoration: none;
|
@@ -785,25 +795,18 @@ footer .footer-icon {
|
|
785
795
|
.article .info .date {
|
786
796
|
color: #5c6b72;
|
787
797
|
display: inline-block;
|
788
|
-
margin-right: 20px;
|
789
|
-
}
|
790
|
-
.article .info .date .tag {
|
791
798
|
margin-right: 10px;
|
792
799
|
}
|
793
800
|
.article .info .category {
|
794
|
-
color: #5c6b72;
|
795
801
|
display: inline-block;
|
796
|
-
margin-right: 20px;
|
797
|
-
}
|
798
|
-
.article .info .category .tag {
|
799
802
|
margin-right: 10px;
|
800
803
|
}
|
801
804
|
.article .info .tags {
|
802
|
-
color: #5c6b72;
|
803
805
|
display: inline-block;
|
804
|
-
margin-right:
|
806
|
+
margin-right: 10px;
|
805
807
|
}
|
806
808
|
.article .info .tags .tag {
|
809
|
+
display: inline-block;
|
807
810
|
margin-right: 10px;
|
808
811
|
}
|
809
812
|
.article .content {
|
@@ -862,24 +865,24 @@ input.ipt:focus {
|
|
862
865
|
border-color: #0969da;
|
863
866
|
box-shadow: 0 0 0 3px #0969da4d;
|
864
867
|
}
|
865
|
-
|
868
|
+
#crypto {
|
866
869
|
margin: 50px auto 0;
|
867
870
|
}
|
868
|
-
|
871
|
+
#crypto.fail {
|
869
872
|
color: #ea4a5a;
|
870
873
|
border-color: #ea4a5a;
|
871
874
|
}
|
872
|
-
|
875
|
+
#crypto.fail:focus {
|
873
876
|
box-shadow: 0 0 0 3px #ea4a5a4d;
|
874
877
|
}
|
875
|
-
|
878
|
+
#crypto.success {
|
876
879
|
color: #34d058;
|
877
880
|
border-color: #34d058;
|
878
881
|
}
|
879
|
-
|
882
|
+
#search-bar {
|
880
883
|
margin: 0 auto 50px;
|
881
884
|
}
|
882
|
-
|
885
|
+
#search-mask {
|
883
886
|
position: relative;
|
884
887
|
margin: auto;
|
885
888
|
margin-top: -125px;
|
@@ -888,58 +891,6 @@ input.search-bar {
|
|
888
891
|
height: 150px;
|
889
892
|
background: #f6f8fa;
|
890
893
|
}
|
891
|
-
.gt-container *:not(.gt-header-textarea) {
|
892
|
-
font-family: unset !important;
|
893
|
-
}
|
894
|
-
.gt-header-textarea {
|
895
|
-
font-family: "Fira Code", "Noto Sans SC", monospace;
|
896
|
-
}
|
897
|
-
.gt-container .gt-comment-content {
|
898
|
-
border: 1px solid #0000001a;
|
899
|
-
border-radius: 5px;
|
900
|
-
}
|
901
|
-
.gt-container .gt-comment-content:hover,
|
902
|
-
.gt-container .gt-header-textarea:hover,
|
903
|
-
.gt-container .gt-header-textarea:focus {
|
904
|
-
box-shadow: 0 2px 8px #00000017 !important;
|
905
|
-
background-color: #fbfbfb;
|
906
|
-
}
|
907
|
-
.gt-container .gt-header-textarea:focus {
|
908
|
-
background-color: #fbfbfb;
|
909
|
-
}
|
910
|
-
.gt-container .gt-avatar img {
|
911
|
-
border-radius: 50% !important;
|
912
|
-
}
|
913
|
-
.gt-container .gt-popup {
|
914
|
-
border-radius: 10px;
|
915
|
-
}
|
916
|
-
.gt-container .markdown-body {
|
917
|
-
color: unset !important;
|
918
|
-
}
|
919
|
-
.gt-container .markdown-body p {
|
920
|
-
margin: 10px 0 !important;
|
921
|
-
}
|
922
|
-
.gt-container .markdown-body blockquote {
|
923
|
-
border-left: unset !important;
|
924
|
-
padding: 1px 20px !important;
|
925
|
-
border-left: 3px solid #1e3e3f !important;
|
926
|
-
color: unset !important;
|
927
|
-
}
|
928
|
-
.gt-container .markdown-body code {
|
929
|
-
font-family: "Fira Code" !important;
|
930
|
-
background: #bddcf76b;
|
931
|
-
border-radius: 4px;
|
932
|
-
font-size: 14px;
|
933
|
-
color: #4b616b;
|
934
|
-
}
|
935
|
-
.gt-container .markdown-body pre {
|
936
|
-
font-family: "Fira Code" !important;
|
937
|
-
font-weight: 500;
|
938
|
-
border: 1px solid #ebeef5;
|
939
|
-
padding: 20px;
|
940
|
-
margin: 25px 0;
|
941
|
-
border-radius: 15px !important;
|
942
|
-
}
|
943
894
|
#showimg {
|
944
895
|
position: fixed !important;
|
945
896
|
display: flex;
|
@@ -962,6 +913,9 @@ input.search-bar {
|
|
962
913
|
max-height: 95%;
|
963
914
|
box-shadow: 0 0 50px 10px #d9d9d980;
|
964
915
|
}
|
916
|
+
.math.display .katex {
|
917
|
+
overflow: auto;
|
918
|
+
}
|
965
919
|
::-webkit-scrollbar {
|
966
920
|
width: 12px;
|
967
921
|
height: 12px;
|
package/source/js/functions.js
CHANGED
@@ -1,12 +1,14 @@
|
|
1
|
-
|
1
|
+
function sleep(ms) {
|
2
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
3
|
+
}
|
2
4
|
let copying = false;
|
3
5
|
function highlight() {
|
4
6
|
hljs.configure({ ignoreUnescapedHTML: true });
|
5
7
|
let codes = document.getElementsByTagName("pre");
|
6
|
-
for (let
|
7
|
-
let lang = [...
|
8
|
-
|
9
|
-
let copycode =
|
8
|
+
for (let i of codes) {
|
9
|
+
let lang = [...i.classList, ...i.firstChild.classList][0] || "text";
|
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];
|
10
12
|
copycode.addEventListener("click", async function () {
|
11
13
|
if (copying) return;
|
12
14
|
copying = true;
|
@@ -16,13 +18,13 @@ function highlight() {
|
|
16
18
|
this.classList.remove("copied");
|
17
19
|
copying = false;
|
18
20
|
});
|
19
|
-
hljs.highlightElement(
|
21
|
+
hljs.highlightElement(i.getElementsByClassName("code-content")[0]);
|
20
22
|
}
|
21
23
|
}
|
22
24
|
function showimg() {
|
23
25
|
let wrap = document.getElementById("showimg"),
|
24
26
|
content = document.getElementById("showimg-content"),
|
25
|
-
|
27
|
+
images = document.querySelectorAll(".article .content img");
|
26
28
|
function show(src) {
|
27
29
|
content.setAttribute("src", src);
|
28
30
|
wrap.style.opacity = 1;
|
@@ -32,12 +34,13 @@ function showimg() {
|
|
32
34
|
wrap.style.opacity = 0;
|
33
35
|
wrap.style.visibility = "hidden";
|
34
36
|
}
|
35
|
-
for (let
|
36
|
-
|
37
|
+
for (let i of images)
|
38
|
+
i.addEventListener("click", function () {
|
37
39
|
show(this.getAttribute("src"));
|
38
40
|
});
|
39
|
-
wrap.addEventListener("click",
|
40
|
-
window.addEventListener("resize",
|
41
|
+
wrap.addEventListener("click", hide);
|
42
|
+
window.addEventListener("resize", hide);
|
43
|
+
window.addEventListener("scroll", hide);
|
41
44
|
}
|
42
45
|
function rendermath() {
|
43
46
|
if (typeof renderMathInElement !== "undefined")
|
@@ -50,3 +53,17 @@ function rendermath() {
|
|
50
53
|
],
|
51
54
|
});
|
52
55
|
}
|
56
|
+
function sha(str) {
|
57
|
+
return CryptoJS.SHA256(str).toString(CryptoJS.enc.Base64);
|
58
|
+
}
|
59
|
+
function decrypt(encrypt, key, check) {
|
60
|
+
try {
|
61
|
+
let res = CryptoJS.AES.decrypt(encrypt, sha(key), {
|
62
|
+
mode: CryptoJS.mode.ECB,
|
63
|
+
padding: CryptoJS.pad.Pkcs7,
|
64
|
+
}).toString(CryptoJS.enc.Utf8);
|
65
|
+
return { decrypt: res, check: sha(res) == check };
|
66
|
+
} catch {
|
67
|
+
return { check: false };
|
68
|
+
}
|
69
|
+
}
|
package/source/js/particlex.js
CHANGED
@@ -5,19 +5,41 @@ const app = Vue.createApp({
|
|
5
5
|
menushow: false,
|
6
6
|
cardtop: 100,
|
7
7
|
barlocal: 0,
|
8
|
+
composition: false,
|
8
9
|
};
|
9
10
|
},
|
10
|
-
created() {
|
11
|
-
let that = this;
|
12
|
-
window.addEventListener("load", () => {
|
13
|
-
that.showpage = true;
|
14
|
-
document.getElementById("loading").style.opacity = 0;
|
15
|
-
document.getElementById("loading").style.visibility = "hidden";
|
16
|
-
});
|
17
|
-
},
|
18
11
|
mounted() {
|
12
|
+
this.showpage = true;
|
13
|
+
document.getElementById("loading").style.opacity = 0;
|
14
|
+
document.getElementById("loading").style.visibility = "hidden";
|
19
15
|
if (document.getElementById("home-head"))
|
20
16
|
document.getElementById("menu").className += " menu-color";
|
17
|
+
if (document.getElementById("crypto")) {
|
18
|
+
let input = document.getElementById("crypto");
|
19
|
+
input.addEventListener("input", () => {
|
20
|
+
if (!this.composition) this.handlecrypto();
|
21
|
+
});
|
22
|
+
input.addEventListener("compositionstart", () => {
|
23
|
+
this.composition = true;
|
24
|
+
});
|
25
|
+
input.addEventListener("compositionend", () => {
|
26
|
+
this.handlecrypto();
|
27
|
+
this.composition = false;
|
28
|
+
});
|
29
|
+
}
|
30
|
+
if (document.getElementById("search-bar")) {
|
31
|
+
let input = document.getElementById("search-bar");
|
32
|
+
input.addEventListener("input", () => {
|
33
|
+
if (!this.composition) this.handlesearch();
|
34
|
+
});
|
35
|
+
input.addEventListener("compositionstart", () => {
|
36
|
+
this.composition = true;
|
37
|
+
});
|
38
|
+
input.addEventListener("compositionend", () => {
|
39
|
+
this.handlesearch();
|
40
|
+
this.composition = false;
|
41
|
+
});
|
42
|
+
}
|
21
43
|
window.addEventListener("scroll", this.handlescroll, true);
|
22
44
|
highlight();
|
23
45
|
showimg();
|
@@ -25,20 +47,16 @@ const app = Vue.createApp({
|
|
25
47
|
},
|
26
48
|
methods: {
|
27
49
|
homeclick() {
|
28
|
-
window.scrollTo({
|
29
|
-
top: window.innerHeight,
|
30
|
-
behavior: "smooth",
|
31
|
-
});
|
50
|
+
window.scrollTo({ top: window.innerHeight, behavior: "smooth" });
|
32
51
|
},
|
33
52
|
handlescroll() {
|
34
53
|
let newlocal = document.documentElement.scrollTop;
|
35
54
|
let menu = document.getElementById("menu");
|
36
55
|
let wrap = document.getElementById("home-posts-wrap");
|
37
56
|
let footer = document.getElementById("footer");
|
38
|
-
let that = this;
|
39
57
|
if (this.barlocal < newlocal) {
|
40
58
|
menu.className = "hidden-menu";
|
41
|
-
|
59
|
+
this.menushow = false;
|
42
60
|
} else menu.className = "show-menu";
|
43
61
|
if (wrap) {
|
44
62
|
if (newlocal <= window.innerHeight - 100) menu.className += " menu-color";
|
@@ -52,6 +70,36 @@ const app = Vue.createApp({
|
|
52
70
|
}
|
53
71
|
this.barlocal = newlocal;
|
54
72
|
},
|
73
|
+
handlecrypto() {
|
74
|
+
let input = document.getElementById("crypto"),
|
75
|
+
content = document.getElementsByClassName("content")[0];
|
76
|
+
let res = decrypt(input.dataset.encrypt, input.value, input.dataset.check);
|
77
|
+
if (res.check) {
|
78
|
+
input.disabled = true;
|
79
|
+
input.classList.remove("fail");
|
80
|
+
input.classList.add("success");
|
81
|
+
content.innerHTML = res.decrypt;
|
82
|
+
content.style.opacity = 1;
|
83
|
+
highlight();
|
84
|
+
showimg();
|
85
|
+
rendermath();
|
86
|
+
} else input.classList.add("fail");
|
87
|
+
},
|
88
|
+
handlesearch() {
|
89
|
+
let input = document.getElementById("search-bar"),
|
90
|
+
timeline = document.getElementsByClassName("timeline"),
|
91
|
+
key = input.value.toLowerCase().replace(/s+/gm, "");
|
92
|
+
for (let i of timeline)
|
93
|
+
if (!key || i.dataset.title.includes(key)) {
|
94
|
+
i.style.opacity = 1;
|
95
|
+
i.style.pointerEvents = "";
|
96
|
+
i.style.marginTop = "";
|
97
|
+
} else {
|
98
|
+
i.style.opacity = 0;
|
99
|
+
i.style.pointerEvents = "none";
|
100
|
+
i.style.marginTop = -i.offsetHeight - 30 + "px";
|
101
|
+
}
|
102
|
+
},
|
55
103
|
},
|
56
104
|
});
|
57
105
|
app.mount("#layout");
|
package/source/js/cryptor.js
DELETED
@@ -1,44 +0,0 @@
|
|
1
|
-
const cryptor = {
|
2
|
-
init(enc, sha) {
|
3
|
-
this.enc = enc;
|
4
|
-
this.sha = sha;
|
5
|
-
this.composition = false;
|
6
|
-
window.addEventListener("load", () => {
|
7
|
-
this.input = document.getElementsByClassName("crypto")[0];
|
8
|
-
this.content = document.getElementsByClassName("content")[0];
|
9
|
-
this.content.style.opacity = 0;
|
10
|
-
this.input.addEventListener("input", () => this.composition || this.update());
|
11
|
-
this.input.addEventListener("compositionstart", () => (this.composition = true));
|
12
|
-
this.input.addEventListener("compositionend", () => {
|
13
|
-
this.update(), (this.composition = false);
|
14
|
-
});
|
15
|
-
});
|
16
|
-
},
|
17
|
-
SHA(str) {
|
18
|
-
return CryptoJS.SHA256(str).toString(CryptoJS.enc.Base64);
|
19
|
-
},
|
20
|
-
decrypt(enc, key, sha) {
|
21
|
-
try {
|
22
|
-
let res = CryptoJS.AES.decrypt(enc, this.SHA(key), {
|
23
|
-
mode: CryptoJS.mode.ECB,
|
24
|
-
padding: CryptoJS.pad.Pkcs7,
|
25
|
-
}).toString(CryptoJS.enc.Utf8);
|
26
|
-
return { dec: res, check: this.SHA(res) == sha };
|
27
|
-
} catch {
|
28
|
-
return { check: false };
|
29
|
-
}
|
30
|
-
},
|
31
|
-
update() {
|
32
|
-
let res = this.decrypt(this.enc, this.input.value, this.sha);
|
33
|
-
if (res.check) {
|
34
|
-
this.input.disabled = true;
|
35
|
-
this.input.classList.remove("fail");
|
36
|
-
this.input.classList.add("success");
|
37
|
-
this.content.innerHTML = res.dec;
|
38
|
-
this.content.style.opacity = 1;
|
39
|
-
highlight();
|
40
|
-
showimg();
|
41
|
-
rendermath();
|
42
|
-
} else this.input.classList.add("fail");
|
43
|
-
},
|
44
|
-
};
|
package/source/js/searcher.js
DELETED
@@ -1,43 +0,0 @@
|
|
1
|
-
const searcher = {
|
2
|
-
init(path) {
|
3
|
-
this.composition = false;
|
4
|
-
window.addEventListener("load", () => {
|
5
|
-
this.input = document.getElementsByClassName("search-bar")[0];
|
6
|
-
this.timeline = document.getElementsByClassName("timeline");
|
7
|
-
this.input.addEventListener("input", () => this.composition || this.update());
|
8
|
-
this.input.addEventListener("compositionstart", () => (this.composition = true));
|
9
|
-
this.input.addEventListener("compositionend", () => {
|
10
|
-
this.update();
|
11
|
-
this.composition = false;
|
12
|
-
});
|
13
|
-
fetch(path)
|
14
|
-
.then(res => res.json())
|
15
|
-
.then(data => {
|
16
|
-
this.data = data;
|
17
|
-
});
|
18
|
-
});
|
19
|
-
},
|
20
|
-
rstr(s) {
|
21
|
-
if (!s) return "";
|
22
|
-
return s.toLowerCase().replace(/\s+/gm, "");
|
23
|
-
},
|
24
|
-
match(s, rs) {
|
25
|
-
return s.indexOf(rs) != -1;
|
26
|
-
},
|
27
|
-
update() {
|
28
|
-
let res = [],
|
29
|
-
rs = this.rstr(this.input.value);
|
30
|
-
if (rs) res = this.data.filter(i => this.match(i.odata, rs)).map(i => i.path);
|
31
|
-
else res = this.data.map(i => i.path);
|
32
|
-
for (let line of this.timeline)
|
33
|
-
if (res.indexOf(line.getAttribute("path")) == -1) {
|
34
|
-
line.style.opacity = 0;
|
35
|
-
line.style.pointerEvents = "none";
|
36
|
-
line.style.marginTop = -line.offsetHeight - 30 + "px";
|
37
|
-
} else {
|
38
|
-
line.style.opacity = 1;
|
39
|
-
line.style.pointerEvents = "";
|
40
|
-
line.style.marginTop = "";
|
41
|
-
}
|
42
|
-
},
|
43
|
-
};
|