hexo-theme-stellar 1.17.1 → 1.18.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.
Files changed (41) hide show
  1. package/_config.yml +35 -28
  2. package/_data/widgets.yml +11 -15
  3. package/layout/_partial/sidebar/header.ejs +4 -4
  4. package/layout/_partial/sidebar/index.ejs +13 -7
  5. package/layout/_partial/widgets/search.ejs +14 -5
  6. package/layout/index.ejs +1 -1
  7. package/layout/wiki.ejs +2 -2
  8. package/package.json +1 -1
  9. package/scripts/generators/search.js +93 -87
  10. package/scripts/tags/{border.js → ablock.js} +8 -10
  11. package/scripts/tags/{split.js → grid.js} +5 -5
  12. package/scripts/tags/note.js +5 -7
  13. package/scripts/tags/poetry.js +4 -5
  14. package/scripts/tags/quot.js +8 -4
  15. package/scripts/tags/tag.js +35 -0
  16. package/scripts/tags/toc.js +2 -2
  17. package/source/css/_common/highlight.styl +0 -3
  18. package/source/css/_custom.styl +13 -27
  19. package/source/css/_defines/theme.styl +47 -34
  20. package/source/css/_layout/md.styl +6 -4
  21. package/source/css/_layout/partial/paginator.styl +2 -1
  22. package/source/css/_layout/partial/related.styl +1 -1
  23. package/source/css/_layout/sidebar/header.styl +2 -2
  24. package/source/css/_layout/tag-plugins/common.styl +51 -65
  25. package/source/css/_layout/tag-plugins/folding.styl +10 -11
  26. package/source/css/_layout/tag-plugins/{split.styl → grid.styl} +4 -4
  27. package/source/css/_layout/tag-plugins/link.styl +1 -1
  28. package/source/css/_layout/tag-plugins/mark.styl +2 -2
  29. package/source/css/_layout/tag-plugins/navbar.styl +1 -1
  30. package/source/css/_layout/tag-plugins/note.styl +3 -1
  31. package/source/css/_layout/tag-plugins/poetry.styl +26 -25
  32. package/source/css/_layout/tag-plugins/quot.styl +47 -58
  33. package/source/css/_layout/tag-plugins/tag.styl +13 -0
  34. package/source/css/_layout/widgets/ghuser.styl +19 -15
  35. package/source/css/_layout/widgets/search.styl +101 -1
  36. package/source/css/_layout/widgets/toc_common.styl +1 -1
  37. package/source/css/_plugins/comments/twikoo.styl +0 -1
  38. package/source/css/_plugins/index.styl +0 -3
  39. package/source/js/plugins/weibo.js +116 -0
  40. package/source/js/search/local-search.js +6 -21
  41. package/source/css/_plugins/search/local-search.styl +0 -89
@@ -1,62 +1,66 @@
1
1
  .md-text .tag-plugin.quot
2
2
  text-align: center
3
- position: relative
4
3
  align-items: center
5
- max-width 400px
6
- .md-text .tag-plugin.quot:not(span)
7
- display: inline-flex
8
- align-self: center
9
- border-bottom: none
10
- font-weight: 700
11
- &:first-child
12
- margin-top: 1.5rem
13
- a.headerlink:before
14
- content: ''
15
- padding: 16px 24px 8px 24px
16
- @media screen and (max-width: $device-mobile)
17
- padding: 16px 20px 8px
18
- line-height: 1.2
4
+ display: flex
5
+ flex-direction: column
6
+
7
+ .content
8
+ display: flex
9
+ align-items: center
10
+ border-bottom: none
11
+ font-weight: 700
12
+ &:first-child
13
+ margin-top: 1.5rem
14
+ a.headerlink:before
15
+ content: ''
16
+ padding: 16px 24px 8px 24px
17
+ @media screen and (max-width: $device-mobile)
18
+ padding: 16px 20px 8px
19
+ line-height: 1.2
19
20
 
21
+ .md-text .tag-plugin.quot .content
22
+ max-width 400px
23
+ position: relative
20
24
  // override
21
- .md-text.content
22
- .quot:not(span)
23
- color: var(--text-p0)
24
- h1.quot
25
+ .tag-plugin.quot
26
+ h1
25
27
  font-size: $fs-h1
26
28
  font-weight: 900
27
29
  padding: 20px 32px 12px 32px
28
30
  @media screen and (max-width: $device-mobile)
29
31
  padding: 20px 24px 12px
30
- h2.quot,h3.quot,h4.quot,h5.quot,h6.quot
32
+ h2,h3,h4,h5,h6
31
33
  font-size: $fs-h3
32
- p.quot
34
+ p
33
35
  font-size: $fs-h4
36
+ color: var(--text-p0)
34
37
 
35
38
  // type=text
36
- .md-text .tag-plugin.quot[type=text]:not(span)
37
- &:before,&:after
38
- content: ""
39
- position: absolute
40
- width: 8px
41
- height: 14px
42
- &:before
43
- top: 8px
44
- left: 0
45
- border-top: 6px solid $color-accent
46
- border-left: 6px solid $color-accent
47
- &:after
48
- right: 0
49
- bottom: 0
50
- border-right: 6px solid $color-accent
51
- border-bottom: 6px solid $color-accent
52
- .md-text.content h1.quot[type=text]
53
- &:before,&:after
54
- width: 12px
55
- height: 20px
56
- border-width: 8px
39
+ .md-text .tag-plugin.quot
40
+ .content[type=text]
41
+ &:before,&:after
42
+ content: ""
43
+ position: absolute
44
+ width: 8px
45
+ height: 14px
46
+ &:before
47
+ top: 8px
48
+ left: 0
49
+ border-top: 6px solid $color-accent
50
+ border-left: 6px solid $color-accent
51
+ &:after
52
+ right: 0
53
+ bottom: 0
54
+ border-right: 6px solid $color-accent
55
+ border-bottom: 6px solid $color-accent
56
+ h1.content[type=text]
57
+ &:before,&:after
58
+ width: 12px
59
+ height: 20px
60
+ border-width: 8px
57
61
 
58
62
  // type=icon
59
- .md-text .tag-plugin.quot[type=icon]:not(span)
63
+ .md-text .tag-plugin.quot .content[type=icon]
60
64
  .icon
61
65
  height: 1.5em
62
66
  display: inline-block
@@ -67,18 +71,3 @@
67
71
  margin-right: .5rem
68
72
  &.suffix
69
73
  margin-left: .5rem
70
-
71
- // inline quot
72
- .md-text span.tag-plugin.quot
73
- font-weight: 500
74
- &:before,&:after
75
- color: $color-accent
76
- font-weight: 900
77
- &:before
78
- content: "「"
79
- margin-left: -0.125em
80
- margin-right: 0.125em
81
- &:after
82
- content: "」"
83
- margin-left: 0.125em
84
- margin-right: -0.125em
@@ -0,0 +1,13 @@
1
+ .md-text .tag-plugin.tag
2
+ padding: 0px 4px
3
+ border-radius: 2px
4
+ background: var(--theme-bg1)
5
+ color: var(--text-p2)
6
+ margin: 2px 0
7
+ display: inline-block
8
+ font-size: $fs-14
9
+ trans2 background color
10
+ &:hover
11
+ background: var(--text-p2)
12
+ color: var(--theme-bg1)
13
+
@@ -52,21 +52,25 @@
52
52
  .menu
53
53
  margin-bottom: 0
54
54
  background: none
55
- a:hover
56
- box-shadow: none
57
- background: var(--block)
58
- a.active
59
- box-shadow: none
60
- position: relative
61
- &:after
62
- content: ''
63
- position: absolute
64
- height: 3px
65
- bottom: 0
66
- width: 32px
67
- left: 'calc(50% - 0.5 * %s)' % @width
68
- border-radius: 4px
69
- background: $color-theme
55
+ border: 0
56
+ a
57
+ margin: 0
58
+ &.active
59
+ box-shadow: none
60
+ position: relative
61
+ background: none
62
+ &:after
63
+ content: ''
64
+ position: absolute
65
+ height: 3px
66
+ bottom: 0
67
+ width: 32px
68
+ left: 'calc(50% - 0.5 * %s)' % @width
69
+ border-radius: 4px
70
+ background: $color-theme
71
+ &:hover
72
+ box-shadow: none
73
+ background: var(--block)
70
74
 
71
75
  .buttons
72
76
  margin: 1rem 0
@@ -1,3 +1,103 @@
1
1
  .widgets .widget-wrapper.search
2
- margin-top: 0
2
+ margin-top: 1rem
3
3
  margin-bottom: 0
4
+
5
+ .search-wrapper
6
+ width: 100%
7
+ >.search-form
8
+ position: sticky
9
+ top: 1rem
10
+ display: flex
11
+ flex-direction: row
12
+ align-items: center
13
+ .search-input
14
+ width: 100%
15
+ padding: 0.5rem
16
+ line-height: 1
17
+ box-sizing: border-box
18
+ border-radius: $border-block
19
+ background-color: var(--card)
20
+ color: var(--text-p0)
21
+ border: 1px solid var(--block-border)
22
+ &:focus
23
+ trans1 border-color
24
+
25
+ &.noresult
26
+ .search-input
27
+ &:focus
28
+ border: 1px solid $c-red
29
+ .search-icon
30
+ color: $c-red
31
+
32
+ .search-no-result
33
+ display: none
34
+ margin: 1em auto
35
+ color: var(--text-p1)
36
+ text-align: center
37
+ font-size: $fs-14
38
+ padding: 2rem
39
+ background: var(--block)
40
+ border-radius: $border-block
41
+
42
+ #search-result
43
+ ul.search-result-list
44
+ padding: 0
45
+ margin: 0
46
+ list-style-type: none
47
+ li
48
+ margin: 1em auto
49
+ &:hover
50
+ .search-result-title
51
+ color: $color-hover
52
+ .search-result-title
53
+ color: var(--text-p1)
54
+ font-weight: 700
55
+ line-height: 1.2
56
+
57
+ .search-result-content
58
+ overflow: hidden
59
+ color: var(--text-p3)
60
+ margin: .4em auto
61
+ max-height: 13em
62
+ text-align: justify
63
+ font-size: $fs-12
64
+ line-height: 1.2
65
+ display: -webkit-box
66
+ -webkit-box-orient: vertical
67
+ overflow: hidden
68
+ -webkit-line-clamp: 3
69
+
70
+ .search-keyword
71
+ border-bottom: 1px dashed $color-hover
72
+ color: $color-hover
73
+ font-weight: bold
74
+
75
+
76
+
77
+ .search-wrapper.noresult
78
+ .search-no-result
79
+ display: block
80
+
81
+ .widget-wrapper
82
+ .search-form
83
+ top: 0
84
+ background: var(--site-bg)
85
+ .search-input
86
+ margin-top: 1rem
87
+ margin-bottom: -1rem
88
+ padding-left: 1.75rem
89
+ .search-icon
90
+ margin-top: 1rem
91
+ margin-bottom: -1rem
92
+ position: absolute
93
+ margin-left: 0.5rem
94
+ left: 0
95
+ pointer-events: none
96
+ color: var(--text-p2)
97
+
98
+ #search-result,.search-no-result
99
+ margin-top: 2rem
100
+
101
+ .widget-wrapper:not(:first-child)
102
+ .search-wrapper
103
+ margin-top: -1rem
@@ -66,6 +66,6 @@
66
66
  &:hover
67
67
  background: var(--block-hover)
68
68
  &.active
69
- color: var(--theme-highlight) !important
69
+ color: $color-theme !important
70
70
  &:before
71
71
  visibility: visible
@@ -110,7 +110,6 @@ set_darkmode_comments()
110
110
  .cmt-body.twikoo
111
111
  --twikoo-lighttext: #f2b94b;
112
112
  --twikoo-secondtext: #a1a2b8;
113
- --twikoo-emoji-background: darken($dark-block, 1);
114
113
  --twikoo-theme: #409eff;
115
114
 
116
115
  if hexo-config('style.darkmode') == 'auto'
@@ -8,9 +8,6 @@ if hexo-config('plugins.scrollreveal.enable')
8
8
  if hexo-config('plugins.fancybox.enable')
9
9
  @import 'fancybox'
10
10
 
11
- // 搜索
12
- if hexo-config('search.service') == 'local_search'
13
- @import 'search/local-search'
14
11
 
15
12
  // 评论
16
13
  if hexo-config('comments.service') == 'beaudar'
@@ -0,0 +1,116 @@
1
+ const weibojs = {
2
+ requestAPI: (url, callback, timeout) => {
3
+ let retryTimes = 5;
4
+ function request() {
5
+ return new Promise((resolve, reject) => {
6
+ let status = 0; // 0 等待 1 完成 2 超时
7
+ let timer = setTimeout(() => {
8
+ if (status === 0) {
9
+ status = 2;
10
+ timer = null;
11
+ reject('请求超时');
12
+ if (retryTimes == 0) {
13
+ timeout();
14
+ }
15
+ }
16
+ }, 5000);
17
+ fetch(url).then(function(response) {
18
+ if (status !== 2) {
19
+ clearTimeout(timer);
20
+ resolve(response);
21
+ timer = null;
22
+ status = 1;
23
+ }
24
+ if (response.ok) {
25
+ return response.json();
26
+ }
27
+ throw new Error('Network response was not ok.');
28
+ }).then(function(data) {
29
+ retryTimes = 0;
30
+ callback(data);
31
+ }).catch(function(error) {
32
+ if (retryTimes > 0) {
33
+ retryTimes -= 1;
34
+ setTimeout(() => {
35
+ request();
36
+ }, 5000);
37
+ } else {
38
+ timeout();
39
+ }
40
+ });
41
+ });
42
+ }
43
+ request();
44
+ },
45
+ layoutDiv: (cfg) => {
46
+ const el = $(cfg.el)[0];
47
+ $(el).append('<div class="loading-wrap"><svg xmlns="http://www.w3.org/2000/svg" width="2rem" height="2rem" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"><g fill="none" stroke="currentColor" stroke-linecap="round" stroke-width="2"><path stroke-dasharray="60" stroke-dashoffset="60" stroke-opacity=".3" d="M12 3C16.9706 3 21 7.02944 21 12C21 16.9706 16.9706 21 12 21C7.02944 21 3 16.9706 3 12C3 7.02944 7.02944 3 12 3Z"><animate fill="freeze" attributeName="stroke-dashoffset" dur="1.3s" values="60;0"/></path><path stroke-dasharray="15" stroke-dashoffset="15" d="M12 3C16.9706 3 21 7.02944 21 12"><animate fill="freeze" attributeName="stroke-dashoffset" dur="0.3s" values="15;0"/><animateTransform attributeName="transform" dur="1.5s" repeatCount="indefinite" type="rotate" values="0 12 12;360 12 12"/></path></g></svg></div>');
48
+ weibojs.requestAPI(cfg.api, function(data) {
49
+ $(el).find('.loading-wrap').remove();
50
+ const arr = data.tweets || [];
51
+ const limit = el.getAttribute('limit');
52
+ arr.forEach((item, i) => {
53
+ if (limit && i >= limit) {
54
+ return;
55
+ }
56
+ var cell = '<div class="timenode" index="' + i + '">';
57
+ cell += '<div class="header">';
58
+ cell += '<div class="user-info">';
59
+ cell += '<img src="' + (data.user.avatar_hd || cfg.avatar) + '" onerror="javascript:this.src=\'' + cfg.avatar + '\';">';
60
+ cell += '<span>' + data.user.nick_name + '</span>';
61
+ cell += '</div>';
62
+ cell += '<p>' + item.created_at + '</p>';
63
+ cell += '</div>';
64
+ cell += '<div class="body">';
65
+ cell += '<a class="body" href="' + item.url + '" target="_blank" rel="external nofollow noopener noreferrer">';
66
+ cell += item.content;
67
+ cell += '</a>';
68
+ // cell += '</div>';
69
+ // 每条微博的右下角 转发 评论 点赞
70
+ cell += '<div class="footer">';
71
+ cell += '<div class="flex left">';
72
+ cell += '</div>';
73
+ cell += '<div class="flex right">';
74
+ cell += '<div class="item reaction repost">';
75
+ cell += '<a class="item comments last" href="' + item.url + '#issuecomment-new" target="_blank" rel="external nofollow noopener noreferrer">';
76
+ cell += '<span>' + '🔗' + ' ' + item.reposts_count + '</span>';
77
+ cell += '</a>';
78
+ cell += '</div>';
79
+ cell += '<a class="item comments last" href="' + item.url + '#issuecomment-new" target="_blank" rel="external nofollow noopener noreferrer">';
80
+ cell += '<span><svg t="1666270368054" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2528" width="200" height="200"><path d="M952 64H72C32.3 64 0 96.3 0 136v508c0 39.7 32.3 72 72 72h261l128 128c14 14 32.5 21.1 50.9 21.1s36.9-7 50.9-21.1l128-128h261c39.7 0 72-32.3 72-72V136c0.2-39.7-32.1-72-71.8-72zM222 462c-39.8 0-72-32.2-72-72s32.2-72 72-72 72 32.2 72 72-32.2 72-72 72z m290-7.7c-39.8 0-72-32.2-72-72s32.2-72 72-72 72 32.2 72 72c0 39.7-32.2 72-72 72z m290 8c-39.8 0-72-32.2-72-72s32.2-72 72-72 72 32.2 72 72c0 39.7-32.2 72-72 72z" p-id="2529"></path></svg> '
81
+ + (item.comments_count || 0) + '</span>';
82
+ cell += '</a>';
83
+ cell += '<div class="item reaction attitudes">';
84
+ cell += '<a class="item comments last" href="' + item.url + '#issuecomment-new" target="_blank" rel="external nofollow noopener noreferrer">';
85
+ cell += '<span>' + '👍' + ' ' + item.attitudes_count + '</span>';
86
+ cell += '</a>';
87
+ cell += '</div>';
88
+
89
+ cell += '</div>';
90
+ cell += '</div>';
91
+ // 右下角结束
92
+ $(el).append(cell);
93
+ });
94
+ }, function() {
95
+ $(el).find('.loading-wrap svg').remove();
96
+ $(el).find('.loading-wrap').append('<svg xmlns="http://www.w3.org/2000/svg" width="2rem" height="2rem" preserveAspectRatio="xMidYMid meet" viewBox="0 0 24 24"><g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><path stroke-dasharray="60" stroke-dashoffset="60" d="M12 3L21 20H3L12 3Z"><animate fill="freeze" attributeName="stroke-dashoffset" dur="0.5s" values="60;0"/></path><path stroke-dasharray="6" stroke-dashoffset="6" d="M12 10V14"><animate fill="freeze" attributeName="stroke-dashoffset" begin="0.6s" dur="0.2s" values="6;0"/></path></g><circle cx="12" cy="17" r="1" fill="currentColor" fill-opacity="0"><animate fill="freeze" attributeName="fill-opacity" begin="0.8s" dur="0.4s" values="0;1"/></circle></svg>');
97
+ $(el).find('.loading-wrap').addClass('error');
98
+ });
99
+ },
100
+ }
101
+
102
+ $(function () {
103
+ const els = document.getElementsByClassName('stellar-weibo-api');
104
+ for (var i = 0; i < els.length; i++) {
105
+ const el = els[i];
106
+ const api = el.getAttribute('api'); // 这个API可以返回微博的json文件
107
+ if (api == null) {
108
+ continue;
109
+ }
110
+ var cfg = new Object();
111
+ cfg.el = el;
112
+ cfg.api = api;
113
+ cfg.avatar = 'https://fastly.jsdelivr.net/gh/cdn-x/placeholder@1.0.1/avatar/round/3442075.svg';
114
+ weibojs.layoutDiv(cfg);
115
+ }
116
+ });
@@ -24,20 +24,6 @@
24
24
  /*exported searchFunc*/
25
25
  var searchFunc = function(path, filter, searchId, contentId) {
26
26
 
27
- function stripHtml(html) {
28
- html = html.replace(/<style([\s\S]*?)<\/style>/gi, "");
29
- html = html.replace(/<script([\s\S]*?)<\/script>/gi, "");
30
- html = html.replace(/<figure([\s\S]*?)<\/figure>/gi, "");
31
- html = html.replace(/<\/div>/ig, "\n");
32
- html = html.replace(/<\/li>/ig, "\n");
33
- html = html.replace(/<li>/ig, " * ");
34
- html = html.replace(/<\/ul>/ig, "\n");
35
- html = html.replace(/<\/p>/ig, "\n");
36
- html = html.replace(/<br\s*[\/]?>/gi, "\n");
37
- html = html.replace(/<[^>]+>/ig, "");
38
- return html;
39
- }
40
-
41
27
  function getAllCombinations(keywords) {
42
28
  var i, j, result = [];
43
29
 
@@ -68,18 +54,17 @@ var searchFunc = function(path, filter, searchId, contentId) {
68
54
  }
69
55
  // perform local searching
70
56
  datas.forEach(function(data) {
57
+ if (!data.title?.trim().length) { return }
58
+ if (!data.content?.trim().length) { return }
71
59
  var matches = 0;
72
- if (!data.title || data.title.trim() === "") {
73
- return;
74
- }
75
- if (filter && !data.url.includes(filter)) {
60
+ if (filter && !data.path.includes(filter)) {
76
61
  return;
77
62
  }
78
- var dataTitle = data.title.trim().toLowerCase();
63
+ var dataTitle = data.title.trim();
79
64
  var dataTitleLowerCase = dataTitle.toLowerCase();
80
- var dataContent = stripHtml(data.content.trim());
65
+ var dataContent = data.content;
81
66
  var dataContentLowerCase = dataContent.toLowerCase();
82
- var dataUrl = data.url;
67
+ var dataUrl = data.path;
83
68
  var indexTitle = -1;
84
69
  var indexContent = -1;
85
70
  var firstOccur = -1;
@@ -1,89 +0,0 @@
1
- .search-wrapper
2
- width: 100%
3
- >.search-form
4
- position: sticky
5
- top: 1rem
6
- .search-input
7
- width: 100%
8
- padding: 0.75rem 1rem
9
- line-height: 1
10
- box-sizing: border-box
11
- border-radius: $border-block
12
- background-color: var(--card)
13
- color: var(--text-p0)
14
- box-shadow: $boxshadow-button
15
- trans1 box-shadow
16
- &:hover
17
- box-shadow: 0 0 2px 0px rgba(0, 0, 0, 0.16), 0 0 8px 0px rgba(0, 0, 0, 0.08)
18
-
19
- &.noresult
20
- .search-input
21
- &:hover
22
- box-shadow: 0 0 2px 0px alpha($c-red, 0.2), 0 0 8px 0px alpha($c-red, 0.2)
23
- &:focus
24
- box-shadow: 0 0 2px 0px alpha($c-red, 0.5), 0 0 8px 0px alpha($c-red, 0.4)
25
-
26
- .search-no-result
27
- display: none
28
- margin: 1em auto
29
- color: var(--text-p1)
30
- text-align: center
31
- font-size: $fs-14
32
- padding: 2rem
33
- background: var(--block)
34
- border-radius: $border-block
35
-
36
- #search-result
37
- ul.search-result-list
38
- padding: 0
39
- margin: 0
40
- list-style-type: none
41
- li
42
- margin: 1em auto
43
- &:hover
44
- .search-result-title
45
- color: $color-hover
46
- .search-result-title
47
- background-image: none
48
- color: var(--text-p1)
49
- text-transform: capitalize
50
- font-weight: bold
51
- line-height: 1.2
52
-
53
- .search-result-content
54
- overflow: hidden
55
- color: var(--text-p3)
56
- margin: .4em auto
57
- max-height: 13em
58
- text-align: justify
59
- font-size: $fs-12
60
- line-height: 1.2
61
- display: -webkit-box
62
- -webkit-box-orient: vertical
63
- overflow: hidden
64
- -webkit-line-clamp: 3
65
-
66
- .search-keyword
67
- border-bottom: 1px dashed $color-hover
68
- color: $color-hover
69
- font-weight: bold
70
-
71
-
72
-
73
- .search-wrapper.noresult
74
- .search-no-result
75
- display: block
76
-
77
- .widget-wrapper
78
- .search-form
79
- top: 0
80
- background: var(--site-bg)
81
- .search-input
82
- margin-top: 1rem
83
- margin-bottom: -1rem
84
- #search-result,.search-no-result
85
- margin-top: 2rem
86
-
87
- .widget-wrapper:not(:first-child)
88
- .search-wrapper
89
- margin-top: -1rem