artalk 2.4.4 → 2.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +27 -0
- package/dist/Artalk.css +1 -1
- package/dist/Artalk.es.js +7066 -6256
- package/dist/Artalk.iife.js +1 -1
- package/dist/Artalk.js +1 -1
- package/dist/ArtalkLite.css +1 -1
- package/dist/ArtalkLite.es.js +5095 -4396
- package/dist/ArtalkLite.iife.js +1 -1
- package/dist/ArtalkLite.js +1 -1
- package/dist/i18n/jp.js +1 -1
- package/dist/i18n/zh-TW.js +1 -1
- package/dist/src/api/index.d.ts +2 -2
- package/dist/src/api/system.d.ts +5 -2
- package/dist/src/artalk.d.ts +42 -34
- package/dist/src/comment/comment.d.ts +2 -2
- package/dist/src/comment/height-limit.d.ts +30 -0
- package/dist/src/comment/render-ctx.d.ts +23 -0
- package/dist/src/comment/render.d.ts +2 -50
- package/dist/src/comment/renders/actions.d.ts +5 -0
- package/dist/src/comment/renders/avatar.d.ts +5 -0
- package/dist/src/comment/renders/content.d.ts +5 -0
- package/dist/src/comment/renders/header.d.ts +5 -0
- package/dist/src/comment/renders/index.d.ts +2 -0
- package/dist/src/comment/renders/pending.d.ts +5 -0
- package/dist/src/comment/renders/reply-at.d.ts +5 -0
- package/dist/src/comment/renders/reply-to.d.ts +5 -0
- package/dist/src/components/dialog.d.ts +1 -1
- package/dist/src/config.d.ts +8 -0
- package/dist/src/context.d.ts +16 -29
- package/dist/src/editor/edit-mode.d.ts +9 -0
- package/dist/src/editor/editor.d.ts +37 -45
- package/dist/src/editor/funcs.d.ts +2 -0
- package/dist/src/editor/mover.d.ts +8 -0
- package/dist/src/editor/plug-manager.d.ts +17 -0
- package/dist/src/editor/plugs/editor-plug.d.ts +13 -1
- package/dist/src/editor/reply.d.ts +9 -0
- package/dist/src/editor/submit.d.ts +16 -0
- package/dist/src/editor/ui.d.ts +25 -0
- package/dist/src/i18n/external.d.ts +70 -0
- package/dist/src/i18n/index.d.ts +11 -75
- package/dist/src/layer/index.d.ts +2 -2
- package/dist/src/layer/layer.d.ts +1 -1
- package/dist/src/lib/checker/captcha-renders.d.ts +5 -0
- package/dist/src/lib/checker/index.d.ts +16 -10
- package/dist/src/lib/dark-mode.d.ts +4 -0
- package/dist/src/lib/marked.d.ts +9 -0
- package/dist/src/lib/user.d.ts +6 -3
- package/dist/src/lib/utils.d.ts +1 -5
- package/dist/src/list/list-lite.d.ts +15 -11
- package/dist/src/list/list-nest.d.ts +2 -2
- package/dist/src/list/list-ui.d.ts +16 -0
- package/dist/src/list/list.d.ts +0 -1
- package/dist/src/list/paginator/adaptors/index.d.ts +12 -0
- package/dist/src/list/paginator/adaptors/pagination.d.ts +9 -0
- package/dist/src/list/paginator/adaptors/read-more.d.ts +10 -0
- package/dist/src/list/paginator/holder.d.ts +16 -0
- package/dist/src/list/paginator/index.d.ts +10 -0
- package/dist/src/service.d.ts +46 -0
- package/dist/types/artalk-config.d.ts +5 -2
- package/dist/types/artalk-data.d.ts +3 -3
- package/dist/types/context.d.ts +13 -20
- package/dist/types/global.d.ts +1 -0
- package/package.json +6 -7
- package/src/api/comment.ts +7 -7
- package/src/api/page.ts +0 -2
- package/src/api/request.ts +6 -4
- package/src/api/system.ts +3 -12
- package/src/api/upload.ts +3 -4
- package/src/api/user.ts +6 -8
- package/src/artalk.ts +103 -158
- package/src/comment/comment.ts +7 -6
- package/src/comment/height-limit.ts +100 -0
- package/src/comment/render-ctx.ts +30 -0
- package/src/comment/render.ts +31 -375
- package/src/comment/renders/actions.ts +114 -0
- package/src/comment/renders/avatar.ts +22 -0
- package/src/comment/renders/content.ts +39 -0
- package/src/comment/renders/header.ts +84 -0
- package/src/comment/renders/index.ts +19 -0
- package/src/comment/renders/pending.ts +12 -0
- package/src/comment/renders/reply-at.ts +16 -0
- package/src/comment/renders/reply-to.ts +24 -0
- package/src/config.ts +65 -0
- package/src/context.ts +33 -86
- package/src/defaults.ts +1 -0
- package/src/editor/edit-mode.ts +103 -0
- package/src/editor/editor.ts +101 -395
- package/src/editor/funcs.ts +97 -0
- package/src/editor/mover.ts +43 -0
- package/src/editor/plug-manager.ts +172 -0
- package/src/editor/plugs/editor-plug.ts +20 -2
- package/src/editor/plugs/{emoticons-plug.less → emoticons-plug.scss} +5 -4
- package/src/editor/plugs/emoticons-plug.ts +2 -1
- package/src/editor/plugs/header-input-plug.ts +11 -10
- package/src/editor/plugs/{preview-plug.less → preview-plug.scss} +1 -1
- package/src/editor/plugs/preview-plug.ts +8 -4
- package/src/editor/plugs/upload-plug.ts +12 -14
- package/src/editor/reply.ts +62 -0
- package/src/editor/submit.ts +99 -0
- package/src/editor/ui.ts +36 -0
- package/src/i18n/external.ts +10 -0
- package/src/i18n/index.ts +22 -19
- package/src/i18n/jp.ts +1 -1
- package/src/i18n/zh-TW.ts +1 -1
- package/src/layer/index.ts +2 -2
- package/src/layer/layer.ts +4 -4
- package/src/layer/sidebar-layer.ts +4 -2
- package/src/lib/checker/admin.ts +37 -0
- package/src/lib/checker/captcha-renders.ts +68 -0
- package/src/lib/checker/captcha.ts +26 -0
- package/src/lib/checker/index.ts +36 -20
- package/src/lib/dark-mode.ts +48 -0
- package/src/lib/marked.ts +133 -0
- package/src/lib/user.ts +13 -7
- package/src/lib/utils.ts +1 -123
- package/src/list/list-lite.ts +59 -162
- package/src/list/list-ui.ts +137 -0
- package/src/list/list.ts +33 -60
- package/src/list/paginator/adaptors/index.ts +21 -0
- package/src/list/paginator/adaptors/pagination.ts +42 -0
- package/src/list/paginator/adaptors/read-more.ts +56 -0
- package/src/list/paginator/holder.ts +56 -0
- package/src/list/paginator/index.ts +13 -0
- package/src/service.ts +118 -0
- package/src/style/{_color.less → _color.scss} +3 -3
- package/src/style/{_extend.less → _extend.scss} +1 -1
- package/src/style/_variables.scss +3 -0
- package/src/style/{comment.less → comment.scss} +36 -12
- package/src/style/{editor.less → editor.scss} +11 -11
- package/src/style/{list.less → list.scss} +12 -10
- package/src/style/{main.less → main.scss} +24 -23
- package/src/style/{sidebar-layer.less → sidebar-layer.scss} +8 -8
- package/types/artalk-config.d.ts +5 -2
- package/types/artalk-data.d.ts +3 -3
- package/types/context.d.ts +13 -20
- package/types/global.d.ts +1 -0
- package/CNAME +0 -1
- package/LICENSE +0 -165
- package/index.html +0 -157
- package/postcss.config.js +0 -5
- package/scripts/build-i18n.mjs +0 -46
- package/src/lib/checker/admin-checker.ts +0 -36
- package/src/lib/checker/captcha-checker.ts +0 -84
- package/src/style/_variables.less +0 -3
- package/test/ArtalkCount.html +0 -16
- package/test/ArtalkI18n.html +0 -16
- package/test/ArtalkLite.html +0 -15
- package/test/CSRF.html +0 -26
- package/tsconfig.json +0 -12
- package/vite-base.config.ts +0 -21
- package/vite-demo.config.ts +0 -12
- package/vite-lite.config.ts +0 -22
- package/vite.config.ts +0 -27
- /package/dist/src/lib/checker/{admin-checker.d.ts → admin.d.ts} +0 -0
- /package/dist/src/lib/checker/{captcha-checker.d.ts → captcha.d.ts} +0 -0
- /package/src/style/{pagination.less → pagination.scss} +0 -0
package/package.json
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "artalk",
|
|
3
|
-
"version": "2.
|
|
4
|
-
"backendMinVersion": "2.3.0",
|
|
3
|
+
"version": "2.5.1",
|
|
5
4
|
"license": "LGPL-3.0",
|
|
6
5
|
"description": "A Selfhosted Comment System",
|
|
7
6
|
"keywords": [
|
|
@@ -14,7 +13,7 @@
|
|
|
14
13
|
"repository": {
|
|
15
14
|
"type": "git",
|
|
16
15
|
"url": "https://github.com/ArtalkJS/Artalk.git",
|
|
17
|
-
"directory": "packages/artalk"
|
|
16
|
+
"directory": "ui/packages/artalk"
|
|
18
17
|
},
|
|
19
18
|
"homepage": "https://artalk.js.org",
|
|
20
19
|
"bugs": "https://github.com/ArtalkJS/Artalk/issue",
|
|
@@ -24,17 +23,17 @@
|
|
|
24
23
|
"module": "./dist/Artalk.es.js",
|
|
25
24
|
"types": "./dist/src/main.d.ts",
|
|
26
25
|
"devDependencies": {
|
|
27
|
-
"@types/marked": "4.0.
|
|
26
|
+
"@types/marked": "4.0.8"
|
|
28
27
|
},
|
|
29
28
|
"dependencies": {
|
|
29
|
+
"abortcontroller-polyfill": "^1.7.5",
|
|
30
30
|
"hanabi": "^0.4.0",
|
|
31
31
|
"insane": "^2.6.2",
|
|
32
|
-
"marked": "^4.
|
|
33
|
-
"abortcontroller-polyfill": "^1.7.5"
|
|
32
|
+
"marked": "^4.2.12"
|
|
34
33
|
},
|
|
35
34
|
"scripts": {
|
|
36
35
|
"dev": "vite",
|
|
37
|
-
"build": "
|
|
36
|
+
"build": "vite build && pnpm build:lite && pnpm build:i18n",
|
|
38
37
|
"build:lite": "vite build --config vite-lite.config.ts",
|
|
39
38
|
"build:i18n": "node scripts/build-i18n.mjs",
|
|
40
39
|
"build:demo": "vite build --config vite-demo.config.ts",
|
package/src/api/comment.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { CommentData, ListData } from '~/types/artalk-data'
|
|
2
2
|
import * as Utils from '../lib/utils'
|
|
3
3
|
import ApiBase from './api-base'
|
|
4
|
+
import User from '../lib/user'
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* 评论 API
|
|
@@ -16,9 +17,9 @@ export default class CommentApi extends ApiBase {
|
|
|
16
17
|
}
|
|
17
18
|
|
|
18
19
|
if (flatMode) params.flat_mode = flatMode // 平铺模式
|
|
19
|
-
if (
|
|
20
|
-
params.name =
|
|
21
|
-
params.email =
|
|
20
|
+
if (User.checkHasBasicUserInfo()) {
|
|
21
|
+
params.name = User.data.nick
|
|
22
|
+
params.email = User.data.email
|
|
22
23
|
}
|
|
23
24
|
|
|
24
25
|
if (paramsEditor) paramsEditor(params)
|
|
@@ -68,14 +69,13 @@ export default class CommentApi extends ApiBase {
|
|
|
68
69
|
/** 投票 */
|
|
69
70
|
public async vote(targetID: number, type: string) {
|
|
70
71
|
const params: any = {
|
|
71
|
-
site_name: this.ctx.conf.site || '',
|
|
72
72
|
target_id: targetID,
|
|
73
73
|
type,
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
if (
|
|
77
|
-
params.name =
|
|
78
|
-
params.email =
|
|
76
|
+
if (User.checkHasBasicUserInfo()) {
|
|
77
|
+
params.name = User.data.nick
|
|
78
|
+
params.email = User.data.email
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
const data = await this.POST<any>('/vote', params)
|
package/src/api/page.ts
CHANGED
|
@@ -55,7 +55,6 @@ export default class PageApi extends ApiBase {
|
|
|
55
55
|
/** PV */
|
|
56
56
|
public async pv() {
|
|
57
57
|
const params: any = {
|
|
58
|
-
site_name: this.ctx.conf.site || '',
|
|
59
58
|
page_key: this.ctx.conf.pageKey || '',
|
|
60
59
|
page_title: this.ctx.conf.pageTitle || ''
|
|
61
60
|
}
|
|
@@ -73,7 +72,6 @@ export default class PageApi extends ApiBase {
|
|
|
73
72
|
) {
|
|
74
73
|
const params: any = {
|
|
75
74
|
type,
|
|
76
|
-
site_name: this.ctx.conf.site || '',
|
|
77
75
|
}
|
|
78
76
|
|
|
79
77
|
if (pageKeys) params.page_keys = Array.isArray(pageKeys) ? pageKeys.join(',') : pageKeys
|
package/src/api/request.ts
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import Context from '~/types/context'
|
|
2
|
+
import User from '../lib/user'
|
|
3
|
+
import $t from '../i18n'
|
|
2
4
|
|
|
3
5
|
/** 公共请求函数 */
|
|
4
6
|
export async function Fetch(ctx: Context, input: RequestInfo, init: RequestInit, timeout?: number): Promise<any> {
|
|
5
7
|
// JWT
|
|
6
|
-
if (
|
|
8
|
+
if (User.data.token) {
|
|
7
9
|
const headers = new Headers(init.headers) // 保留原有 headers
|
|
8
|
-
headers.set('Authorization', `Bearer ${
|
|
10
|
+
headers.set('Authorization', `Bearer ${User.data.token}`)
|
|
9
11
|
init.headers = headers
|
|
10
12
|
}
|
|
11
13
|
|
|
@@ -20,7 +22,7 @@ export async function Fetch(ctx: Context, input: RequestInfo, init: RequestInit,
|
|
|
20
22
|
const isNoAccess = noAccessCodes.includes(respHttpCode)
|
|
21
23
|
|
|
22
24
|
if (!resp.ok && !isNoAccess)
|
|
23
|
-
throw new Error(`${
|
|
25
|
+
throw new Error(`${$t('reqGot')} ${respHttpCode}`)
|
|
24
26
|
|
|
25
27
|
// 解析获取响应的 json
|
|
26
28
|
let json: any = await resp.json()
|
|
@@ -95,7 +97,7 @@ function timeoutFetch(ctx: Context, url: RequestInfo, ms: number, opts: RequestI
|
|
|
95
97
|
promise.finally(() => { clearTimeout(timer) })
|
|
96
98
|
}
|
|
97
99
|
promise = promise.catch((err) => {
|
|
98
|
-
throw ((err || {}).name === 'AbortError') ? new Error(
|
|
100
|
+
throw ((err || {}).name === 'AbortError') ? new Error($t('reqAborted')) : err
|
|
99
101
|
})
|
|
100
102
|
return promise
|
|
101
103
|
}
|
package/src/api/system.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import ArtalkConfig from '~/types/artalk-config'
|
|
2
2
|
import ApiBase from './api-base'
|
|
3
|
+
import { handleBackendRefConf } from '../config'
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* 系统 API
|
|
@@ -10,22 +11,12 @@ export default class SystemApi extends ApiBase {
|
|
|
10
11
|
const data = await this.POST<any>(`/conf`)
|
|
11
12
|
const conf = (data.frontend_conf || {}) as ArtalkConfig
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
if (conf.emoticons && typeof conf.emoticons === "string") {
|
|
15
|
-
conf.emoticons = conf.emoticons.trim()
|
|
16
|
-
if (conf.emoticons.startsWith("[") || conf.emoticons.startsWith("{")) {
|
|
17
|
-
conf.emoticons = JSON.parse(conf.emoticons) // pase json
|
|
18
|
-
} else if (conf.emoticons === "false") {
|
|
19
|
-
conf.emoticons = false
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
return conf
|
|
14
|
+
return handleBackendRefConf(conf)
|
|
24
15
|
}
|
|
25
16
|
|
|
26
17
|
/** 获取配置数据 */
|
|
27
18
|
public async getSettings() {
|
|
28
|
-
const data = await this.POST<string>('/admin/setting-get')
|
|
19
|
+
const data = await this.POST<{custom: string, template: string}>('/admin/setting-get')
|
|
29
20
|
return data
|
|
30
21
|
}
|
|
31
22
|
|
package/src/api/upload.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ToFormData } from './request'
|
|
2
2
|
import ApiBase from './api-base'
|
|
3
|
+
import User from '../lib/user'
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* 上传 API
|
|
@@ -8,13 +9,11 @@ export default class UploadApi extends ApiBase {
|
|
|
8
9
|
/** 图片上传 */
|
|
9
10
|
public async imgUpload(file: File) {
|
|
10
11
|
const params: any = {
|
|
11
|
-
name:
|
|
12
|
-
email:
|
|
12
|
+
name: User.data.nick,
|
|
13
|
+
email: User.data.email,
|
|
13
14
|
page_key: this.ctx.conf.pageKey,
|
|
14
15
|
}
|
|
15
16
|
|
|
16
|
-
if (this.ctx.conf.site) params.site_name = this.ctx.conf.site
|
|
17
|
-
|
|
18
17
|
const form = ToFormData(params)
|
|
19
18
|
form.set('file', file)
|
|
20
19
|
|
package/src/api/user.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { UserData, NotifyData, UserDataForAdmin } from '~/types/artalk-data'
|
|
2
2
|
import ApiBase from './api-base'
|
|
3
3
|
import { ToFormData } from './request'
|
|
4
|
+
import User from '../lib/user'
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* 用户 API
|
|
@@ -12,8 +13,6 @@ export default class UserApi extends ApiBase {
|
|
|
12
13
|
name, email, password
|
|
13
14
|
}
|
|
14
15
|
|
|
15
|
-
if (this.ctx.conf.site) params.site_name = this.ctx.conf.site
|
|
16
|
-
|
|
17
16
|
const data = await this.POST<any>('/login', params)
|
|
18
17
|
return data as { token: string, user: UserData }
|
|
19
18
|
}
|
|
@@ -22,7 +21,7 @@ export default class UserApi extends ApiBase {
|
|
|
22
21
|
public userGet(name: string, email: string) {
|
|
23
22
|
const ctrl = new AbortController()
|
|
24
23
|
const params: any = {
|
|
25
|
-
name, email
|
|
24
|
+
name, email
|
|
26
25
|
}
|
|
27
26
|
|
|
28
27
|
const req = this.Fetch(`/user-get`, {
|
|
@@ -45,8 +44,8 @@ export default class UserApi extends ApiBase {
|
|
|
45
44
|
/** 用户 · 登录状态 */
|
|
46
45
|
public async loginStatus() {
|
|
47
46
|
const data = await this.POST<any>('/login-status', {
|
|
48
|
-
name:
|
|
49
|
-
email:
|
|
47
|
+
name: User.data.nick,
|
|
48
|
+
email: User.data.email
|
|
50
49
|
})
|
|
51
50
|
return (data || { is_login: false, is_admin: false }) as { is_login: boolean, is_admin: boolean }
|
|
52
51
|
}
|
|
@@ -59,15 +58,14 @@ export default class UserApi extends ApiBase {
|
|
|
59
58
|
/** 已读标记 */
|
|
60
59
|
public markRead(notifyKey: string, readAll = false) {
|
|
61
60
|
const params: any = {
|
|
62
|
-
site_name: this.ctx.conf.site || '',
|
|
63
61
|
notify_key: notifyKey,
|
|
64
62
|
}
|
|
65
63
|
|
|
66
64
|
if (readAll) {
|
|
67
65
|
delete params.notify_key
|
|
68
66
|
params.read_all = true
|
|
69
|
-
params.name =
|
|
70
|
-
params.email =
|
|
67
|
+
params.name = User.data.nick
|
|
68
|
+
params.email = User.data.email
|
|
71
69
|
}
|
|
72
70
|
|
|
73
71
|
return this.POST(`/mark-read`, params)
|
package/src/artalk.ts
CHANGED
|
@@ -1,29 +1,25 @@
|
|
|
1
|
-
import './style/main.
|
|
1
|
+
import './style/main.scss'
|
|
2
2
|
|
|
3
|
-
import ArtalkConfig from '~/types/artalk-config'
|
|
4
|
-
import { EventPayloadMap, Handler } from '~/types/event'
|
|
5
|
-
import ArtalkPlug from '~/types/plug'
|
|
6
|
-
import Context from '~/types/context'
|
|
3
|
+
import type ArtalkConfig from '~/types/artalk-config'
|
|
4
|
+
import type { EventPayloadMap, Handler } from '~/types/event'
|
|
5
|
+
import type ArtalkPlug from '~/types/plug'
|
|
6
|
+
import type Context from '~/types/context'
|
|
7
7
|
import ConcreteContext from './context'
|
|
8
8
|
import defaults from './defaults'
|
|
9
|
-
|
|
10
|
-
import
|
|
11
|
-
import CheckerLauncher from './lib/checker'
|
|
12
|
-
import Editor from './editor'
|
|
13
|
-
import List from './list'
|
|
14
|
-
import SidebarLayer from './layer/sidebar-layer'
|
|
15
|
-
|
|
16
|
-
import Layer from './layer'
|
|
17
|
-
import * as Utils from './lib/utils'
|
|
18
|
-
import * as Ui from './lib/ui'
|
|
9
|
+
import { handelBaseConf } from './config'
|
|
10
|
+
import Services from './service'
|
|
19
11
|
import * as Stat from './lib/stat'
|
|
12
|
+
import ListLite from './list/list-lite'
|
|
13
|
+
import Api from './api'
|
|
20
14
|
|
|
21
15
|
/**
|
|
22
16
|
* Artalk
|
|
23
17
|
*
|
|
24
|
-
* @
|
|
18
|
+
* @see https://artalk.js.org
|
|
25
19
|
*/
|
|
26
20
|
export default class Artalk {
|
|
21
|
+
private static instance?: Artalk
|
|
22
|
+
|
|
27
23
|
public static ListLite = ListLite
|
|
28
24
|
public static readonly defaults: ArtalkConfig = defaults
|
|
29
25
|
|
|
@@ -31,192 +27,141 @@ export default class Artalk {
|
|
|
31
27
|
public ctx!: Context
|
|
32
28
|
public $root!: HTMLElement
|
|
33
29
|
|
|
34
|
-
/** Plugins
|
|
35
|
-
protected static
|
|
36
|
-
|
|
37
|
-
/** Plugins (in a instance scope) */
|
|
38
|
-
protected instancePlugins: ArtalkPlug[] = []
|
|
39
|
-
|
|
40
|
-
/** 禁用的组件 */
|
|
30
|
+
/** Plugins */
|
|
31
|
+
protected static plugins: ArtalkPlug[] = [ Stat.PvCountWidget ]
|
|
41
32
|
public static DisabledComponents: string[] = []
|
|
42
33
|
|
|
43
|
-
constructor(
|
|
44
|
-
|
|
45
|
-
|
|
34
|
+
constructor(conf: Partial<ArtalkConfig>) {
|
|
35
|
+
if (Artalk.instance) return Artalk.instance.update(conf)
|
|
36
|
+
|
|
37
|
+
// 初始化基本配置
|
|
38
|
+
this.conf = handelBaseConf(conf)
|
|
46
39
|
if (this.conf.el instanceof HTMLElement) this.$root = this.conf.el
|
|
47
40
|
|
|
48
|
-
|
|
41
|
+
// 初始化 Context
|
|
49
42
|
this.ctx = new ConcreteContext(this.conf, this.$root)
|
|
50
43
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/** 组件初始化 */
|
|
56
|
-
private initComponents() {
|
|
57
|
-
this.initLocale()
|
|
58
|
-
this.initLayer()
|
|
59
|
-
Utils.initMarked(this.ctx)
|
|
60
|
-
|
|
61
|
-
const Components: { [name: string]: () => void } = {
|
|
62
|
-
// CheckerLauncher
|
|
63
|
-
checkerLauncher: () => {
|
|
64
|
-
const checkerLauncher = new CheckerLauncher(this.ctx)
|
|
65
|
-
this.ctx.setCheckerLauncher(checkerLauncher)
|
|
66
|
-
},
|
|
67
|
-
|
|
68
|
-
// 编辑器
|
|
69
|
-
editor: () => {
|
|
70
|
-
const editor = new Editor(this.ctx)
|
|
71
|
-
this.ctx.setEditor(editor)
|
|
72
|
-
this.$root.appendChild(editor.$el)
|
|
73
|
-
},
|
|
74
|
-
|
|
75
|
-
// 评论列表
|
|
76
|
-
list: () => {
|
|
77
|
-
// 评论列表
|
|
78
|
-
const list = new List(this.ctx)
|
|
79
|
-
this.ctx.setList(list)
|
|
80
|
-
this.$root.appendChild(list.$el)
|
|
81
|
-
|
|
82
|
-
// 评论获取
|
|
83
|
-
list.fetchComments(0)
|
|
84
|
-
},
|
|
85
|
-
|
|
86
|
-
// 侧边栏 Layer
|
|
87
|
-
sidebarLayer: () => {
|
|
88
|
-
const sidebarLayer = new SidebarLayer(this.ctx)
|
|
89
|
-
this.ctx.setSidebarLayer(sidebarLayer)
|
|
90
|
-
},
|
|
91
|
-
|
|
92
|
-
// 默认事件绑定
|
|
93
|
-
eventsDefault: () => {
|
|
94
|
-
this.initEventBind()
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// 组件初始化
|
|
99
|
-
Object.entries(Components).forEach(([name, initComponent]) => {
|
|
44
|
+
// 内建服务初始化
|
|
45
|
+
Object.entries(Services).forEach(([name, initService]) => {
|
|
100
46
|
if (Artalk.DisabledComponents.includes(name)) return
|
|
101
|
-
|
|
102
|
-
|
|
47
|
+
const obj = initService(this.ctx)
|
|
48
|
+
if (obj) this.ctx.inject(name as any, obj) // auto inject deps to ctx
|
|
103
49
|
})
|
|
104
50
|
|
|
105
51
|
// 插件初始化 (global scope)
|
|
106
|
-
Artalk.
|
|
52
|
+
Artalk.plugins.forEach(plugin => {
|
|
107
53
|
if (typeof plugin === 'function')
|
|
108
54
|
plugin(this.ctx)
|
|
109
55
|
})
|
|
110
56
|
}
|
|
111
57
|
|
|
112
|
-
/**
|
|
113
|
-
public static
|
|
114
|
-
//
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
if (typeof conf.el === 'string' && !!conf.el) {
|
|
119
|
-
try {
|
|
120
|
-
const findEl = document.querySelector<HTMLElement>(conf.el)
|
|
121
|
-
if (!findEl) throw Error(`Target element "${conf.el}" was not found.`)
|
|
122
|
-
conf.el = findEl
|
|
123
|
-
} catch (e) {
|
|
124
|
-
console.error(e)
|
|
125
|
-
throw new Error('Please check your Artalk `el` config.')
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
// 服务器配置
|
|
130
|
-
conf.server = conf.server.replace(/\/$/, '').replace(/\/api\/?$/, '')
|
|
131
|
-
|
|
132
|
-
// 默认 pageKey
|
|
133
|
-
if (!conf.pageKey) {
|
|
134
|
-
// @link http://bl.ocks.org/abernier/3070589
|
|
135
|
-
conf.pageKey = `${window.location.pathname}`
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
// 默认 pageTitle
|
|
139
|
-
if (!conf.pageTitle) {
|
|
140
|
-
conf.pageTitle = `${document.title}`
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
return conf
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
/** 事件绑定初始化 */
|
|
147
|
-
private initEventBind() {
|
|
148
|
-
// 锚点快速跳转评论
|
|
149
|
-
window.addEventListener('hashchange', () => {
|
|
150
|
-
this.ctx.listHashGotoCheck()
|
|
151
|
-
})
|
|
58
|
+
/** Init Artalk */
|
|
59
|
+
public static init(conf: Partial<ArtalkConfig>): Artalk {
|
|
60
|
+
if (this.instance) return this.instance.update(conf) // 单例模式
|
|
61
|
+
this.instance = new Artalk(conf)
|
|
62
|
+
return this.instance
|
|
63
|
+
}
|
|
152
64
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
})
|
|
65
|
+
/** Use Plugin (plugin will be called in instance `use` func) */
|
|
66
|
+
public use(plugin: ArtalkPlug) {
|
|
67
|
+
Artalk.plugins.push(plugin)
|
|
68
|
+
if (typeof plugin === 'function') plugin(this.ctx)
|
|
158
69
|
}
|
|
159
70
|
|
|
160
|
-
/**
|
|
161
|
-
|
|
162
|
-
if (
|
|
163
|
-
|
|
164
|
-
|
|
71
|
+
/** Update config of Artalk */
|
|
72
|
+
public update(conf: Partial<ArtalkConfig>) {
|
|
73
|
+
if (!Artalk.instance) throw Error('cannot call `update` function before call `load`')
|
|
74
|
+
Artalk.instance.ctx.updateConf(conf)
|
|
75
|
+
return Artalk.instance
|
|
165
76
|
}
|
|
166
77
|
|
|
167
|
-
/**
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
Layer.BodyOrgOverflow = document.body.style.overflow
|
|
171
|
-
Layer.BodyOrgPaddingRight = document.body.style.paddingRight
|
|
78
|
+
/** Reload comment list of Artalk */
|
|
79
|
+
public reload() {
|
|
80
|
+
this.ctx.listReload()
|
|
172
81
|
}
|
|
173
82
|
|
|
174
|
-
/**
|
|
83
|
+
/** Destroy instance of Artalk */
|
|
84
|
+
public destroy() {
|
|
85
|
+
if (!Artalk.instance) throw Error('cannot call `destroy` function before call `load`')
|
|
86
|
+
Artalk.instance.$root.remove()
|
|
87
|
+
delete Artalk.instance
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/** Add an event listener */
|
|
175
91
|
public on<K extends keyof EventPayloadMap>(name: K, handler: Handler<EventPayloadMap[K]>) {
|
|
176
92
|
this.ctx.on(name, handler, 'external')
|
|
177
93
|
}
|
|
178
94
|
|
|
179
|
-
/**
|
|
95
|
+
/** Remove an event listener */
|
|
180
96
|
public off<K extends keyof EventPayloadMap>(name: K, handler: Handler<EventPayloadMap[K]>) {
|
|
181
97
|
this.ctx.off(name, handler, 'external')
|
|
182
98
|
}
|
|
183
99
|
|
|
184
|
-
/**
|
|
100
|
+
/** Trigger an event */
|
|
185
101
|
public trigger<K extends keyof EventPayloadMap>(name: K, payload?: EventPayloadMap[K]) {
|
|
186
102
|
this.ctx.trigger(name, payload, 'external')
|
|
187
103
|
}
|
|
188
104
|
|
|
189
|
-
/**
|
|
190
|
-
public reload() {
|
|
191
|
-
this.ctx.listReload()
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
/** 设置暗黑模式 */
|
|
105
|
+
/** Set dark mode */
|
|
195
106
|
public setDarkMode(darkMode: boolean) {
|
|
196
107
|
this.ctx.setDarkMode(darkMode)
|
|
197
108
|
}
|
|
198
109
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
if (typeof plugin === 'function') plugin(this.ctx)
|
|
203
|
-
}
|
|
110
|
+
// ===========================
|
|
111
|
+
// Static methods
|
|
112
|
+
// ===========================
|
|
204
113
|
|
|
205
|
-
/** Use Plugin (static method
|
|
114
|
+
/** Use Plugin (static method) */
|
|
206
115
|
public static use(plugin: ArtalkPlug) {
|
|
207
|
-
this.
|
|
116
|
+
this.plugins.push(plugin)
|
|
117
|
+
if (this.instance && typeof plugin === 'function') plugin(this.instance.ctx)
|
|
208
118
|
}
|
|
209
119
|
|
|
210
|
-
/**
|
|
211
|
-
public static
|
|
212
|
-
this.
|
|
213
|
-
console.warn('`Use(...)` is deprecated, replace it with lowercase `use(...)`.')
|
|
120
|
+
/** Update config of Artalk */
|
|
121
|
+
public static update(conf: Partial<ArtalkConfig>) {
|
|
122
|
+
return this.instance?.update(conf)
|
|
214
123
|
}
|
|
215
124
|
|
|
216
|
-
/**
|
|
217
|
-
public static
|
|
218
|
-
|
|
219
|
-
|
|
125
|
+
/** Reload comment list of Artalk */
|
|
126
|
+
public static reload() {
|
|
127
|
+
this.instance?.reload()
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/** Destroy instance of Artalk */
|
|
131
|
+
public static destroy() {
|
|
132
|
+
this.instance?.destroy()
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/** Add an event listener */
|
|
136
|
+
public static on<K extends keyof EventPayloadMap>(name: K, handler: Handler<EventPayloadMap[K]>) {
|
|
137
|
+
this.instance?.on(name, handler)
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/** Remove an event listener */
|
|
141
|
+
public static off<K extends keyof EventPayloadMap>(name: K, handler: Handler<EventPayloadMap[K]>) {
|
|
142
|
+
this.instance?.off(name, handler)
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/** Trigger an event */
|
|
146
|
+
public static trigger<K extends keyof EventPayloadMap>(name: K, payload?: EventPayloadMap[K]) {
|
|
147
|
+
this.instance?.trigger(name, payload)
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/** Set dark mode */
|
|
151
|
+
public static setDarkMode(darkMode: boolean) {
|
|
152
|
+
this.instance?.setDarkMode(darkMode)
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/** Load count widget */
|
|
156
|
+
public static loadCountWidget(conf: Partial<ArtalkConfig>) {
|
|
157
|
+
const ctx: Context = new ConcreteContext(handelBaseConf(conf))
|
|
158
|
+
ctx.inject('api', new Api(ctx))
|
|
220
159
|
Stat.initCountWidget({ ctx, pvAdd: false })
|
|
221
160
|
}
|
|
161
|
+
|
|
162
|
+
/** @deprecated Please use `loadCountWidget` instead */
|
|
163
|
+
public static LoadCountWidget(conf: Partial<ArtalkConfig>) {
|
|
164
|
+
console.warn('The method `LoadCountWidget` is deprecated, please use `loadCountWidget` instead.')
|
|
165
|
+
this.loadCountWidget(conf)
|
|
166
|
+
}
|
|
222
167
|
}
|
package/src/comment/comment.ts
CHANGED
|
@@ -2,8 +2,9 @@ import { CommentData } from '~/types/artalk-data'
|
|
|
2
2
|
import Context from '~/types/context'
|
|
3
3
|
import Component from '../lib/component'
|
|
4
4
|
import * as Utils from '../lib/utils'
|
|
5
|
+
import marked from '../lib/marked'
|
|
5
6
|
import UADetect from '../lib/detect'
|
|
6
|
-
import
|
|
7
|
+
import CommentUI from './render'
|
|
7
8
|
import CommentActions from './actions'
|
|
8
9
|
|
|
9
10
|
export interface CommentConf {
|
|
@@ -18,7 +19,7 @@ export interface CommentConf {
|
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
export default class Comment extends Component {
|
|
21
|
-
private renderInstance:
|
|
22
|
+
private renderInstance: CommentUI
|
|
22
23
|
private actionInstance: CommentActions
|
|
23
24
|
|
|
24
25
|
private data: CommentData
|
|
@@ -44,7 +45,7 @@ export default class Comment extends Component {
|
|
|
44
45
|
this.nestCurt = 1 // 现在已嵌套 n 层
|
|
45
46
|
|
|
46
47
|
this.actionInstance = new CommentActions(this)
|
|
47
|
-
this.renderInstance = new
|
|
48
|
+
this.renderInstance = new CommentUI(this)
|
|
48
49
|
}
|
|
49
50
|
|
|
50
51
|
/** 渲染 UI */
|
|
@@ -119,7 +120,7 @@ export default class Comment extends Component {
|
|
|
119
120
|
childC.getRender().playFadeAnim()
|
|
120
121
|
|
|
121
122
|
// 内容限高
|
|
122
|
-
childC.getRender().
|
|
123
|
+
childC.getRender().checkHeightLimit()
|
|
123
124
|
}
|
|
124
125
|
|
|
125
126
|
/** 获取存放子评论的元素对象 */
|
|
@@ -131,7 +132,7 @@ export default class Comment extends Component {
|
|
|
131
132
|
if (this.nestCurt < this.nestMax) {
|
|
132
133
|
$children = this.getRender().renderChildrenWrap()
|
|
133
134
|
} else {
|
|
134
|
-
|
|
135
|
+
$children = this.parent!.getChildrenEl()
|
|
135
136
|
}
|
|
136
137
|
}
|
|
137
138
|
|
|
@@ -164,7 +165,7 @@ export default class Comment extends Component {
|
|
|
164
165
|
|
|
165
166
|
/** 获取评论 markdown 解析后的内容 */
|
|
166
167
|
public getContentMarked() {
|
|
167
|
-
return
|
|
168
|
+
return marked(this.ctx, this.data.content)
|
|
168
169
|
}
|
|
169
170
|
|
|
170
171
|
/** 获取格式化后的日期 */
|