tona-plugins 1.0.1

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 (71) hide show
  1. package/README.md +48 -0
  2. package/index.d.ts +32 -0
  3. package/package.json +51 -0
  4. package/src/constants/cdn.js +12 -0
  5. package/src/index.js +30 -0
  6. package/src/plugins/background/index.js +50 -0
  7. package/src/plugins/background/index.scss +0 -0
  8. package/src/plugins/barrage/index.js +104 -0
  9. package/src/plugins/barrage/index.scss +16 -0
  10. package/src/plugins/catalog/index.js +212 -0
  11. package/src/plugins/catalog/index.scss +0 -0
  12. package/src/plugins/charts/index.js +60 -0
  13. package/src/plugins/charts/index.scss +16 -0
  14. package/src/plugins/clickEffects/index.js +137 -0
  15. package/src/plugins/clickEffects/index.scss +0 -0
  16. package/src/plugins/codeCopy/index.js +94 -0
  17. package/src/plugins/codeCopy/index.scss +65 -0
  18. package/src/plugins/codeHighlight/index.js +35 -0
  19. package/src/plugins/codeHighlight/index.scss +216 -0
  20. package/src/plugins/codeHighlight/themes.js +60 -0
  21. package/src/plugins/codeLang/index.js +51 -0
  22. package/src/plugins/codeLang/index.scss +28 -0
  23. package/src/plugins/codeLinenumbers/index.js +33 -0
  24. package/src/plugins/codeLinenumbers/index.scss +61 -0
  25. package/src/plugins/codeTrafficLight/index.js +18 -0
  26. package/src/plugins/codeTrafficLight/index.scss +0 -0
  27. package/src/plugins/colorMode/index.js +81 -0
  28. package/src/plugins/colorMode/index.scss +0 -0
  29. package/src/plugins/commentsAvatars/index.js +85 -0
  30. package/src/plugins/commentsAvatars/index.scss +3 -0
  31. package/src/plugins/darkMode/index.js +115 -0
  32. package/src/plugins/darkMode/index.scss +67 -0
  33. package/src/plugins/donation/index.js +45 -0
  34. package/src/plugins/donation/index.scss +63 -0
  35. package/src/plugins/emoji/index.js +167 -0
  36. package/src/plugins/emoji/index.scss +155 -0
  37. package/src/plugins/footer/index.js +35 -0
  38. package/src/plugins/footer/index.scss +54 -0
  39. package/src/plugins/imagePreview/index.js +98 -0
  40. package/src/plugins/imagePreview/index.scss +51 -0
  41. package/src/plugins/license/index.js +62 -0
  42. package/src/plugins/license/index.scss +51 -0
  43. package/src/plugins/live2d/index.js +67 -0
  44. package/src/plugins/live2d/index.scss +0 -0
  45. package/src/plugins/live2d/live2d-models.js +21 -0
  46. package/src/plugins/lock/index.js +77 -0
  47. package/src/plugins/lock/index.scss +56 -0
  48. package/src/plugins/musicPlayer/index.js +81 -0
  49. package/src/plugins/musicPlayer/index.scss +68 -0
  50. package/src/plugins/notation/index.js +73 -0
  51. package/src/plugins/notation/index.scss +12 -0
  52. package/src/plugins/notice/index.js +17 -0
  53. package/src/plugins/notice/index.scss +46 -0
  54. package/src/plugins/postBottomImage/index.js +27 -0
  55. package/src/plugins/postBottomImage/index.scss +26 -0
  56. package/src/plugins/postMessage/index.js +89 -0
  57. package/src/plugins/postMessage/index.scss +81 -0
  58. package/src/plugins/postTopImage/index.js +28 -0
  59. package/src/plugins/postTopImage/index.scss +29 -0
  60. package/src/plugins/qrcode/index.js +42 -0
  61. package/src/plugins/qrcode/index.scss +10 -0
  62. package/src/plugins/signature/index.js +47 -0
  63. package/src/plugins/signature/index.scss +18 -0
  64. package/src/plugins/toast/index.js +49 -0
  65. package/src/plugins/tools/index.js +251 -0
  66. package/src/plugins/tools/index.scss +114 -0
  67. package/src/plugins/webTag/index.js +40 -0
  68. package/src/plugins/webTag/index.scss +0 -0
  69. package/src/utils/cnblog.js +282 -0
  70. package/src/utils/helpers.js +418 -0
  71. package/src/utils/shared.js +2 -0
@@ -0,0 +1,81 @@
1
+ @use 'sass:map';
2
+ @use 'sass:list';
3
+
4
+ $postMessage: () !default;
5
+
6
+ $postMessage: map.merge(
7
+ (
8
+ categoriesBackground: #ff6b6b,
9
+ tagsBackground: #22a6b3 #0097e6 #fbc531 #10ac84,
10
+ colorCategories: #fff,
11
+ colorTags: #333,
12
+ colorMessage: #999,
13
+ ),
14
+ $postMessage
15
+ );
16
+
17
+ $color-categories: map.get($postMessage, colorCategories);
18
+ $color-tags: map.get($postMessage, colorTags);
19
+ $color-message: map.get($postMessage, colorMessage);
20
+ $postMessageTagBackground: map.get($postMessage, tagsBackground);
21
+ $categoriesBackground: map.get($postMessage, categoriesBackground);
22
+
23
+ .post-message {
24
+ display: flex;
25
+ flex-direction: column;
26
+ justify-content: space-around;
27
+ margin-bottom: 20px;
28
+ width: 100%;
29
+ }
30
+
31
+ .message-top {
32
+ display: flex;
33
+ flex-wrap: wrap;
34
+ .message-categories,
35
+ .message-tags {
36
+ display: flex;
37
+ align-items: center;
38
+ margin: 8px 0;
39
+ a {
40
+ padding: 4px 8px;
41
+ font-size: 13px;
42
+ line-height: 14px;
43
+ border-radius: 4px;
44
+ margin: 0 0 0 8px;
45
+ }
46
+ }
47
+ .message-categories {
48
+ margin: 0 16px 0 0;
49
+ a {
50
+ color: $color-categories;
51
+ background-color: $categoriesBackground;
52
+ border: 1px solid $categoriesBackground;
53
+ }
54
+ }
55
+ .message-tags {
56
+ a {
57
+ border: 1px solid;
58
+ color: $color-tags;
59
+ }
60
+ }
61
+ }
62
+
63
+ @for $i from 1 through list.length($postMessageTagBackground) {
64
+ .message-tags a:nth-child(#{$i}) {
65
+ border-color: list.nth($postMessageTagBackground, $i);
66
+ }
67
+ }
68
+
69
+ .message-bottom {
70
+ display: flex;
71
+ gap: 8px;
72
+ color: $color-message;
73
+ white-space: nowrap;
74
+ overflow: auto;
75
+ font-size: 13px;
76
+ }
77
+
78
+ #EntryTag,
79
+ #BlogPostCategory {
80
+ display: none;
81
+ }
@@ -0,0 +1,28 @@
1
+ // 在随笔详情页顶部随笔生成一个文章头图
2
+ import { getPostTopImageOptions } from 'tona-options'
3
+ import { isPostDetailsPage } from '../../utils/cnblog'
4
+ import { randomArrayElements, randomImgUrl } from '../../utils/helpers'
5
+
6
+ export function postTopImage(_, devOptions) {
7
+ const { enable, imgs, fixed } = getPostTopImageOptions(devOptions)
8
+
9
+ if (!enable) {
10
+ return
11
+ }
12
+ if (!isPostDetailsPage()) {
13
+ return
14
+ }
15
+
16
+ const url =
17
+ imgs.length === 0 ? randomImgUrl() : randomArrayElements(imgs, 1)[0]
18
+ const ele = `<a href="${url}" target="blank"><div id="custom-post-topimage"></div></a>`
19
+ const style = {
20
+ 'background-image': `url(${url})`,
21
+ }
22
+
23
+ if (fixed) {
24
+ style['background-attachment'] = 'fixed'
25
+ }
26
+ $('.post>.postTitle').before(ele)
27
+ $('#custom-post-topimage').css(style)
28
+ }
@@ -0,0 +1,29 @@
1
+ @use 'sass:map';
2
+
3
+ $postTopimage: () !default;
4
+ $postTopimage: map.merge(
5
+ (
6
+ height: 400px,
7
+ ),
8
+ $postTopimage
9
+ );
10
+
11
+ $height: map.get($postTopimage, height);
12
+
13
+ #custom-post-topimage {
14
+ width: 100%;
15
+ height: $height;
16
+ background-size: cover;
17
+ background-repeat: no-repeat;
18
+ margin-bottom: 10px;
19
+ border-radius: 2px;
20
+ }
21
+ #custom-post-topimage:hover {
22
+ cursor: zoom-in;
23
+ }
24
+
25
+ @media screen and (max-width: 767px) {
26
+ #custom-post-topimage {
27
+ height: 184px;
28
+ }
29
+ }
@@ -0,0 +1,42 @@
1
+ // 二维码
2
+ import { getQrcodeOptions } from 'tona-options'
3
+
4
+ /**
5
+ * 构建二维码图片
6
+ * @param {*} img
7
+ */
8
+ function buildImage(img) {
9
+ if (img === '') {
10
+ return
11
+ }
12
+ const ele = `<img class='custom-qrcode' src='${img}' />`
13
+ $('.custom-signature').length
14
+ ? $('.custom-signature').after(ele)
15
+ : $('#blog-news').after(ele)
16
+ }
17
+
18
+ /**
19
+ * 构建文字描述信息
20
+ * @param {*} desc
21
+ */
22
+ function buildDesc(desc) {
23
+ if (desc === '') {
24
+ return
25
+ }
26
+ const ele = `<div class='custom-qrcode-desc'>${desc}</div>`
27
+ $('.custom-qrcode').after(ele)
28
+ }
29
+
30
+ export function qrcode(_, devOptions) {
31
+ const { enable, img, desc } = getQrcodeOptions(devOptions)
32
+
33
+ if ($('#blog-news').length === 0) {
34
+ return
35
+ }
36
+ if (!enable) {
37
+ return
38
+ }
39
+
40
+ buildImage(img)
41
+ buildDesc(desc)
42
+ }
@@ -0,0 +1,10 @@
1
+ .custom-qrcode {
2
+ width: 100%;
3
+ height: 248px;
4
+ }
5
+
6
+ .custom-qrcode-desc {
7
+ padding: 5px 14px 10px;
8
+ word-break: break-all;
9
+ line-height: 1.5em;
10
+ }
@@ -0,0 +1,47 @@
1
+ // 个性签名
2
+ import { getSignatureOptions } from 'tona-options'
3
+ import { typedJs } from '../../constants/cdn'
4
+ import { loadScript } from '../../utils/helpers'
5
+
6
+ /**
7
+ * 构建容器
8
+ * @param {*} selector
9
+ */
10
+ function build(selector) {
11
+ const el = "<div class='custom-signature'><span></span></div>"
12
+ $(selector).append(el)
13
+ }
14
+
15
+ /**
16
+ * 构建打字机效果
17
+ * @param {*} contents
18
+ */
19
+ function typed(contents) {
20
+ loadScript(typedJs, () => {
21
+ // eslint-disable-next-line no-new
22
+ new window.Typed('.custom-signature span', {
23
+ strings: contents,
24
+ typeSpeed: 70,
25
+ })
26
+ })
27
+ }
28
+
29
+ export function signature(_, devOptions, pluginOptions) {
30
+ const { enable, contents } = getSignatureOptions(devOptions)
31
+ if (!enable) {
32
+ return
33
+ }
34
+
35
+ let pluginConfig = {
36
+ selector: '#sidebar_news',
37
+ }
38
+
39
+ if (pluginOptions) {
40
+ pluginConfig = { ...pluginConfig, ...pluginOptions }
41
+ }
42
+
43
+ const { selector } = pluginConfig
44
+
45
+ build(selector)
46
+ typed(contents)
47
+ }
@@ -0,0 +1,18 @@
1
+ @use 'sass:map';
2
+
3
+ $signature: () !default;
4
+ $signature: map.merge(
5
+ (
6
+ padding: 1rem 14px,
7
+ fontSize: 1em,
8
+ ),
9
+ $signature
10
+ );
11
+ $padding: map.get($signature, padding);
12
+ $fontSize: map.get($signature, fontSize);
13
+
14
+ .custom-signature {
15
+ padding: $padding;
16
+ font-size: $fontSize;
17
+ line-height: 1.5em;
18
+ }
@@ -0,0 +1,49 @@
1
+ import { Notyf } from 'notyf'
2
+ import 'notyf/notyf.min.css'
3
+
4
+ export function toast(message, type = 'success', duration) {
5
+ const notyf = new Notyf({
6
+ position: { x: 'right', y: 'top' },
7
+ icon: false,
8
+ duration: 2500,
9
+ dismissible: true,
10
+ type: 'success',
11
+ types: [
12
+ {
13
+ type: 'info',
14
+ background: 'rgba(0,0,0,0.7)',
15
+ icon: false,
16
+ },
17
+ {
18
+ type: 'warning',
19
+ background: 'orange',
20
+ icon: {
21
+ className: 'material-icons',
22
+ tagName: 'i',
23
+ text: 'warning',
24
+ },
25
+ },
26
+ {
27
+ type: 'error',
28
+ background: 'indianred',
29
+ duration: 2000,
30
+ dismissible: true,
31
+ },
32
+ ],
33
+ })
34
+
35
+ if (type === 'info') {
36
+ notyf.open({
37
+ type,
38
+ message,
39
+ duration,
40
+ icon: false,
41
+ })
42
+ } else {
43
+ notyf[type]({
44
+ message,
45
+ duration,
46
+ icon: false,
47
+ })
48
+ }
49
+ }
@@ -0,0 +1,251 @@
1
+ import { getToolsOptions } from 'tona-options'
2
+ import { getCurrentPage, likePost } from '../../utils/cnblog'
3
+ import { isPhone } from '../../utils/helpers'
4
+ import { toast } from '../toast'
5
+
6
+ /**
7
+ * 滚动到评论输入框
8
+ * @param {string} container
9
+ */
10
+ function scrollToComment(container) {
11
+ $(container).animate(
12
+ {
13
+ scrollTop: $('#mainContent')[0].scrollHeight,
14
+ },
15
+ 300,
16
+ )
17
+ }
18
+
19
+ /**
20
+ * 滚动到顶部
21
+ * @param {string} container
22
+ */
23
+ function scrollToTop(container) {
24
+ $(container).animate(
25
+ {
26
+ scrollTop: 0,
27
+ },
28
+ 200,
29
+ )
30
+ }
31
+
32
+ /**
33
+ * 创建 toolbar 容器
34
+ */
35
+ function createToolbarContainer() {
36
+ return $('<div class="custom-toolbar">')
37
+ }
38
+
39
+ /**
40
+ * 创建按钮项中的图标
41
+ */
42
+ function createIcon(icon, iconType) {
43
+ const $icon = $('<i>')
44
+ iconType === 'className' ? $icon.addClass(icon) : $icon.html(icon)
45
+ return $icon
46
+ }
47
+
48
+ /**
49
+ * 创建按钮项中的工具提示
50
+ */
51
+ function createTooltip(text, className) {
52
+ const ele = $(`<div class="tooltip">${text}</div>`)
53
+ if (className) {
54
+ ele.addClass(className)
55
+ }
56
+ return ele
57
+ }
58
+
59
+ /**
60
+ * 创建 toggle 按钮
61
+ * @param {string} icon
62
+ */
63
+ function createToggleItem(icon, iconType, isActiveIcon) {
64
+ const $ele = $('<div class="toolbar-item toolbar-item-toggle"></div>')
65
+ const $icon = createIcon(icon, iconType)
66
+ const $tooltip = createTooltip(
67
+ isActiveIcon ? '收起' : '展开',
68
+ ' tooltip-toggle',
69
+ )
70
+
71
+ isActiveIcon && $ele.addClass('active').hide()
72
+
73
+ $ele.append($icon)
74
+ $ele.append($tooltip)
75
+
76
+ return $ele
77
+ }
78
+
79
+ /**
80
+ * 创建 toolbar 按钮项
81
+ */
82
+ function createToolbarItem(item, translateY, finalPluginOptions) {
83
+ const { className, callback, icon, iconType, tooltip } = item
84
+
85
+ const $item = $(
86
+ `<div class="toolbar-item" style="transform: translateY(-${translateY}px)">`,
87
+ )
88
+
89
+ if (className) {
90
+ $item.addClass(className)
91
+ }
92
+
93
+ $item.on('click', () => callback(finalPluginOptions))
94
+
95
+ const $icon = createIcon(icon, iconType)
96
+ const $tip = createTooltip(tooltip)
97
+
98
+ $item.append($icon)
99
+ $item.append($tip)
100
+
101
+ return $item
102
+ }
103
+
104
+ /**
105
+ * 创建按钮插件
106
+ */
107
+ function createToolbar(finalPluginOptions) {
108
+ const { toolbarItems, menuIcon, menuActiveIcon, menuIconType } =
109
+ finalPluginOptions
110
+
111
+ const $toolbar = createToolbarContainer()
112
+ const $toggleItem = createToggleItem(menuIcon, menuIconType, false)
113
+ const $toggleActiveItem = createToggleItem(menuActiveIcon, menuIconType, true)
114
+
115
+ const pageCondition = (page) => {
116
+ return page === getCurrentPage() || page === 'all'
117
+ }
118
+
119
+ let translateY = 0
120
+
121
+ toolbarItems.reverse().forEach((item) => {
122
+ if (!item.enable) {
123
+ return
124
+ }
125
+ if (pageCondition(item.page)) {
126
+ const $item = createToolbarItem(item, translateY, finalPluginOptions)
127
+ translateY += 40
128
+ $toolbar.append($item)
129
+ }
130
+ })
131
+
132
+ $toolbar.append($toggleItem).append($toggleActiveItem)
133
+ $('body').append($toolbar)
134
+ $('.toolbar-item-toggle').click(handleToggle)
135
+ }
136
+
137
+ /**
138
+ * 处理展开和收起
139
+ */
140
+ function handleToggle() {
141
+ const transformed = (translateY) => {
142
+ let _translateY = translateY
143
+ $('.toolbar-item:not(.toolbar-item-toggle)').each((_, item) => {
144
+ $(item).css({
145
+ transform: `translateY(${_translateY}px)`,
146
+ })
147
+ _translateY += translateY - 40
148
+ })
149
+ }
150
+
151
+ const toggleExtend = (isExtend) => {
152
+ const translateY = isExtend ? 90 : -50
153
+ const $menuButton = $('.toolbar-item-toggle:not(.active)')
154
+ const $activeMenuButton = $('.toolbar-item-toggle.active')
155
+
156
+ transformed(translateY)
157
+
158
+ if (isExtend) {
159
+ $menuButton.show()
160
+ $activeMenuButton.hide()
161
+ } else {
162
+ $menuButton.hide()
163
+ $activeMenuButton.show()
164
+ }
165
+ }
166
+
167
+ $('.custom-toolbar').toggleClass('extend')
168
+ $('.custom-toolbar').hasClass('extend')
169
+ ? toggleExtend(false)
170
+ : toggleExtend(true)
171
+ }
172
+
173
+ export function tools(_, devOptions, pluginOptions) {
174
+ const { enable, initialOpen } = getToolsOptions(devOptions)
175
+ if (!enable) {
176
+ return
177
+ }
178
+
179
+ const pluginDefaultOptions = {
180
+ scrollContainer: 'html',
181
+ menuIconType: 'html', // 'className' | 'html'
182
+ menuIcon: '➕',
183
+ menuActiveIcon: '➖',
184
+ toolbarItems: [
185
+ {
186
+ enable: true,
187
+ page: 'all',
188
+ icon: '🚀',
189
+ iconType: 'html',
190
+ tooltip: '回顶',
191
+ callback: (config) => scrollToTop(config.scrollContainer),
192
+ },
193
+ {
194
+ enable: false,
195
+ page: 'all',
196
+ icon: '🌜',
197
+ iconType: 'html',
198
+ tooltip: '深色',
199
+ className: 'mode-change',
200
+ callback() {},
201
+ },
202
+ {
203
+ enable: true,
204
+ page: 'post',
205
+ icon: '👍',
206
+ iconType: 'html',
207
+ tooltip: '推荐',
208
+ callback() {
209
+ toast('推荐成功')
210
+ likePost()
211
+ },
212
+ },
213
+ {
214
+ enable: true,
215
+ page: 'post',
216
+ icon: '💗',
217
+ iconType: 'html',
218
+ tooltip: '关注',
219
+ callback() {
220
+ toast('关注成功')
221
+ window.follow()
222
+ },
223
+ },
224
+ {
225
+ enable: true,
226
+ page: 'post',
227
+ icon: '📌',
228
+ iconType: 'html',
229
+ tooltip: '收藏',
230
+ callback() {
231
+ window.AddToWz()
232
+ },
233
+ },
234
+ {
235
+ enable: true,
236
+ page: 'post',
237
+ icon: '💬',
238
+ iconType: 'html',
239
+ tooltip: '评论',
240
+ callback: (config) => scrollToComment(config.scrollContainer),
241
+ },
242
+ ],
243
+ }
244
+
245
+ const finalPluginOptions = $.extend(true, pluginDefaultOptions, pluginOptions)
246
+
247
+ createToolbar(finalPluginOptions)
248
+ if (!isPhone() && initialOpen) {
249
+ handleToggle()
250
+ }
251
+ }
@@ -0,0 +1,114 @@
1
+ @use 'sass:map';
2
+
3
+ $toolMenu: () !default;
4
+ $toolMenu: map.merge(
5
+ (
6
+ background: #fff,
7
+ color: #fff,
8
+ ),
9
+ $toolMenu
10
+ );
11
+
12
+ $background: map.get($toolMenu, background);
13
+ $color: map.get($toolMenu, color);
14
+
15
+ .custom-toolbar {
16
+ position: fixed;
17
+ bottom: 30px;
18
+ right: 30px;
19
+ width: 40px;
20
+ height: 40px;
21
+ }
22
+
23
+ .toolbar-item {
24
+ position: relative;
25
+ width: 40px;
26
+ height: 40px;
27
+ background-color: $background;
28
+ border-radius: 50%;
29
+ text-align: center;
30
+ font-size: 20px;
31
+ line-height: 40px;
32
+ box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
33
+ cursor: pointer;
34
+ &.toolbar-item-toggle {
35
+ position: absolute;
36
+ bottom: 0;
37
+ }
38
+ i {
39
+ display: flex;
40
+ justify-content: center;
41
+ font-style: normal;
42
+ outline: none;
43
+ &::before {
44
+ margin-right: 0;
45
+ }
46
+ &::selection {
47
+ background: none;
48
+ }
49
+ }
50
+ .tooltip {
51
+ position: relative;
52
+ display: flex;
53
+ justify-content: center;
54
+ align-items: center;
55
+ height: 24px;
56
+ background-color: #333;
57
+ color: #fff;
58
+ text-align: center;
59
+ border-radius: 2px;
60
+ font-size: 12px;
61
+ pointer-events: none;
62
+ visibility: hidden;
63
+ transform: translateY(-31px);
64
+ z-index: 9;
65
+ &:after {
66
+ position: absolute;
67
+ right: -5px;
68
+ content: '';
69
+ width: 0;
70
+ height: 0;
71
+ margin: 0;
72
+ border-bottom: 6px solid transparent;
73
+ border-top: 6px solid transparent;
74
+ border-left: 6px solid #333;
75
+ }
76
+ }
77
+ &:hover {
78
+ .tooltip {
79
+ visibility: visible;
80
+ transform: translate(-50px, -31px);
81
+ transition: transform 0.2s;
82
+ }
83
+ }
84
+ &:active {
85
+ filter: brightness(0.8);
86
+ transition: filter 0.2s;
87
+ }
88
+ }
89
+
90
+ @media screen and (max-width: 1366px) {
91
+ .menu-item-tooltip {
92
+ display: none;
93
+ }
94
+ }
95
+
96
+ @media screen and (max-width: 1024px) {
97
+ .toolbar-item {
98
+ &:hover {
99
+ .tooltip {
100
+ visibility: hidden;
101
+ }
102
+ }
103
+ }
104
+ }
105
+
106
+ @media screen and (max-width: 767px) {
107
+ .custom-tools-menu .menu-item:not(:last-child):hover {
108
+ transform: none;
109
+ }
110
+ .custom-tools-menu {
111
+ right: 20px;
112
+ bottom: 20px;
113
+ }
114
+ }
@@ -0,0 +1,40 @@
1
+ // 设置网站图标和标题
2
+ import { getWebsiteTagOptions } from 'tona-options'
3
+
4
+ /**
5
+ * 构建网页标题
6
+ * @param {*} title
7
+ */
8
+ function setTitle(title) {
9
+ if (title === '') {
10
+ return
11
+ }
12
+ document.title = title
13
+ }
14
+
15
+ /**
16
+ * 构建网页 favicon
17
+ * @param {*} favicon
18
+ */
19
+ function setFavicon(favicon) {
20
+ if (favicon === '') {
21
+ return
22
+ }
23
+ const el = document.getElementById('favicon')
24
+ if (el === null) {
25
+ $('title').after(
26
+ `<link id="favicon" rel="shortcut icon" href="${favicon}" type="image/svg+xml">`,
27
+ )
28
+ } else {
29
+ el.href = favicon
30
+ }
31
+ }
32
+
33
+ export function webTag(_, devOptions) {
34
+ const { enable, title, favicon } = getWebsiteTagOptions(devOptions)
35
+ if (!enable) {
36
+ return
37
+ }
38
+ setTitle(title)
39
+ setFavicon(favicon)
40
+ }
File without changes