artalk 2.6.3 → 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.
- package/dist/Artalk.css +1 -1
- package/dist/Artalk.es.js +7673 -7330
- package/dist/Artalk.iife.js +1 -1
- package/dist/Artalk.js +1 -1
- package/dist/ArtalkLite.css +1 -1
- package/dist/ArtalkLite.es.js +5304 -4961
- package/dist/ArtalkLite.iife.js +1 -1
- package/dist/ArtalkLite.js +1 -1
- package/dist/src/api/{api-base.d.ts → _base.d.ts} +3 -7
- package/dist/src/api/_options.d.ts +19 -0
- package/dist/src/api/{request.d.ts → _request.d.ts} +3 -3
- package/dist/src/api/admin.d.ts +1 -1
- package/dist/src/api/captcha.d.ts +1 -1
- package/dist/src/api/comment.d.ts +2 -2
- package/dist/src/api/index.d.ts +2 -4
- package/dist/src/api/page.d.ts +3 -3
- package/dist/src/api/site.d.ts +2 -2
- package/dist/src/api/system.d.ts +13 -3
- package/dist/src/api/upload.d.ts +1 -1
- package/dist/src/api/user.d.ts +2 -2
- package/dist/src/artalk.d.ts +14 -37
- package/dist/src/comment/actions.d.ts +1 -1
- package/dist/src/comment/comment.d.ts +3 -4
- package/dist/src/comment/render.d.ts +21 -3
- package/dist/src/comment/renders/actions.d.ts +2 -2
- package/dist/src/comment/renders/avatar.d.ts +2 -2
- package/dist/src/comment/renders/content.d.ts +2 -2
- package/dist/src/comment/renders/header.d.ts +2 -2
- package/dist/src/comment/renders/index.d.ts +2 -2
- package/dist/src/comment/renders/pending.d.ts +2 -2
- package/dist/src/comment/renders/reply-at.d.ts +2 -2
- package/dist/src/comment/renders/reply-to.d.ts +2 -2
- package/dist/src/components/action-btn.d.ts +3 -5
- package/dist/src/{lib → components}/checker/admin.d.ts +1 -1
- package/dist/src/{lib → components}/checker/captcha-renders.d.ts +1 -1
- package/dist/src/{lib → components}/checker/captcha.d.ts +1 -1
- package/dist/src/{lib → components}/checker/index.d.ts +10 -7
- package/dist/src/components/dark-mode.d.ts +2 -0
- package/dist/src/components/dialog.d.ts +1 -3
- package/dist/src/components/error-dialog.d.ts +8 -0
- package/dist/src/components/pagination.d.ts +4 -3
- package/dist/src/components/read-more-btn.d.ts +3 -3
- package/dist/src/config.d.ts +24 -8
- package/dist/src/context.d.ts +16 -35
- package/dist/src/data.d.ts +27 -0
- package/dist/src/defaults.d.ts +1 -1
- package/dist/src/editor/editor.d.ts +14 -59
- package/dist/src/editor/state.d.ts +20 -0
- package/dist/src/i18n/zh-CN.d.ts +1 -1
- package/dist/src/layer/index.d.ts +4 -3
- package/dist/src/layer/layer-manager.d.ts +9 -0
- package/dist/src/layer/layer.d.ts +8 -28
- package/dist/src/layer/scrollbar-helper.d.ts +5 -0
- package/dist/src/layer/sidebar-layer.d.ts +6 -6
- package/dist/src/layer/wrap.d.ts +13 -0
- package/dist/src/lib/component.d.ts +3 -8
- package/dist/src/lib/event-manager.d.ts +28 -0
- package/dist/src/lib/highlight.d.ts +1 -0
- package/dist/src/lib/marked-renderer.d.ts +4 -0
- package/dist/src/lib/marked.d.ts +4 -2
- package/dist/src/lib/sanitizer.d.ts +1 -0
- package/dist/src/lib/ui.d.ts +3 -2
- package/dist/src/lib/user.d.ts +8 -5
- package/dist/src/lib/utils.d.ts +11 -5
- package/dist/src/list/comment.d.ts +3 -0
- package/dist/src/list/layout.d.ts +23 -0
- package/dist/src/list/list.d.ts +13 -25
- package/dist/src/list/{list-nest.d.ts → nest.d.ts} +1 -1
- package/dist/src/list/page.d.ts +2 -0
- package/dist/src/list/paginator/index.d.ts +22 -7
- package/dist/src/list/paginator/read-more.d.ts +18 -0
- package/dist/src/list/paginator/up-down.d.ts +14 -0
- package/dist/src/main.d.ts +2 -0
- package/dist/src/plugins/admin-only-elem.d.ts +2 -0
- package/dist/src/plugins/conf-remoter.d.ts +2 -0
- package/dist/src/plugins/dark-mode.d.ts +2 -0
- package/dist/src/plugins/editor/_kit.d.ts +27 -0
- package/dist/src/plugins/editor/_plug.d.ts +29 -0
- package/dist/src/plugins/editor/_sample.d.ts +5 -0
- package/dist/src/plugins/editor/closable.d.ts +7 -0
- package/dist/src/{editor/plugs/emoticons-plug.d.ts → plugins/editor/emoticons.d.ts} +10 -16
- package/dist/src/plugins/editor/header-event.d.ts +6 -0
- package/dist/src/plugins/editor/header-link.d.ts +6 -0
- package/dist/src/plugins/editor/header-user.d.ts +16 -0
- package/dist/src/plugins/editor/index.d.ts +6 -0
- package/dist/src/plugins/editor/local-storage.d.ts +6 -0
- package/dist/src/plugins/editor/mover.d.ts +6 -0
- package/dist/src/plugins/editor/preview.d.ts +7 -0
- package/dist/src/plugins/editor/state-edit.d.ts +11 -0
- package/dist/src/plugins/editor/state-reply.d.ts +8 -0
- package/dist/src/plugins/editor/submit-add.d.ts +18 -0
- package/dist/src/plugins/editor/submit-btn.d.ts +5 -0
- package/dist/src/plugins/editor/submit.d.ts +17 -0
- package/dist/src/plugins/editor/textarea.d.ts +8 -0
- package/dist/src/plugins/editor/upload.d.ts +9 -0
- package/dist/src/plugins/editor-kit.d.ts +42 -0
- package/dist/src/plugins/index.d.ts +2 -0
- package/dist/src/plugins/list/copyright.d.ts +2 -0
- package/dist/src/plugins/list/count.d.ts +2 -0
- package/dist/src/plugins/list/dropdown.d.ts +2 -0
- package/dist/src/plugins/list/error-dialog.d.ts +2 -0
- package/dist/src/plugins/list/fetch.d.ts +2 -0
- package/dist/src/plugins/list/goto-first.d.ts +3 -0
- package/dist/src/plugins/list/goto.d.ts +2 -0
- package/dist/src/plugins/list/index.d.ts +3 -0
- package/dist/src/plugins/list/loading.d.ts +2 -0
- package/dist/src/plugins/list/no-comment.d.ts +2 -0
- package/dist/src/plugins/list/reach-bottom.d.ts +2 -0
- package/dist/src/plugins/list/sidebar-btn.d.ts +2 -0
- package/dist/src/plugins/list/time-ticking.d.ts +3 -0
- package/dist/src/plugins/list/unread-badge.d.ts +2 -0
- package/dist/src/plugins/list/unread.d.ts +2 -0
- package/dist/src/plugins/list/with-editor.d.ts +2 -0
- package/dist/src/plugins/markdown.d.ts +2 -0
- package/dist/src/plugins/stat.d.ts +13 -0
- package/dist/src/plugins/version-check.d.ts +2 -0
- package/dist/src/service.d.ts +19 -23
- package/dist/tests/e2e/comment-add.spec.d.ts +1 -0
- package/dist/types/config.d.ts +110 -0
- package/dist/types/context.d.ts +56 -136
- package/dist/types/data.d.ts +194 -0
- package/dist/types/editor.d.ts +76 -0
- package/dist/types/event.d.ts +36 -25
- package/dist/types/index.d.ts +7 -0
- package/dist/types/plugin.d.ts +2 -0
- package/dist/types/sidebar.d.ts +3 -0
- package/package.json +5 -2
- package/src/api/_base.ts +18 -0
- package/src/api/_options.ts +25 -0
- package/src/api/{request.ts → _request.ts} +19 -18
- package/src/api/admin.ts +1 -1
- package/src/api/captcha.ts +1 -1
- package/src/api/comment.ts +4 -4
- package/src/api/index.ts +3 -12
- package/src/api/page.ts +5 -5
- package/src/api/site.ts +2 -2
- package/src/api/system.ts +19 -7
- package/src/api/upload.ts +3 -3
- package/src/api/user.ts +3 -3
- package/src/artalk.ts +49 -97
- package/src/comment/actions.ts +1 -4
- package/src/comment/comment.ts +9 -6
- package/src/comment/render.ts +27 -5
- package/src/comment/renders/actions.ts +45 -45
- package/src/comment/renders/avatar.ts +7 -7
- package/src/comment/renders/content.ts +18 -18
- package/src/comment/renders/header.ts +13 -13
- package/src/comment/renders/index.ts +3 -3
- package/src/comment/renders/pending.ts +5 -5
- package/src/comment/renders/reply-at.ts +8 -8
- package/src/comment/renders/reply-to.ts +13 -13
- package/src/components/action-btn.ts +11 -13
- package/src/{lib → components}/checker/admin.ts +6 -6
- package/src/{lib → components}/checker/captcha-renders.ts +7 -6
- package/src/{lib → components}/checker/captcha.ts +1 -1
- package/src/{lib → components}/checker/index.ts +21 -26
- package/src/components/dark-mode.ts +30 -0
- package/src/components/dialog.ts +4 -9
- package/src/components/error-dialog.ts +35 -0
- package/src/components/pagination.ts +10 -6
- package/src/components/read-more-btn.ts +7 -7
- package/src/config.ts +60 -6
- package/src/context.ts +39 -144
- package/src/data.ts +110 -0
- package/src/defaults.ts +1 -1
- package/src/editor/editor.ts +41 -146
- package/src/editor/state.ts +52 -0
- package/src/i18n/zh-CN.ts +1 -1
- package/src/layer/index.ts +4 -4
- package/src/layer/layer-manager.ts +32 -0
- package/src/layer/layer.ts +20 -144
- package/src/layer/scrollbar-helper.ts +24 -0
- package/src/layer/sidebar-layer.ts +74 -64
- package/src/layer/wrap.ts +77 -0
- package/src/lib/component.ts +4 -11
- package/src/lib/detect.ts +1 -1
- package/src/lib/event-manager.ts +47 -0
- package/src/lib/highlight.ts +5 -0
- package/src/lib/marked-renderer.ts +32 -0
- package/src/lib/marked.ts +43 -104
- package/src/lib/sanitizer.ts +57 -0
- package/src/lib/ui.ts +22 -15
- package/src/lib/user.ts +21 -16
- package/src/lib/utils.ts +29 -18
- package/src/list/comment.ts +20 -0
- package/src/list/layout.ts +120 -0
- package/src/list/list.html +3 -1
- package/src/list/list.ts +56 -200
- package/src/list/{list-nest.ts → nest.ts} +1 -1
- package/src/list/page.ts +97 -0
- package/src/list/paginator/index.ts +20 -8
- package/src/list/paginator/read-more.ts +67 -0
- package/src/list/paginator/up-down.ts +51 -0
- package/src/main.ts +2 -0
- package/src/plugins/admin-only-elem.ts +40 -0
- package/src/plugins/conf-remoter.ts +54 -0
- package/src/plugins/dark-mode.ts +12 -0
- package/src/plugins/editor/_kit.ts +57 -0
- package/src/plugins/editor/_plug.ts +60 -0
- package/src/plugins/editor/_sample.ts +8 -0
- package/src/plugins/editor/closable.ts +44 -0
- package/src/{editor/plugs/emoticons-plug.ts → plugins/editor/emoticons.ts} +51 -52
- package/src/plugins/editor/header-event.ts +35 -0
- package/src/plugins/editor/header-link.ts +31 -0
- package/src/plugins/editor/header-user.ts +98 -0
- package/src/plugins/editor/index.ts +40 -0
- package/src/plugins/editor/local-storage.ts +36 -0
- package/src/plugins/editor/mover.ts +29 -0
- package/src/plugins/editor/preview.ts +41 -0
- package/src/plugins/editor/state-edit.ts +116 -0
- package/src/plugins/editor/state-reply.ts +91 -0
- package/src/plugins/editor/submit-add.ts +33 -0
- package/src/plugins/editor/submit-btn.ts +25 -0
- package/src/plugins/editor/submit.ts +73 -0
- package/src/plugins/editor/textarea.ts +55 -0
- package/src/plugins/editor/upload.ts +145 -0
- package/src/plugins/editor-kit.ts +161 -0
- package/src/plugins/index.ts +16 -0
- package/src/plugins/list/copyright.ts +16 -0
- package/src/plugins/list/count.ts +31 -0
- package/src/plugins/list/dropdown.ts +95 -0
- package/src/plugins/list/error-dialog.ts +22 -0
- package/src/plugins/list/fetch.ts +64 -0
- package/src/plugins/list/goto-first.ts +23 -0
- package/src/plugins/list/goto.ts +72 -0
- package/src/plugins/list/index.ts +25 -0
- package/src/plugins/list/loading.ts +17 -0
- package/src/plugins/list/no-comment.ts +25 -0
- package/src/plugins/list/reach-bottom.ts +46 -0
- package/src/plugins/list/sidebar-btn.ts +39 -0
- package/src/plugins/list/time-ticking.ts +22 -0
- package/src/plugins/list/unread-badge.ts +26 -0
- package/src/plugins/list/unread.ts +38 -0
- package/src/plugins/list/with-editor.ts +59 -0
- package/src/plugins/markdown.ts +10 -0
- package/src/plugins/stat.ts +79 -0
- package/src/plugins/version-check.ts +37 -0
- package/src/service.ts +34 -61
- package/src/style/comment.scss +5 -7
- package/src/style/editor.scss +5 -0
- package/src/style/list.scss +2 -7
- package/types/{artalk-config.d.ts → config.ts} +16 -2
- package/types/context.ts +84 -0
- package/{dist/types/artalk-data.d.ts → types/data.ts} +41 -0
- package/types/editor.ts +95 -0
- package/types/event.ts +40 -0
- package/types/index.ts +7 -0
- package/types/plugin.ts +3 -0
- package/types/sidebar.ts +3 -0
- package/dist/src/comment/render-ctx.d.ts +0 -23
- package/dist/src/editor/edit-mode.d.ts +0 -9
- package/dist/src/editor/funcs.d.ts +0 -2
- package/dist/src/editor/index.d.ts +0 -2
- package/dist/src/editor/mover.d.ts +0 -8
- package/dist/src/editor/plug-manager.d.ts +0 -17
- package/dist/src/editor/plugs/editor-plug.d.ts +0 -38
- package/dist/src/editor/plugs/header-input-plug.d.ts +0 -13
- package/dist/src/editor/plugs/preview-plug.d.ts +0 -10
- package/dist/src/editor/plugs/upload-plug.d.ts +0 -10
- package/dist/src/editor/reply.d.ts +0 -9
- package/dist/src/editor/submit.d.ts +0 -16
- package/dist/src/lib/dark-mode.d.ts +0 -4
- package/dist/src/lib/stat.d.ts +0 -15
- package/dist/src/list/index.d.ts +0 -2
- package/dist/src/list/list-lite.d.ts +0 -77
- package/dist/src/list/list-ui.d.ts +0 -16
- package/dist/src/list/paginator/adaptors/index.d.ts +0 -12
- package/dist/src/list/paginator/adaptors/pagination.d.ts +0 -9
- package/dist/src/list/paginator/adaptors/read-more.d.ts +0 -10
- package/dist/src/list/paginator/holder.d.ts +0 -16
- package/dist/types/artalk-config.d.ts +0 -139
- package/dist/types/plug.d.ts +0 -4
- package/src/api/api-base.ts +0 -27
- package/src/comment/render-ctx.ts +0 -30
- package/src/editor/edit-mode.ts +0 -103
- package/src/editor/funcs.ts +0 -97
- package/src/editor/index.ts +0 -3
- package/src/editor/mover.ts +0 -43
- package/src/editor/plug-manager.ts +0 -172
- package/src/editor/plugs/editor-plug.ts +0 -69
- package/src/editor/plugs/header-input-plug.ts +0 -79
- package/src/editor/plugs/preview-plug.ts +0 -44
- package/src/editor/plugs/upload-plug.ts +0 -122
- package/src/editor/reply.ts +0 -62
- package/src/editor/submit.ts +0 -99
- package/src/lib/dark-mode.ts +0 -48
- package/src/lib/stat.ts +0 -71
- package/src/list/index.ts +0 -3
- package/src/list/list-lite.ts +0 -424
- package/src/list/list-ui.ts +0 -137
- package/src/list/paginator/adaptors/index.ts +0 -21
- package/src/list/paginator/adaptors/pagination.ts +0 -42
- package/src/list/paginator/adaptors/read-more.ts +0 -56
- package/src/list/paginator/holder.ts +0 -56
- package/types/artalk-data.d.ts +0 -230
- package/types/context.d.ts +0 -142
- package/types/event.d.ts +0 -28
- package/types/plug.d.ts +0 -4
- /package/src/{editor/plugs/emoticons-plug.scss → plugins/editor/emoticons.scss} +0 -0
- /package/src/{editor/plugs/preview-plug.scss → plugins/editor/preview.scss} +0 -0
package/src/data.ts
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import type { NotifyData, PageData, CommentData, DataManagerApi, ListFetchParams, ListLastFetchData, EventPayloadMap } from '~/types'
|
|
2
|
+
import EventManager from './lib/event-manager'
|
|
3
|
+
|
|
4
|
+
export class DataManager implements DataManagerApi {
|
|
5
|
+
private loading: boolean = false
|
|
6
|
+
private listLastFetch?: ListLastFetchData
|
|
7
|
+
private comments: CommentData[] = [] // Note: 无层级结构 + 无须排列
|
|
8
|
+
private unreads: NotifyData[] = []
|
|
9
|
+
private page?: PageData
|
|
10
|
+
|
|
11
|
+
constructor(
|
|
12
|
+
protected events: EventManager<EventPayloadMap>
|
|
13
|
+
) {}
|
|
14
|
+
|
|
15
|
+
getLoading() {
|
|
16
|
+
return this.loading
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
setLoading(val: boolean) {
|
|
20
|
+
this.loading = val
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
getListLastFetch() {
|
|
24
|
+
return this.listLastFetch
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
setListLastFetch(val: ListLastFetchData) {
|
|
28
|
+
this.listLastFetch = val
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// -------------------------------------------------------------------
|
|
32
|
+
// Comments
|
|
33
|
+
// -------------------------------------------------------------------
|
|
34
|
+
getComments() {
|
|
35
|
+
return this.comments
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
fetchComments(params: Partial<ListFetchParams>) {
|
|
39
|
+
this.events.trigger('list-fetch', params)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
findComment(id: number) {
|
|
43
|
+
return this.comments.find(c => c.id === id)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
clearComments() {
|
|
47
|
+
this.comments = []
|
|
48
|
+
this.events.trigger('list-loaded', this.comments)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
loadComments(partialComments: CommentData[]) {
|
|
52
|
+
this.events.trigger('list-load', partialComments)
|
|
53
|
+
|
|
54
|
+
this.comments.push(...partialComments)
|
|
55
|
+
|
|
56
|
+
this.events.trigger('list-loaded', this.comments)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
insertComment(comment: CommentData) {
|
|
60
|
+
this.comments.push(comment)
|
|
61
|
+
|
|
62
|
+
this.events.trigger('comment-inserted', comment)
|
|
63
|
+
this.events.trigger('list-loaded', this.comments) // list-loaded should always keep the last
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
updateComment(comment: CommentData) {
|
|
67
|
+
this.comments = this.comments.map(c => {
|
|
68
|
+
if (c.id === comment.id) return comment
|
|
69
|
+
return c
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
this.events.trigger('comment-updated', comment)
|
|
73
|
+
this.events.trigger('list-loaded', this.comments)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
deleteComment(id: number) {
|
|
77
|
+
const comment = this.comments.find(c => c.id === id)
|
|
78
|
+
if (!comment) throw new Error(`Comment ${id} not found`)
|
|
79
|
+
this.comments = this.comments.filter(c => c.id !== id)
|
|
80
|
+
|
|
81
|
+
this.events.trigger('comment-deleted', comment)
|
|
82
|
+
this.events.trigger('list-loaded', this.comments)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// -------------------------------------------------------------------
|
|
86
|
+
// Unreads
|
|
87
|
+
// -------------------------------------------------------------------
|
|
88
|
+
getUnreads() {
|
|
89
|
+
return this.unreads
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
updateUnreads(unread: NotifyData[]) {
|
|
93
|
+
this.unreads = unread
|
|
94
|
+
|
|
95
|
+
this.events.trigger('unreads-updated', this.unreads)
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// -------------------------------------------------------------------
|
|
99
|
+
// Page
|
|
100
|
+
// -------------------------------------------------------------------
|
|
101
|
+
getPage() {
|
|
102
|
+
return this.page
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
updatePage(pageData: PageData) {
|
|
106
|
+
this.page = pageData
|
|
107
|
+
|
|
108
|
+
this.events.trigger('page-loaded', pageData)
|
|
109
|
+
}
|
|
110
|
+
}
|
package/src/defaults.ts
CHANGED
package/src/editor/editor.ts
CHANGED
|
@@ -1,106 +1,59 @@
|
|
|
1
|
-
import type { CommentData } from '~/types
|
|
2
|
-
import type Context from '~/types/context'
|
|
1
|
+
import type { CommentData, ContextApi, EditorApi } from '~/types'
|
|
3
2
|
import Component from '../lib/component'
|
|
4
|
-
import * as Utils from '../lib/utils'
|
|
5
3
|
import * as Ui from '../lib/ui'
|
|
6
4
|
import marked from '../lib/marked'
|
|
7
|
-
import User from '../lib/user'
|
|
8
|
-
import initEditorFuncs from './funcs'
|
|
9
5
|
import { render, EditorUI } from './ui'
|
|
10
|
-
import
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
import { EditModeManager } from './edit-mode'
|
|
14
|
-
import { SubmitManager } from './submit'
|
|
15
|
-
|
|
16
|
-
export default class Editor extends Component {
|
|
17
|
-
/** 界面 */
|
|
6
|
+
import EditorStateManager from './state'
|
|
7
|
+
|
|
8
|
+
class Editor extends Component implements EditorApi {
|
|
18
9
|
private ui: EditorUI
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
/** 评论框移动 */
|
|
27
|
-
private mover?: Mover
|
|
28
|
-
public setMover(m: Mover) { this.mover = m }
|
|
29
|
-
|
|
30
|
-
/** 回复评论 */
|
|
31
|
-
private reply?: ReplyManager
|
|
32
|
-
public setReplyManager(m: ReplyManager) { this.reply = m }
|
|
33
|
-
public getReplyManager() { return this.reply }
|
|
34
|
-
public get isReplyMode() { return !!this.reply?.comment }
|
|
35
|
-
|
|
36
|
-
/** 编辑评论 */
|
|
37
|
-
private editMode?: EditModeManager
|
|
38
|
-
public setEditModeManager(m: EditModeManager) { this.editMode = m }
|
|
39
|
-
public get isEditMode() { return !!this.editMode?.comment }
|
|
40
|
-
|
|
41
|
-
/** 提交评论 */
|
|
42
|
-
private submitManager?: SubmitManager
|
|
43
|
-
public setSubmitManager(m: SubmitManager) { this.submitManager = m }
|
|
44
|
-
public getSubmitManager() { return this.submitManager }
|
|
45
|
-
|
|
46
|
-
public constructor(ctx: Context) {
|
|
10
|
+
private state: EditorStateManager
|
|
11
|
+
|
|
12
|
+
getUI() { return this.ui }
|
|
13
|
+
getPlugs() { return this.ctx.get('editorPlugs') }
|
|
14
|
+
getState() { return this.state.get() }
|
|
15
|
+
|
|
16
|
+
constructor(ctx: ContextApi) {
|
|
47
17
|
super(ctx)
|
|
48
18
|
|
|
49
19
|
// init editor ui
|
|
50
20
|
this.ui = render()
|
|
51
21
|
this.$el = this.ui.$el
|
|
52
22
|
|
|
53
|
-
//
|
|
54
|
-
this.
|
|
55
|
-
initEditorFuncs(this) // init editor funcs
|
|
56
|
-
})
|
|
23
|
+
// init state manager
|
|
24
|
+
this.state = new EditorStateManager(this)
|
|
57
25
|
}
|
|
58
26
|
|
|
59
|
-
|
|
27
|
+
getHeaderInputEls() {
|
|
60
28
|
return { nick: this.ui.$nick, email: this.ui.$email, link: this.ui.$link }
|
|
61
29
|
}
|
|
62
30
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
public refreshSendBtnText() {
|
|
68
|
-
if (this.isEditMode) this.ui.$submitBtn.innerText = this.$t('save')
|
|
69
|
-
else this.ui.$submitBtn.innerText = this.ctx.conf.sendBtn || this.$t('send')
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/** 最终用于 submit 的数据 */
|
|
73
|
-
public getFinalContent() {
|
|
74
|
-
let content = this.getContentOriginal()
|
|
31
|
+
getContentFinal() {
|
|
32
|
+
let content = this.getContentRaw()
|
|
75
33
|
|
|
76
34
|
// plug hook: final content transformer
|
|
77
|
-
|
|
35
|
+
const plugs = this.getPlugs()
|
|
36
|
+
if (plugs) content = plugs.getTransformedContent(content)
|
|
78
37
|
|
|
79
38
|
return content
|
|
80
39
|
}
|
|
81
40
|
|
|
82
|
-
|
|
83
|
-
return this.ui.$textarea.value || ''
|
|
41
|
+
getContentRaw() {
|
|
42
|
+
return this.ui.$textarea.value || ''
|
|
84
43
|
}
|
|
85
44
|
|
|
86
|
-
|
|
87
|
-
return marked(this.
|
|
45
|
+
getContentMarked() {
|
|
46
|
+
return marked(this.getContentFinal())
|
|
88
47
|
}
|
|
89
48
|
|
|
90
|
-
|
|
49
|
+
setContent(val: string) {
|
|
91
50
|
this.ui.$textarea.value = val
|
|
92
|
-
this.saveToLocalStorage()
|
|
93
51
|
|
|
94
52
|
// plug hook: content updated
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
// 延迟执行防止无效
|
|
98
|
-
window.setTimeout(() => {
|
|
99
|
-
this.adjustTextareaHeight()
|
|
100
|
-
}, 80)
|
|
53
|
+
this.getPlugs()?.getEvents().trigger('content-updated', val)
|
|
101
54
|
}
|
|
102
55
|
|
|
103
|
-
|
|
56
|
+
insertContent(val: string) {
|
|
104
57
|
if ((document as any).selection) {
|
|
105
58
|
this.ui.$textarea.focus();
|
|
106
59
|
(document as any).selection.createRange().text = val
|
|
@@ -120,100 +73,42 @@ export default class Editor extends Component {
|
|
|
120
73
|
}
|
|
121
74
|
}
|
|
122
75
|
|
|
123
|
-
|
|
124
|
-
const diff = this.ui.$textarea.offsetHeight - this.ui.$textarea.clientHeight
|
|
125
|
-
this.ui.$textarea.style.height = '0px' // it's a magic. 若不加此行,内容减少,高度回不去
|
|
126
|
-
this.ui.$textarea.style.height = `${this.ui.$textarea.scrollHeight + diff}px`
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
public focus() {
|
|
76
|
+
focus() {
|
|
130
77
|
this.ui.$textarea.focus()
|
|
131
78
|
}
|
|
132
79
|
|
|
133
|
-
|
|
80
|
+
reset() {
|
|
134
81
|
this.setContent('')
|
|
135
|
-
this.
|
|
136
|
-
this.cancelEditComment()
|
|
82
|
+
this.resetState()
|
|
137
83
|
}
|
|
138
84
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
this.reply?.setReply(commentData, $comment, scroll)
|
|
85
|
+
resetState() {
|
|
86
|
+
this.state.switch('normal')
|
|
142
87
|
}
|
|
143
88
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
this.reply?.cancelReply()
|
|
89
|
+
setReply(comment: CommentData, $comment: HTMLElement) {
|
|
90
|
+
this.state.switch('reply', { comment, $comment })
|
|
147
91
|
}
|
|
148
92
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
this.editMode?.setEdit(commentData, $comment)
|
|
93
|
+
setEditComment(comment: CommentData, $comment: HTMLElement) {
|
|
94
|
+
this.state.switch('edit', { comment, $comment })
|
|
152
95
|
}
|
|
153
96
|
|
|
154
|
-
|
|
155
|
-
public cancelEditComment() {
|
|
156
|
-
this.editMode?.cancelEdit()
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
public showNotify(msg: string, type: "i"|"s"|"w"|"e") {
|
|
97
|
+
showNotify(msg: string, type: any) {
|
|
160
98
|
Ui.showNotify(this.ui.$notifyWrap, msg, type)
|
|
161
99
|
}
|
|
162
100
|
|
|
163
|
-
|
|
101
|
+
showLoading() {
|
|
164
102
|
Ui.showLoading(this.ui.$el)
|
|
165
103
|
}
|
|
166
104
|
|
|
167
|
-
|
|
105
|
+
hideLoading() {
|
|
168
106
|
Ui.hideLoading(this.ui.$el)
|
|
169
107
|
}
|
|
170
108
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
if (!this.submitManager) return
|
|
174
|
-
await this.submitManager.do()
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
/** 关闭评论 */
|
|
178
|
-
public close() {
|
|
179
|
-
if (!this.ui.$textareaWrap.querySelector('.atk-comment-closed'))
|
|
180
|
-
this.ui.$textareaWrap.prepend(Utils.createElement(`<div class="atk-comment-closed">${this.$t('onlyAdminCanReply')}</div>`))
|
|
181
|
-
|
|
182
|
-
if (!User.data.isAdmin) {
|
|
183
|
-
this.ui.$textarea.style.display = 'none'
|
|
184
|
-
this.closePlugPanel()
|
|
185
|
-
this.ui.$bottom.style.display = 'none'
|
|
186
|
-
} else {
|
|
187
|
-
// 管理员一直打开评论
|
|
188
|
-
this.ui.$textarea.style.display = ''
|
|
189
|
-
this.ui.$bottom.style.display = ''
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
/** 打开评论 */
|
|
194
|
-
public open() {
|
|
195
|
-
this.ui.$textareaWrap.querySelector('.atk-comment-closed')?.remove()
|
|
196
|
-
this.ui.$textarea.style.display = ''
|
|
197
|
-
this.ui.$bottom.style.display = ''
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
/** 移动评论框到置顶元素之后 */
|
|
201
|
-
public travel($afterEl: HTMLElement) {
|
|
202
|
-
this.mover?.move($afterEl)
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
/** 评论框归位 */
|
|
206
|
-
public travelBack() {
|
|
207
|
-
this.mover?.back()
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
/** 展开插件面板 */
|
|
211
|
-
public openPlugPanel(plugName: string) {
|
|
212
|
-
this.plugs?.openPlugPanel(plugName)
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
/** 收起插件面板 */
|
|
216
|
-
public closePlugPanel() {
|
|
217
|
-
this.plugs?.closePlugPanel()
|
|
109
|
+
submit() {
|
|
110
|
+
this.ctx.trigger('editor-submit')
|
|
218
111
|
}
|
|
219
112
|
}
|
|
113
|
+
|
|
114
|
+
export default Editor
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { EditorState, CommentData } from '~/types'
|
|
2
|
+
import * as Ui from '@/lib/ui'
|
|
3
|
+
import type Editor from './editor'
|
|
4
|
+
import Mover from '../plugins/editor/mover'
|
|
5
|
+
|
|
6
|
+
export default class EditorStateManager {
|
|
7
|
+
constructor(private editor: Editor) {}
|
|
8
|
+
|
|
9
|
+
private stateCurt: EditorState = 'normal'
|
|
10
|
+
private stateUnmountFn: (() => void)|null = null
|
|
11
|
+
|
|
12
|
+
/** Get current state */
|
|
13
|
+
get() {
|
|
14
|
+
return this.stateCurt
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Switch editor state
|
|
19
|
+
*
|
|
20
|
+
* @param state The state to switch
|
|
21
|
+
* @param payload The cause of state switch
|
|
22
|
+
*/
|
|
23
|
+
switch(state: EditorState, payload?: { $comment: HTMLElement, comment: CommentData }) {
|
|
24
|
+
// trigger unmount
|
|
25
|
+
if (this.stateUnmountFn) {
|
|
26
|
+
this.stateUnmountFn()
|
|
27
|
+
this.stateUnmountFn = null
|
|
28
|
+
|
|
29
|
+
// move editor back to the initial position
|
|
30
|
+
this.editor.getPlugs()?.get(Mover)?.back()
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// invoke effect function and save unmount function
|
|
34
|
+
if (state !== 'normal' && payload) {
|
|
35
|
+
// move editor position
|
|
36
|
+
let moveAfterEl = payload.$comment
|
|
37
|
+
if (!this.editor.conf.flatMode) moveAfterEl = moveAfterEl.querySelector<HTMLElement>('.atk-footer')!
|
|
38
|
+
this.editor.getPlugs()?.get(Mover)?.move(moveAfterEl)
|
|
39
|
+
|
|
40
|
+
const $relative = this.editor.ctx.conf.scrollRelativeTo && this.editor.ctx.conf.scrollRelativeTo()
|
|
41
|
+
Ui.scrollIntoView(this.editor.getUI().$el, true, $relative)
|
|
42
|
+
|
|
43
|
+
const plugin = this.editor.getPlugs()?.getPlugs().find(p => p.editorStateEffectWhen === state)
|
|
44
|
+
if (plugin && plugin.editorStateEffect) {
|
|
45
|
+
this.stateUnmountFn = plugin.editorStateEffect(payload.comment)
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// change current state
|
|
50
|
+
this.stateCurt = state
|
|
51
|
+
}
|
|
52
|
+
}
|
package/src/i18n/zh-CN.ts
CHANGED
package/src/layer/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
export
|
|
4
|
-
export
|
|
1
|
+
export * from './layer'
|
|
2
|
+
export * from './wrap'
|
|
3
|
+
export * from './scrollbar-helper'
|
|
4
|
+
export * from './layer-manager'
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { ContextApi } from '~/types'
|
|
2
|
+
import { getScrollbarHelper } from './scrollbar-helper'
|
|
3
|
+
import { LayerWrap } from './wrap'
|
|
4
|
+
import { Layer } from './layer'
|
|
5
|
+
|
|
6
|
+
export class LayerManager {
|
|
7
|
+
private wrap: LayerWrap
|
|
8
|
+
private ctx: ContextApi
|
|
9
|
+
|
|
10
|
+
constructor(ctx: ContextApi) {
|
|
11
|
+
this.ctx = ctx
|
|
12
|
+
|
|
13
|
+
this.wrap = new LayerWrap()
|
|
14
|
+
document.body.appendChild(this.wrap.getWrap())
|
|
15
|
+
|
|
16
|
+
ctx.on('destroy', () => {
|
|
17
|
+
this.wrap.getWrap().remove()
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
// 记录页面原始 CSS 属性
|
|
21
|
+
getScrollbarHelper().init()
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
getEl() {
|
|
25
|
+
return this.wrap.getWrap()
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
create(name: string, el?: HTMLElement | undefined) {
|
|
29
|
+
const layer = new Layer(this.wrap, name, el)
|
|
30
|
+
return layer
|
|
31
|
+
}
|
|
32
|
+
}
|
package/src/layer/layer.ts
CHANGED
|
@@ -1,51 +1,17 @@
|
|
|
1
|
-
import
|
|
2
|
-
import Component from '../lib/component'
|
|
3
|
-
import * as Utils from '../lib/utils'
|
|
4
|
-
import * as Ui from '../lib/ui'
|
|
1
|
+
import type { LayerWrap } from './wrap'
|
|
5
2
|
|
|
6
|
-
export
|
|
7
|
-
private
|
|
8
|
-
private
|
|
9
|
-
private
|
|
3
|
+
export class Layer {
|
|
4
|
+
private $el: HTMLElement
|
|
5
|
+
private wrap: LayerWrap
|
|
6
|
+
private onAfterHide?: () => void
|
|
10
7
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
public static BodyOrgPaddingRight: string
|
|
15
|
-
|
|
16
|
-
public afterHide?: Function
|
|
17
|
-
|
|
18
|
-
constructor (ctx: Context, name: string, el?: HTMLElement) {
|
|
19
|
-
super(ctx)
|
|
20
|
-
|
|
21
|
-
this.name = name
|
|
22
|
-
const { $wrap, $mask } = getLayerWrap()
|
|
23
|
-
this.$wrap = $wrap
|
|
24
|
-
this.$mask = $mask
|
|
25
|
-
|
|
26
|
-
this.$el = this.$wrap.querySelector(`[data-layer-name="${name}"].atk-layer-item`)!
|
|
27
|
-
if (this.$el === null) {
|
|
28
|
-
// 若传递 layer 元素为空
|
|
29
|
-
if (!el) {
|
|
30
|
-
this.$el = Utils.createElement()
|
|
31
|
-
this.$el.classList.add('atk-layer-item')
|
|
32
|
-
} else {
|
|
33
|
-
this.$el = el
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
this.$el.setAttribute('data-layer-name', name)
|
|
37
|
-
this.$el.style.display = 'none'
|
|
38
|
-
|
|
39
|
-
// 添加到 layers wrap 中
|
|
40
|
-
this.$wrap.append(this.$el)
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
getName() {
|
|
44
|
-
return this.name
|
|
8
|
+
constructor(wrap: LayerWrap, name: string, el?: HTMLElement) {
|
|
9
|
+
this.wrap = wrap
|
|
10
|
+
this.$el = this.wrap.createItem(name, el)
|
|
45
11
|
}
|
|
46
12
|
|
|
47
|
-
|
|
48
|
-
|
|
13
|
+
setOnAfterHide(func: () => void) {
|
|
14
|
+
this.onAfterHide = func
|
|
49
15
|
}
|
|
50
16
|
|
|
51
17
|
getEl() {
|
|
@@ -53,111 +19,21 @@ export default class Layer extends Component {
|
|
|
53
19
|
}
|
|
54
20
|
|
|
55
21
|
show() {
|
|
56
|
-
this.fireAllActionTimer()
|
|
57
|
-
|
|
58
|
-
this.$wrap.style.display = 'block'
|
|
59
|
-
this.$mask.style.display = 'block'
|
|
60
|
-
this.$mask.classList.add('atk-fade-in')
|
|
61
22
|
this.$el.style.display = ''
|
|
62
|
-
|
|
63
|
-
this.$mask.onclick = () => {
|
|
64
|
-
if (this.maskClickHideEnable) this.hide()
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// body style 禁止滚动 + 防抖
|
|
68
|
-
this.pageBodyScrollBarHide()
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
hide () {
|
|
72
|
-
if (this.afterHide) this.afterHide()
|
|
73
|
-
this.$wrap.classList.add('atk-fade-out')
|
|
74
|
-
this.$el.style.display = 'none'
|
|
75
|
-
|
|
76
|
-
// body style 禁止滚动解除
|
|
77
|
-
this.pageBodyScrollBarShow()
|
|
78
|
-
|
|
79
|
-
this.newActionTimer(() => {
|
|
80
|
-
this.$wrap.style.display = 'none'
|
|
81
|
-
this.checkCleanLayer()
|
|
82
|
-
}, 450)
|
|
83
|
-
this.newActionTimer(() => {
|
|
84
|
-
this.$wrap.style.display = 'none'
|
|
85
|
-
this.$wrap.classList.remove('atk-fade-out')
|
|
86
|
-
}, 200)
|
|
23
|
+
this.wrap.show()
|
|
87
24
|
}
|
|
88
25
|
|
|
89
|
-
|
|
90
|
-
this.
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
// 页面滚动条隐藏
|
|
94
|
-
pageBodyScrollBarHide() {
|
|
95
|
-
document.body.style.overflow = 'hidden'
|
|
96
|
-
|
|
97
|
-
const bpr = parseInt(window.getComputedStyle(document.body, null).getPropertyValue('padding-right'), 10)
|
|
98
|
-
document.body.style.paddingRight = `${Ui.getScrollBarWidth() + bpr || 0}px`
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
// 页面滚动条显示
|
|
102
|
-
pageBodyScrollBarShow() {
|
|
103
|
-
document.body.style.overflow = Layer.BodyOrgOverflow
|
|
104
|
-
document.body.style.paddingRight = Layer.BodyOrgPaddingRight
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
// Timers
|
|
108
|
-
private static actionTimers: {act: Function, tid: number}[] = []
|
|
109
|
-
|
|
110
|
-
private newActionTimer(func: Function, delay: number) {
|
|
111
|
-
const act = () => {
|
|
112
|
-
func() // 执行
|
|
113
|
-
Layer.actionTimers = Layer.actionTimers.filter(o => o.act !== act) // 删除
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
const tid = window.setTimeout(() => act(), delay)
|
|
117
|
-
|
|
118
|
-
Layer.actionTimers.push({ act, tid })
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
private fireAllActionTimer() {
|
|
122
|
-
Layer.actionTimers.forEach(item => {
|
|
123
|
-
clearTimeout(item.tid)
|
|
124
|
-
item.act() // 立即执行
|
|
26
|
+
hide() {
|
|
27
|
+
this.wrap.hide(() => {
|
|
28
|
+
this.$el.style.display = 'none'
|
|
29
|
+
this.onAfterHide && this.onAfterHide()
|
|
125
30
|
})
|
|
126
31
|
}
|
|
127
32
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
this.checkCleanLayer()
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
/** 销毁 */
|
|
137
|
-
dispose() {
|
|
138
|
-
this.hide()
|
|
139
|
-
this.$el.remove()
|
|
140
|
-
// this.$el dispose
|
|
141
|
-
this.checkCleanLayer()
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
checkCleanLayer() {
|
|
145
|
-
if (this.getWrapEl().querySelectorAll('.atk-layer-item').length === 0) {
|
|
146
|
-
this.$wrap.style.display = 'none'
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
export function getLayerWrap(): { $wrap: HTMLElement, $mask: HTMLElement } {
|
|
152
|
-
let $wrap = document.querySelector<HTMLElement>(`.atk-layer-wrap`)
|
|
153
|
-
if (!$wrap) {
|
|
154
|
-
$wrap = Utils.createElement(
|
|
155
|
-
`<div class="atk-layer-wrap" style="display: none;"><div class="atk-layer-mask"></div></div>`
|
|
156
|
-
)
|
|
157
|
-
document.body.appendChild($wrap)
|
|
33
|
+
destroy() {
|
|
34
|
+
this.wrap.hide(() => {
|
|
35
|
+
this.$el.remove()
|
|
36
|
+
this.onAfterHide && this.onAfterHide()
|
|
37
|
+
})
|
|
158
38
|
}
|
|
159
|
-
|
|
160
|
-
const $mask = $wrap.querySelector<HTMLElement>('.atk-layer-mask')!
|
|
161
|
-
|
|
162
|
-
return { $wrap, $mask }
|
|
163
39
|
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import * as Ui from '@/lib/ui'
|
|
2
|
+
|
|
3
|
+
let bodyOrgOverflow: string
|
|
4
|
+
let bodyOrgPaddingRight: string
|
|
5
|
+
|
|
6
|
+
export function getScrollbarHelper() {
|
|
7
|
+
return {
|
|
8
|
+
init() {
|
|
9
|
+
bodyOrgOverflow = document.body.style.overflow
|
|
10
|
+
bodyOrgPaddingRight = document.body.style.paddingRight
|
|
11
|
+
},
|
|
12
|
+
|
|
13
|
+
unlock() {
|
|
14
|
+
document.body.style.overflow = bodyOrgOverflow
|
|
15
|
+
document.body.style.paddingRight = bodyOrgPaddingRight
|
|
16
|
+
},
|
|
17
|
+
|
|
18
|
+
lock() {
|
|
19
|
+
document.body.style.overflow = 'hidden'
|
|
20
|
+
const barPaddingRight = parseInt(window.getComputedStyle(document.body, null).getPropertyValue('padding-right'), 10)
|
|
21
|
+
document.body.style.paddingRight = `${Ui.getScrollBarWidth() + barPaddingRight || 0}px`
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|