@appsurify-testmap/rrweb 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.
package/dist/rrweb.cjs CHANGED
@@ -892,28 +892,14 @@ function transformAttribute(doc, tagName, name, value) {
892
892
  }
893
893
  return value;
894
894
  }
895
- function isIgnoreAttribute(tagName, name, _value) {
895
+ function ignoreAttribute(tagName, name, _value) {
896
896
  return (tagName === "video" || tagName === "audio") && name === "autoplay";
897
897
  }
898
- function cleanAttributes(doc, element, ignoreAttribute) {
899
- const tagName = getValidTagName$1(element);
900
- const attributes = {};
901
- const len = element.attributes.length;
902
- for (let i2 = 0; i2 < len; i2++) {
903
- const attr = element.attributes[i2];
904
- const name = attr.name;
905
- const value = attr.value;
906
- const shouldIgnoreByName = typeof ignoreAttribute === "string" ? name === ignoreAttribute : ignoreAttribute.test(name);
907
- if (!shouldIgnoreByName && !isIgnoreAttribute(tagName, name)) {
908
- attributes[name] = transformAttribute(
909
- doc,
910
- tagName,
911
- toLowerCase(name),
912
- value
913
- );
914
- }
915
- }
916
- return attributes;
898
+ function isIncludeAttribute(name, include) {
899
+ return typeof include === "string" ? name.includes(include) : include.test(name);
900
+ }
901
+ function isExcludeAttribute(name, exclude) {
902
+ return typeof exclude === "string" ? name.includes(exclude) : exclude.test(name);
917
903
  }
918
904
  function _isBlockedElement(element, blockClass, blockSelector) {
919
905
  try {
@@ -1044,7 +1030,8 @@ function serializeNode(n2, options) {
1044
1030
  mirror: mirror2,
1045
1031
  blockClass,
1046
1032
  blockSelector,
1047
- ignoreAttribute,
1033
+ excludeAttribute,
1034
+ includeAttribute,
1048
1035
  needsMask,
1049
1036
  inlineStylesheet,
1050
1037
  maskInputOptions = {},
@@ -1090,7 +1077,8 @@ function serializeNode(n2, options) {
1090
1077
  doc,
1091
1078
  blockClass,
1092
1079
  blockSelector,
1093
- ignoreAttribute,
1080
+ excludeAttribute,
1081
+ includeAttribute,
1094
1082
  inlineStylesheet,
1095
1083
  maskInputOptions,
1096
1084
  maskInputFn,
@@ -1168,7 +1156,8 @@ function serializeElementNode(n2, options) {
1168
1156
  doc,
1169
1157
  blockClass,
1170
1158
  blockSelector,
1171
- ignoreAttribute,
1159
+ excludeAttribute,
1160
+ includeAttribute,
1172
1161
  inlineStylesheet,
1173
1162
  maskInputOptions = {},
1174
1163
  maskInputFn,
@@ -1182,7 +1171,22 @@ function serializeElementNode(n2, options) {
1182
1171
  } = options;
1183
1172
  const needBlock = _isBlockedElement(n2, blockClass, blockSelector);
1184
1173
  const tagName = getValidTagName$1(n2);
1185
- let attributes = cleanAttributes(doc, n2, ignoreAttribute);
1174
+ let attributes = {};
1175
+ const len = n2.attributes.length;
1176
+ for (let i2 = 0; i2 < len; i2++) {
1177
+ const attr = n2.attributes[i2];
1178
+ if (isExcludeAttribute(attr.name, excludeAttribute) && !isIncludeAttribute(attr.name, includeAttribute)) {
1179
+ continue;
1180
+ }
1181
+ if (!ignoreAttribute(tagName, attr.name, attr.value)) {
1182
+ attributes[attr.name] = transformAttribute(
1183
+ doc,
1184
+ tagName,
1185
+ toLowerCase(attr.name),
1186
+ attr.value
1187
+ );
1188
+ }
1189
+ }
1186
1190
  if (tagName === "link" && inlineStylesheet) {
1187
1191
  const stylesheet = Array.from(doc.styleSheets).find((s2) => {
1188
1192
  return s2.href === n2.href;
@@ -1396,7 +1400,8 @@ function serializeNodeWithId(n2, options) {
1396
1400
  blockSelector,
1397
1401
  maskTextClass,
1398
1402
  maskTextSelector,
1399
- ignoreAttribute,
1403
+ excludeAttribute,
1404
+ includeAttribute,
1400
1405
  skipChild = false,
1401
1406
  inlineStylesheet = true,
1402
1407
  maskInputOptions = {},
@@ -1431,7 +1436,8 @@ function serializeNodeWithId(n2, options) {
1431
1436
  mirror: mirror2,
1432
1437
  blockClass,
1433
1438
  blockSelector,
1434
- ignoreAttribute,
1439
+ excludeAttribute,
1440
+ includeAttribute,
1435
1441
  needsMask,
1436
1442
  inlineStylesheet,
1437
1443
  maskInputOptions,
@@ -1484,7 +1490,8 @@ function serializeNodeWithId(n2, options) {
1484
1490
  needsMask,
1485
1491
  maskTextClass,
1486
1492
  maskTextSelector,
1487
- ignoreAttribute,
1493
+ excludeAttribute,
1494
+ includeAttribute,
1488
1495
  skipChild,
1489
1496
  inlineStylesheet,
1490
1497
  maskInputOptions,
@@ -1544,7 +1551,8 @@ function serializeNodeWithId(n2, options) {
1544
1551
  needsMask,
1545
1552
  maskTextClass,
1546
1553
  maskTextSelector,
1547
- ignoreAttribute,
1554
+ excludeAttribute,
1555
+ includeAttribute,
1548
1556
  skipChild: false,
1549
1557
  inlineStylesheet,
1550
1558
  maskInputOptions,
@@ -1586,7 +1594,8 @@ function serializeNodeWithId(n2, options) {
1586
1594
  needsMask,
1587
1595
  maskTextClass,
1588
1596
  maskTextSelector,
1589
- ignoreAttribute,
1597
+ excludeAttribute,
1598
+ includeAttribute,
1590
1599
  skipChild: false,
1591
1600
  inlineStylesheet,
1592
1601
  maskInputOptions,
@@ -1624,7 +1633,8 @@ function snapshot(n2, options) {
1624
1633
  blockSelector = null,
1625
1634
  maskTextClass = "rr-mask",
1626
1635
  maskTextSelector = null,
1627
- ignoreAttribute = "rr-ignore",
1636
+ excludeAttribute = /^$a/,
1637
+ includeAttribute = /.+/i,
1628
1638
  inlineStylesheet = true,
1629
1639
  inlineImages = false,
1630
1640
  recordCanvas = false,
@@ -1684,7 +1694,8 @@ function snapshot(n2, options) {
1684
1694
  blockSelector,
1685
1695
  maskTextClass,
1686
1696
  maskTextSelector,
1687
- ignoreAttribute,
1697
+ excludeAttribute,
1698
+ includeAttribute,
1688
1699
  skipChild: false,
1689
1700
  inlineStylesheet,
1690
1701
  maskInputOptions,
@@ -10919,9 +10930,8 @@ function hookSetter(target, key, d, isRevoked, win = window) {
10919
10930
  );
10920
10931
  return () => hookSetter(target, key, original || {}, true);
10921
10932
  }
10922
- let nowTimestamp = Date.now;
10923
- if (!/* @__PURE__ */ /[1-9][0-9]{12}/.test(Date.now().toString())) {
10924
- nowTimestamp = () => (/* @__PURE__ */ new Date()).getTime();
10933
+ function nowTimestamp() {
10934
+ return Math.round(performance.timeOrigin + performance.now());
10925
10935
  }
10926
10936
  function getWindowScroll(win = window) {
10927
10937
  var _a2, _b, _c, _d;
@@ -11202,9 +11212,7 @@ const utils = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePropert
11202
11212
  isSerializedStylesheet,
11203
11213
  iterateResolveTree,
11204
11214
  legacy_isTouchEvent,
11205
- get nowTimestamp() {
11206
- return nowTimestamp;
11207
- },
11215
+ nowTimestamp,
11208
11216
  on,
11209
11217
  polyfill: polyfill$1,
11210
11218
  queueToResolveTrees,
@@ -11240,7 +11248,6 @@ var IncrementalSource = /* @__PURE__ */ ((IncrementalSource2) => {
11240
11248
  IncrementalSource2[IncrementalSource2["Selection"] = 14] = "Selection";
11241
11249
  IncrementalSource2[IncrementalSource2["AdoptedStyleSheet"] = 15] = "AdoptedStyleSheet";
11242
11250
  IncrementalSource2[IncrementalSource2["CustomElement"] = 16] = "CustomElement";
11243
- IncrementalSource2[IncrementalSource2["VisibilityChange"] = 17] = "VisibilityChange";
11244
11251
  return IncrementalSource2;
11245
11252
  })(IncrementalSource || {});
11246
11253
  var MouseInteractions = /* @__PURE__ */ ((MouseInteractions2) => {
@@ -11423,7 +11430,8 @@ class MutationBuffer {
11423
11430
  __publicField(this, "blockSelector");
11424
11431
  __publicField(this, "maskTextClass");
11425
11432
  __publicField(this, "maskTextSelector");
11426
- __publicField(this, "ignoreAttribute");
11433
+ __publicField(this, "excludeAttribute");
11434
+ __publicField(this, "includeAttribute");
11427
11435
  __publicField(this, "inlineStylesheet");
11428
11436
  __publicField(this, "maskInputOptions");
11429
11437
  __publicField(this, "maskTextFn");
@@ -11487,7 +11495,8 @@ class MutationBuffer {
11487
11495
  blockSelector: this.blockSelector,
11488
11496
  maskTextClass: this.maskTextClass,
11489
11497
  maskTextSelector: this.maskTextSelector,
11490
- ignoreAttribute: this.ignoreAttribute || "",
11498
+ excludeAttribute: this.excludeAttribute,
11499
+ includeAttribute: this.includeAttribute,
11491
11500
  skipChild: true,
11492
11501
  newlyAddedElement: true,
11493
11502
  inlineStylesheet: this.inlineStylesheet,
@@ -11689,6 +11698,14 @@ class MutationBuffer {
11689
11698
  const target = m.target;
11690
11699
  let attributeName = m.attributeName;
11691
11700
  let value = m.target.getAttribute(attributeName);
11701
+ const propValue = target[attributeName];
11702
+ const isPhantomAttributeMutation = value === null && !target.hasAttribute(attributeName) && m.oldValue !== null && (propValue === "" || propValue === null || typeof propValue === "undefined");
11703
+ if (isPhantomAttributeMutation && !isIncludeAttribute(attributeName, this.includeAttribute)) {
11704
+ return;
11705
+ }
11706
+ if (isExcludeAttribute(attributeName, this.excludeAttribute)) {
11707
+ return;
11708
+ }
11692
11709
  if (attributeName === "value") {
11693
11710
  const type = getInputType(target);
11694
11711
  value = maskInputValue({
@@ -11724,13 +11741,21 @@ class MutationBuffer {
11724
11741
  if (attributeName === "type" && target.tagName === "INPUT" && (m.oldValue || "").toLowerCase() === "password") {
11725
11742
  target.setAttribute("data-rr-is-password", "true");
11726
11743
  }
11727
- if (!isIgnoreAttribute(target.tagName, attributeName)) {
11744
+ if (!ignoreAttribute(target.tagName, attributeName)) {
11728
11745
  item.attributes[attributeName] = transformAttribute(
11729
11746
  this.doc,
11730
11747
  toLowerCase(target.tagName),
11731
11748
  toLowerCase(attributeName),
11732
11749
  value
11733
11750
  );
11751
+ if (value === item.attributes[attributeName] && !isIncludeAttribute(attributeName, this.includeAttribute)) {
11752
+ delete item.attributes[attributeName];
11753
+ if (Object.keys(item.attributes).length === 0) {
11754
+ this.attributes = this.attributes.filter((a2) => a2 !== item);
11755
+ this.attributeMap.delete(m.target);
11756
+ }
11757
+ return;
11758
+ }
11734
11759
  if (attributeName === "style") {
11735
11760
  if (!this.unattachedDoc) {
11736
11761
  try {
@@ -11846,7 +11871,8 @@ class MutationBuffer {
11846
11871
  "blockSelector",
11847
11872
  "maskTextClass",
11848
11873
  "maskTextSelector",
11849
- "ignoreAttribute",
11874
+ "excludeAttribute",
11875
+ "includeAttribute",
11850
11876
  "inlineStylesheet",
11851
11877
  "maskInputOptions",
11852
11878
  "maskTextFn",
@@ -11985,60 +12011,6 @@ function initMutationObserver(options, rootEl) {
11985
12011
  });
11986
12012
  return observer;
11987
12013
  }
11988
- function initVisibilityObserver({
11989
- visibilityChangeCb,
11990
- doc,
11991
- mirror: mirror2,
11992
- sampling
11993
- }) {
11994
- if (!visibilityChangeCb) {
11995
- return () => {
11996
- };
11997
- }
11998
- const observedElements = /* @__PURE__ */ new WeakMap();
11999
- const debounceThreshold = typeof sampling.visibility === "number" ? sampling.visibility : 50;
12000
- const throttledCb = throttle(
12001
- callbackWrapper((entry) => {
12002
- const target = entry.target;
12003
- const id = mirror2.getId(target);
12004
- const isVisible = entry.isIntersecting || entry.intersectionRatio > 0;
12005
- if (id !== -1) {
12006
- visibilityChangeCb({
12007
- id,
12008
- isVisible,
12009
- visibilityRatio: entry.intersectionRatio
12010
- });
12011
- }
12012
- }),
12013
- debounceThreshold,
12014
- { leading: sampling.visibility !== false, trailing: true }
12015
- );
12016
- const observer = new IntersectionObserver((entries) => {
12017
- entries.forEach((entry) => {
12018
- const target = entry.target;
12019
- if (observedElements.has(target)) {
12020
- throttledCb(entry);
12021
- } else {
12022
- observedElements.set(target, true);
12023
- }
12024
- });
12025
- }, { root: null, threshold: [0.1, 0.9] });
12026
- doc.querySelectorAll("*").forEach((el) => observer.observe(el));
12027
- const mutationObserver = new MutationObserver((mutations) => {
12028
- mutations.forEach((mutation) => {
12029
- mutation.addedNodes.forEach((node2) => {
12030
- if (node2 instanceof Element) {
12031
- observer.observe(node2);
12032
- }
12033
- });
12034
- });
12035
- });
12036
- mutationObserver.observe(doc, { childList: true, subtree: true });
12037
- return () => {
12038
- observer.disconnect();
12039
- mutationObserver.disconnect();
12040
- };
12041
- }
12042
12014
  function initMoveObserver({
12043
12015
  mousemoveCb,
12044
12016
  sampling,
@@ -12318,6 +12290,20 @@ function initInputObserver({
12318
12290
  }
12319
12291
  function cbWithDedup(target, v2) {
12320
12292
  const lastInputValue = lastInputValueMap.get(target);
12293
+ const el = target;
12294
+ const hasPlaceholder = el.hasAttribute("placeholder");
12295
+ const isEmpty = el.value === "";
12296
+ const isDefaultEmpty = typeof el.defaultValue === "string" ? el.defaultValue === "" : true;
12297
+ const isNonUser = !v2.userTriggered;
12298
+ const isRepeatEmpty = !lastInputValue || lastInputValue.text === "";
12299
+ const isLikelyPhantom = hasPlaceholder && isEmpty && isDefaultEmpty && isRepeatEmpty && isNonUser && !v2.isChecked && el.type !== "hidden" && INPUT_TAGS.includes(el.tagName);
12300
+ const isRenderDrivenTextInput = el.tagName === "INPUT" && el.type === "text" && !v2.userTriggered && v2.text === el.defaultValue && !lastInputValue && el.hasAttribute("placeholder");
12301
+ const isValueFromDefault = !v2.userTriggered && el.value === el.defaultValue && !lastInputValue && el.hasAttribute("placeholder") && !v2.isChecked && el.type !== "hidden" && INPUT_TAGS.includes(el.tagName);
12302
+ const isPhantomCheckbox = el.type === "checkbox" && !v2.userTriggered && !v2.isChecked && !lastInputValue;
12303
+ const isPhantomRadio = el.type === "radio" && !v2.userTriggered && !v2.isChecked && !lastInputValue;
12304
+ if (isLikelyPhantom || isRenderDrivenTextInput || isValueFromDefault || isPhantomCheckbox || isPhantomRadio) {
12305
+ return;
12306
+ }
12321
12307
  if (!lastInputValue || lastInputValue.text !== v2.text || lastInputValue.isChecked !== v2.isChecked) {
12322
12308
  lastInputValueMap.set(target, v2);
12323
12309
  const id = mirror2.getId(target);
@@ -12855,7 +12841,6 @@ function initCustomElementObserver({
12855
12841
  function mergeHooks(o2, hooks) {
12856
12842
  const {
12857
12843
  mutationCb,
12858
- visibilityChangeCb,
12859
12844
  mousemoveCb,
12860
12845
  mouseInteractionCb,
12861
12846
  scrollCb,
@@ -12875,12 +12860,6 @@ function mergeHooks(o2, hooks) {
12875
12860
  }
12876
12861
  mutationCb(...p);
12877
12862
  };
12878
- o2.visibilityChangeCb = (...p) => {
12879
- if (hooks.visibilityChange) {
12880
- hooks.visibilityChange(...p);
12881
- }
12882
- visibilityChangeCb(...p);
12883
- };
12884
12863
  o2.mousemoveCb = (...p) => {
12885
12864
  if (hooks.mousemove) {
12886
12865
  hooks.mousemove(...p);
@@ -12973,7 +12952,6 @@ function initObservers(o2, hooks = {}) {
12973
12952
  });
12974
12953
  const inputHandler = initInputObserver(o2);
12975
12954
  const mediaInteractionHandler = initMediaInteractionObserver(o2);
12976
- const visibleHandler = initVisibilityObserver(o2);
12977
12955
  let styleSheetObserver = () => {
12978
12956
  };
12979
12957
  let adoptedStyleSheetObserver = () => {
@@ -13003,7 +12981,6 @@ function initObservers(o2, hooks = {}) {
13003
12981
  return callbackWrapper(() => {
13004
12982
  mutationBuffers.forEach((b) => b.reset());
13005
12983
  mutationObserver == null ? void 0 : mutationObserver.disconnect();
13006
- visibleHandler();
13007
12984
  mousemoveHandler();
13008
12985
  mouseInteractionHandler();
13009
12986
  scrollHandler();
@@ -14090,12 +14067,12 @@ function record(options = {}) {
14090
14067
  emit,
14091
14068
  checkoutEveryNms,
14092
14069
  checkoutEveryNth,
14093
- checkoutEveryEvc,
14094
14070
  blockClass = "rr-block",
14095
14071
  blockSelector = null,
14096
14072
  ignoreClass = "rr-ignore",
14097
14073
  ignoreSelector = null,
14098
- ignoreAttribute = "rr-ignore",
14074
+ excludeAttribute: _excludeAttribute,
14075
+ includeAttribute: _includeAttribute,
14099
14076
  maskTextClass = "rr-mask",
14100
14077
  maskTextSelector = null,
14101
14078
  inlineStylesheet = true,
@@ -14144,6 +14121,8 @@ function record(options = {}) {
14144
14121
  sampling.mousemove = mousemoveWait;
14145
14122
  }
14146
14123
  mirror.reset();
14124
+ const excludeAttribute = _excludeAttribute === void 0 ? /^$a/ : _excludeAttribute;
14125
+ const includeAttribute = _includeAttribute === void 0 ? /.+/i : _includeAttribute;
14147
14126
  const maskInputOptions = maskAllInputs === true ? {
14148
14127
  color: true,
14149
14128
  date: true,
@@ -14220,8 +14199,7 @@ function record(options = {}) {
14220
14199
  incrementalSnapshotCount++;
14221
14200
  const exceedCount = checkoutEveryNth && incrementalSnapshotCount >= checkoutEveryNth;
14222
14201
  const exceedTime = checkoutEveryNms && e2.timestamp - lastFullSnapshotEvent.timestamp > checkoutEveryNms;
14223
- const isVisibilityChanged = checkoutEveryEvc && e2.type === EventType.IncrementalSnapshot && e2.data.source === IncrementalSource.VisibilityChange;
14224
- if (exceedCount || exceedTime || isVisibilityChanged) {
14202
+ if (exceedCount || exceedTime) {
14225
14203
  takeFullSnapshot$1(true);
14226
14204
  }
14227
14205
  }
@@ -14294,7 +14272,8 @@ function record(options = {}) {
14294
14272
  blockSelector,
14295
14273
  maskTextClass,
14296
14274
  maskTextSelector,
14297
- ignoreAttribute,
14275
+ excludeAttribute,
14276
+ includeAttribute,
14298
14277
  inlineStylesheet,
14299
14278
  maskInputOptions,
14300
14279
  dataURLOptions,
@@ -14336,7 +14315,8 @@ function record(options = {}) {
14336
14315
  blockSelector,
14337
14316
  maskTextClass,
14338
14317
  maskTextSelector,
14339
- ignoreAttribute,
14318
+ excludeAttribute,
14319
+ includeAttribute,
14340
14320
  inlineStylesheet,
14341
14321
  maskAllInputs: maskInputOptions,
14342
14322
  maskTextFn,
@@ -14392,15 +14372,6 @@ function record(options = {}) {
14392
14372
  return callbackWrapper(initObservers)(
14393
14373
  {
14394
14374
  mutationCb: wrappedMutationEmit,
14395
- visibilityChangeCb: (v2) => {
14396
- wrappedEmit({
14397
- type: EventType.IncrementalSnapshot,
14398
- data: {
14399
- source: IncrementalSource.VisibilityChange,
14400
- ...v2
14401
- }
14402
- });
14403
- },
14404
14375
  mousemoveCb: (positions, source) => wrappedEmit({
14405
14376
  type: EventType.IncrementalSnapshot,
14406
14377
  data: {
@@ -14482,7 +14453,8 @@ function record(options = {}) {
14482
14453
  ignoreSelector,
14483
14454
  maskTextClass,
14484
14455
  maskTextSelector,
14485
- ignoreAttribute,
14456
+ excludeAttribute,
14457
+ includeAttribute,
14486
14458
  maskInputOptions,
14487
14459
  inlineStylesheet,
14488
14460
  sampling,