artalk 2.8.4 → 2.8.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/Artalk.mjs CHANGED
@@ -155,11 +155,14 @@ class HttpClient {
155
155
  /* Json */
156
156
  ];
157
157
  const responseFormat = format || requestParams.format;
158
- return this.customFetch(`${baseUrl || this.baseUrl || ""}${path}${queryString ? `?${queryString}` : ""}`, __spreadProps(__spreadValues({}, requestParams), {
159
- headers: __spreadValues(__spreadValues({}, requestParams.headers || {}), type && type !== "multipart/form-data" ? { "Content-Type": type } : {}),
160
- signal: (cancelToken ? this.createAbortSignal(cancelToken) : requestParams.signal) || null,
161
- body: typeof body === "undefined" || body === null ? null : payloadFormatter(body)
162
- })).then((response) => __async(this, null, function* () {
158
+ return this.customFetch(
159
+ `${baseUrl || this.baseUrl || ""}${path}${queryString ? `?${queryString}` : ""}`,
160
+ __spreadProps(__spreadValues({}, requestParams), {
161
+ headers: __spreadValues(__spreadValues({}, requestParams.headers || {}), type && type !== "multipart/form-data" ? { "Content-Type": type } : {}),
162
+ signal: (cancelToken ? this.createAbortSignal(cancelToken) : requestParams.signal) || null,
163
+ body: typeof body === "undefined" || body === null ? null : payloadFormatter(body)
164
+ })
165
+ ).then((response) => __async(this, null, function* () {
163
166
  const r = response;
164
167
  r.data = null;
165
168
  r.error = null;
@@ -198,7 +201,9 @@ class HttpClient {
198
201
  toQueryString(rawQuery) {
199
202
  const query = rawQuery || {};
200
203
  const keys = Object.keys(query).filter((key) => "undefined" !== typeof query[key]);
201
- return keys.map((key) => Array.isArray(query[key]) ? this.addArrayQueryParam(query, key) : this.addQueryParam(query, key)).join("&");
204
+ return keys.map(
205
+ (key) => Array.isArray(query[key]) ? this.addArrayQueryParam(query, key) : this.addQueryParam(query, key)
206
+ ).join("&");
202
207
  }
203
208
  addQueryParams(rawQuery) {
204
209
  const queryString = this.toQueryString(rawQuery);
@@ -222,6 +227,133 @@ class HttpClient {
222
227
  let Api$1 = class Api extends HttpClient {
223
228
  constructor() {
224
229
  super(...arguments);
230
+ __publicField(this, "auth", {
231
+ /**
232
+ * @description Login by email with verify code (Need send email verify code first) or password
233
+ *
234
+ * @tags Auth
235
+ * @name LoginByEmail
236
+ * @summary Login by email
237
+ * @request POST:/auth/email/login
238
+ * @response `200` `HandlerResponseUserLogin` OK
239
+ * @response `400` `(HandlerMap & {
240
+ msg?: string,
241
+
242
+ })` Bad Request
243
+ * @response `500` `(HandlerMap & {
244
+ msg?: string,
245
+
246
+ })` Internal Server Error
247
+ */
248
+ loginByEmail: (data, params = {}) => this.request(__spreadValues({
249
+ path: `/auth/email/login`,
250
+ method: "POST",
251
+ body: data,
252
+ type: "application/json",
253
+ format: "json"
254
+ }, params)),
255
+ /**
256
+ * @description Register by email and verify code (if user exists, will update user, like forget password. Need send email verify code first)
257
+ *
258
+ * @tags Auth
259
+ * @name RegisterByEmail
260
+ * @summary Register by email
261
+ * @request POST:/auth/email/register
262
+ * @response `200` `HandlerResponseUserLogin` OK
263
+ * @response `400` `(HandlerMap & {
264
+ msg?: string,
265
+
266
+ })` Bad Request
267
+ * @response `500` `(HandlerMap & {
268
+ msg?: string,
269
+
270
+ })` Internal Server Error
271
+ */
272
+ registerByEmail: (data, params = {}) => this.request(__spreadValues({
273
+ path: `/auth/email/register`,
274
+ method: "POST",
275
+ body: data,
276
+ type: "application/json",
277
+ format: "json"
278
+ }, params)),
279
+ /**
280
+ * @description Send email including verify code to user
281
+ *
282
+ * @tags Auth
283
+ * @name SendVerifyEmail
284
+ * @summary Send verify email
285
+ * @request POST:/auth/email/send
286
+ * @response `200` `(HandlerMap & {
287
+ msg?: string,
288
+
289
+ })` OK
290
+ * @response `400` `(HandlerMap & {
291
+ msg?: string,
292
+
293
+ })` Bad Request
294
+ * @response `500` `(HandlerMap & {
295
+ msg?: string,
296
+
297
+ })` Internal Server Error
298
+ */
299
+ sendVerifyEmail: (data, params = {}) => this.request(__spreadValues({
300
+ path: `/auth/email/send`,
301
+ method: "POST",
302
+ body: data,
303
+ type: "application/json",
304
+ format: "json"
305
+ }, params)),
306
+ /**
307
+ * @description Get all users with same email, if there are more than one user with same email, need merge
308
+ *
309
+ * @tags Auth
310
+ * @name CheckDataMerge
311
+ * @summary Check data merge
312
+ * @request GET:/auth/merge
313
+ * @secure
314
+ * @response `200` `HandlerResponseAuthDataMergeCheck` OK
315
+ * @response `400` `(HandlerMap & {
316
+ msg?: string,
317
+
318
+ })` Bad Request
319
+ * @response `500` `(HandlerMap & {
320
+ msg?: string,
321
+
322
+ })` Internal Server Error
323
+ */
324
+ checkDataMerge: (params = {}) => this.request(__spreadValues({
325
+ path: `/auth/merge`,
326
+ method: "GET",
327
+ secure: true,
328
+ format: "json"
329
+ }, params)),
330
+ /**
331
+ * @description This function is to solve the problem of multiple users with the same email address, should be called after user login and then check, and perform data merge.
332
+ *
333
+ * @tags Auth
334
+ * @name ApplyDataMerge
335
+ * @summary Apply data merge
336
+ * @request POST:/auth/merge
337
+ * @secure
338
+ * @response `200` `HandlerResponseAuthDataMergeApply` OK
339
+ * @response `400` `(HandlerMap & {
340
+ msg?: string,
341
+
342
+ })` Bad Request
343
+ * @response `500` `(HandlerMap & {
344
+ msg?: string,
345
+
346
+ })` Internal Server Error
347
+ */
348
+ applyDataMerge: (data, params = {}) => this.request(__spreadValues({
349
+ path: `/auth/merge`,
350
+ method: "POST",
351
+ body: data,
352
+ secure: true,
353
+ type: "application/json",
354
+ format: "json"
355
+ }, params))
356
+ });
225
357
  __publicField(this, "cache", {
226
358
  /**
227
359
  * @description Flush all cache on the server
@@ -482,6 +614,24 @@ let Api$1 = class Api extends HttpClient {
482
614
  method: "GET",
483
615
  format: "json"
484
616
  }, params)),
617
+ /**
618
+ * @description Get social login providers
619
+ *
620
+ * @tags System
621
+ * @name GetSocialLoginProviders
622
+ * @summary Get Social Login Providers
623
+ * @request GET:/conf/auth/providers
624
+ * @response `200` `HandlerResponseConfAuthProviders` OK
625
+ * @response `404` `(HandlerMap & {
626
+ msg?: string,
627
+
628
+ })` Not Found
629
+ */
630
+ getSocialLoginProviders: (params = {}) => this.request(__spreadValues({
631
+ path: `/conf/auth/providers`,
632
+ method: "GET",
633
+ format: "json"
634
+ }, params)),
485
635
  /**
486
636
  * @description Get Domain Info
487
637
  *
@@ -1341,8 +1491,6 @@ function getDefaultExportFromCjs(x) {
1341
1491
  function _createClass(Constructor, protoProps, staticProps) {
1342
1492
  if (protoProps)
1343
1493
  _defineProperties(Constructor.prototype, protoProps);
1344
- if (staticProps)
1345
- _defineProperties(Constructor, staticProps);
1346
1494
  Object.defineProperty(Constructor, "prototype", {
1347
1495
  writable: false
1348
1496
  });
@@ -1719,7 +1867,7 @@ function getDefaultExportFromCjs(x) {
1719
1867
  const Fetch$1 = (opts, input, init2) => __async(void 0, null, function* () {
1720
1868
  const apiToken = opts.getApiToken && opts.getApiToken();
1721
1869
  const headers = new Headers(__spreadValues({
1722
- "Authorization": apiToken ? `Bearer ${apiToken}` : ""
1870
+ Authorization: apiToken ? `Bearer ${apiToken}` : ""
1723
1871
  }, init2 == null ? void 0 : init2.headers));
1724
1872
  if (!headers.get("Authorization"))
1725
1873
  headers.delete("Authorization");
@@ -2057,7 +2205,8 @@ class _Tokenizer {
2057
2205
  blockquote(src) {
2058
2206
  const cap = this.rules.block.blockquote.exec(src);
2059
2207
  if (cap) {
2060
- const text = rtrim(cap[0].replace(/^ *>[ \t]?/gm, ""), "\n");
2208
+ let text = cap[0].replace(/\n {0,3}((?:=+|-+) *)(?=\n|$)/g, "\n $1");
2209
+ text = rtrim(text.replace(/^ *>[ \t]?/gm, ""), "\n");
2061
2210
  const top = this.lexer.state.top;
2062
2211
  this.lexer.state.top = true;
2063
2212
  const tokens = this.lexer.blockTokens(text);
@@ -4249,7 +4398,7 @@ const insaneOptions = {
4249
4398
  allowedAttributes: {
4250
4399
  "*": ["title", "accesskey"],
4251
4400
  a: ["href", "name", "target", "aria-label", "rel"],
4252
- img: ["src", "alt", "title", "atk-emoticon", "aria-label"],
4401
+ img: ["src", "alt", "title", "atk-emoticon", "aria-label", "data-src", "class", "loading"],
4253
4402
  // for code highlight
4254
4403
  code: ["class"],
4255
4404
  span: ["class", "style"]
@@ -4257,7 +4406,8 @@ const insaneOptions = {
4257
4406
  filter: (node) => {
4258
4407
  const allowed = [
4259
4408
  ["code", /^hljs\W+language-(.*)$/],
4260
- ["span", /^(hljs-.*)$/]
4409
+ ["span", /^(hljs-.*)$/],
4410
+ ["img", /^lazyload$/]
4261
4411
  ];
4262
4412
  allowed.forEach(([tag2, reg]) => {
4263
4413
  if (node.tag === tag2 && !!node.attrs.class && !reg.test(node.attrs.class)) {
@@ -4334,16 +4484,27 @@ const hanabi = /* @__PURE__ */ getDefaultExportFromCjs(hanabiExports);
4334
4484
  function renderCode(code) {
4335
4485
  return hanabi(code);
4336
4486
  }
4337
- function getRenderer() {
4487
+ function getRenderer(options) {
4338
4488
  const renderer = new marked$1.Renderer();
4339
4489
  renderer.link = markedLinkRenderer(renderer, renderer.link);
4340
4490
  renderer.code = markedCodeRenderer();
4491
+ renderer.image = markedImageRenderer(renderer, renderer.image, options);
4341
4492
  return renderer;
4342
4493
  }
4343
4494
  const markedLinkRenderer = (renderer, orgLinkRenderer) => (href, title, text) => {
4344
- const localLink = href == null ? void 0 : href.startsWith(`${window.location.protocol}//${window.location.hostname}`);
4495
+ const getLinkOrigin = (link2) => {
4496
+ try {
4497
+ return new URL(link2).origin;
4498
+ } catch (e) {
4499
+ return "";
4500
+ }
4501
+ };
4502
+ const isSameOriginLink = getLinkOrigin(href) === window.location.origin;
4345
4503
  const html2 = orgLinkRenderer.call(renderer, href, title, text);
4346
- return html2.replace(/^<a /, `<a target="_blank" ${!localLink ? `rel="noreferrer noopener nofollow"` : ""} `);
4504
+ return html2.replace(
4505
+ /^<a /,
4506
+ `<a target="_blank" ${!isSameOriginLink ? `rel="noreferrer noopener nofollow"` : ""} `
4507
+ );
4347
4508
  };
4348
4509
  const markedCodeRenderer = () => (block2, lang) => {
4349
4510
  const realLang = !lang ? "plaintext" : lang;
@@ -4359,6 +4520,16 @@ const markedCodeRenderer = () => (block2, lang) => {
4359
4520
  <code class="hljs language-${realLang}">${colorized.replace(/&amp;/g, "&")}</code>
4360
4521
  </pre>`;
4361
4522
  };
4523
+ const markedImageRenderer = (renderer, orgImageRenderer, { imgLazyLoad }) => (href, title, text) => {
4524
+ const html2 = orgImageRenderer.call(renderer, href, title, text);
4525
+ if (!imgLazyLoad)
4526
+ return html2;
4527
+ if (imgLazyLoad === "native" || imgLazyLoad === true)
4528
+ return html2.replace(/^<img /, '<img class="lazyload" loading="lazy" ');
4529
+ if (imgLazyLoad === "data-src")
4530
+ return html2.replace(/^<img /, '<img class="lazyload" ').replace("src=", "data-src=");
4531
+ return html2;
4532
+ };
4362
4533
  let instance;
4363
4534
  let replacers = [];
4364
4535
  const markedOptions = {
@@ -4372,16 +4543,18 @@ function getInstance() {
4372
4543
  function setReplacers(arr) {
4373
4544
  replacers = arr;
4374
4545
  }
4375
- function initMarked() {
4546
+ function initMarked(options) {
4376
4547
  try {
4377
4548
  if (!marked$1.name)
4378
4549
  return;
4379
4550
  } catch (e) {
4380
4551
  return;
4381
4552
  }
4382
- marked$1.setOptions(__spreadValues({
4383
- renderer: getRenderer()
4384
- }, markedOptions));
4553
+ marked$1.setOptions(__spreadValues(__spreadValues({
4554
+ renderer: getRenderer({
4555
+ imgLazyLoad: options.imgLazyLoad
4556
+ })
4557
+ }, markedOptions), options.markedOptions));
4385
4558
  instance = marked$1;
4386
4559
  }
4387
4560
  function marked(src) {
@@ -4398,7 +4571,13 @@ function marked(src) {
4398
4571
  return dest;
4399
4572
  }
4400
4573
  function simpleMarked(src) {
4401
- return src.replace(/```\s*([^]+?.*?[^]+?[^]+?)```/g, (_, code) => `<pre><code>${renderCode(code)}</code></pre>`).replace(/!\[(.*?)\]\((.*?)\)/g, (_, alt, imgSrc) => `<img src="${imgSrc}" alt="${alt}" />`).replace(/\[(.*?)\]\((.*?)\)/g, (_, text, link2) => `<a href="${link2}" target="_blank">${text}</a>`).replace(/\n/g, "<br>");
4574
+ return src.replace(
4575
+ /```\s*([^]+?.*?[^]+?[^]+?)```/g,
4576
+ (_, code) => `<pre><code>${renderCode(code)}</code></pre>`
4577
+ ).replace(/!\[(.*?)\]\((.*?)\)/g, (_, alt, imgSrc) => `<img src="${imgSrc}" alt="${alt}" />`).replace(
4578
+ /\[(.*?)\]\((.*?)\)/g,
4579
+ (_, text, link2) => `<a href="${link2}" target="_blank">${text}</a>`
4580
+ ).replace(/\n/g, "<br>");
4402
4581
  }
4403
4582
  function mergeDeep(...objects) {
4404
4583
  const isObject = (obj) => obj && typeof obj === "object" && obj.constructor === Object;
@@ -4511,6 +4690,8 @@ const en = {
4511
4690
  placeholder: "Leave a comment",
4512
4691
  noComment: "No Comment",
4513
4692
  send: "Send",
4693
+ signIn: "Sign in",
4694
+ signUp: "Sign up",
4514
4695
  save: "Save",
4515
4696
  nick: "Nickname",
4516
4697
  email: "Email",
@@ -4569,7 +4750,26 @@ const en = {
4569
4750
  /* Sidebar */
4570
4751
  msgCenter: "Messages",
4571
4752
  ctrlCenter: "Admin",
4753
+ /* Auth */
4754
+ noAccountPrompt: "Don't have an account?",
4755
+ haveAccountPrompt: "Already have an account?",
4756
+ forgetPassword: "Forget Password",
4757
+ resetPassword: "Reset Password",
4758
+ verificationCode: "Verification Code",
4759
+ verifySend: "Verify",
4760
+ verifyResend: "Resend",
4761
+ waitSeconds: "Wait {seconds}s",
4572
4762
  emailVerified: "Email has been verified",
4763
+ password: "Password",
4764
+ username: "Username",
4765
+ nextStep: "Next Step",
4766
+ skipNotVerify: "Skip, do not verify",
4767
+ logoutConfirm: "Are you sure to logout?",
4768
+ accountMergeNotice: "Your email has multiple accounts with different id.",
4769
+ accountMergeSelectOne: "Please select one you want to merge all the data into it.",
4770
+ accountMergeConfirm: "All data will be merged into one account, the id is {id}.",
4771
+ dismiss: "Dismiss",
4772
+ merge: "Merge",
4573
4773
  /* General */
4574
4774
  frontend: "Frontend",
4575
4775
  backend: "Backend",
@@ -4581,7 +4781,7 @@ const en = {
4581
4781
  deleteFail: "Delete Failed",
4582
4782
  reqGot: "Request got",
4583
4783
  reqAborted: "Request timed out or terminated unexpectedly",
4584
- updateMsg: "Please update Artalk {name} to get the full experience",
4784
+ updateMsg: "Please update Artalk {name} to get the best experience!",
4585
4785
  currentVersion: "Current Version",
4586
4786
  ignore: "Ignore",
4587
4787
  open: "Open",
@@ -4592,6 +4792,8 @@ const zhCN = {
4592
4792
  placeholder: "键入内容...",
4593
4793
  noComment: "「此时无声胜有声」",
4594
4794
  send: "发送",
4795
+ signIn: "登录",
4796
+ signUp: "注册",
4595
4797
  save: "保存",
4596
4798
  nick: "昵称",
4597
4799
  email: "邮箱",
@@ -4650,7 +4852,26 @@ const zhCN = {
4650
4852
  /* Sidebar */
4651
4853
  msgCenter: "通知中心",
4652
4854
  ctrlCenter: "控制中心",
4855
+ /* Auth */
4856
+ noAccountPrompt: "没有账号?",
4857
+ haveAccountPrompt: "已有账号?",
4858
+ forgetPassword: "忘记密码",
4859
+ resetPassword: "重置密码",
4860
+ verificationCode: "验证码",
4861
+ verifySend: "发送验证码",
4862
+ verifyResend: "重新发送",
4863
+ waitSeconds: "等待 {seconds}秒",
4653
4864
  emailVerified: "邮箱已验证",
4865
+ password: "密码",
4866
+ username: "用户名",
4867
+ nextStep: "下一步",
4868
+ skipNotVerify: "跳过,不验证",
4869
+ logoutConfirm: "确定要退出登录吗?",
4870
+ accountMergeNotice: "您的电子邮件下有多个不同 ID 的账户。",
4871
+ accountMergeSelectOne: "请选择将所有数据合并到其中的一个。",
4872
+ accountMergeConfirm: "所有数据将合并到 ID 为 {id} 的账户中。",
4873
+ dismiss: "忽略",
4874
+ merge: "合并",
4654
4875
  /* General */
4655
4876
  frontend: "前端",
4656
4877
  backend: "后端",
@@ -4662,7 +4883,7 @@ const zhCN = {
4662
4883
  deleteFail: "删除失败",
4663
4884
  reqGot: "请求响应",
4664
4885
  reqAborted: "请求超时或意外终止",
4665
- updateMsg: "请更新 Artalk {name} 以获得完整体验",
4886
+ updateMsg: "请更新 Artalk {name} 以获得更好的体验!",
4666
4887
  currentVersion: "当前版本",
4667
4888
  ignore: "忽略",
4668
4889
  open: "打开",
@@ -4753,27 +4974,6 @@ function timeAgo(date, $t = (n) => n) {
4753
4974
  return " - ";
4754
4975
  }
4755
4976
  }
4756
- function onImagesLoaded($container, event) {
4757
- if (!$container)
4758
- return;
4759
- const images = $container.getElementsByTagName("img");
4760
- if (!images.length)
4761
- return;
4762
- let loaded = images.length;
4763
- for (let i = 0; i < images.length; i++) {
4764
- if (images[i].complete) {
4765
- loaded--;
4766
- } else {
4767
- images[i].addEventListener("load", () => {
4768
- loaded--;
4769
- if (loaded === 0)
4770
- event();
4771
- });
4772
- }
4773
- if (loaded === 0)
4774
- event();
4775
- }
4776
- }
4777
4977
  function getGravatarURL(opts) {
4778
4978
  return `${opts.mirror.replace(/\/$/, "")}/${opts.emailMD5}?${opts.params.replace(/^\?/, "")}`;
4779
4979
  }
@@ -4816,7 +5016,10 @@ function getCorrectUserAgent() {
4816
5016
  }
4817
5017
  if (uaData.platform === "macOS") {
4818
5018
  if (majorPlatformVersion >= 11) {
4819
- return uaRaw.replace(/(Mac OS X \d+_\d+_\d+|Mac OS X)/, `Mac OS X ${uaGot.platformVersion.replace(/\./g, "_")}`);
5019
+ return uaRaw.replace(
5020
+ /(Mac OS X \d+_\d+_\d+|Mac OS X)/,
5021
+ `Mac OS X ${uaGot.platformVersion.replace(/\./g, "_")}`
5022
+ );
4820
5023
  }
4821
5024
  }
4822
5025
  return uaRaw;
@@ -4838,7 +5041,7 @@ function getURLBasedOn(baseURL, path) {
4838
5041
  return `${baseURL.replace(/\/$/, "")}/${path.replace(/^\//, "")}`;
4839
5042
  }
4840
5043
  const internal = {
4841
- "en": en,
5044
+ en,
4842
5045
  "en-US": en,
4843
5046
  "zh-CN": zhCN
4844
5047
  };
@@ -4876,7 +5079,10 @@ class EventManager {
4876
5079
  * Add an event listener for a specific event name
4877
5080
  */
4878
5081
  on(name, handler, opts = {}) {
4879
- this.events.push(__spreadValues({ name, handler }, opts));
5082
+ this.events.push(__spreadValues({
5083
+ name,
5084
+ handler
5085
+ }, opts));
4880
5086
  }
4881
5087
  /**
4882
5088
  * Remove an event listener for a specific event name and handler
@@ -4967,17 +5173,12 @@ function handelCustomConf(customConf, full = false) {
4967
5173
  return conf;
4968
5174
  }
4969
5175
  function handleConfFormServer(conf) {
4970
- const DisabledKeys = [
4971
- "el",
4972
- "pageKey",
4973
- "pageTitle",
4974
- "server",
4975
- "site",
4976
- "darkMode"
4977
- ];
5176
+ const DisabledKeys = ["el", "pageKey", "pageTitle", "server", "site"];
4978
5177
  Object.keys(conf).forEach((k) => {
4979
5178
  if (DisabledKeys.includes(k))
4980
5179
  delete conf[k];
5180
+ if (k === "darkMode" && conf[k] !== "auto")
5181
+ delete conf[k];
4981
5182
  });
4982
5183
  if (conf.emoticons && typeof conf.emoticons === "string") {
4983
5184
  conf.emoticons = conf.emoticons.trim();
@@ -5285,8 +5486,6 @@ function playFadeAnim(elem, after, type = "in") {
5285
5486
  const onAnimEnded = () => {
5286
5487
  elem.classList.remove(`atk-fade-${type}`);
5287
5488
  elem.removeEventListener("animationend", onAnimEnded);
5288
- if (after)
5289
- after();
5290
5489
  };
5291
5490
  elem.addEventListener("animationend", onAnimEnded);
5292
5491
  }
@@ -5354,7 +5553,9 @@ function imgBody(checker) {
5354
5553
  }
5355
5554
  function iframeBody(checker) {
5356
5555
  const $iframeWrap = createElement(`<div class="atk-checker-iframe-wrap"></div>`);
5357
- const $iframe = createElement(`<iframe class="atk-fade-in" referrerpolicy="strict-origin-when-cross-origin"></iframe>`);
5556
+ const $iframe = createElement(
5557
+ `<iframe class="atk-fade-in" referrerpolicy="strict-origin-when-cross-origin"></iframe>`
5558
+ );
5358
5559
  $iframe.style.display = "none";
5359
5560
  showLoading($iframeWrap, { transparentBg: true });
5360
5561
  $iframe.src = checker.getOpts().getCaptchaIframeURL();
@@ -5363,7 +5564,9 @@ function iframeBody(checker) {
5363
5564
  hideLoading($iframeWrap);
5364
5565
  };
5365
5566
  $iframeWrap.append($iframe);
5366
- const $closeBtn = createElement(`<div class="atk-close-btn"><i class="atk-icon atk-icon-close"></i></div>`);
5567
+ const $closeBtn = createElement(
5568
+ `<div class="atk-close-btn"><i class="atk-icon atk-icon-close"></i></div>`
5569
+ );
5367
5570
  $iframeWrap.append($closeBtn);
5368
5571
  checker.hideInteractInput();
5369
5572
  let stop = false;
@@ -5575,7 +5778,7 @@ class Component {
5575
5778
  return this.$el;
5576
5779
  }
5577
5780
  }
5578
- const EditorHTML = '<div class="atk-main-editor">\n <div class="atk-header">\n <input name="nick" class="atk-nick" type="text" required="required">\n <input name="email" class="atk-email" type="email" required="required">\n <input name="link" class="atk-link" type="url">\n </div>\n <div class="atk-textarea-wrap">\n <textarea class="atk-textarea"></textarea>\n </div>\n <div class="atk-plug-panel-wrap" style="display: none;"></div>\n <div class="atk-bottom">\n <div class="atk-item atk-bottom-left">\n <span class="atk-state-wrap"></span>\n <span class="atk-plug-btn-wrap"></span>\n </div>\n <div class="atk-item">\n <button type="button" class="atk-send-btn"></button>\n </div>\n </div>\n <div class="atk-notify-wrap"></div>\n</div>\n';
5781
+ const EditorHTML = '<div class="atk-main-editor">\n <div class="atk-header">\n <input name="nick" class="atk-nick" type="text" required="required" />\n <input name="email" class="atk-email" type="email" required="required" />\n <input name="link" class="atk-link" type="url" />\n </div>\n <div class="atk-textarea-wrap">\n <textarea class="atk-textarea"></textarea>\n </div>\n <div class="atk-plug-panel-wrap" style="display: none"></div>\n <div class="atk-bottom">\n <div class="atk-item atk-bottom-left">\n <span class="atk-state-wrap"></span>\n <span class="atk-plug-btn-wrap"></span>\n </div>\n <div class="atk-item">\n <button type="button" class="atk-send-btn"></button>\n </div>\n </div>\n <div class="atk-notify-wrap"></div>\n</div>\n';
5579
5782
  const Sel = {
5580
5783
  $header: ".atk-header",
5581
5784
  $nick: '.atk-header [name="nick"]',
@@ -5749,7 +5952,9 @@ class Editor extends Component {
5749
5952
  const sStart = this.ui.$textarea.selectionStart;
5750
5953
  const sEnd = this.ui.$textarea.selectionEnd;
5751
5954
  const sT = this.ui.$textarea.scrollTop;
5752
- this.setContent(this.ui.$textarea.value.substring(0, sStart) + val + this.ui.$textarea.value.substring(sEnd, this.ui.$textarea.value.length));
5955
+ this.setContent(
5956
+ this.ui.$textarea.value.substring(0, sStart) + val + this.ui.$textarea.value.substring(sEnd, this.ui.$textarea.value.length)
5957
+ );
5753
5958
  this.ui.$textarea.focus();
5754
5959
  this.ui.$textarea.selectionStart = sStart + val.length;
5755
5960
  this.ui.$textarea.selectionEnd = sStart + val.length;
@@ -5793,7 +5998,7 @@ class Editor extends Component {
5793
5998
  }
5794
5999
  }
5795
6000
  }
5796
- const SidebarHTML = '<div class="atk-sidebar-layer">\n <div class="atk-sidebar-inner">\n <div class="atk-sidebar-header">\n <div class="atk-sidebar-close"><i class="atk-icon atk-icon-close-slim"></i></div>\n </div>\n <div class="atk-sidebar-iframe-wrap"></div>\n </div>\n</div>\n';
6001
+ const SidebarHTML = '<div class="atk-sidebar-layer">\n <div class="atk-sidebar-inner">\n <div class="atk-sidebar-header">\n <div class="atk-sidebar-close">\n <i class="atk-icon atk-icon-close-slim"></i>\n </div>\n </div>\n <div class="atk-sidebar-iframe-wrap"></div>\n </div>\n</div>\n';
5797
6002
  class SidebarLayer extends Component {
5798
6003
  constructor(ctx) {
5799
6004
  super(ctx);
@@ -5831,8 +6036,11 @@ class SidebarLayer extends Component {
5831
6036
  } else {
5832
6037
  const $iframe = this.$iframe;
5833
6038
  const iFrameSrc = $iframe.src;
5834
- if (this.conf.darkMode !== iFrameSrc.includes("darkMode=1")) {
5835
- this.iframeLoad($iframe, this.conf.darkMode ? iFrameSrc.concat("&darkMode=1") : iFrameSrc.replace("&darkMode=1", ""));
6039
+ if (this.getDarkMode() !== iFrameSrc.includes("&darkMode=1")) {
6040
+ this.iframeLoad(
6041
+ $iframe,
6042
+ this.getDarkMode() ? iFrameSrc.concat("&darkMode=1") : iFrameSrc.replace("&darkMode=1", "")
6043
+ );
5836
6044
  }
5837
6045
  }
5838
6046
  this.authCheck({
@@ -5886,7 +6094,9 @@ class SidebarLayer extends Component {
5886
6094
  });
5887
6095
  }
5888
6096
  createIframe(view) {
5889
- const $iframe = createElement('<iframe referrerpolicy="strict-origin-when-cross-origin"></iframe>');
6097
+ const $iframe = createElement(
6098
+ '<iframe referrerpolicy="strict-origin-when-cross-origin"></iframe>'
6099
+ );
5890
6100
  const baseURL = getURLBasedOnApi({
5891
6101
  base: this.ctx.conf.server,
5892
6102
  path: "/sidebar/"
@@ -5899,12 +6109,15 @@ class SidebarLayer extends Component {
5899
6109
  };
5900
6110
  if (view)
5901
6111
  query.view = view;
5902
- if (this.conf.darkMode)
6112
+ if (this.getDarkMode())
5903
6113
  query.darkMode = "1";
5904
6114
  const urlParams = new URLSearchParams(query);
5905
6115
  this.iframeLoad($iframe, `${baseURL}?${urlParams.toString()}`);
5906
6116
  return $iframe;
5907
6117
  }
6118
+ getDarkMode() {
6119
+ return this.conf.darkMode === "auto" ? window.matchMedia("(prefers-color-scheme: dark)").matches : this.conf.darkMode;
6120
+ }
5908
6121
  iframeLoad($iframe, src) {
5909
6122
  $iframe.src = src;
5910
6123
  showLoading(this.$iframeWrap);
@@ -5913,7 +6126,7 @@ class SidebarLayer extends Component {
5913
6126
  };
5914
6127
  }
5915
6128
  }
5916
- const ListHTML = '<div class="atk-list">\n <div class="atk-list-header">\n <div class="atk-comment-count">\n <div class="atk-text"></div>\n </div>\n <div class="atk-right-action">\n <span data-action="admin-close-comment" class="atk-hide" atk-only-admin-show></span>\n <span data-action="open-sidebar" class="atk-hide atk-on">\n <span class="atk-unread-badge" style="display: none;"></span>\n <div class="atk-text"></div>\n </span>\n </div>\n </div>\n <div class="atk-list-body">\n <div class="atk-list-comments-wrap"></div>\n </div>\n <div class="atk-list-footer">\n <div class="atk-copyright"></div>\n </div>\n</div>\n';
6129
+ const ListHTML = '<div class="atk-list">\n <div class="atk-list-header">\n <div class="atk-comment-count">\n <div class="atk-text"></div>\n </div>\n <div class="atk-right-action">\n <span data-action="admin-close-comment" class="atk-hide" atk-only-admin-show></span>\n <span data-action="open-sidebar" class="atk-hide atk-on">\n <span class="atk-unread-badge" style="display: none"></span>\n <div class="atk-text"></div>\n </span>\n </div>\n </div>\n <div class="atk-list-body">\n <div class="atk-list-comments-wrap"></div>\n </div>\n <div class="atk-list-footer">\n <div class="atk-copyright"></div>\n </div>\n</div>\n';
5917
6130
  function makeNestCommentNodeList(srcData, sortBy = "DATE_DESC", nestMax = 2) {
5918
6131
  const nodeList = [];
5919
6132
  const roots = srcData.filter((o) => o.rid === 0);
@@ -5975,8 +6188,9 @@ const createNestStrategy = (opts) => ({
5975
6188
  rootC.getRender().playFadeAnim();
5976
6189
  const loadChildren = (parentC, parentNode) => {
5977
6190
  parentNode.children.forEach((node) => {
6191
+ const replyD = comments.find((c) => c.id === node.comment.rid);
5978
6192
  const childD = node.comment;
5979
- const childC = opts.createCommentNode(childD, parentC.getData());
6193
+ const childC = opts.createCommentNode(childD, replyD);
5980
6194
  parentC.putChild(childC);
5981
6195
  loadChildren(childC, node);
5982
6196
  });
@@ -6238,45 +6452,51 @@ function Detect(userAgent) {
6238
6452
  return dest;
6239
6453
  }
6240
6454
  function check(conf, rules) {
6241
- rules.forEach(({
6242
- el,
6243
- max: maxHeight,
6244
- imgContains
6245
- }) => {
6246
- const _apply = () => {
6247
- if (!el)
6248
- return;
6249
- if (!conf.scrollable)
6250
- applyHeightLimit({ el, maxHeight, postBtnClick: conf.postExpandBtnClick });
6251
- else
6252
- applyScrollableHeightLimit({ el, maxHeight });
6253
- };
6455
+ rules.forEach(({ el, max, imgCheck }) => {
6456
+ if (!el)
6457
+ return;
6458
+ if (imgCheck)
6459
+ el.style.maxHeight = `${max + 1}px`;
6460
+ let lock = false;
6254
6461
  const _check = () => {
6255
- if (el && getHeight(el) > maxHeight)
6256
- _apply();
6462
+ if (lock)
6463
+ return;
6464
+ if (getHeight(el) <= max)
6465
+ return;
6466
+ const afterExpandBtnClick = () => {
6467
+ var _a;
6468
+ lock = true;
6469
+ (_a = conf.afterExpandBtnClick) == null ? void 0 : _a.call(conf);
6470
+ };
6471
+ !conf.scrollable ? applyHeightLimit({ el, max, afterExpandBtnClick }) : applyScrollableHeightLimit({ el, max });
6257
6472
  };
6258
6473
  _check();
6259
- if (imgContains && el)
6260
- onImagesLoaded(el, () => _check());
6474
+ if (imgCheck) {
6475
+ el.querySelectorAll(".atk-content img").forEach((img) => {
6476
+ img.onload = () => _check();
6477
+ });
6478
+ }
6261
6479
  });
6262
6480
  }
6263
6481
  const HEIGHT_LIMIT_CSS = "atk-height-limit";
6264
6482
  function applyHeightLimit(obj) {
6265
6483
  if (!obj.el)
6266
6484
  return;
6267
- if (!obj.maxHeight)
6485
+ if (!obj.max)
6268
6486
  return;
6269
6487
  if (obj.el.classList.contains(HEIGHT_LIMIT_CSS))
6270
6488
  return;
6271
6489
  obj.el.classList.add(HEIGHT_LIMIT_CSS);
6272
- obj.el.style.height = `${obj.maxHeight}px`;
6490
+ obj.el.style.height = `${obj.max}px`;
6273
6491
  obj.el.style.overflow = "hidden";
6274
- const $expandBtn = createElement(`<div class="atk-height-limit-btn">${t("readMore")}</span>`);
6492
+ const $expandBtn = createElement(
6493
+ `<div class="atk-height-limit-btn">${t("readMore")}</span>`
6494
+ );
6275
6495
  $expandBtn.onclick = (e) => {
6276
6496
  e.stopPropagation();
6277
6497
  disposeHeightLimit(obj.el);
6278
- if (obj.postBtnClick)
6279
- obj.postBtnClick(e);
6498
+ if (obj.afterExpandBtnClick)
6499
+ obj.afterExpandBtnClick(e);
6280
6500
  };
6281
6501
  obj.el.append($expandBtn);
6282
6502
  }
@@ -6291,16 +6511,17 @@ function disposeHeightLimit($el) {
6291
6511
  e.remove();
6292
6512
  });
6293
6513
  $el.style.height = "";
6514
+ $el.style.maxHeight = "";
6294
6515
  $el.style.overflow = "";
6295
6516
  }
6296
6517
  const HEIGHT_LIMIT_SCROLL_CSS = "atk-height-limit-scroll";
6297
- function applyScrollableHeightLimit(obj) {
6298
- if (!obj.el)
6518
+ function applyScrollableHeightLimit(opt) {
6519
+ if (!opt.el)
6299
6520
  return;
6300
- if (obj.el.classList.contains(HEIGHT_LIMIT_SCROLL_CSS))
6521
+ if (opt.el.classList.contains(HEIGHT_LIMIT_SCROLL_CSS))
6301
6522
  return;
6302
- obj.el.classList.add(HEIGHT_LIMIT_SCROLL_CSS);
6303
- obj.el.style.height = `${obj.maxHeight}px`;
6523
+ opt.el.classList.add(HEIGHT_LIMIT_SCROLL_CSS);
6524
+ opt.el.style.height = `${opt.max}px`;
6304
6525
  }
6305
6526
  const CommentHTML = '<div class="atk-comment-wrap">\n <div class="atk-comment">\n <div class="atk-avatar"></div>\n <div class="atk-main">\n <div class="atk-header">\n <span class="atk-item atk-nick"></span>\n <span class="atk-badge-wrap"></span>\n <span class="atk-item atk-date"></span>\n </div>\n <div class="atk-body">\n <div class="atk-content"></div>\n </div>\n <div class="atk-footer">\n <div class="atk-actions"></div>\n </div>\n </div>\n </div>\n</div>\n';
6306
6527
  function renderAvatar(r) {
@@ -6309,7 +6530,9 @@ function renderAvatar(r) {
6309
6530
  const avatarURLBuilder = r.opts.avatarURLBuilder;
6310
6531
  $avatarImg.src = avatarURLBuilder ? avatarURLBuilder(r.data) : r.comment.getGravatarURL();
6311
6532
  if (r.data.link) {
6312
- const $avatarA = createElement('<a target="_blank" rel="noreferrer noopener nofollow"></a>');
6533
+ const $avatarA = createElement(
6534
+ '<a target="_blank" rel="noreferrer noopener nofollow"></a>'
6535
+ );
6313
6536
  $avatarA.href = isValidURL(r.data.link) ? r.data.link : `https://${r.data.link}`;
6314
6537
  $avatarA.append($avatarImg);
6315
6538
  $avatar.append($avatarA);
@@ -6330,7 +6553,9 @@ function renderHeader(r) {
6330
6553
  function renderNick(r) {
6331
6554
  r.$headerNick = r.$el.querySelector(".atk-nick");
6332
6555
  if (r.data.link) {
6333
- const $nickA = createElement('<a target="_blank" rel="noreferrer noopener nofollow"></a>');
6556
+ const $nickA = createElement(
6557
+ '<a target="_blank" rel="noreferrer noopener nofollow"></a>'
6558
+ );
6334
6559
  $nickA.innerText = r.data.nick;
6335
6560
  $nickA.href = isValidURL(r.data.link) ? r.data.link : `https://${r.data.link}`;
6336
6561
  r.$headerNick.append($nickA);
@@ -6349,7 +6574,9 @@ function renderVerifyBadge(ctx) {
6349
6574
  $badge.style.backgroundColor = badgeColor || "";
6350
6575
  ctx.$headerBadgeWrap.append($badge);
6351
6576
  } else if (ctx.data.is_verified) {
6352
- const $verifiedBadge = createElement(`<span class="atk-verified-icon" title="${t("emailVerified")}"></span>`);
6577
+ const $verifiedBadge = createElement(
6578
+ `<span class="atk-verified-icon" title="${t("emailVerified")}"></span>`
6579
+ );
6353
6580
  ctx.$headerBadgeWrap.append($verifiedBadge);
6354
6581
  }
6355
6582
  if (ctx.data.is_pinned) {
@@ -6423,7 +6650,9 @@ function renderReplyAt(r) {
6423
6650
  return;
6424
6651
  if (!r.opts.replyTo)
6425
6652
  return;
6426
- r.$replyAt = createElement(`<span class="atk-item atk-reply-at"><span class="atk-arrow"></span><span class="atk-nick"></span></span>`);
6653
+ r.$replyAt = createElement(
6654
+ `<span class="atk-item atk-reply-at"><span class="atk-arrow"></span><span class="atk-nick"></span></span>`
6655
+ );
6427
6656
  r.$replyAt.querySelector(".atk-nick").innerText = `${r.opts.replyTo.nick}`;
6428
6657
  r.$replyAt.onclick = () => {
6429
6658
  r.comment.getActions().goToReplyComment();
@@ -6614,7 +6843,9 @@ function renderVote(r) {
6614
6843
  r.comment.getActions().vote("up");
6615
6844
  });
6616
6845
  if (r.opts.voteDown) {
6617
- r.voteBtnDown = new ActionBtn(() => `${t("voteDown")} (${r.data.vote_down || 0})`).appendTo(r.$actions);
6846
+ r.voteBtnDown = new ActionBtn(() => `${t("voteDown")} (${r.data.vote_down || 0})`).appendTo(
6847
+ r.$actions
6848
+ );
6618
6849
  r.voteBtnDown.setClick(() => {
6619
6850
  r.comment.getActions().vote("down");
6620
6851
  });
@@ -6752,20 +6983,23 @@ class Render {
6752
6983
  return;
6753
6984
  const contentMaxH = conf.content;
6754
6985
  const childrenMaxH = conf.children;
6755
- check({
6756
- postExpandBtnClick: () => {
6757
- const children = this.comment.getChildren();
6758
- if (children.length === 1)
6759
- disposeHeightLimit(children[0].getRender().$content);
6986
+ check(
6987
+ {
6988
+ afterExpandBtnClick: () => {
6989
+ const children = this.comment.getChildren();
6990
+ if (children.length === 1)
6991
+ disposeHeightLimit(children[0].getRender().$content);
6992
+ },
6993
+ scrollable: conf.scrollable
6760
6994
  },
6761
- scrollable: conf.scrollable
6762
- }, [
6763
- // 评论内容限高
6764
- { el: this.$content, max: contentMaxH, imgContains: true },
6765
- { el: this.$replyTo, max: contentMaxH, imgContains: true },
6766
- // 子评论区域限高(仅嵌套模式)
6767
- { el: this.$childrenWrap, max: childrenMaxH, imgContains: false }
6768
- ]);
6995
+ [
6996
+ // 评论内容限高
6997
+ { el: this.$content, max: contentMaxH, imgCheck: true },
6998
+ { el: this.$replyTo, max: contentMaxH, imgCheck: true },
6999
+ // 子评论区域限高(仅嵌套模式)
7000
+ { el: this.$childrenWrap, max: childrenMaxH, imgCheck: false }
7001
+ ]
7002
+ );
6769
7003
  }
6770
7004
  /** 子评论区域移除限高 */
6771
7005
  heightLimitRemoveForChildren() {
@@ -6852,7 +7086,7 @@ class CommentActions {
6852
7086
  (_b = this.comment.getRender().voteBtnDown) == null ? void 0 : _b.updateText();
6853
7087
  }).catch((err) => {
6854
7088
  actionBtn == null ? void 0 : actionBtn.setError(t("voteFail"));
6855
- console.log(err);
7089
+ console.error(err);
6856
7090
  });
6857
7091
  }
6858
7092
  /** 管理员 - 评论状态修改 */
@@ -7484,7 +7718,9 @@ class List extends Component {
7484
7718
  }
7485
7719
  });
7486
7720
  this.ctx.on("comment-inserted", (comment) => {
7487
- this.getListLayout().insert(comment);
7721
+ var _a;
7722
+ const replyComment = comment.rid ? (_a = this.commentNodes.find((c) => c.getID() === comment.rid)) == null ? void 0 : _a.getData() : void 0;
7723
+ this.getListLayout().insert(comment, replyComment);
7488
7724
  });
7489
7725
  this.ctx.on("comment-deleted", (comment) => {
7490
7726
  const node = this.commentNodes.find((c) => c.getID() === comment.id);
@@ -7515,7 +7751,10 @@ function getScrollbarHelper() {
7515
7751
  },
7516
7752
  lock() {
7517
7753
  document.body.style.overflow = "hidden";
7518
- const barPaddingRight = parseInt(window.getComputedStyle(document.body, null).getPropertyValue("padding-right"), 10);
7754
+ const barPaddingRight = parseInt(
7755
+ window.getComputedStyle(document.body, null).getPropertyValue("padding-right"),
7756
+ 10
7757
+ );
7519
7758
  document.body.style.paddingRight = `${getScrollBarWidth() + barPaddingRight || 0}px`;
7520
7759
  }
7521
7760
  };
@@ -7726,13 +7965,7 @@ const services = {
7726
7965
  }
7727
7966
  };
7728
7967
  const PvCountWidget = (ctx) => {
7729
- ctx.watchConf([
7730
- "site",
7731
- "pageKey",
7732
- "pageTitle",
7733
- "countEl",
7734
- "pvEl"
7735
- ], (conf) => {
7968
+ ctx.watchConf(["site", "pageKey", "pageTitle", "countEl", "pvEl"], (conf) => {
7736
7969
  initCountWidget({
7737
7970
  getApi: () => ctx.getApi(),
7738
7971
  siteName: conf.site,
@@ -7799,15 +8032,20 @@ ${opts.errMsg}`;
7799
8032
  errEl.appendChild($retryBtn);
7800
8033
  }
7801
8034
  if (opts.onOpenSidebar) {
7802
- const $openSidebar = createElement(`<span atk-only-admin-show> | <span style="cursor:pointer;">${t("openName", { name: t("ctrlCenter") })}</span></span>`);
8035
+ const $openSidebar = createElement(
8036
+ `<span atk-only-admin-show> | <span style="cursor:pointer;">${t("openName", { name: t("ctrlCenter") })}</span></span>`
8037
+ );
7803
8038
  errEl.appendChild($openSidebar);
7804
8039
  $openSidebar.onclick = () => opts.onOpenSidebar && opts.onOpenSidebar();
7805
8040
  }
7806
8041
  setError(opts.$err, errEl);
7807
8042
  }
7808
8043
  const Markdown = (ctx) => {
7809
- initMarked();
7810
- ctx.on("updated", (conf) => {
8044
+ ctx.watchConf(["markedReplacers", "imgLazyLoad", "markedOptions"], (conf) => {
8045
+ initMarked({
8046
+ markedOptions: ctx.getConf().markedOptions,
8047
+ imgLazyLoad: ctx.getConf().imgLazyLoad
8048
+ });
7811
8049
  if (conf.markedReplacers)
7812
8050
  setReplacers(conf.markedReplacers);
7813
8051
  });
@@ -8142,7 +8380,9 @@ class Closable extends EditorPlug {
8142
8380
  }
8143
8381
  close() {
8144
8382
  if (!this.kit.useUI().$textareaWrap.querySelector(".atk-comment-closed"))
8145
- this.kit.useUI().$textareaWrap.prepend(createElement(`<div class="atk-comment-closed">${t("onlyAdminCanReply")}</div>`));
8383
+ this.kit.useUI().$textareaWrap.prepend(
8384
+ createElement(`<div class="atk-comment-closed">${t("onlyAdminCanReply")}</div>`)
8385
+ );
8146
8386
  if (!this.kit.useUser().getData().isAdmin) {
8147
8387
  this.kit.useUI().$textarea.style.display = "none";
8148
8388
  this.kit.useEvents().trigger("panel-close");
@@ -8166,8 +8406,14 @@ class HeaderEvent extends EditorPlug {
8166
8406
  };
8167
8407
  this.kit.useMounted(() => {
8168
8408
  Object.entries(this.$inputs).forEach(([key, $input]) => {
8169
- $input.addEventListener("input", inputEventFns[key] = trigger("header-input", $input, key));
8170
- $input.addEventListener("change", changeEventFns[key] = trigger("header-change", $input, key));
8409
+ $input.addEventListener(
8410
+ "input",
8411
+ inputEventFns[key] = trigger("header-input", $input, key)
8412
+ );
8413
+ $input.addEventListener(
8414
+ "change",
8415
+ changeEventFns[key] = trigger("header-change", $input, key)
8416
+ );
8171
8417
  });
8172
8418
  });
8173
8419
  this.kit.useUnmounted(() => {
@@ -8217,9 +8463,12 @@ class HeaderUser extends EditorPlug {
8217
8463
  const api = this.kit.useApi();
8218
8464
  const CANCEL_TOKEN = "getUserCancelToken";
8219
8465
  this.query.abortFn = () => api.abortRequest(CANCEL_TOKEN);
8220
- api.user.getUser(__spreadValues({}, api.getUserFields()), {
8221
- cancelToken: CANCEL_TOKEN
8222
- }).then((res) => this.onUserInfoFetched(res.data)).catch((err) => {
8466
+ api.user.getUser(
8467
+ __spreadValues({}, api.getUserFields()),
8468
+ {
8469
+ cancelToken: CANCEL_TOKEN
8470
+ }
8471
+ ).then((res) => this.onUserInfoFetched(res.data)).catch((err) => {
8223
8472
  }).finally(() => {
8224
8473
  this.query.abortFn = null;
8225
8474
  });
@@ -8280,7 +8529,9 @@ class Emoticons extends EditorPlug {
8280
8529
  __publicField(this, "isImgLoaded", false);
8281
8530
  this.kit.useMounted(() => {
8282
8531
  this.usePanel(`<div class="atk-editor-plug-emoticons"></div>`);
8283
- this.useBtn(`<i aria-label="${t("emoticon")}"><svg fill="currentColor" aria-hidden="true" height="14" viewBox="0 0 14 14" width="14"><path d="m4.26829 5.29294c0-.94317.45893-1.7074 1.02439-1.7074.56547 0 1.02439.76423 1.02439 1.7074s-.45892 1.7074-1.02439 1.7074c-.56546 0-1.02439-.76423-1.02439-1.7074zm4.43903 1.7074c.56546 0 1.02439-.76423 1.02439-1.7074s-.45893-1.7074-1.02439-1.7074c-.56547 0-1.02439.76423-1.02439 1.7074s.45892 1.7074 1.02439 1.7074zm-1.70732 2.73184c-1.51883 0-2.06312-1.52095-2.08361-1.58173l-1.29551.43231c.03414.10244.868 2.51604 3.3798 2.51604 2.51181 0 3.34502-2.41291 3.37982-2.51604l-1.29484-.43573c-.02254.06488-.56683 1.58583-2.08498 1.58583zm7-2.73252c0 3.86004-3.1401 7.00034-7 7.00034s-7-3.1396-7-6.99966c0-3.86009 3.1401-7.00034 7-7.00034s7 3.14025 7 7.00034zm-1.3659 0c0-3.10679-2.5275-5.63442-5.6341-5.63442-3.10663 0-5.63415 2.52832-5.63415 5.6351 0 3.10676 2.52752 5.63446 5.63415 5.63446 3.1066 0 5.6341-2.5277 5.6341-5.63446z"/></svg></i>`);
8532
+ this.useBtn(
8533
+ `<i aria-label="${t("emoticon")}"><svg fill="currentColor" aria-hidden="true" height="14" viewBox="0 0 14 14" width="14"><path d="m4.26829 5.29294c0-.94317.45893-1.7074 1.02439-1.7074.56547 0 1.02439.76423 1.02439 1.7074s-.45892 1.7074-1.02439 1.7074c-.56546 0-1.02439-.76423-1.02439-1.7074zm4.43903 1.7074c.56546 0 1.02439-.76423 1.02439-1.7074s-.45893-1.7074-1.02439-1.7074c-.56547 0-1.02439.76423-1.02439 1.7074s.45892 1.7074 1.02439 1.7074zm-1.70732 2.73184c-1.51883 0-2.06312-1.52095-2.08361-1.58173l-1.29551.43231c.03414.10244.868 2.51604 3.3798 2.51604 2.51181 0 3.34502-2.41291 3.37982-2.51604l-1.29484-.43573c-.02254.06488-.56683 1.58583-2.08498 1.58583zm7-2.73252c0 3.86004-3.1401 7.00034-7 7.00034s-7-3.1396-7-6.99966c0-3.86009 3.1401-7.00034 7-7.00034s7 3.14025 7 7.00034zm-1.3659 0c0-3.10679-2.5275-5.63442-5.6341-5.63442-3.10663 0-5.63415 2.52832-5.63415 5.6351 0 3.10676 2.52752 5.63446 5.63415 5.63446 3.1066 0 5.6341-2.5277 5.6341-5.63446z"/></svg></i>`
8534
+ );
8284
8535
  });
8285
8536
  this.kit.useUnmounted(() => {
8286
8537
  });
@@ -8340,19 +8591,21 @@ class Emoticons extends EditorPlug {
8340
8591
  data.push(grp);
8341
8592
  };
8342
8593
  const remoteLoad = (d) => __async(this, null, function* () {
8343
- yield Promise.all(d.map((grp, index) => __async(this, null, function* () {
8344
- if (typeof grp === "object" && !Array.isArray(grp)) {
8345
- pushGrp(grp);
8346
- } else if (Array.isArray(grp)) {
8347
- yield remoteLoad(grp);
8348
- } else if (typeof grp === "string") {
8349
- const grpData = yield this.remoteLoad(grp);
8350
- if (Array.isArray(grpData))
8351
- yield remoteLoad(grpData);
8352
- else if (typeof grpData === "object")
8353
- pushGrp(grpData);
8354
- }
8355
- })));
8594
+ yield Promise.all(
8595
+ d.map((grp, index) => __async(this, null, function* () {
8596
+ if (typeof grp === "object" && !Array.isArray(grp)) {
8597
+ pushGrp(grp);
8598
+ } else if (Array.isArray(grp)) {
8599
+ yield remoteLoad(grp);
8600
+ } else if (typeof grp === "string") {
8601
+ const grpData = yield this.remoteLoad(grp);
8602
+ if (Array.isArray(grpData))
8603
+ yield remoteLoad(grpData);
8604
+ else if (typeof grpData === "object")
8605
+ pushGrp(grpData);
8606
+ }
8607
+ }))
8608
+ );
8356
8609
  });
8357
8610
  yield remoteLoad(data);
8358
8611
  data.forEach((item) => {
@@ -8367,7 +8620,9 @@ class Emoticons extends EditorPlug {
8367
8620
  });
8368
8621
  }
8369
8622
  });
8370
- data = data.filter((item) => typeof item === "object" && !Array.isArray(item) && !!item && !!item.name);
8623
+ data = data.filter(
8624
+ (item) => typeof item === "object" && !Array.isArray(item) && !!item && !!item.name
8625
+ );
8371
8626
  this.solveNullKey(data);
8372
8627
  this.solveSameKey(data);
8373
8628
  return data;
@@ -8435,7 +8690,10 @@ class Emoticons extends EditorPlug {
8435
8690
  if (find && find.length > 1)
8436
8691
  item.icon = find[1];
8437
8692
  }
8438
- nGrp.items.push({ key: item.text || `${grpName} ${index + 1}`, val: item.icon });
8693
+ nGrp.items.push({
8694
+ key: item.text || `${grpName} ${index + 1}`,
8695
+ val: item.icon
8696
+ });
8439
8697
  });
8440
8698
  dest.push(nGrp);
8441
8699
  });
@@ -8531,7 +8789,9 @@ class Upload extends EditorPlug {
8531
8789
  this.$imgUploadInput.type = "file";
8532
8790
  this.$imgUploadInput.style.display = "none";
8533
8791
  this.$imgUploadInput.accept = AllowImgExts.map((o) => `.${o}`).join(",");
8534
- const $btn = this.useBtn(`<i aria-label="${t("uploadImage")}"><svg fill="currentColor" aria-hidden="true" height="14" viewBox="0 0 14 14" width="14"><path d="m0 1.94444c0-1.074107.870333-1.94444 1.94444-1.94444h10.11116c1.0741 0 1.9444.870333 1.9444 1.94444v10.11116c0 1.0741-.8703 1.9444-1.9444 1.9444h-10.11116c-1.074107 0-1.94444-.8703-1.94444-1.9444zm1.94444-.38888c-.21466 0-.38888.17422-.38888.38888v7.06689l2.33333-2.33333 2.33333 2.33333 3.88888-3.88889 2.3333 2.33334v-5.51134c0-.21466-.1742-.38888-.3888-.38888zm10.49996 8.09977-2.3333-2.33333-3.88888 3.8889-2.33333-2.33334-2.33333 2.33334v.8447c0 .2146.17422.3888.38888.3888h10.11116c.2146 0 .3888-.1742.3888-.3888zm-7.1944-6.54422c-.75133 0-1.36111.60978-1.36111 1.36111 0 .75134.60978 1.36111 1.36111 1.36111s1.36111-.60977 1.36111-1.36111c0-.75133-.60978-1.36111-1.36111-1.36111z"/></svg></i>`);
8792
+ const $btn = this.useBtn(
8793
+ `<i aria-label="${t("uploadImage")}"><svg fill="currentColor" aria-hidden="true" height="14" viewBox="0 0 14 14" width="14"><path d="m0 1.94444c0-1.074107.870333-1.94444 1.94444-1.94444h10.11116c1.0741 0 1.9444.870333 1.9444 1.94444v10.11116c0 1.0741-.8703 1.9444-1.9444 1.9444h-10.11116c-1.074107 0-1.94444-.8703-1.94444-1.9444zm1.94444-.38888c-.21466 0-.38888.17422-.38888.38888v7.06689l2.33333-2.33333 2.33333 2.33333 3.88888-3.88889 2.3333 2.33334v-5.51134c0-.21466-.1742-.38888-.3888-.38888zm10.49996 8.09977-2.3333-2.33333-3.88888 3.8889-2.33333-2.33334-2.33333 2.33334v.8447c0 .2146.17422.3888.38888.3888h10.11116c.2146 0 .3888-.1742.3888-.3888zm-7.1944-6.54422c-.75133 0-1.36111.60978-1.36111 1.36111 0 .75134.60978 1.36111 1.36111 1.36111s1.36111-.60977 1.36111-1.36111c0-.75133-.60978-1.36111-1.36111-1.36111z"/></svg></i>`
8794
+ );
8535
8795
  $btn.after(this.$imgUploadInput);
8536
8796
  $btn.onclick = () => {
8537
8797
  const $input = this.$imgUploadInput;
@@ -8592,7 +8852,7 @@ class Upload extends EditorPlug {
8592
8852
  uploadImg(file) {
8593
8853
  return __async(this, null, function* () {
8594
8854
  const fileExt = /[^.]+$/.exec(file.name);
8595
- if (!fileExt || !AllowImgExts.includes(fileExt[0]))
8855
+ if (!fileExt || !AllowImgExts.includes(String(fileExt[0]).toLowerCase()))
8596
8856
  return;
8597
8857
  if (!this.kit.useUser().checkHasBasicUserInfo()) {
8598
8858
  this.kit.useEditor().showNotify(t("uploadLoginMsg"), "w");
@@ -8622,7 +8882,9 @@ class Upload extends EditorPlug {
8622
8882
  base: this.kit.useConf().server,
8623
8883
  path: imgURL
8624
8884
  });
8625
- this.kit.useEditor().setContent(this.kit.useUI().$textarea.value.replace(uploadPlaceholderTxt, `${insertPrefix}![](${imgURL})`));
8885
+ this.kit.useEditor().setContent(
8886
+ this.kit.useUI().$textarea.value.replace(uploadPlaceholderTxt, `${insertPrefix}![](${imgURL})`)
8887
+ );
8626
8888
  } else {
8627
8889
  this.kit.useEditor().setContent(this.kit.useUI().$textarea.value.replace(uploadPlaceholderTxt, ""));
8628
8890
  }
@@ -8635,7 +8897,9 @@ class Preview extends EditorPlug {
8635
8897
  __publicField(this, "isPlugPanelShow", false);
8636
8898
  this.kit.useMounted(() => {
8637
8899
  this.usePanel(`<div class="atk-editor-plug-preview"></div>`);
8638
- this.useBtn(`<i aria-label="${t("preview")}"><svg fill="currentColor" aria-hidden="true" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M14.85 3H1.15C.52 3 0 3.52 0 4.15v7.69C0 12.48.52 13 1.15 13h13.69c.64 0 1.15-.52 1.15-1.15v-7.7C16 3.52 15.48 3 14.85 3zM9 11H7V8L5.5 9.92 4 8v3H2V5h2l1.5 2L7 5h2v6zm2.99.5L9.5 8H11V5h2v3h1.5l-2.51 3.5z"></path></svg></i>`);
8900
+ this.useBtn(
8901
+ `<i aria-label="${t("preview")}"><svg fill="currentColor" aria-hidden="true" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M14.85 3H1.15C.52 3 0 3.52 0 4.15v7.69C0 12.48.52 13 1.15 13h13.69c.64 0 1.15-.52 1.15-1.15v-7.7C16 3.52 15.48 3 14.85 3zM9 11H7V8L5.5 9.92 4 8v3H2V5h2l1.5 2L7 5h2v6zm2.99.5L9.5 8H11V5h2v3h1.5l-2.51 3.5z"></path></svg></i>`
8902
+ );
8639
8903
  });
8640
8904
  this.kit.useUnmounted(() => {
8641
8905
  });
@@ -8741,23 +9005,20 @@ class PlugManager {
8741
9005
  __publicField(this, "events", new EventManager());
8742
9006
  this.editor = editor;
8743
9007
  let confLoaded = false;
8744
- this.editor.ctx.watchConf([
8745
- "imgUpload",
8746
- "emoticons",
8747
- "preview",
8748
- "editorTravel",
8749
- "locale"
8750
- ], (conf) => {
8751
- confLoaded && this.getEvents().trigger("unmounted");
8752
- this.clear();
8753
- getEnabledPlugs(conf).forEach((Plug) => {
8754
- const kit = new PlugKit(this);
8755
- this.plugs.push(new Plug(kit));
8756
- });
8757
- this.getEvents().trigger("mounted");
8758
- confLoaded = true;
8759
- this.loadPluginUI();
8760
- });
9008
+ this.editor.ctx.watchConf(
9009
+ ["imgUpload", "emoticons", "preview", "editorTravel", "locale"],
9010
+ (conf) => {
9011
+ confLoaded && this.getEvents().trigger("unmounted");
9012
+ this.clear();
9013
+ getEnabledPlugs(conf).forEach((Plug) => {
9014
+ const kit = new PlugKit(this);
9015
+ this.plugs.push(new Plug(kit));
9016
+ });
9017
+ this.getEvents().trigger("mounted");
9018
+ confLoaded = true;
9019
+ this.loadPluginUI();
9020
+ }
9021
+ );
8761
9022
  this.events.on("panel-close", () => this.closePlugPanel());
8762
9023
  }
8763
9024
  getPlugs() {
@@ -8896,7 +9157,9 @@ const Unread = (ctx) => {
8896
9157
  const notifyKey = getQueryParam("atk_notify_key");
8897
9158
  if (notifyKey) {
8898
9159
  ctx.getApi().notifies.markNotifyRead(commentID, notifyKey).then(() => {
8899
- ctx.getData().updateNotifies(ctx.getData().getNotifies().filter((o) => o.comment_id !== commentID));
9160
+ ctx.getData().updateNotifies(
9161
+ ctx.getData().getNotifies().filter((o) => o.comment_id !== commentID)
9162
+ );
8900
9163
  });
8901
9164
  }
8902
9165
  });
@@ -8908,7 +9171,11 @@ const Count = (ctx) => {
8908
9171
  const $count = list2.$el.querySelector(".atk-comment-count .atk-text");
8909
9172
  if (!$count)
8910
9173
  return;
8911
- const text = htmlEncode(t("counter", { count: `${Number((_b = (_a = ctx.getData().getListLastFetch()) == null ? void 0 : _a.data) == null ? void 0 : _b.count) || 0}` }));
9174
+ const text = htmlEncode(
9175
+ t("counter", {
9176
+ count: `${Number((_b = (_a = ctx.getData().getListLastFetch()) == null ? void 0 : _a.data) == null ? void 0 : _b.count) || 0}`
9177
+ })
9178
+ );
8912
9179
  $count.innerHTML = text.replace(/(\d+)/, '<span class="atk-comment-count-num">$1</span>');
8913
9180
  };
8914
9181
  ctx.on("list-loaded", () => {
@@ -9017,7 +9284,7 @@ const GotoFocus = (ctx) => {
9017
9284
  comment.focus();
9018
9285
  }));
9019
9286
  };
9020
- const version = "2.8.4";
9287
+ const version = "2.8.6";
9021
9288
  const Copyright = (ctx) => {
9022
9289
  ctx.on("mounted", () => {
9023
9290
  const list2 = ctx.get("list");
@@ -9052,26 +9319,38 @@ const Dropdown = (ctx) => {
9052
9319
  renderDropdown({
9053
9320
  $dropdownWrap: $dropdownOn,
9054
9321
  dropdownList: [
9055
- [t("sortLatest"), () => {
9056
- reloadUseParamsEditor((p) => {
9057
- p.sort_by = "date_desc";
9058
- });
9059
- }],
9060
- [t("sortBest"), () => {
9061
- reloadUseParamsEditor((p) => {
9062
- p.sort_by = "vote";
9063
- });
9064
- }],
9065
- [t("sortOldest"), () => {
9066
- reloadUseParamsEditor((p) => {
9067
- p.sort_by = "date_asc";
9068
- });
9069
- }],
9070
- [t("sortAuthor"), () => {
9071
- reloadUseParamsEditor((p) => {
9072
- p.view_only_admin = true;
9073
- });
9074
- }]
9322
+ [
9323
+ t("sortLatest"),
9324
+ () => {
9325
+ reloadUseParamsEditor((p) => {
9326
+ p.sort_by = "date_desc";
9327
+ });
9328
+ }
9329
+ ],
9330
+ [
9331
+ t("sortBest"),
9332
+ () => {
9333
+ reloadUseParamsEditor((p) => {
9334
+ p.sort_by = "vote";
9335
+ });
9336
+ }
9337
+ ],
9338
+ [
9339
+ t("sortOldest"),
9340
+ () => {
9341
+ reloadUseParamsEditor((p) => {
9342
+ p.sort_by = "date_asc";
9343
+ });
9344
+ }
9345
+ ],
9346
+ [
9347
+ t("sortAuthor"),
9348
+ () => {
9349
+ reloadUseParamsEditor((p) => {
9350
+ p.view_only_admin = true;
9351
+ });
9352
+ }
9353
+ ]
9075
9354
  ]
9076
9355
  });
9077
9356
  };
@@ -9220,18 +9499,21 @@ const ReachBottom = (ctx) => {
9220
9499
  let observer = null;
9221
9500
  const setupObserver = ($target) => {
9222
9501
  const scrollEvtAt = ctx.conf.scrollRelativeTo && ctx.conf.scrollRelativeTo() || null;
9223
- observer = new IntersectionObserver(([entries]) => {
9224
- if (entries.isIntersecting) {
9225
- clearObserver();
9226
- ctx.trigger("list-reach-bottom");
9502
+ observer = new IntersectionObserver(
9503
+ ([entries]) => {
9504
+ if (entries.isIntersecting) {
9505
+ clearObserver();
9506
+ ctx.trigger("list-reach-bottom");
9507
+ }
9508
+ },
9509
+ {
9510
+ threshold: 0.9,
9511
+ // when the target is 90% visible
9512
+ // @see https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver/root
9513
+ // If the root is null, then the bounds of the actual document viewport are used.
9514
+ root: scrollEvtAt
9227
9515
  }
9228
- }, {
9229
- threshold: 0.9,
9230
- // when the target is 90% visible
9231
- // @see https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver/root
9232
- // If the root is null, then the bounds of the actual document viewport are used.
9233
- root: scrollEvtAt
9234
- });
9516
+ );
9235
9517
  observer.observe($target);
9236
9518
  };
9237
9519
  const clearObserver = () => {
@@ -9315,22 +9597,26 @@ function versionCheck(list2, feVer, beVer) {
9315
9597
  if (sameVer)
9316
9598
  return;
9317
9599
  const errEl = createElement(
9318
- `<div>${t("updateMsg", { name: comp < 0 ? t("frontend") : t("backend") })}<br/><br/><span style="color: var(--at-color-meta);">${t("currentVersion")}: ${t("frontend")} ${feVer} / ${t("backend")} ${beVer}</span><br/><br/></div>`
9600
+ `<div class="atk-version-check-notice">${t("updateMsg", {
9601
+ name: comp < 0 ? t("frontend") : t("backend")
9602
+ })} <span class="atk-info">${t("currentVersion")}: ${t("frontend")} ${feVer} / ${t("backend")} ${beVer}</span></div>`
9319
9603
  );
9320
- const ignoreBtn = createElement(`<span style="cursor:pointer">${t("ignore")}</span>`);
9604
+ const ignoreBtn = createElement(`<span class="atk-ignore-btn">${t("ignore")}</span>`);
9321
9605
  ignoreBtn.onclick = () => {
9322
- setError(list2.$el.parentElement, null);
9606
+ errEl.remove();
9323
9607
  IgnoreVersionCheck = true;
9324
- list2.ctx.fetch({ offset: 0 });
9325
9608
  };
9326
9609
  errEl.append(ignoreBtn);
9327
- setError(list2.$el.parentElement, errEl, '<span class="atk-warn-title">Artalk Warn</span>');
9610
+ list2.$el.parentElement.prepend(errEl);
9328
9611
  }
9329
9612
  const AdminOnlyElem = (ctx) => {
9330
9613
  const scanApply = () => {
9331
- applyAdminOnlyEls(ctx.get("user").getData().isAdmin, getAdminOnlyEls({
9332
- $root: ctx.$root
9333
- }));
9614
+ applyAdminOnlyEls(
9615
+ ctx.get("user").getData().isAdmin,
9616
+ getAdminOnlyEls({
9617
+ $root: ctx.$root
9618
+ })
9619
+ );
9334
9620
  };
9335
9621
  ctx.on("list-loaded", () => {
9336
9622
  scanApply();
@@ -9427,7 +9713,9 @@ function load(ctx) {
9427
9713
  };
9428
9714
  if (ctx.conf.useBackendConf) {
9429
9715
  if (!data.frontend_conf)
9430
- throw new Error("The remote backend does not respond to the frontend conf, but `useBackendConf` conf is enabled");
9716
+ throw new Error(
9717
+ "The remote backend does not respond to the frontend conf, but `useBackendConf` conf is enabled"
9718
+ );
9431
9719
  conf = __spreadValues(__spreadValues({}, conf), handleConfFormServer(data.frontend_conf));
9432
9720
  }
9433
9721
  ctx.conf.remoteConfModifier && ctx.conf.remoteConfModifier(conf);
@@ -9452,17 +9740,19 @@ function loadNetworkPlugins(scripts, apiBase) {
9452
9740
  scripts.forEach((url) => {
9453
9741
  if (!/^(http|https):\/\//.test(url))
9454
9742
  url = `${apiBase.replace(/\/$/, "")}/${url.replace(/^\//, "")}`;
9455
- tasks.push(new Promise((resolve, reject) => {
9456
- if (document.querySelector(`script[src="${url}"]`)) {
9457
- resolve();
9458
- return;
9459
- }
9460
- const script = document.createElement("script");
9461
- script.src = url;
9462
- document.head.appendChild(script);
9463
- script.onload = () => resolve();
9464
- script.onerror = (err) => reject(err);
9465
- }));
9743
+ tasks.push(
9744
+ new Promise((resolve, reject) => {
9745
+ if (document.querySelector(`script[src="${url}"]`)) {
9746
+ resolve();
9747
+ return;
9748
+ }
9749
+ const script = document.createElement("script");
9750
+ script.src = url;
9751
+ document.head.appendChild(script);
9752
+ script.onload = () => resolve();
9753
+ script.onerror = (err) => reject(err);
9754
+ })
9755
+ );
9466
9756
  });
9467
9757
  yield Promise.all(tasks);
9468
9758
  return Object.values(window.ArtalkPlugins || {});
@@ -9472,7 +9762,10 @@ function onLoadErr(ctx, err) {
9472
9762
  var _a;
9473
9763
  let sidebarOpenView = "";
9474
9764
  if ((_a = err.data) == null ? void 0 : _a.err_no_site) {
9475
- const viewLoadParam = { create_name: ctx.conf.site, create_urls: `${window.location.protocol}//${window.location.host}` };
9765
+ const viewLoadParam = {
9766
+ create_name: ctx.conf.site,
9767
+ create_urls: `${window.location.protocol}//${window.location.host}`
9768
+ };
9476
9769
  sidebarOpenView = `sites|${JSON.stringify(viewLoadParam)}`;
9477
9770
  }
9478
9771
  showErrorDialog({