@appsurify-testmap/rrweb-record 2.1.0-alpha.2 → 2.1.0-alpha.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.
@@ -880,28 +880,14 @@ function transformAttribute(doc, tagName, name, value) {
880
880
  }
881
881
  return value;
882
882
  }
883
- function isIgnoreAttribute(tagName, name, _value) {
883
+ function ignoreAttribute(tagName, name, _value) {
884
884
  return (tagName === "video" || tagName === "audio") && name === "autoplay";
885
885
  }
886
- function cleanAttributes(doc, element, ignoreAttribute) {
887
- const tagName = getValidTagName$1(element);
888
- const attributes = {};
889
- const len = element.attributes.length;
890
- for (let i2 = 0; i2 < len; i2++) {
891
- const attr = element.attributes[i2];
892
- const name = attr.name;
893
- const value = attr.value;
894
- const shouldIgnoreByName = typeof ignoreAttribute === "string" ? name === ignoreAttribute : ignoreAttribute.test(name);
895
- if (!shouldIgnoreByName && !isIgnoreAttribute(tagName, name)) {
896
- attributes[name] = transformAttribute(
897
- doc,
898
- tagName,
899
- toLowerCase(name),
900
- value
901
- );
902
- }
903
- }
904
- return attributes;
886
+ function isIncludeAttribute(name, include) {
887
+ return typeof include === "string" ? name.includes(include) : include.test(name);
888
+ }
889
+ function isExcludeAttribute(name, exclude) {
890
+ return typeof exclude === "string" ? name.includes(exclude) : exclude.test(name);
905
891
  }
906
892
  function _isBlockedElement(element, blockClass, blockSelector) {
907
893
  try {
@@ -1032,7 +1018,8 @@ function serializeNode(n2, options) {
1032
1018
  mirror: mirror2,
1033
1019
  blockClass,
1034
1020
  blockSelector,
1035
- ignoreAttribute,
1021
+ excludeAttribute,
1022
+ includeAttribute,
1036
1023
  needsMask,
1037
1024
  inlineStylesheet,
1038
1025
  maskInputOptions = {},
@@ -1078,7 +1065,8 @@ function serializeNode(n2, options) {
1078
1065
  doc,
1079
1066
  blockClass,
1080
1067
  blockSelector,
1081
- ignoreAttribute,
1068
+ excludeAttribute,
1069
+ includeAttribute,
1082
1070
  inlineStylesheet,
1083
1071
  maskInputOptions,
1084
1072
  maskInputFn,
@@ -1156,7 +1144,8 @@ function serializeElementNode(n2, options) {
1156
1144
  doc,
1157
1145
  blockClass,
1158
1146
  blockSelector,
1159
- ignoreAttribute,
1147
+ excludeAttribute,
1148
+ includeAttribute,
1160
1149
  inlineStylesheet,
1161
1150
  maskInputOptions = {},
1162
1151
  maskInputFn,
@@ -1170,7 +1159,22 @@ function serializeElementNode(n2, options) {
1170
1159
  } = options;
1171
1160
  const needBlock = _isBlockedElement(n2, blockClass, blockSelector);
1172
1161
  const tagName = getValidTagName$1(n2);
1173
- let attributes = cleanAttributes(doc, n2, ignoreAttribute);
1162
+ let attributes = {};
1163
+ const len = n2.attributes.length;
1164
+ for (let i2 = 0; i2 < len; i2++) {
1165
+ const attr = n2.attributes[i2];
1166
+ if (isExcludeAttribute(attr.name, excludeAttribute) && !isIncludeAttribute(attr.name, includeAttribute)) {
1167
+ continue;
1168
+ }
1169
+ if (!ignoreAttribute(tagName, attr.name, attr.value)) {
1170
+ attributes[attr.name] = transformAttribute(
1171
+ doc,
1172
+ tagName,
1173
+ toLowerCase(attr.name),
1174
+ attr.value
1175
+ );
1176
+ }
1177
+ }
1174
1178
  if (tagName === "link" && inlineStylesheet) {
1175
1179
  const stylesheet = Array.from(doc.styleSheets).find((s2) => {
1176
1180
  return s2.href === n2.href;
@@ -1384,7 +1388,8 @@ function serializeNodeWithId(n2, options) {
1384
1388
  blockSelector,
1385
1389
  maskTextClass,
1386
1390
  maskTextSelector,
1387
- ignoreAttribute,
1391
+ excludeAttribute,
1392
+ includeAttribute,
1388
1393
  skipChild = false,
1389
1394
  inlineStylesheet = true,
1390
1395
  maskInputOptions = {},
@@ -1419,7 +1424,8 @@ function serializeNodeWithId(n2, options) {
1419
1424
  mirror: mirror2,
1420
1425
  blockClass,
1421
1426
  blockSelector,
1422
- ignoreAttribute,
1427
+ excludeAttribute,
1428
+ includeAttribute,
1423
1429
  needsMask,
1424
1430
  inlineStylesheet,
1425
1431
  maskInputOptions,
@@ -1472,7 +1478,8 @@ function serializeNodeWithId(n2, options) {
1472
1478
  needsMask,
1473
1479
  maskTextClass,
1474
1480
  maskTextSelector,
1475
- ignoreAttribute,
1481
+ excludeAttribute,
1482
+ includeAttribute,
1476
1483
  skipChild,
1477
1484
  inlineStylesheet,
1478
1485
  maskInputOptions,
@@ -1532,7 +1539,8 @@ function serializeNodeWithId(n2, options) {
1532
1539
  needsMask,
1533
1540
  maskTextClass,
1534
1541
  maskTextSelector,
1535
- ignoreAttribute,
1542
+ excludeAttribute,
1543
+ includeAttribute,
1536
1544
  skipChild: false,
1537
1545
  inlineStylesheet,
1538
1546
  maskInputOptions,
@@ -1574,7 +1582,8 @@ function serializeNodeWithId(n2, options) {
1574
1582
  needsMask,
1575
1583
  maskTextClass,
1576
1584
  maskTextSelector,
1577
- ignoreAttribute,
1585
+ excludeAttribute,
1586
+ includeAttribute,
1578
1587
  skipChild: false,
1579
1588
  inlineStylesheet,
1580
1589
  maskInputOptions,
@@ -1612,7 +1621,8 @@ function snapshot(n2, options) {
1612
1621
  blockSelector = null,
1613
1622
  maskTextClass = "rr-mask",
1614
1623
  maskTextSelector = null,
1615
- ignoreAttribute = "rr-ignore",
1624
+ excludeAttribute = /^$a/,
1625
+ includeAttribute = /.+/i,
1616
1626
  inlineStylesheet = true,
1617
1627
  inlineImages = false,
1618
1628
  recordCanvas = false,
@@ -1672,7 +1682,8 @@ function snapshot(n2, options) {
1672
1682
  blockSelector,
1673
1683
  maskTextClass,
1674
1684
  maskTextSelector,
1675
- ignoreAttribute,
1685
+ excludeAttribute,
1686
+ includeAttribute,
1676
1687
  skipChild: false,
1677
1688
  inlineStylesheet,
1678
1689
  maskInputOptions,
@@ -9179,9 +9190,8 @@ function hookSetter(target, key, d, isRevoked, win = window) {
9179
9190
  );
9180
9191
  return () => hookSetter(target, key, original || {}, true);
9181
9192
  }
9182
- let nowTimestamp = Date.now;
9183
- if (!/* @__PURE__ */ /[1-9][0-9]{12}/.test(Date.now().toString())) {
9184
- nowTimestamp = () => (/* @__PURE__ */ new Date()).getTime();
9193
+ function nowTimestamp() {
9194
+ return Math.round(performance.timeOrigin + performance.now());
9185
9195
  }
9186
9196
  function getWindowScroll(win = window) {
9187
9197
  var _a2, _b, _c, _d;
@@ -9371,7 +9381,6 @@ var IncrementalSource = /* @__PURE__ */ ((IncrementalSource2) => {
9371
9381
  IncrementalSource2[IncrementalSource2["Selection"] = 14] = "Selection";
9372
9382
  IncrementalSource2[IncrementalSource2["AdoptedStyleSheet"] = 15] = "AdoptedStyleSheet";
9373
9383
  IncrementalSource2[IncrementalSource2["CustomElement"] = 16] = "CustomElement";
9374
- IncrementalSource2[IncrementalSource2["VisibilityChange"] = 17] = "VisibilityChange";
9375
9384
  return IncrementalSource2;
9376
9385
  })(IncrementalSource || {});
9377
9386
  var MouseInteractions = /* @__PURE__ */ ((MouseInteractions2) => {
@@ -9517,7 +9526,8 @@ class MutationBuffer {
9517
9526
  __publicField(this, "blockSelector");
9518
9527
  __publicField(this, "maskTextClass");
9519
9528
  __publicField(this, "maskTextSelector");
9520
- __publicField(this, "ignoreAttribute");
9529
+ __publicField(this, "excludeAttribute");
9530
+ __publicField(this, "includeAttribute");
9521
9531
  __publicField(this, "inlineStylesheet");
9522
9532
  __publicField(this, "maskInputOptions");
9523
9533
  __publicField(this, "maskTextFn");
@@ -9581,7 +9591,8 @@ class MutationBuffer {
9581
9591
  blockSelector: this.blockSelector,
9582
9592
  maskTextClass: this.maskTextClass,
9583
9593
  maskTextSelector: this.maskTextSelector,
9584
- ignoreAttribute: this.ignoreAttribute || "",
9594
+ excludeAttribute: this.excludeAttribute,
9595
+ includeAttribute: this.includeAttribute,
9585
9596
  skipChild: true,
9586
9597
  newlyAddedElement: true,
9587
9598
  inlineStylesheet: this.inlineStylesheet,
@@ -9783,6 +9794,14 @@ class MutationBuffer {
9783
9794
  const target = m.target;
9784
9795
  let attributeName = m.attributeName;
9785
9796
  let value = m.target.getAttribute(attributeName);
9797
+ const propValue = target[attributeName];
9798
+ const isPhantomAttributeMutation = value === null && !target.hasAttribute(attributeName) && m.oldValue !== null && (propValue === "" || propValue === null || typeof propValue === "undefined");
9799
+ if (isPhantomAttributeMutation && !isIncludeAttribute(attributeName, this.includeAttribute)) {
9800
+ return;
9801
+ }
9802
+ if (isExcludeAttribute(attributeName, this.excludeAttribute)) {
9803
+ return;
9804
+ }
9786
9805
  if (attributeName === "value") {
9787
9806
  const type = getInputType(target);
9788
9807
  value = maskInputValue({
@@ -9818,13 +9837,21 @@ class MutationBuffer {
9818
9837
  if (attributeName === "type" && target.tagName === "INPUT" && (m.oldValue || "").toLowerCase() === "password") {
9819
9838
  target.setAttribute("data-rr-is-password", "true");
9820
9839
  }
9821
- if (!isIgnoreAttribute(target.tagName, attributeName)) {
9840
+ if (!ignoreAttribute(target.tagName, attributeName)) {
9822
9841
  item.attributes[attributeName] = transformAttribute(
9823
9842
  this.doc,
9824
9843
  toLowerCase(target.tagName),
9825
9844
  toLowerCase(attributeName),
9826
9845
  value
9827
9846
  );
9847
+ if (value === item.attributes[attributeName] && !isIncludeAttribute(attributeName, this.includeAttribute)) {
9848
+ delete item.attributes[attributeName];
9849
+ if (Object.keys(item.attributes).length === 0) {
9850
+ this.attributes = this.attributes.filter((a2) => a2 !== item);
9851
+ this.attributeMap.delete(m.target);
9852
+ }
9853
+ return;
9854
+ }
9828
9855
  if (attributeName === "style") {
9829
9856
  if (!this.unattachedDoc) {
9830
9857
  try {
@@ -9937,7 +9964,8 @@ class MutationBuffer {
9937
9964
  "blockSelector",
9938
9965
  "maskTextClass",
9939
9966
  "maskTextSelector",
9940
- "ignoreAttribute",
9967
+ "excludeAttribute",
9968
+ "includeAttribute",
9941
9969
  "inlineStylesheet",
9942
9970
  "maskInputOptions",
9943
9971
  "maskTextFn",
@@ -10076,60 +10104,6 @@ function initMutationObserver(options, rootEl) {
10076
10104
  });
10077
10105
  return observer;
10078
10106
  }
10079
- function initVisibilityObserver({
10080
- visibilityChangeCb,
10081
- doc,
10082
- mirror: mirror2,
10083
- sampling
10084
- }) {
10085
- if (!visibilityChangeCb) {
10086
- return () => {
10087
- };
10088
- }
10089
- const observedElements = /* @__PURE__ */ new WeakMap();
10090
- const debounceThreshold = typeof sampling.visibility === "number" ? sampling.visibility : 50;
10091
- const throttledCb = throttle(
10092
- callbackWrapper((entry) => {
10093
- const target = entry.target;
10094
- const id = mirror2.getId(target);
10095
- const isVisible = entry.isIntersecting || entry.intersectionRatio > 0;
10096
- if (id !== -1) {
10097
- visibilityChangeCb({
10098
- id,
10099
- isVisible,
10100
- visibilityRatio: entry.intersectionRatio
10101
- });
10102
- }
10103
- }),
10104
- debounceThreshold,
10105
- { leading: sampling.visibility !== false, trailing: true }
10106
- );
10107
- const observer = new IntersectionObserver((entries) => {
10108
- entries.forEach((entry) => {
10109
- const target = entry.target;
10110
- if (observedElements.has(target)) {
10111
- throttledCb(entry);
10112
- } else {
10113
- observedElements.set(target, true);
10114
- }
10115
- });
10116
- }, { root: null, threshold: [0.1, 0.9] });
10117
- doc.querySelectorAll("*").forEach((el) => observer.observe(el));
10118
- const mutationObserver = new MutationObserver((mutations) => {
10119
- mutations.forEach((mutation) => {
10120
- mutation.addedNodes.forEach((node2) => {
10121
- if (node2 instanceof Element) {
10122
- observer.observe(node2);
10123
- }
10124
- });
10125
- });
10126
- });
10127
- mutationObserver.observe(doc, { childList: true, subtree: true });
10128
- return () => {
10129
- observer.disconnect();
10130
- mutationObserver.disconnect();
10131
- };
10132
- }
10133
10107
  function initMoveObserver({
10134
10108
  mousemoveCb,
10135
10109
  sampling,
@@ -10409,6 +10383,20 @@ function initInputObserver({
10409
10383
  }
10410
10384
  function cbWithDedup(target, v2) {
10411
10385
  const lastInputValue = lastInputValueMap.get(target);
10386
+ const el = target;
10387
+ const hasPlaceholder = el.hasAttribute("placeholder");
10388
+ const isEmpty = el.value === "";
10389
+ const isDefaultEmpty = typeof el.defaultValue === "string" ? el.defaultValue === "" : true;
10390
+ const isNonUser = !v2.userTriggered;
10391
+ const isRepeatEmpty = !lastInputValue || lastInputValue.text === "";
10392
+ const isLikelyPhantom = hasPlaceholder && isEmpty && isDefaultEmpty && isRepeatEmpty && isNonUser && !v2.isChecked && el.type !== "hidden" && INPUT_TAGS.includes(el.tagName);
10393
+ const isRenderDrivenTextInput = el.tagName === "INPUT" && el.type === "text" && !v2.userTriggered && v2.text === el.defaultValue && !lastInputValue && el.hasAttribute("placeholder");
10394
+ const isValueFromDefault = !v2.userTriggered && el.value === el.defaultValue && !lastInputValue && el.hasAttribute("placeholder") && !v2.isChecked && el.type !== "hidden" && INPUT_TAGS.includes(el.tagName);
10395
+ const isPhantomCheckbox = el.type === "checkbox" && !v2.userTriggered && !v2.isChecked && !lastInputValue;
10396
+ const isPhantomRadio = el.type === "radio" && !v2.userTriggered && !v2.isChecked && !lastInputValue;
10397
+ if (isLikelyPhantom || isRenderDrivenTextInput || isValueFromDefault || isPhantomCheckbox || isPhantomRadio) {
10398
+ return;
10399
+ }
10412
10400
  if (!lastInputValue || lastInputValue.text !== v2.text || lastInputValue.isChecked !== v2.isChecked) {
10413
10401
  lastInputValueMap.set(target, v2);
10414
10402
  const id = mirror2.getId(target);
@@ -10946,7 +10934,6 @@ function initCustomElementObserver({
10946
10934
  function mergeHooks(o2, hooks) {
10947
10935
  const {
10948
10936
  mutationCb,
10949
- visibilityChangeCb,
10950
10937
  mousemoveCb,
10951
10938
  mouseInteractionCb,
10952
10939
  scrollCb,
@@ -10966,12 +10953,6 @@ function mergeHooks(o2, hooks) {
10966
10953
  }
10967
10954
  mutationCb(...p);
10968
10955
  };
10969
- o2.visibilityChangeCb = (...p) => {
10970
- if (hooks.visibilityChange) {
10971
- hooks.visibilityChange(...p);
10972
- }
10973
- visibilityChangeCb(...p);
10974
- };
10975
10956
  o2.mousemoveCb = (...p) => {
10976
10957
  if (hooks.mousemove) {
10977
10958
  hooks.mousemove(...p);
@@ -11064,7 +11045,6 @@ function initObservers(o2, hooks = {}) {
11064
11045
  });
11065
11046
  const inputHandler = initInputObserver(o2);
11066
11047
  const mediaInteractionHandler = initMediaInteractionObserver(o2);
11067
- const visibleHandler = initVisibilityObserver(o2);
11068
11048
  let styleSheetObserver = () => {
11069
11049
  };
11070
11050
  let adoptedStyleSheetObserver = () => {
@@ -11094,7 +11074,6 @@ function initObservers(o2, hooks = {}) {
11094
11074
  return callbackWrapper(() => {
11095
11075
  mutationBuffers.forEach((b) => b.reset());
11096
11076
  mutationObserver == null ? void 0 : mutationObserver.disconnect();
11097
- visibleHandler();
11098
11077
  mousemoveHandler();
11099
11078
  mouseInteractionHandler();
11100
11079
  scrollHandler();
@@ -12161,12 +12140,12 @@ function record(options = {}) {
12161
12140
  emit,
12162
12141
  checkoutEveryNms,
12163
12142
  checkoutEveryNth,
12164
- checkoutEveryEvc,
12165
12143
  blockClass = "rr-block",
12166
12144
  blockSelector = null,
12167
12145
  ignoreClass = "rr-ignore",
12168
12146
  ignoreSelector = null,
12169
- ignoreAttribute = "rr-ignore",
12147
+ excludeAttribute: _excludeAttribute,
12148
+ includeAttribute: _includeAttribute,
12170
12149
  maskTextClass = "rr-mask",
12171
12150
  maskTextSelector = null,
12172
12151
  inlineStylesheet = true,
@@ -12215,6 +12194,8 @@ function record(options = {}) {
12215
12194
  sampling.mousemove = mousemoveWait;
12216
12195
  }
12217
12196
  mirror.reset();
12197
+ const excludeAttribute = _excludeAttribute === void 0 ? /^$a/ : _excludeAttribute;
12198
+ const includeAttribute = _includeAttribute === void 0 ? /.+/i : _includeAttribute;
12218
12199
  const maskInputOptions = maskAllInputs === true ? {
12219
12200
  color: true,
12220
12201
  date: true,
@@ -12291,8 +12272,7 @@ function record(options = {}) {
12291
12272
  incrementalSnapshotCount++;
12292
12273
  const exceedCount = checkoutEveryNth && incrementalSnapshotCount >= checkoutEveryNth;
12293
12274
  const exceedTime = checkoutEveryNms && e2.timestamp - lastFullSnapshotEvent.timestamp > checkoutEveryNms;
12294
- const isVisibilityChanged = checkoutEveryEvc && e2.type === EventType.IncrementalSnapshot && e2.data.source === IncrementalSource.VisibilityChange;
12295
- if (exceedCount || exceedTime || isVisibilityChanged) {
12275
+ if (exceedCount || exceedTime) {
12296
12276
  takeFullSnapshot$1(true);
12297
12277
  }
12298
12278
  }
@@ -12365,7 +12345,8 @@ function record(options = {}) {
12365
12345
  blockSelector,
12366
12346
  maskTextClass,
12367
12347
  maskTextSelector,
12368
- ignoreAttribute,
12348
+ excludeAttribute,
12349
+ includeAttribute,
12369
12350
  inlineStylesheet,
12370
12351
  maskInputOptions,
12371
12352
  dataURLOptions,
@@ -12407,7 +12388,8 @@ function record(options = {}) {
12407
12388
  blockSelector,
12408
12389
  maskTextClass,
12409
12390
  maskTextSelector,
12410
- ignoreAttribute,
12391
+ excludeAttribute,
12392
+ includeAttribute,
12411
12393
  inlineStylesheet,
12412
12394
  maskAllInputs: maskInputOptions,
12413
12395
  maskTextFn,
@@ -12463,15 +12445,6 @@ function record(options = {}) {
12463
12445
  return callbackWrapper(initObservers)(
12464
12446
  {
12465
12447
  mutationCb: wrappedMutationEmit,
12466
- visibilityChangeCb: (v2) => {
12467
- wrappedEmit({
12468
- type: EventType.IncrementalSnapshot,
12469
- data: {
12470
- source: IncrementalSource.VisibilityChange,
12471
- ...v2
12472
- }
12473
- });
12474
- },
12475
12448
  mousemoveCb: (positions, source) => wrappedEmit({
12476
12449
  type: EventType.IncrementalSnapshot,
12477
12450
  data: {
@@ -12553,7 +12526,8 @@ function record(options = {}) {
12553
12526
  ignoreSelector,
12554
12527
  maskTextClass,
12555
12528
  maskTextSelector,
12556
- ignoreAttribute,
12529
+ excludeAttribute,
12530
+ includeAttribute,
12557
12531
  maskInputOptions,
12558
12532
  inlineStylesheet,
12559
12533
  sampling,