hexo-theme-particlex 2.1.1 → 2.1.3

Sign up to get free protection for your applications and to get access to all the features.
package/README.md CHANGED
@@ -199,24 +199,13 @@ highlightStyle: github # Highlight style
199
199
 
200
200
  - 搜索
201
201
 
202
- 嵌入到 Archives 中的搜索,搜索数据是用 [Hexo-Generator-Search-Lite](https://github.com/argvchs/hexo-generator-search-lite) 生成,默认关闭,使用需要安装上述插件并**设置 `optimize: true`**
202
+ 嵌入到 Archives 中的搜索,默认关闭
203
203
 
204
- 目前只支持搜索文档的 Title Categories Tags(我太弱了)
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
@@ -87,7 +87,6 @@ crypto:
87
87
  # Search
88
88
  search:
89
89
  enable: false
90
- path: /search.json
91
90
 
92
91
  # Gitalk
93
92
  # https://github.com/gitalk/gitalk
@@ -1,12 +1,10 @@
1
1
  <div id="archives">
2
2
  <% if (theme.search.enable) { %>
3
- <div class="search-mask" style="z-index: <%= site.posts.length + 1 %>"></div>
4
- <input class="ipt search-bar" placeholder="搜索..." style="z-index: <%= site.posts.length + 2 %>">
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" path="<%- url_for(post.path) %>" style="z-index: <%= site.posts.length - id %>">
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>
@@ -20,7 +20,8 @@
20
20
  <%
21
21
  posts = category.posts;
22
22
  posts.data.sort((a, b) => {
23
- a.top ??= 0, b.top ??= 0;
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/index.ejs CHANGED
@@ -19,13 +19,13 @@
19
19
  <div id="home-posts-wrap" class="<%- theme.card.enable ? "" : "home-posts-wrap-no-card" %>">
20
20
  <div id="home-posts">
21
21
  <div id="posts">
22
- <%- include("posts") %>
23
- <%- include("current") %>
22
+ <%- partial("posts") %>
23
+ <%- partial("current") %>
24
24
  </div>
25
25
  </div>
26
26
  <% if (theme.card.enable) { %>
27
27
  <div id="home-card">
28
- <%- include("card") %>
28
+ <%- partial("card") %>
29
29
  </div>
30
30
  <% } %>
31
31
  </div>
package/layout/layout.ejs CHANGED
@@ -1,15 +1,15 @@
1
1
  <%
2
- let layout = "post";
2
+ let type = "post";
3
3
  if (is_home())
4
- layout = "index";
4
+ type = "index";
5
5
  else if (is_post())
6
- layout = "post";
6
+ type = "post";
7
7
  else if (is_category() || page.type == "categories")
8
- layout = "categories";
8
+ type = "categories";
9
9
  else if (is_tag() || page.type == "tags")
10
- layout = "tags";
10
+ type = "tags";
11
11
  else if (is_archive() || is_year() || is_month())
12
- layout = "archives";
12
+ type = "archives";
13
13
  let title = "";
14
14
  if (page.title)
15
15
  title = page.title + " | ";
@@ -21,8 +21,9 @@
21
21
  title = "Archives | ";
22
22
  title += config.title;
23
23
  site.posts.data.sort((a, b) => {
24
- a.top ??= 0, b.top ??= 0;
25
- return a.top == b.top ? b.date - a.date : b.top - a.top
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>
@@ -47,20 +48,23 @@
47
48
  <script src="https://cdn.staticfile.org/KaTeX/0.16.4/contrib/auto-render.min.js"></script>
48
49
  <link rel="stylesheet" href="https://cdn.staticfile.org/KaTeX/0.16.4/katex.min.css">
49
50
  <% } %>
51
+ <% if (theme.crypto.enable && typeof page.password !== "undefined") { %>
52
+ <script src="https://cdn.staticfile.org/crypto-js/4.1.1/crypto-js.min.js"></script>
53
+ <% } %>
50
54
  <link rel="stylesheet" href="<%- url_for("/css/fonts.min.css") %>">
51
55
  <link rel="stylesheet" href="<%- url_for("/css/particlex.css") %>">
52
56
  </head>
53
57
  <body>
54
- <%- include("loading") %>
58
+ <%- partial("loading") %>
55
59
  <div id="layout">
56
60
  <transition name="into">
57
61
  <div v-show="showpage" style="display: -not-none">
58
62
  <div id="menushow">
59
- <%- include("menu") %>
63
+ <%- partial("menu") %>
60
64
  </div>
61
65
  <div id="main">
62
- <%- include(layout) %>
63
- <%- include("footer") %>
66
+ <%- partial(type) %>
67
+ <%- partial("footer") %>
64
68
  </div>
65
69
  </div>
66
70
  </transition>
@@ -68,6 +72,6 @@
68
72
  <img id="showimg-content" alt="showimg">
69
73
  </div>
70
74
  </div>
71
- <%- include("script") %>
75
+ <%- partial("script", { type }) %>
72
76
  </body>
73
77
  </html>
package/layout/post.ejs CHANGED
@@ -38,31 +38,27 @@
38
38
  </span>
39
39
  <% } %>
40
40
  </div>
41
- <% if (typeof page.password !== "undefined" && theme.crypto.enable) { %>
41
+ <% if (theme.crypto.enable && typeof page.password !== "undefined") { %>
42
42
  <%
43
43
  const CryptoJS = crypto();
44
- function SHA(str) {
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, SHA(key), {
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
- <script src="https://cdn.staticfile.org/crypto-js/4.1.1/crypto-js.min.js"></script>
57
- <script src="<%- url_for("/js/cryptor.js") %>"></script>
58
- <script>cryptor.init("<%- encrypt(page.content, page.password.toString()) %>", "<%- SHA(page.content) %>")</script>
54
+ <input id="crypto" class="ipt" placeholder="文章被加密,请输入密码" data-encrypt="<%- encrypt(page.content, page.password.toString()) %>" data-check="<%- sha(page.content) %>">
55
+ <div class="content" style="opacity: 0" v-pre></div>
59
56
  <% } else { %>
60
57
  <div class="content" v-pre>
61
58
  <%- page.content %>
62
59
  </div>
63
60
  <% } %>
64
61
  <% if (theme.gitalk.enable) { %>
65
- <link rel="stylesheet" href="https://cdn.staticfile.org/gitalk/1.7.2/gitalk.min.css">
66
62
  <div id="comment">
67
63
  <div id="gitalk-container"></div>
68
64
  </div>
@@ -73,7 +69,6 @@
73
69
  </div>
74
70
  <% } %>
75
71
  <% if (theme.waline.enable) { %>
76
- <link rel="stylesheet" href="https://cdn.staticfile.org/waline/2.9.1/waline.min.css" />
77
72
  <div id="comment">
78
73
  <div id="waline-container"></div>
79
74
  </div>
package/layout/script.ejs CHANGED
@@ -1,10 +1,12 @@
1
1
  <script src="<%- url_for("/js/functions.js") %>"></script>
2
2
  <script src="<%- url_for("/js/particlex.js") %>"></script>
3
- <% if (is_post()) { %>
3
+ <% if (type == "post") { %>
4
4
  <% if (theme.gitalk.enable) { %>
5
5
  <script src="https://cdn.staticfile.org/gitalk/1.7.2/gitalk.min.js"></script>
6
+ <link rel="stylesheet" href="https://cdn.staticfile.org/gitalk/1.7.2/gitalk.min.css">
6
7
  <script>
7
- let clientID = "<%- theme.gitalk.clientID %>", clientSecret = "<%- theme.gitalk.clientSecret %>";
8
+ let clientID = "<%- theme.gitalk.clientID %>",
9
+ clientSecret = "<%- theme.gitalk.clientSecret %>";
8
10
  <% Object.keys(theme.gitalk.sites).forEach(key => { %>
9
11
  if (window.location.host == "<%- key %>") {
10
12
  clientID = "<%- theme.gitalk.sites[key].clientID %>";
@@ -21,10 +23,10 @@
21
23
  id: location.pathname,
22
24
  distractionFreeMode: false,
23
25
  <% if (theme.gitalk.proxy) { %>
24
- proxy: "<%- theme.gitalk.proxy %>"
26
+ proxy: "<%- theme.gitalk.proxy %>",
25
27
  <% } %>
26
28
  })
27
- gitalk.render("gitalk-container")
29
+ gitalk.render("gitalk-container");
28
30
  </script>
29
31
  <% } %>
30
32
  <% if (theme.giscus.enable) { %>
@@ -47,6 +49,7 @@
47
49
  <% } %>
48
50
  <% if (theme.waline.enable) { %>
49
51
  <script src="https://cdn.staticfile.org/waline/2.9.1/waline.min.js"></script>
52
+ <link rel="stylesheet" href="https://cdn.staticfile.org/waline/2.9.1/waline.min.css">
50
53
  <script>
51
54
  Waline.init({
52
55
  el: "#waline-container",
@@ -60,7 +63,7 @@
60
63
  wordLimit: <%- theme.waline.wordLimit %>,
61
64
  pageSize: "<%- theme.waline.pageSize %>",
62
65
  login: "<%- theme.waline.login %>",
63
- locale: <%- JSON.stringify(theme.waline.locale) %>
66
+ locale: <%- JSON.stringify(theme.waline.locale) %>,
64
67
  });
65
68
  </script>
66
69
  <% } %>
@@ -72,7 +75,7 @@
72
75
  envId: "<%- theme.twikoo.envId %>",
73
76
  region: "<%- theme.twikoo.region %>",
74
77
  path: <%- theme.twikoo.path %>,
75
- lang: "<%- theme.twikoo.lang %>"
78
+ lang: "<%- theme.twikoo.lang %>",
76
79
  })
77
80
  </script>
78
81
  <% } %>
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 ??= 0, b.top ??= 0;
24
- return a.top == b.top ? b.date - a.date : b.top - a.top
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.1",
3
+ "version": "2.1.3",
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"
@@ -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 .tag-icon {
722
- color: #5c6b72;
723
- text-decoration: none;
720
+ #archives .info {
721
+ line-height: 1.5;
724
722
  }
725
723
  #archives .category {
726
- margin-right: 20px;
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: 20px;
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
- input.crypto {
868
+ #crypto {
866
869
  margin: 50px auto 0;
867
870
  }
868
- input.crypto.fail {
871
+ #crypto.fail {
869
872
  color: #ea4a5a;
870
873
  border-color: #ea4a5a;
871
874
  }
872
- input.crypto.fail:focus {
875
+ #crypto.fail:focus {
873
876
  box-shadow: 0 0 0 3px #ea4a5a4d;
874
877
  }
875
- input.crypto.success {
878
+ #crypto.success {
876
879
  color: #34d058;
877
880
  border-color: #34d058;
878
881
  }
879
- input.search-bar {
882
+ #search-bar {
880
883
  margin: 0 auto 50px;
881
884
  }
882
- .search-mask {
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;
@@ -1,12 +1,14 @@
1
- const sleep = ms => new Promise(res => setTimeout(res, ms));
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 code of codes) {
7
- let lang = [...code.classList, ...code.firstChild.classList][0] || "text";
8
- code.innerHTML = `<div class="code-content">${code.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>`;
9
- let copycode = code.getElementsByClassName("copycode")[0];
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(code.getElementsByClassName("code-content")[0]);
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
- imgs = document.querySelectorAll(".article .content img");
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,12 @@ function showimg() {
32
34
  wrap.style.opacity = 0;
33
35
  wrap.style.visibility = "hidden";
34
36
  }
35
- for (let img of imgs)
36
- img.addEventListener("click", function () {
37
+ for (let i of images)
38
+ i.addEventListener("click", function () {
37
39
  show(this.getAttribute("src"));
38
40
  });
39
- wrap.addEventListener("click", () => hide());
40
- window.addEventListener("resize", () => hide());
41
+ wrap.addEventListener("click", hide);
42
+ window.addEventListener("resize", hide);
41
43
  }
42
44
  function rendermath() {
43
45
  if (typeof renderMathInElement !== "undefined")
@@ -50,3 +52,17 @@ function rendermath() {
50
52
  ],
51
53
  });
52
54
  }
55
+ function sha(str) {
56
+ return CryptoJS.SHA256(str).toString(CryptoJS.enc.Base64);
57
+ }
58
+ function decrypt(encrypt, key, check) {
59
+ try {
60
+ let res = CryptoJS.AES.decrypt(encrypt, sha(key), {
61
+ mode: CryptoJS.mode.ECB,
62
+ padding: CryptoJS.pad.Pkcs7,
63
+ }).toString(CryptoJS.enc.Utf8);
64
+ return { decrypt: res, check: sha(res) == check };
65
+ } catch {
66
+ return { check: false };
67
+ }
68
+ }
@@ -5,12 +5,12 @@ const app = Vue.createApp({
5
5
  menushow: false,
6
6
  cardtop: 100,
7
7
  barlocal: 0,
8
+ composition: false,
8
9
  };
9
10
  },
10
11
  created() {
11
- let that = this;
12
12
  window.addEventListener("load", () => {
13
- that.showpage = true;
13
+ this.showpage = true;
14
14
  document.getElementById("loading").style.opacity = 0;
15
15
  document.getElementById("loading").style.visibility = "hidden";
16
16
  });
@@ -18,6 +18,32 @@ const app = Vue.createApp({
18
18
  mounted() {
19
19
  if (document.getElementById("home-head"))
20
20
  document.getElementById("menu").className += " menu-color";
21
+ if (document.getElementById("crypto")) {
22
+ let input = document.getElementById("crypto");
23
+ input.addEventListener("input", () => {
24
+ if (!this.composition) this.handlecrypto();
25
+ });
26
+ input.addEventListener("compositionstart", () => {
27
+ this.composition = true;
28
+ });
29
+ input.addEventListener("compositionend", () => {
30
+ this.handlecrypto();
31
+ this.composition = false;
32
+ });
33
+ }
34
+ if (document.getElementById("search-bar")) {
35
+ let input = document.getElementById("search-bar");
36
+ input.addEventListener("input", () => {
37
+ if (!this.composition) this.handlesearch();
38
+ });
39
+ input.addEventListener("compositionstart", () => {
40
+ this.composition = true;
41
+ });
42
+ input.addEventListener("compositionend", () => {
43
+ this.handlesearch();
44
+ this.composition = false;
45
+ });
46
+ }
21
47
  window.addEventListener("scroll", this.handlescroll, true);
22
48
  highlight();
23
49
  showimg();
@@ -25,20 +51,16 @@ const app = Vue.createApp({
25
51
  },
26
52
  methods: {
27
53
  homeclick() {
28
- window.scrollTo({
29
- top: window.innerHeight,
30
- behavior: "smooth",
31
- });
54
+ window.scrollTo({ top: window.innerHeight, behavior: "smooth" });
32
55
  },
33
56
  handlescroll() {
34
57
  let newlocal = document.documentElement.scrollTop;
35
58
  let menu = document.getElementById("menu");
36
59
  let wrap = document.getElementById("home-posts-wrap");
37
60
  let footer = document.getElementById("footer");
38
- let that = this;
39
61
  if (this.barlocal < newlocal) {
40
62
  menu.className = "hidden-menu";
41
- that.menushow = false;
63
+ this.menushow = false;
42
64
  } else menu.className = "show-menu";
43
65
  if (wrap) {
44
66
  if (newlocal <= window.innerHeight - 100) menu.className += " menu-color";
@@ -52,6 +74,36 @@ const app = Vue.createApp({
52
74
  }
53
75
  this.barlocal = newlocal;
54
76
  },
77
+ handlecrypto() {
78
+ let input = document.getElementById("crypto"),
79
+ content = document.getElementsByClassName("content")[0];
80
+ let res = decrypt(input.dataset.encrypt, input.value, input.dataset.check);
81
+ if (res.check) {
82
+ input.disabled = true;
83
+ input.classList.remove("fail");
84
+ input.classList.add("success");
85
+ content.innerHTML = res.decrypt;
86
+ content.style.opacity = 1;
87
+ highlight();
88
+ showimg();
89
+ rendermath();
90
+ } else input.classList.add("fail");
91
+ },
92
+ handlesearch() {
93
+ let input = document.getElementById("search-bar"),
94
+ timeline = document.getElementsByClassName("timeline"),
95
+ key = input.value.toLowerCase().replace(/s+/gm, "");
96
+ for (let i of timeline)
97
+ if (!key || i.dataset.title.includes(key)) {
98
+ i.style.opacity = 1;
99
+ i.style.pointerEvents = "";
100
+ i.style.marginTop = "";
101
+ } else {
102
+ i.style.opacity = 0;
103
+ i.style.pointerEvents = "none";
104
+ i.style.marginTop = -i.offsetHeight - 30 + "px";
105
+ }
106
+ },
55
107
  },
56
108
  });
57
109
  app.mount("#layout");
@@ -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
- };
@@ -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
- };