@whitesev/utils 1.4.1 → 1.4.3

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