artalk 2.6.4 → 2.7.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 (300) hide show
  1. package/dist/Artalk.css +1 -1
  2. package/dist/Artalk.es.js +7794 -7483
  3. package/dist/Artalk.iife.js +1 -1
  4. package/dist/Artalk.js +1 -1
  5. package/dist/ArtalkLite.css +1 -1
  6. package/dist/ArtalkLite.es.js +5587 -5276
  7. package/dist/ArtalkLite.iife.js +1 -1
  8. package/dist/ArtalkLite.js +1 -1
  9. package/dist/src/api/{api-base.d.ts → _base.d.ts} +3 -7
  10. package/dist/src/api/_options.d.ts +19 -0
  11. package/dist/src/api/{request.d.ts → _request.d.ts} +3 -3
  12. package/dist/src/api/admin.d.ts +1 -1
  13. package/dist/src/api/captcha.d.ts +1 -1
  14. package/dist/src/api/comment.d.ts +2 -2
  15. package/dist/src/api/index.d.ts +2 -4
  16. package/dist/src/api/page.d.ts +3 -3
  17. package/dist/src/api/site.d.ts +2 -2
  18. package/dist/src/api/system.d.ts +13 -3
  19. package/dist/src/api/upload.d.ts +1 -1
  20. package/dist/src/api/user.d.ts +2 -2
  21. package/dist/src/artalk.d.ts +14 -37
  22. package/dist/src/comment/actions.d.ts +1 -1
  23. package/dist/src/comment/comment.d.ts +3 -4
  24. package/dist/src/comment/render.d.ts +21 -3
  25. package/dist/src/comment/renders/actions.d.ts +2 -2
  26. package/dist/src/comment/renders/avatar.d.ts +2 -2
  27. package/dist/src/comment/renders/content.d.ts +2 -2
  28. package/dist/src/comment/renders/header.d.ts +2 -2
  29. package/dist/src/comment/renders/index.d.ts +2 -2
  30. package/dist/src/comment/renders/pending.d.ts +2 -2
  31. package/dist/src/comment/renders/reply-at.d.ts +2 -2
  32. package/dist/src/comment/renders/reply-to.d.ts +2 -2
  33. package/dist/src/components/action-btn.d.ts +3 -5
  34. package/dist/src/{lib → components}/checker/admin.d.ts +1 -1
  35. package/dist/src/{lib → components}/checker/captcha-renders.d.ts +1 -1
  36. package/dist/src/{lib → components}/checker/captcha.d.ts +1 -1
  37. package/dist/src/{lib → components}/checker/index.d.ts +10 -7
  38. package/dist/src/components/dark-mode.d.ts +2 -0
  39. package/dist/src/components/dialog.d.ts +1 -3
  40. package/dist/src/components/error-dialog.d.ts +8 -0
  41. package/dist/src/components/pagination.d.ts +4 -3
  42. package/dist/src/components/read-more-btn.d.ts +3 -3
  43. package/dist/src/config.d.ts +24 -8
  44. package/dist/src/context.d.ts +16 -35
  45. package/dist/src/data.d.ts +27 -0
  46. package/dist/src/defaults.d.ts +1 -1
  47. package/dist/src/editor/editor.d.ts +14 -61
  48. package/dist/src/editor/state.d.ts +20 -0
  49. package/dist/src/i18n/zh-CN.d.ts +1 -1
  50. package/dist/src/layer/index.d.ts +4 -3
  51. package/dist/src/layer/layer-manager.d.ts +9 -0
  52. package/dist/src/layer/layer.d.ts +8 -28
  53. package/dist/src/layer/scrollbar-helper.d.ts +5 -0
  54. package/dist/src/layer/sidebar-layer.d.ts +6 -6
  55. package/dist/src/layer/wrap.d.ts +13 -0
  56. package/dist/src/lib/component.d.ts +3 -8
  57. package/dist/src/lib/event-manager.d.ts +28 -0
  58. package/dist/src/lib/highlight.d.ts +1 -0
  59. package/dist/src/lib/marked-renderer.d.ts +4 -0
  60. package/dist/src/lib/marked.d.ts +4 -2
  61. package/dist/src/lib/sanitizer.d.ts +1 -0
  62. package/dist/src/lib/ui.d.ts +3 -2
  63. package/dist/src/lib/user.d.ts +8 -5
  64. package/dist/src/lib/utils.d.ts +11 -5
  65. package/dist/src/list/comment.d.ts +3 -0
  66. package/dist/src/list/layout.d.ts +23 -0
  67. package/dist/src/list/list.d.ts +13 -25
  68. package/dist/src/list/{list-nest.d.ts → nest.d.ts} +1 -1
  69. package/dist/src/list/page.d.ts +2 -0
  70. package/dist/src/list/paginator/index.d.ts +22 -7
  71. package/dist/src/list/paginator/read-more.d.ts +18 -0
  72. package/dist/src/list/paginator/up-down.d.ts +14 -0
  73. package/dist/src/main.d.ts +2 -0
  74. package/dist/src/plugins/admin-only-elem.d.ts +2 -0
  75. package/dist/src/plugins/conf-remoter.d.ts +2 -0
  76. package/dist/src/plugins/dark-mode.d.ts +2 -0
  77. package/dist/src/plugins/editor/_kit.d.ts +27 -0
  78. package/dist/src/plugins/editor/_plug.d.ts +29 -0
  79. package/dist/src/plugins/editor/_sample.d.ts +5 -0
  80. package/dist/src/plugins/editor/closable.d.ts +7 -0
  81. package/dist/src/{editor/plugs/emoticons-plug.d.ts → plugins/editor/emoticons.d.ts} +10 -16
  82. package/dist/src/plugins/editor/header-event.d.ts +6 -0
  83. package/dist/src/plugins/editor/header-link.d.ts +6 -0
  84. package/dist/src/plugins/editor/header-user.d.ts +16 -0
  85. package/dist/src/plugins/editor/index.d.ts +6 -0
  86. package/dist/src/plugins/editor/local-storage.d.ts +6 -0
  87. package/dist/src/plugins/editor/mover.d.ts +6 -0
  88. package/dist/src/plugins/editor/preview.d.ts +7 -0
  89. package/dist/src/plugins/editor/state-edit.d.ts +11 -0
  90. package/dist/src/plugins/editor/state-reply.d.ts +8 -0
  91. package/dist/src/plugins/editor/submit-add.d.ts +18 -0
  92. package/dist/src/plugins/editor/submit-btn.d.ts +5 -0
  93. package/dist/src/plugins/editor/submit.d.ts +17 -0
  94. package/dist/src/plugins/editor/textarea.d.ts +8 -0
  95. package/dist/src/plugins/editor/upload.d.ts +9 -0
  96. package/dist/src/plugins/editor-kit.d.ts +42 -0
  97. package/dist/src/plugins/index.d.ts +2 -0
  98. package/dist/src/plugins/list/copyright.d.ts +2 -0
  99. package/dist/src/plugins/list/count.d.ts +2 -0
  100. package/dist/src/plugins/list/dropdown.d.ts +2 -0
  101. package/dist/src/plugins/list/error-dialog.d.ts +2 -0
  102. package/dist/src/plugins/list/fetch.d.ts +2 -0
  103. package/dist/src/plugins/list/goto-first.d.ts +3 -0
  104. package/dist/src/plugins/list/goto.d.ts +2 -0
  105. package/dist/src/plugins/list/index.d.ts +3 -0
  106. package/dist/src/plugins/list/loading.d.ts +2 -0
  107. package/dist/src/plugins/list/no-comment.d.ts +2 -0
  108. package/dist/src/plugins/list/reach-bottom.d.ts +2 -0
  109. package/dist/src/plugins/list/sidebar-btn.d.ts +2 -0
  110. package/dist/src/plugins/list/time-ticking.d.ts +3 -0
  111. package/dist/src/plugins/list/unread-badge.d.ts +2 -0
  112. package/dist/src/plugins/list/unread.d.ts +2 -0
  113. package/dist/src/plugins/list/with-editor.d.ts +2 -0
  114. package/dist/src/plugins/markdown.d.ts +2 -0
  115. package/dist/src/plugins/stat.d.ts +13 -0
  116. package/dist/src/plugins/version-check.d.ts +2 -0
  117. package/dist/src/service.d.ts +19 -23
  118. package/dist/tests/e2e/comment-add.spec.d.ts +1 -0
  119. package/dist/types/config.d.ts +110 -0
  120. package/dist/types/context.d.ts +56 -136
  121. package/dist/types/data.d.ts +194 -0
  122. package/dist/types/editor.d.ts +76 -0
  123. package/dist/types/event.d.ts +36 -25
  124. package/dist/types/index.d.ts +7 -0
  125. package/dist/types/plugin.d.ts +2 -0
  126. package/dist/types/sidebar.d.ts +3 -0
  127. package/package.json +5 -2
  128. package/src/api/_base.ts +18 -0
  129. package/src/api/_options.ts +25 -0
  130. package/src/api/{request.ts → _request.ts} +19 -18
  131. package/src/api/admin.ts +1 -1
  132. package/src/api/captcha.ts +1 -1
  133. package/src/api/comment.ts +4 -4
  134. package/src/api/index.ts +3 -12
  135. package/src/api/page.ts +5 -5
  136. package/src/api/site.ts +2 -2
  137. package/src/api/system.ts +19 -7
  138. package/src/api/upload.ts +3 -3
  139. package/src/api/user.ts +3 -3
  140. package/src/artalk.ts +49 -97
  141. package/src/comment/actions.ts +1 -4
  142. package/src/comment/comment.ts +9 -6
  143. package/src/comment/render.ts +27 -5
  144. package/src/comment/renders/actions.ts +45 -45
  145. package/src/comment/renders/avatar.ts +7 -7
  146. package/src/comment/renders/content.ts +18 -18
  147. package/src/comment/renders/header.ts +13 -13
  148. package/src/comment/renders/index.ts +3 -3
  149. package/src/comment/renders/pending.ts +5 -5
  150. package/src/comment/renders/reply-at.ts +8 -8
  151. package/src/comment/renders/reply-to.ts +13 -13
  152. package/src/components/action-btn.ts +11 -13
  153. package/src/{lib → components}/checker/admin.ts +6 -6
  154. package/src/{lib → components}/checker/captcha-renders.ts +7 -6
  155. package/src/{lib → components}/checker/captcha.ts +1 -1
  156. package/src/{lib → components}/checker/index.ts +21 -26
  157. package/src/components/dark-mode.ts +30 -0
  158. package/src/components/dialog.ts +4 -9
  159. package/src/components/error-dialog.ts +35 -0
  160. package/src/components/pagination.ts +10 -6
  161. package/src/components/read-more-btn.ts +7 -7
  162. package/src/config.ts +60 -6
  163. package/src/context.ts +39 -144
  164. package/src/data.ts +110 -0
  165. package/src/defaults.ts +1 -1
  166. package/src/editor/editor.ts +39 -152
  167. package/src/editor/state.ts +52 -0
  168. package/src/i18n/zh-CN.ts +1 -1
  169. package/src/layer/index.ts +4 -4
  170. package/src/layer/layer-manager.ts +32 -0
  171. package/src/layer/layer.ts +20 -144
  172. package/src/layer/scrollbar-helper.ts +24 -0
  173. package/src/layer/sidebar-layer.ts +74 -64
  174. package/src/layer/wrap.ts +77 -0
  175. package/src/lib/component.ts +4 -11
  176. package/src/lib/detect.ts +1 -1
  177. package/src/lib/event-manager.ts +47 -0
  178. package/src/lib/highlight.ts +5 -0
  179. package/src/lib/marked-renderer.ts +32 -0
  180. package/src/lib/marked.ts +43 -104
  181. package/src/lib/sanitizer.ts +57 -0
  182. package/src/lib/ui.ts +22 -15
  183. package/src/lib/user.ts +21 -16
  184. package/src/lib/utils.ts +29 -18
  185. package/src/list/comment.ts +20 -0
  186. package/src/list/layout.ts +120 -0
  187. package/src/list/list.html +3 -1
  188. package/src/list/list.ts +56 -200
  189. package/src/list/{list-nest.ts → nest.ts} +1 -1
  190. package/src/list/page.ts +97 -0
  191. package/src/list/paginator/index.ts +20 -8
  192. package/src/list/paginator/read-more.ts +67 -0
  193. package/src/list/paginator/up-down.ts +51 -0
  194. package/src/main.ts +2 -0
  195. package/src/plugins/admin-only-elem.ts +40 -0
  196. package/src/plugins/conf-remoter.ts +54 -0
  197. package/src/plugins/dark-mode.ts +12 -0
  198. package/src/plugins/editor/_kit.ts +57 -0
  199. package/src/plugins/editor/_plug.ts +60 -0
  200. package/src/plugins/editor/_sample.ts +8 -0
  201. package/src/plugins/editor/closable.ts +44 -0
  202. package/src/{editor/plugs/emoticons-plug.ts → plugins/editor/emoticons.ts} +51 -52
  203. package/src/plugins/editor/header-event.ts +35 -0
  204. package/src/plugins/editor/header-link.ts +31 -0
  205. package/src/plugins/editor/header-user.ts +98 -0
  206. package/src/plugins/editor/index.ts +40 -0
  207. package/src/plugins/editor/local-storage.ts +36 -0
  208. package/src/plugins/editor/mover.ts +29 -0
  209. package/src/plugins/editor/preview.ts +41 -0
  210. package/src/plugins/editor/state-edit.ts +116 -0
  211. package/src/plugins/editor/state-reply.ts +91 -0
  212. package/src/plugins/editor/submit-add.ts +33 -0
  213. package/src/plugins/editor/submit-btn.ts +25 -0
  214. package/src/plugins/editor/submit.ts +73 -0
  215. package/src/plugins/editor/textarea.ts +55 -0
  216. package/src/plugins/editor/upload.ts +145 -0
  217. package/src/plugins/editor-kit.ts +161 -0
  218. package/src/plugins/index.ts +16 -0
  219. package/src/plugins/list/copyright.ts +16 -0
  220. package/src/plugins/list/count.ts +31 -0
  221. package/src/plugins/list/dropdown.ts +95 -0
  222. package/src/plugins/list/error-dialog.ts +22 -0
  223. package/src/plugins/list/fetch.ts +64 -0
  224. package/src/plugins/list/goto-first.ts +23 -0
  225. package/src/plugins/list/goto.ts +72 -0
  226. package/src/plugins/list/index.ts +25 -0
  227. package/src/plugins/list/loading.ts +17 -0
  228. package/src/plugins/list/no-comment.ts +25 -0
  229. package/src/plugins/list/reach-bottom.ts +46 -0
  230. package/src/plugins/list/sidebar-btn.ts +39 -0
  231. package/src/plugins/list/time-ticking.ts +22 -0
  232. package/src/plugins/list/unread-badge.ts +26 -0
  233. package/src/plugins/list/unread.ts +38 -0
  234. package/src/plugins/list/with-editor.ts +59 -0
  235. package/src/plugins/markdown.ts +10 -0
  236. package/src/plugins/stat.ts +79 -0
  237. package/src/plugins/version-check.ts +37 -0
  238. package/src/service.ts +34 -61
  239. package/src/style/comment.scss +5 -7
  240. package/src/style/editor.scss +5 -0
  241. package/src/style/list.scss +1 -1
  242. package/types/{artalk-config.d.ts → config.ts} +16 -2
  243. package/types/context.ts +84 -0
  244. package/types/{artalk-data.d.ts → data.ts} +41 -0
  245. package/types/editor.ts +95 -0
  246. package/types/event.ts +40 -0
  247. package/types/index.ts +7 -0
  248. package/types/plugin.ts +3 -0
  249. package/types/sidebar.ts +3 -0
  250. package/dist/src/comment/render-ctx.d.ts +0 -23
  251. package/dist/src/editor/edit-mode.d.ts +0 -9
  252. package/dist/src/editor/funcs.d.ts +0 -2
  253. package/dist/src/editor/index.d.ts +0 -2
  254. package/dist/src/editor/mover.d.ts +0 -8
  255. package/dist/src/editor/plug-manager.d.ts +0 -17
  256. package/dist/src/editor/plugs/editor-plug.d.ts +0 -38
  257. package/dist/src/editor/plugs/header-input-plug.d.ts +0 -13
  258. package/dist/src/editor/plugs/preview-plug.d.ts +0 -10
  259. package/dist/src/editor/plugs/upload-plug.d.ts +0 -10
  260. package/dist/src/editor/reply.d.ts +0 -9
  261. package/dist/src/editor/submit.d.ts +0 -16
  262. package/dist/src/lib/dark-mode.d.ts +0 -4
  263. package/dist/src/lib/stat.d.ts +0 -15
  264. package/dist/src/list/index.d.ts +0 -2
  265. package/dist/src/list/list-lite.d.ts +0 -77
  266. package/dist/src/list/list-ui.d.ts +0 -16
  267. package/dist/src/list/paginator/adaptors/index.d.ts +0 -12
  268. package/dist/src/list/paginator/adaptors/pagination.d.ts +0 -9
  269. package/dist/src/list/paginator/adaptors/read-more.d.ts +0 -10
  270. package/dist/src/list/paginator/holder.d.ts +0 -16
  271. package/dist/types/artalk-config.d.ts +0 -139
  272. package/dist/types/artalk-data.d.ts +0 -230
  273. package/dist/types/plug.d.ts +0 -4
  274. package/src/api/api-base.ts +0 -27
  275. package/src/comment/render-ctx.ts +0 -30
  276. package/src/editor/edit-mode.ts +0 -105
  277. package/src/editor/funcs.ts +0 -150
  278. package/src/editor/index.ts +0 -3
  279. package/src/editor/mover.ts +0 -43
  280. package/src/editor/plug-manager.ts +0 -172
  281. package/src/editor/plugs/editor-plug.ts +0 -69
  282. package/src/editor/plugs/header-input-plug.ts +0 -79
  283. package/src/editor/plugs/preview-plug.ts +0 -44
  284. package/src/editor/plugs/upload-plug.ts +0 -122
  285. package/src/editor/reply.ts +0 -62
  286. package/src/editor/submit.ts +0 -99
  287. package/src/lib/dark-mode.ts +0 -48
  288. package/src/lib/stat.ts +0 -71
  289. package/src/list/index.ts +0 -3
  290. package/src/list/list-lite.ts +0 -424
  291. package/src/list/list-ui.ts +0 -137
  292. package/src/list/paginator/adaptors/index.ts +0 -21
  293. package/src/list/paginator/adaptors/pagination.ts +0 -42
  294. package/src/list/paginator/adaptors/read-more.ts +0 -56
  295. package/src/list/paginator/holder.ts +0 -56
  296. package/types/context.d.ts +0 -142
  297. package/types/event.d.ts +0 -28
  298. package/types/plug.d.ts +0 -4
  299. /package/src/{editor/plugs/emoticons-plug.scss → plugins/editor/emoticons.scss} +0 -0
  300. /package/src/{editor/plugs/preview-plug.scss → plugins/editor/preview.scss} +0 -0
@@ -1,105 +0,0 @@
1
- import type { CommentData } from '~/types/artalk-data'
2
- import * as Utils from '../lib/utils'
3
- import Editor from './editor'
4
- import User from '../lib/user'
5
-
6
- export interface EditModeManager {
7
- editor: Editor
8
- comment?: CommentData
9
- setEdit: (comment: CommentData, $comment: HTMLElement) => void
10
- cancelEdit: () => void
11
- }
12
-
13
- export function createEditModeManager(editor: Editor) {
14
- const m: EditModeManager = {
15
- editor,
16
- comment: undefined,
17
- setEdit: (c, e) => edit(m, c, e),
18
- cancelEdit: () => cancelEdit(m)
19
- }
20
-
21
- initEditModeSubmit(m)
22
-
23
- return m
24
- }
25
-
26
- function edit(m: EditModeManager, comment: CommentData, $comment: HTMLElement) {
27
- cancelEdit(m)
28
- m.editor.cancelReply()
29
-
30
- const ui = m.editor.getUI()
31
- if (!ui.$editCancelBtn) {
32
- const $btn = Utils.createElement(
33
- `<div class="atk-send-reply">` +
34
- `${m.editor.$t('editCancel')} ` +
35
- `<span class="atk-cancel">×</span>` +
36
- `</div>`
37
- )
38
- $btn.onclick = () => {
39
- cancelEdit(m)
40
- }
41
- ui.$textareaWrap.append($btn)
42
- ui.$editCancelBtn = $btn
43
- }
44
- m.comment = comment
45
-
46
- ui.$header.style.display = 'none' // TODO support modify header information
47
-
48
- m.editor.travel($comment)
49
-
50
- ui.$nick.value = comment.nick || ''
51
- ui.$email.value = comment.email || ''
52
- ui.$link.value = comment.link || ''
53
-
54
- m.editor.setContent(comment.content)
55
- ui.$textarea.focus()
56
-
57
- m.editor.refreshSendBtnText()
58
- }
59
-
60
- function cancelEdit(m: EditModeManager) {
61
- if (!m.comment) return
62
-
63
- const ui = m.editor.getUI()
64
-
65
- if (ui.$editCancelBtn) {
66
- ui.$editCancelBtn.remove()
67
- ui.$editCancelBtn = undefined
68
- }
69
-
70
- m.comment = undefined
71
- m.editor.travelBack()
72
-
73
- const { nick, email, link } = User.data
74
- ui.$nick.value = nick
75
- ui.$email.value = email
76
- ui.$link.value = link
77
-
78
- m.editor.setContent('')
79
- m.editor.refreshSendBtnText()
80
-
81
- ui.$header.style.display = '' // TODO support modify header information
82
- }
83
-
84
- function initEditModeSubmit(m: EditModeManager) {
85
- const submitManger = m.editor.getSubmitManager()
86
- if (!submitManger) throw Error("submitManager not initialized")
87
- submitManger.registerCustom({
88
- activeCond: () => !!m.comment, // active this custom submit when edit mode
89
- req: async () => {
90
- const saveData = {
91
- content: m.editor.getFinalContent(),
92
- nick: m.editor.getUI().$nick.value,
93
- email: m.editor.getUI().$email.value,
94
- link: m.editor.getUI().$link.value,
95
- }
96
- const nComment = await m.editor.ctx.getApi().comment.commentEdit({
97
- ...m.comment, ...saveData
98
- })
99
- return nComment
100
- },
101
- post: (nComment: CommentData) => {
102
- m.editor.ctx.updateComment(nComment)
103
- }
104
- })
105
- }
@@ -1,150 +0,0 @@
1
- import Editor from './editor'
2
- import User from '../lib/user'
3
- import { createMover } from './mover'
4
- import { createPlugManager } from './plug-manager'
5
- import { createReplyManager } from './reply'
6
- import { createEditModeManager } from './edit-mode'
7
- import { createSubmitManager } from './submit'
8
-
9
- /** Editor Enabled Functions */
10
- const EditorFuncs = {
11
- localStorage, header, textarea,
12
- submitBtn, submitManager,
13
- mover, reply,
14
- plugs,
15
- }
16
-
17
- export default function initEditorFuncs(editor: Editor) {
18
- // storage the unmount funcs
19
- const unmountFuncs: (() => void)[] = []
20
-
21
- Object.entries(EditorFuncs).forEach(([k, init]) => {
22
- const unmountFunc = init(editor)
23
- if (unmountFunc) unmountFuncs.push(unmountFunc)
24
- })
25
-
26
- return unmountFuncs
27
- }
28
-
29
- // ================== Editor Functions ======================
30
-
31
- function localStorage(editor: Editor) {
32
- // load editor content from localStorage when init
33
- const localContent = window.localStorage.getItem('ArtalkContent') || ''
34
- if (localContent.trim() !== '') {
35
- editor.showNotify(editor.$t('restoredMsg'), 'i')
36
- editor.setContent(localContent)
37
- }
38
-
39
- // save editor content to localStorage when input
40
- const onEditorInput = () => {
41
- editor.saveToLocalStorage()
42
- }
43
-
44
- // bind the event
45
- editor.getUI().$textarea.addEventListener('input', onEditorInput)
46
-
47
- return () => {
48
- // unmount the event
49
- editor.getUI().$textarea.removeEventListener('input', onEditorInput)
50
- }
51
- }
52
-
53
- function header(editor: Editor) {
54
- const $inputs = editor.getHeaderInputEls()
55
- const inputFuncs: {[name: string]: () => void} = {}
56
-
57
- // the input event
58
- const onInput = ($input: HTMLInputElement, key: string) => () => {
59
- if (editor.isEditMode) return // 评论编辑模式,不修改个人信息
60
-
61
- User.update({ [key]: $input.value.trim() })
62
- editor.getPlugs()?.triggerHeaderInputEvt(key, $input)
63
- }
64
-
65
- // set placeholder and sync header input value
66
- Object.entries($inputs).forEach(([key, $input]) => {
67
- $input.placeholder = `${editor.$t(key as any)}`
68
- $input.value = User.data[key] || ''
69
- })
70
-
71
- // bind the event
72
- Object.entries($inputs).forEach(([key, $input]) => {
73
- $input.addEventListener('input', inputFuncs[key] = onInput($input, key))
74
- })
75
-
76
- return () => {
77
- // unmount the event
78
- Object.entries($inputs).forEach(([key, $input]) => {
79
- $input.removeEventListener('input', inputFuncs[key])
80
- })
81
- }
82
- }
83
-
84
- function textarea(editor: Editor) {
85
- // 占位符
86
- editor.getUI().$textarea.placeholder = editor.ctx.conf.placeholder || editor.$t('placeholder')
87
-
88
- // 按下 Tab 输入内容,而不是失去焦距
89
- const onKeydown = (e: KeyboardEvent) => {
90
- const keyCode = e.keyCode || e.which
91
-
92
- if (keyCode === 9) {
93
- e.preventDefault()
94
- editor.insertContent('\t')
95
- }
96
- }
97
-
98
- // 输入框高度随内容而变化
99
- const onInput = () => {
100
- editor.adjustTextareaHeight()
101
- }
102
-
103
- // bind the event
104
- editor.getUI().$textarea.addEventListener('keydown', onKeydown)
105
- editor.getUI().$textarea.addEventListener('input', onInput)
106
-
107
- return () => {
108
- // unmount the event
109
- editor.getUI().$textarea.removeEventListener('keydown', onKeydown)
110
- editor.getUI().$textarea.removeEventListener('input', onInput)
111
- }
112
- }
113
-
114
- function submitBtn(editor: Editor) {
115
- editor.refreshSendBtnText()
116
-
117
- const onClick = () => {
118
- editor.submit()
119
- }
120
-
121
- editor.getUI().$submitBtn.addEventListener('click', onClick)
122
-
123
- return () => {
124
- editor.getUI().$submitBtn.removeEventListener('click', onClick)
125
- }
126
- }
127
-
128
- function submitManager(editor: Editor) {
129
- editor.setSubmitManager(createSubmitManager(editor))
130
-
131
- // Note:
132
- // the EditModeManger depends on the submitManager,
133
- // so must init the submitManager first.
134
- // createEditModeManager will make a side-effect on submitManager (call `submitManger.registerCustom`)
135
- // side-effect is not a good practice, to be improved.
136
- editor.setEditModeManager(createEditModeManager(editor))
137
- }
138
-
139
- function mover(editor: Editor) {
140
- if (!editor.conf.editorTravel) return
141
- editor.setMover(createMover(editor))
142
- }
143
-
144
- function reply(editor: Editor) {
145
- editor.setReplyManager(createReplyManager(editor))
146
- }
147
-
148
- function plugs(editor: Editor) {
149
- editor.setPlugs(createPlugManager(editor))
150
- }
@@ -1,3 +0,0 @@
1
- import Editor from './editor'
2
-
3
- export default Editor
@@ -1,43 +0,0 @@
1
- import Editor from './editor'
2
- import * as Utils from '../lib/utils'
3
-
4
- export interface Mover {
5
- editor: Editor
6
- isMoved: boolean
7
- move(afterEl: HTMLElement): void
8
- back(): void
9
- }
10
-
11
- export function createMover(editor: Editor): Mover {
12
- const m: Mover = {
13
- editor,
14
- isMoved: false,
15
- move: (el) => move(m, el),
16
- back: () => back(m)
17
- }
18
-
19
- return m
20
- }
21
-
22
- function move(m: Mover, afterEl: HTMLElement) {
23
- if (m.isMoved) return
24
- m.isMoved = true
25
-
26
- const editorEl = m.editor.getUI().$el
27
-
28
- editorEl.after(Utils.createElement('<div class="atk-editor-travel-placeholder"></div>'))
29
-
30
- const $travelPlace = Utils.createElement('<div></div>')
31
- afterEl.after($travelPlace)
32
- $travelPlace.replaceWith(editorEl)
33
-
34
- editorEl.classList.add('atk-fade-in') // 添加渐入动画
35
- }
36
-
37
- function back(m: Mover) {
38
- if (!m.isMoved) return
39
- m.isMoved = false
40
- m.editor.ctx.$root.querySelector('.atk-editor-travel-placeholder')?.replaceWith(m.editor.getUI().$el)
41
-
42
- m.editor.cancelReply() // 取消回复
43
- }
@@ -1,172 +0,0 @@
1
- import type ArtalkConfig from '~/types/artalk-config'
2
- import EmoticonsPlug from './plugs/emoticons-plug'
3
- import UploadPlug from './plugs/upload-plug'
4
- import PreviewPlug from './plugs/preview-plug'
5
- import HeaderInputPlug from './plugs/header-input-plug'
6
- import EditorPlug from './plugs/editor-plug'
7
- import Editor from './editor'
8
-
9
- /** The default enabled plugs */
10
- const ENABLED_PLUGS = [ EmoticonsPlug, UploadPlug, PreviewPlug, HeaderInputPlug ]
11
-
12
- /** Context of an editor plug manager */
13
- export interface PlugManager {
14
- editor: Editor
15
- plugList: { [name: string]: EditorPlug }
16
- openedPlugName: string|null
17
-
18
- openPlugPanel(plugName: string): void
19
- closePlugPanel(): void
20
-
21
- triggerHeaderInputEvt(field: string, $input: HTMLInputElement): void
22
- triggerContentUpdatedEvt(content: string): void
23
- getTransformedContent(raw: string): string
24
- }
25
-
26
- /** Create an editor plug manager */
27
- export function createPlugManager(editor: Editor): PlugManager {
28
- const ctx: PlugManager = {
29
- editor,
30
- plugList: {},
31
- openedPlugName: null,
32
- openPlugPanel: (p: string) => openPlugPanel(ctx, p),
33
- closePlugPanel: () => closePlugPanel(ctx),
34
-
35
- triggerHeaderInputEvt: (f, $) => triggerHeaderInputEvt(ctx, f, $),
36
- triggerContentUpdatedEvt: (c) => triggerContentUpdatedEvt(ctx, c),
37
- getTransformedContent: (r) => getTransformedContent(ctx, r),
38
- }
39
-
40
- // handle ui, clear and reset the plug btns and plug panels
41
- editor.getUI().$plugPanelWrap.innerHTML = ''
42
- editor.getUI().$plugPanelWrap.style.display = 'none'
43
- editor.getUI().$plugBtnWrap.innerHTML = ''
44
-
45
- // init the all enabled plugs
46
- const DISABLED = getDisabledPlugNames(editor.conf)
47
-
48
- ENABLED_PLUGS
49
- .filter(p => !DISABLED.includes(p.Name)) // 禁用的插件
50
- .forEach((Plug) => {
51
- initPlugItem(ctx, Plug)
52
- })
53
-
54
- return ctx
55
- }
56
-
57
- /** Get the name list of disabled plugs */
58
- function getDisabledPlugNames(conf: ArtalkConfig) {
59
- return [
60
- {k: 'upload', v: conf.imgUpload},
61
- {k: 'emoticons', v: conf.emoticons},
62
- {k: 'preview', v: conf.preview}
63
- ].filter(n => !n.v).flatMap(n => n.k)
64
- }
65
-
66
- /** Initialization of a plug item */
67
- function initPlugItem(ctx: PlugManager, Plug: typeof ENABLED_PLUGS[number]) {
68
- const plugName = Plug.Name
69
-
70
- // create the plug instance
71
- const plug = new Plug(ctx.editor)
72
- ctx.plugList[plugName] = plug
73
-
74
- // gen plug ui
75
- genPlugBtn(ctx, plugName, plug)
76
- }
77
-
78
- /** Gen the plug btn (and plug panel) on editor ui */
79
- function genPlugBtn(ctx: PlugManager, plugName: string, plug: EditorPlug) {
80
- const $btn = plug.getBtn()
81
- if (!$btn) return
82
- ctx.editor.getUI().$plugBtnWrap.appendChild($btn)
83
- $btn.onclick = $btn.onclick || (() => {
84
- // the event when click plug btn
85
-
86
- // removing the active class from all the buttons
87
- ctx.editor.getUI().$plugBtnWrap
88
- .querySelectorAll('.active')
89
- .forEach(item => item.classList.remove('active'))
90
-
91
-
92
- // if the plugName is the same as the openedPlugName, then close the plugPanel
93
- if (plugName === ctx.openedPlugName) {
94
- closePlugPanel(ctx)
95
- return
96
- }
97
-
98
- // open the plug current clicked plug panel
99
- openPlugPanel(ctx, plugName)
100
-
101
- // add active class for current plug panel
102
- $btn.classList.add('active')
103
- })
104
-
105
- // initialization of plug panel
106
- const $panel = plug.getPanel()
107
- if ($panel) {
108
- $panel.setAttribute('data-plug-name', plugName)
109
- $panel.style.display = 'none'
110
- ctx.editor.getUI().$plugPanelWrap.appendChild($panel)
111
- }
112
- }
113
-
114
- /** Open the editor plug panel */
115
- function openPlugPanel(ctx: PlugManager, plugName: string) {
116
- Object.entries(ctx.plugList).forEach(([aPlugName, plug]) => {
117
- const plugPanel = plug.getPanel()
118
- if (!plugPanel) return
119
-
120
- if (aPlugName === plugName) {
121
- plugPanel.style.display = ''
122
- if (plug.onPanelShow) plug.onPanelShow()
123
- } else {
124
- plugPanel.style.display = 'none'
125
- if (plug.onPanelHide) plug.onPanelHide()
126
- }
127
- })
128
-
129
- ctx.editor.getUI().$plugPanelWrap.style.display = ''
130
- ctx.openedPlugName = plugName
131
- }
132
-
133
- /** Close the editor plug panel */
134
- function closePlugPanel(ctx: PlugManager) {
135
- if (!ctx.openedPlugName) return
136
-
137
- const plug = ctx.plugList[ctx.openedPlugName]
138
- if (!plug) return
139
-
140
- if (plug.onPanelHide) plug.onPanelHide()
141
-
142
- ctx.editor.getUI().$plugPanelWrap.style.display = 'none'
143
- ctx.openedPlugName = null
144
- }
145
-
146
- // ============== Events ====================
147
-
148
- /** Trigger event when editor header input changed */
149
- function triggerHeaderInputEvt(ctx: PlugManager, field: string, $input: HTMLInputElement) {
150
- Object.entries(ctx.plugList).forEach(([plugName, plug]) => {
151
- if (!plug.onHeaderInput) return
152
- plug.onHeaderInput(field, $input)
153
- })
154
- }
155
-
156
- /** Trigger event when editor content updated */
157
- function triggerContentUpdatedEvt(ctx: PlugManager, content: string) {
158
- Object.entries(ctx.plugList).forEach(([plugName, plug]) => {
159
- if (!plug.onContentUpdated) return
160
- plug.onContentUpdated(content)
161
- })
162
- }
163
-
164
- /** Get the content which is transformed by plugs */
165
- function getTransformedContent(ctx: PlugManager, rawContent: string) {
166
- let result = rawContent
167
- Object.entries(ctx.plugList).forEach(([plugName, plug]) => {
168
- if (!plug.contentTransformer) return
169
- result = plug.contentTransformer(result)
170
- })
171
- return result
172
- }
@@ -1,69 +0,0 @@
1
- import * as Utils from '@/lib/utils'
2
- import Editor from '../editor'
3
-
4
- /**
5
- * Editor 插件
6
- *
7
- * @desc 使用 Interface x Abstract 合并声明
8
- * @see https://www.typescriptlang.org/docs/handbook/declaration-merging.html#merging-interfaces
9
- */
10
- interface EditorPlug {
11
- onPanelShow?(): void
12
- onPanelHide?(): void
13
- }
14
-
15
- abstract class EditorPlug {
16
- protected editor: Editor
17
- protected get ctx() { return this.editor.ctx }
18
- protected $panel?: HTMLElement
19
- protected $btn?: HTMLElement
20
- public onHeaderInput?: (key: string, $input: HTMLElement) => void
21
- public contentTransformer?: (rawContent: string) => string
22
- public onContentUpdated?: (content: string) => void
23
-
24
- public constructor(editor: Editor) {
25
- this.editor = editor
26
- }
27
-
28
- /** Name of plug */
29
- public static Name: string
30
-
31
- /** Register plug panel will provide a plug el */
32
- protected registerPanel(html: string = '<div></div>') {
33
- this.$panel = Utils.createElement(html)
34
- return this.$panel
35
- }
36
-
37
- /** Register plug btn will add a btn on the bottom of editor */
38
- protected registerBtn(html: string) {
39
- this.$btn = Utils.createElement(`<span class="atk-plug-btn" data-plug-name="${this.constructor.name}">${html}</span>`)
40
- return this.$btn
41
- }
42
-
43
- /** Register the event of header input is changed */
44
- protected registerHeaderInputEvt(func: (key: string, $input: HTMLElement) => void) {
45
- this.onHeaderInput = func
46
- }
47
-
48
- /** Register the content transformer to handle the content of the last submit by the editor */
49
- protected registerContentTransformer(func: (raw: string) => string) {
50
- this.contentTransformer = func
51
- }
52
-
53
- /** Register the event of editor content is updated */
54
- protected registerContentUpdatedEvt(func: (content: string) => void) {
55
- this.onContentUpdated = func
56
- }
57
-
58
- /** Get panel element of plug */
59
- public getPanel() {
60
- return this.$panel
61
- }
62
-
63
- /** Get btn element of plug */
64
- public getBtn() {
65
- return this.$btn
66
- }
67
- }
68
-
69
- export default EditorPlug
@@ -1,79 +0,0 @@
1
- import Editor from '../editor'
2
- import User from '../../lib/user'
3
- import EditorPlug from './editor-plug'
4
-
5
- export default class HeaderInputPlug extends EditorPlug {
6
- public static Name = 'headerInput'
7
-
8
- public constructor(editor: Editor) {
9
- super(editor)
10
-
11
- this.registerHeaderInputEvt((key, $input) => {
12
- if (key === 'nick' || key === 'email') {
13
- this.fetchUserInfo()
14
- }
15
- })
16
-
17
- // Link URL 自动补全协议
18
- this.editor.getUI().$link.addEventListener('change', () => {
19
- const link = this.editor.getUI().$link.value.trim()
20
- if (!!link && !/^(http|https):\/\//.test(link)) {
21
- this.editor.getUI().$link.value = `https://${link}`
22
- User.update({ link: this.editor.getUI().$link.value })
23
- }
24
- })
25
- }
26
-
27
- queryUserInfo = {
28
- timeout: <number|null>null,
29
- abortFunc: <(() => void)|null>null
30
- }
31
-
32
- /** 远程获取用户数据 */
33
- fetchUserInfo() {
34
- User.logout()
35
-
36
- // 获取用户信息
37
- if (this.queryUserInfo.timeout) window.clearTimeout(this.queryUserInfo.timeout) // 清除待发出的请求
38
- if (this.queryUserInfo.abortFunc) this.queryUserInfo.abortFunc() // 之前发出未完成的请求立刻中止
39
-
40
- this.queryUserInfo.timeout = window.setTimeout(() => {
41
- this.queryUserInfo.timeout = null // 清理
42
-
43
- const {req, abort} = this.ctx.getApi().user.userGet(
44
- User.data.nick, User.data.email
45
- )
46
- this.queryUserInfo.abortFunc = abort
47
- req.then(data => {
48
- if (!data.is_login) {
49
- User.logout()
50
- }
51
-
52
- // 未读消息更新
53
- this.ctx.updateNotifies(data.unread)
54
-
55
- // 若用户为管理员,执行登陆操作
56
- if (User.checkHasBasicUserInfo() && !data.is_login && data.user?.is_admin) {
57
- this.showLoginDialog()
58
- }
59
-
60
- // 自动填入 link
61
- if (data.user && data.user.link) {
62
- this.editor.getUI().$link.value = data.user.link
63
- User.update({ link: data.user.link })
64
- }
65
- })
66
- .catch(() => {})
67
- .finally(() => {
68
- this.queryUserInfo.abortFunc = null // 清理
69
- })
70
- }, 400) // 延迟执行,减少请求次数
71
- }
72
-
73
- showLoginDialog() {
74
- this.ctx.checkAdmin({
75
- onSuccess: () => {
76
- }
77
- })
78
- }
79
- }
@@ -1,44 +0,0 @@
1
- import './preview-plug.scss'
2
-
3
- import Editor from '../editor'
4
- import EditorPlug from './editor-plug'
5
-
6
- export default class PreviewPlug extends EditorPlug {
7
- public static Name = 'preview'
8
- declare protected $panel: HTMLElement
9
-
10
- private isBind = false
11
-
12
- public constructor(editor: Editor) {
13
- super(editor)
14
-
15
- this.registerPanel(`<div class="atk-editor-plug-preview"></div>`)
16
-
17
- let btnText = this.editor.$t('preview')
18
- if (this.ctx.getMarkedInstance()) 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>`
19
- this.registerBtn(btnText)
20
-
21
- this.registerContentUpdatedEvt((content) => {
22
- this.updateContent()
23
- })
24
- }
25
-
26
- public onPanelShow() {
27
- this.updateContent()
28
-
29
- if (!this.isBind) {
30
- const event = () => {
31
- this.updateContent()
32
- }
33
- this.editor.getUI().$textarea.addEventListener('input', event)
34
- this.editor.getUI().$textarea.addEventListener('change', event)
35
- this.isBind = true
36
- }
37
- }
38
-
39
- public updateContent() {
40
- if (this.$panel.style.display !== 'none') {
41
- this.$panel.innerHTML = this.editor.getContentMarked()
42
- }
43
- }
44
- }