@kalayanasundaram123/rrweb 2.0.3 → 2.0.5

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/rrweb.js CHANGED
@@ -23,14 +23,18 @@ const testableAccessors$1 = {
23
23
  "ownerDocument"
24
24
  ],
25
25
  ShadowRoot: ["host", "styleSheets"],
26
- Element: ["shadowRoot", "querySelector", "querySelectorAll"],
27
- MutationObserver: []
26
+ Element: ["shadowRoot"],
27
+ MutationObserver: [],
28
+ EventTarget: []
28
29
  };
29
30
  const testableMethods$1 = {
30
31
  Node: ["contains", "getRootNode"],
31
32
  ShadowRoot: ["getSelection"],
32
- Element: [],
33
- MutationObserver: ["constructor"]
33
+ // PR #1802: moved from testableAccessors
34
+ Element: ["querySelector", "querySelectorAll"],
35
+ MutationObserver: ["constructor"],
36
+ // PR #1814
37
+ EventTarget: ["addEventListener", "removeEventListener"]
34
38
  };
35
39
  const untaintedBasePrototype$1 = {};
36
40
  const untaintedBaseIframeCleanup$1 = {};
@@ -155,10 +159,10 @@ function shadowRoot$1(n2) {
155
159
  return getUntaintedAccessor$1("Element", n2, "shadowRoot");
156
160
  }
157
161
  function querySelector$1(n2, selectors) {
158
- return getUntaintedAccessor$1("Element", n2, "querySelector")(selectors);
162
+ return getUntaintedMethod$1("Element", n2, "querySelector")(selectors);
159
163
  }
160
164
  function querySelectorAll$1(n2, selectors) {
161
- return getUntaintedAccessor$1("Element", n2, "querySelectorAll")(selectors);
165
+ return getUntaintedMethod$1("Element", n2, "querySelectorAll")(selectors);
162
166
  }
163
167
  function mutationObserverCtor$1() {
164
168
  return [
@@ -167,10 +171,67 @@ function mutationObserverCtor$1() {
167
171
  })
168
172
  ];
169
173
  }
174
+ function getUntaintedProxy$1() {
175
+ var _a2;
176
+ let UntaintedProxy = globalThis.Proxy;
177
+ try {
178
+ if (typeof UntaintedProxy !== "function" || !Function.prototype.toString.call(UntaintedProxy).includes("[native code]")) {
179
+ const frame = document.createElement("iframe");
180
+ frame.style.display = "none";
181
+ document.documentElement.appendChild(frame);
182
+ UntaintedProxy = ((_a2 = frame.contentWindow) == null ? void 0 : _a2.Proxy) ?? UntaintedProxy;
183
+ document.documentElement.removeChild(frame);
184
+ }
185
+ } catch {
186
+ }
187
+ return UntaintedProxy;
188
+ }
170
189
  let nowTimestamp$1 = Date.now;
171
190
  if (!/* @__PURE__ */ /[1-9][0-9]{12}/.test(Date.now().toString())) {
172
191
  nowTimestamp$1 = () => (/* @__PURE__ */ new Date()).getTime();
173
192
  }
193
+ const _rrwebNativeMap$2 = /* @__PURE__ */ new WeakMap();
194
+ let _nativeToStringStr$2 = "";
195
+ (function _installToStringProxy() {
196
+ var _a2;
197
+ const _nativeToString = Function.prototype.toString;
198
+ _nativeToStringStr$2 = _nativeToString.call(_nativeToString);
199
+ let _Proxy = globalThis.Proxy;
200
+ try {
201
+ if (typeof _Proxy !== "function" || !_nativeToString.call(_Proxy).includes("[native code]")) {
202
+ const frame = document.createElement("iframe");
203
+ frame.style.display = "none";
204
+ document.documentElement.appendChild(frame);
205
+ _Proxy = ((_a2 = frame.contentWindow) == null ? void 0 : _a2.Proxy) ?? _Proxy;
206
+ document.documentElement.removeChild(frame);
207
+ }
208
+ } catch {
209
+ }
210
+ const _fnProto = Object.getPrototypeOf(_nativeToString);
211
+ const _proxy = new _Proxy(_nativeToString, {
212
+ apply(target, thisArg, args) {
213
+ const str = _rrwebNativeMap$2.get(thisArg);
214
+ if (str !== void 0) return str;
215
+ if (thisArg != null && typeof thisArg === "function" && !_fnProto.isPrototypeOf(
216
+ thisArg.toString
217
+ )) {
218
+ return thisArg.toString();
219
+ }
220
+ return target.apply(thisArg, args);
221
+ }
222
+ });
223
+ _rrwebNativeMap$2.set(_proxy, _nativeToStringStr$2);
224
+ Object.defineProperty(Function.prototype, "toString", {
225
+ value: _proxy,
226
+ configurable: true,
227
+ writable: true
228
+ });
229
+ })();
230
+ function makeNativeFn$1(fn, nativeFn) {
231
+ const name = fn.name || nativeFn.name || "";
232
+ _rrwebNativeMap$2.set(fn, _nativeToStringStr$2.replace("toString", name));
233
+ return fn;
234
+ }
174
235
  function patch$1(source, name, replacement) {
175
236
  try {
176
237
  if (!(name in source)) {
@@ -187,6 +248,10 @@ function patch$1(source, name, replacement) {
187
248
  value: original
188
249
  }
189
250
  });
251
+ _rrwebNativeMap$2.set(
252
+ wrapped,
253
+ _nativeToStringStr$2.replace("toString", name)
254
+ );
190
255
  }
191
256
  source[name] = wrapped;
192
257
  return () => {
@@ -212,7 +277,9 @@ const index$1 = {
212
277
  querySelectorAll: querySelectorAll$1,
213
278
  nowTimestamp: nowTimestamp$1,
214
279
  mutationObserverCtor: mutationObserverCtor$1,
215
- patch: patch$1
280
+ patch: patch$1,
281
+ makeNativeFn: makeNativeFn$1,
282
+ getUntaintedProxy: getUntaintedProxy$1
216
283
  };
217
284
  function isElement(n2) {
218
285
  return n2.nodeType === n2.ELEMENT_NODE;
@@ -5756,6 +5823,43 @@ var __defProp22 = Object.defineProperty;
5756
5823
  var __defNormalProp22 = (obj, key, value) => key in obj ? __defProp22(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
5757
5824
  var __publicField22 = (obj, key, value) => __defNormalProp22(obj, typeof key !== "symbol" ? key + "" : key, value);
5758
5825
  if (!/* @__PURE__ */ /[1-9][0-9]{12}/.test(Date.now().toString())) ;
5826
+ const _rrwebNativeMap$1 = /* @__PURE__ */ new WeakMap();
5827
+ let _nativeToStringStr$1 = "";
5828
+ (function _installToStringProxy2() {
5829
+ var _a2;
5830
+ const _nativeToString = Function.prototype.toString;
5831
+ _nativeToStringStr$1 = _nativeToString.call(_nativeToString);
5832
+ let _Proxy = globalThis.Proxy;
5833
+ try {
5834
+ if (typeof _Proxy !== "function" || !_nativeToString.call(_Proxy).includes("[native code]")) {
5835
+ const frame = document.createElement("iframe");
5836
+ frame.style.display = "none";
5837
+ document.documentElement.appendChild(frame);
5838
+ _Proxy = ((_a2 = frame.contentWindow) == null ? void 0 : _a2.Proxy) ?? _Proxy;
5839
+ document.documentElement.removeChild(frame);
5840
+ }
5841
+ } catch {
5842
+ }
5843
+ const _fnProto = Object.getPrototypeOf(_nativeToString);
5844
+ const _proxy = new _Proxy(_nativeToString, {
5845
+ apply(target, thisArg, args) {
5846
+ const str = _rrwebNativeMap$1.get(thisArg);
5847
+ if (str !== void 0) return str;
5848
+ if (thisArg != null && typeof thisArg === "function" && !_fnProto.isPrototypeOf(
5849
+ thisArg.toString
5850
+ )) {
5851
+ return thisArg.toString();
5852
+ }
5853
+ return target.apply(thisArg, args);
5854
+ }
5855
+ });
5856
+ _rrwebNativeMap$1.set(_proxy, _nativeToStringStr$1);
5857
+ Object.defineProperty(Function.prototype, "toString", {
5858
+ value: _proxy,
5859
+ configurable: true,
5860
+ writable: true
5861
+ });
5862
+ })();
5759
5863
  let Mirror$1 = class Mirror2 {
5760
5864
  constructor() {
5761
5865
  __publicField22(this, "idNodeMap", /* @__PURE__ */ new Map());
@@ -10848,14 +10952,18 @@ const testableAccessors = {
10848
10952
  "ownerDocument"
10849
10953
  ],
10850
10954
  ShadowRoot: ["host", "styleSheets"],
10851
- Element: ["shadowRoot", "querySelector", "querySelectorAll"],
10852
- MutationObserver: []
10955
+ Element: ["shadowRoot"],
10956
+ MutationObserver: [],
10957
+ EventTarget: []
10853
10958
  };
10854
10959
  const testableMethods = {
10855
10960
  Node: ["contains", "getRootNode"],
10856
10961
  ShadowRoot: ["getSelection"],
10857
- Element: [],
10858
- MutationObserver: ["constructor"]
10962
+ // PR #1802: moved from testableAccessors
10963
+ Element: ["querySelector", "querySelectorAll"],
10964
+ MutationObserver: ["constructor"],
10965
+ // PR #1814
10966
+ EventTarget: ["addEventListener", "removeEventListener"]
10859
10967
  };
10860
10968
  const untaintedBasePrototype = {};
10861
10969
  const untaintedBaseIframeCleanup = {};
@@ -10980,10 +11088,10 @@ function shadowRoot(n2) {
10980
11088
  return getUntaintedAccessor("Element", n2, "shadowRoot");
10981
11089
  }
10982
11090
  function querySelector(n2, selectors) {
10983
- return getUntaintedAccessor("Element", n2, "querySelector")(selectors);
11091
+ return getUntaintedMethod("Element", n2, "querySelector")(selectors);
10984
11092
  }
10985
11093
  function querySelectorAll(n2, selectors) {
10986
- return getUntaintedAccessor("Element", n2, "querySelectorAll")(selectors);
11094
+ return getUntaintedMethod("Element", n2, "querySelectorAll")(selectors);
10987
11095
  }
10988
11096
  function mutationObserverCtor() {
10989
11097
  return [
@@ -10992,10 +11100,67 @@ function mutationObserverCtor() {
10992
11100
  })
10993
11101
  ];
10994
11102
  }
11103
+ function getUntaintedProxy() {
11104
+ var _a2;
11105
+ let UntaintedProxy = globalThis.Proxy;
11106
+ try {
11107
+ if (typeof UntaintedProxy !== "function" || !Function.prototype.toString.call(UntaintedProxy).includes("[native code]")) {
11108
+ const frame = document.createElement("iframe");
11109
+ frame.style.display = "none";
11110
+ document.documentElement.appendChild(frame);
11111
+ UntaintedProxy = ((_a2 = frame.contentWindow) == null ? void 0 : _a2.Proxy) ?? UntaintedProxy;
11112
+ document.documentElement.removeChild(frame);
11113
+ }
11114
+ } catch {
11115
+ }
11116
+ return UntaintedProxy;
11117
+ }
10995
11118
  let nowTimestamp = Date.now;
10996
11119
  if (!/* @__PURE__ */ /[1-9][0-9]{12}/.test(Date.now().toString())) {
10997
11120
  nowTimestamp = () => (/* @__PURE__ */ new Date()).getTime();
10998
11121
  }
11122
+ const _rrwebNativeMap = /* @__PURE__ */ new WeakMap();
11123
+ let _nativeToStringStr = "";
11124
+ (function _installToStringProxy3() {
11125
+ var _a2;
11126
+ const _nativeToString = Function.prototype.toString;
11127
+ _nativeToStringStr = _nativeToString.call(_nativeToString);
11128
+ let _Proxy = globalThis.Proxy;
11129
+ try {
11130
+ if (typeof _Proxy !== "function" || !_nativeToString.call(_Proxy).includes("[native code]")) {
11131
+ const frame = document.createElement("iframe");
11132
+ frame.style.display = "none";
11133
+ document.documentElement.appendChild(frame);
11134
+ _Proxy = ((_a2 = frame.contentWindow) == null ? void 0 : _a2.Proxy) ?? _Proxy;
11135
+ document.documentElement.removeChild(frame);
11136
+ }
11137
+ } catch {
11138
+ }
11139
+ const _fnProto = Object.getPrototypeOf(_nativeToString);
11140
+ const _proxy = new _Proxy(_nativeToString, {
11141
+ apply(target, thisArg, args) {
11142
+ const str = _rrwebNativeMap.get(thisArg);
11143
+ if (str !== void 0) return str;
11144
+ if (thisArg != null && typeof thisArg === "function" && !_fnProto.isPrototypeOf(
11145
+ thisArg.toString
11146
+ )) {
11147
+ return thisArg.toString();
11148
+ }
11149
+ return target.apply(thisArg, args);
11150
+ }
11151
+ });
11152
+ _rrwebNativeMap.set(_proxy, _nativeToStringStr);
11153
+ Object.defineProperty(Function.prototype, "toString", {
11154
+ value: _proxy,
11155
+ configurable: true,
11156
+ writable: true
11157
+ });
11158
+ })();
11159
+ function makeNativeFn(fn, nativeFn) {
11160
+ const name = fn.name || nativeFn.name || "";
11161
+ _rrwebNativeMap.set(fn, _nativeToStringStr.replace("toString", name));
11162
+ return fn;
11163
+ }
10999
11164
  function patch(source, name, replacement) {
11000
11165
  try {
11001
11166
  if (!(name in source)) {
@@ -11012,6 +11177,10 @@ function patch(source, name, replacement) {
11012
11177
  value: original
11013
11178
  }
11014
11179
  });
11180
+ _rrwebNativeMap.set(
11181
+ wrapped,
11182
+ _nativeToStringStr.replace("toString", name)
11183
+ );
11015
11184
  }
11016
11185
  source[name] = wrapped;
11017
11186
  return () => {
@@ -11037,12 +11206,23 @@ const index = {
11037
11206
  querySelectorAll,
11038
11207
  nowTimestamp,
11039
11208
  mutationObserverCtor,
11040
- patch
11209
+ patch,
11210
+ makeNativeFn,
11211
+ getUntaintedProxy
11041
11212
  };
11042
11213
  function on(type, fn, target = document) {
11043
11214
  const options = { capture: true, passive: true };
11044
- target.addEventListener(type, fn, options);
11045
- return () => target.removeEventListener(type, fn, options);
11215
+ const eventTarget = target;
11216
+ getUntaintedMethod("EventTarget", eventTarget, "addEventListener")(
11217
+ type,
11218
+ fn,
11219
+ options
11220
+ );
11221
+ return () => getUntaintedMethod("EventTarget", eventTarget, "removeEventListener")(
11222
+ type,
11223
+ fn,
11224
+ options
11225
+ );
11046
11226
  }
11047
11227
  const DEPARTED_MIRROR_ACCESS_WARNING = "Please stop import mirror directly. Instead of that,\r\nnow you can use replayer.getMirror() to access the mirror instance of a replayer,\r\nor you can use record.mirror to access the mirror instance during recording.";
11048
11228
  let _mirror = {
@@ -11104,20 +11284,27 @@ function throttle(func, wait, options = {}) {
11104
11284
  }
11105
11285
  function hookSetter(target, key, d, isRevoked, win = window) {
11106
11286
  const original = win.Object.getOwnPropertyDescriptor(target, key);
11107
- win.Object.defineProperty(
11108
- target,
11109
- key,
11110
- isRevoked ? d : {
11111
- set(value) {
11287
+ if (!isRevoked && (original == null ? void 0 : original.set)) {
11288
+ const hookedSetter = function(value) {
11289
+ setTimeout(() => {
11290
+ d.set.call(this, value);
11291
+ }, 0);
11292
+ original.set.call(this, value);
11293
+ };
11294
+ makeNativeFn(hookedSetter, original.set);
11295
+ win.Object.defineProperty(target, key, { set: hookedSetter });
11296
+ } else {
11297
+ win.Object.defineProperty(
11298
+ target,
11299
+ key,
11300
+ isRevoked ? d : { set(value) {
11112
11301
  setTimeout(() => {
11113
11302
  d.set.call(this, value);
11114
11303
  }, 0);
11115
- if (original && original.set) {
11116
- original.set.call(this, value);
11117
- }
11118
- }
11119
- }
11120
- );
11304
+ if (original && original.set) original.set.call(this, value);
11305
+ } }
11306
+ );
11307
+ }
11121
11308
  return () => hookSetter(target, key, original || {}, true);
11122
11309
  }
11123
11310
  function getWindowScroll(win) {
@@ -12145,6 +12332,7 @@ const callbackWrapper = (cb) => {
12145
12332
  };
12146
12333
  return rrwebWrapped;
12147
12334
  };
12335
+ const Proxy$1 = getUntaintedProxy();
12148
12336
  const mutationBuffers = [];
12149
12337
  function getEventTarget(event) {
12150
12338
  try {
@@ -12548,61 +12736,11 @@ function initStyleSheetObserver({ styleSheetRuleCb, mirror: mirror2, stylesheetM
12548
12736
  };
12549
12737
  }
12550
12738
  const insertRule = win.CSSStyleSheet.prototype.insertRule;
12551
- win.CSSStyleSheet.prototype.insertRule = new Proxy(insertRule, {
12552
- apply: callbackWrapper(
12553
- (target, thisArg, argumentsList) => {
12554
- const [rule2, index2] = argumentsList;
12555
- const { id, styleId } = getIdAndStyleId(
12556
- thisArg,
12557
- mirror2,
12558
- stylesheetManager.styleMirror
12559
- );
12560
- if (id && id !== -1 || styleId && styleId !== -1) {
12561
- styleSheetRuleCb({
12562
- id,
12563
- styleId,
12564
- adds: [{ rule: rule2, index: index2 }]
12565
- });
12566
- }
12567
- return target.apply(thisArg, argumentsList);
12568
- }
12569
- )
12570
- });
12571
- win.CSSStyleSheet.prototype.addRule = function(selector, styleBlock, index2 = this.cssRules.length) {
12572
- const rule2 = `${selector} { ${styleBlock} }`;
12573
- return win.CSSStyleSheet.prototype.insertRule.apply(this, [rule2, index2]);
12574
- };
12575
- const deleteRule = win.CSSStyleSheet.prototype.deleteRule;
12576
- win.CSSStyleSheet.prototype.deleteRule = new Proxy(deleteRule, {
12577
- apply: callbackWrapper(
12578
- (target, thisArg, argumentsList) => {
12579
- const [index2] = argumentsList;
12580
- const { id, styleId } = getIdAndStyleId(
12581
- thisArg,
12582
- mirror2,
12583
- stylesheetManager.styleMirror
12584
- );
12585
- if (id && id !== -1 || styleId && styleId !== -1) {
12586
- styleSheetRuleCb({
12587
- id,
12588
- styleId,
12589
- removes: [{ index: index2 }]
12590
- });
12591
- }
12592
- return target.apply(thisArg, argumentsList);
12593
- }
12594
- )
12595
- });
12596
- win.CSSStyleSheet.prototype.removeRule = function(index2) {
12597
- return win.CSSStyleSheet.prototype.deleteRule.apply(this, [index2]);
12598
- };
12599
- let replace;
12600
- if (win.CSSStyleSheet.prototype.replace) {
12601
- replace = win.CSSStyleSheet.prototype.replace;
12602
- win.CSSStyleSheet.prototype.replace = new Proxy(replace, {
12739
+ win.CSSStyleSheet.prototype.insertRule = makeNativeFn(
12740
+ new Proxy$1(insertRule, {
12603
12741
  apply: callbackWrapper(
12604
12742
  (target, thisArg, argumentsList) => {
12605
- const [text] = argumentsList;
12743
+ const [rule2, index2] = argumentsList;
12606
12744
  const { id, styleId } = getIdAndStyleId(
12607
12745
  thisArg,
12608
12746
  mirror2,
@@ -12612,21 +12750,28 @@ function initStyleSheetObserver({ styleSheetRuleCb, mirror: mirror2, stylesheetM
12612
12750
  styleSheetRuleCb({
12613
12751
  id,
12614
12752
  styleId,
12615
- replace: text
12753
+ adds: [{ rule: rule2, index: index2 }]
12616
12754
  });
12617
12755
  }
12618
12756
  return target.apply(thisArg, argumentsList);
12619
12757
  }
12620
12758
  )
12621
- });
12622
- }
12623
- let replaceSync;
12624
- if (win.CSSStyleSheet.prototype.replaceSync) {
12625
- replaceSync = win.CSSStyleSheet.prototype.replaceSync;
12626
- win.CSSStyleSheet.prototype.replaceSync = new Proxy(replaceSync, {
12759
+ }),
12760
+ insertRule
12761
+ );
12762
+ win.CSSStyleSheet.prototype.addRule = makeNativeFn(
12763
+ function(selector, styleBlock, index2 = this.cssRules.length) {
12764
+ const rule2 = `${selector} { ${styleBlock} }`;
12765
+ return win.CSSStyleSheet.prototype.insertRule.apply(this, [rule2, index2]);
12766
+ },
12767
+ insertRule
12768
+ );
12769
+ const deleteRule = win.CSSStyleSheet.prototype.deleteRule;
12770
+ win.CSSStyleSheet.prototype.deleteRule = makeNativeFn(
12771
+ new Proxy$1(deleteRule, {
12627
12772
  apply: callbackWrapper(
12628
12773
  (target, thisArg, argumentsList) => {
12629
- const [text] = argumentsList;
12774
+ const [index2] = argumentsList;
12630
12775
  const { id, styleId } = getIdAndStyleId(
12631
12776
  thisArg,
12632
12777
  mirror2,
@@ -12636,13 +12781,74 @@ function initStyleSheetObserver({ styleSheetRuleCb, mirror: mirror2, stylesheetM
12636
12781
  styleSheetRuleCb({
12637
12782
  id,
12638
12783
  styleId,
12639
- replaceSync: text
12784
+ removes: [{ index: index2 }]
12640
12785
  });
12641
12786
  }
12642
12787
  return target.apply(thisArg, argumentsList);
12643
12788
  }
12644
12789
  )
12645
- });
12790
+ }),
12791
+ deleteRule
12792
+ );
12793
+ win.CSSStyleSheet.prototype.removeRule = makeNativeFn(
12794
+ function(index2) {
12795
+ return win.CSSStyleSheet.prototype.deleteRule.apply(this, [index2]);
12796
+ },
12797
+ deleteRule
12798
+ );
12799
+ let replace;
12800
+ if (win.CSSStyleSheet.prototype.replace) {
12801
+ replace = win.CSSStyleSheet.prototype.replace;
12802
+ win.CSSStyleSheet.prototype.replace = makeNativeFn(
12803
+ new Proxy$1(replace, {
12804
+ apply: callbackWrapper(
12805
+ (target, thisArg, argumentsList) => {
12806
+ const [text] = argumentsList;
12807
+ const { id, styleId } = getIdAndStyleId(
12808
+ thisArg,
12809
+ mirror2,
12810
+ stylesheetManager.styleMirror
12811
+ );
12812
+ if (id && id !== -1 || styleId && styleId !== -1) {
12813
+ styleSheetRuleCb({
12814
+ id,
12815
+ styleId,
12816
+ replace: text
12817
+ });
12818
+ }
12819
+ return target.apply(thisArg, argumentsList);
12820
+ }
12821
+ )
12822
+ }),
12823
+ replace
12824
+ );
12825
+ }
12826
+ let replaceSync;
12827
+ if (win.CSSStyleSheet.prototype.replaceSync) {
12828
+ replaceSync = win.CSSStyleSheet.prototype.replaceSync;
12829
+ win.CSSStyleSheet.prototype.replaceSync = makeNativeFn(
12830
+ new Proxy$1(replaceSync, {
12831
+ apply: callbackWrapper(
12832
+ (target, thisArg, argumentsList) => {
12833
+ const [text] = argumentsList;
12834
+ const { id, styleId } = getIdAndStyleId(
12835
+ thisArg,
12836
+ mirror2,
12837
+ stylesheetManager.styleMirror
12838
+ );
12839
+ if (id && id !== -1 || styleId && styleId !== -1) {
12840
+ styleSheetRuleCb({
12841
+ id,
12842
+ styleId,
12843
+ replaceSync: text
12844
+ });
12845
+ }
12846
+ return target.apply(thisArg, argumentsList);
12847
+ }
12848
+ )
12849
+ }),
12850
+ replaceSync
12851
+ );
12646
12852
  }
12647
12853
  const supportedNestedCSSRuleTypes = {};
12648
12854
  if (canMonkeyPatchNestedCSSRule("CSSGroupingRule")) {
@@ -12666,9 +12872,8 @@ function initStyleSheetObserver({ styleSheetRuleCb, mirror: mirror2, stylesheetM
12666
12872
  // eslint-disable-next-line @typescript-eslint/unbound-method
12667
12873
  deleteRule: type.prototype.deleteRule
12668
12874
  };
12669
- type.prototype.insertRule = new Proxy(
12670
- unmodifiedFunctions[typeKey].insertRule,
12671
- {
12875
+ type.prototype.insertRule = makeNativeFn(
12876
+ new Proxy$1(unmodifiedFunctions[typeKey].insertRule, {
12672
12877
  apply: callbackWrapper(
12673
12878
  (target, thisArg, argumentsList) => {
12674
12879
  const [rule2, index2] = argumentsList;
@@ -12696,11 +12901,11 @@ function initStyleSheetObserver({ styleSheetRuleCb, mirror: mirror2, stylesheetM
12696
12901
  return target.apply(thisArg, argumentsList);
12697
12902
  }
12698
12903
  )
12699
- }
12904
+ }),
12905
+ unmodifiedFunctions[typeKey].insertRule
12700
12906
  );
12701
- type.prototype.deleteRule = new Proxy(
12702
- unmodifiedFunctions[typeKey].deleteRule,
12703
- {
12907
+ type.prototype.deleteRule = makeNativeFn(
12908
+ new Proxy$1(unmodifiedFunctions[typeKey].deleteRule, {
12704
12909
  apply: callbackWrapper(
12705
12910
  (target, thisArg, argumentsList) => {
12706
12911
  const [index2] = argumentsList;
@@ -12721,7 +12926,8 @@ function initStyleSheetObserver({ styleSheetRuleCb, mirror: mirror2, stylesheetM
12721
12926
  return target.apply(thisArg, argumentsList);
12722
12927
  }
12723
12928
  )
12724
- }
12929
+ }),
12930
+ unmodifiedFunctions[typeKey].deleteRule
12725
12931
  );
12726
12932
  });
12727
12933
  return callbackWrapper(() => {
@@ -12788,7 +12994,7 @@ function initStyleDeclarationObserver({
12788
12994
  stylesheetManager
12789
12995
  }, { win }) {
12790
12996
  const setProperty = win.CSSStyleDeclaration.prototype.setProperty;
12791
- win.CSSStyleDeclaration.prototype.setProperty = new Proxy(setProperty, {
12997
+ win.CSSStyleDeclaration.prototype.setProperty = new Proxy$1(setProperty, {
12792
12998
  apply: callbackWrapper(
12793
12999
  (target, thisArg, argumentsList) => {
12794
13000
  var _a2;
@@ -12819,7 +13025,7 @@ function initStyleDeclarationObserver({
12819
13025
  )
12820
13026
  });
12821
13027
  const removeProperty = win.CSSStyleDeclaration.prototype.removeProperty;
12822
- win.CSSStyleDeclaration.prototype.removeProperty = new Proxy(removeProperty, {
13028
+ win.CSSStyleDeclaration.prototype.removeProperty = new Proxy$1(removeProperty, {
12823
13029
  apply: callbackWrapper(
12824
13030
  (target, thisArg, argumentsList) => {
12825
13031
  var _a2;
@@ -12901,16 +13107,19 @@ function initFontObserver({ fontCb, doc }) {
12901
13107
  const handlers = [];
12902
13108
  const fontMap = /* @__PURE__ */ new WeakMap();
12903
13109
  const originalFontFace = win.FontFace;
12904
- win.FontFace = function FontFace2(family, source, descriptors) {
12905
- const fontFace = new originalFontFace(family, source, descriptors);
12906
- fontMap.set(fontFace, {
12907
- family,
12908
- buffer: typeof source !== "string",
12909
- descriptors,
12910
- fontSource: typeof source === "string" ? source : JSON.stringify(Array.from(new Uint8Array(source)))
12911
- });
12912
- return fontFace;
12913
- };
13110
+ win.FontFace = makeNativeFn(
13111
+ function FontFace2(family, source, descriptors) {
13112
+ const fontFace = new originalFontFace(family, source, descriptors);
13113
+ fontMap.set(fontFace, {
13114
+ family,
13115
+ buffer: typeof source !== "string",
13116
+ descriptors,
13117
+ fontSource: typeof source === "string" ? source : JSON.stringify(Array.from(new Uint8Array(source)))
13118
+ });
13119
+ return fontFace;
13120
+ },
13121
+ originalFontFace
13122
+ );
12914
13123
  const restoreHandler = patch(
12915
13124
  doc.fonts,
12916
13125
  "add",
@@ -13223,7 +13432,7 @@ class CrossOriginIframeMirror {
13223
13432
  return remoteIdToIdMap;
13224
13433
  }
13225
13434
  }
13226
- class IframeManager {
13435
+ const _IframeManager = class _IframeManager {
13227
13436
  constructor(options) {
13228
13437
  __publicField(this, "iframes", /* @__PURE__ */ new WeakMap());
13229
13438
  __publicField(this, "crossOriginIframeMap", /* @__PURE__ */ new WeakMap());
@@ -13236,6 +13445,9 @@ class IframeManager {
13236
13445
  __publicField(this, "loadListener");
13237
13446
  __publicField(this, "stylesheetManager");
13238
13447
  __publicField(this, "recordCrossOriginIframes");
13448
+ // Loop detection: track rapid re-navigations per iframe to prevent CPU spikes
13449
+ // from redirect loops (e.g. OAuth silent-refresh frames that can't complete auth).
13450
+ __publicField(this, "iframeNavStats", /* @__PURE__ */ new WeakMap());
13239
13451
  this.mutationCb = options.mutationCb;
13240
13452
  this.wrappedEmit = options.wrappedEmit;
13241
13453
  this.stylesheetManager = options.stylesheetManager;
@@ -13258,6 +13470,21 @@ class IframeManager {
13258
13470
  addLoadListener(cb) {
13259
13471
  this.loadListener = cb;
13260
13472
  }
13473
+ isIframeLooping(iframeEl) {
13474
+ const now = Date.now();
13475
+ const stats = this.iframeNavStats.get(iframeEl);
13476
+ if (!stats || now - stats.windowStart > _IframeManager.LOOP_NAV_WINDOW_MS) {
13477
+ this.iframeNavStats.set(iframeEl, { count: 1, windowStart: now });
13478
+ return false;
13479
+ }
13480
+ stats.count++;
13481
+ if (stats.count > _IframeManager.LOOP_NAV_LIMIT) {
13482
+ stats.windowStart = now;
13483
+ stats.count = 0;
13484
+ return true;
13485
+ }
13486
+ return false;
13487
+ }
13261
13488
  attachIframe(iframeEl, childSn) {
13262
13489
  var _a2, _b;
13263
13490
  this.mutationCb({
@@ -13278,7 +13505,9 @@ class IframeManager {
13278
13505
  "message",
13279
13506
  this.handleMessage.bind(this)
13280
13507
  );
13281
- (_b = this.loadListener) == null ? void 0 : _b.call(this, iframeEl);
13508
+ if (!this.isIframeLooping(iframeEl)) {
13509
+ (_b = this.loadListener) == null ? void 0 : _b.call(this, iframeEl);
13510
+ }
13282
13511
  if (iframeEl.contentDocument && iframeEl.contentDocument.adoptedStyleSheets && iframeEl.contentDocument.adoptedStyleSheets.length > 0)
13283
13512
  this.stylesheetManager.adoptStyleSheets(
13284
13513
  iframeEl.contentDocument.adoptedStyleSheets,
@@ -13456,7 +13685,10 @@ class IframeManager {
13456
13685
  });
13457
13686
  }
13458
13687
  }
13459
- }
13688
+ };
13689
+ __publicField(_IframeManager, "LOOP_NAV_LIMIT", 5);
13690
+ __publicField(_IframeManager, "LOOP_NAV_WINDOW_MS", 3e3);
13691
+ let IframeManager = _IframeManager;
13460
13692
  class ShadowDomManager {
13461
13693
  constructor(options) {
13462
13694
  __publicField(this, "shadowDoms", /* @__PURE__ */ new WeakSet());
@@ -13948,6 +14180,26 @@ function fnv1aHash(buffer) {
13948
14180
  function canSnapshotCanvas() {
13949
14181
  return typeof OffscreenCanvas !== "undefined";
13950
14182
  }
14183
+ const FPS_WORKER_SOURCE = `
14184
+ var _C='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
14185
+ function _enc(ab){var b=new Uint8Array(ab),i,n=b.length,o='';for(i=0;i<n;i+=3){o+=_C[b[i]>>2];o+=_C[(b[i]&3)<<4|b[i+1]>>4];o+=_C[(b[i+1]&15)<<2|b[i+2]>>6];o+=_C[b[i+2]&63];}if(n%3===2){o=o.substring(0,o.length-1)+'=';}else if(n%3===1){o=o.substring(0,o.length-2)+'==';}return o;}
14186
+ function _fp(ab){var v=new Uint8Array(ab),h=0x811c9dc5;for(var i=0;i<v.length;i++){h^=v[i];h=(h*0x01000193)|0;}return (h>>>0).toString(16);}
14187
+ var _last=new Map(),_cv=null,_ctx=null;
14188
+ self.onmessage=async function(e){
14189
+ var d=e.data,id=d.id,bm=d.bitmap,w=d.width,h=d.height,opt=d.dataURLOptions;
14190
+ try{
14191
+ if(!('OffscreenCanvas' in self)){bm.close();return self.postMessage({id:id});}
14192
+ if(!_cv||_cv.width!==w||_cv.height!==h){_cv=new OffscreenCanvas(w,h);_ctx=_cv.getContext('2d');}
14193
+ _ctx.clearRect(0,0,w,h);_ctx.drawImage(bm,0,0);bm.close();
14194
+ var blob=await _cv.convertToBlob(opt);
14195
+ var buf=await blob.arrayBuffer();
14196
+ var fp=_fp(buf);
14197
+ if(_last.get(id)===fp)return self.postMessage({id:id});
14198
+ _last.set(id,fp);
14199
+ self.postMessage({id:id,type:blob.type,base64:_enc(buf),width:w,height:h});
14200
+ }catch(err){try{bm.close();}catch(_){}self.postMessage({id:id});}
14201
+ };
14202
+ `;
13951
14203
  class CanvasManager {
13952
14204
  constructor(options) {
13953
14205
  __publicField(this, "pendingCanvasMutations", /* @__PURE__ */ new Map());
@@ -13970,6 +14222,9 @@ class CanvasManager {
13970
14222
  __publicField(this, "lastFingerprintMap", /* @__PURE__ */ new Map());
13971
14223
  __publicField(this, "snapshotCanvas", null);
13972
14224
  __publicField(this, "snapshotCtx", null);
14225
+ // Encode worker (created from a `data:` URL). null => encode on the main
14226
+ // thread instead (worker unavailable or blocked by CSP).
14227
+ __publicField(this, "worker", null);
13973
14228
  __publicField(this, "lastSnapshotTime", 0);
13974
14229
  __publicField(this, "processMutation", (target, mutation) => {
13975
14230
  const newFrame = this.rafStamps.invokeId && this.rafStamps.latestId !== this.rafStamps.invokeId;
@@ -13991,10 +14246,12 @@ class CanvasManager {
13991
14246
  this.startPendingCanvasMutationFlusher();
13992
14247
  }
13993
14248
  if (recordCanvas && typeof sampling === "number" && canSnapshotCanvas()) {
14249
+ this.worker = this.initFPSWorker();
13994
14250
  this.initCanvasFPSObserver();
13995
14251
  }
13996
14252
  }
13997
14253
  reset() {
14254
+ var _a2;
13998
14255
  this.pendingCanvasMutations.clear();
13999
14256
  this.restoreHandlers.forEach((handler) => {
14000
14257
  try {
@@ -14010,6 +14267,8 @@ class CanvasManager {
14010
14267
  this.lastFingerprintMap = /* @__PURE__ */ new Map();
14011
14268
  this.snapshotCanvas = null;
14012
14269
  this.snapshotCtx = null;
14270
+ (_a2 = this.worker) == null ? void 0 : _a2.terminate();
14271
+ this.worker = null;
14013
14272
  }
14014
14273
  freeze() {
14015
14274
  this.frozen = true;
@@ -14023,6 +14282,29 @@ class CanvasManager {
14023
14282
  unlock() {
14024
14283
  this.locked = false;
14025
14284
  }
14285
+ initFPSWorker() {
14286
+ try {
14287
+ const worker = new Worker(
14288
+ "data:application/javascript;charset=utf-8," + encodeURIComponent(FPS_WORKER_SOURCE)
14289
+ );
14290
+ worker.onmessage = (e2) => {
14291
+ const data = e2.data;
14292
+ const { id } = data;
14293
+ this.snapshotInProgressMap.set(id, false);
14294
+ if (data.base64 === void 0) return;
14295
+ this.emitCanvasSnapshot(
14296
+ id,
14297
+ data.base64,
14298
+ data.type || "image/png",
14299
+ data.width || 0,
14300
+ data.height || 0
14301
+ );
14302
+ };
14303
+ return worker;
14304
+ } catch {
14305
+ return null;
14306
+ }
14307
+ }
14026
14308
  /**
14027
14309
  * Begin observing canvas activity inside `win` — the top window, or the
14028
14310
  * `contentWindow` of a same-origin iframe. De-duplicated, so it is safe to
@@ -14229,9 +14511,22 @@ class CanvasManager {
14229
14511
  }
14230
14512
  const width = canvas.width;
14231
14513
  const height = canvas.height;
14232
- createImageBitmap(canvas).then(
14233
- (bitmap) => this.snapshotImageBitmap(id, bitmap, width, height, dataURLOptions)
14234
- ).catch(() => {
14514
+ createImageBitmap(canvas).then((bitmap) => {
14515
+ if (this.worker) {
14516
+ this.worker.postMessage(
14517
+ { id, bitmap, width, height, dataURLOptions },
14518
+ [bitmap]
14519
+ );
14520
+ } else {
14521
+ void this.snapshotImageBitmap(
14522
+ id,
14523
+ bitmap,
14524
+ width,
14525
+ height,
14526
+ dataURLOptions
14527
+ );
14528
+ }
14529
+ }).catch(() => {
14235
14530
  this.snapshotInProgressMap.set(id, false);
14236
14531
  });
14237
14532
  });
@@ -14777,9 +15072,20 @@ function record(options = {}) {
14777
15072
  hooks
14778
15073
  );
14779
15074
  };
15075
+ const iframeObservers = /* @__PURE__ */ new Map();
14780
15076
  iframeManager.addLoadListener((iframeEl) => {
14781
15077
  try {
14782
- handlers.push(observe(iframeEl.contentDocument));
15078
+ const prevCleanup = iframeObservers.get(iframeEl);
15079
+ if (prevCleanup) {
15080
+ try {
15081
+ prevCleanup();
15082
+ } catch {
15083
+ }
15084
+ iframeObservers.delete(iframeEl);
15085
+ }
15086
+ const cleanup = observe(iframeEl.contentDocument);
15087
+ handlers.push(cleanup);
15088
+ iframeObservers.set(iframeEl, cleanup);
14783
15089
  } catch (error) {
14784
15090
  console.warn(error);
14785
15091
  }