hexo-theme-stellar 1.11.0 → 1.13.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 (78) hide show
  1. package/README.md +7 -7
  2. package/_config.yml +22 -37
  3. package/_data/links.yml +7 -0
  4. package/_data/widgets.yml +30 -6
  5. package/languages/zh-CN.yml +4 -4
  6. package/languages/zh-TW.yml +4 -4
  7. package/layout/_partial/head.ejs +2 -0
  8. package/layout/_partial/main/article/read_next.ejs +16 -17
  9. package/layout/_partial/main/navbar/breadcrumb.ejs +1 -1
  10. package/layout/_partial/main/navbar/list_post.ejs +57 -34
  11. package/layout/_partial/main/post_list/post_card.ejs +25 -15
  12. package/layout/_partial/main/post_list/wiki_card.ejs +1 -1
  13. package/layout/_partial/scripts/index.ejs +1 -0
  14. package/layout/_partial/sidebar/header.ejs +2 -26
  15. package/layout/_partial/sidebar/logo.ejs +2 -2
  16. package/layout/_partial/sidebar/menu.ejs +27 -0
  17. package/layout/_partial/sidebar/widgets/ghissues.ejs +45 -0
  18. package/layout/_partial/sidebar/widgets/ghrepo.ejs +3 -3
  19. package/layout/_partial/sidebar/widgets/ghuser.ejs +4 -0
  20. package/layout/_partial/sidebar/widgets/markdown.ejs +1 -1
  21. package/layout/_partial/sidebar/widgets/recent.ejs +8 -11
  22. package/layout/_partial/sidebar/widgets/{wiki_more.ejs → related.ejs} +7 -7
  23. package/layout/_partial/sidebar/widgets/tagcloud.ejs +24 -0
  24. package/layout/_partial/sidebar/widgets/timeline.ejs +27 -0
  25. package/layout/_partial/sidebar/widgets/toc.ejs +1 -5
  26. package/layout/index.ejs +1 -1
  27. package/layout/page.ejs +19 -10
  28. package/package.json +1 -1
  29. package/scripts/events/lib/config.js +1 -1
  30. package/scripts/events/lib/doc_tree.js +3 -0
  31. package/scripts/helpers/related_posts.js +11 -39
  32. package/scripts/tags/about.js +10 -7
  33. package/scripts/tags/{grid.js → border.js} +4 -4
  34. package/scripts/tags/friends.js +36 -75
  35. package/scripts/tags/link.js +11 -9
  36. package/scripts/tags/navbar.js +1 -1
  37. package/scripts/tags/sites.js +40 -79
  38. package/scripts/tags/split.js +51 -0
  39. package/scripts/tags/timeline.js +6 -4
  40. package/source/css/_common/base.styl +2 -2
  41. package/source/css/_common/blur.styl +3 -0
  42. package/source/css/_common/device.styl +2 -0
  43. package/source/css/_common/highlight.styl +1 -1
  44. package/source/css/_common/loading.styl +16 -3
  45. package/source/css/_common/title.styl +0 -13
  46. package/source/css/_custom.styl +4 -4
  47. package/source/css/_layout/list.styl +40 -12
  48. package/source/css/_layout/main.styl +1 -1
  49. package/source/css/_layout/md.styl +1 -4
  50. package/source/css/_layout/partial/navbar.styl +1 -1
  51. package/source/css/_layout/partial/related.styl +62 -93
  52. package/source/css/_layout/sidebar/footer.styl +4 -2
  53. package/source/css/_layout/sidebar/ghrepo.styl +11 -5
  54. package/source/css/_layout/sidebar/ghuser.styl +19 -1
  55. package/source/css/_layout/sidebar/sidebar.styl +11 -96
  56. package/source/css/_layout/sidebar/toc_common.styl +5 -3
  57. package/source/css/_layout/sidebar/widgets.styl +103 -0
  58. package/source/css/_layout/tag-plugins/about.styl +21 -18
  59. package/source/css/_layout/tag-plugins/common.styl +36 -31
  60. package/source/css/_layout/tag-plugins/link.styl +41 -27
  61. package/source/css/_layout/tag-plugins/navbar.styl +10 -4
  62. package/source/css/_layout/tag-plugins/quot.styl +1 -1
  63. package/source/css/_layout/tag-plugins/split.styl +32 -0
  64. package/source/css/_layout/tag-plugins/timeline.styl +40 -14
  65. package/source/css/_plugins/comments/twikoo.styl +11 -5
  66. package/source/css/_plugins/comments/waline.styl +5 -1
  67. package/source/css/_plugins/index.styl +0 -2
  68. package/source/js/main.js +15 -9
  69. package/source/js/plugins/fcircle.js +92 -0
  70. package/source/js/plugins/friends.js +3 -2
  71. package/source/js/plugins/ghinfo.js +14 -2
  72. package/source/js/plugins/linkcard.js +124 -0
  73. package/source/js/plugins/sites.js +4 -3
  74. package/source/js/plugins/timeline.js +58 -40
  75. package/layout/_partial/plugins/comments/valine/layout.ejs +0 -19
  76. package/layout/_partial/plugins/comments/valine/script.ejs +0 -48
  77. package/scripts/tags/issues.js +0 -30
  78. package/source/css/_plugins/comments/valine.styl +0 -218
@@ -20,13 +20,15 @@
20
20
  &:before
21
21
  display: none
22
22
 
23
- .tag-plugin.timeline .timenode
23
+ .md .tag-plugin.timeline .timenode
24
24
  position: relative
25
25
  display: flex
26
26
  flex-direction: column
27
27
  align-items: flex-start
28
- max-width: 'calc(100% - %s)' % 1rem
28
+ box-sizing: border-box
29
+ max-width: 100%
29
30
  >.header, >.body
31
+ box-sizing: border-box
30
32
  max-width: @max-width
31
33
  &[highlight] .header:before
32
34
  background: $color-theme
@@ -50,6 +52,7 @@
50
52
  align-items: center
51
53
  position: relative
52
54
  margin: 0.25rem 0
55
+ font-size: $fs-12
53
56
  .user-info
54
57
  display: flex
55
58
  align-items: center
@@ -70,13 +73,14 @@
70
73
  object-fit: contain
71
74
  &:hover
72
75
  background: $color-hover
73
- p
74
- margin: 0
75
- font-size: $fs-12
76
+ &,p
76
77
  font-weight: 500
77
78
  color: var(--text-p3)
78
79
  trans1 color
79
80
  line-height: 1
81
+ p
82
+ margin: 0 !important
83
+ font-size: $fs-12 !important
80
84
  a
81
85
  color: inherit
82
86
  font-weight: inherit
@@ -109,27 +113,49 @@
109
113
  .tag-plugin.copy
110
114
  width: 240px
111
115
 
116
+ .tag-plugin.timeline[api]
117
+ &.stellar-fcircle-api .timenode:hover .header
118
+ .user-info
119
+ background: inherit
120
+ span
121
+ color: inherit
122
+ a.body
123
+ color: var(--text-p1)
124
+ trans2: transform box-shadow
125
+ line-height: 1.25
126
+ padding: 0.75rem 1rem
127
+ &:hover
128
+ transform: translateY(-1px)
129
+ box-shadow: $boxshadow-card-float
130
+
112
131
 
113
- .tag-plugin.timeline.stellar-timeline-api .body
114
- max-height: convert(hexo-config('tag_plugins.timeline.max-height'))
132
+ .tag-plugin.timeline[api] .body
115
133
  overflow: scroll
116
- p.title
134
+ p.title
117
135
  font-size: 1rem
118
136
  font-weight: 700
119
- margin: 0
120
- padding: 0.5rem 0 0.75rem
137
+ margin: 0.5rem 0 0.75rem
121
138
  line-height: 1.25
122
- border-bottom: 1px dashed var(--block-border)
139
+ &:only-child
140
+ margin-bottom: 0.5rem
141
+ font-weight: 500
123
142
  a
124
143
  color: inherit
125
144
  &:hover
126
145
  color: $color-hover
146
+ a
147
+ &:has(img):after
148
+ display: none
149
+ img
150
+ margin: 0 auto
151
+ img
152
+ margin: 0.5rem auto
127
153
  pre code
128
154
  font-size: $fs-12
129
155
 
130
- .tag-plugin.timeline.stellar-timeline-api .body .footer
156
+ .tag-plugin.timeline[api] .body .footer
157
+ margin: 0 0 -0.5rem
131
158
  padding: 0.5rem 0 1rem
132
- margin-bottom: -0.5rem
133
159
  user-select: none
134
160
  font-weight: 500
135
161
  display: flex
@@ -150,7 +176,7 @@
150
176
  font-size: $fs-12
151
177
  align-items: stretch
152
178
 
153
- .tag-plugin.timeline.stellar-timeline-api .body .footer
179
+ .tag-plugin.timeline[api] .body .footer
154
180
  .item
155
181
  border-width: 1px
156
182
  border-style: solid
@@ -106,10 +106,16 @@
106
106
  .tk-comments-no
107
107
  color: var(--text-p1);
108
108
 
109
+ set_darkmode_comments()
110
+ .cmt-body.twikoo
111
+ --twikoo-lighttext: #f2b94b;
112
+ --twikoo-secondtext: #a1a2b8;
113
+ --twikoo-emoji-background: darken($dark-block, 1);
114
+ --twikoo-theme: #409eff;
115
+
109
116
  if hexo-config('style.darkmode') == 'auto'
110
117
  @media (prefers-color-scheme: dark)
111
- .cmt-body.twikoo
112
- --twikoo-lighttext: #f2b94b;
113
- --twikoo-secondtext: #a1a2b8;
114
- --twikoo-emoji-background: darken($dark-block, 1);
115
- --twikoo-theme: #409eff;
118
+ set_darkmode_comments()
119
+
120
+ if hexo-config('style.darkmode') == 'always'
121
+ set_darkmode_comments()
@@ -1,4 +1,8 @@
1
1
  .cmt-body.waline
2
+ .wl-panel
3
+ margin: 0.5em 0 !important
4
+ .wl-meta-head
5
+ padding: 0 !important
2
6
  --waline-font-size: 0.9375rem;
3
7
  /* 常规颜色 */
4
8
  --waline-white: #fff;
@@ -6,7 +10,7 @@
6
10
  --waline-dark-grey: #666;
7
11
  /* 主题色 */
8
12
  --waline-theme-color: $color-theme;
9
- --waline-active-color: #2ecc71;
13
+ --waline-active-color: $color-hover;
10
14
  /* 布局颜色 */
11
15
  --waline-color: #444;
12
16
  --waline-bgcolor: #fff;
@@ -15,7 +15,5 @@ if hexo-config('comments.service') == 'twikoo'
15
15
  @import 'comments/twikoo'
16
16
  if hexo-config('comments.service') == 'utterances'
17
17
  @import 'comments/utterances'
18
- if hexo-config('comments.service') == 'valine'
19
- @import 'comments/valine'
20
18
  if hexo-config('comments.service') == 'waline'
21
19
  @import 'comments/waline'
package/source/js/main.js CHANGED
@@ -1,4 +1,4 @@
1
- console.log('hexo-theme-stellar:\n' + stellar.github);
1
+ console.log('\n' + '%c Stellar v' + stellar.version + ' %c\n' + stellar.github + '\n', 'color:#e8fafe;background:#03c7fa;padding:8px;border-radius:4px', 'margin-top:8px');
2
2
  // utils
3
3
  const util = {
4
4
 
@@ -217,14 +217,20 @@ if (stellar.plugins.lazyload) {
217
217
  if (stellar.plugins.stellar) {
218
218
  for (let key of Object.keys(stellar.plugins.stellar)) {
219
219
  let js = stellar.plugins.stellar[key];
220
- const els = document.getElementsByClassName('stellar-' + key + '-api');
221
- if (els != undefined && els.length > 0) {
222
- stellar.jQuery(() => {
223
- stellar.loadScript(js, { defer: true });
224
- if (key == 'timeline') {
225
- stellar.loadScript(stellar.plugins.marked);
226
- }
227
- })
220
+ if (key == 'linkcard') {
221
+ stellar.loadScript(js, { defer: true }).then(function () {
222
+ setCardLink(document.querySelectorAll('a.link-card'));
223
+ });
224
+ } else {
225
+ const els = document.getElementsByClassName('stellar-' + key + '-api');
226
+ if (els != undefined && els.length > 0) {
227
+ stellar.jQuery(() => {
228
+ stellar.loadScript(js, { defer: true });
229
+ if (key == 'timeline') {
230
+ stellar.loadScript(stellar.plugins.marked);
231
+ }
232
+ })
233
+ }
228
234
  }
229
235
  }
230
236
  }
@@ -0,0 +1,92 @@
1
+ const FCircle = {
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
+ FCircle.requestAPI(cfg.api, function(data) {
49
+ $(el).find('.loading-wrap').remove();
50
+ const arr = data.article_data || [];
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="' + (item.avatar || cfg.avatar) + '" onerror="javascript:this.src=\'' + cfg.avatar + '\';">';
60
+ cell += '<span>' + item.author + '</span>';
61
+ cell += '</div>';
62
+ cell += '<p>' + item.updated + '</p>';
63
+ cell += '</div>';
64
+ cell += '<a class="body" href="' + item.link + '" target="_blank" rel="external nofollow noopener noreferrer">';
65
+ cell += item.title;
66
+ cell += '</a>';
67
+ cell += '</div>';
68
+ $(el).append(cell);
69
+ });
70
+ }, function() {
71
+ $(el).find('.loading-wrap svg').remove();
72
+ $(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>');
73
+ $(el).find('.loading-wrap').addClass('error');
74
+ });
75
+ },
76
+ }
77
+
78
+ $(function () {
79
+ const els = document.getElementsByClassName('stellar-fcircle-api');
80
+ for (var i = 0; i < els.length; i++) {
81
+ const el = els[i];
82
+ const api = el.getAttribute('api');
83
+ if (api == null) {
84
+ continue;
85
+ }
86
+ var cfg = new Object();
87
+ cfg.el = el;
88
+ cfg.api = api;
89
+ cfg.avatar = 'https://fastly.jsdelivr.net/gh/cdn-x/placeholder@1.0.1/avatar/round/3442075.svg';
90
+ FCircle.layoutDiv(cfg);
91
+ }
92
+ });
@@ -44,7 +44,7 @@ const friendsjs = {
44
44
  },
45
45
  layout: (cfg) => {
46
46
  const el = $(cfg.el)[0];
47
- $(el).append('<div class="loading-wrap"><svg class="loading" style="vertical-align: middle;fill: currentColor;overflow: hidden;" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2709"><path d="M832 512c0-176-144-320-320-320V128c211.2 0 384 172.8 384 384h-64zM192 512c0 176 144 320 320 320v64C300.8 896 128 723.2 128 512h64z" p-id="2710"></path></svg><p></p></div>');
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
48
  friendsjs.requestAPI(cfg.api, function(data) {
49
49
  $(el).find('.loading-wrap').remove();
50
50
  const arr = data.content || data;
@@ -60,7 +60,8 @@ const friendsjs = {
60
60
  });
61
61
  }, function() {
62
62
  $(el).find('.loading-wrap svg').remove();
63
- $(el).find('.loading-wrap p').text('加载失败,请稍后重试。');
63
+ $(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>');
64
+ $(el).find('.loading-wrap').addClass('error');
64
65
  });
65
66
  },
66
67
  }
@@ -44,13 +44,25 @@ const GitHubInfo = {
44
44
  },
45
45
  layout: (cfg) => {
46
46
  const el = $(cfg.el)[0];
47
- GitHubInfo.requestAPI(cfg.api, function(data) {
48
- const arr = data.content || data;
47
+ function fill(data) {
49
48
  for (let key of Object.keys(data)) {
50
49
  $(el).find("[type=text]#" + key).text(data[key]);
51
50
  $(el).find("[type=link]#" + key).attr("href", data[key]);
52
51
  $(el).find("[type=img]#" + key).attr("src", data[key]);
53
52
  }
53
+ }
54
+ GitHubInfo.requestAPI(cfg.api, function(data) {
55
+ const idx = el.getAttribute('index');
56
+ if (idx != undefined) {
57
+ const arr = data.content || data;
58
+ if (arr && arr.length > idx) {
59
+ let obj = arr[idx];
60
+ obj['latest-tag-name'] = obj['name'];
61
+ fill(arr[idx]);
62
+ }
63
+ } else {
64
+ fill(data);
65
+ }
54
66
  }, function() {
55
67
  });
56
68
  },
@@ -0,0 +1,124 @@
1
+ // 本插件由CardLink定制而成,原项目源码: https://github.com/Lete114/CardLink
2
+
3
+ var cardLink = {};
4
+ cardLink.caches = {};
5
+ cardLink.server = 'https://api.allorigins.win/raw?url=';
6
+
7
+ /**
8
+ * Remove '/' and '/index.html'
9
+ * @param {String} params
10
+ * @returns { String }
11
+ */
12
+ function indexHandler(params) {
13
+ let path = params.replace(/(\/index\.html|\/)*$/gi, '')
14
+ if (path.length === 0) path += '/'
15
+ return path
16
+ }
17
+
18
+ /**
19
+ * Determine if it is a ['https://', 'http://', '//'] protocol
20
+ * @param {String} url Website url
21
+ * @returns {Boolean}
22
+ */
23
+ function isHttp(url) {
24
+ return /^(https?:)?\/\//g.test(url)
25
+ }
26
+
27
+ function renderer(el, obj) {
28
+ if (obj.title && obj.title.length > 0) {
29
+ el.querySelector('.title').innerHTML = obj.title;
30
+ }
31
+ if (obj.icon && obj.icon.length > 0) {
32
+ el.querySelector('.img').style = 'background-image: url("' + obj.icon + '");';
33
+ }
34
+ let desc = el.querySelector('.desc');
35
+ if (desc && obj.desc && obj.desc.length > 0) {
36
+ desc.innerHTML = obj.desc;
37
+ }
38
+ }
39
+
40
+ /**
41
+ * Get info
42
+ * @param {Element} el Element
43
+ * @param {String} html String type html
44
+ * @param {String} link Website address
45
+ */
46
+ // eslint-disable-next-line max-statements
47
+ function getInfo(el, html, link) {
48
+ try {
49
+ let title, icon, desc
50
+ const doc = new DOMParser().parseFromString(html, 'text/html')
51
+ // If there is no title, no card link is generated
52
+ title = doc.querySelector('title')
53
+ if (title) {
54
+ title = title.textContent
55
+
56
+ // Get the src of the first img tag in the body tag
57
+ let tmp = doc.querySelector('head link[rel="apple-touch-icon"]')
58
+ if (!tmp) {
59
+ tmp = doc.querySelector('head link[rel="icon"]')
60
+ }
61
+ icon = tmp && tmp.getAttribute('href')
62
+
63
+ if (/^data:image/.test(icon)) icon = ''
64
+
65
+ // If there is no src then get the site icon
66
+ if (!icon) {
67
+ const links = [].slice.call(doc.querySelectorAll('link[rel][href]'))
68
+ icon = links.find((_el) => _el.rel.includes('icon'))
69
+ icon = icon && icon.getAttribute('href')
70
+ }
71
+
72
+ desc = doc.querySelector('head meta[name="description"]')
73
+
74
+ if (desc) {
75
+ desc = desc.content;
76
+ }
77
+ // If `icon` is not the ['https://', 'http://', '//'] protocol, splice on the `origin` of the a tag
78
+ if (icon && !isHttp(icon)) icon = new URL(link).origin + icon
79
+ cardLink.caches[link] = { title, link, icon, desc }
80
+
81
+ renderer(el, cardLink.caches[link])
82
+ }
83
+ } catch (error) {
84
+ // eslint-disable-next-line no-console
85
+ console.warn('CardLink Error: Failed to parse', error)
86
+ }
87
+ }
88
+
89
+ function fetchPage(link, callback) {
90
+ fetch(link)
91
+ .then((result) => result.text())
92
+ .then(callback)
93
+ .catch((error) => {
94
+ const server = cardLink.server
95
+ // eslint-disable-next-line no-console
96
+ if (link.includes(server) || !server) return console.error('CardLink Error:', error)
97
+ fetchPage(server + link, callback)
98
+ })
99
+ }
100
+
101
+ /**
102
+ * Create card links
103
+ * @param {NodeList} nodes A collection of nodes or a collection of arrays,
104
+ * if it is an array then the array must always contain node element
105
+ */
106
+ function setCardLink(nodes) {
107
+ // If the `nodes` do not contain a `forEach` method, then the default `a[cardlink]` is used
108
+ nodes = 'forEach' in (nodes || {}) ? nodes : document.querySelectorAll('a[cardlink]')
109
+ nodes.forEach((el) => {
110
+ // If it is not a tag element then it is not processed
111
+ if (el.nodeType !== 1) return
112
+ el.removeAttribute('cardlink')
113
+ const link = el.href
114
+
115
+ const cache = cardLink.caches[link]
116
+ if (cache) return renderer(el, cache)
117
+
118
+ if (isHttp(link)) {
119
+ fetchPage(link, (html) => {
120
+ getInfo(el, html, link)
121
+ })
122
+ }
123
+ })
124
+ }
@@ -44,14 +44,14 @@ const sitesjs = {
44
44
  },
45
45
  layout: (cfg) => {
46
46
  const el = $(cfg.el)[0];
47
- $(el).append('<div class="loading-wrap"><svg class="loading" style="vertical-align: middle;fill: currentColor;overflow: hidden;" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2709"><path d="M832 512c0-176-144-320-320-320V128c211.2 0 384 172.8 384 384h-64zM192 512c0 176 144 320 320 320v64C300.8 896 128 723.2 128 512h64z" p-id="2710"></path></svg><p></p></div>');
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
48
  sitesjs.requestAPI(cfg.api, function(data) {
49
49
  $(el).find('.loading-wrap').remove();
50
50
  const arr = data.content;
51
51
  arr.forEach((item, i) => {
52
52
  var cell = '<div class="site-card">';
53
53
  cell += '<a class="card-link" target="_blank" rel="external nofollow noopener noreferrer" href="' + item.url + '">';
54
- cell += '<img src="' + (item.screenshot || ('https://image.thum.io/get/width/1024/crop/768/' + item.url)) + '" onerror="javascript:this.src=\'' + cfg.screenshot + '\';"/>';
54
+ cell += '<img src="' + (item.screenshot || ('https://screenshot-api.xaoxuu.com/api?url=' + item.url + '&width=1280&height=720')) + '" onerror="javascript:this.src=\'' + cfg.screenshot + '\';"/>';
55
55
  cell += '<div class="info">';
56
56
  cell += '<img src="' + (item.avatar || cfg.avatar) + '" onerror="javascript:this.src=\'' + cfg.avatar + '\';"/>';
57
57
  cell += '<span class="title">' + item.title + '</span>';
@@ -63,7 +63,8 @@ const sitesjs = {
63
63
  });
64
64
  }, function() {
65
65
  $(el).find('.loading-wrap svg').remove();
66
- $(el).find('.loading-wrap p').text('加载失败,请稍后重试。');
66
+ $(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>');
67
+ $(el).find('.loading-wrap').addClass('error');
67
68
  });
68
69
  },
69
70
  }
@@ -54,20 +54,30 @@ const StellarTimeline = {
54
54
  },
55
55
  layoutDiv: (cfg) => {
56
56
  const el = $(cfg.el)[0];
57
- $(el).append('<div class="loading-wrap"><svg class="loading" style="vertical-align: middle;fill: currentColor;overflow: hidden;" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2709"><path d="M832 512c0-176-144-320-320-320V128c211.2 0 384 172.8 384 384h-64zM192 512c0 176 144 320 320 320v64C300.8 896 128 723.2 128 512h64z" p-id="2710"></path></svg><p></p></div>');
57
+ $(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>');
58
58
  StellarTimeline.requestAPI(cfg.api, function(data) {
59
59
  $(el).find('.loading-wrap').remove();
60
- const user = el.getAttribute('user');
60
+ const query = new URL(cfg.api).search;
61
61
  const arr = data.content || data;
62
+ var users = [];
63
+ const filter = el.getAttribute('user');
64
+ if (filter && filter.length > 0) {
65
+ users = filter.split(",");
66
+ }
67
+ var hide = [];
68
+ const hideStr = el.getAttribute('hide');
69
+ if (hideStr && hideStr.length > 0) {
70
+ hide = hideStr.split(",");
71
+ }
62
72
  arr.forEach((item, i) => {
63
- if (item.user && item.user.login && user && user.length > 0) {
64
- if (!user.includes(item.user.login)) {
73
+ if (item.user && item.user.login && users.length > 0) {
74
+ if (!users.includes(item.user.login)) {
65
75
  return;
66
76
  }
67
77
  }
68
78
  var cell = '<div class="timenode" index="' + i + '">';
69
79
  cell += '<div class="header">';
70
- if (!user && item.user) {
80
+ if (!users.length && item.user) {
71
81
  cell += '<a class="user-info" href="' + item.user.html_url + '" target="_blank" rel="external nofollow noopener noreferrer">';
72
82
  cell += '<img src="' + item.user.avatar_url + '">';
73
83
  cell += '<span>' + item.user.login + '</span>';
@@ -77,53 +87,61 @@ const StellarTimeline = {
77
87
  cell += '<p>' + date.toString().replace(/\sGMT([^.]*)/i, "") + '</p>';
78
88
  cell += '</div>';
79
89
  cell += '<div class="body">';
80
- cell += '<p class="title">';
81
- cell += '<a href="' + item.html_url + '" target="_blank" rel="external nofollow noopener noreferrer">';
82
- cell += item.title || item.name || item.tag_name;
83
- cell += '</a>';
84
- cell += '</p>';
85
-
86
- cell += marked.parse(item.body);
87
- cell += '<div class="footer">';
88
- cell += '<div class="flex left">';
89
- if (item.labels) {
90
- item.labels.forEach((label, i) => {
91
- cell += '<div class="item label ' + label.name + '" style="background:#' + label.color + '18;border-color:#' + label.color + '36">';
92
- cell += '<span>' + label.name + '</span>';
93
- cell += '</div>';
94
- });
95
- } else if (item.zipball_url) {
96
- cell += '<a class="item download" href="' + item.zipball_url + '" target="_blank" rel="external nofollow noopener noreferrer">';
97
- cell += '<span>📦 ' + item.tag_name + '.zip</span>';
90
+ if (!hide.includes('title')) {
91
+ cell += '<p class="title">';
92
+ cell += '<a href="' + item.html_url + '" target="_blank" rel="external nofollow noopener noreferrer">';
93
+ cell += item.title || item.name || item.tag_name;
98
94
  cell += '</a>';
95
+ cell += '</p>';
99
96
  }
100
- cell += '</div>';
101
- cell += '<div class="flex right">';
102
- if (item.reactions && item.reactions.total_count > 0) {
103
- for (let key of Object.keys(StellarTimeline.reactions)) {
104
- let num = item.reactions[key];
105
- if (num > 0) {
106
- cell += '<div class="item reaction ' + key + '">';
107
- cell += '<span>' + StellarTimeline.reactions[key] + ' ' + item.reactions[key] + '</span>';
108
- cell += '</div>';
97
+
98
+ cell += marked.parse(item.body);
99
+ if (!hide.includes('footer')) {
100
+ cell += '<div class="footer">';
101
+ cell += '<div class="flex left">';
102
+ if (item.labels) {
103
+ item.labels.forEach((label, i) => {
104
+ if (!query || !query.includes(encodeURI(label.name))) {
105
+ cell += '<div class="item label ' + label.name + '" style="background:#' + label.color + '18;border-color:#' + label.color + '36">';
106
+ cell += '<span>' + label.name + '</span>';
107
+ cell += '</div>';
108
+ }
109
+ });
110
+ } else if (item.zipball_url) {
111
+ cell += '<a class="item download" href="' + item.zipball_url + '" target="_blank" rel="external nofollow noopener noreferrer">';
112
+ cell += '<span>📦 ' + item.tag_name + '.zip</span>';
113
+ cell += '</a>';
114
+ }
115
+ cell += '</div>';
116
+ cell += '<div class="flex right">';
117
+ if (item.reactions && item.reactions.total_count > 0) {
118
+ for (let key of Object.keys(StellarTimeline.reactions)) {
119
+ let num = item.reactions[key];
120
+ if (num > 0) {
121
+ cell += '<div class="item reaction ' + key + '">';
122
+ cell += '<span>' + StellarTimeline.reactions[key] + ' ' + item.reactions[key] + '</span>';
123
+ cell += '</div>';
124
+ }
109
125
  }
110
126
  }
111
- }
112
- if (item.comments != null) {
113
- cell += '<a class="item comments last" href="' + item.html_url + '#issuecomment-new" target="_blank" rel="external nofollow noopener noreferrer">';
114
- 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> ' + (item.comments || 0) + '</span>';
115
- cell += '</a>';
127
+ if (item.comments != null) {
128
+ cell += '<a class="item comments last" href="' + item.html_url + '#issuecomment-new" target="_blank" rel="external nofollow noopener noreferrer">';
129
+ 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> ' + (item.comments || 0) + '</span>';
130
+ cell += '</a>';
131
+ }
132
+
133
+ cell += '</div>';
134
+ cell += '</div>';
116
135
  }
117
136
 
118
- cell += '</div>';
119
- cell += '</div>';
120
137
  cell += '</div>';
121
138
  cell += '</div>';
122
139
  $(el).append(cell);
123
140
  });
124
141
  }, function() {
125
142
  $(el).find('.loading-wrap svg').remove();
126
- $(el).find('.loading-wrap p').text('加载失败,请稍后重试。');
143
+ $(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>');
144
+ $(el).find('.loading-wrap').addClass('error');
127
145
  });
128
146
  },
129
147
  }