@whitesev/utils 2.6.8 → 2.7.0
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/index.amd.js +1173 -901
- package/dist/index.amd.js.map +1 -1
- package/dist/index.cjs.js +1173 -901
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +1173 -901
- package/dist/index.esm.js.map +1 -1
- package/dist/index.iife.js +1173 -901
- package/dist/index.iife.js.map +1 -1
- package/dist/index.system.js +1173 -901
- package/dist/index.system.js.map +1 -1
- package/dist/index.umd.js +1173 -901
- package/dist/index.umd.js.map +1 -1
- package/dist/types/src/CommonUtil.d.ts +109 -0
- package/dist/types/src/DOMUtils.d.ts +95 -0
- package/dist/types/src/Utils.d.ts +14 -10
- package/dist/types/src/ajaxHooker/ajaxHooker.d.ts +1 -1
- package/package.json +11 -8
- package/src/CommonUtil.ts +302 -0
- package/src/DOMUtils.ts +287 -0
- package/src/Dictionary.ts +2 -2
- package/src/Hooks.ts +11 -12
- package/src/Httpx.ts +22 -16
- package/src/LockFunction.ts +4 -7
- package/src/Progress.ts +2 -2
- package/src/TryCatch.ts +6 -9
- package/src/Utils.ts +23 -216
- package/src/UtilsGMCookie.ts +7 -7
- package/src/UtilsGMMenu.ts +2 -2
- package/src/ajaxHooker/ajaxHooker.js +536 -554
package/dist/index.esm.js
CHANGED
|
@@ -224,6 +224,273 @@ class GBKEncoder {
|
|
|
224
224
|
}
|
|
225
225
|
}
|
|
226
226
|
|
|
227
|
+
const TryCatch = function (...args) {
|
|
228
|
+
/* 定义变量和函数 */
|
|
229
|
+
let callbackFunction = null;
|
|
230
|
+
let context = null;
|
|
231
|
+
let handleError = (error) => { };
|
|
232
|
+
let defaultDetails = {
|
|
233
|
+
log: true,
|
|
234
|
+
};
|
|
235
|
+
const TryCatchCore = {
|
|
236
|
+
/**
|
|
237
|
+
*
|
|
238
|
+
* @param paramDetails 配置
|
|
239
|
+
* @returns
|
|
240
|
+
*/
|
|
241
|
+
config(paramDetails) {
|
|
242
|
+
defaultDetails = Object.assign(defaultDetails, paramDetails);
|
|
243
|
+
return TryCatchCore;
|
|
244
|
+
},
|
|
245
|
+
/**
|
|
246
|
+
* 处理错误
|
|
247
|
+
* @param handler
|
|
248
|
+
*/
|
|
249
|
+
error(handler) {
|
|
250
|
+
// @ts-ignore
|
|
251
|
+
handleError = handler;
|
|
252
|
+
return TryCatchCore;
|
|
253
|
+
},
|
|
254
|
+
/**
|
|
255
|
+
* 执行传入的函数并捕获其可能抛出的错误,并通过传入的错误处理函数进行处理。
|
|
256
|
+
* @param callback 待执行函数,可以是 function 或者 string 类型。如果是 string 类型,则会被当做代码进行执行。
|
|
257
|
+
* @param __context__ 待执行函数的作用域,用于apply指定
|
|
258
|
+
* @returns 如果函数有返回值,则返回该返回值;否则返回 tryCatchObj 函数以支持链式调用。
|
|
259
|
+
* @throws {Error} 如果传入参数不符合要求,则会抛出相应类型的错误。
|
|
260
|
+
*/
|
|
261
|
+
run(callback, __context__) {
|
|
262
|
+
callbackFunction = callback;
|
|
263
|
+
context = __context__ || this;
|
|
264
|
+
let result = executeTryCatch(callbackFunction, handleError, context);
|
|
265
|
+
// @ts-ignore
|
|
266
|
+
return result !== void 0 ? result : TryCatchCore;
|
|
267
|
+
},
|
|
268
|
+
};
|
|
269
|
+
/**
|
|
270
|
+
* 执行传入的函数并捕获其可能抛出的错误,并通过传入的错误处理函数进行处理。
|
|
271
|
+
* @param callback - 待执行函数,可以是 function 或者 string 类型。如果是 string 类型,则会被当做代码进行执行。
|
|
272
|
+
* @param handleErrorFunc - 错误处理函数,可以是 function 或者 string 类型。如果是 string 类型,则会被当做代码进行执行。
|
|
273
|
+
* @param funcThis - 待执行函数的作用域,用于apply指定
|
|
274
|
+
* @returns 如果函数有返回值,则返回该返回值;否则返回 undefined。
|
|
275
|
+
*/
|
|
276
|
+
function executeTryCatch(callback, handleErrorFunc, funcThis) {
|
|
277
|
+
let result = void 0;
|
|
278
|
+
try {
|
|
279
|
+
if (typeof callback === "string") {
|
|
280
|
+
result = new Function(callback).apply(funcThis, args);
|
|
281
|
+
}
|
|
282
|
+
else {
|
|
283
|
+
result = callback.apply(funcThis, args);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
catch (error) {
|
|
287
|
+
if (defaultDetails.log) {
|
|
288
|
+
callback = callback;
|
|
289
|
+
console.log(`%c ${callback?.name ? callback?.name : callback + "出现错误"} `, "color: #f20000");
|
|
290
|
+
console.log(`%c 错误原因:${error}`, "color: #f20000");
|
|
291
|
+
console.trace(callback);
|
|
292
|
+
}
|
|
293
|
+
if (handleErrorFunc) {
|
|
294
|
+
if (typeof handleErrorFunc === "string") {
|
|
295
|
+
result = new Function(handleErrorFunc).apply(funcThis, [
|
|
296
|
+
...args,
|
|
297
|
+
error,
|
|
298
|
+
]);
|
|
299
|
+
}
|
|
300
|
+
else {
|
|
301
|
+
result = handleErrorFunc.apply(funcThis, [...args, error]);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
return result;
|
|
306
|
+
}
|
|
307
|
+
return TryCatchCore;
|
|
308
|
+
};
|
|
309
|
+
|
|
310
|
+
class CommonUtil {
|
|
311
|
+
assign(target = {}, source = {}, isAdd = false) {
|
|
312
|
+
let UtilsContext = this;
|
|
313
|
+
if (Array.isArray(source)) {
|
|
314
|
+
let canTraverse = source.filter((item) => {
|
|
315
|
+
return typeof item === "object";
|
|
316
|
+
});
|
|
317
|
+
if (!canTraverse.length) {
|
|
318
|
+
return source;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
if (source == null) {
|
|
322
|
+
return target;
|
|
323
|
+
}
|
|
324
|
+
if (target == null) {
|
|
325
|
+
target = {};
|
|
326
|
+
}
|
|
327
|
+
if (isAdd) {
|
|
328
|
+
for (const sourceKeyName in source) {
|
|
329
|
+
const targetKeyName = sourceKeyName;
|
|
330
|
+
let targetValue = target[targetKeyName];
|
|
331
|
+
let sourceValue = source[sourceKeyName];
|
|
332
|
+
if (typeof sourceValue === "object" &&
|
|
333
|
+
sourceValue != null &&
|
|
334
|
+
sourceKeyName in target &&
|
|
335
|
+
!UtilsContext.isDOM(sourceValue)) {
|
|
336
|
+
/* 源端的值是object类型,且不是元素节点 */
|
|
337
|
+
target[sourceKeyName] = UtilsContext.assign(targetValue, sourceValue, isAdd);
|
|
338
|
+
continue;
|
|
339
|
+
}
|
|
340
|
+
target[sourceKeyName] = sourceValue;
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
else {
|
|
344
|
+
for (const targetKeyName in target) {
|
|
345
|
+
if (targetKeyName in source) {
|
|
346
|
+
let targetValue = target[targetKeyName];
|
|
347
|
+
let sourceValue = source[targetKeyName];
|
|
348
|
+
if (typeof sourceValue === "object" &&
|
|
349
|
+
sourceValue != null &&
|
|
350
|
+
!UtilsContext.isDOM(sourceValue) &&
|
|
351
|
+
Object.keys(sourceValue).length) {
|
|
352
|
+
/* 源端的值是object类型,且不是元素节点 */
|
|
353
|
+
target[targetKeyName] = UtilsContext.assign(targetValue, sourceValue, isAdd);
|
|
354
|
+
continue;
|
|
355
|
+
}
|
|
356
|
+
/* 直接赋值 */
|
|
357
|
+
target[targetKeyName] = sourceValue;
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
return target;
|
|
362
|
+
}
|
|
363
|
+
isNull(...args) {
|
|
364
|
+
let result = true;
|
|
365
|
+
let checkList = [...args];
|
|
366
|
+
for (const objItem of checkList) {
|
|
367
|
+
let itemResult = false;
|
|
368
|
+
if (objItem === null || objItem === undefined) {
|
|
369
|
+
itemResult = true;
|
|
370
|
+
}
|
|
371
|
+
else {
|
|
372
|
+
switch (typeof objItem) {
|
|
373
|
+
case "object":
|
|
374
|
+
if (typeof objItem[Symbol.iterator] === "function") {
|
|
375
|
+
/* 可迭代 */
|
|
376
|
+
itemResult = objItem.length === 0;
|
|
377
|
+
}
|
|
378
|
+
else {
|
|
379
|
+
itemResult = Object.keys(objItem).length === 0;
|
|
380
|
+
}
|
|
381
|
+
break;
|
|
382
|
+
case "number":
|
|
383
|
+
itemResult = objItem === 0;
|
|
384
|
+
break;
|
|
385
|
+
case "string":
|
|
386
|
+
itemResult =
|
|
387
|
+
objItem.trim() === "" ||
|
|
388
|
+
objItem === "null" ||
|
|
389
|
+
objItem === "undefined";
|
|
390
|
+
break;
|
|
391
|
+
case "boolean":
|
|
392
|
+
itemResult = !objItem;
|
|
393
|
+
break;
|
|
394
|
+
case "function":
|
|
395
|
+
let funcStr = objItem.toString().replace(/\s/g, "");
|
|
396
|
+
/* 排除()=>{}、(xxx="")=>{}、function(){}、function(xxx=""){} */
|
|
397
|
+
itemResult = Boolean(funcStr.match(/^\(.*?\)=>\{\}$|^function.*?\(.*?\)\{\}$/));
|
|
398
|
+
break;
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
result = result && itemResult;
|
|
402
|
+
}
|
|
403
|
+
return result;
|
|
404
|
+
}
|
|
405
|
+
/**
|
|
406
|
+
* 判断对象是否是元素
|
|
407
|
+
* @param target
|
|
408
|
+
* @returns
|
|
409
|
+
* + true 是元素
|
|
410
|
+
* + false 不是元素
|
|
411
|
+
* @example
|
|
412
|
+
* Utils.isDOM(document.querySelector("a"))
|
|
413
|
+
* > true
|
|
414
|
+
*/
|
|
415
|
+
isDOM(target) {
|
|
416
|
+
return target instanceof Node;
|
|
417
|
+
}
|
|
418
|
+
isNotNull(...args) {
|
|
419
|
+
let UtilsContext = this;
|
|
420
|
+
return !UtilsContext.isNull.apply(this, args);
|
|
421
|
+
}
|
|
422
|
+
deepClone(obj) {
|
|
423
|
+
let UtilsContext = this;
|
|
424
|
+
if (obj === void 0)
|
|
425
|
+
return void 0;
|
|
426
|
+
if (obj === null)
|
|
427
|
+
return null;
|
|
428
|
+
let clone = obj instanceof Array ? [] : {};
|
|
429
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
430
|
+
clone[key] =
|
|
431
|
+
typeof value === "object" ? UtilsContext.deepClone(value) : value;
|
|
432
|
+
}
|
|
433
|
+
return clone;
|
|
434
|
+
}
|
|
435
|
+
/**
|
|
436
|
+
* 覆盖对象中的函数this指向
|
|
437
|
+
* @param target 需要覆盖的对象
|
|
438
|
+
* @param [objectThis] 覆盖的this指向,如果为传入,则默认为对象本身
|
|
439
|
+
*/
|
|
440
|
+
coverObjectFunctionThis(target, objectThis) {
|
|
441
|
+
if (typeof target !== "object" || target === null) {
|
|
442
|
+
throw new Error("target must be object");
|
|
443
|
+
}
|
|
444
|
+
objectThis = objectThis || target;
|
|
445
|
+
Object.keys(target).forEach((key) => {
|
|
446
|
+
if (typeof target[key] === "function") {
|
|
447
|
+
target[key] = target[key].bind(objectThis);
|
|
448
|
+
}
|
|
449
|
+
});
|
|
450
|
+
}
|
|
451
|
+
toJSON(data, errorCallBack) {
|
|
452
|
+
let result = {};
|
|
453
|
+
if (typeof data === "object") {
|
|
454
|
+
return data;
|
|
455
|
+
}
|
|
456
|
+
TryCatch()
|
|
457
|
+
.config({ log: false })
|
|
458
|
+
.error((error) => {
|
|
459
|
+
TryCatch()
|
|
460
|
+
.error(() => {
|
|
461
|
+
try {
|
|
462
|
+
result = new Function("return " + data)();
|
|
463
|
+
}
|
|
464
|
+
catch (error2) {
|
|
465
|
+
if (typeof errorCallBack === "function") {
|
|
466
|
+
errorCallBack(error2);
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
})
|
|
470
|
+
.run(() => {
|
|
471
|
+
if (data &&
|
|
472
|
+
/^[\],:{}\s]*$/.test(data
|
|
473
|
+
.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, "@")
|
|
474
|
+
.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]")
|
|
475
|
+
.replace(/(?:^|:|,)(?:\s*\[)+/g, ""))) {
|
|
476
|
+
result = new Function("return " + data)();
|
|
477
|
+
}
|
|
478
|
+
else {
|
|
479
|
+
if (typeof errorCallBack === "function") {
|
|
480
|
+
errorCallBack(new Error("target is not a JSON"));
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
});
|
|
484
|
+
})
|
|
485
|
+
.run(() => {
|
|
486
|
+
data = data.trim();
|
|
487
|
+
result = JSON.parse(data);
|
|
488
|
+
});
|
|
489
|
+
return result;
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
let commonUtil = new CommonUtil();
|
|
493
|
+
|
|
227
494
|
class UtilsGMCookie {
|
|
228
495
|
windowApi = {
|
|
229
496
|
window: window,
|
|
@@ -252,7 +519,7 @@ class UtilsGMCookie {
|
|
|
252
519
|
throw new TypeError("Utils.GMCookie.get 参数cookieName 必须为字符串");
|
|
253
520
|
}
|
|
254
521
|
let cookies = this.getCookiesList();
|
|
255
|
-
let findValue =
|
|
522
|
+
let findValue = void 0;
|
|
256
523
|
for (const cookieItem of cookies) {
|
|
257
524
|
let item = cookieItem.trim();
|
|
258
525
|
let itemSplit = item.split("=");
|
|
@@ -296,7 +563,7 @@ class UtilsGMCookie {
|
|
|
296
563
|
name: "",
|
|
297
564
|
path: "/",
|
|
298
565
|
};
|
|
299
|
-
defaultOption =
|
|
566
|
+
defaultOption = commonUtil.assign(defaultOption, option);
|
|
300
567
|
let cookies = this.getCookiesList();
|
|
301
568
|
cookies.forEach((item) => {
|
|
302
569
|
item = item.trim();
|
|
@@ -347,7 +614,7 @@ class UtilsGMCookie {
|
|
|
347
614
|
name: "",
|
|
348
615
|
path: "/",
|
|
349
616
|
};
|
|
350
|
-
defaultOption =
|
|
617
|
+
defaultOption = commonUtil.assign(defaultOption, option);
|
|
351
618
|
let cookies = this.getCookiesList();
|
|
352
619
|
cookies.forEach((item) => {
|
|
353
620
|
item = item.trim();
|
|
@@ -396,7 +663,7 @@ class UtilsGMCookie {
|
|
|
396
663
|
*/
|
|
397
664
|
expirationDate: Math.floor(Date.now()) + 60 * 60 * 24 * 30,
|
|
398
665
|
};
|
|
399
|
-
defaultOption =
|
|
666
|
+
defaultOption = commonUtil.assign(defaultOption, option);
|
|
400
667
|
let life = defaultOption.expirationDate
|
|
401
668
|
? defaultOption.expirationDate
|
|
402
669
|
: Math.floor(Date.now()) + 60 * 60 * 24 * 30;
|
|
@@ -406,7 +673,7 @@ class UtilsGMCookie {
|
|
|
406
673
|
";expires=" +
|
|
407
674
|
new Date(life).toGMTString() +
|
|
408
675
|
"; path=/";
|
|
409
|
-
if (
|
|
676
|
+
if (commonUtil.isNull(defaultOption.domain)) {
|
|
410
677
|
cookieStr += "; domain=" + defaultOption.domain;
|
|
411
678
|
}
|
|
412
679
|
this.windowApi.document.cookie = cookieStr;
|
|
@@ -434,9 +701,9 @@ class UtilsGMCookie {
|
|
|
434
701
|
path: "/",
|
|
435
702
|
firstPartyDomain: "",
|
|
436
703
|
};
|
|
437
|
-
defaultOption =
|
|
704
|
+
defaultOption = commonUtil.assign(defaultOption, option);
|
|
438
705
|
let cookieStr = `${defaultOption.name}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=${defaultOption.path}`;
|
|
439
|
-
if (
|
|
706
|
+
if (commonUtil.isNull(defaultOption.firstPartyDomain)) {
|
|
440
707
|
cookieStr += `; domain=${defaultOption.firstPartyDomain};`;
|
|
441
708
|
}
|
|
442
709
|
this.windowApi.document.cookie = cookieStr;
|
|
@@ -476,189 +743,189 @@ class UtilsGMCookie {
|
|
|
476
743
|
}
|
|
477
744
|
}
|
|
478
745
|
|
|
746
|
+
// ==UserScript==
|
|
479
747
|
// @name ajaxHooker
|
|
480
748
|
// @author cxxjackie
|
|
481
|
-
// @version 1.4.
|
|
482
|
-
// @updateLog 修复头条、抖音部分站点下this引用错误的问题。
|
|
749
|
+
// @version 1.4.6
|
|
483
750
|
// @supportURL https://bbs.tampermonkey.net.cn/thread-3284-1-1.html
|
|
751
|
+
// @license GNU LGPL-3.0
|
|
752
|
+
// ==/UserScript==
|
|
484
753
|
|
|
485
|
-
const
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
console.error(err);
|
|
531
|
-
}
|
|
532
|
-
}
|
|
533
|
-
function defineProp(obj, prop, getter, setter) {
|
|
534
|
-
Object.defineProperty(obj, prop, {
|
|
535
|
-
configurable: true,
|
|
536
|
-
enumerable: true,
|
|
537
|
-
get: getter,
|
|
538
|
-
set: setter,
|
|
539
|
-
});
|
|
540
|
-
}
|
|
541
|
-
function readonly(obj, prop, value = obj[prop]) {
|
|
542
|
-
defineProp(obj, prop, () => value, emptyFn);
|
|
543
|
-
}
|
|
544
|
-
function writable(obj, prop, value = obj[prop]) {
|
|
545
|
-
Object.defineProperty(obj, prop, {
|
|
546
|
-
configurable: true,
|
|
547
|
-
enumerable: true,
|
|
548
|
-
writable: true,
|
|
549
|
-
value: value,
|
|
550
|
-
});
|
|
754
|
+
const ajaxHooker = function () {
|
|
755
|
+
const version = "1.4.6";
|
|
756
|
+
const hookInst = {
|
|
757
|
+
hookFns: [],
|
|
758
|
+
filters: [],
|
|
759
|
+
};
|
|
760
|
+
const win = window.unsafeWindow || document.defaultView || window;
|
|
761
|
+
let winAh = win.__ajaxHooker;
|
|
762
|
+
const resProto = win.Response.prototype;
|
|
763
|
+
const xhrResponses = ["response", "responseText", "responseXML"];
|
|
764
|
+
const fetchResponses = ["arrayBuffer", "blob", "formData", "json", "text"];
|
|
765
|
+
const fetchInitProps = [
|
|
766
|
+
"method",
|
|
767
|
+
"headers",
|
|
768
|
+
"body",
|
|
769
|
+
"mode",
|
|
770
|
+
"credentials",
|
|
771
|
+
"cache",
|
|
772
|
+
"redirect",
|
|
773
|
+
"referrer",
|
|
774
|
+
"referrerPolicy",
|
|
775
|
+
"integrity",
|
|
776
|
+
"keepalive",
|
|
777
|
+
"signal",
|
|
778
|
+
"priority",
|
|
779
|
+
];
|
|
780
|
+
const xhrAsyncEvents = ["readystatechange", "load", "loadend"];
|
|
781
|
+
const getType = {}.toString.call.bind({}.toString);
|
|
782
|
+
const getDescriptor = Object.getOwnPropertyDescriptor.bind(Object);
|
|
783
|
+
const emptyFn = () => {};
|
|
784
|
+
const errorFn = (e) => console.error(e);
|
|
785
|
+
function isThenable(obj) {
|
|
786
|
+
return (
|
|
787
|
+
obj &&
|
|
788
|
+
["object", "function"].includes(typeof obj) &&
|
|
789
|
+
typeof obj.then === "function"
|
|
790
|
+
);
|
|
791
|
+
}
|
|
792
|
+
function catchError(fn, ...args) {
|
|
793
|
+
try {
|
|
794
|
+
const result = fn(...args);
|
|
795
|
+
if (isThenable(result)) return result.then(null, errorFn);
|
|
796
|
+
return result;
|
|
797
|
+
} catch (err) {
|
|
798
|
+
console.error(err);
|
|
551
799
|
}
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
800
|
+
}
|
|
801
|
+
function defineProp(obj, prop, getter, setter) {
|
|
802
|
+
Object.defineProperty(obj, prop, {
|
|
803
|
+
configurable: true,
|
|
804
|
+
enumerable: true,
|
|
805
|
+
get: getter,
|
|
806
|
+
set: setter,
|
|
807
|
+
});
|
|
808
|
+
}
|
|
809
|
+
function readonly(obj, prop, value = obj[prop]) {
|
|
810
|
+
defineProp(obj, prop, () => value, emptyFn);
|
|
811
|
+
}
|
|
812
|
+
function writable(obj, prop, value = obj[prop]) {
|
|
813
|
+
Object.defineProperty(obj, prop, {
|
|
814
|
+
configurable: true,
|
|
815
|
+
enumerable: true,
|
|
816
|
+
writable: true,
|
|
817
|
+
value: value,
|
|
818
|
+
});
|
|
819
|
+
}
|
|
820
|
+
function parseHeaders(obj) {
|
|
821
|
+
const headers = {};
|
|
822
|
+
switch (getType(obj)) {
|
|
823
|
+
case "[object String]":
|
|
824
|
+
for (const line of obj.trim().split(/[\r\n]+/)) {
|
|
825
|
+
const [header, value] = line.split(/(?<=^[^:]+)\s*:\s*/);
|
|
826
|
+
if (!value) continue;
|
|
827
|
+
const lheader = header.toLowerCase();
|
|
828
|
+
headers[lheader] =
|
|
829
|
+
lheader in headers ? `${headers[lheader]}, ${value}` : value;
|
|
830
|
+
}
|
|
831
|
+
break;
|
|
832
|
+
case "[object Headers]":
|
|
833
|
+
for (const [key, val] of obj) {
|
|
834
|
+
headers[key] = val;
|
|
835
|
+
}
|
|
836
|
+
break;
|
|
837
|
+
case "[object Object]":
|
|
838
|
+
return { ...obj };
|
|
839
|
+
}
|
|
840
|
+
return headers;
|
|
841
|
+
}
|
|
842
|
+
function stopImmediatePropagation() {
|
|
843
|
+
this.ajaxHooker_isStopped = true;
|
|
844
|
+
}
|
|
845
|
+
class SyncThenable {
|
|
846
|
+
then(fn) {
|
|
847
|
+
fn && fn();
|
|
848
|
+
return new SyncThenable();
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
class AHRequest {
|
|
852
|
+
constructor(request) {
|
|
853
|
+
this.request = request;
|
|
854
|
+
this.requestClone = { ...this.request };
|
|
573
855
|
}
|
|
574
|
-
|
|
575
|
-
|
|
856
|
+
shouldFilter(filters) {
|
|
857
|
+
const { type, url, method, async } = this.request;
|
|
858
|
+
return (
|
|
859
|
+
filters.length &&
|
|
860
|
+
!filters.find((obj) => {
|
|
861
|
+
switch (true) {
|
|
862
|
+
case obj.type && obj.type !== type:
|
|
863
|
+
case getType(obj.url) === "[object String]" &&
|
|
864
|
+
!url.includes(obj.url):
|
|
865
|
+
case getType(obj.url) === "[object RegExp]" && !obj.url.test(url):
|
|
866
|
+
case obj.method &&
|
|
867
|
+
obj.method.toUpperCase() !== method.toUpperCase():
|
|
868
|
+
case "async" in obj && obj.async !== async:
|
|
869
|
+
return false;
|
|
870
|
+
}
|
|
871
|
+
return true;
|
|
872
|
+
})
|
|
873
|
+
);
|
|
576
874
|
}
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
875
|
+
waitForRequestKeys() {
|
|
876
|
+
const requestKeys = ["url", "method", "abort", "headers", "data"];
|
|
877
|
+
if (!this.request.async) {
|
|
878
|
+
win.__ajaxHooker.hookInsts.forEach(({ hookFns, filters }) => {
|
|
879
|
+
if (this.shouldFilter(filters)) return;
|
|
880
|
+
hookFns.forEach((fn) => {
|
|
881
|
+
if (getType(fn) === "[object Function]")
|
|
882
|
+
catchError(fn, this.request);
|
|
883
|
+
});
|
|
884
|
+
requestKeys.forEach((key) => {
|
|
885
|
+
if (isThenable(this.request[key]))
|
|
886
|
+
this.request[key] = this.requestClone[key];
|
|
887
|
+
});
|
|
888
|
+
});
|
|
580
889
|
return new SyncThenable();
|
|
581
890
|
}
|
|
891
|
+
const promises = [];
|
|
892
|
+
win.__ajaxHooker.hookInsts.forEach(({ hookFns, filters }) => {
|
|
893
|
+
if (this.shouldFilter(filters)) return;
|
|
894
|
+
promises.push(
|
|
895
|
+
Promise.all(hookFns.map((fn) => catchError(fn, this.request))).then(
|
|
896
|
+
() =>
|
|
897
|
+
Promise.all(
|
|
898
|
+
requestKeys.map((key) =>
|
|
899
|
+
Promise.resolve(this.request[key]).then(
|
|
900
|
+
(val) => (this.request[key] = val),
|
|
901
|
+
() => (this.request[key] = this.requestClone[key])
|
|
902
|
+
)
|
|
903
|
+
)
|
|
904
|
+
)
|
|
905
|
+
)
|
|
906
|
+
);
|
|
907
|
+
});
|
|
908
|
+
return Promise.all(promises);
|
|
582
909
|
}
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
this.request
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
case getType(obj.url) === "[object String]" &&
|
|
596
|
-
!url.includes(obj.url):
|
|
597
|
-
case getType(obj.url) === "[object RegExp]" && !obj.url.test(url):
|
|
598
|
-
case obj.method &&
|
|
599
|
-
obj.method.toUpperCase() !== method.toUpperCase():
|
|
600
|
-
case "async" in obj && obj.async !== async:
|
|
601
|
-
return false;
|
|
910
|
+
waitForResponseKeys(response) {
|
|
911
|
+
const responseKeys =
|
|
912
|
+
this.request.type === "xhr" ? xhrResponses : fetchResponses;
|
|
913
|
+
if (!this.request.async) {
|
|
914
|
+
if (getType(this.request.response) === "[object Function]") {
|
|
915
|
+
catchError(this.request.response, response);
|
|
916
|
+
responseKeys.forEach((key) => {
|
|
917
|
+
if (
|
|
918
|
+
"get" in getDescriptor(response, key) ||
|
|
919
|
+
isThenable(response[key])
|
|
920
|
+
) {
|
|
921
|
+
delete response[key];
|
|
602
922
|
}
|
|
603
|
-
return true;
|
|
604
|
-
})
|
|
605
|
-
);
|
|
606
|
-
}
|
|
607
|
-
waitForRequestKeys() {
|
|
608
|
-
const requestKeys = ["url", "method", "abort", "headers", "data"];
|
|
609
|
-
if (!this.request.async) {
|
|
610
|
-
win.__ajaxHooker.hookInsts.forEach(({ hookFns, filters }) => {
|
|
611
|
-
if (this.shouldFilter(filters)) return;
|
|
612
|
-
hookFns.forEach((fn) => {
|
|
613
|
-
if (getType(fn) === "[object Function]")
|
|
614
|
-
catchError(fn, this.request);
|
|
615
|
-
});
|
|
616
|
-
requestKeys.forEach((key) => {
|
|
617
|
-
if (isThenable(this.request[key]))
|
|
618
|
-
this.request[key] = this.requestClone[key];
|
|
619
|
-
});
|
|
620
923
|
});
|
|
621
|
-
return new SyncThenable();
|
|
622
924
|
}
|
|
623
|
-
|
|
624
|
-
win.__ajaxHooker.hookInsts.forEach(({ hookFns, filters }) => {
|
|
625
|
-
if (this.shouldFilter(filters)) return;
|
|
626
|
-
promises.push(
|
|
627
|
-
Promise.all(hookFns.map((fn) => catchError(fn, this.request))).then(
|
|
628
|
-
() =>
|
|
629
|
-
Promise.all(
|
|
630
|
-
requestKeys.map((key) =>
|
|
631
|
-
Promise.resolve(this.request[key]).then(
|
|
632
|
-
(val) => (this.request[key] = val),
|
|
633
|
-
() => (this.request[key] = this.requestClone[key])
|
|
634
|
-
)
|
|
635
|
-
)
|
|
636
|
-
)
|
|
637
|
-
)
|
|
638
|
-
);
|
|
639
|
-
});
|
|
640
|
-
return Promise.all(promises);
|
|
925
|
+
return new SyncThenable();
|
|
641
926
|
}
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
this.request.type === "xhr" ? xhrResponses : fetchResponses;
|
|
645
|
-
if (!this.request.async) {
|
|
646
|
-
if (getType(this.request.response) === "[object Function]") {
|
|
647
|
-
catchError(this.request.response, response);
|
|
648
|
-
responseKeys.forEach((key) => {
|
|
649
|
-
if (
|
|
650
|
-
"get" in getDescriptor(response, key) ||
|
|
651
|
-
isThenable(response[key])
|
|
652
|
-
) {
|
|
653
|
-
delete response[key];
|
|
654
|
-
}
|
|
655
|
-
});
|
|
656
|
-
}
|
|
657
|
-
return new SyncThenable();
|
|
658
|
-
}
|
|
659
|
-
return Promise.resolve(
|
|
660
|
-
catchError(this.request.response, response)
|
|
661
|
-
).then(() =>
|
|
927
|
+
return Promise.resolve(catchError(this.request.response, response)).then(
|
|
928
|
+
() =>
|
|
662
929
|
Promise.all(
|
|
663
930
|
responseKeys.map((key) => {
|
|
664
931
|
const descriptor = getDescriptor(response, key);
|
|
@@ -672,424 +939,406 @@ const AjaxHooker = function () {
|
|
|
672
939
|
}
|
|
673
940
|
})
|
|
674
941
|
)
|
|
675
|
-
|
|
676
|
-
}
|
|
942
|
+
);
|
|
677
943
|
}
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
const ah = target.__ajaxHooker;
|
|
689
|
-
if (ah && ah.proxyProps) {
|
|
690
|
-
if (prop in ah.proxyProps) {
|
|
691
|
-
const pDescriptor = ah.proxyProps[prop];
|
|
692
|
-
if ("get" in pDescriptor) return pDescriptor.get();
|
|
693
|
-
if (typeof pDescriptor.value === "function")
|
|
694
|
-
return pDescriptor.value.bind(ah);
|
|
695
|
-
return pDescriptor.value;
|
|
696
|
-
}
|
|
697
|
-
if (typeof target[prop] === "function")
|
|
698
|
-
return target[prop].bind(target);
|
|
699
|
-
}
|
|
944
|
+
}
|
|
945
|
+
const proxyHandler = {
|
|
946
|
+
get(target, prop) {
|
|
947
|
+
const descriptor = getDescriptor(target, prop);
|
|
948
|
+
if (
|
|
949
|
+
descriptor &&
|
|
950
|
+
!descriptor.configurable &&
|
|
951
|
+
!descriptor.writable &&
|
|
952
|
+
!descriptor.get
|
|
953
|
+
)
|
|
700
954
|
return target[prop];
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
if (
|
|
705
|
-
descriptor &&
|
|
706
|
-
!descriptor.configurable &&
|
|
707
|
-
!descriptor.writable &&
|
|
708
|
-
!descriptor.set
|
|
709
|
-
)
|
|
710
|
-
return true;
|
|
711
|
-
const ah = target.__ajaxHooker;
|
|
712
|
-
if (ah && ah.proxyProps && prop in ah.proxyProps) {
|
|
955
|
+
const ah = target.__ajaxHooker;
|
|
956
|
+
if (ah && ah.proxyProps) {
|
|
957
|
+
if (prop in ah.proxyProps) {
|
|
713
958
|
const pDescriptor = ah.proxyProps[prop];
|
|
714
|
-
pDescriptor.
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
target[prop] = value;
|
|
719
|
-
}
|
|
720
|
-
return true;
|
|
721
|
-
},
|
|
722
|
-
};
|
|
723
|
-
class XhrHooker {
|
|
724
|
-
constructor(xhr) {
|
|
725
|
-
const ah = this;
|
|
726
|
-
Object.assign(ah, {
|
|
727
|
-
originalXhr: xhr,
|
|
728
|
-
proxyXhr: new Proxy(xhr, proxyHandler),
|
|
729
|
-
resThenable: new SyncThenable(),
|
|
730
|
-
proxyProps: {},
|
|
731
|
-
proxyEvents: {},
|
|
732
|
-
});
|
|
733
|
-
xhr.addEventListener("readystatechange", (e) => {
|
|
734
|
-
if (
|
|
735
|
-
ah.proxyXhr.readyState === 4 &&
|
|
736
|
-
ah.request &&
|
|
737
|
-
typeof ah.request.response === "function"
|
|
738
|
-
) {
|
|
739
|
-
const response = {
|
|
740
|
-
finalUrl: ah.proxyXhr.responseURL,
|
|
741
|
-
status: ah.proxyXhr.status,
|
|
742
|
-
responseHeaders: parseHeaders(
|
|
743
|
-
ah.proxyXhr.getAllResponseHeaders()
|
|
744
|
-
),
|
|
745
|
-
};
|
|
746
|
-
const tempValues = {};
|
|
747
|
-
for (const key of xhrResponses) {
|
|
748
|
-
try {
|
|
749
|
-
tempValues[key] = ah.originalXhr[key];
|
|
750
|
-
} catch (err) {}
|
|
751
|
-
defineProp(
|
|
752
|
-
response,
|
|
753
|
-
key,
|
|
754
|
-
() => {
|
|
755
|
-
return (response[key] = tempValues[key]);
|
|
756
|
-
},
|
|
757
|
-
(val) => {
|
|
758
|
-
delete response[key];
|
|
759
|
-
response[key] = val;
|
|
760
|
-
}
|
|
761
|
-
);
|
|
762
|
-
}
|
|
763
|
-
ah.resThenable = new AHRequest(ah.request)
|
|
764
|
-
.waitForResponseKeys(response)
|
|
765
|
-
.then(() => {
|
|
766
|
-
for (const key of xhrResponses) {
|
|
767
|
-
ah.proxyProps[key] = {
|
|
768
|
-
get: () => {
|
|
769
|
-
if (!(key in response)) response[key] = tempValues[key];
|
|
770
|
-
return response[key];
|
|
771
|
-
},
|
|
772
|
-
};
|
|
773
|
-
}
|
|
774
|
-
});
|
|
775
|
-
}
|
|
776
|
-
ah.dispatchEvent(e);
|
|
777
|
-
});
|
|
778
|
-
xhr.addEventListener("load", (e) => ah.dispatchEvent(e));
|
|
779
|
-
xhr.addEventListener("loadend", (e) => ah.dispatchEvent(e));
|
|
780
|
-
for (const evt of xhrAsyncEvents) {
|
|
781
|
-
const onEvt = "on" + evt;
|
|
782
|
-
ah.proxyProps[onEvt] = {
|
|
783
|
-
get: () => ah.proxyEvents[onEvt] || null,
|
|
784
|
-
set: (val) => ah.addEvent(onEvt, val),
|
|
785
|
-
};
|
|
786
|
-
}
|
|
787
|
-
for (const method of [
|
|
788
|
-
"setRequestHeader",
|
|
789
|
-
"addEventListener",
|
|
790
|
-
"removeEventListener",
|
|
791
|
-
"open",
|
|
792
|
-
"send",
|
|
793
|
-
]) {
|
|
794
|
-
ah.proxyProps[method] = { value: ah[method] };
|
|
795
|
-
}
|
|
796
|
-
}
|
|
797
|
-
toJSON() {} // Converting circular structure to JSON
|
|
798
|
-
addEvent(type, event) {
|
|
799
|
-
if (type.startsWith("on")) {
|
|
800
|
-
this.proxyEvents[type] = typeof event === "function" ? event : null;
|
|
801
|
-
} else {
|
|
802
|
-
if (typeof event === "object" && event !== null)
|
|
803
|
-
event = event.handleEvent;
|
|
804
|
-
if (typeof event !== "function") return;
|
|
805
|
-
this.proxyEvents[type] = this.proxyEvents[type] || new Set();
|
|
806
|
-
this.proxyEvents[type].add(event);
|
|
959
|
+
if ("get" in pDescriptor) return pDescriptor.get();
|
|
960
|
+
if (typeof pDescriptor.value === "function")
|
|
961
|
+
return pDescriptor.value.bind(ah);
|
|
962
|
+
return pDescriptor.value;
|
|
807
963
|
}
|
|
964
|
+
if (typeof target[prop] === "function")
|
|
965
|
+
return target[prop].bind(target);
|
|
808
966
|
}
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
967
|
+
return target[prop];
|
|
968
|
+
},
|
|
969
|
+
set(target, prop, value) {
|
|
970
|
+
const descriptor = getDescriptor(target, prop);
|
|
971
|
+
if (
|
|
972
|
+
descriptor &&
|
|
973
|
+
!descriptor.configurable &&
|
|
974
|
+
!descriptor.writable &&
|
|
975
|
+
!descriptor.set
|
|
976
|
+
)
|
|
977
|
+
return true;
|
|
978
|
+
const ah = target.__ajaxHooker;
|
|
979
|
+
if (ah && ah.proxyProps && prop in ah.proxyProps) {
|
|
980
|
+
const pDescriptor = ah.proxyProps[prop];
|
|
981
|
+
pDescriptor.set ? pDescriptor.set(value) : (pDescriptor.value = value);
|
|
982
|
+
} else {
|
|
983
|
+
target[prop] = value;
|
|
817
984
|
}
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
985
|
+
return true;
|
|
986
|
+
},
|
|
987
|
+
};
|
|
988
|
+
class XhrHooker {
|
|
989
|
+
constructor(xhr) {
|
|
990
|
+
const ah = this;
|
|
991
|
+
Object.assign(ah, {
|
|
992
|
+
originalXhr: xhr,
|
|
993
|
+
proxyXhr: new Proxy(xhr, proxyHandler),
|
|
994
|
+
resThenable: new SyncThenable(),
|
|
995
|
+
proxyProps: {},
|
|
996
|
+
proxyEvents: {},
|
|
997
|
+
});
|
|
998
|
+
xhr.addEventListener("readystatechange", (e) => {
|
|
999
|
+
if (
|
|
1000
|
+
ah.proxyXhr.readyState === 4 &&
|
|
1001
|
+
ah.request &&
|
|
1002
|
+
typeof ah.request.response === "function"
|
|
1003
|
+
) {
|
|
1004
|
+
const response = {
|
|
1005
|
+
finalUrl: ah.proxyXhr.responseURL,
|
|
1006
|
+
status: ah.proxyXhr.status,
|
|
1007
|
+
responseHeaders: parseHeaders(ah.proxyXhr.getAllResponseHeaders()),
|
|
1008
|
+
};
|
|
1009
|
+
const tempValues = {};
|
|
1010
|
+
for (const key of xhrResponses) {
|
|
1011
|
+
try {
|
|
1012
|
+
tempValues[key] = ah.originalXhr[key];
|
|
1013
|
+
} catch (err) {}
|
|
1014
|
+
defineProp(
|
|
1015
|
+
response,
|
|
1016
|
+
key,
|
|
1017
|
+
() => {
|
|
1018
|
+
return (response[key] = tempValues[key]);
|
|
1019
|
+
},
|
|
1020
|
+
(val) => {
|
|
1021
|
+
delete response[key];
|
|
1022
|
+
response[key] = val;
|
|
1023
|
+
}
|
|
826
1024
|
);
|
|
827
|
-
}
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
1025
|
+
}
|
|
1026
|
+
ah.resThenable = new AHRequest(ah.request)
|
|
1027
|
+
.waitForResponseKeys(response)
|
|
1028
|
+
.then(() => {
|
|
1029
|
+
for (const key of xhrResponses) {
|
|
1030
|
+
ah.proxyProps[key] = {
|
|
1031
|
+
get: () => {
|
|
1032
|
+
if (!(key in response)) response[key] = tempValues[key];
|
|
1033
|
+
return response[key];
|
|
1034
|
+
},
|
|
1035
|
+
};
|
|
1036
|
+
}
|
|
1037
|
+
});
|
|
1038
|
+
}
|
|
1039
|
+
ah.dispatchEvent(e);
|
|
1040
|
+
});
|
|
1041
|
+
xhr.addEventListener("load", (e) => ah.dispatchEvent(e));
|
|
1042
|
+
xhr.addEventListener("loadend", (e) => ah.dispatchEvent(e));
|
|
1043
|
+
for (const evt of xhrAsyncEvents) {
|
|
1044
|
+
const onEvt = "on" + evt;
|
|
1045
|
+
ah.proxyProps[onEvt] = {
|
|
1046
|
+
get: () => ah.proxyEvents[onEvt] || null,
|
|
1047
|
+
set: (val) => ah.addEvent(onEvt, val),
|
|
1048
|
+
};
|
|
831
1049
|
}
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
1050
|
+
for (const method of [
|
|
1051
|
+
"setRequestHeader",
|
|
1052
|
+
"addEventListener",
|
|
1053
|
+
"removeEventListener",
|
|
1054
|
+
"open",
|
|
1055
|
+
"send",
|
|
1056
|
+
]) {
|
|
1057
|
+
ah.proxyProps[method] = { value: ah[method] };
|
|
838
1058
|
}
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
1059
|
+
}
|
|
1060
|
+
toJSON() {} // Converting circular structure to JSON
|
|
1061
|
+
addEvent(type, event) {
|
|
1062
|
+
if (type.startsWith("on")) {
|
|
1063
|
+
this.proxyEvents[type] = typeof event === "function" ? event : null;
|
|
1064
|
+
} else {
|
|
1065
|
+
if (typeof event === "object" && event !== null)
|
|
1066
|
+
event = event.handleEvent;
|
|
1067
|
+
if (typeof event !== "function") return;
|
|
1068
|
+
this.proxyEvents[type] = this.proxyEvents[type] || new Set();
|
|
1069
|
+
this.proxyEvents[type].add(event);
|
|
845
1070
|
}
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
1071
|
+
}
|
|
1072
|
+
removeEvent(type, event) {
|
|
1073
|
+
if (type.startsWith("on")) {
|
|
1074
|
+
this.proxyEvents[type] = null;
|
|
1075
|
+
} else {
|
|
1076
|
+
if (typeof event === "object" && event !== null)
|
|
1077
|
+
event = event.handleEvent;
|
|
1078
|
+
this.proxyEvents[type] && this.proxyEvents[type].delete(event);
|
|
852
1079
|
}
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
};
|
|
864
|
-
this.openArgs = args;
|
|
865
|
-
this.resThenable = new SyncThenable();
|
|
866
|
-
[
|
|
867
|
-
"responseURL",
|
|
868
|
-
"readyState",
|
|
869
|
-
"status",
|
|
870
|
-
"statusText",
|
|
871
|
-
...xhrResponses,
|
|
872
|
-
].forEach((key) => {
|
|
873
|
-
delete this.proxyProps[key];
|
|
1080
|
+
}
|
|
1081
|
+
dispatchEvent(e) {
|
|
1082
|
+
e.stopImmediatePropagation = stopImmediatePropagation;
|
|
1083
|
+
defineProp(e, "target", () => this.proxyXhr);
|
|
1084
|
+
defineProp(e, "currentTarget", () => this.proxyXhr);
|
|
1085
|
+
this.proxyEvents[e.type] &&
|
|
1086
|
+
this.proxyEvents[e.type].forEach((fn) => {
|
|
1087
|
+
this.resThenable.then(
|
|
1088
|
+
() => !e.ajaxHooker_isStopped && fn.call(this.proxyXhr, e)
|
|
1089
|
+
);
|
|
874
1090
|
});
|
|
875
|
-
|
|
1091
|
+
if (e.ajaxHooker_isStopped) return;
|
|
1092
|
+
const onEvent = this.proxyEvents["on" + e.type];
|
|
1093
|
+
onEvent && this.resThenable.then(onEvent.bind(this.proxyXhr, e));
|
|
1094
|
+
}
|
|
1095
|
+
setRequestHeader(header, value) {
|
|
1096
|
+
this.originalXhr.setRequestHeader(header, value);
|
|
1097
|
+
if (!this.request) return;
|
|
1098
|
+
const headers = this.request.headers;
|
|
1099
|
+
headers[header] =
|
|
1100
|
+
header in headers ? `${headers[header]}, ${value}` : value;
|
|
1101
|
+
}
|
|
1102
|
+
addEventListener(...args) {
|
|
1103
|
+
if (xhrAsyncEvents.includes(args[0])) {
|
|
1104
|
+
this.addEvent(args[0], args[1]);
|
|
1105
|
+
} else {
|
|
1106
|
+
this.originalXhr.addEventListener(...args);
|
|
876
1107
|
}
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
new AHRequest(request).waitForRequestKeys().then(() => {
|
|
884
|
-
if (request.abort) {
|
|
885
|
-
if (typeof request.response === "function") {
|
|
886
|
-
Object.assign(ah.proxyProps, {
|
|
887
|
-
responseURL: { value: request.url },
|
|
888
|
-
readyState: { value: 4 },
|
|
889
|
-
status: { value: 200 },
|
|
890
|
-
statusText: { value: "OK" },
|
|
891
|
-
});
|
|
892
|
-
xhrAsyncEvents.forEach((evt) =>
|
|
893
|
-
xhr.dispatchEvent(new Event(evt))
|
|
894
|
-
);
|
|
895
|
-
}
|
|
896
|
-
} else {
|
|
897
|
-
xhr.open(
|
|
898
|
-
request.method,
|
|
899
|
-
request.url,
|
|
900
|
-
request.async,
|
|
901
|
-
...ah.openArgs
|
|
902
|
-
);
|
|
903
|
-
for (const header in request.headers) {
|
|
904
|
-
xhr.setRequestHeader(header, request.headers[header]);
|
|
905
|
-
}
|
|
906
|
-
xhr.send(request.data);
|
|
907
|
-
}
|
|
908
|
-
});
|
|
1108
|
+
}
|
|
1109
|
+
removeEventListener(...args) {
|
|
1110
|
+
if (xhrAsyncEvents.includes(args[0])) {
|
|
1111
|
+
this.removeEvent(args[0], args[1]);
|
|
1112
|
+
} else {
|
|
1113
|
+
this.originalXhr.removeEventListener(...args);
|
|
909
1114
|
}
|
|
910
1115
|
}
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
1116
|
+
open(method, url, async = true, ...args) {
|
|
1117
|
+
this.request = {
|
|
1118
|
+
type: "xhr",
|
|
1119
|
+
url: url.toString(),
|
|
1120
|
+
method: method.toUpperCase(),
|
|
1121
|
+
abort: false,
|
|
1122
|
+
headers: {},
|
|
1123
|
+
data: null,
|
|
1124
|
+
response: null,
|
|
1125
|
+
async: !!async,
|
|
1126
|
+
};
|
|
1127
|
+
this.openArgs = args;
|
|
1128
|
+
this.resThenable = new SyncThenable();
|
|
1129
|
+
[
|
|
1130
|
+
"responseURL",
|
|
1131
|
+
"readyState",
|
|
1132
|
+
"status",
|
|
1133
|
+
"statusText",
|
|
1134
|
+
...xhrResponses,
|
|
1135
|
+
].forEach((key) => {
|
|
1136
|
+
delete this.proxyProps[key];
|
|
1137
|
+
});
|
|
1138
|
+
return this.originalXhr.open(method, url, async, ...args);
|
|
917
1139
|
}
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
const init = {};
|
|
926
|
-
if (getType(url) === "[object Request]") {
|
|
927
|
-
for (const prop of fetchInitProps) init[prop] = url[prop];
|
|
928
|
-
if (url.body) init.body = await url.arrayBuffer();
|
|
929
|
-
url = url.url;
|
|
930
|
-
}
|
|
931
|
-
url = url.toString();
|
|
932
|
-
Object.assign(init, options);
|
|
933
|
-
init.method = init.method || "GET";
|
|
934
|
-
init.headers = init.headers || {};
|
|
935
|
-
const request = {
|
|
936
|
-
type: "fetch",
|
|
937
|
-
url: url,
|
|
938
|
-
method: init.method.toUpperCase(),
|
|
939
|
-
abort: false,
|
|
940
|
-
headers: parseHeaders(init.headers),
|
|
941
|
-
data: init.body,
|
|
942
|
-
response: null,
|
|
943
|
-
async: true,
|
|
944
|
-
};
|
|
945
|
-
const req = new AHRequest(request);
|
|
946
|
-
await req.waitForRequestKeys();
|
|
1140
|
+
send(data) {
|
|
1141
|
+
const ah = this;
|
|
1142
|
+
const xhr = ah.originalXhr;
|
|
1143
|
+
const request = ah.request;
|
|
1144
|
+
if (!request) return xhr.send(data);
|
|
1145
|
+
request.data = data;
|
|
1146
|
+
new AHRequest(request).waitForRequestKeys().then(() => {
|
|
947
1147
|
if (request.abort) {
|
|
948
1148
|
if (typeof request.response === "function") {
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
await req.waitForResponseKeys(response);
|
|
955
|
-
const key = fetchResponses.find((k) => k in response);
|
|
956
|
-
let val = response[key];
|
|
957
|
-
if (key === "json" && typeof val === "object") {
|
|
958
|
-
val = catchError(JSON.stringify.bind(JSON), val);
|
|
959
|
-
}
|
|
960
|
-
const res = new Response(val, {
|
|
961
|
-
status: 200,
|
|
962
|
-
statusText: "OK",
|
|
1149
|
+
Object.assign(ah.proxyProps, {
|
|
1150
|
+
responseURL: { value: request.url },
|
|
1151
|
+
readyState: { value: 4 },
|
|
1152
|
+
status: { value: 200 },
|
|
1153
|
+
statusText: { value: "OK" },
|
|
963
1154
|
});
|
|
964
|
-
|
|
965
|
-
defineProp(res, "url", () => request.url);
|
|
966
|
-
resolve(res);
|
|
967
|
-
} else {
|
|
968
|
-
reject(new DOMException("aborted", "AbortError"));
|
|
1155
|
+
xhrAsyncEvents.forEach((evt) => xhr.dispatchEvent(new Event(evt)));
|
|
969
1156
|
}
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
init.body = request.data;
|
|
975
|
-
winAh.realFetch.call(win, request.url, init).then((res) => {
|
|
976
|
-
if (typeof request.response === "function") {
|
|
977
|
-
const response = {
|
|
978
|
-
finalUrl: res.url,
|
|
979
|
-
status: res.status,
|
|
980
|
-
responseHeaders: parseHeaders(res.headers),
|
|
981
|
-
};
|
|
982
|
-
fetchResponses.forEach(
|
|
983
|
-
(key) =>
|
|
984
|
-
(res[key] = function () {
|
|
985
|
-
if (key in response) return Promise.resolve(response[key]);
|
|
986
|
-
return resProto[key].call(this).then((val) => {
|
|
987
|
-
response[key] = val;
|
|
988
|
-
return req
|
|
989
|
-
.waitForResponseKeys(response)
|
|
990
|
-
.then(() => (key in response ? response[key] : val));
|
|
991
|
-
});
|
|
992
|
-
})
|
|
993
|
-
);
|
|
1157
|
+
} else {
|
|
1158
|
+
xhr.open(request.method, request.url, request.async, ...ah.openArgs);
|
|
1159
|
+
for (const header in request.headers) {
|
|
1160
|
+
xhr.setRequestHeader(header, request.headers[header]);
|
|
994
1161
|
}
|
|
995
|
-
|
|
996
|
-
}
|
|
1162
|
+
xhr.send(request.data);
|
|
1163
|
+
}
|
|
997
1164
|
});
|
|
998
1165
|
}
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
return res;
|
|
1004
|
-
}
|
|
1005
|
-
winAh = win.__ajaxHooker = winAh || {
|
|
1006
|
-
version,
|
|
1007
|
-
fakeXHR,
|
|
1008
|
-
fakeFetch,
|
|
1009
|
-
fakeFetchClone,
|
|
1010
|
-
realXHR: win.XMLHttpRequest,
|
|
1011
|
-
realFetch: win.fetch,
|
|
1012
|
-
realFetchClone: resProto.clone,
|
|
1013
|
-
hookInsts: new Set(),
|
|
1014
|
-
};
|
|
1015
|
-
if (winAh.version !== version)
|
|
1166
|
+
}
|
|
1167
|
+
function fakeXHR() {
|
|
1168
|
+
const xhr = new winAh.realXHR();
|
|
1169
|
+
if ("__ajaxHooker" in xhr)
|
|
1016
1170
|
console.warn("检测到不同版本的ajaxHooker,可能发生冲突!");
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1171
|
+
xhr.__ajaxHooker = new XhrHooker(xhr);
|
|
1172
|
+
return xhr.__ajaxHooker.proxyXhr;
|
|
1173
|
+
}
|
|
1174
|
+
fakeXHR.prototype = win.XMLHttpRequest.prototype;
|
|
1175
|
+
Object.keys(win.XMLHttpRequest).forEach(
|
|
1176
|
+
(key) => (fakeXHR[key] = win.XMLHttpRequest[key])
|
|
1177
|
+
);
|
|
1178
|
+
function fakeFetch(url, options = {}) {
|
|
1179
|
+
if (!url) return winAh.realFetch.call(win, url, options);
|
|
1180
|
+
return new Promise(async (resolve, reject) => {
|
|
1181
|
+
const init = {};
|
|
1182
|
+
if (getType(url) === "[object Request]") {
|
|
1183
|
+
for (const prop of fetchInitProps) init[prop] = url[prop];
|
|
1184
|
+
if (url.body) init.body = await url.arrayBuffer();
|
|
1185
|
+
url = url.url;
|
|
1186
|
+
}
|
|
1187
|
+
url = url.toString();
|
|
1188
|
+
Object.assign(init, options);
|
|
1189
|
+
init.method = init.method || "GET";
|
|
1190
|
+
init.headers = init.headers || {};
|
|
1191
|
+
const request = {
|
|
1192
|
+
type: "fetch",
|
|
1193
|
+
url: url,
|
|
1194
|
+
method: init.method.toUpperCase(),
|
|
1195
|
+
abort: false,
|
|
1196
|
+
headers: parseHeaders(init.headers),
|
|
1197
|
+
data: init.body,
|
|
1198
|
+
response: null,
|
|
1199
|
+
async: true,
|
|
1200
|
+
};
|
|
1201
|
+
const req = new AHRequest(request);
|
|
1202
|
+
await req.waitForRequestKeys();
|
|
1203
|
+
if (request.abort) {
|
|
1204
|
+
if (typeof request.response === "function") {
|
|
1205
|
+
const response = {
|
|
1206
|
+
finalUrl: request.url,
|
|
1207
|
+
status: 200,
|
|
1208
|
+
responseHeaders: {},
|
|
1209
|
+
};
|
|
1210
|
+
await req.waitForResponseKeys(response);
|
|
1211
|
+
const key = fetchResponses.find((k) => k in response);
|
|
1212
|
+
let val = response[key];
|
|
1213
|
+
if (key === "json" && typeof val === "object") {
|
|
1214
|
+
val = catchError(JSON.stringify.bind(JSON), val);
|
|
1215
|
+
}
|
|
1216
|
+
const res = new Response(val, {
|
|
1217
|
+
status: 200,
|
|
1218
|
+
statusText: "OK",
|
|
1219
|
+
});
|
|
1220
|
+
defineProp(res, "type", () => "basic");
|
|
1221
|
+
defineProp(res, "url", () => request.url);
|
|
1222
|
+
resolve(res);
|
|
1223
|
+
} else {
|
|
1224
|
+
reject(new DOMException("aborted", "AbortError"));
|
|
1030
1225
|
}
|
|
1031
|
-
return
|
|
1226
|
+
return;
|
|
1032
1227
|
}
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1228
|
+
init.method = request.method;
|
|
1229
|
+
init.headers = request.headers;
|
|
1230
|
+
init.body = request.data;
|
|
1231
|
+
winAh.realFetch.call(win, request.url, init).then((res) => {
|
|
1232
|
+
if (typeof request.response === "function") {
|
|
1233
|
+
const response = {
|
|
1234
|
+
finalUrl: res.url,
|
|
1235
|
+
status: res.status,
|
|
1236
|
+
responseHeaders: parseHeaders(res.headers),
|
|
1237
|
+
};
|
|
1238
|
+
fetchResponses.forEach(
|
|
1239
|
+
(key) =>
|
|
1240
|
+
(res[key] = function () {
|
|
1241
|
+
if (key in response) return Promise.resolve(response[key]);
|
|
1242
|
+
return resProto[key].call(this).then((val) => {
|
|
1243
|
+
response[key] = val;
|
|
1244
|
+
return req
|
|
1245
|
+
.waitForResponseKeys(response)
|
|
1246
|
+
.then(() => (key in response ? response[key] : val));
|
|
1247
|
+
});
|
|
1248
|
+
})
|
|
1249
|
+
);
|
|
1040
1250
|
}
|
|
1041
|
-
|
|
1251
|
+
resolve(res);
|
|
1252
|
+
}, reject);
|
|
1253
|
+
});
|
|
1254
|
+
}
|
|
1255
|
+
function fakeFetchClone() {
|
|
1256
|
+
const descriptors = Object.getOwnPropertyDescriptors(this);
|
|
1257
|
+
const res = winAh.realFetchClone.call(this);
|
|
1258
|
+
Object.defineProperties(res, descriptors);
|
|
1259
|
+
return res;
|
|
1260
|
+
}
|
|
1261
|
+
winAh = win.__ajaxHooker = winAh || {
|
|
1262
|
+
version,
|
|
1263
|
+
fakeXHR,
|
|
1264
|
+
fakeFetch,
|
|
1265
|
+
fakeFetchClone,
|
|
1266
|
+
realXHR: win.XMLHttpRequest,
|
|
1267
|
+
realFetch: win.fetch,
|
|
1268
|
+
realFetchClone: resProto.clone,
|
|
1269
|
+
hookInsts: new Set(),
|
|
1270
|
+
};
|
|
1271
|
+
if (winAh.version !== version)
|
|
1272
|
+
console.warn("检测到不同版本的ajaxHooker,可能发生冲突!");
|
|
1273
|
+
win.XMLHttpRequest = winAh.fakeXHR;
|
|
1274
|
+
win.fetch = winAh.fakeFetch;
|
|
1275
|
+
resProto.clone = winAh.fakeFetchClone;
|
|
1276
|
+
winAh.hookInsts.add(hookInst);
|
|
1277
|
+
// 针对头条、抖音 secsdk.umd.js 的兼容性处理
|
|
1278
|
+
class AHFunction extends Function {
|
|
1279
|
+
call(thisArg, ...args) {
|
|
1280
|
+
if (
|
|
1281
|
+
thisArg &&
|
|
1282
|
+
thisArg.__ajaxHooker &&
|
|
1283
|
+
thisArg.__ajaxHooker.proxyXhr === thisArg
|
|
1284
|
+
) {
|
|
1285
|
+
thisArg = thisArg.__ajaxHooker.originalXhr;
|
|
1042
1286
|
}
|
|
1287
|
+
return Reflect.apply(this, thisArg, args);
|
|
1043
1288
|
}
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
);
|
|
1053
|
-
Object.setPrototypeOf(
|
|
1054
|
-
csrf.nativeXMLHttpRequestSend,
|
|
1055
|
-
AHFunction.prototype
|
|
1056
|
-
);
|
|
1289
|
+
apply(thisArg, args) {
|
|
1290
|
+
if (
|
|
1291
|
+
thisArg &&
|
|
1292
|
+
thisArg.__ajaxHooker &&
|
|
1293
|
+
thisArg.__ajaxHooker.proxyXhr === thisArg
|
|
1294
|
+
) {
|
|
1295
|
+
thisArg = thisArg.__ajaxHooker.originalXhr;
|
|
1296
|
+
}
|
|
1297
|
+
return Reflect.apply(this, thisArg, args || []);
|
|
1057
1298
|
}
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1299
|
+
}
|
|
1300
|
+
function hookSecsdk(csrf) {
|
|
1301
|
+
Object.setPrototypeOf(
|
|
1302
|
+
csrf.nativeXMLHttpRequestSetRequestHeader,
|
|
1303
|
+
AHFunction.prototype
|
|
1304
|
+
);
|
|
1305
|
+
Object.setPrototypeOf(csrf.nativeXMLHttpRequestOpen, AHFunction.prototype);
|
|
1306
|
+
Object.setPrototypeOf(csrf.nativeXMLHttpRequestSend, AHFunction.prototype);
|
|
1307
|
+
}
|
|
1308
|
+
if (win.secsdk) {
|
|
1309
|
+
if (win.secsdk.csrf && win.secsdk.csrf.nativeXMLHttpRequestOpen)
|
|
1310
|
+
hookSecsdk(win.secsdk.csrf);
|
|
1311
|
+
} else {
|
|
1312
|
+
defineProp(win, "secsdk", emptyFn, (secsdk) => {
|
|
1313
|
+
delete win.secsdk;
|
|
1314
|
+
win.secsdk = secsdk;
|
|
1315
|
+
defineProp(secsdk, "csrf", emptyFn, (csrf) => {
|
|
1316
|
+
delete secsdk.csrf;
|
|
1317
|
+
secsdk.csrf = csrf;
|
|
1318
|
+
if (csrf.nativeXMLHttpRequestOpen) hookSecsdk(csrf);
|
|
1070
1319
|
});
|
|
1071
|
-
}
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
}
|
|
1091
|
-
}
|
|
1092
|
-
}
|
|
1320
|
+
});
|
|
1321
|
+
}
|
|
1322
|
+
return {
|
|
1323
|
+
hook: (fn) => hookInst.hookFns.push(fn),
|
|
1324
|
+
filter: (arr) => {
|
|
1325
|
+
if (Array.isArray(arr)) hookInst.filters = arr;
|
|
1326
|
+
},
|
|
1327
|
+
protect: () => {
|
|
1328
|
+
readonly(win, "XMLHttpRequest", winAh.fakeXHR);
|
|
1329
|
+
readonly(win, "fetch", winAh.fakeFetch);
|
|
1330
|
+
readonly(resProto, "clone", winAh.fakeFetchClone);
|
|
1331
|
+
},
|
|
1332
|
+
unhook: () => {
|
|
1333
|
+
winAh.hookInsts.delete(hookInst);
|
|
1334
|
+
if (!winAh.hookInsts.size) {
|
|
1335
|
+
writable(win, "XMLHttpRequest", winAh.realXHR);
|
|
1336
|
+
writable(win, "fetch", winAh.realFetch);
|
|
1337
|
+
writable(resProto, "clone", winAh.realFetchClone);
|
|
1338
|
+
delete win.__ajaxHooker;
|
|
1339
|
+
}
|
|
1340
|
+
},
|
|
1341
|
+
};
|
|
1093
1342
|
};
|
|
1094
1343
|
|
|
1095
1344
|
// ==UserScript==
|
|
@@ -1621,7 +1870,7 @@ class GMMenu {
|
|
|
1621
1870
|
menuOptions = [menuOptions];
|
|
1622
1871
|
}
|
|
1623
1872
|
for (let index = 0; index < menuOptions.length; index++) {
|
|
1624
|
-
let cloneMenuOptionData =
|
|
1873
|
+
let cloneMenuOptionData = commonUtil.deepClone(menuOptions[index].data);
|
|
1625
1874
|
const { showText, clickCallBack } = this.handleMenuData(cloneMenuOptionData);
|
|
1626
1875
|
let menuId = that.context.GM_Api.registerMenuCommand(showText, clickCallBack);
|
|
1627
1876
|
menuOptions[index].id = menuId;
|
|
@@ -1793,14 +2042,14 @@ class GMMenu {
|
|
|
1793
2042
|
const option = menuOption[index];
|
|
1794
2043
|
this.MenuHandle.$data.data.push({
|
|
1795
2044
|
data: option,
|
|
1796
|
-
id:
|
|
2045
|
+
id: void 0,
|
|
1797
2046
|
});
|
|
1798
2047
|
}
|
|
1799
2048
|
}
|
|
1800
2049
|
else {
|
|
1801
2050
|
this.MenuHandle.$data.data.push({
|
|
1802
2051
|
data: menuOption,
|
|
1803
|
-
id:
|
|
2052
|
+
id: void 0,
|
|
1804
2053
|
});
|
|
1805
2054
|
}
|
|
1806
2055
|
}
|
|
@@ -2023,16 +2272,12 @@ class Hooks {
|
|
|
2023
2272
|
return "";
|
|
2024
2273
|
}
|
|
2025
2274
|
try {
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
"return _context['realFunc_" +
|
|
2033
|
-
_funcName +
|
|
2034
|
-
"'].apply(obj,args);\n" +
|
|
2035
|
-
"};");
|
|
2275
|
+
new Function("_context", "_funcName", "hookFunc", `_context[_funcName] = function ${_funcName}() {
|
|
2276
|
+
let args = Array.prototype.slice.call(arguments, 0);
|
|
2277
|
+
let obj = this;
|
|
2278
|
+
hookFunc.apply(obj, args);
|
|
2279
|
+
return _context['realFunc_${_funcName}'].apply(obj, args);
|
|
2280
|
+
};`)(_context, _funcName, hookFunc);
|
|
2036
2281
|
_context[_funcName].prototype.isHooked = true;
|
|
2037
2282
|
return true;
|
|
2038
2283
|
}
|
|
@@ -2292,14 +2537,14 @@ class Httpx {
|
|
|
2292
2537
|
if (typeof args[1] === "object") {
|
|
2293
2538
|
/* 处理第二个参数details */
|
|
2294
2539
|
let optionArg = args[1];
|
|
2295
|
-
|
|
2540
|
+
commonUtil.assign(option, optionArg, true);
|
|
2296
2541
|
option.url = url;
|
|
2297
2542
|
}
|
|
2298
2543
|
}
|
|
2299
2544
|
else {
|
|
2300
2545
|
/* 传入的是配置 */
|
|
2301
2546
|
let optionArg = args[0];
|
|
2302
|
-
|
|
2547
|
+
commonUtil.assign(option, optionArg, true);
|
|
2303
2548
|
}
|
|
2304
2549
|
return option;
|
|
2305
2550
|
},
|
|
@@ -2332,7 +2577,7 @@ class Httpx {
|
|
|
2332
2577
|
responseType: userRequestOption.responseType ||
|
|
2333
2578
|
this.context.#defaultRequestOption.responseType,
|
|
2334
2579
|
/* 对象使用深拷贝 */
|
|
2335
|
-
headers:
|
|
2580
|
+
headers: commonUtil.deepClone(this.context.#defaultRequestOption.headers),
|
|
2336
2581
|
data: userRequestOption.data || this.context.#defaultRequestOption.data,
|
|
2337
2582
|
redirect: userRequestOption.redirect ||
|
|
2338
2583
|
this.context.#defaultRequestOption.redirect,
|
|
@@ -2345,7 +2590,7 @@ class Httpx {
|
|
|
2345
2590
|
revalidate: userRequestOption.revalidate ||
|
|
2346
2591
|
this.context.#defaultRequestOption.revalidate,
|
|
2347
2592
|
/* 对象使用深拷贝 */
|
|
2348
|
-
context:
|
|
2593
|
+
context: commonUtil.deepClone(userRequestOption.context ||
|
|
2349
2594
|
this.context.#defaultRequestOption.context),
|
|
2350
2595
|
overrideMimeType: userRequestOption.overrideMimeType ||
|
|
2351
2596
|
this.context.#defaultRequestOption.overrideMimeType,
|
|
@@ -2353,7 +2598,7 @@ class Httpx {
|
|
|
2353
2598
|
this.context.#defaultRequestOption.anonymous,
|
|
2354
2599
|
fetch: userRequestOption.fetch || this.context.#defaultRequestOption.fetch,
|
|
2355
2600
|
/* 对象使用深拷贝 */
|
|
2356
|
-
fetchInit:
|
|
2601
|
+
fetchInit: commonUtil.deepClone(this.context.#defaultRequestOption.fetchInit),
|
|
2357
2602
|
allowInterceptConfig: {
|
|
2358
2603
|
beforeRequest: this.context.#defaultRequestOption
|
|
2359
2604
|
.allowInterceptConfig.beforeRequest,
|
|
@@ -2579,12 +2824,12 @@ class Httpx {
|
|
|
2579
2824
|
Object.keys(option).forEach((keyName) => {
|
|
2580
2825
|
if (option[keyName] == null ||
|
|
2581
2826
|
(option[keyName] instanceof Function &&
|
|
2582
|
-
|
|
2827
|
+
commonUtil.isNull(option[keyName]))) {
|
|
2583
2828
|
Reflect.deleteProperty(option, keyName);
|
|
2584
2829
|
return;
|
|
2585
2830
|
}
|
|
2586
2831
|
});
|
|
2587
|
-
if (
|
|
2832
|
+
if (commonUtil.isNull(option.url)) {
|
|
2588
2833
|
throw new TypeError(`Utils.Httpx 参数 url不符合要求: ${option.url}`);
|
|
2589
2834
|
}
|
|
2590
2835
|
return option;
|
|
@@ -2783,10 +3028,10 @@ class Httpx {
|
|
|
2783
3028
|
/* X浏览器会因为设置了responseType导致不返回responseText */
|
|
2784
3029
|
let originResponse = argsResult[0];
|
|
2785
3030
|
/* responseText为空,response不为空的情况 */
|
|
2786
|
-
if (
|
|
2787
|
-
|
|
3031
|
+
if (commonUtil.isNull(originResponse["responseText"]) &&
|
|
3032
|
+
commonUtil.isNotNull(originResponse["response"])) {
|
|
2788
3033
|
if (typeof originResponse["response"] === "object") {
|
|
2789
|
-
|
|
3034
|
+
TryCatch().run(() => {
|
|
2790
3035
|
originResponse["responseText"] = JSON.stringify(originResponse["response"]);
|
|
2791
3036
|
});
|
|
2792
3037
|
}
|
|
@@ -2803,7 +3048,7 @@ class Httpx {
|
|
|
2803
3048
|
// 自定义个新的response
|
|
2804
3049
|
let httpxResponse = httpxResponseText;
|
|
2805
3050
|
if (details.responseType === "json") {
|
|
2806
|
-
httpxResponse =
|
|
3051
|
+
httpxResponse = commonUtil.toJSON(httpxResponseText);
|
|
2807
3052
|
}
|
|
2808
3053
|
else if (details.responseType === "document") {
|
|
2809
3054
|
let parser = new DOMParser();
|
|
@@ -2947,13 +3192,13 @@ class Httpx {
|
|
|
2947
3192
|
status: fetchResponse.status,
|
|
2948
3193
|
statusText: fetchResponse.statusText,
|
|
2949
3194
|
// @ts-ignore
|
|
2950
|
-
response:
|
|
3195
|
+
response: void 0,
|
|
2951
3196
|
responseFetchHeaders: fetchResponse.headers,
|
|
2952
3197
|
responseHeaders: "",
|
|
2953
3198
|
// @ts-ignore
|
|
2954
|
-
responseText:
|
|
3199
|
+
responseText: void 0,
|
|
2955
3200
|
responseType: option.responseType,
|
|
2956
|
-
responseXML:
|
|
3201
|
+
responseXML: void 0,
|
|
2957
3202
|
};
|
|
2958
3203
|
Object.assign(httpxResponse, option.context || {});
|
|
2959
3204
|
// 把headers转为字符串
|
|
@@ -3013,7 +3258,7 @@ class Httpx {
|
|
|
3013
3258
|
(typeof fetchResponseType === "string" &&
|
|
3014
3259
|
fetchResponseType.includes("application/json"))) {
|
|
3015
3260
|
// response返回格式是JSON格式
|
|
3016
|
-
response =
|
|
3261
|
+
response = commonUtil.toJSON(responseText);
|
|
3017
3262
|
}
|
|
3018
3263
|
else if (option.responseType === "document" ||
|
|
3019
3264
|
option.responseType == null) {
|
|
@@ -3065,30 +3310,30 @@ class Httpx {
|
|
|
3065
3310
|
* 默认配置
|
|
3066
3311
|
*/
|
|
3067
3312
|
#defaultRequestOption = {
|
|
3068
|
-
url:
|
|
3313
|
+
url: void 0,
|
|
3069
3314
|
timeout: 5000,
|
|
3070
3315
|
async: false,
|
|
3071
|
-
responseType:
|
|
3072
|
-
headers:
|
|
3073
|
-
data:
|
|
3074
|
-
redirect:
|
|
3075
|
-
cookie:
|
|
3076
|
-
cookiePartition:
|
|
3077
|
-
binary:
|
|
3078
|
-
nocache:
|
|
3079
|
-
revalidate:
|
|
3080
|
-
context:
|
|
3081
|
-
overrideMimeType:
|
|
3082
|
-
anonymous:
|
|
3083
|
-
fetch:
|
|
3084
|
-
fetchInit:
|
|
3316
|
+
responseType: void 0,
|
|
3317
|
+
headers: void 0,
|
|
3318
|
+
data: void 0,
|
|
3319
|
+
redirect: void 0,
|
|
3320
|
+
cookie: void 0,
|
|
3321
|
+
cookiePartition: void 0,
|
|
3322
|
+
binary: void 0,
|
|
3323
|
+
nocache: void 0,
|
|
3324
|
+
revalidate: void 0,
|
|
3325
|
+
context: void 0,
|
|
3326
|
+
overrideMimeType: void 0,
|
|
3327
|
+
anonymous: void 0,
|
|
3328
|
+
fetch: void 0,
|
|
3329
|
+
fetchInit: void 0,
|
|
3085
3330
|
allowInterceptConfig: {
|
|
3086
3331
|
beforeRequest: true,
|
|
3087
3332
|
afterResponseSuccess: true,
|
|
3088
3333
|
afterResponseError: true,
|
|
3089
3334
|
},
|
|
3090
|
-
user:
|
|
3091
|
-
password:
|
|
3335
|
+
user: void 0,
|
|
3336
|
+
password: void 0,
|
|
3092
3337
|
onabort() { },
|
|
3093
3338
|
onerror() { },
|
|
3094
3339
|
ontimeout() { },
|
|
@@ -3100,7 +3345,7 @@ class Httpx {
|
|
|
3100
3345
|
/**
|
|
3101
3346
|
* `baseURL` 将自动加在 `url` 前面,除非 `url` 是一个绝对 URL。
|
|
3102
3347
|
*/
|
|
3103
|
-
baseURL:
|
|
3348
|
+
baseURL: void 0,
|
|
3104
3349
|
/**
|
|
3105
3350
|
* 当前使用请求时,输出请求的配置,一般用于DEBUG|DEV
|
|
3106
3351
|
*/
|
|
@@ -3114,7 +3359,7 @@ class Httpx {
|
|
|
3114
3359
|
if (typeof option.xmlHttpRequest !== "function") {
|
|
3115
3360
|
console.warn("[Httpx-constructor] 未传入GM_xmlhttpRequest函数或传入的GM_xmlhttpRequest不是Function,将默认使用window.fetch");
|
|
3116
3361
|
}
|
|
3117
|
-
|
|
3362
|
+
commonUtil.coverObjectFunctionThis(this);
|
|
3118
3363
|
this.interceptors.request.context = this;
|
|
3119
3364
|
this.interceptors.response.context = this;
|
|
3120
3365
|
this.config(option);
|
|
@@ -3127,8 +3372,8 @@ class Httpx {
|
|
|
3127
3372
|
if (typeof option.xmlHttpRequest === "function") {
|
|
3128
3373
|
this.GM_Api.xmlHttpRequest = option.xmlHttpRequest;
|
|
3129
3374
|
}
|
|
3130
|
-
this.#defaultRequestOption =
|
|
3131
|
-
this.#defaultInitOption =
|
|
3375
|
+
this.#defaultRequestOption = commonUtil.assign(this.#defaultRequestOption, option);
|
|
3376
|
+
this.#defaultInitOption = commonUtil.assign(this.#defaultInitOption, option);
|
|
3132
3377
|
}
|
|
3133
3378
|
/**
|
|
3134
3379
|
* 拦截器
|
|
@@ -3505,7 +3750,7 @@ class indexedDB {
|
|
|
3505
3750
|
success: false,
|
|
3506
3751
|
code: that.#statusCode.getFailed.code,
|
|
3507
3752
|
msg: that.#statusCode.getFailed.msg,
|
|
3508
|
-
data:
|
|
3753
|
+
data: void 0,
|
|
3509
3754
|
});
|
|
3510
3755
|
}
|
|
3511
3756
|
else {
|
|
@@ -3515,7 +3760,7 @@ class indexedDB {
|
|
|
3515
3760
|
let result = target.result;
|
|
3516
3761
|
/* result 返回的是 {key: string, value: any} */
|
|
3517
3762
|
/* 键值对存储 */
|
|
3518
|
-
let data = result ? result.value :
|
|
3763
|
+
let data = result ? result.value : void 0;
|
|
3519
3764
|
if (data == null) {
|
|
3520
3765
|
resolve({
|
|
3521
3766
|
success: true,
|
|
@@ -3542,7 +3787,7 @@ class indexedDB {
|
|
|
3542
3787
|
success: false,
|
|
3543
3788
|
code: that.#statusCode.getFailed.code,
|
|
3544
3789
|
msg: that.#statusCode.getFailed.msg,
|
|
3545
|
-
data:
|
|
3790
|
+
data: void 0,
|
|
3546
3791
|
event: event,
|
|
3547
3792
|
});
|
|
3548
3793
|
};
|
|
@@ -3692,7 +3937,7 @@ class LockFunction {
|
|
|
3692
3937
|
#flag = false;
|
|
3693
3938
|
#delayTime = 0;
|
|
3694
3939
|
#callback;
|
|
3695
|
-
#
|
|
3940
|
+
#timeId = void 0;
|
|
3696
3941
|
lock;
|
|
3697
3942
|
unlock;
|
|
3698
3943
|
run;
|
|
@@ -3702,23 +3947,22 @@ class LockFunction {
|
|
|
3702
3947
|
this.#callback = callback;
|
|
3703
3948
|
if (typeof context === "number") {
|
|
3704
3949
|
this.#delayTime = context;
|
|
3705
|
-
this.#context = utils;
|
|
3706
3950
|
}
|
|
3707
3951
|
else {
|
|
3708
3952
|
this.#delayTime = delayTime;
|
|
3709
|
-
this.#context = context;
|
|
3710
3953
|
}
|
|
3711
3954
|
/**
|
|
3712
3955
|
* 锁
|
|
3713
3956
|
*/
|
|
3714
3957
|
this.lock = function () {
|
|
3715
3958
|
that.#flag = true;
|
|
3959
|
+
clearTimeout(that.#timeId);
|
|
3716
3960
|
};
|
|
3717
3961
|
/**
|
|
3718
3962
|
* 解锁
|
|
3719
3963
|
*/
|
|
3720
3964
|
this.unlock = function () {
|
|
3721
|
-
|
|
3965
|
+
that.#timeId = setTimeout(() => {
|
|
3722
3966
|
that.#flag = false;
|
|
3723
3967
|
}, that.#delayTime);
|
|
3724
3968
|
};
|
|
@@ -3736,7 +3980,7 @@ class LockFunction {
|
|
|
3736
3980
|
return;
|
|
3737
3981
|
}
|
|
3738
3982
|
that.lock();
|
|
3739
|
-
await that.#callback.apply(
|
|
3983
|
+
await that.#callback.apply(this, args);
|
|
3740
3984
|
that.unlock();
|
|
3741
3985
|
};
|
|
3742
3986
|
}
|
|
@@ -4024,7 +4268,7 @@ class Progress {
|
|
|
4024
4268
|
* @param paramConfig 配置信息
|
|
4025
4269
|
*/
|
|
4026
4270
|
constructor(paramConfig) {
|
|
4027
|
-
this.#config =
|
|
4271
|
+
this.#config = commonUtil.assign(this.#config, paramConfig);
|
|
4028
4272
|
if (!(this.#config.canvasNode instanceof HTMLCanvasElement)) {
|
|
4029
4273
|
throw new Error("Utils.Progress 参数 canvasNode 必须是 HTMLCanvasElement");
|
|
4030
4274
|
}
|
|
@@ -4076,97 +4320,12 @@ class Progress {
|
|
|
4076
4320
|
let txt = parseInt(this.#config.progress.toString()) + "%";
|
|
4077
4321
|
this.#ctx.font = this.#config.fontSize + "px SimHei";
|
|
4078
4322
|
/* 获取文本宽度 */
|
|
4079
|
-
let w = this.#ctx.measureText(txt).width;
|
|
4080
|
-
let h = this.#config.fontSize / 2;
|
|
4081
|
-
this.#ctx.fillStyle = this.#config.textColor;
|
|
4082
|
-
this.#ctx.fillText(txt, this.#width / 2 - w / 2, this.#height / 2 + h / 2);
|
|
4083
|
-
}
|
|
4084
|
-
}
|
|
4085
|
-
|
|
4086
|
-
const TryCatch = function (...args) {
|
|
4087
|
-
/* 定义变量和函数 */
|
|
4088
|
-
let callbackFunction = null;
|
|
4089
|
-
let context = null;
|
|
4090
|
-
let handleError = (error) => { };
|
|
4091
|
-
let defaultDetails = {
|
|
4092
|
-
log: true,
|
|
4093
|
-
};
|
|
4094
|
-
const TryCatchCore = {
|
|
4095
|
-
/**
|
|
4096
|
-
*
|
|
4097
|
-
* @param paramDetails 配置
|
|
4098
|
-
* @returns
|
|
4099
|
-
*/
|
|
4100
|
-
config(paramDetails) {
|
|
4101
|
-
defaultDetails = utils.assign(defaultDetails, paramDetails);
|
|
4102
|
-
return TryCatchCore;
|
|
4103
|
-
},
|
|
4104
|
-
/**
|
|
4105
|
-
* 处理错误
|
|
4106
|
-
* @param handler
|
|
4107
|
-
*/
|
|
4108
|
-
error(handler) {
|
|
4109
|
-
// @ts-ignore
|
|
4110
|
-
handleError = handler;
|
|
4111
|
-
return TryCatchCore;
|
|
4112
|
-
},
|
|
4113
|
-
/**
|
|
4114
|
-
* 执行传入的函数并捕获其可能抛出的错误,并通过传入的错误处理函数进行处理。
|
|
4115
|
-
* @param callback 待执行函数,可以是 function 或者 string 类型。如果是 string 类型,则会被当做代码进行执行。
|
|
4116
|
-
* @param __context__ 待执行函数的作用域,用于apply指定
|
|
4117
|
-
* @returns 如果函数有返回值,则返回该返回值;否则返回 tryCatchObj 函数以支持链式调用。
|
|
4118
|
-
* @throws {Error} 如果传入参数不符合要求,则会抛出相应类型的错误。
|
|
4119
|
-
*/
|
|
4120
|
-
run(callback, __context__) {
|
|
4121
|
-
callbackFunction = callback;
|
|
4122
|
-
context = __context__ || this;
|
|
4123
|
-
let result = executeTryCatch(callbackFunction, handleError, context);
|
|
4124
|
-
// @ts-ignore
|
|
4125
|
-
return result !== undefined ? result : TryCatchCore;
|
|
4126
|
-
},
|
|
4127
|
-
};
|
|
4128
|
-
/**
|
|
4129
|
-
* 执行传入的函数并捕获其可能抛出的错误,并通过传入的错误处理函数进行处理。
|
|
4130
|
-
* @param callback - 待执行函数,可以是 function 或者 string 类型。如果是 string 类型,则会被当做代码进行执行。
|
|
4131
|
-
* @param handleErrorFunc - 错误处理函数,可以是 function 或者 string 类型。如果是 string 类型,则会被当做代码进行执行。
|
|
4132
|
-
* @param funcThis - 待执行函数的作用域,用于apply指定
|
|
4133
|
-
* @returns 如果函数有返回值,则返回该返回值;否则返回 undefined。
|
|
4134
|
-
*/
|
|
4135
|
-
function executeTryCatch(callback, handleErrorFunc, funcThis) {
|
|
4136
|
-
let result = undefined;
|
|
4137
|
-
try {
|
|
4138
|
-
if (typeof callback === "string") {
|
|
4139
|
-
(function () {
|
|
4140
|
-
eval(callback);
|
|
4141
|
-
}).apply(funcThis, args);
|
|
4142
|
-
}
|
|
4143
|
-
else {
|
|
4144
|
-
result = callback.apply(funcThis, args);
|
|
4145
|
-
}
|
|
4146
|
-
}
|
|
4147
|
-
catch (error) {
|
|
4148
|
-
if (defaultDetails.log) {
|
|
4149
|
-
callback = callback;
|
|
4150
|
-
console.log(`%c ${callback?.name ? callback?.name : callback + "出现错误"} `, "color: #f20000");
|
|
4151
|
-
console.log(`%c 错误原因:${error}`, "color: #f20000");
|
|
4152
|
-
console.trace(callback);
|
|
4153
|
-
}
|
|
4154
|
-
if (handleErrorFunc) {
|
|
4155
|
-
if (typeof handleErrorFunc === "string") {
|
|
4156
|
-
result = function () {
|
|
4157
|
-
return eval(handleErrorFunc);
|
|
4158
|
-
// @ts-ignore
|
|
4159
|
-
}.apply(funcThis, [...args, error]);
|
|
4160
|
-
}
|
|
4161
|
-
else {
|
|
4162
|
-
result = handleErrorFunc.apply(funcThis, [...args, error]);
|
|
4163
|
-
}
|
|
4164
|
-
}
|
|
4165
|
-
}
|
|
4166
|
-
return result;
|
|
4323
|
+
let w = this.#ctx.measureText(txt).width;
|
|
4324
|
+
let h = this.#config.fontSize / 2;
|
|
4325
|
+
this.#ctx.fillStyle = this.#config.textColor;
|
|
4326
|
+
this.#ctx.fillText(txt, this.#width / 2 - w / 2, this.#height / 2 + h / 2);
|
|
4167
4327
|
}
|
|
4168
|
-
|
|
4169
|
-
};
|
|
4328
|
+
}
|
|
4170
4329
|
|
|
4171
4330
|
class UtilsDictionary {
|
|
4172
4331
|
items = {};
|
|
@@ -4201,7 +4360,7 @@ class UtilsDictionary {
|
|
|
4201
4360
|
*/
|
|
4202
4361
|
getStartsWith(key) {
|
|
4203
4362
|
let allKeys = this.keys();
|
|
4204
|
-
let result =
|
|
4363
|
+
let result = void 0;
|
|
4205
4364
|
for (const keyName of allKeys) {
|
|
4206
4365
|
if (String(keyName).startsWith(String(key))) {
|
|
4207
4366
|
result = this.get(keyName);
|
|
@@ -4216,7 +4375,7 @@ class UtilsDictionary {
|
|
|
4216
4375
|
* @param val 值,默认为""
|
|
4217
4376
|
*/
|
|
4218
4377
|
set(key, val) {
|
|
4219
|
-
if (key ===
|
|
4378
|
+
if (key === void 0) {
|
|
4220
4379
|
throw new Error("Utils.Dictionary().set 参数 key 不能为空");
|
|
4221
4380
|
}
|
|
4222
4381
|
Reflect.set(this.items, key, val);
|
|
@@ -4283,7 +4442,7 @@ class UtilsDictionary {
|
|
|
4283
4442
|
* @param data 需要合并的字典
|
|
4284
4443
|
*/
|
|
4285
4444
|
concat(data) {
|
|
4286
|
-
this.items =
|
|
4445
|
+
this.items = commonUtil.assign(this.items, data.getItems());
|
|
4287
4446
|
}
|
|
4288
4447
|
forEach(callbackfn) {
|
|
4289
4448
|
for (const key in this.getItems()) {
|
|
@@ -4842,7 +5001,7 @@ const worker = `(()=>{var e={455:function(e,t){!function(e){"use strict";var t=f
|
|
|
4842
5001
|
|
|
4843
5002
|
const loadOrReturnBroker = createLoadOrReturnBroker(load, worker);
|
|
4844
5003
|
const clearInterval = (timerId) => loadOrReturnBroker().clearInterval(timerId);
|
|
4845
|
-
const clearTimeout = (timerId) => loadOrReturnBroker().clearTimeout(timerId);
|
|
5004
|
+
const clearTimeout$1 = (timerId) => loadOrReturnBroker().clearTimeout(timerId);
|
|
4846
5005
|
const setInterval = (...args) => loadOrReturnBroker().setInterval(...args);
|
|
4847
5006
|
const setTimeout$1 = (...args) => loadOrReturnBroker().setTimeout(...args);
|
|
4848
5007
|
|
|
@@ -5244,13 +5403,194 @@ class ModuleRaid {
|
|
|
5244
5403
|
}
|
|
5245
5404
|
}
|
|
5246
5405
|
|
|
5406
|
+
class DOMUtils {
|
|
5407
|
+
windowApi;
|
|
5408
|
+
constructor(option) {
|
|
5409
|
+
this.windowApi = new WindowApi(option);
|
|
5410
|
+
}
|
|
5411
|
+
selector(selector, parent) {
|
|
5412
|
+
return this.selectorAll(selector, parent)[0];
|
|
5413
|
+
}
|
|
5414
|
+
selectorAll(selector, parent) {
|
|
5415
|
+
const context = this;
|
|
5416
|
+
parent = parent || context.windowApi.document;
|
|
5417
|
+
selector = selector.trim();
|
|
5418
|
+
if (selector.match(/[^\s]{1}:empty$/gi)) {
|
|
5419
|
+
// empty 语法
|
|
5420
|
+
selector = selector.replace(/:empty$/gi, "");
|
|
5421
|
+
return Array.from(parent.querySelectorAll(selector)).filter(($ele) => {
|
|
5422
|
+
return $ele?.innerHTML?.trim() === "";
|
|
5423
|
+
});
|
|
5424
|
+
}
|
|
5425
|
+
else if (selector.match(/[^\s]{1}:contains\("(.*)"\)$/i) ||
|
|
5426
|
+
selector.match(/[^\s]{1}:contains\('(.*)'\)$/i)) {
|
|
5427
|
+
// contains 语法
|
|
5428
|
+
let textMatch = selector.match(/:contains\(("|')(.*)("|')\)$/i);
|
|
5429
|
+
let text = textMatch[2];
|
|
5430
|
+
selector = selector.replace(/:contains\(("|')(.*)("|')\)$/gi, "");
|
|
5431
|
+
return Array.from(parent.querySelectorAll(selector)).filter(($ele) => {
|
|
5432
|
+
// @ts-ignore
|
|
5433
|
+
return ($ele?.textContent || $ele?.innerText)?.includes(text);
|
|
5434
|
+
});
|
|
5435
|
+
}
|
|
5436
|
+
else if (selector.match(/[^\s]{1}:regexp\("(.*)"\)$/i) ||
|
|
5437
|
+
selector.match(/[^\s]{1}:regexp\('(.*)'\)$/i)) {
|
|
5438
|
+
// regexp 语法
|
|
5439
|
+
let textMatch = selector.match(/:regexp\(("|')(.*)("|')\)$/i);
|
|
5440
|
+
let pattern = textMatch[2];
|
|
5441
|
+
let flagMatch = pattern.match(/("|'),[\s]*("|')([igm]{0,3})$/i);
|
|
5442
|
+
let flags = "";
|
|
5443
|
+
if (flagMatch) {
|
|
5444
|
+
pattern = pattern.replace(/("|'),[\s]*("|')([igm]{0,3})$/gi, "");
|
|
5445
|
+
flags = flagMatch[3];
|
|
5446
|
+
}
|
|
5447
|
+
let regexp = new RegExp(pattern, flags);
|
|
5448
|
+
selector = selector.replace(/:regexp\(("|')(.*)("|')\)$/gi, "");
|
|
5449
|
+
return Array.from(parent.querySelectorAll(selector)).filter(($ele) => {
|
|
5450
|
+
// @ts-ignore
|
|
5451
|
+
return Boolean(($ele?.textContent || $ele?.innerText)?.match(regexp));
|
|
5452
|
+
});
|
|
5453
|
+
}
|
|
5454
|
+
else {
|
|
5455
|
+
// 普通语法
|
|
5456
|
+
return Array.from(parent.querySelectorAll(selector));
|
|
5457
|
+
}
|
|
5458
|
+
}
|
|
5459
|
+
/**
|
|
5460
|
+
* 匹配元素,可使用以下的额外语法
|
|
5461
|
+
*
|
|
5462
|
+
* + :contains([text]) 作用: 找到包含指定文本内容的指定元素
|
|
5463
|
+
* + :empty 作用:找到既没有文本内容也没有子元素的指定元素
|
|
5464
|
+
* + :regexp([text]) 作用: 找到符合正则表达式的内容的指定元素
|
|
5465
|
+
* @param $el 元素
|
|
5466
|
+
* @param selector 选择器
|
|
5467
|
+
* @example
|
|
5468
|
+
* DOMUtils.matches("div:contains('测试')")
|
|
5469
|
+
* > true
|
|
5470
|
+
* @example
|
|
5471
|
+
* DOMUtils.matches("div:empty")
|
|
5472
|
+
* > true
|
|
5473
|
+
* @example
|
|
5474
|
+
* DOMUtils.matches("div:regexp('^xxxx$')")
|
|
5475
|
+
* > true
|
|
5476
|
+
* @example
|
|
5477
|
+
* DOMUtils.matches("div:regexp(/^xxx/ig)")
|
|
5478
|
+
* > false
|
|
5479
|
+
*/
|
|
5480
|
+
matches($el, selector) {
|
|
5481
|
+
selector = selector.trim();
|
|
5482
|
+
if ($el == null) {
|
|
5483
|
+
return false;
|
|
5484
|
+
}
|
|
5485
|
+
if (selector.match(/[^\s]{1}:empty$/gi)) {
|
|
5486
|
+
// empty 语法
|
|
5487
|
+
selector = selector.replace(/:empty$/gi, "");
|
|
5488
|
+
return $el.matches(selector) && $el?.innerHTML?.trim() === "";
|
|
5489
|
+
}
|
|
5490
|
+
else if (selector.match(/[^\s]{1}:contains\("(.*)"\)$/i) ||
|
|
5491
|
+
selector.match(/[^\s]{1}:contains\('(.*)'\)$/i)) {
|
|
5492
|
+
// contains 语法
|
|
5493
|
+
let textMatch = selector.match(/:contains\(("|')(.*)("|')\)$/i);
|
|
5494
|
+
let text = textMatch[2];
|
|
5495
|
+
selector = selector.replace(/:contains\(("|')(.*)("|')\)$/gi, "");
|
|
5496
|
+
// @ts-ignore
|
|
5497
|
+
let content = $el?.textContent || $el?.innerText;
|
|
5498
|
+
if (typeof content !== "string") {
|
|
5499
|
+
content = "";
|
|
5500
|
+
}
|
|
5501
|
+
return $el.matches(selector) && content?.includes(text);
|
|
5502
|
+
}
|
|
5503
|
+
else if (selector.match(/[^\s]{1}:regexp\("(.*)"\)$/i) ||
|
|
5504
|
+
selector.match(/[^\s]{1}:regexp\('(.*)'\)$/i)) {
|
|
5505
|
+
// regexp 语法
|
|
5506
|
+
let textMatch = selector.match(/:regexp\(("|')(.*)("|')\)$/i);
|
|
5507
|
+
let pattern = textMatch[2];
|
|
5508
|
+
let flagMatch = pattern.match(/("|'),[\s]*("|')([igm]{0,3})$/i);
|
|
5509
|
+
let flags = "";
|
|
5510
|
+
if (flagMatch) {
|
|
5511
|
+
pattern = pattern.replace(/("|'),[\s]*("|')([igm]{0,3})$/gi, "");
|
|
5512
|
+
flags = flagMatch[3];
|
|
5513
|
+
}
|
|
5514
|
+
let regexp = new RegExp(pattern, flags);
|
|
5515
|
+
selector = selector.replace(/:regexp\(("|')(.*)("|')\)$/gi, "");
|
|
5516
|
+
// @ts-ignore
|
|
5517
|
+
let content = $el?.textContent || $el?.innerText;
|
|
5518
|
+
if (typeof content !== "string") {
|
|
5519
|
+
content = "";
|
|
5520
|
+
}
|
|
5521
|
+
return $el.matches(selector) && Boolean(content?.match(regexp));
|
|
5522
|
+
}
|
|
5523
|
+
else {
|
|
5524
|
+
// 普通语法
|
|
5525
|
+
return $el.matches(selector);
|
|
5526
|
+
}
|
|
5527
|
+
}
|
|
5528
|
+
closest($el, selector) {
|
|
5529
|
+
selector = selector.trim();
|
|
5530
|
+
if (selector.match(/[^\s]{1}:empty$/gi)) {
|
|
5531
|
+
// empty 语法
|
|
5532
|
+
selector = selector.replace(/:empty$/gi, "");
|
|
5533
|
+
let $closest = $el?.closest(selector);
|
|
5534
|
+
if ($closest && $closest?.innerHTML?.trim() === "") {
|
|
5535
|
+
return $closest;
|
|
5536
|
+
}
|
|
5537
|
+
return null;
|
|
5538
|
+
}
|
|
5539
|
+
else if (selector.match(/[^\s]{1}:contains\("(.*)"\)$/i) ||
|
|
5540
|
+
selector.match(/[^\s]{1}:contains\('(.*)'\)$/i)) {
|
|
5541
|
+
// contains 语法
|
|
5542
|
+
let textMatch = selector.match(/:contains\(("|')(.*)("|')\)$/i);
|
|
5543
|
+
let text = textMatch[2];
|
|
5544
|
+
selector = selector.replace(/:contains\(("|')(.*)("|')\)$/gi, "");
|
|
5545
|
+
let $closest = $el?.closest(selector);
|
|
5546
|
+
if ($closest) {
|
|
5547
|
+
// @ts-ignore
|
|
5548
|
+
let content = $el?.textContent || $el?.innerText;
|
|
5549
|
+
if (typeof content === "string" && content.includes(text)) {
|
|
5550
|
+
return $closest;
|
|
5551
|
+
}
|
|
5552
|
+
}
|
|
5553
|
+
return null;
|
|
5554
|
+
}
|
|
5555
|
+
else if (selector.match(/[^\s]{1}:regexp\("(.*)"\)$/i) ||
|
|
5556
|
+
selector.match(/[^\s]{1}:regexp\('(.*)'\)$/i)) {
|
|
5557
|
+
// regexp 语法
|
|
5558
|
+
let textMatch = selector.match(/:regexp\(("|')(.*)("|')\)$/i);
|
|
5559
|
+
let pattern = textMatch[2];
|
|
5560
|
+
let flagMatch = pattern.match(/("|'),[\s]*("|')([igm]{0,3})$/i);
|
|
5561
|
+
let flags = "";
|
|
5562
|
+
if (flagMatch) {
|
|
5563
|
+
pattern = pattern.replace(/("|'),[\s]*("|')([igm]{0,3})$/gi, "");
|
|
5564
|
+
flags = flagMatch[3];
|
|
5565
|
+
}
|
|
5566
|
+
let regexp = new RegExp(pattern, flags);
|
|
5567
|
+
selector = selector.replace(/:regexp\(("|')(.*)("|')\)$/gi, "");
|
|
5568
|
+
let $closest = $el?.closest(selector);
|
|
5569
|
+
if ($closest) {
|
|
5570
|
+
// @ts-ignore
|
|
5571
|
+
let content = $el?.textContent || $el?.innerText;
|
|
5572
|
+
if (typeof content === "string" && content.match(regexp)) {
|
|
5573
|
+
return $closest;
|
|
5574
|
+
}
|
|
5575
|
+
}
|
|
5576
|
+
return null;
|
|
5577
|
+
}
|
|
5578
|
+
else {
|
|
5579
|
+
// 普通语法
|
|
5580
|
+
let $closest = $el?.closest(selector);
|
|
5581
|
+
return $closest;
|
|
5582
|
+
}
|
|
5583
|
+
}
|
|
5584
|
+
}
|
|
5585
|
+
let domUtils = new DOMUtils();
|
|
5586
|
+
|
|
5247
5587
|
class Utils {
|
|
5248
5588
|
windowApi;
|
|
5249
5589
|
constructor(option) {
|
|
5250
5590
|
this.windowApi = new WindowApi(option);
|
|
5251
5591
|
}
|
|
5252
5592
|
/** 版本号 */
|
|
5253
|
-
version = "2025.
|
|
5593
|
+
version = "2025.6.26";
|
|
5254
5594
|
addStyle(cssText) {
|
|
5255
5595
|
if (typeof cssText !== "string") {
|
|
5256
5596
|
throw new Error("Utils.addStyle 参数cssText 必须为String类型");
|
|
@@ -5276,58 +5616,22 @@ class Utils {
|
|
|
5276
5616
|
}
|
|
5277
5617
|
return cssNode;
|
|
5278
5618
|
}
|
|
5279
|
-
|
|
5280
|
-
|
|
5281
|
-
|
|
5282
|
-
|
|
5283
|
-
|
|
5284
|
-
|
|
5285
|
-
|
|
5286
|
-
|
|
5287
|
-
|
|
5288
|
-
|
|
5289
|
-
|
|
5290
|
-
|
|
5291
|
-
}
|
|
5292
|
-
if (target == null) {
|
|
5293
|
-
target = {};
|
|
5294
|
-
}
|
|
5295
|
-
if (isAdd) {
|
|
5296
|
-
for (const sourceKeyName in source) {
|
|
5297
|
-
const targetKeyName = sourceKeyName;
|
|
5298
|
-
let targetValue = target[targetKeyName];
|
|
5299
|
-
let sourceValue = source[sourceKeyName];
|
|
5300
|
-
if (typeof sourceValue === "object" &&
|
|
5301
|
-
sourceValue != null &&
|
|
5302
|
-
sourceKeyName in target &&
|
|
5303
|
-
!UtilsContext.isDOM(sourceValue)) {
|
|
5304
|
-
/* 源端的值是object类型,且不是元素节点 */
|
|
5305
|
-
target[sourceKeyName] = UtilsContext.assign(targetValue, sourceValue, isAdd);
|
|
5306
|
-
continue;
|
|
5307
|
-
}
|
|
5308
|
-
target[sourceKeyName] = sourceValue;
|
|
5309
|
-
}
|
|
5310
|
-
}
|
|
5311
|
-
else {
|
|
5312
|
-
for (const targetKeyName in target) {
|
|
5313
|
-
if (targetKeyName in source) {
|
|
5314
|
-
let targetValue = target[targetKeyName];
|
|
5315
|
-
let sourceValue = source[targetKeyName];
|
|
5316
|
-
if (typeof sourceValue === "object" &&
|
|
5317
|
-
sourceValue != null &&
|
|
5318
|
-
!UtilsContext.isDOM(sourceValue) &&
|
|
5319
|
-
Object.keys(sourceValue).length) {
|
|
5320
|
-
/* 源端的值是object类型,且不是元素节点 */
|
|
5321
|
-
target[targetKeyName] = UtilsContext.assign(targetValue, sourceValue, isAdd);
|
|
5322
|
-
continue;
|
|
5323
|
-
}
|
|
5324
|
-
/* 直接赋值 */
|
|
5325
|
-
target[targetKeyName] = sourceValue;
|
|
5326
|
-
}
|
|
5619
|
+
/**
|
|
5620
|
+
* JSON数据从源端替换到目标端中,如果目标端存在该数据则替换,不添加,返回结果为目标端替换完毕的结果
|
|
5621
|
+
* @param target 目标数据
|
|
5622
|
+
* @param source 源数据
|
|
5623
|
+
* @param isAdd 是否可以追加键,默认false
|
|
5624
|
+
* @example
|
|
5625
|
+
* Utils.assign({"1":1,"2":{"3":3}}, {"2":{"3":4}});
|
|
5626
|
+
* >
|
|
5627
|
+
* {
|
|
5628
|
+
"1": 1,
|
|
5629
|
+
"2": {
|
|
5630
|
+
"3": 4
|
|
5327
5631
|
}
|
|
5328
5632
|
}
|
|
5329
|
-
|
|
5330
|
-
|
|
5633
|
+
*/
|
|
5634
|
+
assign = commonUtil.assign.bind(commonUtil);
|
|
5331
5635
|
async asyncReplaceAll(string, pattern, asyncFn) {
|
|
5332
5636
|
let UtilsContext = this;
|
|
5333
5637
|
if (typeof string !== "string") {
|
|
@@ -5370,7 +5674,7 @@ class Utils {
|
|
|
5370
5674
|
* ajax劫持库,支持xhr和fetch劫持。
|
|
5371
5675
|
* + 来源:https://bbs.tampermonkey.net.cn/thread-3284-1-1.html
|
|
5372
5676
|
* + 作者:cxxjackie
|
|
5373
|
-
* + 版本:1.4.
|
|
5677
|
+
* + 版本:1.4.6
|
|
5374
5678
|
* + 旧版本:1.2.4
|
|
5375
5679
|
* + 文档:https://scriptcat.org/zh-CN/script-show-page/637/
|
|
5376
5680
|
* @param useOldVersion 是否使用旧版本,默认false
|
|
@@ -5380,7 +5684,7 @@ class Utils {
|
|
|
5380
5684
|
return AjaxHooker1_2_4();
|
|
5381
5685
|
}
|
|
5382
5686
|
else {
|
|
5383
|
-
return
|
|
5687
|
+
return ajaxHooker();
|
|
5384
5688
|
}
|
|
5385
5689
|
};
|
|
5386
5690
|
canvasClickByPosition(canvasElement, clientX = 0, clientY = 0, view = globalThis) {
|
|
@@ -5480,19 +5784,11 @@ class Utils {
|
|
|
5480
5784
|
* @returns
|
|
5481
5785
|
*/
|
|
5482
5786
|
ColorConversion = ColorConversion;
|
|
5483
|
-
|
|
5484
|
-
|
|
5485
|
-
|
|
5486
|
-
|
|
5487
|
-
|
|
5488
|
-
return null;
|
|
5489
|
-
let clone = obj instanceof Array ? [] : {};
|
|
5490
|
-
for (const [key, value] of Object.entries(obj)) {
|
|
5491
|
-
clone[key] =
|
|
5492
|
-
typeof value === "object" ? UtilsContext.deepClone(value) : value;
|
|
5493
|
-
}
|
|
5494
|
-
return clone;
|
|
5495
|
-
}
|
|
5787
|
+
/**
|
|
5788
|
+
* 深拷贝
|
|
5789
|
+
* @param obj 对象
|
|
5790
|
+
*/
|
|
5791
|
+
deepClone = commonUtil.deepClone.bind(commonUtil);
|
|
5496
5792
|
debounce(fn, delay = 0) {
|
|
5497
5793
|
let timer = null;
|
|
5498
5794
|
let UtilsContext = this;
|
|
@@ -5515,7 +5811,7 @@ class Utils {
|
|
|
5515
5811
|
throw new Error("Utils.deleteParentNode 参数 targetSelector 必须为 string 类型");
|
|
5516
5812
|
}
|
|
5517
5813
|
let result = false;
|
|
5518
|
-
let needRemoveDOM =
|
|
5814
|
+
let needRemoveDOM = domUtils.closest(element, targetSelector);
|
|
5519
5815
|
if (needRemoveDOM) {
|
|
5520
5816
|
needRemoveDOM.remove();
|
|
5521
5817
|
result = true;
|
|
@@ -6503,9 +6799,17 @@ class Utils {
|
|
|
6503
6799
|
throw new TypeError("参数1类型错误" + typeof firstArg);
|
|
6504
6800
|
}
|
|
6505
6801
|
}
|
|
6506
|
-
|
|
6507
|
-
|
|
6508
|
-
|
|
6802
|
+
/**
|
|
6803
|
+
* 判断对象是否是元素
|
|
6804
|
+
* @param target
|
|
6805
|
+
* @returns
|
|
6806
|
+
* + true 是元素
|
|
6807
|
+
* + false 不是元素
|
|
6808
|
+
* @example
|
|
6809
|
+
* Utils.isDOM(document.querySelector("a"))
|
|
6810
|
+
* > true
|
|
6811
|
+
*/
|
|
6812
|
+
isDOM = commonUtil.isDOM.bind(commonUtil);
|
|
6509
6813
|
isFullscreenEnabled() {
|
|
6510
6814
|
return !!(this.windowApi.document.fullscreenEnabled ||
|
|
6511
6815
|
this.windowApi.document.webkitFullScreenEnabled ||
|
|
@@ -6696,52 +7000,62 @@ class Utils {
|
|
|
6696
7000
|
}
|
|
6697
7001
|
return result;
|
|
6698
7002
|
}
|
|
6699
|
-
|
|
6700
|
-
|
|
6701
|
-
|
|
6702
|
-
|
|
6703
|
-
|
|
6704
|
-
|
|
6705
|
-
|
|
6706
|
-
|
|
6707
|
-
|
|
6708
|
-
|
|
6709
|
-
|
|
6710
|
-
|
|
6711
|
-
|
|
6712
|
-
|
|
6713
|
-
|
|
6714
|
-
|
|
6715
|
-
|
|
6716
|
-
|
|
6717
|
-
|
|
6718
|
-
|
|
6719
|
-
|
|
6720
|
-
|
|
6721
|
-
|
|
6722
|
-
|
|
6723
|
-
|
|
6724
|
-
|
|
6725
|
-
|
|
6726
|
-
|
|
6727
|
-
|
|
6728
|
-
|
|
6729
|
-
|
|
6730
|
-
|
|
6731
|
-
|
|
6732
|
-
|
|
6733
|
-
|
|
6734
|
-
|
|
6735
|
-
|
|
6736
|
-
|
|
6737
|
-
|
|
6738
|
-
|
|
6739
|
-
|
|
6740
|
-
|
|
6741
|
-
|
|
6742
|
-
|
|
6743
|
-
|
|
6744
|
-
|
|
7003
|
+
/**
|
|
7004
|
+
* 判断对象是否不为空
|
|
7005
|
+
* @returns {boolean}
|
|
7006
|
+
* + true 不为空
|
|
7007
|
+
* + false 为空
|
|
7008
|
+
* @example
|
|
7009
|
+
* Utils.isNotNull("123");
|
|
7010
|
+
* > true
|
|
7011
|
+
*/
|
|
7012
|
+
isNotNull = commonUtil.isNotNull.bind(commonUtil);
|
|
7013
|
+
/**
|
|
7014
|
+
* 判断对象或数据是否为空
|
|
7015
|
+
* + `String`判空的值,如 ""、"null"、"undefined"、" "
|
|
7016
|
+
* + `Number`判空的值,如 0
|
|
7017
|
+
* + `Object`判空的值,如 {}、null、undefined
|
|
7018
|
+
* + `Array`(存在属性Symbol.iterator)判空的值,如 []
|
|
7019
|
+
* + `Boolean`判空的值,如false
|
|
7020
|
+
* + `Function`判空的值,如()=>{}、(xxx="")=>{}、function(){}、function(xxx=""){}
|
|
7021
|
+
* @returns
|
|
7022
|
+
* + true 为空
|
|
7023
|
+
* + false 不为空
|
|
7024
|
+
* @example
|
|
7025
|
+
Utils.isNull({});
|
|
7026
|
+
> true
|
|
7027
|
+
* @example
|
|
7028
|
+
Utils.isNull([]);
|
|
7029
|
+
> true
|
|
7030
|
+
* @example
|
|
7031
|
+
Utils.isNull(" ");
|
|
7032
|
+
> true
|
|
7033
|
+
* @example
|
|
7034
|
+
Utils.isNull(function(){});
|
|
7035
|
+
> true
|
|
7036
|
+
* @example
|
|
7037
|
+
Utils.isNull(()=>{}));
|
|
7038
|
+
> true
|
|
7039
|
+
* @example
|
|
7040
|
+
Utils.isNull("undefined");
|
|
7041
|
+
> true
|
|
7042
|
+
* @example
|
|
7043
|
+
Utils.isNull("null");
|
|
7044
|
+
> true
|
|
7045
|
+
* @example
|
|
7046
|
+
Utils.isNull(" ", false);
|
|
7047
|
+
> true
|
|
7048
|
+
* @example
|
|
7049
|
+
Utils.isNull([1],[]);
|
|
7050
|
+
> false
|
|
7051
|
+
* @example
|
|
7052
|
+
Utils.isNull([],[1]);
|
|
7053
|
+
> false
|
|
7054
|
+
* @example
|
|
7055
|
+
Utils.isNull(false,[123]);
|
|
7056
|
+
> false
|
|
7057
|
+
**/
|
|
7058
|
+
isNull = commonUtil.isNull.bind(commonUtil);
|
|
6745
7059
|
isThemeDark() {
|
|
6746
7060
|
return this.windowApi.globalThis.matchMedia("(prefers-color-scheme: dark)")
|
|
6747
7061
|
.matches;
|
|
@@ -6931,36 +7245,36 @@ class Utils {
|
|
|
6931
7245
|
* + true 监听以 target 为根节点的整个子树。包括子树中所有节点的属性,而不仅仅是针对 target
|
|
6932
7246
|
* + false (默认) 不生效
|
|
6933
7247
|
*/
|
|
6934
|
-
subtree:
|
|
7248
|
+
subtree: void 0,
|
|
6935
7249
|
/**
|
|
6936
7250
|
* + true 监听 target 节点中发生的节点的新增与删除(同时,如果 subtree 为 true,会针对整个子树生效)
|
|
6937
7251
|
* + false (默认) 不生效
|
|
6938
7252
|
*/
|
|
6939
|
-
childList:
|
|
7253
|
+
childList: void 0,
|
|
6940
7254
|
/**
|
|
6941
7255
|
* + true 观察所有监听的节点属性值的变化。默认值为 true,当声明了 attributeFilter 或 attributeOldValue
|
|
6942
7256
|
* + false (默认) 不生效
|
|
6943
7257
|
*/
|
|
6944
|
-
attributes:
|
|
7258
|
+
attributes: void 0,
|
|
6945
7259
|
/**
|
|
6946
7260
|
* 一个用于声明哪些属性名会被监听的数组。如果不声明该属性,所有属性的变化都将触发通知
|
|
6947
7261
|
*/
|
|
6948
|
-
attributeFilter:
|
|
7262
|
+
attributeFilter: void 0,
|
|
6949
7263
|
/**
|
|
6950
7264
|
* + true 记录上一次被监听的节点的属性变化;可查阅 MutationObserver 中的 Monitoring attribute values 了解关于观察属性变化和属性值记录的详情
|
|
6951
7265
|
* + false (默认) 不生效
|
|
6952
7266
|
*/
|
|
6953
|
-
attributeOldValue:
|
|
7267
|
+
attributeOldValue: void 0,
|
|
6954
7268
|
/**
|
|
6955
7269
|
* + true 监听声明的 target 节点上所有字符的变化。默认值为 true,如果声明了 characterDataOldValue
|
|
6956
7270
|
* + false (默认) 不生效
|
|
6957
7271
|
*/
|
|
6958
|
-
characterData:
|
|
7272
|
+
characterData: void 0,
|
|
6959
7273
|
/**
|
|
6960
7274
|
* + true 记录前一个被监听的节点中发生的文本变化
|
|
6961
7275
|
* + false (默认) 不生效
|
|
6962
7276
|
*/
|
|
6963
|
-
characterDataOldValue:
|
|
7277
|
+
characterDataOldValue: void 0,
|
|
6964
7278
|
},
|
|
6965
7279
|
immediate: false,
|
|
6966
7280
|
};
|
|
@@ -7536,7 +7850,7 @@ class Utils {
|
|
|
7536
7850
|
}
|
|
7537
7851
|
return new Promise((resolve) => {
|
|
7538
7852
|
UtilsContext.workerSetTimeout(() => {
|
|
7539
|
-
resolve(
|
|
7853
|
+
resolve(void 0);
|
|
7540
7854
|
}, delayTime);
|
|
7541
7855
|
});
|
|
7542
7856
|
}
|
|
@@ -7550,7 +7864,7 @@ class Utils {
|
|
|
7550
7864
|
return mouseEvent;
|
|
7551
7865
|
}
|
|
7552
7866
|
let sliderElement = typeof selector === "string"
|
|
7553
|
-
?
|
|
7867
|
+
? domUtils.selector(selector)
|
|
7554
7868
|
: selector;
|
|
7555
7869
|
if (!(sliderElement instanceof Node) ||
|
|
7556
7870
|
!(sliderElement instanceof Element)) {
|
|
@@ -7760,47 +8074,15 @@ class Utils {
|
|
|
7760
8074
|
}
|
|
7761
8075
|
return newTargetString;
|
|
7762
8076
|
}
|
|
7763
|
-
|
|
7764
|
-
|
|
7765
|
-
|
|
7766
|
-
|
|
7767
|
-
|
|
7768
|
-
|
|
7769
|
-
|
|
7770
|
-
|
|
7771
|
-
|
|
7772
|
-
UtilsContext.tryCatch()
|
|
7773
|
-
.error(() => {
|
|
7774
|
-
try {
|
|
7775
|
-
result = UtilsContext.windowApi.window.eval("(" + data + ")");
|
|
7776
|
-
}
|
|
7777
|
-
catch (error2) {
|
|
7778
|
-
if (typeof errorCallBack === "function") {
|
|
7779
|
-
errorCallBack(error2);
|
|
7780
|
-
}
|
|
7781
|
-
}
|
|
7782
|
-
})
|
|
7783
|
-
.run(() => {
|
|
7784
|
-
if (data &&
|
|
7785
|
-
/^[\],:{}\s]*$/.test(data
|
|
7786
|
-
.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, "@")
|
|
7787
|
-
.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]")
|
|
7788
|
-
.replace(/(?:^|:|,)(?:\s*\[)+/g, ""))) {
|
|
7789
|
-
result = new Function("return " + data)();
|
|
7790
|
-
}
|
|
7791
|
-
else {
|
|
7792
|
-
if (typeof errorCallBack === "function") {
|
|
7793
|
-
errorCallBack(new Error("target is not a JSON"));
|
|
7794
|
-
}
|
|
7795
|
-
}
|
|
7796
|
-
});
|
|
7797
|
-
})
|
|
7798
|
-
.run(() => {
|
|
7799
|
-
data = data.trim();
|
|
7800
|
-
result = JSON.parse(data);
|
|
7801
|
-
});
|
|
7802
|
-
return result;
|
|
7803
|
-
}
|
|
8077
|
+
/**
|
|
8078
|
+
* 字符串转Object对象,类似'{"test":""}' => {"test":""}
|
|
8079
|
+
* @param data
|
|
8080
|
+
* @param errorCallBack (可选)错误回调
|
|
8081
|
+
* @example
|
|
8082
|
+
* Utils.toJSON("{123:123}")
|
|
8083
|
+
* > {123:123}
|
|
8084
|
+
*/
|
|
8085
|
+
toJSON = commonUtil.toJSON.bind(commonUtil);
|
|
7804
8086
|
toSearchParamsStr(obj, addPrefix) {
|
|
7805
8087
|
let UtilsContext = this;
|
|
7806
8088
|
let searhParamsStr = "";
|
|
@@ -7911,7 +8193,7 @@ class Utils {
|
|
|
7911
8193
|
}
|
|
7912
8194
|
waitNode(...args) {
|
|
7913
8195
|
// 过滤掉undefined
|
|
7914
|
-
args = args.filter((arg) => arg !==
|
|
8196
|
+
args = args.filter((arg) => arg !== void 0);
|
|
7915
8197
|
let UtilsContext = this;
|
|
7916
8198
|
// 选择器
|
|
7917
8199
|
let selector = args[0];
|
|
@@ -7966,7 +8248,7 @@ class Utils {
|
|
|
7966
8248
|
if (Array.isArray(selector)) {
|
|
7967
8249
|
let result = [];
|
|
7968
8250
|
for (let index = 0; index < selector.length; index++) {
|
|
7969
|
-
let node =
|
|
8251
|
+
let node = domUtils.selector(selector[index]);
|
|
7970
8252
|
if (node) {
|
|
7971
8253
|
result.push(node);
|
|
7972
8254
|
}
|
|
@@ -7979,7 +8261,7 @@ class Utils {
|
|
|
7979
8261
|
return selector();
|
|
7980
8262
|
}
|
|
7981
8263
|
else {
|
|
7982
|
-
return
|
|
8264
|
+
return domUtils.selector(selector, parent);
|
|
7983
8265
|
}
|
|
7984
8266
|
}
|
|
7985
8267
|
return UtilsContext.wait(() => {
|
|
@@ -8000,7 +8282,7 @@ class Utils {
|
|
|
8000
8282
|
}
|
|
8001
8283
|
waitAnyNode(...args) {
|
|
8002
8284
|
// 过滤掉undefined
|
|
8003
|
-
args = args.filter((arg) => arg !==
|
|
8285
|
+
args = args.filter((arg) => arg !== void 0);
|
|
8004
8286
|
let UtilsContext = this;
|
|
8005
8287
|
// 选择器
|
|
8006
8288
|
let selectorList = args[0];
|
|
@@ -8056,7 +8338,7 @@ class Utils {
|
|
|
8056
8338
|
}
|
|
8057
8339
|
waitNodeList(...args) {
|
|
8058
8340
|
// 过滤掉undefined
|
|
8059
|
-
args = args.filter((arg) => arg !==
|
|
8341
|
+
args = args.filter((arg) => arg !== void 0);
|
|
8060
8342
|
let UtilsContext = this;
|
|
8061
8343
|
// 选择器数组
|
|
8062
8344
|
let selector = args[0];
|
|
@@ -8109,7 +8391,7 @@ class Utils {
|
|
|
8109
8391
|
if (Array.isArray(selector)) {
|
|
8110
8392
|
let result = [];
|
|
8111
8393
|
for (let index = 0; index < selector.length; index++) {
|
|
8112
|
-
let nodeList =
|
|
8394
|
+
let nodeList = domUtils.selectorAll(selector[index], parent);
|
|
8113
8395
|
if (nodeList.length) {
|
|
8114
8396
|
result.push(nodeList);
|
|
8115
8397
|
}
|
|
@@ -8119,7 +8401,7 @@ class Utils {
|
|
|
8119
8401
|
}
|
|
8120
8402
|
}
|
|
8121
8403
|
else {
|
|
8122
|
-
let nodeList =
|
|
8404
|
+
let nodeList = domUtils.selectorAll(selector, parent);
|
|
8123
8405
|
if (nodeList.length) {
|
|
8124
8406
|
return nodeList;
|
|
8125
8407
|
}
|
|
@@ -8143,7 +8425,7 @@ class Utils {
|
|
|
8143
8425
|
}
|
|
8144
8426
|
waitAnyNodeList(...args) {
|
|
8145
8427
|
// 过滤掉undefined
|
|
8146
|
-
args = args.filter((arg) => arg !==
|
|
8428
|
+
args = args.filter((arg) => arg !== void 0);
|
|
8147
8429
|
let UtilsContext = this;
|
|
8148
8430
|
// 选择器数组
|
|
8149
8431
|
let selectorList = args[0];
|
|
@@ -8428,17 +8710,7 @@ class Utils {
|
|
|
8428
8710
|
* @param target 需要覆盖的对象
|
|
8429
8711
|
* @param [objectThis] 覆盖的this指向,如果为传入,则默认为对象本身
|
|
8430
8712
|
*/
|
|
8431
|
-
coverObjectFunctionThis(
|
|
8432
|
-
if (typeof target !== "object" || target === null) {
|
|
8433
|
-
throw new Error("target must be object");
|
|
8434
|
-
}
|
|
8435
|
-
objectThis = objectThis || target;
|
|
8436
|
-
Object.keys(target).forEach((key) => {
|
|
8437
|
-
if (typeof target[key] === "function") {
|
|
8438
|
-
target[key] = target[key].bind(objectThis);
|
|
8439
|
-
}
|
|
8440
|
-
});
|
|
8441
|
-
}
|
|
8713
|
+
coverObjectFunctionThis = commonUtil.coverObjectFunctionThis.bind(commonUtil);
|
|
8442
8714
|
/**
|
|
8443
8715
|
* 生成uuid
|
|
8444
8716
|
* @example
|
|
@@ -8479,7 +8751,7 @@ class Utils {
|
|
|
8479
8751
|
workerClearTimeout(timeId) {
|
|
8480
8752
|
try {
|
|
8481
8753
|
if (timeId != null) {
|
|
8482
|
-
clearTimeout(timeId);
|
|
8754
|
+
clearTimeout$1(timeId);
|
|
8483
8755
|
}
|
|
8484
8756
|
}
|
|
8485
8757
|
catch (error) {
|