hexo-theme-stellar 1.18.4 → 1.19.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/_config.yml CHANGED
@@ -1,6 +1,6 @@
1
1
  ######## Stellar info ########
2
2
  stellar:
3
- version: '1.18.4'
3
+ version: '1.19.0'
4
4
  homepage: 'https://xaoxuu.com/wiki/stellar/'
5
5
  repo: 'https://github.com/xaoxuu/hexo-theme-stellar'
6
6
  cdn_css: # Use cdn links instead of /css/main.css
@@ -72,14 +72,13 @@ article:
72
72
  enable: false
73
73
  max_count: 5
74
74
 
75
-
76
75
  search:
77
76
  service: local_search # local_search, todo...
78
77
  local_search: # 在 front-matter 中设置 indexing:false 来避免被搜索索引
79
78
  field: all # post, page, all
80
79
  path: /search.json # 搜索文件存放位置
81
80
  content: true # 是否搜索内容
82
-
81
+
83
82
 
84
83
  ######## Comments ########
85
84
  comments:
@@ -127,7 +126,7 @@ comments:
127
126
  twikoo:
128
127
  js: https://gcore.jsdelivr.net/npm/twikoo@1.6.8/dist/twikoo.all.min.js # 建议锁定版本
129
128
  envId: https://xxx # vercel函数
130
-
129
+
131
130
  # Waline
132
131
  # https://waline.js.org/
133
132
  waline:
@@ -148,12 +147,32 @@ comments:
148
147
  # - https://unpkg.com/@waline/emojis@1.1.0/tieba
149
148
  # - https://unpkg.com/@waline/emojis@1.1.0/tw-emoji
150
149
  # - https://unpkg.com/@waline/emojis@1.1.0/bmoji
151
-
150
+ # 设置自己的图床服务,替换默认的 Base 64 编码嵌入(有体积大小限制),在评论中上传图片更加方便
151
+ # imageUploader:
152
+ # 适配了兰空图床V1、V2版本
153
+ # 以兰空图床V1为例,下列填写内容为:
154
+ # fileName: file
155
+ # tokenName: Authorization
156
+ # api: https://xxxxxx/api/v1/upload
157
+ # token: Bearer xxxxxxxxxxxxxx
158
+ # resp: data.links.url
159
+ # 以兰空图床V2为例,下列填写内容为:
160
+ # fileName: image
161
+ # tokenName: token
162
+ # api: https://xxxxxx/api/upload
163
+ # token: xxxxxxxxxxxxxx
164
+ # resp: data.url
165
+ # fileName: # 根据版本二选一
166
+ # tokenName: # 根据版本二选一
167
+ # api: # 图床 api 地址
168
+ # token: # 图床验证
169
+ # resp: # 图片地址返回值的字段
170
+
152
171
  # Artalk
153
172
  # https://artalk.js.org/
154
173
  artalk:
155
174
  css: https://unpkg.com/artalk@2.4.3/dist/Artalk.css
156
- js: https://unpkg.com/artalk@2.4.3/dist/Artalk.js
175
+ js: https://unpkg.com/artalk@2.4.3/dist/Artalk.js
157
176
  server: # 后端服务地址
158
177
  placeholder: ''
159
178
  darkMode: auto
@@ -220,7 +239,9 @@ tag_plugins:
220
239
  blobcat: https://gcore.jsdelivr.net/gh/norevi/waline-blobcatemojis@1.0/blobs/${name}.png
221
240
  # {% image %}
222
241
  image:
223
- fancybox: # true, false
242
+ fancybox: false # true, false
243
+ parse_markdown: true # 把 markdown 格式的图片解析成图片标签
244
+
224
245
  # {% timeline %}
225
246
  timeline:
226
247
  max-height: 80vh
@@ -249,7 +270,7 @@ plugins:
249
270
  weibo: /js/plugins/weibo.js
250
271
 
251
272
  marked: https://cdn.bootcdn.net/ajax/libs/marked/4.0.18/marked.min.js
252
-
273
+
253
274
  ## optional plugins ##
254
275
  # preload
255
276
  preload:
@@ -312,9 +333,40 @@ plugins:
312
333
  # 使用 hexo-renderer-markdown-it-plus 作为公式渲染器:npm uninstall hexo-renderer-marked --save npm install hexo-renderer-markdown-it-plus --save
313
334
  katex:
314
335
  enable: false
315
- min_css: <link rel="stylesheet" href="https://gcore.jsdelivr.net/npm/katex@0.16.4/dist/katex.min.css" integrity="sha384-Xi8rHCmBmhbuyyhbI88391ZKP2dmfnOl4rT9ZfRI7mLTdk1wblIUnrIq35nqwEvC" crossorigin="anonymous">
316
- min_js: <script defer src="https://gcore.jsdelivr.net/npm/katex@0.16.4/dist/katex.min.js" integrity="sha384-X/XCfMm41VSsqRNQgDerQczD69XqmjOOOwYQvr/uuC+j4OPoNhVgjdGFwhvN02Ja" crossorigin="anonymous"></script>
317
- auto_render_min_js: <script defer src="https://gcore.jsdelivr.net/npm/katex@0.16.4/dist/contrib/auto-render.min.js" integrity="sha384-+XBljXPPiv+OzfbB3cVmLHf4hdUFHlWNZN5spNQ7rmHTXpd7WvJum6fIACpNNfIR" crossorigin="anonymous"onload="renderMathInElement(document.body);"></script>
336
+ min_css: <link rel="stylesheet" href="https://gcore.jsdelivr.net/npm/katex@0.16.4/dist/katex.min.css" integrity="sha384-vKruj+a13U8yHIkAyGgK1J3ArTLzrFGBbBc0tDp4ad/EyewESeXE/Iv67Aj8gKZ0" crossorigin="anonymous">
337
+ min_js: <script defer src="https://gcore.jsdelivr.net/npm/katex@0.16.4/dist/katex.min.js" integrity="sha384-PwRUT/YqbnEjkZO0zZxNqcxACrXe+j766U2amXcgMg5457rve2Y7I6ZJSm2A0mS4" crossorigin="anonymous"></script>
338
+ auto_render_min_js: <script defer src="https://gcore.jsdelivr.net/npm/katex@0.16.4/dist/contrib/auto-render.min.js" integrity="sha384-+VBxd3r6XgURycqtZ117nYw44OOcIax56Z4dCRWbxyPt0Koah1uHoK0o4+/RRE05" crossorigin="anonymous"onload="renderMathInElement(document.body);"></script>
339
+
340
+ # Mermaid - markdwon to flow chart, seq chart, class chart ...
341
+ # 需要安装 npm install --save hexo-filter-mermaid-diagrams
342
+ # 使用时 需要在Markdown文件开头加入 mermaid: true
343
+ # 使用示例:
344
+ # ```mermaid
345
+ # graph LR
346
+ # A(Section A) -->|option 1| B(Section A)
347
+ # B -->|option 2| C(Section C)
348
+ # ```
349
+ mermaid:
350
+ enable: false
351
+ # js: https://unpkg.com/mermaid@9.0.0/dist/mermaid.min.js
352
+ js: https://cdn.jsdelivr.net/npm/mermaid@v9/dist/mermaid.min.js
353
+ # Available themes: default | dark | forest | neutral
354
+ # 推荐使用 dark 主题 在夜间模式下显示效果更好
355
+ theme: dark
356
+
357
+ # 代码块复制按钮
358
+ copycode:
359
+ enable: true
360
+ js: /js/plugins/copycode.js
361
+ default_text: 'Copy'
362
+ success_text: 'Copied'
363
+
364
+ # AI 摘要
365
+ # https://github.com/zhheo/Post-Abstract-AI
366
+ tianli_gpt:
367
+ enable: false
368
+ field: post # all, post, wiki
369
+ api: 5Q5mpqRK5DkwT1X9Gi5e
318
370
 
319
371
  style:
320
372
  darkmode: auto # auto / always / false
@@ -357,7 +409,7 @@ style:
357
409
  loading: 正在加载
358
410
  error: 加载失败,请稍后重试。
359
411
  gradient: # https://webgradients.com/
360
- start: 'linear-gradient(to right, #92fe9d 0%, #00c9ff 50%, #92fe9d 100%)'
412
+ start: 'linear-gradient(to right, hsl(215, 95%, 64%), hsl(195, 95%, 60%), hsl(165, 95%, 56%), hsl(165, 95%, 56%), hsl(195 95% 60%), hsl(215, 95%, 64%))'
361
413
  search: 'linear-gradient(to right, #04F3FF, #08FFC6, #DDF730, #FFBD19, #FF1FE0, #C418FF, #04F3FF)'
362
414
 
363
415
  default:
@@ -369,4 +421,4 @@ default:
369
421
  api_host:
370
422
  ghapi: https://api.github.com
371
423
  ghraw: https://raw.githubusercontent.com
372
- gist: https://gist.github.com
424
+ gist: https://gist.github.com
@@ -37,6 +37,17 @@ function generate_description() {
37
37
  }
38
38
  return '<meta name="description" content="' + config.description + '">';
39
39
  }
40
+ function generate_keywords() {
41
+ if (page.keywords && page.keywords.length > 0) {
42
+ return '<meta name="keywords" content="' + page.keywords + '">';
43
+ } else if (page.tags && page.tags.length > 0) {
44
+ return '<meta name="keywords" content="' + page.tags.map(tag => tag.name).join(',') + '">';
45
+ } else if (config.keywords && config.keywords.length > 0) {
46
+ return '<meta name="keywords" content="' + config.keywords + '">';
47
+ } else {
48
+ return '';
49
+ }
50
+ }
40
51
 
41
52
  function generate_robots() {
42
53
  if (is_home() == true) {
@@ -82,6 +93,8 @@ function og_args() {
82
93
  <%- open_graph(og_args()) %>
83
94
  <% } %>
84
95
  <%- generate_description() %>
96
+
97
+ <%- generate_keywords() %>
85
98
 
86
99
  <!-- feed -->
87
100
  <% if (config.feed && config.feed.path) { %>
@@ -0,0 +1,7 @@
1
+ <% if (page.layout === 'post' || (page.layout === 'wiki' && page.wiki && page.wiki.length > 0)) { %>
2
+ <script>
3
+ let tianliGPT_postSelector = '.md-text.content.<%= page.layout === 'post' ? 'post' : 'wiki' %>';
4
+ let tianliGPT_key = '<%= theme.plugins.tianli_gpt.api %>';
5
+ </script>
6
+ <script defer src="https://cdn1.tianli0.top/gh/zhheo/Post-Abstract-AI@0.9/tianli_gpt.js"></script>
7
+ <% } %>
@@ -99,7 +99,7 @@ function layoutDiv() {
99
99
  el += '</div>';
100
100
  if (theme.article.share.includes('wechat')) {
101
101
  el += '<div class="qrcode" id="qrcode-wechat" style="visibility:hidden;height:0">';
102
- el += '<img src="https://api.qrserver.com/v1/create-qr-code/?size=256x256&data=' + url + '"/>';
102
+ el += '<img src="https://api.qrserver.com/v1/create-qr-code/?size=256x256&data=' + page.permalink + '"/>';
103
103
  el += '</div>';
104
104
  }
105
105
  el += '</div>';
@@ -1,4 +1,4 @@
1
- <% if (is_home() && page.total > 1) { %>
1
+ <% if ((is_home() || is_category() || is_tag()) && page.total > 1) { %>
2
2
  <div class='paginator-wrap dis-select'>
3
3
  <%- paginator({
4
4
  prev_text: '',
@@ -11,6 +11,23 @@
11
11
  Waline.init(Object.assign(<%- JSON.stringify(theme.comments.waline) %>, {
12
12
  el: '#waline_container',
13
13
  path: path,
14
+ <% if(!!theme.comments.waline.imageUploader?.api){ %>
15
+ imageUploader: function(file) {
16
+ let headers = new Headers();
17
+ headers.set('Accept', 'application/json');
18
+ <% if(!!theme.comments.waline.imageUploader?.token) { %>
19
+ headers.set('<%= theme.comments.waline.imageUploader?.tokenName %>', '<%= theme.comments.waline.imageUploader?.token %>')
20
+ <% } %>
21
+ let formData = new FormData();
22
+ formData.append('<%= theme.comments.waline.imageUploader?.fileName %>', file);
23
+ return fetch('<%= theme.comments.waline.imageUploader?.api %>',{
24
+ method: 'POST',
25
+ body: formData,
26
+ headers: headers
27
+ }).then((resp) => resp.json())
28
+ .then((resp) => resp.<%= theme.comments.waline.imageUploader?.resp %>)
29
+ },
30
+ <% } %>
14
31
  }));
15
32
  });
16
33
  }
@@ -62,6 +62,9 @@
62
62
  // 从 butterfly 和 volantis 获得灵感
63
63
  loadScript: (src, opt) => new Promise((resolve, reject) => {
64
64
  var script = document.createElement('script');
65
+ if (src.startsWith('/')){
66
+ src = stellar.config.root + src.substring(1);
67
+ }
65
68
  script.src = src;
66
69
  if (opt) {
67
70
  for (let key of Object.keys(opt)) {
@@ -100,6 +103,7 @@
100
103
  day: '<%- __('meta.date_suffix.day') %>',
101
104
  month: '<%- __('meta.date_suffix.month') %>',
102
105
  },
106
+ root : '<%- config.root %>',
103
107
  };
104
108
 
105
109
  // required plugins (only load if needs)
@@ -139,6 +143,9 @@
139
143
  if ('<%- theme.plugins.heti.enable %>' == 'true') {
140
144
  stellar.plugins.heti = Object.assign(<%- JSON.stringify(theme.plugins.heti) %>);
141
145
  }
146
+ if ('<%- theme.plugins.copycode.enable %>' == 'true') {
147
+ stellar.plugins.copycode = Object.assign(<%- JSON.stringify(theme.plugins.copycode) %>);
148
+ }
142
149
  </script>
143
150
 
144
151
  <!-- required -->
@@ -0,0 +1,28 @@
1
+ <% if (theme.plugins.mermaid.enable) { %>
2
+ <script type="text/javascript" src="<%- theme.plugins.mermaid.js %>"></script>
3
+
4
+ <script>
5
+ var mermaid_config = {
6
+ startOnLoad: true,
7
+ theme: '<%- theme.plugins.mermaid.theme %>',
8
+ logLevel: 3,
9
+ themeVariables: {
10
+ darkMode: true
11
+ },
12
+ flowchart: {
13
+ useMaxWidth: false,
14
+ htmlLabels: true,
15
+ curve: 'linear'
16
+ },
17
+ gantt: {
18
+ axisFormat: '%m/%d/%Y'
19
+ },
20
+ sequence: {
21
+ actorMargin: 50
22
+ }
23
+ }
24
+ if (window.mermaid) {
25
+ mermaid.initialize(mermaid_config);
26
+ }
27
+ </script>
28
+ <% } %>
package/layout/post.ejs CHANGED
@@ -22,10 +22,16 @@ if (theme.plugins.heti && theme.plugins.heti.enable) {
22
22
  <% if (page.mathjax == true){ %>
23
23
  <%- partial('mathjax') %>
24
24
  <% } %>
25
+ <% if (page.mermaid == true){ %>
26
+ <%- partial('mermaid') %>
27
+ <% } %>
25
28
  <%- partial('_partial/main/navbar/breadcrumb') %>
26
29
  <article class='md-text content<%- heti %> <%- post.layout %><%- post.indent ? ' indent' : '' %><%- scrollreveal() %>'>
27
30
  <%- layoutTitle() %>
28
31
  <%- post.content %>
32
+ <% if (theme.plugins.tianli_gpt.enable && ['all', 'post'].includes(theme.plugins.tianli_gpt.field)) { %>
33
+ <%- partial('_partial/main/article/ai_abstract') %>
34
+ <% } %>
29
35
  <%- partial('_partial/main/article/article_footer') %>
30
36
  </article>
31
37
  <%- partial('_partial/main/article/read_next') %>
package/layout/wiki.ejs CHANGED
@@ -33,6 +33,9 @@ function layoutTitle() {
33
33
  <article class='md-text content <%- page.layout %><%- page.indent ? ' indent' : '' %><%- scrollreveal() %>'>
34
34
  <%- layoutTitle() %>
35
35
  <%- page.content %>
36
+ <% if (theme.plugins.tianli_gpt.enable && ['all', 'wiki'].includes(theme.plugins.tianli_gpt.field)) { %>
37
+ <%- partial('_partial/main/article/ai_abstract') %>
38
+ <% } %>
36
39
  <%- partial('_partial/main/article/article_footer') %>
37
40
  </article>
38
41
  <%- partial('_partial/main/article/read_next') %>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hexo-theme-stellar",
3
- "version": "1.18.4",
3
+ "version": "1.19.0",
4
4
  "description": "Elegant and powerful theme for Hexo.",
5
5
  "main": "package.json",
6
6
  "scripts": {
@@ -2,3 +2,13 @@
2
2
 
3
3
  hexo.extend.filter.register('after_render:html', require('./lib/img_lazyload').processSite);
4
4
  hexo.extend.filter.register('after_render:html', require('./lib/img_onerror').processSite);
5
+
6
+ function change_image(data) {
7
+ if (this.theme.config.tag_plugins.image.parse_markdown) {
8
+ data.content = data.content.replace(/!\[([^\]]*)]\(([^(]+)\)/g, '{% image $2 $1 %}');
9
+ }
10
+ return data;
11
+ }
12
+
13
+
14
+ hexo.extend.filter.register('before_post_render', change_image, 9);
@@ -40,7 +40,7 @@ module.exports = ctx => function(args) {
40
40
  el += '>'
41
41
  el += '<input class="copy-area" readonly id="' + copy_id + '"'
42
42
  el += ' value="' + text + '">'
43
- el += '<button class="copy-btn" onclick="util.copy(&quot' + copy_id + '&quot,&quotCopied!&quot)">'
43
+ el += '<button class="copy-btn" onclick="util.copy(&quot;' + copy_id + '&quot;,&quot;Copied!&quot;)">'
44
44
  el += '<svg class="icon copy-btn" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M5.75 1a.75.75 0 00-.75.75v3c0 .414.336.75.75.75h4.5a.75.75 0 00.75-.75v-3a.75.75 0 00-.75-.75h-4.5zm.75 3V2.5h3V4h-3zm-2.874-.467a.75.75 0 00-.752-1.298A1.75 1.75 0 002 3.75v9.5c0 .966.784 1.75 1.75 1.75h8.5A1.75 1.75 0 0014 13.25v-9.5a1.75 1.75 0 00-.874-1.515.75.75 0 10-.752 1.298.25.25 0 01.126.217v9.5a.25.25 0 01-.25.25h-8.5a.25.25 0 01-.25-.25v-9.5a.25.25 0 01.126-.217z"></path></svg>'
45
45
  el += '</button>'
46
46
 
@@ -4,7 +4,7 @@
4
4
  *
5
5
  * {% folding [color:yellow] [child:codeblock] [open:false] title %}
6
6
  * body
7
- * {% endtable %}
7
+ * {% endfolding %}
8
8
  */
9
9
 
10
10
  'use strict'
@@ -71,7 +71,7 @@ module.exports = ctx => function(args) {
71
71
  if (args.download == 'true') {
72
72
  href = args.src
73
73
  }
74
- el += '<a class="image-download blur" style="opacity:0" href="' + href + '"><svg class="icon" style="width: 1em; height: 1em;vertical-align: middle;fill: currentColor;overflow: hidden;" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3734"><path d="M561.00682908 685.55838913a111.03077546 111.03077546 0 0 1-106.8895062 0L256.23182837 487.72885783a55.96309219 55.96309219 0 0 1 79.13181253-79.18777574L450.70357448 523.88101491V181.55477937a55.96309219 55.96309219 0 0 1 111.92618438 0v344.06109173l117.07478902-117.07478901a55.96309219 55.96309219 0 0 1 79.13181252 79.18777574zM282.81429711 797.1487951h447.70473912a55.96309219 55.96309219 0 0 1 0 111.92618438H282.81429711a55.96309219 55.96309219 0 0 1 0-111.92618438z" p-id="3735"></path></svg></a>'
74
+ el += '<a class="image-download blur" style="opacity:0" target="_blank" download="' + args.alt + 'href="' + href + '"><svg class="icon" style="width: 1em; height: 1em;vertical-align: middle;fill: currentColor;overflow: hidden;" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3734"><path d="M561.00682908 685.55838913a111.03077546 111.03077546 0 0 1-106.8895062 0L256.23182837 487.72885783a55.96309219 55.96309219 0 0 1 79.13181253-79.18777574L450.70357448 523.88101491V181.55477937a55.96309219 55.96309219 0 0 1 111.92618438 0v344.06109173l117.07478902-117.07478901a55.96309219 55.96309219 0 0 1 79.13181252 79.18777574zM282.81429711 797.1487951h447.70473912a55.96309219 55.96309219 0 0 1 0 111.92618438H282.81429711a55.96309219 55.96309219 0 0 1 0-111.92618438z" p-id="3735"></path></svg></a>'
75
75
  }
76
76
  el += '</div>'
77
77
 
@@ -32,7 +32,7 @@ module.exports = ctx => function(args) {
32
32
  if (item.url && item.title) {
33
33
  var cell = '<div class="site-card">'
34
34
  cell += '<a class="card-link" target="_blank" rel="external nofollow noopener noreferrer" href="' + item.url + '">'
35
- cell += '<img src="' + (item.screenshot || ('https://screenshot-api.xaoxuu.com/api?url=' + item.url + '&width=1280&height=720')) + '" onerror="javascript:this.removeAttribute(&quot;data-src&quot;);this.src=&quot;' + ctx.theme.config.default.cover + '&quot;;"/>'
35
+ cell += '<img src="' + (item.screenshot || ('https://api.vlts.cc/screenshot?url=' + item.url + '&width=1280&height=720')) + '" onerror="javascript:this.removeAttribute(&quot;data-src&quot;);this.src=&quot;' + ctx.theme.config.default.cover + '&quot;;"/>'
36
36
  cell += '<div class="info">'
37
37
  cell += '<img src="' + (item.avatar || ctx.theme.config.default.link) + '" onerror="javascript:this.removeAttribute(&quot;data-src&quot;);this.src=&quot;' + ctx.theme.config.default.link + '&quot;;"/>'
38
38
  cell += '<span class="title">' + item.title + '</span>'
@@ -32,6 +32,7 @@ a.button.start.gradient
32
32
  background: convert(hexo-config('style.gradient.start'))
33
33
  background-size: 1000%
34
34
  color: white
35
+ text-shadow: 0 0 1px rgba(0,0,0,0.12)
35
36
  animation: glow 60s linear infinite
36
37
  @keyframes glow {
37
38
  from {
@@ -153,3 +153,8 @@ h1.article-title
153
153
  bottom: 0
154
154
  left: -2px
155
155
  right: -2px
156
+ .md-text li:not([class]) a:not([class]):before, .md-text p:not([class]) a:not([class]):before
157
+ background unset !important
158
+
159
+ .md-text li:not([class]) a:not([class]):hover:before, .md-text p:not([class]) a:not([class]):hover:before
160
+ background var(--theme-link) !important
@@ -0,0 +1,155 @@
1
+ :root
2
+ --heo-none: #00000000
3
+ --heo-theme = var(--theme-link)
4
+ --heo-main: var(--theme-link)
5
+ --heo-snackbar-time: 5s
6
+ --heo-theme-none: #4259ef01
7
+ --heo-background: var(--site-bg)
8
+ --heo-hovertext: var(--text-code)
9
+ --heo-secondtext: var(--text-p0)
10
+ --heo-scrollbar: rgba(60, 60, 67, 0.4)
11
+ --heo-secondbg: var(--block)
12
+ --heo-card-bg: var(--block)
13
+ --heo-card-bg-none: rgba(255, 255, 255, 0)
14
+ --heo-card-border: var(--block-border)
15
+ --heo-shadow-border: 0 8px 16px -4px #2c2d300c
16
+ --style-border: 1px solid var(--heo-card-border)
17
+ --style-border-always: 1px solid var(--heo-card-border)
18
+
19
+ .post-TianliGPT
20
+ background: var(--block)
21
+ border-radius: 12px
22
+ padding: 12px
23
+ line-height: 1.3
24
+ border: var(--style-border-always)
25
+ margin: 16px 0
26
+
27
+ @media screen and (max-width: 768px)
28
+ .post-TianliGPT
29
+ margin-top: 22px
30
+
31
+ .tianliGPT-title
32
+ display: flex
33
+ color: var(--theme-link)
34
+ border-radius: 8px
35
+ align-items: center
36
+ padding: 0 12px
37
+ cursor: default
38
+ user-select: none
39
+
40
+ .tianliGPT-title-text
41
+ font-weight: bold
42
+ margin-left: 8px
43
+ line-height: 1
44
+
45
+ .tianliGPT-explanation
46
+ margin-top: 12px
47
+ padding: 8px 12px
48
+ background: var(--card)
49
+ border-radius: 8px
50
+ border: var(--style-border-always)
51
+ font-size: 15px
52
+ line-height: 1.4
53
+ display: flex
54
+
55
+ .tianliGPT-suggestions
56
+ display: flex
57
+ flex-wrap: wrap
58
+
59
+ .tianliGPT-suggestions .tianliGPT-suggestions-item
60
+ margin-top: 12px
61
+ padding: 8px 12px
62
+ background: var(--card)
63
+ border-radius: 8px 8px 8px 0
64
+ border: var(--style-border-always)
65
+ font-size: 15px
66
+ line-height: 1.4
67
+ display: flex
68
+ width: fit-content
69
+ margin-right: 12px
70
+ cursor: pointer
71
+ transition: 0.3s
72
+
73
+ .tianliGPT-suggestions .tianliGPT-suggestions-item:hover
74
+ background: var(--heo-main)
75
+ color: var(--text-p0)
76
+
77
+ .blinking-cursor
78
+ background-color: var(--heo-main)
79
+ width: 10px
80
+ height: 16px
81
+ display: inline-block
82
+ vertical-align: middle
83
+ animation: blinking-cursor 0.5s infinite
84
+ -webkit-animation: blinking-cursor 0.5s infinite
85
+ margin-left: 4px
86
+
87
+ @keyframes blinking-cursor
88
+ 0%
89
+ opacity: 1
90
+
91
+ 40%
92
+ opacity: 1
93
+
94
+ 50%
95
+ opacity: 0
96
+
97
+ 90%
98
+ opacity: 0
99
+
100
+ 100%
101
+ opacity: 1
102
+
103
+ .tianliGPT-tag
104
+ font-size: 12px
105
+ background-color: var(--theme-link)
106
+ color: var(--card)
107
+ font-weight: bold
108
+ border-radius: 4px
109
+ margin-left: auto
110
+ line-height: 1
111
+ padding: 4px
112
+ display: flex
113
+ align-items: center
114
+ justify-content: center
115
+ cursor: pointer
116
+ transition: 0.3s
117
+
118
+ .tianliGPT-tag:hover
119
+ background: var(--text-p2)
120
+ color: var(--card)
121
+
122
+ ins.adsbygoogle
123
+ margin: 16px 0
124
+ background: var(--card)
125
+ border-radius: 12px
126
+ overflow: hidden
127
+ border: var(--style-border-always)
128
+
129
+ #tianliGPT-Toggle
130
+ font-size: 12px
131
+ background: var(--theme-link)
132
+ color: var(--card)
133
+ padding: 4px
134
+ border-radius: 4px
135
+ margin-left: 6px
136
+ transform: scale(0.8)
137
+ cursor: pointer
138
+ transition: 0.3s
139
+ font-weight: bold
140
+
141
+ #tianliGPT-Toggle:hover
142
+ background: var(--block-hover)
143
+ color: var(--card)
144
+
145
+ .tianliGPT-title-icon
146
+ width: 20px
147
+ height: 20px
148
+
149
+ .tianliGPT-title-icon svg
150
+ width: 20px
151
+ height: 20px
152
+ fill: var(--heo-main)
153
+
154
+ .tianliGPT-title-icon svg path
155
+ fill: var(--heo-main)
@@ -1,10 +1,7 @@
1
1
  .md-text .tag-plugin.link
2
- max-width: 100%
3
2
  margin: 1em auto
4
3
  display: flex
5
4
  justify-content: center
6
- @media screen and (max-width: $device-mobile-375)
7
- width: 100%
8
5
 
9
6
  .md-text .link-card
10
7
  background: var(--card)
@@ -12,11 +9,8 @@
12
9
  justify-content: space-between
13
10
  align-items: center
14
11
  cursor: pointer
15
- // min-width 280px
16
- // max-width: 100%
17
12
  width: 320px
18
- @media screen and (max-width: $device-mobile-375)
19
- width: 100%
13
+ max-width: 100%
20
14
  box-shadow: $boxshadow-card
21
15
  border-radius: $border-bar
22
16
  trans2: box-shadow transform
@@ -0,0 +1,27 @@
1
+ .highlight
2
+ position: relative
3
+
4
+ .highlight .code .copy-btn
5
+ position: absolute
6
+ top: 0
7
+ right: 0
8
+ padding: 4px 0.5rem
9
+ opacity: 0
10
+ font-weight: 700
11
+ color: var(--theme)
12
+ cursor: pointer
13
+
14
+ .highlight:hover .copy-btn
15
+ opacity 0.25
16
+
17
+ .highlight .code .copy-btn:hover
18
+ color: var(--theme)
19
+ opacity: 0.75
20
+
21
+ .highlight .code .copy-btn.success
22
+ color: $c-green
23
+ opacity: 0.75
24
+
25
+ .highlight .code .copy-btn.warning
26
+ color: $c-orange
27
+ opacity: 0.75
@@ -9,6 +9,10 @@ if hexo-config('plugins.scrollreveal.enable')
9
9
  @import 'scrollreveal'
10
10
  if hexo-config('plugins.fancybox.enable')
11
11
  @import 'fancybox'
12
+ if hexo-config('plugins.mermaid.enable')
13
+ @import 'mermaid'
14
+ if hexo-config('plugins.copycode.enable')
15
+ @import 'copycode'
12
16
 
13
17
 
14
18
  // 评论
@@ -0,0 +1,10 @@
1
+ pre.mermaid {
2
+ display: inline-block;
3
+ width: 100%;
4
+ text-align: center;
5
+ }
6
+
7
+ .mermaid svg {
8
+ width: 100%;
9
+ display: inline-block;
10
+ }
package/source/js/main.js CHANGED
@@ -334,9 +334,10 @@ if (stellar.search.service) {
334
334
  var $resultArea = document.querySelector("div#search-result");
335
335
  $inputArea.focus(function() {
336
336
  var path = stellar.search[stellar.search.service]?.path || '/search.json';
337
- if (!path.startsWith('/')) {
338
- path = '/' + path;
337
+ if (path.startsWith('/')) {
338
+ path = path.substring(1);
339
339
  }
340
+ path = stellar.config.root + path;
340
341
  const filter = $inputArea.attr('data-filter') || '';
341
342
  searchFunc(path, filter, 'search-input', 'search-result');
342
343
  });
@@ -384,3 +385,7 @@ if (stellar.plugins.heti) {
384
385
  stellar.plugins.heti.enable = false;
385
386
  });
386
387
  }
388
+
389
+ if (stellar.plugins.copycode) {
390
+ stellar.loadScript(stellar.plugins.copycode.js, { defer: true })
391
+ }
@@ -0,0 +1,51 @@
1
+ const codeElementArr = document.querySelectorAll('.code')
2
+ codeElementArr.forEach(code => {
3
+ const codeBeforeWidth = window.getComputedStyle(code, '::before').width.split('px')[0]
4
+ const codeBeforePadding = window.getComputedStyle(code, '::before').padding.split(' ').pop().split('px')[0]
5
+
6
+ // copy btn
7
+ const codeCopyBtn = document.createElement('div')
8
+ codeCopyBtn.classList.add('copy-btn')
9
+ codeCopyBtn.style.right = Number(codeBeforeWidth) + Number(codeBeforePadding) * 2 + 'px'
10
+ codeCopyBtn.innerText = stellar.plugins.copycode.default_text
11
+
12
+ code.appendChild(codeCopyBtn)
13
+
14
+ codeCopyBtn.addEventListener('click', async () => {
15
+ const currentCodeElement = code.children[0]?.innerText
16
+ await copyCode(currentCodeElement)
17
+
18
+ codeCopyBtn.innerText = stellar.plugins.copycode.success_text
19
+ codeCopyBtn.classList.add('success')
20
+
21
+ setTimeout(() => {
22
+ codeCopyBtn.innerText = stellar.plugins.copycode.default_text
23
+ codeCopyBtn.classList.remove('success')
24
+ },3000)
25
+ })
26
+ })
27
+
28
+ async function copyCode(currentCode) {
29
+ // console.log(currentCode)
30
+ // console.log('复制代码')
31
+ if (navigator.clipboard) {
32
+ try {
33
+ await navigator.clipboard.writeText(currentCode)
34
+ } catch (error) {
35
+ // 未获得用户许可
36
+ codeCopyBtn.innerText = '未获得用户许可'
37
+ codeCopyBtn.classList.add('warning')
38
+ setTimeout(() => {
39
+ codeCopyBtn.innerText = stellar.plugins.copycode.default_text
40
+ codeCopyBtn.classList.remove('warning')
41
+ },3000)
42
+ }
43
+ } else {
44
+ codeCopyBtn.innerText = '当前浏览器不支持此api'
45
+ codeCopyBtn.classList.add('warning')
46
+ setTimeout(() => {
47
+ codeCopyBtn.innerText = stellar.plugins.copycode.default_text
48
+ codeCopyBtn.classList.remove('warning')
49
+ },3000)
50
+ }
51
+ }
@@ -51,7 +51,7 @@ const sitesjs = {
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://screenshot-api.xaoxuu.com/api?url=' + item.url + '&width=1280&height=720')) + '" onerror="javascript:this.src=\'' + cfg.screenshot + '\';"/>';
54
+ cell += '<img src="' + (item.screenshot || ('https://api.vlts.cc/screenshot?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>';