artalk 2.6.4 → 2.7.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.
Files changed (316) hide show
  1. package/dist/Artalk.css +1 -1
  2. package/dist/Artalk.es.js +7756 -7432
  3. package/dist/Artalk.es.js.map +1 -0
  4. package/dist/Artalk.iife.js +2 -1
  5. package/dist/Artalk.iife.js.map +1 -0
  6. package/dist/Artalk.js +2 -1
  7. package/dist/Artalk.js.map +1 -0
  8. package/dist/ArtalkLite.css +1 -1
  9. package/dist/ArtalkLite.es.js +5576 -5252
  10. package/dist/ArtalkLite.es.js.map +1 -0
  11. package/dist/ArtalkLite.iife.js +2 -1
  12. package/dist/ArtalkLite.iife.js.map +1 -0
  13. package/dist/ArtalkLite.js +2 -1
  14. package/dist/ArtalkLite.js.map +1 -0
  15. package/dist/i18n/jp.js +1 -1
  16. package/dist/i18n/zh-TW.js +1 -1
  17. package/dist/src/api/{api-base.d.ts → _base.d.ts} +3 -7
  18. package/dist/src/api/_options.d.ts +19 -0
  19. package/dist/src/api/{request.d.ts → _request.d.ts} +3 -3
  20. package/dist/src/api/admin.d.ts +1 -1
  21. package/dist/src/api/captcha.d.ts +1 -1
  22. package/dist/src/api/comment.d.ts +2 -2
  23. package/dist/src/api/index.d.ts +2 -4
  24. package/dist/src/api/page.d.ts +3 -3
  25. package/dist/src/api/site.d.ts +2 -2
  26. package/dist/src/api/system.d.ts +13 -3
  27. package/dist/src/api/upload.d.ts +1 -1
  28. package/dist/src/api/user.d.ts +2 -2
  29. package/dist/src/artalk.d.ts +12 -37
  30. package/dist/src/comment/actions.d.ts +1 -1
  31. package/dist/src/comment/comment.d.ts +3 -4
  32. package/dist/src/comment/render.d.ts +21 -3
  33. package/dist/src/comment/renders/actions.d.ts +2 -2
  34. package/dist/src/comment/renders/avatar.d.ts +2 -2
  35. package/dist/src/comment/renders/content.d.ts +2 -2
  36. package/dist/src/comment/renders/header.d.ts +2 -2
  37. package/dist/src/comment/renders/index.d.ts +2 -2
  38. package/dist/src/comment/renders/pending.d.ts +2 -2
  39. package/dist/src/comment/renders/reply-at.d.ts +2 -2
  40. package/dist/src/comment/renders/reply-to.d.ts +2 -2
  41. package/dist/src/components/action-btn.d.ts +3 -5
  42. package/dist/src/{lib → components}/checker/admin.d.ts +1 -1
  43. package/dist/src/{lib → components}/checker/captcha-renders.d.ts +1 -1
  44. package/dist/src/{lib → components}/checker/captcha.d.ts +1 -1
  45. package/dist/src/{lib → components}/checker/index.d.ts +10 -7
  46. package/dist/src/components/dark-mode.d.ts +2 -0
  47. package/dist/src/components/dialog.d.ts +1 -3
  48. package/dist/src/components/error-dialog.d.ts +8 -0
  49. package/dist/src/components/pagination.d.ts +4 -3
  50. package/dist/src/components/read-more-btn.d.ts +3 -3
  51. package/dist/src/config.d.ts +24 -8
  52. package/dist/src/context.d.ts +16 -35
  53. package/dist/src/data.d.ts +27 -0
  54. package/dist/src/defaults.d.ts +1 -1
  55. package/dist/src/editor/editor.d.ts +14 -61
  56. package/dist/src/editor/state.d.ts +20 -0
  57. package/dist/src/i18n/en.d.ts +3 -0
  58. package/dist/src/i18n/external.d.ts +3 -0
  59. package/dist/src/i18n/index.d.ts +9 -0
  60. package/dist/src/i18n/jp.d.ts +3 -0
  61. package/dist/src/i18n/zh-CN.d.ts +1 -1
  62. package/dist/src/i18n/zh-TW.d.ts +3 -0
  63. package/dist/src/layer/index.d.ts +4 -3
  64. package/dist/src/layer/layer-manager.d.ts +9 -0
  65. package/dist/src/layer/layer.d.ts +8 -28
  66. package/dist/src/layer/scrollbar-helper.d.ts +5 -0
  67. package/dist/src/layer/sidebar-layer.d.ts +6 -6
  68. package/dist/src/layer/wrap.d.ts +13 -0
  69. package/dist/src/lib/component.d.ts +3 -8
  70. package/dist/src/lib/event-manager.d.ts +28 -0
  71. package/dist/src/lib/highlight.d.ts +1 -0
  72. package/dist/src/lib/marked-renderer.d.ts +4 -0
  73. package/dist/src/lib/marked.d.ts +4 -2
  74. package/dist/src/lib/sanitizer.d.ts +1 -0
  75. package/dist/src/lib/ui.d.ts +3 -2
  76. package/dist/src/lib/user.d.ts +8 -5
  77. package/dist/src/lib/utils.d.ts +11 -5
  78. package/dist/src/list/comment.d.ts +3 -0
  79. package/dist/src/list/layout.d.ts +23 -0
  80. package/dist/src/list/list.d.ts +13 -25
  81. package/dist/src/list/{list-nest.d.ts → nest.d.ts} +1 -1
  82. package/dist/src/list/page.d.ts +2 -0
  83. package/dist/src/list/paginator/index.d.ts +22 -7
  84. package/dist/src/list/paginator/read-more.d.ts +18 -0
  85. package/dist/src/list/paginator/up-down.d.ts +14 -0
  86. package/dist/src/main.d.ts +5 -0
  87. package/dist/src/plugins/admin-only-elem.d.ts +2 -0
  88. package/dist/src/plugins/conf-remoter.d.ts +2 -0
  89. package/dist/src/plugins/dark-mode.d.ts +2 -0
  90. package/dist/src/plugins/editor/_kit.d.ts +27 -0
  91. package/dist/src/plugins/editor/_plug.d.ts +29 -0
  92. package/dist/src/plugins/editor/_sample.d.ts +5 -0
  93. package/dist/src/plugins/editor/closable.d.ts +7 -0
  94. package/dist/src/{editor/plugs/emoticons-plug.d.ts → plugins/editor/emoticons.d.ts} +10 -16
  95. package/dist/src/plugins/editor/header-event.d.ts +6 -0
  96. package/dist/src/plugins/editor/header-link.d.ts +6 -0
  97. package/dist/src/plugins/editor/header-user.d.ts +16 -0
  98. package/dist/src/plugins/editor/index.d.ts +6 -0
  99. package/dist/src/plugins/editor/local-storage.d.ts +6 -0
  100. package/dist/src/plugins/editor/mover.d.ts +6 -0
  101. package/dist/src/plugins/editor/preview.d.ts +7 -0
  102. package/dist/src/plugins/editor/state-edit.d.ts +11 -0
  103. package/dist/src/plugins/editor/state-reply.d.ts +8 -0
  104. package/dist/src/plugins/editor/submit-add.d.ts +18 -0
  105. package/dist/src/plugins/editor/submit-btn.d.ts +5 -0
  106. package/dist/src/plugins/editor/submit.d.ts +17 -0
  107. package/dist/src/plugins/editor/textarea.d.ts +8 -0
  108. package/dist/src/plugins/editor/upload.d.ts +9 -0
  109. package/dist/src/plugins/editor-kit.d.ts +42 -0
  110. package/dist/src/plugins/index.d.ts +2 -0
  111. package/dist/src/plugins/list/copyright.d.ts +2 -0
  112. package/dist/src/plugins/list/count.d.ts +2 -0
  113. package/dist/src/plugins/list/dropdown.d.ts +2 -0
  114. package/dist/src/plugins/list/error-dialog.d.ts +2 -0
  115. package/dist/src/plugins/list/fetch.d.ts +2 -0
  116. package/dist/src/plugins/list/goto-first.d.ts +3 -0
  117. package/dist/src/plugins/list/goto.d.ts +2 -0
  118. package/dist/src/plugins/list/index.d.ts +3 -0
  119. package/dist/src/plugins/list/loading.d.ts +2 -0
  120. package/dist/src/plugins/list/no-comment.d.ts +2 -0
  121. package/dist/src/plugins/list/reach-bottom.d.ts +2 -0
  122. package/dist/src/plugins/list/sidebar-btn.d.ts +2 -0
  123. package/dist/src/plugins/list/time-ticking.d.ts +3 -0
  124. package/dist/src/plugins/list/unread-badge.d.ts +2 -0
  125. package/dist/src/plugins/list/unread.d.ts +2 -0
  126. package/dist/src/plugins/list/with-editor.d.ts +2 -0
  127. package/dist/src/plugins/markdown.d.ts +2 -0
  128. package/dist/src/plugins/stat.d.ts +13 -0
  129. package/dist/src/plugins/version-check.d.ts +2 -0
  130. package/dist/src/service.d.ts +19 -23
  131. package/dist/tests/e2e/comment-add.spec.d.ts +1 -0
  132. package/dist/types/config.d.ts +110 -0
  133. package/dist/types/context.d.ts +56 -136
  134. package/dist/types/data.d.ts +194 -0
  135. package/dist/types/editor.d.ts +76 -0
  136. package/dist/types/event.d.ts +36 -25
  137. package/dist/types/index.d.ts +7 -0
  138. package/dist/types/plugin.d.ts +2 -0
  139. package/dist/types/sidebar.d.ts +3 -0
  140. package/package.json +5 -2
  141. package/src/api/_base.ts +18 -0
  142. package/src/api/_options.ts +25 -0
  143. package/src/api/{request.ts → _request.ts} +19 -18
  144. package/src/api/admin.ts +1 -1
  145. package/src/api/captcha.ts +1 -1
  146. package/src/api/comment.ts +4 -4
  147. package/src/api/index.ts +3 -12
  148. package/src/api/page.ts +5 -5
  149. package/src/api/site.ts +2 -2
  150. package/src/api/system.ts +19 -7
  151. package/src/api/upload.ts +3 -3
  152. package/src/api/user.ts +3 -3
  153. package/src/artalk.ts +47 -99
  154. package/src/comment/actions.ts +1 -4
  155. package/src/comment/comment.ts +9 -6
  156. package/src/comment/render.ts +27 -5
  157. package/src/comment/renders/actions.ts +45 -45
  158. package/src/comment/renders/avatar.ts +7 -7
  159. package/src/comment/renders/content.ts +18 -18
  160. package/src/comment/renders/header.ts +13 -13
  161. package/src/comment/renders/index.ts +3 -3
  162. package/src/comment/renders/pending.ts +5 -5
  163. package/src/comment/renders/reply-at.ts +8 -8
  164. package/src/comment/renders/reply-to.ts +13 -13
  165. package/src/components/action-btn.ts +11 -13
  166. package/src/{lib → components}/checker/admin.ts +6 -6
  167. package/src/{lib → components}/checker/captcha-renders.ts +7 -6
  168. package/src/{lib → components}/checker/captcha.ts +1 -1
  169. package/src/{lib → components}/checker/index.ts +21 -26
  170. package/src/components/dark-mode.ts +30 -0
  171. package/src/components/dialog.ts +4 -9
  172. package/src/components/error-dialog.ts +35 -0
  173. package/src/components/pagination.ts +10 -6
  174. package/src/components/read-more-btn.ts +7 -7
  175. package/src/config.ts +60 -6
  176. package/src/context.ts +39 -144
  177. package/src/data.ts +110 -0
  178. package/src/defaults.ts +1 -1
  179. package/src/editor/editor.ts +39 -152
  180. package/src/editor/state.ts +52 -0
  181. package/src/i18n/en.ts +3 -0
  182. package/src/i18n/jp.ts +3 -0
  183. package/src/i18n/zh-CN.ts +4 -1
  184. package/src/i18n/zh-TW.ts +3 -0
  185. package/src/layer/index.ts +4 -4
  186. package/src/layer/layer-manager.ts +32 -0
  187. package/src/layer/layer.ts +20 -144
  188. package/src/layer/scrollbar-helper.ts +24 -0
  189. package/src/layer/sidebar-layer.ts +74 -64
  190. package/src/layer/wrap.ts +77 -0
  191. package/src/lib/component.ts +4 -11
  192. package/src/lib/detect.ts +1 -1
  193. package/src/lib/event-manager.ts +47 -0
  194. package/src/lib/highlight.ts +5 -0
  195. package/src/lib/marked-renderer.ts +32 -0
  196. package/src/lib/marked.ts +43 -104
  197. package/src/lib/sanitizer.ts +57 -0
  198. package/src/lib/ui.ts +22 -15
  199. package/src/lib/user.ts +21 -16
  200. package/src/lib/utils.ts +29 -18
  201. package/src/list/comment.ts +20 -0
  202. package/src/list/layout.ts +120 -0
  203. package/src/list/list.html +3 -1
  204. package/src/list/list.ts +56 -200
  205. package/src/list/{list-nest.ts → nest.ts} +1 -1
  206. package/src/list/page.ts +97 -0
  207. package/src/list/paginator/index.ts +20 -8
  208. package/src/list/paginator/read-more.ts +67 -0
  209. package/src/list/paginator/up-down.ts +51 -0
  210. package/src/main.ts +11 -0
  211. package/src/plugins/admin-only-elem.ts +40 -0
  212. package/src/plugins/conf-remoter.ts +54 -0
  213. package/src/plugins/dark-mode.ts +12 -0
  214. package/src/plugins/editor/_kit.ts +57 -0
  215. package/src/plugins/editor/_plug.ts +60 -0
  216. package/src/plugins/editor/_sample.ts +8 -0
  217. package/src/plugins/editor/closable.ts +44 -0
  218. package/src/{editor/plugs/emoticons-plug.ts → plugins/editor/emoticons.ts} +51 -52
  219. package/src/plugins/editor/header-event.ts +35 -0
  220. package/src/plugins/editor/header-link.ts +31 -0
  221. package/src/plugins/editor/header-user.ts +98 -0
  222. package/src/plugins/editor/index.ts +40 -0
  223. package/src/plugins/editor/local-storage.ts +36 -0
  224. package/src/plugins/editor/mover.ts +29 -0
  225. package/src/plugins/editor/preview.ts +41 -0
  226. package/src/plugins/editor/state-edit.ts +116 -0
  227. package/src/plugins/editor/state-reply.ts +91 -0
  228. package/src/plugins/editor/submit-add.ts +33 -0
  229. package/src/plugins/editor/submit-btn.ts +25 -0
  230. package/src/plugins/editor/submit.ts +73 -0
  231. package/src/plugins/editor/textarea.ts +55 -0
  232. package/src/plugins/editor/upload.ts +145 -0
  233. package/src/plugins/editor-kit.ts +161 -0
  234. package/src/plugins/index.ts +16 -0
  235. package/src/plugins/list/copyright.ts +16 -0
  236. package/src/plugins/list/count.ts +31 -0
  237. package/src/plugins/list/dropdown.ts +95 -0
  238. package/src/plugins/list/error-dialog.ts +22 -0
  239. package/src/plugins/list/fetch.ts +64 -0
  240. package/src/plugins/list/goto-first.ts +23 -0
  241. package/src/plugins/list/goto.ts +72 -0
  242. package/src/plugins/list/index.ts +25 -0
  243. package/src/plugins/list/loading.ts +17 -0
  244. package/src/plugins/list/no-comment.ts +25 -0
  245. package/src/plugins/list/reach-bottom.ts +46 -0
  246. package/src/plugins/list/sidebar-btn.ts +39 -0
  247. package/src/plugins/list/time-ticking.ts +22 -0
  248. package/src/plugins/list/unread-badge.ts +26 -0
  249. package/src/plugins/list/unread.ts +38 -0
  250. package/src/plugins/list/with-editor.ts +59 -0
  251. package/src/plugins/markdown.ts +10 -0
  252. package/src/plugins/stat.ts +82 -0
  253. package/src/plugins/version-check.ts +36 -0
  254. package/src/service.ts +34 -61
  255. package/src/style/comment.scss +5 -7
  256. package/src/style/editor.scss +5 -0
  257. package/src/style/list.scss +1 -1
  258. package/types/{artalk-config.d.ts → config.ts} +16 -2
  259. package/types/context.ts +84 -0
  260. package/types/{artalk-data.d.ts → data.ts} +41 -0
  261. package/types/editor.ts +95 -0
  262. package/types/event.ts +40 -0
  263. package/types/index.ts +7 -0
  264. package/types/plugin.ts +3 -0
  265. package/types/sidebar.ts +3 -0
  266. package/dist/src/comment/render-ctx.d.ts +0 -23
  267. package/dist/src/editor/edit-mode.d.ts +0 -9
  268. package/dist/src/editor/funcs.d.ts +0 -2
  269. package/dist/src/editor/index.d.ts +0 -2
  270. package/dist/src/editor/mover.d.ts +0 -8
  271. package/dist/src/editor/plug-manager.d.ts +0 -17
  272. package/dist/src/editor/plugs/editor-plug.d.ts +0 -38
  273. package/dist/src/editor/plugs/header-input-plug.d.ts +0 -13
  274. package/dist/src/editor/plugs/preview-plug.d.ts +0 -10
  275. package/dist/src/editor/plugs/upload-plug.d.ts +0 -10
  276. package/dist/src/editor/reply.d.ts +0 -9
  277. package/dist/src/editor/submit.d.ts +0 -16
  278. package/dist/src/lib/dark-mode.d.ts +0 -4
  279. package/dist/src/lib/stat.d.ts +0 -15
  280. package/dist/src/list/index.d.ts +0 -2
  281. package/dist/src/list/list-lite.d.ts +0 -77
  282. package/dist/src/list/list-ui.d.ts +0 -16
  283. package/dist/src/list/paginator/adaptors/index.d.ts +0 -12
  284. package/dist/src/list/paginator/adaptors/pagination.d.ts +0 -9
  285. package/dist/src/list/paginator/adaptors/read-more.d.ts +0 -10
  286. package/dist/src/list/paginator/holder.d.ts +0 -16
  287. package/dist/types/artalk-config.d.ts +0 -139
  288. package/dist/types/artalk-data.d.ts +0 -230
  289. package/dist/types/plug.d.ts +0 -4
  290. package/src/api/api-base.ts +0 -27
  291. package/src/comment/render-ctx.ts +0 -30
  292. package/src/editor/edit-mode.ts +0 -105
  293. package/src/editor/funcs.ts +0 -150
  294. package/src/editor/index.ts +0 -3
  295. package/src/editor/mover.ts +0 -43
  296. package/src/editor/plug-manager.ts +0 -172
  297. package/src/editor/plugs/editor-plug.ts +0 -69
  298. package/src/editor/plugs/header-input-plug.ts +0 -79
  299. package/src/editor/plugs/preview-plug.ts +0 -44
  300. package/src/editor/plugs/upload-plug.ts +0 -122
  301. package/src/editor/reply.ts +0 -62
  302. package/src/editor/submit.ts +0 -99
  303. package/src/lib/dark-mode.ts +0 -48
  304. package/src/lib/stat.ts +0 -71
  305. package/src/list/index.ts +0 -3
  306. package/src/list/list-lite.ts +0 -424
  307. package/src/list/list-ui.ts +0 -137
  308. package/src/list/paginator/adaptors/index.ts +0 -21
  309. package/src/list/paginator/adaptors/pagination.ts +0 -42
  310. package/src/list/paginator/adaptors/read-more.ts +0 -56
  311. package/src/list/paginator/holder.ts +0 -56
  312. package/types/context.d.ts +0 -142
  313. package/types/event.d.ts +0 -28
  314. package/types/plug.d.ts +0 -4
  315. /package/src/{editor/plugs/emoticons-plug.scss → plugins/editor/emoticons.scss} +0 -0
  316. /package/src/{editor/plugs/preview-plug.scss → plugins/editor/preview.scss} +0 -0
@@ -0,0 +1,18 @@
1
+ import { ApiOptions } from './_options'
2
+ import { POST, Fetch } from './_request'
3
+
4
+ abstract class ApiBase {
5
+ constructor(
6
+ protected options: ApiOptions
7
+ ) {}
8
+
9
+ protected async POST<T>(path: string, data?: {[key: string]: any}) {
10
+ return POST<T>(this.options, this.options.baseURL+path, data)
11
+ }
12
+
13
+ protected async Fetch(path: string, init: RequestInit, timeout?: number): Promise<any> {
14
+ return Fetch(this.options, this.options.baseURL+path, init, timeout)
15
+ }
16
+ }
17
+
18
+ export default ApiBase
@@ -0,0 +1,25 @@
1
+ export interface ApiOptions {
2
+ baseURL: string
3
+ siteName: string
4
+ pageKey: string
5
+ pageTitle: string
6
+ timeout?: number
7
+
8
+ // -------------------------------------------------------------------
9
+ // Hooks
10
+ // -------------------------------------------------------------------
11
+
12
+ onNeedCheckCaptcha?: (payload: {
13
+ recall: () => void
14
+ reject: () => void
15
+ data: {
16
+ imgData: string
17
+ iframe: string
18
+ }
19
+ }) => void
20
+
21
+ onNeedCheckAdmin?: (payload: {
22
+ recall: () => void
23
+ reject: () => void
24
+ }) => void
25
+ }
@@ -1,9 +1,11 @@
1
- import Context from '~/types/context'
1
+ import 'abortcontroller-polyfill/dist/polyfill-patch-fetch'
2
+
3
+ import { ApiOptions } from './_options'
2
4
  import User from '../lib/user'
3
5
  import $t from '../i18n'
4
6
 
5
7
  /** 公共请求函数 */
6
- export async function Fetch(ctx: Context, input: RequestInfo, init: RequestInit, timeout?: number): Promise<any> {
8
+ export async function Fetch(opts: ApiOptions, input: RequestInfo, init: RequestInit, timeout?: number): Promise<any> {
7
9
  // JWT
8
10
  if (User.data.token) {
9
11
  const headers = new Headers(init.headers) // 保留原有 headers
@@ -15,7 +17,7 @@ export async function Fetch(ctx: Context, input: RequestInfo, init: RequestInit,
15
17
  // init.credentials = 'include'
16
18
 
17
19
  // 请求操作
18
- const resp = await timeoutFetch(ctx, input, timeout || ctx.conf.reqTimeout || 15000, init)
20
+ const resp = await timeoutFetch(input, timeout || opts.timeout || 15000, init)
19
21
 
20
22
  const respHttpCode = resp.status
21
23
  const noAccessCodes = [401, 400]
@@ -29,7 +31,7 @@ export async function Fetch(ctx: Context, input: RequestInfo, init: RequestInit,
29
31
 
30
32
  // 重新发起请求
31
33
  const recall = (resolve, reject) => {
32
- Fetch(ctx, input, init)
34
+ Fetch(opts, input, init)
33
35
  .then(d => { resolve(d) })
34
36
  .catch(e => { reject(e) })
35
37
  }
@@ -38,19 +40,18 @@ export async function Fetch(ctx: Context, input: RequestInfo, init: RequestInit,
38
40
  if (json.data?.need_captcha) {
39
41
  // 请求需要验证码
40
42
  json = await (new Promise<any>((resolve, reject) => {
41
- ctx.checkCaptcha({
42
- imgData: json.data.img_data,
43
- iframe: json.data.iframe,
44
- onSuccess: () => { recall(resolve, reject) },
45
- onCancel: () => { reject(json) }
43
+ opts.onNeedCheckCaptcha && opts.onNeedCheckCaptcha({
44
+ data: { imgData: json.data.img_data, iframe: json.data.iframe },
45
+ recall: () => { recall(resolve, reject) },
46
+ reject: () => { reject(json) }
46
47
  })
47
48
  }))
48
49
  } else if (json.data?.need_login || isNoAccess) {
49
50
  // 请求需要管理员权限
50
51
  json = await (new Promise<any>((resolve, reject) => {
51
- ctx.checkAdmin({
52
- onSuccess: () => { recall(resolve, reject) },
53
- onCancel: () => { reject(json) }
52
+ opts.onNeedCheckAdmin && opts.onNeedCheckAdmin({
53
+ recall: () => { recall(resolve, reject) },
54
+ reject: () => { reject(json) }
54
55
  })
55
56
  }))
56
57
  }
@@ -61,20 +62,20 @@ export async function Fetch(ctx: Context, input: RequestInfo, init: RequestInit,
61
62
  }
62
63
 
63
64
  /** 公共 POST 请求 */
64
- export async function POST<T>(ctx: Context, url: string, data?: {[key: string]: any}) {
65
+ export async function POST<T>(opts: ApiOptions, url: string, data?: {[key: string]: any}) {
65
66
  const init: RequestInit = {
66
67
  method: 'POST',
67
68
  }
68
- data = { site_name: ctx.conf.site || '', ...(data || {}) } // 总是携带 site_name
69
+ data = { site_name: opts.siteName || '', ...(data || {}) } // 总是携带 site_name
69
70
  init.body = ToFormData(data)
70
71
 
71
- const json = await Fetch(ctx, url, init)
72
+ const json = await Fetch(opts, url, init)
72
73
  return ((json.data || {}) as T)
73
74
  }
74
75
 
75
76
  /** 公共 GET 请求 (无 GET 方式 API) */
76
- // export async function GET<T>(ctx: Context, url: string, data?: {[key: string]: any}) {
77
- // const json = await Fetch(ctx, url + (data ? (`?${new URLSearchParams(data)}`) : ''), {
77
+ // export async function GET<T>(opts: ApiOptions, url: string, data?: {[key: string]: any}) {
78
+ // const json = await Fetch(opts, url + (data ? (`?${new URLSearchParams(data)}`) : ''), {
78
79
  // method: 'GET',
79
80
  // })
80
81
  // return ((json.data || {}) as T)
@@ -88,7 +89,7 @@ export function ToFormData(object: {[key: string]: any}): FormData {
88
89
  }
89
90
 
90
91
  /** 我靠,fetch 一个 timeout,都要丑陋的实现 */
91
- function timeoutFetch(ctx: Context, url: RequestInfo, ms: number, opts: RequestInit) {
92
+ function timeoutFetch(url: RequestInfo, ms: number, opts: RequestInit) {
92
93
  const controller = new AbortController()
93
94
  opts.signal?.addEventListener('abort', () => controller.abort()) // 保留原有 signal 功能
94
95
  let promise = fetch(url, { ...opts, signal: controller.signal })
package/src/api/admin.ts CHANGED
@@ -1,4 +1,4 @@
1
- import ApiBase from './api-base'
1
+ import ApiBase from './_base'
2
2
 
3
3
  /**
4
4
  * 管理员 API
@@ -1,4 +1,4 @@
1
- import ApiBase from './api-base'
1
+ import ApiBase from './_base'
2
2
 
3
3
  /**
4
4
  * 验证码 API
@@ -1,6 +1,6 @@
1
- import { CommentData, ListData } from '~/types/artalk-data'
1
+ import type { CommentData, ListData } from '~/types'
2
2
  import * as Utils from '../lib/utils'
3
- import ApiBase from './api-base'
3
+ import ApiBase from './_base'
4
4
  import User from '../lib/user'
5
5
 
6
6
  /**
@@ -10,8 +10,8 @@ export default class CommentApi extends ApiBase {
10
10
  /** 评论 · 获取 */
11
11
  public get(offset: number, pageSize: number, flatMode?: boolean, paramsEditor?: (params: any) => void) {
12
12
  const params: any = {
13
- page_key: this.ctx.conf.pageKey,
14
- site_name: this.ctx.conf.site || '',
13
+ page_key: this.options.pageKey,
14
+ site_name: this.options.siteName,
15
15
  limit: pageSize,
16
16
  offset,
17
17
  }
package/src/api/index.ts CHANGED
@@ -1,6 +1,4 @@
1
- import Context from '~/types/context'
2
- import 'abortcontroller-polyfill/dist/polyfill-patch-fetch'
3
-
1
+ import { ApiOptions } from './_options'
4
2
  import comment from './comment'
5
3
  import page from './page'
6
4
  import site from './site'
@@ -17,16 +15,9 @@ const ApiComponents = {
17
15
  }
18
16
 
19
17
  class Api {
20
- protected ctx: Context
21
- public get baseURL() {
22
- return `${this.ctx.conf.server}/api`
23
- }
24
-
25
- constructor (ctx: Context) {
26
- this.ctx = ctx
27
-
18
+ constructor (opts: ApiOptions) {
28
19
  Object.entries(ApiComponents).forEach(([key, ApiComponent]) => {
29
- this[key] = new ApiComponent(this, this.ctx)
20
+ this[key] = new ApiComponent(opts)
30
21
  })
31
22
  }
32
23
  }
package/src/api/page.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { PageData, CommentData } from '~/types/artalk-data'
2
- import ApiBase from './api-base'
1
+ import type { PageData, CommentData } from '~/types'
2
+ import ApiBase from './_base'
3
3
 
4
4
  /**
5
5
  * 页面 API
@@ -24,7 +24,7 @@ export default class PageApi extends ApiBase {
24
24
  key: data.key,
25
25
  title: data.title,
26
26
  admin_only: data.admin_only,
27
- site_name: data.site_name || this.ctx.conf.site,
27
+ site_name: data.site_name || this.options.siteName,
28
28
  }
29
29
 
30
30
  const d = await this.POST<any>('/admin/page-edit', params)
@@ -55,8 +55,8 @@ export default class PageApi extends ApiBase {
55
55
  /** PV */
56
56
  public async pv() {
57
57
  const params: any = {
58
- page_key: this.ctx.conf.pageKey || '',
59
- page_title: this.ctx.conf.pageTitle || ''
58
+ page_key: this.options.pageKey || '',
59
+ page_title: this.options.pageTitle || ''
60
60
  }
61
61
 
62
62
  const p = await this.POST<any>('/pv', params)
package/src/api/site.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { SiteData } from '~/types/artalk-data'
2
- import ApiBase from './api-base'
1
+ import type { SiteData } from '~/types'
2
+ import ApiBase from './_base'
3
3
 
4
4
  /**
5
5
  * 站点 API
package/src/api/system.ts CHANGED
@@ -1,17 +1,29 @@
1
- import ArtalkConfig from '~/types/artalk-config'
2
- import ApiBase from './api-base'
3
- import { handleBackendRefConf } from '../config'
1
+ import type { ArtalkConfig } from '~/types'
2
+ import ApiBase from './_base'
3
+
4
+ interface ApiVersionInfo {
5
+ app: string
6
+ version: string
7
+ commit_hash: string
8
+ }
9
+
10
+ interface SystemConfResp {
11
+ frontend_conf: Partial<ArtalkConfig>
12
+ version: ApiVersionInfo
13
+ }
4
14
 
5
15
  /**
6
16
  * 系统 API
7
17
  */
8
18
  export default class SystemApi extends ApiBase {
9
19
  /** 获取配置 */
10
- public async conf() {
20
+ public async conf(): Promise<SystemConfResp> {
11
21
  const data = await this.POST<any>(`/conf`)
12
- const conf = (data.frontend_conf || {}) as ArtalkConfig
13
22
 
14
- return handleBackendRefConf(conf)
23
+ return {
24
+ frontend_conf: data.frontend_conf,
25
+ version: data.version,
26
+ }
15
27
  }
16
28
 
17
29
  /** 获取配置数据 */
@@ -30,7 +42,7 @@ export default class SystemApi extends ApiBase {
30
42
 
31
43
  /** 获取 API 版本信息 */
32
44
  public async version() {
33
- const resp = await fetch(`${this.api.baseURL}/version`, { method: 'POST' })
45
+ const resp = await fetch(`${this.options.baseURL}/version`, { method: 'POST' })
34
46
  const data = await resp.json()
35
47
  return data as { app: string, version: string, commit_hash: string, fe_min_version: string }
36
48
  }
package/src/api/upload.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { ToFormData } from './request'
2
- import ApiBase from './api-base'
1
+ import { ToFormData } from './_request'
2
+ import ApiBase from './_base'
3
3
  import User from '../lib/user'
4
4
 
5
5
  /**
@@ -11,7 +11,7 @@ export default class UploadApi extends ApiBase {
11
11
  const params: any = {
12
12
  name: User.data.nick,
13
13
  email: User.data.email,
14
- page_key: this.ctx.conf.pageKey,
14
+ page_key: this.options.pageKey,
15
15
  }
16
16
 
17
17
  const form = ToFormData(params)
package/src/api/user.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { UserData, NotifyData, UserDataForAdmin } from '~/types/artalk-data'
2
- import ApiBase from './api-base'
3
- import { ToFormData } from './request'
1
+ import type { UserData, NotifyData, UserDataForAdmin } from '~/types'
2
+ import ApiBase from './_base'
3
+ import { ToFormData } from './_request'
4
4
  import User from '../lib/user'
5
5
 
6
6
  /**
package/src/artalk.ts CHANGED
@@ -1,105 +1,83 @@
1
1
  import './style/main.scss'
2
2
 
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'
3
+ import type { ArtalkConfig, EventPayloadMap, ArtalkPlugin, ContextApi } from '~/types'
4
+ import type { EventHandler } from './lib/event-manager'
7
5
  import ConcreteContext from './context'
8
- import defaults from './defaults'
9
- import { handelBaseConf } from './config'
6
+ import { handelCustomConf, convertApiOptions } from './config'
10
7
  import Services from './service'
11
- import * as Stat from './lib/stat'
12
- import ListLite from './list/list-lite'
8
+ import { DefaultPlugins } from './plugins'
9
+ import * as Stat from './plugins/stat'
13
10
  import Api from './api'
14
11
 
12
+ /** Global Plugins for all instances */
13
+ const GlobalPlugins: ArtalkPlugin[] = [ ...DefaultPlugins ]
14
+
15
15
  /**
16
16
  * Artalk
17
17
  *
18
18
  * @see https://artalk.js.org
19
19
  */
20
20
  export default class Artalk {
21
- private static instance?: Artalk
22
-
23
- public static ListLite = ListLite
24
- public static readonly defaults: ArtalkConfig = defaults
25
-
26
21
  public conf!: ArtalkConfig
27
- public ctx!: Context
22
+ public ctx!: ContextApi
28
23
  public $root!: HTMLElement
29
24
 
30
25
  /** Plugins */
31
- protected static plugins: ArtalkPlug[] = [ Stat.PvCountWidget ]
32
- public static DisabledComponents: string[] = []
26
+ protected plugins: ArtalkPlugin[] = [ ...GlobalPlugins ]
33
27
 
34
28
  constructor(conf: Partial<ArtalkConfig>) {
35
- if (Artalk.instance) Artalk.destroy()
36
-
37
- // 初始化基本配置
38
- this.conf = handelBaseConf(conf)
29
+ // Init Config
30
+ this.conf = handelCustomConf(conf)
39
31
  if (this.conf.el instanceof HTMLElement) this.$root = this.conf.el
40
32
 
41
- // 初始化 Context
33
+ // Init Context
42
34
  this.ctx = new ConcreteContext(this.conf, this.$root)
43
35
 
44
- // 内建服务初始化
36
+ // Init Services
45
37
  Object.entries(Services).forEach(([name, initService]) => {
46
- if (Artalk.DisabledComponents.includes(name)) return
47
38
  const obj = initService(this.ctx)
48
39
  if (obj) this.ctx.inject(name as any, obj) // auto inject deps to ctx
49
40
  })
50
41
 
51
- // 插件初始化 (global scope)
52
- Artalk.plugins.forEach(plugin => {
53
- if (typeof plugin === 'function')
54
- plugin(this.ctx)
42
+ // Init Plugins
43
+ this.plugins.forEach(plugin => {
44
+ if (typeof plugin === 'function') plugin(this.ctx)
55
45
  })
56
- }
57
-
58
- /** Init Artalk */
59
- public static init(conf: Partial<ArtalkConfig>): Artalk {
60
- if (this.instance) Artalk.destroy()
61
- this.instance = new Artalk(conf)
62
- return this.instance
63
- }
64
46
 
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)
47
+ // Trigger inited event
48
+ this.ctx.trigger('inited')
69
49
  }
70
50
 
71
51
  /** Update config of Artalk */
72
52
  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
53
+ this.ctx.updateConf(conf)
54
+ return this
76
55
  }
77
56
 
78
57
  /** Reload comment list of Artalk */
79
58
  public reload() {
80
- this.ctx.listReload()
59
+ this.ctx.reload()
81
60
  }
82
61
 
83
62
  /** Destroy instance of Artalk */
84
63
  public destroy() {
85
- if (!Artalk.instance) throw Error('cannot call `destroy` function before call `load`')
86
- Artalk.instance.$root.remove()
87
- delete Artalk.instance
64
+ this.ctx.trigger('destroy')
65
+ this.$root.remove()
88
66
  }
89
67
 
90
68
  /** Add an event listener */
91
- public on<K extends keyof EventPayloadMap>(name: K, handler: Handler<EventPayloadMap[K]>) {
92
- this.ctx.on(name, handler, 'external')
69
+ public on<K extends keyof EventPayloadMap>(name: K, handler: EventHandler<EventPayloadMap[K]>) {
70
+ this.ctx.on(name, handler)
93
71
  }
94
72
 
95
73
  /** Remove an event listener */
96
- public off<K extends keyof EventPayloadMap>(name: K, handler: Handler<EventPayloadMap[K]>) {
97
- this.ctx.off(name, handler, 'external')
74
+ public off<K extends keyof EventPayloadMap>(name: K, handler: EventHandler<EventPayloadMap[K]>) {
75
+ this.ctx.off(name, handler)
98
76
  }
99
77
 
100
78
  /** Trigger an event */
101
79
  public trigger<K extends keyof EventPayloadMap>(name: K, payload?: EventPayloadMap[K]) {
102
- this.ctx.trigger(name, payload, 'external')
80
+ this.ctx.trigger(name, payload)
103
81
  }
104
82
 
105
83
  /** Set dark mode */
@@ -108,60 +86,30 @@ export default class Artalk {
108
86
  }
109
87
 
110
88
  // ===========================
111
- // Static methods
89
+ // Static Members
112
90
  // ===========================
113
91
 
114
- /** Use Plugin (static method) */
115
- public static use(plugin: ArtalkPlug) {
116
- this.plugins.push(plugin)
117
- if (this.instance && typeof plugin === 'function') plugin(this.instance.ctx)
118
- }
119
-
120
- /** Update config of Artalk */
121
- public static update(conf: Partial<ArtalkConfig>) {
122
- return this.instance?.update(conf)
123
- }
124
-
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)
92
+ /** Init Artalk */
93
+ public static init(conf: Partial<ArtalkConfig>): Artalk {
94
+ return new Artalk(conf)
148
95
  }
149
96
 
150
- /** Set dark mode */
151
- public static setDarkMode(darkMode: boolean) {
152
- this.instance?.setDarkMode(darkMode)
97
+ /** Use plugin, the plugin will be used when Artalk.init */
98
+ public static use(plugin: ArtalkPlugin) {
99
+ if (GlobalPlugins.includes(plugin)) return
100
+ GlobalPlugins.push(plugin)
153
101
  }
154
102
 
155
103
  /** 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))
159
- Stat.initCountWidget({ ctx, pvAdd: false })
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)
104
+ public static loadCountWidget(c: Partial<ArtalkConfig>) {
105
+ const conf = handelCustomConf(c)
106
+
107
+ Stat.initCountWidget({
108
+ getApi: () => new Api(convertApiOptions(conf)),
109
+ pageKey: conf.pageKey,
110
+ countEl: conf.countEl,
111
+ pvEl: conf.pvEl,
112
+ pvAdd: false
113
+ })
166
114
  }
167
115
  }
@@ -1,4 +1,4 @@
1
- import Comment from './comment'
1
+ import type Comment from './comment'
2
2
  import ActionBtn from '../components/action-btn'
3
3
 
4
4
  export default class CommentActions {
@@ -50,9 +50,6 @@ export default class CommentActions {
50
50
 
51
51
  // 刷新当前 Comment UI
52
52
  this.comment.setData(data)
53
-
54
- // 刷新 List UI
55
- this.ctx.listRefreshUI()
56
53
  }).catch((err) => {
57
54
  console.error(err)
58
55
  btnElem.setError(this.ctx.$t('editFail'))
@@ -1,5 +1,4 @@
1
- import { CommentData } from '~/types/artalk-data'
2
- import Context from '~/types/context'
1
+ import type { CommentData, ContextApi } from '~/types'
3
2
  import Component from '../lib/component'
4
3
  import * as Utils from '../lib/utils'
5
4
  import marked from '../lib/marked'
@@ -31,7 +30,7 @@ export default class Comment extends Component {
31
30
  private nestCurt: number // 当前嵌套层数
32
31
  private nestMax: number // 最大嵌套层数
33
32
 
34
- constructor(ctx: Context, data: CommentData, conf: CommentConf) {
33
+ constructor(ctx: ContextApi, data: CommentData, conf: CommentConf) {
35
34
  super(ctx)
36
35
 
37
36
  // 最大嵌套数
@@ -160,17 +159,21 @@ export default class Comment extends Component {
160
159
 
161
160
  /** 获取 Gravatar 头像 URL */
162
161
  public getGravatarURL() {
163
- return Utils.getGravatarURL(this.ctx, this.data.email_encrypted)
162
+ return Utils.getGravatarURL({
163
+ mirror: this.ctx.conf.gravatar.mirror,
164
+ params: this.ctx.conf.gravatar.params,
165
+ emailMD5: this.data.email_encrypted,
166
+ })
164
167
  }
165
168
 
166
169
  /** 获取评论 markdown 解析后的内容 */
167
170
  public getContentMarked() {
168
- return marked(this.ctx, this.data.content)
171
+ return marked(this.data.content)
169
172
  }
170
173
 
171
174
  /** 获取格式化后的日期 */
172
175
  public getDateFormatted() {
173
- return Utils.timeAgo(new Date(this.data.date), this.ctx)
176
+ return Utils.timeAgo(new Date(this.data.date), this.ctx.$t)
174
177
  }
175
178
 
176
179
  /** 获取用户 UserAgent 信息 */
@@ -1,15 +1,37 @@
1
+ import type Comment from './comment'
2
+ import ActionBtn from '../components/action-btn'
1
3
  import * as Utils from '../lib/utils'
2
4
  import * as Ui from '../lib/ui'
3
5
 
6
+ import * as HeightLimit from './height-limit'
4
7
  import CommentHTML from './comment.html?raw'
5
- import Comment from './comment'
6
- import RenderCtx from './render-ctx'
7
8
  import loadRenders from './renders'
8
- import * as HeightLimit from './height-limit'
9
9
 
10
- export default class CommentRender extends RenderCtx {
10
+ export default class Render {
11
+ public comment: Comment
12
+
13
+ public get ctx() { return this.comment.ctx }
14
+ public get data() { return this.comment.getData() }
15
+ public get conf() { return this.comment.conf }
16
+ public get cConf() { return this.comment.getConf() }
17
+
18
+ public $el!: HTMLElement
19
+ public $main!: HTMLElement
20
+ public $header!: HTMLElement
21
+ public $headerNick!: HTMLElement
22
+ public $headerBadgeWrap!: HTMLElement
23
+ public $body!: HTMLElement
24
+ public $content!: HTMLElement
25
+ public $childrenWrap!: HTMLElement|null
26
+ public $actions!: HTMLElement
27
+ public voteBtnUp?: ActionBtn
28
+ public voteBtnDown?: ActionBtn
29
+
30
+ public $replyTo?: HTMLElement // 回复评论内容 (平铺下显示)
31
+ public $replyAt?: HTMLElement // 回复 AT(层级嵌套下显示)
32
+
11
33
  public constructor(comment: Comment) {
12
- super(comment)
34
+ this.comment = comment
13
35
  }
14
36
 
15
37
  public render() {