hexo-theme-volantis 5.3.1 → 5.5.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/CHANGELOG.md +44 -0
  2. package/_config.yml +47 -7
  3. package/languages/en.yml +4 -0
  4. package/languages/zh-CN.yml +4 -0
  5. package/layout/_meta/artalkcount.ejs +14 -6
  6. package/layout/_meta/counter.ejs +11 -2
  7. package/layout/_meta/walinecount.ejs +14 -5
  8. package/layout/_partial/article.ejs +63 -10
  9. package/layout/_partial/scripts/global.ejs +6 -0
  10. package/layout/_partial/scripts/index.ejs +2 -0
  11. package/layout/_plugins/comments/artalk/script.ejs +3 -3
  12. package/layout/_plugins/end-of-support/script.ejs +1 -1
  13. package/layout/_plugins/slow-network/script.ejs +14 -0
  14. package/layout/_widget/_pre.ejs +3 -8
  15. package/layout/_widget/blogger.ejs +1 -1
  16. package/layout/_widget/category.ejs +1 -1
  17. package/layout/_widget/copyright.ejs +1 -1
  18. package/layout/_widget/grid.ejs +1 -1
  19. package/layout/_widget/lastupdate.ejs +1 -1
  20. package/layout/_widget/list.ejs +1 -1
  21. package/layout/_widget/load.ejs +20 -3
  22. package/layout/_widget/music.ejs +1 -1
  23. package/layout/_widget/page.ejs +1 -1
  24. package/layout/_widget/qrcode.ejs +1 -1
  25. package/layout/_widget/related_posts.ejs +1 -1
  26. package/layout/_widget/tagcloud.ejs +1 -1
  27. package/layout/_widget/text.ejs +1 -1
  28. package/layout/_widget/toc.ejs +1 -1
  29. package/layout/_widget/webinfo.ejs +1 -1
  30. package/package.json +1 -1
  31. package/scripts/events/lib/check-configuration.js +5 -6
  32. package/scripts/events/lib/check-environment.js +5 -7
  33. package/scripts/helpers/revisioned.js +80 -71
  34. package/source/css/_defines/color.styl +2 -0
  35. package/source/css/_first/base_first.styl +1 -0
  36. package/source/css/_first/dark_first.styl +1 -0
  37. package/source/css/_style/_layout/article.styl +48 -0
  38. package/source/css/_style/_layout/sidebar.styl +5 -0
  39. package/source/css/_style/_layout/toc.styl +2 -2
  40. package/source/js/app.js +45 -1
  41. package/source/js/plugins/rightMenus.js +17 -15
package/CHANGELOG.md CHANGED
@@ -1,5 +1,49 @@
1
1
  # Changelog
2
2
 
3
+ ## [5.5.0](https://github.com/volantis-x/hexo-theme-volantis/compare/v5.4.0...v5.5.0) (2022-06-18)
4
+
5
+
6
+ ### Features
7
+
8
+ * **copyright:** 精确到文章的版权声明 ([1621fbb](https://github.com/volantis-x/hexo-theme-volantis/commit/1621fbb211057b037bb28328a364fbe4fc32df5a))
9
+ * **scrollreveal&style.css:** slow network ([c31f54a](https://github.com/volantis-x/hexo-theme-volantis/commit/c31f54a01537bd68b83ed289a406b154499d8f21))
10
+ * **widget:** 允许侧边栏卡片的粘性定位 ([5d5c9d5](https://github.com/volantis-x/hexo-theme-volantis/commit/5d5c9d5e7e288eb654922c4659dfdc5a1442ceda))
11
+
12
+
13
+ ### Bug Fixes
14
+
15
+ * **artalk:** 深色模式主动切换修复 ([e4a7e2d](https://github.com/volantis-x/hexo-theme-volantis/commit/e4a7e2d247a8ab63365b1c0c6fc04e8f9bdb5656))
16
+ * **background:** [#776](https://github.com/volantis-x/hexo-theme-volantis/issues/776) bing ([26dc230](https://github.com/volantis-x/hexo-theme-volantis/commit/26dc230ab6377356edb86a21e7c7267433110ac1))
17
+ * **comment:** 指定地址的评论计数统计 ([482601a](https://github.com/volantis-x/hexo-theme-volantis/commit/482601ae02ce686bce1aff6b961dd6ead28a6985))
18
+ * **rightmenu:** aplayer disable ([1c89b63](https://github.com/volantis-x/hexo-theme-volantis/commit/1c89b631371c89975f9977550d8a5c2f586b5fd5))
19
+ * **walinecount:** 移除重复代码 ([2e2e05d](https://github.com/volantis-x/hexo-theme-volantis/commit/2e2e05d7ca19e94f6036c48b3448c58d0401e10b))
20
+ * **widget:** z-index ([c9c823c](https://github.com/volantis-x/hexo-theme-volantis/commit/c9c823cf772f5c26f54ddc82064e5bba79c76331))
21
+
22
+
23
+ ### Performance Improvements
24
+
25
+ * **GLOBAL_CONFIG:** 减少不必要的配置输出 ([2aa234f](https://github.com/volantis-x/hexo-theme-volantis/commit/2aa234f47be05c711f4af526d0e293f5dd8e7926))
26
+
27
+ ## [5.4.0](https://github.com/volantis-x/hexo-theme-volantis/compare/v5.3.2...v5.4.0) (2022-06-09)
28
+
29
+
30
+ ### Features
31
+
32
+ * **VolantisRequest:** Fetch, POST, Get ([ea98dbc](https://github.com/volantis-x/hexo-theme-volantis/commit/ea98dbcc4c3a9bfc0bf6de452e0da826276ff29c))
33
+
34
+
35
+ ### Bug Fixes
36
+
37
+ * **fcircle:** CDN ([#765](https://github.com/volantis-x/hexo-theme-volantis/issues/765)) ([35a2e97](https://github.com/volantis-x/hexo-theme-volantis/commit/35a2e971da07eb30e4cb9a0fdeaafe74580cbcd0))
38
+
39
+ ### [5.3.2](https://github.com/volantis-x/hexo-theme-volantis/compare/v5.3.1...v5.3.2) (2022-05-24)
40
+
41
+
42
+ ### Bug Fixes
43
+
44
+ * **check:** Check environment first ([f5692dd](https://github.com/volantis-x/hexo-theme-volantis/commit/f5692dd862cb0790a656866853e41908b2967de6))
45
+ * **revisioned:** calcFileHash ([1402b9e](https://github.com/volantis-x/hexo-theme-volantis/commit/1402b9ea7747bdcf60e6190b243970567c033528))
46
+
3
47
  ### [5.3.1](https://github.com/volantis-x/hexo-theme-volantis/compare/v5.3.0...v5.3.1) (2022-05-23)
4
48
 
5
49
 
package/_config.yml CHANGED
@@ -59,7 +59,7 @@ cdn:
59
59
  cdn_version: true
60
60
  # volantis static 静态资源文件 npm 包 CDN 地址 (后面加 "/" )
61
61
  # https://github.com/volantis-x/volantis-static
62
- volantis_static_cdn: https://unpkg.com/volantis-static@0.0.1649552113628/
62
+ volantis_static_cdn: https://unpkg.com/volantis-static@0.0.1654736714924/
63
63
  ########################################################################
64
64
  # 全局页面字符串替换 A => B (可用于临时修改错字等)
65
65
  replace:
@@ -113,7 +113,7 @@ cover:
113
113
  home: true
114
114
  archive: true
115
115
  others: false # can be written in front-matter 'cover: true'
116
- background: https://uploadbeta.com/api/pictures/random/?key=BingEverydayWallpaperPicture
116
+ background: https://fastly.jsdelivr.net/gh/MHG-LAB/cron@gh-pages/bing/bing.jpg
117
117
  # background: https://bing.ioliu.cn/v1/rand?w=1920&h=1200
118
118
  logo: # https://cdn.jsdelivr.net/gh/volantis-x/cdn-org/blog/Logo-Cover@3x.png
119
119
  title: 'Volantis'
@@ -210,6 +210,40 @@ article:
210
210
  content:
211
211
  - '博客内容遵循 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 协议'
212
212
  - permalink
213
+ # 自定义版权组件:精细到文章的版权声明
214
+ custom: true # 开启后替代上方内容的版权显示
215
+ customData:
216
+ default: type1 # 默认授权声明
217
+ #############################
218
+ # 你可以在文章的 front-matter 覆盖默认版权声明
219
+ # 配置示例(均可选):
220
+ # copyright:
221
+ # type: type3 # 当前文章版权声明类型
222
+ # author: 张三 # 本文作者
223
+ # ref: # 原文出处
224
+ # title: # 原文出处 - 标题
225
+ # url: # 原文出处 - 链接
226
+ #############################
227
+ rules:
228
+ type1:
229
+ text: <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh#" target="_blank">CC BY-NC-SA 4.0</a>
230
+ desc: 署名-非商业性使用-相同方式共享 4.0 国际。
231
+ type2:
232
+ text: 禁止转载引用
233
+ desc: 除非获得原作者的单独授权,任何第三方不得转载!
234
+ type3:
235
+ text: 原作许可协议
236
+ desc: 本文转载自他站,转载或引用本文时,请遵守原作许可协议!
237
+ type4:
238
+ text: 来自互联网
239
+ desc: 本文来自互联网,未知来源,侵权请联系删除。
240
+ type5:
241
+ text: 允许规范转载
242
+ desc: 转载请保留本文转载地址,著作权归作者所有!
243
+ type6:
244
+ text: 允许付费转载
245
+ desc: 您可以联系作者通过付费方式获得授权。
246
+ # 还能自行添加更多
213
247
  # ----------------
214
248
  # 打赏组件 (for layout: post)
215
249
  donate:
@@ -482,6 +516,7 @@ sidebar:
482
516
  toc:
483
517
  class: toc
484
518
  display: [desktop, mobile] # [desktop, mobile]
519
+ sticky: true
485
520
  header:
486
521
  icon: fa-solid fa-list
487
522
  title: 本文目录
@@ -841,7 +876,7 @@ plugins:
841
876
  bbtalk:
842
877
  # Set `plugins: ["bbtalk"]` to enable in front-matter
843
878
  # 不支持 Pjax
844
- js: https://unpkg.com/bbtalk@0/dist/bbtalk.js # BBtalk.js
879
+ js: https://unpkg.com/bbtalk@0.1.5/dist/bbtalk.js # BBtalk.js
845
880
  appId: 0KzOX4vC7Jsk6vzUGNeEiUaI-gzGzoHsz # your appID
846
881
  appKey: HwCiWuxfpvKiLm4teCUgTIba # your appKEY
847
882
  serverURLs: https://bbapi.heson10.com # Request Api 域名
@@ -852,10 +887,10 @@ plugins:
852
887
  fcircle:
853
888
  # Set `plugins: ["fcircle"]` to enable in front-matter
854
889
  # 支持 Pjax
855
- api: '' # api 地址
856
- message: '与主机通讯中……' # 占位文字
857
- css: 'https://cdn.jsdelivr.net/gh/lmm214/immmmm/themes/hello-friend/static/fcircle-beta.css'
858
- js: 'https://cdn.jsdelivr.net/gh/lmm214/immmmm/themes/hello-friend/static/fcircle-beta.js'
890
+ api: https://fcircle-api.example.com/ # api 地址
891
+ message: 与主机通讯中…… # 占位文字
892
+ css: volantis-static/libs/fcircle/fcircle.css
893
+ js: volantis-static/libs/fcircle/fcircle.js
859
894
 
860
895
  # 消息提示
861
896
  # izitoast@1.4.0
@@ -1116,6 +1151,9 @@ color_scheme:
1116
1151
  list_hl: 'mix($color-theme, #000, 80)'
1117
1152
  # 辅助性文字
1118
1153
  meta: '#888'
1154
+
1155
+ # 版权卡片背景色
1156
+ copyright_bkg: '#f5f5f5'
1119
1157
  # ------------
1120
1158
  # 暗色主题
1121
1159
  # https://www.maijisheji.com/2094.html
@@ -1155,6 +1193,8 @@ color_scheme:
1155
1193
  list_hl: 'mix($color-theme, #fff, 80)'
1156
1194
  # 辅助性文字 # Dark Grey 5
1157
1195
  meta: '#bfbfbfde'
1196
+ # 版权卡片背景色
1197
+ copyright_bkg: '#21252b'
1158
1198
  # 夜间图片亮度
1159
1199
  brightness: 70%
1160
1200
  ############################### Color Scheme ############################### > end
package/languages/en.yml CHANGED
@@ -23,6 +23,10 @@ post:
23
23
  link: Post link
24
24
  license_title: Copyright Notice
25
25
  license_content: "All articles in this blog are licensed under %s unless stating additionally."
26
+ date: Posted on
27
+ updated: Update
28
+ references: References
29
+ license: License
26
30
  footer:
27
31
  license: 'Blog content follows the [Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0) License](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.en)'
28
32
  use: Use
@@ -23,6 +23,10 @@ post:
23
23
  link: 本文链接
24
24
  license_title: 版权声明
25
25
  license_content: "本博客所有文章除特别声明外,均采用 %s 许可协议。转载请注明出处!"
26
+ date: 发布于
27
+ updated: 更新于
28
+ references: 原文出处
29
+ license: 许可协议
26
30
  footer:
27
31
  license: '博客内容遵循 [署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 协议](https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh)'
28
32
  use: 本站使用
@@ -1,11 +1,19 @@
1
- <% if (theme.comments.service == 'artalk'){ %>
1
+ <% if (theme.comments.service == 'artalk' && page.comments !== false) { %>
2
2
  <div class="new-meta-item comments-count">
3
3
  <%
4
- var path = post.path || page.path;
5
- if (path.length > 9 && (path.substring(path.length - 10) == 'index.html')) {
6
- path = path.substring(0, path.length - 10);
7
- }
8
- if(!!theme.comments.artalk.path) path = theme.comments.artalk.path
4
+ let commentPath;
5
+ let path = post.path || page.path;
6
+ if (theme.comments.service && theme.comments.service.length > 0) {
7
+ let service = theme.comments.service;
8
+ if (page.comments == undefined || page.comments != false) {
9
+ if (service in page && page[service].path) {
10
+ commentPath = page[service].path;
11
+ }
12
+ }
13
+ }
14
+ if(!!theme.comments.artalk.path) path = theme.comments.artalk.path
15
+ if(commentPath) path = commentPath;
16
+ path = path.replaceAll('/index.html', '/').replaceAll('.html', '')
9
17
  %>
10
18
  <a href="<%- url_for(path) %>#comments">
11
19
  <i class="<%- theme.article.body.meta_library.artalkcount.icon %> fa-fw"></i>
@@ -1,8 +1,17 @@
1
1
  <%
2
2
  let path = post.path || page.path;
3
- if (path.length > 9 && (path.substring(path.length - 10) == 'index.html')) {
4
- path = path.substring(0, path.length - 10);
3
+ let commentPath;
4
+ if (theme.comments.service && theme.comments.service.length > 0) {
5
+ let service = theme.comments.service;
6
+ if (page.comments == undefined || page.comments != false) {
7
+ if (service in page && page[service].path) {
8
+ commentPath = page[service].path;
9
+ }
10
+ }
5
11
  }
12
+
13
+ if(commentPath) path = commentPath;
14
+ path = path.replaceAll('/index.html', '/').replaceAll('.html', '')
6
15
  %>
7
16
 
8
17
  <% if (!!page.comments) { %>
@@ -1,12 +1,21 @@
1
1
  <% if (theme.comments.service == 'waline'){ %>
2
2
  <div class="new-meta-item comments-count">
3
- <%
4
- var path = post.path || page.path;
5
- if (path.length > 9 && (path.substring(path.length - 10) == 'index.html')) {
6
- path = path.substring(0, path.length - 10);
3
+ <%
4
+ let commentPath;
5
+ let path = post.path || page.path;
6
+ if (theme.comments.service && theme.comments.service.length > 0) {
7
+ let service = theme.comments.service;
8
+ if (page.comments == undefined || page.comments != false) {
9
+ if (service in page && page[service].path) {
10
+ commentPath = page[service].path;
11
+ }
12
+ }
7
13
  }
8
14
  if(!!theme.comments.waline.path) path = theme.comments.waline.path
9
- %>
15
+ if(commentPath) path = commentPath;
16
+ path = path.replaceAll('/index.html', '/').replaceAll('.html', '')
17
+ %>
18
+
10
19
  <a href="<%- url_for(path) %>#comments">
11
20
  <i class="<%- theme.article.body.meta_library.walinecount.icon %> fa-fw"></i>
12
21
  <p>
@@ -22,6 +22,7 @@
22
22
  <% if (['post','docs'].includes(page.layout)) { %>
23
23
  <% let footer_widget = theme.article.body.footer_widget; %>
24
24
  <div class='footer'>
25
+ <!-- 参考资料、相关资料等 -->
25
26
  <% if (page.references && page.references.length > 0) { %>
26
27
  <div class='references'>
27
28
  <section class='header'>
@@ -43,6 +44,7 @@
43
44
  </section>
44
45
  </div>
45
46
  <% } %>
47
+ <!-- 相关文章 -->
46
48
  <% if (['post'].includes(page.layout) && footer_widget.related_posts && footer_widget.related_posts.enable == true) { %>
47
49
  <%-
48
50
  htmlGenerator(
@@ -50,19 +52,70 @@
50
52
  )
51
53
  %>
52
54
  <% } %>
55
+ <!-- 版权声明组件 -->
53
56
  <% if (['post'].includes(page.layout) && footer_widget.copyright && footer_widget.copyright.enable == true && post.copyright != false) { %>
54
- <div class='copyright'>
55
- <blockquote>
56
- <% (footer_widget.copyright.content||[]).forEach(function(row){ %>
57
- <% if (row == 'permalink') { %>
58
- <p><%- footer_widget.copyright.permalink %><a href=<%- page.permalink %>><%- page.permalink %></a></p>
59
- <% } else { %>
60
- <%- markdown(row) %>
57
+ <% if (footer_widget.copyright.custom) { %>
58
+ <%
59
+ let author = theme.article.body.meta_library.author;
60
+ let aid = post.author;
61
+ if (aid && site.data && site.data.author && (aid in site.data.author)) {
62
+ author = site.data.author[aid];
63
+ }
64
+ let articleCreate = date(post.date, theme.article.body.meta_library.date.format);
65
+ let articleUpdate = date(post.updated, theme.article.body.meta_library.updated.format);
66
+ let copyrightRule = post.copyright?.type || theme.article.body.footer_widget.copyright.customData.default;
67
+ let copyrightRuleText = theme.article.body.footer_widget.copyright.customData.rules[copyrightRule]?.text;
68
+ let copyrightRuleDesc = theme.article.body.footer_widget.copyright.customData.rules[copyrightRule]?.desc;
69
+ %>
70
+ <div class="copyright license">
71
+ <div class="license-title"><%- post.title %></div>
72
+ <div class="license-link"><a href="<%- page.permalink %>"><%- page.permalink %></a>
73
+ </div>
74
+ <div class="license-meta">
75
+ <div class="license-meta-item">
76
+ <div class="license-meta-title"><%- __('post.copyright.author') %></div>
77
+ <div class="license-meta-text"><%- post.copyright?.author || author.name %></div>
78
+ </div>
79
+ <div class="license-meta-item">
80
+ <div class="license-meta-title"><%- __('post.copyright.date') %></div>
81
+ <div class="license-meta-text"><%- articleCreate %></div>
82
+ </div>
83
+ <% if (articleCreate !== articleUpdate) { %>
84
+ <div class="license-meta-item">
85
+ <div class="license-meta-title"><%- __('post.copyright.updated') %></div>
86
+ <div class="license-meta-text"><%- articleUpdate %></div>
87
+ </div>
61
88
  <% } %>
62
- <% }) %>
63
- </blockquote>
64
- </div>
89
+ <% if (post.copyright?.ref?.title) { %>
90
+ <div class="license-meta-item">
91
+ <div class="license-meta-title"><%- __('post.copyright.references') %></div>
92
+ <div class="license-meta-text">
93
+ <a href="<%- post.copyright.ref?.url %>" target="_blank"><%- post.copyright.ref?.title %></a>
94
+ </div>
95
+ </div>
96
+ <% } %>
97
+ <div class="license-meta-item">
98
+ <div class="license-meta-title"><%- __('post.copyright.license') %></div>
99
+ <div class="license-meta-text"><%- copyrightRuleText %></div>
100
+ </div>
101
+ </div>
102
+ <div class="license-statement"><%- copyrightRuleDesc %></div>
103
+ </div>
104
+ <% } else { %>
105
+ <div class='copyright'>
106
+ <blockquote>
107
+ <% (footer_widget.copyright.content||[]).forEach(function(row){ %>
108
+ <% if (row == 'permalink') { %>
109
+ <p><%- footer_widget.copyright.permalink %><a href=<%- page.permalink %>><%- page.permalink %></a></p>
110
+ <% } else { %>
111
+ <%- markdown(row) %>
112
+ <% } %>
113
+ <% }) %>
114
+ </blockquote>
115
+ </div>
116
+ <% } %>
65
117
  <% } %>
118
+ <!-- 打赏组件 -->
66
119
  <% if (['post'].includes(page.layout) && footer_widget.donate && footer_widget.donate.enable == true) { %>
67
120
  <div class='donate'>
68
121
  <div class='imgs'>
@@ -26,17 +26,23 @@
26
26
  plugins: {
27
27
  message: <%- JSON.stringify(theme.plugins.message) %>,
28
28
  fancybox: <%- JSON.stringify(theme.plugins.fancybox) %>,
29
+ <% if(theme.plugins.aplayer.enable) { %>
29
30
  aplayer: {
30
31
  id: <%- JSON.stringify(theme.plugins.aplayer.id) %>,
31
32
  enable:<%- JSON.stringify(theme.plugins.aplayer.enable) %>
32
33
  },
34
+ <% } %>
35
+ <% if(theme.rightmenu.enable) { %>
33
36
  rightmenu: {
34
37
  faicon: <%- JSON.stringify(theme.rightmenu.faicon) %>,
35
38
  layout: <%- JSON.stringify(theme.rightmenu.layout) %>,
36
39
  music_alwaysShow: <%- JSON.stringify(theme.rightmenu.music.alwaysShow) %>,
37
40
  customPicUrl: <%- JSON.stringify(theme.rightmenu.customPicUrl) %>
38
41
  },
42
+ <% } %>
43
+ <% if(theme.rightmenus.enable) { %>
39
44
  rightmenus: <%- JSON.stringify(theme.rightmenus) %>
45
+ <% } %>
40
46
  }
41
47
  }
42
48
 
@@ -138,6 +138,8 @@
138
138
 
139
139
  <%- partial('content-visibility-scroll-fix') %>
140
140
 
141
+ <%- partial('../../_plugins/slow-network/script') %>
142
+
141
143
  <% if (theme.structured_data && theme.structured_data.enable) { %>
142
144
  <%- structured_data() %>
143
145
  <% } %>
@@ -14,10 +14,10 @@
14
14
  path = '<%= theme.comments.artalk.path %>' || decodeURI(window.location.pathname);
15
15
  }
16
16
  if(!'<%= config.permalink %>'.includes('/index.html')) {
17
- path = path.replaceAll('/index.html', '/')
17
+ path = path.replaceAll('/index.html', '/').replaceAll('.html', '')
18
18
  }
19
19
 
20
- new Artalk(Object.assign(<%- JSON.stringify(theme.comments.artalk) %>, {
20
+ volantis.artalk = new Artalk(Object.assign(<%- JSON.stringify(theme.comments.artalk) %>, {
21
21
  el: '#artalk_container',
22
22
  pageKey: path,
23
23
  pageTitle: document.title,
@@ -72,7 +72,7 @@
72
72
 
73
73
  function dark_artalk() {
74
74
  if(!document.querySelectorAll("#artalk_container")[0]) return;
75
- Artalk.Use(ctx => {
75
+ volantis.artalk.then(ctx => {
76
76
  ctx.setDarkMode(volantis.dark.mode === "dark")
77
77
  })
78
78
  }
@@ -26,7 +26,7 @@ if (/*@cc_on!@*/false || (!!window.MSInputMethodContext && !!document.documentMo
26
26
  '<div class="kill-ie">'+
27
27
  `<span class="kill-t"><b><%- __('kill.title')%></b></span><br/>`+
28
28
  `<span class="kill-c"><%- __('kill.ie')%></span><br/>`+
29
- `<a href="https://www.microsoft.com/zh-cn/WindowsForBusiness/End-of-IE-support"><strong><%- __('kill.more')%></strong></a>`+
29
+ `<a href="https://blogs.windows.com/windowsexperience/2021/05/19/the-future-of-internet-explorer-on-windows-10-is-in-microsoft-edge/"><strong><%- __('kill.more')%></strong></a>`+
30
30
  '</div>');
31
31
  </script>
32
32
  <% } %>
@@ -0,0 +1,14 @@
1
+ <script>
2
+ document.onreadystatechange = function () {
3
+ if (document.readyState == 'complete') {
4
+ // 页面加载完毕 样式加载失败,或是当前网速慢,或是开启了省流模式
5
+ const { saveData, effectiveType } = navigator.connection || navigator.mozConnection || navigator.webkitConnection || {}
6
+ if (getComputedStyle(document.querySelector("#safearea"), null)["display"] == "none" || saveData || /2g/.test(effectiveType)) {
7
+ document.querySelectorAll(".reveal").forEach(function (e) {
8
+ e.style["opacity"] = "1";
9
+ });
10
+ document.querySelector("#safearea").style["display"] = "block";
11
+ }
12
+ }
13
+ }
14
+ </script>
@@ -7,20 +7,15 @@ if (item.display) {
7
7
  } else {
8
8
  pf = ['desktop', 'mobile'];
9
9
  }
10
- if (item.sticky == true) {
11
- page.widget_style = 'sticky '
12
- } else {
13
- page.widget_style = ''
14
- }
15
10
  if (where == 'sidebar') {
16
11
  page.widget_style += theme.custom_css.sidebar.effect.join(' ');
17
12
  } else if (where == 'body') {
18
13
  page.widget_style += theme.custom_css.body.effect.join(' ');
19
14
  }
20
15
  page.widget_platform = pf.join(' ');
21
- if (item.pjaxReload || item.pjaxReload===undefined){
22
- page.widget_pjax = "pjax"
16
+ if (item.sticky !== true && (item.pjaxReload || item.pjaxReload===undefined)){
17
+ page.widget_pjax = "pjax";
23
18
  }else{
24
19
  page.widget_pjax = ""
25
20
  }
26
- %>
21
+ %>
@@ -1,5 +1,5 @@
1
1
  <%- partial('_pre') %>
2
- <section class="widget <%- item.class %> <%- page.widget_style %> <%- page.widget_platform %> <%- page.widget_pjax %>">
2
+ <section class="widget <%- item.class %> <%- page.widget_platform %> <%- page.widget_pjax %>">
3
3
  <div class='content'>
4
4
  <% if (item.avatar) { %>
5
5
  <% if (item.url) { %>
@@ -1,6 +1,6 @@
1
1
  <% if (site.categories.length){ %>
2
2
  <%- partial('_pre') %>
3
- <section class="widget <%- item.class %> <%- page.widget_style %> <%- page.widget_platform %> <%- page.widget_pjax %>">
3
+ <section class="widget <%- item.class %> <%- page.widget_platform %> <%- page.widget_pjax %>">
4
4
  <%- partial('header', {item: item}) %>
5
5
  <div class='content'>
6
6
  <ul class="entry navigation">
@@ -1,5 +1,5 @@
1
1
  <%- partial('_pre') %>
2
- <section class="widget <%- item.class %> <%- page.widget_style %> <%- page.widget_platform %> <%- page.widget_pjax %>">
2
+ <section class="widget <%- item.class %> <%- page.widget_platform %> <%- page.widget_pjax %>">
3
3
  <div class='content'>
4
4
  <% if (item.blockquote == true) { %>
5
5
  <blockquote>
@@ -1,5 +1,5 @@
1
1
  <%- partial('_pre') %>
2
- <section class="widget <%- item.class %> <%- page.widget_style %> <%- page.widget_platform %> <%- page.widget_pjax %>">
2
+ <section class="widget <%- item.class %> <%- page.widget_platform %> <%- page.widget_pjax %>">
3
3
  <%- partial('header', {item: item}) %>
4
4
  <div class='content'>
5
5
  <div class="grid navigation<%- item.fixed ? ' fixed' : '' %>">
@@ -19,7 +19,7 @@ function genList() {
19
19
  }
20
20
  %>
21
21
  <%- partial('_pre') %>
22
- <section class="widget <%- page.widget_style %> <%- page.widget_platform %> <%- page.widget_pjax %>">
22
+ <section class="widget <%- page.widget_platform %> <%- page.widget_pjax %>">
23
23
  <%- partial('header', {item: item}) %>
24
24
  <div class='content'>
25
25
  <%- genList() %>
@@ -1,5 +1,5 @@
1
1
  <%- partial('_pre') %>
2
- <section class="widget <%- item.class == 'list' ? item.class : 'list ' + item.class %> <%- page.widget_style %> <%- page.widget_platform %> <%- page.widget_pjax %>">
2
+ <section class="widget <%- item.class == 'list' ? item.class : 'list ' + item.class %> <%- page.widget_platform %> <%- page.widget_pjax %>">
3
3
  <%- partial('header', {item: item}) %>
4
4
  <div class='content'>
5
5
  <ul class="list entry navigation">
@@ -1,15 +1,32 @@
1
+ <%
2
+ let widget_library_temp = [];
3
+ %>
1
4
  <% (widgets||[]).forEach(function(widget){ %>
2
5
  <% if (theme.sidebar.widget_library && (widget in theme.sidebar.widget_library)){ %>
3
6
  <% let w = theme.sidebar.widget_library[widget]; w.id = widget; %>
4
- <%- partial(w.class, {item: w, where: where}) %>
7
+ <% if(w.sticky) { %>
8
+ <% widget_library_temp.push(w) %>
9
+ <% } else { %>
10
+ <%- partial(w.class, {item: w, where: where}) %>
11
+ <% } %>
5
12
  <% } %>
6
13
  <% }) %>
14
+
15
+ <div class="widget-sticky pjax">
16
+ <% if(widget_library_temp.length !== 0) { %>
17
+ <% widget_library_temp.forEach( w => { %>
18
+ <%- partial(w.class, {item: w, where: where}) %>
19
+ <% }) %>
20
+ <% } %>
21
+ </div>
22
+
7
23
  <%
8
24
  let widget_pjax_length = 0;
9
25
  page.sidebar.forEach(function(e){
10
26
  if (e&&theme.sidebar.widget_library&&theme.sidebar.widget_library[e]) {
11
27
  let widget_pjax_flag = theme.sidebar.widget_library[e].pjaxReload
12
- if (widget_pjax_flag || widget_pjax_flag===undefined) {
28
+ let widget_stickys = theme.sidebar.widget_library[e].sticky
29
+ if (widget_stickys !== true && (widget_pjax_flag || widget_pjax_flag===undefined)) {
13
30
  widget_pjax_length ++;
14
31
  }
15
32
  }
@@ -21,4 +38,4 @@ let widget_pjax_place_length = Object.keys(theme.sidebar.widget_library).length
21
38
  <div class="pjax">
22
39
  <!-- pjax占位 -->
23
40
  </div>
24
- <% } %>
41
+ <% } %>
@@ -1,6 +1,6 @@
1
1
  <%- partial('_pre') %>
2
2
  <% if (theme.plugins.aplayer.enable == true) { %>
3
- <section class='widget <%- page.widget_style %> <%- page.widget_platform %> <%- page.widget_pjax %> <%- item.class %>'>
3
+ <section class='widget <%- page.widget_platform %> <%- page.widget_pjax %> <%- item.class %>'>
4
4
  <%- partial('header', {item: item}) %>
5
5
  <div class='content'>
6
6
  <%- partial('../_plugins/aplayer/layout', {post: null, where: 'widget'}) %>
@@ -1,5 +1,5 @@
1
1
  <%- partial('_pre') %>
2
- <section class="widget <%- item.class %> <%- page.widget_style %> <%- page.widget_platform %> <%- page.widget_pjax %>">
2
+ <section class="widget <%- item.class %> <%- page.widget_platform %> <%- page.widget_pjax %>">
3
3
  <%- partial('header', {item: item}) %>
4
4
  <div class='content'>
5
5
  <% site.pages.forEach(function(post){ %>
@@ -1,5 +1,5 @@
1
1
  <%- partial('_pre') %>
2
- <section class="widget <%- item.class %> <%- page.widget_style %> <%- page.widget_platform %> <%- page.widget_pjax %>">
2
+ <section class="widget <%- item.class %> <%- page.widget_platform %> <%- page.widget_pjax %>">
3
3
  <%- partial('header', {item: item}) %>
4
4
  <div class='content article-entry'>
5
5
  <% (item.images||[]).forEach(function(url){ %>
@@ -1,6 +1,6 @@
1
1
  <% if(page.layout == 'post' && page.content && page.path != undefined){ %>
2
2
  <%- partial('_pre') %>
3
- <section class="widget <%- item.class %> <%- page.widget_style %> <%- page.widget_platform %> <%- page.widget_pjax %>">
3
+ <section class="widget <%- item.class %> <%- page.widget_platform %> <%- page.widget_pjax %>">
4
4
  <%- partial('header', {item: item}) %>
5
5
  <div class="content">
6
6
  <%- popular_posts( { maxCount: item.max_count , ulClass: 'popular-posts' , PPMixingRate: 0.2 } , page ) %>
@@ -1,6 +1,6 @@
1
1
  <% if (site.tags.length){ %>
2
2
  <%- partial('_pre') %>
3
- <section class="widget <%- item.class %> <%- page.widget_style %> <%- page.widget_platform %> <%- page.widget_pjax %>">
3
+ <section class="widget <%- item.class %> <%- page.widget_platform %> <%- page.widget_pjax %>">
4
4
  <%- partial('header', {item: item}) %>
5
5
  <div class='content'>
6
6
  <%- tagcloud(site.tags, {
@@ -1,5 +1,5 @@
1
1
  <%- partial('_pre') %>
2
- <section class="widget <%- item.class %> <%- page.widget_style %> <%- page.widget_platform %> <%- page.widget_pjax %>">
2
+ <section class="widget <%- item.class %> <%- page.widget_platform %> <%- page.widget_pjax %>">
3
3
  <%- partial('header', {item: item}) %>
4
4
  <div class='content'>
5
5
  <% (item.content||[]).forEach(function(row){ %>
@@ -1,7 +1,7 @@
1
1
  <%- partial('_pre') %>
2
2
  <% var realcontent = (page.encrypt == true) ? page.origin : page.content; %>
3
3
  <% if (realcontent && page.toc != false && toc(realcontent).length > 0) { %>
4
- <section class="widget toc-wrapper <%- page.widget_style %> <%- page.widget_platform %> <%- page.widget_pjax %>" id="toc-div" <% if (page.encrypt == true) { %>style="display:none" <% } %>>
4
+ <section class="widget toc-wrapper <%- page.widget_platform %> <%- page.widget_pjax %>" id="toc-div" <% if (page.encrypt == true) { %>style="display:none" <% } %>>
5
5
  <%- partial('header', {item: item}) %>
6
6
  <div class='content'>
7
7
  <%- toc(realcontent, {list_number: item.list_number, min_depth: item.min_depth, max_depth: item.max_depth}) %>
@@ -1,5 +1,5 @@
1
1
  <%- partial('_pre') %>
2
- <section class="widget <%- page.widget_style %> <%- page.widget_platform %> <%- page.widget_pjax %>">
2
+ <section class="widget <%- page.widget_platform %> <%- page.widget_pjax %>">
3
3
  <%- partial('header', {item: item}) %>
4
4
  <div class='content'>
5
5
  <div class="webinfo">
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hexo-theme-volantis",
3
- "version": "5.3.1",
3
+ "version": "5.5.0",
4
4
  "description": "Elegant and powerful theme for Hexo.",
5
5
  "main": "package.json",
6
6
  "scripts": {
@@ -6,16 +6,14 @@ module.exports =(hexo) => {
6
6
  return `title 未配置!
7
7
  请在站点配置 _config.yml 中配置 title
8
8
  see: https://hexo.io/zh-cn/docs/configuration
9
- title not configured!
10
- see: https://hexo.io/zh-cn/docs/configuration`
9
+ title is not configured!`
11
10
  }
12
11
  if (!config.description) {
13
12
  return `description 未配置!
14
13
  请在站点配置 _config.yml 中配置 description
15
14
  description主要用于SEO,告诉搜索引擎一个关于您站点的简单描述,通常建议在其中包含您网站的关键词。
16
15
  see: https://hexo.io/zh-cn/docs/configuration
17
- description not configured!
18
- see: https://hexo.io/zh-cn/docs/configuration`
16
+ description is not configured!`
19
17
  }
20
18
  if (themeConfig?.search?.service===`google`||themeConfig?.search?.service===`algolia`||themeConfig?.search?.service===`azure`||themeConfig?.search?.service===`baidu`) {
21
19
  return `原 google, algolia, azure, baidu 站内搜索 系祖传代码, 且文档丢失, 不便后续维护 在 5.0 版本被移除
@@ -29,15 +27,16 @@ see: https://volantis.js.org/v5/theme-settings/#幻灯片背景-视差滚动效
29
27
  }
30
28
  if ("valinecount" in themeConfig?.article?.body?.top_meta||"valinecount" in themeConfig?.article?.body?.bottom_meta||"valinecount" in themeConfig?.article?.body?.meta_library) {
31
29
  return `ValineCount 在 5.0 版本被移除
32
- ValineCount has been removed in 5.0 version
30
+ ValineCount has been removed in version 5.0
33
31
  see: https://volantis.js.org/v5/theme-settings/#文章布局配置`
34
32
  }
35
33
  if (themeConfig?.comments?.service=="valine"||themeConfig?.comments?.service=="minivaline") {
36
34
  return `Valine 在 5.0 版本被移除
37
- Valine has been removed in 5.0 version
35
+ Valine has been removed in version 5.0
38
36
  see: https://volantis.js.org/v5/theme-settings/#选择评论系统`
39
37
  }
40
38
  } catch (error) {}
39
+ hexo.log.info(`Check environment configuration success!`);
41
40
  return true;
42
41
  };
43
42
 
@@ -6,12 +6,6 @@ module.exports =(hexo) => {
6
6
  hexo.checkEnvironment=1;
7
7
  hexo.log.info(`Checking environment configuration...`);
8
8
 
9
- // Checking configuration
10
- let checkConfiguration = require('./check-configuration')(hexo);
11
- if (checkConfiguration!==true) {
12
- CheckConfError(hexo,checkConfiguration);
13
- }
14
-
15
9
  // Checking environment
16
10
  exec('node -v', (err, stdout, stderr) => {
17
11
  if (err) {
@@ -38,7 +32,11 @@ module.exports =(hexo) => {
38
32
  hexo.log.info(`hexo-cli 版本:${stdout}`);
39
33
  CheckError(hexo,`hexo-cli 版本过低,请升级至 4.1 以上版本!`);
40
34
  }else{
41
- hexo.log.info(`Check environment configuration success!`);
35
+ // Checking configuration
36
+ let checkConfiguration = require('./check-configuration')(hexo);
37
+ if (checkConfiguration!==true) {
38
+ CheckConfError(hexo,checkConfiguration);
39
+ }
42
40
  }
43
41
  }
44
42
  });
@@ -74,9 +74,15 @@ const revisioned = (filePath) => {
74
74
  hexo.extend.helper.register("revisioned", revisioned);
75
75
 
76
76
  const calcFileHash = async (filePath) => {
77
- const buffer = await stream2buffer(hexo.route.get(filePath));
78
- const fileHash = crypto.createHash("md5").update(buffer).digest('hex').substring(0, 8);
79
- return fileHash;
77
+ if (hexo.route.get(filePath)) {
78
+ const buffer = await stream2buffer(hexo.route.get(filePath));
79
+ const fileHash = crypto.createHash("md5").update(buffer).digest('hex').substring(0, 8);
80
+ return fileHash;
81
+ } else {
82
+ // 随机生成 hash
83
+ return crypto.randomBytes(16).toString('hex').substring(0, 8);
84
+ }
85
+
80
86
  };
81
87
 
82
88
  const replaceRevisionPlaceholder = async () => {
@@ -84,75 +90,78 @@ const replaceRevisionPlaceholder = async () => {
84
90
  if (!hexo.theme.config.cdn_version) {
85
91
  return;
86
92
  }
87
-
88
- const options = hexo.config.new_revision || {};
89
- const include = options.include || [];
90
-
91
- const hashPromiseMap = {};
92
- const hashMap = {};
93
- const doHash = (filePath) =>
94
- calcFileHash(filePath).then((hash) => {
95
- hashMap[filePath] = hash;
96
- });
97
-
98
- await Promise.all(
99
- hexo.route.list().map(async (path) => {
100
- const [, , extension] = parseFilePath(path);
101
- if (![".css", ".js", ".html"].includes(extension)) {
102
- return;
103
- }
104
-
105
- let fileContent = await readFileAsString(path);
106
-
107
- const regexp = /\.!!revision:([^\)]+?)!!/g;
108
- const matchResult = [...fileContent.matchAll(regexp)];
109
- if (matchResult.length) {
110
- const hashTaskList = [];
111
-
112
- // 异步获取文件 hash
113
- matchResult.forEach((group) => {
114
- const filePath = group[1];
115
- if (!(filePath in hashPromiseMap)) {
116
- hashPromiseMap[filePath] = doHash(filePath);
117
- }
118
- hashTaskList.push(hashPromiseMap[filePath]);
119
- });
120
-
121
- // 等待全部 hash 完成
122
- await Promise.all(hashTaskList);
123
-
124
- // 替换 placeholder
125
- fileContent = fileContent.replace(regexp, function (match, filePath) {
126
- if (!(filePath in hashMap)) {
127
- throw new Error("file hash not computed");
93
+ try {
94
+ const options = hexo.config.new_revision || {};
95
+ const include = options.include || [];
96
+
97
+ const hashPromiseMap = {};
98
+ const hashMap = {};
99
+ const doHash = (filePath) =>
100
+ calcFileHash(filePath).then((hash) => {
101
+ hashMap[filePath] = hash;
102
+ });
103
+
104
+ await Promise.all(
105
+ hexo.route.list().map(async (path) => {
106
+ const [, , extension] = parseFilePath(path);
107
+ if (![".css", ".js", ".html"].includes(extension)) {
108
+ return;
109
+ }
110
+
111
+ let fileContent = await readFileAsString(path);
112
+
113
+ const regexp = /\.!!revision:([^\)]+?)!!/g;
114
+ const matchResult = [...fileContent.matchAll(regexp)];
115
+ if (matchResult.length) {
116
+ const hashTaskList = [];
117
+
118
+ // 异步获取文件 hash
119
+ matchResult.forEach((group) => {
120
+ const filePath = group[1];
121
+ if (!(filePath in hashPromiseMap)) {
122
+ hashPromiseMap[filePath] = doHash(filePath);
123
+ }
124
+ hashTaskList.push(hashPromiseMap[filePath]);
125
+ });
126
+
127
+ // 等待全部 hash 完成
128
+ await Promise.all(hashTaskList);
129
+
130
+ // 替换 placeholder
131
+ fileContent = fileContent.replace(regexp, function (match, filePath) {
132
+ if (!(filePath in hashMap)) {
133
+ throw new Error("file hash not computed");
134
+ }
135
+ return "." + hashMap[filePath];
136
+ });
137
+
138
+ hexo.route.set(path, fileContent);
139
+ }
140
+ })
141
+ );
142
+
143
+ await Promise.all(
144
+ hexo.route.list().map(async (path) => {
145
+ for (let i = 0, len = include.length; i < len; i++) {
146
+ if (minimatch(path, include[i])) {
147
+ return doHash(path);
128
148
  }
129
- return "." + hashMap[filePath];
130
- });
131
-
132
- hexo.route.set(path, fileContent);
133
- }
134
- })
135
- );
136
-
137
- await Promise.all(
138
- hexo.route.list().map(async (path) => {
139
- for (let i = 0, len = include.length; i < len; i++) {
140
- if (minimatch(path, include[i])) {
141
- return doHash(path);
142
149
  }
143
- }
144
- })
145
- );
146
-
147
- await Promise.all(
148
- Object.keys(hashMap).map(async (filePath) => {
149
- hexo.route.set(
150
- getRevisionedFilePath(filePath, hashMap[filePath]),
151
- await readFileAsBuffer(filePath)
152
- );
153
- hexo.route.remove(filePath);
154
- })
155
- );
150
+ })
151
+ );
152
+
153
+ await Promise.all(
154
+ Object.keys(hashMap).map(async (filePath) => {
155
+ hexo.route.set(
156
+ getRevisionedFilePath(filePath, hashMap[filePath]),
157
+ await readFileAsBuffer(filePath)
158
+ );
159
+ hexo.route.remove(filePath);
160
+ })
161
+ );
162
+ } catch (error) {
163
+
164
+ }
156
165
  };
157
166
 
158
- hexo.extend.filter.register("after_generate", replaceRevisionPlaceholder,999999999999999999999999999999999999);
167
+ hexo.extend.filter.register("after_generate", replaceRevisionPlaceholder,9999);
@@ -63,6 +63,7 @@ $color-p = convert(hexo-config('color_scheme.light.p'))
63
63
  $color-list = convert(hexo-config('color_scheme.light.list'))
64
64
  $color-list-hl = convert(hexo-config('color_scheme.light.list_hl'))
65
65
  $color-meta = convert(hexo-config('color_scheme.light.meta'))
66
+ $color-copyright-bkg = convert(hexo-config('color_scheme.light.copyright_bkg'))
66
67
 
67
68
  // 深色配色方案在 darkmode.styl 中按需加载
68
69
  $color-dark-site-body = convert(hexo-config('color_scheme.dark.site_bd')) // Dark Grey 1
@@ -88,6 +89,7 @@ $color-dark-list = convert(hexo-config('color_scheme.dark.list'))
88
89
  $color-dark-list-hl = convert(hexo-config('color_scheme.dark.list_hl'))
89
90
  $color-dark-meta = convert(hexo-config('color_scheme.dark.meta'))
90
91
  $color-dark-link = convert(hexo-config('color_scheme.dark.meta'))
92
+ $color-dark-copyright-bkg = convert(hexo-config('color_scheme.dark.copyright_bkg'))
91
93
 
92
94
  bgcolor($c, $mix = 10)
93
95
  return mix($c, $color-card, $mix)
@@ -20,6 +20,7 @@
20
20
  --color-meta: $color-meta
21
21
  --color-read-bkg: $color-read-bkg
22
22
  --color-read-post: $color-read-post
23
+ --color-copyright-bkg: $color-copyright-bkg
23
24
 
24
25
  *
25
26
  box-sizing: border-box
@@ -24,6 +24,7 @@ fitst_dark()
24
24
  --color-list-hl: $color-dark-list-hl
25
25
  --color-meta: $color-dark-meta
26
26
  --color-link: $color-dark-link
27
+ --color-copyright-bkg: $color-dark-copyright-bkg
27
28
 
28
29
  img
29
30
  filter: brightness(convert(hexo-config('color_scheme.dark.brightness'))) !important
@@ -323,3 +323,51 @@ article .readmore
323
323
  display: block
324
324
  margin-top: $gap * 1.5
325
325
  font-size: $fontsize-meta
326
+
327
+ .copyright.license
328
+ &:after
329
+ background: url("data:image/svg+xml;charset=utf-8,%3Csvg version='1.1' id='Capa_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 367.467 367.467' style='enable-background:new 0 0 367.467 367.467;' xml:space='preserve'%3E%3Cg%3E%3Cpath d='M183.73,0.018C82.427,0.018,0,82.404,0,183.733c0,101.289,82.427,183.716,183.73,183.716 c101.315,0,183.737-82.427,183.737-183.716C367.467,82.404,285.045,0.018,183.73,0.018z M183.73,326.518 c-78.743,0-142.798-64.052-142.798-142.784c0-78.766,64.055-142.817,142.798-142.817c78.752,0,142.807,64.052,142.807,142.817 C326.536,262.466,262.481,326.518,183.73,326.518z'/%3E%3Cpath d='M244.036,217.014c-11.737,20.141-33.562,32.635-56.956,32.635c-36.329,0-65.921-29.585-65.921-65.915 c0-36.36,29.592-65.955,65.921-65.955c23.395,0,45.219,12.54,56.956,32.641l1.517,2.627h44.28l-2.658-7.129 c-7.705-20.413-21.225-37.769-39.122-50.157c-17.942-12.42-39.017-19.009-60.973-19.009c-58.981,0-106.946,48.006-106.946,106.982 c0,58.98,47.965,106.941,106.946,106.941c21.956,0,43.03-6.567,60.973-19.006c17.897-12.391,31.417-29.741,39.122-50.154 l2.658-7.133h-44.28L244.036,217.014z'/%3E%3C/g%3E%3C/svg%3E")
330
+ content: " ";
331
+ opacity: .1;
332
+ height: 180px;
333
+ right: -10px;
334
+ top: -35px;
335
+ width: 180px;
336
+ position: absolute;
337
+ a
338
+ color: var(--color-meta);
339
+ &:hover
340
+ color: #ff5722;
341
+ background: var(--color-copyright-bkg);
342
+ color: var(--color-meta);
343
+ display: block;
344
+ font-size: .95rem;
345
+ line-height: 1.2;
346
+ margin: 15px -40px;
347
+ overflow: hidden;
348
+ padding: 1.25em 40px;
349
+ position: relative;
350
+ border-radius: 4px;
351
+ .license-title,
352
+ .license-meta-title
353
+ margin: 0 0 .25rem;
354
+ .license-link,
355
+ .license-meta-title
356
+ font-size: .8rem;
357
+ .license-title
358
+ font-weight: 700;
359
+ .license-link
360
+ margin-bottom: 1rem;
361
+ .license-meta
362
+ align-items: center;
363
+ display: flex;
364
+ flex-wrap: wrap;
365
+ justify-content: flex-start;
366
+ .license-meta-item
367
+ margin: 0 2rem 1em 0;
368
+ .license-meta-text
369
+ margin: 0;
370
+ a
371
+ border-bottom: 1px solid var(--color-meta);
372
+ &:hover
373
+ border-bottom-color: #ff5722
@@ -358,3 +358,8 @@
358
358
  white-space: nowrap // 不换行
359
359
  overflow: hidden // 超出宽度部分隐藏
360
360
  text-overflow: ellipsis // 超出部分以点号替代
361
+
362
+ .widget-sticky
363
+ position: sticky
364
+ top: $navbar-height + $gap
365
+ z-index 10
@@ -2,8 +2,8 @@
2
2
  z-index: 1
3
3
  overflow: hidden
4
4
  border-radius: $border-card
5
- position: sticky
6
- top: $navbar-height + $gap
5
+ //position: sticky
6
+ //top: $navbar-height + $gap
7
7
  trans()
8
8
  line-height: 1.6
9
9
  header
package/source/js/app.js CHANGED
@@ -67,7 +67,7 @@ const VolantisApp = (() => {
67
67
  }
68
68
 
69
69
  fn.event = () => {
70
- volantis.dom.$(document.getElementById("scroll-down")).on('click', function () {
70
+ volantis.dom.$(document.getElementById("scroll-down"))?.on('click', function () {
71
71
  fn.scrolltoElement(volantis.dom.bodyAnchor);
72
72
  });
73
73
 
@@ -1126,3 +1126,47 @@ const DOMController = {
1126
1126
  }
1127
1127
  }
1128
1128
  Object.freeze(DOMController);
1129
+
1130
+ const VolantisRequest = {
1131
+ timeoutFetch: (url, ms, requestInit) => {
1132
+ const controller = new AbortController()
1133
+ requestInit.signal?.addEventListener('abort', () => controller.abort())
1134
+ let promise = fetch(url, { ...requestInit, signal: controller.signal })
1135
+ if (ms > 0) {
1136
+ const timer = setTimeout(() => controller.abort(), ms)
1137
+ promise.finally(() => { clearTimeout(timer) })
1138
+ }
1139
+ promise = promise.catch((err) => {
1140
+ throw ((err || {}).name === 'AbortError') ? new Error(`Fetch timeout: ${url}`) : err
1141
+ })
1142
+ return promise
1143
+ },
1144
+
1145
+ Fetch: async (url, requestInit, timeout = 15000) => {
1146
+ const resp = await VolantisRequest.timeoutFetch(url, timeout, requestInit);
1147
+ if (!resp.ok) throw new Error(`Fetch error: ${url} | ${resp.status}`);
1148
+ let json = await resp.json()
1149
+ if (!json.success) throw json
1150
+ return json
1151
+ },
1152
+
1153
+ POST: async (url, data) => {
1154
+ const requestInit = {
1155
+ method: 'POST',
1156
+ }
1157
+ if (data) {
1158
+ const formData = new FormData();
1159
+ Object.keys(data).forEach(key => formData.append(key, String(data[key])))
1160
+ requestInit.body = formData;
1161
+ }
1162
+ const json = await VolantisRequest.Fetch(url, requestInit)
1163
+ return json.data;
1164
+ },
1165
+
1166
+ Get: async (url, data) => {
1167
+ const json = await VolantisRequest.Fetch(url + (data ? (`?${new URLSearchParams(data)}`) : ''), {
1168
+ method: 'GET'
1169
+ })
1170
+ }
1171
+ }
1172
+ Object.freeze(VolantisRequest);
@@ -191,7 +191,7 @@ RightMenus.fun = (() => {
191
191
  _rightMenuWrapper.style.top = `${showTop}px`;
192
192
  if (volantis.GLOBAL_CONFIG.plugins.message.rightmenu.notice) fn.menuNotic();
193
193
  } catch (error) {
194
- if (volantis.GLOBAL_CONFIG.debug) console.error(error);
194
+ console.error(error);
195
195
  fn.hideMenu();
196
196
  return true;
197
197
  }
@@ -316,7 +316,7 @@ RightMenus.fun = (() => {
316
316
  }
317
317
 
318
318
  // 判断是否显示音乐控制器
319
- if (volantis.GLOBAL_CONFIG.plugins.aplayer.enable
319
+ if (volantis.GLOBAL_CONFIG.plugins.aplayer?.enable
320
320
  && typeof RightMenuAplayer !== 'undefined'
321
321
  && RightMenuAplayer.APlayer.player !== undefined) {
322
322
  if (rightMenuConfig.options.musicAlwaysShow
@@ -563,19 +563,21 @@ RightMenus.fun = (() => {
563
563
 
564
564
  fn.readMode = () => {
565
565
  if (typeof ScrollReveal === 'function') ScrollReveal().clean('#comments');
566
- DOMController.fadeToggleList([
567
- document.querySelector('#l_header'), document.querySelector('footer'),
568
- document.querySelector('#s-top'), document.querySelector('.article-meta#bottom'),
569
- document.querySelector('.prev-next'), document.querySelector('#l_side'),
570
- document.querySelector('#comments')
571
- ]);
572
- DOMController.toggleClassList([
573
- [document.querySelector('#l_main'), 'common_read'], [document.querySelector('#l_main'), 'common_read_main'],
574
- [document.querySelector('#l_body'), 'common_read'], [document.querySelector('#safearea'), 'common_read'],
575
- [document.querySelector('#pjax-container'), 'common_read'], [document.querySelector('#read_bkg'), 'common_read_hide'],
576
- [document.querySelector('h1'), 'common_read_h1'], [document.querySelector('#post'), 'post_read'],
577
- [document.querySelector('#l_cover'), 'read_cover'], [document.querySelector('.widget.toc-wrapper'), 'post_read']
578
- ]);
566
+ DOMController.removeList([
567
+ '.cus-article-bkg', '.iziToast-overlay', '.iziToast-wrapper', '.prev-next',
568
+ 'footer', '#l_header', '#l_cover', '#l_side', '#comments', '#s-top', '#BKG',
569
+ '#rightmenu-wrapper', '.nav-tabs', '.parallax-mirror', '.new-meta-item.share',
570
+ '.new-meta-box', 'button.btn-copy', 'iframe'
571
+ ]);
572
+ DOMController.setStyleList([
573
+ ['body', 'backgroundColor', 'unset'], ['#l_main, .copyright.license', 'width', '100%'],
574
+ ['#post', 'boxShadow', 'none'], ['#post', 'background', 'none'], ['#post', 'padding', '0'],
575
+ ['h1', 'textAlign', 'center'], ['h1', 'fontWeight', '600'], ['h1', 'fontSize', '2rem'], ['h1', 'marginBottom', '20px'],
576
+ ['.tab-pane', 'display', 'block'], ['.tab-content', 'borderTop', 'none'], ['.highlight>table pre', 'whiteSpace', 'pre-wrap'],
577
+ ['.highlight>table pre', 'wordBreak', 'break-all'], ['.fancybox img', 'height', 'auto'], ['.fancybox img', 'weight', 'auto'],
578
+ ['.copyright.license', 'margin', '0'], ['.copyright.license', 'padding', '1.25em 20px'],
579
+ ['figure.highlight, .copyright.license', 'display', 'inline-block'],
580
+ ]);
579
581
  volantis.isReadModel = volantis.isReadModel === undefined ? true : !volantis.isReadModel;
580
582
  if (volantis.isReadModel) {
581
583
  if (RightMenus.messageRightMenu) VolantisApp.message('系统提示', '阅读模式已开启,您可以点击屏幕空白处退出。', {