hexo-theme-particlex 2.5.8 → 2.5.9
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/layout/card.ejs +1 -1
- package/layout/comment.ejs +1 -1
- package/layout/index.ejs +3 -5
- package/layout/layout.ejs +14 -23
- package/layout/menu.ejs +4 -4
- package/layout/post.ejs +6 -13
- package/package.json +1 -1
- package/source/css/main.css +13 -17
- package/source/js/lib/crypto.js +18 -27
- package/source/js/lib/highlight.js +17 -12
- package/source/js/lib/home.js +5 -6
- package/source/js/lib/preview.js +4 -5
- package/source/js/main.js +14 -13
package/layout/card.ejs
CHANGED
package/layout/comment.ejs
CHANGED
package/layout/index.ejs
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
<div
|
3
3
|
id="home-background"
|
4
4
|
ref="homeBackground"
|
5
|
-
data-
|
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
|
-
|
24
|
-
|
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
|
3
|
-
if (is_home())
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
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
|
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"
|
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"
|
15
|
-
<div class="title" @click="
|
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> <%= config.title.toUpperCase() %></span>
|
18
18
|
</div>
|
19
19
|
<transition name="slide">
|
20
|
-
<div class="items" v-show="
|
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="<%-
|
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
package/source/css/main.css
CHANGED
@@ -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
|
-
.
|
509
|
+
.copycode {
|
508
510
|
color: #5c6b72;
|
509
511
|
position: absolute;
|
510
512
|
right: 0;
|
511
513
|
top: 0;
|
512
514
|
}
|
513
|
-
.
|
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
|
-
.
|
522
|
+
.copycode.copied i {
|
521
523
|
transform: scale(1.25);
|
522
524
|
}
|
523
|
-
.
|
524
|
-
.
|
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 .
|
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
|
-
.
|
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:
|
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:
|
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,
|
package/source/js/lib/crypto.js
CHANGED
@@ -2,40 +2,31 @@ mixins.crypto = {
|
|
2
2
|
data() {
|
3
3
|
return {
|
4
4
|
crypto: "",
|
5
|
-
check:
|
5
|
+
check: null,
|
6
6
|
};
|
7
7
|
},
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
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
|
15
|
-
|
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
|
-
|
21
|
+
this.check = false;
|
18
22
|
}
|
19
23
|
},
|
20
24
|
},
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
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
|
-
|
19
|
-
let
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
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
|
-
|
27
|
-
|
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
|
},
|
package/source/js/lib/home.js
CHANGED
@@ -1,11 +1,10 @@
|
|
1
1
|
mixins.home = {
|
2
2
|
mounted() {
|
3
|
-
let
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
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() {
|
package/source/js/lib/preview.js
CHANGED
@@ -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",
|
18
|
-
content.alt =
|
19
|
-
content.src =
|
20
|
-
|
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
|
-
|
7
|
-
|
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
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
this.
|
31
|
-
|
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 (
|
35
|
-
else
|
36
|
-
if (
|
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.
|
40
|
+
this.scrollTop = newScrollTop;
|
40
41
|
},
|
41
42
|
},
|
42
43
|
});
|