artalk 2.2.0 → 2.2.3

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/index.html CHANGED
@@ -29,6 +29,9 @@
29
29
  body.dark-mode .to-night { background: #fff;border: 1px solid #2d3235;color: #0083ff; }
30
30
  .to-top { right: 25px; }
31
31
  </style>
32
+ <!--<link rel="stylesheet"
33
+ href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.5.1/styles/arta.min.css">
34
+ <script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/11.5.1/highlight.min.js"></script>-->
32
35
  </head>
33
36
  <body>
34
37
  <div class="card billboard atk-fade-in">
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "artalk",
3
- "version": "2.2.0",
3
+ "version": "2.2.3",
4
4
  "backendMinVersion": "2.1.1",
5
5
  "license": "LGPL-3.0",
6
6
  "description": "A Selfhosted Comment System",
package/src/api/index.ts CHANGED
@@ -119,7 +119,7 @@ export default class Api {
119
119
 
120
120
  /** 用户 · 登录状态 */
121
121
  public async loginStatus() {
122
- const data = await GET<any>(this.ctx, `${this.baseURL}/login-status`)
122
+ const data = await POST<any>(this.ctx, `${this.baseURL}/login-status`)
123
123
  return (data || { is_login: false }) as { is_login: boolean }
124
124
  }
125
125
 
@@ -299,19 +299,19 @@ export default class Api {
299
299
 
300
300
  /** 验证码 · 获取 */
301
301
  public async captchaGet() {
302
- const data = await GET<any>(this.ctx, `${this.baseURL}/captcha/refresh`)
302
+ const data = await POST<any>(this.ctx, `${this.baseURL}/captcha/refresh`)
303
303
  return (data.img_data || '') as string
304
304
  }
305
305
 
306
306
  /** 验证码 · 检验 */
307
307
  public async captchaCheck(value: string) {
308
- const data = await GET<any>(this.ctx, `${this.baseURL}/captcha/check`, { value })
308
+ const data = await POST<any>(this.ctx, `${this.baseURL}/captcha/check`, { value })
309
309
  return (data.img_data || '') as string
310
310
  }
311
311
 
312
312
  /** 验证码 · 状态 */
313
313
  public async captchaStatus() {
314
- const data = await GET<any>(this.ctx, `${this.baseURL}/captcha/status`)
314
+ const data = await POST<any>(this.ctx, `${this.baseURL}/captcha/status`)
315
315
  return (data || { is_pass: false }) as { is_pass: boolean }
316
316
  }
317
317
  }
@@ -317,7 +317,7 @@ export default class Comment extends Component {
317
317
  }
318
318
 
319
319
  getIsRoot() {
320
- return this.parent === null
320
+ return this.data.rid === 0
321
321
  }
322
322
 
323
323
  getChildren() {
@@ -551,6 +551,8 @@ export default class Editor extends Component {
551
551
  const $travelPlace = Utils.createElement('<div></div>')
552
552
  $afterEl.after($travelPlace)
553
553
  $travelPlace.replaceWith(this.$el)
554
+
555
+ this.$el.classList.add('atk-fade-in') // 添加渐入动画
554
556
  }
555
557
 
556
558
  travelBack () {
@@ -93,6 +93,7 @@ export default class SidebarLayer extends Component {
93
93
  + `?pageKey=${encodeURIComponent(this.conf.pageKey)}`
94
94
  + `&site=${encodeURIComponent(this.conf.site || '')}`
95
95
  + `&user=${userData}`
96
+ + `&time=${+new Date()}`
96
97
  + `&referer=${encodeURIComponent(`${location.protocol}//${location.host}${location.pathname}`)}`
97
98
  + `${((this.conf.darkMode) ? `&darkMode=1` : ``)}`)
98
99
 
package/src/lib/utils.ts CHANGED
@@ -150,25 +150,34 @@ export function initMarked(ctx: Context) {
150
150
  return html.replace(/^<a /, `<a target="_blank" ${!localLink ? `rel="noreferrer noopener nofollow"` : ''} `);
151
151
  }
152
152
 
153
+ renderer.code = (block, lang) => {
154
+ // Colorize the block only if the language is known to highlight.js
155
+ const realLang = (!lang ? 'plaintext' : lang)
156
+ let colorized = block
157
+ if ((window as any).hljs) {
158
+ if (realLang && (window as any).hljs.getLanguage(realLang)) {
159
+ colorized = (window as any).hljs.highlight(realLang, block).value
160
+ }
161
+ } else {
162
+ colorized = hanabi(block)
163
+ }
164
+
165
+ return `<pre rel="${realLang}">\n`
166
+ + `<code class="hljs language-${realLang}">${colorized.replace(/&amp;/g, '&')}</code>\n`
167
+ + `</pre>`
168
+ }
169
+
153
170
  // @see https://github.com/markedjs/marked/blob/4afb228d956a415624c4e5554bb8f25d047676fe/src/Tokenizer.js#L329
154
171
  const nMarked = libMarked
155
172
  libMarked.setOptions({
156
173
  renderer,
157
- highlight: (code) => hanabi(code),
158
174
  pedantic: false,
159
175
  gfm: true,
160
176
  breaks: true,
161
177
  smartLists: true,
162
178
  smartypants: true,
163
179
  xhtml: false,
164
- sanitize: true,
165
- sanitizer: (html) => insane(html, {
166
- ...insane.defaults,
167
- allowedAttributes: {
168
- ...insane.defaults.allowedAttributes,
169
- img: ['src', 'atk-emoticon']
170
- },
171
- }),
180
+ sanitize: false,
172
181
  silent: true,
173
182
  })
174
183
 
@@ -177,7 +186,49 @@ export function initMarked(ctx: Context) {
177
186
 
178
187
  /** 解析 markdown */
179
188
  export function marked(ctx: Context, src: string): string {
180
- return ctx.markedInstance.parse(src)
189
+ // @link https://gist.github.com/lionel-rowe/bb384465ba4e4c81a9c8dada84167225
190
+ return insane(ctx.markedInstance.parse(src), {
191
+ allowedClasses: {},
192
+ allowedSchemes: ['http', 'https', 'mailto'],
193
+ allowedTags: [
194
+ 'a', 'abbr', 'article', 'b', 'blockquote', 'br', 'caption', 'code', 'del', 'details', 'div', 'em',
195
+ 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'ins', 'kbd', 'li', 'main', 'mark',
196
+ 'ol', 'p', 'pre', 'section', 'span', 'strike', 'strong', 'sub', 'summary', 'sup', 'table',
197
+ 'tbody', 'td', 'th', 'thead', 'tr', 'u', 'ul'
198
+ ],
199
+ allowedAttributes: {
200
+ '*': ['title', 'accesskey'],
201
+ a: ['href', 'name', 'target', 'aria-label'],
202
+ img: ['src', 'alt', 'title', 'atk-emoticon', 'aria-label'],
203
+ // for code highlight
204
+ code: ['class'],
205
+ span: ['class', 'style'],
206
+ },
207
+ filter: node => {
208
+ // allow hljs style
209
+ const allowed = [
210
+ [ 'code', /^hljs\W+language-(.*)$/ ],
211
+ [ 'span', /^(hljs-.*)$/ ]
212
+ ]
213
+ allowed.forEach(([ tag, reg ]) => {
214
+ if (
215
+ node.tag === tag
216
+ && !!node.attrs.class
217
+ && !(reg as RegExp).test(node.attrs.class)
218
+ ) {
219
+ delete node.attrs.class
220
+ }
221
+ })
222
+
223
+ // allow <span> set color sty
224
+ if (node.tag === 'span' && !!node.attrs.style
225
+ && !/^color:(\W+)?#[0-9a-f]{3,6};?$/i.test(node.attrs.style)) {
226
+ delete node.attrs.style
227
+ }
228
+
229
+ return true
230
+ }
231
+ })
181
232
  }
182
233
 
183
234
  /** 获取修正后的 UserAgent */
@@ -7,28 +7,46 @@
7
7
  }
8
8
 
9
9
  .artalk, .atk-layer-wrap {
10
+ line-height: @line-height;
11
+ color: var(--at-color-font);
12
+ font-family: @font-family;
13
+ word-wrap: break-word;
14
+ word-break: break-all;
15
+
10
16
  * {
11
17
  box-sizing: border-box;
12
- line-height: @line-height;
18
+ }
19
+
20
+ input, textarea, button, optgroup, select {
21
+ font-family: inherit;
22
+ }
23
+
24
+ @codeFont: Source Code Pro,courier new,Input Mono,PT Mono,SFMono-Regular,Consolas,Monaco,Menlo,PingFang SC,Liberation Mono,Microsoft YaHei,Courier,monospace;
25
+
26
+ code {
27
+ font-family: @codeFont;
28
+ margin: 0 .3em;
29
+ padding: .1em .2em;
30
+ background-color: var(--at-color-bg-grey);
13
31
  color: var(--at-color-font);
14
- font-family: @font-family;
15
- word-wrap: break-word;
16
- word-break: break-all;
32
+ border-radius: @block-radius;
17
33
  }
18
34
 
19
35
  pre {
20
- padding: 10px;
36
+ margin-top: 10px;
37
+ margin-bottom: 0;
38
+ line-height: 0;
39
+ }
40
+
41
+ pre code {
42
+ * { font-family: @codeFont; }
21
43
  line-height: @line-height;
44
+ display: block;
45
+ padding: 10px 15px;
46
+ white-space: pre-wrap;
22
47
  background-color: var(--at-color-bg-grey);
23
48
  color: var(--at-color-font);
24
- padding: 10px 15px;
25
- border-radius: @block-radius;
26
49
  margin: 0;
27
- font-family: Source Code Pro,courier new,Input Mono,PT Mono,SFMono-Regular,Consolas,Monaco,Menlo,PingFang SC,Liberation Mono,Microsoft YaHei,Courier,monospace;
28
-
29
- code {
30
- white-space: pre-wrap;
31
- }
32
50
  }
33
51
 
34
52
  a {
@@ -55,6 +73,28 @@
55
73
  img {
56
74
  max-width: 100%;
57
75
  }
76
+
77
+ table {
78
+ width: 100%;
79
+ border-collapse: collapse;
80
+ border-spacing: 0;
81
+ margin-bottom: 1.5em;
82
+ font-size: .96em
83
+ }
84
+
85
+ td, th {
86
+ text-align: left;
87
+ padding: 4px 8px 4px 10px;
88
+ border: 1px solid var(--at-color-border)
89
+ }
90
+
91
+ td {
92
+ vertical-align: top
93
+ }
94
+
95
+ tr:nth-child(even) {
96
+ background-color: var(--at-color-bg-grey);
97
+ }
58
98
  }
59
99
 
60
100
  .atk-hide {