artalk 2.7.1 → 2.7.2
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.
- package/README.md +1 -1
- package/dist/Artalk.css +1 -1
- package/dist/Artalk.es.js +155 -147
- package/dist/Artalk.es.js.map +1 -1
- package/dist/Artalk.iife.js +1 -1
- package/dist/Artalk.iife.js.map +1 -1
- package/dist/Artalk.js +1 -1
- package/dist/Artalk.js.map +1 -1
- package/dist/ArtalkLite.css +1 -1
- package/dist/ArtalkLite.es.js +155 -147
- package/dist/ArtalkLite.es.js.map +1 -1
- package/dist/ArtalkLite.iife.js +1 -1
- package/dist/ArtalkLite.iife.js.map +1 -1
- package/dist/ArtalkLite.js +1 -1
- package/dist/ArtalkLite.js.map +1 -1
- package/dist/i18n/jp.js +1 -1
- package/dist/i18n/zh-TW.js +1 -1
- package/dist/src/api/_base.d.ts +7 -0
- package/dist/src/api/_options.d.ts +5 -0
- package/dist/src/components/checker/index.d.ts +2 -0
- package/dist/src/i18n/en.d.ts +1 -0
- package/dist/src/i18n/external.d.ts +1 -0
- package/dist/src/i18n/index.d.ts +3 -0
- package/dist/src/i18n/jp.d.ts +1 -0
- package/dist/src/i18n/zh-TW.d.ts +1 -0
- package/dist/src/lib/user.d.ts +8 -6
- package/dist/src/plugins/editor/_kit.d.ts +7 -1
- package/dist/src/service.d.ts +2 -8
- package/dist/types/event.d.ts +1 -1
- package/package.json +43 -17
- package/dist/src/components/dark-mode.d.ts +0 -2
- package/src/api/_base.ts +0 -18
- package/src/api/_options.ts +0 -25
- package/src/api/_request.ts +0 -104
- package/src/api/admin.ts +0 -18
- package/src/api/captcha.ts +0 -24
- package/src/api/comment.ts +0 -84
- package/src/api/index.ts +0 -29
- package/src/api/page.ts +0 -83
- package/src/api/site.ts +0 -51
- package/src/api/system.ts +0 -49
- package/src/api/upload.ts +0 -28
- package/src/api/user.ts +0 -132
- package/src/artalk.ts +0 -115
- package/src/comment/actions.ts +0 -83
- package/src/comment/comment.html +0 -18
- package/src/comment/comment.ts +0 -192
- package/src/comment/height-limit.ts +0 -100
- package/src/comment/index.ts +0 -3
- package/src/comment/render.ts +0 -150
- package/src/comment/renders/actions.ts +0 -114
- package/src/comment/renders/avatar.ts +0 -22
- package/src/comment/renders/content.ts +0 -39
- package/src/comment/renders/header.ts +0 -84
- package/src/comment/renders/index.ts +0 -19
- package/src/comment/renders/pending.ts +0 -12
- package/src/comment/renders/reply-at.ts +0 -16
- package/src/comment/renders/reply-to.ts +0 -24
- package/src/components/action-btn.ts +0 -170
- package/src/components/checker/admin.ts +0 -37
- package/src/components/checker/captcha-renders.ts +0 -69
- package/src/components/checker/captcha.ts +0 -26
- package/src/components/checker/index.ts +0 -192
- package/src/components/dark-mode.ts +0 -30
- package/src/components/dialog.ts +0 -62
- package/src/components/error-dialog.ts +0 -35
- package/src/components/pagination.ts +0 -153
- package/src/components/read-more-btn.ts +0 -92
- package/src/config.ts +0 -119
- package/src/context.ts +0 -146
- package/src/data.ts +0 -110
- package/src/defaults.ts +0 -61
- package/src/editor/editor.html +0 -18
- package/src/editor/editor.ts +0 -114
- package/src/editor/state.ts +0 -52
- package/src/editor/ui.ts +0 -36
- package/src/i18n/en.ts +0 -84
- package/src/i18n/external.ts +0 -10
- package/src/i18n/index.ts +0 -67
- package/src/i18n/jp.ts +0 -86
- package/src/i18n/zh-CN.ts +0 -88
- package/src/i18n/zh-TW.ts +0 -86
- package/src/layer/index.ts +0 -4
- package/src/layer/layer-manager.ts +0 -32
- package/src/layer/layer.ts +0 -39
- package/src/layer/scrollbar-helper.ts +0 -24
- package/src/layer/sidebar-layer.html +0 -8
- package/src/layer/sidebar-layer.ts +0 -155
- package/src/layer/wrap.ts +0 -77
- package/src/lib/component.ts +0 -12
- package/src/lib/detect.ts +0 -222
- package/src/lib/event-manager.ts +0 -47
- package/src/lib/highlight.ts +0 -5
- package/src/lib/marked-renderer.ts +0 -32
- package/src/lib/marked.ts +0 -72
- package/src/lib/sanitizer.ts +0 -57
- package/src/lib/ui.ts +0 -193
- package/src/lib/user.ts +0 -55
- package/src/lib/utils.ts +0 -236
- package/src/list/comment.ts +0 -20
- package/src/list/layout.ts +0 -120
- package/src/list/list.html +0 -20
- package/src/list/list.ts +0 -79
- package/src/list/nest.ts +0 -66
- package/src/list/page.ts +0 -97
- package/src/list/paginator/index.ts +0 -25
- package/src/list/paginator/read-more.ts +0 -67
- package/src/list/paginator/up-down.ts +0 -51
- package/src/main.ts +0 -14
- package/src/plugins/admin-only-elem.ts +0 -40
- package/src/plugins/conf-remoter.ts +0 -54
- package/src/plugins/dark-mode.ts +0 -12
- package/src/plugins/editor/_kit.ts +0 -57
- package/src/plugins/editor/_plug.ts +0 -60
- package/src/plugins/editor/_sample.ts +0 -8
- package/src/plugins/editor/closable.ts +0 -44
- package/src/plugins/editor/emoticons.scss +0 -72
- package/src/plugins/editor/emoticons.ts +0 -293
- package/src/plugins/editor/header-event.ts +0 -35
- package/src/plugins/editor/header-link.ts +0 -31
- package/src/plugins/editor/header-user.ts +0 -98
- package/src/plugins/editor/index.ts +0 -40
- package/src/plugins/editor/local-storage.ts +0 -36
- package/src/plugins/editor/mover.ts +0 -29
- package/src/plugins/editor/preview.scss +0 -7
- package/src/plugins/editor/preview.ts +0 -41
- package/src/plugins/editor/state-edit.ts +0 -116
- package/src/plugins/editor/state-reply.ts +0 -91
- package/src/plugins/editor/submit-add.ts +0 -33
- package/src/plugins/editor/submit-btn.ts +0 -25
- package/src/plugins/editor/submit.ts +0 -73
- package/src/plugins/editor/textarea.ts +0 -55
- package/src/plugins/editor/upload.ts +0 -145
- package/src/plugins/editor-kit.ts +0 -161
- package/src/plugins/index.ts +0 -16
- package/src/plugins/list/copyright.ts +0 -16
- package/src/plugins/list/count.ts +0 -31
- package/src/plugins/list/dropdown.ts +0 -95
- package/src/plugins/list/error-dialog.ts +0 -22
- package/src/plugins/list/fetch.ts +0 -64
- package/src/plugins/list/goto-first.ts +0 -23
- package/src/plugins/list/goto.ts +0 -72
- package/src/plugins/list/index.ts +0 -25
- package/src/plugins/list/loading.ts +0 -17
- package/src/plugins/list/no-comment.ts +0 -25
- package/src/plugins/list/reach-bottom.ts +0 -46
- package/src/plugins/list/sidebar-btn.ts +0 -39
- package/src/plugins/list/time-ticking.ts +0 -22
- package/src/plugins/list/unread-badge.ts +0 -26
- package/src/plugins/list/unread.ts +0 -38
- package/src/plugins/list/with-editor.ts +0 -59
- package/src/plugins/markdown.ts +0 -10
- package/src/plugins/stat.ts +0 -82
- package/src/plugins/version-check.ts +0 -36
- package/src/service.ts +0 -91
- package/src/style/_color.scss +0 -41
- package/src/style/_extend.scss +0 -20
- package/src/style/_variables.scss +0 -3
- package/src/style/comment.scss +0 -360
- package/src/style/editor.scss +0 -194
- package/src/style/list.scss +0 -212
- package/src/style/main.scss +0 -486
- package/src/style/pagination.scss +0 -58
- package/src/style/sidebar-layer.scss +0 -92
- package/types/config.ts +0 -153
- package/types/context.ts +0 -84
- package/types/data.ts +0 -271
- package/types/editor.ts +0 -95
- package/types/event.ts +0 -40
- package/types/global.d.ts +0 -1
- package/types/index.ts +0 -7
- package/types/plugin.ts +0 -3
- package/types/sidebar.ts +0 -3
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
import type { CommentData } from '~/types'
|
|
2
|
-
import $t from '@/i18n'
|
|
3
|
-
import * as Utils from '@/lib/utils'
|
|
4
|
-
import User from '@/lib/user'
|
|
5
|
-
import type PlugKit from './_kit'
|
|
6
|
-
import EditorPlug from './_plug'
|
|
7
|
-
import Submit from './submit'
|
|
8
|
-
|
|
9
|
-
export default class StateEdit extends EditorPlug {
|
|
10
|
-
private comment?: CommentData
|
|
11
|
-
|
|
12
|
-
constructor(kit: PlugKit) {
|
|
13
|
-
super(kit)
|
|
14
|
-
|
|
15
|
-
// add effect when state switch to `edit`
|
|
16
|
-
this.useEditorStateEffect('edit', (comment) => {
|
|
17
|
-
this.edit(comment)
|
|
18
|
-
|
|
19
|
-
return () => {
|
|
20
|
-
this.cancelEdit()
|
|
21
|
-
}
|
|
22
|
-
})
|
|
23
|
-
|
|
24
|
-
// register submit preset
|
|
25
|
-
this.kit.useMounted(() => {
|
|
26
|
-
const submitPlug = this.kit.useDeps(Submit)
|
|
27
|
-
if (!submitPlug) throw Error("SubmitPlug not initialized")
|
|
28
|
-
|
|
29
|
-
submitPlug.registerCustom({
|
|
30
|
-
activeCond: () => !!this.comment, // active this custom submit when edit mode
|
|
31
|
-
req: async () => {
|
|
32
|
-
const saveData = {
|
|
33
|
-
content: this.kit.useEditor().getContentFinal(),
|
|
34
|
-
nick: this.kit.useUI().$nick.value,
|
|
35
|
-
email: this.kit.useUI().$email.value,
|
|
36
|
-
link: this.kit.useUI().$link.value,
|
|
37
|
-
}
|
|
38
|
-
const nComment = await this.kit.useApi().comment.commentEdit({
|
|
39
|
-
...this.comment, ...saveData
|
|
40
|
-
})
|
|
41
|
-
return nComment
|
|
42
|
-
},
|
|
43
|
-
post: (nComment: CommentData) => {
|
|
44
|
-
this.kit.useGlobalCtx().getData().updateComment(nComment)
|
|
45
|
-
}
|
|
46
|
-
})
|
|
47
|
-
})
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
private edit(comment: CommentData) {
|
|
51
|
-
const ui = this.kit.useUI()
|
|
52
|
-
if (!ui.$editCancelBtn) {
|
|
53
|
-
const $btn = Utils.createElement(
|
|
54
|
-
`<div class="atk-send-reply">` +
|
|
55
|
-
`${$t('editCancel')} ` +
|
|
56
|
-
`<span class="atk-cancel">×</span>` +
|
|
57
|
-
`</div>`
|
|
58
|
-
)
|
|
59
|
-
$btn.onclick = () => {
|
|
60
|
-
this.kit.useEditor().resetState()
|
|
61
|
-
}
|
|
62
|
-
ui.$textareaWrap.append($btn)
|
|
63
|
-
ui.$editCancelBtn = $btn
|
|
64
|
-
}
|
|
65
|
-
this.comment = comment
|
|
66
|
-
|
|
67
|
-
ui.$header.style.display = 'none' // TODO support modify header information
|
|
68
|
-
|
|
69
|
-
ui.$nick.value = comment.nick || ''
|
|
70
|
-
ui.$email.value = comment.email || ''
|
|
71
|
-
ui.$link.value = comment.link || ''
|
|
72
|
-
|
|
73
|
-
this.kit.useEditor().setContent(comment.content)
|
|
74
|
-
ui.$textarea.focus()
|
|
75
|
-
|
|
76
|
-
this.updateSubmitBtnText($t('save'))
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
private cancelEdit() {
|
|
80
|
-
if (!this.comment) return
|
|
81
|
-
|
|
82
|
-
const ui = this.kit.useUI()
|
|
83
|
-
|
|
84
|
-
if (ui.$editCancelBtn) {
|
|
85
|
-
ui.$editCancelBtn.remove()
|
|
86
|
-
ui.$editCancelBtn = undefined
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
this.comment = undefined
|
|
90
|
-
|
|
91
|
-
const { nick, email, link } = User.data
|
|
92
|
-
ui.$nick.value = nick
|
|
93
|
-
ui.$email.value = email
|
|
94
|
-
ui.$link.value = link
|
|
95
|
-
|
|
96
|
-
this.kit.useEditor().setContent('')
|
|
97
|
-
this.restoreSubmitBtnText()
|
|
98
|
-
|
|
99
|
-
ui.$header.style.display = '' // TODO support modify header information
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
// -------------------------------------------------------------------
|
|
103
|
-
// Submit Btn Text Modifier
|
|
104
|
-
// -------------------------------------------------------------------
|
|
105
|
-
|
|
106
|
-
private originalSubmitBtnText = 'Send'
|
|
107
|
-
|
|
108
|
-
private updateSubmitBtnText(text: string) {
|
|
109
|
-
this.originalSubmitBtnText = this.kit.useUI().$submitBtn.innerText
|
|
110
|
-
this.kit.useUI().$submitBtn.innerText = text
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
private restoreSubmitBtnText() {
|
|
114
|
-
this.kit.useUI().$submitBtn.innerText = this.originalSubmitBtnText
|
|
115
|
-
}
|
|
116
|
-
}
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
import type { CommentData } from '~/types'
|
|
2
|
-
import * as Utils from '@/lib/utils'
|
|
3
|
-
import * as Ui from '@/lib/ui'
|
|
4
|
-
import $t from '@/i18n'
|
|
5
|
-
import EditorPlug from './_plug'
|
|
6
|
-
import type PlugKit from './_kit'
|
|
7
|
-
import Submit from './submit'
|
|
8
|
-
import SubmitAddPreset from './submit-add'
|
|
9
|
-
|
|
10
|
-
export default class StateReply extends EditorPlug {
|
|
11
|
-
private comment?: CommentData
|
|
12
|
-
|
|
13
|
-
constructor(kit: PlugKit) {
|
|
14
|
-
super(kit)
|
|
15
|
-
|
|
16
|
-
// add effect when state switch to `reply`
|
|
17
|
-
this.useEditorStateEffect('reply', (commentData) => {
|
|
18
|
-
this.setReply(commentData)
|
|
19
|
-
|
|
20
|
-
return () => {
|
|
21
|
-
this.cancelReply()
|
|
22
|
-
}
|
|
23
|
-
})
|
|
24
|
-
|
|
25
|
-
// register submit preset
|
|
26
|
-
this.kit.useEvents().on('mounted', () => {
|
|
27
|
-
const submitPlug = this.kit.useDeps(Submit)
|
|
28
|
-
if (!submitPlug) throw Error("SubmitPlug not initialized")
|
|
29
|
-
|
|
30
|
-
const defaultPreset = new SubmitAddPreset(this.kit)
|
|
31
|
-
|
|
32
|
-
submitPlug.registerCustom({
|
|
33
|
-
activeCond: () => !!this.comment, // active this custom submit when reply mode
|
|
34
|
-
req: async () => {
|
|
35
|
-
if (!this.comment) throw new Error('reply comment cannot be empty')
|
|
36
|
-
|
|
37
|
-
const nComment = await this.kit.useApi().comment.add({
|
|
38
|
-
...defaultPreset.getSubmitAddParams(),
|
|
39
|
-
rid: this.comment.id,
|
|
40
|
-
page_key: this.comment.page_key,
|
|
41
|
-
page_title: undefined,
|
|
42
|
-
site_name: this.comment.site_name
|
|
43
|
-
})
|
|
44
|
-
|
|
45
|
-
return nComment
|
|
46
|
-
},
|
|
47
|
-
post: (nComment: CommentData) => {
|
|
48
|
-
// open another page when reply comment is not the same pageKey
|
|
49
|
-
const conf = this.kit.useConf()
|
|
50
|
-
if (nComment.page_key !== conf.pageKey) {
|
|
51
|
-
window.open(`${nComment.page_url}#atk-comment-${nComment.id}`)
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
defaultPreset.postSubmitAdd(nComment)
|
|
55
|
-
}
|
|
56
|
-
})
|
|
57
|
-
})
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
private setReply(commentData: CommentData) {
|
|
61
|
-
const ui = this.kit.useUI()
|
|
62
|
-
if (!ui.$sendReply) {
|
|
63
|
-
ui.$sendReply = Utils.createElement(
|
|
64
|
-
`<div class="atk-send-reply">` +
|
|
65
|
-
`${$t('reply')} ` +
|
|
66
|
-
`<span class="atk-text"></span><span class="atk-cancel">×</span>` +
|
|
67
|
-
`</div>`
|
|
68
|
-
)
|
|
69
|
-
ui.$sendReply.querySelector<HTMLElement>('.atk-text')!.innerText = `@${commentData.nick}`
|
|
70
|
-
ui.$sendReply.addEventListener('click', () => {
|
|
71
|
-
this.kit.useEditor().resetState()
|
|
72
|
-
})
|
|
73
|
-
ui.$textareaWrap.append(ui.$sendReply)
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
this.comment = commentData
|
|
77
|
-
|
|
78
|
-
ui.$textarea.focus()
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
private cancelReply() {
|
|
82
|
-
if (!this.comment) return
|
|
83
|
-
|
|
84
|
-
const ui = this.kit.useUI()
|
|
85
|
-
if (ui.$sendReply) {
|
|
86
|
-
ui.$sendReply.remove()
|
|
87
|
-
ui.$sendReply = undefined
|
|
88
|
-
}
|
|
89
|
-
this.comment = undefined
|
|
90
|
-
}
|
|
91
|
-
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import type { CommentData } from '~/types'
|
|
2
|
-
import User from '@/lib/user'
|
|
3
|
-
import type PlugKit from './_kit'
|
|
4
|
-
|
|
5
|
-
export default class SubmitAddPreset {
|
|
6
|
-
constructor(private kit: PlugKit) {}
|
|
7
|
-
|
|
8
|
-
async reqAdd() {
|
|
9
|
-
const nComment = await this.kit.useApi().comment.add({
|
|
10
|
-
...this.getSubmitAddParams()
|
|
11
|
-
})
|
|
12
|
-
return nComment
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
getSubmitAddParams() {
|
|
16
|
-
const { nick, email, link } = User.data
|
|
17
|
-
const conf = this.kit.useConf()
|
|
18
|
-
|
|
19
|
-
return {
|
|
20
|
-
content: this.kit.useEditor().getContentFinal(),
|
|
21
|
-
nick, email, link,
|
|
22
|
-
rid: 0,
|
|
23
|
-
page_key: conf.pageKey,
|
|
24
|
-
page_title: conf.pageTitle,
|
|
25
|
-
site_name: conf.site
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
postSubmitAdd(commentNew: CommentData) {
|
|
30
|
-
// insert the new comment to list
|
|
31
|
-
this.kit.useGlobalCtx().getData().insertComment(commentNew)
|
|
32
|
-
}
|
|
33
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import $t from '@/i18n'
|
|
2
|
-
import EditorPlug from './_plug'
|
|
3
|
-
import type PlugKit from './_kit'
|
|
4
|
-
|
|
5
|
-
export default class SubmitBtn extends EditorPlug {
|
|
6
|
-
constructor(kit: PlugKit) {
|
|
7
|
-
super(kit)
|
|
8
|
-
|
|
9
|
-
const onClick = () => {
|
|
10
|
-
this.kit.useEditor().submit()
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
this.kit.useMounted(() => {
|
|
14
|
-
// apply the submit button text from user custom config
|
|
15
|
-
this.kit.useUI().$submitBtn.innerText = this.kit.useConf().sendBtn || $t('send')
|
|
16
|
-
|
|
17
|
-
// bind the event when click the submit button
|
|
18
|
-
this.kit.useUI().$submitBtn.addEventListener('click', onClick)
|
|
19
|
-
})
|
|
20
|
-
|
|
21
|
-
this.kit.useUnmounted(() => {
|
|
22
|
-
this.kit.useUI().$submitBtn.removeEventListener('click', onClick)
|
|
23
|
-
})
|
|
24
|
-
}
|
|
25
|
-
}
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import type { CommentData } from '~/types'
|
|
2
|
-
import $t from '@/i18n'
|
|
3
|
-
import EditorPlug from './_plug'
|
|
4
|
-
import type PlugKit from './_kit'
|
|
5
|
-
import SubmitAddPreset from './submit-add'
|
|
6
|
-
|
|
7
|
-
interface CustomSubmit {
|
|
8
|
-
activeCond: () => void
|
|
9
|
-
pre?: () => void
|
|
10
|
-
req?: () => Promise<CommentData>
|
|
11
|
-
post?: (nComment: CommentData) => void
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export default class Submit extends EditorPlug {
|
|
15
|
-
private customs: CustomSubmit[] = []
|
|
16
|
-
private defaultPreset: SubmitAddPreset
|
|
17
|
-
|
|
18
|
-
constructor(kit: PlugKit) {
|
|
19
|
-
super(kit)
|
|
20
|
-
|
|
21
|
-
this.defaultPreset = new SubmitAddPreset(this.kit)
|
|
22
|
-
|
|
23
|
-
const onEditorSubmit = () => this.do()
|
|
24
|
-
|
|
25
|
-
this.kit.useMounted(() => {
|
|
26
|
-
// invoke `do()` when event `editor-submit` is triggered
|
|
27
|
-
this.kit.useGlobalCtx().on('editor-submit', onEditorSubmit)
|
|
28
|
-
})
|
|
29
|
-
this.kit.useUnmounted(() => {
|
|
30
|
-
this.kit.useGlobalCtx().off('editor-submit', onEditorSubmit)
|
|
31
|
-
})
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
registerCustom(c: CustomSubmit) {
|
|
35
|
-
this.customs.push(c)
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
private async do() {
|
|
39
|
-
if (this.kit.useEditor().getContentFinal().trim() === '') {
|
|
40
|
-
this.kit.useEditor().focus()
|
|
41
|
-
return
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
const custom = this.customs.find(o => o.activeCond())
|
|
45
|
-
|
|
46
|
-
this.kit.useEditor().showLoading()
|
|
47
|
-
|
|
48
|
-
try {
|
|
49
|
-
// pre submit
|
|
50
|
-
if (custom?.pre) custom.pre()
|
|
51
|
-
|
|
52
|
-
let nComment: CommentData
|
|
53
|
-
|
|
54
|
-
// submit request
|
|
55
|
-
if (custom?.req) nComment = await custom.req()
|
|
56
|
-
else nComment = await this.defaultPreset.reqAdd()
|
|
57
|
-
|
|
58
|
-
// post submit
|
|
59
|
-
if (custom?.post) custom.post(nComment)
|
|
60
|
-
else this.defaultPreset.postSubmitAdd(nComment)
|
|
61
|
-
} catch (err: any) {
|
|
62
|
-
// submit error
|
|
63
|
-
console.error(err)
|
|
64
|
-
this.kit.useEditor().showNotify(`${$t('commentFail')},${err.msg || String(err)}`, 'e')
|
|
65
|
-
return
|
|
66
|
-
} finally {
|
|
67
|
-
this.kit.useEditor().hideLoading()
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
this.kit.useEditor().reset() // 复原编辑器
|
|
71
|
-
this.kit.useGlobalCtx().trigger('editor-submitted')
|
|
72
|
-
}
|
|
73
|
-
}
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import $t from '@/i18n'
|
|
2
|
-
import EditorPlug from './_plug'
|
|
3
|
-
import type PlugKit from './_kit'
|
|
4
|
-
|
|
5
|
-
export default class Textarea extends EditorPlug {
|
|
6
|
-
constructor(kit: PlugKit) {
|
|
7
|
-
super(kit)
|
|
8
|
-
|
|
9
|
-
const onKeydown = (e: KeyboardEvent) => this.onKeydown(e)
|
|
10
|
-
const onInput = () => this.onInput()
|
|
11
|
-
|
|
12
|
-
this.kit.useMounted(() => {
|
|
13
|
-
// 占位符
|
|
14
|
-
this.kit.useUI().$textarea.placeholder = this.kit.useConf().placeholder || $t('placeholder')
|
|
15
|
-
|
|
16
|
-
// bind the event
|
|
17
|
-
this.kit.useUI().$textarea.addEventListener('keydown', onKeydown)
|
|
18
|
-
this.kit.useUI().$textarea.addEventListener('input', onInput)
|
|
19
|
-
})
|
|
20
|
-
|
|
21
|
-
this.kit.useUnmounted(() => {
|
|
22
|
-
// unmount the event
|
|
23
|
-
this.kit.useUI().$textarea.removeEventListener('keydown', onKeydown)
|
|
24
|
-
this.kit.useUI().$textarea.removeEventListener('input', onInput)
|
|
25
|
-
})
|
|
26
|
-
|
|
27
|
-
this.kit.useEvents().on('content-updated', () => {
|
|
28
|
-
// delay 80ms to prevent invalid execution
|
|
29
|
-
window.setTimeout(() => {
|
|
30
|
-
this.adaptiveHeightByContent()
|
|
31
|
-
}, 80)
|
|
32
|
-
})
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
// 按下 Tab 输入内容,而不是失去焦距
|
|
36
|
-
private onKeydown(e: KeyboardEvent) {
|
|
37
|
-
const keyCode = e.keyCode || e.which
|
|
38
|
-
|
|
39
|
-
if (keyCode === 9) {
|
|
40
|
-
e.preventDefault()
|
|
41
|
-
this.kit.useEditor().insertContent('\t')
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
private onInput() {
|
|
46
|
-
this.kit.useEvents().trigger('content-updated', this.kit.useEditor().getContentRaw())
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// Resize the textarea height by content
|
|
50
|
-
public adaptiveHeightByContent() {
|
|
51
|
-
const diff = this.kit.useUI().$textarea.offsetHeight - this.kit.useUI().$textarea.clientHeight
|
|
52
|
-
this.kit.useUI().$textarea.style.height = '0px' // it's a magic. 若不加此行,内容减少,高度回不去
|
|
53
|
-
this.kit.useUI().$textarea.style.height = `${this.kit.useUI().$textarea.scrollHeight + diff}px`
|
|
54
|
-
}
|
|
55
|
-
}
|
|
@@ -1,145 +0,0 @@
|
|
|
1
|
-
import * as Utils from '@/lib/utils'
|
|
2
|
-
import User from '@/lib/user'
|
|
3
|
-
import $t from '@/i18n'
|
|
4
|
-
import type PlugKit from './_kit'
|
|
5
|
-
import EditorPlug from './_plug'
|
|
6
|
-
|
|
7
|
-
/** 允许的图片格式 */
|
|
8
|
-
const AllowImgExts = ['png', 'jpg', 'jpeg', 'gif', 'bmp', 'svg', 'webp']
|
|
9
|
-
|
|
10
|
-
export default class Upload extends EditorPlug {
|
|
11
|
-
private $imgUploadInput?: HTMLInputElement
|
|
12
|
-
|
|
13
|
-
constructor(kit: PlugKit) {
|
|
14
|
-
super(kit)
|
|
15
|
-
|
|
16
|
-
this.kit.useMounted(() => this.init())
|
|
17
|
-
|
|
18
|
-
this.initDragImg()
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
private init() {
|
|
22
|
-
this.$imgUploadInput = document.createElement('input')
|
|
23
|
-
this.$imgUploadInput.type = 'file'
|
|
24
|
-
this.$imgUploadInput.style.display = 'none'
|
|
25
|
-
this.$imgUploadInput.accept = AllowImgExts.map(o => `.${o}`).join(',')
|
|
26
|
-
|
|
27
|
-
// TODO Use btn cannot refresh when mounted event is triggered
|
|
28
|
-
const $btn = this.useBtn(`${$t('image')}`)
|
|
29
|
-
$btn.after(this.$imgUploadInput)
|
|
30
|
-
$btn.onclick = () => {
|
|
31
|
-
// 选择图片
|
|
32
|
-
const $input = this.$imgUploadInput!
|
|
33
|
-
$input.onchange = () => {
|
|
34
|
-
(async () => { // 解决阻塞 UI 问题
|
|
35
|
-
if (!$input.files || $input.files.length === 0) return
|
|
36
|
-
const file = $input.files[0]
|
|
37
|
-
this.uploadImg(file)
|
|
38
|
-
})()
|
|
39
|
-
}
|
|
40
|
-
$input.click() // 显示选择图片对话框
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
if (!this.kit.useConf().imgUpload) {
|
|
44
|
-
this.$btn!.setAttribute('atk-only-admin-show', '')
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
private initDragImg() {
|
|
49
|
-
// 统一从 FileList 获取文件并上传图片方法
|
|
50
|
-
const uploadFromFileList = (files?: FileList) => {
|
|
51
|
-
if (!files) return
|
|
52
|
-
|
|
53
|
-
for (let i = 0; i < files.length; i++) {
|
|
54
|
-
const file = files[i]
|
|
55
|
-
this.uploadImg(file)
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// 拖拽图片
|
|
60
|
-
// @link https://developer.mozilla.org/zh-CN/docs/Web/API/HTML_Drag_and_Drop_API/File_drag_and_drop
|
|
61
|
-
// 阻止浏览器的默认释放行为
|
|
62
|
-
const onDragover = (evt: Event) => {
|
|
63
|
-
evt.stopPropagation()
|
|
64
|
-
evt.preventDefault()
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
const onDrop = (evt: DragEvent) => {
|
|
68
|
-
const files = evt.dataTransfer?.files
|
|
69
|
-
if (files?.length) {
|
|
70
|
-
evt.preventDefault()
|
|
71
|
-
uploadFromFileList(files)
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// 粘贴图片
|
|
76
|
-
const onPaste = (evt: ClipboardEvent) => {
|
|
77
|
-
const files = evt.clipboardData?.files
|
|
78
|
-
if (files?.length) {
|
|
79
|
-
evt.preventDefault()
|
|
80
|
-
uploadFromFileList(files)
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
this.kit.useMounted(() => {
|
|
85
|
-
this.kit.useUI().$textarea.addEventListener('dragover', onDragover)
|
|
86
|
-
this.kit.useUI().$textarea.addEventListener('drop', onDrop)
|
|
87
|
-
this.kit.useUI().$textarea.addEventListener('paste', onPaste)
|
|
88
|
-
})
|
|
89
|
-
this.kit.useUnmounted(() => {
|
|
90
|
-
this.kit.useUI().$textarea.removeEventListener('dragover', onDragover)
|
|
91
|
-
this.kit.useUI().$textarea.removeEventListener('drop', onDrop)
|
|
92
|
-
this.kit.useUI().$textarea.removeEventListener('paste', onPaste)
|
|
93
|
-
})
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
async uploadImg(file: File) {
|
|
97
|
-
const fileExt = /[^.]+$/.exec(file.name)
|
|
98
|
-
if (!fileExt || !AllowImgExts.includes(fileExt[0])) return
|
|
99
|
-
|
|
100
|
-
// 未登录提示
|
|
101
|
-
if (!User.checkHasBasicUserInfo()) {
|
|
102
|
-
this.kit.useEditor().showNotify($t('uploadLoginMsg'), 'w')
|
|
103
|
-
return
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
// 插入图片前换一行
|
|
107
|
-
let insertPrefix = '\n'
|
|
108
|
-
if (this.kit.useUI().$textarea.value.trim() === '') insertPrefix = ''
|
|
109
|
-
|
|
110
|
-
// 插入占位加载文字
|
|
111
|
-
const uploadPlaceholderTxt = `${insertPrefix}`
|
|
112
|
-
this.kit.useEditor().insertContent(uploadPlaceholderTxt)
|
|
113
|
-
|
|
114
|
-
// 上传图片
|
|
115
|
-
let resp: any
|
|
116
|
-
try {
|
|
117
|
-
const customUploaderFn = this.kit.useConf().imgUploader
|
|
118
|
-
if (!customUploaderFn) {
|
|
119
|
-
// 使用 Artalk 进行图片上传
|
|
120
|
-
resp = await this.kit.useApi().upload.imgUpload(file)
|
|
121
|
-
} else {
|
|
122
|
-
// 使用自定义的图片上传器
|
|
123
|
-
resp = {img_url: await customUploaderFn(file)}
|
|
124
|
-
}
|
|
125
|
-
} catch (err: any) {
|
|
126
|
-
console.error(err)
|
|
127
|
-
this.kit.useEditor().showNotify(`${$t('uploadFail')},${err.msg}`, 'e')
|
|
128
|
-
}
|
|
129
|
-
if (!!resp && resp.img_url) {
|
|
130
|
-
let imgURL = resp.img_url as string
|
|
131
|
-
|
|
132
|
-
// 若为相对路径,加上 artalk server
|
|
133
|
-
if (!Utils.isValidURL(imgURL)) imgURL = Utils.getURLBasedOnApi({
|
|
134
|
-
base: this.kit.useConf().server,
|
|
135
|
-
path: imgURL,
|
|
136
|
-
})
|
|
137
|
-
|
|
138
|
-
// 上传成功插入图片
|
|
139
|
-
this.kit.useEditor().setContent(this.kit.useUI().$textarea.value.replace(uploadPlaceholderTxt, `${insertPrefix}`))
|
|
140
|
-
} else {
|
|
141
|
-
// 上传失败删除加载文字
|
|
142
|
-
this.kit.useEditor().setContent(this.kit.useUI().$textarea.value.replace(uploadPlaceholderTxt, ''))
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
}
|
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
import type { EditorApi, ArtalkPlugin } from '~/types'
|
|
2
|
-
import EventManager from '@/lib/event-manager'
|
|
3
|
-
import { ENABLED_PLUGS, getDisabledPlugByConf } from './editor'
|
|
4
|
-
import EditorPlug from './editor/_plug'
|
|
5
|
-
import PlugKit from './editor/_kit'
|
|
6
|
-
|
|
7
|
-
export interface EditorEventPayloadMap {
|
|
8
|
-
'mounted': undefined
|
|
9
|
-
'unmounted': undefined
|
|
10
|
-
'header-input': { field: string, $input: HTMLInputElement }
|
|
11
|
-
'header-change': { field: string, $input: HTMLInputElement }
|
|
12
|
-
'content-updated': string
|
|
13
|
-
'panel-show': EditorPlug
|
|
14
|
-
'panel-hide': EditorPlug
|
|
15
|
-
'panel-close': undefined
|
|
16
|
-
|
|
17
|
-
'editor-close': undefined
|
|
18
|
-
'editor-open': undefined
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export const EditorKit: ArtalkPlugin = (ctx) => {
|
|
22
|
-
const editor = ctx.get('editor')
|
|
23
|
-
|
|
24
|
-
const editorPlugs = new PlugManager(editor)
|
|
25
|
-
ctx.inject('editorPlugs', editorPlugs)
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export class PlugManager {
|
|
29
|
-
private plugs: EditorPlug[] = []
|
|
30
|
-
private openedPlug: EditorPlug|null = null
|
|
31
|
-
private events = new EventManager<EditorEventPayloadMap>()
|
|
32
|
-
|
|
33
|
-
getPlugs() { return this.plugs }
|
|
34
|
-
getEvents() { return this.events }
|
|
35
|
-
|
|
36
|
-
private clear() {
|
|
37
|
-
this.plugs = []
|
|
38
|
-
this.events = new EventManager()
|
|
39
|
-
if (this.openedPlug) this.closePlugPanel()
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
constructor(
|
|
43
|
-
public editor: EditorApi
|
|
44
|
-
) {
|
|
45
|
-
let confLoaded = false // config not loaded at first time
|
|
46
|
-
this.editor.ctx.on('conf-loaded', () => {
|
|
47
|
-
// trigger unmount event will call all plugs' unmount function
|
|
48
|
-
// (this will only be called while conf reloaded, not be called at first time)
|
|
49
|
-
confLoaded && this.getEvents().trigger('unmounted')
|
|
50
|
-
|
|
51
|
-
// reset the plugs
|
|
52
|
-
this.clear()
|
|
53
|
-
|
|
54
|
-
// init the all enabled plugs
|
|
55
|
-
const DISABLED = getDisabledPlugByConf(this.editor.ctx.conf)
|
|
56
|
-
|
|
57
|
-
ENABLED_PLUGS
|
|
58
|
-
.filter(p => !DISABLED.includes(p)) // 禁用的插件
|
|
59
|
-
.forEach((Plug) => {
|
|
60
|
-
// create the plug instance
|
|
61
|
-
const kit = new PlugKit(this)
|
|
62
|
-
this.plugs.push(new Plug(kit))
|
|
63
|
-
})
|
|
64
|
-
|
|
65
|
-
// trigger event for plug initialization
|
|
66
|
-
this.getEvents().trigger('mounted')
|
|
67
|
-
confLoaded = true
|
|
68
|
-
|
|
69
|
-
// refresh the plug UI
|
|
70
|
-
this.loadPluginUI()
|
|
71
|
-
})
|
|
72
|
-
|
|
73
|
-
this.events.on('panel-close', () => this.closePlugPanel())
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
private loadPluginUI() {
|
|
77
|
-
// handle ui, clear and reset the plug btns and plug panels
|
|
78
|
-
this.editor.getUI().$plugPanelWrap.innerHTML = ''
|
|
79
|
-
this.editor.getUI().$plugPanelWrap.style.display = 'none'
|
|
80
|
-
this.editor.getUI().$plugBtnWrap.innerHTML = ''
|
|
81
|
-
|
|
82
|
-
// load the plug UI
|
|
83
|
-
this.plugs.forEach((plug) => this.loadPluginItem(plug))
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/** Load the plug btn and plug panel on editor ui */
|
|
87
|
-
private loadPluginItem(plug: EditorPlug) {
|
|
88
|
-
const $btn = plug.$btn
|
|
89
|
-
if (!$btn) return
|
|
90
|
-
this.editor.getUI().$plugBtnWrap.appendChild($btn)
|
|
91
|
-
|
|
92
|
-
// bind the event when click plug btn
|
|
93
|
-
!$btn.onclick && ($btn.onclick = () => {
|
|
94
|
-
// removing the active class from all the buttons
|
|
95
|
-
this.editor.getUI().$plugBtnWrap
|
|
96
|
-
.querySelectorAll('.active')
|
|
97
|
-
.forEach(item => item.classList.remove('active'))
|
|
98
|
-
|
|
99
|
-
// if the plug is not the same as the openedPlug,
|
|
100
|
-
if (plug !== this.openedPlug) {
|
|
101
|
-
// then open the plug current clicked plug panel
|
|
102
|
-
this.openPlugPanel(plug)
|
|
103
|
-
|
|
104
|
-
// add active class for current plug panel
|
|
105
|
-
$btn.classList.add('active')
|
|
106
|
-
} else {
|
|
107
|
-
// then close the plug
|
|
108
|
-
this.closePlugPanel()
|
|
109
|
-
}
|
|
110
|
-
})
|
|
111
|
-
|
|
112
|
-
// initialization of plug panel
|
|
113
|
-
const $panel = plug.$panel
|
|
114
|
-
if ($panel) {
|
|
115
|
-
$panel.style.display = 'none'
|
|
116
|
-
this.editor.getUI().$plugPanelWrap.appendChild($panel)
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
get<T extends typeof EditorPlug>(plug: T) {
|
|
121
|
-
return this.plugs.find(p => p instanceof plug) as InstanceType<T> | undefined;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
/** Open the editor plug panel */
|
|
125
|
-
openPlugPanel(plug: EditorPlug) {
|
|
126
|
-
this.plugs.forEach((aPlug) => {
|
|
127
|
-
const plugPanel = aPlug.$panel
|
|
128
|
-
if (!plugPanel) return
|
|
129
|
-
|
|
130
|
-
if (aPlug === plug) {
|
|
131
|
-
plugPanel.style.display = ''
|
|
132
|
-
this.events.trigger('panel-show', plug)
|
|
133
|
-
} else {
|
|
134
|
-
plugPanel.style.display = 'none'
|
|
135
|
-
this.events.trigger('panel-hide', plug)
|
|
136
|
-
}
|
|
137
|
-
})
|
|
138
|
-
|
|
139
|
-
this.editor.getUI().$plugPanelWrap.style.display = ''
|
|
140
|
-
this.openedPlug = plug
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
/** Close the editor plug panel */
|
|
144
|
-
closePlugPanel() {
|
|
145
|
-
if (!this.openedPlug) return
|
|
146
|
-
|
|
147
|
-
this.editor.getUI().$plugPanelWrap.style.display = 'none'
|
|
148
|
-
this.events.trigger('panel-hide', this.openedPlug)
|
|
149
|
-
this.openedPlug = null
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
/** Get the content which is transformed by plugs */
|
|
153
|
-
getTransformedContent(rawContent: string) {
|
|
154
|
-
let result = rawContent
|
|
155
|
-
this.plugs.forEach((aPlug) => {
|
|
156
|
-
if (!aPlug.contentTransformer) return
|
|
157
|
-
result = aPlug.contentTransformer(result)
|
|
158
|
-
})
|
|
159
|
-
return result
|
|
160
|
-
}
|
|
161
|
-
}
|