hexo-theme-gnix 9.0.0 → 10.0.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 (66) hide show
  1. package/README.md +4 -2
  2. package/include/hexo/feed.js +5 -5
  3. package/include/hexo/filter.js +25 -1
  4. package/include/hexo/generator/archive.js +116 -0
  5. package/include/hexo/generator/home.js +64 -0
  6. package/include/hexo/generator/index.js +82 -0
  7. package/include/hexo/generator/md_generator.js +87 -0
  8. package/include/hexo/generator/page.js +55 -0
  9. package/include/hexo/generator/tag.js +84 -0
  10. package/include/hexo/helper.js +38 -0
  11. package/include/hexo/i18n.js +183 -0
  12. package/include/util/article_font.js +132 -0
  13. package/include/util/i18n.js +280 -0
  14. package/include/util/theme.js +84 -0
  15. package/languages/en.yml +28 -0
  16. package/languages/zh-CN.yml +28 -0
  17. package/layout/archive.jsx +131 -127
  18. package/layout/common/article.jsx +283 -16
  19. package/layout/common/article_info.jsx +339 -0
  20. package/layout/common/article_media.jsx +11 -4
  21. package/layout/common/comment.jsx +15 -7
  22. package/layout/common/footer.jsx +6 -5
  23. package/layout/common/head.jsx +121 -32
  24. package/layout/common/navbar.jsx +195 -65
  25. package/layout/common/theme_selector.jsx +16 -14
  26. package/layout/layout.jsx +43 -5
  27. package/layout/misc/open_graph.jsx +162 -66
  28. package/layout/misc/paginator.jsx +2 -8
  29. package/layout/plugin/cookie_consent.jsx +252 -53
  30. package/layout/plugin/swup.jsx +1 -1
  31. package/layout/search/insight.jsx +1 -1
  32. package/layout/tag.jsx +3 -2
  33. package/layout/tags.jsx +81 -73
  34. package/package.json +5 -5
  35. package/scripts/index.js +1 -0
  36. package/source/css/archive.css +225 -180
  37. package/source/css/default.css +1162 -98
  38. package/source/css/responsive.css +426 -0
  39. package/source/css/shiki/shiki.css +12 -2081
  40. package/source/css/tags.css +183 -0
  41. package/source/css/twikoo.css +1049 -1045
  42. package/source/img/favicon.svg +1 -6
  43. package/source/img/og_image.webp +0 -0
  44. package/source/js/article-font-utils.js +99 -0
  45. package/source/js/busuanzi.js +91 -24
  46. package/source/js/components/chat.js +169 -50
  47. package/source/js/components/image-carousel.js +152 -108
  48. package/source/js/components/sidenote.js +210 -0
  49. package/source/js/components/text-image-section.js +78 -90
  50. package/source/js/components/theme-stacked.js +65 -33
  51. package/source/js/components/tree.js +30 -16
  52. package/source/js/decrypt.js +7 -2
  53. package/source/js/main.js +428 -5
  54. package/source/js/swup.js +39 -0
  55. package/source/js/theme-selector.js +26 -16
  56. package/include/hexo/generator.js +0 -53
  57. package/layout/misc/article_licensing.jsx +0 -99
  58. package/source/css/responsive/desktop.css +0 -36
  59. package/source/css/responsive/mobile.css +0 -29
  60. package/source/css/responsive/tablet.css +0 -43
  61. package/source/css/responsive/touch.css +0 -155
  62. package/source/img/logo.svg +0 -9
  63. package/source/js/archive-breadcrumb.js +0 -132
  64. package/source/js/host/cookieconsent/3.1.1/build/cookieconsent.min.css +0 -6
  65. package/source/js/host/cookieconsent/3.1.1/build/cookieconsent.min.js +0 -1
  66. package/source/js/swup.bundle.js +0 -1
@@ -1,7 +1,7 @@
1
1
  const { Component, Fragment, dateFormatters } = require("../../include/util/common");
2
2
  const Comment = require("./comment");
3
- const ArticleLicensing = require("../misc/article_licensing");
4
3
  const ArticleCover = require("./article_cover");
4
+ const ArticleInfo = require("./article_info");
5
5
 
6
6
  /**
7
7
  * Get the word count of text.
@@ -20,12 +20,14 @@ module.exports = class extends Component {
20
20
  // index: true if in article list, false if in article page
21
21
  const { config, helper, page, index } = this.props;
22
22
 
23
- const { article } = config;
24
23
  const { url_for } = helper;
25
24
 
26
25
  const cover = page.cover ? url_for(page.cover) : null;
27
26
  const wordCount = getWordCount(page._content);
28
27
  const readTime = Math.ceil(wordCount / 200); // 假设每分钟阅读200字
28
+ const hasComment = !index && config.comment && typeof config.comment.type === "string";
29
+ const translatedCommentsLabel = helper.__("article.comments");
30
+ const commentsLabel = translatedCommentsLabel === "article.comments" ? "Comments" : translatedCommentsLabel;
29
31
 
30
32
  return (
31
33
  <Fragment>
@@ -69,45 +71,310 @@ module.exports = class extends Component {
69
71
  ) : null}
70
72
  {page.title !== "" && !index ? <h1 class="article-title">{page.title}</h1> : null}
71
73
 
72
- {!index && page.excerpt && <div class="content article-excerpt" dangerouslySetInnerHTML={{ __html: page.excerpt }}></div>}
74
+ {!index && page.excerpt && <div class="article-excerpt" dangerouslySetInnerHTML={{ __html: page.excerpt }}></div>}
73
75
 
74
76
  {(index || !page.excerpt) && (
75
77
  <div
76
- class={index && page.excerpt ? "content article-excerpt" : "content"}
78
+ class={index && page.excerpt ? "article-excerpt" : "content"}
77
79
  dangerouslySetInnerHTML={{
78
80
  __html: index && page.excerpt ? page.excerpt : page.content,
79
81
  }}
80
82
  ></div>
81
83
  )}
82
84
 
83
- {page.tags?.length && (
85
+ {!index && (
86
+ <div class="article-footer article-meta-bar">
87
+ <div class="article-tags">
88
+ {page.tags?.length
89
+ ? page.tags.map((tag, i) => (
90
+ <Fragment>
91
+ {i > 0 && <span class="meta-separator">·</span>}
92
+ <a class="article-tag" rel="tag" href={helper.localized_tag_url(tag, helper.language_key(page))}>
93
+ {tag.name}
94
+ </a>
95
+ </Fragment>
96
+ ))
97
+ : null}
98
+ </div>
99
+ <div class="article-title-actions">
100
+ {hasComment && (
101
+ <button type="button" class="article-action-btn" popovertarget="article-comment-popover" aria-label={commentsLabel} title={commentsLabel}>
102
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" role="img" aria-label={commentsLabel}>
103
+ <title>{commentsLabel}</title>
104
+ <g fill="none">
105
+ <path d="m12.593 23.258l-.011.002l-.071.035l-.02.004l-.014-.004l-.071-.035q-.016-.005-.024.005l-.004.01l-.017.428l.005.02l.01.013l.104.074l.015.004l.012-.004l.104-.074l.012-.016l.004-.017l-.017-.427q-.004-.016-.017-.018m.265-.113l-.013.002l-.185.093l-.01.01l-.003.011l.018.43l.005.012l.008.007l.201.093q.019.005.029-.008l.004-.014l-.034-.614q-.005-.018-.02-.022m-.715.002a.02.02 0 0 0-.027.006l-.006.014l-.034.614q.001.018.017.024l.015-.002l.201-.093l.01-.008l.004-.011l.017-.43l-.003-.012l-.01-.01z" />
106
+ <path
107
+ fill="currentColor"
108
+ d="M16 4a3 3 0 0 1 2.995 2.824L19 7v2a3 3 0 0 1 2.995 2.824L22 12v4a3 3 0 0 1-2.824 2.995L19 19v.966c0 1.02-1.143 1.594-1.954 1.033l-.096-.072L14.638 19H11a3 3 0 0 1-1.998-.762l-.14-.134L7 19.5c-.791.593-1.906.075-1.994-.879L5 18.5V17a3 3 0 0 1-2.995-2.824L2 14V7a3 3 0 0 1 2.824-2.995L5 4zm3 7h-8a1 1 0 0 0-1 1v4a1 1 0 0 0 1 1h3.638a2 2 0 0 1 1.28.464l1.088.906A1.5 1.5 0 0 1 18.5 17h.5a1 1 0 0 0 1-1v-4a1 1 0 0 0-1-1m-3-5H5a1 1 0 0 0-1 1v7a1 1 0 0 0 1 1h.5A1.5 1.5 0 0 1 7 16.5v.5l1.01-.757A3 3 0 0 1 8 16v-4a3 3 0 0 1 3-3h6V7a1 1 0 0 0-1-1"
109
+ />
110
+ </g>
111
+ </svg>
112
+ </button>
113
+ )}
114
+ <button type="button" class="article-action-btn" popovertarget="article-font-settings" aria-label={helper.__("article.font_settings")} title={helper.__("article.font_settings")}>
115
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" role="img" aria-label={helper.__("article.font_settings")}>
116
+ <title>{helper.__("article.font_settings")}</title>
117
+ <g fill="none" fill-rule="evenodd">
118
+ <path d="m12.593 23.258l-.011.002l-.071.035l-.02.004l-.014-.004l-.071-.035q-.016-.005-.024.005l-.004.01l-.017.428l.005.02l.01.013l.104.074l.015.004l.012-.004l.104-.074l.012-.016l.004-.017l-.017-.427q-.004-.016-.017-.018m.265-.113l-.013.002l-.185.093l-.01.01l-.003.011l.018.43l.005.012l.008.007l.201.093q.019.005.029-.008l.004-.014l-.034-.614q-.005-.018-.02-.022m-.715.002a.02.02 0 0 0-.027.006l-.006.014l-.034.614q.001.018.017.024l.015-.002l.201-.093l.01-.008l.004-.011l.017-.43l-.003-.012l-.01-.01z" />
119
+ <path
120
+ fill="currentColor"
121
+ d="M21 12a1 1 0 0 1 1 1v6a1 1 0 0 1-1.911.412a4 4 0 1 1 0-6.824A1 1 0 0 1 21 12M8 4c.732 0 1.381.473 1.605 1.17l4.347 13.524a1 1 0 0 1-1.904.612L10.664 15H5.336l-1.384 4.306a1 1 0 0 1-1.904-.612L6.395 5.17A1.69 1.69 0 0 1 8 4m10 10a2 2 0 1 0 0 4a2 2 0 0 0 0-4M8 6.712L5.979 13h4.042z"
122
+ />
123
+ </g>
124
+ </svg>
125
+ </button>
126
+ <button type="button" class="article-action-btn" popovertarget="article-info-popover" aria-label={helper.__("article.article_info")} title={helper.__("article.article_info")}>
127
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" role="img" aria-label={helper.__("article.article_info")}>
128
+ <title>{helper.__("article.article_info")}</title>
129
+ <g fill="none">
130
+ <path d="m12.593 23.258l-.011.002l-.071.035l-.02.004l-.014-.004l-.071-.035q-.016-.005-.024.005l-.004.01l-.017.428l.005.02l.01.013l.104.074l.015.004l.012-.004l.104-.074l.012-.016l.004-.017l-.017-.427q-.004-.016-.017-.018m.265-.113l-.013.002l-.185.093l-.01.01l-.003.011l.018.43l.005.012l.008.007l.201.093q.019.005.029-.008l.004-.014l-.034-.614q-.005-.018-.02-.022m-.715.002a.02.02 0 0 0-.027.006l-.006.014l-.034.614q.001.018.017.024l.015-.002l.201-.093l.01-.008l.004-.011l.017-.43l-.003-.012l-.01-.01z" />
131
+ <path
132
+ fill="currentColor"
133
+ d="M12 2c5.523 0 10 4.477 10 10s-4.477 10-10 10S2 17.523 2 12S6.477 2 12 2m0 2a8 8 0 1 0 0 16a8 8 0 0 0 0-16m-.01 6c.558 0 1.01.452 1.01 1.01v5.124A1 1 0 0 1 12.5 18h-.49A1.01 1.01 0 0 1 11 16.99V12a1 1 0 1 1 0-2zM12 7a1 1 0 1 1 0 2a1 1 0 0 1 0-2"
134
+ />
135
+ </g>
136
+ </svg>
137
+ </button>
138
+ </div>
139
+ </div>
140
+ )}
141
+ {index && page.tags?.length && (
84
142
  <div class="article-footer">
85
143
  <div class="article-tags">
86
144
  {page.tags.map((tag, i) => (
87
145
  <Fragment>
88
146
  {i > 0 && <span class="meta-separator">·</span>}
89
- <a class="article-tag" rel="tag" href={url_for(tag.path)}>
147
+ <a class="article-tag" rel="tag" href={helper.localized_tag_url(tag, helper.language_key(page))}>
90
148
  {tag.name}
91
149
  </a>
92
150
  </Fragment>
93
151
  ))}
94
152
  </div>
95
- {index && (
96
- <a class="article-read-more" href={url_for(page.link || page.path)}>
97
- Read More →
98
- </a>
99
- )}
153
+ <a class="article-read-more" href={url_for(page.link || page.path)}>
154
+ Read More
155
+ </a>
100
156
  </div>
101
157
  )}
102
158
 
103
159
  {!index && page.excerpt && <div class="content" dangerouslySetInnerHTML={{ __html: page.content }}></div>}
104
-
105
- {/* Licensing block */}
106
- {!index && article && article.licenses && Object.keys(article.licenses) ? <ArticleLicensing.Cacheable page={page} config={config} helper={helper} /> : null}
107
160
  </article>
161
+
162
+ {!index && (
163
+ <div id="article-font-settings" popover="auto" class="article-popover article-font-popover">
164
+ <div class="article-popover-header">
165
+ <h3>Display Settings</h3>
166
+ <button type="button" class="article-popover-close" popovertarget="article-font-settings" popovertargetaction="hide" aria-label="Close">
167
+ <svg
168
+ xmlns="http://www.w3.org/2000/svg"
169
+ width="18"
170
+ height="18"
171
+ viewBox="0 0 24 24"
172
+ fill="none"
173
+ stroke="currentColor"
174
+ stroke-width="2"
175
+ stroke-linecap="round"
176
+ stroke-linejoin="round"
177
+ role="img"
178
+ aria-label="Close"
179
+ >
180
+ <title>Close</title>
181
+ <path d="M18 6 6 18" />
182
+ <path d="m6 6 12 12" />
183
+ </svg>
184
+ </button>
185
+ </div>
186
+ <div class="article-popover-body">
187
+ <div class="font-settings-column">
188
+ <div class="font-setting-group font-size-group">
189
+ <div class="font-size-selector">
190
+ <button type="button" class="font-size-btn" data-size="small" aria-label="Small">
191
+ <span class="font-size-preview">A</span>
192
+ </button>
193
+ <button type="button" class="font-size-btn" data-size="medium-small" aria-label="Medium Small">
194
+ <span class="font-size-preview">A</span>
195
+ </button>
196
+ <button type="button" class="font-size-btn is-active" data-size="medium" aria-label="Medium">
197
+ <span class="font-size-preview">A</span>
198
+ </button>
199
+ <button type="button" class="font-size-btn" data-size="medium-large" aria-label="Medium Large">
200
+ <span class="font-size-preview">A</span>
201
+ </button>
202
+ <button type="button" class="font-size-btn" data-size="large" aria-label="Large">
203
+ <span class="font-size-preview">A</span>
204
+ </button>
205
+ </div>
206
+ </div>
207
+ <div class="font-setting-group font-line-height-group">
208
+ <div class="font-line-height-control">
209
+ <span class="font-line-height-label">Compact</span>
210
+ <input id="article-line-height-slider" class="font-line-height-slider" type="range" min="1.45" max="1.9" step="0.05" value="1.7" aria-label="Line Height" />
211
+ <span class="font-line-height-label">Relaxed</span>
212
+ </div>
213
+ <div class="font-line-height-meta">
214
+ <span>Normal</span>
215
+ <output class="font-line-height-value" for="article-line-height-slider">
216
+ 1.70
217
+ </output>
218
+ </div>
219
+ </div>
220
+ <div class="font-setting-group font-type-group">
221
+ <div class="font-type-selector">
222
+ <button type="button" class="font-type-btn is-active" data-font="serif">
223
+ <span class="font-type-preview">Aa</span>
224
+ <span class="font-type-name">Serif</span>
225
+ </button>
226
+ <button type="button" class="font-type-btn" data-font="sans-serif">
227
+ <span class="font-type-preview">Aa</span>
228
+ <span class="font-type-name">Sans Serif</span>
229
+ </button>
230
+ <button type="button" class="font-type-btn" data-font="mono">
231
+ <span class="font-type-preview">Aa</span>
232
+ <span class="font-type-name">Monospace</span>
233
+ </button>
234
+ <button type="button" class="font-type-btn" data-font="handwriting">
235
+ <span class="font-type-preview">Aa</span>
236
+ <span class="font-type-name">Handwriting</span>
237
+ </button>
238
+ </div>
239
+ </div>
240
+ <div class="font-setting-group font-weight-group">
241
+ <div class="font-weight-selector">
242
+ <button type="button" class="font-weight-btn" data-weight="light" aria-label="Light">
243
+ <span class="font-option-name">Light</span>
244
+ </button>
245
+ <button type="button" class="font-weight-btn is-active" data-weight="regular" aria-label="Regular">
246
+ <span class="font-option-name">Regular</span>
247
+ </button>
248
+ <button type="button" class="font-weight-btn" data-weight="medium" aria-label="Medium">
249
+ <span class="font-option-name">Medium</span>
250
+ </button>
251
+ </div>
252
+ </div>
253
+ <div class="font-setting-group font-custom-group">
254
+ <button type="button" class="font-custom-toggle" aria-expanded="false" aria-controls="font-custom-panel" aria-label="Custom Fonts">
255
+ <span>Custom Fonts</span>
256
+ <span class="font-custom-toggle-icon" aria-hidden="true">
257
+ <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14" fill="none" aria-hidden="true" focusable="false">
258
+ <path d="M7 2.25v9.5" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" />
259
+ <path d="M2.25 7h9.5" stroke="currentColor" stroke-width="1.3" stroke-linecap="round" />
260
+ </svg>
261
+ </span>
262
+ </button>
263
+ <div id="font-custom-panel" class="font-custom-panel" data-expanded="false" aria-hidden="true">
264
+ <div class="font-custom-panel-inner">
265
+ <form class="font-custom-form">
266
+ <label class="font-custom-field font-custom-import-field">
267
+ <span class="font-custom-label-row">
268
+ <span>Web Font CSS URL</span>
269
+ <button type="button" class="font-custom-help-btn" popovertarget="font-custom-help-popover" aria-label="Font CSS help">
270
+ <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" role="img" aria-hidden="true">
271
+ <circle cx="12" cy="12" r="9" stroke="currentColor" stroke-width="1.8" />
272
+ <path d="M12 10.25v5.75" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" />
273
+ <circle cx="12" cy="7.9" r="1" fill="currentColor" />
274
+ </svg>
275
+ </button>
276
+ </span>
277
+ <textarea
278
+ class="font-custom-imports"
279
+ name="font-custom-imports"
280
+ rows="3"
281
+ placeholder="https://fonts.googleapis.com/css2?family=..."
282
+ aria-label="Web Font CSS URL"
283
+ ></textarea>
284
+ </label>
285
+ <div class="font-custom-family-grid">
286
+ <label class="font-custom-field">
287
+ <span>Serif</span>
288
+ <input class="font-custom-family-input" name="font-custom-family-serif" type="text" data-font-family="serif" placeholder={'"Noto Serif SC", serif'} autocomplete="off" />
289
+ </label>
290
+ <label class="font-custom-field">
291
+ <span>Sans Serif</span>
292
+ <input
293
+ class="font-custom-family-input"
294
+ name="font-custom-family-sans-serif"
295
+ type="text"
296
+ data-font-family="sans-serif"
297
+ placeholder={'"Inter", sans-serif'}
298
+ autocomplete="off"
299
+ />
300
+ </label>
301
+ <label class="font-custom-field">
302
+ <span>Monospace</span>
303
+ <input class="font-custom-family-input" name="font-custom-family-mono" type="text" data-font-family="mono" placeholder={'"Fira Code", monospace'} autocomplete="off" />
304
+ </label>
305
+ <label class="font-custom-field">
306
+ <span>Handwriting</span>
307
+ <input
308
+ class="font-custom-family-input"
309
+ name="font-custom-family-handwriting"
310
+ type="text"
311
+ data-font-family="handwriting"
312
+ placeholder={'"LXGW WenKai", cursive'}
313
+ autocomplete="off"
314
+ />
315
+ </label>
316
+ </div>
317
+ <div class="font-custom-actions">
318
+ <button type="submit" class="font-custom-apply">
319
+ Apply
320
+ </button>
321
+ <button type="button" class="font-custom-reset">
322
+ Reset
323
+ </button>
324
+ </div>
325
+ </form>
326
+ </div>
327
+ </div>
328
+ </div>
329
+ <div id="font-custom-help-popover" popover="manual" class="font-custom-help-popover" role="tooltip">
330
+ Paste one web font CSS URL per line. Each URL can load one or more font families.
331
+ </div>
332
+ </div>
333
+ <aside class="font-preview-column">
334
+ <div class="font-setting-group font-preview-group">
335
+ <span class="font-setting-label">Preview</span>
336
+ <div class="font-preview-box">
337
+ <p class="font-preview-title">{page.title}</p>
338
+ {page.excerpt && <p class="font-preview-excerpt" dangerouslySetInnerHTML={{ __html: `${page.excerpt.substring(0, 80)}...` }}></p>}
339
+ </div>
340
+ </div>
341
+ </aside>
342
+ </div>
343
+ </div>
344
+ )}
345
+
346
+ {hasComment && (
347
+ <div id="article-comment-popover" popover="auto" class="article-popover article-comment-popover">
348
+ <div class="article-popover-header">
349
+ <h3>{commentsLabel}</h3>
350
+ <button type="button" class="article-popover-close" popovertarget="article-comment-popover" popovertargetaction="hide" aria-label={helper.__("article.close")}>
351
+ <svg
352
+ xmlns="http://www.w3.org/2000/svg"
353
+ width="18"
354
+ height="18"
355
+ viewBox="0 0 24 24"
356
+ fill="none"
357
+ stroke="currentColor"
358
+ stroke-width="2"
359
+ stroke-linecap="round"
360
+ stroke-linejoin="round"
361
+ role="img"
362
+ aria-label="Close"
363
+ >
364
+ <title>Close</title>
365
+ <path d="M18 6 6 18" />
366
+ <path d="m6 6 12 12" />
367
+ </svg>
368
+ </button>
369
+ </div>
370
+ <div class="article-popover-body article-comment-popover-body">
371
+ <Comment config={config} page={page} helper={helper} embedded />
372
+ </div>
373
+ </div>
374
+ )}
375
+
376
+ {!index && <ArticleInfo page={page} config={config} helper={helper} />}
108
377
  </div>
109
- {/* Comment */}
110
- {!index ? <Comment config={config} page={page} helper={helper} /> : null}
111
378
  </Fragment>
112
379
  );
113
380
  }