hexo-theme-particlex 2.1.1 → 2.1.2
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 -13
- package/_config.yml +0 -1
- package/layout/archives.ejs +3 -5
- package/layout/categories.ejs +2 -1
- package/layout/layout.ejs +3 -2
- package/layout/post.ejs +4 -6
- package/layout/tags.ejs +3 -2
- 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
@@ -199,24 +199,13 @@ highlightStyle: github # Highlight style
|
|
199
199
|
|
200
200
|
- 搜索
|
201
201
|
|
202
|
-
嵌入到 Archives
|
202
|
+
嵌入到 Archives 中的搜索,默认关闭
|
203
203
|
|
204
|
-
|
205
|
-
|
206
|
-
要同时在主题和根目录的两个 `_config.yml` 添加配置
|
204
|
+
目前只支持搜索文档标题(我太弱了)
|
207
205
|
|
208
206
|
```yaml
|
209
|
-
# Theme config
|
210
207
|
search:
|
211
208
|
enable: false
|
212
|
-
path: /search.json
|
213
|
-
```
|
214
|
-
|
215
|
-
```yaml
|
216
|
-
# Site config
|
217
|
-
search:
|
218
|
-
path: /search.json
|
219
|
-
optimize: true
|
220
209
|
```
|
221
210
|
|
222
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
@@ -20,7 +20,8 @@
|
|
20
20
|
<%
|
21
21
|
posts = category.posts;
|
22
22
|
posts.data.sort((a, b) => {
|
23
|
-
a.top
|
23
|
+
if (typeof a.top === "undefined") a.top = 0;
|
24
|
+
if (typeof b.top === "undefined") b.top = 0;
|
24
25
|
return a.top == b.top ? b.date - a.date : b.top - a.top
|
25
26
|
});
|
26
27
|
%>
|
package/layout/layout.ejs
CHANGED
@@ -21,8 +21,9 @@
|
|
21
21
|
title = "Archives | ";
|
22
22
|
title += config.title;
|
23
23
|
site.posts.data.sort((a, b) => {
|
24
|
-
a.top
|
25
|
-
|
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;
|
26
27
|
});
|
27
28
|
%>
|
28
29
|
<!DOCTYPE html>
|
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
@@ -20,8 +20,9 @@
|
|
20
20
|
<%
|
21
21
|
posts = tag.posts;
|
22
22
|
posts.data.sort((a, b) => {
|
23
|
-
a.top
|
24
|
-
|
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;
|
25
26
|
});
|
26
27
|
%>
|
27
28
|
<% } %>
|
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
|
-
};
|