hexo-theme-fluid 1.9.8 → 1.9.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -18
- package/_config.yml +35 -9
- package/languages/de.yml +4 -0
- package/languages/en.yml +4 -0
- package/languages/eo.yml +4 -0
- package/languages/es.yml +4 -0
- package/languages/ja.yml +4 -0
- package/languages/ru.yml +4 -0
- package/languages/zh-CN.yml +4 -0
- package/languages/zh-HK.yml +4 -0
- package/languages/zh-TW.yml +11 -7
- package/layout/_partials/comments/cusdis.ejs +33 -1
- package/layout/_partials/comments/disqus.ejs +6 -1
- package/layout/_partials/comments/waline.ejs +3 -3
- package/layout/_partials/footer/statistics.ejs +17 -0
- package/layout/_partials/header/banner.ejs +39 -3
- package/layout/_partials/header/navigation.ejs +74 -1
- package/layout/_partials/plugins/analytics.ejs +5 -0
- package/layout/_partials/plugins/typed.ejs +4 -0
- package/layout/_partials/post/copyright.ejs +1 -1
- package/layout/_partials/post/meta-top.ejs +7 -1
- package/layout/_partials/post/toc.ejs +66 -2
- package/layout/index.ejs +1 -0
- package/package.json +1 -1
- package/scripts/events/index.js +1 -0
- package/scripts/events/lib/footnote.js +11 -2
- package/scripts/events/lib/random-banner.js +45 -0
- package/scripts/filters/post-filter.js +24 -1
- package/scripts/helpers/wordcount.js +3 -6
- package/scripts/tags/fold.js +1 -1
- package/scripts/tags/note.js +1 -1
- package/source/css/_pages/_base/_widget/header.styl +97 -0
- package/source/css/_pages/_base/_widget/toc.styl +32 -1
- package/source/css/_pages/_base/base.styl +3 -0
- package/source/css/_pages/_base/keyframes.styl +8 -0
- package/source/img/random/default.png +0 -0
- package/source/js/color-schema.js +33 -20
- package/source/js/events.js +46 -1
- package/source/js/openkounter.js +173 -0
- package/source/js/umami-view.js +6 -4
- package/source/js/utils.js +11 -6
package/README.md
CHANGED
|
@@ -111,18 +111,16 @@ layout: about
|
|
|
111
111
|
<table>
|
|
112
112
|
<thead>
|
|
113
113
|
<tr>
|
|
114
|
-
<th align="center" style="width: 240px;">
|
|
115
|
-
<a href="https://flowus.cn/share/eebf2144-8db7-4d68-b31e-bc2c116871de">
|
|
116
|
-
<img src="https://github-production-user-asset-6210df.s3.amazonaws.com/32983588/243899272-092eeb46-9172-4c10-9e72-53561ff37a00.png" height="200px"><br>
|
|
117
|
-
<sub>首席赞助商 ORENCEAI</sub><br>
|
|
118
|
-
<sub>全新的 ChatGPT 人工智能对话平台</sub>
|
|
119
|
-
</a>
|
|
120
|
-
</th>
|
|
121
114
|
<th align="center" style="width: 240px;">
|
|
122
115
|
<a href="https://www.jetbrains.com/?from=hexo-theme-fluid">
|
|
123
116
|
<img src="https://raw.githubusercontent.com/fluid-dev/static/690616966f34a58d66aa15ac7b550dd7bbc03967/hexo-theme-fluid/jetbrains.svg" height="200px"><br>
|
|
124
117
|
<sub>免费开发工具提供方 JetBrains</sub><br>
|
|
125
|
-
|
|
118
|
+
</a>
|
|
119
|
+
</th>
|
|
120
|
+
<th align="center" style="width: 240px;">
|
|
121
|
+
<a href="https://dartnode.com">
|
|
122
|
+
<img src="https://dartnode.com/branding/DN-Open-Source-sm.png" height="200px"><br>
|
|
123
|
+
<sub>免费 VPS 提供方 DartNode</sub><br>
|
|
126
124
|
</a>
|
|
127
125
|
</th>
|
|
128
126
|
</tr>
|
|
@@ -146,21 +144,12 @@ layout: about
|
|
|
146
144
|
<table>
|
|
147
145
|
<thead>
|
|
148
146
|
<tr>
|
|
149
|
-
<th align="center"
|
|
147
|
+
<th align="center" width="240">
|
|
150
148
|
<div>
|
|
151
149
|
<img src="https://github.com/fluid-dev/static/blob/master/hexo-theme-fluid/sponsor.png?s=200&v=4" height="200px" alt="微信赞赏码"><br>
|
|
152
150
|
<sub>微信赞赏码</sub>
|
|
153
151
|
</div>
|
|
154
152
|
</th>
|
|
155
|
-
<th align="center" style="width: 240px;">
|
|
156
|
-
<div>
|
|
157
|
-
<a href="https://etherscan.io/address/0x0021395954710be29c0BFDCB3f98f4D2fa5A1448">
|
|
158
|
-
<img src="https://avatars.githubusercontent.com/u/6250754?s=200&v=4" height="200px" alt="ERC20 Token">
|
|
159
|
-
</a>
|
|
160
|
-
<br>
|
|
161
|
-
<sub>ERC20 Token: 0x0021395954710<br>be29c0BFDCB3f98f4D2fa5A1448</sub>
|
|
162
|
-
</div>
|
|
163
|
-
</th>
|
|
164
153
|
</tr>
|
|
165
154
|
</thead>
|
|
166
155
|
</table>
|
package/_config.yml
CHANGED
|
@@ -282,9 +282,23 @@ web_analytics:
|
|
|
282
282
|
# If true, ignore localhost & 127.0.0.1
|
|
283
283
|
ignore_local: false
|
|
284
284
|
|
|
285
|
+
# OpenKounter 计数统计(基于 EdgeOne Pages),可用于 PV UV 展示
|
|
286
|
+
# OpenKounter count statistics (based on EdgeOne Pages), which can be used for PV UV display
|
|
287
|
+
# See: https://github.com/Mintimate/open-kounter
|
|
288
|
+
openkounter:
|
|
289
|
+
# OpenKounter API 服务器地址
|
|
290
|
+
# OpenKounter API server URL
|
|
291
|
+
server_url: https://open-kounter.mintimate.cn
|
|
292
|
+
# 统计页面时获取路径的属性,通常使用 window.location.pathname
|
|
293
|
+
# Get the attribute of the page path during statistics
|
|
294
|
+
path: window.location.pathname
|
|
295
|
+
# 开启后不统计本地路径(localhost、127.0.0.1、[::1])
|
|
296
|
+
# If true, ignore localhost & 127.0.0.1 & [::1]
|
|
297
|
+
ignore_local: false
|
|
298
|
+
|
|
285
299
|
# Umami Analytics,仅支持自部署。如果要展示 PV UV 需要填写所有配置项,否则只填写 `src` 和 `website_id` 即可
|
|
286
300
|
# Umami Analytics, only Self-host support. If you want to display PV UV need to set all config items, otherwise only set 'src' and 'website_id'
|
|
287
|
-
# See: https://umami.is/docs
|
|
301
|
+
# See: https://umami.is/docs
|
|
288
302
|
umami:
|
|
289
303
|
# umami js 文件地址,需要在 umami 后台创建站点后获取
|
|
290
304
|
# umami js file url, get after create website in umami
|
|
@@ -399,6 +413,10 @@ search:
|
|
|
399
413
|
# 首屏图片的相关配置
|
|
400
414
|
# Config of the big image on the first screen
|
|
401
415
|
banner:
|
|
416
|
+
# 是否开启所有页面的随机头图,仅在页面对应 banner_img 为空时生效,将图片放在 source/img/random/ 目录下
|
|
417
|
+
# Enable random banner for all pages, only works when banner_img is empty, put images in the directory `source/img/random/`
|
|
418
|
+
random_img: false
|
|
419
|
+
|
|
402
420
|
# 视差滚动,图片与板块会随着屏幕滚动产生视差效果
|
|
403
421
|
# Scrolling parallax
|
|
404
422
|
parallax: true
|
|
@@ -456,9 +474,9 @@ footer:
|
|
|
456
474
|
statistics:
|
|
457
475
|
enable: false
|
|
458
476
|
|
|
459
|
-
# 统计数据来源,使用 leancloud, umami 需要设置 `web_analytics` 中对应的参数;使用 busuanzi 不需要额外设置,但是有时不稳定,另外本地运行时 busuanzi 显示统计数据很大属于正常现象,部署后会正常
|
|
460
|
-
# Data source. If use leancloud, umami, you need to set the parameter in `web_analytics`
|
|
461
|
-
# Options: busuanzi | leancloud | umami
|
|
477
|
+
# 统计数据来源,使用 leancloud, umami, openkounter 需要设置 `web_analytics` 中对应的参数;使用 busuanzi 不需要额外设置,但是有时不稳定,另外本地运行时 busuanzi 显示统计数据很大属于正常现象,部署后会正常
|
|
478
|
+
# Data source. If use leancloud, umami, openkounter, you need to set the parameter in `web_analytics`
|
|
479
|
+
# Options: busuanzi | leancloud | umami | openkounter
|
|
462
480
|
source: "busuanzi"
|
|
463
481
|
|
|
464
482
|
# 国内大陆服务器的备案信息
|
|
@@ -499,8 +517,8 @@ index:
|
|
|
499
517
|
slogan:
|
|
500
518
|
enable: true
|
|
501
519
|
|
|
502
|
-
# 为空则按 hexo config.subtitle
|
|
503
|
-
# If empty, text based on `subtitle` in hexo config
|
|
520
|
+
# 为空则按 hexo config.subtitle 显示,支持列表格式来实现随机选择一行文字显示
|
|
521
|
+
# If empty, text based on `subtitle` in hexo config, support list format to random selection of a row for display
|
|
504
522
|
text: "An elegant Material-Design theme for Hexo"
|
|
505
523
|
|
|
506
524
|
# 通过 API 接口作为首页副标题的内容,必须返回的是 JSON 格式,如果请求失败则按 text 字段显示,该功能必须先开启 typing 打字机功能
|
|
@@ -650,6 +668,9 @@ post:
|
|
|
650
668
|
# Table of contents (TOC) in the sidebar
|
|
651
669
|
toc:
|
|
652
670
|
enable: true
|
|
671
|
+
# 进入文章时是否默认展开全部目录
|
|
672
|
+
# Expand all TOC items on enter
|
|
673
|
+
expand_all: true
|
|
653
674
|
|
|
654
675
|
# 置于板块的左侧或右侧
|
|
655
676
|
# place in the board
|
|
@@ -779,11 +800,16 @@ utterances:
|
|
|
779
800
|
# See: https://disqus.com
|
|
780
801
|
disqus:
|
|
781
802
|
shortname:
|
|
782
|
-
# 以下为 Disqusjs 支持, 国内用户如果想使用 Disqus
|
|
783
|
-
# The following are Disqusjs configurations, please ignore if DisqusJS is not required
|
|
803
|
+
# 以下为 Disqusjs 支持, 国内用户如果想使用 Disqus 建议配合使用,支持填入多个 apikey,建议自行搭建 api 端点
|
|
804
|
+
# The following are Disqusjs configurations, please ignore if DisqusJS is not required, it supports filling in multiple apikeys, it is recommended to build the API endpoint by yourself
|
|
784
805
|
# See: https://github.com/SukkaW/DisqusJS
|
|
785
806
|
disqusjs: false
|
|
786
807
|
apikey:
|
|
808
|
+
- 'KEY1'
|
|
809
|
+
#- 'KEY2'
|
|
810
|
+
api: https://disqus.skk.moe/disqus/
|
|
811
|
+
admin:
|
|
812
|
+
adminLabel:
|
|
787
813
|
|
|
788
814
|
# Gitalk
|
|
789
815
|
# 基于 GitHub Issues
|
|
@@ -1114,7 +1140,7 @@ static_prefix:
|
|
|
1114
1140
|
|
|
1115
1141
|
valine: https://lib.baomitu.com/valine/1.5.1/
|
|
1116
1142
|
|
|
1117
|
-
waline: https://
|
|
1143
|
+
waline: https://lib.baomitu.com/waline/3.6.0/
|
|
1118
1144
|
|
|
1119
1145
|
gitalk: https://lib.baomitu.com/gitalk/1.8.0/
|
|
1120
1146
|
|
package/languages/de.yml
CHANGED
package/languages/en.yml
CHANGED
package/languages/eo.yml
CHANGED
package/languages/es.yml
CHANGED
package/languages/ja.yml
CHANGED
package/languages/ru.yml
CHANGED
package/languages/zh-CN.yml
CHANGED
package/languages/zh-HK.yml
CHANGED
package/languages/zh-TW.yml
CHANGED
|
@@ -52,12 +52,12 @@ post:
|
|
|
52
52
|
posted: '發布於'
|
|
53
53
|
updated: '更新於'
|
|
54
54
|
licensed: '許可協議'
|
|
55
|
-
CC: 'CC -
|
|
56
|
-
BY: 'BY -
|
|
57
|
-
SA: 'SA -
|
|
58
|
-
NC: 'NC -
|
|
59
|
-
ND: 'ND -
|
|
60
|
-
ZERO: 'CC0 -
|
|
55
|
+
CC: 'CC - 創用 CC 授權'
|
|
56
|
+
BY: 'BY - 姓名標示'
|
|
57
|
+
SA: 'SA - 相同方式分享'
|
|
58
|
+
NC: 'NC - 非商業性'
|
|
59
|
+
ND: 'ND - 禁止改作'
|
|
60
|
+
ZERO: 'CC0 - 公眾領域貢獻宣告'
|
|
61
61
|
|
|
62
62
|
footer:
|
|
63
63
|
pv: '總訪問量 {} 次'
|
|
@@ -67,4 +67,8 @@ search:
|
|
|
67
67
|
title: '搜尋'
|
|
68
68
|
keyword: '關鍵字'
|
|
69
69
|
|
|
70
|
-
noscript_warning: '
|
|
70
|
+
noscript_warning: '部落格在允許 JavaScript 執行的環境下瀏覽效果更佳'
|
|
71
|
+
|
|
72
|
+
darkmode:
|
|
73
|
+
light: '開燈'
|
|
74
|
+
dark: '關燈'
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<% if (theme.cusdis.host && theme.cusdis.app_id) { %>
|
|
2
|
-
<div class="cusdis" style="width:100
|
|
2
|
+
<div class="cusdis" style="width:100%; overflow:visible; min-height:480px;">
|
|
3
3
|
<div id="cusdis_thread"
|
|
4
|
+
style="width:100%; overflow:visible;"
|
|
4
5
|
data-host="<%= theme.cusdis.host %>"
|
|
5
6
|
data-app-id="<%= theme.cusdis.app_id %>"
|
|
6
7
|
data-page-id="<%= md5(page.path) %>"
|
|
@@ -15,6 +16,37 @@
|
|
|
15
16
|
Fluid.utils.createScript('<%= url_join(theme.cusdis.host,
|
|
16
17
|
`/js/widget/lang/${ String(theme.cusdis.lang || 'zh-cn').toLowerCase() }.js`) %>');
|
|
17
18
|
Fluid.utils.createScript('<%= url_join(theme.cusdis.host, 'js/cusdis.es.js') %>');
|
|
19
|
+
|
|
20
|
+
// 取消容器滚动条,尝试让 iframe 展开显示
|
|
21
|
+
var container = document.querySelector('.cusdis');
|
|
22
|
+
var thread = document.querySelector('#cusdis_thread');
|
|
23
|
+
if (container) container.style.overflow = 'visible';
|
|
24
|
+
if (thread) thread.style.overflow = 'visible';
|
|
25
|
+
|
|
26
|
+
// 等待 widget 加载后调整 iframe 样式
|
|
27
|
+
setTimeout(function() {
|
|
28
|
+
try {
|
|
29
|
+
var iframe = thread && thread.querySelector('iframe');
|
|
30
|
+
if (iframe) {
|
|
31
|
+
iframe.style.width = '100%';
|
|
32
|
+
iframe.style.border = 'none';
|
|
33
|
+
iframe.style.overflow = 'visible';
|
|
34
|
+
iframe.style.minHeight = '600px';
|
|
35
|
+
iframe.setAttribute('scrolling', 'no');
|
|
36
|
+
|
|
37
|
+
// 若同源,尝试根据内容自适应高度
|
|
38
|
+
try {
|
|
39
|
+
var doc = iframe.contentDocument || iframe.contentWindow.document;
|
|
40
|
+
if (doc && doc.body) {
|
|
41
|
+
iframe.style.height = doc.body.scrollHeight + 'px';
|
|
42
|
+
}
|
|
43
|
+
} catch (e) {
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
} catch (e) {
|
|
47
|
+
}
|
|
48
|
+
}, 600);
|
|
49
|
+
|
|
18
50
|
var schema = document.documentElement.getAttribute('data-user-color-scheme');
|
|
19
51
|
if (schema) {
|
|
20
52
|
document.querySelector('#cusdis_thread').dataset.theme = schema
|
|
@@ -8,7 +8,12 @@
|
|
|
8
8
|
Fluid.utils.createScript('<%= url_join(theme.static_prefix.disqusjs, 'disqus.js') %>', function() {
|
|
9
9
|
new DisqusJS({
|
|
10
10
|
shortname: '<%= theme.disqus.shortname %>',
|
|
11
|
-
apikey:
|
|
11
|
+
apikey: <%- JSON.stringify(theme.disqus.apikey) %>,
|
|
12
|
+
api: '<%= theme.disqus.api %>',
|
|
13
|
+
url: '<%= page.permalink %>',
|
|
14
|
+
identifier: '<%= url_for(page.path) %>',
|
|
15
|
+
admin: '<%= theme.disqus.admin %>',
|
|
16
|
+
adminLabel: '<%= theme.disqus.adminLabel %>'
|
|
12
17
|
});
|
|
13
18
|
});
|
|
14
19
|
});
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
<% if (theme.waline.serverURL) { %>
|
|
2
2
|
<div id="waline"></div>
|
|
3
|
-
<script type="
|
|
3
|
+
<script type="module">
|
|
4
4
|
Fluid.utils.loadComments('#waline', function() {
|
|
5
5
|
Fluid.utils.createCssLink('<%= url_join(theme.static_prefix.waline, 'waline.css') %>')
|
|
6
|
-
|
|
6
|
+
import('<%= url_join(theme.static_prefix.waline, 'waline.js') %>').then(({ init }) => {
|
|
7
7
|
var options = Object.assign(
|
|
8
8
|
<%- JSON.stringify(theme.waline || {}) %>,
|
|
9
9
|
{
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
path: <%= theme.waline.path %>
|
|
12
12
|
}
|
|
13
13
|
)
|
|
14
|
-
|
|
14
|
+
init(options);
|
|
15
15
|
Fluid.utils.waitElementVisible('#waline .vcontent', () => {
|
|
16
16
|
var imgSelector = '#waline .vcontent img:not(.vemoji)';
|
|
17
17
|
Fluid.plugins.imageCaption(imgSelector);
|
|
@@ -19,6 +19,23 @@
|
|
|
19
19
|
<% } %>
|
|
20
20
|
<% import_js(theme.static_prefix.internal_js, 'leancloud.js', 'defer') %>
|
|
21
21
|
|
|
22
|
+
<% } else if (theme.footer.statistics.source === 'openkounter') { %>
|
|
23
|
+
<% if (pv_texts.length >= 2) { %>
|
|
24
|
+
<span id="openkounter-site-pv-container" style="display: none">
|
|
25
|
+
<%- pv_texts[0] %>
|
|
26
|
+
<span id="openkounter-site-pv"></span>
|
|
27
|
+
<%- pv_texts[1] %>
|
|
28
|
+
</span>
|
|
29
|
+
<% } %>
|
|
30
|
+
<% if (uv_texts.length >= 2) { %>
|
|
31
|
+
<span id="openkounter-site-uv-container" style="display: none">
|
|
32
|
+
<%- uv_texts[0] %>
|
|
33
|
+
<span id="openkounter-site-uv"></span>
|
|
34
|
+
<%- uv_texts[1] %>
|
|
35
|
+
</span>
|
|
36
|
+
<% } %>
|
|
37
|
+
<% import_js(theme.static_prefix.internal_js, 'openkounter.js', 'defer') %>
|
|
38
|
+
|
|
22
39
|
<% } else if (theme.footer.statistics.source === 'busuanzi') { %>
|
|
23
40
|
<% if (pv_texts.length >= 2) { %>
|
|
24
41
|
<span id="busuanzi_container_site_pv" style="display: none">
|
|
@@ -1,14 +1,35 @@
|
|
|
1
1
|
<%
|
|
2
|
-
var banner_img = page.banner_img || theme.index.banner_img
|
|
2
|
+
var banner_img = page.banner_img || (is_post() && theme.post ? theme.post.banner_img : theme.index.banner_img)
|
|
3
|
+
var random_enabled = theme.banner && typeof theme.banner.random_img === 'boolean'
|
|
4
|
+
? theme.banner.random_img
|
|
5
|
+
: false
|
|
6
|
+
var random_banner_list = []
|
|
7
|
+
if (!banner_img && random_enabled && Array.isArray(theme.banner_img_list) && theme.banner_img_list.length > 0) {
|
|
8
|
+
for (var i = 0; i < theme.banner_img_list.length; i++) {
|
|
9
|
+
random_banner_list.push(url_for(theme.banner_img_list[i]))
|
|
10
|
+
}
|
|
11
|
+
banner_img = random_banner_list[0]
|
|
12
|
+
}
|
|
13
|
+
var random_banner_attr = ''
|
|
14
|
+
if (random_banner_list.length > 0) {
|
|
15
|
+
random_banner_attr = "data-random-banner='" + random_banner_list.join(',') + "'"
|
|
16
|
+
}
|
|
17
|
+
var banner_attrs = ''
|
|
18
|
+
if (theme.banner && theme.banner.parallax) {
|
|
19
|
+
banner_attrs += ' parallax=true'
|
|
20
|
+
}
|
|
21
|
+
if (random_banner_attr) {
|
|
22
|
+
banner_attrs += ' ' + random_banner_attr
|
|
23
|
+
}
|
|
3
24
|
var banner_img_height = parseFloat(page.banner_img_height || theme.index.banner_img_height)
|
|
4
25
|
var banner_mask_alpha = parseFloat(page.banner_mask_alpha || theme.index.banner_mask_alpha)
|
|
5
26
|
var subtitle = page.subtitle || page.title
|
|
6
27
|
%>
|
|
7
28
|
|
|
8
|
-
<div id="banner" class="banner"
|
|
29
|
+
<div id="banner" class="banner"<%- banner_attrs %>
|
|
9
30
|
style="background: url('<%- url_for(banner_img) %>') no-repeat center center; background-size: cover;">
|
|
10
31
|
<div class="full-bg-img">
|
|
11
|
-
<div class="mask flex-center" style="background-color: rgba(0, 0, 0, <%=
|
|
32
|
+
<div class="mask flex-center" style="background-color: rgba(0, 0, 0, <%= banner_mask_alpha %>)">
|
|
12
33
|
<div class="banner-text text-center fade-in-up">
|
|
13
34
|
<div class="h2">
|
|
14
35
|
<% if(theme.fun_features.typing.enable && in_scope(theme.fun_features.typing.scope)) { %>
|
|
@@ -31,3 +52,18 @@ var subtitle = page.subtitle || page.title
|
|
|
31
52
|
</div>
|
|
32
53
|
</div>
|
|
33
54
|
</div>
|
|
55
|
+
|
|
56
|
+
<% if (random_banner_list.length > 0) { %>
|
|
57
|
+
<script>
|
|
58
|
+
(function() {
|
|
59
|
+
var banner = document.getElementById('banner');
|
|
60
|
+
if (!banner) return;
|
|
61
|
+
var list = banner.getAttribute('data-random-banner');
|
|
62
|
+
if (!list) return;
|
|
63
|
+
list = list.split(',').filter(Boolean);
|
|
64
|
+
if (list.length === 0) return;
|
|
65
|
+
var pick = list[Math.floor(Math.random() * list.length)];
|
|
66
|
+
banner.style.backgroundImage = "url('" + pick + "')";
|
|
67
|
+
})();
|
|
68
|
+
</script>
|
|
69
|
+
<% } %>
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
<div class="animated-icon"><span></span><span></span><span></span></div>
|
|
11
11
|
</button>
|
|
12
12
|
|
|
13
|
-
<!-- Collapsible content -->
|
|
13
|
+
<!-- Collapsible content (desktop) -->
|
|
14
14
|
<div class="collapse navbar-collapse" id="navbarSupportedContent">
|
|
15
15
|
<ul class="navbar-nav ml-auto text-center">
|
|
16
16
|
<% for(const each of theme.navbar.menu || []) { %>
|
|
@@ -68,3 +68,76 @@
|
|
|
68
68
|
</div>
|
|
69
69
|
</div>
|
|
70
70
|
</nav>
|
|
71
|
+
|
|
72
|
+
<!-- Mobile grid menu overlay -->
|
|
73
|
+
<div id="mobile-grid-menu" class="d-lg-none">
|
|
74
|
+
<div class="mobile-grid-menu-inner">
|
|
75
|
+
<div class="container">
|
|
76
|
+
<div class="row">
|
|
77
|
+
<% for(const each of theme.navbar.menu || []) { %>
|
|
78
|
+
<% if (!each.submenu && !each.link) continue %>
|
|
79
|
+
<% var gridText = each.name || __(each.key + '.menu') || __(each.key + '.title') %>
|
|
80
|
+
<% if (gridText.indexOf('.menu') !== -1 || gridText.indexOf('.title') !== -1) {
|
|
81
|
+
gridText = each.key
|
|
82
|
+
} %>
|
|
83
|
+
<% if (each.submenu) { %>
|
|
84
|
+
<%
|
|
85
|
+
// Flatten submenu items as grid cells grouped under a header
|
|
86
|
+
// First render the parent as a header row, then sub items
|
|
87
|
+
%>
|
|
88
|
+
<div class="col-12 mobile-grid-group-header">
|
|
89
|
+
<%- each.icon ? '<i class="' + each.icon + '"></i>' : '' %>
|
|
90
|
+
<span><%- gridText %></span>
|
|
91
|
+
</div>
|
|
92
|
+
<% for(const subEach of each.submenu || []) { %>
|
|
93
|
+
<% if (!subEach.link) continue %>
|
|
94
|
+
<% var subGridText = subEach.name || __(subEach.key + '.title') %>
|
|
95
|
+
<% if (subGridText.indexOf('.title') !== -1) {
|
|
96
|
+
subGridText = subEach.key
|
|
97
|
+
} %>
|
|
98
|
+
<div class="col-4 mobile-grid-cell">
|
|
99
|
+
<a href="<%= url_for(subEach.link) %>" target="<%= subEach.target || '_self' %>">
|
|
100
|
+
<div class="mobile-grid-item">
|
|
101
|
+
<%- subEach.icon ? '<i class="' + subEach.icon + '"></i>' : '<i class="iconfont icon-link-fill"></i>' %>
|
|
102
|
+
<span><%- subGridText %></span>
|
|
103
|
+
</div>
|
|
104
|
+
</a>
|
|
105
|
+
</div>
|
|
106
|
+
<% } %>
|
|
107
|
+
<% } else { %>
|
|
108
|
+
<div class="col-4 mobile-grid-cell">
|
|
109
|
+
<a href="<%= url_for(each.link) %>" target="<%= each.target || '_self' %>">
|
|
110
|
+
<div class="mobile-grid-item">
|
|
111
|
+
<%- each.icon ? '<i class="' + each.icon + '"></i>' : '<i class="iconfont icon-link-fill"></i>' %>
|
|
112
|
+
<span><%- gridText %></span>
|
|
113
|
+
</div>
|
|
114
|
+
</a>
|
|
115
|
+
</div>
|
|
116
|
+
<% } %>
|
|
117
|
+
<% } %>
|
|
118
|
+
<% if(theme.search.enable) { %>
|
|
119
|
+
<div class="col-4 mobile-grid-cell" id="mobile-search-btn">
|
|
120
|
+
<a href="javascript:;" data-toggle="modal" data-target="#modalSearch" aria-label="Search">
|
|
121
|
+
<div class="mobile-grid-item">
|
|
122
|
+
<i class="iconfont icon-search"></i>
|
|
123
|
+
<span><%= __('search.title') !== 'search.title' ? __('search.title') : 'Search' %></span>
|
|
124
|
+
</div>
|
|
125
|
+
</a>
|
|
126
|
+
</div>
|
|
127
|
+
<% } %>
|
|
128
|
+
<% if(theme.dark_mode && theme.dark_mode.enable) { %>
|
|
129
|
+
<div class="col-4 mobile-grid-cell" id="mobile-color-toggle-btn"
|
|
130
|
+
data-label-light="<%= __('darkmode.light') %>"
|
|
131
|
+
data-label-dark="<%= __('darkmode.dark') %>">
|
|
132
|
+
<a href="javascript:;" aria-label="Color Toggle">
|
|
133
|
+
<div class="mobile-grid-item">
|
|
134
|
+
<i class="iconfont icon-dark" id="mobile-color-toggle-icon"></i>
|
|
135
|
+
<span id="mobile-color-toggle-label"><%= __('darkmode.dark') %></span>
|
|
136
|
+
</div>
|
|
137
|
+
</a>
|
|
138
|
+
</div>
|
|
139
|
+
<% } %>
|
|
140
|
+
</div>
|
|
141
|
+
</div>
|
|
142
|
+
</div>
|
|
143
|
+
</div>
|
|
@@ -67,4 +67,9 @@
|
|
|
67
67
|
<% if(theme.web_analytics.leancloud && theme.web_analytics.leancloud.app_id && theme.web_analytics.leancloud.app_key) { %>
|
|
68
68
|
<% import_js(theme.static_prefix.internal_js, 'leancloud.js', 'defer') %>
|
|
69
69
|
<% } %>
|
|
70
|
+
|
|
71
|
+
<% if(theme.web_analytics.openkounter && theme.web_analytics.openkounter.server_url) { %>
|
|
72
|
+
<% import_js(theme.static_prefix.internal_js, 'openkounter.js', 'defer') %>
|
|
73
|
+
<% } %>
|
|
74
|
+
|
|
70
75
|
<% } %>
|
|
@@ -40,6 +40,10 @@
|
|
|
40
40
|
typing(text);
|
|
41
41
|
}
|
|
42
42
|
})
|
|
43
|
+
<% } else if (is_home() && Array.isArray(theme.index.slogan.text) && theme.index.slogan.text.length > 0) { %>
|
|
44
|
+
var texts = <%- JSON.stringify(theme.index.slogan.text) %>;
|
|
45
|
+
var idx = Math.floor(Math.random() * texts.length);
|
|
46
|
+
typing(texts[idx]);
|
|
43
47
|
<% } else { %>
|
|
44
48
|
typing(text);
|
|
45
49
|
<% } %>
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
<div class="license-box my-3">
|
|
13
13
|
<div class="license-title">
|
|
14
14
|
<div><%= page.title %></div>
|
|
15
|
-
<div><%= decode_url(page.
|
|
15
|
+
<div><%= decode_url(full_url_for(page.path)) %></div>
|
|
16
16
|
</div>
|
|
17
17
|
<div class="license-meta">
|
|
18
18
|
<% if (theme.post.copyright.author.enable && (page.author || config.author)) { %>
|
|
@@ -51,7 +51,13 @@
|
|
|
51
51
|
<%- views_texts[0] %><span id="leancloud-page-views"></span><%- views_texts[1] %>
|
|
52
52
|
</span>
|
|
53
53
|
<% import_js(theme.static_prefix.internal_js, 'leancloud.js', 'defer') %>
|
|
54
|
-
|
|
54
|
+
<% } else if (theme.post.meta.views.source === 'openkounter') { %>
|
|
55
|
+
<span id="openkounter-page-views-container" style="display: none">
|
|
56
|
+
<i class="iconfont icon-eye" aria-hidden="true"></i>
|
|
57
|
+
<%- views_texts[0] %><span id="openkounter-page-views"></span><%- views_texts[1] %>
|
|
58
|
+
</span>
|
|
59
|
+
<% import_js(theme.static_prefix.internal_js, 'openkounter.js', 'defer') %>
|
|
60
|
+
|
|
55
61
|
<% } else if (theme.post.meta.views.source === 'busuanzi') { %>
|
|
56
62
|
<span id="busuanzi_container_page_pv" style="display: none">
|
|
57
63
|
<i class="iconfont icon-eye" aria-hidden="true"></i>
|
|
@@ -15,7 +15,63 @@ import_script(`
|
|
|
15
15
|
var boardCtn = jQuery('#board-ctn');
|
|
16
16
|
var boardTop = boardCtn.offset().top;
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
function isExpandAllEnabled() {
|
|
19
|
+
return CONFIG.toc && CONFIG.toc.expand_all === true;
|
|
20
|
+
}
|
|
21
|
+
function expandAllToc() {
|
|
22
|
+
if (!isExpandAllEnabled()) { return; }
|
|
23
|
+
jQuery('#toc-body .tocbot-is-collapsed').removeClass('tocbot-is-collapsed');
|
|
24
|
+
}
|
|
25
|
+
function updateTocToggle($li, $childList) {
|
|
26
|
+
var $toggle = $li.children('.toc-toggle');
|
|
27
|
+
if ($toggle.length === 0) { return; }
|
|
28
|
+
var collapsed = $childList.hasClass('tocbot-is-collapsed');
|
|
29
|
+
$toggle
|
|
30
|
+
.toggleClass('toc-toggle-collapsed', collapsed)
|
|
31
|
+
.toggleClass('toc-toggle-expanded', !collapsed);
|
|
32
|
+
}
|
|
33
|
+
function bindTocToggle() {
|
|
34
|
+
if (!isExpandAllEnabled()) { return; }
|
|
35
|
+
jQuery('#toc-body .toc-list-item').each(function() {
|
|
36
|
+
var $li = jQuery(this);
|
|
37
|
+
var $childList = $li.children('ol');
|
|
38
|
+
if ($childList.length === 0) {
|
|
39
|
+
if ($li.children('.toc-toggle').length === 0) {
|
|
40
|
+
$li.prepend('<span class="toc-toggle toc-toggle-placeholder" aria-hidden="true">›</span>');
|
|
41
|
+
}
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if ($li.children('.toc-toggle').length === 0) {
|
|
46
|
+
$li.prepend('<span class="toc-toggle toc-toggle-expanded" aria-hidden="true">›</span>');
|
|
47
|
+
}
|
|
48
|
+
updateTocToggle($li, $childList);
|
|
49
|
+
});
|
|
50
|
+
jQuery('#toc-body').off('click.tocToggle').on('click.tocToggle', '.toc-toggle', function(e) {
|
|
51
|
+
e.preventDefault();
|
|
52
|
+
e.stopPropagation();
|
|
53
|
+
var $li = jQuery(this).parent('.toc-list-item');
|
|
54
|
+
var $childList = $li.children('ol');
|
|
55
|
+
if ($childList.length === 0) { return; }
|
|
56
|
+
$childList.toggleClass('tocbot-is-collapsed');
|
|
57
|
+
updateTocToggle($li, $childList);
|
|
58
|
+
});
|
|
59
|
+
if (!window.__tocToggleObserver) {
|
|
60
|
+
window.__tocToggleObserver = new MutationObserver(function(mutations) {
|
|
61
|
+
mutations.forEach(function(mutation) {
|
|
62
|
+
if (mutation.type !== 'attributes' || mutation.attributeName !== 'class') { return; }
|
|
63
|
+
var $list = jQuery(mutation.target);
|
|
64
|
+
var $li = $list.parent('.toc-list-item');
|
|
65
|
+
if ($li.length === 0) { return; }
|
|
66
|
+
updateTocToggle($li, $list);
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
jQuery('#toc-body ol').each(function() {
|
|
70
|
+
window.__tocToggleObserver.observe(this, { attributes: true });
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
var tocConfig = Object.assign({
|
|
19
75
|
tocSelector : '#toc-body',
|
|
20
76
|
contentSelector : '.markdown-body',
|
|
21
77
|
linkClass : 'tocbot-link',
|
|
@@ -26,10 +82,16 @@ import_script(`
|
|
|
26
82
|
scrollSmooth : true,
|
|
27
83
|
includeTitleTags: true,
|
|
28
84
|
headingsOffset : -boardTop,
|
|
29
|
-
}, CONFIG.toc)
|
|
85
|
+
}, CONFIG.toc);
|
|
86
|
+
if (isExpandAllEnabled()) {
|
|
87
|
+
tocConfig.collapseDepth = 6;
|
|
88
|
+
}
|
|
89
|
+
window.tocbot.init(tocConfig);
|
|
30
90
|
if (toc.find('.toc-list-item').length > 0) {
|
|
31
91
|
toc.css('visibility', 'visible');
|
|
32
92
|
}
|
|
93
|
+
expandAllToc();
|
|
94
|
+
bindTocToggle();
|
|
33
95
|
|
|
34
96
|
Fluid.events.registerRefreshCallback(function() {
|
|
35
97
|
if ('tocbot' in window) {
|
|
@@ -41,6 +103,8 @@ import_script(`
|
|
|
41
103
|
if (toc.find('.toc-list-item').length > 0) {
|
|
42
104
|
toc.css('visibility', 'visible');
|
|
43
105
|
}
|
|
106
|
+
expandAllToc();
|
|
107
|
+
bindTocToggle();
|
|
44
108
|
}
|
|
45
109
|
});
|
|
46
110
|
});
|
package/layout/index.ejs
CHANGED
|
@@ -7,6 +7,7 @@ page.banner_img_height = theme.index.banner_img_height
|
|
|
7
7
|
page.banner_mask_alpha = theme.index.banner_mask_alpha
|
|
8
8
|
%>
|
|
9
9
|
|
|
10
|
+
<h1 style="display: none"><%= config.title %></h1>
|
|
10
11
|
<% page.posts.each(function (post) { %>
|
|
11
12
|
<div class="row mx-auto index-card">
|
|
12
13
|
<% var post_url = url_for(post.path), index_img = post.index_img || theme.post.default_index_img %>
|