@whitesev/utils 1.4.0 → 1.4.2

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.umd.js CHANGED
@@ -464,47 +464,31 @@
464
464
  /// <reference path="./index.d.ts" />
465
465
  // @name ajaxHooker
466
466
  // @author cxxjackie
467
- // @version 1.4.1
467
+ // @version 1.4.2
468
+ // @updateLog 修复了fetch请求的参数为Request类型时body类型不正确的bug。
468
469
  // @supportURL https://bbs.tampermonkey.net.cn/thread-3284-1-1.html
469
470
 
470
471
  const AjaxHooker = function () {
471
- return (function () {
472
- const version = "1.4.1";
472
+ return function() {
473
+ const version = '1.4.2';
473
474
  const hookInst = {
474
475
  hookFns: [],
475
- filters: [],
476
+ filters: []
476
477
  };
477
478
  const win = window.unsafeWindow || document.defaultView || window;
478
479
  let winAh = win.__ajaxHooker;
479
480
  const resProto = win.Response.prototype;
480
- const xhrResponses = ["response", "responseText", "responseXML"];
481
- const fetchResponses = ["arrayBuffer", "blob", "formData", "json", "text"];
482
- const fetchInitProps = [
483
- "method",
484
- "headers",
485
- "body",
486
- "mode",
487
- "credentials",
488
- "cache",
489
- "redirect",
490
- "referrer",
491
- "referrerPolicy",
492
- "integrity",
493
- "keepalive",
494
- "signal",
495
- "priority",
496
- ];
497
- const xhrAsyncEvents = ["readystatechange", "load", "loadend"];
498
- const getType = {}.toString.call.bind({}.toString);
481
+ const xhrResponses = ['response', 'responseText', 'responseXML'];
482
+ const fetchResponses = ['arrayBuffer', 'blob', 'formData', 'json', 'text'];
483
+ const fetchInitProps = ['method', 'headers', 'body', 'mode', 'credentials', 'cache', 'redirect',
484
+ 'referrer', 'referrerPolicy', 'integrity', 'keepalive', 'signal', 'priority'];
485
+ const xhrAsyncEvents = ['readystatechange', 'load', 'loadend'];
486
+ const getType = ({}).toString.call.bind(({}).toString);
499
487
  const getDescriptor = Object.getOwnPropertyDescriptor.bind(Object);
500
488
  const emptyFn = () => {};
501
- const errorFn = (e) => console.error(e);
489
+ const errorFn = e => console.error(e);
502
490
  function isThenable(obj) {
503
- return (
504
- obj &&
505
- ["object", "function"].includes(typeof obj) &&
506
- typeof obj.then === "function"
507
- );
491
+ return obj && ['object', 'function'].includes(typeof obj) && typeof obj.then === 'function';
508
492
  }
509
493
  function catchError(fn, ...args) {
510
494
  try {
@@ -520,7 +504,7 @@
520
504
  configurable: true,
521
505
  enumerable: true,
522
506
  get: getter,
523
- set: setter,
507
+ set: setter
524
508
  });
525
509
  }
526
510
  function readonly(obj, prop, value = obj[prop]) {
@@ -531,28 +515,27 @@
531
515
  configurable: true,
532
516
  enumerable: true,
533
517
  writable: true,
534
- value: value,
518
+ value: value
535
519
  });
536
520
  }
537
521
  function parseHeaders(obj) {
538
522
  const headers = {};
539
523
  switch (getType(obj)) {
540
- case "[object String]":
524
+ case '[object String]':
541
525
  for (const line of obj.trim().split(/[\r\n]+/)) {
542
526
  const [header, value] = line.split(/\s*:\s*/);
543
527
  if (!header) break;
544
528
  const lheader = header.toLowerCase();
545
- headers[lheader] =
546
- lheader in headers ? `${headers[lheader]}, ${value}` : value;
529
+ headers[lheader] = lheader in headers ? `${headers[lheader]}, ${value}` : value;
547
530
  }
548
531
  break;
549
- case "[object Headers]":
532
+ case '[object Headers]':
550
533
  for (const [key, val] of obj) {
551
534
  headers[key] = val;
552
535
  }
553
536
  break;
554
- case "[object Object]":
555
- return { ...obj };
537
+ case '[object Object]':
538
+ return {...obj};
556
539
  }
557
540
  return headers;
558
541
  }
@@ -568,142 +551,104 @@
568
551
  class AHRequest {
569
552
  constructor(request) {
570
553
  this.request = request;
571
- this.requestClone = { ...this.request };
554
+ this.requestClone = {...this.request};
572
555
  }
573
556
  shouldFilter(filters) {
574
- const { type, url, method, async } = this.request;
575
- return (
576
- filters.length &&
577
- !filters.find((obj) => {
578
- switch (true) {
579
- case obj.type && obj.type !== type:
580
- case getType(obj.url) === "[object String]" &&
581
- !url.includes(obj.url):
582
- case getType(obj.url) === "[object RegExp]" && !obj.url.test(url):
583
- case obj.method &&
584
- obj.method.toUpperCase() !== method.toUpperCase():
585
- case "async" in obj && obj.async !== async:
586
- return false;
587
- }
588
- return true;
589
- })
590
- );
557
+ const {type, url, method, async} = this.request;
558
+ return filters.length && !filters.find(obj => {
559
+ switch (true) {
560
+ case obj.type && obj.type !== type:
561
+ case getType(obj.url) === '[object String]' && !url.includes(obj.url):
562
+ case getType(obj.url) === '[object RegExp]' && !obj.url.test(url):
563
+ case obj.method && obj.method.toUpperCase() !== method.toUpperCase():
564
+ case 'async' in obj && obj.async !== async:
565
+ return false;
566
+ }
567
+ return true;
568
+ });
591
569
  }
592
570
  waitForRequestKeys() {
593
- const requestKeys = ["url", "method", "abort", "headers", "data"];
571
+ const requestKeys = ['url', 'method', 'abort', 'headers', 'data'];
594
572
  if (!this.request.async) {
595
- win.__ajaxHooker.hookInsts.forEach(({ hookFns, filters }) => {
573
+ win.__ajaxHooker.hookInsts.forEach(({hookFns, filters}) => {
596
574
  if (this.shouldFilter(filters)) return;
597
- hookFns.forEach((fn) => {
598
- if (getType(fn) === "[object Function]")
599
- catchError(fn, this.request);
575
+ hookFns.forEach(fn => {
576
+ if (getType(fn) === '[object Function]') catchError(fn, this.request);
600
577
  });
601
- requestKeys.forEach((key) => {
602
- if (isThenable(this.request[key]))
603
- this.request[key] = this.requestClone[key];
578
+ requestKeys.forEach(key => {
579
+ if (isThenable(this.request[key])) this.request[key] = this.requestClone[key];
604
580
  });
605
581
  });
606
582
  return new SyncThenable();
607
583
  }
608
584
  const promises = [];
609
- win.__ajaxHooker.hookInsts.forEach(({ hookFns, filters }) => {
585
+ win.__ajaxHooker.hookInsts.forEach(({hookFns, filters}) => {
610
586
  if (this.shouldFilter(filters)) return;
611
- promises.push(
612
- Promise.all(hookFns.map((fn) => catchError(fn, this.request))).then(
613
- () =>
614
- Promise.all(
615
- requestKeys.map((key) =>
616
- Promise.resolve(this.request[key]).then(
617
- (val) => (this.request[key] = val),
618
- () => (this.request[key] = this.requestClone[key])
619
- )
620
- )
621
- )
622
- )
623
- );
587
+ promises.push(Promise.all(hookFns.map(fn => catchError(fn, this.request))).then(() =>
588
+ Promise.all(requestKeys.map(key => Promise.resolve(this.request[key]).then(
589
+ val => this.request[key] = val,
590
+ () => this.request[key] = this.requestClone[key]
591
+ )))
592
+ ));
624
593
  });
625
594
  return Promise.all(promises);
626
595
  }
627
596
  waitForResponseKeys(response) {
628
- const responseKeys =
629
- this.request.type === "xhr" ? xhrResponses : fetchResponses;
597
+ const responseKeys = this.request.type === 'xhr' ? xhrResponses : fetchResponses;
630
598
  if (!this.request.async) {
631
- if (getType(this.request.response) === "[object Function]") {
599
+ if (getType(this.request.response) === '[object Function]') {
632
600
  catchError(this.request.response, response);
633
- responseKeys.forEach((key) => {
634
- if (
635
- "get" in getDescriptor(response, key) ||
636
- isThenable(response[key])
637
- ) {
601
+ responseKeys.forEach(key => {
602
+ if ('get' in getDescriptor(response, key) || isThenable(response[key])) {
638
603
  delete response[key];
639
604
  }
640
605
  });
641
606
  }
642
607
  return new SyncThenable();
643
608
  }
644
- return Promise.resolve(
645
- catchError(this.request.response, response)
646
- ).then(() =>
647
- Promise.all(
648
- responseKeys.map((key) => {
649
- const descriptor = getDescriptor(response, key);
650
- if (descriptor && "value" in descriptor) {
651
- return Promise.resolve(descriptor.value).then(
652
- (val) => (response[key] = val),
653
- () => delete response[key]
654
- );
655
- } else {
656
- delete response[key];
657
- }
658
- })
659
- )
609
+ return Promise.resolve(catchError(this.request.response, response)).then(() =>
610
+ Promise.all(responseKeys.map(key => {
611
+ const descriptor = getDescriptor(response, key);
612
+ if (descriptor && 'value' in descriptor) {
613
+ return Promise.resolve(descriptor.value).then(
614
+ val => response[key] = val,
615
+ () => delete response[key]
616
+ );
617
+ } else {
618
+ delete response[key];
619
+ }
620
+ }))
660
621
  );
661
622
  }
662
623
  }
663
624
  const proxyHandler = {
664
625
  get(target, prop) {
665
626
  const descriptor = getDescriptor(target, prop);
666
- if (
667
- descriptor &&
668
- !descriptor.configurable &&
669
- !descriptor.writable &&
670
- !descriptor.get
671
- )
672
- return target[prop];
627
+ if (descriptor && !descriptor.configurable && !descriptor.writable && !descriptor.get) return target[prop];
673
628
  const ah = target.__ajaxHooker;
674
629
  if (ah && ah.proxyProps) {
675
630
  if (prop in ah.proxyProps) {
676
631
  const pDescriptor = ah.proxyProps[prop];
677
- if ("get" in pDescriptor) return pDescriptor.get();
678
- if (typeof pDescriptor.value === "function")
679
- return pDescriptor.value.bind(ah);
632
+ if ('get' in pDescriptor) return pDescriptor.get();
633
+ if (typeof pDescriptor.value === 'function') return pDescriptor.value.bind(ah);
680
634
  return pDescriptor.value;
681
635
  }
682
- if (typeof target[prop] === "function")
683
- return target[prop].bind(target);
636
+ if (typeof target[prop] === 'function') return target[prop].bind(target);
684
637
  }
685
638
  return target[prop];
686
639
  },
687
640
  set(target, prop, value) {
688
641
  const descriptor = getDescriptor(target, prop);
689
- if (
690
- descriptor &&
691
- !descriptor.configurable &&
692
- !descriptor.writable &&
693
- !descriptor.set
694
- )
695
- return true;
642
+ if (descriptor && !descriptor.configurable && !descriptor.writable && !descriptor.set) return true;
696
643
  const ah = target.__ajaxHooker;
697
644
  if (ah && ah.proxyProps && prop in ah.proxyProps) {
698
645
  const pDescriptor = ah.proxyProps[prop];
699
- pDescriptor.set
700
- ? pDescriptor.set(value)
701
- : (pDescriptor.value = value);
646
+ pDescriptor.set ? pDescriptor.set(value) : (pDescriptor.value = value);
702
647
  } else {
703
648
  target[prop] = value;
704
649
  }
705
650
  return true;
706
- },
651
+ }
707
652
  };
708
653
  class XhrHooker {
709
654
  constructor(xhr) {
@@ -713,112 +658,85 @@
713
658
  proxyXhr: new Proxy(xhr, proxyHandler),
714
659
  resThenable: new SyncThenable(),
715
660
  proxyProps: {},
716
- proxyEvents: {},
661
+ proxyEvents: {}
717
662
  });
718
- xhr.addEventListener("readystatechange", (e) => {
719
- if (
720
- ah.proxyXhr.readyState === 4 &&
721
- ah.request &&
722
- typeof ah.request.response === "function"
723
- ) {
663
+ xhr.addEventListener('readystatechange', e => {
664
+ if (ah.proxyXhr.readyState === 4 && ah.request && typeof ah.request.response === 'function') {
724
665
  const response = {
725
666
  finalUrl: ah.proxyXhr.responseURL,
726
667
  status: ah.proxyXhr.status,
727
- responseHeaders: parseHeaders(
728
- ah.proxyXhr.getAllResponseHeaders()
729
- ),
668
+ responseHeaders: parseHeaders(ah.proxyXhr.getAllResponseHeaders())
730
669
  };
731
670
  const tempValues = {};
732
671
  for (const key of xhrResponses) {
733
672
  try {
734
673
  tempValues[key] = ah.originalXhr[key];
735
674
  } catch (err) {}
736
- defineProp(
737
- response,
738
- key,
739
- () => {
740
- return (response[key] = tempValues[key]);
741
- },
742
- (val) => {
743
- delete response[key];
744
- response[key] = val;
745
- }
746
- );
747
- }
748
- ah.resThenable = new AHRequest(ah.request)
749
- .waitForResponseKeys(response)
750
- .then(() => {
751
- for (const key of xhrResponses) {
752
- ah.proxyProps[key] = {
753
- get: () => {
754
- if (!(key in response)) response[key] = tempValues[key];
755
- return response[key];
756
- },
757
- };
758
- }
675
+ defineProp(response, key, () => {
676
+ return response[key] = tempValues[key];
677
+ }, val => {
678
+ delete response[key];
679
+ response[key] = val;
759
680
  });
681
+ }
682
+ ah.resThenable = new AHRequest(ah.request).waitForResponseKeys(response).then(() => {
683
+ for (const key of xhrResponses) {
684
+ ah.proxyProps[key] = {get: () => {
685
+ if (!(key in response)) response[key] = tempValues[key];
686
+ return response[key];
687
+ }};
688
+ }
689
+ });
760
690
  }
761
691
  ah.dispatchEvent(e);
762
692
  });
763
- xhr.addEventListener("load", (e) => ah.dispatchEvent(e));
764
- xhr.addEventListener("loadend", (e) => ah.dispatchEvent(e));
693
+ xhr.addEventListener('load', e => ah.dispatchEvent(e));
694
+ xhr.addEventListener('loadend', e => ah.dispatchEvent(e));
765
695
  for (const evt of xhrAsyncEvents) {
766
- const onEvt = "on" + evt;
696
+ const onEvt = 'on' + evt;
767
697
  ah.proxyProps[onEvt] = {
768
698
  get: () => ah.proxyEvents[onEvt] || null,
769
- set: (val) => ah.addEvent(onEvt, val),
699
+ set: val => ah.addEvent(onEvt, val)
770
700
  };
771
701
  }
772
- for (const method of [
773
- "setRequestHeader",
774
- "addEventListener",
775
- "removeEventListener",
776
- "open",
777
- "send",
778
- ]) {
779
- ah.proxyProps[method] = { value: ah[method] };
702
+ for (const method of ['setRequestHeader', 'addEventListener', 'removeEventListener', 'open', 'send']) {
703
+ ah.proxyProps[method] = {value: ah[method]};
780
704
  }
781
705
  }
782
706
  toJSON() {} // Converting circular structure to JSON
783
707
  addEvent(type, event) {
784
- if (type.startsWith("on")) {
785
- this.proxyEvents[type] = typeof event === "function" ? event : null;
708
+ if (type.startsWith('on')) {
709
+ this.proxyEvents[type] = typeof event === 'function' ? event : null;
786
710
  } else {
787
- if (typeof event === "object" && event !== null)
788
- event = event.handleEvent;
789
- if (typeof event !== "function") return;
711
+ if (typeof event === 'object' && event !== null) event = event.handleEvent;
712
+ if (typeof event !== 'function') return;
790
713
  this.proxyEvents[type] = this.proxyEvents[type] || new Set();
791
714
  this.proxyEvents[type].add(event);
792
715
  }
793
716
  }
794
717
  removeEvent(type, event) {
795
- if (type.startsWith("on")) {
718
+ if (type.startsWith('on')) {
796
719
  this.proxyEvents[type] = null;
797
720
  } else {
798
- if (typeof event === "object" && event !== null)
799
- event = event.handleEvent;
721
+ if (typeof event === 'object' && event !== null) event = event.handleEvent;
800
722
  this.proxyEvents[type] && this.proxyEvents[type].delete(event);
801
723
  }
802
724
  }
803
725
  dispatchEvent(e) {
804
726
  e.stopImmediatePropagation = stopImmediatePropagation;
805
- defineProp(e, "target", () => this.proxyXhr);
806
- this.proxyEvents[e.type] &&
807
- this.proxyEvents[e.type].forEach((fn) => {
808
- this.resThenable.then(
809
- () => !e.ajaxHooker_isStopped && fn.call(this.proxyXhr, e)
810
- );
811
- });
727
+ defineProp(e, 'target', () => this.proxyXhr);
728
+ this.proxyEvents[e.type] && this.proxyEvents[e.type].forEach(fn => {
729
+ this.resThenable.then(() => !e.ajaxHooker_isStopped && fn.call(this.proxyXhr, e));
730
+ });
812
731
  if (e.ajaxHooker_isStopped) return;
813
- const onEvent = this.proxyEvents["on" + e.type];
732
+ const onEvent = this.proxyEvents['on' + e.type];
814
733
  onEvent && this.resThenable.then(onEvent.bind(this.proxyXhr, e));
815
734
  }
816
735
  setRequestHeader(header, value) {
817
736
  this.originalXhr.setRequestHeader(header, value);
818
737
  if (this.originalXhr.readyState !== 1) return;
819
738
  const headers = this.request.headers;
820
- headers[header] =
821
- header in headers ? `${headers[header]}, ${value}` : value;
739
+ headers[header] = header in headers ? `${headers[header]}, ${value}` : value;
822
740
  }
823
741
  addEventListener(...args) {
824
742
  if (xhrAsyncEvents.includes(args[0])) {
@@ -836,24 +754,18 @@
836
754
  }
837
755
  open(method, url, async = true, ...args) {
838
756
  this.request = {
839
- type: "xhr",
757
+ type: 'xhr',
840
758
  url: url.toString(),
841
759
  method: method.toUpperCase(),
842
760
  abort: false,
843
761
  headers: {},
844
762
  data: null,
845
763
  response: null,
846
- async: !!async,
764
+ async: !!async
847
765
  };
848
766
  this.openArgs = args;
849
767
  this.resThenable = new SyncThenable();
850
- [
851
- "responseURL",
852
- "readyState",
853
- "status",
854
- "statusText",
855
- ...xhrResponses,
856
- ].forEach((key) => {
768
+ ['responseURL', 'readyState', 'status', 'statusText', ...xhrResponses].forEach(key => {
857
769
  delete this.proxyProps[key];
858
770
  });
859
771
  return this.originalXhr.open(method, url, async, ...args);
@@ -866,24 +778,17 @@
866
778
  request.data = data;
867
779
  new AHRequest(request).waitForRequestKeys().then(() => {
868
780
  if (request.abort) {
869
- if (typeof request.response === "function") {
781
+ if (typeof request.response === 'function') {
870
782
  Object.assign(ah.proxyProps, {
871
- responseURL: { value: request.url },
872
- readyState: { value: 4 },
873
- status: { value: 200 },
874
- statusText: { value: "OK" },
783
+ responseURL: {value: request.url},
784
+ readyState: {value: 4},
785
+ status: {value: 200},
786
+ statusText: {value: 'OK'}
875
787
  });
876
- xhrAsyncEvents.forEach((evt) =>
877
- xhr.dispatchEvent(new Event(evt))
878
- );
788
+ xhrAsyncEvents.forEach(evt => xhr.dispatchEvent(new Event(evt)));
879
789
  }
880
790
  } else {
881
- xhr.open(
882
- request.method,
883
- request.url,
884
- request.async,
885
- ...ah.openArgs
886
- );
791
+ xhr.open(request.method, request.url, request.async, ...ah.openArgs);
887
792
  for (const header in request.headers) {
888
793
  xhr.setRequestHeader(header, request.headers[header]);
889
794
  }
@@ -894,98 +799,82 @@
894
799
  }
895
800
  function fakeXHR() {
896
801
  const xhr = new winAh.realXHR();
897
- if ("__ajaxHooker" in xhr)
898
- console.warn("检测到不同版本的ajaxHooker,可能发生冲突!");
802
+ if ('__ajaxHooker' in xhr) console.warn('检测到不同版本的ajaxHooker,可能发生冲突!');
899
803
  xhr.__ajaxHooker = new XhrHooker(xhr);
900
804
  return xhr.__ajaxHooker.proxyXhr;
901
805
  }
902
806
  fakeXHR.prototype = win.XMLHttpRequest.prototype;
903
- Object.keys(win.XMLHttpRequest).forEach(
904
- (key) => (fakeXHR[key] = win.XMLHttpRequest[key])
905
- );
807
+ Object.keys(win.XMLHttpRequest).forEach(key => fakeXHR[key] = win.XMLHttpRequest[key]);
906
808
  function fakeFetch(url, options = {}) {
907
809
  if (!url) return winAh.realFetch.call(win, url, options);
908
- const init = {};
909
- if (getType(url) === "[object Request]") {
910
- for (const prop of fetchInitProps) init[prop] = url[prop];
911
- url = url.url;
912
- }
913
- url = url.toString();
914
- Object.assign(init, options);
915
- init.method = init.method || "GET";
916
- init.headers = init.headers || {};
917
- const request = {
918
- type: "fetch",
919
- url: url,
920
- method: init.method.toUpperCase(),
921
- abort: false,
922
- headers: parseHeaders(init.headers),
923
- data: init.body,
924
- response: null,
925
- async: true,
926
- };
927
- const req = new AHRequest(request);
928
- return new Promise((resolve, reject) => {
929
- req
930
- .waitForRequestKeys()
931
- .then(() => {
932
- if (request.abort) {
933
- if (typeof request.response === "function") {
934
- const response = {
935
- finalUrl: request.url,
936
- status: 200,
937
- responseHeaders: {},
938
- };
939
- req.waitForResponseKeys(response).then(() => {
940
- const key = fetchResponses.find((k) => k in response);
941
- let val = response[key];
942
- if (key === "json" && typeof val === "object") {
943
- val = catchError(JSON.stringify.bind(JSON), val);
944
- }
945
- const res = new Response(val, {
946
- status: 200,
947
- statusText: "OK",
948
- });
949
- defineProp(res, "type", () => "basic");
950
- defineProp(res, "url", () => request.url);
951
- resolve(res);
952
- });
953
- } else {
954
- reject(new DOMException("aborted", "AbortError"));
955
- }
956
- return;
810
+ return new Promise(async (resolve, reject) => {
811
+ const init = {};
812
+ if (getType(url) === '[object Request]') {
813
+ for (const prop of fetchInitProps) init[prop] = url[prop];
814
+ if (url.body) init.body = await url.arrayBuffer();
815
+ url = url.url;
816
+ }
817
+ url = url.toString();
818
+ Object.assign(init, options);
819
+ init.method = init.method || 'GET';
820
+ init.headers = init.headers || {};
821
+ const request = {
822
+ type: 'fetch',
823
+ url: url,
824
+ method: init.method.toUpperCase(),
825
+ abort: false,
826
+ headers: parseHeaders(init.headers),
827
+ data: init.body,
828
+ response: null,
829
+ async: true
830
+ };
831
+ const req = new AHRequest(request);
832
+ await req.waitForRequestKeys();
833
+ if (request.abort) {
834
+ if (typeof request.response === 'function') {
835
+ const response = {
836
+ finalUrl: request.url,
837
+ status: 200,
838
+ responseHeaders: {}
839
+ };
840
+ await req.waitForResponseKeys(response);
841
+ const key = fetchResponses.find(k => k in response);
842
+ let val = response[key];
843
+ if (key === 'json' && typeof val === 'object') {
844
+ val = catchError(JSON.stringify.bind(JSON), val);
957
845
  }
958
- init.method = request.method;
959
- init.headers = request.headers;
960
- init.body = request.data;
961
- winAh.realFetch.call(win, request.url, init).then((res) => {
962
- if (typeof request.response === "function") {
963
- const response = {
964
- finalUrl: res.url,
965
- status: res.status,
966
- responseHeaders: parseHeaders(res.headers),
967
- };
968
- fetchResponses.forEach(
969
- (key) =>
970
- (res[key] = function () {
971
- if (key in response)
972
- return Promise.resolve(response[key]);
973
- return resProto[key].call(this).then((val) => {
974
- response[key] = val;
975
- return req
976
- .waitForResponseKeys(response)
977
- .then(() => (key in response ? response[key] : val));
978
- });
979
- })
980
- );
981
- }
982
- resolve(res);
983
- }, reject);
984
- })
985
- .catch((err) => {
986
- console.error(err);
987
- resolve(winAh.realFetch.call(win, url, init));
988
- });
846
+ const res = new Response(val, {
847
+ status: 200,
848
+ statusText: 'OK'
849
+ });
850
+ defineProp(res, 'type', () => 'basic');
851
+ defineProp(res, 'url', () => request.url);
852
+ resolve(res);
853
+ } else {
854
+ reject(new DOMException('aborted', 'AbortError'));
855
+ }
856
+ return;
857
+ }
858
+ init.method = request.method;
859
+ init.headers = request.headers;
860
+ init.body = request.data;
861
+ winAh.realFetch.call(win, request.url, init).then(res => {
862
+ if (typeof request.response === 'function') {
863
+ const response = {
864
+ finalUrl: res.url,
865
+ status: res.status,
866
+ responseHeaders: parseHeaders(res.headers)
867
+ };
868
+ fetchResponses.forEach(key => res[key] = function() {
869
+ if (key in response) return Promise.resolve(response[key]);
870
+ return resProto[key].call(this).then(val => {
871
+ response[key] = val;
872
+ return req.waitForResponseKeys(response).then(() => key in response ? response[key] : val);
873
+ });
874
+ });
875
+ }
876
+ resolve(res);
877
+ }, reject);
989
878
  });
990
879
  }
991
880
  function fakeFetchClone() {
@@ -995,42 +884,38 @@
995
884
  return res;
996
885
  }
997
886
  winAh = win.__ajaxHooker = winAh || {
998
- version,
999
- fakeXHR,
1000
- fakeFetch,
1001
- fakeFetchClone,
887
+ version, fakeXHR, fakeFetch, fakeFetchClone,
1002
888
  realXHR: win.XMLHttpRequest,
1003
889
  realFetch: win.fetch,
1004
890
  realFetchClone: resProto.clone,
1005
- hookInsts: new Set(),
891
+ hookInsts: new Set()
1006
892
  };
1007
- if (winAh.version !== version)
1008
- console.warn("检测到不同版本的ajaxHooker,可能发生冲突!");
893
+ if (winAh.version !== version) console.warn('检测到不同版本的ajaxHooker,可能发生冲突!');
1009
894
  win.XMLHttpRequest = winAh.fakeXHR;
1010
895
  win.fetch = winAh.fakeFetch;
1011
896
  resProto.clone = winAh.fakeFetchClone;
1012
897
  winAh.hookInsts.add(hookInst);
1013
898
  return {
1014
- hook: (fn) => hookInst.hookFns.push(fn),
1015
- filter: (arr) => {
899
+ hook: fn => hookInst.hookFns.push(fn),
900
+ filter: arr => {
1016
901
  if (Array.isArray(arr)) hookInst.filters = arr;
1017
902
  },
1018
903
  protect: () => {
1019
- readonly(win, "XMLHttpRequest", winAh.fakeXHR);
1020
- readonly(win, "fetch", winAh.fakeFetch);
1021
- readonly(resProto, "clone", winAh.fakeFetchClone);
904
+ readonly(win, 'XMLHttpRequest', winAh.fakeXHR);
905
+ readonly(win, 'fetch', winAh.fakeFetch);
906
+ readonly(resProto, 'clone', winAh.fakeFetchClone);
1022
907
  },
1023
908
  unhook: () => {
1024
909
  winAh.hookInsts.delete(hookInst);
1025
910
  if (!winAh.hookInsts.size) {
1026
- writable(win, "XMLHttpRequest", winAh.realXHR);
1027
- writable(win, "fetch", winAh.realFetch);
1028
- writable(resProto, "clone", winAh.realFetchClone);
911
+ writable(win, 'XMLHttpRequest', winAh.realXHR);
912
+ writable(win, 'fetch', winAh.realFetch);
913
+ writable(resProto, 'clone', winAh.realFetchClone);
1029
914
  delete win.__ajaxHooker;
1030
915
  }
1031
- },
916
+ }
1032
917
  };
1033
- })();
918
+ }();
1034
919
  };
1035
920
 
1036
921
  class GMMenu {
@@ -3178,7 +3063,7 @@
3178
3063
  UtilsCore.init(option);
3179
3064
  }
3180
3065
  /** 版本号 */
3181
- version = "2024.6.5";
3066
+ version = "2024.6.10";
3182
3067
  addStyle(cssText) {
3183
3068
  if (typeof cssText !== "string") {
3184
3069
  throw new Error("Utils.addStyle 参数cssText 必须为String类型");
@@ -5958,6 +5843,9 @@
5958
5843
  if (typeof obj !== "object") {
5959
5844
  return;
5960
5845
  }
5846
+ if (obj == null) {
5847
+ return;
5848
+ }
5961
5849
  if ((typeof checkPropertyName === "function" && checkPropertyName(obj)) ||
5962
5850
  Reflect.has(obj, checkPropertyName)) {
5963
5851
  isResolve = true;