hexo-theme-shokax 0.2.0 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,12 +1,8 @@
1
- /* global hexo */
2
-
3
- 'use strict'
4
- const { htmlTag, url_for, stripHTML } = require('hexo-util')
5
- const theme_env = require('../../package.json')
6
-
1
+ import theme_env from '../../package.json';
2
+ import { htmlTag, url_for, stripHTML } from 'hexo-util';
7
3
  hexo.extend.helper.register('_new_comments', function (mode) {
8
- if (mode === 'twikoo') {
9
- return `<script data-pjax type="module">
4
+ if (mode === 'twikoo') {
5
+ return `<script data-pjax type="module">
10
6
  let comments = []
11
7
  twikoo.getRecentComments({
12
8
  envId: "${hexo.theme.config?.twikoo?.envId}",
@@ -35,9 +31,10 @@ hexo.extend.helper.register('_new_comments', function (mode) {
35
31
  }).catch(function (err) {
36
32
  console.error(err)
37
33
  })
38
- </script>`
39
- } else if (mode === 'waline') {
40
- return `
34
+ </script>`;
35
+ }
36
+ else if (mode === 'waline') {
37
+ return `
41
38
  <script type="module" data-pjax>
42
39
  import { RecentComments } from 'https://unpkg.com/@waline/client@v2/dist/waline.mjs'
43
40
  RecentComments({
@@ -46,138 +43,130 @@ hexo.extend.helper.register('_new_comments', function (mode) {
46
43
  count: 10,
47
44
  });
48
45
  </script>
49
- `
50
- } else {
51
- console.log(`${mode} is not supported recent comment`)
52
- }
53
- })
54
-
46
+ `;
47
+ }
48
+ else {
49
+ console.log(`${mode} is not supported recent comment`);
50
+ }
51
+ });
55
52
  hexo.extend.helper.register('_safedump', (source) => {
56
- return JSON.stringify(source)
57
- })
58
-
53
+ return JSON.stringify(source);
54
+ });
59
55
  hexo.extend.helper.register('hexo_env', function (type) {
60
- return this.env[type]
61
- })
62
-
56
+ return this.env[type];
57
+ });
63
58
  hexo.extend.helper.register('theme_env', function (type) {
64
- return theme_env[type]
65
- })
66
-
59
+ return theme_env[type];
60
+ });
67
61
  hexo.extend.helper.register('_vendor_font', () => {
68
- const config = hexo.theme.config.font
69
-
70
- if (!config || !config.enable) return ''
71
-
72
- const fontDisplay = '&display=swap'
73
- const fontSubset = '&subset=latin,latin-ext'
74
- const fontStyles = ':300,300italic,400,400italic,700,700italic'
75
- const fontHost = '//fonts.geekzu.org'
76
-
77
- // Get a font list from config
78
- let fontFamilies = ['global', 'logo', 'title', 'headings', 'posts', 'codes'].map(item => {
79
- if (config[item] && config[item].family && config[item].external) {
80
- return config[item].family + fontStyles
81
- }
82
- return ''
83
- })
84
-
85
- fontFamilies = fontFamilies.filter(item => item !== '')
86
- fontFamilies = [...new Set(fontFamilies)]
87
- fontFamilies = fontFamilies.join('|')
88
-
89
- // Merge extra parameters to the final processed font string
90
- return fontFamilies
91
- ? htmlTag('link', {
92
- rel: 'stylesheet',
93
- href: `${fontHost}/css?family=${fontFamilies.concat(fontDisplay, fontSubset)}`
94
- })
95
- : ''
96
- })
97
-
98
- // TODO 废弃方法
62
+ const config = hexo.theme.config.font;
63
+ if (!config || !config.enable)
64
+ return '';
65
+ const fontDisplay = '&display=swap';
66
+ const fontSubset = '&subset=latin,latin-ext';
67
+ const fontStyles = ':300,300italic,400,400italic,700,700italic';
68
+ const fontHost = '//fonts.geekzu.org';
69
+ let fontFamilies = ['global', 'logo', 'title', 'headings', 'posts', 'codes'].map(item => {
70
+ if (config[item] && config[item].family && config[item].external) {
71
+ return config[item].family + fontStyles;
72
+ }
73
+ return '';
74
+ });
75
+ fontFamilies = fontFamilies.filter(item => item !== '');
76
+ fontFamilies = [...new Set(fontFamilies)];
77
+ fontFamilies = fontFamilies.join('|');
78
+ return fontFamilies
79
+ ? htmlTag('link', {
80
+ rel: 'stylesheet',
81
+ href: `${fontHost}/css?family=${fontFamilies.concat(fontDisplay, fontSubset)}`
82
+ })
83
+ : '';
84
+ });
99
85
  hexo.extend.helper.register('_vendor_js', () => {
100
- const config = hexo.theme.config.vendors.js
101
-
102
- if (!config) return ''
103
-
104
- // Get a font list from config
105
- let vendorJs = ['pace', 'pjax', 'fetch', 'anime', 'algolia', 'instantsearch', 'lazyload', 'quicklink'].map(item => {
106
- if (config[item]) {
107
- return config[item]
108
- }
109
- return ''
110
- })
111
-
112
- vendorJs = vendorJs.filter(item => item !== '')
113
- vendorJs = [...new Set(vendorJs)]
114
- vendorJs = vendorJs.join(',')
115
- return vendorJs ? htmlTag('script', { src: `https://cdn.jsdelivr.net/combine/${vendorJs}` }, '') : ''
116
- })
117
-
86
+ const config = hexo.theme.config.vendors.js;
87
+ if (!config)
88
+ return '';
89
+ let vendorJs = ['pace', 'pjax', 'fetch', 'anime', 'algolia', 'instantsearch', 'lazyload', 'quicklink'].map(item => {
90
+ if (config[item]) {
91
+ return config[item];
92
+ }
93
+ return '';
94
+ });
95
+ vendorJs = vendorJs.filter(item => item !== '');
96
+ vendorJs = [...new Set(vendorJs)];
97
+ vendorJs = vendorJs.join(',');
98
+ return vendorJs ? htmlTag('script', { src: `https://cdn.jsdelivr.net/combine/${vendorJs}` }, '') : '';
99
+ });
118
100
  hexo.extend.helper.register('_css', function (...urls) {
119
- const { statics, css } = hexo.theme.config
120
-
121
- return urls.map(url => htmlTag('link', {
122
- rel: 'stylesheet',
123
- href: url_for.call(this, `${statics}${css}/${url}?v=${theme_env.version}`)
124
- })).join('')
125
- })
126
-
101
+ const { statics, css } = hexo.theme.config;
102
+ return urls.map(url => htmlTag('link', {
103
+ rel: 'stylesheet',
104
+ href: url_for.call(this, `${statics}${css}/${url}?v=${theme_env.version}`)
105
+ })).join('');
106
+ });
127
107
  hexo.extend.helper.register('_js', function (...urls) {
128
- const { statics, js } = hexo.theme.config
129
-
130
- return urls.map(url => htmlTag('script', { src: url_for.call(this, `${statics}${js}/${url}?v=${theme_env.version}`) }, '')).join('')
131
- })
108
+ const { statics, js } = hexo.theme.config;
109
+ return urls.map(url => htmlTag('script', { src: url_for.call(this, `${statics}${js}/${url}?v=${theme_env.version}`) }, '')).join('');
110
+ });
132
111
  hexo.extend.helper.register('_list_vendor_js', () => {
133
- return hexo.theme.config.vendorsList.js
134
- })
135
-
112
+ return hexo.theme.config.vendorsList.js;
113
+ });
136
114
  hexo.extend.helper.register('_adv_vendor_js', function (js_name) {
137
- const srcHelpers = (src) => { return src.endsWith('/') ? src : src + '/' }
138
- const config = hexo.theme.config.advVendors.js[js_name]
139
- const themeConfig = hexo.theme.config
140
- const src = config.src
141
- const publicCdns = {
142
- npm: srcHelpers(themeConfig.advVendors.npm),
143
- gh: srcHelpers(themeConfig.advVendors.github),
144
- combine: srcHelpers(themeConfig.advVendors.combine),
145
- bytedance: 'https://lf9-cdn-tos.bytecdntp.com/cdn/expire-6-M/',
146
- baomitu: 'https://lib.baomitu.com/'
147
- }
148
- let result
149
- if (src.startsWith('http')) {
150
- result = src
151
- } else if (src.startsWith('combine:')) {
152
- hexo.log.info('The combine feature is not recommended!')
153
- result = publicCdns.combine + src
154
- } else if (src.startsWith('npm:')) {
155
- result = publicCdns.npm + src.substring(4)
156
- } else if (src.startsWith('gh:')) {
157
- result = publicCdns.gh + src.substring(3)
158
- } else if (src.startsWith('bytedance:')) {
159
- result = publicCdns.bytedance + src.substring(10)
160
- } else if (src.startsWith('baomitu:')) {
161
- result = publicCdns.baomitu + src.substring(8)
162
- } else {
163
- result = '/' + src
164
- }
165
- const attr = { src: result }
166
- if (config.async) attr.async = 'async'
167
- if (config['data-pjax']) attr['data-pjax'] = 'data-pjax'
168
- if (config['hash-value']) attr.integrity = config['hash-value']
169
- if (config.deferLoad) {
170
- return htmlTag('script', { 'data-pjax': true }, `
115
+ const srcHelpers = (src) => { return src.endsWith('/') ? src : src + '/'; };
116
+ const config = hexo.theme.config.advVendors.js[js_name];
117
+ const themeConfig = hexo.theme.config;
118
+ const src = config.src;
119
+ const publicCdns = {
120
+ npm: srcHelpers(themeConfig.advVendors.npm),
121
+ gh: srcHelpers(themeConfig.advVendors.github),
122
+ combine: srcHelpers(themeConfig.advVendors.combine),
123
+ bytedance: 'https://lf9-cdn-tos.bytecdntp.com/cdn/expire-6-M/',
124
+ baomitu: 'https://lib.baomitu.com/'
125
+ };
126
+ let result;
127
+ if (src.startsWith('http')) {
128
+ result = src;
129
+ }
130
+ else if (src.startsWith('combine:')) {
131
+ hexo.log.info('The combine feature is not recommended!');
132
+ result = publicCdns.combine + src;
133
+ }
134
+ else if (src.startsWith('npm:')) {
135
+ result = publicCdns.npm + src.substring(4);
136
+ }
137
+ else if (src.startsWith('gh:')) {
138
+ result = publicCdns.gh + src.substring(3);
139
+ }
140
+ else if (src.startsWith('bytedance:')) {
141
+ result = publicCdns.bytedance + src.substring(10);
142
+ }
143
+ else if (src.startsWith('baomitu:')) {
144
+ result = publicCdns.baomitu + src.substring(8);
145
+ }
146
+ else {
147
+ result = '/' + src;
148
+ }
149
+ const attr = {
150
+ src: result,
151
+ integrity: undefined,
152
+ async: undefined
153
+ };
154
+ if (config.async)
155
+ attr.async = 'async';
156
+ if (config['data-pjax'])
157
+ attr['data-pjax'] = 'data-pjax';
158
+ if (config['hash-value'])
159
+ attr.integrity = config['hash-value'];
160
+ if (config.deferLoad) {
161
+ return htmlTag('script', { 'data-pjax': true }, `
171
162
  const script=document.createElement("script");script.src="${result}",script.async=true,document.body.appendChild(script)
172
- `)
173
- }
174
- return htmlTag('script', attr, '')
175
- })
176
-
163
+ `);
164
+ }
165
+ return htmlTag('script', attr, '');
166
+ });
177
167
  hexo.extend.helper.register('_striptags', function (data) {
178
- return stripHTML(data)
179
- })
180
-
168
+ return stripHTML(data);
169
+ });
181
170
  hexo.extend.helper.register('_truncate', function (data, end) {
182
- return data.substring(0, end)
183
- })
171
+ return data.substring(0, end);
172
+ });
@@ -1,201 +1,143 @@
1
- /* global hexo */
2
-
3
- 'use strict'
4
-
5
- const { htmlTag, url_for } = require('hexo-util')
6
-
7
- const randomServer = parseInt(String(Math.random() * 4), 10) + 1
8
-
1
+ 'use strict';
2
+ import { htmlTag, url_for } from 'hexo-util';
3
+ const randomServer = parseInt(String(Math.random() * 4), 10) + 1;
9
4
  const randomBG = function (count = 1, image_server = null, image_list = []) {
10
- let i
11
- if (image_server) {
5
+ let i;
6
+ if (image_server) {
7
+ if (count && count > 1) {
8
+ const arr = new Array(count);
9
+ for (i = 0; i < arr.length; i++) {
10
+ arr[i] = image_server + '?' + Math.floor(Math.random() * 999999);
11
+ }
12
+ return arr;
13
+ }
14
+ return image_server + '?' + Math.floor(Math.random() * 999999);
15
+ }
16
+ const parseImage = function (img, size) {
17
+ if (img.startsWith('//') || img.startsWith('http')) {
18
+ return img;
19
+ }
20
+ else if (hexo.theme.config.experiments?.usingRelative) {
21
+ return img;
22
+ }
23
+ else {
24
+ console.warn("sinaimg blocked all request from outside website,so don't use this format");
25
+ return `https://tva${randomServer}.sinaimg.cn/` + size + '/' + img;
26
+ }
27
+ };
12
28
  if (count && count > 1) {
13
- const arr = new Array(count)
14
- for (i = 0; i < arr.length; i++) {
15
- arr[i] = image_server + '?' + Math.floor(Math.random() * 999999)
16
- }
17
-
18
- return arr
29
+ const shuffled = image_list.slice(0);
30
+ i = image_list.length;
31
+ const min = i - count;
32
+ let temp;
33
+ let index;
34
+ while (i-- > min) {
35
+ index = Math.floor((i + 1) * Math.random());
36
+ temp = shuffled[index];
37
+ shuffled[index] = shuffled[i];
38
+ shuffled[i] = temp;
39
+ }
40
+ return shuffled.slice(min).map(function (img) {
41
+ return parseImage(img, 'large');
42
+ });
19
43
  }
20
-
21
- return image_server + '?' + Math.floor(Math.random() * 999999)
22
- }
23
-
24
- const parseImage = function (img, size) {
25
- if (img.startsWith('//') || img.startsWith('http')) {
26
- return img
27
- } else if (hexo.theme.config.experiments?.usingRelative) { // support relative url
28
- return img
29
- } else {
30
- console.warn("sinaimg blocked all request from outside website,so don't use this format")
31
- return `https://tva${randomServer}.sinaimg.cn/` + size + '/' + img
44
+ return parseImage(image_list[Math.floor(Math.random() * image_list.length)], 'mw690');
45
+ };
46
+ hexo.extend.helper.register('_url', function (path, text, options = {}) {
47
+ if (!path) {
48
+ return;
32
49
  }
33
- }
34
-
35
- if (count && count > 1) {
36
- const shuffled = image_list.slice(0)
37
- i = image_list.length
38
- const min = i - count; let temp; let index
39
- while (i-- > min) {
40
- index = Math.floor((i + 1) * Math.random())
41
- temp = shuffled[index]
42
- shuffled[index] = shuffled[i]
43
- shuffled[i] = temp
50
+ const { config } = this;
51
+ const data = new URL(path, hexo.config.url);
52
+ const siteHost = new URL(config.url).hostname || config.url;
53
+ const theme = hexo.theme.config;
54
+ let exturl = '';
55
+ let tag = 'a';
56
+ let attrs = { href: url_for.call(this, path), class: undefined, external: undefined, rel: undefined, 'data-url': undefined };
57
+ if (theme.exturl && data.protocol && data.hostname !== siteHost) {
58
+ tag = 'span';
59
+ exturl = 'exturl';
60
+ const encoded = Buffer.from(path).toString('base64');
61
+ attrs = {
62
+ class: exturl,
63
+ 'data-url': encoded
64
+ };
44
65
  }
45
-
46
- return shuffled.slice(min).map(function (img) {
47
- return parseImage(img, 'large')
48
- })
49
- }
50
-
51
- return parseImage(image_list[Math.floor(Math.random() * image_list.length)], 'mw690')
52
- }
53
-
54
- // 注册hexo主题中的URL帮助方法
55
- hexo.extend.helper.register('_url', function (path, text, options = {}) {
56
- // 如果未提供URL路径,则返回
57
- if (!path) { return }
58
-
59
- // 获取hexo配置和URL路径信息
60
- const { config } = this
61
- const data = new URL(path, hexo.config.url)
62
- const siteHost = new URL(config.url).hostname || config.url
63
-
64
- // 获取主题配置
65
- const theme = hexo.theme.config
66
- let exturl = ''
67
- let tag = 'a'
68
- let attrs = { href: url_for.call(this, path) }
69
-
70
- // 如果启用了 `exturl`,则只为外部链接设置spanned链接。
71
- if (theme.exturl && data.protocol && data.hostname !== siteHost) {
72
- tag = 'span'
73
- exturl = 'exturl'
74
- // 编码URL字符串,并将其存储在数据属性中。
75
- const encoded = Buffer.from(path).toString('base64')
76
- attrs = {
77
- class: exturl,
78
- 'data-url': encoded
66
+ for (const key in options) {
67
+ if (exturl !== '' && key === 'class') {
68
+ attrs[key] += ' ' + options[key];
69
+ }
70
+ else {
71
+ attrs[key] = options[key];
72
+ }
79
73
  }
80
- }
81
-
82
- for (const key in options) {
83
- /**
84
- * 如果选项包含 `class` 属性,则将其添加到 `exturl` 类中(如果启用了 `exturl` 选项)。
85
- * 否则,将其添加到属性集中。
86
- */
87
- if (exturl !== '' && key === 'class') {
88
- attrs[key] += ' ' + options[key]
89
- } else {
90
- attrs[key] = options[key]
74
+ if (attrs.class && Array.isArray(attrs.class)) {
75
+ attrs.class = attrs.class.join(' ');
91
76
  }
92
- }
93
-
94
- if (attrs.class && Array.isArray(attrs.class)) {
95
- attrs.class = attrs.class.join(' ')
96
- }
97
-
98
- // 如果是外部链接,则重写属性
99
- if (data.protocol && data.hostname !== siteHost) {
100
- attrs.external = null
101
-
102
- if (!theme.exturl) {
103
- // 仅需要为简单链接重写/添加属性。
104
- attrs.rel = 'noopener'
105
- attrs.target = '_blank'
106
- } else {
107
- // 在主菜单中移除 `exturl` 的 rel 属性。
108
- attrs.rel = null
77
+ if (data.protocol && data.hostname !== siteHost) {
78
+ attrs.external = null;
79
+ if (!theme.exturl) {
80
+ attrs.rel = 'noopener';
81
+ attrs.target = '_blank';
82
+ }
83
+ else {
84
+ attrs.rel = null;
85
+ }
109
86
  }
110
- }
111
-
112
- // 返回HTML标记字符串
113
- return htmlTag(tag, attrs, decodeURI(text), false)
114
- })
115
-
87
+ return htmlTag(tag, attrs, decodeURI(text), false);
88
+ });
116
89
  hexo.extend.helper.register('_image_url', function (img, path = '') {
117
- const { statics } = hexo.theme.config
118
- const { post_asset_folder } = hexo.config
119
-
120
- if (img.startsWith('//') || img.startsWith('http')) {
121
- return img
122
- } else {
123
- return url_for.call(this, statics + (post_asset_folder ? path : '') + img)
124
- }
125
- })
126
-
90
+ const { statics } = hexo.theme.config;
91
+ const { post_asset_folder } = hexo.config;
92
+ if (img.startsWith('//') || img.startsWith('http')) {
93
+ return img;
94
+ }
95
+ else {
96
+ return url_for.call(this, statics + (post_asset_folder ? path : '') + img);
97
+ }
98
+ });
127
99
  hexo.extend.helper.register('_cover', function (item, num) {
128
- const { image_server, image_list } = hexo.theme.config
129
-
130
- if (item.cover) {
131
- return this._image_url(item.cover, item.path)
132
- } else if (item.photos && item.photos.length > 0) {
133
- return this._image_url(item.photos[0], item.path)
134
- } else {
135
- return randomBG(num || 1, image_server, image_list)
136
- }
137
- })
138
-
139
- // 注册hexo主题的永久链接帮助方法
100
+ const { image_server, image_list } = hexo.theme.config;
101
+ if (item.cover) {
102
+ return this._image_url(item.cover, item.path);
103
+ }
104
+ else if (item.photos && item.photos.length > 0) {
105
+ return this._image_url(item.photos[0], item.path);
106
+ }
107
+ else {
108
+ return randomBG(num || 1, image_server, image_list);
109
+ }
110
+ });
140
111
  hexo.extend.helper.register('_permapath', function (str) {
141
- // 获取hexo的永久链接配置
142
- const { permalink } = hexo.config
143
- // 将输入字符串中的'index.html'替换为空字符串
144
- let url = str.replace(/index\.html$/, '')
145
- // 如果永久链接不以'.html'结尾,将输入字符串中的'.html'替换为空字符串
146
- if (!permalink.endsWith('.html')) {
147
- url = url.replace(/\.html$/, '')
148
- }
149
- // 返回处理后的URL字符串
150
- return url
151
- })
152
-
112
+ const { permalink } = hexo.config;
113
+ let url = str.replace(/index\.html$/, '');
114
+ if (!permalink.endsWith('.html')) {
115
+ url = url.replace(/\.html$/, '');
116
+ }
117
+ return url;
118
+ });
153
119
  hexo.extend.helper.register('canonical', function () {
154
- return `<link rel="canonical" href="${this._permapath(this.url)}">`
155
- })
156
-
157
- /**
158
- * Get page path given a certain language tag
159
- */
160
- // 注册hexo主题的国际化路径帮助方法
120
+ return `<link rel="canonical" href="${this._permapath(this.url)}">`;
121
+ });
161
122
  hexo.extend.helper.register('i18n_path', function (language) {
162
- // 获取当前页面的pathlang
163
- const { path, lang } = this.page
164
- // 如果path以lang开头,则截取掉lang部分,作为基础路径
165
- const base = path.startsWith(lang) ? path.slice(lang.length + 1) : path
166
- // 通过调用url_for方法,生成国际化路径
167
- return url_for.call(this, `${this.languages.indexOf(language) === 0 ? '' : '/' + language}/${base}`)
168
- })
169
-
170
- /**
171
- * Get the language name
172
- */
173
- // 注册hexo主题的语言名称帮助方法
123
+ const { path, lang } = this.page;
124
+ const base = path.startsWith(lang) ? path.slice(lang.length + 1) : path;
125
+ return url_for.call(this, `${this.languages.indexOf(language) === 0 ? '' : '/' + language}/${base}`);
126
+ });
174
127
  hexo.extend.helper.register('language_name', function (language) {
175
- // 从主题配置中获取指定语言的名称
176
- const name = hexo.theme.i18n.__(language)('name')
177
- // 如果名称为默认值'name',则返回语言代码,否则返回语言名称
178
- return name === 'name' ? language : name
179
- })
180
-
128
+ const name = hexo.theme.i18n.__(language)('name');
129
+ return name === 'name' ? language : name;
130
+ });
181
131
  hexo.extend.helper.register('random_color', function () {
182
- /**
183
- @type {number[]}
184
- */
185
- const arr = []
186
- for (let i = 0; i < 3; i++) {
187
- arr.push(Math.floor(Math.random() * 128 + 128))
188
- }
189
- const [r, g, b] = arr
190
- return `#${
191
- r.toString(16).length > 1 ? r.toString(16) : '0' + r.toString(16)
192
- }${g.toString(16).length > 1 ? g.toString(16) : '0' + g.toString(16)}${
193
- b.toString(16).length > 1 ? b.toString(16) : '0' + b.toString(16)
194
- }`
195
- })
196
-
132
+ const arr = [];
133
+ for (let i = 0; i < 3; i++) {
134
+ arr.push(Math.floor(Math.random() * 128 + 128));
135
+ }
136
+ const [r, g, b] = arr;
137
+ return `#${r.toString(16).length > 1 ? r.toString(16) : '0' + r.toString(16)}${g.toString(16).length > 1 ? g.toString(16) : '0' + g.toString(16)}${b.toString(16).length > 1 ? b.toString(16) : '0' + b.toString(16)}`;
138
+ });
197
139
  hexo.extend.helper.register('shokax_inject', function (point) {
198
- return hexo.theme.config.injects[point]
199
- .map(item => this.partial(item.layout, item.locals, item.options))
200
- .join('')
201
- })
140
+ return hexo.theme.config.injects[point]
141
+ .map(item => this.partial(item.layout, item.locals, item.options))
142
+ .join('');
143
+ });