hexo-theme-stellar 1.32.4 → 1.33.1

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.
Files changed (89) hide show
  1. package/_config.yml +24 -14
  2. package/_data/icons.yml +8 -1
  3. package/languages/en.yml +1 -1
  4. package/languages/zh-CN.yml +1 -1
  5. package/languages/zh-TW.yml +1 -1
  6. package/layout/_partial/comments/artalk/script.ejs +7 -6
  7. package/layout/_partial/head.ejs +7 -1
  8. package/layout/_partial/main/article/contributors.ejs +1 -1
  9. package/layout/_partial/main/article/read_next.ejs +2 -2
  10. package/layout/_partial/main/navbar/article_banner.ejs +1 -1
  11. package/layout/_partial/main/navbar/breadcrumb/blog.ejs +3 -3
  12. package/layout/_partial/main/navbar/breadcrumb/note.ejs +2 -2
  13. package/layout/_partial/main/navbar/breadcrumb/page.ejs +1 -1
  14. package/layout/_partial/main/navbar/breadcrumb/wiki.ejs +2 -2
  15. package/layout/_partial/main/navbar/dateinfo.ejs +1 -1
  16. package/layout/_partial/main/navbar/ghinfo.ejs +1 -1
  17. package/layout/_partial/main/navbar/nav_tabs_blog.ejs +12 -12
  18. package/layout/_partial/main/navbar/nav_tabs_wiki.ejs +2 -2
  19. package/layout/_partial/main/notebook/note_tags.ejs +1 -1
  20. package/layout/_partial/scripts/lazyload.ejs +1 -1
  21. package/layout/_partial/scripts/utils.ejs +69 -39
  22. package/layout/_partial/sidebar/index_leftbar.ejs +1 -1
  23. package/layout/_partial/sidebar/menu.ejs +1 -1
  24. package/layout/_partial/widgets/components/link.ejs +1 -1
  25. package/layout/_partial/widgets/ghissues.ejs +7 -1
  26. package/layout/_partial/widgets/ghrepo.ejs +2 -2
  27. package/layout/_partial/widgets/ghuser.ejs +1 -1
  28. package/layout/_partial/widgets/recent.ejs +1 -1
  29. package/layout/_partial/widgets/related.ejs +2 -2
  30. package/layout/_partial/widgets/tagtree.ejs +1 -1
  31. package/layout/_partial/widgets/timeline.ejs +7 -1
  32. package/layout/_partial/widgets/tree.ejs +1 -1
  33. package/layout/_plugins/mathjax.ejs +47 -18
  34. package/layout/archive.ejs +1 -1
  35. package/layout/categories.ejs +1 -1
  36. package/layout/index.ejs +1 -1
  37. package/layout/index_topic.ejs +1 -1
  38. package/layout/index_wiki.ejs +2 -2
  39. package/layout/notebooks.ejs +1 -1
  40. package/layout/notes.ejs +1 -1
  41. package/layout/tags.ejs +1 -1
  42. package/package.json +1 -1
  43. package/scripts/events/index.js +1 -1
  44. package/scripts/events/lib/config.js +7 -1
  45. package/scripts/filters/pretty_urls.js +25 -0
  46. package/scripts/helpers/json_ld.js +5 -4
  47. package/scripts/helpers/pretty_url.js +22 -0
  48. package/scripts/tags/index.js +2 -0
  49. package/scripts/tags/lib/albums.js +1 -1
  50. package/scripts/tags/lib/chat.js +1 -1
  51. package/scripts/tags/lib/friends.js +1 -1
  52. package/scripts/tags/lib/link.js +1 -1
  53. package/scripts/tags/lib/posters.js +1 -1
  54. package/scripts/tags/lib/rating.js +32 -0
  55. package/scripts/tags/lib/sites.js +1 -1
  56. package/scripts/tags/lib/timeline.js +2 -1
  57. package/scripts/tags/lib/vote.js +28 -0
  58. package/source/css/_common/button.styl +1 -0
  59. package/source/css/_components/md.styl +2 -0
  60. package/source/css/_components/pages/article-story.styl +2 -0
  61. package/source/css/_components/partial/navbar.styl +2 -2
  62. package/source/css/_components/tag-plugins/image.styl +1 -0
  63. package/source/css/_components/tag-plugins/rating.styl +39 -0
  64. package/source/css/_components/tag-plugins/timeline.styl +5 -5
  65. package/source/css/_components/tag-plugins/vote.styl +49 -0
  66. package/source/css/_components/widgets/timeline.styl +1 -1
  67. package/source/css/_custom.styl +4 -2
  68. package/source/css/_defines/func.styl +16 -8
  69. package/source/css/_defines/theme_base.styl +2 -1
  70. package/source/css/_plugins/comments/artalk.styl +51 -11
  71. package/source/css/_plugins/lazyload.styl +3 -0
  72. package/source/js/main.js +12 -5
  73. package/source/js/search/local-search.js +3 -1
  74. package/source/js/services/artalk_latest_comment.js +1 -1
  75. package/source/js/services/contributors.js +1 -1
  76. package/source/js/services/fcircle.js +1 -1
  77. package/source/js/services/friends.js +1 -1
  78. package/source/js/services/friends_and_posts.js +1 -1
  79. package/source/js/services/ghinfo.js +1 -1
  80. package/source/js/services/giscus_latest_comment.js +1 -1
  81. package/source/js/services/memos.js +1 -1
  82. package/source/js/services/rating.js +142 -0
  83. package/source/js/services/siteinfo.js +1 -1
  84. package/source/js/services/sites.js +1 -1
  85. package/source/js/services/timeline.js +1 -1
  86. package/source/js/services/twikoo_latest_comment.js +1 -1
  87. package/source/js/services/vote.js +113 -0
  88. package/source/js/services/waline_latest_comment.js +1 -1
  89. package/source/js/services/weibo.js +1 -1
@@ -15,7 +15,7 @@ function relatedPostsInTopic() {
15
15
  el += `<div class="widget-body">`
16
16
  for (let post of topic.pages) {
17
17
  const isActive = post.path == page.path
18
- el += `<a class="item${isActive ? ' active' : ''}" href="${url_for(post.path)}">`
18
+ el += `<a class="item${isActive ? ' active' : ''}" href="${pretty_url(post.path)}">`
19
19
  el += `<span class="title">${post.title}</span>`
20
20
  if (isActive) {
21
21
  el += icon('default:bookmark.active')
@@ -42,7 +42,7 @@ function relatedWiki() {
42
42
  for (let id of relatedItem.items) {
43
43
  // 同一个分组中的其它项目
44
44
  let item = theme.wiki.tree[id]
45
- el += `<a class="item wiki" href="${url_for(item.homepage?.path)}">`
45
+ el += `<a class="item wiki" href="${pretty_url(item.homepage?.path)}">`
46
46
  el += `<span class="title">${item.title}</span>`
47
47
  if (item.description && item.description.length > 0) {
48
48
  el += `<span class="excerpt">${item.description}</span>`
@@ -9,7 +9,7 @@
9
9
 
10
10
  <% function layoutTag(tag, level) { %>
11
11
  <% const active = page.activeTag === tag.id %>
12
- <a class="link<%= active ? ' active' : '' %>" href="<%= url_for(tag.path) %>">
12
+ <a class="link<%= active ? ' active' : '' %>" href="<%= pretty_url(tag.path) %>">
13
13
  <span class="toc-text"<% if (level > 0) { %> style="padding-left: <%= level * 0.875 %>rem;"<% } %>>
14
14
  <% if (tag.id === '') { %>
15
15
  <%= __('meta.all_notes') %>
@@ -12,7 +12,13 @@ function layoutDiv() {
12
12
  }
13
13
  el += '<div class="widget-body fs14">';
14
14
  el += `<div class="tag-plugin timeline data-service ds-${(item.type || 'timeline')}"`;
15
- ['api', 'user', 'hide', 'limit'].forEach(key => {
15
+ // dataset
16
+ ['api'].forEach(key => {
17
+ if (item[key]) {
18
+ el += ' data-' + key + '="' + item[key] + '"';
19
+ }
20
+ });
21
+ ['user', 'hide', 'limit'].forEach(key => {
16
22
  if (item[key]) {
17
23
  el += ' ' + key + '="' + item[key] + '"';
18
24
  }
@@ -20,7 +20,7 @@ function layoutDocTree(pages) {
20
20
  isActive += ' active'
21
21
  }
22
22
  if (proj.pages.length > 1) {
23
- let href = url_for(p.path);
23
+ let href = pretty_url(p.path);
24
24
  if (p.is_homepage) {
25
25
  href += '#start'
26
26
  }
@@ -1,20 +1,49 @@
1
- <script type="text/javascript" src="<%- conf.js %>"></script>
1
+ <% if (conf.v3) { %>
2
+ <script>
3
+ window.MathJax = {
4
+ tex: {
5
+ inlineMath: [
6
+ ["$", "$"],
7
+ ["\\(", "\\)"],
8
+ ],
9
+ processEscapes: true,
10
+ skipTags: ["script", "noscript", "style", "textarea", "pre", "code"],
11
+ },
12
+ startup: {
13
+ ready() {
14
+ MathJax.startup.defaultReady();
15
+ MathJax.typesetPromise().then(() => {
16
+ const math = document.querySelectorAll("mjx-container");
17
+ math.forEach((element) => {
18
+ if (element.parentNode) {
19
+ element.parentNode.classList.add("has-jax");
20
+ }
21
+ });
22
+ });
23
+ },
24
+ },
25
+ };
26
+ </script>
27
+ <% } %>
28
+ <script id="MathJax-script" src="<%- conf.js %>" async></script>
29
+ <% if (!conf.v3) { %>
2
30
  <script type="text/x-mathjax-config">
3
- MathJax.Hub.Config({
4
- tex2jax: {
5
- inlineMath: [ ['$','$'], ["\\(","\\)"] ],
6
- processEscapes: true
7
- }
8
- });
9
- MathJax.Hub.Config({
10
- tex2jax: {
11
- skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code']
12
- }
13
- });
14
- MathJax.Hub.Queue(function() {
15
- var all = MathJax.Hub.getAllJax(), i;
16
- for(i=0; i < all.length; i += 1) {
17
- all[i].SourceElement().parentNode.className += ' has-jax';
18
- }
19
- });
31
+ MathJax.Hub.Config({
32
+ tex2jax: {
33
+ inlineMath: [ ['$','$'], ["\\(","\\)"] ],
34
+ processEscapes: true
35
+ }
36
+ });
37
+ MathJax.Hub.Config({
38
+ tex2jax: {
39
+ skipTags: ['script', 'noscript', 'style', 'textarea', 'pre', 'code']
40
+ }
41
+ });
42
+ MathJax.Hub.Queue(function() {
43
+ var all = MathJax.Hub.getAllJax(), i;
44
+ for(i=0; i < all.length; i += 1) {
45
+ all[i].SourceElement().parentNode.className += ' has-jax';
46
+ }
47
+ });
20
48
  </script>
49
+ <% } %>
@@ -39,7 +39,7 @@ function layoutArchiveList() {
39
39
  return post.year == year
40
40
  }).each(function(post) {
41
41
  el += `<div class="archive-list">`
42
- el +=`<a class='post fs14' href="${url_for(post.link || post.path)}">`
42
+ el +=`<a class='post fs14' href="${pretty_url(post.link || post.path)}">`
43
43
  el += `<time>${date(post.date, 'MM-DD')}</time>`
44
44
  el += `<span>`
45
45
  if (post.title) {
@@ -12,7 +12,7 @@ if (page.menu_id == undefined) {
12
12
  <article class='<%- scrollreveal("") %>' id='cats'>
13
13
  <% site.categories.sort('path').each(function(category){ %>
14
14
  <div>
15
- <a class="<%= category.parent ? 'cat child' : 'cat'%>" href="<%= url_for(category.path) %>">
15
+ <a class="<%= category.parent ? 'cat child' : 'cat'%>" href="<%= pretty_url(category.path) %>">
16
16
  <span class='name'><%- icon('default:category') %><%- category.name %></span>
17
17
  <span class='badge'>(<%- category.posts.length %>)</span>
18
18
  </a>
package/layout/index.ejs CHANGED
@@ -12,7 +12,7 @@ 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 += `<a class="post-card${scrollreveal(' ')} ${layout}" href="${url_for(post.link || post.path)}">`
15
+ el += `<a class="post-card${scrollreveal(' ')} ${layout}" href="${pretty_url(post.link || post.path)}">`
16
16
  el += content;
17
17
  el += '</a>';
18
18
  return el;
@@ -8,7 +8,7 @@ function layout_topic_list(partial) {
8
8
  continue
9
9
  }
10
10
  el += `<div class="post-list wiki topic">`
11
- el += `<a class="post-card wiki topic${scrollreveal(' ')}" href="${url_for(topic.homepage?.path || '/')}">`
11
+ el += `<a class="post-card wiki topic${scrollreveal(' ')}" href="${pretty_url(topic.homepage?.path || '/')}">`
12
12
  el += partial(topic)
13
13
  el += `</a>`
14
14
  el += `</div>`
@@ -13,14 +13,14 @@ function layout_wiki_list(partial) {
13
13
  if (page.filter === false) {
14
14
  // wikiList
15
15
  el += `<div class="post-list wiki">`
16
- el += `<a class="post-card wiki${scrollreveal(' ')}" href="${url_for(proj.homepage?.path || '/')}">`
16
+ el += `<a class="post-card wiki${scrollreveal(' ')}" 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
22
  el += `<div class="post-list wiki filter">`
23
- el += `<a class="post-card wiki${scrollreveal(' ')}" href="${url_for(proj.homepage?.path || '/')}">`
23
+ el += `<a class="post-card wiki${scrollreveal(' ')}" href="${pretty_url(proj.homepage?.path || '/')}">`
24
24
  el += partial(proj)
25
25
  el += `</a>`
26
26
  el += `</div>`
@@ -1,7 +1,7 @@
1
1
  <%# 笔记本列表页主体部分 %>
2
2
  <% for (const notebook of Object.values(theme.notebooks.tree)) { %>
3
3
  <div class="post-list wiki">
4
- <a class="post-card wiki<%= scrollreveal(' ') %>" href="<%= url_for(notebook.base_dir) %>">
4
+ <a class="post-card wiki<%= scrollreveal(' ') %>" href="<%= pretty_url(notebook.base_dir) %>">
5
5
  <%- include('_partial/main/notebook/notebook_card', { notebook: notebook }) %>
6
6
  </a>
7
7
  </div>
package/layout/notes.ejs CHANGED
@@ -3,7 +3,7 @@
3
3
  <% page.posts.each(post => { %>
4
4
  <a
5
5
  class="post-card<%= scrollreveal(' ') %> post"
6
- href="<%= url_for(post.link || post.path) %><%= page.activeTag ? `?tag=${page.activeTag}` : '' %>"
6
+ href="<%= pretty_url(post.link || post.path) %><%= page.activeTag ? `?tag=${page.activeTag}` : '' %>"
7
7
  >
8
8
  <%- include('_partial/main/notebook/note_card', { note: post }) %>
9
9
  </a>
package/layout/tags.ejs CHANGED
@@ -11,7 +11,7 @@ if (page.menu_id == undefined) {
11
11
  <div class='post-list'>
12
12
  <article class='<%- scrollreveal("") %>' id='tags'>
13
13
  <% site.tags.sort('length', -1).each(function(tag){ %>
14
- <a class='tag' href="<%= url_for(tag.path) %>">
14
+ <a class='tag' href="<%= pretty_url(tag.path) %>">
15
15
  <span class='name'><%= tag.name %></span>
16
16
  </a>
17
17
  <% }) %>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hexo-theme-stellar",
3
- "version": "1.32.4",
3
+ "version": "1.33.1",
4
4
  "description": "Elegant and powerful theme for Hexo.",
5
5
  "main": "package.json",
6
6
  "scripts": {
@@ -53,7 +53,7 @@ hexo.extend.filter.register('before_generate', async () => {
53
53
  hasRun = true;
54
54
 
55
55
  // 读取主题配置开关
56
- const enabled = hexo.theme.config.plugins?.lazyload?.fix_ratio === true;
56
+ const enabled = hexo.theme.config.dependencies.lazyload?.fix_ratio === true;
57
57
 
58
58
  const generateImageRatios = require('./lib/get_image_ratios');
59
59
  const fixMarkdownImages = require('./lib/fix_image_tags');
@@ -11,11 +11,17 @@ const path = require('path')
11
11
 
12
12
  module.exports = ctx => {
13
13
 
14
- const { cache, language_switcher } = ctx.theme.config
14
+ const { cache, language_switcher, system } = ctx.theme.config
15
15
  const warning = function(...args) {
16
16
  ctx.log.warn(`Since ${args[0]} is turned on, the ${args[1]} is disabled to avoid potential hazards.`)
17
17
  }
18
18
 
19
+ if (system.override_pretty_urls !== false) {
20
+ // 强制修改 pretty_urls 配置项
21
+ ctx.config.pretty_urls.trailing_index = false
22
+ ctx.config.pretty_urls.trailing_html = false
23
+ }
24
+
19
25
  if (cache && cache.enable && language_switcher) {
20
26
  warning('language_switcher', 'caching')
21
27
  cache.enable = false
@@ -0,0 +1,25 @@
1
+ // scripts/override-page-generator.js
2
+
3
+ hexo.extend.generator.register('page', function (locals) {
4
+ return locals.pages.map(page => {
5
+ const path = (
6
+ page.path.endsWith('.html') && !page.path.endsWith('/index.html')
7
+ )
8
+ ? page.path.replace(/\.html$/, '/index.html')
9
+ : page.path;
10
+
11
+ const layout = (
12
+ page.layout === false ||
13
+ page.layout === 'false' ||
14
+ typeof page.layout === 'undefined'
15
+ ) ? false : page.layout;
16
+
17
+ const isRawOutput = /\.(txt|json|xml|js|css)$/.test(path);
18
+
19
+ return {
20
+ path,
21
+ layout,
22
+ data: isRawOutput ? page.content : page
23
+ };
24
+ });
25
+ });
@@ -13,6 +13,7 @@ hexo.extend.helper.register('json_ld', function(args) {
13
13
  const structured_data = this.theme.structured_data;
14
14
  const authorEmail = config.email;
15
15
  const authorImage = config.avatar || (authorEmail ? this.gravatar(authorEmail) : null);
16
+ const isPage = page.layout == 'page';
16
17
 
17
18
  const author = {
18
19
  '@type': 'Person',
@@ -45,10 +46,10 @@ hexo.extend.helper.register('json_ld', function(args) {
45
46
  headline: page.title,
46
47
  mainEntityOfPage: {
47
48
  '@type': 'WebPage',
48
- '@id': this.url_for(page.permalink)
49
+ '@id': this.pretty_url(page.permalink)
49
50
  },
50
51
  publisher,
51
- url: this.url_for(page.permalink)
52
+ url: this.pretty_url(page.permalink)
52
53
  };
53
54
 
54
55
  if (page.tags && page.tags.length > 0) {
@@ -69,9 +70,9 @@ hexo.extend.helper.register('json_ld', function(args) {
69
70
  schema.thumbnailUrl = page.cover || page.banner;
70
71
  schema.image = images;
71
72
 
72
- } else if (this.is_page() || this.is_home()) {
73
+ } else if (isPage || this.is_home()) {
73
74
 
74
- const url = this.is_home() ? config.url : this.url_for(page.permalink);
75
+ const url = this.is_home() ? config.url : this.pretty_url(page.permalink);
75
76
  schema = {
76
77
  '@context': 'https://schema.org',
77
78
  '@type': 'Website',
@@ -0,0 +1,22 @@
1
+ 'use strict';
2
+
3
+ hexo.extend.helper.register('pretty_url', function (path = '') {
4
+ let url = this.url_for(path);
5
+
6
+ // 替换 /index.html → /
7
+ url = url.replace(/\/index\.html$/, '/');
8
+
9
+ // 替换 /about.html → /about/
10
+ url = url.replace(/\.html$/, '/');
11
+
12
+ // 如果没有扩展名,并且不以 / 结尾,补一个 /
13
+ const hasExtension = /\.[a-zA-Z0-9]+$/.test(url);
14
+ if (!hasExtension && !url.endsWith('/')) {
15
+ url += '/';
16
+ }
17
+
18
+ // 去除多余斜杠(避免 // 出现,但保留://协议部分)
19
+ url = url.replace(/([^:]\/)\/+/g, '$1');
20
+
21
+ return url;
22
+ });
@@ -45,6 +45,8 @@ hexo.extend.tag.register('hashtag', require('./lib/hashtag')(hexo))
45
45
  hexo.extend.tag.register('okr', require('./lib/okr')(hexo), {ends: true})
46
46
  hexo.extend.tag.register('audio', require('./lib/audio')(hexo))
47
47
  hexo.extend.tag.register('video', require('./lib/video')(hexo))
48
+ hexo.extend.tag.register('rating', require('./lib/rating')(hexo))
49
+ hexo.extend.tag.register('vote', require('./lib/vote')(hexo))
48
50
 
49
51
  // read 阅读类
50
52
  hexo.extend.tag.register('reel', require('./lib/read/reel')(hexo), true)
@@ -23,7 +23,7 @@ module.exports = ctx => function(args) {
23
23
  var el = ''
24
24
  el += `<div class="tag-plugin albums-wrap">`
25
25
  if (api) {
26
- el += `<div class="data-service ds-friends" api="${api}"><div class="tag-plugin gallery grid-box" layout="grid" ratio="square" ${ctx.args.joinTags(args, ['size']).join(' ')}></div></div>`
26
+ el += `<div class="data-service ds-friends" data-api="${api}"><div class="tag-plugin gallery grid-box" layout="grid" ratio="square" ${ctx.args.joinTags(args, ['size']).join(' ')}></div></div>`
27
27
  } else if (args.group) {
28
28
  const links = ctx.theme.config.links || {}
29
29
  el += `<div class="tag-plugin gallery grid-box" layout="grid" ratio="square" ${ctx.args.joinTags(args, ['size']).join(' ')}>`
@@ -410,7 +410,7 @@ module.exports = ctx => function(args, content) {
410
410
  let urlTarget = cell['link'].includes('://') ? ' target="_blank" rel="external nofollow noopener noreferrer"' : ''
411
411
  let linkFrom = cell['from'] || 'QQ小程序'
412
412
  el += `
413
- <a class="link-card rich" href="${cell['link']}"${urlTarget} api="${ctx.theme.config.tag_plugins.chat?.api + '?url=' + cell['link']}" cardlink autofill="title,icon,desc">
413
+ <a class="link-card rich" href="${cell['link']}"${urlTarget} data-api="${ctx.theme.config.tag_plugins.chat?.api + '?url=' + cell['link']}" cardlink autofill="title,icon,desc">
414
414
  <div class="top">
415
415
  <span class="title">${cell['link']}</span>
416
416
  </div>
@@ -19,7 +19,7 @@ module.exports = ctx => function(args) {
19
19
 
20
20
  var el = `<div class="tag-plugin ${args.posts ? 'users-posts-wrap' : 'users-wrap'}">`
21
21
  if (api) {
22
- el += `<div class="data-service ds-friends${args.posts ? '_and_posts' : ''}" ${ctx.args.joinTags(args, ['size']).join(' ')} api="${api}"><div class="grid-box"></div></div>`
22
+ el += `<div class="data-service ds-friends${args.posts ? '_and_posts' : ''}" ${ctx.args.joinTags(args, ['size']).join(' ')} data-api="${api}"><div class="grid-box"></div></div>`
23
23
  } else if (args.group) {
24
24
  const links = ctx.theme.config.links || {}
25
25
  el += '<div class="grid-box">'
@@ -36,7 +36,7 @@ module.exports = ctx => function(args) {
36
36
  }
37
37
  el += ' cardlink'
38
38
  if (args.api) {
39
- el += ` api="${args.api}"`
39
+ el += ` data-api="${args.api}"`
40
40
  }
41
41
  el += ' autofill="'
42
42
  el += autofill.join(',')
@@ -23,7 +23,7 @@ module.exports = ctx => function(args) {
23
23
  var el = ''
24
24
  el += `<div class="tag-plugin posters-wrap">`
25
25
  if (api) {
26
- el += `<div class="data-service ds-friends" api="${api}"><div class="tag-plugin gallery grid-box" layout="grid" ratio="square" ${ctx.args.joinTags(args, ['size']).join(' ')}></div></div>`
26
+ el += `<div class="data-service ds-friends" data-api="${api}"><div class="tag-plugin gallery grid-box" layout="grid" ratio="square" ${ctx.args.joinTags(args, ['size']).join(' ')}></div></div>`
27
27
  } else if (args.group) {
28
28
  const links = ctx.theme.config.links || {}
29
29
  el += `<div class="tag-plugin gallery grid-box" layout="grid" ratio="portrait" ${ctx.args.joinTags(args, ['size']).join(' ')}>`
@@ -0,0 +1,32 @@
1
+ /**
2
+ * rating.js v1.0 | https://github.com/xaoxuu/hexo-theme-stellar/
3
+ * 格式与官方标签插件一致使用空格分隔,中括号内的是可选参数(中括号不需要写出来)
4
+ *
5
+ * rating:
6
+ * {% rating id %}
7
+ *
8
+ */
9
+
10
+ 'use strict'
11
+
12
+ module.exports = ctx => function (args) {
13
+ args = ctx.args.map(args, ['id', 'icon'], ['title'])
14
+
15
+ const api = ctx.theme.config.data_services.rating.api
16
+ const id = args.id || 'default'
17
+
18
+ const star = ctx.utils.icon(args.icon || 'rating:star')
19
+ let el = `<div class="tag-plugin ds-rating" data-api="${api}" data-api="${api}" data-id="${id}">`
20
+ if (args.title) {
21
+ el += `<div class="header"><span>${args.title}</span></div>`
22
+ }
23
+ el += `<div class="body">`
24
+ for (let i = 1; i <= 5; i++) {
25
+ el += `<button class="star" data-value="${i}">${star}</button>`
26
+ }
27
+ el += `<span class="avg">(0.0)</span>`
28
+ el += `</div>`
29
+ el += `<div class="footer"><span class="count">0</span><span class="suffix">人已评分</span></div>`
30
+ el += `</div>`
31
+ return el.trim()
32
+ }
@@ -20,7 +20,7 @@ module.exports = ctx => function(args) {
20
20
  var el = '<div class="tag-plugin sites-wrap">'
21
21
  if (api) {
22
22
  el += '<div class="data-service ds-sites"'
23
- el += ' api="' + api + '"'
23
+ el += ' data-api="' + api + '"'
24
24
  el += '>'
25
25
  el += '<div class="grid-box"></div>'
26
26
  el += '</div>'
@@ -36,13 +36,14 @@ function layoutNodeContent(ctx, content) {
36
36
 
37
37
  module.exports = ctx => function(args, content = '') {
38
38
  args = ctx.args.map(args, ['api', 'user', 'type', 'limit', 'hide', 'avatar'])
39
+ args['data-api'] = args.api
39
40
  var el = ''
40
41
  if (!args.type) {
41
42
  args.type = 'timeline'
42
43
  }
43
44
  if (args.api && args.api.length > 0) {
44
45
  el += `<div class="tag-plugin timeline data-service ds-${args.type}"`
45
- el += ' ' + ctx.args.joinTags(args, ['api', 'user', 'limit', 'hide', 'avatar']).join(' ')
46
+ el += ' ' + ctx.args.joinTags(args, ['data-api', 'user', 'limit', 'hide', 'avatar']).join(' ')
46
47
  el += '>'
47
48
  } else {
48
49
  el += '<div class="tag-plugin timeline">'
@@ -0,0 +1,28 @@
1
+ /**
2
+ * vote.js v1.0 | https://github.com/xaoxuu/hexo-theme-stellar/
3
+ * 格式与官方标签插件一致使用空格分隔,中括号内的是可选参数(中括号不需要写出来)
4
+ *
5
+ * vote:
6
+ * {% vote id %}
7
+ *
8
+ */
9
+
10
+ 'use strict'
11
+
12
+ module.exports = ctx => function (args) {
13
+ args = ctx.args.map(args, ['id', 'yes', 'no'], ['title'])
14
+
15
+ const api = ctx.theme.config.data_services.vote.api
16
+ const id = args.id || 'default'
17
+
18
+ var el = `<div class="tag-plugin ds-vote" data-api="${api}" data-id="${id}">`
19
+ if (args.title) {
20
+ el += `<div class="header"><span>${args.title}</span></div>`
21
+ }
22
+ el += `<div class="body">`
23
+ el += `<button class="vote-up">${ctx.utils.icon(args.yes || 'vote:thumbsup')} <span class="up">0</span></button>`
24
+ el += `<button class="vote-down">${ctx.utils.icon(args.no || 'vote:thumbsdown')} <span class="down">0</span></button>`
25
+ el += `</div>`
26
+ el += `</div>`
27
+ return el.trim()
28
+ }
@@ -4,6 +4,7 @@ button
4
4
  outline: none
5
5
  disable-select()
6
6
  cursor: pointer
7
+ background: none
7
8
 
8
9
  a.button
9
10
  font-weight: 500
@@ -44,6 +44,8 @@
44
44
  margin-top: var(--gap-p)
45
45
  margin-bottom: var(--gap-p)
46
46
  iframe
47
+ margin-left: auto
48
+ margin-right: auto
47
49
  display: block
48
50
 
49
51
  // titles
@@ -91,6 +91,8 @@
91
91
 
92
92
  p>img, .tag-plugin.image .image-bg
93
93
  border-radius: $border-image-l
94
+ >img
95
+ border-radius: $border-image-l
94
96
 
95
97
 
96
98
  .l_body[type=story] .md-text.content>blockquote, .md-text.content .tag-plugin.blockquote
@@ -35,14 +35,14 @@
35
35
  z-index: 1
36
36
  trans1 all
37
37
  &:hover
38
- background: var(--bg-a100)
38
+ background: var(--bg-a50)
39
39
  &.active, &:hover
40
40
  color: var(--text)
41
41
  &.active
42
42
  background: var(--bg-a60)
43
43
  @media (prefers-color-scheme: dark)
44
44
  background: rgba(white, 0.25)
45
- box-shadow: $boxshadow-button
45
+ box-shadow: 0 0 1px rgba(0, 0, 0, 0.04), 0 0 2px rgba(0, 0, 0, 0.04), 0 0 4px rgba(0, 0, 0, 0.08)
46
46
  cursor default
47
47
  pointer-events: none
48
48
  backdrop-filter: saturate(300%)
@@ -22,6 +22,7 @@
22
22
  img
23
23
  display: block
24
24
  object-fit: cover
25
+ border-radius: $border-image
25
26
  .image-download
26
27
  position: absolute
27
28
  bottom: 8px
@@ -0,0 +1,39 @@
1
+ .tag-plugin.ds-rating
2
+ text-align: center
3
+ .tag-plugin.ds-rating .header
4
+ margin: .5rem
5
+ font-weight: 500
6
+ color: var(--text)
7
+ .tag-plugin.ds-rating .body
8
+ display: flex
9
+ align-items: center
10
+ justify-content: center
11
+ button
12
+ color: var(--text-p1)
13
+ font-size: 1rem
14
+ padding: 0
15
+ border-radius: $border-button
16
+ display: flex
17
+ svg
18
+ font-size: 1.5em
19
+ margin: 4px
20
+ img
21
+ margin: 4px
22
+ trans1 all
23
+ color: var(--theme)
24
+ opacity: 0.2
25
+ &:hover,&.hover,&.preview
26
+ opacity: 1
27
+ span
28
+ line-height: 1
29
+ font-size: 1em
30
+ margin: 4px
31
+
32
+ .tag-plugin.ds-rating .footer
33
+ margin: .5rem
34
+ color: var(--text-p3)
35
+ font-weight: 500
36
+ font-size: $fs-12
37
+
38
+ .tag-plugin.ds-rating.rated
39
+ pointer-events: none
@@ -102,7 +102,7 @@
102
102
  .tag-plugin.copy
103
103
  width: 240px
104
104
 
105
- .tag-plugin.timeline[api]
105
+ .tag-plugin.timeline[data-api]
106
106
  a.body
107
107
  display: block
108
108
  color: var(--text-p1)
@@ -112,7 +112,7 @@
112
112
  font-size: var(--fsp)
113
113
 
114
114
 
115
- .tag-plugin.timeline[api] .body
115
+ .tag-plugin.timeline[data-api] .body
116
116
  p.title
117
117
  font-weight: 700
118
118
  margin: 0.5rem 0 0.75rem
@@ -149,10 +149,10 @@
149
149
  pre code
150
150
  font-size: $fs-13
151
151
 
152
- aside .tag-plugin.timeline[api] .body .lazy-box
152
+ aside .tag-plugin.timeline[data-api] .body .lazy-box
153
153
  border-radius: $border-image-s
154
154
 
155
- .tag-plugin.timeline[api] .body .footer
155
+ .tag-plugin.timeline[data-api] .body .footer
156
156
  margin: 0 0 -0.5rem
157
157
  padding: 0.5rem 0 1rem
158
158
  user-select: none
@@ -173,7 +173,7 @@ aside .tag-plugin.timeline[api] .body .lazy-box
173
173
  .left+.right
174
174
  margin-left: 4px
175
175
 
176
- .tag-plugin.timeline[api] .body .footer
176
+ .tag-plugin.timeline[data-api] .body .footer
177
177
  .item
178
178
  border-width: 1px
179
179
  border-style: solid