hexo-theme-particlex 2.5.8 → 2.5.10

Sign up to get free protection for your applications and to get access to all the features.
package/README.md CHANGED
@@ -130,7 +130,7 @@ card:
130
130
  iconLinks:
131
131
  {}
132
132
  friendLinks:
133
- Argvchs: https://argvchs.netlify.app
133
+ Argvchs: https://argvchs.github.io
134
134
  ```
135
135
 
136
136
  ### 3.2.3. 页脚
@@ -275,7 +275,7 @@ Gitalk 是一个基于 GitHub Issue 和 Preact 的评论系统
275
275
 
276
276
  **同样如果没有其他网站,请在 `sites:` 后添加一个 `{}`**
277
277
 
278
- 由于 Gitalk 官方 CORS 代理用的是 Cloudflare,速度过慢,添加了 `proxy` 参数,搭建 CORS 代理可以看[这篇文章](https://argvchs.netlify.app/2022/07/04/build-cors-anywhere)
278
+ 由于 Gitalk 官方 CORS 代理用的是 Cloudflare,速度过慢,添加了 `proxy` 参数,搭建 CORS 代理可以看[这篇文章](https://argvchs.github.io/2022/07/04/build-cors-anywhere)
279
279
 
280
280
  ```yaml
281
281
  # Gitalk
package/_config.yml CHANGED
@@ -43,7 +43,7 @@ card:
43
43
  iconLinks:
44
44
  {}
45
45
  friendLinks:
46
- Argvchs: https://argvchs.netlify.app
46
+ Argvchs: https://argvchs.github.io
47
47
 
48
48
  # Footer info
49
49
  footer:
package/layout/card.ejs CHANGED
@@ -1,5 +1,5 @@
1
1
  <div id="card-div">
2
- <div class="card-style" style="width: 300px">
2
+ <div class="card-style">
3
3
  <div class="avatar">
4
4
  <img src="<%- url_for(theme.avatar) %>" alt="avatar" />
5
5
  </div>
@@ -18,7 +18,7 @@
18
18
  <% } %>
19
19
  <% if (theme.gitalk.enable) { %>
20
20
  <script>
21
- (function () {
21
+ (() => {
22
22
  let clientID = "<%- theme.gitalk.clientID %>",
23
23
  clientSecret = "<%- theme.gitalk.clientSecret %>";
24
24
  <% Object.keys(theme.gitalk.sites).forEach(key => { %>
package/layout/index.ejs CHANGED
@@ -2,7 +2,7 @@
2
2
  <div
3
3
  id="home-background"
4
4
  ref="homeBackground"
5
- data-image="<%- theme.background.map(i => url_for(i)) %>"
5
+ data-images="<%- theme.background.map(i => url_for(i)) %>"
6
6
  ></div>
7
7
  <div id="home-info" @click="homeClick">
8
8
  <span class="loop"></span>
@@ -20,10 +20,8 @@
20
20
  </div>
21
21
  <div id="home-posts-wrap" <%- theme.card.enable ? "" : 'class="home-posts-wrap-no-card"' %> ref="homePostsWrap">
22
22
  <div id="home-posts">
23
- <div id="posts">
24
- <%- partial("posts") %>
25
- <%- partial("current") %>
26
- </div>
23
+ <%- partial("posts") %>
24
+ <%- partial("current") %>
27
25
  </div>
28
26
  <% if (theme.card.enable) { %>
29
27
  <div id="home-card">
package/layout/layout.ejs CHANGED
@@ -1,25 +1,16 @@
1
1
  <%
2
- let type = "post";
3
- if (is_home())
4
- type = "index";
5
- else if (is_post())
6
- type = "post";
7
- else if (is_category() || page.type === "categories")
8
- type = "categories";
9
- else if (is_tag() || page.type === "tags")
10
- type = "tags";
11
- else if (is_archive())
12
- type = "archives";
13
- let title = "";
14
- if (page.title)
15
- title = page.title + " | ";
16
- else if (is_category())
17
- title = "Categories: " + page.category + " | ";
18
- else if (is_tag())
19
- title = "Tags: " + page.tag + " | ";
20
- else if (is_archive())
21
- title = "Archives | ";
22
- title += config.title;
2
+ let type;
3
+ if (is_home()) type = "index";
4
+ if (is_post() || is_page()) type = "post";
5
+ if (is_category() || page.type === "categories") type = "categories";
6
+ if (is_tag() || page.type === "tags") type = "tags";
7
+ if (is_archive()) type = "archives";
8
+ let title;
9
+ if (is_home()) title = config.title;
10
+ if (is_post() || is_page()) title = page.title + " | " + config.title;
11
+ if (is_category()) title = "Categories: " + page.category + " | " + config.title;
12
+ if (is_tag()) title = "Tags: " + page.tag + " | " + config.title;
13
+ if (is_archive()) title = "Archives | " + config.title;
23
14
  %>
24
15
  <!DOCTYPE html>
25
16
  <html lang="<%- config.language %>">
@@ -39,14 +30,14 @@
39
30
  <div id="loading" v-show="loading">
40
31
  <div id="loading-circle">
41
32
  <h2>LOADING</h2>
42
- <p>加载过慢请开启缓存&ensp;浏览器默认开启</p>
33
+ <p>加载过慢请开启缓存 浏览器默认开启</p>
43
34
  <img src="<%- url_for("/images/loading.gif") %>" />
44
35
  </div>
45
36
  </div>
46
37
  </transition>
38
+ <%- partial("menu") %>
47
39
  <transition name="into">
48
40
  <div id="main" v-show="!loading">
49
- <%- partial("menu") %>
50
41
  <%- partial(type) %>
51
42
  <%- partial("footer") %>
52
43
  </div>
package/layout/menu.ejs CHANGED
@@ -1,4 +1,4 @@
1
- <nav id="menu" ref="menu">
1
+ <nav id="menu" :class="{ hidden: hiddenMenu, 'menu-color': menuColor}">
2
2
  <div class="desktop-menu">
3
3
  <a class="title" href="<%- config.root %>">
4
4
  <span><%= config.title.toUpperCase() %></span>
@@ -11,13 +11,13 @@
11
11
  <% }); %>
12
12
  </div>
13
13
  <div id="mobile-menu">
14
- <div class="curtain" v-show="showMenu" @click="showMenu = !showMenu"></div>
15
- <div class="title" @click="showMenu = !showMenu">
14
+ <div class="curtain" @click="shouMenuItems = !shouMenuItems" v-show="shouMenuItems"></div>
15
+ <div class="title" @click="shouMenuItems = !shouMenuItems">
16
16
  <i class="fa-solid fa-bars fa-fw"></i>
17
17
  <span>&emsp;<%= config.title.toUpperCase() %></span>
18
18
  </div>
19
19
  <transition name="slide">
20
- <div class="items" v-show="showMenu">
20
+ <div class="items" v-show="shouMenuItems">
21
21
  <% Object.keys(theme.menu).forEach(key => { %>
22
22
  <a href="<%- url_for(theme.menu[key].link) %>">
23
23
  <div class="item">
package/layout/post.ejs CHANGED
@@ -43,26 +43,19 @@
43
43
  <% } %>
44
44
  </div>
45
45
  <% if (theme.crypto.enable && typeof page.secret !== "undefined") { %>
46
- <%
47
- const CryptoJS = crypto();
48
- function SHA(word) {
49
- return CryptoJS.SHA256(word).toString();
50
- }
51
- function encrypt(word, secret) {
52
- return CryptoJS.AES.encrypt(word, secret).toString();
53
- }
54
- %>
46
+ <% const CryptoJS = crypto(); %>
55
47
  <input
56
48
  id="crypto"
57
- class="input"
49
+ :class="['input', cryptoClass]"
50
+ :disabled="check"
58
51
  ref="crypto"
59
52
  placeholder="文章被加密,请输入密码"
60
- data-encrypted="<%- encrypt(page.content, page.secret) %>"
61
- data-shasum="<%- SHA(page.content) %>"
53
+ data-encrypted="<%- CryptoJS.AES.encrypt(page.content, page.secret).toString() %>"
54
+ data-shasum="<%- CryptoJS.SHA256(page.content).toString() %>"
62
55
  v-model="crypto"
63
56
  />
64
57
  <transition name="fade">
65
- <div class="content" ref="content" v-show="check"></div>
58
+ <div class="content" ref="content" v-html="decrypted" v-show="check"></div>
66
59
  </transition>
67
60
  <% } else { %>
68
61
  <div class="content" v-pre>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hexo-theme-particlex",
3
- "version": "2.5.8",
3
+ "version": "2.5.10",
4
4
  "description": "A concise Hexo theme, based on Particle.",
5
5
  "repository": {
6
6
  "type": "git",
@@ -92,6 +92,7 @@
92
92
  box-shadow: 0 0 20px #d9d9d980;
93
93
  padding: 25px 0;
94
94
  text-align: center;
95
+ width: 300px;
95
96
  }
96
97
  #home-card .card-style .avatar {
97
98
  border: #f1f1f1 solid 3px;
@@ -360,10 +361,10 @@
360
361
  height: 50vmin;
361
362
  justify-content: center;
362
363
  padding: 50px;
364
+ text-align: center;
363
365
  width: 50vmin;
364
366
  }
365
367
  #main {
366
- display: grid;
367
368
  margin-right: calc(100% - 100vw);
368
369
  }
369
370
  #menu {
@@ -488,6 +489,7 @@
488
489
  line-height: 2;
489
490
  overflow: auto;
490
491
  padding: 50px 30px 20px;
492
+ white-space: pre;
491
493
  }
492
494
  .comment iframe,
493
495
  body::-webkit-scrollbar-track {
@@ -504,24 +506,24 @@ body::-webkit-scrollbar-track {
504
506
  margin: 15px auto;
505
507
  max-width: 75%;
506
508
  }
507
- .code-copy {
509
+ .copycode {
508
510
  color: #5c6b72;
509
511
  position: absolute;
510
512
  right: 0;
511
513
  top: 0;
512
514
  }
513
- .code-copy i {
515
+ .copycode i {
514
516
  padding: 15px;
515
517
  position: absolute;
516
518
  right: 0;
517
519
  top: 0;
518
520
  transition: transform 0.25s;
519
521
  }
520
- .code-copy.copied i {
522
+ .copycode.copied i {
521
523
  transform: scale(1.25);
522
524
  }
523
- .code-copy.copied i:first-child,
524
- .code-copy:not(.copied) i:last-child {
525
+ .copycode.copied i:first-child,
526
+ .copycode:not(.copied) i:last-child {
525
527
  opacity: 0;
526
528
  }
527
529
  .fade-enter-active,
@@ -658,7 +660,7 @@ a {
658
660
  text-decoration: none;
659
661
  }
660
662
  a:hover,
661
- .content .code-copy:hover {
663
+ .content .copycode:hover {
662
664
  opacity: 0.8;
663
665
  }
664
666
  b,
@@ -694,13 +696,12 @@ iframe,
694
696
  .friend-link a,
695
697
  .icon-link a,
696
698
  .language,
697
- .code-copy {
699
+ .copycode {
698
700
  user-select: none;
699
701
  }
700
702
  code {
701
703
  background: #bddcf76b;
702
704
  border-radius: 4px;
703
- font-size: 14px;
704
705
  line-height: 2.5;
705
706
  padding: 4px 8px;
706
707
  }
@@ -764,6 +765,7 @@ pre {
764
765
  box-shadow: 0 2px 12px 0 #0000001a;
765
766
  margin: 25px 0;
766
767
  margin: 25px 0;
768
+ white-space: normal;
767
769
  }
768
770
  pre,
769
771
  code,
@@ -824,9 +826,6 @@ ol li {
824
826
  }
825
827
  }
826
828
  @media (min-width: 900px) {
827
- #home-card {
828
- margin-right: auto;
829
- }
830
829
  #home-head #home-info .info .wrap {
831
830
  padding: 25px;
832
831
  }
@@ -855,9 +854,8 @@ ol li {
855
854
  width: 500px;
856
855
  }
857
856
  #home-posts {
858
- margin-left: auto;
859
857
  margin-right: 50px;
860
- width: 900px;
858
+ width: 850px;
861
859
  }
862
860
  #home-posts .post {
863
861
  margin-bottom: 25px;
@@ -867,8 +865,7 @@ ol li {
867
865
  padding: 20px 0;
868
866
  }
869
867
  #home-posts-wrap {
870
- max-width: 1150px;
871
- padding: 30px 0;
868
+ max-width: 1200px;
872
869
  }
873
870
  #menu .desktop-menu {
874
871
  display: block;
@@ -894,7 +891,6 @@ ol li {
894
891
  display: none;
895
892
  }
896
893
  #home-posts {
897
- margin: auto;
898
894
  width: 100%;
899
895
  }
900
896
  #home-posts-wrap,
@@ -2,40 +2,31 @@ mixins.crypto = {
2
2
  data() {
3
3
  return {
4
4
  crypto: "",
5
- check: false,
5
+ check: null,
6
6
  };
7
7
  },
8
- methods: {
9
- SHA(word) {
10
- return CryptoJS.SHA256(word).toString();
11
- },
12
- decrypt(word, secret, shasum) {
8
+ watch: {
9
+ crypto(value) {
10
+ let input = this.$refs.crypto,
11
+ content = this.$refs.content;
12
+ let { encrypted, shasum } = input.dataset;
13
13
  try {
14
- let res = CryptoJS.AES.decrypt(word, secret).toString(CryptoJS.enc.Utf8);
15
- return { check: this.SHA(res) === shasum, decrypted: res };
14
+ let decrypted = CryptoJS.AES.decrypt(encrypted, value).toString(CryptoJS.enc.Utf8);
15
+ if (CryptoJS.SHA256(decrypted).toString() === shasum) {
16
+ this.check = true;
17
+ content.innerHTML = decrypted;
18
+ this.render();
19
+ } else this.check = false;
16
20
  } catch {
17
- return { check: false };
21
+ this.check = false;
18
22
  }
19
23
  },
20
24
  },
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");
25
+ computed: {
26
+ cryptoClass() {
27
+ if (this.check === null) return "";
28
+ if (this.check === true) return "success";
29
+ if (this.check === false) return "fail";
38
30
  },
39
31
  },
40
32
  };
41
- mixins.push(cryptoMixin);
@@ -10,24 +10,29 @@ mixins.highlight = {
10
10
  },
11
11
  methods: {
12
12
  highlight() {
13
- let that = this;
14
13
  let codes = document.querySelectorAll("pre");
15
14
  for (let i of codes) {
16
- let lang = [...i.classList, ...i.firstChild.classList][0] || "plaintext";
17
15
  let code = i.innerText;
18
- i.innerHTML = `<div class="code-content">${code}</div><div class="language">${lang}</div><div class="code-copy"><i class="fa-solid fa-copy fa-fw"></i><i class="fa-solid fa-clone fa-fw"></i></div>`;
19
- let copy = i.querySelector(".code-copy");
20
- copy.addEventListener("click", async function () {
21
- if (that.copying) return;
22
- that.copying = true;
23
- this.classList.add("copied");
16
+ let language = [...i.classList, ...i.firstChild.classList][0] || "plaintext";
17
+ let highlighted = hljs.highlight(code, { language }).value;
18
+ i.innerHTML = `
19
+ <div class="code-content">${highlighted}</div>
20
+ <div class="language">${language}</div>
21
+ <div class="copycode">
22
+ <i class="fa-solid fa-copy fa-fw"></i>
23
+ <i class="fa-solid fa-clone fa-fw"></i>
24
+ </div>
25
+ `;
26
+ let copycode = i.querySelector(".copycode");
27
+ copycode.addEventListener("click", async () => {
28
+ if (this.copying) return;
29
+ this.copying = true;
30
+ copycode.classList.add("copied");
24
31
  await navigator.clipboard.writeText(code);
25
32
  await new Promise(resolve => setTimeout(resolve, 1000));
26
- this.classList.remove("copied");
27
- that.copying = false;
33
+ copycode.classList.remove("copied");
34
+ this.copying = false;
28
35
  });
29
- let content = i.querySelector(".code-content");
30
- hljs.highlightElement(content);
31
36
  }
32
37
  },
33
38
  },
@@ -1,11 +1,10 @@
1
1
  mixins.home = {
2
2
  mounted() {
3
- let menu = this.$refs.menu,
4
- background = this.$refs.homeBackground;
5
- menu.classList.add("menu-color");
6
- let image = background.dataset.image.split(",");
7
- let id = Math.floor(Math.random() * image.length);
8
- background.style.backgroundImage = `url('${image[id]}')`;
3
+ let background = this.$refs.homeBackground;
4
+ let images = background.dataset.images.split(",");
5
+ let id = Math.floor(Math.random() * images.length);
6
+ background.style.backgroundImage = `url('${images[id]}')`;
7
+ this.menuColor = true;
9
8
  },
10
9
  methods: {
11
10
  homeClick() {
@@ -9,15 +9,14 @@ mixins.preview = {
9
9
  },
10
10
  methods: {
11
11
  preview() {
12
- let that = this;
13
12
  let preview = this.$refs.preview,
14
13
  content = this.$refs.previewContent;
15
14
  let images = document.querySelectorAll("img");
16
15
  for (let i of images)
17
- i.addEventListener("click", function () {
18
- content.alt = this.alt;
19
- content.src = this.src;
20
- that.previewShow = true;
16
+ i.addEventListener("click", () => {
17
+ content.alt = i.alt;
18
+ content.src = i.src;
19
+ this.previewShow = true;
21
20
  });
22
21
  preview.addEventListener("click", () => {
23
22
  this.previewShow = false;
package/source/js/main.js CHANGED
@@ -3,8 +3,10 @@ const app = Vue.createApp({
3
3
  data() {
4
4
  return {
5
5
  loading: true,
6
- showMenu: false,
7
- barLocal: 0,
6
+ hiddenMenu: false,
7
+ showMenuItems: false,
8
+ menuColor: false,
9
+ scrollTop: 0,
8
10
  renderers: [],
9
11
  };
10
12
  },
@@ -23,20 +25,19 @@ const app = Vue.createApp({
23
25
  for (let i of this.renderers) i();
24
26
  },
25
27
  handleScroll() {
26
- let menu = this.$refs.menu,
27
- wrap = this.$refs.homePostsWrap;
28
- let newlocal = document.documentElement.scrollTop;
29
- if (this.barLocal < newlocal) {
30
- this.showMenu = false;
31
- menu.classList.add("hidden");
32
- } else menu.classList.remove("hidden");
28
+ let wrap = this.$refs.homePostsWrap;
29
+ let newScrollTop = document.documentElement.scrollTop;
30
+ if (this.scrollTop < newScrollTop) {
31
+ this.hiddenMenu = true;
32
+ this.showMenuItems = false;
33
+ } else this.hiddenMenu = false;
33
34
  if (wrap) {
34
- if (newlocal <= window.innerHeight - 100) menu.classList.add("menu-color");
35
- else menu.classList.remove("menu-color");
36
- if (newlocal <= 400) wrap.style.marginTop = -newlocal / 5 + "px";
35
+ if (newScrollTop <= window.innerHeight - 100) this.menuColor = true;
36
+ else this.menuColor = false;
37
+ if (newScrollTop <= 400) wrap.style.marginTop = -newScrollTop / 5 + "px";
37
38
  else wrap.style.marginTop = "-80px";
38
39
  }
39
- this.barLocal = newlocal;
40
+ this.scrollTop = newScrollTop;
40
41
  },
41
42
  },
42
43
  });