hexo-theme-volantis 4.3.1 → 5.0.0-alpha.112

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 (309) hide show
  1. package/README.md +6 -4
  2. package/_config.yml +599 -246
  3. package/languages/en.yml +7 -0
  4. package/languages/zh-CN.yml +13 -2
  5. package/languages/zh-TW.yml +7 -0
  6. package/layout/404.ejs +1 -1
  7. package/layout/_meta/author.ejs +4 -4
  8. package/layout/_meta/category.ejs +11 -8
  9. package/layout/_meta/counter.ejs +29 -7
  10. package/layout/_meta/date.ejs +1 -1
  11. package/layout/_meta/music.ejs +1 -1
  12. package/layout/_meta/share.ejs +1 -1
  13. package/layout/_meta/tags.ejs +3 -0
  14. package/layout/_meta/thumbnail.ejs +3 -1
  15. package/layout/_meta/updated.ejs +1 -1
  16. package/layout/_meta/walinecount.ejs +2 -1
  17. package/layout/{_cover → _partial/_cover}/blank.ejs +0 -0
  18. package/layout/{_cover → _partial/_cover}/dock.ejs +1 -1
  19. package/layout/{_cover → _partial/_cover}/featured.ejs +1 -1
  20. package/layout/{_cover → _partial/_cover}/focus.ejs +1 -1
  21. package/layout/_partial/_cover/layout.ejs +8 -0
  22. package/layout/{_cover → _partial/_cover}/search.ejs +2 -2
  23. package/layout/_partial/archive.ejs +2 -2
  24. package/layout/_partial/article.ejs +21 -16
  25. package/layout/_partial/categories.ejs +1 -1
  26. package/layout/_partial/cover.ejs +8 -28
  27. package/layout/_partial/footer.ejs +19 -11
  28. package/layout/_partial/head.ejs +70 -116
  29. package/layout/_partial/header.ejs +17 -11
  30. package/layout/_partial/meta.ejs +18 -4
  31. package/layout/_partial/post.ejs +35 -9
  32. package/layout/_partial/scripts/_ctrl/cdnCtrl.ejs +126 -0
  33. package/layout/_partial/scripts/{coverCtrl.ejs → _ctrl/coverCtrl.ejs} +17 -25
  34. package/layout/_partial/scripts/_ctrl.ejs +2 -0
  35. package/layout/_partial/scripts/content-visibility-scroll-fix.ejs +88 -0
  36. package/layout/_partial/scripts/global.ejs +422 -109
  37. package/layout/_partial/scripts/index.ejs +91 -46
  38. package/layout/_partial/scripts/toc.ejs +98 -68
  39. package/layout/_partial/side.ejs +4 -1
  40. package/layout/_plugins/_page_plugins/artitalk/index.ejs +15 -0
  41. package/layout/_plugins/_page_plugins/bbtalk/index.ejs +10 -0
  42. package/layout/_plugins/_page_plugins/fcircle/index.ejs +12 -0
  43. package/layout/_plugins/_page_plugins/gitter/index.ejs +14 -0
  44. package/layout/_plugins/_page_plugins/indent/index.ejs +16 -0
  45. package/layout/_plugins/_page_plugins/index.ejs +27 -0
  46. package/layout/_plugins/_page_plugins/katex/index.ejs +13 -0
  47. package/layout/{_third-party/math/mathjax/script.ejs → _plugins/_page_plugins/mathjax/index.ejs} +2 -2
  48. package/layout/_plugins/_page_plugins/snackbar/index.ejs +55 -0
  49. package/layout/{_partial/scripts/counter.ejs → _plugins/analytics/LCCounter.ejs} +0 -0
  50. package/layout/{_third-party → _plugins}/analytics/script.ejs +43 -5
  51. package/layout/{_third-party → _plugins}/aplayer/layout.ejs +0 -0
  52. package/layout/_plugins/aplayer/script.ejs +74 -0
  53. package/layout/_plugins/chat/gitter/script.ejs +17 -0
  54. package/layout/_plugins/chat/index.ejs +1 -0
  55. package/layout/_plugins/chat/tidio/script.ejs +1 -0
  56. package/layout/_plugins/comments/artalk/script.ejs +59 -0
  57. package/layout/_plugins/comments/beaudar/script.ejs +61 -0
  58. package/layout/_plugins/comments/discuss/script.ejs +30 -0
  59. package/layout/_plugins/comments/disqus/script.ejs +98 -0
  60. package/layout/_plugins/comments/disqusjs/script.ejs +35 -0
  61. package/layout/_plugins/comments/giscus/script.ejs +47 -0
  62. package/layout/_plugins/comments/gitalk/script.ejs +24 -0
  63. package/layout/_plugins/comments/hashover/script.ejs +5 -0
  64. package/layout/{_third-party → _plugins}/comments/index.ejs +10 -3
  65. package/layout/_plugins/comments/isso/script.ejs +27 -0
  66. package/layout/_plugins/comments/livere/script.ejs +15 -0
  67. package/layout/_plugins/comments/twikoo/script.ejs +40 -0
  68. package/layout/_plugins/comments/utterances/script.ejs +43 -0
  69. package/layout/_plugins/comments/vssue/script.ejs +37 -0
  70. package/layout/_plugins/comments/waline/script.ejs +62 -0
  71. package/layout/_plugins/comments/z-custom/script.ejs +1 -0
  72. package/layout/_plugins/darkmode/script.ejs +114 -0
  73. package/layout/{_third-party → _plugins}/end-of-support/script.ejs +25 -8
  74. package/layout/_plugins/github-api/script.ejs +27 -0
  75. package/layout/_plugins/highlight/highlightjs/script.ejs +26 -0
  76. package/layout/_plugins/highlight/prismjs/script.ejs +25 -0
  77. package/layout/_plugins/highlight/script.ejs +1 -0
  78. package/layout/{_third-party → _plugins}/lazyload/script.ejs +1 -1
  79. package/layout/{_third-party → _plugins}/nodewaves/script.ejs +1 -1
  80. package/layout/_plugins/parallax/script.ejs +74 -0
  81. package/layout/{_third-party → _plugins}/pjax/animate.ejs +31 -31
  82. package/layout/_plugins/pjax/index.ejs +73 -0
  83. package/layout/_plugins/pjax/pdata.ejs +56 -0
  84. package/layout/{_third-party → _plugins}/preload/script.ejs +3 -3
  85. package/layout/_plugins/rightmenu/layout.ejs +119 -0
  86. package/layout/_plugins/rightmenus/layout.ejs +137 -0
  87. package/layout/_plugins/scrollreveal/script.ejs +25 -0
  88. package/layout/_plugins/search/script.ejs +50 -0
  89. package/layout/{_third-party → _plugins}/share/layout.ejs +0 -0
  90. package/layout/_plugins/swiper/script.ejs +37 -0
  91. package/layout/_pre.ejs +2 -2
  92. package/layout/_widget/_pre.ejs +5 -0
  93. package/layout/_widget/blogger.ejs +1 -1
  94. package/layout/_widget/category.ejs +2 -2
  95. package/layout/_widget/copyright.ejs +1 -1
  96. package/layout/_widget/grid.ejs +3 -3
  97. package/layout/_widget/lastupdate.ejs +27 -0
  98. package/layout/_widget/list.ejs +2 -2
  99. package/layout/_widget/load.ejs +18 -0
  100. package/layout/_widget/music.ejs +3 -2
  101. package/layout/_widget/page.ejs +1 -1
  102. package/layout/_widget/qrcode.ejs +1 -1
  103. package/layout/_widget/related_posts.ejs +1 -1
  104. package/layout/_widget/tagcloud.ejs +1 -1
  105. package/layout/_widget/text.ejs +1 -1
  106. package/layout/_widget/toc.ejs +6 -2
  107. package/layout/_widget/webinfo.ejs +13 -76
  108. package/layout/archive.ejs +4 -4
  109. package/layout/category.ejs +9 -4
  110. package/layout/docs.ejs +1 -1
  111. package/layout/friends.ejs +6 -25
  112. package/layout/index.ejs +1 -1
  113. package/layout/layout.ejs +30 -12
  114. package/layout/list.ejs +1 -1
  115. package/layout/page.ejs +1 -1
  116. package/layout/post.ejs +1 -1
  117. package/layout/tag.ejs +8 -3
  118. package/package.json +5 -3
  119. package/scripts/events/index.js +13 -0
  120. package/scripts/events/lib/check-configuration.js +43 -0
  121. package/scripts/events/lib/check-environment.js +74 -0
  122. package/scripts/events/lib/config.js +34 -9
  123. package/scripts/events/lib/render-stylus.js +78 -0
  124. package/scripts/events/lib/stellar-tag-utils.js +76 -0
  125. package/scripts/filters/content-visibility.js +25 -0
  126. package/scripts/{render → filters}/img.js +0 -0
  127. package/scripts/filters/replace.js +15 -0
  128. package/scripts/{z-lazyload/lib/process.js → filters/z-lazyload.js} +6 -3
  129. package/scripts/helpers/custom-files.js +165 -0
  130. package/scripts/helpers/first-style.js +19 -0
  131. package/scripts/helpers/head/autoCanonical.js +15 -0
  132. package/scripts/helpers/head/generate_preload_fontfamily.js +22 -0
  133. package/scripts/helpers/head/generate_seo.js +24 -0
  134. package/scripts/helpers/head/generate_title__keywords__description.js +101 -0
  135. package/scripts/{related_posts/index.js → helpers/related-posts.js} +1 -1
  136. package/scripts/helpers/revisioned.js +158 -0
  137. package/scripts/helpers/structured-data/index.js +2 -0
  138. package/scripts/helpers/structured-data/lib/blogposting.js +77 -0
  139. package/scripts/helpers/structured-data/lib/breadcrumblist.js +152 -0
  140. package/scripts/helpers/structured-data/lib/config.js +31 -0
  141. package/scripts/helpers/structured-data/lib/index.js +30 -0
  142. package/scripts/helpers/structured-data/lib/organization.js +15 -0
  143. package/scripts/helpers/structured-data/lib/person.js +16 -0
  144. package/scripts/helpers/structured-data/lib/website.js +42 -0
  145. package/scripts/tags/btn.js +6 -1
  146. package/scripts/tags/btns.js +7 -2
  147. package/scripts/tags/checkbox.js +12 -2
  148. package/scripts/tags/contributors.js +100 -0
  149. package/scripts/tags/dropmenu.js +18 -3
  150. package/scripts/tags/fancybox.js +44 -10
  151. package/scripts/tags/folding.js +6 -1
  152. package/scripts/tags/frame.js +6 -1
  153. package/scripts/tags/friends.js +99 -0
  154. package/scripts/tags/ghcard.js +6 -1
  155. package/scripts/tags/image.js +14 -2
  156. package/scripts/tags/link.js +6 -1
  157. package/scripts/tags/md.js +59 -0
  158. package/scripts/tags/media.js +25 -1
  159. package/scripts/tags/note.js +36 -3
  160. package/scripts/tags/site.js +87 -51
  161. package/scripts/tags/span.js +12 -2
  162. package/scripts/tags/swiper.js +38 -0
  163. package/scripts/tags/tabs.js +33 -3
  164. package/scripts/tags/timeline.js +6 -1
  165. package/source/css/Readme.md +28 -0
  166. package/source/css/_defines/AutoPrefixCSS.styl +347 -0
  167. package/source/css/_defines/Readme.md +3 -0
  168. package/source/css/_defines/color.styl +41 -1
  169. package/source/css/_defines/effect.styl +0 -13
  170. package/source/css/_defines/fonts.styl +17 -18
  171. package/source/css/_defines/func.styl +12 -30
  172. package/source/css/_first/base_first.styl +118 -0
  173. package/source/css/_first/{cover.styl → cover_first.styl} +113 -87
  174. package/source/css/_first/dark_first.styl +76 -0
  175. package/source/css/_first/fontfamily_first.styl +17 -0
  176. package/source/css/_first/{navbar.styl → navbar_first.styl} +4 -10
  177. package/source/css/_first/search_first.styl +12 -0
  178. package/source/css/{_base/index.styl → _style/_base/base.styl} +9 -93
  179. package/source/css/_style/_base/fontfamily_async.styl +8 -0
  180. package/source/css/{_layout → _style/_layout}/archive.styl +0 -0
  181. package/source/css/{_layout → _style/_layout}/article.styl +3 -30
  182. package/source/css/{_layout → _style/_layout}/footer.styl +0 -0
  183. package/source/css/_style/_layout/friends-simpleuser.styl +23 -0
  184. package/source/css/_style/_layout/friends-traditional.styl +81 -0
  185. package/source/css/{_layout → _style/_layout}/img.styl +0 -0
  186. package/source/css/_style/_layout/loading.styl +14 -0
  187. package/source/css/{_layout → _style/_layout}/main.styl +19 -7
  188. package/source/css/{_layout → _style/_layout}/md.styl +0 -0
  189. package/source/css/{_layout → _style/_layout}/pagination.styl +1 -1
  190. package/source/css/{_layout → _style/_layout}/posts.styl +2 -0
  191. package/source/css/{_first → _style/_layout}/search.styl +0 -103
  192. package/source/css/{_layout → _style/_layout}/sidebar.styl +23 -3
  193. package/source/css/{_layout → _style/_layout}/snackbar.styl +0 -0
  194. package/source/css/{_layout → _style/_layout}/toc.styl +3 -3
  195. package/source/css/{_layout → _style/_layout}/video.styl +0 -0
  196. package/source/css/_style/_plugins/_dark/dark_async.styl +41 -0
  197. package/source/css/_style/_plugins/_dark/dark_plugins.styl +136 -0
  198. package/source/css/_style/_plugins/_highlight/highlightjs/clipboard.styl +36 -0
  199. package/source/css/_style/_plugins/_highlight/highlightjs/color.styl +96 -0
  200. package/source/css/_style/_plugins/_highlight/highlightjs/index.styl +102 -0
  201. package/source/css/_style/_plugins/_highlight/highlightjs/language.styl +63 -0
  202. package/source/css/_style/_plugins/_highlight/index.styl +1 -0
  203. package/source/css/_style/_plugins/_highlight/prismjs/clipboard.styl +33 -0
  204. package/source/css/_style/_plugins/_highlight/prismjs/index.styl +8 -0
  205. package/source/css/_style/_plugins/_highlight/prismjs/language.styl +63 -0
  206. package/source/css/_style/_plugins/_rightmenu/reading.styl +56 -0
  207. package/source/css/{_plugins → _style/_plugins/_rightmenu}/rightmenu.styl +22 -2
  208. package/source/css/{_plugins → _style/_plugins}/aplayer.styl +8 -1
  209. package/source/css/{_plugins → _style/_plugins}/cursor.styl +49 -19
  210. package/source/css/_style/_plugins/fontcolor.styl +84 -0
  211. package/source/css/{_plugins → _style/_plugins}/gitalk.styl +0 -0
  212. package/source/css/_style/_plugins/index.styl +24 -0
  213. package/source/css/{_plugins → _style/_plugins}/mathjax.styl +0 -0
  214. package/source/css/_style/_plugins/message.styl +14 -0
  215. package/source/css/{_plugins → _style/_plugins}/pjaxanimate.styl +0 -0
  216. package/source/css/_style/_tag-plugins/Readme.md +6 -0
  217. package/source/css/{_tag-plugins → _style/_tag-plugins}/btns.styl +0 -0
  218. package/source/css/{_tag-plugins → _style/_tag-plugins}/checkbox.styl +0 -0
  219. package/source/css/{_tag-plugins → _style/_tag-plugins}/dropmenu.styl +0 -0
  220. package/source/css/{_plugins → _style/_tag-plugins}/fancybox.styl +8 -9
  221. package/source/css/{_tag-plugins → _style/_tag-plugins}/folding.styl +0 -0
  222. package/source/css/{_tag-plugins → _style/_tag-plugins}/frame.styl +0 -0
  223. package/source/css/_style/_tag-plugins/friends.styl +72 -0
  224. package/source/css/{_tag-plugins → _style/_tag-plugins}/ghcard.styl +0 -0
  225. package/source/css/{_tag-plugins → _style/_tag-plugins}/image.styl +0 -0
  226. package/source/css/{_tag-plugins → _style/_tag-plugins}/link.styl +0 -0
  227. package/source/css/{_tag-plugins → _style/_tag-plugins}/media.styl +0 -0
  228. package/source/css/{_tag-plugins → _style/_tag-plugins}/note.styl +0 -0
  229. package/source/css/_style/_tag-plugins/sites.styl +87 -0
  230. package/source/css/{_tag-plugins → _style/_tag-plugins}/span.styl +0 -0
  231. package/source/css/_style/_tag-plugins/swiper.styl +44 -0
  232. package/source/css/{_tag-plugins → _style/_tag-plugins}/table.styl +0 -0
  233. package/source/css/{_tag-plugins → _style/_tag-plugins}/tabs.styl +0 -0
  234. package/source/css/_style/_tag-plugins/tag.json +35 -0
  235. package/source/css/_style/_tag-plugins/text.styl +31 -0
  236. package/source/css/{_tag-plugins → _style/_tag-plugins}/timeline.styl +0 -0
  237. package/source/css/_style/index.styl +8 -0
  238. package/source/css/first.styl +17 -6
  239. package/source/css/style.styl +9 -7
  240. package/source/js/app.js +1051 -278
  241. package/source/js/plugins/aplayer.js +186 -0
  242. package/source/js/plugins/parallax.js +191 -0
  243. package/source/js/plugins/rightMenu.js +577 -0
  244. package/source/js/plugins/rightMenus.js +616 -0
  245. package/source/js/plugins/tags/contributors.js +92 -0
  246. package/source/js/plugins/tags/friends.js +93 -0
  247. package/source/js/plugins/tags/sites.js +96 -0
  248. package/source/js/search/hexo.js +180 -373
  249. package/.eslintrc.json +0 -111
  250. package/layout/_meta/valinecount.ejs +0 -15
  251. package/layout/_partial/rightmenu.ejs +0 -199
  252. package/layout/_partial/scripts/cover.ejs +0 -45
  253. package/layout/_partial/scripts/darkmode.ejs +0 -85
  254. package/layout/_partial/scripts/import.ejs +0 -3
  255. package/layout/_partial/scripts/issues.ejs +0 -18
  256. package/layout/_partial/scripts/search.ejs +0 -62
  257. package/layout/_partial/snackbar.ejs +0 -22
  258. package/layout/_third-party/aplayer/script.ejs +0 -26
  259. package/layout/_third-party/clipboard/script.ejs +0 -54
  260. package/layout/_third-party/comments/disqus/layout.ejs +0 -5
  261. package/layout/_third-party/comments/disqus/script.ejs +0 -90
  262. package/layout/_third-party/comments/disqusjs/layout.ejs +0 -1
  263. package/layout/_third-party/comments/disqusjs/script.ejs +0 -34
  264. package/layout/_third-party/comments/gitalk/layout.ejs +0 -1
  265. package/layout/_third-party/comments/gitalk/script.ejs +0 -22
  266. package/layout/_third-party/comments/hashover/layout.ejs +0 -2
  267. package/layout/_third-party/comments/hashover/script.ejs +0 -1
  268. package/layout/_third-party/comments/isso/layout.ejs +0 -1
  269. package/layout/_third-party/comments/isso/script.ejs +0 -1
  270. package/layout/_third-party/comments/livere/layout.ejs +0 -3
  271. package/layout/_third-party/comments/livere/script.ejs +0 -10
  272. package/layout/_third-party/comments/minivaline/layout.ejs +0 -3
  273. package/layout/_third-party/comments/minivaline/script.ejs +0 -34
  274. package/layout/_third-party/comments/twikoo/layout.ejs +0 -3
  275. package/layout/_third-party/comments/twikoo/script.ejs +0 -32
  276. package/layout/_third-party/comments/valine/layout.ejs +0 -3
  277. package/layout/_third-party/comments/valine/script.ejs +0 -49
  278. package/layout/_third-party/comments/vssue/layout.ejs +0 -1
  279. package/layout/_third-party/comments/vssue/script.ejs +0 -21
  280. package/layout/_third-party/comments/waline/layout.ejs +0 -3
  281. package/layout/_third-party/comments/waline/script.ejs +0 -33
  282. package/layout/_third-party/fancybox/script.ejs +0 -61
  283. package/layout/_third-party/highlightjs/script.ejs +0 -11
  284. package/layout/_third-party/pjax/index.ejs +0 -78
  285. package/layout/_third-party/pjax/pdata.ejs +0 -53
  286. package/layout/_third-party/scrollreveal/script.ejs +0 -21
  287. package/layout/_third-party/tidio/script.ejs +0 -3
  288. package/layout/artitalk.ejs +0 -13
  289. package/layout/bb.ejs +0 -10
  290. package/package-lock.json +0 -916
  291. package/scripts/tags/issues.js +0 -41
  292. package/scripts/z-lazyload/index.js +0 -4
  293. package/source/css/_highlight/index.styl +0 -316
  294. package/source/css/_layout/friends.styl +0 -79
  295. package/source/css/_plugins/clipboard.styl +0 -37
  296. package/source/css/_plugins/dark.styl +0 -149
  297. package/source/css/_plugins/darkmode.styl +0 -9
  298. package/source/css/_plugins/index.styl +0 -18
  299. package/source/css/_plugins/twikoo.styl +0 -21
  300. package/source/css/_plugins/valine.styl +0 -183
  301. package/source/css/_tag-plugins/simpleuser.styl +0 -21
  302. package/source/css/_tag-plugins/site-card.styl +0 -70
  303. package/source/js/aplayer.js +0 -167
  304. package/source/js/issues.js +0 -186
  305. package/source/js/search/algolia.js +0 -344
  306. package/source/js/search/azure.js +0 -355
  307. package/source/js/search/baidu.js +0 -340
  308. package/source/js/search/google.js +0 -339
  309. package/source/js/valine.js +0 -5137
@@ -0,0 +1,158 @@
1
+ // hexo g 执行 hexo s 跳出
2
+
3
+ // https://blog.imkero.com/posts/hexo-page-performance.html#静态资源版本控制
4
+
5
+
6
+ const minimatch = require("minimatch");
7
+ const crypto = require('crypto');
8
+
9
+ const stream2buffer = (stream) => {
10
+ if(!stream) return;
11
+ return new Promise((resolve, reject) => {
12
+ const _buf = [];
13
+ stream.on("data", (chunk) => _buf.push(chunk));
14
+ stream.on("end", () => resolve(Buffer.concat(_buf)));
15
+ stream.on("error", (err) => reject(err));
16
+ });
17
+ };
18
+
19
+ const readFileAsBuffer = (filePath) => {
20
+ return stream2buffer(hexo.route.get(filePath));
21
+ };
22
+
23
+ const readFileAsString = async (filePath) => {
24
+ const buffer = await readFileAsBuffer(filePath);
25
+ return buffer.toString();
26
+ };
27
+
28
+ const parseFilePath = (filePath) => {
29
+ const parts = filePath.split("/");
30
+ const originalFileName = parts[parts.length - 1];
31
+
32
+ const dotPosition = originalFileName.lastIndexOf(".");
33
+
34
+ const dirname = parts.slice(0, parts.length - 1).join("/");
35
+ const basename =
36
+ dotPosition === -1
37
+ ? originalFileName
38
+ : originalFileName.substring(0, dotPosition);
39
+ const extension =
40
+ dotPosition === -1 ? "" : originalFileName.substring(dotPosition);
41
+
42
+ return [dirname, basename, extension];
43
+ };
44
+
45
+ const genFilePath = (dirname, basename, extension) => {
46
+ let dirPrefix = "";
47
+ if (dirname) {
48
+ dirPrefix += dirname + "/";
49
+ }
50
+
51
+ if (extension && !extension.startsWith(".")) {
52
+ extension = "." + extension;
53
+ }
54
+
55
+ return dirPrefix + basename + extension;
56
+ };
57
+
58
+ const getRevisionedFilePath = (filePath, revision) => {
59
+ const [dirname, basename, extension] = parseFilePath(filePath);
60
+ return genFilePath(dirname, `${basename}.${revision}`, extension);
61
+ };
62
+
63
+ const revisioned = (filePath) => {
64
+ if (!hexo.theme.config.cdn_version) {
65
+ return;
66
+ }
67
+ let arg = process.argv[2];
68
+ if (arg == "s" || arg == "server") {
69
+ return filePath
70
+ }
71
+ return getRevisionedFilePath(filePath, `!!revision:${filePath}!!`);
72
+ };
73
+
74
+ hexo.extend.helper.register("revisioned", revisioned);
75
+
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;
80
+ };
81
+
82
+ const replaceRevisionPlaceholder = async () => {
83
+
84
+ if (!hexo.theme.config.cdn_version) {
85
+ return;
86
+ }
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");
128
+ }
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
+ }
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
+ );
156
+ };
157
+
158
+ hexo.extend.filter.register("after_generate", replaceRevisionPlaceholder,999999999999999999999999999999999999);
@@ -0,0 +1,2 @@
1
+ /*globals hexo */
2
+ hexo.extend.helper.register("structured_data", require('./lib/'));
@@ -0,0 +1,77 @@
1
+ module.exports = (hexo, option) => {
2
+ const { config, page: post } = hexo;
3
+
4
+ const blogposting = {
5
+ "@context": "http://schema.org",
6
+ "@type": "BlogPosting",
7
+ headline: post.title || post.seo_title,
8
+ description: post.description || hexo.strip_html(post.excerpt) || config.description,
9
+ inLanguage: config.language,
10
+ mainEntityOfPage: {
11
+ "@type": "WebPage",
12
+ "@id": post.permalink,
13
+ },
14
+ author: {
15
+ "@type": "Person",
16
+ name: option.person.name,
17
+ image: {
18
+ "@type": "ImageObject",
19
+ url: option.logo.path,
20
+ },
21
+ url: option.person.url,
22
+ },
23
+ publisher: {
24
+ "@type": "Organization",
25
+ name: option.organization.name,
26
+ logo: {
27
+ "@type": "ImageObject",
28
+ url: option.logo.path,
29
+ width: option.logo.width,
30
+ height: option.logo.height,
31
+ },
32
+ },
33
+ url: post.permalink,
34
+ };
35
+
36
+ blogposting.wordCount = hexo.strip_html(post.excerpt).length;
37
+
38
+ if (post.date) {
39
+ blogposting.datePublished = post.date.toISOString();
40
+ }
41
+ if (post.updated) {
42
+ blogposting.dateModified = post.updated.toISOString();
43
+ }
44
+ if (post.categories && post.categories.length) {
45
+ if (post.categories.data) {
46
+ blogposting.articleSection = post.categories.data[0].name;
47
+ } else {
48
+ blogposting.articleSection = post.categories[0];
49
+ }
50
+ }
51
+
52
+ if (post.tags && post.tags.length) {
53
+ if (post.tags.data) {
54
+ blogposting.keywords = post.tags.map((tag) => tag.name).join(",");
55
+ } else {
56
+ blogposting.keywords = post.tags.map((tag) => tag).join(",");
57
+ }
58
+ }
59
+ let image = post.headimg || "";
60
+ if (image) {
61
+ blogposting.image = {
62
+ "@type": "ImageObject",
63
+ url: image,
64
+ width: 1024,
65
+ height: 768,
66
+ };
67
+ }else{
68
+ blogposting.image = {
69
+ "@type": "ImageObject",
70
+ url: option.logo.path,
71
+ width: option.logo.width,
72
+ height: option.logo.height,
73
+ };
74
+ }
75
+
76
+ return blogposting;
77
+ };
@@ -0,0 +1,152 @@
1
+ module.exports = (hexo, option) => {
2
+ const { config, page } = hexo;
3
+
4
+ const breadcrumb = {
5
+ "@context": "http://schema.org",
6
+ "@type": "BreadcrumbList",
7
+ itemListElement: [
8
+ {
9
+ "@type": "ListItem",
10
+ position: 1,
11
+ item: {
12
+ "@id": config.url + config.root,
13
+ name: config.title,
14
+ },
15
+ },
16
+ ],
17
+ };
18
+
19
+ if (hexo.is_category()) {
20
+ let { category_dir, category_map: map } = config;
21
+ if (!Array.isArray(map)) map = [];
22
+ if (category_dir === "/") category_dir = "";
23
+ if (category_dir.slice(-1) !== "/") category_dir += "/";
24
+ const category_path =
25
+ category_dir + (map[page.category] || page.category) + "/";
26
+
27
+ breadcrumb.itemListElement.push({
28
+ "@type": "ListItem",
29
+ position: 2,
30
+ item: {
31
+ "@id": config.url + config.root + category_path,
32
+ name: page.category,
33
+ },
34
+ });
35
+ }
36
+
37
+ if (hexo.is_tag()) {
38
+ let { tag_dir, tag_map: map } = config;
39
+ if (!Array.isArray(map)) map = [];
40
+ if (tag_dir === "/") tag_dir = "";
41
+ if (tag_dir.slice(-1) !== "/") tag_dir += "/";
42
+ const tag_path = tag_dir + (map[page.tag] || page.tag) + "/";
43
+
44
+ breadcrumb.itemListElement.push({
45
+ "@type": "ListItem",
46
+ position: 2,
47
+ item: {
48
+ "@id": config.url + config.root + tag_path,
49
+ name: page.tag,
50
+ },
51
+ });
52
+ }
53
+
54
+ if (hexo.is_archive()) {
55
+ let { archive_dir } = config;
56
+ if (archive_dir.slice(-1) !== "/") archive_dir += "/";
57
+
58
+ breadcrumb.itemListElement.push({
59
+ "@type": "ListItem",
60
+ position: 2,
61
+ item: {
62
+ "@id": config.url + config.root + archive_dir,
63
+ name: "Archive",
64
+ },
65
+ });
66
+ let timezone = config.timezone || "Asia/Shanghai";
67
+ if (hexo.is_year()) {
68
+ const dtf = new Intl.DateTimeFormat(config.language, {
69
+ year: "numeric",
70
+ timeZone: timezone,
71
+ });
72
+ breadcrumb.itemListElement.push({
73
+ "@type": "ListItem",
74
+ position: 3,
75
+ item: {
76
+ "@id": config.url + config.root + archive_dir + page.year + "/",
77
+ name: dtf.format(new Date(page.year, 0, 1)),
78
+ },
79
+ });
80
+ }
81
+
82
+ if (hexo.is_month()) {
83
+ const dtf = new Intl.DateTimeFormat(config.language, {
84
+ month: "numeric",
85
+ timeZone: timezone,
86
+ });
87
+ breadcrumb.itemListElement.push({
88
+ "@type": "ListItem",
89
+ position: 4,
90
+ item: {
91
+ "@id":
92
+ config.url +
93
+ config.root +
94
+ archive_dir +
95
+ page.year +
96
+ "/" +
97
+ page.month +
98
+ "/",
99
+ name: dtf.format(new Date(page.year, page.month - 1, 1)),
100
+ },
101
+ });
102
+ }
103
+ }
104
+
105
+ if (hexo.is_post()) {
106
+ page.categories.data.forEach((category) =>
107
+ breadcrumb.itemListElement.push({
108
+ "@type": "ListItem",
109
+ position: 2,
110
+ item: {
111
+ "@id": config.url + config.root + category.path,
112
+ name: category.name,
113
+ },
114
+ })
115
+ );
116
+
117
+ breadcrumb.itemListElement.push({
118
+ "@type": "ListItem",
119
+ position: 3,
120
+ item: {
121
+ "@id": config.url + config.root + page.path,
122
+ name: page.title || page.seo_title,
123
+ },
124
+ });
125
+ }
126
+
127
+ if (hexo.is_page()&&page.categories) {
128
+ let temp = "/"
129
+ for (let index = 0; index < page.categories.length; index++) {
130
+ const cat = page.categories[index];
131
+ temp = temp + cat + "/"
132
+ breadcrumb.itemListElement.push({
133
+ "@type": "ListItem",
134
+ position: 2,
135
+ item: {
136
+ "@id": config.url + config.root + config.category_dir + temp,
137
+ name: cat,
138
+ },
139
+ })
140
+ }
141
+ breadcrumb.itemListElement.push({
142
+ "@type": "ListItem",
143
+ position: 3,
144
+ item: {
145
+ "@id": config.url + config.root + page.path,
146
+ name: page.title || page.seo_title,
147
+ },
148
+ });
149
+ }
150
+
151
+ return breadcrumb;
152
+ };
@@ -0,0 +1,31 @@
1
+ module.exports = function (hexo) {
2
+ const {config} = hexo;
3
+ return {
4
+ person: {
5
+ name: config.author,
6
+ url: config.url + config.root,
7
+ sns: [],
8
+ description: config.description,
9
+ },
10
+ logo: {
11
+ path: /404/,
12
+ width: 192,
13
+ height: 192,
14
+ },
15
+ organization: {
16
+ name: config.title,
17
+ url: config.url + config.root,
18
+ },
19
+ website: {
20
+ name: config.title,
21
+ url: config.url + config.root,
22
+ keywords: config.keywords,
23
+ description: config.description,
24
+ search: {
25
+ name: "Site Search",
26
+ url: config.url + "?s={search_term_string}",
27
+ query: "required name=search_term_string",
28
+ },
29
+ },
30
+ };
31
+ };
@@ -0,0 +1,30 @@
1
+ const config = require("./config");
2
+
3
+ const WebSite = require("./website");
4
+ const Organization = require("./organization");
5
+ const Person = require("./person");
6
+ const BlogPosting = require("./blogposting");
7
+ const BreadcrumbList = require("./breadcrumblist");
8
+
9
+ function isObject(item) {
10
+ return item && typeof item === 'object' && !Array.isArray(item);
11
+ }
12
+
13
+ function merge(target, source) {
14
+ for (const key in source) {
15
+ if (isObject(target[key]) && isObject(source[key])) {
16
+ merge(target[key], source[key]);
17
+ } else {
18
+ target[key] = source[key];
19
+ }
20
+ }
21
+ return target;
22
+ }
23
+
24
+ module.exports = function () {
25
+ const hexo = this;
26
+ const option = merge(config(hexo), hexo.theme.structured_data.data);
27
+ const builder = [Organization, Person, BreadcrumbList, WebSite, BlogPosting];
28
+ const jsonld = JSON.stringify(builder.map((f) => f(hexo, option)));
29
+ return `<script type="application/ld+json">${jsonld}</script>`;
30
+ };
@@ -0,0 +1,15 @@
1
+
2
+ module.exports = (hexo, option) => {
3
+ return {
4
+ "@context": "http://schema.org",
5
+ "@type": "Organization",
6
+ "name": option.organization.name,
7
+ "url": option.organization.url,
8
+ "logo": {
9
+ "@type": "ImageObject",
10
+ "url": option.logo.path,
11
+ "width": option.logo.width,
12
+ "height": option.logo.height
13
+ }
14
+ };
15
+ };
@@ -0,0 +1,16 @@
1
+ module.exports = (hexo, option) => {
2
+ const { config } = hexo;
3
+
4
+ return {
5
+ "@context": "http://schema.org",
6
+ "@type": "Person",
7
+ name: option.person.name,
8
+ image: {
9
+ "@type": "ImageObject",
10
+ url: option.logo.path,
11
+ },
12
+ url: option.person.url,
13
+ sameAs: option.person.sns,
14
+ description: option.person.description,
15
+ };
16
+ };
@@ -0,0 +1,42 @@
1
+ module.exports = (hexo,option) => {
2
+ const { config } = hexo;
3
+
4
+ return {
5
+ "@context": "http://schema.org",
6
+ "@type": "WebSite",
7
+ name: option.website.name,
8
+ url: option.website.url,
9
+ keywords: option.website.keywords,
10
+ description: option.website.description,
11
+ author: {
12
+ "@type": "Person",
13
+ name: option.person.name,
14
+ image: {
15
+ "@type": "ImageObject",
16
+ url: option.logo.path,
17
+ },
18
+ url: option.person.url,
19
+ description: option.person.description,
20
+ },
21
+ publisher: {
22
+ "@type": "Organization",
23
+ name: option.organization.name,
24
+ url: option.organization.url,
25
+ logo: {
26
+ "@type": "ImageObject",
27
+ url: option.logo.path,
28
+ width: option.logo.width,
29
+ height: option.logo.height,
30
+ },
31
+ },
32
+ potentialAction: {
33
+ "@type": "SearchAction",
34
+ name: option.website.search.name,
35
+ target: {
36
+ "@type": "EntryPoint",
37
+ urlTemplate: option.website.search.url,
38
+ },
39
+ "query-input": option.website.search.query,
40
+ },
41
+ };
42
+ };
@@ -1,7 +1,12 @@
1
1
  'use strict';
2
2
 
3
3
  function postBtn(args) {
4
- args = args.join(' ').split(',');
4
+ if(/::/g.test(args)){
5
+ args = args.join(' ').split('::');
6
+ }
7
+ else{
8
+ args = args.join(' ').split(',');
9
+ }
5
10
  let cls = '';
6
11
  let text = '';
7
12
  let url = '';
@@ -7,7 +7,12 @@ function postBtns(args, content) {
7
7
  }
8
8
 
9
9
  function postCell(args, content) {
10
- args = args.join(' ').split(',');
10
+ if(/::/g.test(args)){
11
+ args = args.join(' ').split('::');
12
+ }
13
+ else{
14
+ args = args.join(' ').split(',');
15
+ }
11
16
  let text = args[0] || '';
12
17
  let url = args[1] || '';
13
18
  text = text.trim();
@@ -16,7 +21,7 @@ function postCell(args, content) {
16
21
  url = 'href=\'' + url + '\'';
17
22
  }
18
23
  let icon = '';
19
- let img = 'https://cdn.jsdelivr.net/gh/volantis-x/cdn-volantis@3/img/placeholder/d570170f4f12e1ee829ca0e85a7dffeb77343a.svg';
24
+ let img = hexo.theme.config.default.image;
20
25
  if (args.length > 2) {
21
26
  if (args[2].indexOf(' fa-') > -1) {
22
27
  icon = args[2].trim();
@@ -1,7 +1,12 @@
1
1
  'use strict';
2
2
 
3
3
  function postCheckbox(args) {
4
- args = args.join(' ').split(',');
4
+ if(/::/g.test(args)){
5
+ args = args.join(' ').split('::');
6
+ }
7
+ else{
8
+ args = args.join(' ').split(',');
9
+ }
5
10
  var cls = '';
6
11
  var text = '';
7
12
  var checked = false;
@@ -24,7 +29,12 @@ function postCheckbox(args) {
24
29
  }
25
30
  }
26
31
  function postRadio(args) {
27
- args = args.join(' ').split(',');
32
+ if(/::/g.test(args)){
33
+ args = args.join(' ').split('::');
34
+ }
35
+ else{
36
+ args = args.join(' ').split(',');
37
+ }
28
38
  var cls = '';
29
39
  var text = '';
30
40
  var checked = false;
@@ -0,0 +1,100 @@
1
+ /**
2
+ * friends.js v1 | https://github.com/xaoxuu/hexo-theme-stellar/
3
+ * 格式与官方标签插件一致使用空格分隔,中括号内的是可选参数(中括号不需要写出来)
4
+ *
5
+ * {% friends [only:group1] [not:group2] %}
6
+ */
7
+
8
+ 'use strict';
9
+
10
+ hexo.extend.tag.register('contributors', function(args) {
11
+ args = hexo.args.map(args, ['only', 'not', 'api', 'source', 'repo']);
12
+ if (args.only) {
13
+ if(/::/g.test(args.only)){
14
+ args.only = args.only.split('::');
15
+ }else{
16
+ args.only = args.only.split(',');
17
+ }
18
+ }
19
+ if (args.not) {
20
+ if(/::/g.test(args.not)){
21
+ args.not = args.not.split('::');
22
+ }else{
23
+ args.not = args.not.split(',');
24
+ }
25
+ }
26
+ var friends = hexo.locals.get('data').contributors;
27
+ if (friends == undefined) {
28
+ friends = {};
29
+ }
30
+ if (args.repo) {
31
+ friends = {
32
+ group: {
33
+ api: args.api || 'https://gh-api.xaoxuu.com',
34
+ source: args.source || 'volantis-x/github-api',
35
+ repo: args.repo
36
+ }
37
+ }
38
+ }
39
+ var el = '<div class="tag-plugin users-wrap">';
40
+ function groupHeader(group) {
41
+ var header = '<div class="group-header">';
42
+ if (group.title) {
43
+ header += hexo.render.renderSync({text: group.title, engine: 'markdown'}).split('\n').join('');
44
+ }
45
+ if (group.description) {
46
+ header += hexo.render.renderSync({text: group.description, engine: 'markdown'}).split('\n').join('');
47
+ }
48
+ header += '</div>';
49
+ return header;
50
+ }
51
+ function cell(friend) {
52
+ if (friend.url && friend.title) {
53
+ var cell = '<div class="user-card">';
54
+ cell += '<a class="card-link" target="_blank" rel="external noopener noreferrer" href="' + friend.url + '">';
55
+ cell += '<img src="' + (friend.avatar || hexo.theme.config.default.avatar) + '" onerror="errorImgAvatar(this)"/>';
56
+ cell += '<div class="name"><span>' + friend.title + '</span></div>';
57
+ cell += '</a></div>'
58
+ return cell;
59
+ } else {
60
+ return '';
61
+ }
62
+ }
63
+ for (let groupId of Object.keys(friends)) {
64
+ function f() {
65
+ if (args.not && args.not.includes(groupId)) {
66
+ return;
67
+ }
68
+ if (groupId in friends) {
69
+ let group = friends[groupId];
70
+ if (group.title || group.description) {
71
+ el += groupHeader(group);
72
+ }
73
+ if (group.repo) {
74
+ el += '<div class="contributorsjs-wrap"';
75
+ el += ' id="contributors-api"';
76
+ el += ' api="' + group.api + '/v1/contributors?source=' + group.source + '&target=' + group.repo + '"';
77
+ el += '>';
78
+ el += '<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>';
79
+ el += '<div class="group-body"></div>';
80
+ el += '</div>';
81
+ } else if (group.items) {
82
+ el += '<div class="group-body">';
83
+ group.items.forEach((friend, i) => {
84
+ el += cell(friend);
85
+ });
86
+ el += '</div>';
87
+ }
88
+ }
89
+ }
90
+ if (args.only) {
91
+ if (args.only.includes(groupId)) {
92
+ f();
93
+ }
94
+ } else {
95
+ f();
96
+ }
97
+ }
98
+ el += '</div>';
99
+ return el;
100
+ });