@whitesev/utils 2.11.11 → 2.11.12

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.
@@ -240,7 +240,7 @@ var Utils = (function () {
240
240
  const setInterval$1 = (...args) => loadOrReturnBroker().setInterval(...args);
241
241
  const setTimeout$1 = (...args) => loadOrReturnBroker().setTimeout(...args);
242
242
 
243
- const version = "2.11.11";
243
+ const version = "2.11.12";
244
244
 
245
245
  /* eslint-disable */
246
246
  // ==UserScript==
@@ -375,8 +375,12 @@ var Utils = (function () {
375
375
  }));
376
376
  }
377
377
  waitForRequestKeys() {
378
+ /**
379
+ * @type {Set<typeof hookInst>}
380
+ */
381
+ const winHookInsts = win.__ajaxHooker.hookInsts;
378
382
  if (!this.request.async) {
379
- win.__ajaxHooker.hookInsts.forEach(({ hookFns, filters }) => {
383
+ winHookInsts.forEach(({ hookFns, filters }) => {
380
384
  if (this.shouldFilter(filters))
381
385
  return;
382
386
  hookFns.forEach((fn) => {
@@ -392,10 +396,10 @@ var Utils = (function () {
392
396
  }
393
397
  const promises = [];
394
398
  const ignoreKeys = new Set(["type", "async", "response"]);
395
- win.__ajaxHooker.hookInsts.forEach(({ hookFns, filters }) => {
399
+ winHookInsts.forEach(({ hookFns, filters }) => {
396
400
  if (this.shouldFilter(filters))
397
401
  return;
398
- promises.push(Promise.all(hookFns.map((fn) => catchError(fn, this.request))).then(() => {
402
+ promises.push(Promise.all(hookFns.map((fn, index) => catchError(fn, this.request, index))).then(() => {
399
403
  const requestKeys = [];
400
404
  for (const key in this.request)
401
405
  !ignoreKeys.has(key) && requestKeys.push(key);
@@ -817,11 +821,52 @@ var Utils = (function () {
817
821
  });
818
822
  });
819
823
  }
824
+ /**
825
+ *
826
+ * @type {import("./../types/ajaxHooker.d.ts").UtilsAjaxHookResult["removeHook"]}
827
+ */
828
+ const removeHook = (fn, onlyRemove = false) => {
829
+ let flag = false;
830
+ for (let index = hookInst.hookFns.length - 1; index >= 0; index--) {
831
+ const __fn__ = hookInst.hookFns[index];
832
+ if (fn === __fn__) {
833
+ hookInst.hookFns.splice(index, 1);
834
+ flag = true;
835
+ if (onlyRemove) {
836
+ break;
837
+ }
838
+ }
839
+ }
840
+ return flag;
841
+ };
842
+ /**
843
+ *
844
+ * @type {import("./../types/ajaxHooker.d.ts").UtilsAjaxHookResult["removeFilter"]}
845
+ */
846
+ const removeFilter = () => {
847
+ if (Array.isArray(hookInst.filters)) {
848
+ hookInst.filters.length = 0;
849
+ }
850
+ else {
851
+ hookInst.filters = [];
852
+ }
853
+ };
820
854
  return {
821
- hook: (fn) => hookInst.hookFns.push(fn),
855
+ hook: (fn) => {
856
+ hookInst.hookFns.push(fn);
857
+ return {
858
+ remove: () => {
859
+ return removeHook(fn, true);
860
+ }
861
+ };
862
+ },
822
863
  filter: (arr) => {
823
- if (Array.isArray(arr))
864
+ if (Array.isArray(arr)) {
824
865
  hookInst.filters = arr;
866
+ }
867
+ return {
868
+ remove: removeFilter
869
+ };
825
870
  },
826
871
  protect: () => {
827
872
  readonly(win, "XMLHttpRequest", winAh.fakeXHR);
@@ -837,6 +882,8 @@ var Utils = (function () {
837
882
  delete win.__ajaxHooker;
838
883
  }
839
884
  },
885
+ removeHook: removeHook,
886
+ removeFilter: removeFilter
840
887
  };
841
888
  };
842
889
 
@@ -1235,10 +1282,50 @@ var Utils = (function () {
1235
1282
  Object.keys(realXhr).forEach((key) => (fakeXhr[key] = realXhr[key]));
1236
1283
  fakeXhr.prototype = realXhr.prototype;
1237
1284
  win.fetch = fakeFetch;
1285
+ /**
1286
+ *
1287
+ * @type {import("./../types/ajaxHooker.d.ts").UtilsAjaxHookResult["removeHook"]}
1288
+ */
1289
+ const removeHook = (fn, onlyRemove = false) => {
1290
+ let flag = false;
1291
+ for (let index = hookFns.length - 1; index >= 0; index--) {
1292
+ const __fn__ = hookFns[index];
1293
+ if (fn === __fn__) {
1294
+ hookFns.splice(index, 1);
1295
+ flag = true;
1296
+ if (onlyRemove) {
1297
+ break;
1298
+ }
1299
+ }
1300
+ }
1301
+ return flag;
1302
+ };
1303
+ /**
1304
+ *
1305
+ * @type {import("./../types/ajaxHooker.d.ts").UtilsAjaxHookResult["removeFilter"]}
1306
+ */
1307
+ const removeFilter = () => {
1308
+ if (Array.isArray(filter)) {
1309
+ filter.length = 0;
1310
+ }
1311
+ else {
1312
+ filter = void 0;
1313
+ }
1314
+ };
1238
1315
  return {
1239
- hook: (fn) => hookFns.push(fn),
1316
+ hook: (fn) => {
1317
+ hookFns.push(fn);
1318
+ return {
1319
+ remove: () => {
1320
+ return removeHook(fn, true);
1321
+ }
1322
+ };
1323
+ },
1240
1324
  filter: (arr) => {
1241
1325
  filter = Array.isArray(arr) && arr.map(toFilterObj);
1326
+ return {
1327
+ remove: removeFilter
1328
+ };
1242
1329
  },
1243
1330
  protect: () => {
1244
1331
  readonly(win, "XMLHttpRequest", fakeXhr);
@@ -1248,6 +1335,8 @@ var Utils = (function () {
1248
1335
  writable(win, "XMLHttpRequest", realXhr);
1249
1336
  writable(win, "fetch", realFetch);
1250
1337
  },
1338
+ removeHook: removeHook,
1339
+ removeFilter: removeFilter
1251
1340
  };
1252
1341
  })();
1253
1342
  };
@@ -2672,42 +2761,42 @@ var Utils = (function () {
2672
2761
  const method = requestOption.method;
2673
2762
  if (method === "GET" || method === "HEAD") {
2674
2763
  // GET类型,data如果有,那么需要转为searchParams
2675
- const urlObj = new URL(requestOption.url);
2764
+ const urlInst = new URL(requestOption.url);
2676
2765
  let urlSearch = "";
2677
- let isHandler = false;
2766
+ let deleteData = false;
2678
2767
  if (typeof requestOption.data === "string") {
2679
- isHandler = true;
2768
+ deleteData = true;
2680
2769
  urlSearch = requestOption.data;
2681
2770
  }
2682
2771
  else if (typeof requestOption.data === "object") {
2683
- isHandler = true;
2772
+ deleteData = true;
2684
2773
  // URLSearchParams参数可以转普通的string:string,包括FormData
2685
2774
  const searchParams = new URLSearchParams(requestOption.data);
2686
2775
  urlSearch = searchParams.toString();
2687
2776
  }
2688
- if (isHandler) {
2777
+ if (deleteData) {
2689
2778
  // GET/HEAD请求不支持data参数
2690
2779
  // 对data进行处理了才可以删除
2691
2780
  Reflect.deleteProperty(requestOption, "data");
2692
2781
  }
2693
- if (urlSearch != "") {
2694
- if (urlObj.search === "") {
2782
+ if (urlSearch.trim() != "") {
2783
+ if (urlInst.search.trim() === "") {
2695
2784
  // url没有search参数,直接覆盖
2696
- urlObj.search = urlSearch;
2785
+ urlInst.search = urlSearch;
2697
2786
  }
2698
2787
  else {
2699
2788
  // 有search参数
2700
- if (urlObj.search.endsWith("&")) {
2789
+ if (urlInst.search.trim().endsWith("&")) {
2701
2790
  // xxx=xxx&
2702
- urlObj.search = urlObj.search + urlSearch;
2791
+ urlInst.search = urlInst.search + urlSearch;
2703
2792
  }
2704
2793
  else {
2705
2794
  // xxx=xxx&xxx=
2706
- urlObj.search = `${urlObj.search}&${urlSearch}`;
2795
+ urlInst.search = `${urlInst.search}&${urlSearch}`;
2707
2796
  }
2708
2797
  }
2709
2798
  }
2710
- requestOption.url = urlObj.toString();
2799
+ requestOption.url = urlInst.toString();
2711
2800
  }
2712
2801
  else if (method === "POST" && requestOption.headers != null) {
2713
2802
  // POST类型,data如果是FormData,那么需要转为string
@@ -2717,10 +2806,10 @@ var Utils = (function () {
2717
2806
  typeof requestOption.headers[headerKey] === "string");
2718
2807
  });
2719
2808
  if (ContentTypeIndex !== -1) {
2720
- const ContentTypeKey = headersKeyList[ContentTypeIndex];
2721
- const ContentType = requestOption.headers[ContentTypeKey];
2809
+ const contentTypeKey = headersKeyList[ContentTypeIndex];
2810
+ const contentType = requestOption.headers[contentTypeKey].toLowerCase();
2722
2811
  // 设置了Content-Type
2723
- if (ContentType.includes("application/json")) {
2812
+ if (contentType.includes("application/json")) {
2724
2813
  // application/json
2725
2814
  if (requestOption.data instanceof FormData) {
2726
2815
  const entries = {};
@@ -2733,16 +2822,16 @@ var Utils = (function () {
2733
2822
  requestOption.data = JSON.stringify(requestOption.data);
2734
2823
  }
2735
2824
  }
2736
- else if (ContentType.includes("application/x-www-form-urlencoded")) {
2825
+ else if (contentType.includes("application/x-www-form-urlencoded")) {
2737
2826
  // application/x-www-form-urlencoded
2738
2827
  if (typeof requestOption.data === "object") {
2739
2828
  requestOption.data = new URLSearchParams(requestOption.data).toString();
2740
2829
  }
2741
2830
  }
2742
- else if (ContentType.includes("multipart/form-data")) {
2831
+ else if (contentType.includes("multipart/form-data")) {
2743
2832
  // multipart/form-data
2744
2833
  if (requestOption.data instanceof FormData) {
2745
- Reflect.deleteProperty(requestOption.headers, ContentTypeKey);
2834
+ Reflect.deleteProperty(requestOption.headers, contentTypeKey);
2746
2835
  }
2747
2836
  }
2748
2837
  }
@@ -5700,20 +5789,25 @@ var Utils = (function () {
5700
5789
  }
5701
5790
  /**
5702
5791
  * ajax劫持库,支持xhr和fetch劫持。
5703
- * + 来源:https://bbs.tampermonkey.net.cn/thread-3284-1-1.html
5704
- * + 作者:cxxjackie
5705
- * + 版本:1.4.8
5706
- * + 旧版本:1.2.4
5707
- * + 文档:https://scriptcat.org/zh-CN/script-show-page/637/
5708
- * @param useOldVersion 是否使用旧版本,默认false
5709
- */
5710
- ajaxHooker = (useOldVersion = false) => {
5711
- if (useOldVersion) {
5712
- return AjaxHooker1_2_4();
5713
- }
5714
- else {
5715
- return ajaxHooker();
5716
- }
5792
+ * + 来源: https://bbs.tampermonkey.net.cn/thread-3284-1-1.html
5793
+ * + 作者: cxxjackie
5794
+ * + 实现方式: Proxy
5795
+ * + 版本: `1.4.8`
5796
+ * + 文档: https://scriptcat.org/zh-CN/script-show-page/637/
5797
+ */
5798
+ ajaxHooker = () => {
5799
+ return ajaxHooker();
5800
+ };
5801
+ /**
5802
+ * ajax劫持库,支持xhr和fetch劫持。
5803
+ * + 来源: https://bbs.tampermonkey.net.cn/thread-3284-1-1.html
5804
+ * + 作者: cxxjackie
5805
+ * + 实现方式: Object.defineProperty
5806
+ * + 版本: `1.2.4`
5807
+ * + 文档: https://scriptcat.org/zh-CN/script-show-page/637/
5808
+ */
5809
+ oldAjaxHooker = () => {
5810
+ return AjaxHooker1_2_4();
5717
5811
  };
5718
5812
  canvasClickByPosition(canvasElement, clientX = 0, clientY = 0, view = this.windowApi.window) {
5719
5813
  if (!(canvasElement instanceof HTMLCanvasElement)) {
@@ -7238,6 +7332,26 @@ var Utils = (function () {
7238
7332
  }
7239
7333
  return content;
7240
7334
  }
7335
+ /**
7336
+ * 监听页面元素改变并处理
7337
+ * @param target 需要监听的元素,如果不存在,可以等待它出现
7338
+ * @param observer_config MutationObserver的配置
7339
+ * @example
7340
+ Utils.mutationObserver(document.querySelector("div.xxxx"),{
7341
+ "callback":(mutations, observer)=>{},
7342
+ "config":{childList:true,attributes:true}
7343
+ });
7344
+ * @example
7345
+ Utils.mutationObserver(document.querySelectorAll("div.xxxx"),{
7346
+ "callback":(mutations, observer)=>{},
7347
+ "config":{childList:true,attributes:true}}
7348
+ );
7349
+ * @example
7350
+ Utils.mutationObserver($("div.xxxx"),{
7351
+ "callback":(mutations, observer)=>{},
7352
+ "config":{childList:true,attributes:true}}
7353
+ );
7354
+ **/
7241
7355
  mutationObserver(target, observer_config) {
7242
7356
  const that = this;
7243
7357
  const default_obverser_config = {
@@ -7280,16 +7394,24 @@ var Utils = (function () {
7280
7394
  characterDataOldValue: void 0,
7281
7395
  },
7282
7396
  immediate: false,
7397
+ once: false,
7283
7398
  };
7284
7399
  observer_config = that.assign(default_obverser_config, observer_config);
7285
7400
  const windowMutationObserver = this.windowApi.window.MutationObserver ||
7286
7401
  this.windowApi.window.webkitMutationObserver ||
7287
7402
  this.windowApi.window.MozMutationObserver;
7288
7403
  // 观察者对象
7289
- const mutationObserver = new windowMutationObserver(function (mutations, observer) {
7404
+ const handler = (mutations, observer) => {
7405
+ if (observer_config.once) {
7406
+ // 仅触发一次
7407
+ observer.disconnect();
7408
+ }
7290
7409
  if (typeof observer_config.callback === "function") {
7291
7410
  observer_config.callback(mutations, observer);
7292
7411
  }
7412
+ };
7413
+ const mutationObserver = new windowMutationObserver(function (mutations, observer) {
7414
+ handler(mutations, observer);
7293
7415
  });
7294
7416
  if (Array.isArray(target) || target instanceof NodeList) {
7295
7417
  // 传入的是数组或者元素数组
@@ -7298,7 +7420,7 @@ var Utils = (function () {
7298
7420
  });
7299
7421
  }
7300
7422
  else if (that.isJQuery(target)) {
7301
- /* 传入的参数是jQuery对象 */
7423
+ // 传入的参数是jQuery对象
7302
7424
  target.each((_, item) => {
7303
7425
  mutationObserver.observe(item, observer_config.config);
7304
7426
  });
@@ -7307,16 +7429,14 @@ var Utils = (function () {
7307
7429
  mutationObserver.observe(target, observer_config.config);
7308
7430
  }
7309
7431
  if (observer_config.immediate) {
7310
- /* 主动触发一次 */
7311
- if (typeof observer_config.callback === "function") {
7312
- observer_config.callback([], mutationObserver);
7313
- }
7432
+ // 主动触发一次
7433
+ handler([], mutationObserver);
7314
7434
  }
7315
7435
  return mutationObserver;
7316
7436
  }
7317
7437
  /**
7318
7438
  * 使用观察器观察元素出现在视图内,出现的话触发回调
7319
- * @param target 目标元素
7439
+ * @param $el 目标元素
7320
7440
  * @param callback 触发的回调
7321
7441
  * @param options 观察器配置
7322
7442
  * @example
@@ -7324,34 +7444,47 @@ var Utils = (function () {
7324
7444
  * console.log("该元素出现在视图内");
7325
7445
  * }))
7326
7446
  */
7327
- mutationVisible(target, callback, options) {
7447
+ mutationVisible($el, callback, options) {
7328
7448
  if (typeof IntersectionObserver === "undefined") {
7329
7449
  throw new TypeError("IntersectionObserver is not defined");
7330
7450
  }
7331
- if (target == null) {
7451
+ if ($el == null) {
7332
7452
  throw new TypeError("mutatuinVisible target is null");
7333
7453
  }
7454
+ options = options || {};
7334
7455
  let defaultOptions = {
7335
7456
  root: null,
7336
7457
  rootMargin: "0px 0px 0px 0px",
7337
7458
  threshold: [0.01, 0.99],
7338
7459
  };
7339
- defaultOptions = this.assign(defaultOptions, options || {});
7460
+ defaultOptions = this.assign(defaultOptions, options);
7461
+ const handler = (entries, observer) => {
7462
+ if (options.once) {
7463
+ // 仅触发一次
7464
+ observer.disconnect();
7465
+ }
7466
+ if (typeof callback === "function") {
7467
+ callback(entries, observer);
7468
+ }
7469
+ };
7340
7470
  const intersectionObserver = new IntersectionObserver((entries, observer) => {
7341
7471
  if (entries[0].isIntersecting) {
7342
- if (typeof callback === "function") {
7343
- callback(entries, observer);
7344
- }
7472
+ handler(entries, observer);
7345
7473
  }
7346
7474
  }, defaultOptions);
7347
- if (Array.isArray(target)) {
7348
- target.forEach((item) => {
7349
- intersectionObserver.observe(item);
7475
+ if (Array.isArray($el)) {
7476
+ $el.forEach(($elItem) => {
7477
+ intersectionObserver.observe($elItem);
7350
7478
  });
7351
7479
  }
7352
7480
  else {
7353
- intersectionObserver.observe(target);
7481
+ intersectionObserver.observe($el);
7354
7482
  }
7483
+ if (options.immediate) {
7484
+ // 立即触发
7485
+ handler([], intersectionObserver);
7486
+ }
7487
+ return intersectionObserver;
7355
7488
  }
7356
7489
  /**
7357
7490
  * 去除全局window下的Utils,返回控制权
@@ -8140,12 +8273,25 @@ var Utils = (function () {
8140
8273
  }
8141
8274
  /**
8142
8275
  * 将UrlSearchParams格式的字符串转为对象
8276
+ * @param searhParamsStr 字符串或对象
8277
+ * @example
8278
+ * Utils.searchParamStrToObj("xxx=xx&xx2=xx2")
8279
+ * @example
8280
+ * Utils.searchParamStrToObj(new URLSearchParams({
8281
+ * test1: 1,
8282
+ * test2: 2
8283
+ * }))
8143
8284
  */
8144
8285
  searchParamStrToObj(searhParamsStr) {
8145
- if (typeof searhParamsStr !== "string") {
8146
- return {};
8286
+ const params = {};
8287
+ if (searhParamsStr == null) {
8288
+ return params;
8147
8289
  }
8148
- return Object.fromEntries(new URLSearchParams(searhParamsStr));
8290
+ const urlSearchParams = searhParamsStr instanceof URLSearchParams ? searhParamsStr : new URLSearchParams(searhParamsStr);
8291
+ urlSearchParams.forEach((value, key) => {
8292
+ Reflect.set(params, key, value);
8293
+ });
8294
+ return params;
8149
8295
  }
8150
8296
  /**
8151
8297
  * 提供一个封装了 try-catch 的函数,可以执行传入的函数并捕获其可能抛出的错误,并通过传入的错误处理函数进行处理。