artalk 2.7.1 → 2.7.3

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 (305) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1 -1
  3. package/dist/Artalk.cjs +2 -0
  4. package/dist/Artalk.cjs.map +1 -0
  5. package/dist/Artalk.css +1 -1
  6. package/dist/Artalk.iife.js +1 -1
  7. package/dist/Artalk.iife.js.map +1 -1
  8. package/dist/Artalk.js +1 -1
  9. package/dist/Artalk.js.map +1 -1
  10. package/dist/{Artalk.es.js → Artalk.mjs} +250 -222
  11. package/dist/Artalk.mjs.map +1 -0
  12. package/dist/ArtalkLite.cjs +2 -0
  13. package/dist/ArtalkLite.cjs.map +1 -0
  14. package/dist/ArtalkLite.css +1 -1
  15. package/dist/ArtalkLite.iife.js +1 -1
  16. package/dist/ArtalkLite.iife.js.map +1 -1
  17. package/dist/ArtalkLite.js +1 -1
  18. package/dist/ArtalkLite.js.map +1 -1
  19. package/dist/{ArtalkLite.es.js → ArtalkLite.mjs} +250 -227
  20. package/dist/ArtalkLite.mjs.map +1 -0
  21. package/dist/i18n/jp.cjs +1 -0
  22. package/dist/i18n/jp.d.cts +3 -0
  23. package/dist/i18n/jp.d.ts +3 -0
  24. package/dist/i18n/jp.js +1 -1
  25. package/dist/i18n/jp.mjs +93 -0
  26. package/dist/i18n/zh-TW.cjs +1 -0
  27. package/dist/i18n/zh-TW.d.cts +3 -0
  28. package/dist/i18n/zh-TW.d.ts +3 -0
  29. package/dist/i18n/zh-TW.js +1 -1
  30. package/dist/i18n/zh-TW.mjs +93 -0
  31. package/dist/main.d.cts +1476 -0
  32. package/dist/main.d.ts +1476 -0
  33. package/package.json +80 -22
  34. package/dist/Artalk.es.js.map +0 -1
  35. package/dist/ArtalkLite.es.js.map +0 -1
  36. package/dist/src/api/_base.d.ts +0 -10
  37. package/dist/src/api/_options.d.ts +0 -19
  38. package/dist/src/api/_request.d.ts +0 -12
  39. package/dist/src/api/admin.d.ts +0 -10
  40. package/dist/src/api/captcha.d.ts +0 -14
  41. package/dist/src/api/comment.d.ts +0 -29
  42. package/dist/src/api/index.d.ts +0 -29
  43. package/dist/src/api/page.d.ts +0 -22
  44. package/dist/src/api/site.d.ts +0 -17
  45. package/dist/src/api/system.d.ts +0 -33
  46. package/dist/src/api/upload.d.ts +0 -11
  47. package/dist/src/api/user.d.ts +0 -42
  48. package/dist/src/artalk.d.ts +0 -35
  49. package/dist/src/comment/actions.d.ts +0 -17
  50. package/dist/src/comment/comment.d.ts +0 -66
  51. package/dist/src/comment/height-limit.d.ts +0 -30
  52. package/dist/src/comment/index.d.ts +0 -2
  53. package/dist/src/comment/render.d.ts +0 -46
  54. package/dist/src/comment/renders/actions.d.ts +0 -5
  55. package/dist/src/comment/renders/avatar.d.ts +0 -5
  56. package/dist/src/comment/renders/content.d.ts +0 -5
  57. package/dist/src/comment/renders/header.d.ts +0 -5
  58. package/dist/src/comment/renders/index.d.ts +0 -2
  59. package/dist/src/comment/renders/pending.d.ts +0 -5
  60. package/dist/src/comment/renders/reply-at.d.ts +0 -5
  61. package/dist/src/comment/renders/reply-to.d.ts +0 -5
  62. package/dist/src/components/action-btn.d.ts +0 -50
  63. package/dist/src/components/checker/admin.d.ts +0 -3
  64. package/dist/src/components/checker/captcha-renders.d.ts +0 -5
  65. package/dist/src/components/checker/captcha.d.ts +0 -3
  66. package/dist/src/components/checker/index.d.ts +0 -51
  67. package/dist/src/components/dark-mode.d.ts +0 -2
  68. package/dist/src/components/dialog.d.ts +0 -16
  69. package/dist/src/components/error-dialog.d.ts +0 -8
  70. package/dist/src/components/pagination.d.ts +0 -31
  71. package/dist/src/components/read-more-btn.d.ts +0 -33
  72. package/dist/src/config.d.ts +0 -24
  73. package/dist/src/context.d.ts +0 -45
  74. package/dist/src/data.d.ts +0 -27
  75. package/dist/src/defaults.d.ts +0 -3
  76. package/dist/src/editor/editor.d.ts +0 -31
  77. package/dist/src/editor/state.d.ts +0 -20
  78. package/dist/src/editor/ui.d.ts +0 -25
  79. package/dist/src/i18n/en.d.ts +0 -72
  80. package/dist/src/i18n/external.d.ts +0 -73
  81. package/dist/src/i18n/index.d.ts +0 -233
  82. package/dist/src/i18n/jp.d.ts +0 -72
  83. package/dist/src/i18n/zh-CN.d.ts +0 -3
  84. package/dist/src/i18n/zh-TW.d.ts +0 -72
  85. package/dist/src/layer/index.d.ts +0 -4
  86. package/dist/src/layer/layer-manager.d.ts +0 -9
  87. package/dist/src/layer/layer.d.ts +0 -12
  88. package/dist/src/layer/scrollbar-helper.d.ts +0 -5
  89. package/dist/src/layer/sidebar-layer.d.ts +0 -20
  90. package/dist/src/layer/wrap.d.ts +0 -13
  91. package/dist/src/lib/component.d.ts +0 -7
  92. package/dist/src/lib/detect.d.ts +0 -10
  93. package/dist/src/lib/event-manager.d.ts +0 -28
  94. package/dist/src/lib/highlight.d.ts +0 -1
  95. package/dist/src/lib/marked-renderer.d.ts +0 -4
  96. package/dist/src/lib/marked.d.ts +0 -11
  97. package/dist/src/lib/sanitizer.d.ts +0 -1
  98. package/dist/src/lib/ui.d.ts +0 -24
  99. package/dist/src/lib/user.d.ts +0 -19
  100. package/dist/src/lib/utils.d.ts +0 -41
  101. package/dist/src/list/comment.d.ts +0 -3
  102. package/dist/src/list/layout.d.ts +0 -23
  103. package/dist/src/list/list.d.ts +0 -14
  104. package/dist/src/list/nest.d.ts +0 -10
  105. package/dist/src/list/page.d.ts +0 -2
  106. package/dist/src/list/paginator/index.d.ts +0 -25
  107. package/dist/src/list/paginator/read-more.d.ts +0 -18
  108. package/dist/src/list/paginator/up-down.d.ts +0 -14
  109. package/dist/src/main.d.ts +0 -7
  110. package/dist/src/plugins/admin-only-elem.d.ts +0 -2
  111. package/dist/src/plugins/conf-remoter.d.ts +0 -2
  112. package/dist/src/plugins/dark-mode.d.ts +0 -2
  113. package/dist/src/plugins/editor/_kit.d.ts +0 -27
  114. package/dist/src/plugins/editor/_plug.d.ts +0 -29
  115. package/dist/src/plugins/editor/_sample.d.ts +0 -5
  116. package/dist/src/plugins/editor/closable.d.ts +0 -7
  117. package/dist/src/plugins/editor/emoticons.d.ts +0 -30
  118. package/dist/src/plugins/editor/header-event.d.ts +0 -6
  119. package/dist/src/plugins/editor/header-link.d.ts +0 -6
  120. package/dist/src/plugins/editor/header-user.d.ts +0 -16
  121. package/dist/src/plugins/editor/index.d.ts +0 -6
  122. package/dist/src/plugins/editor/local-storage.d.ts +0 -6
  123. package/dist/src/plugins/editor/mover.d.ts +0 -6
  124. package/dist/src/plugins/editor/preview.d.ts +0 -7
  125. package/dist/src/plugins/editor/state-edit.d.ts +0 -11
  126. package/dist/src/plugins/editor/state-reply.d.ts +0 -8
  127. package/dist/src/plugins/editor/submit-add.d.ts +0 -18
  128. package/dist/src/plugins/editor/submit-btn.d.ts +0 -5
  129. package/dist/src/plugins/editor/submit.d.ts +0 -17
  130. package/dist/src/plugins/editor/textarea.d.ts +0 -8
  131. package/dist/src/plugins/editor/upload.d.ts +0 -9
  132. package/dist/src/plugins/editor-kit.d.ts +0 -42
  133. package/dist/src/plugins/index.d.ts +0 -2
  134. package/dist/src/plugins/list/copyright.d.ts +0 -2
  135. package/dist/src/plugins/list/count.d.ts +0 -2
  136. package/dist/src/plugins/list/dropdown.d.ts +0 -2
  137. package/dist/src/plugins/list/error-dialog.d.ts +0 -2
  138. package/dist/src/plugins/list/fetch.d.ts +0 -2
  139. package/dist/src/plugins/list/goto-first.d.ts +0 -3
  140. package/dist/src/plugins/list/goto.d.ts +0 -2
  141. package/dist/src/plugins/list/index.d.ts +0 -3
  142. package/dist/src/plugins/list/loading.d.ts +0 -2
  143. package/dist/src/plugins/list/no-comment.d.ts +0 -2
  144. package/dist/src/plugins/list/reach-bottom.d.ts +0 -2
  145. package/dist/src/plugins/list/sidebar-btn.d.ts +0 -2
  146. package/dist/src/plugins/list/time-ticking.d.ts +0 -3
  147. package/dist/src/plugins/list/unread-badge.d.ts +0 -2
  148. package/dist/src/plugins/list/unread.d.ts +0 -2
  149. package/dist/src/plugins/list/with-editor.d.ts +0 -2
  150. package/dist/src/plugins/markdown.d.ts +0 -2
  151. package/dist/src/plugins/stat.d.ts +0 -13
  152. package/dist/src/plugins/version-check.d.ts +0 -2
  153. package/dist/src/service.d.ts +0 -42
  154. package/dist/tests/e2e/comment-add.spec.d.ts +0 -1
  155. package/dist/types/config.d.ts +0 -110
  156. package/dist/types/context.d.ts +0 -62
  157. package/dist/types/data.d.ts +0 -194
  158. package/dist/types/editor.d.ts +0 -76
  159. package/dist/types/event.d.ts +0 -39
  160. package/dist/types/global.d.ts +0 -1
  161. package/dist/types/index.d.ts +0 -7
  162. package/dist/types/plugin.d.ts +0 -2
  163. package/dist/types/sidebar.d.ts +0 -3
  164. package/src/api/_base.ts +0 -18
  165. package/src/api/_options.ts +0 -25
  166. package/src/api/_request.ts +0 -104
  167. package/src/api/admin.ts +0 -18
  168. package/src/api/captcha.ts +0 -24
  169. package/src/api/comment.ts +0 -84
  170. package/src/api/index.ts +0 -29
  171. package/src/api/page.ts +0 -83
  172. package/src/api/site.ts +0 -51
  173. package/src/api/system.ts +0 -49
  174. package/src/api/upload.ts +0 -28
  175. package/src/api/user.ts +0 -132
  176. package/src/artalk.ts +0 -115
  177. package/src/comment/actions.ts +0 -83
  178. package/src/comment/comment.html +0 -18
  179. package/src/comment/comment.ts +0 -192
  180. package/src/comment/height-limit.ts +0 -100
  181. package/src/comment/index.ts +0 -3
  182. package/src/comment/render.ts +0 -150
  183. package/src/comment/renders/actions.ts +0 -114
  184. package/src/comment/renders/avatar.ts +0 -22
  185. package/src/comment/renders/content.ts +0 -39
  186. package/src/comment/renders/header.ts +0 -84
  187. package/src/comment/renders/index.ts +0 -19
  188. package/src/comment/renders/pending.ts +0 -12
  189. package/src/comment/renders/reply-at.ts +0 -16
  190. package/src/comment/renders/reply-to.ts +0 -24
  191. package/src/components/action-btn.ts +0 -170
  192. package/src/components/checker/admin.ts +0 -37
  193. package/src/components/checker/captcha-renders.ts +0 -69
  194. package/src/components/checker/captcha.ts +0 -26
  195. package/src/components/checker/index.ts +0 -192
  196. package/src/components/dark-mode.ts +0 -30
  197. package/src/components/dialog.ts +0 -62
  198. package/src/components/error-dialog.ts +0 -35
  199. package/src/components/pagination.ts +0 -153
  200. package/src/components/read-more-btn.ts +0 -92
  201. package/src/config.ts +0 -119
  202. package/src/context.ts +0 -146
  203. package/src/data.ts +0 -110
  204. package/src/defaults.ts +0 -61
  205. package/src/editor/editor.html +0 -18
  206. package/src/editor/editor.ts +0 -114
  207. package/src/editor/state.ts +0 -52
  208. package/src/editor/ui.ts +0 -36
  209. package/src/i18n/en.ts +0 -84
  210. package/src/i18n/external.ts +0 -10
  211. package/src/i18n/index.ts +0 -67
  212. package/src/i18n/jp.ts +0 -86
  213. package/src/i18n/zh-CN.ts +0 -88
  214. package/src/i18n/zh-TW.ts +0 -86
  215. package/src/layer/index.ts +0 -4
  216. package/src/layer/layer-manager.ts +0 -32
  217. package/src/layer/layer.ts +0 -39
  218. package/src/layer/scrollbar-helper.ts +0 -24
  219. package/src/layer/sidebar-layer.html +0 -8
  220. package/src/layer/sidebar-layer.ts +0 -155
  221. package/src/layer/wrap.ts +0 -77
  222. package/src/lib/component.ts +0 -12
  223. package/src/lib/detect.ts +0 -222
  224. package/src/lib/event-manager.ts +0 -47
  225. package/src/lib/highlight.ts +0 -5
  226. package/src/lib/marked-renderer.ts +0 -32
  227. package/src/lib/marked.ts +0 -72
  228. package/src/lib/sanitizer.ts +0 -57
  229. package/src/lib/ui.ts +0 -193
  230. package/src/lib/user.ts +0 -55
  231. package/src/lib/utils.ts +0 -236
  232. package/src/list/comment.ts +0 -20
  233. package/src/list/layout.ts +0 -120
  234. package/src/list/list.html +0 -20
  235. package/src/list/list.ts +0 -79
  236. package/src/list/nest.ts +0 -66
  237. package/src/list/page.ts +0 -97
  238. package/src/list/paginator/index.ts +0 -25
  239. package/src/list/paginator/read-more.ts +0 -67
  240. package/src/list/paginator/up-down.ts +0 -51
  241. package/src/main.ts +0 -14
  242. package/src/plugins/admin-only-elem.ts +0 -40
  243. package/src/plugins/conf-remoter.ts +0 -54
  244. package/src/plugins/dark-mode.ts +0 -12
  245. package/src/plugins/editor/_kit.ts +0 -57
  246. package/src/plugins/editor/_plug.ts +0 -60
  247. package/src/plugins/editor/_sample.ts +0 -8
  248. package/src/plugins/editor/closable.ts +0 -44
  249. package/src/plugins/editor/emoticons.scss +0 -72
  250. package/src/plugins/editor/emoticons.ts +0 -293
  251. package/src/plugins/editor/header-event.ts +0 -35
  252. package/src/plugins/editor/header-link.ts +0 -31
  253. package/src/plugins/editor/header-user.ts +0 -98
  254. package/src/plugins/editor/index.ts +0 -40
  255. package/src/plugins/editor/local-storage.ts +0 -36
  256. package/src/plugins/editor/mover.ts +0 -29
  257. package/src/plugins/editor/preview.scss +0 -7
  258. package/src/plugins/editor/preview.ts +0 -41
  259. package/src/plugins/editor/state-edit.ts +0 -116
  260. package/src/plugins/editor/state-reply.ts +0 -91
  261. package/src/plugins/editor/submit-add.ts +0 -33
  262. package/src/plugins/editor/submit-btn.ts +0 -25
  263. package/src/plugins/editor/submit.ts +0 -73
  264. package/src/plugins/editor/textarea.ts +0 -55
  265. package/src/plugins/editor/upload.ts +0 -145
  266. package/src/plugins/editor-kit.ts +0 -161
  267. package/src/plugins/index.ts +0 -16
  268. package/src/plugins/list/copyright.ts +0 -16
  269. package/src/plugins/list/count.ts +0 -31
  270. package/src/plugins/list/dropdown.ts +0 -95
  271. package/src/plugins/list/error-dialog.ts +0 -22
  272. package/src/plugins/list/fetch.ts +0 -64
  273. package/src/plugins/list/goto-first.ts +0 -23
  274. package/src/plugins/list/goto.ts +0 -72
  275. package/src/plugins/list/index.ts +0 -25
  276. package/src/plugins/list/loading.ts +0 -17
  277. package/src/plugins/list/no-comment.ts +0 -25
  278. package/src/plugins/list/reach-bottom.ts +0 -46
  279. package/src/plugins/list/sidebar-btn.ts +0 -39
  280. package/src/plugins/list/time-ticking.ts +0 -22
  281. package/src/plugins/list/unread-badge.ts +0 -26
  282. package/src/plugins/list/unread.ts +0 -38
  283. package/src/plugins/list/with-editor.ts +0 -59
  284. package/src/plugins/markdown.ts +0 -10
  285. package/src/plugins/stat.ts +0 -82
  286. package/src/plugins/version-check.ts +0 -36
  287. package/src/service.ts +0 -91
  288. package/src/style/_color.scss +0 -41
  289. package/src/style/_extend.scss +0 -20
  290. package/src/style/_variables.scss +0 -3
  291. package/src/style/comment.scss +0 -360
  292. package/src/style/editor.scss +0 -194
  293. package/src/style/list.scss +0 -212
  294. package/src/style/main.scss +0 -486
  295. package/src/style/pagination.scss +0 -58
  296. package/src/style/sidebar-layer.scss +0 -92
  297. package/types/config.ts +0 -153
  298. package/types/context.ts +0 -84
  299. package/types/data.ts +0 -271
  300. package/types/editor.ts +0 -95
  301. package/types/event.ts +0 -40
  302. package/types/global.d.ts +0 -1
  303. package/types/index.ts +0 -7
  304. package/types/plugin.ts +0 -3
  305. package/types/sidebar.ts +0 -3
@@ -1,293 +0,0 @@
1
- import './emoticons.scss'
2
-
3
- import type { EmoticonListData, EmoticonGrpData } from '~/types'
4
- import * as Utils from '@/lib/utils'
5
- import * as Ui from '@/lib/ui'
6
- import $t from '@/i18n'
7
- import EditorPlug from './_plug'
8
- import type PlugKit from './_kit'
9
-
10
- type OwOFormatType = {
11
- [key: string] : {
12
- type: 'emoticon'|'emoji'|'image',
13
- container: {icon: string, text: string}[]
14
- }
15
- }
16
-
17
- export default class Emoticons extends EditorPlug {
18
- private emoticons: EmoticonListData = []
19
- private loadingTask: Promise<void>|null = null
20
-
21
- private $grpWrap!: HTMLElement
22
- private $grpSwitcher!: HTMLElement
23
-
24
- constructor(kit: PlugKit) {
25
- super(kit)
26
-
27
- this.kit.useMounted(() => {
28
- this.usePanel(`<div class="atk-editor-plug-emoticons"></div>`)
29
- this.useBtn($t('emoticon'))
30
- })
31
- this.kit.useUnmounted(() => {})
32
-
33
- this.useContentTransformer((raw) => this.transEmoticonImageText(raw))
34
- this.usePanelShow(() => {
35
- ;(async () => {
36
- await this.loadEmoticonsData()
37
-
38
- // 初始化元素
39
- if (!this.isImgLoaded) {
40
- this.initEmoticonsList()
41
- this.isImgLoaded = true
42
- }
43
-
44
- // 延迟执行,防止无法读取高度
45
- setTimeout(() => {
46
- this.changeListHeight()
47
- }, 30)
48
- })()
49
- })
50
- this.usePanelHide(() => {
51
- this.$panel!.parentElement!.style.height = ''
52
- })
53
-
54
- // 表情包预加载
55
- window.setTimeout(() => {
56
- this.loadEmoticonsData()
57
- }, 1000) // 延迟 1s 加载
58
- }
59
-
60
- private isListLoaded = false
61
- private isImgLoaded = false
62
-
63
- public async loadEmoticonsData() {
64
- if (this.isListLoaded) return
65
- if (this.loadingTask !== null) {
66
- await this.loadingTask
67
- return
68
- }
69
-
70
- // 数据处理
71
- this.loadingTask = (async () => {
72
- Ui.showLoading(this.$panel!)
73
- this.emoticons = await this.handleData(this.kit.useConf().emoticons)
74
- Ui.hideLoading(this.$panel!)
75
- this.loadingTask = null
76
- this.isListLoaded = true
77
- })()
78
- await this.loadingTask
79
- }
80
-
81
- private async handleData(data: any): Promise<any[]> {
82
- if (!Array.isArray(data) && ['object', 'string'].includes(typeof data)) {
83
- data = [data]
84
- }
85
-
86
- if (!Array.isArray(data)) {
87
- Ui.setError(this.$panel!, "表情包数据必须为 Array/Object/String 类型")
88
- Ui.hideLoading(this.$panel!)
89
- return []
90
- }
91
-
92
- const pushGrp = (grp: EmoticonGrpData) => {
93
- if (typeof grp !== 'object') return
94
- if (grp.name && data.find(o => o.name === grp.name)) return
95
- data.push(grp)
96
- }
97
-
98
- // 加载子内容
99
- const remoteLoad = async (d: any[]) => {
100
- await Promise.all(d.map(async (grp, index) => {
101
- if (typeof grp === 'object' && !Array.isArray(grp)) {
102
- pushGrp(grp)
103
- } else if (Array.isArray(grp)) {
104
- await remoteLoad(grp)
105
- } else if (typeof grp === "string") {
106
- const grpData = await this.remoteLoad(grp)
107
-
108
- if (Array.isArray(grpData)) await remoteLoad(grpData)
109
- else if (typeof grpData === 'object') pushGrp(grpData)
110
- }
111
- }))
112
- }
113
- await remoteLoad(data)
114
-
115
- // 处理数组数据
116
- data.forEach((item: any) => {
117
- if (this.isOwOFormat(item)) {
118
- const c = this.convertOwO(item)
119
- c.forEach((grp) => { pushGrp(grp) })
120
- } else if (Array.isArray(item)) {
121
- item.forEach((grp) => { pushGrp(grp) })
122
- }
123
- })
124
-
125
- // 剔除非法数据
126
- data = data.filter((item: any) => (typeof item === 'object' && !Array.isArray(item) && !!item && !!item.name))
127
-
128
- // console.log(data)
129
-
130
- this.solveNullKey(data)
131
- this.solveSameKey(data)
132
-
133
- return data
134
- }
135
-
136
- /** 远程加载 */
137
- private async remoteLoad(url: string): Promise<any> {
138
- if (!url) return []
139
-
140
- try {
141
- const resp = await fetch(url)
142
- const json = await resp.json()
143
- return json
144
- } catch (err) {
145
- Ui.hideLoading(this.$panel!)
146
- Ui.setError(this.$panel!, `表情加载失败 ${String(err)}`)
147
- return []
148
- }
149
- }
150
-
151
- /** 避免表情 item.key 为 null 的情况 */
152
- private solveNullKey(data: EmoticonGrpData[]) {
153
- data.forEach((grp) => {
154
- grp.items.forEach((item, index) => {
155
- if (!item.key) item.key = `${grp.name} ${index+1}`
156
- })
157
- })
158
- }
159
-
160
- /** 避免相同 item.key */
161
- private solveSameKey(data: EmoticonGrpData[]) {
162
- const tmp: {[key: string]: number} = {}
163
- data.forEach((grp) => {
164
- grp.items.forEach(item => {
165
- if (!item.key || String(item.key).trim() === "") return
166
- if (!tmp[item.key]) tmp[item.key] = 1
167
- else tmp[item.key]++
168
-
169
- if (tmp[item.key] > 1) item.key = `${item.key} ${tmp[item.key]}`
170
- })
171
- })
172
- }
173
-
174
- /** 判断是否为 OwO 格式 */
175
- private isOwOFormat(data: any) {
176
- try {
177
- return (typeof data === 'object') && !!Object.values(data).length
178
- && Array.isArray(Object.keys(Object.values<any>(data)[0].container))
179
- && Object.keys(Object.values<any>(data)[0].container[0]).includes('icon')
180
- } catch { return false }
181
- }
182
-
183
- /** 转换 OwO 格式数据 */
184
- private convertOwO(owoData: OwOFormatType): EmoticonListData {
185
- const dest: EmoticonListData = []
186
- Object.entries(owoData).forEach(([grpName, grp]) => {
187
- const nGrp: EmoticonGrpData = { name: grpName, type: grp.type, items: [] }
188
- grp.container.forEach((item, index) => {
189
- // 图片标签提取 src 属性值
190
- const iconStr = item.icon
191
- if (/<(img|IMG)/.test(iconStr)) {
192
- const find = /src=["'](.*?)["']/.exec(iconStr)
193
- if (find && find.length > 1) item.icon = find[1]
194
- }
195
- nGrp.items.push({ key: item.text || `${grpName} ${index+1}`, val: item.icon })
196
- })
197
- dest.push(nGrp)
198
- })
199
- return dest
200
- }
201
-
202
- /** 初始化表情列表界面 */
203
- private initEmoticonsList() {
204
- // 表情列表
205
- this.$grpWrap = Utils.createElement(`<div class="atk-grp-wrap"></div>`)
206
- this.$panel!.append(this.$grpWrap)
207
-
208
- this.emoticons.forEach((grp, index) => {
209
- const $grp = Utils.createElement(`<div class="atk-grp" style="display: none;"></div>`)
210
- this.$grpWrap.append($grp)
211
- $grp.setAttribute('data-index', String(index))
212
- $grp.setAttribute('data-grp-name', grp.name)
213
- $grp.setAttribute('data-type', grp.type)
214
- grp.items.forEach((item) => {
215
- const $item = Utils.createElement(`<span class="atk-item"></span>`)
216
- $grp.append($item)
217
-
218
- if (!!item.key && !(new RegExp(`^(${grp.name})?\\s?[0-9]+$`).test(item.key)))
219
- $item.setAttribute('title', item.key)
220
-
221
- if (grp.type === 'image') {
222
- const imgEl = document.createElement('img')
223
- imgEl.src = item.val
224
- imgEl.alt = item.key
225
- $item.append(imgEl)
226
- } else {
227
- $item.innerText = item.val
228
- }
229
-
230
- $item.onclick = () => {
231
- if (grp.type === 'image') {
232
- this.kit.useEditor().insertContent(`:[${item.key}]`)
233
- } else {
234
- this.kit.useEditor().insertContent(item.val || '')
235
- }
236
- }
237
- })
238
- })
239
-
240
- // 表情分类切换 bar
241
- if (this.emoticons.length > 1) {
242
- this.$grpSwitcher = Utils.createElement(`<div class="atk-grp-switcher"></div>`)
243
- this.$panel!.append(this.$grpSwitcher)
244
- this.emoticons.forEach((grp, index) => {
245
- const $item = Utils.createElement('<span />')
246
- $item.innerText = grp.name
247
- $item.setAttribute('data-index', String(index))
248
- $item.onclick = () => (this.openGrp(index))
249
- this.$grpSwitcher.append($item)
250
- })
251
- }
252
-
253
- // 默认打开第一个分类
254
- if (this.emoticons.length > 0) this.openGrp(0)
255
- }
256
-
257
- /** 打开一个表情组 */
258
- public openGrp(index: number) {
259
- Array.from(this.$grpWrap.children).forEach((item) => {
260
- const el = item as HTMLElement
261
- if (el.getAttribute('data-index') !== String(index)) {
262
- el.style.display = 'none'
263
- } else {
264
- el.style.display = ''
265
- }
266
- })
267
-
268
- this.$grpSwitcher?.querySelectorAll('span.active').forEach(item => item.classList.remove('active'))
269
- this.$grpSwitcher?.querySelector(`span[data-index="${index}"]`)?.classList.add('active')
270
-
271
- this.changeListHeight()
272
- }
273
-
274
- private changeListHeight() {
275
- /* const listWrapHeight = Utils.getHeight(this.$grpWrapem)
276
- this.editor.plugWrapEl.style.height = `${listWrapHeight > 150 ? listWrapHeight : 150}px` */
277
- }
278
-
279
- /** 处理评论 content 中的表情内容 */
280
- public transEmoticonImageText(text: string) {
281
- if (!this.emoticons || !Array.isArray(this.emoticons))
282
- return text
283
-
284
- this.emoticons.forEach((grp) => {
285
- if (grp.type !== 'image') return
286
- Object.entries(grp.items).forEach(([index, item]) => {
287
- text = text.split(`:[${item.key}]`).join(`<img src="${item.val}" atk-emoticon="${item.key}">`) // replaceAll(...)
288
- })
289
- })
290
-
291
- return text
292
- }
293
- }
@@ -1,35 +0,0 @@
1
- import EditorPlug from './_plug'
2
- import type PlugKit from './_kit'
3
-
4
- export default class HeaderEvent extends EditorPlug {
5
- private get $inputs() {
6
- return this.kit.useEditor().getHeaderInputEls()
7
- }
8
-
9
- constructor(kit: PlugKit) {
10
- super(kit)
11
-
12
- const inputEventFns: {[name: string]: () => void} = {}
13
- const changeEventFns: {[name: string]: () => void} = {}
14
-
15
- const trigger = (evt: 'header-input'|'header-change', $input: HTMLInputElement, field: string) => () => {
16
- this.kit.useEvents().trigger(evt, { field, $input })
17
- }
18
-
19
- this.kit.useMounted(() => {
20
- // batch bind the events
21
- Object.entries(this.$inputs).forEach(([key, $input]) => {
22
- $input.addEventListener('input', inputEventFns[key] = trigger('header-input', $input, key))
23
- $input.addEventListener('change', changeEventFns[key] = trigger('header-change', $input, key))
24
- })
25
- })
26
-
27
- this.kit.useUnmounted(() => {
28
- // unmount the event
29
- Object.entries(this.$inputs).forEach(([key, $input]) => {
30
- $input.removeEventListener('input', inputEventFns[key])
31
- $input.removeEventListener('change', changeEventFns[key])
32
- })
33
- })
34
- }
35
- }
@@ -1,31 +0,0 @@
1
- import User from '@/lib/user'
2
- import EditorPlug from './_plug'
3
- import type PlugKit from './_kit'
4
-
5
- export default class HeaderLink extends EditorPlug {
6
- constructor(kit: PlugKit) {
7
- super(kit)
8
-
9
- const onLinkChange = ({ field }: { field: string }) => {
10
- if (field === 'link') this.onLinkInputChange()
11
- }
12
-
13
- // bind events
14
- this.kit.useMounted(() => {
15
- this.kit.useEvents().on('header-change', onLinkChange)
16
- })
17
-
18
- this.kit.useUnmounted(() => {
19
- this.kit.useEvents().off('header-change', onLinkChange)
20
- })
21
- }
22
-
23
- private onLinkInputChange() {
24
- // auto and force add protocol prefix for user input link
25
- const link = this.kit.useUI().$link.value.trim()
26
- if (!!link && !/^(http|https):\/\//.test(link)) {
27
- this.kit.useUI().$link.value = `https://${link}`
28
- User.update({ link: this.kit.useUI().$link.value })
29
- }
30
- }
31
- }
@@ -1,98 +0,0 @@
1
- import User from '@/lib/user'
2
- import $t from '@/i18n'
3
- import EditorPlug from './_plug'
4
- import type PlugKit from './_kit'
5
-
6
- export default class HeaderUser extends EditorPlug {
7
- constructor(kit: PlugKit) {
8
- super(kit)
9
-
10
- const onInput = ({ $input, field }: { $input: HTMLInputElement, field: string }) => {
11
- if (this.kit.useEditor().getState() === 'edit')
12
- return // TODO prevent execute when editing, since update comment.user not support
13
-
14
- // update user data
15
- User.update({ [field]: $input.value.trim() })
16
-
17
- // remote fetch user info
18
- if (field === 'nick' || field === 'email')
19
- this.fetchUserInfo() // must after update user data, since fetchUserInfo() will use User.data
20
- }
21
-
22
- this.kit.useMounted(() => {
23
- Object.entries(this.kit.useEditor().getHeaderInputEls())
24
- .forEach(([key, $input]) => {
25
- // set placeholder
26
- $input.placeholder = `${$t(key as any)}`
27
-
28
- // sync header values from User.data
29
- $input.value = User.data[key] || ''
30
- })
31
-
32
- // bind events
33
- this.kit.useEvents().on('header-input', onInput)
34
- })
35
-
36
- this.kit.useUnmounted(() => {
37
- this.kit.useEvents().off('header-input', onInput)
38
- })
39
- }
40
-
41
- private query = {
42
- timer: <number|null>null,
43
- abortFn: <(() => void)|null>null
44
- }
45
-
46
- /**
47
- * Fetch user info from server
48
- */
49
- private fetchUserInfo() {
50
- User.logout() // clear login status
51
-
52
- if (this.query.timer) window.clearTimeout(this.query.timer) // clear the not executed timeout task
53
- if (this.query.abortFn) this.query.abortFn() // abort the last request (if request is pending not finished)
54
-
55
- this.query.timer = window.setTimeout(() => {
56
- this.query.timer = null // clear the timer (clarify the timer is executing)
57
-
58
- const {req, abort} = this.kit.useApi().user.userGet(
59
- User.data.nick, User.data.email
60
- )
61
- this.query.abortFn = abort
62
- req.then(data => this.onUserInfoFetched(data))
63
- .catch((err) => {})
64
- .finally(() => {
65
- this.query.abortFn = null // clear the abort function (clarify the request is finished)
66
- })
67
- }, 400) // delay to reduce request
68
- }
69
-
70
- /**
71
- * Function called when user info fetched
72
- *
73
- * @param data The response data from server
74
- */
75
- private onUserInfoFetched(
76
- data: any // TODO fix type
77
- ) {
78
- // If api response is not login, logout
79
- if (!data.is_login) User.logout()
80
-
81
- // Update unread notifies
82
- this.kit.useGlobalCtx().getData().updateUnreads(data.unread)
83
-
84
- // If user is admin and not login,
85
- if (User.checkHasBasicUserInfo() && !data.is_login && data.user?.is_admin) {
86
- // then show login window
87
- this.kit.useGlobalCtx().checkAdmin({
88
- onSuccess: () => {}
89
- })
90
- }
91
-
92
- // Auto fill user link from server
93
- if (data.user && data.user.link) {
94
- this.kit.useUI().$link.value = data.user.link
95
- User.update({ link: data.user.link })
96
- }
97
- }
98
- }
@@ -1,40 +0,0 @@
1
- import type { ArtalkConfig } from '~/types'
2
- import type EditorPlug from './_plug'
3
- import LocalStorage from './local-storage'
4
- import Textarea from './textarea'
5
- import SubmitBtn from './submit-btn'
6
- import Submit from './submit'
7
- import StateReply from './state-reply'
8
- import StateEdit from './state-edit'
9
- import Closable from './closable'
10
- import HeaderEvent from './header-event'
11
- import HeaderUser from './header-user'
12
- import HeaderLink from './header-link'
13
- import Mover from './mover'
14
- import Emoticons from './emoticons'
15
- import Upload from './upload'
16
- import Preview from './preview'
17
-
18
- /** The default enabled plugs */
19
- export const ENABLED_PLUGS: (typeof EditorPlug)[] = [
20
- // Core
21
- LocalStorage,
22
- HeaderEvent, HeaderUser, HeaderLink,
23
- Textarea,
24
- Submit, SubmitBtn,
25
- Mover, StateReply, StateEdit,
26
- Closable,
27
-
28
- // Extensions
29
- Emoticons, Upload, Preview
30
- ]
31
-
32
- /** Get the name list of disabled plugs */
33
- export function getDisabledPlugByConf(conf: ArtalkConfig): (typeof EditorPlug)[] {
34
- return [
35
- {k: Upload, v: conf.imgUpload},
36
- {k: Emoticons, v: conf.emoticons},
37
- {k: Preview, v: conf.preview},
38
- {k: Mover, v: conf.editorTravel},
39
- ].filter(n => !n.v).flatMap(n => n.k)
40
- }
@@ -1,36 +0,0 @@
1
- import $t from '@/i18n'
2
- import type PlugKit from './_kit'
3
- import EditorPlug from './_plug'
4
-
5
- const LocalStorageKey = 'ArtalkContent'
6
-
7
- export default class LocalStorage extends EditorPlug {
8
- constructor(kit: PlugKit) {
9
- super(kit)
10
-
11
- const onContentUpdated = () => {
12
- this.save()
13
- }
14
-
15
- this.kit.useMounted(() => {
16
- // load editor content from localStorage when init
17
- const localContent = window.localStorage.getItem(LocalStorageKey) || ''
18
- if (localContent.trim() !== '') {
19
- this.kit.useEditor().showNotify($t('restoredMsg'), 'i')
20
- this.kit.useEditor().setContent(localContent)
21
- }
22
-
23
- // bind event
24
- this.kit.useEvents().on('content-updated', onContentUpdated)
25
- })
26
-
27
- this.kit.useUnmounted(() => {
28
- this.kit.useEvents().off('content-updated', onContentUpdated)
29
- })
30
- }
31
-
32
- // Save editor content to localStorage
33
- public save() {
34
- window.localStorage.setItem(LocalStorageKey, this.kit.useEditor().getContentRaw().trim())
35
- }
36
- }
@@ -1,29 +0,0 @@
1
- import * as Utils from '@/lib/utils'
2
- import EditorPlug from './_plug'
3
-
4
- export default class Mover extends EditorPlug {
5
- private isMoved = false
6
-
7
- move(afterEl: HTMLElement) {
8
- if (this.isMoved) return
9
- this.isMoved = true
10
-
11
- const editorEl = this.kit.useUI().$el
12
-
13
- editorEl.after(Utils.createElement('<div class="atk-editor-travel-placeholder"></div>'))
14
-
15
- const $travelPlace = Utils.createElement('<div></div>')
16
- afterEl.after($travelPlace)
17
- $travelPlace.replaceWith(editorEl)
18
-
19
- editorEl.classList.add('atk-fade-in') // 添加渐入动画
20
- editorEl.classList.add('editor-traveling')
21
- }
22
-
23
- back() {
24
- if (!this.isMoved) return
25
- this.isMoved = false
26
- this.kit.useGlobalCtx().$root.querySelector('.atk-editor-travel-placeholder')?.replaceWith(this.kit.useUI().$el)
27
- this.kit.useUI().$el.classList.remove('editor-traveling')
28
- }
29
- }
@@ -1,7 +0,0 @@
1
- .atk-editor-plug-preview {
2
- overflow-y: scroll;
3
- overflow-x: hidden;
4
- height: 100%;
5
- width: 100%;
6
- padding: 10px calc(10px + 5px);
7
- }
@@ -1,41 +0,0 @@
1
- import './preview.scss'
2
-
3
- import * as marked from '@/lib/marked'
4
- import $t from '@/i18n'
5
- import EditorPlug from './_plug'
6
- import type PlugKit from './_kit'
7
-
8
- export default class Preview extends EditorPlug {
9
- private isPlugPanelShow = false
10
-
11
- constructor(kit: PlugKit) {
12
- super(kit)
13
-
14
- this.kit.useMounted(() => {
15
- this.usePanel(`<div class="atk-editor-plug-preview"></div>`)
16
-
17
- // initialize plug button
18
- let btnText = $t('preview')
19
- if (marked.getInstance()) btnText += ` <i title="Markdown is supported"><svg class="markdown" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path fill-rule="evenodd" d="M14.85 3H1.15C.52 3 0 3.52 0 4.15v7.69C0 12.48.52 13 1.15 13h13.69c.64 0 1.15-.52 1.15-1.15v-7.7C16 3.52 15.48 3 14.85 3zM9 11H7V8L5.5 9.92 4 8v3H2V5h2l1.5 2L7 5h2v6zm2.99.5L9.5 8H11V5h2v3h1.5l-2.51 3.5z"></path></svg></i>`
20
- this.useBtn(btnText)
21
- })
22
- this.kit.useUnmounted(() => {})
23
-
24
- // function to update content
25
- this.kit.useEvents().on('content-updated', (content) => {
26
- this.isPlugPanelShow && this.updateContent()
27
- })
28
-
29
- this.usePanelShow(() => {
30
- this.isPlugPanelShow = true
31
- this.updateContent()
32
- })
33
- this.usePanelHide(() => {
34
- this.isPlugPanelShow = false
35
- })
36
- }
37
-
38
- updateContent() {
39
- this.$panel!.innerHTML = this.kit.useEditor().getContentMarked()
40
- }
41
- }