hexo-theme-stellar 1.33.0 → 1.34.0
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/CLAUDE.md +217 -0
- package/README.md +2 -0
- package/_config.yml +35 -26
- package/docs/audits/2026-08-08-stellar-analysis.md +267 -0
- package/docs/release-process.md +59 -0
- package/layout/_partial/comments/artalk/script.ejs +56 -41
- package/layout/_partial/comments/beaudar/script.ejs +35 -20
- package/layout/_partial/comments/giscus/script.ejs +34 -19
- package/layout/_partial/comments/twikoo/script.ejs +29 -14
- package/layout/_partial/comments/utterances/script.ejs +35 -20
- package/layout/_partial/comments/waline/script.ejs +40 -28
- package/layout/_partial/cover/wiki_cover.ejs +1 -1
- package/layout/_partial/head.ejs +53 -4
- package/layout/_partial/scripts/defines.ejs +21 -3
- package/layout/_partial/scripts/lazyload.ejs +2 -2
- package/layout/_partial/scripts/services.ejs +101 -41
- package/layout/_partial/scripts/utils.ejs +144 -5
- package/layout/_partial/sidebar/index_leftbar.ejs +3 -0
- package/layout/_partial/sidebar/search.ejs +3 -0
- package/layout/_partial/widgets/ghuser.ejs +18 -4
- package/layout/_partial/widgets/linklist.ejs +1 -1
- package/layout/_partial/widgets/timeline.ejs +36 -33
- package/layout/_plugins/copycode.ejs +9 -5
- package/layout/_plugins/mathjax.ejs +47 -18
- package/layout/_plugins/mermaid.ejs +28 -24
- package/layout/_plugins/pjax.ejs +8 -0
- package/layout/_plugins/scrollreveal.ejs +14 -13
- package/layout/_plugins/swiper.ejs +2 -2
- package/layout/index.ejs +4 -2
- package/layout/index_topic.ejs +4 -2
- package/layout/index_wiki.ejs +6 -4
- package/layout/layout.ejs +3 -2
- package/package.json +2 -1
- package/scripts/commands/new-note.js +49 -0
- package/scripts/filters/lib/img_onerror.js +0 -2
- package/scripts/helpers/json_ld.js +11 -8
- package/scripts/helpers/pretty_url.js +5 -0
- package/scripts/tags/lib/chat.js +16 -9
- package/scripts/tags/lib/frame.js +2 -1
- package/scripts/tags/lib/image.js +6 -5
- package/scripts/tags/lib/link.js +6 -4
- package/scripts/tags/lib/timeline.js +101 -79
- package/source/css/_common/canonical.styl +11 -6
- package/source/css/_common/highlight.styl +4 -1
- package/source/css/_common/html.styl +4 -0
- package/source/css/_common/loading.styl +5 -1
- package/source/css/_components/md.styl +3 -0
- package/source/css/_components/pages/article-story.styl +2 -0
- package/source/css/_components/partial/article-footer.styl +1 -0
- package/source/css/_components/partial/navbar.styl +4 -2
- package/source/css/_components/sidebar/menu.styl +1 -0
- package/source/css/_components/sidebar/search.styl +4 -0
- package/source/css/_components/sidebar/sidebar.styl +12 -5
- package/source/css/_components/tag-plugins/chat.styl +6 -8
- package/source/css/_components/tag-plugins/folding.styl +1 -0
- package/source/css/_components/tag-plugins/gallery.styl +2 -0
- package/source/css/_components/tag-plugins/grid.styl +1 -0
- package/source/css/_components/tag-plugins/image.styl +3 -0
- package/source/css/_components/tag-plugins/link.styl +1 -0
- package/source/css/_components/tag-plugins/navbar.styl +15 -13
- package/source/css/_components/tag-plugins/note.styl +1 -0
- package/source/css/_components/tag-plugins/okr.styl +1 -0
- package/source/css/_components/tag-plugins/sites.styl +2 -0
- package/source/css/_components/tag-plugins/timeline.styl +9 -0
- package/source/css/_components/tag-plugins/vote.styl +2 -0
- package/source/css/_components/widgets/components.styl +1 -0
- package/source/css/_components/widgets/ghuser.styl +19 -3
- package/source/css/_components/widgets/list.styl +1 -0
- package/source/css/_components/widgets/toc.styl +3 -0
- package/source/css/_components/widgets/widgets.styl +4 -0
- package/source/css/_custom.styl +6 -3
- package/source/css/_defines/func.styl +24 -8
- package/source/css/_defines/theme_base.styl +1 -1
- package/source/css/_plugins/comments/artalk.styl +6 -2
- package/source/css/_plugins/comments/twikoo.styl +2 -0
- package/source/css/_plugins/index.styl +2 -0
- package/source/css/_plugins/pjax.styl +61 -0
- package/source/js/main.js +80 -26
- package/source/js/plugins/copycode.js +34 -27
- package/source/js/plugins/pjax.js +646 -0
- package/source/js/search/local-search.js +5 -2
- package/source/js/services/memos.js +42 -4
- package/source/js/services/rss.js +200 -0
|
@@ -1,29 +1,33 @@
|
|
|
1
1
|
<script defer type="text/javascript" src="<%- conf.js %>"></script>
|
|
2
2
|
<script>
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
3
|
+
utils.initPlugin(() => {
|
|
4
|
+
const els = document.querySelectorAll('.mermaid');
|
|
5
|
+
if (els.length > 0) {
|
|
6
|
+
const mermaid_config = {
|
|
7
|
+
startOnLoad: false,
|
|
8
|
+
theme:
|
|
9
|
+
"<%- theme.style.prefers_theme %>" == "auto" &&
|
|
10
|
+
window.matchMedia("(prefers-color-scheme: dark)").matches
|
|
11
|
+
? "dark"
|
|
12
|
+
: "<%- conf.theme %>",
|
|
13
|
+
logLevel: 3,
|
|
14
|
+
themeVariables: {
|
|
15
|
+
darkMode: true
|
|
16
|
+
},
|
|
17
|
+
flowchart: {
|
|
18
|
+
useMaxWidth: false,
|
|
19
|
+
htmlLabels: true,
|
|
20
|
+
curve: "linear"
|
|
21
|
+
},
|
|
22
|
+
gantt: {
|
|
23
|
+
axisFormat: "%Y/%m/%d"
|
|
24
|
+
},
|
|
25
|
+
sequence: {
|
|
26
|
+
actorMargin: 50
|
|
27
|
+
}
|
|
25
28
|
}
|
|
29
|
+
mermaid.initialize(mermaid_config);
|
|
30
|
+
mermaid.run();
|
|
26
31
|
}
|
|
27
|
-
|
|
28
|
-
});
|
|
32
|
+
}, 'mermaid');
|
|
29
33
|
</script>
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
window.StellarPjaxConfig = {
|
|
3
|
+
selectors: <%- JSON.stringify((conf.selectors || ['title', '#l_cover', '.l_body']).includes('#l_cover') ? (conf.selectors || ['title', '#l_cover', '.l_body']) : (conf.selectors || ['title', '#l_cover', '.l_body']).concat('#l_cover')) %>,
|
|
4
|
+
timeout: <%= conf.timeout || 10000 %>,
|
|
5
|
+
cacheBust: <%= conf.cacheBust || false %>
|
|
6
|
+
};
|
|
7
|
+
</script>
|
|
8
|
+
<script src="<%- url_for('/js/plugins/pjax.js') %>" defer></script>
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
<script defer src="<%- conf.js %>"></script>
|
|
2
2
|
<script>
|
|
3
|
-
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
3
|
+
utils.initPlugin(() => {
|
|
4
|
+
const els = document.querySelectorAll('.slide-up');
|
|
5
|
+
if (els.length > 0) {
|
|
6
|
+
const slideUp = {
|
|
7
|
+
distance: `<%- conf.distance %>`,
|
|
8
|
+
duration: `<%- conf.duration %>`,
|
|
9
|
+
interval: `<%- conf.interval %>`,
|
|
10
|
+
scale: `<%- conf.scale %>`,
|
|
11
|
+
opacity: 0,
|
|
12
|
+
easing: "ease-out"
|
|
13
|
+
};
|
|
14
|
+
ScrollReveal().reveal('.slide-up', { ...slideUp });
|
|
15
|
+
}
|
|
16
|
+
}, 'scrollreveal');
|
|
16
17
|
</script>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script>
|
|
2
|
-
|
|
2
|
+
utils.initPlugin(() => {
|
|
3
3
|
const swiper_api = document.getElementById('swiper-api');
|
|
4
4
|
if (swiper_api != undefined) {
|
|
5
5
|
utils.css(`<%- conf.css %>`);
|
|
@@ -22,5 +22,5 @@
|
|
|
22
22
|
});
|
|
23
23
|
})
|
|
24
24
|
}
|
|
25
|
-
});
|
|
25
|
+
}, 'swiper');
|
|
26
26
|
</script>
|
package/layout/index.ejs
CHANGED
|
@@ -12,15 +12,17 @@ function layout_post_card(layout, post, content) {
|
|
|
12
12
|
if (layout == 'post' && post.cover != undefined && post.poster != undefined) {
|
|
13
13
|
layout += ' photo';
|
|
14
14
|
}
|
|
15
|
-
el += `<
|
|
15
|
+
el += `<div class="post-card-wrap${scrollreveal(' ')}">`;
|
|
16
|
+
el += `<a class="post-card ${layout}" href="${pretty_url(post.link || post.path)}">`
|
|
16
17
|
el += content;
|
|
17
18
|
el += '</a>';
|
|
19
|
+
el += '</div>';
|
|
18
20
|
return el;
|
|
19
21
|
}
|
|
20
22
|
|
|
21
23
|
function layout_post_list(partial) {
|
|
22
24
|
var el = '';
|
|
23
|
-
el +=
|
|
25
|
+
el += `<div class="post-list post">`;
|
|
24
26
|
page.posts.each(function(post){
|
|
25
27
|
if (post.indexing != false) {
|
|
26
28
|
el += layout_post_card('post', post, partial(post));
|
package/layout/index_topic.ejs
CHANGED
|
@@ -7,8 +7,8 @@ function layout_topic_list(partial) {
|
|
|
7
7
|
if (topic == null) {
|
|
8
8
|
continue
|
|
9
9
|
}
|
|
10
|
-
el += `<div class="post-
|
|
11
|
-
el += `<a class="post-card wiki topic
|
|
10
|
+
el += `<div class="post-card-wrap${scrollreveal(' ')}">`
|
|
11
|
+
el += `<a class="post-card wiki topic" href="${pretty_url(topic.homepage?.path || '/')}">`
|
|
12
12
|
el += partial(topic)
|
|
13
13
|
el += `</a>`
|
|
14
14
|
el += `</div>`
|
|
@@ -18,9 +18,11 @@ function layout_topic_list(partial) {
|
|
|
18
18
|
function layoutDiv() {
|
|
19
19
|
var el = ''
|
|
20
20
|
el += partial('_partial/main/navbar/nav_tabs_blog')
|
|
21
|
+
el += `<div class="post-list wiki topic">`;
|
|
21
22
|
el += layout_topic_list(function(topic) {
|
|
22
23
|
return partial('_partial/main/post_list/topic_card', {topic: topic})
|
|
23
24
|
})
|
|
25
|
+
el += `</div>`
|
|
24
26
|
return el
|
|
25
27
|
}
|
|
26
28
|
%>
|
package/layout/index_wiki.ejs
CHANGED
|
@@ -12,15 +12,15 @@ function layout_wiki_list(partial) {
|
|
|
12
12
|
}
|
|
13
13
|
if (page.filter === false) {
|
|
14
14
|
// wikiList
|
|
15
|
-
el += `<div class="post-
|
|
16
|
-
el += `<a class="post-card wiki
|
|
15
|
+
el += `<div class="post-card-wrap${scrollreveal(' ')}">`
|
|
16
|
+
el += `<a class="post-card wiki" href="${pretty_url(proj.homepage?.path || '/')}">`
|
|
17
17
|
el += partial(proj)
|
|
18
18
|
el += `</a>`
|
|
19
19
|
el += `</div>`
|
|
20
20
|
} else if (proj.tags && proj.tags.includes(page.tagName) === true) {
|
|
21
21
|
// filtered wikiList
|
|
22
|
-
el += `<div class="post-
|
|
23
|
-
el += `<a class="post-card wiki
|
|
22
|
+
el += `<div class="post-card-wrap${scrollreveal(' ')} filter">`
|
|
23
|
+
el += `<a class="post-card wiki" href="${pretty_url(proj.homepage?.path || '/')}">`
|
|
24
24
|
el += partial(proj)
|
|
25
25
|
el += `</a>`
|
|
26
26
|
el += `</div>`
|
|
@@ -32,9 +32,11 @@ function layout_wiki_list(partial) {
|
|
|
32
32
|
function layoutDiv() {
|
|
33
33
|
var el = ''
|
|
34
34
|
el += partial('_partial/main/navbar/nav_tabs_wiki')
|
|
35
|
+
el += `<div class="post-list wiki">`;
|
|
35
36
|
el += layout_wiki_list(function(proj) {
|
|
36
37
|
return partial('_partial/main/post_list/wiki_card', {proj: proj})
|
|
37
38
|
})
|
|
39
|
+
el += `</div>`
|
|
38
40
|
return el
|
|
39
41
|
}
|
|
40
42
|
%>
|
package/layout/layout.ejs
CHANGED
|
@@ -47,7 +47,7 @@ if (theme.style.prefers_theme === 'auto') {
|
|
|
47
47
|
html += partial('_partial/head')
|
|
48
48
|
html += `<body>`
|
|
49
49
|
html += site_background
|
|
50
|
-
html += partial('_partial/cover/index')
|
|
50
|
+
html += `<div id="l_cover">${partial('_partial/cover/index').trim()}</div>`
|
|
51
51
|
html += `<div class="l_body ${page_type}" id="start" layout="${page.layout}" type="${article_type}" ${indent ? 'text-indent' : ''}>`
|
|
52
52
|
html += `<aside class="l_left">`
|
|
53
53
|
html += `<div class="sidebg"></div>`
|
|
@@ -62,13 +62,14 @@ if (theme.style.prefers_theme === 'auto') {
|
|
|
62
62
|
html += `<div class="main-mask" onclick="sidebar.dismiss()"></div>`
|
|
63
63
|
html += `</div>`
|
|
64
64
|
html += `<aside class="l_right">`
|
|
65
|
-
html += partial('_partial/sidebar/index_rightbar')
|
|
65
|
+
html += partial('_partial/sidebar/index_rightbar').trim()
|
|
66
66
|
html += `</aside>`
|
|
67
67
|
html += partial('_partial/menubtn')
|
|
68
68
|
html += `</div>`
|
|
69
69
|
html += `<div class="scripts">`
|
|
70
70
|
html += partial('_partial/scripts')
|
|
71
71
|
html += `</div>`
|
|
72
|
+
html += `<div class="page-loading-bar"><img src="${theme.default.loading}"></div>`
|
|
72
73
|
html += `</body>`
|
|
73
74
|
html += `</html>`
|
|
74
75
|
%>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hexo-theme-stellar",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.34.0",
|
|
4
4
|
"description": "Elegant and powerful theme for Hexo.",
|
|
5
5
|
"main": "package.json",
|
|
6
6
|
"scripts": {
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"cheerio": "^1.1.0",
|
|
25
|
+
"glob": "^10.4.0",
|
|
25
26
|
"hexo-renderer-ejs": "^2.0.0",
|
|
26
27
|
"hexo-renderer-stylus": "^3.0.1",
|
|
27
28
|
"probe-image-size": "^7.2.3"
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
|
|
4
|
+
hexo.extend.console.register('new-note', 'Create a new note', {
|
|
5
|
+
options: [
|
|
6
|
+
{ name: '-n, --name', desc: 'Note name', required: true },
|
|
7
|
+
{ name: '-bk, --book', desc: 'Notebook name', required: true },
|
|
8
|
+
{ name: '-tag, --tag', desc: 'Tags (comma separated)', required: false }
|
|
9
|
+
]
|
|
10
|
+
}, function(args, callback) {
|
|
11
|
+
const name = args.name || args.n;
|
|
12
|
+
const book = args.book || args.bk || args.k;
|
|
13
|
+
const tagStr = args.tag ||args.g ||'';
|
|
14
|
+
if (!name || !book) {
|
|
15
|
+
console.log('Usage: hexo new-note -n "name" -bk "notebook" -tag "tag1,tag2/subtag1"');
|
|
16
|
+
return callback();
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const date = new Date();
|
|
20
|
+
const filename = `${name}.md`;
|
|
21
|
+
const notebookDir = path.join(hexo.source_dir, 'notebooks', book);
|
|
22
|
+
if (!fs.existsSync(notebookDir)) {
|
|
23
|
+
fs.mkdirSync(notebookDir, { recursive: true });
|
|
24
|
+
}
|
|
25
|
+
const filePath = path.join(notebookDir, filename);
|
|
26
|
+
if (fs.existsSync(filePath)) {
|
|
27
|
+
console.log(`File ${filename} already exists in ${notebookDir}.`);
|
|
28
|
+
return callback();
|
|
29
|
+
}
|
|
30
|
+
// 处理标签
|
|
31
|
+
let tags = [];
|
|
32
|
+
if (tagStr) {
|
|
33
|
+
tags = tagStr.split(',').map(t => t.trim()).filter(Boolean);
|
|
34
|
+
}
|
|
35
|
+
// 生成表头
|
|
36
|
+
const frontMatter = [
|
|
37
|
+
'---',
|
|
38
|
+
`title: ${name}`,
|
|
39
|
+
`date: ${date.getFullYear()}-${String(date.getMonth()+1).padStart(2,'0')}-${String(date.getDate()).padStart(2,'0')} ${String(date.getHours()).padStart(2,'0')}:${String(date.getMinutes()).padStart(2,'0')}:${String(date.getSeconds()).padStart(2,'0')}`,
|
|
40
|
+
`tags: [${tags.map(t => '"'+t+'"').join(', ')}]`,
|
|
41
|
+
`notebook: ${book}`,
|
|
42
|
+
'---',
|
|
43
|
+
'',
|
|
44
|
+
''
|
|
45
|
+
].join('\n');
|
|
46
|
+
fs.writeFileSync(filePath, frontMatter);
|
|
47
|
+
console.log(`Created: ${filePath}`);
|
|
48
|
+
callback();
|
|
49
|
+
});
|
|
@@ -6,19 +6,22 @@
|
|
|
6
6
|
'use strict';
|
|
7
7
|
|
|
8
8
|
const util = require('hexo-util');
|
|
9
|
-
|
|
9
|
+
|
|
10
10
|
hexo.extend.helper.register('json_ld', function(args) {
|
|
11
11
|
const page = this.page;
|
|
12
12
|
const config = this.config;
|
|
13
13
|
const structured_data = this.theme.structured_data;
|
|
14
14
|
const authorEmail = config.email;
|
|
15
|
-
|
|
15
|
+
let authorImage = config.avatar || (authorEmail ? this.gravatar(authorEmail) : null);
|
|
16
16
|
const isPage = page.layout == 'page';
|
|
17
|
+
if (authorImage && authorImage.startsWith("/")) {
|
|
18
|
+
authorImage = config.url.endsWith("/") ? config.url + authorImage.slice(1) : config.url + authorImage
|
|
19
|
+
}
|
|
17
20
|
|
|
18
21
|
const author = {
|
|
19
22
|
'@type': 'Person',
|
|
20
23
|
name: config.author,
|
|
21
|
-
sameAs: structured_data.
|
|
24
|
+
sameAs: structured_data.links || []
|
|
22
25
|
};
|
|
23
26
|
// Google does not accept `Person` as item type for the publisher property
|
|
24
27
|
const publisher = Object.assign({}, author, {'@type': 'Organization'});
|
|
@@ -69,9 +72,9 @@ hexo.extend.helper.register('json_ld', function(args) {
|
|
|
69
72
|
|
|
70
73
|
schema.thumbnailUrl = page.cover || page.banner;
|
|
71
74
|
schema.image = images;
|
|
72
|
-
|
|
75
|
+
|
|
73
76
|
} else if (isPage || this.is_home()) {
|
|
74
|
-
|
|
77
|
+
|
|
75
78
|
const url = this.is_home() ? config.url : this.pretty_url(page.permalink);
|
|
76
79
|
schema = {
|
|
77
80
|
'@context': 'https://schema.org',
|
|
@@ -99,9 +102,9 @@ hexo.extend.helper.register('json_ld', function(args) {
|
|
|
99
102
|
}
|
|
100
103
|
|
|
101
104
|
}
|
|
102
|
-
|
|
105
|
+
|
|
103
106
|
} else {
|
|
104
|
-
|
|
107
|
+
|
|
105
108
|
// default to WebPage for other layouts
|
|
106
109
|
schema = {
|
|
107
110
|
'@context': 'https://schema.org',
|
|
@@ -112,7 +115,7 @@ hexo.extend.helper.register('json_ld', function(args) {
|
|
|
112
115
|
description: config.description,
|
|
113
116
|
url: config.url
|
|
114
117
|
};
|
|
115
|
-
|
|
118
|
+
|
|
116
119
|
}
|
|
117
120
|
|
|
118
121
|
return `<script type="application/ld+json">${JSON.stringify(schema)}</script>`;
|
package/scripts/tags/lib/chat.js
CHANGED
|
@@ -52,7 +52,11 @@ module.exports = ctx => function(args, content) {
|
|
|
52
52
|
// users
|
|
53
53
|
var arr = content.split(/<!--\s*([\s\S]*?)\s*-->/g).filter(item => item.trim().length > 0)
|
|
54
54
|
if (arr.length > 0) {
|
|
55
|
-
|
|
55
|
+
// 避免用户在没有配置chat_users.yaml时出错
|
|
56
|
+
if (ctx.theme.config.chat_users){
|
|
57
|
+
var users = merge(ctx.theme.config.chat_users, ctx.render.renderSync({ text: (arr[0] || ''), engine: 'yaml' }));
|
|
58
|
+
}
|
|
59
|
+
var users = ctx.render.renderSync({ text: (arr[0] || ''), engine: 'yaml' });
|
|
56
60
|
}
|
|
57
61
|
|
|
58
62
|
|
|
@@ -286,13 +290,16 @@ module.exports = ctx => function(args, content) {
|
|
|
286
290
|
el += '<div class="user-main">'
|
|
287
291
|
|
|
288
292
|
el += '<div class="header">'
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
+
// 防止徽章为空
|
|
294
|
+
if (user['label']){
|
|
295
|
+
if (!args.labelColorStyle || args.labelColorStyle == 'dynamic') {
|
|
296
|
+
el += `<span class="label dynamic-color" style="color:var(--chat-${chatIndex}-label-text-color-${userColorMap[cell['user']]});background:var(--chat-${chatIndex}-label-bg-${userColorMap[cell['user']]});">`
|
|
297
|
+
} else {
|
|
298
|
+
el += `<span class="label hand-color" style="color:${user['label']['textColor']};background:${user['label']['bgColor']};">`
|
|
299
|
+
}
|
|
300
|
+
el += user['label']['text']
|
|
301
|
+
el += '</span>'
|
|
293
302
|
}
|
|
294
|
-
el += user['label']['text']
|
|
295
|
-
el += '</span>'
|
|
296
303
|
el += '<span class="name">'
|
|
297
304
|
el += user['name']
|
|
298
305
|
el += '</span>'
|
|
@@ -429,7 +436,7 @@ module.exports = ctx => function(args, content) {
|
|
|
429
436
|
</a>
|
|
430
437
|
`
|
|
431
438
|
} else if (cell['file']) {
|
|
432
|
-
el += ` file" url="${cell["file"]}">`
|
|
439
|
+
el += ` chat-file" url="${cell["file"]}">`
|
|
433
440
|
el += `
|
|
434
441
|
<div class="content">
|
|
435
442
|
<div class="top">
|
|
@@ -508,4 +515,4 @@ module.exports = ctx => function(args, content) {
|
|
|
508
515
|
el += '</div>' // tag-plugin chat
|
|
509
516
|
|
|
510
517
|
return el
|
|
511
|
-
}
|
|
518
|
+
}
|
|
@@ -9,11 +9,12 @@
|
|
|
9
9
|
|
|
10
10
|
module.exports = ctx => function(args) {
|
|
11
11
|
args = ctx.args.map(args, ['focus', 'img', 'video'], ['device', 'alt'])
|
|
12
|
+
const escapeHTML = require('hexo-util').escapeHTML
|
|
12
13
|
const img = args.img || ''
|
|
13
14
|
const video = args.video || ''
|
|
14
15
|
const device = args.device || ''
|
|
15
16
|
const focus = args.focus || ''
|
|
16
|
-
const alt = args.alt || ''
|
|
17
|
+
const alt = escapeHTML(args.alt || '')
|
|
17
18
|
if ((img.length == 0 && video.length == 0) || device.length == 0) {
|
|
18
19
|
return
|
|
19
20
|
}
|
|
@@ -37,13 +37,14 @@ module.exports = ctx => function(args) {
|
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
+
var safeAlt = require('hexo-util').escapeHTML(args.alt || '')
|
|
40
41
|
function img(src, alt, style) {
|
|
41
42
|
let a = '<a data-fancybox'
|
|
42
43
|
let img = ''
|
|
43
44
|
img += `<img class="lazy" src="${src}" data-src="${src}"`
|
|
44
|
-
if (
|
|
45
|
-
img += ` alt="${
|
|
46
|
-
a += ` data-caption="${
|
|
45
|
+
if (safeAlt) {
|
|
46
|
+
img += ` alt="${safeAlt}"`
|
|
47
|
+
a += ` data-caption="${safeAlt}"`
|
|
47
48
|
}
|
|
48
49
|
if (fancybox && !fancyboxHref) {
|
|
49
50
|
img += ` data-fancybox="${fancybox}"`
|
|
@@ -101,9 +102,9 @@ module.exports = ctx => function(args) {
|
|
|
101
102
|
}
|
|
102
103
|
el += '</div>'
|
|
103
104
|
|
|
104
|
-
if (
|
|
105
|
+
if (safeAlt) {
|
|
105
106
|
el += '<div class="image-meta">'
|
|
106
|
-
el += '<span class="image-caption center">' +
|
|
107
|
+
el += '<span class="image-caption center">' + safeAlt + '</span>'
|
|
107
108
|
el += '</div>'
|
|
108
109
|
}
|
|
109
110
|
|
package/scripts/tags/lib/link.js
CHANGED
|
@@ -9,11 +9,13 @@
|
|
|
9
9
|
|
|
10
10
|
module.exports = ctx => function(args) {
|
|
11
11
|
const full_url_for = require('hexo-util').full_url_for.bind(ctx)
|
|
12
|
+
const escapeHTML = require('hexo-util').escapeHTML
|
|
12
13
|
args = ctx.args.map(args, ['icon', 'desc'], ['url', 'title'])
|
|
13
14
|
if (args.url == null) {
|
|
14
15
|
return '';
|
|
15
16
|
}
|
|
16
17
|
const url = full_url_for(args.url)
|
|
18
|
+
const safeTitle = escapeHTML(args.title || '')
|
|
17
19
|
args.api = ctx.theme.config.data_services.siteinfo?.api
|
|
18
20
|
if (args.api) {
|
|
19
21
|
args.api = args.api.replace('{href}', url)
|
|
@@ -25,12 +27,12 @@ module.exports = ctx => function(args) {
|
|
|
25
27
|
if (!args.icon) {
|
|
26
28
|
autofill.push('icon')
|
|
27
29
|
}
|
|
28
|
-
if (args.desc) {
|
|
30
|
+
if (args.desc !== 'true' && args.desc !== true && !args.desc) {
|
|
29
31
|
autofill.push('desc')
|
|
30
32
|
}
|
|
31
33
|
var el = ''
|
|
32
34
|
el += '<div class="tag-plugin link dis-select">'
|
|
33
|
-
el += '<a class="link-card' + (args.desc ? ' rich' : ' plain') + '" title="' +
|
|
35
|
+
el += '<a class="link-card' + (args.desc ? ' rich' : ' plain') + '" title="' + safeTitle + '" href="' + args.url + '"'
|
|
34
36
|
if (args.url.includes('://')) {
|
|
35
37
|
el += ' target="_blank" rel="external nofollow noopener noreferrer"'
|
|
36
38
|
}
|
|
@@ -49,10 +51,10 @@ module.exports = ctx => function(args) {
|
|
|
49
51
|
return el
|
|
50
52
|
}
|
|
51
53
|
function loadTitle() {
|
|
52
|
-
return '<span class="title">' + (
|
|
54
|
+
return '<span class="title">' + (safeTitle || args.url) + '</span>'
|
|
53
55
|
}
|
|
54
56
|
function loadDesc() {
|
|
55
|
-
return
|
|
57
|
+
return `<span class="cap desc footnote">${escapeHTML(args.desc)}</span>`
|
|
56
58
|
}
|
|
57
59
|
function loadLink() {
|
|
58
60
|
return '<span class="cap link footnote">' + full_url_for(args.url) + '</span>'
|