hexo-component-inferno 1.0.2 → 2.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 (125) hide show
  1. package/lib/hexo/generator/insight.js +8 -1
  2. package/lib/hexo/generator/insight.test.js +16 -0
  3. package/lib/hexo/helper/cdn.js +4 -11
  4. package/lib/hexo/helper/cdn.test.js +9 -37
  5. package/lib/hexo/tag/message.js +100 -0
  6. package/lib/hexo/tag/message.test.js +79 -0
  7. package/lib/hexo/tag/tabs.js +290 -0
  8. package/lib/hexo/tag/tabs.test.js +106 -0
  9. package/lib/schema/comment/twikoo.json +28 -0
  10. package/lib/schema/comment/waline.json +46 -43
  11. package/lib/schema/schema/comment/changyan.json +21 -0
  12. package/lib/schema/schema/comment/disqus.json +17 -0
  13. package/lib/schema/schema/comment/disqusjs.json +53 -0
  14. package/lib/schema/schema/comment/facebook.json +13 -0
  15. package/lib/schema/schema/comment/gitalk.json +81 -0
  16. package/lib/schema/schema/comment/gitment.json +47 -0
  17. package/lib/schema/schema/comment/isso.json +17 -0
  18. package/lib/schema/schema/comment/livere.json +17 -0
  19. package/lib/schema/schema/comment/twikoo.json +28 -0
  20. package/lib/schema/schema/comment/utterances.json +59 -0
  21. package/lib/schema/schema/comment/valine.json +105 -0
  22. package/lib/schema/schema/comment/waline.json +176 -0
  23. package/lib/schema/schema/donate/afdian.json +17 -0
  24. package/lib/schema/schema/donate/alipay.json +17 -0
  25. package/lib/schema/schema/donate/buymeacoffee.json +17 -0
  26. package/lib/schema/schema/donate/patreon.json +17 -0
  27. package/lib/schema/schema/donate/paypal.json +22 -0
  28. package/lib/schema/schema/donate/wechat.json +17 -0
  29. package/lib/schema/schema/misc/manifest.json +66 -0
  30. package/lib/schema/schema/misc/meta.json +11 -0
  31. package/lib/schema/schema/misc/open_graph.json +78 -0
  32. package/lib/schema/schema/misc/poly_links.json +35 -0
  33. package/lib/schema/schema/misc/structured_data.json +47 -0
  34. package/lib/schema/schema/plugin/baidu_analytics.json +14 -0
  35. package/lib/schema/schema/plugin/bing_webmaster.json +14 -0
  36. package/lib/schema/schema/plugin/busuanzi.json +7 -0
  37. package/lib/schema/schema/plugin/cnzz.json +19 -0
  38. package/lib/schema/schema/plugin/cookie_consent.json +38 -0
  39. package/lib/schema/schema/plugin/gallery.json +7 -0
  40. package/lib/schema/schema/plugin/google_analytics.json +14 -0
  41. package/lib/schema/schema/plugin/hotjar.json +14 -0
  42. package/lib/schema/schema/plugin/katex.json +7 -0
  43. package/lib/schema/schema/plugin/mathjax.json +7 -0
  44. package/lib/schema/schema/plugin/outdated_browser.json +7 -0
  45. package/lib/schema/schema/plugin/progressbar.json +7 -0
  46. package/lib/schema/schema/plugin/statcounter.json +19 -0
  47. package/lib/schema/schema/plugin/twitter_conversion_tracking.json +14 -0
  48. package/lib/schema/schema/search/algolia.json +13 -0
  49. package/lib/schema/schema/search/baidu.json +13 -0
  50. package/lib/schema/schema/search/google_cse.json +17 -0
  51. package/lib/schema/schema/search/insight.json +19 -0
  52. package/lib/schema/schema/share/addthis.json +17 -0
  53. package/lib/schema/schema/share/addtoany.json +13 -0
  54. package/lib/schema/schema/share/bdshare.json +13 -0
  55. package/lib/schema/schema/share/sharejs.json +13 -0
  56. package/lib/schema/schema/share/sharethis.json +17 -0
  57. package/lib/schema/schema/widget/adsense.json +21 -0
  58. package/lib/schema/schema/widget/archives.json +13 -0
  59. package/lib/schema/schema/widget/categories.json +13 -0
  60. package/lib/schema/schema/widget/followit.json +26 -0
  61. package/lib/schema/schema/widget/links.json +47 -0
  62. package/lib/schema/schema/widget/recent_posts.json +13 -0
  63. package/lib/schema/schema/widget/subscribe_email.json +22 -0
  64. package/lib/schema/schema/widget/tags.json +30 -0
  65. package/lib/schema/schema/widget/toc.json +31 -0
  66. package/lib/schema/search/insight.json +6 -0
  67. package/lib/schema/widget/tags.json +17 -0
  68. package/lib/view/comment/changyan.js +2 -2
  69. package/lib/view/comment/disqus.js +2 -2
  70. package/lib/view/comment/disqusjs.js +2 -2
  71. package/lib/view/comment/facebook.js +2 -2
  72. package/lib/view/comment/gitalk.js +2 -2
  73. package/lib/view/comment/gitment.js +2 -2
  74. package/lib/view/comment/isso.js +2 -2
  75. package/lib/view/comment/livere.js +2 -2
  76. package/lib/view/comment/twikoo.js +113 -0
  77. package/lib/view/comment/utterances.js +3 -3
  78. package/lib/view/comment/valine.js +3 -3
  79. package/lib/view/comment/waline.js +63 -52
  80. package/lib/view/common/article_media.js +2 -2
  81. package/lib/view/donate/afdian.js +2 -2
  82. package/lib/view/donate/alipay.js +2 -2
  83. package/lib/view/donate/buymeacoffee.js +2 -2
  84. package/lib/view/donate/patreon.js +2 -2
  85. package/lib/view/donate/paypal.js +2 -2
  86. package/lib/view/donate/wechat.js +2 -2
  87. package/lib/view/misc/article_licensing.js +2 -2
  88. package/lib/view/misc/meta.js +2 -2
  89. package/lib/view/misc/open_graph.js +12 -4
  90. package/lib/view/misc/paginator.js +2 -2
  91. package/lib/view/misc/structured_data.js +2 -2
  92. package/lib/view/misc/web_app.js +2 -2
  93. package/lib/view/plugin/baidu_analytics.js +2 -2
  94. package/lib/view/plugin/bing_webmaster.js +2 -2
  95. package/lib/view/plugin/busuanzi.js +2 -2
  96. package/lib/view/plugin/cnzz.js +2 -2
  97. package/lib/view/plugin/cookie_consent.js +2 -2
  98. package/lib/view/plugin/gallery.js +2 -2
  99. package/lib/view/plugin/google_analytics.js +2 -2
  100. package/lib/view/plugin/hotjar.js +2 -2
  101. package/lib/view/plugin/katex.js +2 -2
  102. package/lib/view/plugin/mathjax.js +2 -2
  103. package/lib/view/plugin/outdated_browser.js +2 -2
  104. package/lib/view/plugin/progressbar.js +2 -2
  105. package/lib/view/plugin/statcounter.js +2 -2
  106. package/lib/view/plugin/twitter_conversion_tracking.js +2 -2
  107. package/lib/view/search/algolia.js +2 -2
  108. package/lib/view/search/baidu.js +2 -2
  109. package/lib/view/search/google_cse.js +2 -2
  110. package/lib/view/search/insight.js +2 -2
  111. package/lib/view/share/addthis.js +2 -2
  112. package/lib/view/share/addtoany.js +2 -2
  113. package/lib/view/share/bdshare.js +2 -2
  114. package/lib/view/share/sharejs.js +2 -2
  115. package/lib/view/share/sharethis.js +2 -2
  116. package/lib/view/widget/adsense.js +2 -2
  117. package/lib/view/widget/archives.js +2 -2
  118. package/lib/view/widget/categories.js +2 -2
  119. package/lib/view/widget/followit.js +2 -2
  120. package/lib/view/widget/links.js +2 -2
  121. package/lib/view/widget/recent_posts.js +2 -2
  122. package/lib/view/widget/subscribe_email.js +2 -2
  123. package/lib/view/widget/tags.js +16 -15
  124. package/lib/view/widget/toc.js +2 -2
  125. package/package.json +10 -11
@@ -0,0 +1,290 @@
1
+ /**
2
+ * Register custom Hexo tag {% tabs %}.
3
+ * @module hexo/tag/tabs
4
+ */
5
+
6
+ /**
7
+ * Register custom Hexo tag {% tabs %}.
8
+ * <p>
9
+ * This tag is rendered as a Bulma tabs component.
10
+ * <p>
11
+ * Each individual tab must be wrapped with <code>&lt;!-- tab [...tab_param] --&gt;&lt;!-- endtab --&gt;</code>
12
+ *
13
+ * <h5>Tag Parameters:<h5>
14
+ * <table class="params">
15
+ * <tr>
16
+ * <th>Name</th>
17
+ * <th>Type</th>
18
+ * <th class="description">Description</th>
19
+ * </tr>
20
+ * <tr>
21
+ * <td class="name"><code>align</code></td>
22
+ * <td class="type"><span class="param-type"><code>string</code></span></td>
23
+ * <td class="description">[Optional] Alignment of the tabs. Available values are: left, centered, right, fullwidth. Default alignment is left.</td>
24
+ * </tr>
25
+ * <tr>
26
+ * <td class="name"><code>size</code></td>
27
+ * <td class="type"><span class="param-type"><code>string</code></span></td>
28
+ * <td class="description">[Optional] Size of the tabs. Available values are: small, medium, large. Default size is normal.</td>
29
+ * </tr>
30
+ * <tr>
31
+ * <td class="name"><code>style</code></td>
32
+ * <td class="type"><span class="param-type"><code>string</code></span></td>
33
+ * <td class="description">[Optional] Style of the tabs. Available values are: boxed, toggle, toggle-rounded. Default style is none.</td>
34
+ * </tr>
35
+ * </table>
36
+ *
37
+ * <h5>Tab Parameters:<h5>
38
+ * <table class="params">
39
+ * <tr>
40
+ * <th>Name</th>
41
+ * <th>Type</th>
42
+ * <th class="description">Description</th>
43
+ * </tr>
44
+ * <tr>
45
+ * <td class="name"><code>id</code></td>
46
+ * <td class="type"><span class="param-type"><code>string</code></span></td>
47
+ * <td class="description">[Optional] The ID of the current tab. This value must be unique on each page.</td>
48
+ * </tr>
49
+ * <tr>
50
+ * <td class="name"><code>active</code></td>
51
+ * <td class="type"><span class="param-type"><code>boolean</code></span></td>
52
+ * <td class="description">[Optional] Whether to show current tab by default. Only one of the tabs can be set to active.</td>
53
+ * </tr>
54
+ * <tr>
55
+ * <td class="name"><code>title</code></td>
56
+ * <td class="type"><span class="param-type"><code>string</code></span></td>
57
+ * <td class="description">[Optional] Title of the current tab.</td>
58
+ * </tr>
59
+ * <tr>
60
+ * <td class="name"><code>icon</code></td>
61
+ * <td class="type"><span class="param-type"><code>string</code></span></td>
62
+ * <td class="description">[Optional] Icon of the current tab. Use FontAwesome icon class name for this field.</td>
63
+ * </tr>
64
+ * </table>
65
+ *
66
+ * @see https://bulma.io/documentation/components/tabs/.
67
+ *
68
+ * @param {Hexo} hexo The Hexo instance.
69
+ *
70
+ * @example
71
+ * {% tabs align:fullwidth size:small style:toggle-rounded %}
72
+ * <!-- tab active id:tab_hello title:Hello -->
73
+ * This is hello.
74
+ * <!-- endtab -->
75
+ * <!-- tab id:tab_info 'icon:fas fa-info' 'title:Info Tab' -->This is info.<!-- endtab -->
76
+ * {% endmessage %}
77
+ */
78
+ module.exports = function (hexo) {
79
+ function splitTabOptions(s) {
80
+ const options = [];
81
+ const EOL = -1;
82
+ let i = 0;
83
+ let state = 1;
84
+ let begin = 0;
85
+
86
+ while (i <= s.length) {
87
+ const c = i < s.length ? s.charAt(i) : '';
88
+
89
+ switch (state) {
90
+ case 1:
91
+ if (c === ' ') {
92
+ state = 1;
93
+ begin = i + 1;
94
+ } else if (c === '"') {
95
+ state = 2;
96
+ begin = i + 1;
97
+ } else if (c === "'") {
98
+ state = 4;
99
+ begin = i + 1;
100
+ } else if (c === '') {
101
+ state = EOL;
102
+ } else {
103
+ state = 7;
104
+ }
105
+
106
+ break;
107
+
108
+ case 2:
109
+ if (c === '\\') {
110
+ state = 3;
111
+ } else if (c === '"') {
112
+ state = 6;
113
+ }
114
+
115
+ break;
116
+
117
+ case 3:
118
+ state = 2;
119
+ break;
120
+
121
+ case 4:
122
+ if (c === '\\') {
123
+ state = 5;
124
+ } else if (c === "'") {
125
+ state = 6;
126
+ }
127
+
128
+ break;
129
+
130
+ case 5:
131
+ state = 4;
132
+ break;
133
+
134
+ case 6:
135
+ options.push(s.substring(begin, i - 1));
136
+ begin = i + 1;
137
+
138
+ if (c === ' ') {
139
+ state = 1;
140
+ } else if (c === '') {
141
+ state = EOL;
142
+ } else {
143
+ throw new Error(`malformatted tab options: ${s}`);
144
+ }
145
+
146
+ break;
147
+
148
+ case 7:
149
+ if (c === ' ') {
150
+ options.push(s.substring(begin, i));
151
+ begin = i + 1;
152
+ state = 1;
153
+ } else if (c === '') {
154
+ options.push(s.substring(begin, i));
155
+ begin = i + 1;
156
+ state = EOL;
157
+ }
158
+
159
+ break;
160
+ }
161
+
162
+ i++;
163
+ }
164
+
165
+ if (state !== EOL) {
166
+ throw new Error(`malformatted tab options: ${s}`);
167
+ }
168
+
169
+ return options;
170
+ }
171
+
172
+ function processTag(options, content) {
173
+ let classes = '';
174
+
175
+ for (const option of options) {
176
+ const [key, value] = option.split(':');
177
+
178
+ switch (key) {
179
+ case 'align':
180
+ classes += ` is-${value}`;
181
+ break;
182
+
183
+ case 'size':
184
+ classes += ` is-${value}`;
185
+ break;
186
+
187
+ case 'style':
188
+ if (value === 'toggle-rounded') {
189
+ classes += ' is-toggle';
190
+ }
191
+
192
+ classes += ` is-${value}`;
193
+ break;
194
+ }
195
+ }
196
+
197
+ const pattern = /<!--\s*tab\s*(.*?)\s*-->([\s\S]*?)<!--\s*endtab\s*-->/g;
198
+ let match;
199
+ let tabElements = '';
200
+ let contentElements = '';
201
+
202
+ while ((match = pattern.exec(content)) !== null) {
203
+ const [, tabOptions, tabContent] = match;
204
+ let id = 'tab-' + Date.now() + (Math.random() * 1000 | 0);
205
+ let icon = '';
206
+ let title = '';
207
+ let active = false;
208
+
209
+ for (const option of splitTabOptions(tabOptions)) {
210
+ const [key, value] = option.split(':');
211
+
212
+ switch (key) {
213
+ case 'id':
214
+ id = value;
215
+ break;
216
+
217
+ case 'active':
218
+ active = true;
219
+ break;
220
+
221
+ case 'icon':
222
+ icon = `<span class="icon is-small ml-0">
223
+ <i class="${value}" aria-hidden="true"></i>
224
+ </span>`;
225
+ break;
226
+
227
+ case 'title':
228
+ title = value;
229
+ break;
230
+ }
231
+ }
232
+
233
+ tabElements += `<li${active ? ' class="is-active"' : ''}>
234
+ <a href="#${id}">
235
+ ${hexo.render.renderSync({
236
+ text: icon + title,
237
+ engine: 'markdown'
238
+ })}
239
+ </a>
240
+ </li>`;
241
+ contentElements += `<div id="${id}" class="tab-content${active ? '' : ' is-hidden'}">
242
+ ${hexo.render.renderSync({
243
+ text: tabContent,
244
+ engine: 'markdown'
245
+ })}
246
+ </div>`;
247
+ }
248
+
249
+ return `<div class="tabs my-3${classes}">
250
+ <ul class="mx-0 my-0">
251
+ ${tabElements}
252
+ </ul>
253
+ </div>
254
+ ${contentElements}`;
255
+ }
256
+
257
+ const script = `<script>
258
+ (function () {
259
+ function switchTab() {
260
+ if (!location.hash) {
261
+ return;
262
+ }
263
+ Array
264
+ .from(document.querySelectorAll('.tab-content'))
265
+ .forEach($tab => {
266
+ $tab.classList.add('is-hidden');
267
+ });
268
+ Array
269
+ .from(document.querySelectorAll('.tabs li'))
270
+ .forEach($tab => {
271
+ $tab.classList.remove('is-active');
272
+ });
273
+ const $activeTab = document.querySelector(location.hash);
274
+ if ($activeTab) {
275
+ $activeTab.classList.remove('is-hidden');
276
+ }
277
+ const $tabMenu = document.querySelector(\`a[href="\${location.hash}"]\`);
278
+ if ($tabMenu) {
279
+ $tabMenu.parentElement.classList.add('is-active');
280
+ }
281
+ }
282
+ switchTab();
283
+ window.addEventListener('hashchange', switchTab, false);
284
+ })();
285
+ </script>`;
286
+ hexo.extend.injector.register('head_end', script);
287
+ hexo.extend.tag.register('tabs', processTag, {
288
+ ends: true
289
+ });
290
+ };
@@ -0,0 +1,106 @@
1
+ const {
2
+ join
3
+ } = require('path');
4
+
5
+ const Hexo = require('hexo');
6
+
7
+ const {
8
+ minify
9
+ } = require('html-minifier');
10
+
11
+ const cheerio = require('cheerio');
12
+
13
+ const register = require('./tabs');
14
+
15
+ const rootDir = join(__dirname, '../../../fixture/site');
16
+ const hexo = new Hexo(rootDir, {
17
+ silent: true
18
+ });
19
+ const cheerioOptions = {
20
+ xml: {
21
+ normalizeWhitespace: true
22
+ }
23
+ };
24
+ const minifierOptions = {
25
+ collapseWhitespace: true,
26
+ conservativeCollapse: true,
27
+ keepClosingSlash: true
28
+ };
29
+ beforeAll(async () => {
30
+ await hexo.init();
31
+ await hexo.load();
32
+ register(hexo);
33
+ await hexo.loadPlugin(require.resolve('hexo-renderer-marked'));
34
+ });
35
+ test('create default tabs', async () => {
36
+ const render = hexo.extend.tag.render.bind(hexo.extend.tag);
37
+ let source = '{% tabs %}<!--tab id:tab1-->**content**<!--endtab-->{% endtabs %}';
38
+ let actual = cheerio.load(await render(source), cheerioOptions, false).html();
39
+ expect(minify(actual, minifierOptions)).toEqual('<div class="tabs my-3"> <ul class="mx-0 my-0"> <li> <a href="#tab1"> </a> </li> </ul> ' + '</div> <div id="tab1" class="tab-content is-hidden"> <p><strong>content</strong></p> </div>');
40
+ source = `{% tabs %}
41
+ <!-- tab --># title 1<!-- endtab -->
42
+ <!-- tab --># title 2<!-- endtab -->
43
+ {% endtabs %}`;
44
+ const $ = cheerio.load(await render(source), cheerioOptions, false);
45
+ const [tabId1, tabId2] = $('.tab-content').get().map(element => $(element).attr('id'));
46
+ actual = $.html();
47
+ expect(minify(actual, minifierOptions)).toEqual(`<div class="tabs my-3"> <ul class="mx-0 my-0"> <li> <a href="#${tabId1}"> </a> ` + `</li><li> <a href="#${tabId2}"> </a> </li> </ul> </div> ` + `<div id="${tabId1}" class="tab-content is-hidden"> <h1 id="title-1">` + '<a href="#title-1" class="headerlink" title="title 1"/>title 1</h1> </div>' + `<div id="${tabId2}" class="tab-content is-hidden"> <h1 id="title-2">` + '<a href="#title-2" class="headerlink" title="title 2"/>title 2</h1> </div>');
48
+ });
49
+ test('create tabs with different alignment', async () => {
50
+ const render = hexo.extend.tag.render.bind(hexo.extend.tag);
51
+
52
+ for (const align of ['left', 'centered', 'right', 'fullwidth']) {
53
+ const source = `{% tabs align:${align} %}<!--tab id:tab1-->content<!--endtab-->{% endtabs %}`;
54
+ const actual = cheerio.load(await render(source), cheerioOptions, false).html();
55
+ expect(minify(actual, minifierOptions)).toEqual(`<div class="tabs my-3 is-${align}"> <ul class="mx-0 my-0"> <li> <a href="#tab1"> </a> ` + '</li> </ul> </div> <div id="tab1" class="tab-content is-hidden"> ' + '<p>content</p> </div>');
56
+ }
57
+ });
58
+ test('create tabs with different sizes', async () => {
59
+ const render = hexo.extend.tag.render.bind(hexo.extend.tag);
60
+
61
+ for (const size of ['small', 'medium', 'large']) {
62
+ const source = `{% tabs size:${size} %}<!--tab id:tab1-->content<!--endtab-->{% endtabs %}`;
63
+ const actual = cheerio.load(await render(source), cheerioOptions, false).html();
64
+ expect(minify(actual, minifierOptions)).toEqual(`<div class="tabs my-3 is-${size}"> <ul class="mx-0 my-0"> <li> <a href="#tab1"> </a> ` + '</li> </ul> </div> <div id="tab1" class="tab-content is-hidden"> ' + '<p>content</p> </div>');
65
+ }
66
+ });
67
+ test('create tabs with different styles', async () => {
68
+ const render = hexo.extend.tag.render.bind(hexo.extend.tag);
69
+
70
+ for (const style of ['boxed', 'toggle', 'toggle-rounded']) {
71
+ const source = `{% tabs style:${style} %}<!--tab id:tab1-->content<!--endtab-->{% endtabs %}`;
72
+ const actual = cheerio.load(await render(source), cheerioOptions, false).html();
73
+ const classname = style === 'toggle-rounded' ? 'toggle is-toggle-rounded' : style;
74
+ expect(minify(actual, minifierOptions)).toEqual(`<div class="tabs my-3 is-${classname}"> <ul class="mx-0 my-0"> <li> <a href="#tab1"> </a> ` + '</li> </ul> </div> <div id="tab1" class="tab-content is-hidden"> ' + '<p>content</p> </div>');
75
+ }
76
+ });
77
+ test('create tabs with active status', async () => {
78
+ const render = hexo.extend.tag.render.bind(hexo.extend.tag);
79
+ const source = `{% tabs %}
80
+ <!-- tab id:tab1 -->tab 1<!-- endtab -->
81
+ <!-- tab id:tab2 active -->tab 2<!-- endtab -->
82
+ {% endtabs %}`;
83
+ const actual = cheerio.load(await render(source), cheerioOptions, false).html();
84
+ expect(minify(actual, minifierOptions)).toEqual('<div class="tabs my-3"> <ul class="mx-0 my-0"> <li> <a href="#tab1"> </a> ' + '</li><li class="is-active"> <a href="#tab2"> </a> </li> </ul> </div> ' + '<div id="tab1" class="tab-content is-hidden"> <p>tab 1</p> </div>' + '<div id="tab2" class="tab-content"> <p>tab 2</p> </div>');
85
+ });
86
+ test('create tabs with a title', async () => {
87
+ const render = hexo.extend.tag.render.bind(hexo.extend.tag);
88
+ const source = '{% tabs %}<!--tab id:tab1 "title:Tab Title"-->tab<!--endtab-->{% endtabs %}';
89
+ const actual = cheerio.load(await render(source), cheerioOptions, false).html();
90
+ expect(minify(actual, minifierOptions)).toEqual('<div class="tabs my-3"> <ul class="mx-0 my-0"> <li> <a href="#tab1"> <p>Tab Title</p> </a> ' + '</li> </ul> </div> <div id="tab1" class="tab-content is-hidden"> <p>tab</p> </div>');
91
+ });
92
+ test('create tabs with an icon', async () => {
93
+ const render = hexo.extend.tag.render.bind(hexo.extend.tag);
94
+ const source = '{% tabs %}<!--tab id:tab1 "icon:fab fa-github"-->tab<!--endtab-->{% endtabs %}';
95
+ const actual = cheerio.load(await render(source), cheerioOptions, false).html();
96
+ expect(minify(actual, minifierOptions)).toEqual('<div class="tabs my-3"> <ul class="mx-0 my-0"> <li> <a href="#tab1"> ' + '<span class="icon is-small ml-0"> <i class="fab fa-github" aria-hidden="true"/> ' + '</span> </a> </li> </ul> </div> <div id="tab1" class="tab-content is-hidden"> ' + '<p>tab</p> </div>');
97
+ });
98
+ test('create tabs with all properties', async () => {
99
+ const render = hexo.extend.tag.render.bind(hexo.extend.tag);
100
+ const source = `{% tabs align:fullwidth 'size:large' style:boxed %}
101
+ <!-- tab id:tab1 "icon:fas\\ fa-file" -->tab 1<!-- endtab -->
102
+ <!-- tab id:tab2 active 'title:Tim\\'s Tab' -->tab 2<!-- endtab -->
103
+ {% endtabs %}`;
104
+ const actual = cheerio.load(await render(source), cheerioOptions, false).html();
105
+ expect(minify(actual, minifierOptions)).toEqual('<div class="tabs my-3 is-fullwidth is-large is-boxed"> <ul class="mx-0 my-0"> <li> ' + '<a href="#tab1"> <span class="icon is-small ml-0"> ' + '<i class="fas\\ fa-file" aria-hidden="true"/> </span> </a> </li><li class="is-active"> ' + '<a href="#tab2"> <p>Tim&apos;s Tab</p> </a> </li> </ul> </div> ' + '<div id="tab1" class="tab-content is-hidden"> <p>tab 1</p> </div>' + '<div id="tab2" class="tab-content"> <p>tab 2</p> </div>');
106
+ });
@@ -0,0 +1,28 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "/comment/twikoo.json",
4
+ "description": "Twikoo comment plugin configurations",
5
+ "type": "object",
6
+ "properties": {
7
+ "type": {
8
+ "type": "string",
9
+ "const": "twikoo"
10
+ },
11
+ "env_id": {
12
+ "type": "string",
13
+ "description": "envId from Tencent CloudBase or Vercel URL"
14
+ },
15
+ "region": {
16
+ "type": "string",
17
+ "description": "Region of Tencent CloudBase",
18
+ "nullable": true
19
+ },
20
+ "lang": {
21
+ "type": "string",
22
+ "description": "i18n support",
23
+ "default": "zh-CN",
24
+ "nullable": true
25
+ }
26
+ },
27
+ "required": ["type", "env_id"]
28
+ }
@@ -12,17 +12,20 @@
12
12
  "type": "string",
13
13
  "description": "Waline server address url."
14
14
  },
15
+ "path": {
16
+ "type": "string",
17
+ "description": "Article path id."
18
+ },
15
19
  "lang": {
16
20
  "type": "string",
17
21
  "description": "Display language.",
18
- "enum": ["zh", "zh-CN", "zh-TW", "en", "en-US", "jp", "jp-JP"],
22
+ "enum": ["zh", "zh-CN", "zh-TW", "en", "en-US", "jp", "jp-JP", "pt-BR", "ru", "ru-RU"],
19
23
  "default": "zh-CN",
20
24
  "nullable": true
21
25
  },
22
- "visitor": {
23
- "type": "boolean",
24
- "description": "Show visitor count",
25
- "default": false,
26
+ "locale": {
27
+ "type": "object",
28
+ "description": "I18n configurations",
26
29
  "nullable": true
27
30
  },
28
31
  "emoji": {
@@ -34,31 +37,31 @@
34
37
  },
35
38
  {
36
39
  "type": "object",
37
- "description": "Emoji set configuration",
40
+ "description": "Emoji set configuration.",
38
41
  "properties": {
39
42
  "name": {
40
43
  "type": "string",
41
- "description": "Emoji name on the tab"
44
+ "description": "Emoji name on the tab."
42
45
  },
43
46
  "folder": {
44
47
  "type": "string",
45
- "description": "Image folder link"
48
+ "description": "Image folder link."
46
49
  },
47
50
  "prefix": {
48
51
  "type": "string",
49
- "description": "The general prefix of images' filename"
52
+ "description": "The general prefix of images' filename."
50
53
  },
51
54
  "type": {
52
55
  "type": "string",
53
- "description": "Type of the picture, which will be used as file extension"
56
+ "description": "Type of the picture, which will be used as file extension."
54
57
  },
55
58
  "icon": {
56
59
  "type": "string",
57
- "description": "Filename of the icon image used in tab (requirement is the same as items)"
60
+ "description": "Filename of the icon image used in tab (requirement is the same as items)."
58
61
  },
59
62
  "items": {
60
63
  "type": "array",
61
- "description": "Each item is the picture filename without common prefix (do not include file extension)",
64
+ "description": "Each item is the picture filename without common prefix (do not include file extension).",
62
65
  "items": {
63
66
  "type": "string"
64
67
  }
@@ -68,18 +71,18 @@
68
71
  }
69
72
  ]
70
73
  },
71
- "description": "Emoji settings",
72
- "default": ["https://cdn.jsdelivr.net/gh/walinejs/emojis/weibo"],
74
+ "description": "Emoji settings.",
75
+ "default": ["//unpkg.com/@waline/emojis@1.0.1/weibo"],
73
76
  "nullable": true
74
77
  },
75
78
  "dark": {
76
- "type": "string",
77
- "description": "Darkmode support",
79
+ "type": ["string", "boolean"],
80
+ "description": "Darkmode support.",
78
81
  "nullable": true
79
82
  },
80
83
  "meta": {
81
84
  "type": "array",
82
- "description": "Reviewer attributes",
85
+ "description": "Reviewer attributes.",
83
86
  "items": {
84
87
  "type": "string"
85
88
  },
@@ -88,24 +91,17 @@
88
91
  },
89
92
  "required_meta": {
90
93
  "type": "array",
91
- "description": "Required commenter information fields",
94
+ "description": "Required commenter information fields.",
92
95
  "default": [],
93
96
  "nullable": true
94
97
  },
95
98
  "login": {
96
99
  "type": "string",
97
- "description": "Login mode status",
100
+ "description": "Login mode status.",
98
101
  "enum": ["enable", "disable", "force"],
99
102
  "default": "enable",
100
103
  "nullable": true
101
104
  },
102
- "avatar": {
103
- "type": "string",
104
- "description": "Gravatar type",
105
- "enum": ["", "mp", "identicon", "monsterid", "wavatar", "robohash", "retro", "hide", "mm"],
106
- "default": "mp",
107
- "nullable": true
108
- },
109
105
  "word_limit": {
110
106
  "oneOf": [
111
107
  {
@@ -129,31 +125,43 @@
129
125
  },
130
126
  "page_size": {
131
127
  "type": "number",
132
- "description": "number of comments per page.",
128
+ "description": "Number of comments per page.",
133
129
  "default": 10,
134
130
  "nullable": true
135
131
  },
136
- "avatar_cdn": {
137
- "type": "string",
138
- "description": "Gravatar CDN baseURL.",
139
- "default": "https://sdn.geekzu.org/avatar/",
132
+ "image_uploader": {
133
+ "type": "boolean",
134
+ "description": "Whether to disable the image upload feature.",
135
+ "default": false,
140
136
  "nullable": true
141
137
  },
142
- "avatar_force": {
138
+ "highlighter": {
143
139
  "type": "boolean",
144
- "description": "Whether force pulling the latest avatar each time.",
140
+ "description": "Whether to disable the code highlight feature.",
145
141
  "default": false,
146
142
  "nullable": true
147
143
  },
148
- "highlight": {
144
+ "tex_renderer": {
149
145
  "type": "boolean",
150
- "description": "Code highlighting, it's enabled by default, please close it selectively.",
151
- "default": true,
146
+ "description": "Whether to disable TeX rendering.",
147
+ "default": false,
152
148
  "nullable": true
153
149
  },
154
- "math_tag_support": {
150
+ "search": {
155
151
  "type": "boolean",
156
- "description": "Whether inject extra styles to display <math> block",
152
+ "description": "Whether to disable the search feature.",
153
+ "default": false,
154
+ "nullable": true
155
+ },
156
+ "pageview": {
157
+ "type": ["string", "boolean"],
158
+ "description": "Whether to show page view count. It can also be a CSS selector to page view count container.",
159
+ "default": false,
160
+ "nullable": true
161
+ },
162
+ "comment": {
163
+ "type": ["string", "boolean"],
164
+ "description": "Whether to show comment count. It can also be a CSS selector to comment count container.",
157
165
  "default": false,
158
166
  "nullable": true
159
167
  },
@@ -162,11 +170,6 @@
162
170
  "description": "Whether show copyright and version in footer.",
163
171
  "default": true,
164
172
  "nullable": true
165
- },
166
- "locale": {
167
- "type": "object",
168
- "description": "I18n configurations",
169
- "nullable": true
170
173
  }
171
174
  },
172
175
  "required": ["type", "server_url"]
@@ -0,0 +1,21 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "/comment/changyan.json",
4
+ "description": "Changyan comment plugin configurations",
5
+ "type": "object",
6
+ "properties": {
7
+ "type": {
8
+ "type": "string",
9
+ "const": "changyan"
10
+ },
11
+ "app_id": {
12
+ "type": "string",
13
+ "description": "Changyan app ID"
14
+ },
15
+ "conf": {
16
+ "type": "string",
17
+ "description": "Changyan configuration ID"
18
+ }
19
+ },
20
+ "required": ["type", "app_id", "conf"]
21
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "/comment/disqus.json",
4
+ "description": "Disqus comment plugin configurations",
5
+ "type": "object",
6
+ "properties": {
7
+ "type": {
8
+ "type": "string",
9
+ "const": "disqus"
10
+ },
11
+ "shortname": {
12
+ "type": "string",
13
+ "description": "Disqus shortname"
14
+ }
15
+ },
16
+ "required": ["type", "shortname"]
17
+ }