artalk 2.8.0 → 2.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/Artalk.mjs CHANGED
@@ -381,6 +381,29 @@ let Api$1 = class Api extends HttpClient {
381
381
  type: "application/json",
382
382
  format: "json"
383
383
  }, params)),
384
+ /**
385
+ * @description Get the detail of a comment by comment id
386
+ *
387
+ * @tags Comment
388
+ * @name GetComment
389
+ * @summary Get a comment
390
+ * @request GET:/comments/{id}
391
+ * @response `200` `HandlerResponseCommentGet` OK
392
+ * @response `404` `(HandlerMap & {
393
+ msg?: string,
394
+
395
+ })` Not Found
396
+ * @response `500` `(HandlerMap & {
397
+ msg?: string,
398
+
399
+ })` Internal Server Error
400
+ */
401
+ getComment: (id, params = {}) => this.request(__spreadValues({
402
+ path: `/comments/${id}`,
403
+ method: "GET",
404
+ type: "application/json",
405
+ format: "json"
406
+ }, params)),
384
407
  /**
385
408
  * @description Update a specific comment
386
409
  *
@@ -5152,7 +5175,7 @@ function showLoading(parentElem, conf) {
5152
5175
  let $loading = parentElem.querySelector(":scope > .atk-loading");
5153
5176
  if (!$loading) {
5154
5177
  $loading = createElement(
5155
- `<div class="atk-loading atk-fade-in" style="display: none;">
5178
+ `<div class="atk-loading" style="display: none;">
5156
5179
  <div class="atk-loading-spinner">
5157
5180
  <svg viewBox="25 25 50 50"><circle cx="50" cy="50" r="20" fill="none" stroke-width="2" stroke-miterlimit="10"></circle></svg>
5158
5181
  </div>
@@ -5167,7 +5190,8 @@ function showLoading(parentElem, conf) {
5167
5190
  if ($spinner) {
5168
5191
  $spinner.style.display = "none";
5169
5192
  window.setTimeout(() => {
5170
- $spinner.style.display = "";
5193
+ if ($spinner.isConnected)
5194
+ $spinner.style.display = "";
5171
5195
  }, 500);
5172
5196
  }
5173
5197
  }
@@ -5187,8 +5211,7 @@ function scrollIntoView(elem, enableAnim = true, relativeTo) {
5187
5211
  if (relativeTo) {
5188
5212
  const containerRect = relativeTo.getBoundingClientRect();
5189
5213
  const elementRect = elem.getBoundingClientRect();
5190
- top = elementRect.top - containerRect.top + relativeTo.scrollTop;
5191
- top += getHeight(relativeTo) / 2 - getHeight(elem) / 2;
5214
+ top = elementRect.top - containerRect.top + relativeTo.scrollTop - relativeTo.clientHeight / 2 + elem.clientHeight / 2;
5192
5215
  } else {
5193
5216
  const rect = elem.getBoundingClientRect();
5194
5217
  const elemTop = rect.top + window.scrollY;
@@ -5522,6 +5545,9 @@ class Component {
5522
5545
  get conf() {
5523
5546
  return this.ctx.conf;
5524
5547
  }
5548
+ getEl() {
5549
+ return this.$el;
5550
+ }
5525
5551
  }
5526
5552
  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-plug-btn-wrap"></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';
5527
5553
  const Sel = {
@@ -5906,39 +5932,18 @@ function makeNestCommentNodeList(srcData, sortBy = "DATE_DESC", nestMax = 2) {
5906
5932
  })(nodeList);
5907
5933
  return nodeList;
5908
5934
  }
5909
- class ListLayout {
5910
- constructor(options) {
5911
- this.options = options;
5912
- }
5913
- // TODO: refactor `if syntax` to strategy pattern
5914
- import(comments) {
5915
- if (this.options.flatMode) {
5916
- comments.forEach((commentData) => {
5917
- this.putCommentFlatMode(commentData, comments, "append");
5918
- });
5919
- } else {
5920
- this.importCommentsNestMode(comments);
5921
- }
5922
- }
5923
- insert(comment) {
5924
- if (!this.options.flatMode) {
5925
- this.insertCommentNest(comment);
5926
- } else {
5927
- this.insertCommentFlatMode(comment);
5928
- }
5929
- }
5930
- // 导入评论 · 嵌套模式
5931
- importCommentsNestMode(srcData) {
5932
- const rootNodes = makeNestCommentNodeList(srcData, this.options.nestSortBy, this.options.nestMax);
5935
+ const createNestStrategy = (opts) => ({
5936
+ import: (comments) => {
5937
+ const rootNodes = makeNestCommentNodeList(comments, opts.nestSortBy, opts.nestMax);
5933
5938
  rootNodes.forEach((rootNode) => {
5934
5939
  var _a;
5935
- const rootC = this.options.createCommentNode(rootNode.comment, srcData);
5936
- (_a = this.options.$commentsWrap) == null ? void 0 : _a.appendChild(rootC.getEl());
5940
+ const rootC = opts.createCommentNode(rootNode.comment);
5941
+ (_a = opts.$commentsWrap) == null ? void 0 : _a.appendChild(rootC.getEl());
5937
5942
  rootC.getRender().playFadeAnim();
5938
5943
  const loadChildren = (parentC, parentNode) => {
5939
5944
  parentNode.children.forEach((node) => {
5940
5945
  const childD = node.comment;
5941
- const childC = this.options.createCommentNode(childD, srcData);
5946
+ const childC = opts.createCommentNode(childD, parentC.getData());
5942
5947
  parentC.putChild(childC);
5943
5948
  loadChildren(childC, node);
5944
5949
  });
@@ -5946,44 +5951,66 @@ class ListLayout {
5946
5951
  loadChildren(rootC, rootNode);
5947
5952
  rootC.getRender().checkHeightLimit();
5948
5953
  });
5949
- }
5950
- /** 导入评论 · 平铺模式 */
5951
- putCommentFlatMode(cData, ctxData, insertMode) {
5952
- var _a, _b;
5953
- if (cData.is_collapsed)
5954
- cData.is_allow_reply = false;
5955
- const comment = this.options.createCommentNode(cData, ctxData);
5956
- if (cData.visible) {
5957
- if (insertMode === "append")
5958
- (_a = this.options.$commentsWrap) == null ? void 0 : _a.append(comment.getEl());
5959
- if (insertMode === "prepend")
5960
- (_b = this.options.$commentsWrap) == null ? void 0 : _b.prepend(comment.getEl());
5961
- comment.getRender().playFadeAnim();
5962
- }
5963
- comment.getRender().checkHeightLimit();
5964
- return comment;
5965
- }
5966
- insertCommentNest(commentData) {
5954
+ },
5955
+ insert: (comment, replyComment) => {
5967
5956
  var _a;
5968
- const comment = this.options.createCommentNode(commentData, this.options.getCommentDataList());
5969
- if (commentData.rid === 0) {
5970
- (_a = this.options.$commentsWrap) == null ? void 0 : _a.prepend(comment.getEl());
5957
+ const node = opts.createCommentNode(comment, replyComment);
5958
+ if (comment.rid === 0) {
5959
+ (_a = opts.$commentsWrap) == null ? void 0 : _a.prepend(node.getEl());
5971
5960
  } else {
5972
- const parent = this.options.findCommentNode(commentData.rid);
5961
+ const parent = opts.findCommentNode(comment.rid);
5973
5962
  if (parent) {
5974
- parent.putChild(comment, this.options.nestSortBy === "DATE_ASC" ? "append" : "prepend");
5975
- comment.getParents().forEach((p) => {
5963
+ parent.putChild(node, opts.nestSortBy === "DATE_ASC" ? "append" : "prepend");
5964
+ node.getParents().forEach((p) => {
5976
5965
  p.getRender().heightLimitRemoveForChildren();
5977
5966
  });
5978
5967
  }
5979
5968
  }
5980
- comment.getRender().checkHeightLimit();
5981
- scrollIntoView(comment.getEl());
5982
- comment.getRender().playFadeAnim();
5969
+ node.getRender().checkHeightLimit();
5970
+ node.scrollIntoView();
5971
+ node.getRender().playFadeAnim();
5972
+ }
5973
+ });
5974
+ const createFlatStrategy = (opts) => ({
5975
+ import: (comments) => {
5976
+ comments.forEach((comment) => {
5977
+ const replyComment = comment.rid === 0 ? void 0 : comments.find((c) => c.id === comment.rid);
5978
+ insertComment(opts, "append", comment, replyComment);
5979
+ });
5980
+ },
5981
+ insert: (comment, replyComment) => {
5982
+ const node = insertComment(opts, "prepend", comment, replyComment);
5983
+ node.scrollIntoView();
5983
5984
  }
5984
- insertCommentFlatMode(commentData) {
5985
- const comment = this.putCommentFlatMode(commentData, this.options.getCommentDataList(), "prepend");
5986
- scrollIntoView(comment.getEl());
5985
+ });
5986
+ function insertComment(opts, insertMode, comment, replyComment) {
5987
+ if (comment.is_collapsed)
5988
+ comment.is_allow_reply = false;
5989
+ const node = opts.createCommentNode(comment, replyComment);
5990
+ if (comment.visible) {
5991
+ const $comment = node.getEl();
5992
+ const $listCommentsWrap = opts.$commentsWrap;
5993
+ if (insertMode === "append")
5994
+ $listCommentsWrap == null ? void 0 : $listCommentsWrap.append($comment);
5995
+ if (insertMode === "prepend")
5996
+ $listCommentsWrap == null ? void 0 : $listCommentsWrap.prepend($comment);
5997
+ node.getRender().playFadeAnim();
5998
+ }
5999
+ node.getRender().checkHeightLimit();
6000
+ return node;
6001
+ }
6002
+ class ListLayout {
6003
+ constructor(options) {
6004
+ this.options = options;
6005
+ }
6006
+ getStrategy() {
6007
+ return this.options.flatMode ? createFlatStrategy(this.options) : createNestStrategy(this.options);
6008
+ }
6009
+ import(comments) {
6010
+ this.getStrategy().import(comments);
6011
+ }
6012
+ insert(comment, replyComment) {
6013
+ this.getStrategy().insert(comment, replyComment);
5987
6014
  }
5988
6015
  }
5989
6016
  function Detect(userAgent) {
@@ -6246,7 +6273,7 @@ const CommentHTML = '<div class="atk-comment-wrap">\n <div class="atk-comment">
6246
6273
  function renderAvatar(r) {
6247
6274
  const $avatar = r.$el.querySelector(".atk-avatar");
6248
6275
  const $avatarImg = createElement("<img />");
6249
- const avatarURLBuilder = r.conf.avatarURLBuilder;
6276
+ const avatarURLBuilder = r.opts.avatarURLBuilder;
6250
6277
  $avatarImg.src = avatarURLBuilder ? avatarURLBuilder(r.data) : r.comment.getGravatarURL();
6251
6278
  if (r.data.link) {
6252
6279
  const $avatarA = createElement('<a target="_blank" rel="noreferrer noopener nofollow"></a>');
@@ -6285,12 +6312,12 @@ function renderVerifyBadge(ctx) {
6285
6312
  const badgeColor = ctx.data.badge_color;
6286
6313
  if (badgeText) {
6287
6314
  const $badge = createElement(`<span class="atk-badge"></span>`);
6288
- $badge.innerText = badgeText.replace("管理员", ctx.ctx.$t("admin"));
6315
+ $badge.innerText = badgeText.replace("管理员", t("admin"));
6289
6316
  $badge.style.backgroundColor = badgeColor || "";
6290
6317
  ctx.$headerBadgeWrap.append($badge);
6291
6318
  }
6292
6319
  if (ctx.data.is_pinned) {
6293
- const $pinnedBadge = createElement(`<span class="atk-pinned-badge">${ctx.ctx.$t("pin")}</span>`);
6320
+ const $pinnedBadge = createElement(`<span class="atk-pinned-badge">${t("pin")}</span>`);
6294
6321
  ctx.$headerBadgeWrap.append($pinnedBadge);
6295
6322
  }
6296
6323
  }
@@ -6300,7 +6327,7 @@ function renderDate(ctx) {
6300
6327
  $date.setAttribute("data-atk-comment-date", String(+new Date(ctx.data.date)));
6301
6328
  }
6302
6329
  function renderUABadge(ctx) {
6303
- if (!ctx.ctx.conf.uaBadge && !ctx.data.ip_region)
6330
+ if (!ctx.opts.uaBadge && !ctx.data.ip_region)
6304
6331
  return;
6305
6332
  let $uaWrap = ctx.$header.querySelector("atk-ua-wrap");
6306
6333
  if (!$uaWrap) {
@@ -6313,7 +6340,7 @@ function renderUABadge(ctx) {
6313
6340
  $regionBadge.innerText = ctx.data.ip_region;
6314
6341
  $uaWrap.append($regionBadge);
6315
6342
  }
6316
- if (ctx.ctx.conf.uaBadge) {
6343
+ if (ctx.opts.uaBadge) {
6317
6344
  const { browser, os } = ctx.comment.getUserUA();
6318
6345
  if (String(browser).trim()) {
6319
6346
  const $uaBrowser = createElement(`<span class="atk-ua ua-browser"></span>`);
@@ -6336,8 +6363,8 @@ function renderContent(r) {
6336
6363
  r.$content.classList.add("atk-hide", "atk-type-collapsed");
6337
6364
  const collapsedInfoEl = createElement(`
6338
6365
  <div class="atk-collapsed">
6339
- <span class="atk-text">${r.ctx.$t("collapsedMsg")}</span>
6340
- <span class="atk-show-btn">${r.ctx.$t("expand")}</span>
6366
+ <span class="atk-text">${t("collapsedMsg")}</span>
6367
+ <span class="atk-show-btn">${t("expand")}</span>
6341
6368
  </div>`);
6342
6369
  r.$body.insertAdjacentElement("beforeend", collapsedInfoEl);
6343
6370
  const contentShowBtn = collapsedInfoEl.querySelector(".atk-show-btn");
@@ -6347,51 +6374,51 @@ function renderContent(r) {
6347
6374
  r.$content.innerHTML = r.comment.getContentMarked();
6348
6375
  r.$content.classList.remove("atk-hide");
6349
6376
  playFadeInAnim(r.$content);
6350
- contentShowBtn.innerText = r.ctx.$t("collapse");
6377
+ contentShowBtn.innerText = t("collapse");
6351
6378
  } else {
6352
6379
  r.$content.innerHTML = "";
6353
6380
  r.$content.classList.add("atk-hide");
6354
- contentShowBtn.innerText = r.ctx.$t("expand");
6381
+ contentShowBtn.innerText = t("expand");
6355
6382
  }
6356
6383
  });
6357
6384
  }
6358
6385
  function renderReplyAt(r) {
6359
- if (r.cConf.isFlatMode || r.data.rid === 0)
6386
+ if (r.opts.flatMode || r.data.rid === 0)
6360
6387
  return;
6361
- if (!r.cConf.replyTo)
6388
+ if (!r.opts.replyTo)
6362
6389
  return;
6363
6390
  r.$replyAt = createElement(`<span class="atk-item atk-reply-at"><span class="atk-arrow"></span><span class="atk-nick"></span></span>`);
6364
- r.$replyAt.querySelector(".atk-nick").innerText = `${r.cConf.replyTo.nick}`;
6391
+ r.$replyAt.querySelector(".atk-nick").innerText = `${r.opts.replyTo.nick}`;
6365
6392
  r.$replyAt.onclick = () => {
6366
6393
  r.comment.getActions().goToReplyComment();
6367
6394
  };
6368
6395
  r.$headerBadgeWrap.insertAdjacentElement("afterend", r.$replyAt);
6369
6396
  }
6370
6397
  function renderReplyTo(r) {
6371
- if (!r.cConf.isFlatMode)
6398
+ if (!r.opts.flatMode)
6372
6399
  return;
6373
- if (!r.cConf.replyTo)
6400
+ if (!r.opts.replyTo)
6374
6401
  return;
6375
6402
  r.$replyTo = createElement(`
6376
6403
  <div class="atk-reply-to">
6377
- <div class="atk-meta">${r.ctx.$t("reply")} <span class="atk-nick"></span>:</div>
6404
+ <div class="atk-meta">${t("reply")} <span class="atk-nick"></span>:</div>
6378
6405
  <div class="atk-content"></div>
6379
6406
  </div>`);
6380
6407
  const $nick = r.$replyTo.querySelector(".atk-nick");
6381
- $nick.innerText = `@${r.cConf.replyTo.nick}`;
6408
+ $nick.innerText = `@${r.opts.replyTo.nick}`;
6382
6409
  $nick.onclick = () => {
6383
6410
  r.comment.getActions().goToReplyComment();
6384
6411
  };
6385
- let replyContent = marked(r.cConf.replyTo.content);
6386
- if (r.cConf.replyTo.is_collapsed)
6387
- replyContent = `[${r.ctx.$t("collapsed")}]`;
6412
+ let replyContent = marked(r.opts.replyTo.content);
6413
+ if (r.opts.replyTo.is_collapsed)
6414
+ replyContent = `[${t("collapsed")}]`;
6388
6415
  r.$replyTo.querySelector(".atk-content").innerHTML = replyContent;
6389
6416
  r.$body.prepend(r.$replyTo);
6390
6417
  }
6391
6418
  function renderPending(r) {
6392
6419
  if (!r.data.is_pending)
6393
6420
  return;
6394
- const pendingEl = createElement(`<div class="atk-pending">${r.ctx.$t("pendingMsg")}</div>`);
6421
+ const pendingEl = createElement(`<div class="atk-pending">${t("pendingMsg")}</div>`);
6395
6422
  r.$body.prepend(pendingEl);
6396
6423
  }
6397
6424
  class ActionBtn {
@@ -6544,14 +6571,14 @@ function renderActions(r) {
6544
6571
  });
6545
6572
  }
6546
6573
  function renderVote(r) {
6547
- if (!r.ctx.conf.vote)
6574
+ if (!r.opts.vote)
6548
6575
  return;
6549
- r.voteBtnUp = new ActionBtn(() => `${r.ctx.$t("voteUp")} (${r.data.vote_up || 0})`).appendTo(r.$actions);
6576
+ r.voteBtnUp = new ActionBtn(() => `${t("voteUp")} (${r.data.vote_up || 0})`).appendTo(r.$actions);
6550
6577
  r.voteBtnUp.setClick(() => {
6551
6578
  r.comment.getActions().vote("up");
6552
6579
  });
6553
- if (r.ctx.conf.voteDown) {
6554
- r.voteBtnDown = new ActionBtn(() => `${r.ctx.$t("voteDown")} (${r.data.vote_down || 0})`).appendTo(r.$actions);
6580
+ if (r.opts.voteDown) {
6581
+ r.voteBtnDown = new ActionBtn(() => `${t("voteDown")} (${r.data.vote_down || 0})`).appendTo(r.$actions);
6555
6582
  r.voteBtnDown.setClick(() => {
6556
6583
  r.comment.getActions().vote("down");
6557
6584
  });
@@ -6560,20 +6587,16 @@ function renderVote(r) {
6560
6587
  function renderReply(r) {
6561
6588
  if (!r.data.is_allow_reply)
6562
6589
  return;
6563
- const replyBtn = createElement(`<span>${r.ctx.$t("reply")}</span>`);
6590
+ const replyBtn = createElement(`<span>${t("reply")}</span>`);
6564
6591
  r.$actions.append(replyBtn);
6565
6592
  replyBtn.addEventListener("click", (e) => {
6566
6593
  e.stopPropagation();
6567
- if (!r.cConf.onReplyBtnClick) {
6568
- r.ctx.replyComment(r.data, r.$el);
6569
- } else {
6570
- r.cConf.onReplyBtnClick();
6571
- }
6594
+ r.opts.replyComment(r.data, r.$el);
6572
6595
  });
6573
6596
  }
6574
6597
  function renderCollapse(r) {
6575
6598
  const collapseBtn = new ActionBtn({
6576
- text: () => r.data.is_collapsed ? r.ctx.$t("expand") : r.ctx.$t("collapse"),
6599
+ text: () => r.data.is_collapsed ? t("expand") : t("collapse"),
6577
6600
  adminOnly: true
6578
6601
  });
6579
6602
  collapseBtn.appendTo(r.$actions);
@@ -6583,7 +6606,7 @@ function renderCollapse(r) {
6583
6606
  }
6584
6607
  function renderModerator(r) {
6585
6608
  const pendingBtn = new ActionBtn({
6586
- text: () => r.data.is_pending ? r.ctx.$t("pending") : r.ctx.$t("approved"),
6609
+ text: () => r.data.is_pending ? t("pending") : t("approved"),
6587
6610
  adminOnly: true
6588
6611
  });
6589
6612
  pendingBtn.appendTo(r.$actions);
@@ -6593,7 +6616,7 @@ function renderModerator(r) {
6593
6616
  }
6594
6617
  function renderPin(r) {
6595
6618
  const pinnedBtn = new ActionBtn({
6596
- text: () => r.data.is_pinned ? r.ctx.$t("unpin") : r.ctx.$t("pin"),
6619
+ text: () => r.data.is_pinned ? t("unpin") : t("pin"),
6597
6620
  adminOnly: true
6598
6621
  });
6599
6622
  pinnedBtn.appendTo(r.$actions);
@@ -6603,19 +6626,19 @@ function renderPin(r) {
6603
6626
  }
6604
6627
  function renderEdit(r) {
6605
6628
  const editBtn = new ActionBtn({
6606
- text: r.ctx.$t("edit"),
6629
+ text: t("edit"),
6607
6630
  adminOnly: true
6608
6631
  });
6609
6632
  editBtn.appendTo(r.$actions);
6610
6633
  editBtn.setClick(() => {
6611
- r.ctx.editComment(r.data, r.$el);
6634
+ r.opts.editComment(r.data, r.$el);
6612
6635
  });
6613
6636
  }
6614
6637
  function renderDel(r) {
6615
6638
  const delBtn = new ActionBtn({
6616
- text: r.ctx.$t("delete"),
6639
+ text: t("delete"),
6617
6640
  confirm: true,
6618
- confirmText: r.ctx.$t("deleteConfirm"),
6641
+ confirmText: t("deleteConfirm"),
6619
6642
  adminOnly: true
6620
6643
  });
6621
6644
  delBtn.appendTo(r.$actions);
@@ -6657,18 +6680,21 @@ class Render {
6657
6680
  __publicField(this, "$replyAt");
6658
6681
  this.comment = comment;
6659
6682
  }
6660
- get ctx() {
6661
- return this.comment.ctx;
6662
- }
6663
6683
  get data() {
6664
6684
  return this.comment.getData();
6665
6685
  }
6666
- get conf() {
6667
- return this.comment.conf;
6668
- }
6669
- get cConf() {
6670
- return this.comment.getConf();
6686
+ get opts() {
6687
+ return this.comment.getOpts();
6671
6688
  }
6689
+ /**
6690
+ * Render the comment ui
6691
+ *
6692
+ * If comment data is updated, call this method to re-render the comment ui.
6693
+ * The method will be called multiple times, so it should be idempotent.
6694
+ *
6695
+ * Renders may add event listeners to the comment ui, so it should be called only once or override the original.
6696
+ * Please be aware of the memory leak caused by the event listener.
6697
+ */
6672
6698
  render() {
6673
6699
  this.$el = createElement(CommentHTML);
6674
6700
  this.$main = this.$el.querySelector(".atk-main");
@@ -6678,12 +6704,14 @@ class Render {
6678
6704
  this.$actions = this.$el.querySelector(".atk-actions");
6679
6705
  this.$el.setAttribute("id", `atk-comment-${this.data.id}`);
6680
6706
  loadRenders(this);
6681
- this.recoveryChildrenWrap();
6707
+ if (this.$childrenWrap) {
6708
+ this.$main.append(this.$childrenWrap);
6709
+ }
6682
6710
  return this.$el;
6683
6711
  }
6684
6712
  /** 内容限高检测 */
6685
6713
  checkHeightLimit() {
6686
- const conf = this.ctx.conf.heightLimit;
6714
+ const conf = this.opts.heightLimit;
6687
6715
  if (!conf || !conf.content || !conf.children)
6688
6716
  return;
6689
6717
  const contentMaxH = conf.content;
@@ -6717,24 +6745,21 @@ class Render {
6717
6745
  playFadeAnimForBody() {
6718
6746
  playFadeInAnim(this.comment.getRender().$body);
6719
6747
  }
6748
+ /** Perform the flash animation */
6749
+ playFlashAnim() {
6750
+ this.$el.classList.remove("atk-flash-once");
6751
+ window.setTimeout(() => {
6752
+ this.$el.classList.add("atk-flash-once");
6753
+ }, 150);
6754
+ }
6720
6755
  /** 获取子评论 Wrap */
6721
6756
  getChildrenWrap() {
6722
- return this.$childrenWrap;
6723
- }
6724
- /** 初始化子评论区域 Wrap */
6725
- renderChildrenWrap() {
6726
6757
  if (!this.$childrenWrap) {
6727
6758
  this.$childrenWrap = createElement('<div class="atk-comment-children"></div>');
6728
6759
  this.$main.append(this.$childrenWrap);
6729
6760
  }
6730
6761
  return this.$childrenWrap;
6731
6762
  }
6732
- /** 恢复原有的子评论区域 Wrap */
6733
- recoveryChildrenWrap() {
6734
- if (this.$childrenWrap) {
6735
- this.$main.append(this.$childrenWrap);
6736
- }
6737
- }
6738
6763
  /** 设置已读 */
6739
6764
  setUnread(val) {
6740
6765
  if (val)
@@ -6753,17 +6778,15 @@ class Render {
6753
6778
  setOpenURL(url) {
6754
6779
  this.setOpenable(true);
6755
6780
  this.$el.onclick = (evt) => {
6756
- evt.preventDefault();
6781
+ evt.stopPropagation();
6757
6782
  window.open(url);
6758
- if (this.cConf.openEvt)
6759
- this.cConf.openEvt();
6760
6783
  };
6761
6784
  }
6762
6785
  /** 设置点击评论时的操作 */
6763
6786
  setOpenAction(action) {
6764
6787
  this.setOpenable(true);
6765
6788
  this.$el.onclick = (evt) => {
6766
- evt.preventDefault();
6789
+ evt.stopPropagation();
6767
6790
  action();
6768
6791
  };
6769
6792
  }
@@ -6773,26 +6796,26 @@ class CommentActions {
6773
6796
  __publicField(this, "comment");
6774
6797
  this.comment = comment;
6775
6798
  }
6776
- get ctx() {
6777
- return this.comment.ctx;
6778
- }
6779
6799
  get data() {
6780
6800
  return this.comment.getData();
6781
6801
  }
6782
- get cConf() {
6783
- return this.comment.getConf();
6802
+ get opts() {
6803
+ return this.comment.getOpts();
6804
+ }
6805
+ getApi() {
6806
+ return this.comment.getOpts().getApi();
6784
6807
  }
6785
6808
  /** 投票操作 */
6786
6809
  vote(type) {
6787
6810
  const actionBtn = type === "up" ? this.comment.getRender().voteBtnUp : this.comment.getRender().voteBtnDown;
6788
- this.ctx.getApi().votes.vote(`comment_${type}`, this.data.id, __spreadValues({}, this.ctx.getApi().getUserFields())).then((res) => {
6811
+ this.getApi().votes.vote(`comment_${type}`, this.data.id, __spreadValues({}, this.getApi().getUserFields())).then((res) => {
6789
6812
  var _a, _b;
6790
6813
  this.data.vote_up = res.data.up;
6791
6814
  this.data.vote_down = res.data.down;
6792
6815
  (_a = this.comment.getRender().voteBtnUp) == null ? void 0 : _a.updateText();
6793
6816
  (_b = this.comment.getRender().voteBtnDown) == null ? void 0 : _b.updateText();
6794
6817
  }).catch((err) => {
6795
- actionBtn == null ? void 0 : actionBtn.setError(this.ctx.$t("voteFail"));
6818
+ actionBtn == null ? void 0 : actionBtn.setError(t("voteFail"));
6796
6819
  console.log(err);
6797
6820
  });
6798
6821
  }
@@ -6800,7 +6823,7 @@ class CommentActions {
6800
6823
  adminEdit(type, btnElem) {
6801
6824
  if (btnElem.isLoading)
6802
6825
  return;
6803
- btnElem.setLoading(true, `${this.ctx.$t("editing")}...`);
6826
+ btnElem.setLoading(true, `${t("editing")}...`);
6804
6827
  const modify = __spreadValues({}, this.data);
6805
6828
  if (type === "collapsed") {
6806
6829
  modify.is_collapsed = !modify.is_collapsed;
@@ -6809,26 +6832,26 @@ class CommentActions {
6809
6832
  } else if (type === "pinned") {
6810
6833
  modify.is_pinned = !modify.is_pinned;
6811
6834
  }
6812
- this.ctx.getApi().comments.updateComment(this.data.id, __spreadValues({}, modify)).then((res) => {
6835
+ this.getApi().comments.updateComment(this.data.id, __spreadValues({}, modify)).then((res) => {
6813
6836
  btnElem.setLoading(false);
6814
6837
  this.comment.setData(res.data);
6815
6838
  }).catch((err) => {
6816
6839
  console.error(err);
6817
- btnElem.setError(this.ctx.$t("editFail"));
6840
+ btnElem.setError(t("editFail"));
6818
6841
  });
6819
6842
  }
6820
6843
  /** 管理员 - 评论删除 */
6821
6844
  adminDelete(btnElem) {
6822
6845
  if (btnElem.isLoading)
6823
6846
  return;
6824
- btnElem.setLoading(true, `${this.ctx.$t("deleting")}...`);
6825
- this.ctx.getApi().comments.deleteComment(this.data.id).then(() => {
6847
+ btnElem.setLoading(true, `${t("deleting")}...`);
6848
+ this.getApi().comments.deleteComment(this.data.id).then(() => {
6826
6849
  btnElem.setLoading(false);
6827
- if (this.cConf.onDelete)
6828
- this.cConf.onDelete(this.comment);
6850
+ if (this.opts.onDelete)
6851
+ this.opts.onDelete(this.comment);
6829
6852
  }).catch((e) => {
6830
6853
  console.error(e);
6831
- btnElem.setError(this.ctx.$t("deleteFail"));
6854
+ btnElem.setError(t("deleteFail"));
6832
6855
  });
6833
6856
  }
6834
6857
  /** 快速跳转到该评论 */
@@ -6840,21 +6863,18 @@ class CommentActions {
6840
6863
  window.dispatchEvent(new Event("hashchange"));
6841
6864
  }
6842
6865
  }
6843
- class CommentNode extends Component {
6844
- // 最大嵌套层数
6845
- constructor(ctx, data, conf) {
6846
- super(ctx);
6866
+ class CommentNode {
6867
+ // 当前嵌套层数
6868
+ constructor(data, opts) {
6869
+ __publicField(this, "$el");
6847
6870
  __publicField(this, "renderInstance");
6848
6871
  __publicField(this, "actionInstance");
6849
6872
  __publicField(this, "data");
6850
- __publicField(this, "cConf");
6873
+ __publicField(this, "opts");
6851
6874
  __publicField(this, "parent");
6852
6875
  __publicField(this, "children", []);
6853
6876
  __publicField(this, "nestCurt");
6854
- // 当前嵌套层数
6855
- __publicField(this, "nestMax");
6856
- this.nestMax = ctx.conf.nestMax || 3;
6857
- this.cConf = conf;
6877
+ this.opts = opts;
6858
6878
  this.data = __spreadValues({}, data);
6859
6879
  this.data.date = this.data.date.replace(/-/g, "/");
6860
6880
  this.parent = null;
@@ -6868,8 +6888,8 @@ class CommentNode extends Component {
6868
6888
  if (this.$el)
6869
6889
  this.$el.replaceWith(newEl);
6870
6890
  this.$el = newEl;
6871
- if (this.cConf.afterRender)
6872
- this.cConf.afterRender();
6891
+ if (this.opts.onAfterRender)
6892
+ this.opts.onAfterRender();
6873
6893
  }
6874
6894
  /** 获取评论操作实例对象 */
6875
6895
  getActions() {
@@ -6910,51 +6930,76 @@ class CommentNode extends Component {
6910
6930
  return this.data.id;
6911
6931
  }
6912
6932
  /** 置入子评论 */
6913
- putChild(childC, insertMode = "append") {
6914
- childC.parent = this;
6915
- childC.nestCurt = this.nestCurt + 1;
6916
- this.children.push(childC);
6917
- const $children = this.getChildrenEl();
6933
+ putChild(childNode, insertMode = "append") {
6934
+ childNode.parent = this;
6935
+ childNode.nestCurt = this.nestCurt + 1;
6936
+ this.children.push(childNode);
6937
+ const $childrenWrap = this.getChildrenWrapEl();
6938
+ const $childComment = childNode.getEl();
6918
6939
  if (insertMode === "append")
6919
- $children.append(childC.getEl());
6940
+ $childrenWrap.append($childComment);
6920
6941
  else if (insertMode === "prepend")
6921
- $children.prepend(childC.getEl());
6922
- childC.getRender().playFadeAnim();
6923
- childC.getRender().checkHeightLimit();
6942
+ $childrenWrap.prepend($childComment);
6943
+ childNode.getRender().playFadeAnim();
6944
+ childNode.getRender().checkHeightLimit();
6924
6945
  }
6925
6946
  /** 获取存放子评论的元素对象 */
6926
- getChildrenEl() {
6927
- let $children = this.getRender().getChildrenWrap();
6928
- if (!$children) {
6929
- if (this.nestCurt < this.nestMax) {
6930
- $children = this.getRender().renderChildrenWrap();
6931
- } else {
6932
- $children = this.parent.getChildrenEl();
6933
- }
6947
+ getChildrenWrapEl() {
6948
+ if (this.nestCurt >= this.opts.nestMax) {
6949
+ return this.parent.getChildrenWrapEl();
6934
6950
  }
6935
- return $children;
6951
+ return this.getRender().getChildrenWrap();
6936
6952
  }
6937
6953
  /** 获取所有父评论 */
6938
6954
  getParents() {
6939
- const parents = [];
6940
- const once = (c) => {
6941
- if (c.parent) {
6942
- parents.push(c.parent);
6943
- once(c.parent);
6944
- }
6945
- };
6946
- once(this);
6947
- return parents;
6955
+ const flattenParents = [];
6956
+ let parent = this.parent;
6957
+ while (parent) {
6958
+ flattenParents.push(parent);
6959
+ parent = parent.getParent();
6960
+ }
6961
+ return flattenParents;
6948
6962
  }
6949
- /** 获取评论元素对象 */
6963
+ /**
6964
+ * Get the element of the comment
6965
+ *
6966
+ * The `getEl()` will always return the latest $el after calling `render()`.
6967
+ * Please be aware of the memory leak if you use the $el reference directly.
6968
+ */
6950
6969
  getEl() {
6970
+ if (!this.$el)
6971
+ throw new Error("comment element not initialized before `getEl()`");
6951
6972
  return this.$el;
6952
6973
  }
6974
+ /**
6975
+ * Focus on the comment
6976
+ *
6977
+ * Scroll to the comment and perform flash animation
6978
+ */
6979
+ focus() {
6980
+ if (!this.$el)
6981
+ throw new Error("comment element not initialized before `focus()`");
6982
+ this.getParents().forEach((p) => {
6983
+ p.getRender().heightLimitRemoveForChildren();
6984
+ });
6985
+ this.scrollIntoView();
6986
+ this.getRender().playFlashAnim();
6987
+ }
6988
+ scrollIntoView() {
6989
+ this.$el && scrollIntoView(this.$el, false, this.opts.scrollRelativeTo && this.opts.scrollRelativeTo());
6990
+ }
6991
+ /**
6992
+ * Remove the comment node
6993
+ */
6994
+ remove() {
6995
+ var _a;
6996
+ (_a = this.$el) == null ? void 0 : _a.remove();
6997
+ }
6953
6998
  /** 获取 Gravatar 头像 URL */
6954
6999
  getGravatarURL() {
6955
7000
  return getGravatarURL({
6956
- mirror: this.ctx.conf.gravatar.mirror,
6957
- params: this.ctx.conf.gravatar.params,
7001
+ mirror: this.opts.gravatar.mirror,
7002
+ params: this.opts.gravatar.params,
6958
7003
  emailMD5: this.data.email_encrypted
6959
7004
  });
6960
7005
  }
@@ -6964,7 +7009,7 @@ class CommentNode extends Component {
6964
7009
  }
6965
7010
  /** 获取格式化后的日期 */
6966
7011
  getDateFormatted() {
6967
- return timeAgo(new Date(this.data.date), this.ctx.$t);
7012
+ return timeAgo(new Date(this.data.date), t);
6968
7013
  }
6969
7014
  /** 获取用户 UserAgent 信息 */
6970
7015
  getUserUA() {
@@ -6975,21 +7020,33 @@ class CommentNode extends Component {
6975
7020
  };
6976
7021
  }
6977
7022
  /** 获取配置 */
6978
- getConf() {
6979
- return this.cConf;
7023
+ getOpts() {
7024
+ return this.opts;
6980
7025
  }
6981
7026
  }
6982
- function createComment(ctx, comment, ctxComments) {
6983
- var _a;
6984
- const instance2 = new CommentNode(ctx, comment, {
6985
- isFlatMode: (_a = ctx.getData().getListLastFetch()) == null ? void 0 : _a.params.flatMode,
6986
- afterRender: () => {
7027
+ function createCommentNode(ctx, comment, replyComment, opts) {
7028
+ const instance2 = new CommentNode(comment, {
7029
+ onAfterRender: () => {
6987
7030
  ctx.trigger("comment-rendered", instance2);
6988
7031
  },
6989
7032
  onDelete: (c) => {
6990
7033
  ctx.getData().deleteComment(c.getID());
6991
7034
  },
6992
- replyTo: comment.rid ? ctxComments.find((c) => c.id === comment.rid) : void 0
7035
+ replyTo: replyComment,
7036
+ // TODO simplify reference
7037
+ flatMode: typeof (opts == null ? void 0 : opts.forceFlatMode) === "boolean" ? opts == null ? void 0 : opts.forceFlatMode : ctx.conf.flatMode,
7038
+ gravatar: ctx.conf.gravatar,
7039
+ nestMax: ctx.conf.nestMax,
7040
+ heightLimit: ctx.conf.heightLimit,
7041
+ avatarURLBuilder: ctx.conf.avatarURLBuilder,
7042
+ scrollRelativeTo: ctx.conf.scrollRelativeTo,
7043
+ vote: ctx.conf.vote,
7044
+ voteDown: ctx.conf.voteDown,
7045
+ uaBadge: ctx.conf.uaBadge,
7046
+ // TODO: move to plugin folder and remove from core
7047
+ getApi: () => ctx.getApi(),
7048
+ replyComment: (c, $el) => ctx.replyComment(c, $el),
7049
+ editComment: (c, $el) => ctx.editComment(c, $el)
6993
7050
  });
6994
7051
  instance2.render();
6995
7052
  return instance2;
@@ -7365,20 +7422,19 @@ class List extends Component {
7365
7422
  getCommentNodes() {
7366
7423
  return this.commentNodes;
7367
7424
  }
7368
- getListLayout() {
7425
+ getListLayout({ forceFlatMode } = {}) {
7369
7426
  return new ListLayout({
7370
7427
  $commentsWrap: this.$commentsWrap,
7371
7428
  nestSortBy: this.ctx.conf.nestSort,
7372
7429
  nestMax: this.ctx.conf.nestMax,
7373
- flatMode: this.ctx.conf.flatMode,
7430
+ flatMode: typeof forceFlatMode === "boolean" ? forceFlatMode : this.ctx.conf.flatMode,
7374
7431
  // flatMode must be boolean because it had been handled when Artalk.init
7375
- createCommentNode: (d, c) => {
7376
- const node = createComment(this.ctx, d, c);
7432
+ createCommentNode: (d, r) => {
7433
+ const node = createCommentNode(this.ctx, d, r, { forceFlatMode });
7377
7434
  this.commentNodes.push(node);
7378
7435
  return node;
7379
7436
  },
7380
- findCommentNode: (id) => this.commentNodes.find((c) => c.getID() === id),
7381
- getCommentDataList: () => this.ctx.getData().getComments()
7437
+ findCommentNode: (id) => this.commentNodes.find((c) => c.getID() === id)
7382
7438
  });
7383
7439
  }
7384
7440
  initCrudEvents() {
@@ -7386,8 +7442,10 @@ class List extends Component {
7386
7442
  this.getListLayout().import(comments);
7387
7443
  });
7388
7444
  this.ctx.on("list-loaded", (comments) => {
7389
- if (comments.length === 0)
7445
+ if (comments.length === 0) {
7446
+ this.commentNodes = [];
7390
7447
  this.$commentsWrap.innerHTML = "";
7448
+ }
7391
7449
  });
7392
7450
  this.ctx.on("comment-inserted", (comment) => {
7393
7451
  this.getListLayout().insert(comment);
@@ -7398,7 +7456,7 @@ class List extends Component {
7398
7456
  console.error(`comment node id=${comment.id} not found`);
7399
7457
  return;
7400
7458
  }
7401
- node.getEl().remove();
7459
+ node.remove();
7402
7460
  this.commentNodes = this.commentNodes.filter((c) => c.getID() !== comment.id);
7403
7461
  });
7404
7462
  this.ctx.on("comment-updated", (comment) => {
@@ -8883,62 +8941,50 @@ const UnreadBadge = (ctx) => {
8883
8941
  showUnreadBadge(notifies.length || 0);
8884
8942
  });
8885
8943
  };
8886
- const Goto = (ctx) => {
8887
- let delayGoto = true;
8888
- const check2 = () => {
8944
+ const GotoDispatcher = (ctx) => {
8945
+ let lastID = 0;
8946
+ const check2 = ({ locker }) => {
8889
8947
  const commentID = extractCommentID();
8890
8948
  if (!commentID)
8891
8949
  return;
8950
+ if (locker && lastID === commentID)
8951
+ return;
8952
+ lastID = commentID;
8892
8953
  ctx.trigger("list-goto", commentID);
8893
- delayGoto = true;
8894
- };
8895
- const hashChangeHandler = () => {
8896
- delayGoto = false;
8897
- check2();
8898
8954
  };
8955
+ const hashChangeHandler = () => check2({ locker: false });
8956
+ const listLoadedHandler = () => check2({ locker: true });
8899
8957
  ctx.on("mounted", () => {
8900
8958
  window.addEventListener("hashchange", hashChangeHandler);
8901
- ctx.on("list-loaded", check2);
8959
+ ctx.on("list-loaded", listLoadedHandler);
8902
8960
  });
8903
8961
  ctx.on("unmounted", () => {
8904
8962
  window.removeEventListener("hashchange", hashChangeHandler);
8905
- ctx.off("list-loaded", check2);
8906
- });
8907
- let foundID = 0;
8908
- ctx.on("list-goto", (commentID) => {
8909
- if (foundID === commentID)
8910
- return;
8911
- const comment = ctx.get("list").getCommentNodes().find((c) => c.getID() === commentID);
8912
- if (!comment)
8913
- return;
8914
- foundID = commentID;
8915
- comment.getParents().forEach((p) => {
8916
- p.getRender().heightLimitRemoveForChildren();
8917
- });
8918
- const goTo = () => {
8919
- scrollIntoView(comment.getEl(), false);
8920
- comment.getEl().classList.remove("atk-flash-once");
8921
- window.setTimeout(() => {
8922
- comment.getEl().classList.add("atk-flash-once");
8923
- }, 150);
8924
- };
8925
- if (!delayGoto)
8926
- goTo();
8927
- else
8928
- window.setTimeout(() => goTo(), 350);
8963
+ ctx.off("list-loaded", listLoadedHandler);
8929
8964
  });
8930
8965
  };
8931
8966
  function extractCommentID() {
8932
- let commentId = Number(getQueryParam("atk_comment"));
8967
+ const match = window.location.hash.match(/#atk-comment-([0-9]+)/);
8968
+ let commentId = match && match[1] && !Number.isNaN(parseFloat(match[1])) ? parseFloat(match[1]) : null;
8933
8969
  if (!commentId) {
8934
- const match = window.location.hash.match(/#atk-comment-([0-9]+)/);
8935
- if (!match || !match[1] || Number.isNaN(Number(match[1])))
8936
- return null;
8937
- commentId = Number(match[1]);
8970
+ commentId = Number(getQueryParam("atk_comment"));
8938
8971
  }
8939
8972
  return commentId || null;
8940
8973
  }
8941
- const version = "2.8.0";
8974
+ const GotoFocus = (ctx) => {
8975
+ ctx.on("list-goto", (commentID) => __async(void 0, null, function* () {
8976
+ let comment = ctx.getCommentNodes().find((c) => c.getID() === commentID);
8977
+ if (!comment) {
8978
+ const data = (yield ctx.getApi().comments.getComment(commentID)).data;
8979
+ ctx.get("list").getListLayout({ forceFlatMode: true }).insert(data.comment, data.reply_comment);
8980
+ comment = ctx.getCommentNodes().find((c) => c.getID() === commentID);
8981
+ }
8982
+ if (!comment)
8983
+ return;
8984
+ comment.focus();
8985
+ }));
8986
+ };
8987
+ const version = "2.8.1";
8942
8988
  const Copyright = (ctx) => {
8943
8989
  ctx.on("mounted", () => {
8944
8990
  const list2 = ctx.get("list");
@@ -8949,14 +8995,7 @@ const Copyright = (ctx) => {
8949
8995
  });
8950
8996
  };
8951
8997
  const NoComment = (ctx) => {
8952
- let isFetching = false;
8953
- ctx.on("list-fetch", (params) => {
8954
- isFetching = true;
8955
- });
8956
8998
  ctx.on("list-loaded", (comments) => {
8957
- if (!isFetching)
8958
- return;
8959
- isFetching = false;
8960
8999
  const list2 = ctx.get("list");
8961
9000
  const isNoComment = comments.length <= 0;
8962
9001
  let $noComment = list2.getCommentsWrapEl().querySelector(".atk-list-no-comment");
@@ -9208,7 +9247,8 @@ const ListPlugins = [
9208
9247
  SidebarBtn,
9209
9248
  UnreadBadge,
9210
9249
  Dropdown,
9211
- Goto,
9250
+ GotoDispatcher,
9251
+ GotoFocus,
9212
9252
  NoComment,
9213
9253
  Copyright,
9214
9254
  TimeTicking,
@@ -9232,6 +9272,7 @@ const PvCountWidget = (ctx) => {
9232
9272
  ctx.watchConf([
9233
9273
  "site",
9234
9274
  "pageKey",
9275
+ "pageTitle",
9235
9276
  "countEl",
9236
9277
  "pvEl"
9237
9278
  ], (conf) => {
@@ -9239,6 +9280,7 @@ const PvCountWidget = (ctx) => {
9239
9280
  getApi: () => ctx.getApi(),
9240
9281
  siteName: conf.site,
9241
9282
  pageKey: conf.pageKey,
9283
+ pageTitle: conf.pageTitle,
9242
9284
  countEl: conf.countEl,
9243
9285
  pvEl: conf.pvEl,
9244
9286
  pvAdd: typeof ctx.conf.pvAdd === "boolean" ? ctx.conf.pvAdd : true
@@ -9250,10 +9292,10 @@ function initCountWidget(opt) {
9250
9292
  if (opt.countEl && document.querySelector(opt.countEl)) {
9251
9293
  refreshStatCount(opt, { query: "page_comment", numEl: opt.countEl });
9252
9294
  }
9253
- const initialData = opt.pvAdd ? {
9295
+ const initialData = opt.pvAdd && opt.pageKey ? {
9254
9296
  [opt.pageKey]: (yield opt.getApi().pages.logPv({
9255
9297
  page_key: opt.pageKey,
9256
- page_title: opt.pageKey,
9298
+ page_title: opt.pageTitle,
9257
9299
  site_name: opt.siteName
9258
9300
  })).data.pv
9259
9301
  // pv+1 and get pv count
@@ -9270,7 +9312,7 @@ function initCountWidget(opt) {
9270
9312
  function refreshStatCount(opt, args) {
9271
9313
  return __async(this, null, function* () {
9272
9314
  let data = args.data || {};
9273
- let queryPageKeys = Array.from(document.querySelectorAll(args.numEl)).map((e) => e.getAttribute("data-page-key") || opt.pageKey).filter((k) => typeof data[k] !== "number");
9315
+ let queryPageKeys = Array.from(document.querySelectorAll(args.numEl)).map((e) => e.getAttribute("data-page-key") || opt.pageKey).filter((k) => k && typeof data[k] !== "number");
9274
9316
  queryPageKeys = [...new Set(queryPageKeys)];
9275
9317
  if (queryPageKeys.length > 0) {
9276
9318
  const res = (yield opt.getApi().stats.getStats(args.query, {
@@ -9279,7 +9321,8 @@ function refreshStatCount(opt, args) {
9279
9321
  })).data.data;
9280
9322
  data = __spreadValues(__spreadValues({}, data), res);
9281
9323
  }
9282
- applyCountData(args.numEl, data, data[opt.pageKey]);
9324
+ const defaultCount = opt.pageKey ? data[opt.pageKey] : 0;
9325
+ applyCountData(args.numEl, data, defaultCount);
9283
9326
  });
9284
9327
  }
9285
9328
  function applyCountData(selector, data, defaultCount) {
@@ -9468,7 +9511,6 @@ class Artalk {
9468
9511
  initCountWidget({
9469
9512
  getApi: () => new Api2(convertApiOptions(conf)),
9470
9513
  siteName: conf.site,
9471
- pageKey: conf.pageKey,
9472
9514
  countEl: conf.countEl,
9473
9515
  pvEl: conf.pvEl,
9474
9516
  pvAdd: false