@posthog/rrweb-record 0.0.36 → 0.0.38

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.
@@ -14,20 +14,20 @@ var NodeType$1$1 = /* @__PURE__ */ ((NodeType2) => {
14
14
  NodeType2[NodeType2["Comment"] = 5] = "Comment";
15
15
  return NodeType2;
16
16
  })(NodeType$1$1 || {});
17
- const testableAccessors$1 = {
17
+ const testableAccessors$2 = {
18
18
  Node: ["childNodes", "parentNode", "parentElement", "textContent"],
19
19
  ShadowRoot: ["host", "styleSheets"],
20
20
  Element: ["shadowRoot", "querySelector", "querySelectorAll"],
21
21
  MutationObserver: []
22
22
  };
23
- const testableMethods$1 = {
23
+ const testableMethods$2 = {
24
24
  Node: ["contains", "getRootNode"],
25
25
  ShadowRoot: ["getSelection"],
26
26
  Element: [],
27
27
  MutationObserver: ["constructor"]
28
28
  };
29
- const untaintedBasePrototype$1 = {};
30
- function angularZoneUnpatchedAlternative$1(key) {
29
+ const untaintedBasePrototype$2 = {};
30
+ function angularZoneUnpatchedAlternative$2(key) {
31
31
  var _a2, _b;
32
32
  const angularUnpatchedVersionSymbol = (_b = (_a2 = globalThis == null ? void 0 : globalThis.Zone) == null ? void 0 : _a2.__symbol__) == null ? void 0 : _b.call(_a2, key);
33
33
  if (angularUnpatchedVersionSymbol && globalThis[angularUnpatchedVersionSymbol]) {
@@ -36,12 +36,12 @@ function angularZoneUnpatchedAlternative$1(key) {
36
36
  return void 0;
37
37
  }
38
38
  }
39
- function getUntaintedPrototype$1(key) {
40
- if (untaintedBasePrototype$1[key])
41
- return untaintedBasePrototype$1[key];
42
- const candidate = angularZoneUnpatchedAlternative$1(key) || globalThis[key];
39
+ function getUntaintedPrototype$2(key) {
40
+ if (untaintedBasePrototype$2[key])
41
+ return untaintedBasePrototype$2[key];
42
+ const candidate = angularZoneUnpatchedAlternative$2(key) || globalThis[key];
43
43
  const defaultPrototype = candidate.prototype;
44
- const accessorNames = key in testableAccessors$1 ? testableAccessors$1[key] : void 0;
44
+ const accessorNames = key in testableAccessors$2 ? testableAccessors$2[key] : void 0;
45
45
  const isUntaintedAccessors = Boolean(
46
46
  accessorNames && // @ts-expect-error 2345
47
47
  accessorNames.every(
@@ -53,7 +53,7 @@ function getUntaintedPrototype$1(key) {
53
53
  }
54
54
  )
55
55
  );
56
- const methodNames = key in testableMethods$1 ? testableMethods$1[key] : void 0;
56
+ const methodNames = key in testableMethods$2 ? testableMethods$2[key] : void 0;
57
57
  const isUntaintedMethods = Boolean(
58
58
  methodNames && methodNames.every(
59
59
  // @ts-expect-error 2345
@@ -64,7 +64,7 @@ function getUntaintedPrototype$1(key) {
64
64
  )
65
65
  );
66
66
  if (isUntaintedAccessors && isUntaintedMethods) {
67
- untaintedBasePrototype$1[key] = candidate.prototype;
67
+ untaintedBasePrototype$2[key] = candidate.prototype;
68
68
  return candidate.prototype;
69
69
  }
70
70
  try {
@@ -75,80 +75,80 @@ function getUntaintedPrototype$1(key) {
75
75
  const untaintedObject = win[key].prototype;
76
76
  document.body.removeChild(iframeEl);
77
77
  if (!untaintedObject) return defaultPrototype;
78
- return untaintedBasePrototype$1[key] = untaintedObject;
78
+ return untaintedBasePrototype$2[key] = untaintedObject;
79
79
  } catch {
80
80
  return defaultPrototype;
81
81
  }
82
82
  }
83
- const untaintedAccessorCache$1 = {};
84
- function getUntaintedAccessor$1(key, instance, accessor) {
83
+ const untaintedAccessorCache$2 = {};
84
+ function getUntaintedAccessor$2(key, instance, accessor) {
85
85
  var _a2;
86
86
  const cacheKey = `${key}.${String(accessor)}`;
87
- if (untaintedAccessorCache$1[cacheKey])
88
- return untaintedAccessorCache$1[cacheKey].call(
87
+ if (untaintedAccessorCache$2[cacheKey])
88
+ return untaintedAccessorCache$2[cacheKey].call(
89
89
  instance
90
90
  );
91
- const untaintedPrototype = getUntaintedPrototype$1(key);
91
+ const untaintedPrototype = getUntaintedPrototype$2(key);
92
92
  const untaintedAccessor = (_a2 = Object.getOwnPropertyDescriptor(
93
93
  untaintedPrototype,
94
94
  accessor
95
95
  )) == null ? void 0 : _a2.get;
96
96
  if (!untaintedAccessor) return instance[accessor];
97
- untaintedAccessorCache$1[cacheKey] = untaintedAccessor;
97
+ untaintedAccessorCache$2[cacheKey] = untaintedAccessor;
98
98
  return untaintedAccessor.call(instance);
99
99
  }
100
- const untaintedMethodCache$1 = {};
101
- function getUntaintedMethod$1(key, instance, method) {
100
+ const untaintedMethodCache$2 = {};
101
+ function getUntaintedMethod$2(key, instance, method) {
102
102
  const cacheKey = `${key}.${String(method)}`;
103
- if (untaintedMethodCache$1[cacheKey])
104
- return untaintedMethodCache$1[cacheKey].bind(
103
+ if (untaintedMethodCache$2[cacheKey])
104
+ return untaintedMethodCache$2[cacheKey].bind(
105
105
  instance
106
106
  );
107
- const untaintedPrototype = getUntaintedPrototype$1(key);
107
+ const untaintedPrototype = getUntaintedPrototype$2(key);
108
108
  const untaintedMethod = untaintedPrototype[method];
109
109
  if (typeof untaintedMethod !== "function") return instance[method];
110
- untaintedMethodCache$1[cacheKey] = untaintedMethod;
110
+ untaintedMethodCache$2[cacheKey] = untaintedMethod;
111
111
  return untaintedMethod.bind(instance);
112
112
  }
113
- function childNodes$1(n2) {
114
- return getUntaintedAccessor$1("Node", n2, "childNodes");
113
+ function childNodes$2(n2) {
114
+ return getUntaintedAccessor$2("Node", n2, "childNodes");
115
115
  }
116
- function parentNode$1(n2) {
117
- return getUntaintedAccessor$1("Node", n2, "parentNode");
116
+ function parentNode$2(n2) {
117
+ return getUntaintedAccessor$2("Node", n2, "parentNode");
118
118
  }
119
- function parentElement$1(n2) {
120
- return getUntaintedAccessor$1("Node", n2, "parentElement");
119
+ function parentElement$2(n2) {
120
+ return getUntaintedAccessor$2("Node", n2, "parentElement");
121
121
  }
122
- function textContent$1(n2) {
123
- return getUntaintedAccessor$1("Node", n2, "textContent");
122
+ function textContent$2(n2) {
123
+ return getUntaintedAccessor$2("Node", n2, "textContent");
124
124
  }
125
- function contains$1(n2, other) {
126
- return getUntaintedMethod$1("Node", n2, "contains")(other);
125
+ function contains$2(n2, other) {
126
+ return getUntaintedMethod$2("Node", n2, "contains")(other);
127
127
  }
128
- function getRootNode$1(n2) {
129
- return getUntaintedMethod$1("Node", n2, "getRootNode")();
128
+ function getRootNode$2(n2) {
129
+ return getUntaintedMethod$2("Node", n2, "getRootNode")();
130
130
  }
131
- function host$1(n2) {
131
+ function host$2(n2) {
132
132
  if (!n2 || !("host" in n2)) return null;
133
- return getUntaintedAccessor$1("ShadowRoot", n2, "host");
133
+ return getUntaintedAccessor$2("ShadowRoot", n2, "host");
134
134
  }
135
- function styleSheets$1(n2) {
135
+ function styleSheets$2(n2) {
136
136
  return n2.styleSheets;
137
137
  }
138
- function shadowRoot$1(n2) {
138
+ function shadowRoot$2(n2) {
139
139
  if (!n2 || !("shadowRoot" in n2)) return null;
140
- return getUntaintedAccessor$1("Element", n2, "shadowRoot");
140
+ return getUntaintedAccessor$2("Element", n2, "shadowRoot");
141
141
  }
142
- function querySelector$1(n2, selectors) {
143
- return getUntaintedAccessor$1("Element", n2, "querySelector")(selectors);
142
+ function querySelector$2(n2, selectors) {
143
+ return getUntaintedAccessor$2("Element", n2, "querySelector")(selectors);
144
144
  }
145
- function querySelectorAll$1(n2, selectors) {
146
- return getUntaintedAccessor$1("Element", n2, "querySelectorAll")(selectors);
145
+ function querySelectorAll$2(n2, selectors) {
146
+ return getUntaintedAccessor$2("Element", n2, "querySelectorAll")(selectors);
147
147
  }
148
- function mutationObserverCtor$1() {
149
- return getUntaintedPrototype$1("MutationObserver").constructor;
148
+ function mutationObserverCtor$2() {
149
+ return getUntaintedPrototype$2("MutationObserver").constructor;
150
150
  }
151
- function patch$1(source, name, replacement) {
151
+ function patch$2(source, name, replacement) {
152
152
  try {
153
153
  if (!(name in source)) {
154
154
  return () => {
@@ -174,32 +174,32 @@ function patch$1(source, name, replacement) {
174
174
  };
175
175
  }
176
176
  }
177
- const index$1 = {
178
- childNodes: childNodes$1,
179
- parentNode: parentNode$1,
180
- parentElement: parentElement$1,
181
- textContent: textContent$1,
182
- contains: contains$1,
183
- getRootNode: getRootNode$1,
184
- host: host$1,
185
- styleSheets: styleSheets$1,
186
- shadowRoot: shadowRoot$1,
187
- querySelector: querySelector$1,
188
- querySelectorAll: querySelectorAll$1,
189
- mutationObserver: mutationObserverCtor$1,
190
- patch: patch$1
177
+ const index$2 = {
178
+ childNodes: childNodes$2,
179
+ parentNode: parentNode$2,
180
+ parentElement: parentElement$2,
181
+ textContent: textContent$2,
182
+ contains: contains$2,
183
+ getRootNode: getRootNode$2,
184
+ host: host$2,
185
+ styleSheets: styleSheets$2,
186
+ shadowRoot: shadowRoot$2,
187
+ querySelector: querySelector$2,
188
+ querySelectorAll: querySelectorAll$2,
189
+ mutationObserver: mutationObserverCtor$2,
190
+ patch: patch$2
191
191
  };
192
- function isElement(n2) {
192
+ function isElement$1(n2) {
193
193
  return n2.nodeType === n2.ELEMENT_NODE;
194
194
  }
195
195
  function isShadowRoot(n2) {
196
196
  const hostEl = (
197
197
  // anchor and textarea elements also have a `host` property
198
198
  // but only shadow roots have a `mode` property
199
- n2 && "host" in n2 && "mode" in n2 && index$1.host(n2) || null
199
+ n2 && "host" in n2 && "mode" in n2 && index$2.host(n2) || null
200
200
  );
201
201
  return Boolean(
202
- hostEl && "shadowRoot" in hostEl && index$1.shadowRoot(hostEl) === n2
202
+ hostEl && "shadowRoot" in hostEl && index$2.shadowRoot(hostEl) === n2
203
203
  );
204
204
  }
205
205
  function isNativeShadowDom(shadowRoot2) {
@@ -320,6 +320,17 @@ class Mirror {
320
320
  (childNode) => this.removeNodeFromMap(childNode)
321
321
  );
322
322
  }
323
+ if (isElement$1(n2)) {
324
+ const shadowRootEl = index$2.shadowRoot(n2);
325
+ if (shadowRootEl) {
326
+ this.removeNodeFromMap(shadowRootEl);
327
+ }
328
+ if (n2.nodeName === "IFRAME" && n2.contentDocument) {
329
+ this.removeNodeFromMap(
330
+ n2.contentDocument
331
+ );
332
+ }
333
+ }
323
334
  }
324
335
  has(id) {
325
336
  return this.idNodeMap.has(id);
@@ -655,7 +666,7 @@ function classMatchesRegex(node2, regex, checkAncestors) {
655
666
  if (!node2) return false;
656
667
  if (node2.nodeType !== node2.ELEMENT_NODE) {
657
668
  if (!checkAncestors) return false;
658
- return classMatchesRegex(index$1.parentNode(node2), regex, checkAncestors);
669
+ return classMatchesRegex(index$2.parentNode(node2), regex, checkAncestors);
659
670
  }
660
671
  for (let eIndex = node2.classList.length; eIndex--; ) {
661
672
  const className = node2.classList[eIndex];
@@ -664,19 +675,19 @@ function classMatchesRegex(node2, regex, checkAncestors) {
664
675
  }
665
676
  }
666
677
  if (!checkAncestors) return false;
667
- return classMatchesRegex(index$1.parentNode(node2), regex, checkAncestors);
678
+ return classMatchesRegex(index$2.parentNode(node2), regex, checkAncestors);
668
679
  }
669
680
  function needMaskingText(node2, maskTextClass, maskTextSelector, checkAncestors) {
670
681
  let el;
671
- if (isElement(node2)) {
682
+ if (isElement$1(node2)) {
672
683
  el = node2;
673
- if (!index$1.childNodes(el).length) {
684
+ if (!index$2.childNodes(el).length) {
674
685
  return false;
675
686
  }
676
- } else if (index$1.parentElement(node2) === null) {
687
+ } else if (index$2.parentElement(node2) === null) {
677
688
  return false;
678
689
  } else {
679
- el = index$1.parentElement(node2);
690
+ el = index$2.parentElement(node2);
680
691
  }
681
692
  try {
682
693
  if (typeof maskTextClass === "string") {
@@ -825,7 +836,7 @@ function serializeNode(n2, options) {
825
836
  case n2.COMMENT_NODE:
826
837
  return {
827
838
  type: NodeType$1$1.Comment,
828
- textContent: index$1.textContent(n2) || "",
839
+ textContent: index$2.textContent(n2) || "",
829
840
  rootId
830
841
  };
831
842
  default:
@@ -840,9 +851,9 @@ function getRootId(doc, mirror2) {
840
851
  function serializeTextNode(n2, options) {
841
852
  var _a2;
842
853
  const { needsMask, maskTextFn, rootId } = options;
843
- const parent = index$1.parentNode(n2);
854
+ const parent = index$2.parentNode(n2);
844
855
  const parentTagName = parent && parent.tagName;
845
- let text = index$1.textContent(n2);
856
+ let text = index$2.textContent(n2);
846
857
  const isStyle = parentTagName === "STYLE" ? true : void 0;
847
858
  const isScript = parentTagName === "SCRIPT" ? true : void 0;
848
859
  if (isStyle && text) {
@@ -863,7 +874,7 @@ function serializeTextNode(n2, options) {
863
874
  text = "SCRIPT_PLACEHOLDER";
864
875
  }
865
876
  if (!isStyle && !isScript && text && needsMask) {
866
- text = maskTextFn ? maskTextFn(text, index$1.parentElement(n2)) : text.replace(/[\S]/g, "*");
877
+ text = maskTextFn ? maskTextFn(text, index$2.parentElement(n2)) : text.replace(/[\S]/g, "*");
867
878
  }
868
879
  return {
869
880
  type: NodeType$1$1.Text,
@@ -933,7 +944,7 @@ function serializeElementNode(n2, options) {
933
944
  }
934
945
  }
935
946
  if (tagName === "style" && n2.sheet && // TODO: Currently we only try to get dynamic stylesheet when it is an empty style element
936
- !(n2.innerText || index$1.textContent(n2) || "").trim().length) {
947
+ !(n2.innerText || index$2.textContent(n2) || "").trim().length) {
937
948
  const cssText = stringifyStylesheet(
938
949
  n2.sheet
939
950
  );
@@ -1199,7 +1210,7 @@ function serializeNodeWithId(n2, options) {
1199
1210
  if (serializedNode.type === NodeType$1$1.Element) {
1200
1211
  recordChild = recordChild && !serializedNode.needBlock;
1201
1212
  delete serializedNode.needBlock;
1202
- const shadowRootEl = index$1.shadowRoot(n2);
1213
+ const shadowRootEl = index$2.shadowRoot(n2);
1203
1214
  if (shadowRootEl && isNativeShadowDom(shadowRootEl))
1204
1215
  serializedNode.isShadowHost = true;
1205
1216
  }
@@ -1234,7 +1245,7 @@ function serializeNodeWithId(n2, options) {
1234
1245
  };
1235
1246
  if (serializedNode.type === NodeType$1$1.Element && serializedNode.tagName === "textarea" && serializedNode.attributes.value !== void 0) ;
1236
1247
  else {
1237
- for (const childN of Array.from(index$1.childNodes(n2))) {
1248
+ for (const childN of Array.from(index$2.childNodes(n2))) {
1238
1249
  const serializedChildNode = serializeNodeWithId(childN, bypassOptions);
1239
1250
  if (serializedChildNode) {
1240
1251
  serializedNode.childNodes.push(serializedChildNode);
@@ -1242,8 +1253,8 @@ function serializeNodeWithId(n2, options) {
1242
1253
  }
1243
1254
  }
1244
1255
  let shadowRootEl = null;
1245
- if (isElement(n2) && (shadowRootEl = index$1.shadowRoot(n2))) {
1246
- for (const childN of Array.from(index$1.childNodes(shadowRootEl))) {
1256
+ if (isElement$1(n2) && (shadowRootEl = index$2.shadowRoot(n2))) {
1257
+ for (const childN of Array.from(index$2.childNodes(shadowRootEl))) {
1247
1258
  const serializedChildNode = serializeNodeWithId(childN, bypassOptions);
1248
1259
  if (serializedChildNode) {
1249
1260
  isNativeShadowDom(shadowRootEl) && (serializedChildNode.isShadow = true);
@@ -1252,7 +1263,7 @@ function serializeNodeWithId(n2, options) {
1252
1263
  }
1253
1264
  }
1254
1265
  }
1255
- const parent = index$1.parentNode(n2);
1266
+ const parent = index$2.parentNode(n2);
1256
1267
  if (parent && isShadowRoot(parent) && isNativeShadowDom(parent)) {
1257
1268
  serializedNode.isShadow = true;
1258
1269
  }
@@ -11803,14 +11814,22 @@ class IframeManager {
11803
11814
  }
11804
11815
  removeIframeById(iframeId) {
11805
11816
  const entry = this.attachedIframes.get(iframeId);
11806
- if (!entry) return;
11807
- const win = entry.element.contentWindow;
11808
- if (win && this.nestedIframeListeners.has(win)) {
11809
- const handler = this.nestedIframeListeners.get(win);
11810
- win.removeEventListener("message", handler);
11811
- this.nestedIframeListeners.delete(win);
11817
+ const iframe = (entry == null ? void 0 : entry.element) || this.mirror.getNode(iframeId);
11818
+ if (iframe) {
11819
+ const win = iframe.contentWindow;
11820
+ if (win && this.nestedIframeListeners.has(win)) {
11821
+ const handler = this.nestedIframeListeners.get(win);
11822
+ win.removeEventListener("message", handler);
11823
+ this.nestedIframeListeners.delete(win);
11824
+ }
11825
+ if (win) {
11826
+ this.crossOriginIframeMap.delete(win);
11827
+ }
11828
+ this.iframes.delete(iframe);
11829
+ }
11830
+ if (entry) {
11831
+ this.attachedIframes.delete(iframeId);
11812
11832
  }
11813
- this.attachedIframes.delete(iframeId);
11814
11833
  }
11815
11834
  reattachIframes() {
11816
11835
  this.attachedIframes.forEach(({ content }, iframeId) => {
@@ -12779,9 +12798,12 @@ function record(options = {}) {
12779
12798
  }
12780
12799
  };
12781
12800
  const wrappedMutationEmit = (m) => {
12782
- if (recordCrossOriginIframes && m.removes) {
12801
+ if (recordCrossOriginIframes && m.removes && m.removes.length > 0) {
12802
+ const addedIds = m.adds.length > 0 ? new Set(m.adds.map((add) => add.node.id)) : null;
12783
12803
  m.removes.forEach(({ id }) => {
12784
- iframeManager.removeIframeById(id);
12804
+ if (!addedIds || !addedIds.has(id)) {
12805
+ iframeManager.removeIframeById(id);
12806
+ }
12785
12807
  });
12786
12808
  }
12787
12809
  wrappedEmit({