@appsurify-testmap/rrweb-snapshot 2.0.0-alpha.41 → 2.1.0-alpha.2

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/index.d.cts CHANGED
@@ -62,8 +62,6 @@ export declare type idNodeMap = Map<number, Node>;
62
62
 
63
63
  export declare const IGNORED_NODE = -2;
64
64
 
65
- export declare function inspectInlineEventHandlers(doc: Document): void;
66
-
67
65
  export declare const interactiveEvents: string[];
68
66
 
69
67
  export declare const interactiveTags: string[];
@@ -145,7 +143,7 @@ export declare function needMaskingText(node: Node, maskTextClass: string | RegE
145
143
 
146
144
  export declare type nodeMetaMap = WeakMap<Node, serializedNodeWithId>;
147
145
 
148
- export declare function normalizeCssString(cssText: string): string;
146
+ export declare function normalizeCssString(cssText: string, _testNoPxNorm?: boolean): string;
149
147
 
150
148
  export declare function rebuild(n: serializedNodeWithId, options: {
151
149
  doc: Document;
@@ -156,8 +154,6 @@ export declare function rebuild(n: serializedNodeWithId, options: {
156
154
  mirror: Mirror;
157
155
  }): Node | null;
158
156
 
159
- export declare function scheduleInlineEventInspection(doc: Document): void;
160
-
161
157
  export declare function serializeNodeWithId(n: Node, options: {
162
158
  doc: Document;
163
159
  mirror: Mirror;
@@ -225,7 +221,7 @@ export declare function snapshot(n: Document, options?: {
225
221
  keepIframeSrcFn?: KeepIframeSrcFn;
226
222
  }): serializedNodeWithId | null;
227
223
 
228
- export declare function splitCssText(cssText: string, style: HTMLStyleElement): string[];
224
+ export declare function splitCssText(cssText: string, style: HTMLStyleElement, _testNoPxNorm?: boolean): string[];
229
225
 
230
226
  export declare function stringifyRule(rule: CSSRule, sheetHref: string | null): string;
231
227
 
package/dist/index.d.ts CHANGED
@@ -62,8 +62,6 @@ export declare type idNodeMap = Map<number, Node>;
62
62
 
63
63
  export declare const IGNORED_NODE = -2;
64
64
 
65
- export declare function inspectInlineEventHandlers(doc: Document): void;
66
-
67
65
  export declare const interactiveEvents: string[];
68
66
 
69
67
  export declare const interactiveTags: string[];
@@ -145,7 +143,7 @@ export declare function needMaskingText(node: Node, maskTextClass: string | RegE
145
143
 
146
144
  export declare type nodeMetaMap = WeakMap<Node, serializedNodeWithId>;
147
145
 
148
- export declare function normalizeCssString(cssText: string): string;
146
+ export declare function normalizeCssString(cssText: string, _testNoPxNorm?: boolean): string;
149
147
 
150
148
  export declare function rebuild(n: serializedNodeWithId, options: {
151
149
  doc: Document;
@@ -156,8 +154,6 @@ export declare function rebuild(n: serializedNodeWithId, options: {
156
154
  mirror: Mirror;
157
155
  }): Node | null;
158
156
 
159
- export declare function scheduleInlineEventInspection(doc: Document): void;
160
-
161
157
  export declare function serializeNodeWithId(n: Node, options: {
162
158
  doc: Document;
163
159
  mirror: Mirror;
@@ -225,7 +221,7 @@ export declare function snapshot(n: Document, options?: {
225
221
  keepIframeSrcFn?: KeepIframeSrcFn;
226
222
  }): serializedNodeWithId | null;
227
223
 
228
- export declare function splitCssText(cssText: string, style: HTMLStyleElement): string[];
224
+ export declare function splitCssText(cssText: string, style: HTMLStyleElement, _testNoPxNorm?: boolean): string[];
229
225
 
230
226
  export declare function stringifyRule(rule: CSSRule, sheetHref: string | null): string;
231
227
 
@@ -140,6 +140,32 @@ function querySelectorAll(n, selectors) {
140
140
  function mutationObserverCtor() {
141
141
  return getUntaintedPrototype("MutationObserver").constructor;
142
142
  }
143
+ function patch(source, name, replacement) {
144
+ try {
145
+ if (!(name in source)) {
146
+ return () => {
147
+ };
148
+ }
149
+ const original = source[name];
150
+ const wrapped = replacement(original);
151
+ if (typeof wrapped === "function") {
152
+ wrapped.prototype = wrapped.prototype || {};
153
+ Object.defineProperties(wrapped, {
154
+ __rrweb_original__: {
155
+ enumerable: false,
156
+ value: original
157
+ }
158
+ });
159
+ }
160
+ source[name] = wrapped;
161
+ return () => {
162
+ source[name] = original;
163
+ };
164
+ } catch {
165
+ return () => {
166
+ };
167
+ }
168
+ }
143
169
  const index = {
144
170
  childNodes,
145
171
  parentNode,
@@ -152,8 +178,12 @@ const index = {
152
178
  shadowRoot,
153
179
  querySelector,
154
180
  querySelectorAll,
155
- mutationObserver: mutationObserverCtor
181
+ mutationObserver: mutationObserverCtor,
182
+ patch
156
183
  };
184
+ function isElement(n) {
185
+ return n.nodeType === n.ELEMENT_NODE;
186
+ }
157
187
  function isShadowRoot(n) {
158
188
  const hostEl = (
159
189
  // anchor and textarea elements also have a `host` property
@@ -430,19 +460,27 @@ function absolutifyURLs(cssText, href) {
430
460
  }
431
461
  );
432
462
  }
433
- function normalizeCssString(cssText) {
434
- return cssText.replace(/(\/\*[^*]*\*\/)|[\s;]/g, "");
463
+ function normalizeCssString(cssText, _testNoPxNorm = false) {
464
+ if (_testNoPxNorm) {
465
+ return cssText.replace(/(\/\*[^*]*\*\/)|[\s;]/g, "");
466
+ } else {
467
+ return cssText.replace(/(\/\*[^*]*\*\/)|[\s;]/g, "").replace(/0px/g, "0");
468
+ }
435
469
  }
436
- function splitCssText(cssText, style) {
470
+ function splitCssText(cssText, style, _testNoPxNorm = false) {
437
471
  const childNodes2 = Array.from(style.childNodes);
438
472
  const splits = [];
439
- let iterLimit = 0;
473
+ let iterCount = 0;
440
474
  if (childNodes2.length > 1 && cssText && typeof cssText === "string") {
441
- let cssTextNorm = normalizeCssString(cssText);
475
+ let cssTextNorm = normalizeCssString(cssText, _testNoPxNorm);
442
476
  const normFactor = cssTextNorm.length / cssText.length;
443
477
  for (let i = 1; i < childNodes2.length; i++) {
444
478
  if (childNodes2[i].textContent && typeof childNodes2[i].textContent === "string") {
445
- const textContentNorm = normalizeCssString(childNodes2[i].textContent);
479
+ const textContentNorm = normalizeCssString(
480
+ childNodes2[i].textContent,
481
+ _testNoPxNorm
482
+ );
483
+ const jLimit = 100;
446
484
  let j = 3;
447
485
  for (; j < textContentNorm.length; j++) {
448
486
  if (
@@ -455,23 +493,49 @@ function splitCssText(cssText, style) {
455
493
  break;
456
494
  }
457
495
  for (; j < textContentNorm.length; j++) {
458
- const bit = textContentNorm.substring(0, j);
459
- const bits = cssTextNorm.split(bit);
496
+ let startSubstring = textContentNorm.substring(0, j);
497
+ let cssNormSplits = cssTextNorm.split(startSubstring);
460
498
  let splitNorm = -1;
461
- if (bits.length === 2) {
462
- splitNorm = cssTextNorm.indexOf(bit);
463
- } else if (bits.length > 2 && bits[0] === "" && childNodes2[i - 1].textContent !== "") {
464
- splitNorm = cssTextNorm.indexOf(bit, 1);
499
+ if (cssNormSplits.length === 2) {
500
+ splitNorm = cssNormSplits[0].length;
501
+ } else if (cssNormSplits.length > 2 && cssNormSplits[0] === "" && childNodes2[i - 1].textContent !== "") {
502
+ splitNorm = cssTextNorm.indexOf(startSubstring, 1);
503
+ } else if (cssNormSplits.length === 1) {
504
+ startSubstring = startSubstring.substring(
505
+ 0,
506
+ startSubstring.length - 1
507
+ );
508
+ cssNormSplits = cssTextNorm.split(startSubstring);
509
+ if (cssNormSplits.length <= 1) {
510
+ splits.push(cssText);
511
+ return splits;
512
+ }
513
+ j = jLimit + 1;
514
+ } else if (j === textContentNorm.length - 1) {
515
+ splitNorm = cssTextNorm.indexOf(startSubstring);
516
+ }
517
+ if (cssNormSplits.length >= 2 && j > jLimit) {
518
+ const prevTextContent = childNodes2[i - 1].textContent;
519
+ if (prevTextContent && typeof prevTextContent === "string") {
520
+ const prevMinLength = normalizeCssString(prevTextContent).length;
521
+ splitNorm = cssTextNorm.indexOf(startSubstring, prevMinLength);
522
+ }
523
+ if (splitNorm === -1) {
524
+ splitNorm = cssNormSplits[0].length;
525
+ }
465
526
  }
466
527
  if (splitNorm !== -1) {
467
528
  let k = Math.floor(splitNorm / normFactor);
468
529
  for (; k > 0 && k < cssText.length; ) {
469
- iterLimit += 1;
470
- if (iterLimit > 50 * childNodes2.length) {
530
+ iterCount += 1;
531
+ if (iterCount > 50 * childNodes2.length) {
471
532
  splits.push(cssText);
472
533
  return splits;
473
534
  }
474
- const normPart = normalizeCssString(cssText.substring(0, k));
535
+ const normPart = normalizeCssString(
536
+ cssText.substring(0, k),
537
+ _testNoPxNorm
538
+ );
475
539
  if (normPart.length === splitNorm) {
476
540
  splits.push(cssText.substring(0, k));
477
541
  cssText = cssText.substring(k);
@@ -567,9 +631,6 @@ function getXPath(node2) {
567
631
  }
568
632
  return "";
569
633
  }
570
- function isElement(n) {
571
- return n.nodeType === n.ELEMENT_NODE;
572
- }
573
634
  function isTextVisible(n) {
574
635
  var _a;
575
636
  const parent = index.parentNode(n);
@@ -590,10 +651,10 @@ function isElementVisible(n) {
590
651
  const style = win ? win.getComputedStyle(n) : null;
591
652
  const isStyleVisible = style != null && style.display !== "none" && style.visibility !== "hidden" && parseFloat(style.opacity) !== 0;
592
653
  const rect = n.getBoundingClientRect();
593
- const result2 = isStyleVisible && isRectVisible(rect, win);
654
+ const result2 = isStyleVisible && isRectVisible(rect);
594
655
  return result2;
595
656
  }
596
- function isRectVisible(rect, win) {
657
+ function isRectVisible(rect, win = window) {
597
658
  var _a, _b, _c, _d;
598
659
  const height = (win == null ? void 0 : win.innerHeight) ?? ((_b = (_a = win == null ? void 0 : win.document) == null ? void 0 : _a.documentElement) == null ? void 0 : _b.clientHeight) ?? 0;
599
660
  const width = (win == null ? void 0 : win.innerWidth) ?? ((_d = (_c = win == null ? void 0 : win.document) == null ? void 0 : _c.documentElement) == null ? void 0 : _d.clientWidth) ?? 0;
@@ -662,28 +723,20 @@ const inlineEventAttributes = [
662
723
  "ontouchcancel"
663
724
  ];
664
725
  const interactiveElementsRegistry = /* @__PURE__ */ new WeakSet();
665
- if (typeof Element !== "undefined" && typeof EventTarget !== "undefined") {
666
- const originalAddEventListener = EventTarget.prototype.addEventListener;
667
- EventTarget.prototype.addEventListener = function(type, listener, options) {
668
- originalAddEventListener.call(this, type, listener, options);
669
- if (this instanceof Element) {
670
- const eventType = type.toLowerCase();
671
- if (interactiveEvents.includes(eventType)) {
672
- interactiveElementsRegistry.add(this);
673
- }
726
+ const originalAddEventListener = EventTarget.prototype.addEventListener;
727
+ EventTarget.prototype.addEventListener = function(type, listener, options) {
728
+ originalAddEventListener.call(this, type, listener, options);
729
+ if (this instanceof Element) {
730
+ const eventType = type.toLowerCase();
731
+ if (interactiveEvents.includes(eventType)) {
732
+ interactiveElementsRegistry.add(this);
674
733
  }
675
- };
676
- }
677
- if (typeof Element !== "undefined" && typeof EventTarget !== "undefined") {
678
- const originalRemoveEventListener = EventTarget.prototype.removeEventListener;
679
- EventTarget.prototype.removeEventListener = function(type, listener, options) {
680
- originalRemoveEventListener.call(this, type, listener, options);
681
- if (this instanceof Element) {
682
- const eventType = type.toLowerCase();
683
- if (interactiveEvents.includes(eventType)) ;
684
- }
685
- };
686
- }
734
+ }
735
+ };
736
+ const originalRemoveEventListener = EventTarget.prototype.removeEventListener;
737
+ EventTarget.prototype.removeEventListener = function(type, listener, options) {
738
+ originalRemoveEventListener.call(this, type, listener, options);
739
+ };
687
740
  function hasEventListeners(n) {
688
741
  return n instanceof Element && interactiveElementsRegistry.has(n);
689
742
  }
@@ -703,9 +756,8 @@ function isElementInteractive(n) {
703
756
  }
704
757
  return false;
705
758
  }
706
- function inspectInlineEventHandlers(doc) {
707
- if (!doc || typeof doc.querySelectorAll !== "function") return;
708
- const allElements = doc.querySelectorAll("*");
759
+ function inspectInlineEventHandlers() {
760
+ const allElements = document.querySelectorAll("*");
709
761
  allElements.forEach((el) => {
710
762
  inlineEventAttributes.forEach((attr) => {
711
763
  if (el.hasAttribute(attr)) {
@@ -714,22 +766,10 @@ function inspectInlineEventHandlers(doc) {
714
766
  });
715
767
  });
716
768
  }
717
- function scheduleInlineEventInspection(doc) {
718
- if (!doc || typeof doc.addEventListener !== "function" || typeof doc.querySelectorAll !== "function") {
719
- return;
720
- }
721
- try {
722
- if (doc.readyState === "complete" || doc.readyState === "interactive") {
723
- inspectInlineEventHandlers(doc);
724
- } else {
725
- doc.addEventListener("DOMContentLoaded", () => inspectInlineEventHandlers(doc), {
726
- once: true,
727
- capture: false
728
- });
729
- }
730
- } catch (e) {
731
- console.warn("[inlineEventInspection] Failed to inspect document:", e);
732
- }
769
+ if (document.readyState === "complete" || document.readyState === "interactive") {
770
+ inspectInlineEventHandlers();
771
+ } else {
772
+ document.addEventListener("DOMContentLoaded", inspectInlineEventHandlers);
733
773
  }
734
774
  let _id = 1;
735
775
  const tagNameRegex = new RegExp("[^a-z0-9-_:]");
@@ -1023,6 +1063,7 @@ function serializeNode(n, options) {
1023
1063
  childNodes: [],
1024
1064
  xPath,
1025
1065
  compatMode: n.compatMode
1066
+ // probably "BackCompat"
1026
1067
  };
1027
1068
  } else {
1028
1069
  return {
@@ -1317,7 +1358,7 @@ function slimDOMExcluded(sn, slimDOMOptions) {
1317
1358
  } else if (sn.type === NodeType.Element) {
1318
1359
  if (slimDOMOptions.script && // script tag
1319
1360
  (sn.tagName === "script" || // (module)preload link
1320
- sn.tagName === "link" && (sn.attributes.rel === "preload" || sn.attributes.rel === "modulepreload") && sn.attributes.as === "script" || // prefetch link
1361
+ sn.tagName === "link" && (sn.attributes.rel === "preload" && sn.attributes.as === "script" || sn.attributes.rel === "modulepreload") || // prefetch link
1321
1362
  sn.tagName === "link" && sn.attributes.rel === "prefetch" && typeof sn.attributes.href === "string" && extractFileExtension(sn.attributes.href) === "js")) {
1322
1363
  return true;
1323
1364
  } else if (slimDOMOptions.headFavicon && (sn.tagName === "link" && sn.attributes.rel === "shortcut icon" || sn.tagName === "meta" && (lowerIfExists(sn.attributes.name).match(
@@ -1579,7 +1620,7 @@ function snapshot(n, options) {
1579
1620
  blockSelector = null,
1580
1621
  maskTextClass = "rr-mask",
1581
1622
  maskTextSelector = null,
1582
- ignoreAttribute = "rr-ignore-attr",
1623
+ ignoreAttribute = "rr-ignore",
1583
1624
  inlineStylesheet = true,
1584
1625
  inlineImages = false,
1585
1626
  recordCanvas = false,
@@ -1596,7 +1637,6 @@ function snapshot(n, options) {
1596
1637
  stylesheetLoadTimeout,
1597
1638
  keepIframeSrcFn = () => false
1598
1639
  } = options || {};
1599
- scheduleInlineEventInspection(n);
1600
1640
  const maskInputOptions = maskAllInputs === true ? {
1601
1641
  color: true,
1602
1642
  date: true,
@@ -5305,11 +5345,16 @@ function getTagName(n) {
5305
5345
  function adaptCssForReplay(cssText, cache) {
5306
5346
  const cachedStyle = cache == null ? void 0 : cache.stylesWithHoverClass.get(cssText);
5307
5347
  if (cachedStyle) return cachedStyle;
5308
- const ast = postcss$1([
5309
- mediaSelectorPlugin,
5310
- pseudoClassPlugin
5311
- ]).process(cssText);
5312
- const result2 = ast.css;
5348
+ let result2 = cssText;
5349
+ try {
5350
+ const ast = postcss$1([
5351
+ mediaSelectorPlugin,
5352
+ pseudoClassPlugin
5353
+ ]).process(cssText);
5354
+ result2 = ast.css;
5355
+ } catch (error) {
5356
+ console.warn("Failed to adapt css for replay", error);
5357
+ }
5313
5358
  cache == null ? void 0 : cache.stylesWithHoverClass.set(cssText, result2);
5314
5359
  return result2;
5315
5360
  }
@@ -5330,11 +5375,39 @@ function applyCssSplits(n, cssText, hackCss, cache) {
5330
5375
  while (cssTextSplits.length > 1 && cssTextSplits.length > childTextNodes.length) {
5331
5376
  cssTextSplits.splice(-2, 2, cssTextSplits.slice(-2).join(""));
5332
5377
  }
5378
+ let adaptedCss = "";
5379
+ if (hackCss) {
5380
+ adaptedCss = adaptCssForReplay(cssTextSplits.join(""), cache);
5381
+ }
5382
+ let startIndex = 0;
5333
5383
  for (let i = 0; i < childTextNodes.length; i++) {
5384
+ if (i === cssTextSplits.length) {
5385
+ break;
5386
+ }
5334
5387
  const childTextNode = childTextNodes[i];
5335
- const cssTextSection = cssTextSplits[i];
5336
- if (childTextNode && cssTextSection) {
5337
- childTextNode.textContent = hackCss ? adaptCssForReplay(cssTextSection, cache) : cssTextSection;
5388
+ if (!hackCss) {
5389
+ childTextNode.textContent = cssTextSplits[i];
5390
+ } else if (i < cssTextSplits.length - 1) {
5391
+ let endIndex = startIndex;
5392
+ let endSearch = cssTextSplits[i + 1].length;
5393
+ endSearch = Math.min(endSearch, 30);
5394
+ let found = false;
5395
+ for (; endSearch > 2; endSearch--) {
5396
+ const searchBit = cssTextSplits[i + 1].substring(0, endSearch);
5397
+ const searchIndex = adaptedCss.substring(startIndex).indexOf(searchBit);
5398
+ found = searchIndex !== -1;
5399
+ if (found) {
5400
+ endIndex += searchIndex;
5401
+ break;
5402
+ }
5403
+ }
5404
+ if (!found) {
5405
+ endIndex += cssTextSplits[i].length;
5406
+ }
5407
+ childTextNode.textContent = adaptedCss.substring(startIndex, endIndex);
5408
+ startIndex = endIndex;
5409
+ } else {
5410
+ childTextNode.textContent = adaptedCss.substring(startIndex);
5338
5411
  }
5339
5412
  }
5340
5413
  }
@@ -5418,8 +5491,8 @@ function buildNode(n, options) {
5418
5491
  } else if (tagName === "meta" && n.attributes["http-equiv"] === "Content-Security-Policy" && name === "content") {
5419
5492
  node2.setAttribute("csp-content", value.toString());
5420
5493
  continue;
5421
- } else if (tagName === "link" && (n.attributes.rel === "preload" || n.attributes.rel === "modulepreload") && n.attributes.as === "script") {
5422
- } else if (tagName === "link" && n.attributes.rel === "prefetch" && typeof n.attributes.href === "string" && n.attributes.href.endsWith(".js")) {
5494
+ } else if (tagName === "link" && (n.attributes.rel === "preload" && n.attributes.as === "script" || n.attributes.rel === "modulepreload")) {
5495
+ } else if (tagName === "link" && n.attributes.rel === "prefetch" && typeof n.attributes.href === "string" && extractFileExtension(n.attributes.href) === "js") {
5423
5496
  } else if (tagName === "img" && n.attributes.srcset && n.attributes.rr_dataURL) {
5424
5497
  node2.setAttribute(
5425
5498
  "rrweb-original-srcset",
@@ -5654,7 +5727,6 @@ exports.fixSafariColons = fixSafariColons;
5654
5727
  exports.genId = genId;
5655
5728
  exports.getInputType = getInputType;
5656
5729
  exports.getXPath = getXPath;
5657
- exports.inspectInlineEventHandlers = inspectInlineEventHandlers;
5658
5730
  exports.interactiveEvents = interactiveEvents;
5659
5731
  exports.interactiveTags = interactiveTags;
5660
5732
  exports.is2DCanvasBlank = is2DCanvasBlank;
@@ -5673,7 +5745,6 @@ exports.maskInputValue = maskInputValue;
5673
5745
  exports.needMaskingText = needMaskingText;
5674
5746
  exports.normalizeCssString = normalizeCssString;
5675
5747
  exports.rebuild = rebuild;
5676
- exports.scheduleInlineEventInspection = scheduleInlineEventInspection;
5677
5748
  exports.serializeNodeWithId = serializeNodeWithId;
5678
5749
  exports.snapshot = snapshot;
5679
5750
  exports.splitCssText = splitCssText;