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,137 @@
1
+ import { getClickEffectsOptions } from 'tona-options'
2
+
3
+ function ColorBall(params) {
4
+ const defaultParams = {
5
+ colors: ['#eb125f', '#6eff8a', '#6386ff', '#f9f383'],
6
+ size: 30,
7
+ maxCount: 30,
8
+ }
9
+ this.params = { ...defaultParams, ...params }
10
+ if (!params.colors.length) {
11
+ this.params.colors = defaultParams.colors
12
+ }
13
+ }
14
+
15
+ function getOneRandom(arr) {
16
+ return arr[Math.floor(Math.random() * arr.length)]
17
+ }
18
+
19
+ function _run(ball) {
20
+ const randomXFlag = Math.random() > 0.5
21
+ const randomYFlag = Math.random() > 0.5
22
+ let randomX = Number.parseInt(Math.random() * 160, 10)
23
+ let randomY = Number.parseInt(Math.random() * 160, 10)
24
+ if (randomXFlag) {
25
+ randomX = randomX * -1
26
+ }
27
+ if (randomYFlag) {
28
+ randomY = randomY * -1
29
+ }
30
+ const transform = `translate3d(${randomX}px,${randomY}px, 0) scale(0)`
31
+ ball.style.webkitTransform = transform
32
+ ball.style.MozTransform = transform
33
+ ball.style.msTransform = transform
34
+ ball.style.OTransform = transform
35
+ ball.style.transform = transform
36
+ }
37
+
38
+ ColorBall.prototype.fly = function (x, y, playCount, loopTimer = 300) {
39
+ const ballElements = []
40
+ const fragment = document.createDocumentFragment()
41
+ let ballNum = this.params.maxCount
42
+
43
+ if (playCount) {
44
+ ballNum = ballNum * playCount
45
+ }
46
+
47
+ let loop = 0
48
+
49
+ for (let i = 0; i < ballNum; i++) {
50
+ const curLoop = Number.parseInt(i / this.params.maxCount, 10)
51
+ const ball = document.createElement('i')
52
+ ball.className = `color-ball ball-loop-${curLoop}`
53
+ let blurX = Math.random() * 10
54
+ if (Math.random() > 0.5) {
55
+ blurX = blurX * -1
56
+ }
57
+ let blurY = Math.random() * 10
58
+ if (Math.random() > 0.5) {
59
+ blurY = blurY * -1
60
+ }
61
+ ball.style.left = `${x}px`
62
+ ball.style.top = `${y}px`
63
+ ball.style.width = `${this.params.size}px`
64
+ ball.style.height = `${this.params.size}px`
65
+ ball.style.position = 'fixed'
66
+ ball.style.borderRadius = '1000px'
67
+ ball.style.boxSizing = 'border-box'
68
+ ball.style.zIndex = 9999
69
+ ball.style.opacity = 0
70
+ if (curLoop === 0) {
71
+ ball.style.opacity = 1
72
+ }
73
+ ball.style.transform = 'translate3d(0px, 0px, 0px) scale(1)'
74
+ ball.style.transition = `transform 0.7s ${
75
+ (curLoop * loopTimer) / 1000
76
+ }s ease-out`
77
+ ball.style.backgroundColor = getOneRandom(this.params.colors)
78
+ fragment.appendChild(ball)
79
+ ballElements.push(ball)
80
+
81
+ if (curLoop !== loop) {
82
+ ;((num) => {
83
+ setTimeout(
84
+ () => {
85
+ const loopBalls = document.getElementsByClassName(
86
+ `ball-loop-${num}`,
87
+ )
88
+ for (let j = 0; j < loopBalls.length; j++) {
89
+ loopBalls[j].style.opacity = 1
90
+ }
91
+ if (num === loop) {
92
+ _clear(ballElements)
93
+ }
94
+ },
95
+ num * loopTimer + 30,
96
+ )
97
+ })(curLoop)
98
+ loop = curLoop
99
+ }
100
+ }
101
+
102
+ document.body.appendChild(fragment)
103
+ // 延迟删除
104
+ !playCount && _clear(ballElements)
105
+ // 执行动画
106
+ setTimeout(() => {
107
+ for (let i = 0; i < ballElements.length; i++) {
108
+ _run(ballElements[i])
109
+ }
110
+ }, 10)
111
+ }
112
+
113
+ function _clear(balls) {
114
+ setTimeout(() => {
115
+ for (let i = 0; i < balls.length; i++) {
116
+ document.body.removeChild(balls[i])
117
+ }
118
+ }, 1000)
119
+ }
120
+
121
+ function build(options) {
122
+ const colorBallConfig = {
123
+ colors: options.colors,
124
+ size: options.size,
125
+ maxCount: options.maxCount,
126
+ }
127
+ const color = new ColorBall(colorBallConfig)
128
+
129
+ $('body').click((e) => {
130
+ color.fly(e.clientX, e.clientY)
131
+ })
132
+ }
133
+
134
+ export function clickEffects(_, devOptions) {
135
+ const options = getClickEffectsOptions(devOptions)
136
+ options.enable && build(options)
137
+ }
File without changes
@@ -0,0 +1,94 @@
1
+ /**
2
+ * 构建代码块复制按钮
3
+ */
4
+ import { getCodeCopyOptions } from 'tona-options'
5
+ import { isMd, isPostDetailsPage } from '../../utils/cnblog'
6
+ import { copyToClipboard } from '../../utils/helpers'
7
+ import { toast } from '../toast'
8
+
9
+ /**
10
+ * 创建复制按钮
11
+ */
12
+ function createCopyButtons() {
13
+ return '<div class="copy-btns">复制代码</div>'
14
+ }
15
+
16
+ /**
17
+ * 将代码复制到剪切板
18
+ * @param {string} code - 代码字符串
19
+ */
20
+ function handleCopyCode(code, btn) {
21
+ copyToClipboard(code)
22
+ .then(() => {
23
+ toast('复制成功')
24
+ btn.text('复制成功')
25
+ setTimeout(() => {
26
+ btn.text('复制代码')
27
+ }, 1500)
28
+ })
29
+ .catch(() => {
30
+ btn.text('复制失败')
31
+ })
32
+ }
33
+
34
+ /**
35
+ * 处理复制按钮点击事件
36
+ */
37
+ function handleClickCopyButton() {
38
+ const __MD__ = isMd()
39
+ const position = __MD__ ? 'pre' : '.cnblogs_code'
40
+ const selector = `${position},.cnblogs_Highlighter`
41
+
42
+ $(selector).on('click', '.copy-btns', function () {
43
+ let code
44
+
45
+ if ($(this).parent().hasClass('cnblogs_Highlighter')) {
46
+ code = $(this).siblings().find('code').text()
47
+ } else {
48
+ const codeBlockTagName = __MD__ ? 'code' : 'pre'
49
+ code = $(this).siblings(codeBlockTagName).text()
50
+ }
51
+
52
+ handleCopyCode(code, $(this))
53
+ })
54
+ }
55
+
56
+ /**
57
+ * 在代码块挂载复制按钮
58
+ */
59
+ function mountButtons() {
60
+ const __MD__ = isMd()
61
+ const copyBtn = createCopyButtons()
62
+ const pres = $('#cnblogs_post_body').find('pre')
63
+
64
+ if (pres.length) {
65
+ const fn = __MD__ ? 'prepend' : 'before'
66
+ pres.each((_, item) => {
67
+ $(item)[fn](copyBtn)
68
+ })
69
+ }
70
+
71
+ if (!__MD__) {
72
+ const highlighters = $('.cnblogs_Highlighter')
73
+ if (!highlighters.length) {
74
+ return
75
+ }
76
+ highlighters.each((_, item) => {
77
+ $(item).prepend(copyBtn)
78
+ })
79
+ }
80
+ }
81
+
82
+ export function codeCopy(_, devOptions) {
83
+ const { enable } = getCodeCopyOptions(devOptions)
84
+
85
+ if (!enable) {
86
+ return
87
+ }
88
+ if (!isPostDetailsPage()) {
89
+ return
90
+ }
91
+
92
+ mountButtons()
93
+ handleClickCopyButton()
94
+ }
@@ -0,0 +1,65 @@
1
+ @use 'sass:map';
2
+
3
+ $copy: () !default;
4
+ $copy: map.merge(
5
+ (
6
+ bg: rgba(0, 0, 0, 0.6),
7
+ color: rgb(241, 239, 239),
8
+ hover-bg: rgba(0, 0, 0, 0.2),
9
+ hover-color: #eee,
10
+ ),
11
+ $copy
12
+ );
13
+
14
+ $bg: map.get($copy, bg);
15
+ $color: map.get($copy, color);
16
+ $hover-bg: map.get($copy, hover-bg);
17
+ $hover-color: map.get($copy, hover-color);
18
+
19
+ #cnblogs_post_body pre {
20
+ position: relative;
21
+ }
22
+
23
+ .cnblogs_code,
24
+ .cnblogs_Highlighter {
25
+ position: relative;
26
+ .copy-btns {
27
+ z-index: 1;
28
+ }
29
+ }
30
+
31
+ pre:hover,
32
+ .cnblogs_code:hover,
33
+ .cnblogs_Highlighter:hover {
34
+ .copy-btns {
35
+ visibility: visible;
36
+ }
37
+ }
38
+
39
+ .copy-btns {
40
+ position: absolute;
41
+ top: 10px;
42
+ right: 10px;
43
+ padding: 2px 8px;
44
+ visibility: hidden;
45
+ color: $color !important;
46
+ font-size: 12px;
47
+ border-radius: 4px;
48
+ cursor: pointer;
49
+ transition: all 0.2s;
50
+ user-select: none;
51
+ }
52
+
53
+ .copy-btns {
54
+ background-color: $bg !important;
55
+ &:active {
56
+ background: $hover-bg;
57
+ color: $hover-color;
58
+ }
59
+ }
60
+
61
+ @media screen and (max-width: 768px) {
62
+ .copy-btns {
63
+ display: none;
64
+ }
65
+ }
@@ -0,0 +1,35 @@
1
+ import { getCodeHighlightOptions } from 'tona-options'
2
+ import { getCurrentPage, isMd } from '../../utils/cnblog'
3
+ import { themes } from './themes.js'
4
+
5
+ /**
6
+ * 构建 Markdown 代码块高亮
7
+ * @param {*} light
8
+ * @param {*} dark
9
+ */
10
+ function buildMarkdownHighlight(light, dark) {
11
+ let style
12
+ if (!isMd()) {
13
+ style = `<style>
14
+ :root{${themes.github}}
15
+ </style>`
16
+ } else {
17
+ style = `<style>
18
+ :root{${themes[light]}}
19
+ :root[theme="dark"]{${themes[dark]}}
20
+ </style>`
21
+ }
22
+ $('head').append(style)
23
+ }
24
+
25
+ export function codeHighlight(_, devOptions) {
26
+ if (getCurrentPage() !== 'post') {
27
+ return
28
+ }
29
+ if ($('pre').length === 0) {
30
+ return
31
+ }
32
+
33
+ const { light, dark } = getCodeHighlightOptions(devOptions)
34
+ buildMarkdownHighlight(light, dark)
35
+ }
@@ -0,0 +1,216 @@
1
+ // https://highlightjs.readthedocs.io/en/latest/theme-guide.html
2
+
3
+ $background: var(--hl-base);
4
+ $keyword: var(--hl-hue-3);
5
+ $string: var(--hl-hue-4);
6
+ $plain: var(--hl-mono-1);
7
+ $comments: var(--hl-mono-3);
8
+ $variable: var(--hl-mono-1);
9
+ $functions: var(--hl-hue-2);
10
+ $codeFontFamily:
11
+ Consolas,
12
+ Lucida Console,
13
+ Monaco,
14
+ Andale Mono,
15
+ Ubuntu Mono,
16
+ monospace;
17
+
18
+ // tinymce5
19
+ // Markdown
20
+ #cnblogs_post_body.blogpost-body-html,
21
+ #mainContent .cnblogs-markdown {
22
+ pre {
23
+ margin-top: 8px;
24
+ padding: 24px 0 10px;
25
+ border-radius: 4px;
26
+ background: $background;
27
+ font-family: $codeFontFamily !important;
28
+ }
29
+ // 单行代码及代码块
30
+ code {
31
+ font-family: $codeFontFamily !important;
32
+ font-size: 15px !important;
33
+ margin: 0;
34
+ word-break: break-word !important;
35
+ border: none !important;
36
+ }
37
+ // 代码块
38
+ li code {
39
+ font-weight: 700;
40
+ }
41
+ .hljs {
42
+ display: block !important;
43
+ color: var(--hl-mono-1) !important;
44
+ background: $background !important;
45
+ border: none !important;
46
+ padding: 16px 10px 8px 13px !important;
47
+ font-weight: normal;
48
+ white-space: inherit;
49
+ }
50
+ .hljs-punctuation,
51
+ .hljs-tag {
52
+ color: var(--hl-mono-1);
53
+ }
54
+ .hljs-comment,
55
+ .hljs-quote {
56
+ color: var(--hl-mono-3);
57
+ font-style: italic;
58
+ }
59
+ .hljs-tag {
60
+ color: var(--hl-tag);
61
+ }
62
+ .hljs-doctag,
63
+ .hljs-formula,
64
+ .hljs-keyword {
65
+ color: $keyword;
66
+ }
67
+ .hljs-deletion,
68
+ .hljs-name,
69
+ .hljs-section,
70
+ .hljs-selector-tag,
71
+ .hljs-subst {
72
+ color: var(--hl-hue-5);
73
+ }
74
+ .hljs-literal {
75
+ color: var(--hl-hue-1);
76
+ }
77
+ .hljs-addition,
78
+ .hljs-attribute,
79
+ .hljs-meta-string,
80
+ .hljs-regexp,
81
+ .hljs-string {
82
+ color: var(--hl-hue-4);
83
+ }
84
+ .hljs-built_in,
85
+ .hljs-class .hljs-title {
86
+ color: var(--hl-hue-6-2);
87
+ }
88
+ .hljs-attr,
89
+ .hljs-number,
90
+ .hljs-selector-attr,
91
+ .hljs-selector-class,
92
+ .hljs-selector-pseudo,
93
+ .hljs-template-variable,
94
+ .hljs-type,
95
+ .hljs-variable {
96
+ color: var(--hl-hue-6);
97
+ }
98
+ .hljs-bullet,
99
+ .hljs-link,
100
+ .hljs-meta,
101
+ .hljs-selector-id,
102
+ .hljs-symbol,
103
+ .hljs-title {
104
+ color: var(--hl-hue-2);
105
+ }
106
+ .hljs-emphasis {
107
+ font-style: italic;
108
+ }
109
+ .hljs-strong {
110
+ font-weight: 700;
111
+ }
112
+ .hljs-link {
113
+ text-decoration: underline;
114
+ }
115
+ }
116
+
117
+ // tinymce
118
+ #cnblogs_post_body {
119
+ .cnblogs_code {
120
+ border: none;
121
+ background-color: $background;
122
+ border-radius: 4px;
123
+ pre {
124
+ padding: 30px 12px 12px;
125
+ overflow: auto;
126
+ &::before {
127
+ display: none;
128
+ }
129
+ }
130
+ & > img {
131
+ display: none;
132
+ }
133
+ span {
134
+ background-color: $background !important;
135
+ &[style='color: #008000;'] {
136
+ color: var(--hl-mono-3) !important;
137
+ font-style: italic;
138
+ }
139
+ &[style='color: rgba(0, 128, 128, 1);'] {
140
+ color: red !important;
141
+ }
142
+ &[style='background-color: #f5f5f5; color: #000000;'],
143
+ &[style='color: #000000;'] {
144
+ color: var(--hl-mono-1) !important;
145
+ }
146
+ &[style='background-color: #f5f5f5; color: #800000;'] {
147
+ color: var(--hl-hue-2) !important;
148
+ }
149
+ &[style='color: #0000ff;'],
150
+ &[style='background-color: #f5f5f5; color: #0000ff;'] {
151
+ color: $keyword !important;
152
+ }
153
+ &[style='color: #800000;'],
154
+ &[style='color: #ff0000;'],
155
+ &[style='background-color: #f5f5f5; color: #ff0000;'] {
156
+ color: var(--hl-hue-4) !important;
157
+ }
158
+ &[style='color: #8b0000;'] {
159
+ color: var(--hl-hue-6) !important;
160
+ }
161
+ }
162
+ }
163
+ .cnblogs_code_collapse,
164
+ .cnblogs_code_toolbar,
165
+ .code_img_opened,
166
+ .code_img_closed {
167
+ display: none;
168
+ }
169
+ .cnblogs_code_hide {
170
+ display: block;
171
+ }
172
+ }
173
+
174
+ .syntaxhighlighter {
175
+ background: $background !important;
176
+ .line.alt1,
177
+ .line.alt2 {
178
+ background-color: $background !important;
179
+ }
180
+ }
181
+
182
+ #cnblogs_post_body {
183
+ .cnblogs_Highlighter {
184
+ table {
185
+ tbody {
186
+ width: 100% !important;
187
+ }
188
+ .gutter {
189
+ padding-bottom: 0 !important;
190
+ }
191
+ }
192
+
193
+ code {
194
+ background-color: $background !important;
195
+ }
196
+ .keyword {
197
+ color: $keyword !important;
198
+ }
199
+ .string {
200
+ color: $string !important;
201
+ }
202
+ .plain {
203
+ color: $plain !important;
204
+ }
205
+ .variable {
206
+ color: $variable !important;
207
+ }
208
+ .comments {
209
+ color: $comments !important;
210
+ font-style: italic !important;
211
+ }
212
+ .functions {
213
+ color: $functions !important;
214
+ }
215
+ }
216
+ }
@@ -0,0 +1,60 @@
1
+ // https://highlightjs.readthedocs.io/en/latest/theme-guide.html
2
+
3
+ const atomOneDark =
4
+ '--hl-base: #282c34;' +
5
+ '--hl-mono-1: #abb2bf;' +
6
+ '--hl-mono-3: #5c6370;' +
7
+ '--hl-hue-1: #56b6c2;' +
8
+ '--hl-hue-2: #61aeee;' +
9
+ '--hl-hue-3: #c678dd;' +
10
+ '--hl-hue-4: #98c379;' +
11
+ '--hl-hue-5: #e06c75;' +
12
+ '--hl-hue-6: #d19a66;' +
13
+ '--hl-hue-6-2: #e6c07b;' +
14
+ '--hl-tag: #abb2bf;'
15
+
16
+ const atomOneLight =
17
+ '--hl-base: #f6f8fa;' +
18
+ '--hl-mono-1: #383a42;' +
19
+ '--hl-mono-3: #a0a1a7;' +
20
+ '--hl-hue-1: #0184bb;' +
21
+ '--hl-hue-2: #4078f2;' +
22
+ '--hl-hue-3: #a626a4;' +
23
+ '--hl-hue-4: #50a14f;' +
24
+ '--hl-hue-5: #e45649;' +
25
+ '--hl-hue-6: #986801;' +
26
+ '--hl-hue-6-2: #c18401;' +
27
+ '--hl-tag: #383A42;'
28
+
29
+ const github =
30
+ '--hl-base: #f6f8fa;' +
31
+ '--hl-mono-1: #333333;' +
32
+ '--hl-mono-3: #6a737d;' +
33
+ '--hl-hue-1: #0086b3;' +
34
+ '--hl-hue-2: #0086b3;' +
35
+ '--hl-hue-3: #d73a49;' +
36
+ '--hl-hue-4: #55a532;' +
37
+ '--hl-hue-5: #63a35c;' +
38
+ '--hl-hue-6: #6f42c1;' +
39
+ '--hl-hue-6-2: #6f42c1;' +
40
+ '--hl-tag: #d73a49;'
41
+
42
+ const pande =
43
+ '--hl-base: #292a2b;' +
44
+ '--hl-mono-1: #e6e6e6;' +
45
+ '--hl-mono-3: #ffcc95;' +
46
+ '--hl-hue-1: #0086b3;' +
47
+ '--hl-hue-2: #0086b3;' +
48
+ '--hl-hue-3: #d73a49;' +
49
+ '--hl-hue-4: #19f9d866;' +
50
+ '--hl-hue-5: #19f9d8;' +
51
+ '--hl-hue-6: #ff4b82;' +
52
+ '--hl-hue-6-2: #ff4b82;' +
53
+ '--hl-tag: #ffb86c;'
54
+
55
+ export const themes = {
56
+ atomOneDark,
57
+ atomOneLight,
58
+ github,
59
+ pande,
60
+ }
@@ -0,0 +1,51 @@
1
+ /**
2
+ * 构建代码块语言
3
+ * 仅在 Markdown 博文中生效
4
+ */
5
+ import { getCodeLangOptions } from 'tona-options'
6
+ import { isMd, isPostDetailsPage } from '../../utils/cnblog'
7
+
8
+ /**
9
+ * 创建代码语言容器
10
+ */
11
+ function createCodeLangContainer(lang) {
12
+ return $('<div>').addClass('awes-lang').text(lang)
13
+ }
14
+
15
+ /**
16
+ * 构建代码块语言
17
+ */
18
+ function buildCodeWrapLanguage() {
19
+ $('pre code').each(function () {
20
+ let lang = $(this)[0].classList[0]
21
+ if (lang !== undefined) {
22
+ lang = lang.substring(9)
23
+
24
+ if (lang === '') {
25
+ lang = $(this)[0].classList[1]
26
+ if (lang === undefined || lang === '') {
27
+ return
28
+ }
29
+ }
30
+
31
+ const container = createCodeLangContainer(lang)
32
+ $(this).before(container)
33
+ }
34
+ })
35
+ }
36
+
37
+ export function codeLang(_, devOptions) {
38
+ const { enable } = getCodeLangOptions(devOptions)
39
+
40
+ if (!enable) {
41
+ return
42
+ }
43
+ if (!isPostDetailsPage()) {
44
+ return
45
+ }
46
+ if (!isMd()) {
47
+ return
48
+ }
49
+
50
+ buildCodeWrapLanguage()
51
+ }
@@ -0,0 +1,28 @@
1
+ @use 'sass:map';
2
+
3
+ $codeLanguage: () !default;
4
+ $codeLanguage: map.merge(
5
+ (
6
+ color: #999999,
7
+ backgroundColor: var(--hl-base),
8
+ ),
9
+ $codeLanguage
10
+ );
11
+
12
+ $color: map.get($codeLanguage, color);
13
+ $backgroundColor: map.get($codeLanguage, backgroundColor);
14
+
15
+ #cnblogs_post_body pre {
16
+ margin: 24px 0;
17
+ }
18
+
19
+ .awes-lang {
20
+ position: absolute;
21
+ top: -19px;
22
+ right: 32px;
23
+ padding: 0 16px;
24
+ font-size: 12px;
25
+ color: $color;
26
+ background: $backgroundColor;
27
+ border-radius: 4px 4px 0 0;
28
+ }