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
@@ -1,51 +1,17 @@
1
- import Context from '~/types/context'
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 default class Layer extends Component {
7
- private name: string
8
- private $wrap: HTMLElement
9
- private $mask: HTMLElement
3
+ export class Layer {
4
+ private $el: HTMLElement
5
+ private wrap: LayerWrap
6
+ private onAfterHide?: () => void
10
7
 
11
- private maskClickHideEnable: boolean = true
12
-
13
- public static BodyOrgOverflow: string
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
- getWrapEl() {
48
- return this.$wrap
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
- setMaskClickHide (enable: boolean) {
90
- this.maskClickHideEnable = enable
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
- disposeNow() {
130
- this.$el.remove()
131
- this.pageBodyScrollBarShow()
132
- // this.$el dispose
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
+ }
@@ -1,14 +1,10 @@
1
- import Context from '~/types/context'
1
+ import type { ContextApi, SidebarShowPayload } from '~/types'
2
2
  import Component from '@/lib/component'
3
3
  import * as Utils from '@/lib/utils'
4
4
  import * as Ui from '@/lib/ui'
5
5
  import SidebarHTML from './sidebar-layer.html?raw'
6
6
  import User from '../lib/user'
7
- import Layer from './layer'
8
-
9
- export interface SidebarShowPayload {
10
- view?: 'comments'|'sites'|'pages'|'transfer'
11
- }
7
+ import type { Layer } from './layer'
12
8
 
13
9
  export default class SidebarLayer extends Component {
14
10
  public layer?: Layer
@@ -17,7 +13,7 @@ export default class SidebarLayer extends Component {
17
13
  public $iframeWrap: HTMLElement
18
14
  public $iframe?: HTMLIFrameElement
19
15
 
20
- constructor(ctx: Context) {
16
+ constructor(ctx: ContextApi) {
21
17
  super(ctx)
22
18
 
23
19
  this.$el = Utils.createElement(SidebarHTML)
@@ -40,72 +36,31 @@ export default class SidebarLayer extends Component {
40
36
  this.$el.style.transform = '' // 动画清除,防止二次打开失效
41
37
 
42
38
  // 获取 Layer
43
- if (this.layer == null) {
44
- this.layer = new Layer(this.ctx, 'sidebar', this.$el)
45
- this.layer.afterHide = () => {
46
- // 防止评论框被吞
47
- if (this.ctx.conf.editorTravel === true) {
48
- this.ctx.editorTravelBack()
49
- }
50
- }
51
- }
52
- this.layer.show()
53
-
54
- // viewWrap 滚动条归位
55
- // this.$viewWrap.scrollTo(0, 0)
39
+ this.initLayer()
40
+ this.layer!.show()
56
41
 
57
42
  // 管理员身份验证 (若身份失效,弹出验证窗口)
58
- ;(async () => {
59
- const resp = await this.ctx.getApi().user.loginStatus()
60
- if (resp.is_admin && !resp.is_login) {
61
- this.layer?.hide()
62
- this.firstShow = true
63
-
64
- this.ctx.checkAdmin({
65
- onSuccess: () => {
66
- setTimeout(() => {
67
- this.show(conf)
68
- }, 500)
69
- },
70
- onCancel: () => {}
71
- })
72
- }
73
- })()
43
+ this.authCheck({
44
+ onSuccess: () => this.show(conf) // retry show after auth check
45
+ })
74
46
 
75
47
  // 第一次加载
76
48
  if (this.firstShow) {
77
49
  this.$iframeWrap.innerHTML = ''
78
- this.$iframe = Utils.createElement<HTMLIFrameElement>('<iframe></iframe>')
79
-
80
- // 准备 Iframe 参数
81
- const baseURL = (import.meta.env.DEV) ? 'http://localhost:23367/'
82
- : Utils.getURLBasedOnApi(this.ctx, '/sidebar/')
83
-
84
- const query: any = {
85
- pageKey: this.conf.pageKey,
86
- site: this.conf.site || '',
87
- user: JSON.stringify(User.data),
88
- time: +new Date()
89
- }
90
-
91
- if (conf.view) query.view = conf.view
92
- if (this.conf.darkMode) query.darkMode = '1'
93
- if (typeof this.conf.locale === 'string') query.locale = this.conf.locale
94
-
95
- const urlParams = new URLSearchParams(query);
96
- this.iframeLoad(`${baseURL}?${urlParams.toString()}`)
97
-
50
+ this.$iframe = this.createIframe(conf.view)
98
51
  this.$iframeWrap.append(this.$iframe)
99
52
  this.firstShow = false
100
53
  } else {
54
+ const $iframe = this.$iframe!
55
+
101
56
  // 夜间模式
102
- const isIframeSrcDarkMode = this.$iframe!.src.includes('darkMode=1')
57
+ const isIframeSrcDarkMode = $iframe.src.includes('darkMode=1')
103
58
 
104
59
  if (this.conf.darkMode && !isIframeSrcDarkMode)
105
- this.iframeLoad(`${this.$iframe!.src}&darkMode=1`)
60
+ this.iframeLoad($iframe, `${this.$iframe!.src}&darkMode=1`)
106
61
 
107
62
  if (!this.conf.darkMode && isIframeSrcDarkMode)
108
- this.iframeLoad(this.$iframe!.src.replace('&darkMode=1', ''))
63
+ this.iframeLoad($iframe, this.$iframe!.src.replace('&darkMode=1', ''))
109
64
  }
110
65
 
111
66
  // 执行滑动显示动画
@@ -115,7 +70,7 @@ export default class SidebarLayer extends Component {
115
70
 
116
71
  // 清空 unread
117
72
  setTimeout(() => {
118
- this.ctx.updateNotifies([])
73
+ this.ctx.getData().updateUnreads([])
119
74
  }, 0)
120
75
 
121
76
  this.ctx.trigger('sidebar-show')
@@ -131,14 +86,69 @@ export default class SidebarLayer extends Component {
131
86
  this.ctx.trigger('sidebar-hide')
132
87
  }
133
88
 
134
- private iframeLoad(src: string) {
135
- if (!this.$iframe) return
89
+ // --------------------------------------------------
90
+
91
+ private async authCheck(opts: { onSuccess: () => void }) {
92
+ const resp = await this.ctx.getApi().user.loginStatus()
93
+ if (resp.is_admin && !resp.is_login) {
94
+ this.firstShow = true
95
+
96
+ this.ctx.checkAdmin({
97
+ onSuccess: () => {
98
+ setTimeout(() => {
99
+ opts.onSuccess()
100
+ }, 500)
101
+ },
102
+ onCancel: () => {
103
+ this.hide()
104
+ }
105
+ })
106
+ }
107
+ }
108
+
109
+ private initLayer() {
110
+ if (this.layer) return
111
+
112
+ this.layer = this.ctx.get('layerManager').create('sidebar', this.$el)
113
+ this.layer.setOnAfterHide(() => {
114
+ // 防止评论框被吞
115
+ this.ctx.editorResetState()
116
+ })
117
+ }
118
+
119
+ private createIframe(view?: string) {
120
+ const $iframe = Utils.createElement<HTMLIFrameElement>('<iframe></iframe>')
121
+
122
+ // 准备 Iframe 参数
123
+ const baseURL = (import.meta.env.DEV) ? 'http://localhost:23367/'
124
+ : Utils.getURLBasedOnApi({
125
+ base: this.ctx.conf.server,
126
+ path: '/sidebar/',
127
+ })
128
+
129
+ const query: any = {
130
+ pageKey: this.conf.pageKey,
131
+ site: this.conf.site || '',
132
+ user: JSON.stringify(User.data),
133
+ time: +new Date()
134
+ }
135
+
136
+ if (view) query.view = view
137
+ if (this.conf.darkMode) query.darkMode = '1'
138
+ if (typeof this.conf.locale === 'string') query.locale = this.conf.locale
139
+
140
+ const urlParams = new URLSearchParams(query);
141
+ this.iframeLoad($iframe, `${baseURL}?${urlParams.toString()}`)
142
+
143
+ return $iframe
144
+ }
136
145
 
137
- this.$iframe.src = src
146
+ private iframeLoad($iframe: HTMLIFrameElement, src: string) {
147
+ $iframe.src = src
138
148
 
139
149
  // 加载动画
140
150
  Ui.showLoading(this.$iframeWrap)
141
- this.$iframe.onload = () => {
151
+ $iframe.onload = () => {
142
152
  Ui.hideLoading(this.$iframeWrap)
143
153
  }
144
154
  }
@@ -0,0 +1,77 @@
1
+ import * as Utils from '@/lib/utils'
2
+ import { getScrollbarHelper } from './scrollbar-helper'
3
+
4
+ export class LayerWrap {
5
+ private $wrap: HTMLElement
6
+ private $mask: HTMLElement
7
+ private allowMaskClose: boolean = true
8
+ private items: HTMLElement[] = []
9
+
10
+ constructor() {
11
+ this.$wrap = Utils.createElement(
12
+ `<div class="atk-layer-wrap" style="display: none;"><div class="atk-layer-mask"></div></div>`
13
+ )
14
+ this.$mask = this.$wrap.querySelector<HTMLElement>('.atk-layer-mask')!
15
+ }
16
+
17
+ createItem(name: string, el?: HTMLElement) {
18
+ if (!el) {
19
+ el = document.createElement('div')
20
+ el.classList.add('atk-layer-item')
21
+ el.setAttribute('data-layer-name', name)
22
+ el.style.display = 'none'
23
+ }
24
+ this.$wrap.appendChild(el)
25
+ this.items.push(el)
26
+ return el
27
+ }
28
+
29
+ getWrap() {
30
+ return this.$wrap
31
+ }
32
+
33
+ getMask() {
34
+ return this.$mask
35
+ }
36
+
37
+ setMaskClose(enabled: boolean) {
38
+ this.allowMaskClose = enabled
39
+ }
40
+
41
+ show() {
42
+ this.$wrap.style.display = 'block'
43
+ this.$mask.style.display = 'block'
44
+ this.$mask.classList.add('atk-fade-in')
45
+ this.$mask.onclick = () => {
46
+ if (this.allowMaskClose) this.hide()
47
+ }
48
+ getScrollbarHelper().lock()
49
+ }
50
+
51
+ hide(callback?: () => void) {
52
+ // if wrap contains more than one item, do not hide entire wrap
53
+ if (this.items.filter(e => e.isConnected && e.style.display !== 'none').length > 1) {
54
+ callback && callback()
55
+ return
56
+ }
57
+
58
+ const onAfterHide = () => {
59
+ this.$wrap.style.display = 'none'
60
+ this.$wrap.classList.remove('atk-fade-out')
61
+
62
+ callback && callback()
63
+
64
+ getScrollbarHelper().unlock()
65
+
66
+ this.$wrap.onanimationend = null
67
+ }
68
+
69
+ // perform animation
70
+ this.$wrap.classList.add('atk-fade-out')
71
+ if (window.getComputedStyle(this.$wrap)['animation-name'] !== 'none') {
72
+ this.$wrap.onanimationend = () => onAfterHide()
73
+ } else {
74
+ onAfterHide()
75
+ }
76
+ }
77
+ }
@@ -1,19 +1,12 @@
1
- import ArtalkConfig from '~/types/artalk-config'
2
- import Context from '~/types/context'
3
- import { I18n } from '../i18n'
1
+ import type { ArtalkConfig, ContextApi } from '~/types'
4
2
 
5
3
  export default abstract class Component {
6
4
  public $el!: HTMLElement
7
-
8
- public ctx: Context
9
5
  public readonly conf: ArtalkConfig
10
6
 
11
- public constructor(ctx: Context) {
12
- this.ctx = ctx
7
+ public constructor(
8
+ public ctx: ContextApi
9
+ ) {
13
10
  this.conf = ctx.conf
14
11
  }
15
-
16
- public $t(key: keyof I18n, args: {[key: string]: string} = {}): string {
17
- return this.ctx.$t(key, args)
18
- }
19
12
  }
package/src/lib/detect.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  const win = (window as any) || {}
2
2
  const nav = navigator || {}
3
3
 
4
- function Detect (userAgent?: string) {
4
+ function Detect(userAgent?: string) {
5
5
  const u = String(userAgent || nav.userAgent)
6
6
  const dest = {
7
7
  os: '',
@@ -0,0 +1,47 @@
1
+ export type EventHandler<T> = (payload: T) => void
2
+ export interface Event<PayloadMap, K extends keyof PayloadMap = keyof PayloadMap> extends EventOptions {
3
+ name: K
4
+ handler: EventHandler<PayloadMap[K]>
5
+ }
6
+ export interface EventOptions {
7
+ once?: boolean
8
+ }
9
+
10
+ export interface EventManagerFuncs<PayloadMap> {
11
+ on<K extends keyof PayloadMap>(name: K, handler: EventHandler<PayloadMap[K]>, opts?: EventOptions): void
12
+ off<K extends keyof PayloadMap>(name: K, handler: EventHandler<PayloadMap[K]>): void
13
+ trigger<K extends keyof PayloadMap>(name: K, payload?: PayloadMap[K]): void
14
+ }
15
+
16
+ export default class EventManager<PayloadMap> implements EventManagerFuncs<PayloadMap> {
17
+ private events: Event<PayloadMap>[] = []
18
+
19
+ /**
20
+ * Add an event listener for a specific event name
21
+ */
22
+ public on<K extends keyof PayloadMap>(name: K, handler: EventHandler<PayloadMap[K]>, opts: EventOptions = {}) {
23
+ this.events.push({ name, handler: handler as EventHandler<PayloadMap[keyof PayloadMap]>, ...opts })
24
+ }
25
+
26
+ /**
27
+ * Remove an event listener for a specific event name and handler
28
+ */
29
+ public off<K extends keyof PayloadMap>(name: K, handler: EventHandler<PayloadMap[K]>) {
30
+ if (!handler) return // not allow remove all events with same name
31
+ this.events = this.events.filter((evt) =>
32
+ !(evt.name === name && evt.handler === handler))
33
+ }
34
+
35
+ /**
36
+ * Trigger an event with an optional payload
37
+ */
38
+ public trigger<K extends keyof PayloadMap>(name: K, payload?: PayloadMap[K]) {
39
+ this.events
40
+ .slice(0) // make a copy, in case listeners are removed while iterating
41
+ .filter((evt) => evt.name === name && typeof evt.handler === 'function')
42
+ .forEach((evt) => {
43
+ if (evt.once) this.off(name, evt.handler)
44
+ evt.handler(payload!)
45
+ })
46
+ }
47
+ }
@@ -0,0 +1,5 @@
1
+ import hanabi from 'hanabi'
2
+
3
+ export function renderCode(code: string) {
4
+ return hanabi(code)
5
+ }
@@ -0,0 +1,32 @@
1
+ import { marked as libMarked } from 'marked'
2
+ import { renderCode } from './highlight'
3
+
4
+ export function getRenderer() {
5
+ const renderer = new libMarked.Renderer()
6
+ renderer.link = markedLinkRenderer(renderer, renderer.link)
7
+ renderer.code = markedCodeRenderer()
8
+ return renderer
9
+ }
10
+
11
+ export const markedLinkRenderer = (renderer: any, orgLinkRenderer: Function) => (href: string, title: string, text: string): string => {
12
+ const localLink = href?.startsWith(`${window.location.protocol}//${window.location.hostname}`);
13
+ const html = orgLinkRenderer.call(renderer, href, title, text);
14
+ return html.replace(/^<a /, `<a target="_blank" ${!localLink ? `rel="noreferrer noopener nofollow"` : ''} `);
15
+ }
16
+
17
+ export const markedCodeRenderer = () => (block: string, lang: string | undefined): string => {
18
+ // Colorize the block only if the language is known to highlight.js
19
+ const realLang = (!lang ? 'plaintext' : lang)
20
+ let colorized = block
21
+ if ((window as any).hljs) {
22
+ if (realLang && (window as any).hljs.getLanguage(realLang)) {
23
+ colorized = (window as any).hljs.highlight(realLang, block).value
24
+ }
25
+ } else {
26
+ colorized = renderCode(block)
27
+ }
28
+
29
+ return `<pre rel="${realLang}">\n`
30
+ + `<code class="hljs language-${realLang}">${colorized.replace(/&amp;/g, '&')}</code>\n`
31
+ + `</pre>`
32
+ }