hexo-theme-volantis 5.8.1 → 6.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.
- package/CHANGELOG.md +3 -44
- package/_cdn.yml +449 -0
- package/_config.yml +155 -157
- package/languages/en.yml +9 -10
- package/languages/zh-CN.yml +11 -15
- package/languages/zh-TW.yml +10 -11
- package/layout/_meta/category.ejs +10 -5
- package/layout/_meta/counter.ejs +14 -17
- package/layout/_meta/tags.ejs +3 -0
- package/layout/_meta/walinecount.ejs +1 -1
- package/layout/_partial/article.ejs +8 -3
- package/layout/_partial/cover.ejs +4 -4
- package/layout/_partial/footer.ejs +1 -1
- package/layout/_partial/head.ejs +7 -18
- package/layout/_partial/header.ejs +6 -6
- package/layout/_partial/post.ejs +3 -3
- package/layout/_partial/scripts/_ctrl.ejs +43 -2
- package/layout/_partial/scripts/config.ejs +69 -0
- package/layout/_partial/scripts/global.ejs +137 -60
- package/layout/_partial/scripts/index.ejs +16 -23
- package/layout/_plugins/_page_plugins/artitalk/index.ejs +1 -1
- package/layout/_plugins/_page_plugins/bbtalk/index.ejs +1 -1
- package/layout/_plugins/_page_plugins/fcircle/index.ejs +9 -8
- package/layout/_plugins/_page_plugins/katex/index.ejs +3 -3
- package/layout/_plugins/_page_plugins/mathjax/index.ejs +1 -1
- package/layout/_plugins/aplayer/layout.ejs +31 -23
- package/layout/_plugins/aplayer/script.ejs +93 -65
- package/layout/_plugins/comments/artalk/script.ejs +31 -40
- package/layout/_plugins/comments/discuss/script.ejs +1 -1
- package/layout/_plugins/comments/disqusjs/script.ejs +2 -2
- package/layout/_plugins/comments/gitalk/script.ejs +1 -1
- package/layout/_plugins/comments/twikoo/script.ejs +1 -1
- package/layout/_plugins/comments/vssue/script.ejs +3 -3
- package/layout/_plugins/comments/waline/script.ejs +2 -2
- package/layout/_plugins/github-api/script.ejs +3 -3
- package/layout/_plugins/lazyload/script.ejs +1 -1
- package/layout/_plugins/nodewaves/script.ejs +1 -1
- package/layout/_plugins/pace/script.ejs +15 -0
- package/layout/_plugins/parallax/script.ejs +1 -1
- package/layout/_plugins/pjax/index.ejs +66 -11
- package/layout/_plugins/pjax/pdata.ejs +5 -5
- package/layout/_plugins/preload/script.ejs +2 -2
- package/layout/_plugins/rightmenus/layout.ejs +4 -4
- package/layout/_plugins/scrollreveal/script.ejs +2 -2
- package/layout/_plugins/search/script.ejs +11 -8
- package/layout/_plugins/swiper/script.ejs +2 -2
- package/layout/{_partial/scripts/toc.ejs → _plugins/toc/script.ejs} +40 -36
- package/layout/_widget/webinfo.ejs +13 -14
- package/layout/friends.ejs +2 -2
- package/layout/layout.ejs +1 -15
- package/package.json +4 -4
- package/scripts/events/lib/cdn.js +206 -0
- package/scripts/events/lib/check-configuration.js +7 -7
- package/scripts/events/lib/check-environment.js +17 -17
- package/scripts/events/lib/config.js +0 -24
- package/scripts/events/lib/render-stylus.js +5 -5
- package/scripts/events/lib/stellar-tag-utils.js +2 -2
- package/scripts/filters/hexo-blog-encrypt-callback.js +44 -0
- package/scripts/filters/img.js +1 -1
- package/scripts/filters/replace.js +3 -3
- package/scripts/filters/z-lazyload.js +3 -5
- package/scripts/helpers/first-style.js +2 -2
- package/scripts/helpers/head/generate_seo.js +11 -9
- package/scripts/helpers/head/generate_title__keywords__description.js +19 -6
- package/scripts/helpers/related-posts.js +3 -3
- package/scripts/helpers/structured-data/lib/blogposting.js +1 -1
- package/scripts/helpers/structured-data/lib/breadcrumblist.js +1 -1
- package/scripts/helpers/structured-data/lib/config.js +1 -1
- package/scripts/helpers/structured-data/lib/website.js +1 -1
- package/scripts/helpers//346/226/207/347/253/240/346/216/250/350/215/220.js +184 -0
- package/scripts/tags/btn.js +2 -2
- package/scripts/tags/btns.js +3 -3
- package/scripts/tags/checkbox.js +6 -6
- package/scripts/tags/contributors.js +7 -7
- package/scripts/tags/dropmenu.js +8 -8
- package/scripts/tags/fancybox.js +6 -6
- package/scripts/tags/folding.js +5 -5
- package/scripts/tags/frame.js +3 -3
- package/scripts/tags/friends.js +8 -8
- package/scripts/tags/ghcard.js +7 -7
- package/scripts/tags/image.js +6 -6
- package/scripts/tags/inline-labels.js +6 -6
- package/scripts/tags/link.js +5 -5
- package/scripts/tags/md.js +4 -4
- package/scripts/tags/media.js +5 -5
- package/scripts/tags/note.js +12 -12
- package/scripts/tags/pandown.js +29 -29
- package/scripts/tags/site.js +4 -4
- package/scripts/tags/span.js +4 -4
- package/scripts/tags/table.js +2 -2
- package/scripts/tags/tabs.js +23 -23
- package/scripts/tags/timeline.js +5 -5
- package/source/css/_first/base_first.styl +1 -1
- package/source/css/_style/_layout/article.styl +43 -0
- package/source/css/_style/_layout/main.styl +1 -1
- package/source/css/_style/_layout/search.styl +206 -14
- package/source/css/_style/_plugins/index.styl +1 -3
- package/source/js/app.js +133 -160
- package/source/js/plugins/parallax.js +1 -1
- package/source/js/plugins/rightMenus.js +24 -20
- package/source/js/search/algolia.js +239 -0
- package/source/js/search/hexo.js +8 -2
- package/source/js/search/meilisearch.js +220 -0
- package/layout/_partial/scripts/_ctrl/cdnCtrl.ejs +0 -127
- package/layout/_partial/scripts/_ctrl/coverCtrl.ejs +0 -43
- package/layout/_plugins/analytics/LCCounter.ejs +0 -207
- package/layout/_plugins/pjax/animate.ejs +0 -31
- package/layout/_plugins/rightmenu/layout.ejs +0 -119
- package/scripts/helpers/revisioned.js +0 -167
- package/source/css/_style/_plugins/pjaxanimate.styl +0 -160
- package/source/js/plugins/rightMenu.js +0 -577
- /package/layout/{_partial/scripts/content-visibility-scroll-fix.ejs → _plugins/content-visibility/script.ejs} +0 -0
|
@@ -1,207 +0,0 @@
|
|
|
1
|
-
<script defer>
|
|
2
|
-
|
|
3
|
-
const LCCounter = {
|
|
4
|
-
app_id: '<%= theme.analytics.leancloud.app_id %>',
|
|
5
|
-
app_key: '<%= theme.analytics.leancloud.app_key %>',
|
|
6
|
-
custom_api_server: '<%= theme.analytics.leancloud.custom_api_server %>',
|
|
7
|
-
|
|
8
|
-
// 查询存储的记录
|
|
9
|
-
getRecord(Counter, url, title) {
|
|
10
|
-
return new Promise(function (resolve, reject) {
|
|
11
|
-
Counter('get', '/classes/Counter?where=' + encodeURIComponent(JSON.stringify({url})))
|
|
12
|
-
.then(resp => resp.json())
|
|
13
|
-
.then(({results, code, error}) => {
|
|
14
|
-
if (code === 401) {
|
|
15
|
-
throw error;
|
|
16
|
-
}
|
|
17
|
-
if (results && results.length > 0) {
|
|
18
|
-
var record = results[0];
|
|
19
|
-
resolve(record);
|
|
20
|
-
} else {
|
|
21
|
-
Counter('post', '/classes/Counter', {url, title: title, times: 0})
|
|
22
|
-
.then(resp => resp.json())
|
|
23
|
-
.then((record, error) => {
|
|
24
|
-
if (error) {
|
|
25
|
-
throw error;
|
|
26
|
-
}
|
|
27
|
-
resolve(record);
|
|
28
|
-
}).catch(error => {
|
|
29
|
-
console.error('Failed to create', error);
|
|
30
|
-
reject(error);
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
|
-
}).catch((error) => {
|
|
34
|
-
console.error('LeanCloud Counter Error:', error);
|
|
35
|
-
reject(error);
|
|
36
|
-
});
|
|
37
|
-
})
|
|
38
|
-
},
|
|
39
|
-
|
|
40
|
-
// 发起自增请求
|
|
41
|
-
increment(Counter, incrArr) {
|
|
42
|
-
return new Promise(function (resolve, reject) {
|
|
43
|
-
Counter('post', '/batch', {
|
|
44
|
-
"requests": incrArr
|
|
45
|
-
}).then((res) => {
|
|
46
|
-
res = res.json();
|
|
47
|
-
if (res.error) {
|
|
48
|
-
throw res.error;
|
|
49
|
-
}
|
|
50
|
-
resolve(res);
|
|
51
|
-
}).catch((error) => {
|
|
52
|
-
console.error('Failed to save visitor count', error);
|
|
53
|
-
reject(error);
|
|
54
|
-
});
|
|
55
|
-
});
|
|
56
|
-
},
|
|
57
|
-
|
|
58
|
-
// 构建自增请求体
|
|
59
|
-
buildIncrement(objectId) {
|
|
60
|
-
return {
|
|
61
|
-
"method": "PUT",
|
|
62
|
-
"path": `/1.1/classes/Counter/${ objectId }`,
|
|
63
|
-
"body": {
|
|
64
|
-
"times": {
|
|
65
|
-
'__op': 'Increment',
|
|
66
|
-
'amount': 1
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
},
|
|
71
|
-
|
|
72
|
-
// 校验是否为有效的 UV
|
|
73
|
-
validUV() {
|
|
74
|
-
var key = 'LeanCloudUVTimestamp';
|
|
75
|
-
var flag = localStorage.getItem(key);
|
|
76
|
-
if (flag) {
|
|
77
|
-
// 距离标记小于 24 小时则不计为 UV
|
|
78
|
-
if (new Date().getTime() - parseInt(flag) <= 86400000) {
|
|
79
|
-
return false;
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
localStorage.setItem(key, new Date().getTime().toString());
|
|
83
|
-
return true;
|
|
84
|
-
},
|
|
85
|
-
|
|
86
|
-
addCount(Counter) {
|
|
87
|
-
var enableIncr = '<%= theme.analytics.enable %>' === 'true' && window.location.hostname !== 'localhost';
|
|
88
|
-
enableIncr = true;
|
|
89
|
-
var getterArr = [];
|
|
90
|
-
var incrArr = [];
|
|
91
|
-
// 请求 PV 并自增
|
|
92
|
-
var pvCtn = document.querySelector('#lc-sv');
|
|
93
|
-
if (pvCtn || enableIncr) {
|
|
94
|
-
var pvGetter = this.getRecord(Counter, '<%- config.url %>' + '/#lc-sv', 'Visits').then((record) => {
|
|
95
|
-
incrArr.push(this.buildIncrement(record.objectId))
|
|
96
|
-
var eles = document.querySelectorAll('#lc-sv #number');
|
|
97
|
-
if (eles.length > 0) {
|
|
98
|
-
eles.forEach((el,index,array)=>{
|
|
99
|
-
el.innerText = record.times + 1;
|
|
100
|
-
if (pvCtn) {
|
|
101
|
-
pvCtn.style.display = 'inline';
|
|
102
|
-
}
|
|
103
|
-
})
|
|
104
|
-
}
|
|
105
|
-
});
|
|
106
|
-
getterArr.push(pvGetter);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// 请求 UV 并自增
|
|
110
|
-
var uvCtn = document.querySelector('#lc-uv');
|
|
111
|
-
if (uvCtn || enableIncr) {
|
|
112
|
-
var uvGetter = this.getRecord(Counter, '<%- config.url %>' + '/#lc-uv', 'Visitors').then((record) => {
|
|
113
|
-
var vuv = this.validUV();
|
|
114
|
-
vuv && incrArr.push(this.buildIncrement(record.objectId))
|
|
115
|
-
var eles = document.querySelectorAll('#lc-uv #number');
|
|
116
|
-
if (eles.length > 0) {
|
|
117
|
-
eles.forEach((el,index,array)=>{
|
|
118
|
-
el.innerText = record.times + (vuv ? 1 : 0);
|
|
119
|
-
if (uvCtn) {
|
|
120
|
-
uvCtn.style.display = 'inline';
|
|
121
|
-
}
|
|
122
|
-
})
|
|
123
|
-
}
|
|
124
|
-
});
|
|
125
|
-
getterArr.push(uvGetter);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// 请求文章的浏览数,如果是当前页面就自增
|
|
129
|
-
var allPV = document.querySelectorAll('#lc-pv');
|
|
130
|
-
if (allPV.length > 0 || enableIncr) {
|
|
131
|
-
for (i = 0; i < allPV.length; i++) {
|
|
132
|
-
let pv = allPV[i];
|
|
133
|
-
let title = pv.getAttribute('data-title');
|
|
134
|
-
var url = '<%- config.url %>' + pv.getAttribute('data-path');
|
|
135
|
-
if (url) {
|
|
136
|
-
var viewGetter = this.getRecord(Counter, url, title).then((record) => {
|
|
137
|
-
// 是当前页面就自增
|
|
138
|
-
let curPath = window.location.pathname;
|
|
139
|
-
if (curPath.includes('index.html')) {
|
|
140
|
-
curPath = curPath.substring(0, curPath.lastIndexOf('index.html'));
|
|
141
|
-
}
|
|
142
|
-
if (pv.getAttribute('data-path') == curPath) {
|
|
143
|
-
incrArr.push(this.buildIncrement(record.objectId));
|
|
144
|
-
}
|
|
145
|
-
if (pv) {
|
|
146
|
-
var ele = pv.querySelector('#lc-pv #number');
|
|
147
|
-
if (ele) {
|
|
148
|
-
if (pv.getAttribute('data-path') == curPath) {
|
|
149
|
-
ele.innerText = (record.times || 0) + 1;
|
|
150
|
-
} else {
|
|
151
|
-
ele.innerText = record.times || 0;
|
|
152
|
-
}
|
|
153
|
-
pv.style.display = 'inline';
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
});
|
|
157
|
-
getterArr.push(viewGetter);
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
// 如果启动计数自增,批量发起自增请求
|
|
163
|
-
if (enableIncr) {
|
|
164
|
-
Promise.all(getterArr).then(() => {
|
|
165
|
-
incrArr.length > 0 && this.increment(Counter, incrArr);
|
|
166
|
-
})
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
},
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
fetchData(api_server) {
|
|
173
|
-
var Counter = (method, url, data) => {
|
|
174
|
-
return fetch(`${ api_server }/1.1${ url }`, {
|
|
175
|
-
method,
|
|
176
|
-
headers: {
|
|
177
|
-
'X-LC-Id': this.app_id,
|
|
178
|
-
'X-LC-Key': this.app_key,
|
|
179
|
-
'Content-Type': 'application/json',
|
|
180
|
-
},
|
|
181
|
-
body: JSON.stringify(data)
|
|
182
|
-
});
|
|
183
|
-
};
|
|
184
|
-
this.addCount(Counter);
|
|
185
|
-
},
|
|
186
|
-
|
|
187
|
-
refreshCounter() {
|
|
188
|
-
var api_server = this.custom_api_server || `https://${ this.app_id.slice(0, 8).toLowerCase() }.api.lncldglobal.com`;
|
|
189
|
-
if (api_server) {
|
|
190
|
-
this.fetchData(api_server);
|
|
191
|
-
} else {
|
|
192
|
-
fetch('https://app-router.leancloud.cn/2/route?appId=' + this.app_id)
|
|
193
|
-
.then(resp => resp.json())
|
|
194
|
-
.then(({api_server}) => {
|
|
195
|
-
this.fetchData('https://' + api_server);
|
|
196
|
-
});
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
};
|
|
201
|
-
|
|
202
|
-
LCCounter.refreshCounter();
|
|
203
|
-
|
|
204
|
-
document.addEventListener('pjax:complete', function () {
|
|
205
|
-
LCCounter.refreshCounter();
|
|
206
|
-
});
|
|
207
|
-
</script>
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
<!-- 样式位于:source/css/_plugins/pjaxanimate.styl -->
|
|
2
|
-
|
|
3
|
-
<div class="pjax-animate">
|
|
4
|
-
<% if (theme.plugins.pjax.animation == 'nprogress') { %>
|
|
5
|
-
<script src="<%- theme.plugins.pjax.nprogress %>"></script>
|
|
6
|
-
<div id="loading-bar-wrapper"><script>NProgress.configure({parent:"#loading-bar-wrapper",trickleSpeed: 100})</script></div>
|
|
7
|
-
<script>
|
|
8
|
-
window.ShowLoading = function() {
|
|
9
|
-
NProgress.start();
|
|
10
|
-
};
|
|
11
|
-
window.HideLoading = function() {
|
|
12
|
-
NProgress.done();
|
|
13
|
-
}
|
|
14
|
-
</script>
|
|
15
|
-
<%} else if (theme.plugins.pjax.animation == 'circle') { %>
|
|
16
|
-
<div class="loading-circle"><div id="loader-circle"></div></div>
|
|
17
|
-
<script>
|
|
18
|
-
window.ShowLoading = function() {
|
|
19
|
-
document.querySelector(".loading-circle").style.display="block"
|
|
20
|
-
};
|
|
21
|
-
window.HideLoading = function() {
|
|
22
|
-
document.querySelector(".loading-circle").style.display="none"
|
|
23
|
-
}
|
|
24
|
-
</script>
|
|
25
|
-
<% } %>
|
|
26
|
-
<script>
|
|
27
|
-
volantis.pjax.push(window.HideLoading,'HideLoading');
|
|
28
|
-
volantis.pjax.send(window.ShowLoading,'ShowLoading');
|
|
29
|
-
volantis.pjax.error(window.HideLoading,'HideLoading');
|
|
30
|
-
</script>
|
|
31
|
-
</div>
|
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
<% if (theme.rightmenu.enable == true && theme.rightmenu.layout.length > 0) { %>
|
|
2
|
-
<% let faIcon = theme.rightmenu.faicon %>
|
|
3
|
-
<% function loadmenu(obj) { %>
|
|
4
|
-
<li class="menuLoad-Content">
|
|
5
|
-
<a class='vlts-menu fix-cursor-default' <%= obj.url ? 'href='+ url_for(obj.url)+'' : ''%>
|
|
6
|
-
<% if (obj.rel) { %>
|
|
7
|
-
rel="<%- obj.rel %>"
|
|
8
|
-
<% } %>
|
|
9
|
-
<% if (obj.target) { %>
|
|
10
|
-
target="<%- obj.target %>"
|
|
11
|
-
<% } %>
|
|
12
|
-
<% if (obj.onclick) { %>
|
|
13
|
-
onclick="<%- obj.onclick %>"
|
|
14
|
-
<% } %>
|
|
15
|
-
<% if (obj.id) { %>
|
|
16
|
-
id="<%- obj.id %>"
|
|
17
|
-
<% } else if (obj.url) { %>
|
|
18
|
-
id="<%= url_for(obj.url).replace(/\/|%|\./g, "")?url_for(obj.url).replace(/\/|%|\./g, ""):"home" %>"
|
|
19
|
-
<% } %>
|
|
20
|
-
>
|
|
21
|
-
<% if (obj.icon) { %><i class='<%= obj.icon %> fa-fw'></i><% } %> <%- obj.name %>
|
|
22
|
-
</a>
|
|
23
|
-
</li>
|
|
24
|
-
<% } %>
|
|
25
|
-
<div id="rightmenu-wrapper">
|
|
26
|
-
<ul class="list-v rightmenu" id="rightmenu-content">
|
|
27
|
-
<li class='navigation menuNavigation-Content'>
|
|
28
|
-
<a class='nav icon-only fix-cursor-default' onclick='history.back()'><i class='<%= faIcon %> fa-arrow-left fa-fw'></i></a>
|
|
29
|
-
<a class='nav icon-only fix-cursor-default' onclick='history.forward()'><i class='<%= faIcon %> fa-arrow-right fa-fw'></i></a>
|
|
30
|
-
<a class='nav icon-only fix-cursor-default' onclick='window.location.reload()'><i class='<%= faIcon %> fa-redo fa-fw'></i></a>
|
|
31
|
-
<a class='nav icon-only fix-cursor-default' href='/'><i class='<%= faIcon %> fa-home fa-fw'></i></a>
|
|
32
|
-
</li>
|
|
33
|
-
<li class='option menuOption-Content'>
|
|
34
|
-
<span class='vlts-menu opt fix-cursor-default menu-Option' data-fn-type='copyText'>
|
|
35
|
-
<% let copy_text = __('rightmenu.copy_text') %>
|
|
36
|
-
<i class='<%= faIcon %> fa-copy fa-fw'></i> <%- trim(copy_text) %>
|
|
37
|
-
</span>
|
|
38
|
-
<span class='vlts-menu opt fix-cursor-default menu-Option' data-fn-type='copyPaste'>
|
|
39
|
-
<% let copy_paste = __('rightmenu.copy_paste') %>
|
|
40
|
-
<i class='<%= faIcon %> fa-paste fa-fw mR12'></i> <%- trim(copy_paste) %>
|
|
41
|
-
</span>
|
|
42
|
-
<span class='vlts-menu opt fix-cursor-default menu-Option' data-fn-type='copySelect'>
|
|
43
|
-
<% let copy_select = __('rightmenu.copy_select') %>
|
|
44
|
-
<i class='<%= faIcon %> fa-object-ungroup fa-fw mR12'></i> <%- trim(copy_select) %>
|
|
45
|
-
</span>
|
|
46
|
-
<span class='vlts-menu opt fix-cursor-default menu-Option' data-fn-type='copyCut'>
|
|
47
|
-
<% let copy_cut = __('rightmenu.copy_cut') %>
|
|
48
|
-
<i class='<%= faIcon %> fa-cut fa-fw mR12'></i> <%- trim(copy_cut) %>
|
|
49
|
-
</span>
|
|
50
|
-
<% if (theme.search.enable) { %>
|
|
51
|
-
<span class='vlts-menu opt fix-cursor-default menu-Option' data-fn-type='searchWord'>
|
|
52
|
-
<% let search_word = __('rightmenu.search_word') %>
|
|
53
|
-
<i class='<%= faIcon %> fa-search fa-fw'></i> <%- trim(search_word) %>
|
|
54
|
-
</span>
|
|
55
|
-
<% } %>
|
|
56
|
-
<span class='vlts-menu opt fix-cursor-default menu-Option' data-fn-type='openTab'>
|
|
57
|
-
<% let open_in_new_tab = __('rightmenu.open_in_new_tab') %>
|
|
58
|
-
<i class='<%= faIcon %> fa-external-link-square-alt fa-fw mR12'></i> <%- trim(open_in_new_tab) %>
|
|
59
|
-
</span>
|
|
60
|
-
<span class='vlts-menu opt fix-cursor-default menu-Option' data-fn-type='copySrc'>
|
|
61
|
-
<% let copy_image_src = __('rightmenu.copy_image_src') %>
|
|
62
|
-
<i class='<%= faIcon %> fa-image fa-fw mR12'></i> <%- trim(copy_image_src) %>
|
|
63
|
-
</span>
|
|
64
|
-
<span class='vlts-menu opt fix-cursor-default menu-Option' data-fn-type='copyImg'>
|
|
65
|
-
<% let copy_image_file = __('rightmenu.copy_image_file') %>
|
|
66
|
-
<i class='<%= faIcon %> fa-images fa-fw mR12'></i> <%- trim(copy_image_file) %>
|
|
67
|
-
</span>
|
|
68
|
-
</li>
|
|
69
|
-
<% theme.rightmenu.layout.forEach(function(item){ %>
|
|
70
|
-
<% if (item == 'hr') { %>
|
|
71
|
-
<hr class="menuLoad-Content">
|
|
72
|
-
<% } else if (item == 'darkmode') { %>
|
|
73
|
-
<li class='option menuOption-Content'>
|
|
74
|
-
<span class='vlts-menu opt fix-cursor-default toggle-mode-btn' id='menuDarkBtn'>
|
|
75
|
-
<i class='<%= theme.rightmenu.darkmode.icon %> fa-fw '></i> <%- trim(theme.rightmenu.darkmode.name) %>
|
|
76
|
-
</span>
|
|
77
|
-
</li>
|
|
78
|
-
<% } else if (item == 'print') { %>
|
|
79
|
-
<li class='option menuOption-Content'>
|
|
80
|
-
<span class='vlts-menu opt fix-cursor-default' id='printHtml'>
|
|
81
|
-
<i class='<%= theme.rightmenu.print.icon %> fa-fw '></i> <%- trim(theme.rightmenu.print.name) %>
|
|
82
|
-
</span>
|
|
83
|
-
</li>
|
|
84
|
-
<% } else if (item == 'reading') { %>
|
|
85
|
-
<li class='option menuOption-Content'>
|
|
86
|
-
<span class='vlts-menu opt fix-cursor-default' id='readingModel'>
|
|
87
|
-
<i class='<%= theme.rightmenu.reading.icon %> fa-fw '></i> <%- trim(theme.rightmenu.reading.name) %>
|
|
88
|
-
</span>
|
|
89
|
-
</li>
|
|
90
|
-
<% } else if (item == 'music' && theme.plugins.aplayer.enable == true) { %>
|
|
91
|
-
<div id="menuMusic">
|
|
92
|
-
<li class='music name menuOption-Content'>
|
|
93
|
-
<p class='nav music-title fix-cursor-default'></p>
|
|
94
|
-
</li>
|
|
95
|
-
<li class='music ctrl'>
|
|
96
|
-
<a class='nav icon-only backward fix-cursor-default' href="/" onclick="return false;" title="backward"><i class='<%= faIcon %> fa-step-backward fa-fw'></i></a>
|
|
97
|
-
<a class='nav icon-only toggle fix-cursor-default' href="/" onclick="return false;" title="toggle"><i class='<%= faIcon %> fa-play fa-fw'></i></a>
|
|
98
|
-
<a class='nav icon-only forward fix-cursor-default' href="/" onclick="return false;" title="forward"><i class='<%= faIcon %> fa-step-forward fa-fw'></i></a>
|
|
99
|
-
</li>
|
|
100
|
-
<li class='music volume'>
|
|
101
|
-
<div class='nav volume'>
|
|
102
|
-
<div class="aplayer-volume-bar-wrap">
|
|
103
|
-
<div class="aplayer-volume-bar fix-cursor-pointer">
|
|
104
|
-
<div class="aplayer-volume"></div>
|
|
105
|
-
<i class='left <%= faIcon %> fa-volume-off fa-fw'></i>
|
|
106
|
-
<i class='right <%= faIcon %> fa-volume-up fa-fw'></i>
|
|
107
|
-
</div>
|
|
108
|
-
</div>
|
|
109
|
-
</div>
|
|
110
|
-
</li>
|
|
111
|
-
</div>
|
|
112
|
-
<% } else if (item in theme.rightmenu) { %>
|
|
113
|
-
<% loadmenu(theme.rightmenu[item]) %>
|
|
114
|
-
<% } %>
|
|
115
|
-
<% }) %>
|
|
116
|
-
</ul>
|
|
117
|
-
</div>
|
|
118
|
-
<script>volantis.js('<%- theme.cdn.map.js.rightMenu %>')</script>
|
|
119
|
-
<% } %>
|
|
@@ -1,167 +0,0 @@
|
|
|
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 filePath;
|
|
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
|
-
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
|
-
|
|
86
|
-
};
|
|
87
|
-
|
|
88
|
-
const replaceRevisionPlaceholder = async () => {
|
|
89
|
-
|
|
90
|
-
if (!hexo.theme.config.cdn_version) {
|
|
91
|
-
return;
|
|
92
|
-
}
|
|
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);
|
|
148
|
-
}
|
|
149
|
-
}
|
|
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
|
-
hexo.log.error("cdn_version ERROR: " + error);
|
|
164
|
-
}
|
|
165
|
-
};
|
|
166
|
-
|
|
167
|
-
hexo.extend.filter.register("after_generate", replaceRevisionPlaceholder,9999);
|
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
// nprogress
|
|
2
|
-
/* Make clicks pass-through */
|
|
3
|
-
#nprogress
|
|
4
|
-
pointer-events: none
|
|
5
|
-
|
|
6
|
-
#nprogress .bar
|
|
7
|
-
background: $color-theme
|
|
8
|
-
position: fixed
|
|
9
|
-
z-index: 3000
|
|
10
|
-
top: 0
|
|
11
|
-
left: 0
|
|
12
|
-
width: 100%
|
|
13
|
-
height: 100%
|
|
14
|
-
|
|
15
|
-
/* Fancy blur effect */
|
|
16
|
-
#nprogress .peg
|
|
17
|
-
display: block
|
|
18
|
-
position: absolute
|
|
19
|
-
right: 0px
|
|
20
|
-
width: 100px
|
|
21
|
-
height: 100%
|
|
22
|
-
opacity: 1.0
|
|
23
|
-
-webkit-transform: rotate(3deg) translate(0px, -4px)
|
|
24
|
-
-ms-transform: rotate(3deg) translate(0px, -4px)
|
|
25
|
-
transform: rotate(3deg) translate(0px, -4px)
|
|
26
|
-
|
|
27
|
-
/* Remove these to get rid of the spinner */
|
|
28
|
-
#nprogress .spinner
|
|
29
|
-
display: block
|
|
30
|
-
position: fixed
|
|
31
|
-
z-index: 3000
|
|
32
|
-
top: 15px
|
|
33
|
-
right: 15px
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
#nprogress .spinner-icon
|
|
37
|
-
width: 18px
|
|
38
|
-
height: 18px
|
|
39
|
-
box-sizing: border-box
|
|
40
|
-
border: solid 2px transparent
|
|
41
|
-
border-top-color: #29d
|
|
42
|
-
border-left-color: #29d
|
|
43
|
-
border-radius: 50%
|
|
44
|
-
|
|
45
|
-
-webkit-animation: nprogress-spinner 400ms linear infinite
|
|
46
|
-
animation: nprogress-spinner 400ms linear infinite
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
.nprogress-custom-parent
|
|
50
|
-
overflow: hidden
|
|
51
|
-
position: relative
|
|
52
|
-
|
|
53
|
-
.nprogress-custom-parent #nprogress .spinner,
|
|
54
|
-
.nprogress-custom-parent #nprogress .bar
|
|
55
|
-
position: absolute
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
@-webkit-keyframes nprogress-spinner
|
|
59
|
-
0%
|
|
60
|
-
-webkit-transform: rotate(0deg)
|
|
61
|
-
100%
|
|
62
|
-
-webkit-transform: rotate(360deg)
|
|
63
|
-
|
|
64
|
-
@keyframes nprogress-spinner
|
|
65
|
-
0%
|
|
66
|
-
transform: rotate(0deg)
|
|
67
|
-
100%
|
|
68
|
-
transform: rotate(360deg)
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
#loading-bar-wrapper
|
|
73
|
-
position: fixed
|
|
74
|
-
width: 100px
|
|
75
|
-
top: 8px
|
|
76
|
-
left: 50%
|
|
77
|
-
transform: translateX(-50%)
|
|
78
|
-
height: 8px
|
|
79
|
-
border-radius: 8px
|
|
80
|
-
z-index: 2000
|
|
81
|
-
background: transparent
|
|
82
|
-
&.nprogress-custom-parent
|
|
83
|
-
background: var(--color-card)
|
|
84
|
-
box-shadow: $boxshadow-card
|
|
85
|
-
|
|
86
|
-
// circle
|
|
87
|
-
.loading-circle
|
|
88
|
-
display none
|
|
89
|
-
height 100%
|
|
90
|
-
width 100%
|
|
91
|
-
position fixed
|
|
92
|
-
top 0
|
|
93
|
-
left 0
|
|
94
|
-
z-index 999999
|
|
95
|
-
background-color rgba(250,250,250,.9)
|
|
96
|
-
img
|
|
97
|
-
width 280px
|
|
98
|
-
height 210px
|
|
99
|
-
position relative
|
|
100
|
-
top 45%
|
|
101
|
-
left 50%
|
|
102
|
-
margin-left -140px
|
|
103
|
-
margin-top -105px
|
|
104
|
-
|
|
105
|
-
#loader-circle
|
|
106
|
-
display block
|
|
107
|
-
position relative
|
|
108
|
-
left 50%
|
|
109
|
-
top 50%
|
|
110
|
-
width 150px
|
|
111
|
-
height 150px
|
|
112
|
-
margin -75px 0 0 -75px
|
|
113
|
-
border-radius 50%
|
|
114
|
-
border 3px solid transparent
|
|
115
|
-
border-top-color #ff5a5a
|
|
116
|
-
-webkit-animation spin 1s linear infinite
|
|
117
|
-
animation spin 1s linear infinite
|
|
118
|
-
&:before
|
|
119
|
-
content ""
|
|
120
|
-
position absolute
|
|
121
|
-
top 5px
|
|
122
|
-
left 5px
|
|
123
|
-
right 5px
|
|
124
|
-
bottom 5px
|
|
125
|
-
border-radius 50%
|
|
126
|
-
border 3px solid transparent
|
|
127
|
-
border-top-color #5af33f
|
|
128
|
-
-webkit-animation spin 3s linear infinite
|
|
129
|
-
animation spin 3s linear infinite
|
|
130
|
-
&:after
|
|
131
|
-
content ""
|
|
132
|
-
position absolute
|
|
133
|
-
top 15px
|
|
134
|
-
left 15px
|
|
135
|
-
right 15px
|
|
136
|
-
bottom 15px
|
|
137
|
-
border-radius 50%
|
|
138
|
-
border 3px solid transparent
|
|
139
|
-
border-top-color #6dc9ff
|
|
140
|
-
-webkit-animation spin 2s linear infinite
|
|
141
|
-
animation spin 2s linear infinite
|
|
142
|
-
|
|
143
|
-
@-webkit-keyframes spin
|
|
144
|
-
0%
|
|
145
|
-
-webkit-transform: rotate(0deg)
|
|
146
|
-
-ms-transform: rotate(0deg)
|
|
147
|
-
transform: rotate(0deg)
|
|
148
|
-
100%
|
|
149
|
-
-webkit-transform: rotate(360deg)
|
|
150
|
-
-ms-transform: rotate(360deg)
|
|
151
|
-
transform: rotate(360deg)
|
|
152
|
-
@keyframes spin
|
|
153
|
-
0%
|
|
154
|
-
-webkit-transform: rotate(0deg)
|
|
155
|
-
-ms-transform: rotate(0deg)
|
|
156
|
-
transform: rotate(0deg)
|
|
157
|
-
100%
|
|
158
|
-
-webkit-transform: rotate(360deg)
|
|
159
|
-
-ms-transform: rotate(360deg)
|
|
160
|
-
transform: rotate(360deg)
|