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