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.
@@ -368,6 +368,29 @@ let Api$1 = class Api extends HttpClient {
368
368
  type: "application/json",
369
369
  format: "json"
370
370
  }, params)),
371
+ /**
372
+ * @description Get the detail of a comment by comment id
373
+ *
374
+ * @tags Comment
375
+ * @name GetComment
376
+ * @summary Get a comment
377
+ * @request GET:/comments/{id}
378
+ * @response `200` `HandlerResponseCommentGet` OK
379
+ * @response `404` `(HandlerMap & {
380
+ msg?: string,
381
+
382
+ })` Not Found
383
+ * @response `500` `(HandlerMap & {
384
+ msg?: string,
385
+
386
+ })` Internal Server Error
387
+ */
388
+ getComment: (id, params = {}) => this.request(__spreadValues({
389
+ path: `/comments/${id}`,
390
+ method: "GET",
391
+ type: "application/json",
392
+ format: "json"
393
+ }, params)),
371
394
  /**
372
395
  * @description Update a specific comment
373
396
  *
@@ -3131,7 +3154,7 @@ function showLoading(parentElem, conf) {
3131
3154
  let $loading = parentElem.querySelector(":scope > .atk-loading");
3132
3155
  if (!$loading) {
3133
3156
  $loading = createElement(
3134
- `<div class="atk-loading atk-fade-in" style="display: none;">
3157
+ `<div class="atk-loading" style="display: none;">
3135
3158
  <div class="atk-loading-spinner">
3136
3159
  <svg viewBox="25 25 50 50"><circle cx="50" cy="50" r="20" fill="none" stroke-width="2" stroke-miterlimit="10"></circle></svg>
3137
3160
  </div>
@@ -3146,7 +3169,8 @@ function showLoading(parentElem, conf) {
3146
3169
  if ($spinner) {
3147
3170
  $spinner.style.display = "none";
3148
3171
  window.setTimeout(() => {
3149
- $spinner.style.display = "";
3172
+ if ($spinner.isConnected)
3173
+ $spinner.style.display = "";
3150
3174
  }, 500);
3151
3175
  }
3152
3176
  }
@@ -3166,8 +3190,7 @@ function scrollIntoView(elem, enableAnim = true, relativeTo) {
3166
3190
  if (relativeTo) {
3167
3191
  const containerRect = relativeTo.getBoundingClientRect();
3168
3192
  const elementRect = elem.getBoundingClientRect();
3169
- top = elementRect.top - containerRect.top + relativeTo.scrollTop;
3170
- top += getHeight(relativeTo) / 2 - getHeight(elem) / 2;
3193
+ top = elementRect.top - containerRect.top + relativeTo.scrollTop - relativeTo.clientHeight / 2 + elem.clientHeight / 2;
3171
3194
  } else {
3172
3195
  const rect = elem.getBoundingClientRect();
3173
3196
  const elemTop = rect.top + window.scrollY;
@@ -3501,6 +3524,9 @@ class Component {
3501
3524
  get conf() {
3502
3525
  return this.ctx.conf;
3503
3526
  }
3527
+ getEl() {
3528
+ return this.$el;
3529
+ }
3504
3530
  }
3505
3531
  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';
3506
3532
  const Sel = {
@@ -3885,39 +3911,18 @@ function makeNestCommentNodeList(srcData, sortBy = "DATE_DESC", nestMax = 2) {
3885
3911
  })(nodeList);
3886
3912
  return nodeList;
3887
3913
  }
3888
- class ListLayout {
3889
- constructor(options) {
3890
- this.options = options;
3891
- }
3892
- // TODO: refactor `if syntax` to strategy pattern
3893
- import(comments) {
3894
- if (this.options.flatMode) {
3895
- comments.forEach((commentData) => {
3896
- this.putCommentFlatMode(commentData, comments, "append");
3897
- });
3898
- } else {
3899
- this.importCommentsNestMode(comments);
3900
- }
3901
- }
3902
- insert(comment) {
3903
- if (!this.options.flatMode) {
3904
- this.insertCommentNest(comment);
3905
- } else {
3906
- this.insertCommentFlatMode(comment);
3907
- }
3908
- }
3909
- // 导入评论 · 嵌套模式
3910
- importCommentsNestMode(srcData) {
3911
- const rootNodes = makeNestCommentNodeList(srcData, this.options.nestSortBy, this.options.nestMax);
3914
+ const createNestStrategy = (opts) => ({
3915
+ import: (comments) => {
3916
+ const rootNodes = makeNestCommentNodeList(comments, opts.nestSortBy, opts.nestMax);
3912
3917
  rootNodes.forEach((rootNode) => {
3913
3918
  var _a;
3914
- const rootC = this.options.createCommentNode(rootNode.comment, srcData);
3915
- (_a = this.options.$commentsWrap) == null ? void 0 : _a.appendChild(rootC.getEl());
3919
+ const rootC = opts.createCommentNode(rootNode.comment);
3920
+ (_a = opts.$commentsWrap) == null ? void 0 : _a.appendChild(rootC.getEl());
3916
3921
  rootC.getRender().playFadeAnim();
3917
3922
  const loadChildren = (parentC, parentNode) => {
3918
3923
  parentNode.children.forEach((node) => {
3919
3924
  const childD = node.comment;
3920
- const childC = this.options.createCommentNode(childD, srcData);
3925
+ const childC = opts.createCommentNode(childD, parentC.getData());
3921
3926
  parentC.putChild(childC);
3922
3927
  loadChildren(childC, node);
3923
3928
  });
@@ -3925,44 +3930,66 @@ class ListLayout {
3925
3930
  loadChildren(rootC, rootNode);
3926
3931
  rootC.getRender().checkHeightLimit();
3927
3932
  });
3928
- }
3929
- /** 导入评论 · 平铺模式 */
3930
- putCommentFlatMode(cData, ctxData, insertMode) {
3931
- var _a, _b;
3932
- if (cData.is_collapsed)
3933
- cData.is_allow_reply = false;
3934
- const comment = this.options.createCommentNode(cData, ctxData);
3935
- if (cData.visible) {
3936
- if (insertMode === "append")
3937
- (_a = this.options.$commentsWrap) == null ? void 0 : _a.append(comment.getEl());
3938
- if (insertMode === "prepend")
3939
- (_b = this.options.$commentsWrap) == null ? void 0 : _b.prepend(comment.getEl());
3940
- comment.getRender().playFadeAnim();
3941
- }
3942
- comment.getRender().checkHeightLimit();
3943
- return comment;
3944
- }
3945
- insertCommentNest(commentData) {
3933
+ },
3934
+ insert: (comment, replyComment) => {
3946
3935
  var _a;
3947
- const comment = this.options.createCommentNode(commentData, this.options.getCommentDataList());
3948
- if (commentData.rid === 0) {
3949
- (_a = this.options.$commentsWrap) == null ? void 0 : _a.prepend(comment.getEl());
3936
+ const node = opts.createCommentNode(comment, replyComment);
3937
+ if (comment.rid === 0) {
3938
+ (_a = opts.$commentsWrap) == null ? void 0 : _a.prepend(node.getEl());
3950
3939
  } else {
3951
- const parent = this.options.findCommentNode(commentData.rid);
3940
+ const parent = opts.findCommentNode(comment.rid);
3952
3941
  if (parent) {
3953
- parent.putChild(comment, this.options.nestSortBy === "DATE_ASC" ? "append" : "prepend");
3954
- comment.getParents().forEach((p) => {
3942
+ parent.putChild(node, opts.nestSortBy === "DATE_ASC" ? "append" : "prepend");
3943
+ node.getParents().forEach((p) => {
3955
3944
  p.getRender().heightLimitRemoveForChildren();
3956
3945
  });
3957
3946
  }
3958
3947
  }
3959
- comment.getRender().checkHeightLimit();
3960
- scrollIntoView(comment.getEl());
3961
- comment.getRender().playFadeAnim();
3948
+ node.getRender().checkHeightLimit();
3949
+ node.scrollIntoView();
3950
+ node.getRender().playFadeAnim();
3951
+ }
3952
+ });
3953
+ const createFlatStrategy = (opts) => ({
3954
+ import: (comments) => {
3955
+ comments.forEach((comment) => {
3956
+ const replyComment = comment.rid === 0 ? void 0 : comments.find((c) => c.id === comment.rid);
3957
+ insertComment(opts, "append", comment, replyComment);
3958
+ });
3959
+ },
3960
+ insert: (comment, replyComment) => {
3961
+ const node = insertComment(opts, "prepend", comment, replyComment);
3962
+ node.scrollIntoView();
3963
+ }
3964
+ });
3965
+ function insertComment(opts, insertMode, comment, replyComment) {
3966
+ if (comment.is_collapsed)
3967
+ comment.is_allow_reply = false;
3968
+ const node = opts.createCommentNode(comment, replyComment);
3969
+ if (comment.visible) {
3970
+ const $comment = node.getEl();
3971
+ const $listCommentsWrap = opts.$commentsWrap;
3972
+ if (insertMode === "append")
3973
+ $listCommentsWrap == null ? void 0 : $listCommentsWrap.append($comment);
3974
+ if (insertMode === "prepend")
3975
+ $listCommentsWrap == null ? void 0 : $listCommentsWrap.prepend($comment);
3976
+ node.getRender().playFadeAnim();
3977
+ }
3978
+ node.getRender().checkHeightLimit();
3979
+ return node;
3980
+ }
3981
+ class ListLayout {
3982
+ constructor(options) {
3983
+ this.options = options;
3984
+ }
3985
+ getStrategy() {
3986
+ return this.options.flatMode ? createFlatStrategy(this.options) : createNestStrategy(this.options);
3987
+ }
3988
+ import(comments) {
3989
+ this.getStrategy().import(comments);
3962
3990
  }
3963
- insertCommentFlatMode(commentData) {
3964
- const comment = this.putCommentFlatMode(commentData, this.options.getCommentDataList(), "prepend");
3965
- scrollIntoView(comment.getEl());
3991
+ insert(comment, replyComment) {
3992
+ this.getStrategy().insert(comment, replyComment);
3966
3993
  }
3967
3994
  }
3968
3995
  function Detect(userAgent) {
@@ -4225,7 +4252,7 @@ const CommentHTML = '<div class="atk-comment-wrap">\n <div class="atk-comment">
4225
4252
  function renderAvatar(r) {
4226
4253
  const $avatar = r.$el.querySelector(".atk-avatar");
4227
4254
  const $avatarImg = createElement("<img />");
4228
- const avatarURLBuilder = r.conf.avatarURLBuilder;
4255
+ const avatarURLBuilder = r.opts.avatarURLBuilder;
4229
4256
  $avatarImg.src = avatarURLBuilder ? avatarURLBuilder(r.data) : r.comment.getGravatarURL();
4230
4257
  if (r.data.link) {
4231
4258
  const $avatarA = createElement('<a target="_blank" rel="noreferrer noopener nofollow"></a>');
@@ -4264,12 +4291,12 @@ function renderVerifyBadge(ctx) {
4264
4291
  const badgeColor = ctx.data.badge_color;
4265
4292
  if (badgeText) {
4266
4293
  const $badge = createElement(`<span class="atk-badge"></span>`);
4267
- $badge.innerText = badgeText.replace("管理员", ctx.ctx.$t("admin"));
4294
+ $badge.innerText = badgeText.replace("管理员", t("admin"));
4268
4295
  $badge.style.backgroundColor = badgeColor || "";
4269
4296
  ctx.$headerBadgeWrap.append($badge);
4270
4297
  }
4271
4298
  if (ctx.data.is_pinned) {
4272
- const $pinnedBadge = createElement(`<span class="atk-pinned-badge">${ctx.ctx.$t("pin")}</span>`);
4299
+ const $pinnedBadge = createElement(`<span class="atk-pinned-badge">${t("pin")}</span>`);
4273
4300
  ctx.$headerBadgeWrap.append($pinnedBadge);
4274
4301
  }
4275
4302
  }
@@ -4279,7 +4306,7 @@ function renderDate(ctx) {
4279
4306
  $date.setAttribute("data-atk-comment-date", String(+new Date(ctx.data.date)));
4280
4307
  }
4281
4308
  function renderUABadge(ctx) {
4282
- if (!ctx.ctx.conf.uaBadge && !ctx.data.ip_region)
4309
+ if (!ctx.opts.uaBadge && !ctx.data.ip_region)
4283
4310
  return;
4284
4311
  let $uaWrap = ctx.$header.querySelector("atk-ua-wrap");
4285
4312
  if (!$uaWrap) {
@@ -4292,7 +4319,7 @@ function renderUABadge(ctx) {
4292
4319
  $regionBadge.innerText = ctx.data.ip_region;
4293
4320
  $uaWrap.append($regionBadge);
4294
4321
  }
4295
- if (ctx.ctx.conf.uaBadge) {
4322
+ if (ctx.opts.uaBadge) {
4296
4323
  const { browser, os } = ctx.comment.getUserUA();
4297
4324
  if (String(browser).trim()) {
4298
4325
  const $uaBrowser = createElement(`<span class="atk-ua ua-browser"></span>`);
@@ -4315,8 +4342,8 @@ function renderContent(r) {
4315
4342
  r.$content.classList.add("atk-hide", "atk-type-collapsed");
4316
4343
  const collapsedInfoEl = createElement(`
4317
4344
  <div class="atk-collapsed">
4318
- <span class="atk-text">${r.ctx.$t("collapsedMsg")}</span>
4319
- <span class="atk-show-btn">${r.ctx.$t("expand")}</span>
4345
+ <span class="atk-text">${t("collapsedMsg")}</span>
4346
+ <span class="atk-show-btn">${t("expand")}</span>
4320
4347
  </div>`);
4321
4348
  r.$body.insertAdjacentElement("beforeend", collapsedInfoEl);
4322
4349
  const contentShowBtn = collapsedInfoEl.querySelector(".atk-show-btn");
@@ -4326,51 +4353,51 @@ function renderContent(r) {
4326
4353
  r.$content.innerHTML = r.comment.getContentMarked();
4327
4354
  r.$content.classList.remove("atk-hide");
4328
4355
  playFadeInAnim(r.$content);
4329
- contentShowBtn.innerText = r.ctx.$t("collapse");
4356
+ contentShowBtn.innerText = t("collapse");
4330
4357
  } else {
4331
4358
  r.$content.innerHTML = "";
4332
4359
  r.$content.classList.add("atk-hide");
4333
- contentShowBtn.innerText = r.ctx.$t("expand");
4360
+ contentShowBtn.innerText = t("expand");
4334
4361
  }
4335
4362
  });
4336
4363
  }
4337
4364
  function renderReplyAt(r) {
4338
- if (r.cConf.isFlatMode || r.data.rid === 0)
4365
+ if (r.opts.flatMode || r.data.rid === 0)
4339
4366
  return;
4340
- if (!r.cConf.replyTo)
4367
+ if (!r.opts.replyTo)
4341
4368
  return;
4342
4369
  r.$replyAt = createElement(`<span class="atk-item atk-reply-at"><span class="atk-arrow"></span><span class="atk-nick"></span></span>`);
4343
- r.$replyAt.querySelector(".atk-nick").innerText = `${r.cConf.replyTo.nick}`;
4370
+ r.$replyAt.querySelector(".atk-nick").innerText = `${r.opts.replyTo.nick}`;
4344
4371
  r.$replyAt.onclick = () => {
4345
4372
  r.comment.getActions().goToReplyComment();
4346
4373
  };
4347
4374
  r.$headerBadgeWrap.insertAdjacentElement("afterend", r.$replyAt);
4348
4375
  }
4349
4376
  function renderReplyTo(r) {
4350
- if (!r.cConf.isFlatMode)
4377
+ if (!r.opts.flatMode)
4351
4378
  return;
4352
- if (!r.cConf.replyTo)
4379
+ if (!r.opts.replyTo)
4353
4380
  return;
4354
4381
  r.$replyTo = createElement(`
4355
4382
  <div class="atk-reply-to">
4356
- <div class="atk-meta">${r.ctx.$t("reply")} <span class="atk-nick"></span>:</div>
4383
+ <div class="atk-meta">${t("reply")} <span class="atk-nick"></span>:</div>
4357
4384
  <div class="atk-content"></div>
4358
4385
  </div>`);
4359
4386
  const $nick = r.$replyTo.querySelector(".atk-nick");
4360
- $nick.innerText = `@${r.cConf.replyTo.nick}`;
4387
+ $nick.innerText = `@${r.opts.replyTo.nick}`;
4361
4388
  $nick.onclick = () => {
4362
4389
  r.comment.getActions().goToReplyComment();
4363
4390
  };
4364
- let replyContent = marked(r.cConf.replyTo.content);
4365
- if (r.cConf.replyTo.is_collapsed)
4366
- replyContent = `[${r.ctx.$t("collapsed")}]`;
4391
+ let replyContent = marked(r.opts.replyTo.content);
4392
+ if (r.opts.replyTo.is_collapsed)
4393
+ replyContent = `[${t("collapsed")}]`;
4367
4394
  r.$replyTo.querySelector(".atk-content").innerHTML = replyContent;
4368
4395
  r.$body.prepend(r.$replyTo);
4369
4396
  }
4370
4397
  function renderPending(r) {
4371
4398
  if (!r.data.is_pending)
4372
4399
  return;
4373
- const pendingEl = createElement(`<div class="atk-pending">${r.ctx.$t("pendingMsg")}</div>`);
4400
+ const pendingEl = createElement(`<div class="atk-pending">${t("pendingMsg")}</div>`);
4374
4401
  r.$body.prepend(pendingEl);
4375
4402
  }
4376
4403
  class ActionBtn {
@@ -4523,14 +4550,14 @@ function renderActions(r) {
4523
4550
  });
4524
4551
  }
4525
4552
  function renderVote(r) {
4526
- if (!r.ctx.conf.vote)
4553
+ if (!r.opts.vote)
4527
4554
  return;
4528
- r.voteBtnUp = new ActionBtn(() => `${r.ctx.$t("voteUp")} (${r.data.vote_up || 0})`).appendTo(r.$actions);
4555
+ r.voteBtnUp = new ActionBtn(() => `${t("voteUp")} (${r.data.vote_up || 0})`).appendTo(r.$actions);
4529
4556
  r.voteBtnUp.setClick(() => {
4530
4557
  r.comment.getActions().vote("up");
4531
4558
  });
4532
- if (r.ctx.conf.voteDown) {
4533
- r.voteBtnDown = new ActionBtn(() => `${r.ctx.$t("voteDown")} (${r.data.vote_down || 0})`).appendTo(r.$actions);
4559
+ if (r.opts.voteDown) {
4560
+ r.voteBtnDown = new ActionBtn(() => `${t("voteDown")} (${r.data.vote_down || 0})`).appendTo(r.$actions);
4534
4561
  r.voteBtnDown.setClick(() => {
4535
4562
  r.comment.getActions().vote("down");
4536
4563
  });
@@ -4539,20 +4566,16 @@ function renderVote(r) {
4539
4566
  function renderReply(r) {
4540
4567
  if (!r.data.is_allow_reply)
4541
4568
  return;
4542
- const replyBtn = createElement(`<span>${r.ctx.$t("reply")}</span>`);
4569
+ const replyBtn = createElement(`<span>${t("reply")}</span>`);
4543
4570
  r.$actions.append(replyBtn);
4544
4571
  replyBtn.addEventListener("click", (e) => {
4545
4572
  e.stopPropagation();
4546
- if (!r.cConf.onReplyBtnClick) {
4547
- r.ctx.replyComment(r.data, r.$el);
4548
- } else {
4549
- r.cConf.onReplyBtnClick();
4550
- }
4573
+ r.opts.replyComment(r.data, r.$el);
4551
4574
  });
4552
4575
  }
4553
4576
  function renderCollapse(r) {
4554
4577
  const collapseBtn = new ActionBtn({
4555
- text: () => r.data.is_collapsed ? r.ctx.$t("expand") : r.ctx.$t("collapse"),
4578
+ text: () => r.data.is_collapsed ? t("expand") : t("collapse"),
4556
4579
  adminOnly: true
4557
4580
  });
4558
4581
  collapseBtn.appendTo(r.$actions);
@@ -4562,7 +4585,7 @@ function renderCollapse(r) {
4562
4585
  }
4563
4586
  function renderModerator(r) {
4564
4587
  const pendingBtn = new ActionBtn({
4565
- text: () => r.data.is_pending ? r.ctx.$t("pending") : r.ctx.$t("approved"),
4588
+ text: () => r.data.is_pending ? t("pending") : t("approved"),
4566
4589
  adminOnly: true
4567
4590
  });
4568
4591
  pendingBtn.appendTo(r.$actions);
@@ -4572,7 +4595,7 @@ function renderModerator(r) {
4572
4595
  }
4573
4596
  function renderPin(r) {
4574
4597
  const pinnedBtn = new ActionBtn({
4575
- text: () => r.data.is_pinned ? r.ctx.$t("unpin") : r.ctx.$t("pin"),
4598
+ text: () => r.data.is_pinned ? t("unpin") : t("pin"),
4576
4599
  adminOnly: true
4577
4600
  });
4578
4601
  pinnedBtn.appendTo(r.$actions);
@@ -4582,19 +4605,19 @@ function renderPin(r) {
4582
4605
  }
4583
4606
  function renderEdit(r) {
4584
4607
  const editBtn = new ActionBtn({
4585
- text: r.ctx.$t("edit"),
4608
+ text: t("edit"),
4586
4609
  adminOnly: true
4587
4610
  });
4588
4611
  editBtn.appendTo(r.$actions);
4589
4612
  editBtn.setClick(() => {
4590
- r.ctx.editComment(r.data, r.$el);
4613
+ r.opts.editComment(r.data, r.$el);
4591
4614
  });
4592
4615
  }
4593
4616
  function renderDel(r) {
4594
4617
  const delBtn = new ActionBtn({
4595
- text: r.ctx.$t("delete"),
4618
+ text: t("delete"),
4596
4619
  confirm: true,
4597
- confirmText: r.ctx.$t("deleteConfirm"),
4620
+ confirmText: t("deleteConfirm"),
4598
4621
  adminOnly: true
4599
4622
  });
4600
4623
  delBtn.appendTo(r.$actions);
@@ -4636,18 +4659,21 @@ class Render {
4636
4659
  __publicField(this, "$replyAt");
4637
4660
  this.comment = comment;
4638
4661
  }
4639
- get ctx() {
4640
- return this.comment.ctx;
4641
- }
4642
4662
  get data() {
4643
4663
  return this.comment.getData();
4644
4664
  }
4645
- get conf() {
4646
- return this.comment.conf;
4647
- }
4648
- get cConf() {
4649
- return this.comment.getConf();
4665
+ get opts() {
4666
+ return this.comment.getOpts();
4650
4667
  }
4668
+ /**
4669
+ * Render the comment ui
4670
+ *
4671
+ * If comment data is updated, call this method to re-render the comment ui.
4672
+ * The method will be called multiple times, so it should be idempotent.
4673
+ *
4674
+ * Renders may add event listeners to the comment ui, so it should be called only once or override the original.
4675
+ * Please be aware of the memory leak caused by the event listener.
4676
+ */
4651
4677
  render() {
4652
4678
  this.$el = createElement(CommentHTML);
4653
4679
  this.$main = this.$el.querySelector(".atk-main");
@@ -4657,12 +4683,14 @@ class Render {
4657
4683
  this.$actions = this.$el.querySelector(".atk-actions");
4658
4684
  this.$el.setAttribute("id", `atk-comment-${this.data.id}`);
4659
4685
  loadRenders(this);
4660
- this.recoveryChildrenWrap();
4686
+ if (this.$childrenWrap) {
4687
+ this.$main.append(this.$childrenWrap);
4688
+ }
4661
4689
  return this.$el;
4662
4690
  }
4663
4691
  /** 内容限高检测 */
4664
4692
  checkHeightLimit() {
4665
- const conf = this.ctx.conf.heightLimit;
4693
+ const conf = this.opts.heightLimit;
4666
4694
  if (!conf || !conf.content || !conf.children)
4667
4695
  return;
4668
4696
  const contentMaxH = conf.content;
@@ -4696,24 +4724,21 @@ class Render {
4696
4724
  playFadeAnimForBody() {
4697
4725
  playFadeInAnim(this.comment.getRender().$body);
4698
4726
  }
4727
+ /** Perform the flash animation */
4728
+ playFlashAnim() {
4729
+ this.$el.classList.remove("atk-flash-once");
4730
+ window.setTimeout(() => {
4731
+ this.$el.classList.add("atk-flash-once");
4732
+ }, 150);
4733
+ }
4699
4734
  /** 获取子评论 Wrap */
4700
4735
  getChildrenWrap() {
4701
- return this.$childrenWrap;
4702
- }
4703
- /** 初始化子评论区域 Wrap */
4704
- renderChildrenWrap() {
4705
4736
  if (!this.$childrenWrap) {
4706
4737
  this.$childrenWrap = createElement('<div class="atk-comment-children"></div>');
4707
4738
  this.$main.append(this.$childrenWrap);
4708
4739
  }
4709
4740
  return this.$childrenWrap;
4710
4741
  }
4711
- /** 恢复原有的子评论区域 Wrap */
4712
- recoveryChildrenWrap() {
4713
- if (this.$childrenWrap) {
4714
- this.$main.append(this.$childrenWrap);
4715
- }
4716
- }
4717
4742
  /** 设置已读 */
4718
4743
  setUnread(val) {
4719
4744
  if (val)
@@ -4732,17 +4757,15 @@ class Render {
4732
4757
  setOpenURL(url) {
4733
4758
  this.setOpenable(true);
4734
4759
  this.$el.onclick = (evt) => {
4735
- evt.preventDefault();
4760
+ evt.stopPropagation();
4736
4761
  window.open(url);
4737
- if (this.cConf.openEvt)
4738
- this.cConf.openEvt();
4739
4762
  };
4740
4763
  }
4741
4764
  /** 设置点击评论时的操作 */
4742
4765
  setOpenAction(action) {
4743
4766
  this.setOpenable(true);
4744
4767
  this.$el.onclick = (evt) => {
4745
- evt.preventDefault();
4768
+ evt.stopPropagation();
4746
4769
  action();
4747
4770
  };
4748
4771
  }
@@ -4752,26 +4775,26 @@ class CommentActions {
4752
4775
  __publicField(this, "comment");
4753
4776
  this.comment = comment;
4754
4777
  }
4755
- get ctx() {
4756
- return this.comment.ctx;
4757
- }
4758
4778
  get data() {
4759
4779
  return this.comment.getData();
4760
4780
  }
4761
- get cConf() {
4762
- return this.comment.getConf();
4781
+ get opts() {
4782
+ return this.comment.getOpts();
4783
+ }
4784
+ getApi() {
4785
+ return this.comment.getOpts().getApi();
4763
4786
  }
4764
4787
  /** 投票操作 */
4765
4788
  vote(type) {
4766
4789
  const actionBtn = type === "up" ? this.comment.getRender().voteBtnUp : this.comment.getRender().voteBtnDown;
4767
- this.ctx.getApi().votes.vote(`comment_${type}`, this.data.id, __spreadValues({}, this.ctx.getApi().getUserFields())).then((res) => {
4790
+ this.getApi().votes.vote(`comment_${type}`, this.data.id, __spreadValues({}, this.getApi().getUserFields())).then((res) => {
4768
4791
  var _a, _b;
4769
4792
  this.data.vote_up = res.data.up;
4770
4793
  this.data.vote_down = res.data.down;
4771
4794
  (_a = this.comment.getRender().voteBtnUp) == null ? void 0 : _a.updateText();
4772
4795
  (_b = this.comment.getRender().voteBtnDown) == null ? void 0 : _b.updateText();
4773
4796
  }).catch((err) => {
4774
- actionBtn == null ? void 0 : actionBtn.setError(this.ctx.$t("voteFail"));
4797
+ actionBtn == null ? void 0 : actionBtn.setError(t("voteFail"));
4775
4798
  console.log(err);
4776
4799
  });
4777
4800
  }
@@ -4779,7 +4802,7 @@ class CommentActions {
4779
4802
  adminEdit(type, btnElem) {
4780
4803
  if (btnElem.isLoading)
4781
4804
  return;
4782
- btnElem.setLoading(true, `${this.ctx.$t("editing")}...`);
4805
+ btnElem.setLoading(true, `${t("editing")}...`);
4783
4806
  const modify = __spreadValues({}, this.data);
4784
4807
  if (type === "collapsed") {
4785
4808
  modify.is_collapsed = !modify.is_collapsed;
@@ -4788,26 +4811,26 @@ class CommentActions {
4788
4811
  } else if (type === "pinned") {
4789
4812
  modify.is_pinned = !modify.is_pinned;
4790
4813
  }
4791
- this.ctx.getApi().comments.updateComment(this.data.id, __spreadValues({}, modify)).then((res) => {
4814
+ this.getApi().comments.updateComment(this.data.id, __spreadValues({}, modify)).then((res) => {
4792
4815
  btnElem.setLoading(false);
4793
4816
  this.comment.setData(res.data);
4794
4817
  }).catch((err) => {
4795
4818
  console.error(err);
4796
- btnElem.setError(this.ctx.$t("editFail"));
4819
+ btnElem.setError(t("editFail"));
4797
4820
  });
4798
4821
  }
4799
4822
  /** 管理员 - 评论删除 */
4800
4823
  adminDelete(btnElem) {
4801
4824
  if (btnElem.isLoading)
4802
4825
  return;
4803
- btnElem.setLoading(true, `${this.ctx.$t("deleting")}...`);
4804
- this.ctx.getApi().comments.deleteComment(this.data.id).then(() => {
4826
+ btnElem.setLoading(true, `${t("deleting")}...`);
4827
+ this.getApi().comments.deleteComment(this.data.id).then(() => {
4805
4828
  btnElem.setLoading(false);
4806
- if (this.cConf.onDelete)
4807
- this.cConf.onDelete(this.comment);
4829
+ if (this.opts.onDelete)
4830
+ this.opts.onDelete(this.comment);
4808
4831
  }).catch((e) => {
4809
4832
  console.error(e);
4810
- btnElem.setError(this.ctx.$t("deleteFail"));
4833
+ btnElem.setError(t("deleteFail"));
4811
4834
  });
4812
4835
  }
4813
4836
  /** 快速跳转到该评论 */
@@ -4819,21 +4842,18 @@ class CommentActions {
4819
4842
  window.dispatchEvent(new Event("hashchange"));
4820
4843
  }
4821
4844
  }
4822
- class CommentNode extends Component {
4823
- // 最大嵌套层数
4824
- constructor(ctx, data, conf) {
4825
- super(ctx);
4845
+ class CommentNode {
4846
+ // 当前嵌套层数
4847
+ constructor(data, opts) {
4848
+ __publicField(this, "$el");
4826
4849
  __publicField(this, "renderInstance");
4827
4850
  __publicField(this, "actionInstance");
4828
4851
  __publicField(this, "data");
4829
- __publicField(this, "cConf");
4852
+ __publicField(this, "opts");
4830
4853
  __publicField(this, "parent");
4831
4854
  __publicField(this, "children", []);
4832
4855
  __publicField(this, "nestCurt");
4833
- // 当前嵌套层数
4834
- __publicField(this, "nestMax");
4835
- this.nestMax = ctx.conf.nestMax || 3;
4836
- this.cConf = conf;
4856
+ this.opts = opts;
4837
4857
  this.data = __spreadValues({}, data);
4838
4858
  this.data.date = this.data.date.replace(/-/g, "/");
4839
4859
  this.parent = null;
@@ -4847,8 +4867,8 @@ class CommentNode extends Component {
4847
4867
  if (this.$el)
4848
4868
  this.$el.replaceWith(newEl);
4849
4869
  this.$el = newEl;
4850
- if (this.cConf.afterRender)
4851
- this.cConf.afterRender();
4870
+ if (this.opts.onAfterRender)
4871
+ this.opts.onAfterRender();
4852
4872
  }
4853
4873
  /** 获取评论操作实例对象 */
4854
4874
  getActions() {
@@ -4889,51 +4909,76 @@ class CommentNode extends Component {
4889
4909
  return this.data.id;
4890
4910
  }
4891
4911
  /** 置入子评论 */
4892
- putChild(childC, insertMode = "append") {
4893
- childC.parent = this;
4894
- childC.nestCurt = this.nestCurt + 1;
4895
- this.children.push(childC);
4896
- const $children = this.getChildrenEl();
4912
+ putChild(childNode, insertMode = "append") {
4913
+ childNode.parent = this;
4914
+ childNode.nestCurt = this.nestCurt + 1;
4915
+ this.children.push(childNode);
4916
+ const $childrenWrap = this.getChildrenWrapEl();
4917
+ const $childComment = childNode.getEl();
4897
4918
  if (insertMode === "append")
4898
- $children.append(childC.getEl());
4919
+ $childrenWrap.append($childComment);
4899
4920
  else if (insertMode === "prepend")
4900
- $children.prepend(childC.getEl());
4901
- childC.getRender().playFadeAnim();
4902
- childC.getRender().checkHeightLimit();
4921
+ $childrenWrap.prepend($childComment);
4922
+ childNode.getRender().playFadeAnim();
4923
+ childNode.getRender().checkHeightLimit();
4903
4924
  }
4904
4925
  /** 获取存放子评论的元素对象 */
4905
- getChildrenEl() {
4906
- let $children = this.getRender().getChildrenWrap();
4907
- if (!$children) {
4908
- if (this.nestCurt < this.nestMax) {
4909
- $children = this.getRender().renderChildrenWrap();
4910
- } else {
4911
- $children = this.parent.getChildrenEl();
4912
- }
4926
+ getChildrenWrapEl() {
4927
+ if (this.nestCurt >= this.opts.nestMax) {
4928
+ return this.parent.getChildrenWrapEl();
4913
4929
  }
4914
- return $children;
4930
+ return this.getRender().getChildrenWrap();
4915
4931
  }
4916
4932
  /** 获取所有父评论 */
4917
4933
  getParents() {
4918
- const parents = [];
4919
- const once = (c) => {
4920
- if (c.parent) {
4921
- parents.push(c.parent);
4922
- once(c.parent);
4923
- }
4924
- };
4925
- once(this);
4926
- return parents;
4934
+ const flattenParents = [];
4935
+ let parent = this.parent;
4936
+ while (parent) {
4937
+ flattenParents.push(parent);
4938
+ parent = parent.getParent();
4939
+ }
4940
+ return flattenParents;
4927
4941
  }
4928
- /** 获取评论元素对象 */
4942
+ /**
4943
+ * Get the element of the comment
4944
+ *
4945
+ * The `getEl()` will always return the latest $el after calling `render()`.
4946
+ * Please be aware of the memory leak if you use the $el reference directly.
4947
+ */
4929
4948
  getEl() {
4949
+ if (!this.$el)
4950
+ throw new Error("comment element not initialized before `getEl()`");
4930
4951
  return this.$el;
4931
4952
  }
4953
+ /**
4954
+ * Focus on the comment
4955
+ *
4956
+ * Scroll to the comment and perform flash animation
4957
+ */
4958
+ focus() {
4959
+ if (!this.$el)
4960
+ throw new Error("comment element not initialized before `focus()`");
4961
+ this.getParents().forEach((p) => {
4962
+ p.getRender().heightLimitRemoveForChildren();
4963
+ });
4964
+ this.scrollIntoView();
4965
+ this.getRender().playFlashAnim();
4966
+ }
4967
+ scrollIntoView() {
4968
+ this.$el && scrollIntoView(this.$el, false, this.opts.scrollRelativeTo && this.opts.scrollRelativeTo());
4969
+ }
4970
+ /**
4971
+ * Remove the comment node
4972
+ */
4973
+ remove() {
4974
+ var _a;
4975
+ (_a = this.$el) == null ? void 0 : _a.remove();
4976
+ }
4932
4977
  /** 获取 Gravatar 头像 URL */
4933
4978
  getGravatarURL() {
4934
4979
  return getGravatarURL({
4935
- mirror: this.ctx.conf.gravatar.mirror,
4936
- params: this.ctx.conf.gravatar.params,
4980
+ mirror: this.opts.gravatar.mirror,
4981
+ params: this.opts.gravatar.params,
4937
4982
  emailMD5: this.data.email_encrypted
4938
4983
  });
4939
4984
  }
@@ -4943,7 +4988,7 @@ class CommentNode extends Component {
4943
4988
  }
4944
4989
  /** 获取格式化后的日期 */
4945
4990
  getDateFormatted() {
4946
- return timeAgo(new Date(this.data.date), this.ctx.$t);
4991
+ return timeAgo(new Date(this.data.date), t);
4947
4992
  }
4948
4993
  /** 获取用户 UserAgent 信息 */
4949
4994
  getUserUA() {
@@ -4954,21 +4999,33 @@ class CommentNode extends Component {
4954
4999
  };
4955
5000
  }
4956
5001
  /** 获取配置 */
4957
- getConf() {
4958
- return this.cConf;
5002
+ getOpts() {
5003
+ return this.opts;
4959
5004
  }
4960
5005
  }
4961
- function createComment(ctx, comment, ctxComments) {
4962
- var _a;
4963
- const instance2 = new CommentNode(ctx, comment, {
4964
- isFlatMode: (_a = ctx.getData().getListLastFetch()) == null ? void 0 : _a.params.flatMode,
4965
- afterRender: () => {
5006
+ function createCommentNode(ctx, comment, replyComment, opts) {
5007
+ const instance2 = new CommentNode(comment, {
5008
+ onAfterRender: () => {
4966
5009
  ctx.trigger("comment-rendered", instance2);
4967
5010
  },
4968
5011
  onDelete: (c) => {
4969
5012
  ctx.getData().deleteComment(c.getID());
4970
5013
  },
4971
- replyTo: comment.rid ? ctxComments.find((c) => c.id === comment.rid) : void 0
5014
+ replyTo: replyComment,
5015
+ // TODO simplify reference
5016
+ flatMode: typeof (opts == null ? void 0 : opts.forceFlatMode) === "boolean" ? opts == null ? void 0 : opts.forceFlatMode : ctx.conf.flatMode,
5017
+ gravatar: ctx.conf.gravatar,
5018
+ nestMax: ctx.conf.nestMax,
5019
+ heightLimit: ctx.conf.heightLimit,
5020
+ avatarURLBuilder: ctx.conf.avatarURLBuilder,
5021
+ scrollRelativeTo: ctx.conf.scrollRelativeTo,
5022
+ vote: ctx.conf.vote,
5023
+ voteDown: ctx.conf.voteDown,
5024
+ uaBadge: ctx.conf.uaBadge,
5025
+ // TODO: move to plugin folder and remove from core
5026
+ getApi: () => ctx.getApi(),
5027
+ replyComment: (c, $el) => ctx.replyComment(c, $el),
5028
+ editComment: (c, $el) => ctx.editComment(c, $el)
4972
5029
  });
4973
5030
  instance2.render();
4974
5031
  return instance2;
@@ -5344,20 +5401,19 @@ class List extends Component {
5344
5401
  getCommentNodes() {
5345
5402
  return this.commentNodes;
5346
5403
  }
5347
- getListLayout() {
5404
+ getListLayout({ forceFlatMode } = {}) {
5348
5405
  return new ListLayout({
5349
5406
  $commentsWrap: this.$commentsWrap,
5350
5407
  nestSortBy: this.ctx.conf.nestSort,
5351
5408
  nestMax: this.ctx.conf.nestMax,
5352
- flatMode: this.ctx.conf.flatMode,
5409
+ flatMode: typeof forceFlatMode === "boolean" ? forceFlatMode : this.ctx.conf.flatMode,
5353
5410
  // flatMode must be boolean because it had been handled when Artalk.init
5354
- createCommentNode: (d, c) => {
5355
- const node = createComment(this.ctx, d, c);
5411
+ createCommentNode: (d, r) => {
5412
+ const node = createCommentNode(this.ctx, d, r, { forceFlatMode });
5356
5413
  this.commentNodes.push(node);
5357
5414
  return node;
5358
5415
  },
5359
- findCommentNode: (id) => this.commentNodes.find((c) => c.getID() === id),
5360
- getCommentDataList: () => this.ctx.getData().getComments()
5416
+ findCommentNode: (id) => this.commentNodes.find((c) => c.getID() === id)
5361
5417
  });
5362
5418
  }
5363
5419
  initCrudEvents() {
@@ -5365,8 +5421,10 @@ class List extends Component {
5365
5421
  this.getListLayout().import(comments);
5366
5422
  });
5367
5423
  this.ctx.on("list-loaded", (comments) => {
5368
- if (comments.length === 0)
5424
+ if (comments.length === 0) {
5425
+ this.commentNodes = [];
5369
5426
  this.$commentsWrap.innerHTML = "";
5427
+ }
5370
5428
  });
5371
5429
  this.ctx.on("comment-inserted", (comment) => {
5372
5430
  this.getListLayout().insert(comment);
@@ -5377,7 +5435,7 @@ class List extends Component {
5377
5435
  console.error(`comment node id=${comment.id} not found`);
5378
5436
  return;
5379
5437
  }
5380
- node.getEl().remove();
5438
+ node.remove();
5381
5439
  this.commentNodes = this.commentNodes.filter((c) => c.getID() !== comment.id);
5382
5440
  });
5383
5441
  this.ctx.on("comment-updated", (comment) => {
@@ -6862,62 +6920,50 @@ const UnreadBadge = (ctx) => {
6862
6920
  showUnreadBadge(notifies.length || 0);
6863
6921
  });
6864
6922
  };
6865
- const Goto = (ctx) => {
6866
- let delayGoto = true;
6867
- const check2 = () => {
6923
+ const GotoDispatcher = (ctx) => {
6924
+ let lastID = 0;
6925
+ const check2 = ({ locker }) => {
6868
6926
  const commentID = extractCommentID();
6869
6927
  if (!commentID)
6870
6928
  return;
6929
+ if (locker && lastID === commentID)
6930
+ return;
6931
+ lastID = commentID;
6871
6932
  ctx.trigger("list-goto", commentID);
6872
- delayGoto = true;
6873
- };
6874
- const hashChangeHandler = () => {
6875
- delayGoto = false;
6876
- check2();
6877
6933
  };
6934
+ const hashChangeHandler = () => check2({ locker: false });
6935
+ const listLoadedHandler = () => check2({ locker: true });
6878
6936
  ctx.on("mounted", () => {
6879
6937
  window.addEventListener("hashchange", hashChangeHandler);
6880
- ctx.on("list-loaded", check2);
6938
+ ctx.on("list-loaded", listLoadedHandler);
6881
6939
  });
6882
6940
  ctx.on("unmounted", () => {
6883
6941
  window.removeEventListener("hashchange", hashChangeHandler);
6884
- ctx.off("list-loaded", check2);
6885
- });
6886
- let foundID = 0;
6887
- ctx.on("list-goto", (commentID) => {
6888
- if (foundID === commentID)
6889
- return;
6890
- const comment = ctx.get("list").getCommentNodes().find((c) => c.getID() === commentID);
6891
- if (!comment)
6892
- return;
6893
- foundID = commentID;
6894
- comment.getParents().forEach((p) => {
6895
- p.getRender().heightLimitRemoveForChildren();
6896
- });
6897
- const goTo = () => {
6898
- scrollIntoView(comment.getEl(), false);
6899
- comment.getEl().classList.remove("atk-flash-once");
6900
- window.setTimeout(() => {
6901
- comment.getEl().classList.add("atk-flash-once");
6902
- }, 150);
6903
- };
6904
- if (!delayGoto)
6905
- goTo();
6906
- else
6907
- window.setTimeout(() => goTo(), 350);
6942
+ ctx.off("list-loaded", listLoadedHandler);
6908
6943
  });
6909
6944
  };
6910
6945
  function extractCommentID() {
6911
- let commentId = Number(getQueryParam("atk_comment"));
6946
+ const match = window.location.hash.match(/#atk-comment-([0-9]+)/);
6947
+ let commentId = match && match[1] && !Number.isNaN(parseFloat(match[1])) ? parseFloat(match[1]) : null;
6912
6948
  if (!commentId) {
6913
- const match = window.location.hash.match(/#atk-comment-([0-9]+)/);
6914
- if (!match || !match[1] || Number.isNaN(Number(match[1])))
6915
- return null;
6916
- commentId = Number(match[1]);
6949
+ commentId = Number(getQueryParam("atk_comment"));
6917
6950
  }
6918
6951
  return commentId || null;
6919
6952
  }
6920
- const version = "2.8.0";
6953
+ const GotoFocus = (ctx) => {
6954
+ ctx.on("list-goto", (commentID) => __async(void 0, null, function* () {
6955
+ let comment = ctx.getCommentNodes().find((c) => c.getID() === commentID);
6956
+ if (!comment) {
6957
+ const data = (yield ctx.getApi().comments.getComment(commentID)).data;
6958
+ ctx.get("list").getListLayout({ forceFlatMode: true }).insert(data.comment, data.reply_comment);
6959
+ comment = ctx.getCommentNodes().find((c) => c.getID() === commentID);
6960
+ }
6961
+ if (!comment)
6962
+ return;
6963
+ comment.focus();
6964
+ }));
6965
+ };
6966
+ const version = "2.8.1";
6921
6967
  const Copyright = (ctx) => {
6922
6968
  ctx.on("mounted", () => {
6923
6969
  const list = ctx.get("list");
@@ -6928,14 +6974,7 @@ const Copyright = (ctx) => {
6928
6974
  });
6929
6975
  };
6930
6976
  const NoComment = (ctx) => {
6931
- let isFetching = false;
6932
- ctx.on("list-fetch", (params) => {
6933
- isFetching = true;
6934
- });
6935
6977
  ctx.on("list-loaded", (comments) => {
6936
- if (!isFetching)
6937
- return;
6938
- isFetching = false;
6939
6978
  const list = ctx.get("list");
6940
6979
  const isNoComment = comments.length <= 0;
6941
6980
  let $noComment = list.getCommentsWrapEl().querySelector(".atk-list-no-comment");
@@ -7187,7 +7226,8 @@ const ListPlugins = [
7187
7226
  SidebarBtn,
7188
7227
  UnreadBadge,
7189
7228
  Dropdown,
7190
- Goto,
7229
+ GotoDispatcher,
7230
+ GotoFocus,
7191
7231
  NoComment,
7192
7232
  Copyright,
7193
7233
  TimeTicking,
@@ -7211,6 +7251,7 @@ const PvCountWidget = (ctx) => {
7211
7251
  ctx.watchConf([
7212
7252
  "site",
7213
7253
  "pageKey",
7254
+ "pageTitle",
7214
7255
  "countEl",
7215
7256
  "pvEl"
7216
7257
  ], (conf) => {
@@ -7218,6 +7259,7 @@ const PvCountWidget = (ctx) => {
7218
7259
  getApi: () => ctx.getApi(),
7219
7260
  siteName: conf.site,
7220
7261
  pageKey: conf.pageKey,
7262
+ pageTitle: conf.pageTitle,
7221
7263
  countEl: conf.countEl,
7222
7264
  pvEl: conf.pvEl,
7223
7265
  pvAdd: typeof ctx.conf.pvAdd === "boolean" ? ctx.conf.pvAdd : true
@@ -7229,10 +7271,10 @@ function initCountWidget(opt) {
7229
7271
  if (opt.countEl && document.querySelector(opt.countEl)) {
7230
7272
  refreshStatCount(opt, { query: "page_comment", numEl: opt.countEl });
7231
7273
  }
7232
- const initialData = opt.pvAdd ? {
7274
+ const initialData = opt.pvAdd && opt.pageKey ? {
7233
7275
  [opt.pageKey]: (yield opt.getApi().pages.logPv({
7234
7276
  page_key: opt.pageKey,
7235
- page_title: opt.pageKey,
7277
+ page_title: opt.pageTitle,
7236
7278
  site_name: opt.siteName
7237
7279
  })).data.pv
7238
7280
  // pv+1 and get pv count
@@ -7249,7 +7291,7 @@ function initCountWidget(opt) {
7249
7291
  function refreshStatCount(opt, args) {
7250
7292
  return __async(this, null, function* () {
7251
7293
  let data = args.data || {};
7252
- let queryPageKeys = Array.from(document.querySelectorAll(args.numEl)).map((e) => e.getAttribute("data-page-key") || opt.pageKey).filter((k) => typeof data[k] !== "number");
7294
+ let queryPageKeys = Array.from(document.querySelectorAll(args.numEl)).map((e) => e.getAttribute("data-page-key") || opt.pageKey).filter((k) => k && typeof data[k] !== "number");
7253
7295
  queryPageKeys = [...new Set(queryPageKeys)];
7254
7296
  if (queryPageKeys.length > 0) {
7255
7297
  const res = (yield opt.getApi().stats.getStats(args.query, {
@@ -7258,7 +7300,8 @@ function refreshStatCount(opt, args) {
7258
7300
  })).data.data;
7259
7301
  data = __spreadValues(__spreadValues({}, data), res);
7260
7302
  }
7261
- applyCountData(args.numEl, data, data[opt.pageKey]);
7303
+ const defaultCount = opt.pageKey ? data[opt.pageKey] : 0;
7304
+ applyCountData(args.numEl, data, defaultCount);
7262
7305
  });
7263
7306
  }
7264
7307
  function applyCountData(selector, data, defaultCount) {
@@ -7447,7 +7490,6 @@ class Artalk {
7447
7490
  initCountWidget({
7448
7491
  getApi: () => new Api2(convertApiOptions(conf)),
7449
7492
  siteName: conf.site,
7450
- pageKey: conf.pageKey,
7451
7493
  countEl: conf.countEl,
7452
7494
  pvEl: conf.pvEl,
7453
7495
  pvAdd: false