artalk 2.1.8 → 2.2.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/LICENSE +165 -0
- package/dist/Artalk.css +1 -1
- package/dist/Artalk.es.js +255 -107
- package/dist/Artalk.iife.js +1 -1
- package/dist/Artalk.js +1 -1
- package/package.json +14 -13
- package/src/api/index.ts +14 -2
- package/src/api/request.ts +1 -0
- package/src/artalk.ts +17 -0
- package/src/components/editor.ts +48 -22
- package/src/components/layer.ts +19 -8
- package/src/components/list-lite.ts +12 -10
- package/src/components/list.ts +5 -2
- package/src/components/sidebar-layer.ts +24 -2
- package/src/context.ts +3 -0
- package/src/defaults.ts +1 -0
- package/src/lib/checker/admin-checker.ts +4 -4
- package/src/lib/checker/captcha-checker.ts +52 -6
- package/src/lib/checker/index.ts +65 -23
- package/src/lib/ui.ts +2 -1
- package/src/lib/utils.ts +56 -35
- package/src/style/comment.less +3 -0
- package/src/style/list.less +4 -1
- package/src/style/main.less +35 -0
- package/tsconfig.json +1 -16
- package/types/artalk-config.d.ts +3 -0
- package/types/event.d.ts +1 -0
- package/types/vite-env.d.ts +0 -1
package/dist/Artalk.es.js
CHANGED
|
@@ -68,6 +68,7 @@ class Context {
|
|
|
68
68
|
__publicField(this, "conf");
|
|
69
69
|
__publicField(this, "user");
|
|
70
70
|
__publicField(this, "eventList", []);
|
|
71
|
+
__publicField(this, "markedInstance");
|
|
71
72
|
this.cid = +new Date();
|
|
72
73
|
this.$root = rootEl;
|
|
73
74
|
this.conf = conf;
|
|
@@ -102,6 +103,7 @@ const defaults$3 = {
|
|
|
102
103
|
vote: true,
|
|
103
104
|
voteDown: false,
|
|
104
105
|
uaBadge: true,
|
|
106
|
+
listSort: true,
|
|
105
107
|
pvEl: "#ArtalkPV",
|
|
106
108
|
flatMode: "auto",
|
|
107
109
|
maxNesting: 3,
|
|
@@ -2655,37 +2657,36 @@ function versionCompare(a, b) {
|
|
|
2655
2657
|
}
|
|
2656
2658
|
return 0;
|
|
2657
2659
|
}
|
|
2658
|
-
|
|
2660
|
+
function initMarked(ctx) {
|
|
2661
|
+
const renderer = new marked$1.Renderer();
|
|
2662
|
+
const linkRenderer = renderer.link;
|
|
2663
|
+
renderer.link = (href, title, text) => {
|
|
2664
|
+
const localLink = href == null ? void 0 : href.startsWith(`${window.location.protocol}//${window.location.hostname}`);
|
|
2665
|
+
const html = linkRenderer.call(renderer, href, title, text);
|
|
2666
|
+
return html.replace(/^<a /, `<a target="_blank" ${!localLink ? `rel="noreferrer noopener nofollow"` : ""} `);
|
|
2667
|
+
};
|
|
2668
|
+
const nMarked = marked$1;
|
|
2669
|
+
marked$1.setOptions({
|
|
2670
|
+
renderer,
|
|
2671
|
+
highlight: (code) => hanabi(code),
|
|
2672
|
+
pedantic: false,
|
|
2673
|
+
gfm: true,
|
|
2674
|
+
breaks: true,
|
|
2675
|
+
smartLists: true,
|
|
2676
|
+
smartypants: true,
|
|
2677
|
+
xhtml: false,
|
|
2678
|
+
sanitize: true,
|
|
2679
|
+
sanitizer: (html) => insane_1(html, __spreadProps(__spreadValues({}, insane_1.defaults), {
|
|
2680
|
+
allowedAttributes: __spreadProps(__spreadValues({}, insane_1.defaults.allowedAttributes), {
|
|
2681
|
+
img: ["src", "atk-emoticon"]
|
|
2682
|
+
})
|
|
2683
|
+
})),
|
|
2684
|
+
silent: true
|
|
2685
|
+
});
|
|
2686
|
+
ctx.markedInstance = nMarked;
|
|
2687
|
+
}
|
|
2659
2688
|
function marked(ctx, src) {
|
|
2660
|
-
|
|
2661
|
-
const renderer = new marked$1.Renderer();
|
|
2662
|
-
const linkRenderer = renderer.link;
|
|
2663
|
-
renderer.link = (href, title, text) => {
|
|
2664
|
-
const localLink = href == null ? void 0 : href.startsWith(`${window.location.protocol}//${window.location.hostname}`);
|
|
2665
|
-
const html = linkRenderer.call(renderer, href, title, text);
|
|
2666
|
-
return html.replace(/^<a /, `<a target="_blank" ${!localLink ? `rel="noreferrer noopener nofollow"` : ""} `);
|
|
2667
|
-
};
|
|
2668
|
-
const nMarked = marked$1;
|
|
2669
|
-
marked$1.setOptions({
|
|
2670
|
-
renderer,
|
|
2671
|
-
highlight: (code) => hanabi(code),
|
|
2672
|
-
pedantic: false,
|
|
2673
|
-
gfm: true,
|
|
2674
|
-
breaks: true,
|
|
2675
|
-
smartLists: true,
|
|
2676
|
-
smartypants: true,
|
|
2677
|
-
xhtml: false,
|
|
2678
|
-
sanitize: true,
|
|
2679
|
-
sanitizer: (html) => insane_1(html, __spreadProps(__spreadValues({}, insane_1.defaults), {
|
|
2680
|
-
allowedAttributes: __spreadProps(__spreadValues({}, insane_1.defaults.allowedAttributes), {
|
|
2681
|
-
img: ["src", "atk-emoticon"]
|
|
2682
|
-
})
|
|
2683
|
-
})),
|
|
2684
|
-
silent: true
|
|
2685
|
-
});
|
|
2686
|
-
markedInstance = nMarked;
|
|
2687
|
-
}
|
|
2688
|
-
return markedInstance.parse(src);
|
|
2689
|
+
return ctx.markedInstance.parse(src);
|
|
2689
2690
|
}
|
|
2690
2691
|
function getCorrectUserAgent() {
|
|
2691
2692
|
return __async(this, null, function* () {
|
|
@@ -2711,7 +2712,19 @@ function getCorrectUserAgent() {
|
|
|
2711
2712
|
return uaRaw;
|
|
2712
2713
|
});
|
|
2713
2714
|
}
|
|
2714
|
-
function
|
|
2715
|
+
function isValidURL(urlRaw) {
|
|
2716
|
+
let url;
|
|
2717
|
+
try {
|
|
2718
|
+
url = new URL(urlRaw);
|
|
2719
|
+
} catch (_) {
|
|
2720
|
+
return false;
|
|
2721
|
+
}
|
|
2722
|
+
return url.protocol === "http:" || url.protocol === "https:";
|
|
2723
|
+
}
|
|
2724
|
+
function getURLBasedOnApi(ctx, path) {
|
|
2725
|
+
return `${ctx.conf.server.replace(/\/api\/?$/, "")}/${path.replace(/^\//, "")}`;
|
|
2726
|
+
}
|
|
2727
|
+
function showLoading(parentElem, conf) {
|
|
2715
2728
|
if (parentElem instanceof Context)
|
|
2716
2729
|
parentElem = parentElem.$root;
|
|
2717
2730
|
let $loading = parentElem.querySelector(".atk-loading");
|
|
@@ -2721,6 +2734,8 @@ function showLoading(parentElem) {
|
|
|
2721
2734
|
<svg viewBox="25 25 50 50"><circle cx="50" cy="50" r="20" fill="none" stroke-width="2" stroke-miterlimit="10"></circle></svg>
|
|
2722
2735
|
</div>
|
|
2723
2736
|
</div>`);
|
|
2737
|
+
if (conf == null ? void 0 : conf.transparentBg)
|
|
2738
|
+
$loading.style.background = "transparent";
|
|
2724
2739
|
parentElem.appendChild($loading);
|
|
2725
2740
|
}
|
|
2726
2741
|
$loading.style.display = "";
|
|
@@ -2887,11 +2902,7 @@ const _Layer = class extends Component {
|
|
|
2887
2902
|
if (this.maskClickHideEnable)
|
|
2888
2903
|
this.hide();
|
|
2889
2904
|
};
|
|
2890
|
-
this.
|
|
2891
|
-
this.bodyStyleOrgPaddingRight = document.body.style.paddingRight;
|
|
2892
|
-
document.body.style.overflow = "hidden";
|
|
2893
|
-
const bpr = parseInt(window.getComputedStyle(document.body, null).getPropertyValue("padding-right"), 10);
|
|
2894
|
-
document.body.style.paddingRight = `${getScrollBarWidth() + bpr || 0}px`;
|
|
2905
|
+
this.pageBodyScrollBarHide();
|
|
2895
2906
|
}
|
|
2896
2907
|
hide() {
|
|
2897
2908
|
if (this.afterHide)
|
|
@@ -2900,8 +2911,7 @@ const _Layer = class extends Component {
|
|
|
2900
2911
|
this.$el.style.display = "none";
|
|
2901
2912
|
this.newActionTimer(() => {
|
|
2902
2913
|
this.$wrap.style.display = "none";
|
|
2903
|
-
|
|
2904
|
-
document.body.style.paddingRight = this.bodyStyleOrgPaddingRight;
|
|
2914
|
+
this.pageBodyScrollBarShow();
|
|
2905
2915
|
this.checkCleanLayer();
|
|
2906
2916
|
}, 450);
|
|
2907
2917
|
this.newActionTimer(() => {
|
|
@@ -2912,6 +2922,17 @@ const _Layer = class extends Component {
|
|
|
2912
2922
|
setMaskClickHide(enable) {
|
|
2913
2923
|
this.maskClickHideEnable = enable;
|
|
2914
2924
|
}
|
|
2925
|
+
pageBodyScrollBarHide() {
|
|
2926
|
+
this.bodyStyleOrgOverflow = document.body.style.overflow;
|
|
2927
|
+
this.bodyStyleOrgPaddingRight = document.body.style.paddingRight;
|
|
2928
|
+
document.body.style.overflow = "hidden";
|
|
2929
|
+
const bpr = parseInt(window.getComputedStyle(document.body, null).getPropertyValue("padding-right"), 10);
|
|
2930
|
+
document.body.style.paddingRight = `${getScrollBarWidth() + bpr || 0}px`;
|
|
2931
|
+
}
|
|
2932
|
+
pageBodyScrollBarShow() {
|
|
2933
|
+
document.body.style.overflow = this.bodyStyleOrgOverflow;
|
|
2934
|
+
document.body.style.paddingRight = this.bodyStyleOrgPaddingRight;
|
|
2935
|
+
}
|
|
2915
2936
|
newActionTimer(func, delay) {
|
|
2916
2937
|
const act = () => {
|
|
2917
2938
|
func();
|
|
@@ -2929,6 +2950,7 @@ const _Layer = class extends Component {
|
|
|
2929
2950
|
disposeNow() {
|
|
2930
2951
|
document.body.style.overflow = "";
|
|
2931
2952
|
this.$el.remove();
|
|
2953
|
+
this.pageBodyScrollBarShow();
|
|
2932
2954
|
this.checkCleanLayer();
|
|
2933
2955
|
}
|
|
2934
2956
|
dispose() {
|
|
@@ -3019,6 +3041,7 @@ function Fetch(ctx, input, init, timeout) {
|
|
|
3019
3041
|
json = yield new Promise((resolve, reject) => {
|
|
3020
3042
|
ctx.trigger("checker-captcha", {
|
|
3021
3043
|
imgData: json.data.img_data,
|
|
3044
|
+
iframe: json.data.iframe,
|
|
3022
3045
|
onSuccess: () => {
|
|
3023
3046
|
recall(resolve, reject);
|
|
3024
3047
|
},
|
|
@@ -3061,14 +3084,6 @@ function POST(ctx, url, data) {
|
|
|
3061
3084
|
return json.data || {};
|
|
3062
3085
|
});
|
|
3063
3086
|
}
|
|
3064
|
-
function GET(ctx, url, data) {
|
|
3065
|
-
return __async(this, null, function* () {
|
|
3066
|
-
const json = yield Fetch(ctx, url + (data ? `?${new URLSearchParams(data)}` : ""), {
|
|
3067
|
-
method: "GET"
|
|
3068
|
-
});
|
|
3069
|
-
return json.data || {};
|
|
3070
|
-
});
|
|
3071
|
-
}
|
|
3072
3087
|
function ToFormData(object) {
|
|
3073
3088
|
const formData = new FormData();
|
|
3074
3089
|
Object.keys(object).forEach((key) => formData.append(key, String(object[key])));
|
|
@@ -3183,6 +3198,12 @@ class Api {
|
|
|
3183
3198
|
}
|
|
3184
3199
|
};
|
|
3185
3200
|
}
|
|
3201
|
+
loginStatus() {
|
|
3202
|
+
return __async(this, null, function* () {
|
|
3203
|
+
const data = yield POST(this.ctx, `${this.baseURL}/login-status`);
|
|
3204
|
+
return data || { is_login: false };
|
|
3205
|
+
});
|
|
3206
|
+
}
|
|
3186
3207
|
pageGet(siteName, offset, limit) {
|
|
3187
3208
|
return __async(this, null, function* () {
|
|
3188
3209
|
const params = {
|
|
@@ -3322,23 +3343,74 @@ class Api {
|
|
|
3322
3343
|
}
|
|
3323
3344
|
captchaGet() {
|
|
3324
3345
|
return __async(this, null, function* () {
|
|
3325
|
-
const data = yield
|
|
3346
|
+
const data = yield POST(this.ctx, `${this.baseURL}/captcha/refresh`);
|
|
3326
3347
|
return data.img_data || "";
|
|
3327
3348
|
});
|
|
3328
3349
|
}
|
|
3329
3350
|
captchaCheck(value) {
|
|
3330
3351
|
return __async(this, null, function* () {
|
|
3331
|
-
const data = yield
|
|
3352
|
+
const data = yield POST(this.ctx, `${this.baseURL}/captcha/check`, { value });
|
|
3332
3353
|
return data.img_data || "";
|
|
3333
3354
|
});
|
|
3334
3355
|
}
|
|
3356
|
+
captchaStatus() {
|
|
3357
|
+
return __async(this, null, function* () {
|
|
3358
|
+
const data = yield POST(this.ctx, `${this.baseURL}/captcha/status`);
|
|
3359
|
+
return data || { is_pass: false };
|
|
3360
|
+
});
|
|
3361
|
+
}
|
|
3335
3362
|
}
|
|
3336
3363
|
const CaptchaChecker = {
|
|
3337
|
-
request(that, inputVal) {
|
|
3364
|
+
request(that, ctx, inputVal) {
|
|
3338
3365
|
return new Api(that.ctx).captchaCheck(inputVal);
|
|
3339
3366
|
},
|
|
3340
|
-
body(that) {
|
|
3341
|
-
|
|
3367
|
+
body(that, ctx) {
|
|
3368
|
+
if (that.captchaConf.iframe) {
|
|
3369
|
+
const $iframeWrap = createElement(`<div class="atk-checker-iframe-wrap"></div>`);
|
|
3370
|
+
const $iframe = createElement(`<iframe class="atk-fade-in"></iframe>`);
|
|
3371
|
+
$iframe.style.display = "none";
|
|
3372
|
+
showLoading($iframeWrap, { transparentBg: true });
|
|
3373
|
+
$iframe.src = `${that.ctx.conf.server}/captcha/get`;
|
|
3374
|
+
$iframe.onload = () => {
|
|
3375
|
+
$iframe.style.display = "";
|
|
3376
|
+
hideLoading($iframeWrap);
|
|
3377
|
+
};
|
|
3378
|
+
$iframeWrap.append($iframe);
|
|
3379
|
+
const $closeBtn = createElement(`<div class="atk-close-btn"><i class="atk-icon atk-icon-close"></i></div>`);
|
|
3380
|
+
$iframeWrap.append($closeBtn);
|
|
3381
|
+
ctx.hideInteractInput();
|
|
3382
|
+
let stop = false;
|
|
3383
|
+
const sleep = (ms) => new Promise((resolve) => {
|
|
3384
|
+
window.setTimeout(() => {
|
|
3385
|
+
resolve(null);
|
|
3386
|
+
}, ms);
|
|
3387
|
+
});
|
|
3388
|
+
(function queryStatus() {
|
|
3389
|
+
return __async(this, null, function* () {
|
|
3390
|
+
yield sleep(1e3);
|
|
3391
|
+
if (stop)
|
|
3392
|
+
return;
|
|
3393
|
+
let isPass = false;
|
|
3394
|
+
try {
|
|
3395
|
+
const resp = yield new Api(that.ctx).captchaStatus();
|
|
3396
|
+
isPass = resp.is_pass;
|
|
3397
|
+
} catch (e) {
|
|
3398
|
+
isPass = false;
|
|
3399
|
+
}
|
|
3400
|
+
if (isPass) {
|
|
3401
|
+
ctx.triggerSuccess();
|
|
3402
|
+
} else {
|
|
3403
|
+
queryStatus();
|
|
3404
|
+
}
|
|
3405
|
+
});
|
|
3406
|
+
})();
|
|
3407
|
+
$closeBtn.onclick = () => {
|
|
3408
|
+
stop = true;
|
|
3409
|
+
ctx.cancel();
|
|
3410
|
+
};
|
|
3411
|
+
return $iframeWrap;
|
|
3412
|
+
}
|
|
3413
|
+
const elem = createElement(`<span><img class="atk-captcha-img" src="${that.captchaConf.imgData || ""}" alt="\u9A8C\u8BC1\u7801">\u6572\u5165\u9A8C\u8BC1\u7801\u7EE7\u7EED\uFF1A</span>`);
|
|
3342
3414
|
elem.querySelector(".atk-captcha-img").onclick = () => {
|
|
3343
3415
|
const imgEl = elem.querySelector(".atk-captcha-img");
|
|
3344
3416
|
new Api(that.ctx).captchaGet().then((imgData) => {
|
|
@@ -3349,16 +3421,16 @@ const CaptchaChecker = {
|
|
|
3349
3421
|
};
|
|
3350
3422
|
return elem;
|
|
3351
3423
|
},
|
|
3352
|
-
onSuccess(that, data, inputVal, formEl) {
|
|
3353
|
-
that.
|
|
3424
|
+
onSuccess(that, ctx, data, inputVal, formEl) {
|
|
3425
|
+
that.captchaConf.val = inputVal;
|
|
3354
3426
|
},
|
|
3355
|
-
onError(that, err, inputVal, formEl) {
|
|
3427
|
+
onError(that, ctx, err, inputVal, formEl) {
|
|
3356
3428
|
formEl.querySelector(".atk-captcha-img").click();
|
|
3357
3429
|
}
|
|
3358
3430
|
};
|
|
3359
3431
|
const AdminChecker = {
|
|
3360
3432
|
inputType: "password",
|
|
3361
|
-
request(that, inputVal) {
|
|
3433
|
+
request(that, ctx, inputVal) {
|
|
3362
3434
|
const data = {
|
|
3363
3435
|
name: that.ctx.user.data.nick,
|
|
3364
3436
|
email: that.ctx.user.data.email,
|
|
@@ -3366,33 +3438,33 @@ const AdminChecker = {
|
|
|
3366
3438
|
};
|
|
3367
3439
|
return new Api(that.ctx).login(data.name, data.email, data.password);
|
|
3368
3440
|
},
|
|
3369
|
-
body() {
|
|
3441
|
+
body(that, ctx) {
|
|
3370
3442
|
return createElement("<span>\u6572\u5165\u5BC6\u7801\u6765\u9A8C\u8BC1\u7BA1\u7406\u5458\u8EAB\u4EFD\uFF1A</span>");
|
|
3371
3443
|
},
|
|
3372
|
-
onSuccess(that, userToken, inputVal, formEl) {
|
|
3444
|
+
onSuccess(that, ctx, userToken, inputVal, formEl) {
|
|
3373
3445
|
that.ctx.user.data.isAdmin = true;
|
|
3374
3446
|
that.ctx.user.data.token = userToken;
|
|
3375
3447
|
that.ctx.user.save();
|
|
3376
3448
|
that.ctx.trigger("user-changed", that.ctx.user.data);
|
|
3377
3449
|
that.ctx.trigger("list-reload");
|
|
3378
3450
|
},
|
|
3379
|
-
onError(that, err, inputVal, formEl) {
|
|
3451
|
+
onError(that, ctx, err, inputVal, formEl) {
|
|
3380
3452
|
}
|
|
3381
3453
|
};
|
|
3382
3454
|
class CheckerLauncher {
|
|
3383
3455
|
constructor(ctx) {
|
|
3384
3456
|
__publicField(this, "ctx");
|
|
3385
3457
|
__publicField(this, "launched", []);
|
|
3386
|
-
__publicField(this, "
|
|
3387
|
-
__publicField(this, "submitCaptchaImgData");
|
|
3458
|
+
__publicField(this, "captchaConf", {});
|
|
3388
3459
|
this.ctx = ctx;
|
|
3389
3460
|
this.initEventBind();
|
|
3390
3461
|
}
|
|
3391
3462
|
initEventBind() {
|
|
3392
3463
|
this.ctx.on("checker-captcha", (conf) => {
|
|
3393
|
-
if (conf.imgData)
|
|
3394
|
-
this.
|
|
3395
|
-
|
|
3464
|
+
if (conf.imgData)
|
|
3465
|
+
this.captchaConf.imgData = conf.imgData;
|
|
3466
|
+
if (conf.iframe)
|
|
3467
|
+
this.captchaConf.iframe = conf.iframe;
|
|
3396
3468
|
this.fire(CaptchaChecker, conf);
|
|
3397
3469
|
});
|
|
3398
3470
|
this.ctx.on("checker-admin", (conf) => {
|
|
@@ -3406,12 +3478,31 @@ class CheckerLauncher {
|
|
|
3406
3478
|
const layer = new Layer(this.ctx, `checker-${new Date().getTime()}`);
|
|
3407
3479
|
layer.setMaskClickHide(false);
|
|
3408
3480
|
layer.show();
|
|
3481
|
+
let hideInteractInput = false;
|
|
3482
|
+
const checkerCtx = {
|
|
3483
|
+
getLayer: () => layer,
|
|
3484
|
+
hideInteractInput: () => {
|
|
3485
|
+
hideInteractInput = true;
|
|
3486
|
+
},
|
|
3487
|
+
triggerSuccess: () => {
|
|
3488
|
+
this.close(checker, layer);
|
|
3489
|
+
if (checker.onSuccess)
|
|
3490
|
+
checker.onSuccess(this, checkerCtx, "", "", formEl);
|
|
3491
|
+
if (payload.onSuccess)
|
|
3492
|
+
payload.onSuccess("", dialog.$el);
|
|
3493
|
+
},
|
|
3494
|
+
cancel: () => {
|
|
3495
|
+
this.close(checker, layer);
|
|
3496
|
+
if (payload.onCancel)
|
|
3497
|
+
payload.onCancel();
|
|
3498
|
+
}
|
|
3499
|
+
};
|
|
3409
3500
|
const formEl = createElement();
|
|
3410
|
-
formEl.appendChild(checker.body(this));
|
|
3411
|
-
const input = createElement(`<input id="check" type="${checker.inputType || "text"}" autocomplete="off" required placeholder="">`);
|
|
3412
|
-
formEl.appendChild(input);
|
|
3413
|
-
setTimeout(() => input.focus(), 80);
|
|
3414
|
-
input.onkeyup = (evt) => {
|
|
3501
|
+
formEl.appendChild(checker.body(this, checkerCtx));
|
|
3502
|
+
const $input = createElement(`<input id="check" type="${checker.inputType || "text"}" autocomplete="off" required placeholder="">`);
|
|
3503
|
+
formEl.appendChild($input);
|
|
3504
|
+
setTimeout(() => $input.focus(), 80);
|
|
3505
|
+
$input.onkeyup = (evt) => {
|
|
3415
3506
|
if (evt.key === "Enter" || evt.keyCode === 13) {
|
|
3416
3507
|
evt.preventDefault();
|
|
3417
3508
|
layer.getEl().querySelector('button[data-action="confirm"]').click();
|
|
@@ -3420,7 +3511,7 @@ class CheckerLauncher {
|
|
|
3420
3511
|
let btnTextOrg;
|
|
3421
3512
|
const dialog = new Dialog(formEl);
|
|
3422
3513
|
dialog.setYes((btnEl) => {
|
|
3423
|
-
const inputVal = input.value.trim();
|
|
3514
|
+
const inputVal = $input.value.trim();
|
|
3424
3515
|
if (!btnTextOrg)
|
|
3425
3516
|
btnTextOrg = btnEl.innerText;
|
|
3426
3517
|
const btnTextSet = (btnText) => {
|
|
@@ -3432,18 +3523,18 @@ class CheckerLauncher {
|
|
|
3432
3523
|
btnEl.classList.remove("error");
|
|
3433
3524
|
};
|
|
3434
3525
|
btnEl.innerText = "\u52A0\u8F7D\u4E2D...";
|
|
3435
|
-
checker.request(this, inputVal).then((data) => {
|
|
3436
|
-
this.
|
|
3526
|
+
checker.request(this, checkerCtx, inputVal).then((data) => {
|
|
3527
|
+
this.close(checker, layer);
|
|
3437
3528
|
if (checker.onSuccess)
|
|
3438
|
-
checker.onSuccess(this, data, inputVal, formEl);
|
|
3529
|
+
checker.onSuccess(this, checkerCtx, data, inputVal, formEl);
|
|
3439
3530
|
if (payload.onSuccess)
|
|
3440
3531
|
payload.onSuccess(inputVal, dialog.$el);
|
|
3441
3532
|
}).catch((err) => {
|
|
3442
3533
|
btnTextSet(String(err.msg || String(err)));
|
|
3443
3534
|
if (checker.onError)
|
|
3444
|
-
checker.onError(this, err, inputVal, formEl);
|
|
3535
|
+
checker.onError(this, checkerCtx, err, inputVal, formEl);
|
|
3445
3536
|
const tf = setTimeout(() => btnTextRestore(), 3e3);
|
|
3446
|
-
input.onfocus = () => {
|
|
3537
|
+
$input.onfocus = () => {
|
|
3447
3538
|
btnTextRestore();
|
|
3448
3539
|
clearTimeout(tf);
|
|
3449
3540
|
};
|
|
@@ -3451,16 +3542,20 @@ class CheckerLauncher {
|
|
|
3451
3542
|
return false;
|
|
3452
3543
|
});
|
|
3453
3544
|
dialog.setNo(() => {
|
|
3454
|
-
this.
|
|
3545
|
+
this.close(checker, layer);
|
|
3455
3546
|
if (payload.onCancel)
|
|
3456
3547
|
payload.onCancel();
|
|
3457
3548
|
return false;
|
|
3458
3549
|
});
|
|
3550
|
+
if (hideInteractInput) {
|
|
3551
|
+
$input.style.display = "none";
|
|
3552
|
+
dialog.$el.querySelector(".atk-layer-dialog-actions").style.display = "none";
|
|
3553
|
+
}
|
|
3459
3554
|
layer.getEl().append(dialog.$el);
|
|
3460
3555
|
if (payload.onMount)
|
|
3461
3556
|
payload.onMount(dialog.$el);
|
|
3462
3557
|
}
|
|
3463
|
-
|
|
3558
|
+
close(checker, layer) {
|
|
3464
3559
|
layer.disposeNow();
|
|
3465
3560
|
this.launched = this.launched.filter((c) => c !== checker);
|
|
3466
3561
|
}
|
|
@@ -3913,14 +4008,14 @@ class Editor extends Component {
|
|
|
3913
4008
|
btnElem.classList.add("active");
|
|
3914
4009
|
});
|
|
3915
4010
|
});
|
|
3916
|
-
this.
|
|
4011
|
+
this.initImgUpload();
|
|
3917
4012
|
}
|
|
3918
4013
|
closePlug() {
|
|
3919
4014
|
this.$plugWrap.innerHTML = "";
|
|
3920
4015
|
this.$plugWrap.style.display = "none";
|
|
3921
4016
|
this.openedPlugName = null;
|
|
3922
4017
|
}
|
|
3923
|
-
|
|
4018
|
+
initImgUpload() {
|
|
3924
4019
|
this.$imgUploadBtn = createElement(`<span class="atk-plug-btn">\u56FE\u7247</span>`);
|
|
3925
4020
|
this.$plugBtnWrap.querySelector('[data-plug-name="preview"]').before(this.$imgUploadBtn);
|
|
3926
4021
|
this.$imgUploadBtn.onclick = () => {
|
|
@@ -3937,18 +4032,32 @@ class Editor extends Component {
|
|
|
3937
4032
|
};
|
|
3938
4033
|
$input.click();
|
|
3939
4034
|
};
|
|
4035
|
+
const uploadFromFileList = (files) => {
|
|
4036
|
+
if (!files)
|
|
4037
|
+
return;
|
|
4038
|
+
for (let i = 0; i < files.length; i++) {
|
|
4039
|
+
const file = files[i];
|
|
4040
|
+
this.uploadImg(file);
|
|
4041
|
+
}
|
|
4042
|
+
};
|
|
3940
4043
|
this.$textarea.addEventListener("dragover", (evt) => {
|
|
3941
4044
|
evt.stopPropagation();
|
|
3942
4045
|
evt.preventDefault();
|
|
3943
4046
|
});
|
|
3944
4047
|
this.$textarea.addEventListener("drop", (evt) => {
|
|
3945
4048
|
var _a;
|
|
3946
|
-
|
|
4049
|
+
const files = (_a = evt.dataTransfer) == null ? void 0 : _a.files;
|
|
4050
|
+
if (files == null ? void 0 : files.length) {
|
|
3947
4051
|
evt.preventDefault();
|
|
3948
|
-
|
|
3949
|
-
|
|
3950
|
-
|
|
3951
|
-
|
|
4052
|
+
uploadFromFileList(files);
|
|
4053
|
+
}
|
|
4054
|
+
});
|
|
4055
|
+
this.$textarea.addEventListener("paste", (evt) => {
|
|
4056
|
+
var _a;
|
|
4057
|
+
const files = (_a = evt.clipboardData) == null ? void 0 : _a.files;
|
|
4058
|
+
if (files == null ? void 0 : files.length) {
|
|
4059
|
+
evt.preventDefault();
|
|
4060
|
+
uploadFromFileList(files);
|
|
3952
4061
|
}
|
|
3953
4062
|
});
|
|
3954
4063
|
}
|
|
@@ -3965,8 +4074,14 @@ class Editor extends Component {
|
|
|
3965
4074
|
const fileExt = /[^.]+$/.exec(file.name);
|
|
3966
4075
|
if (!fileExt || !this.allowImgExts.includes(fileExt[0]))
|
|
3967
4076
|
return;
|
|
3968
|
-
|
|
3969
|
-
|
|
4077
|
+
if (!this.ctx.user.checkHasBasicUserInfo()) {
|
|
4078
|
+
this.showNotify("\u586B\u5165\u4F60\u7684\u540D\u5B57\u90AE\u7BB1\u624D\u80FD\u4E0A\u4F20\u54E6", "w");
|
|
4079
|
+
return;
|
|
4080
|
+
}
|
|
4081
|
+
let insertPrefix = "\n";
|
|
4082
|
+
if (this.$textarea.value.trim() === "")
|
|
4083
|
+
insertPrefix = "";
|
|
4084
|
+
const uploadPlaceholderTxt = `${insertPrefix}`;
|
|
3970
4085
|
this.insertContent(uploadPlaceholderTxt);
|
|
3971
4086
|
let resp;
|
|
3972
4087
|
try {
|
|
@@ -3977,15 +4092,12 @@ class Editor extends Component {
|
|
|
3977
4092
|
}
|
|
3978
4093
|
if (!!resp && resp.img_url) {
|
|
3979
4094
|
let imgURL = resp.img_url;
|
|
3980
|
-
if (
|
|
3981
|
-
imgURL =
|
|
3982
|
-
}
|
|
3983
|
-
this.$textarea.value = this.$textarea.value.replace(uploadPlaceholderTxt, `
|
|
3984
|
-
`);
|
|
4095
|
+
if (!isValidURL(imgURL))
|
|
4096
|
+
imgURL = getURLBasedOnApi(this.ctx, imgURL);
|
|
4097
|
+
this.setContent(this.$textarea.value.replace(uploadPlaceholderTxt, `${insertPrefix}`));
|
|
3985
4098
|
} else {
|
|
3986
|
-
this
|
|
4099
|
+
this.setContent(this.$textarea.value.replace(uploadPlaceholderTxt, ""));
|
|
3987
4100
|
}
|
|
3988
|
-
this.saveContent();
|
|
3989
4101
|
});
|
|
3990
4102
|
}
|
|
3991
4103
|
insertContent(val) {
|
|
@@ -4019,7 +4131,7 @@ class Editor extends Component {
|
|
|
4019
4131
|
this.setContent("");
|
|
4020
4132
|
this.cancelReply();
|
|
4021
4133
|
}
|
|
4022
|
-
|
|
4134
|
+
getFinalContent() {
|
|
4023
4135
|
let content = this.getContentOriginal();
|
|
4024
4136
|
if (this.plugList && this.plugList.emoticons) {
|
|
4025
4137
|
const emoticonsPlug2 = this.plugList.emoticons;
|
|
@@ -4031,7 +4143,7 @@ class Editor extends Component {
|
|
|
4031
4143
|
return this.$textarea.value || "";
|
|
4032
4144
|
}
|
|
4033
4145
|
getContentMarked() {
|
|
4034
|
-
return marked(this.ctx, this.
|
|
4146
|
+
return marked(this.ctx, this.getFinalContent());
|
|
4035
4147
|
}
|
|
4036
4148
|
initBottomPart() {
|
|
4037
4149
|
this.initReply();
|
|
@@ -4080,7 +4192,7 @@ class Editor extends Component {
|
|
|
4080
4192
|
}
|
|
4081
4193
|
submit() {
|
|
4082
4194
|
return __async(this, null, function* () {
|
|
4083
|
-
if (this.
|
|
4195
|
+
if (this.getFinalContent().trim() === "") {
|
|
4084
4196
|
this.$textarea.focus();
|
|
4085
4197
|
return;
|
|
4086
4198
|
}
|
|
@@ -4088,7 +4200,7 @@ class Editor extends Component {
|
|
|
4088
4200
|
showLoading(this.$el);
|
|
4089
4201
|
try {
|
|
4090
4202
|
const nComment = yield new Api(this.ctx).add({
|
|
4091
|
-
content: this.
|
|
4203
|
+
content: this.getFinalContent(),
|
|
4092
4204
|
nick: this.user.data.nick,
|
|
4093
4205
|
email: this.user.data.email,
|
|
4094
4206
|
link: this.user.data.link,
|
|
@@ -5163,6 +5275,7 @@ class ReadMoreBtn {
|
|
|
5163
5275
|
this.hide();
|
|
5164
5276
|
}
|
|
5165
5277
|
}
|
|
5278
|
+
const backendMinVersion = "2.1.1";
|
|
5166
5279
|
class ListLite extends Component {
|
|
5167
5280
|
constructor(ctx) {
|
|
5168
5281
|
super(ctx);
|
|
@@ -5244,11 +5357,15 @@ class ListLite extends Component {
|
|
|
5244
5357
|
});
|
|
5245
5358
|
}
|
|
5246
5359
|
onLoad(data, offset) {
|
|
5360
|
+
var _a, _b;
|
|
5247
5361
|
if (this.pageMode === "pagination") {
|
|
5248
5362
|
this.clearAllComments();
|
|
5249
5363
|
}
|
|
5250
5364
|
this.data = data;
|
|
5251
|
-
|
|
5365
|
+
const feMinVersion = ((_a = data.api_version) == null ? void 0 : _a.fe_min_version) || "0.0.0";
|
|
5366
|
+
if (this.ctx.conf.versionCheck && this.versionCheck("\u524D\u7AEF", feMinVersion, "2.2.1"))
|
|
5367
|
+
return;
|
|
5368
|
+
if (this.ctx.conf.versionCheck && this.versionCheck("\u540E\u7AEF", backendMinVersion, (_b = data.api_version) == null ? void 0 : _b.version))
|
|
5252
5369
|
return;
|
|
5253
5370
|
if (data.conf && typeof data.conf.img_upload === "boolean") {
|
|
5254
5371
|
this.ctx.conf.imgUpload = data.conf.img_upload;
|
|
@@ -5523,20 +5640,19 @@ class ListLite extends Component {
|
|
|
5523
5640
|
});
|
|
5524
5641
|
}
|
|
5525
5642
|
}
|
|
5526
|
-
versionCheck(
|
|
5527
|
-
const
|
|
5528
|
-
const needUpdate = versionCompare(needVersion, "2.1.8") === 1;
|
|
5643
|
+
versionCheck(name, needVersion, curtVersion) {
|
|
5644
|
+
const needUpdate = versionCompare(needVersion, curtVersion) === 1;
|
|
5529
5645
|
if (needUpdate) {
|
|
5530
|
-
const errEl = createElement(`<div
|
|
5646
|
+
const errEl = createElement(`<div>Artalk ${name}\u7248\u672C\u5DF2\u8FC7\u65F6\uFF0C\u8BF7\u66F4\u65B0\u4EE5\u83B7\u5F97\u5B8C\u6574\u4F53\u9A8C<br/>\u5982\u679C\u4F60\u662F\u7BA1\u7406\u5458\uFF0C\u8BF7\u524D\u5F80 \u201C<a href="https://artalk.js.org/" target="_blank">\u5B98\u65B9\u6587\u6863</a>\u201D \u83B7\u5F97\u5E2E\u52A9<br/><br/><span style="color: var(--at-color-meta);">\u5F53\u524D${name}\u7248\u672C ${curtVersion}\uFF0C\u9700\u6C42\u7248\u672C >= ${needVersion}</span><br/><br/></div>`);
|
|
5531
5647
|
const ignoreBtn = createElement('<span style="cursor:pointer;">\u5FFD\u7565</span>');
|
|
5532
5648
|
ignoreBtn.onclick = () => {
|
|
5533
|
-
setError(this.
|
|
5649
|
+
setError(this.$el.parentElement, null);
|
|
5534
5650
|
this.ctx.conf.versionCheck = false;
|
|
5535
5651
|
this.ctx.trigger("conf-updated");
|
|
5536
5652
|
this.fetchComments(0);
|
|
5537
5653
|
};
|
|
5538
5654
|
errEl.append(ignoreBtn);
|
|
5539
|
-
setError(this.
|
|
5655
|
+
setError(this.$el.parentElement, errEl, '<span class="atk-warn-title">Artalk Warn</span>');
|
|
5540
5656
|
}
|
|
5541
5657
|
return needUpdate;
|
|
5542
5658
|
}
|
|
@@ -5566,8 +5682,10 @@ class List extends ListLite {
|
|
|
5566
5682
|
this.repositionAt = this.$el;
|
|
5567
5683
|
this.initListActionBtn();
|
|
5568
5684
|
this.$commentCount = this.$el.querySelector(".atk-comment-count");
|
|
5569
|
-
this.
|
|
5570
|
-
|
|
5685
|
+
if (this.ctx.conf.listSort) {
|
|
5686
|
+
this.initDropdown();
|
|
5687
|
+
}
|
|
5688
|
+
this.$el.querySelector(".atk-copyright").innerHTML = `Powered By <a href="https://artalk.js.org" target="_blank" title="Artalk v${"2.2.1"}">Artalk</a>`;
|
|
5571
5689
|
this.ctx.on("list-reload", () => this.fetchComments(0));
|
|
5572
5690
|
this.ctx.on("list-refresh-ui", () => this.refreshUI());
|
|
5573
5691
|
this.ctx.on("list-import", (data) => this.importComments(data));
|
|
@@ -5773,11 +5891,31 @@ class SidebarLayer extends Component {
|
|
|
5773
5891
|
this.$el.style.transform = "translate(0, 0)";
|
|
5774
5892
|
}, 20);
|
|
5775
5893
|
if (this.firstShow) {
|
|
5894
|
+
if (this.ctx.user.data.isAdmin) {
|
|
5895
|
+
const resp = yield new Api(this.ctx).loginStatus();
|
|
5896
|
+
if (!resp.is_login) {
|
|
5897
|
+
yield new Promise((resolve, reject) => {
|
|
5898
|
+
this.ctx.trigger("checker-admin", {
|
|
5899
|
+
onSuccess: () => {
|
|
5900
|
+
resolve(null);
|
|
5901
|
+
setTimeout(() => {
|
|
5902
|
+
this.show();
|
|
5903
|
+
}, 500);
|
|
5904
|
+
},
|
|
5905
|
+
onCancel: () => {
|
|
5906
|
+
var _a;
|
|
5907
|
+
(_a = this.layer) == null ? void 0 : _a.hide();
|
|
5908
|
+
}
|
|
5909
|
+
});
|
|
5910
|
+
});
|
|
5911
|
+
}
|
|
5912
|
+
}
|
|
5776
5913
|
this.$iframeWrap.innerHTML = "";
|
|
5777
5914
|
this.$iframe = createElement("<iframe></iframe>");
|
|
5778
|
-
const baseURL =
|
|
5915
|
+
const baseURL = getURLBasedOnApi(this.ctx, "sidebar/");
|
|
5779
5916
|
const userData = encodeURIComponent(JSON.stringify(this.ctx.user.data));
|
|
5780
|
-
|
|
5917
|
+
const location = window.location;
|
|
5918
|
+
this.iframeLoad(`${baseURL}?pageKey=${encodeURIComponent(this.conf.pageKey)}&site=${encodeURIComponent(this.conf.site || "")}&user=${userData}&referer=${encodeURIComponent(`${location.protocol}//${location.host}${location.pathname}`)}${this.conf.darkMode ? `&darkMode=1` : ``}`);
|
|
5781
5919
|
this.$iframeWrap.append(this.$iframe);
|
|
5782
5920
|
this.firstShow = false;
|
|
5783
5921
|
} else {
|
|
@@ -5857,6 +5995,7 @@ const _Artalk = class {
|
|
|
5857
5995
|
this.$root.innerHTML = "";
|
|
5858
5996
|
this.initDarkMode();
|
|
5859
5997
|
this.checkerLauncher = new CheckerLauncher(this.ctx);
|
|
5998
|
+
initMarked(this.ctx);
|
|
5860
5999
|
this.editor = new Editor(this.ctx);
|
|
5861
6000
|
this.$root.appendChild(this.editor.$el);
|
|
5862
6001
|
this.list = new List(this.ctx);
|
|
@@ -5866,6 +6005,11 @@ const _Artalk = class {
|
|
|
5866
6005
|
this.list.fetchComments(0);
|
|
5867
6006
|
this.initEventBind();
|
|
5868
6007
|
this.initPV();
|
|
6008
|
+
_Artalk.Plugins.forEach((plugin) => {
|
|
6009
|
+
if (typeof plugin === "function") {
|
|
6010
|
+
plugin(this.ctx);
|
|
6011
|
+
}
|
|
6012
|
+
});
|
|
5869
6013
|
}
|
|
5870
6014
|
initEventBind() {
|
|
5871
6015
|
window.addEventListener("hashchange", () => {
|
|
@@ -5936,7 +6080,11 @@ const _Artalk = class {
|
|
|
5936
6080
|
trigger(name, payload) {
|
|
5937
6081
|
this.ctx.trigger(name, payload, "external");
|
|
5938
6082
|
}
|
|
6083
|
+
static Use(plugin) {
|
|
6084
|
+
this.Plugins.push(plugin);
|
|
6085
|
+
}
|
|
5939
6086
|
};
|
|
5940
6087
|
let Artalk = _Artalk;
|
|
5941
6088
|
__publicField(Artalk, "defaults", defaults$3);
|
|
6089
|
+
__publicField(Artalk, "Plugins", []);
|
|
5942
6090
|
export { Artalk as default };
|