artalk 2.8.5 → 2.8.7
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.cjs +1 -1
- package/dist/Artalk.cjs.map +1 -1
- package/dist/Artalk.iife.js +1 -1
- package/dist/Artalk.iife.js.map +1 -1
- package/dist/Artalk.js +1 -1
- package/dist/Artalk.js.map +1 -1
- package/dist/Artalk.mjs +592 -358
- package/dist/Artalk.mjs.map +1 -1
- package/dist/ArtalkLite.cjs +2 -2
- package/dist/ArtalkLite.cjs.map +1 -1
- package/dist/ArtalkLite.iife.js +2 -2
- package/dist/ArtalkLite.iife.js.map +1 -1
- package/dist/ArtalkLite.js +2 -2
- package/dist/ArtalkLite.js.map +1 -1
- package/dist/ArtalkLite.mjs +590 -357
- package/dist/ArtalkLite.mjs.map +1 -1
- package/dist/i18n/jp.cjs +1 -1
- package/dist/i18n/jp.js +1 -1
- package/dist/i18n/jp.mjs +21 -0
- package/dist/i18n/zh-TW.cjs +1 -1
- package/dist/i18n/zh-TW.js +1 -1
- package/dist/i18n/zh-TW.mjs +21 -4
- package/dist/main.d.cts +213 -12
- package/dist/main.d.ts +213 -12
- package/package.json +9 -11
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(
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
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(
|
|
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
|
});
|
|
@@ -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
|
-
|
|
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,18 +4484,26 @@ 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
|
|
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
4504
|
return html2.replace(
|
|
4347
4505
|
/^<a /,
|
|
4348
|
-
`<a target="_blank" ${!
|
|
4506
|
+
`<a target="_blank" ${!isSameOriginLink ? `rel="noreferrer noopener nofollow"` : ""} `
|
|
4349
4507
|
);
|
|
4350
4508
|
};
|
|
4351
4509
|
const markedCodeRenderer = () => (block2, lang) => {
|
|
@@ -4362,6 +4520,16 @@ const markedCodeRenderer = () => (block2, lang) => {
|
|
|
4362
4520
|
<code class="hljs language-${realLang}">${colorized.replace(/&/g, "&")}</code>
|
|
4363
4521
|
</pre>`;
|
|
4364
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
|
+
};
|
|
4365
4533
|
let instance;
|
|
4366
4534
|
let replacers = [];
|
|
4367
4535
|
const markedOptions = {
|
|
@@ -4375,16 +4543,18 @@ function getInstance() {
|
|
|
4375
4543
|
function setReplacers(arr) {
|
|
4376
4544
|
replacers = arr;
|
|
4377
4545
|
}
|
|
4378
|
-
function initMarked() {
|
|
4546
|
+
function initMarked(options) {
|
|
4379
4547
|
try {
|
|
4380
4548
|
if (!marked$1.name)
|
|
4381
4549
|
return;
|
|
4382
4550
|
} catch (e) {
|
|
4383
4551
|
return;
|
|
4384
4552
|
}
|
|
4385
|
-
marked$1.setOptions(__spreadValues({
|
|
4386
|
-
renderer: getRenderer(
|
|
4387
|
-
|
|
4553
|
+
marked$1.setOptions(__spreadValues(__spreadValues({
|
|
4554
|
+
renderer: getRenderer({
|
|
4555
|
+
imgLazyLoad: options.imgLazyLoad
|
|
4556
|
+
})
|
|
4557
|
+
}, markedOptions), options.markedOptions));
|
|
4388
4558
|
instance = marked$1;
|
|
4389
4559
|
}
|
|
4390
4560
|
function marked(src) {
|
|
@@ -4515,176 +4685,14 @@ class DataManager {
|
|
|
4515
4685
|
this.events.trigger("page-loaded", pageData);
|
|
4516
4686
|
}
|
|
4517
4687
|
}
|
|
4518
|
-
const en = {
|
|
4519
|
-
/* Editor */
|
|
4520
|
-
placeholder: "Leave a comment",
|
|
4521
|
-
noComment: "No Comment",
|
|
4522
|
-
send: "Send",
|
|
4523
|
-
save: "Save",
|
|
4524
|
-
nick: "Nickname",
|
|
4525
|
-
email: "Email",
|
|
4526
|
-
link: "Website",
|
|
4527
|
-
emoticon: "Emoji",
|
|
4528
|
-
preview: "Preview",
|
|
4529
|
-
uploadImage: "Upload Image",
|
|
4530
|
-
uploadFail: "Upload Failed",
|
|
4531
|
-
commentFail: "Failed to comment",
|
|
4532
|
-
restoredMsg: "Content has been restored",
|
|
4533
|
-
onlyAdminCanReply: "Only admin can reply",
|
|
4534
|
-
uploadLoginMsg: "Please fill in your name and email to upload",
|
|
4535
|
-
/* List */
|
|
4536
|
-
counter: "{count} Comments",
|
|
4537
|
-
sortLatest: "Latest",
|
|
4538
|
-
sortOldest: "Oldest",
|
|
4539
|
-
sortBest: "Best",
|
|
4540
|
-
sortAuthor: "Author",
|
|
4541
|
-
openComment: "Open Comment",
|
|
4542
|
-
closeComment: "Close Comment",
|
|
4543
|
-
listLoadFailMsg: "Failed to load comments",
|
|
4544
|
-
listRetry: "Retry",
|
|
4545
|
-
loadMore: "Load More",
|
|
4546
|
-
/* Comment */
|
|
4547
|
-
admin: "Admin",
|
|
4548
|
-
reply: "Reply",
|
|
4549
|
-
voteUp: "Up",
|
|
4550
|
-
voteDown: "Down",
|
|
4551
|
-
voteFail: "Vote Failed",
|
|
4552
|
-
readMore: "Read More",
|
|
4553
|
-
actionConfirm: "Confirm",
|
|
4554
|
-
collapse: "Collapse",
|
|
4555
|
-
collapsed: "Collapsed",
|
|
4556
|
-
collapsedMsg: "This comment has been collapsed",
|
|
4557
|
-
expand: "Expand",
|
|
4558
|
-
approved: "Approved",
|
|
4559
|
-
pending: "Pending",
|
|
4560
|
-
pendingMsg: "Pending, visible only to commenter.",
|
|
4561
|
-
edit: "Edit",
|
|
4562
|
-
editCancel: "Cancel Edit",
|
|
4563
|
-
delete: "Delete",
|
|
4564
|
-
deleteConfirm: "Confirm",
|
|
4565
|
-
pin: "Pin",
|
|
4566
|
-
unpin: "Unpin",
|
|
4567
|
-
/* Time */
|
|
4568
|
-
seconds: "seconds ago",
|
|
4569
|
-
minutes: "minutes ago",
|
|
4570
|
-
hours: "hours ago",
|
|
4571
|
-
days: "days ago",
|
|
4572
|
-
now: "just now",
|
|
4573
|
-
/* Checker */
|
|
4574
|
-
adminCheck: "Enter admin password:",
|
|
4575
|
-
captchaCheck: "Enter the CAPTCHA to continue:",
|
|
4576
|
-
confirm: "Confirm",
|
|
4577
|
-
cancel: "Cancel",
|
|
4578
|
-
/* Sidebar */
|
|
4579
|
-
msgCenter: "Messages",
|
|
4580
|
-
ctrlCenter: "Admin",
|
|
4581
|
-
emailVerified: "Email has been verified",
|
|
4582
|
-
/* General */
|
|
4583
|
-
frontend: "Frontend",
|
|
4584
|
-
backend: "Backend",
|
|
4585
|
-
loading: "Loading",
|
|
4586
|
-
loadFail: "Load Failed",
|
|
4587
|
-
editing: "Editing",
|
|
4588
|
-
editFail: "Edit Failed",
|
|
4589
|
-
deleting: "Deleting",
|
|
4590
|
-
deleteFail: "Delete Failed",
|
|
4591
|
-
reqGot: "Request got",
|
|
4592
|
-
reqAborted: "Request timed out or terminated unexpectedly",
|
|
4593
|
-
updateMsg: "Please update Artalk {name} to get the best experience!",
|
|
4594
|
-
currentVersion: "Current Version",
|
|
4595
|
-
ignore: "Ignore",
|
|
4596
|
-
open: "Open",
|
|
4597
|
-
openName: "Open {name}"
|
|
4598
|
-
};
|
|
4599
|
-
const zhCN = {
|
|
4600
|
-
/* Editor */
|
|
4601
|
-
placeholder: "键入内容...",
|
|
4602
|
-
noComment: "「此时无声胜有声」",
|
|
4603
|
-
send: "发送",
|
|
4604
|
-
save: "保存",
|
|
4605
|
-
nick: "昵称",
|
|
4606
|
-
email: "邮箱",
|
|
4607
|
-
link: "网址",
|
|
4608
|
-
emoticon: "表情",
|
|
4609
|
-
preview: "预览",
|
|
4610
|
-
uploadImage: "上传图片",
|
|
4611
|
-
uploadFail: "上传失败",
|
|
4612
|
-
commentFail: "评论失败",
|
|
4613
|
-
restoredMsg: "内容已自动恢复",
|
|
4614
|
-
onlyAdminCanReply: "仅管理员可评论",
|
|
4615
|
-
uploadLoginMsg: "填入你的名字邮箱才能上传哦",
|
|
4616
|
-
/* List */
|
|
4617
|
-
counter: "{count} 条评论",
|
|
4618
|
-
sortLatest: "最新",
|
|
4619
|
-
sortOldest: "最早",
|
|
4620
|
-
sortBest: "最热",
|
|
4621
|
-
sortAuthor: "作者",
|
|
4622
|
-
openComment: "打开评论",
|
|
4623
|
-
closeComment: "关闭评论",
|
|
4624
|
-
listLoadFailMsg: "无法获取评论列表数据",
|
|
4625
|
-
listRetry: "点击重新获取",
|
|
4626
|
-
loadMore: "加载更多",
|
|
4627
|
-
/* Comment */
|
|
4628
|
-
admin: "管理员",
|
|
4629
|
-
reply: "回复",
|
|
4630
|
-
voteUp: "赞同",
|
|
4631
|
-
voteDown: "反对",
|
|
4632
|
-
voteFail: "投票失败",
|
|
4633
|
-
readMore: "阅读更多",
|
|
4634
|
-
actionConfirm: "确认操作",
|
|
4635
|
-
collapse: "折叠",
|
|
4636
|
-
collapsed: "已折叠",
|
|
4637
|
-
collapsedMsg: "该评论已被系统或管理员折叠",
|
|
4638
|
-
expand: "展开",
|
|
4639
|
-
approved: "已审",
|
|
4640
|
-
pending: "待审",
|
|
4641
|
-
pendingMsg: "审核中,仅本人可见。",
|
|
4642
|
-
edit: "编辑",
|
|
4643
|
-
editCancel: "取消编辑",
|
|
4644
|
-
delete: "删除",
|
|
4645
|
-
deleteConfirm: "确认删除",
|
|
4646
|
-
pin: "置顶",
|
|
4647
|
-
unpin: "取消置顶",
|
|
4648
|
-
/* Time */
|
|
4649
|
-
seconds: "秒前",
|
|
4650
|
-
minutes: "分钟前",
|
|
4651
|
-
hours: "小时前",
|
|
4652
|
-
days: "天前",
|
|
4653
|
-
now: "刚刚",
|
|
4654
|
-
/* Checker */
|
|
4655
|
-
adminCheck: "键入密码来验证管理员身份:",
|
|
4656
|
-
captchaCheck: "键入验证码继续:",
|
|
4657
|
-
confirm: "确认",
|
|
4658
|
-
cancel: "取消",
|
|
4659
|
-
/* Sidebar */
|
|
4660
|
-
msgCenter: "通知中心",
|
|
4661
|
-
ctrlCenter: "控制中心",
|
|
4662
|
-
emailVerified: "邮箱已验证",
|
|
4663
|
-
/* General */
|
|
4664
|
-
frontend: "前端",
|
|
4665
|
-
backend: "后端",
|
|
4666
|
-
loading: "加载中",
|
|
4667
|
-
loadFail: "加载失败",
|
|
4668
|
-
editing: "修改中",
|
|
4669
|
-
editFail: "修改失败",
|
|
4670
|
-
deleting: "删除中",
|
|
4671
|
-
deleteFail: "删除失败",
|
|
4672
|
-
reqGot: "请求响应",
|
|
4673
|
-
reqAborted: "请求超时或意外终止",
|
|
4674
|
-
updateMsg: "请更新 Artalk {name} 以获得更好的体验!",
|
|
4675
|
-
currentVersion: "当前版本",
|
|
4676
|
-
ignore: "忽略",
|
|
4677
|
-
open: "打开",
|
|
4678
|
-
openName: "打开{name}"
|
|
4679
|
-
};
|
|
4680
|
-
const GLOBAL_LOCALES_KEY = "ArtalkI18n";
|
|
4681
4688
|
function createElement(htmlStr = "") {
|
|
4682
4689
|
const div = document.createElement("div");
|
|
4683
4690
|
div.innerHTML = htmlStr.trim();
|
|
4684
4691
|
return div.firstElementChild || div;
|
|
4685
4692
|
}
|
|
4686
4693
|
function getHeight(el) {
|
|
4687
|
-
|
|
4694
|
+
const num = parseFloat(getComputedStyle(el, null).height.replace("px", ""));
|
|
4695
|
+
return num || 0;
|
|
4688
4696
|
}
|
|
4689
4697
|
function htmlEncode(str) {
|
|
4690
4698
|
const temp = document.createElement("div");
|
|
@@ -4762,29 +4770,8 @@ function timeAgo(date, $t = (n) => n) {
|
|
|
4762
4770
|
return " - ";
|
|
4763
4771
|
}
|
|
4764
4772
|
}
|
|
4765
|
-
function onImagesLoaded($container, event) {
|
|
4766
|
-
if (!$container)
|
|
4767
|
-
return;
|
|
4768
|
-
const images = $container.getElementsByTagName("img");
|
|
4769
|
-
if (!images.length)
|
|
4770
|
-
return;
|
|
4771
|
-
let loaded = images.length;
|
|
4772
|
-
for (let i = 0; i < images.length; i++) {
|
|
4773
|
-
if (images[i].complete) {
|
|
4774
|
-
loaded--;
|
|
4775
|
-
} else {
|
|
4776
|
-
images[i].addEventListener("load", () => {
|
|
4777
|
-
loaded--;
|
|
4778
|
-
if (loaded === 0)
|
|
4779
|
-
event();
|
|
4780
|
-
});
|
|
4781
|
-
}
|
|
4782
|
-
if (loaded === 0)
|
|
4783
|
-
event();
|
|
4784
|
-
}
|
|
4785
|
-
}
|
|
4786
4773
|
function getGravatarURL(opts) {
|
|
4787
|
-
return `${opts.mirror.replace(/\/$/, "")}/${opts.
|
|
4774
|
+
return `${opts.mirror.replace(/\/$/, "")}/${opts.emailHash}?${opts.params.replace(/^\?/, "")}`;
|
|
4788
4775
|
}
|
|
4789
4776
|
function versionCompare(a, b) {
|
|
4790
4777
|
const pa = a.split(".");
|
|
@@ -4849,6 +4836,211 @@ function getURLBasedOnApi(opts) {
|
|
|
4849
4836
|
function getURLBasedOn(baseURL, path) {
|
|
4850
4837
|
return `${baseURL.replace(/\/$/, "")}/${path.replace(/^\//, "")}`;
|
|
4851
4838
|
}
|
|
4839
|
+
const en = {
|
|
4840
|
+
/* Editor */
|
|
4841
|
+
placeholder: "Leave a comment",
|
|
4842
|
+
noComment: "No Comment",
|
|
4843
|
+
send: "Send",
|
|
4844
|
+
signIn: "Sign in",
|
|
4845
|
+
signUp: "Sign up",
|
|
4846
|
+
save: "Save",
|
|
4847
|
+
nick: "Nickname",
|
|
4848
|
+
email: "Email",
|
|
4849
|
+
link: "Website",
|
|
4850
|
+
emoticon: "Emoji",
|
|
4851
|
+
preview: "Preview",
|
|
4852
|
+
uploadImage: "Upload Image",
|
|
4853
|
+
uploadFail: "Upload Failed",
|
|
4854
|
+
commentFail: "Failed to comment",
|
|
4855
|
+
restoredMsg: "Content has been restored",
|
|
4856
|
+
onlyAdminCanReply: "Only admin can reply",
|
|
4857
|
+
uploadLoginMsg: "Please fill in your name and email to upload",
|
|
4858
|
+
/* List */
|
|
4859
|
+
counter: "{count} Comments",
|
|
4860
|
+
sortLatest: "Latest",
|
|
4861
|
+
sortOldest: "Oldest",
|
|
4862
|
+
sortBest: "Best",
|
|
4863
|
+
sortAuthor: "Author",
|
|
4864
|
+
openComment: "Open Comment",
|
|
4865
|
+
closeComment: "Close Comment",
|
|
4866
|
+
listLoadFailMsg: "Failed to load comments",
|
|
4867
|
+
listRetry: "Retry",
|
|
4868
|
+
loadMore: "Load More",
|
|
4869
|
+
/* Comment */
|
|
4870
|
+
admin: "Admin",
|
|
4871
|
+
reply: "Reply",
|
|
4872
|
+
voteUp: "Up",
|
|
4873
|
+
voteDown: "Down",
|
|
4874
|
+
voteFail: "Vote Failed",
|
|
4875
|
+
readMore: "Read More",
|
|
4876
|
+
actionConfirm: "Confirm",
|
|
4877
|
+
collapse: "Collapse",
|
|
4878
|
+
collapsed: "Collapsed",
|
|
4879
|
+
collapsedMsg: "This comment has been collapsed",
|
|
4880
|
+
expand: "Expand",
|
|
4881
|
+
approved: "Approved",
|
|
4882
|
+
pending: "Pending",
|
|
4883
|
+
pendingMsg: "Pending, visible only to commenter.",
|
|
4884
|
+
edit: "Edit",
|
|
4885
|
+
editCancel: "Cancel Edit",
|
|
4886
|
+
delete: "Delete",
|
|
4887
|
+
deleteConfirm: "Confirm",
|
|
4888
|
+
pin: "Pin",
|
|
4889
|
+
unpin: "Unpin",
|
|
4890
|
+
/* Time */
|
|
4891
|
+
seconds: "seconds ago",
|
|
4892
|
+
minutes: "minutes ago",
|
|
4893
|
+
hours: "hours ago",
|
|
4894
|
+
days: "days ago",
|
|
4895
|
+
now: "just now",
|
|
4896
|
+
/* Checker */
|
|
4897
|
+
adminCheck: "Enter admin password:",
|
|
4898
|
+
captchaCheck: "Enter the CAPTCHA to continue:",
|
|
4899
|
+
confirm: "Confirm",
|
|
4900
|
+
cancel: "Cancel",
|
|
4901
|
+
/* Sidebar */
|
|
4902
|
+
msgCenter: "Messages",
|
|
4903
|
+
ctrlCenter: "Admin",
|
|
4904
|
+
/* Auth */
|
|
4905
|
+
noAccountPrompt: "Don't have an account?",
|
|
4906
|
+
haveAccountPrompt: "Already have an account?",
|
|
4907
|
+
forgetPassword: "Forget Password",
|
|
4908
|
+
resetPassword: "Reset Password",
|
|
4909
|
+
verificationCode: "Verification Code",
|
|
4910
|
+
verifySend: "Verify",
|
|
4911
|
+
verifyResend: "Resend",
|
|
4912
|
+
waitSeconds: "Wait {seconds}s",
|
|
4913
|
+
emailVerified: "Email has been verified",
|
|
4914
|
+
password: "Password",
|
|
4915
|
+
username: "Username",
|
|
4916
|
+
nextStep: "Next Step",
|
|
4917
|
+
skipNotVerify: "Skip, do not verify",
|
|
4918
|
+
logoutConfirm: "Are you sure to logout?",
|
|
4919
|
+
accountMergeNotice: "Your email has multiple accounts with different id.",
|
|
4920
|
+
accountMergeSelectOne: "Please select one you want to merge all the data into it.",
|
|
4921
|
+
accountMergeConfirm: "All data will be merged into one account, the id is {id}.",
|
|
4922
|
+
dismiss: "Dismiss",
|
|
4923
|
+
merge: "Merge",
|
|
4924
|
+
/* General */
|
|
4925
|
+
frontend: "Frontend",
|
|
4926
|
+
backend: "Backend",
|
|
4927
|
+
loading: "Loading",
|
|
4928
|
+
loadFail: "Load Failed",
|
|
4929
|
+
editing: "Editing",
|
|
4930
|
+
editFail: "Edit Failed",
|
|
4931
|
+
deleting: "Deleting",
|
|
4932
|
+
deleteFail: "Delete Failed",
|
|
4933
|
+
reqGot: "Request got",
|
|
4934
|
+
reqAborted: "Request timed out or terminated unexpectedly",
|
|
4935
|
+
updateMsg: "Please update Artalk {name} to get the best experience!",
|
|
4936
|
+
currentVersion: "Current Version",
|
|
4937
|
+
ignore: "Ignore",
|
|
4938
|
+
open: "Open",
|
|
4939
|
+
openName: "Open {name}"
|
|
4940
|
+
};
|
|
4941
|
+
const zhCN = {
|
|
4942
|
+
/* Editor */
|
|
4943
|
+
placeholder: "键入内容...",
|
|
4944
|
+
noComment: "「此时无声胜有声」",
|
|
4945
|
+
send: "发送",
|
|
4946
|
+
signIn: "登录",
|
|
4947
|
+
signUp: "注册",
|
|
4948
|
+
save: "保存",
|
|
4949
|
+
nick: "昵称",
|
|
4950
|
+
email: "邮箱",
|
|
4951
|
+
link: "网址",
|
|
4952
|
+
emoticon: "表情",
|
|
4953
|
+
preview: "预览",
|
|
4954
|
+
uploadImage: "上传图片",
|
|
4955
|
+
uploadFail: "上传失败",
|
|
4956
|
+
commentFail: "评论失败",
|
|
4957
|
+
restoredMsg: "内容已自动恢复",
|
|
4958
|
+
onlyAdminCanReply: "仅管理员可评论",
|
|
4959
|
+
uploadLoginMsg: "填入你的名字邮箱才能上传哦",
|
|
4960
|
+
/* List */
|
|
4961
|
+
counter: "{count} 条评论",
|
|
4962
|
+
sortLatest: "最新",
|
|
4963
|
+
sortOldest: "最早",
|
|
4964
|
+
sortBest: "最热",
|
|
4965
|
+
sortAuthor: "作者",
|
|
4966
|
+
openComment: "打开评论",
|
|
4967
|
+
closeComment: "关闭评论",
|
|
4968
|
+
listLoadFailMsg: "无法获取评论列表数据",
|
|
4969
|
+
listRetry: "点击重新获取",
|
|
4970
|
+
loadMore: "加载更多",
|
|
4971
|
+
/* Comment */
|
|
4972
|
+
admin: "管理员",
|
|
4973
|
+
reply: "回复",
|
|
4974
|
+
voteUp: "赞同",
|
|
4975
|
+
voteDown: "反对",
|
|
4976
|
+
voteFail: "投票失败",
|
|
4977
|
+
readMore: "阅读更多",
|
|
4978
|
+
actionConfirm: "确认操作",
|
|
4979
|
+
collapse: "折叠",
|
|
4980
|
+
collapsed: "已折叠",
|
|
4981
|
+
collapsedMsg: "该评论已被系统或管理员折叠",
|
|
4982
|
+
expand: "展开",
|
|
4983
|
+
approved: "已审",
|
|
4984
|
+
pending: "待审",
|
|
4985
|
+
pendingMsg: "审核中,仅本人可见。",
|
|
4986
|
+
edit: "编辑",
|
|
4987
|
+
editCancel: "取消编辑",
|
|
4988
|
+
delete: "删除",
|
|
4989
|
+
deleteConfirm: "确认删除",
|
|
4990
|
+
pin: "置顶",
|
|
4991
|
+
unpin: "取消置顶",
|
|
4992
|
+
/* Time */
|
|
4993
|
+
seconds: "秒前",
|
|
4994
|
+
minutes: "分钟前",
|
|
4995
|
+
hours: "小时前",
|
|
4996
|
+
days: "天前",
|
|
4997
|
+
now: "刚刚",
|
|
4998
|
+
/* Checker */
|
|
4999
|
+
adminCheck: "键入密码来验证管理员身份:",
|
|
5000
|
+
captchaCheck: "键入验证码继续:",
|
|
5001
|
+
confirm: "确认",
|
|
5002
|
+
cancel: "取消",
|
|
5003
|
+
/* Sidebar */
|
|
5004
|
+
msgCenter: "通知中心",
|
|
5005
|
+
ctrlCenter: "控制中心",
|
|
5006
|
+
/* Auth */
|
|
5007
|
+
noAccountPrompt: "没有账号?",
|
|
5008
|
+
haveAccountPrompt: "已有账号?",
|
|
5009
|
+
forgetPassword: "忘记密码",
|
|
5010
|
+
resetPassword: "重置密码",
|
|
5011
|
+
verificationCode: "验证码",
|
|
5012
|
+
verifySend: "发送验证码",
|
|
5013
|
+
verifyResend: "重新发送",
|
|
5014
|
+
waitSeconds: "等待 {seconds}秒",
|
|
5015
|
+
emailVerified: "邮箱已验证",
|
|
5016
|
+
password: "密码",
|
|
5017
|
+
username: "用户名",
|
|
5018
|
+
nextStep: "下一步",
|
|
5019
|
+
skipNotVerify: "跳过,不验证",
|
|
5020
|
+
logoutConfirm: "确定要退出登录吗?",
|
|
5021
|
+
accountMergeNotice: "您的电子邮件下有多个不同 ID 的账户。",
|
|
5022
|
+
accountMergeSelectOne: "请选择将所有数据合并到其中的一个。",
|
|
5023
|
+
accountMergeConfirm: "所有数据将合并到 ID 为 {id} 的账户中。",
|
|
5024
|
+
dismiss: "忽略",
|
|
5025
|
+
merge: "合并",
|
|
5026
|
+
/* General */
|
|
5027
|
+
frontend: "前端",
|
|
5028
|
+
backend: "后端",
|
|
5029
|
+
loading: "加载中",
|
|
5030
|
+
loadFail: "加载失败",
|
|
5031
|
+
editing: "修改中",
|
|
5032
|
+
editFail: "修改失败",
|
|
5033
|
+
deleting: "删除中",
|
|
5034
|
+
deleteFail: "删除失败",
|
|
5035
|
+
reqGot: "请求响应",
|
|
5036
|
+
reqAborted: "请求超时或意外终止",
|
|
5037
|
+
updateMsg: "请更新 Artalk {name} 以获得更好的体验!",
|
|
5038
|
+
currentVersion: "当前版本",
|
|
5039
|
+
ignore: "忽略",
|
|
5040
|
+
open: "打开",
|
|
5041
|
+
openName: "打开{name}"
|
|
5042
|
+
};
|
|
5043
|
+
const GLOBAL_LOCALES_KEY = "ArtalkI18n";
|
|
4852
5044
|
const internal = {
|
|
4853
5045
|
en,
|
|
4854
5046
|
"en-US": en,
|
|
@@ -4932,11 +5124,12 @@ const defaults = {
|
|
|
4932
5124
|
uaBadge: true,
|
|
4933
5125
|
listSort: true,
|
|
4934
5126
|
preview: true,
|
|
4935
|
-
countEl: "
|
|
4936
|
-
pvEl: "
|
|
5127
|
+
countEl: ".artalk-comment-count",
|
|
5128
|
+
pvEl: ".artalk-pv-count",
|
|
5129
|
+
statPageKeyAttr: "data-page-key",
|
|
4937
5130
|
gravatar: {
|
|
4938
|
-
mirror: "https://
|
|
4939
|
-
params: "d=mp&s=240"
|
|
5131
|
+
mirror: "https://www.gravatar.com/avatar/",
|
|
5132
|
+
params: "sha256=1&d=mp&s=240"
|
|
4940
5133
|
},
|
|
4941
5134
|
pagination: {
|
|
4942
5135
|
pageSize: 20,
|
|
@@ -4982,16 +5175,20 @@ function handelCustomConf(customConf, full = false) {
|
|
|
4982
5175
|
return conf;
|
|
4983
5176
|
}
|
|
4984
5177
|
function handleConfFormServer(conf) {
|
|
4985
|
-
const
|
|
5178
|
+
const ExcludedKeys = [
|
|
4986
5179
|
"el",
|
|
4987
5180
|
"pageKey",
|
|
4988
5181
|
"pageTitle",
|
|
4989
5182
|
"server",
|
|
4990
5183
|
"site",
|
|
4991
|
-
"
|
|
5184
|
+
"pvEl",
|
|
5185
|
+
"countEl",
|
|
5186
|
+
"statPageKeyAttr"
|
|
4992
5187
|
];
|
|
4993
5188
|
Object.keys(conf).forEach((k) => {
|
|
4994
|
-
if (
|
|
5189
|
+
if (ExcludedKeys.includes(k))
|
|
5190
|
+
delete conf[k];
|
|
5191
|
+
if (k === "darkMode" && conf[k] !== "auto")
|
|
4995
5192
|
delete conf[k];
|
|
4996
5193
|
});
|
|
4997
5194
|
if (conf.emoticons && typeof conf.emoticons === "string") {
|
|
@@ -5168,50 +5365,6 @@ class Context {
|
|
|
5168
5365
|
watchConf(this, keys, effect);
|
|
5169
5366
|
}
|
|
5170
5367
|
}
|
|
5171
|
-
class Dialog {
|
|
5172
|
-
constructor(contentEl) {
|
|
5173
|
-
__publicField(this, "$el");
|
|
5174
|
-
__publicField(this, "$content");
|
|
5175
|
-
__publicField(this, "$actions");
|
|
5176
|
-
this.$el = createElement(
|
|
5177
|
-
`<div class="atk-layer-dialog-wrap">
|
|
5178
|
-
<div class="atk-layer-dialog">
|
|
5179
|
-
<div class="atk-layer-dialog-content"></div>
|
|
5180
|
-
<div class="atk-layer-dialog-actions"></div>
|
|
5181
|
-
</div>
|
|
5182
|
-
</div>`
|
|
5183
|
-
);
|
|
5184
|
-
this.$actions = this.$el.querySelector(".atk-layer-dialog-actions");
|
|
5185
|
-
this.$content = this.$el.querySelector(".atk-layer-dialog-content");
|
|
5186
|
-
this.$content.appendChild(contentEl);
|
|
5187
|
-
}
|
|
5188
|
-
/** 按钮 · 确定 */
|
|
5189
|
-
setYes(handler) {
|
|
5190
|
-
const btn = createElement(
|
|
5191
|
-
`<button data-action="confirm">${t("confirm")}</button>`
|
|
5192
|
-
);
|
|
5193
|
-
btn.onclick = this.onBtnClick(handler);
|
|
5194
|
-
this.$actions.appendChild(btn);
|
|
5195
|
-
return this;
|
|
5196
|
-
}
|
|
5197
|
-
/** 按钮 · 取消 */
|
|
5198
|
-
setNo(handler) {
|
|
5199
|
-
const btn = createElement(
|
|
5200
|
-
`<button data-action="cancel">${t("cancel")}</button>`
|
|
5201
|
-
);
|
|
5202
|
-
btn.onclick = this.onBtnClick(handler);
|
|
5203
|
-
this.$actions.appendChild(btn);
|
|
5204
|
-
return this;
|
|
5205
|
-
}
|
|
5206
|
-
onBtnClick(handler) {
|
|
5207
|
-
return (evt) => {
|
|
5208
|
-
const re = handler(evt.currentTarget, this);
|
|
5209
|
-
if (re === void 0 || re === true) {
|
|
5210
|
-
this.$el.remove();
|
|
5211
|
-
}
|
|
5212
|
-
};
|
|
5213
|
-
}
|
|
5214
|
-
}
|
|
5215
5368
|
function showLoading(parentElem, conf) {
|
|
5216
5369
|
let $loading = parentElem.querySelector(":scope > .atk-loading");
|
|
5217
5370
|
if (!$loading) {
|
|
@@ -5300,8 +5453,6 @@ function playFadeAnim(elem, after, type = "in") {
|
|
|
5300
5453
|
const onAnimEnded = () => {
|
|
5301
5454
|
elem.classList.remove(`atk-fade-${type}`);
|
|
5302
5455
|
elem.removeEventListener("animationend", onAnimEnded);
|
|
5303
|
-
if (after)
|
|
5304
|
-
after();
|
|
5305
5456
|
};
|
|
5306
5457
|
elem.addEventListener("animationend", onAnimEnded);
|
|
5307
5458
|
}
|
|
@@ -5459,6 +5610,50 @@ const AdminChecker = {
|
|
|
5459
5610
|
onError(checker, err, inputVal, formEl) {
|
|
5460
5611
|
}
|
|
5461
5612
|
};
|
|
5613
|
+
class Dialog {
|
|
5614
|
+
constructor(contentEl) {
|
|
5615
|
+
__publicField(this, "$el");
|
|
5616
|
+
__publicField(this, "$content");
|
|
5617
|
+
__publicField(this, "$actions");
|
|
5618
|
+
this.$el = createElement(
|
|
5619
|
+
`<div class="atk-layer-dialog-wrap">
|
|
5620
|
+
<div class="atk-layer-dialog">
|
|
5621
|
+
<div class="atk-layer-dialog-content"></div>
|
|
5622
|
+
<div class="atk-layer-dialog-actions"></div>
|
|
5623
|
+
</div>
|
|
5624
|
+
</div>`
|
|
5625
|
+
);
|
|
5626
|
+
this.$actions = this.$el.querySelector(".atk-layer-dialog-actions");
|
|
5627
|
+
this.$content = this.$el.querySelector(".atk-layer-dialog-content");
|
|
5628
|
+
this.$content.appendChild(contentEl);
|
|
5629
|
+
}
|
|
5630
|
+
/** 按钮 · 确定 */
|
|
5631
|
+
setYes(handler) {
|
|
5632
|
+
const btn = createElement(
|
|
5633
|
+
`<button data-action="confirm">${t("confirm")}</button>`
|
|
5634
|
+
);
|
|
5635
|
+
btn.onclick = this.onBtnClick(handler);
|
|
5636
|
+
this.$actions.appendChild(btn);
|
|
5637
|
+
return this;
|
|
5638
|
+
}
|
|
5639
|
+
/** 按钮 · 取消 */
|
|
5640
|
+
setNo(handler) {
|
|
5641
|
+
const btn = createElement(
|
|
5642
|
+
`<button data-action="cancel">${t("cancel")}</button>`
|
|
5643
|
+
);
|
|
5644
|
+
btn.onclick = this.onBtnClick(handler);
|
|
5645
|
+
this.$actions.appendChild(btn);
|
|
5646
|
+
return this;
|
|
5647
|
+
}
|
|
5648
|
+
onBtnClick(handler) {
|
|
5649
|
+
return (evt) => {
|
|
5650
|
+
const re = handler(evt.currentTarget, this);
|
|
5651
|
+
if (re === void 0 || re === true) {
|
|
5652
|
+
this.$el.remove();
|
|
5653
|
+
}
|
|
5654
|
+
};
|
|
5655
|
+
}
|
|
5656
|
+
}
|
|
5462
5657
|
function wrapPromise(fn) {
|
|
5463
5658
|
return (payload) => new Promise((resolve, reject) => {
|
|
5464
5659
|
const cancelFn = payload.onCancel;
|
|
@@ -5852,10 +6047,10 @@ class SidebarLayer extends Component {
|
|
|
5852
6047
|
} else {
|
|
5853
6048
|
const $iframe = this.$iframe;
|
|
5854
6049
|
const iFrameSrc = $iframe.src;
|
|
5855
|
-
if (this.
|
|
6050
|
+
if (this.getDarkMode() !== iFrameSrc.includes("&darkMode=1")) {
|
|
5856
6051
|
this.iframeLoad(
|
|
5857
6052
|
$iframe,
|
|
5858
|
-
this.
|
|
6053
|
+
this.getDarkMode() ? iFrameSrc.concat("&darkMode=1") : iFrameSrc.replace("&darkMode=1", "")
|
|
5859
6054
|
);
|
|
5860
6055
|
}
|
|
5861
6056
|
}
|
|
@@ -5925,12 +6120,15 @@ class SidebarLayer extends Component {
|
|
|
5925
6120
|
};
|
|
5926
6121
|
if (view)
|
|
5927
6122
|
query.view = view;
|
|
5928
|
-
if (this.
|
|
6123
|
+
if (this.getDarkMode())
|
|
5929
6124
|
query.darkMode = "1";
|
|
5930
6125
|
const urlParams = new URLSearchParams(query);
|
|
5931
6126
|
this.iframeLoad($iframe, `${baseURL}?${urlParams.toString()}`);
|
|
5932
6127
|
return $iframe;
|
|
5933
6128
|
}
|
|
6129
|
+
getDarkMode() {
|
|
6130
|
+
return this.conf.darkMode === "auto" ? window.matchMedia("(prefers-color-scheme: dark)").matches : this.conf.darkMode;
|
|
6131
|
+
}
|
|
5934
6132
|
iframeLoad($iframe, src) {
|
|
5935
6133
|
$iframe.src = src;
|
|
5936
6134
|
showLoading(this.$iframeWrap);
|
|
@@ -6265,38 +6463,45 @@ function Detect(userAgent) {
|
|
|
6265
6463
|
return dest;
|
|
6266
6464
|
}
|
|
6267
6465
|
function check(conf, rules) {
|
|
6268
|
-
rules.forEach(({ el, max
|
|
6269
|
-
|
|
6270
|
-
|
|
6271
|
-
|
|
6272
|
-
|
|
6273
|
-
|
|
6274
|
-
el,
|
|
6275
|
-
maxHeight,
|
|
6276
|
-
postBtnClick: conf.postExpandBtnClick
|
|
6277
|
-
});
|
|
6278
|
-
else
|
|
6279
|
-
applyScrollableHeightLimit({ el, maxHeight });
|
|
6280
|
-
};
|
|
6466
|
+
rules.forEach(({ el, max, imgCheck }) => {
|
|
6467
|
+
if (!el)
|
|
6468
|
+
return;
|
|
6469
|
+
if (imgCheck)
|
|
6470
|
+
el.style.maxHeight = `${max + 1}px`;
|
|
6471
|
+
let lock = false;
|
|
6281
6472
|
const _check = () => {
|
|
6282
|
-
if (
|
|
6283
|
-
|
|
6473
|
+
if (lock)
|
|
6474
|
+
return;
|
|
6475
|
+
if (getHeight(el) <= max)
|
|
6476
|
+
return;
|
|
6477
|
+
const afterExpandBtnClick = () => {
|
|
6478
|
+
var _a;
|
|
6479
|
+
lock = true;
|
|
6480
|
+
(_a = conf.afterExpandBtnClick) == null ? void 0 : _a.call(conf);
|
|
6481
|
+
};
|
|
6482
|
+
!conf.scrollable ? applyHeightLimit({ el, max, afterExpandBtnClick }) : applyScrollableHeightLimit({ el, max });
|
|
6284
6483
|
};
|
|
6285
6484
|
_check();
|
|
6286
|
-
if (
|
|
6287
|
-
|
|
6485
|
+
if (imgCheck) {
|
|
6486
|
+
const imgs = el.querySelectorAll(".atk-content img");
|
|
6487
|
+
if (imgs.length === 0)
|
|
6488
|
+
el.style.maxHeight = "";
|
|
6489
|
+
imgs.forEach((img) => {
|
|
6490
|
+
img.onload = () => _check();
|
|
6491
|
+
});
|
|
6492
|
+
}
|
|
6288
6493
|
});
|
|
6289
6494
|
}
|
|
6290
6495
|
const HEIGHT_LIMIT_CSS = "atk-height-limit";
|
|
6291
6496
|
function applyHeightLimit(obj) {
|
|
6292
6497
|
if (!obj.el)
|
|
6293
6498
|
return;
|
|
6294
|
-
if (!obj.
|
|
6499
|
+
if (!obj.max)
|
|
6295
6500
|
return;
|
|
6296
6501
|
if (obj.el.classList.contains(HEIGHT_LIMIT_CSS))
|
|
6297
6502
|
return;
|
|
6298
6503
|
obj.el.classList.add(HEIGHT_LIMIT_CSS);
|
|
6299
|
-
obj.el.style.height = `${obj.
|
|
6504
|
+
obj.el.style.height = `${obj.max}px`;
|
|
6300
6505
|
obj.el.style.overflow = "hidden";
|
|
6301
6506
|
const $expandBtn = createElement(
|
|
6302
6507
|
`<div class="atk-height-limit-btn">${t("readMore")}</span>`
|
|
@@ -6304,8 +6509,8 @@ function applyHeightLimit(obj) {
|
|
|
6304
6509
|
$expandBtn.onclick = (e) => {
|
|
6305
6510
|
e.stopPropagation();
|
|
6306
6511
|
disposeHeightLimit(obj.el);
|
|
6307
|
-
if (obj.
|
|
6308
|
-
obj.
|
|
6512
|
+
if (obj.afterExpandBtnClick)
|
|
6513
|
+
obj.afterExpandBtnClick(e);
|
|
6309
6514
|
};
|
|
6310
6515
|
obj.el.append($expandBtn);
|
|
6311
6516
|
}
|
|
@@ -6320,16 +6525,17 @@ function disposeHeightLimit($el) {
|
|
|
6320
6525
|
e.remove();
|
|
6321
6526
|
});
|
|
6322
6527
|
$el.style.height = "";
|
|
6528
|
+
$el.style.maxHeight = "";
|
|
6323
6529
|
$el.style.overflow = "";
|
|
6324
6530
|
}
|
|
6325
6531
|
const HEIGHT_LIMIT_SCROLL_CSS = "atk-height-limit-scroll";
|
|
6326
|
-
function applyScrollableHeightLimit(
|
|
6327
|
-
if (!
|
|
6532
|
+
function applyScrollableHeightLimit(opt) {
|
|
6533
|
+
if (!opt.el)
|
|
6328
6534
|
return;
|
|
6329
|
-
if (
|
|
6535
|
+
if (opt.el.classList.contains(HEIGHT_LIMIT_SCROLL_CSS))
|
|
6330
6536
|
return;
|
|
6331
|
-
|
|
6332
|
-
|
|
6537
|
+
opt.el.classList.add(HEIGHT_LIMIT_SCROLL_CSS);
|
|
6538
|
+
opt.el.style.height = `${opt.max}px`;
|
|
6333
6539
|
}
|
|
6334
6540
|
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';
|
|
6335
6541
|
function renderAvatar(r) {
|
|
@@ -6793,7 +6999,7 @@ class Render {
|
|
|
6793
6999
|
const childrenMaxH = conf.children;
|
|
6794
7000
|
check(
|
|
6795
7001
|
{
|
|
6796
|
-
|
|
7002
|
+
afterExpandBtnClick: () => {
|
|
6797
7003
|
const children = this.comment.getChildren();
|
|
6798
7004
|
if (children.length === 1)
|
|
6799
7005
|
disposeHeightLimit(children[0].getRender().$content);
|
|
@@ -6802,10 +7008,10 @@ class Render {
|
|
|
6802
7008
|
},
|
|
6803
7009
|
[
|
|
6804
7010
|
// 评论内容限高
|
|
6805
|
-
{ el: this.$content, max: contentMaxH,
|
|
6806
|
-
{ el: this.$replyTo, max: contentMaxH,
|
|
7011
|
+
{ el: this.$content, max: contentMaxH, imgCheck: true },
|
|
7012
|
+
{ el: this.$replyTo, max: contentMaxH, imgCheck: true },
|
|
6807
7013
|
// 子评论区域限高(仅嵌套模式)
|
|
6808
|
-
{ el: this.$childrenWrap, max: childrenMaxH,
|
|
7014
|
+
{ el: this.$childrenWrap, max: childrenMaxH, imgCheck: false }
|
|
6809
7015
|
]
|
|
6810
7016
|
);
|
|
6811
7017
|
}
|
|
@@ -6894,7 +7100,7 @@ class CommentActions {
|
|
|
6894
7100
|
(_b = this.comment.getRender().voteBtnDown) == null ? void 0 : _b.updateText();
|
|
6895
7101
|
}).catch((err) => {
|
|
6896
7102
|
actionBtn == null ? void 0 : actionBtn.setError(t("voteFail"));
|
|
6897
|
-
console.
|
|
7103
|
+
console.error(err);
|
|
6898
7104
|
});
|
|
6899
7105
|
}
|
|
6900
7106
|
/** 管理员 - 评论状态修改 */
|
|
@@ -7078,7 +7284,7 @@ class CommentNode {
|
|
|
7078
7284
|
return getGravatarURL({
|
|
7079
7285
|
mirror: this.opts.gravatar.mirror,
|
|
7080
7286
|
params: this.opts.gravatar.params,
|
|
7081
|
-
|
|
7287
|
+
emailHash: this.data.email_encrypted
|
|
7082
7288
|
});
|
|
7083
7289
|
}
|
|
7084
7290
|
/** 获取评论 markdown 解析后的内容 */
|
|
@@ -7773,7 +7979,7 @@ const services = {
|
|
|
7773
7979
|
}
|
|
7774
7980
|
};
|
|
7775
7981
|
const PvCountWidget = (ctx) => {
|
|
7776
|
-
ctx.watchConf(["site", "pageKey", "pageTitle", "countEl", "pvEl"], (conf) => {
|
|
7982
|
+
ctx.watchConf(["site", "pageKey", "pageTitle", "countEl", "pvEl", "statPageKeyAttr"], (conf) => {
|
|
7777
7983
|
initCountWidget({
|
|
7778
7984
|
getApi: () => ctx.getApi(),
|
|
7779
7985
|
siteName: conf.site,
|
|
@@ -7781,78 +7987,85 @@ const PvCountWidget = (ctx) => {
|
|
|
7781
7987
|
pageTitle: conf.pageTitle,
|
|
7782
7988
|
countEl: conf.countEl,
|
|
7783
7989
|
pvEl: conf.pvEl,
|
|
7990
|
+
pageKeyAttr: conf.statPageKeyAttr,
|
|
7784
7991
|
pvAdd: typeof ctx.conf.pvAdd === "boolean" ? ctx.conf.pvAdd : true
|
|
7785
7992
|
});
|
|
7786
7993
|
});
|
|
7787
7994
|
};
|
|
7788
7995
|
function initCountWidget(opt) {
|
|
7789
7996
|
return __async(this, null, function* () {
|
|
7790
|
-
|
|
7791
|
-
|
|
7792
|
-
|
|
7793
|
-
|
|
7794
|
-
|
|
7795
|
-
|
|
7796
|
-
|
|
7797
|
-
|
|
7798
|
-
|
|
7799
|
-
|
|
7800
|
-
|
|
7801
|
-
|
|
7802
|
-
|
|
7803
|
-
|
|
7804
|
-
|
|
7805
|
-
|
|
7806
|
-
|
|
7807
|
-
|
|
7997
|
+
yield loadCommentCount(opt);
|
|
7998
|
+
const cacheData = yield incrementPvCount(opt);
|
|
7999
|
+
yield loadPvCount(opt, cacheData);
|
|
8000
|
+
});
|
|
8001
|
+
}
|
|
8002
|
+
function incrementPvCount(opt) {
|
|
8003
|
+
return __async(this, null, function* () {
|
|
8004
|
+
if (!opt.pvAdd || !opt.pageKey)
|
|
8005
|
+
return void 0;
|
|
8006
|
+
const pvCount = (yield opt.getApi().pages.logPv({
|
|
8007
|
+
page_key: opt.pageKey,
|
|
8008
|
+
page_title: opt.pageTitle,
|
|
8009
|
+
site_name: opt.siteName
|
|
8010
|
+
})).data.pv;
|
|
8011
|
+
return {
|
|
8012
|
+
[opt.pageKey]: pvCount
|
|
8013
|
+
};
|
|
8014
|
+
});
|
|
8015
|
+
}
|
|
8016
|
+
function loadCommentCount(opt) {
|
|
8017
|
+
return __async(this, null, function* () {
|
|
8018
|
+
yield loadStatCount({ opt, query: "page_comment", containers: [opt.countEl, "#ArtalkCount"] });
|
|
8019
|
+
});
|
|
8020
|
+
}
|
|
8021
|
+
function loadPvCount(opt, cache) {
|
|
8022
|
+
return __async(this, null, function* () {
|
|
8023
|
+
yield loadStatCount({ opt, query: "page_pv", containers: [opt.pvEl, "#ArtalkPv"], cache });
|
|
7808
8024
|
});
|
|
7809
8025
|
}
|
|
7810
|
-
function
|
|
8026
|
+
function loadStatCount(args) {
|
|
7811
8027
|
return __async(this, null, function* () {
|
|
7812
|
-
|
|
7813
|
-
let
|
|
7814
|
-
|
|
7815
|
-
|
|
8028
|
+
const { opt } = args;
|
|
8029
|
+
let cache = args.cache || {};
|
|
8030
|
+
const els = retrieveElements(args.containers);
|
|
8031
|
+
const pageKeys = getPageKeys(els, opt.pageKeyAttr, opt.pageKey, cache);
|
|
8032
|
+
if (pageKeys.length > 0) {
|
|
7816
8033
|
const res = (yield opt.getApi().stats.getStats(args.query, {
|
|
7817
|
-
page_keys:
|
|
8034
|
+
page_keys: pageKeys.join(","),
|
|
7818
8035
|
site_name: opt.siteName
|
|
7819
8036
|
})).data.data;
|
|
7820
|
-
|
|
8037
|
+
cache = __spreadValues(__spreadValues({}, cache), res);
|
|
7821
8038
|
}
|
|
7822
|
-
|
|
7823
|
-
applyCountData(args.numEl, data, defaultCount);
|
|
8039
|
+
updateElementsText(els, cache, opt.pageKey);
|
|
7824
8040
|
});
|
|
7825
8041
|
}
|
|
7826
|
-
function
|
|
7827
|
-
|
|
7828
|
-
|
|
7829
|
-
|
|
7830
|
-
el.innerHTML = `${count}`;
|
|
8042
|
+
function retrieveElements(containers) {
|
|
8043
|
+
const els = /* @__PURE__ */ new Set();
|
|
8044
|
+
new Set(containers).forEach((selector) => {
|
|
8045
|
+
document.querySelectorAll(selector).forEach((el) => els.add(el));
|
|
7831
8046
|
});
|
|
8047
|
+
return els;
|
|
7832
8048
|
}
|
|
7833
|
-
function
|
|
7834
|
-
const
|
|
7835
|
-
|
|
7836
|
-
|
|
7837
|
-
|
|
7838
|
-
|
|
7839
|
-
|
|
7840
|
-
|
|
7841
|
-
|
|
7842
|
-
|
|
7843
|
-
const $openSidebar = createElement(
|
|
7844
|
-
`<span atk-only-admin-show> | <span style="cursor:pointer;">${t("openName", { name: t("ctrlCenter") })}</span></span>`
|
|
7845
|
-
);
|
|
7846
|
-
errEl.appendChild($openSidebar);
|
|
7847
|
-
$openSidebar.onclick = () => opts.onOpenSidebar && opts.onOpenSidebar();
|
|
7848
|
-
}
|
|
7849
|
-
setError(opts.$err, errEl);
|
|
8049
|
+
function getPageKeys(els, pageKeyAttr, pageKey, cache) {
|
|
8050
|
+
const pageKeys = Array.from(els).map((el) => el.getAttribute(pageKeyAttr) || pageKey).filter((key) => key && typeof cache[key] !== "number");
|
|
8051
|
+
return [...new Set(pageKeys)];
|
|
8052
|
+
}
|
|
8053
|
+
function updateElementsText(els, data, defaultPageKey) {
|
|
8054
|
+
els.forEach((el) => {
|
|
8055
|
+
const pageKey = el.getAttribute("data-page-key");
|
|
8056
|
+
const count = pageKey && data[pageKey] || defaultPageKey && data[defaultPageKey] || 0;
|
|
8057
|
+
el.innerText = `${Number(count)}`;
|
|
8058
|
+
});
|
|
7850
8059
|
}
|
|
7851
8060
|
const Markdown = (ctx) => {
|
|
7852
|
-
|
|
7853
|
-
|
|
7854
|
-
|
|
7855
|
-
|
|
8061
|
+
ctx.watchConf(["imgLazyLoad", "markedOptions"], (conf) => {
|
|
8062
|
+
initMarked({
|
|
8063
|
+
markedOptions: ctx.getConf().markedOptions,
|
|
8064
|
+
imgLazyLoad: ctx.getConf().imgLazyLoad
|
|
8065
|
+
});
|
|
8066
|
+
});
|
|
8067
|
+
ctx.watchConf(["markedReplacers"], (conf) => {
|
|
8068
|
+
conf.markedReplacers && setReplacers(conf.markedReplacers);
|
|
7856
8069
|
});
|
|
7857
8070
|
};
|
|
7858
8071
|
const LocalStorageKey = "ArtalkContent";
|
|
@@ -9089,7 +9302,7 @@ const GotoFocus = (ctx) => {
|
|
|
9089
9302
|
comment.focus();
|
|
9090
9303
|
}));
|
|
9091
9304
|
};
|
|
9092
|
-
const version = "2.8.
|
|
9305
|
+
const version = "2.8.7";
|
|
9093
9306
|
const Copyright = (ctx) => {
|
|
9094
9307
|
ctx.on("mounted", () => {
|
|
9095
9308
|
const list2 = ctx.get("list");
|
|
@@ -9194,8 +9407,7 @@ function renderDropdown(conf) {
|
|
|
9194
9407
|
};
|
|
9195
9408
|
const $dropdown = createElement(`<ul class="atk-dropdown atk-fade-in"></ul>`);
|
|
9196
9409
|
dropdownList.forEach((item, i) => {
|
|
9197
|
-
const name = item
|
|
9198
|
-
const action = item[1];
|
|
9410
|
+
const [name, action] = item;
|
|
9199
9411
|
const $item = createElement(`<li class="atk-dropdown-item"><span></span></li>`);
|
|
9200
9412
|
const $link = $item.querySelector("span");
|
|
9201
9413
|
$link.innerText = name;
|
|
@@ -9230,6 +9442,24 @@ const TimeTicking = (ctx) => {
|
|
|
9230
9442
|
timer && window.clearInterval(timer);
|
|
9231
9443
|
});
|
|
9232
9444
|
};
|
|
9445
|
+
function showErrorDialog(opts) {
|
|
9446
|
+
const errEl = createElement(`<span><span class="error-message"></span><br/><br/></span>`);
|
|
9447
|
+
errEl.querySelector(".error-message").innerText = `${t("listLoadFailMsg")}
|
|
9448
|
+
${opts.errMsg}`;
|
|
9449
|
+
if (opts.retryFn) {
|
|
9450
|
+
const $retryBtn = createElement(`<span style="cursor:pointer;">${t("listRetry")}</span>`);
|
|
9451
|
+
$retryBtn.onclick = () => opts.retryFn && opts.retryFn();
|
|
9452
|
+
errEl.appendChild($retryBtn);
|
|
9453
|
+
}
|
|
9454
|
+
if (opts.onOpenSidebar) {
|
|
9455
|
+
const $openSidebar = createElement(
|
|
9456
|
+
`<span atk-only-admin-show> | <span style="cursor:pointer;">${t("openName", { name: t("ctrlCenter") })}</span></span>`
|
|
9457
|
+
);
|
|
9458
|
+
errEl.appendChild($openSidebar);
|
|
9459
|
+
$openSidebar.onclick = () => opts.onOpenSidebar && opts.onOpenSidebar();
|
|
9460
|
+
}
|
|
9461
|
+
setError(opts.$err, errEl);
|
|
9462
|
+
}
|
|
9233
9463
|
const ErrorDialog = (ctx) => {
|
|
9234
9464
|
ctx.on("list-fetch", () => {
|
|
9235
9465
|
const list2 = ctx.get("list");
|
|
@@ -9494,16 +9724,16 @@ const DefaultPlugins = [
|
|
|
9494
9724
|
VersionCheck,
|
|
9495
9725
|
DarkMode
|
|
9496
9726
|
];
|
|
9497
|
-
const GlobalPlugins = [...DefaultPlugins];
|
|
9727
|
+
const GlobalPlugins = /* @__PURE__ */ new Set([...DefaultPlugins]);
|
|
9498
9728
|
function load(ctx) {
|
|
9499
9729
|
return __async(this, null, function* () {
|
|
9500
9730
|
var _a;
|
|
9501
|
-
const loadedPlugins =
|
|
9731
|
+
const loadedPlugins = /* @__PURE__ */ new Set();
|
|
9502
9732
|
const loadPlugins = (plugins) => {
|
|
9503
9733
|
plugins.forEach((plugin) => {
|
|
9504
|
-
if (typeof plugin === "function" && !loadedPlugins.
|
|
9734
|
+
if (typeof plugin === "function" && !loadedPlugins.has(plugin)) {
|
|
9505
9735
|
plugin(ctx);
|
|
9506
|
-
loadedPlugins.
|
|
9736
|
+
loadedPlugins.add(plugin);
|
|
9507
9737
|
}
|
|
9508
9738
|
});
|
|
9509
9739
|
};
|
|
@@ -9539,8 +9769,9 @@ function load(ctx) {
|
|
|
9539
9769
|
}
|
|
9540
9770
|
function loadNetworkPlugins(scripts, apiBase) {
|
|
9541
9771
|
return __async(this, null, function* () {
|
|
9772
|
+
const networkPlugins = /* @__PURE__ */ new Set();
|
|
9542
9773
|
if (!scripts || !Array.isArray(scripts))
|
|
9543
|
-
return
|
|
9774
|
+
return networkPlugins;
|
|
9544
9775
|
const tasks = [];
|
|
9545
9776
|
scripts.forEach((url) => {
|
|
9546
9777
|
if (!/^(http|https):\/\//.test(url))
|
|
@@ -9560,7 +9791,11 @@ function loadNetworkPlugins(scripts, apiBase) {
|
|
|
9560
9791
|
);
|
|
9561
9792
|
});
|
|
9562
9793
|
yield Promise.all(tasks);
|
|
9563
|
-
|
|
9794
|
+
Object.values(window.ArtalkPlugins || {}).forEach((plugin) => {
|
|
9795
|
+
if (typeof plugin === "function")
|
|
9796
|
+
networkPlugins.add(plugin);
|
|
9797
|
+
});
|
|
9798
|
+
return networkPlugins;
|
|
9564
9799
|
});
|
|
9565
9800
|
}
|
|
9566
9801
|
function onLoadErr(ctx, err) {
|
|
@@ -9646,9 +9881,7 @@ class Artalk {
|
|
|
9646
9881
|
}
|
|
9647
9882
|
/** Use plugin, the plugin will be used when Artalk.init */
|
|
9648
9883
|
static use(plugin) {
|
|
9649
|
-
|
|
9650
|
-
return;
|
|
9651
|
-
GlobalPlugins.push(plugin);
|
|
9884
|
+
GlobalPlugins.add(plugin);
|
|
9652
9885
|
}
|
|
9653
9886
|
/** Load count widget */
|
|
9654
9887
|
static loadCountWidget(c) {
|
|
@@ -9658,6 +9891,7 @@ class Artalk {
|
|
|
9658
9891
|
siteName: conf.site,
|
|
9659
9892
|
countEl: conf.countEl,
|
|
9660
9893
|
pvEl: conf.pvEl,
|
|
9894
|
+
pageKeyAttr: conf.statPageKeyAttr,
|
|
9661
9895
|
pvAdd: false
|
|
9662
9896
|
});
|
|
9663
9897
|
}
|