@whitesev/utils 2.11.11 → 2.11.13

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.
Files changed (39) hide show
  1. package/dist/index.amd.js +220 -62
  2. package/dist/index.amd.js.map +1 -1
  3. package/dist/index.amd.min.js +1 -1
  4. package/dist/index.amd.min.js.map +1 -1
  5. package/dist/index.cjs.js +220 -62
  6. package/dist/index.cjs.js.map +1 -1
  7. package/dist/index.cjs.min.js +1 -1
  8. package/dist/index.cjs.min.js.map +1 -1
  9. package/dist/index.esm.js +220 -62
  10. package/dist/index.esm.js.map +1 -1
  11. package/dist/index.esm.min.js +1 -1
  12. package/dist/index.esm.min.js.map +1 -1
  13. package/dist/index.iife.js +220 -62
  14. package/dist/index.iife.js.map +1 -1
  15. package/dist/index.iife.min.js +1 -1
  16. package/dist/index.iife.min.js.map +1 -1
  17. package/dist/index.system.js +220 -62
  18. package/dist/index.system.js.map +1 -1
  19. package/dist/index.system.min.js +1 -1
  20. package/dist/index.system.min.js.map +1 -1
  21. package/dist/index.umd.js +220 -62
  22. package/dist/index.umd.js.map +1 -1
  23. package/dist/index.umd.min.js +1 -1
  24. package/dist/index.umd.min.js.map +1 -1
  25. package/dist/types/src/Dictionary.d.ts +13 -2
  26. package/dist/types/src/Utils.d.ts +37 -11
  27. package/dist/types/src/ajaxHooker/ajaxHooker.d.ts +8 -2
  28. package/dist/types/src/ajaxHooker/ajaxHooker1.2.4.d.ts +8 -2
  29. package/dist/types/src/types/Httpx.d.ts +16 -16
  30. package/dist/types/src/types/ajaxHooker.d.ts +92 -56
  31. package/package.json +3 -4
  32. package/src/Dictionary.ts +24 -3
  33. package/src/Httpx.ts +18 -18
  34. package/src/LockFunction.ts +3 -6
  35. package/src/Utils.ts +85 -53
  36. package/src/ajaxHooker/ajaxHooker.js +55 -5
  37. package/src/ajaxHooker/ajaxHooker1.2.4.js +58 -14
  38. package/src/types/Httpx.d.ts +16 -16
  39. package/src/types/ajaxHooker.d.ts +92 -56
package/dist/index.amd.js CHANGED
@@ -239,7 +239,7 @@ define((function () { 'use strict';
239
239
  const setInterval$1 = (...args) => loadOrReturnBroker().setInterval(...args);
240
240
  const setTimeout$1 = (...args) => loadOrReturnBroker().setTimeout(...args);
241
241
 
242
- const version = "2.11.11";
242
+ const version = "2.11.13";
243
243
 
244
244
  /* eslint-disable */
245
245
  // ==UserScript==
@@ -374,8 +374,12 @@ define((function () { 'use strict';
374
374
  }));
375
375
  }
376
376
  waitForRequestKeys() {
377
+ /**
378
+ * @type {Set<typeof hookInst>}
379
+ */
380
+ const winHookInsts = win.__ajaxHooker.hookInsts;
377
381
  if (!this.request.async) {
378
- win.__ajaxHooker.hookInsts.forEach(({ hookFns, filters }) => {
382
+ winHookInsts.forEach(({ hookFns, filters }) => {
379
383
  if (this.shouldFilter(filters))
380
384
  return;
381
385
  hookFns.forEach((fn) => {
@@ -391,10 +395,10 @@ define((function () { 'use strict';
391
395
  }
392
396
  const promises = [];
393
397
  const ignoreKeys = new Set(["type", "async", "response"]);
394
- win.__ajaxHooker.hookInsts.forEach(({ hookFns, filters }) => {
398
+ winHookInsts.forEach(({ hookFns, filters }) => {
395
399
  if (this.shouldFilter(filters))
396
400
  return;
397
- promises.push(Promise.all(hookFns.map((fn) => catchError(fn, this.request))).then(() => {
401
+ promises.push(Promise.all(hookFns.map((fn, index) => catchError(fn, this.request, index))).then(() => {
398
402
  const requestKeys = [];
399
403
  for (const key in this.request)
400
404
  !ignoreKeys.has(key) && requestKeys.push(key);
@@ -816,11 +820,52 @@ define((function () { 'use strict';
816
820
  });
817
821
  });
818
822
  }
823
+ /**
824
+ *
825
+ * @type {import("./../types/ajaxHooker.d.ts").UtilsAjaxHookResult["removeHook"]}
826
+ */
827
+ const removeHook = (fn, onlyRemove = false) => {
828
+ let flag = false;
829
+ for (let index = hookInst.hookFns.length - 1; index >= 0; index--) {
830
+ const __fn__ = hookInst.hookFns[index];
831
+ if (fn === __fn__) {
832
+ hookInst.hookFns.splice(index, 1);
833
+ flag = true;
834
+ if (onlyRemove) {
835
+ break;
836
+ }
837
+ }
838
+ }
839
+ return flag;
840
+ };
841
+ /**
842
+ *
843
+ * @type {import("./../types/ajaxHooker.d.ts").UtilsAjaxHookResult["removeFilter"]}
844
+ */
845
+ const removeFilter = () => {
846
+ if (Array.isArray(hookInst.filters)) {
847
+ hookInst.filters.length = 0;
848
+ }
849
+ else {
850
+ hookInst.filters = [];
851
+ }
852
+ };
819
853
  return {
820
- hook: (fn) => hookInst.hookFns.push(fn),
854
+ hook: (fn) => {
855
+ hookInst.hookFns.push(fn);
856
+ return {
857
+ remove: () => {
858
+ return removeHook(fn, true);
859
+ }
860
+ };
861
+ },
821
862
  filter: (arr) => {
822
- if (Array.isArray(arr))
863
+ if (Array.isArray(arr)) {
823
864
  hookInst.filters = arr;
865
+ }
866
+ return {
867
+ remove: removeFilter
868
+ };
824
869
  },
825
870
  protect: () => {
826
871
  readonly(win, "XMLHttpRequest", winAh.fakeXHR);
@@ -836,6 +881,8 @@ define((function () { 'use strict';
836
881
  delete win.__ajaxHooker;
837
882
  }
838
883
  },
884
+ removeHook: removeHook,
885
+ removeFilter: removeFilter
839
886
  };
840
887
  };
841
888
 
@@ -1234,10 +1281,50 @@ define((function () { 'use strict';
1234
1281
  Object.keys(realXhr).forEach((key) => (fakeXhr[key] = realXhr[key]));
1235
1282
  fakeXhr.prototype = realXhr.prototype;
1236
1283
  win.fetch = fakeFetch;
1284
+ /**
1285
+ *
1286
+ * @type {import("./../types/ajaxHooker.d.ts").UtilsAjaxHookResult["removeHook"]}
1287
+ */
1288
+ const removeHook = (fn, onlyRemove = false) => {
1289
+ let flag = false;
1290
+ for (let index = hookFns.length - 1; index >= 0; index--) {
1291
+ const __fn__ = hookFns[index];
1292
+ if (fn === __fn__) {
1293
+ hookFns.splice(index, 1);
1294
+ flag = true;
1295
+ if (onlyRemove) {
1296
+ break;
1297
+ }
1298
+ }
1299
+ }
1300
+ return flag;
1301
+ };
1302
+ /**
1303
+ *
1304
+ * @type {import("./../types/ajaxHooker.d.ts").UtilsAjaxHookResult["removeFilter"]}
1305
+ */
1306
+ const removeFilter = () => {
1307
+ if (Array.isArray(filter)) {
1308
+ filter.length = 0;
1309
+ }
1310
+ else {
1311
+ filter = void 0;
1312
+ }
1313
+ };
1237
1314
  return {
1238
- hook: (fn) => hookFns.push(fn),
1315
+ hook: (fn) => {
1316
+ hookFns.push(fn);
1317
+ return {
1318
+ remove: () => {
1319
+ return removeHook(fn, true);
1320
+ }
1321
+ };
1322
+ },
1239
1323
  filter: (arr) => {
1240
1324
  filter = Array.isArray(arr) && arr.map(toFilterObj);
1325
+ return {
1326
+ remove: removeFilter
1327
+ };
1241
1328
  },
1242
1329
  protect: () => {
1243
1330
  readonly(win, "XMLHttpRequest", fakeXhr);
@@ -1247,6 +1334,8 @@ define((function () { 'use strict';
1247
1334
  writable(win, "XMLHttpRequest", realXhr);
1248
1335
  writable(win, "fetch", realFetch);
1249
1336
  },
1337
+ removeHook: removeHook,
1338
+ removeFilter: removeFilter
1250
1339
  };
1251
1340
  })();
1252
1341
  };
@@ -1831,13 +1920,25 @@ define((function () { 'use strict';
1831
1920
  }
1832
1921
  /**
1833
1922
  * 迭代字典
1834
- * @param callbackfn 回调函数
1923
+ * @param cb 回调函数
1835
1924
  */
1836
- forEach(callbackfn) {
1925
+ forEach(cb) {
1837
1926
  this.items.forEach((value, key) => {
1838
- callbackfn(value, key, this);
1927
+ cb(value, key, this);
1839
1928
  });
1840
1929
  }
1930
+ /**
1931
+ * 找到字典中对应的键和值
1932
+ * @param cb 回调函数
1933
+ */
1934
+ find(cb) {
1935
+ for (const [key, value] of this.items.entries()) {
1936
+ const result = cb(value, key, this);
1937
+ if (result) {
1938
+ return result;
1939
+ }
1940
+ }
1941
+ }
1841
1942
  /**
1842
1943
  * 检查已有的键中是否以xx开头
1843
1944
  * @param key 需要匹配的键
@@ -2671,42 +2772,42 @@ define((function () { 'use strict';
2671
2772
  const method = requestOption.method;
2672
2773
  if (method === "GET" || method === "HEAD") {
2673
2774
  // GET类型,data如果有,那么需要转为searchParams
2674
- const urlObj = new URL(requestOption.url);
2775
+ const urlInst = new URL(requestOption.url);
2675
2776
  let urlSearch = "";
2676
- let isHandler = false;
2777
+ let deleteData = false;
2677
2778
  if (typeof requestOption.data === "string") {
2678
- isHandler = true;
2779
+ deleteData = true;
2679
2780
  urlSearch = requestOption.data;
2680
2781
  }
2681
2782
  else if (typeof requestOption.data === "object") {
2682
- isHandler = true;
2783
+ deleteData = true;
2683
2784
  // URLSearchParams参数可以转普通的string:string,包括FormData
2684
2785
  const searchParams = new URLSearchParams(requestOption.data);
2685
2786
  urlSearch = searchParams.toString();
2686
2787
  }
2687
- if (isHandler) {
2788
+ if (deleteData) {
2688
2789
  // GET/HEAD请求不支持data参数
2689
2790
  // 对data进行处理了才可以删除
2690
2791
  Reflect.deleteProperty(requestOption, "data");
2691
2792
  }
2692
- if (urlSearch != "") {
2693
- if (urlObj.search === "") {
2793
+ if (urlSearch.trim() != "") {
2794
+ if (urlInst.search.trim() === "") {
2694
2795
  // url没有search参数,直接覆盖
2695
- urlObj.search = urlSearch;
2796
+ urlInst.search = urlSearch;
2696
2797
  }
2697
2798
  else {
2698
2799
  // 有search参数
2699
- if (urlObj.search.endsWith("&")) {
2800
+ if (urlInst.search.trim().endsWith("&")) {
2700
2801
  // xxx=xxx&
2701
- urlObj.search = urlObj.search + urlSearch;
2802
+ urlInst.search = urlInst.search + urlSearch;
2702
2803
  }
2703
2804
  else {
2704
2805
  // xxx=xxx&xxx=
2705
- urlObj.search = `${urlObj.search}&${urlSearch}`;
2806
+ urlInst.search = `${urlInst.search}&${urlSearch}`;
2706
2807
  }
2707
2808
  }
2708
2809
  }
2709
- requestOption.url = urlObj.toString();
2810
+ requestOption.url = urlInst.toString();
2710
2811
  }
2711
2812
  else if (method === "POST" && requestOption.headers != null) {
2712
2813
  // POST类型,data如果是FormData,那么需要转为string
@@ -2716,10 +2817,10 @@ define((function () { 'use strict';
2716
2817
  typeof requestOption.headers[headerKey] === "string");
2717
2818
  });
2718
2819
  if (ContentTypeIndex !== -1) {
2719
- const ContentTypeKey = headersKeyList[ContentTypeIndex];
2720
- const ContentType = requestOption.headers[ContentTypeKey];
2820
+ const contentTypeKey = headersKeyList[ContentTypeIndex];
2821
+ const contentType = requestOption.headers[contentTypeKey].toLowerCase();
2721
2822
  // 设置了Content-Type
2722
- if (ContentType.includes("application/json")) {
2823
+ if (contentType.includes("application/json")) {
2723
2824
  // application/json
2724
2825
  if (requestOption.data instanceof FormData) {
2725
2826
  const entries = {};
@@ -2732,16 +2833,16 @@ define((function () { 'use strict';
2732
2833
  requestOption.data = JSON.stringify(requestOption.data);
2733
2834
  }
2734
2835
  }
2735
- else if (ContentType.includes("application/x-www-form-urlencoded")) {
2836
+ else if (contentType.includes("application/x-www-form-urlencoded")) {
2736
2837
  // application/x-www-form-urlencoded
2737
2838
  if (typeof requestOption.data === "object") {
2738
2839
  requestOption.data = new URLSearchParams(requestOption.data).toString();
2739
2840
  }
2740
2841
  }
2741
- else if (ContentType.includes("multipart/form-data")) {
2842
+ else if (contentType.includes("multipart/form-data")) {
2742
2843
  // multipart/form-data
2743
2844
  if (requestOption.data instanceof FormData) {
2744
- Reflect.deleteProperty(requestOption.headers, ContentTypeKey);
2845
+ Reflect.deleteProperty(requestOption.headers, contentTypeKey);
2745
2846
  }
2746
2847
  }
2747
2848
  }
@@ -5699,20 +5800,25 @@ define((function () { 'use strict';
5699
5800
  }
5700
5801
  /**
5701
5802
  * ajax劫持库,支持xhr和fetch劫持。
5702
- * + 来源:https://bbs.tampermonkey.net.cn/thread-3284-1-1.html
5703
- * + 作者:cxxjackie
5704
- * + 版本:1.4.8
5705
- * + 旧版本:1.2.4
5706
- * + 文档:https://scriptcat.org/zh-CN/script-show-page/637/
5707
- * @param useOldVersion 是否使用旧版本,默认false
5708
- */
5709
- ajaxHooker = (useOldVersion = false) => {
5710
- if (useOldVersion) {
5711
- return AjaxHooker1_2_4();
5712
- }
5713
- else {
5714
- return ajaxHooker();
5715
- }
5803
+ * + 来源: https://bbs.tampermonkey.net.cn/thread-3284-1-1.html
5804
+ * + 作者: cxxjackie
5805
+ * + 实现方式: Proxy
5806
+ * + 版本: `1.4.8`
5807
+ * + 文档: https://scriptcat.org/zh-CN/script-show-page/637/
5808
+ */
5809
+ ajaxHooker = () => {
5810
+ return ajaxHooker();
5811
+ };
5812
+ /**
5813
+ * ajax劫持库,支持xhr和fetch劫持。
5814
+ * + 来源: https://bbs.tampermonkey.net.cn/thread-3284-1-1.html
5815
+ * + 作者: cxxjackie
5816
+ * + 实现方式: Object.defineProperty
5817
+ * + 版本: `1.2.4`
5818
+ * + 文档: https://scriptcat.org/zh-CN/script-show-page/637/
5819
+ */
5820
+ oldAjaxHooker = () => {
5821
+ return AjaxHooker1_2_4();
5716
5822
  };
5717
5823
  canvasClickByPosition(canvasElement, clientX = 0, clientY = 0, view = this.windowApi.window) {
5718
5824
  if (!(canvasElement instanceof HTMLCanvasElement)) {
@@ -7237,6 +7343,26 @@ define((function () { 'use strict';
7237
7343
  }
7238
7344
  return content;
7239
7345
  }
7346
+ /**
7347
+ * 监听页面元素改变并处理
7348
+ * @param target 需要监听的元素,如果不存在,可以等待它出现
7349
+ * @param observer_config MutationObserver的配置
7350
+ * @example
7351
+ Utils.mutationObserver(document.querySelector("div.xxxx"),{
7352
+ "callback":(mutations, observer)=>{},
7353
+ "config":{childList:true,attributes:true}
7354
+ });
7355
+ * @example
7356
+ Utils.mutationObserver(document.querySelectorAll("div.xxxx"),{
7357
+ "callback":(mutations, observer)=>{},
7358
+ "config":{childList:true,attributes:true}}
7359
+ );
7360
+ * @example
7361
+ Utils.mutationObserver($("div.xxxx"),{
7362
+ "callback":(mutations, observer)=>{},
7363
+ "config":{childList:true,attributes:true}}
7364
+ );
7365
+ **/
7240
7366
  mutationObserver(target, observer_config) {
7241
7367
  const that = this;
7242
7368
  const default_obverser_config = {
@@ -7279,16 +7405,24 @@ define((function () { 'use strict';
7279
7405
  characterDataOldValue: void 0,
7280
7406
  },
7281
7407
  immediate: false,
7408
+ once: false,
7282
7409
  };
7283
7410
  observer_config = that.assign(default_obverser_config, observer_config);
7284
7411
  const windowMutationObserver = this.windowApi.window.MutationObserver ||
7285
7412
  this.windowApi.window.webkitMutationObserver ||
7286
7413
  this.windowApi.window.MozMutationObserver;
7287
7414
  // 观察者对象
7288
- const mutationObserver = new windowMutationObserver(function (mutations, observer) {
7415
+ const handler = (mutations, observer) => {
7416
+ if (observer_config.once) {
7417
+ // 仅触发一次
7418
+ observer.disconnect();
7419
+ }
7289
7420
  if (typeof observer_config.callback === "function") {
7290
7421
  observer_config.callback(mutations, observer);
7291
7422
  }
7423
+ };
7424
+ const mutationObserver = new windowMutationObserver(function (mutations, observer) {
7425
+ handler(mutations, observer);
7292
7426
  });
7293
7427
  if (Array.isArray(target) || target instanceof NodeList) {
7294
7428
  // 传入的是数组或者元素数组
@@ -7297,7 +7431,7 @@ define((function () { 'use strict';
7297
7431
  });
7298
7432
  }
7299
7433
  else if (that.isJQuery(target)) {
7300
- /* 传入的参数是jQuery对象 */
7434
+ // 传入的参数是jQuery对象
7301
7435
  target.each((_, item) => {
7302
7436
  mutationObserver.observe(item, observer_config.config);
7303
7437
  });
@@ -7306,16 +7440,14 @@ define((function () { 'use strict';
7306
7440
  mutationObserver.observe(target, observer_config.config);
7307
7441
  }
7308
7442
  if (observer_config.immediate) {
7309
- /* 主动触发一次 */
7310
- if (typeof observer_config.callback === "function") {
7311
- observer_config.callback([], mutationObserver);
7312
- }
7443
+ // 主动触发一次
7444
+ handler([], mutationObserver);
7313
7445
  }
7314
7446
  return mutationObserver;
7315
7447
  }
7316
7448
  /**
7317
7449
  * 使用观察器观察元素出现在视图内,出现的话触发回调
7318
- * @param target 目标元素
7450
+ * @param $el 目标元素
7319
7451
  * @param callback 触发的回调
7320
7452
  * @param options 观察器配置
7321
7453
  * @example
@@ -7323,34 +7455,47 @@ define((function () { 'use strict';
7323
7455
  * console.log("该元素出现在视图内");
7324
7456
  * }))
7325
7457
  */
7326
- mutationVisible(target, callback, options) {
7458
+ mutationVisible($el, callback, options) {
7327
7459
  if (typeof IntersectionObserver === "undefined") {
7328
7460
  throw new TypeError("IntersectionObserver is not defined");
7329
7461
  }
7330
- if (target == null) {
7462
+ if ($el == null) {
7331
7463
  throw new TypeError("mutatuinVisible target is null");
7332
7464
  }
7465
+ options = options || {};
7333
7466
  let defaultOptions = {
7334
7467
  root: null,
7335
7468
  rootMargin: "0px 0px 0px 0px",
7336
7469
  threshold: [0.01, 0.99],
7337
7470
  };
7338
- defaultOptions = this.assign(defaultOptions, options || {});
7471
+ defaultOptions = this.assign(defaultOptions, options);
7472
+ const handler = (entries, observer) => {
7473
+ if (options.once) {
7474
+ // 仅触发一次
7475
+ observer.disconnect();
7476
+ }
7477
+ if (typeof callback === "function") {
7478
+ callback(entries, observer);
7479
+ }
7480
+ };
7339
7481
  const intersectionObserver = new IntersectionObserver((entries, observer) => {
7340
7482
  if (entries[0].isIntersecting) {
7341
- if (typeof callback === "function") {
7342
- callback(entries, observer);
7343
- }
7483
+ handler(entries, observer);
7344
7484
  }
7345
7485
  }, defaultOptions);
7346
- if (Array.isArray(target)) {
7347
- target.forEach((item) => {
7348
- intersectionObserver.observe(item);
7486
+ if (Array.isArray($el)) {
7487
+ $el.forEach(($elItem) => {
7488
+ intersectionObserver.observe($elItem);
7349
7489
  });
7350
7490
  }
7351
7491
  else {
7352
- intersectionObserver.observe(target);
7492
+ intersectionObserver.observe($el);
7353
7493
  }
7494
+ if (options.immediate) {
7495
+ // 立即触发
7496
+ handler([], intersectionObserver);
7497
+ }
7498
+ return intersectionObserver;
7354
7499
  }
7355
7500
  /**
7356
7501
  * 去除全局window下的Utils,返回控制权
@@ -8139,12 +8284,25 @@ define((function () { 'use strict';
8139
8284
  }
8140
8285
  /**
8141
8286
  * 将UrlSearchParams格式的字符串转为对象
8287
+ * @param searhParamsStr 字符串或对象
8288
+ * @example
8289
+ * Utils.searchParamStrToObj("xxx=xx&xx2=xx2")
8290
+ * @example
8291
+ * Utils.searchParamStrToObj(new URLSearchParams({
8292
+ * test1: 1,
8293
+ * test2: 2
8294
+ * }))
8142
8295
  */
8143
8296
  searchParamStrToObj(searhParamsStr) {
8144
- if (typeof searhParamsStr !== "string") {
8145
- return {};
8297
+ const params = {};
8298
+ if (searhParamsStr == null) {
8299
+ return params;
8146
8300
  }
8147
- return Object.fromEntries(new URLSearchParams(searhParamsStr));
8301
+ const urlSearchParams = searhParamsStr instanceof URLSearchParams ? searhParamsStr : new URLSearchParams(searhParamsStr);
8302
+ urlSearchParams.forEach((value, key) => {
8303
+ Reflect.set(params, key, value);
8304
+ });
8305
+ return params;
8148
8306
  }
8149
8307
  /**
8150
8308
  * 提供一个封装了 try-catch 的函数,可以执行传入的函数并捕获其可能抛出的错误,并通过传入的错误处理函数进行处理。