@sentry/replay 7.66.0-alpha.0 → 7.66.0

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/esm/index.js CHANGED
@@ -61,135 +61,44 @@ var NodeType$1;
61
61
  NodeType[NodeType["Comment"] = 5] = "Comment";
62
62
  })(NodeType$1 || (NodeType$1 = {}));
63
63
 
64
- function isElement$1(n) {
64
+ function isElement(n) {
65
65
  return n.nodeType === n.ELEMENT_NODE;
66
66
  }
67
67
  function isShadowRoot(n) {
68
68
  const host = n === null || n === void 0 ? void 0 : n.host;
69
- return Boolean((host === null || host === void 0 ? void 0 : host.shadowRoot) === n);
69
+ return Boolean(host && host.shadowRoot && host.shadowRoot === n);
70
70
  }
71
- function isNativeShadowDom(shadowRoot) {
72
- return Object.prototype.toString.call(shadowRoot) === '[object ShadowRoot]';
73
- }
74
- function fixBrowserCompatibilityIssuesInCSS(cssText) {
75
- if (cssText.includes(' background-clip: text;') &&
76
- !cssText.includes(' -webkit-background-clip: text;')) {
77
- cssText = cssText.replace(' background-clip: text;', ' -webkit-background-clip: text; background-clip: text;');
78
- }
79
- return cssText;
80
- }
81
- function getCssRulesString(s) {
82
- try {
83
- const rules = s.rules || s.cssRules;
84
- return rules
85
- ? fixBrowserCompatibilityIssuesInCSS(Array.from(rules).map(getCssRuleString).join(''))
86
- : null;
87
- }
88
- catch (error) {
89
- return null;
90
- }
91
- }
92
- function getCssRuleString(rule) {
93
- let cssStringified = rule.cssText;
94
- if (isCSSImportRule(rule)) {
95
- try {
96
- cssStringified = getCssRulesString(rule.styleSheet) || cssStringified;
97
- }
98
- catch (_a) {
99
- }
100
- }
101
- return validateStringifiedCssRule(cssStringified);
102
- }
103
- function validateStringifiedCssRule(cssStringified) {
104
- if (cssStringified.includes(':')) {
105
- const regex = /(\[(?:[\w-]+)[^\\])(:(?:[\w-]+)\])/gm;
106
- return cssStringified.replace(regex, '$1\\$2');
71
+ function isInputTypeMasked({ maskInputOptions, tagName, type, }) {
72
+ if (tagName.toLowerCase() === 'option') {
73
+ tagName = 'select';
107
74
  }
108
- return cssStringified;
75
+ const actualType = typeof type === 'string' ? type.toLowerCase() : undefined;
76
+ return (maskInputOptions[tagName.toLowerCase()] ||
77
+ (actualType && maskInputOptions[actualType]) ||
78
+ actualType === 'password' ||
79
+ (tagName === 'input' && !type && maskInputOptions['text']));
109
80
  }
110
- function isCSSImportRule(rule) {
111
- return 'styleSheet' in rule;
81
+ function hasInputMaskOptions({ tagName, type, maskInputOptions, maskInputSelector, }) {
82
+ return (maskInputSelector || isInputTypeMasked({ maskInputOptions, tagName, type }));
112
83
  }
113
- class Mirror {
114
- constructor() {
115
- this.idNodeMap = new Map();
116
- this.nodeMetaMap = new WeakMap();
117
- }
118
- getId(n) {
119
- var _a;
120
- if (!n)
121
- return -1;
122
- const id = (_a = this.getMeta(n)) === null || _a === void 0 ? void 0 : _a.id;
123
- return id !== null && id !== void 0 ? id : -1;
124
- }
125
- getNode(id) {
126
- return this.idNodeMap.get(id) || null;
127
- }
128
- getIds() {
129
- return Array.from(this.idNodeMap.keys());
84
+ function maskInputValue({ input, maskInputSelector, unmaskInputSelector, maskInputOptions, tagName, type, value, maskInputFn, }) {
85
+ let text = value || '';
86
+ if (unmaskInputSelector && input.matches(unmaskInputSelector)) {
87
+ return text;
130
88
  }
131
- getMeta(n) {
132
- return this.nodeMetaMap.get(n) || null;
89
+ if (input.hasAttribute('data-rr-is-password')) {
90
+ type = 'password';
133
91
  }
134
- removeNodeFromMap(n) {
135
- const id = this.getId(n);
136
- this.idNodeMap.delete(id);
137
- if (n.childNodes) {
138
- n.childNodes.forEach((childNode) => this.removeNodeFromMap(childNode));
92
+ if (isInputTypeMasked({ maskInputOptions, tagName, type }) ||
93
+ (maskInputSelector && input.matches(maskInputSelector))) {
94
+ if (maskInputFn) {
95
+ text = maskInputFn(text);
139
96
  }
140
- }
141
- has(id) {
142
- return this.idNodeMap.has(id);
143
- }
144
- hasNode(node) {
145
- return this.nodeMetaMap.has(node);
146
- }
147
- add(n, meta) {
148
- const id = meta.id;
149
- this.idNodeMap.set(id, n);
150
- this.nodeMetaMap.set(n, meta);
151
- }
152
- replace(id, n) {
153
- const oldNode = this.getNode(id);
154
- if (oldNode) {
155
- const meta = this.nodeMetaMap.get(oldNode);
156
- if (meta)
157
- this.nodeMetaMap.set(n, meta);
97
+ else {
98
+ text = '*'.repeat(text.length);
158
99
  }
159
- this.idNodeMap.set(id, n);
160
- }
161
- reset() {
162
- this.idNodeMap = new Map();
163
- this.nodeMetaMap = new WeakMap();
164
- }
165
- }
166
- function createMirror() {
167
- return new Mirror();
168
- }
169
- function shouldMaskInput({ maskInputOptions, tagName, type, }) {
170
- if (tagName === 'OPTION') {
171
- tagName = 'SELECT';
172
- }
173
- return Boolean(maskInputOptions[tagName.toLowerCase()] ||
174
- (type && maskInputOptions[type]) ||
175
- type === 'password' ||
176
- (tagName === 'INPUT' && !type && maskInputOptions['text']));
177
- }
178
- function maskInputValue({ isMasked, element, value, maskInputFn, }) {
179
- let text = value || '';
180
- if (!isMasked) {
181
- return text;
182
- }
183
- if (maskInputFn) {
184
- text = maskInputFn(text, element);
185
100
  }
186
- return '*'.repeat(text.length);
187
- }
188
- function toLowerCase(str) {
189
- return str.toLowerCase();
190
- }
191
- function toUpperCase(str) {
192
- return str.toUpperCase();
101
+ return text;
193
102
  }
194
103
  const ORIGINAL_ATTRIBUTE_NAME = '__rrweb_original__';
195
104
  function is2DCanvasBlank(canvas) {
@@ -215,11 +124,11 @@ function getInputType(element) {
215
124
  return element.hasAttribute('data-rr-is-password')
216
125
  ? 'password'
217
126
  : type
218
- ?
219
- toLowerCase(type)
127
+ ? type.toLowerCase()
220
128
  : null;
221
129
  }
222
130
  function getInputValue(el, tagName, type) {
131
+ typeof type === 'string' ? type.toLowerCase() : '';
223
132
  if (tagName === 'INPUT' && (type === 'radio' || type === 'checkbox')) {
224
133
  return el.getAttribute('value') || '';
225
134
  }
@@ -229,6 +138,9 @@ function getInputValue(el, tagName, type) {
229
138
  let _id = 1;
230
139
  const tagNameRegex = new RegExp('[^a-z0-9-_:]');
231
140
  const IGNORED_NODE = -2;
141
+ function defaultMaskFn(str) {
142
+ return str ? str.replace(/[\S]/g, '*') : '';
143
+ }
232
144
  function genId() {
233
145
  return _id++;
234
146
  }
@@ -236,12 +148,42 @@ function getValidTagName(element) {
236
148
  if (element instanceof HTMLFormElement) {
237
149
  return 'form';
238
150
  }
239
- const processedTagName = toLowerCase(element.tagName);
151
+ const processedTagName = element.tagName.toLowerCase().trim();
240
152
  if (tagNameRegex.test(processedTagName)) {
241
153
  return 'div';
242
154
  }
243
155
  return processedTagName;
244
156
  }
157
+ function getCssRulesString(s) {
158
+ try {
159
+ const rules = s.rules || s.cssRules;
160
+ return rules ? Array.from(rules).map(getCssRuleString).join('') : null;
161
+ }
162
+ catch (error) {
163
+ return null;
164
+ }
165
+ }
166
+ function getCssRuleString(rule) {
167
+ let cssStringified = rule.cssText;
168
+ if (isCSSImportRule(rule)) {
169
+ try {
170
+ cssStringified = getCssRulesString(rule.styleSheet) || cssStringified;
171
+ }
172
+ catch (_a) {
173
+ }
174
+ }
175
+ return validateStringifiedCssRule(cssStringified);
176
+ }
177
+ function validateStringifiedCssRule(cssStringified) {
178
+ if (cssStringified.indexOf(':') > -1) {
179
+ const regex = /(\[(?:[\w-]+)[^\\])(:(?:[\w-]+)\])/gm;
180
+ return cssStringified.replace(regex, '$1\\$2');
181
+ }
182
+ return cssStringified;
183
+ }
184
+ function isCSSImportRule(rule) {
185
+ return 'styleSheet' in rule;
186
+ }
245
187
  function stringifyStyleSheet(sheet) {
246
188
  return sheet.cssRules
247
189
  ? Array.from(sheet.cssRules)
@@ -263,8 +205,7 @@ function extractOrigin(url) {
263
205
  let canvasService;
264
206
  let canvasCtx;
265
207
  const URL_IN_CSS_REF = /url\((?:(')([^']*)'|(")(.*?)"|([^)]*))\)/gm;
266
- const URL_PROTOCOL_MATCH = /^(?:[a-z+]+:)?\/\//i;
267
- const URL_WWW_MATCH = /^www\..*/i;
208
+ const RELATIVE_PATH = /^(?!www\.|(?:http|ftp)s?:\/\/|[A-Za-z]:\\|\/\/|#).*/;
268
209
  const DATA_URI = /^(data:)([^,]*),(.*)/i;
269
210
  function absoluteToStylesheet(cssText, href) {
270
211
  return (cssText || '').replace(URL_IN_CSS_REF, (origin, quote1, path1, quote2, path2, path3) => {
@@ -273,7 +214,7 @@ function absoluteToStylesheet(cssText, href) {
273
214
  if (!filePath) {
274
215
  return origin;
275
216
  }
276
- if (URL_PROTOCOL_MATCH.test(filePath) || URL_WWW_MATCH.test(filePath)) {
217
+ if (!RELATIVE_PATH.test(filePath)) {
277
218
  return `url(${maybeQuote}${filePath}${maybeQuote})`;
278
219
  }
279
220
  if (DATA_URI.test(filePath)) {
@@ -308,7 +249,7 @@ function getAbsoluteSrcsetString(doc, attributeValue) {
308
249
  let pos = 0;
309
250
  function collectCharacters(regEx) {
310
251
  let chars;
311
- const match = regEx.exec(attributeValue.substring(pos));
252
+ let match = regEx.exec(attributeValue.substring(pos));
312
253
  if (match) {
313
254
  chars = match[0];
314
255
  pos += chars.length;
@@ -316,7 +257,7 @@ function getAbsoluteSrcsetString(doc, attributeValue) {
316
257
  }
317
258
  return '';
318
259
  }
319
- const output = [];
260
+ let output = [];
320
261
  while (true) {
321
262
  collectCharacters(SRCSET_COMMAS_OR_SPACES);
322
263
  if (pos >= attributeValue.length) {
@@ -332,7 +273,7 @@ function getAbsoluteSrcsetString(doc, attributeValue) {
332
273
  url = absoluteToDoc(doc, url);
333
274
  let inParens = false;
334
275
  while (true) {
335
- const c = attributeValue.charAt(pos);
276
+ let c = attributeValue.charAt(pos);
336
277
  if (c === '') {
337
278
  output.push((url + descriptorsStr).trim());
338
279
  break;
@@ -375,12 +316,13 @@ function getHref() {
375
316
  a.href = '';
376
317
  return a.href;
377
318
  }
378
- function transformAttribute(doc, tagName, name, value, element, maskAttributeFn) {
319
+ function transformAttribute(doc, element, _tagName, _name, value, maskAllText, unmaskTextSelector, maskTextFn) {
379
320
  if (!value) {
380
321
  return value;
381
322
  }
382
- if (name === 'src' ||
383
- (name === 'href' && !(tagName === 'use' && value[0] === '#'))) {
323
+ const name = _name.toLowerCase();
324
+ const tagName = _tagName.toLowerCase();
325
+ if (name === 'src' || name === 'href') {
384
326
  return absoluteToDoc(doc, value);
385
327
  }
386
328
  else if (name === 'xlink:href' && value[0] !== '#') {
@@ -399,113 +341,79 @@ function transformAttribute(doc, tagName, name, value, element, maskAttributeFn)
399
341
  else if (tagName === 'object' && name === 'data') {
400
342
  return absoluteToDoc(doc, value);
401
343
  }
402
- if (typeof maskAttributeFn === 'function') {
403
- return maskAttributeFn(name, value, element);
344
+ else if (maskAllText &&
345
+ _shouldMaskAttribute(element, name, tagName, unmaskTextSelector)) {
346
+ return maskTextFn ? maskTextFn(value) : defaultMaskFn(value);
404
347
  }
405
348
  return value;
406
349
  }
407
- function ignoreAttribute(tagName, name, _value) {
408
- return (tagName === 'video' || tagName === 'audio') && name === 'autoplay';
350
+ function _shouldMaskAttribute(element, attribute, tagName, unmaskTextSelector) {
351
+ if (unmaskTextSelector && element.matches(unmaskTextSelector)) {
352
+ return false;
353
+ }
354
+ return (['placeholder', 'title', 'aria-label'].indexOf(attribute) > -1 ||
355
+ (tagName === 'input' &&
356
+ attribute === 'value' &&
357
+ element.hasAttribute('type') &&
358
+ ['submit', 'button'].indexOf(element.getAttribute('type').toLowerCase()) > -1));
409
359
  }
410
360
  function _isBlockedElement(element, blockClass, blockSelector, unblockSelector) {
411
- try {
412
- if (unblockSelector && element.matches(unblockSelector)) {
413
- return false;
361
+ if (unblockSelector && element.matches(unblockSelector)) {
362
+ return false;
363
+ }
364
+ if (typeof blockClass === 'string') {
365
+ if (element.classList.contains(blockClass)) {
366
+ return true;
414
367
  }
415
- if (typeof blockClass === 'string') {
416
- if (element.classList.contains(blockClass)) {
368
+ }
369
+ else {
370
+ for (let eIndex = 0; eIndex < element.classList.length; eIndex++) {
371
+ const className = element.classList[eIndex];
372
+ if (blockClass.test(className)) {
417
373
  return true;
418
374
  }
419
375
  }
420
- else {
421
- for (let eIndex = element.classList.length; eIndex--;) {
422
- const className = element.classList[eIndex];
423
- if (blockClass.test(className)) {
424
- return true;
425
- }
426
- }
427
- }
428
- if (blockSelector) {
429
- return element.matches(blockSelector);
430
- }
431
376
  }
432
- catch (e) {
377
+ if (blockSelector) {
378
+ return element.matches(blockSelector);
433
379
  }
434
380
  return false;
435
381
  }
436
- function elementClassMatchesRegex(el, regex) {
437
- for (let eIndex = el.classList.length; eIndex--;) {
438
- const className = el.classList[eIndex];
439
- if (regex.test(className)) {
440
- return true;
441
- }
382
+ function needMaskingText(node, maskTextClass, maskTextSelector, unmaskTextSelector, maskAllText) {
383
+ if (!node) {
384
+ return false;
442
385
  }
443
- return false;
444
- }
445
- function distanceToMatch(node, matchPredicate, limit = Infinity, distance = 0) {
446
- if (!node)
447
- return -1;
448
- if (node.nodeType !== node.ELEMENT_NODE)
449
- return -1;
450
- if (distance > limit)
451
- return -1;
452
- if (matchPredicate(node))
453
- return distance;
454
- return distanceToMatch(node.parentNode, matchPredicate, limit, distance + 1);
455
- }
456
- function createMatchPredicate(className, selector) {
457
- return (node) => {
458
- const el = node;
459
- if (el === null)
386
+ if (node.nodeType !== node.ELEMENT_NODE) {
387
+ return needMaskingText(node.parentNode, maskTextClass, maskTextSelector, unmaskTextSelector, maskAllText);
388
+ }
389
+ if (unmaskTextSelector) {
390
+ if (node.matches(unmaskTextSelector) ||
391
+ node.closest(unmaskTextSelector)) {
460
392
  return false;
461
- if (className) {
462
- if (typeof className === 'string') {
463
- if (el.matches(`.${className}`))
464
- return true;
465
- }
466
- else if (elementClassMatchesRegex(el, className)) {
467
- return true;
468
- }
469
393
  }
470
- if (selector && el.matches(selector))
394
+ }
395
+ if (maskAllText) {
396
+ return true;
397
+ }
398
+ if (typeof maskTextClass === 'string') {
399
+ if (node.classList.contains(maskTextClass)) {
471
400
  return true;
472
- return false;
473
- };
474
- }
475
- function needMaskingText(node, maskTextClass, maskTextSelector, unmaskTextClass, unmaskTextSelector, maskAllText) {
476
- try {
477
- const el = node.nodeType === node.ELEMENT_NODE
478
- ? node
479
- : node.parentElement;
480
- if (el === null)
481
- return false;
482
- let maskDistance = -1;
483
- let unmaskDistance = -1;
484
- if (maskAllText) {
485
- unmaskDistance = distanceToMatch(el, createMatchPredicate(unmaskTextClass, unmaskTextSelector));
486
- if (unmaskDistance < 0) {
487
- return true;
488
- }
489
- maskDistance = distanceToMatch(el, createMatchPredicate(maskTextClass, maskTextSelector), unmaskDistance >= 0 ? unmaskDistance : Infinity);
490
401
  }
491
- else {
492
- maskDistance = distanceToMatch(el, createMatchPredicate(maskTextClass, maskTextSelector));
493
- if (maskDistance < 0) {
494
- return false;
402
+ }
403
+ else {
404
+ for (let eIndex = 0; eIndex < node.classList.length; eIndex++) {
405
+ const className = node.classList[eIndex];
406
+ if (maskTextClass.test(className)) {
407
+ return true;
495
408
  }
496
- unmaskDistance = distanceToMatch(el, createMatchPredicate(unmaskTextClass, unmaskTextSelector), maskDistance >= 0 ? maskDistance : Infinity);
497
409
  }
498
- return maskDistance >= 0
499
- ? unmaskDistance >= 0
500
- ? maskDistance <= unmaskDistance
501
- : true
502
- : unmaskDistance >= 0
503
- ? false
504
- : !!maskAllText;
505
410
  }
506
- catch (e) {
411
+ if (maskTextSelector) {
412
+ if (node.matches(maskTextSelector)) {
413
+ return true;
414
+ }
507
415
  }
508
- return !!maskAllText;
416
+ return needMaskingText(node.parentNode, maskTextClass, maskTextSelector, unmaskTextSelector, maskAllText);
509
417
  }
510
418
  function onceIframeLoaded(iframeEl, listener, iframeLoadTimeout) {
511
419
  const win = iframeEl.contentWindow;
@@ -539,36 +447,18 @@ function onceIframeLoaded(iframeEl, listener, iframeLoadTimeout) {
539
447
  iframeEl.src === blankUrl ||
540
448
  iframeEl.src === '') {
541
449
  setTimeout(listener, 0);
542
- return iframeEl.addEventListener('load', listener);
543
- }
544
- iframeEl.addEventListener('load', listener);
545
- }
546
- function onceStylesheetLoaded(link, listener, styleSheetLoadTimeout) {
547
- let fired = false;
548
- let styleSheetLoaded;
549
- try {
550
- styleSheetLoaded = link.sheet;
551
- }
552
- catch (error) {
553
450
  return;
554
451
  }
555
- if (styleSheetLoaded)
556
- return;
557
- const timer = setTimeout(() => {
558
- if (!fired) {
559
- listener();
560
- fired = true;
561
- }
562
- }, styleSheetLoadTimeout);
563
- link.addEventListener('load', () => {
564
- clearTimeout(timer);
565
- fired = true;
566
- listener();
567
- });
452
+ iframeEl.addEventListener('load', listener);
568
453
  }
569
454
  function serializeNode(n, options) {
570
- const { doc, mirror, blockClass, blockSelector, unblockSelector, maskAllText, maskAttributeFn, maskTextClass, unmaskTextClass, maskTextSelector, unmaskTextSelector, inlineStylesheet, maskInputOptions = {}, maskTextFn, maskInputFn, dataURLOptions = {}, inlineImages, recordCanvas, keepIframeSrcFn, newlyAddedElement = false, } = options;
571
- const rootId = getRootId(doc, mirror);
455
+ var _a;
456
+ const { doc, blockClass, blockSelector, unblockSelector, maskTextClass, maskTextSelector, unmaskTextSelector, inlineStylesheet, maskInputSelector, unmaskInputSelector, maskAllText, maskInputOptions = {}, maskTextFn, maskInputFn, dataURLOptions = {}, inlineImages, recordCanvas, keepIframeSrcFn, } = options;
457
+ let rootId;
458
+ if (doc.__sn) {
459
+ const docId = doc.__sn.id;
460
+ rootId = docId === 1 ? undefined : docId;
461
+ }
572
462
  switch (n.nodeType) {
573
463
  case n.DOCUMENT_NODE:
574
464
  if (n.compatMode !== 'CSS1Compat') {
@@ -576,12 +466,14 @@ function serializeNode(n, options) {
576
466
  type: NodeType$1.Document,
577
467
  childNodes: [],
578
468
  compatMode: n.compatMode,
469
+ rootId,
579
470
  };
580
471
  }
581
472
  else {
582
473
  return {
583
474
  type: NodeType$1.Document,
584
475
  childNodes: [],
476
+ rootId,
585
477
  };
586
478
  }
587
479
  case n.DOCUMENT_TYPE_NODE:
@@ -593,39 +485,202 @@ function serializeNode(n, options) {
593
485
  rootId,
594
486
  };
595
487
  case n.ELEMENT_NODE:
596
- return serializeElementNode(n, {
597
- doc,
598
- blockClass,
599
- blockSelector,
600
- unblockSelector,
601
- inlineStylesheet,
602
- maskAttributeFn,
603
- maskInputOptions,
604
- maskInputFn,
605
- dataURLOptions,
606
- inlineImages,
607
- recordCanvas,
608
- keepIframeSrcFn,
609
- newlyAddedElement,
488
+ const needBlock = _isBlockedElement(n, blockClass, blockSelector, unblockSelector);
489
+ const tagName = getValidTagName(n);
490
+ let attributes = {};
491
+ for (const { name, value } of Array.from(n.attributes)) {
492
+ if (!skipAttribute(tagName, name)) {
493
+ attributes[name] = transformAttribute(doc, n, tagName, name, value, maskAllText, unmaskTextSelector, maskTextFn);
494
+ }
495
+ }
496
+ if (tagName === 'link' && inlineStylesheet) {
497
+ const stylesheet = Array.from(doc.styleSheets).find((s) => {
498
+ return s.href === n.href;
499
+ });
500
+ let cssText = null;
501
+ if (stylesheet) {
502
+ cssText = getCssRulesString(stylesheet);
503
+ }
504
+ if (cssText) {
505
+ delete attributes.rel;
506
+ delete attributes.href;
507
+ attributes._cssText = absoluteToStylesheet(cssText, stylesheet.href);
508
+ }
509
+ }
510
+ if (tagName === 'style' &&
511
+ n.sheet &&
512
+ !(n.innerText ||
513
+ n.textContent ||
514
+ '').trim().length) {
515
+ const cssText = getCssRulesString(n.sheet);
516
+ if (cssText) {
517
+ attributes._cssText = absoluteToStylesheet(cssText, getHref());
518
+ }
519
+ }
520
+ if (tagName === 'input' ||
521
+ tagName === 'textarea' ||
522
+ tagName === 'select' ||
523
+ tagName === 'option') {
524
+ const el = n;
525
+ const type = getInputType(el);
526
+ const value = getInputValue(el, tagName.toUpperCase(), type);
527
+ const checked = n.checked;
528
+ if (type !== 'submit' &&
529
+ type !== 'button' &&
530
+ value) {
531
+ attributes.value = maskInputValue({
532
+ input: el,
533
+ type,
534
+ tagName,
535
+ value,
536
+ maskInputSelector,
537
+ unmaskInputSelector,
538
+ maskInputOptions,
539
+ maskInputFn,
540
+ });
541
+ }
542
+ if (checked) {
543
+ attributes.checked = checked;
544
+ }
545
+ }
546
+ if (tagName === 'option') {
547
+ if (n.selected && !maskInputOptions['select']) {
548
+ attributes.selected = true;
549
+ }
550
+ else {
551
+ delete attributes.selected;
552
+ }
553
+ }
554
+ if (tagName === 'canvas' && recordCanvas) {
555
+ if (n.__context === '2d') {
556
+ if (!is2DCanvasBlank(n)) {
557
+ attributes.rr_dataURL = n.toDataURL(dataURLOptions.type, dataURLOptions.quality);
558
+ }
559
+ }
560
+ else if (!('__context' in n)) {
561
+ const canvasDataURL = n.toDataURL(dataURLOptions.type, dataURLOptions.quality);
562
+ const blankCanvas = document.createElement('canvas');
563
+ blankCanvas.width = n.width;
564
+ blankCanvas.height = n.height;
565
+ const blankCanvasDataURL = blankCanvas.toDataURL(dataURLOptions.type, dataURLOptions.quality);
566
+ if (canvasDataURL !== blankCanvasDataURL) {
567
+ attributes.rr_dataURL = canvasDataURL;
568
+ }
569
+ }
570
+ }
571
+ if (tagName === 'img' && inlineImages) {
572
+ if (!canvasService) {
573
+ canvasService = doc.createElement('canvas');
574
+ canvasCtx = canvasService.getContext('2d');
575
+ }
576
+ const image = n;
577
+ const oldValue = image.crossOrigin;
578
+ image.crossOrigin = 'anonymous';
579
+ const recordInlineImage = () => {
580
+ try {
581
+ canvasService.width = image.naturalWidth;
582
+ canvasService.height = image.naturalHeight;
583
+ canvasCtx.drawImage(image, 0, 0);
584
+ attributes.rr_dataURL = canvasService.toDataURL(dataURLOptions.type, dataURLOptions.quality);
585
+ }
586
+ catch (err) {
587
+ console.warn(`Cannot inline img src=${image.currentSrc}! Error: ${err}`);
588
+ }
589
+ oldValue
590
+ ? (attributes.crossOrigin = oldValue)
591
+ : delete attributes.crossOrigin;
592
+ };
593
+ if (image.complete && image.naturalWidth !== 0)
594
+ recordInlineImage();
595
+ else
596
+ image.onload = recordInlineImage;
597
+ }
598
+ if (tagName === 'audio' || tagName === 'video') {
599
+ attributes.rr_mediaState = n.paused
600
+ ? 'paused'
601
+ : 'played';
602
+ attributes.rr_mediaCurrentTime = n.currentTime;
603
+ }
604
+ if (n.scrollLeft) {
605
+ attributes.rr_scrollLeft = n.scrollLeft;
606
+ }
607
+ if (n.scrollTop) {
608
+ attributes.rr_scrollTop = n.scrollTop;
609
+ }
610
+ if (needBlock) {
611
+ const { width, height } = n.getBoundingClientRect();
612
+ attributes = {
613
+ class: attributes.class,
614
+ rr_width: `${width}px`,
615
+ rr_height: `${height}px`,
616
+ };
617
+ }
618
+ if (tagName === 'iframe' && !keepIframeSrcFn(attributes.src)) {
619
+ if (!n.contentDocument) {
620
+ attributes.rr_src = attributes.src;
621
+ }
622
+ delete attributes.src;
623
+ }
624
+ return {
625
+ type: NodeType$1.Element,
626
+ tagName,
627
+ attributes,
628
+ childNodes: [],
629
+ isSVG: isSVGElement(n) || undefined,
630
+ needBlock,
610
631
  rootId,
611
- maskAllText,
612
- maskTextClass,
613
- unmaskTextClass,
614
- maskTextSelector,
615
- unmaskTextSelector,
616
- });
632
+ };
617
633
  case n.TEXT_NODE:
618
- return serializeTextNode(n, {
619
- maskAllText,
620
- maskTextClass,
621
- unmaskTextClass,
622
- maskTextSelector,
623
- unmaskTextSelector,
624
- maskTextFn,
625
- maskInputOptions,
626
- maskInputFn,
634
+ const parentTagName = n.parentNode && n.parentNode.tagName;
635
+ let textContent = n.textContent;
636
+ const isStyle = parentTagName === 'STYLE' ? true : undefined;
637
+ const isScript = parentTagName === 'SCRIPT' ? true : undefined;
638
+ if (isStyle && textContent) {
639
+ try {
640
+ if (n.nextSibling || n.previousSibling) {
641
+ }
642
+ else if ((_a = n.parentNode.sheet) === null || _a === void 0 ? void 0 : _a.cssRules) {
643
+ textContent = stringifyStyleSheet(n.parentNode.sheet);
644
+ }
645
+ }
646
+ catch (err) {
647
+ console.warn(`Cannot get CSS styles from text's parentNode. Error: ${err}`, n);
648
+ }
649
+ textContent = absoluteToStylesheet(textContent, getHref());
650
+ }
651
+ if (isScript) {
652
+ textContent = 'SCRIPT_PLACEHOLDER';
653
+ }
654
+ if (parentTagName === 'TEXTAREA' && textContent) {
655
+ textContent = '';
656
+ }
657
+ else if (parentTagName === 'OPTION' && textContent) {
658
+ const option = n.parentNode;
659
+ textContent = maskInputValue({
660
+ input: option,
661
+ type: null,
662
+ tagName: parentTagName,
663
+ value: textContent,
664
+ maskInputSelector,
665
+ unmaskInputSelector,
666
+ maskInputOptions,
667
+ maskInputFn,
668
+ });
669
+ }
670
+ else if (!isStyle &&
671
+ !isScript &&
672
+ needMaskingText(n, maskTextClass, maskTextSelector, unmaskTextSelector, maskAllText) &&
673
+ textContent) {
674
+ textContent = maskTextFn
675
+ ? maskTextFn(textContent)
676
+ : defaultMaskFn(textContent);
677
+ }
678
+ return {
679
+ type: NodeType$1.Text,
680
+ textContent: textContent || '',
681
+ isStyle,
627
682
  rootId,
628
- });
683
+ };
629
684
  case n.CDATA_SECTION_NODE:
630
685
  return {
631
686
  type: NodeType$1.CDATA,
@@ -642,249 +697,30 @@ function serializeNode(n, options) {
642
697
  return false;
643
698
  }
644
699
  }
645
- function getRootId(doc, mirror) {
646
- if (!mirror.hasNode(doc))
647
- return undefined;
648
- const docId = mirror.getId(doc);
649
- return docId === 1 ? undefined : docId;
650
- }
651
- function serializeTextNode(n, options) {
652
- var _a;
653
- const { maskAllText, maskTextClass, unmaskTextClass, maskTextSelector, unmaskTextSelector, maskTextFn, maskInputOptions, maskInputFn, rootId, } = options;
654
- const parentTagName = n.parentNode && n.parentNode.tagName;
655
- let textContent = n.textContent;
656
- const isStyle = parentTagName === 'STYLE' ? true : undefined;
657
- const isScript = parentTagName === 'SCRIPT' ? true : undefined;
658
- const isTextarea = parentTagName === 'TEXTAREA' ? true : undefined;
659
- if (isStyle && textContent) {
660
- try {
661
- if (n.nextSibling || n.previousSibling) {
662
- }
663
- else if ((_a = n.parentNode.sheet) === null || _a === void 0 ? void 0 : _a.cssRules) {
664
- textContent = stringifyStyleSheet(n.parentNode.sheet);
665
- }
666
- }
667
- catch (err) {
668
- console.warn(`Cannot get CSS styles from text's parentNode. Error: ${err}`, n);
669
- }
670
- textContent = absoluteToStylesheet(textContent, getHref());
671
- }
672
- if (isScript) {
673
- textContent = 'SCRIPT_PLACEHOLDER';
674
- }
675
- const forceMask = needMaskingText(n, maskTextClass, maskTextSelector, unmaskTextClass, unmaskTextSelector, maskAllText);
676
- if (!isStyle && !isScript && !isTextarea && textContent && forceMask) {
677
- textContent = maskTextFn
678
- ? maskTextFn(textContent)
679
- : textContent.replace(/[\S]/g, '*');
680
- }
681
- if (isTextarea && textContent && (maskInputOptions.textarea || forceMask)) {
682
- textContent = maskInputFn
683
- ? maskInputFn(textContent, n.parentNode)
684
- : textContent.replace(/[\S]/g, '*');
685
- }
686
- if (parentTagName === 'OPTION' && textContent) {
687
- const isInputMasked = shouldMaskInput({
688
- type: null,
689
- tagName: parentTagName,
690
- maskInputOptions,
691
- });
692
- textContent = maskInputValue({
693
- isMasked: needMaskingText(n, maskTextClass, maskTextSelector, unmaskTextClass, unmaskTextSelector, isInputMasked),
694
- element: n,
695
- value: textContent,
696
- maskInputFn,
697
- });
700
+ function lowerIfExists(maybeAttr) {
701
+ if (maybeAttr === undefined || maybeAttr === null) {
702
+ return '';
703
+ }
704
+ else {
705
+ return maybeAttr.toLowerCase();
698
706
  }
699
- return {
700
- type: NodeType$1.Text,
701
- textContent: textContent || '',
702
- isStyle,
703
- rootId,
704
- };
705
707
  }
706
- function serializeElementNode(n, options) {
707
- const { doc, blockClass, blockSelector, unblockSelector, inlineStylesheet, maskInputOptions = {}, maskAttributeFn, maskInputFn, dataURLOptions = {}, inlineImages, recordCanvas, keepIframeSrcFn, newlyAddedElement = false, rootId, maskAllText, maskTextClass, unmaskTextClass, maskTextSelector, unmaskTextSelector, } = options;
708
- const needBlock = _isBlockedElement(n, blockClass, blockSelector, unblockSelector);
709
- const tagName = getValidTagName(n);
710
- let attributes = {};
711
- const len = n.attributes.length;
712
- for (let i = 0; i < len; i++) {
713
- const attr = n.attributes[i];
714
- if (!ignoreAttribute(tagName, attr.name, attr.value)) {
715
- attributes[attr.name] = transformAttribute(doc, tagName, toLowerCase(attr.name), attr.value, n, maskAttributeFn);
716
- }
708
+ function slimDOMExcluded(sn, slimDOMOptions) {
709
+ if (slimDOMOptions.comment && sn.type === NodeType$1.Comment) {
710
+ return true;
717
711
  }
718
- if (tagName === 'link' && inlineStylesheet) {
719
- const stylesheet = Array.from(doc.styleSheets).find((s) => {
720
- return s.href === n.href;
721
- });
722
- let cssText = null;
723
- if (stylesheet) {
724
- cssText = getCssRulesString(stylesheet);
725
- }
726
- if (cssText) {
727
- delete attributes.rel;
728
- delete attributes.href;
729
- attributes._cssText = absoluteToStylesheet(cssText, stylesheet.href);
730
- }
731
- }
732
- if (tagName === 'style' &&
733
- n.sheet &&
734
- !(n.innerText || n.textContent || '').trim().length) {
735
- const cssText = getCssRulesString(n.sheet);
736
- if (cssText) {
737
- attributes._cssText = absoluteToStylesheet(cssText, getHref());
738
- }
739
- }
740
- if (tagName === 'input' ||
741
- tagName === 'textarea' ||
742
- tagName === 'select' ||
743
- tagName === 'option') {
744
- const el = n;
745
- const type = getInputType(el);
746
- const value = getInputValue(el, toUpperCase(tagName), type);
747
- const checked = el.checked;
748
- if (type !== 'submit' && type !== 'button' && value) {
749
- const forceMask = needMaskingText(el, maskTextClass, maskTextSelector, unmaskTextClass, unmaskTextSelector, shouldMaskInput({
750
- type,
751
- tagName: toUpperCase(tagName),
752
- maskInputOptions,
753
- }));
754
- attributes.value = maskInputValue({
755
- isMasked: forceMask,
756
- element: el,
757
- value,
758
- maskInputFn,
759
- });
760
- }
761
- if (checked) {
762
- attributes.checked = checked;
763
- }
764
- }
765
- if (tagName === 'option') {
766
- if (n.selected && !maskInputOptions['select']) {
767
- attributes.selected = true;
768
- }
769
- else {
770
- delete attributes.selected;
771
- }
772
- }
773
- if (tagName === 'canvas' && recordCanvas) {
774
- if (n.__context === '2d') {
775
- if (!is2DCanvasBlank(n)) {
776
- attributes.rr_dataURL = n.toDataURL(dataURLOptions.type, dataURLOptions.quality);
777
- }
778
- }
779
- else if (!('__context' in n)) {
780
- const canvasDataURL = n.toDataURL(dataURLOptions.type, dataURLOptions.quality);
781
- const blankCanvas = document.createElement('canvas');
782
- blankCanvas.width = n.width;
783
- blankCanvas.height = n.height;
784
- const blankCanvasDataURL = blankCanvas.toDataURL(dataURLOptions.type, dataURLOptions.quality);
785
- if (canvasDataURL !== blankCanvasDataURL) {
786
- attributes.rr_dataURL = canvasDataURL;
787
- }
788
- }
789
- }
790
- if (tagName === 'img' && inlineImages) {
791
- if (!canvasService) {
792
- canvasService = doc.createElement('canvas');
793
- canvasCtx = canvasService.getContext('2d');
794
- }
795
- const image = n;
796
- const oldValue = image.crossOrigin;
797
- image.crossOrigin = 'anonymous';
798
- const recordInlineImage = () => {
799
- image.removeEventListener('load', recordInlineImage);
800
- try {
801
- canvasService.width = image.naturalWidth;
802
- canvasService.height = image.naturalHeight;
803
- canvasCtx.drawImage(image, 0, 0);
804
- attributes.rr_dataURL = canvasService.toDataURL(dataURLOptions.type, dataURLOptions.quality);
805
- }
806
- catch (err) {
807
- console.warn(`Cannot inline img src=${image.currentSrc}! Error: ${err}`);
808
- }
809
- oldValue
810
- ? (attributes.crossOrigin = oldValue)
811
- : image.removeAttribute('crossorigin');
812
- };
813
- if (image.complete && image.naturalWidth !== 0)
814
- recordInlineImage();
815
- else
816
- image.addEventListener('load', recordInlineImage);
817
- }
818
- if (tagName === 'audio' || tagName === 'video') {
819
- attributes.rr_mediaState = n.paused
820
- ? 'paused'
821
- : 'played';
822
- attributes.rr_mediaCurrentTime = n.currentTime;
823
- }
824
- if (!newlyAddedElement) {
825
- if (n.scrollLeft) {
826
- attributes.rr_scrollLeft = n.scrollLeft;
827
- }
828
- if (n.scrollTop) {
829
- attributes.rr_scrollTop = n.scrollTop;
830
- }
831
- }
832
- if (needBlock) {
833
- const { width, height } = n.getBoundingClientRect();
834
- attributes = {
835
- class: attributes.class,
836
- rr_width: `${width}px`,
837
- rr_height: `${height}px`,
838
- };
839
- }
840
- if (tagName === 'iframe' && !keepIframeSrcFn(attributes.src)) {
841
- if (!n.contentDocument) {
842
- attributes.rr_src = attributes.src;
843
- }
844
- delete attributes.src;
845
- }
846
- let isCustomElement;
847
- try {
848
- if (customElements.get(tagName))
849
- isCustomElement = true;
850
- }
851
- catch (e) {
852
- }
853
- return {
854
- type: NodeType$1.Element,
855
- tagName,
856
- attributes,
857
- childNodes: [],
858
- isSVG: isSVGElement(n) || undefined,
859
- needBlock,
860
- rootId,
861
- isCustom: isCustomElement,
862
- };
863
- }
864
- function lowerIfExists(maybeAttr) {
865
- if (maybeAttr === undefined || maybeAttr === null) {
866
- return '';
867
- }
868
- else {
869
- return maybeAttr.toLowerCase();
870
- }
871
- }
872
- function slimDOMExcluded(sn, slimDOMOptions) {
873
- if (slimDOMOptions.comment && sn.type === NodeType$1.Comment) {
874
- return true;
875
- }
876
- else if (sn.type === NodeType$1.Element) {
877
- if (slimDOMOptions.script &&
878
- (sn.tagName === 'script' ||
879
- (sn.tagName === 'link' &&
880
- (sn.attributes.rel === 'preload' ||
881
- sn.attributes.rel === 'modulepreload') &&
882
- sn.attributes.as === 'script') ||
883
- (sn.tagName === 'link' &&
884
- sn.attributes.rel === 'prefetch' &&
885
- typeof sn.attributes.href === 'string' &&
886
- sn.attributes.href.endsWith('.js')))) {
887
- return true;
712
+ else if (sn.type === NodeType$1.Element) {
713
+ if (slimDOMOptions.script &&
714
+ (sn.tagName === 'script' ||
715
+ (sn.tagName === 'link' &&
716
+ (sn.attributes.rel === 'preload' ||
717
+ sn.attributes.rel === 'modulepreload') &&
718
+ sn.attributes.as === 'script') ||
719
+ (sn.tagName === 'link' &&
720
+ sn.attributes.rel === 'prefetch' &&
721
+ typeof sn.attributes.href === 'string' &&
722
+ sn.attributes.href.endsWith('.js')))) {
723
+ return true;
888
724
  }
889
725
  else if (slimDOMOptions.headFavicon &&
890
726
  ((sn.tagName === 'link' && sn.attributes.rel === 'shortcut icon') ||
@@ -942,37 +778,35 @@ function slimDOMExcluded(sn, slimDOMOptions) {
942
778
  return false;
943
779
  }
944
780
  function serializeNodeWithId(n, options) {
945
- const { doc, mirror, blockClass, blockSelector, unblockSelector, maskAllText, maskTextClass, unmaskTextClass, maskTextSelector, unmaskTextSelector, skipChild = false, inlineStylesheet = true, maskInputOptions = {}, maskAttributeFn, maskTextFn, maskInputFn, slimDOMOptions, dataURLOptions = {}, inlineImages = false, recordCanvas = false, onSerialize, onIframeLoad, iframeLoadTimeout = 5000, onStylesheetLoad, stylesheetLoadTimeout = 5000, keepIframeSrcFn = () => false, newlyAddedElement = false, } = options;
781
+ const { doc, map, blockClass, blockSelector, unblockSelector, maskTextClass, maskTextSelector, unmaskTextSelector, skipChild = false, inlineStylesheet = true, maskInputSelector, unmaskInputSelector, maskAllText, maskInputOptions = {}, maskTextFn, maskInputFn, slimDOMOptions, dataURLOptions = {}, inlineImages = false, recordCanvas = false, onSerialize, onIframeLoad, iframeLoadTimeout = 5000, keepIframeSrcFn = () => false, } = options;
946
782
  let { preserveWhiteSpace = true } = options;
947
783
  const _serializedNode = serializeNode(n, {
948
784
  doc,
949
- mirror,
950
785
  blockClass,
951
786
  blockSelector,
952
- maskAllText,
953
787
  unblockSelector,
954
788
  maskTextClass,
955
- unmaskTextClass,
956
789
  maskTextSelector,
957
790
  unmaskTextSelector,
958
791
  inlineStylesheet,
792
+ maskInputSelector,
793
+ unmaskInputSelector,
794
+ maskAllText,
959
795
  maskInputOptions,
960
- maskAttributeFn,
961
796
  maskTextFn,
962
797
  maskInputFn,
963
798
  dataURLOptions,
964
799
  inlineImages,
965
800
  recordCanvas,
966
801
  keepIframeSrcFn,
967
- newlyAddedElement,
968
802
  });
969
803
  if (!_serializedNode) {
970
804
  console.warn(n, 'not serialized');
971
805
  return null;
972
806
  }
973
807
  let id;
974
- if (mirror.hasNode(n)) {
975
- id = mirror.getId(n);
808
+ if ('__sn' in n) {
809
+ id = n.__sn.id;
976
810
  }
977
811
  else if (slimDOMExcluded(_serializedNode, slimDOMOptions) ||
978
812
  (!preserveWhiteSpace &&
@@ -985,10 +819,11 @@ function serializeNodeWithId(n, options) {
985
819
  id = genId();
986
820
  }
987
821
  const serializedNode = Object.assign(_serializedNode, { id });
988
- mirror.add(n, serializedNode);
822
+ n.__sn = serializedNode;
989
823
  if (id === IGNORED_NODE) {
990
824
  return null;
991
825
  }
826
+ map[id] = n;
992
827
  if (onSerialize) {
993
828
  onSerialize(n);
994
829
  }
@@ -996,33 +831,32 @@ function serializeNodeWithId(n, options) {
996
831
  if (serializedNode.type === NodeType$1.Element) {
997
832
  recordChild = recordChild && !serializedNode.needBlock;
998
833
  delete serializedNode.needBlock;
999
- const shadowRoot = n.shadowRoot;
1000
- if (shadowRoot && isNativeShadowDom(shadowRoot))
834
+ if (n.shadowRoot)
1001
835
  serializedNode.isShadowHost = true;
1002
836
  }
1003
837
  if ((serializedNode.type === NodeType$1.Document ||
1004
838
  serializedNode.type === NodeType$1.Element) &&
1005
839
  recordChild) {
1006
840
  if (slimDOMOptions.headWhitespace &&
1007
- serializedNode.type === NodeType$1.Element &&
1008
- serializedNode.tagName === 'head') {
841
+ _serializedNode.type === NodeType$1.Element &&
842
+ _serializedNode.tagName === 'head') {
1009
843
  preserveWhiteSpace = false;
1010
844
  }
1011
845
  const bypassOptions = {
1012
846
  doc,
1013
- mirror,
847
+ map,
1014
848
  blockClass,
1015
849
  blockSelector,
1016
- maskAllText,
1017
850
  unblockSelector,
1018
851
  maskTextClass,
1019
- unmaskTextClass,
1020
852
  maskTextSelector,
1021
853
  unmaskTextSelector,
1022
854
  skipChild,
1023
855
  inlineStylesheet,
856
+ maskInputSelector,
857
+ unmaskInputSelector,
858
+ maskAllText,
1024
859
  maskInputOptions,
1025
- maskAttributeFn,
1026
860
  maskTextFn,
1027
861
  maskInputFn,
1028
862
  slimDOMOptions,
@@ -1033,8 +867,6 @@ function serializeNodeWithId(n, options) {
1033
867
  onSerialize,
1034
868
  onIframeLoad,
1035
869
  iframeLoadTimeout,
1036
- onStylesheetLoad,
1037
- stylesheetLoadTimeout,
1038
870
  keepIframeSrcFn,
1039
871
  };
1040
872
  for (const childN of Array.from(n.childNodes)) {
@@ -1043,20 +875,17 @@ function serializeNodeWithId(n, options) {
1043
875
  serializedNode.childNodes.push(serializedChildNode);
1044
876
  }
1045
877
  }
1046
- if (isElement$1(n) && n.shadowRoot) {
878
+ if (isElement(n) && n.shadowRoot) {
1047
879
  for (const childN of Array.from(n.shadowRoot.childNodes)) {
1048
880
  const serializedChildNode = serializeNodeWithId(childN, bypassOptions);
1049
881
  if (serializedChildNode) {
1050
- isNativeShadowDom(n.shadowRoot) &&
1051
- (serializedChildNode.isShadow = true);
882
+ serializedChildNode.isShadow = true;
1052
883
  serializedNode.childNodes.push(serializedChildNode);
1053
884
  }
1054
885
  }
1055
886
  }
1056
887
  }
1057
- if (n.parentNode &&
1058
- isShadowRoot(n.parentNode) &&
1059
- isNativeShadowDom(n.parentNode)) {
888
+ if (n.parentNode && isShadowRoot(n.parentNode)) {
1060
889
  serializedNode.isShadow = true;
1061
890
  }
1062
891
  if (serializedNode.type === NodeType$1.Element &&
@@ -1066,19 +895,19 @@ function serializeNodeWithId(n, options) {
1066
895
  if (iframeDoc && onIframeLoad) {
1067
896
  const serializedIframeNode = serializeNodeWithId(iframeDoc, {
1068
897
  doc: iframeDoc,
1069
- mirror,
898
+ map,
1070
899
  blockClass,
1071
900
  blockSelector,
1072
901
  unblockSelector,
1073
- maskAllText,
1074
902
  maskTextClass,
1075
- unmaskTextClass,
1076
903
  maskTextSelector,
1077
904
  unmaskTextSelector,
1078
905
  skipChild: false,
1079
906
  inlineStylesheet,
907
+ maskInputSelector,
908
+ unmaskInputSelector,
909
+ maskAllText,
1080
910
  maskInputOptions,
1081
- maskAttributeFn,
1082
911
  maskTextFn,
1083
912
  maskInputFn,
1084
913
  slimDOMOptions,
@@ -1089,8 +918,6 @@ function serializeNodeWithId(n, options) {
1089
918
  onSerialize,
1090
919
  onIframeLoad,
1091
920
  iframeLoadTimeout,
1092
- onStylesheetLoad,
1093
- stylesheetLoadTimeout,
1094
921
  keepIframeSrcFn,
1095
922
  });
1096
923
  if (serializedIframeNode) {
@@ -1099,50 +926,11 @@ function serializeNodeWithId(n, options) {
1099
926
  }
1100
927
  }, iframeLoadTimeout);
1101
928
  }
1102
- if (serializedNode.type === NodeType$1.Element &&
1103
- serializedNode.tagName === 'link' &&
1104
- serializedNode.attributes.rel === 'stylesheet') {
1105
- onceStylesheetLoaded(n, () => {
1106
- if (onStylesheetLoad) {
1107
- const serializedLinkNode = serializeNodeWithId(n, {
1108
- doc,
1109
- mirror,
1110
- blockClass,
1111
- blockSelector,
1112
- unblockSelector,
1113
- maskAllText,
1114
- maskTextClass,
1115
- unmaskTextClass,
1116
- maskTextSelector,
1117
- unmaskTextSelector,
1118
- skipChild: false,
1119
- inlineStylesheet,
1120
- maskInputOptions,
1121
- maskAttributeFn,
1122
- maskTextFn,
1123
- maskInputFn,
1124
- slimDOMOptions,
1125
- dataURLOptions,
1126
- inlineImages,
1127
- recordCanvas,
1128
- preserveWhiteSpace,
1129
- onSerialize,
1130
- onIframeLoad,
1131
- iframeLoadTimeout,
1132
- onStylesheetLoad,
1133
- stylesheetLoadTimeout,
1134
- keepIframeSrcFn,
1135
- });
1136
- if (serializedLinkNode) {
1137
- onStylesheetLoad(n, serializedLinkNode);
1138
- }
1139
- }
1140
- }, stylesheetLoadTimeout);
1141
- }
1142
929
  return serializedNode;
1143
930
  }
1144
931
  function snapshot(n, options) {
1145
- const { mirror = new Mirror(), blockClass = 'rr-block', blockSelector = null, unblockSelector = null, maskAllText = false, maskTextClass = 'rr-mask', unmaskTextClass = null, maskTextSelector = null, unmaskTextSelector = null, inlineStylesheet = true, inlineImages = false, recordCanvas = false, maskAllInputs = false, maskAttributeFn, maskTextFn, maskInputFn, slimDOM = false, dataURLOptions, preserveWhiteSpace, onSerialize, onIframeLoad, iframeLoadTimeout, onStylesheetLoad, stylesheetLoadTimeout, keepIframeSrcFn = () => false, } = options || {};
932
+ const { blockClass = 'rr-block', blockSelector = null, unblockSelector = null, maskTextClass = 'rr-mask', maskTextSelector = null, unmaskTextSelector = null, inlineStylesheet = true, inlineImages = false, recordCanvas = false, maskInputSelector = null, unmaskInputSelector = null, maskAllText = false, maskAllInputs = false, maskTextFn, maskInputFn, slimDOM = false, dataURLOptions, preserveWhiteSpace, onSerialize, onIframeLoad, iframeLoadTimeout, keepIframeSrcFn = () => false, } = options || {};
933
+ const idNodeMap = {};
1146
934
  const maskInputOptions = maskAllInputs === true
1147
935
  ? {
1148
936
  color: true,
@@ -1181,43 +969,147 @@ function snapshot(n, options) {
1181
969
  : slimDOM === false
1182
970
  ? {}
1183
971
  : slimDOM;
1184
- return serializeNodeWithId(n, {
1185
- doc: n,
1186
- mirror,
1187
- blockClass,
1188
- blockSelector,
1189
- unblockSelector,
1190
- maskAllText,
1191
- maskTextClass,
1192
- unmaskTextClass,
1193
- maskTextSelector,
1194
- unmaskTextSelector,
1195
- skipChild: false,
1196
- inlineStylesheet,
1197
- maskInputOptions,
1198
- maskAttributeFn,
1199
- maskTextFn,
1200
- maskInputFn,
1201
- slimDOMOptions,
1202
- dataURLOptions,
1203
- inlineImages,
1204
- recordCanvas,
1205
- preserveWhiteSpace,
1206
- onSerialize,
1207
- onIframeLoad,
1208
- iframeLoadTimeout,
1209
- onStylesheetLoad,
1210
- stylesheetLoadTimeout,
1211
- keepIframeSrcFn,
1212
- newlyAddedElement: false,
1213
- });
972
+ return [
973
+ serializeNodeWithId(n, {
974
+ doc: n,
975
+ map: idNodeMap,
976
+ blockClass,
977
+ blockSelector,
978
+ unblockSelector,
979
+ maskTextClass,
980
+ maskTextSelector,
981
+ unmaskTextSelector,
982
+ skipChild: false,
983
+ inlineStylesheet,
984
+ maskInputSelector,
985
+ unmaskInputSelector,
986
+ maskAllText,
987
+ maskInputOptions,
988
+ maskTextFn,
989
+ maskInputFn,
990
+ slimDOMOptions,
991
+ dataURLOptions,
992
+ inlineImages,
993
+ recordCanvas,
994
+ preserveWhiteSpace,
995
+ onSerialize,
996
+ onIframeLoad,
997
+ iframeLoadTimeout,
998
+ keepIframeSrcFn,
999
+ }),
1000
+ idNodeMap,
1001
+ ];
1214
1002
  }
1003
+ function skipAttribute(tagName, attributeName, value) {
1004
+ return ((tagName === 'video' || tagName === 'audio') && attributeName === 'autoplay');
1005
+ }
1006
+
1007
+ var EventType;
1008
+ (function (EventType) {
1009
+ EventType[EventType["DomContentLoaded"] = 0] = "DomContentLoaded";
1010
+ EventType[EventType["Load"] = 1] = "Load";
1011
+ EventType[EventType["FullSnapshot"] = 2] = "FullSnapshot";
1012
+ EventType[EventType["IncrementalSnapshot"] = 3] = "IncrementalSnapshot";
1013
+ EventType[EventType["Meta"] = 4] = "Meta";
1014
+ EventType[EventType["Custom"] = 5] = "Custom";
1015
+ EventType[EventType["Plugin"] = 6] = "Plugin";
1016
+ })(EventType || (EventType = {}));
1017
+ var IncrementalSource;
1018
+ (function (IncrementalSource) {
1019
+ IncrementalSource[IncrementalSource["Mutation"] = 0] = "Mutation";
1020
+ IncrementalSource[IncrementalSource["MouseMove"] = 1] = "MouseMove";
1021
+ IncrementalSource[IncrementalSource["MouseInteraction"] = 2] = "MouseInteraction";
1022
+ IncrementalSource[IncrementalSource["Scroll"] = 3] = "Scroll";
1023
+ IncrementalSource[IncrementalSource["ViewportResize"] = 4] = "ViewportResize";
1024
+ IncrementalSource[IncrementalSource["Input"] = 5] = "Input";
1025
+ IncrementalSource[IncrementalSource["TouchMove"] = 6] = "TouchMove";
1026
+ IncrementalSource[IncrementalSource["MediaInteraction"] = 7] = "MediaInteraction";
1027
+ IncrementalSource[IncrementalSource["StyleSheetRule"] = 8] = "StyleSheetRule";
1028
+ IncrementalSource[IncrementalSource["CanvasMutation"] = 9] = "CanvasMutation";
1029
+ IncrementalSource[IncrementalSource["Font"] = 10] = "Font";
1030
+ IncrementalSource[IncrementalSource["Log"] = 11] = "Log";
1031
+ IncrementalSource[IncrementalSource["Drag"] = 12] = "Drag";
1032
+ IncrementalSource[IncrementalSource["StyleDeclaration"] = 13] = "StyleDeclaration";
1033
+ })(IncrementalSource || (IncrementalSource = {}));
1034
+ var MouseInteractions;
1035
+ (function (MouseInteractions) {
1036
+ MouseInteractions[MouseInteractions["MouseUp"] = 0] = "MouseUp";
1037
+ MouseInteractions[MouseInteractions["MouseDown"] = 1] = "MouseDown";
1038
+ MouseInteractions[MouseInteractions["Click"] = 2] = "Click";
1039
+ MouseInteractions[MouseInteractions["ContextMenu"] = 3] = "ContextMenu";
1040
+ MouseInteractions[MouseInteractions["DblClick"] = 4] = "DblClick";
1041
+ MouseInteractions[MouseInteractions["Focus"] = 5] = "Focus";
1042
+ MouseInteractions[MouseInteractions["Blur"] = 6] = "Blur";
1043
+ MouseInteractions[MouseInteractions["TouchStart"] = 7] = "TouchStart";
1044
+ MouseInteractions[MouseInteractions["TouchMove_Departed"] = 8] = "TouchMove_Departed";
1045
+ MouseInteractions[MouseInteractions["TouchEnd"] = 9] = "TouchEnd";
1046
+ MouseInteractions[MouseInteractions["TouchCancel"] = 10] = "TouchCancel";
1047
+ })(MouseInteractions || (MouseInteractions = {}));
1048
+ var CanvasContext;
1049
+ (function (CanvasContext) {
1050
+ CanvasContext[CanvasContext["2D"] = 0] = "2D";
1051
+ CanvasContext[CanvasContext["WebGL"] = 1] = "WebGL";
1052
+ CanvasContext[CanvasContext["WebGL2"] = 2] = "WebGL2";
1053
+ })(CanvasContext || (CanvasContext = {}));
1054
+ var MediaInteractions;
1055
+ (function (MediaInteractions) {
1056
+ MediaInteractions[MediaInteractions["Play"] = 0] = "Play";
1057
+ MediaInteractions[MediaInteractions["Pause"] = 1] = "Pause";
1058
+ MediaInteractions[MediaInteractions["Seeked"] = 2] = "Seeked";
1059
+ MediaInteractions[MediaInteractions["VolumeChange"] = 3] = "VolumeChange";
1060
+ })(MediaInteractions || (MediaInteractions = {}));
1061
+ var ReplayerEvents;
1062
+ (function (ReplayerEvents) {
1063
+ ReplayerEvents["Start"] = "start";
1064
+ ReplayerEvents["Pause"] = "pause";
1065
+ ReplayerEvents["Resume"] = "resume";
1066
+ ReplayerEvents["Resize"] = "resize";
1067
+ ReplayerEvents["Finish"] = "finish";
1068
+ ReplayerEvents["FullsnapshotRebuilded"] = "fullsnapshot-rebuilded";
1069
+ ReplayerEvents["LoadStylesheetStart"] = "load-stylesheet-start";
1070
+ ReplayerEvents["LoadStylesheetEnd"] = "load-stylesheet-end";
1071
+ ReplayerEvents["SkipStart"] = "skip-start";
1072
+ ReplayerEvents["SkipEnd"] = "skip-end";
1073
+ ReplayerEvents["MouseInteraction"] = "mouse-interaction";
1074
+ ReplayerEvents["EventCast"] = "event-cast";
1075
+ ReplayerEvents["CustomEvent"] = "custom-event";
1076
+ ReplayerEvents["Flush"] = "flush";
1077
+ ReplayerEvents["StateChange"] = "state-change";
1078
+ ReplayerEvents["PlayBack"] = "play-back";
1079
+ })(ReplayerEvents || (ReplayerEvents = {}));
1215
1080
 
1216
1081
  function on(type, fn, target = document) {
1217
1082
  const options = { capture: true, passive: true };
1218
1083
  target.addEventListener(type, fn, options);
1219
1084
  return () => target.removeEventListener(type, fn, options);
1220
1085
  }
1086
+ function createMirror() {
1087
+ return {
1088
+ map: {},
1089
+ getId(n) {
1090
+ if (!n || !n.__sn) {
1091
+ return -1;
1092
+ }
1093
+ return n.__sn.id;
1094
+ },
1095
+ getNode(id) {
1096
+ return this.map[id] || null;
1097
+ },
1098
+ removeNodeFromMap(n) {
1099
+ const id = n.__sn && n.__sn.id;
1100
+ delete this.map[id];
1101
+ if (n.childNodes) {
1102
+ n.childNodes.forEach((child) => this.removeNodeFromMap(child));
1103
+ }
1104
+ },
1105
+ has(id) {
1106
+ return this.map.hasOwnProperty(id);
1107
+ },
1108
+ reset() {
1109
+ this.map = {};
1110
+ },
1111
+ };
1112
+ }
1221
1113
  const DEPARTED_MIRROR_ACCESS_WARNING = 'Please stop import mirror directly. Instead of that,' +
1222
1114
  '\r\n' +
1223
1115
  'now you can use replayer.getMirror() to access the mirror instance of a replayer,' +
@@ -1257,13 +1149,14 @@ if (typeof window !== 'undefined' && window.Proxy && window.Reflect) {
1257
1149
  function throttle$1(func, wait, options = {}) {
1258
1150
  let timeout = null;
1259
1151
  let previous = 0;
1260
- return function (...args) {
1261
- const now = Date.now();
1152
+ return function (arg) {
1153
+ let now = Date.now();
1262
1154
  if (!previous && options.leading === false) {
1263
1155
  previous = now;
1264
1156
  }
1265
- const remaining = wait - (now - previous);
1266
- const context = this;
1157
+ let remaining = wait - (now - previous);
1158
+ let context = this;
1159
+ let args = arguments;
1267
1160
  if (remaining <= 0 || remaining > wait) {
1268
1161
  if (timeout) {
1269
1162
  clearTimeout(timeout);
@@ -1300,8 +1193,7 @@ function hookSetter(target, key, d, isRevoked, win = window) {
1300
1193
  function patch(source, name, replacement) {
1301
1194
  try {
1302
1195
  if (!(name in source)) {
1303
- return () => {
1304
- };
1196
+ return () => { };
1305
1197
  }
1306
1198
  const original = source[name];
1307
1199
  const wrapped = replacement(original);
@@ -1320,36 +1212,9 @@ function patch(source, name, replacement) {
1320
1212
  };
1321
1213
  }
1322
1214
  catch (_a) {
1323
- return () => {
1324
- };
1215
+ return () => { };
1325
1216
  }
1326
1217
  }
1327
- let nowTimestamp = Date.now;
1328
- if (!(/[1-9][0-9]{12}/.test(Date.now().toString()))) {
1329
- nowTimestamp = () => new Date().getTime();
1330
- }
1331
- function getWindowScroll(win) {
1332
- var _a, _b, _c, _d, _e, _f;
1333
- const doc = win.document;
1334
- return {
1335
- left: doc.scrollingElement
1336
- ? doc.scrollingElement.scrollLeft
1337
- : win.pageXOffset !== undefined
1338
- ? win.pageXOffset
1339
- : (doc === null || doc === void 0 ? void 0 : doc.documentElement.scrollLeft) ||
1340
- ((_b = (_a = doc === null || doc === void 0 ? void 0 : doc.body) === null || _a === void 0 ? void 0 : _a.parentElement) === null || _b === void 0 ? void 0 : _b.scrollLeft) ||
1341
- ((_c = doc === null || doc === void 0 ? void 0 : doc.body) === null || _c === void 0 ? void 0 : _c.scrollLeft) ||
1342
- 0,
1343
- top: doc.scrollingElement
1344
- ? doc.scrollingElement.scrollTop
1345
- : win.pageYOffset !== undefined
1346
- ? win.pageYOffset
1347
- : (doc === null || doc === void 0 ? void 0 : doc.documentElement.scrollTop) ||
1348
- ((_e = (_d = doc === null || doc === void 0 ? void 0 : doc.body) === null || _d === void 0 ? void 0 : _d.parentElement) === null || _e === void 0 ? void 0 : _e.scrollTop) ||
1349
- ((_f = doc === null || doc === void 0 ? void 0 : doc.body) === null || _f === void 0 ? void 0 : _f.scrollTop) ||
1350
- 0,
1351
- };
1352
- }
1353
1218
  function getWindowHeight() {
1354
1219
  return (window.innerHeight ||
1355
1220
  (document.documentElement && document.documentElement.clientHeight) ||
@@ -1360,38 +1225,48 @@ function getWindowWidth() {
1360
1225
  (document.documentElement && document.documentElement.clientWidth) ||
1361
1226
  (document.body && document.body.clientWidth));
1362
1227
  }
1363
- function isBlocked(node, blockClass, blockSelector, unblockSelector, checkAncestors) {
1228
+ function isBlocked(node, blockClass, blockSelector, unblockSelector) {
1364
1229
  if (!node) {
1365
1230
  return false;
1366
1231
  }
1367
- const el = node.nodeType === node.ELEMENT_NODE
1368
- ? node
1369
- : node.parentElement;
1370
- if (!el)
1371
- return false;
1372
- const blockedPredicate = createMatchPredicate(blockClass, blockSelector);
1373
- if (!checkAncestors) {
1374
- const isUnblocked = unblockSelector && el.matches(unblockSelector);
1375
- return blockedPredicate(el) && !isUnblocked;
1376
- }
1377
- const blockDistance = distanceToMatch(el, blockedPredicate);
1378
- let unblockDistance = -1;
1379
- if (blockDistance < 0) {
1380
- return false;
1381
- }
1382
- if (unblockSelector) {
1383
- unblockDistance = distanceToMatch(el, createMatchPredicate(null, unblockSelector));
1232
+ if (node.nodeType === node.ELEMENT_NODE) {
1233
+ let needBlock = false;
1234
+ const needUnblock = unblockSelector && node.matches(unblockSelector);
1235
+ if (typeof blockClass === 'string') {
1236
+ if (node.closest !== undefined) {
1237
+ needBlock =
1238
+ !needUnblock &&
1239
+ node.closest('.' + blockClass) !== null;
1240
+ }
1241
+ else {
1242
+ needBlock =
1243
+ !needUnblock && node.classList.contains(blockClass);
1244
+ }
1245
+ }
1246
+ else {
1247
+ !needUnblock &&
1248
+ node.classList.forEach((className) => {
1249
+ if (blockClass.test(className)) {
1250
+ needBlock = true;
1251
+ }
1252
+ });
1253
+ }
1254
+ if (!needBlock && blockSelector) {
1255
+ needBlock = node.matches(blockSelector);
1256
+ }
1257
+ return ((!needUnblock && needBlock) ||
1258
+ isBlocked(node.parentNode, blockClass, blockSelector, unblockSelector));
1384
1259
  }
1385
- if (blockDistance > -1 && unblockDistance < 0) {
1386
- return true;
1260
+ if (node.nodeType === node.TEXT_NODE) {
1261
+ return isBlocked(node.parentNode, blockClass, blockSelector, unblockSelector);
1387
1262
  }
1388
- return blockDistance < unblockDistance;
1263
+ return isBlocked(node.parentNode, blockClass, blockSelector, unblockSelector);
1389
1264
  }
1390
- function isSerialized(n, mirror) {
1391
- return mirror.getId(n) !== -1;
1392
- }
1393
- function isIgnored(n, mirror) {
1394
- return mirror.getId(n) === IGNORED_NODE;
1265
+ function isIgnored(n) {
1266
+ if ('__sn' in n) {
1267
+ return n.__sn.id === IGNORED_NODE;
1268
+ }
1269
+ return false;
1395
1270
  }
1396
1271
  function isAncestorRemoved(target, mirror) {
1397
1272
  if (isShadowRoot(target)) {
@@ -1410,7 +1285,7 @@ function isAncestorRemoved(target, mirror) {
1410
1285
  }
1411
1286
  return isAncestorRemoved(target.parentNode, mirror);
1412
1287
  }
1413
- function legacy_isTouchEvent(event) {
1288
+ function isTouchEvent(event) {
1414
1289
  return Boolean(event.changedTouches);
1415
1290
  }
1416
1291
  function polyfill(win = window) {
@@ -1423,9 +1298,8 @@ function polyfill(win = window) {
1423
1298
  .forEach;
1424
1299
  }
1425
1300
  if (!Node.prototype.contains) {
1426
- Node.prototype.contains = (...args) => {
1427
- let node = args[0];
1428
- if (!(0 in args)) {
1301
+ Node.prototype.contains = function contains(node) {
1302
+ if (!(0 in arguments)) {
1429
1303
  throw new TypeError('1 argument is required');
1430
1304
  }
1431
1305
  do {
@@ -1437,142 +1311,15 @@ function polyfill(win = window) {
1437
1311
  };
1438
1312
  }
1439
1313
  }
1440
- function isSerializedIframe(n, mirror) {
1441
- return Boolean(n.nodeName === 'IFRAME' && mirror.getMeta(n));
1442
- }
1443
- function isSerializedStylesheet(n, mirror) {
1444
- return Boolean(n.nodeName === 'LINK' &&
1445
- n.nodeType === n.ELEMENT_NODE &&
1446
- n.getAttribute &&
1447
- n.getAttribute('rel') === 'stylesheet' &&
1448
- mirror.getMeta(n));
1314
+ function isIframeINode(node) {
1315
+ if ('__sn' in node) {
1316
+ return (node.__sn.type === NodeType$1.Element && node.__sn.tagName === 'iframe');
1317
+ }
1318
+ return false;
1449
1319
  }
1450
1320
  function hasShadowRoot(n) {
1451
1321
  return Boolean(n === null || n === void 0 ? void 0 : n.shadowRoot);
1452
1322
  }
1453
- class StyleSheetMirror {
1454
- constructor() {
1455
- this.id = 1;
1456
- this.styleIDMap = new WeakMap();
1457
- this.idStyleMap = new Map();
1458
- }
1459
- getId(stylesheet) {
1460
- var _a;
1461
- return (_a = this.styleIDMap.get(stylesheet)) !== null && _a !== void 0 ? _a : -1;
1462
- }
1463
- has(stylesheet) {
1464
- return this.styleIDMap.has(stylesheet);
1465
- }
1466
- add(stylesheet, id) {
1467
- if (this.has(stylesheet))
1468
- return this.getId(stylesheet);
1469
- let newId;
1470
- if (id === undefined) {
1471
- newId = this.id++;
1472
- }
1473
- else
1474
- newId = id;
1475
- this.styleIDMap.set(stylesheet, newId);
1476
- this.idStyleMap.set(newId, stylesheet);
1477
- return newId;
1478
- }
1479
- getStyle(id) {
1480
- return this.idStyleMap.get(id) || null;
1481
- }
1482
- reset() {
1483
- this.styleIDMap = new WeakMap();
1484
- this.idStyleMap = new Map();
1485
- this.id = 1;
1486
- }
1487
- generateId() {
1488
- return this.id++;
1489
- }
1490
- }
1491
- function getShadowHost(n) {
1492
- var _a, _b;
1493
- let shadowHost = null;
1494
- if (((_b = (_a = n.getRootNode) === null || _a === void 0 ? void 0 : _a.call(n)) === null || _b === void 0 ? void 0 : _b.nodeType) === Node.DOCUMENT_FRAGMENT_NODE &&
1495
- n.getRootNode().host)
1496
- shadowHost = n.getRootNode().host;
1497
- return shadowHost;
1498
- }
1499
- function getRootShadowHost(n) {
1500
- let rootShadowHost = n;
1501
- let shadowHost;
1502
- while ((shadowHost = getShadowHost(rootShadowHost)))
1503
- rootShadowHost = shadowHost;
1504
- return rootShadowHost;
1505
- }
1506
- function shadowHostInDom(n) {
1507
- const doc = n.ownerDocument;
1508
- if (!doc)
1509
- return false;
1510
- const shadowHost = getRootShadowHost(n);
1511
- return doc.contains(shadowHost);
1512
- }
1513
- function inDom(n) {
1514
- const doc = n.ownerDocument;
1515
- if (!doc)
1516
- return false;
1517
- return doc.contains(n) || shadowHostInDom(n);
1518
- }
1519
-
1520
- var EventType = /* @__PURE__ */ ((EventType2) => {
1521
- EventType2[EventType2["DomContentLoaded"] = 0] = "DomContentLoaded";
1522
- EventType2[EventType2["Load"] = 1] = "Load";
1523
- EventType2[EventType2["FullSnapshot"] = 2] = "FullSnapshot";
1524
- EventType2[EventType2["IncrementalSnapshot"] = 3] = "IncrementalSnapshot";
1525
- EventType2[EventType2["Meta"] = 4] = "Meta";
1526
- EventType2[EventType2["Custom"] = 5] = "Custom";
1527
- EventType2[EventType2["Plugin"] = 6] = "Plugin";
1528
- return EventType2;
1529
- })(EventType || {});
1530
- var IncrementalSource = /* @__PURE__ */ ((IncrementalSource2) => {
1531
- IncrementalSource2[IncrementalSource2["Mutation"] = 0] = "Mutation";
1532
- IncrementalSource2[IncrementalSource2["MouseMove"] = 1] = "MouseMove";
1533
- IncrementalSource2[IncrementalSource2["MouseInteraction"] = 2] = "MouseInteraction";
1534
- IncrementalSource2[IncrementalSource2["Scroll"] = 3] = "Scroll";
1535
- IncrementalSource2[IncrementalSource2["ViewportResize"] = 4] = "ViewportResize";
1536
- IncrementalSource2[IncrementalSource2["Input"] = 5] = "Input";
1537
- IncrementalSource2[IncrementalSource2["TouchMove"] = 6] = "TouchMove";
1538
- IncrementalSource2[IncrementalSource2["MediaInteraction"] = 7] = "MediaInteraction";
1539
- IncrementalSource2[IncrementalSource2["StyleSheetRule"] = 8] = "StyleSheetRule";
1540
- IncrementalSource2[IncrementalSource2["CanvasMutation"] = 9] = "CanvasMutation";
1541
- IncrementalSource2[IncrementalSource2["Font"] = 10] = "Font";
1542
- IncrementalSource2[IncrementalSource2["Log"] = 11] = "Log";
1543
- IncrementalSource2[IncrementalSource2["Drag"] = 12] = "Drag";
1544
- IncrementalSource2[IncrementalSource2["StyleDeclaration"] = 13] = "StyleDeclaration";
1545
- IncrementalSource2[IncrementalSource2["Selection"] = 14] = "Selection";
1546
- IncrementalSource2[IncrementalSource2["AdoptedStyleSheet"] = 15] = "AdoptedStyleSheet";
1547
- IncrementalSource2[IncrementalSource2["CustomElement"] = 16] = "CustomElement";
1548
- return IncrementalSource2;
1549
- })(IncrementalSource || {});
1550
- var MouseInteractions = /* @__PURE__ */ ((MouseInteractions2) => {
1551
- MouseInteractions2[MouseInteractions2["MouseUp"] = 0] = "MouseUp";
1552
- MouseInteractions2[MouseInteractions2["MouseDown"] = 1] = "MouseDown";
1553
- MouseInteractions2[MouseInteractions2["Click"] = 2] = "Click";
1554
- MouseInteractions2[MouseInteractions2["ContextMenu"] = 3] = "ContextMenu";
1555
- MouseInteractions2[MouseInteractions2["DblClick"] = 4] = "DblClick";
1556
- MouseInteractions2[MouseInteractions2["Focus"] = 5] = "Focus";
1557
- MouseInteractions2[MouseInteractions2["Blur"] = 6] = "Blur";
1558
- MouseInteractions2[MouseInteractions2["TouchStart"] = 7] = "TouchStart";
1559
- MouseInteractions2[MouseInteractions2["TouchMove_Departed"] = 8] = "TouchMove_Departed";
1560
- MouseInteractions2[MouseInteractions2["TouchEnd"] = 9] = "TouchEnd";
1561
- MouseInteractions2[MouseInteractions2["TouchCancel"] = 10] = "TouchCancel";
1562
- return MouseInteractions2;
1563
- })(MouseInteractions || {});
1564
- var PointerTypes = /* @__PURE__ */ ((PointerTypes2) => {
1565
- PointerTypes2[PointerTypes2["Mouse"] = 0] = "Mouse";
1566
- PointerTypes2[PointerTypes2["Pen"] = 1] = "Pen";
1567
- PointerTypes2[PointerTypes2["Touch"] = 2] = "Touch";
1568
- return PointerTypes2;
1569
- })(PointerTypes || {});
1570
- var CanvasContext = /* @__PURE__ */ ((CanvasContext2) => {
1571
- CanvasContext2[CanvasContext2["2D"] = 0] = "2D";
1572
- CanvasContext2[CanvasContext2["WebGL"] = 1] = "WebGL";
1573
- CanvasContext2[CanvasContext2["WebGL2"] = 2] = "WebGL2";
1574
- return CanvasContext2;
1575
- })(CanvasContext || {});
1576
1323
 
1577
1324
  function isNodeInLinkedList(n) {
1578
1325
  return '__ln' in n;
@@ -1581,7 +1328,6 @@ class DoubleLinkedList {
1581
1328
  constructor() {
1582
1329
  this.length = 0;
1583
1330
  this.head = null;
1584
- this.tail = null;
1585
1331
  }
1586
1332
  get(position) {
1587
1333
  if (position >= this.length) {
@@ -1627,9 +1373,6 @@ class DoubleLinkedList {
1627
1373
  node.next = this.head;
1628
1374
  this.head = node;
1629
1375
  }
1630
- if (node.next === null) {
1631
- this.tail = node;
1632
- }
1633
1376
  this.length++;
1634
1377
  }
1635
1378
  removeNode(n) {
@@ -1642,18 +1385,12 @@ class DoubleLinkedList {
1642
1385
  if (this.head) {
1643
1386
  this.head.previous = null;
1644
1387
  }
1645
- else {
1646
- this.tail = null;
1647
- }
1648
1388
  }
1649
1389
  else {
1650
1390
  current.previous.next = current.next;
1651
1391
  if (current.next) {
1652
1392
  current.next.previous = current.previous;
1653
1393
  }
1654
- else {
1655
- this.tail = current.previous;
1656
- }
1657
1394
  }
1658
1395
  if (n.__ln) {
1659
1396
  delete n.__ln;
@@ -1662,6 +1399,9 @@ class DoubleLinkedList {
1662
1399
  }
1663
1400
  }
1664
1401
  const moveKey = (id, parentId) => `${id}@${parentId}`;
1402
+ function isINode(n) {
1403
+ return '__sn' in n;
1404
+ }
1665
1405
  class MutationBuffer {
1666
1406
  constructor() {
1667
1407
  this.frozen = false;
@@ -1683,7 +1423,6 @@ class MutationBuffer {
1683
1423
  return;
1684
1424
  }
1685
1425
  const adds = [];
1686
- const addedIds = new Set();
1687
1426
  const addList = new DoubleLinkedList();
1688
1427
  const getNextId = (n) => {
1689
1428
  let ns = n;
@@ -1695,56 +1434,59 @@ class MutationBuffer {
1695
1434
  return nextId;
1696
1435
  };
1697
1436
  const pushAdd = (n) => {
1698
- if (!n.parentNode || !inDom(n)) {
1437
+ var _a, _b, _c, _d, _e;
1438
+ const shadowHost = n.getRootNode
1439
+ ? (_a = n.getRootNode()) === null || _a === void 0 ? void 0 : _a.host
1440
+ : null;
1441
+ let rootShadowHost = shadowHost;
1442
+ while ((_c = (_b = rootShadowHost === null || rootShadowHost === void 0 ? void 0 : rootShadowHost.getRootNode) === null || _b === void 0 ? void 0 : _b.call(rootShadowHost)) === null || _c === void 0 ? void 0 : _c.host)
1443
+ rootShadowHost =
1444
+ ((_e = (_d = rootShadowHost === null || rootShadowHost === void 0 ? void 0 : rootShadowHost.getRootNode) === null || _d === void 0 ? void 0 : _d.call(rootShadowHost)) === null || _e === void 0 ? void 0 : _e.host) ||
1445
+ null;
1446
+ const notInDoc = !this.doc.contains(n) &&
1447
+ (!rootShadowHost || !this.doc.contains(rootShadowHost));
1448
+ if (!n.parentNode || notInDoc) {
1699
1449
  return;
1700
1450
  }
1701
1451
  const parentId = isShadowRoot(n.parentNode)
1702
- ? this.mirror.getId(getShadowHost(n))
1452
+ ? this.mirror.getId(shadowHost)
1703
1453
  : this.mirror.getId(n.parentNode);
1704
1454
  const nextId = getNextId(n);
1705
1455
  if (parentId === -1 || nextId === -1) {
1706
1456
  return addList.addNode(n);
1707
1457
  }
1708
- const sn = serializeNodeWithId(n, {
1458
+ let sn = serializeNodeWithId(n, {
1709
1459
  doc: this.doc,
1710
- mirror: this.mirror,
1460
+ map: this.mirror.map,
1711
1461
  blockClass: this.blockClass,
1712
1462
  blockSelector: this.blockSelector,
1713
- maskAllText: this.maskAllText,
1714
1463
  unblockSelector: this.unblockSelector,
1715
1464
  maskTextClass: this.maskTextClass,
1716
- unmaskTextClass: this.unmaskTextClass,
1717
1465
  maskTextSelector: this.maskTextSelector,
1718
1466
  unmaskTextSelector: this.unmaskTextSelector,
1467
+ maskInputSelector: this.maskInputSelector,
1468
+ unmaskInputSelector: this.unmaskInputSelector,
1719
1469
  skipChild: true,
1720
- newlyAddedElement: true,
1721
1470
  inlineStylesheet: this.inlineStylesheet,
1471
+ maskAllText: this.maskAllText,
1722
1472
  maskInputOptions: this.maskInputOptions,
1723
- maskAttributeFn: this.maskAttributeFn,
1724
1473
  maskTextFn: this.maskTextFn,
1725
1474
  maskInputFn: this.maskInputFn,
1726
1475
  slimDOMOptions: this.slimDOMOptions,
1727
- dataURLOptions: this.dataURLOptions,
1728
1476
  recordCanvas: this.recordCanvas,
1729
1477
  inlineImages: this.inlineImages,
1730
1478
  onSerialize: (currentN) => {
1731
- if (isSerializedIframe(currentN, this.mirror)) {
1479
+ if (isIframeINode(currentN)) {
1732
1480
  this.iframeManager.addIframe(currentN);
1733
1481
  }
1734
- if (isSerializedStylesheet(currentN, this.mirror)) {
1735
- this.stylesheetManager.trackLinkElement(currentN);
1736
- }
1737
1482
  if (hasShadowRoot(n)) {
1738
- this.shadowDomManager.addShadowRoot(n.shadowRoot, this.doc);
1483
+ this.shadowDomManager.addShadowRoot(n.shadowRoot, document);
1739
1484
  }
1740
1485
  },
1741
1486
  onIframeLoad: (iframe, childSn) => {
1742
1487
  this.iframeManager.attachIframe(iframe, childSn);
1743
1488
  this.shadowDomManager.observeAttachShadow(iframe);
1744
1489
  },
1745
- onStylesheetLoad: (link, childSn) => {
1746
- this.stylesheetManager.attachLinkElement(link, childSn);
1747
- },
1748
1490
  });
1749
1491
  if (sn) {
1750
1492
  adds.push({
@@ -1752,7 +1494,6 @@ class MutationBuffer {
1752
1494
  nextId,
1753
1495
  node: sn,
1754
1496
  });
1755
- addedIds.add(sn.id);
1756
1497
  }
1757
1498
  };
1758
1499
  while (this.mapRemoves.length) {
@@ -1788,33 +1529,15 @@ class MutationBuffer {
1788
1529
  }
1789
1530
  }
1790
1531
  if (!node) {
1791
- let tailNode = addList.tail;
1792
- while (tailNode) {
1793
- const _node = tailNode;
1794
- tailNode = tailNode.previous;
1532
+ for (let index = addList.length - 1; index >= 0; index--) {
1533
+ const _node = addList.get(index);
1795
1534
  if (_node) {
1796
1535
  const parentId = this.mirror.getId(_node.value.parentNode);
1797
1536
  const nextId = getNextId(_node.value);
1798
- if (nextId === -1)
1799
- continue;
1800
- else if (parentId !== -1) {
1537
+ if (parentId !== -1 && nextId !== -1) {
1801
1538
  node = _node;
1802
1539
  break;
1803
1540
  }
1804
- else {
1805
- const unhandledNode = _node.value;
1806
- if (unhandledNode.parentNode &&
1807
- unhandledNode.parentNode.nodeType ===
1808
- Node.DOCUMENT_FRAGMENT_NODE) {
1809
- const shadowHost = unhandledNode.parentNode
1810
- .host;
1811
- const parentId = this.mirror.getId(shadowHost);
1812
- if (parentId !== -1) {
1813
- node = _node;
1814
- break;
1815
- }
1816
- }
1817
- }
1818
1541
  }
1819
1542
  }
1820
1543
  }
@@ -1834,27 +1557,12 @@ class MutationBuffer {
1834
1557
  id: this.mirror.getId(text.node),
1835
1558
  value: text.value,
1836
1559
  }))
1837
- .filter((text) => !addedIds.has(text.id))
1838
1560
  .filter((text) => this.mirror.has(text.id)),
1839
1561
  attributes: this.attributes
1840
- .map((attribute) => {
1841
- const { attributes } = attribute;
1842
- if (typeof attributes.style === 'string') {
1843
- const diffAsStr = JSON.stringify(attribute.styleDiff);
1844
- const unchangedAsStr = JSON.stringify(attribute._unchangedStyles);
1845
- if (diffAsStr.length < attributes.style.length) {
1846
- if ((diffAsStr + unchangedAsStr).split('var(').length ===
1847
- attributes.style.split('var(').length) {
1848
- attributes.style = attribute.styleDiff;
1849
- }
1850
- }
1851
- }
1852
- return {
1853
- id: this.mirror.getId(attribute.node),
1854
- attributes: attributes,
1855
- };
1856
- })
1857
- .filter((attribute) => !addedIds.has(attribute.id))
1562
+ .map((attribute) => ({
1563
+ id: this.mirror.getId(attribute.node),
1564
+ attributes: attribute.attributes,
1565
+ }))
1858
1566
  .filter((attribute) => this.mirror.has(attribute.id)),
1859
1567
  removes: this.removes,
1860
1568
  adds,
@@ -1875,23 +1583,15 @@ class MutationBuffer {
1875
1583
  this.mutationCb(payload);
1876
1584
  };
1877
1585
  this.processMutation = (m) => {
1878
- if (isIgnored(m.target, this.mirror)) {
1586
+ if (isIgnored(m.target)) {
1879
1587
  return;
1880
1588
  }
1881
- let unattachedDoc;
1882
- try {
1883
- unattachedDoc = document.implementation.createHTMLDocument();
1884
- }
1885
- catch (e) {
1886
- unattachedDoc = this.doc;
1887
- }
1888
1589
  switch (m.type) {
1889
1590
  case 'characterData': {
1890
1591
  const value = m.target.textContent;
1891
- if (!isBlocked(m.target, this.blockClass, this.blockSelector, this.unblockSelector, false) &&
1892
- value !== m.oldValue) {
1592
+ if (!isBlocked(m.target, this.blockClass, this.blockSelector, this.unblockSelector) && value !== m.oldValue) {
1893
1593
  this.texts.push({
1894
- value: needMaskingText(m.target, this.maskTextClass, this.maskTextSelector, this.unmaskTextClass, this.unmaskTextSelector, this.maskAllText) && value
1594
+ value: needMaskingText(m.target, this.maskTextClass, this.maskTextSelector, this.unmaskTextSelector, this.maskAllText) && value
1895
1595
  ? this.maskTextFn
1896
1596
  ? this.maskTextFn(value)
1897
1597
  : value.replace(/[\S]/g, '*')
@@ -1903,99 +1603,83 @@ class MutationBuffer {
1903
1603
  }
1904
1604
  case 'attributes': {
1905
1605
  const target = m.target;
1906
- let attributeName = m.attributeName;
1907
- let value = m.target.getAttribute(attributeName);
1908
- if (attributeName === 'value') {
1909
- const type = getInputType(target);
1910
- const tagName = target.tagName;
1911
- value = getInputValue(target, tagName, type);
1912
- const isInputMasked = shouldMaskInput({
1913
- maskInputOptions: this.maskInputOptions,
1914
- tagName,
1915
- type,
1916
- });
1917
- const forceMask = needMaskingText(m.target, this.maskTextClass, this.maskTextSelector, this.unmaskTextClass, this.unmaskTextSelector, isInputMasked);
1606
+ let value = target.getAttribute(m.attributeName);
1607
+ if (m.attributeName === 'value') {
1918
1608
  value = maskInputValue({
1919
- isMasked: forceMask,
1920
- element: target,
1609
+ input: target,
1610
+ maskInputSelector: this.maskInputSelector,
1611
+ unmaskInputSelector: this.unmaskInputSelector,
1612
+ maskInputOptions: this.maskInputOptions,
1613
+ tagName: target.tagName,
1614
+ type: target.getAttribute('type'),
1921
1615
  value,
1922
1616
  maskInputFn: this.maskInputFn,
1923
1617
  });
1924
1618
  }
1925
- if (isBlocked(m.target, this.blockClass, this.blockSelector, this.unblockSelector, false) ||
1926
- value === m.oldValue) {
1619
+ if (isBlocked(m.target, this.blockClass, this.blockSelector, this.unblockSelector) || value === m.oldValue) {
1927
1620
  return;
1928
1621
  }
1929
1622
  let item = this.attributes.find((a) => a.node === m.target);
1930
- if (target.tagName === 'IFRAME' &&
1931
- attributeName === 'src' &&
1932
- !this.keepIframeSrcFn(value)) {
1933
- if (!target.contentDocument) {
1934
- attributeName = 'rr_src';
1935
- }
1936
- else {
1937
- return;
1938
- }
1939
- }
1940
1623
  if (!item) {
1941
1624
  item = {
1942
1625
  node: m.target,
1943
1626
  attributes: {},
1944
- styleDiff: {},
1945
- _unchangedStyles: {},
1946
1627
  };
1947
1628
  this.attributes.push(item);
1948
1629
  }
1949
- if (attributeName === 'type' &&
1630
+ if (m.attributeName === 'type' &&
1950
1631
  target.tagName === 'INPUT' &&
1951
1632
  (m.oldValue || '').toLowerCase() === 'password') {
1952
1633
  target.setAttribute('data-rr-is-password', 'true');
1953
1634
  }
1954
- if (!ignoreAttribute(target.tagName, attributeName)) {
1955
- item.attributes[attributeName] = transformAttribute(this.doc, toLowerCase(target.tagName), toLowerCase(attributeName), value, target, this.maskAttributeFn);
1956
- if (attributeName === 'style') {
1957
- const old = unattachedDoc.createElement('span');
1958
- if (m.oldValue) {
1959
- old.setAttribute('style', m.oldValue);
1960
- }
1635
+ if (m.attributeName === 'style') {
1636
+ const old = this.doc.createElement('span');
1637
+ if (m.oldValue) {
1638
+ old.setAttribute('style', m.oldValue);
1639
+ }
1640
+ if (item.attributes.style === undefined ||
1641
+ item.attributes.style === null) {
1642
+ item.attributes.style = {};
1643
+ }
1644
+ try {
1645
+ const styleObj = item.attributes.style;
1961
1646
  for (const pname of Array.from(target.style)) {
1962
1647
  const newValue = target.style.getPropertyValue(pname);
1963
1648
  const newPriority = target.style.getPropertyPriority(pname);
1964
1649
  if (newValue !== old.style.getPropertyValue(pname) ||
1965
1650
  newPriority !== old.style.getPropertyPriority(pname)) {
1966
1651
  if (newPriority === '') {
1967
- item.styleDiff[pname] = newValue;
1652
+ styleObj[pname] = newValue;
1968
1653
  }
1969
1654
  else {
1970
- item.styleDiff[pname] = [newValue, newPriority];
1655
+ styleObj[pname] = [newValue, newPriority];
1971
1656
  }
1972
1657
  }
1973
- else {
1974
- item._unchangedStyles[pname] = [newValue, newPriority];
1975
- }
1976
1658
  }
1977
1659
  for (const pname of Array.from(old.style)) {
1978
1660
  if (target.style.getPropertyValue(pname) === '') {
1979
- item.styleDiff[pname] = false;
1661
+ styleObj[pname] = false;
1980
1662
  }
1981
1663
  }
1982
1664
  }
1665
+ catch (error) {
1666
+ console.warn('[rrweb] Error when parsing update to style attribute:', error);
1667
+ }
1668
+ }
1669
+ else {
1670
+ const element = m.target;
1671
+ item.attributes[m.attributeName] = transformAttribute(this.doc, element, element.tagName, m.attributeName, value, this.maskAllText, this.unmaskTextSelector, this.maskTextFn);
1983
1672
  }
1984
1673
  break;
1985
1674
  }
1986
1675
  case 'childList': {
1987
- if (isBlocked(m.target, this.blockClass, this.blockSelector, this.unblockSelector, true)) {
1988
- return;
1989
- }
1990
1676
  m.addedNodes.forEach((n) => this.genAdds(n, m.target));
1991
1677
  m.removedNodes.forEach((n) => {
1992
1678
  const nodeId = this.mirror.getId(n);
1993
1679
  const parentId = isShadowRoot(m.target)
1994
1680
  ? this.mirror.getId(m.target.host)
1995
1681
  : this.mirror.getId(m.target);
1996
- if (isBlocked(m.target, this.blockClass, this.blockSelector, this.unblockSelector, false) ||
1997
- isIgnored(n, this.mirror) ||
1998
- !isSerialized(n, this.mirror)) {
1682
+ if (isBlocked(m.target, this.blockClass, this.blockSelector, this.unblockSelector) || isIgnored(n)) {
1999
1683
  return;
2000
1684
  }
2001
1685
  if (this.addedSet.has(n)) {
@@ -2012,9 +1696,7 @@ class MutationBuffer {
2012
1696
  this.removes.push({
2013
1697
  parentId,
2014
1698
  id: nodeId,
2015
- isShadow: isShadowRoot(m.target) && isNativeShadowDom(m.target)
2016
- ? true
2017
- : undefined,
1699
+ isShadow: isShadowRoot(m.target) ? true : undefined,
2018
1700
  });
2019
1701
  }
2020
1702
  this.mapRemoves.push(n);
@@ -2024,36 +1706,28 @@ class MutationBuffer {
2024
1706
  }
2025
1707
  };
2026
1708
  this.genAdds = (n, target) => {
2027
- if (this.processedNodeManager.inOtherBuffer(n, this))
2028
- return;
2029
- if (this.addedSet.has(n) || this.movedSet.has(n))
1709
+ if (target && isBlocked(target, this.blockClass, this.blockSelector, this.unblockSelector)) {
2030
1710
  return;
2031
- if (this.mirror.hasNode(n)) {
2032
- if (isIgnored(n, this.mirror)) {
1711
+ }
1712
+ if (isINode(n)) {
1713
+ if (isIgnored(n)) {
2033
1714
  return;
2034
1715
  }
2035
1716
  this.movedSet.add(n);
2036
1717
  let targetId = null;
2037
- if (target && this.mirror.hasNode(target)) {
2038
- targetId = this.mirror.getId(target);
1718
+ if (target && isINode(target)) {
1719
+ targetId = target.__sn.id;
2039
1720
  }
2040
- if (targetId && targetId !== -1) {
2041
- this.movedMap[moveKey(this.mirror.getId(n), targetId)] = true;
1721
+ if (targetId) {
1722
+ this.movedMap[moveKey(n.__sn.id, targetId)] = true;
2042
1723
  }
2043
1724
  }
2044
1725
  else {
2045
1726
  this.addedSet.add(n);
2046
1727
  this.droppedSet.delete(n);
2047
1728
  }
2048
- if (!isBlocked(n, this.blockClass, this.blockSelector, this.unblockSelector, false)) {
1729
+ if (!isBlocked(n, this.blockClass, this.blockSelector, this.unblockSelector))
2049
1730
  n.childNodes.forEach((childN) => this.genAdds(childN));
2050
- if (hasShadowRoot(n)) {
2051
- n.shadowRoot.childNodes.forEach((childN) => {
2052
- this.processedNodeManager.add(childN, this);
2053
- this.genAdds(childN, n);
2054
- });
2055
- }
2056
- }
2057
1731
  };
2058
1732
  }
2059
1733
  init(options) {
@@ -2062,28 +1736,24 @@ class MutationBuffer {
2062
1736
  'blockClass',
2063
1737
  'blockSelector',
2064
1738
  'unblockSelector',
2065
- 'maskAllText',
2066
1739
  'maskTextClass',
2067
- 'unmaskTextClass',
2068
1740
  'maskTextSelector',
2069
1741
  'unmaskTextSelector',
1742
+ 'maskInputSelector',
1743
+ 'unmaskInputSelector',
2070
1744
  'inlineStylesheet',
1745
+ 'maskAllText',
2071
1746
  'maskInputOptions',
2072
- 'maskAttributeFn',
2073
1747
  'maskTextFn',
2074
1748
  'maskInputFn',
2075
- 'keepIframeSrcFn',
2076
1749
  'recordCanvas',
2077
1750
  'inlineImages',
2078
1751
  'slimDOMOptions',
2079
- 'dataURLOptions',
2080
1752
  'doc',
2081
1753
  'mirror',
2082
1754
  'iframeManager',
2083
- 'stylesheetManager',
2084
1755
  'shadowDomManager',
2085
1756
  'canvasManager',
2086
- 'processedNodeManager',
2087
1757
  ].forEach((key) => {
2088
1758
  this[key] = options[key];
2089
1759
  });
@@ -2119,11 +1789,6 @@ function deepDelete(addsSet, n) {
2119
1789
  n.childNodes.forEach((childN) => deepDelete(addsSet, childN));
2120
1790
  }
2121
1791
  function isParentRemoved(removes, n, mirror) {
2122
- if (removes.length === 0)
2123
- return false;
2124
- return _isParentRemoved(removes, n, mirror);
2125
- }
2126
- function _isParentRemoved(removes, n, mirror) {
2127
1792
  const { parentNode } = n;
2128
1793
  if (!parentNode) {
2129
1794
  return false;
@@ -2132,14 +1797,9 @@ function _isParentRemoved(removes, n, mirror) {
2132
1797
  if (removes.some((r) => r.id === parentId)) {
2133
1798
  return true;
2134
1799
  }
2135
- return _isParentRemoved(removes, parentNode, mirror);
1800
+ return isParentRemoved(removes, parentNode, mirror);
2136
1801
  }
2137
1802
  function isAncestorInSet(set, n) {
2138
- if (set.size === 0)
2139
- return false;
2140
- return _isAncestorInSet(set, n);
2141
- }
2142
- function _isAncestorInSet(set, n) {
2143
1803
  const { parentNode } = n;
2144
1804
  if (!parentNode) {
2145
1805
  return false;
@@ -2147,31 +1807,23 @@ function _isAncestorInSet(set, n) {
2147
1807
  if (set.has(parentNode)) {
2148
1808
  return true;
2149
1809
  }
2150
- return _isAncestorInSet(set, parentNode);
1810
+ return isAncestorInSet(set, parentNode);
2151
1811
  }
2152
1812
 
2153
- let errorHandler;
2154
- function registerErrorHandler(handler) {
2155
- errorHandler = handler;
2156
- }
2157
- function unregisterErrorHandler() {
2158
- errorHandler = undefined;
2159
- }
2160
1813
  const callbackWrapper = (cb) => {
2161
- if (!errorHandler) {
2162
- return cb;
2163
- }
2164
- const rrwebWrapped = ((...rest) => {
1814
+ const rrwebWrapped = (...rest) => {
2165
1815
  try {
2166
1816
  return cb(...rest);
2167
1817
  }
2168
1818
  catch (error) {
2169
- if (errorHandler && errorHandler(error) === true) {
2170
- return;
1819
+ try {
1820
+ error.__rrweb__ = true;
1821
+ }
1822
+ catch (_a) {
2171
1823
  }
2172
1824
  throw error;
2173
1825
  }
2174
- });
1826
+ };
2175
1827
  return rrwebWrapped;
2176
1828
  };
2177
1829
 
@@ -2188,8 +1840,7 @@ function getEventTarget(event) {
2188
1840
  return event.path[0];
2189
1841
  }
2190
1842
  }
2191
- catch (_a) {
2192
- }
1843
+ catch (_a) { }
2193
1844
  return event && event.target;
2194
1845
  }
2195
1846
  function initMutationObserver(options, rootEl) {
@@ -2208,7 +1859,7 @@ function initMutationObserver(options, rootEl) {
2208
1859
  if (options.onMutation && options.onMutation(mutations) === false) {
2209
1860
  return;
2210
1861
  }
2211
- mutationBuffer.processMutations.bind(mutationBuffer)(mutations);
1862
+ mutationBuffer.processMutations(mutations);
2212
1863
  }));
2213
1864
  observer.observe(rootEl, {
2214
1865
  attributes: true,
@@ -2222,8 +1873,7 @@ function initMutationObserver(options, rootEl) {
2222
1873
  }
2223
1874
  function initMoveObserver({ mousemoveCb, sampling, doc, mirror, }) {
2224
1875
  if (sampling.mousemove === false) {
2225
- return () => {
2226
- };
1876
+ return () => { };
2227
1877
  }
2228
1878
  const threshold = typeof sampling.mousemove === 'number' ? sampling.mousemove : 50;
2229
1879
  const callbackThreshold = typeof sampling.mousemoveCallback === 'number'
@@ -2231,41 +1881,41 @@ function initMoveObserver({ mousemoveCb, sampling, doc, mirror, }) {
2231
1881
  : 500;
2232
1882
  let positions = [];
2233
1883
  let timeBaseline;
2234
- const wrappedCb = throttle$1(callbackWrapper((source) => {
1884
+ const wrappedCb = throttle$1((source) => {
2235
1885
  const totalOffset = Date.now() - timeBaseline;
2236
- mousemoveCb(positions.map((p) => {
1886
+ callbackWrapper(mousemoveCb)(positions.map((p) => {
2237
1887
  p.timeOffset -= totalOffset;
2238
1888
  return p;
2239
1889
  }), source);
2240
1890
  positions = [];
2241
1891
  timeBaseline = null;
2242
- }), callbackThreshold);
2243
- const updatePosition = callbackWrapper(throttle$1(callbackWrapper((evt) => {
1892
+ }, callbackThreshold);
1893
+ const updatePosition = throttle$1((evt) => {
2244
1894
  const target = getEventTarget(evt);
2245
- const { clientX, clientY } = legacy_isTouchEvent(evt)
1895
+ const { clientX, clientY } = isTouchEvent(evt)
2246
1896
  ? evt.changedTouches[0]
2247
1897
  : evt;
2248
1898
  if (!timeBaseline) {
2249
- timeBaseline = nowTimestamp();
1899
+ timeBaseline = Date.now();
2250
1900
  }
2251
1901
  positions.push({
2252
1902
  x: clientX,
2253
1903
  y: clientY,
2254
1904
  id: mirror.getId(target),
2255
- timeOffset: nowTimestamp() - timeBaseline,
1905
+ timeOffset: Date.now() - timeBaseline,
2256
1906
  });
2257
1907
  wrappedCb(typeof DragEvent !== 'undefined' && evt instanceof DragEvent
2258
1908
  ? IncrementalSource.Drag
2259
1909
  : evt instanceof MouseEvent
2260
1910
  ? IncrementalSource.MouseMove
2261
1911
  : IncrementalSource.TouchMove);
2262
- }), threshold, {
1912
+ }, threshold, {
2263
1913
  trailing: false,
2264
- }));
1914
+ });
2265
1915
  const handlers = [
2266
- on('mousemove', updatePosition, doc),
2267
- on('touchmove', updatePosition, doc),
2268
- on('drag', updatePosition, doc),
1916
+ on('mousemove', callbackWrapper(updatePosition), doc),
1917
+ on('touchmove', callbackWrapper(updatePosition), doc),
1918
+ on('drag', callbackWrapper(updatePosition), doc),
2269
1919
  ];
2270
1920
  return callbackWrapper(() => {
2271
1921
  handlers.forEach((h) => h());
@@ -2273,68 +1923,31 @@ function initMoveObserver({ mousemoveCb, sampling, doc, mirror, }) {
2273
1923
  }
2274
1924
  function initMouseInteractionObserver({ mouseInteractionCb, doc, mirror, blockClass, blockSelector, unblockSelector, sampling, }) {
2275
1925
  if (sampling.mouseInteraction === false) {
2276
- return () => {
2277
- };
1926
+ return () => { };
2278
1927
  }
2279
1928
  const disableMap = sampling.mouseInteraction === true ||
2280
1929
  sampling.mouseInteraction === undefined
2281
1930
  ? {}
2282
1931
  : sampling.mouseInteraction;
2283
1932
  const handlers = [];
2284
- let currentPointerType = null;
2285
1933
  const getHandler = (eventKey) => {
2286
1934
  return (event) => {
2287
1935
  const target = getEventTarget(event);
2288
- if (isBlocked(target, blockClass, blockSelector, unblockSelector, true)) {
1936
+ if (isBlocked(target, blockClass, blockSelector, unblockSelector)) {
2289
1937
  return;
2290
1938
  }
2291
- let pointerType = null;
2292
- let thisEventKey = eventKey;
2293
- if ('pointerType' in event) {
2294
- switch (event.pointerType) {
2295
- case 'mouse':
2296
- pointerType = PointerTypes.Mouse;
2297
- break;
2298
- case 'touch':
2299
- pointerType = PointerTypes.Touch;
2300
- break;
2301
- case 'pen':
2302
- pointerType = PointerTypes.Pen;
2303
- break;
2304
- }
2305
- if (pointerType === PointerTypes.Touch) {
2306
- if (MouseInteractions[eventKey] === MouseInteractions.MouseDown) {
2307
- thisEventKey = 'TouchStart';
2308
- }
2309
- else if (MouseInteractions[eventKey] === MouseInteractions.MouseUp) {
2310
- thisEventKey = 'TouchEnd';
2311
- }
2312
- }
2313
- else if (pointerType === PointerTypes.Pen) ;
2314
- }
2315
- else if (legacy_isTouchEvent(event)) {
2316
- pointerType = PointerTypes.Touch;
2317
- }
2318
- if (pointerType !== null) {
2319
- currentPointerType = pointerType;
2320
- if ((thisEventKey.startsWith('Touch') &&
2321
- pointerType === PointerTypes.Touch) ||
2322
- (thisEventKey.startsWith('Mouse') &&
2323
- pointerType === PointerTypes.Mouse)) {
2324
- pointerType = null;
2325
- }
2326
- }
2327
- else if (MouseInteractions[eventKey] === MouseInteractions.Click) {
2328
- pointerType = currentPointerType;
2329
- currentPointerType = null;
2330
- }
2331
- const e = legacy_isTouchEvent(event) ? event.changedTouches[0] : event;
1939
+ const e = isTouchEvent(event) ? event.changedTouches[0] : event;
2332
1940
  if (!e) {
2333
1941
  return;
2334
1942
  }
2335
1943
  const id = mirror.getId(target);
2336
1944
  const { clientX, clientY } = e;
2337
- callbackWrapper(mouseInteractionCb)(Object.assign({ type: MouseInteractions[thisEventKey], id, x: clientX, y: clientY }, (pointerType !== null && { pointerType })));
1945
+ callbackWrapper(mouseInteractionCb)({
1946
+ type: MouseInteractions[eventKey],
1947
+ id,
1948
+ x: clientX,
1949
+ y: clientY,
1950
+ });
2338
1951
  };
2339
1952
  };
2340
1953
  Object.keys(MouseInteractions)
@@ -2342,19 +1955,8 @@ function initMouseInteractionObserver({ mouseInteractionCb, doc, mirror, blockCl
2342
1955
  !key.endsWith('_Departed') &&
2343
1956
  disableMap[key] !== false)
2344
1957
  .forEach((eventKey) => {
2345
- let eventName = toLowerCase(eventKey);
2346
- const handler = getHandler(eventKey);
2347
- if (window.PointerEvent) {
2348
- switch (MouseInteractions[eventKey]) {
2349
- case MouseInteractions.MouseDown:
2350
- case MouseInteractions.MouseUp:
2351
- eventName = eventName.replace('mouse', 'pointer');
2352
- break;
2353
- case MouseInteractions.TouchStart:
2354
- case MouseInteractions.TouchEnd:
2355
- return;
2356
- }
2357
- }
1958
+ const eventName = eventKey.toLowerCase();
1959
+ const handler = callbackWrapper(getHandler(eventKey));
2358
1960
  handlers.push(on(eventName, handler, doc));
2359
1961
  });
2360
1962
  return callbackWrapper(() => {
@@ -2362,47 +1964,47 @@ function initMouseInteractionObserver({ mouseInteractionCb, doc, mirror, blockCl
2362
1964
  });
2363
1965
  }
2364
1966
  function initScrollObserver({ scrollCb, doc, mirror, blockClass, blockSelector, unblockSelector, sampling, }) {
2365
- const updatePosition = callbackWrapper(throttle$1(callbackWrapper((evt) => {
1967
+ const updatePosition = throttle$1((evt) => {
2366
1968
  const target = getEventTarget(evt);
2367
1969
  if (!target ||
2368
- isBlocked(target, blockClass, blockSelector, unblockSelector, true)) {
1970
+ isBlocked(target, blockClass, blockSelector, unblockSelector)) {
2369
1971
  return;
2370
1972
  }
2371
1973
  const id = mirror.getId(target);
2372
- if (target === doc && doc.defaultView) {
2373
- const scrollLeftTop = getWindowScroll(doc.defaultView);
2374
- scrollCb({
1974
+ if (target === doc) {
1975
+ const scrollEl = (doc.scrollingElement || doc.documentElement);
1976
+ callbackWrapper(scrollCb)({
2375
1977
  id,
2376
- x: scrollLeftTop.left,
2377
- y: scrollLeftTop.top,
1978
+ x: scrollEl.scrollLeft,
1979
+ y: scrollEl.scrollTop,
2378
1980
  });
2379
1981
  }
2380
1982
  else {
2381
- scrollCb({
1983
+ callbackWrapper(scrollCb)({
2382
1984
  id,
2383
1985
  x: target.scrollLeft,
2384
1986
  y: target.scrollTop,
2385
1987
  });
2386
1988
  }
2387
- }), sampling.scroll || 100));
2388
- return on('scroll', updatePosition, doc);
1989
+ }, sampling.scroll || 100);
1990
+ return on('scroll', callbackWrapper(updatePosition), doc);
2389
1991
  }
2390
- function initViewportResizeObserver({ viewportResizeCb }, { win }) {
1992
+ function initViewportResizeObserver({ viewportResizeCb, }) {
2391
1993
  let lastH = -1;
2392
1994
  let lastW = -1;
2393
- const updateDimension = callbackWrapper(throttle$1(callbackWrapper(() => {
1995
+ const updateDimension = throttle$1(() => {
2394
1996
  const height = getWindowHeight();
2395
1997
  const width = getWindowWidth();
2396
1998
  if (lastH !== height || lastW !== width) {
2397
- viewportResizeCb({
1999
+ callbackWrapper(viewportResizeCb)({
2398
2000
  width: Number(width),
2399
2001
  height: Number(height),
2400
2002
  });
2401
2003
  lastH = height;
2402
2004
  lastW = width;
2403
2005
  }
2404
- }), 200));
2405
- return on('resize', updateDimension, win);
2006
+ }, 200);
2007
+ return on('resize', callbackWrapper(updateDimension), window);
2406
2008
  }
2407
2009
  function wrapEventWithUserTriggeredFlag(v, enable) {
2408
2010
  const value = Object.assign({}, v);
@@ -2412,42 +2014,47 @@ function wrapEventWithUserTriggeredFlag(v, enable) {
2412
2014
  }
2413
2015
  const INPUT_TAGS = ['INPUT', 'TEXTAREA', 'SELECT'];
2414
2016
  const lastInputValueMap = new WeakMap();
2415
- function initInputObserver({ inputCb, doc, mirror, blockClass, blockSelector, unblockSelector, ignoreClass, ignoreSelector, maskInputOptions, maskInputFn, sampling, userTriggeredOnInput, maskTextClass, unmaskTextClass, maskTextSelector, unmaskTextSelector, }) {
2017
+ function initInputObserver({ inputCb, doc, mirror, blockClass, blockSelector, unblockSelector, ignoreClass, ignoreSelector, maskInputSelector, unmaskInputSelector, maskInputOptions, maskInputFn, sampling, userTriggeredOnInput, }) {
2416
2018
  function eventHandler(event) {
2417
2019
  let target = getEventTarget(event);
2020
+ const tagName = target && target.tagName;
2418
2021
  const userTriggered = event.isTrusted;
2419
- const tagName = target && toUpperCase(target.tagName);
2420
2022
  if (tagName === 'OPTION')
2421
2023
  target = target.parentElement;
2422
2024
  if (!target ||
2423
2025
  !tagName ||
2424
2026
  INPUT_TAGS.indexOf(tagName) < 0 ||
2425
- isBlocked(target, blockClass, blockSelector, unblockSelector, true)) {
2027
+ isBlocked(target, blockClass, blockSelector, unblockSelector)) {
2426
2028
  return;
2427
2029
  }
2428
2030
  const el = target;
2031
+ const type = getInputType(el);
2429
2032
  if (el.classList.contains(ignoreClass) ||
2430
2033
  (ignoreSelector && el.matches(ignoreSelector))) {
2431
2034
  return;
2432
2035
  }
2433
- const type = getInputType(target);
2434
2036
  let text = getInputValue(el, tagName, type);
2435
2037
  let isChecked = false;
2436
- const isInputMasked = shouldMaskInput({
2038
+ if (type === 'radio' || type === 'checkbox') {
2039
+ isChecked = target.checked;
2040
+ }
2041
+ if (hasInputMaskOptions({
2437
2042
  maskInputOptions,
2043
+ maskInputSelector,
2438
2044
  tagName,
2439
2045
  type,
2440
- });
2441
- const forceMask = needMaskingText(target, maskTextClass, maskTextSelector, unmaskTextClass, unmaskTextSelector, isInputMasked);
2442
- if (type === 'radio' || type === 'checkbox') {
2443
- isChecked = target.checked;
2046
+ })) {
2047
+ text = maskInputValue({
2048
+ input: el,
2049
+ maskInputOptions,
2050
+ maskInputSelector,
2051
+ unmaskInputSelector,
2052
+ tagName,
2053
+ type,
2054
+ value: text,
2055
+ maskInputFn,
2056
+ });
2444
2057
  }
2445
- text = maskInputValue({
2446
- isMasked: forceMask,
2447
- element: target,
2448
- value: text,
2449
- maskInputFn,
2450
- });
2451
2058
  cbWithDedup(target, callbackWrapper(wrapEventWithUserTriggeredFlag)({ text, isChecked, userTriggered }, userTriggeredOnInput));
2452
2059
  const name = target.name;
2453
2060
  if (type === 'radio' && name && isChecked) {
@@ -2456,8 +2063,12 @@ function initInputObserver({ inputCb, doc, mirror, blockClass, blockSelector, un
2456
2063
  .forEach((el) => {
2457
2064
  if (el !== target) {
2458
2065
  const text = maskInputValue({
2459
- isMasked: forceMask,
2460
- element: el,
2066
+ input: el,
2067
+ maskInputOptions,
2068
+ maskInputSelector,
2069
+ unmaskInputSelector,
2070
+ tagName,
2071
+ type,
2461
2072
  value: getInputValue(el, tagName, type),
2462
2073
  maskInputFn,
2463
2074
  });
@@ -2477,35 +2088,26 @@ function initInputObserver({ inputCb, doc, mirror, blockClass, blockSelector, un
2477
2088
  lastInputValue.isChecked !== v.isChecked) {
2478
2089
  lastInputValueMap.set(target, v);
2479
2090
  const id = mirror.getId(target);
2480
- callbackWrapper(inputCb)(Object.assign(Object.assign({}, v), { id }));
2091
+ inputCb(Object.assign(Object.assign({}, v), { id }));
2481
2092
  }
2482
2093
  }
2483
2094
  const events = sampling.input === 'last' ? ['change'] : ['input', 'change'];
2484
2095
  const handlers = events.map((eventName) => on(eventName, callbackWrapper(eventHandler), doc));
2485
- const currentWindow = doc.defaultView;
2486
- if (!currentWindow) {
2487
- return () => {
2488
- handlers.forEach((h) => h());
2489
- };
2490
- }
2491
- const propertyDescriptor = currentWindow.Object.getOwnPropertyDescriptor(currentWindow.HTMLInputElement.prototype, 'value');
2096
+ const propertyDescriptor = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value');
2492
2097
  const hookProperties = [
2493
- [currentWindow.HTMLInputElement.prototype, 'value'],
2494
- [currentWindow.HTMLInputElement.prototype, 'checked'],
2495
- [currentWindow.HTMLSelectElement.prototype, 'value'],
2496
- [currentWindow.HTMLTextAreaElement.prototype, 'value'],
2497
- [currentWindow.HTMLSelectElement.prototype, 'selectedIndex'],
2498
- [currentWindow.HTMLOptionElement.prototype, 'selected'],
2098
+ [HTMLInputElement.prototype, 'value'],
2099
+ [HTMLInputElement.prototype, 'checked'],
2100
+ [HTMLSelectElement.prototype, 'value'],
2101
+ [HTMLTextAreaElement.prototype, 'value'],
2102
+ [HTMLSelectElement.prototype, 'selectedIndex'],
2103
+ [HTMLOptionElement.prototype, 'selected'],
2499
2104
  ];
2500
2105
  if (propertyDescriptor && propertyDescriptor.set) {
2501
2106
  handlers.push(...hookProperties.map((p) => hookSetter(p[0], p[1], {
2502
2107
  set() {
2503
- callbackWrapper(eventHandler)({
2504
- target: this,
2505
- isTrusted: false,
2506
- });
2108
+ callbackWrapper(eventHandler)({ target: this });
2507
2109
  },
2508
- }, false, currentWindow)));
2110
+ })));
2509
2111
  }
2510
2112
  return callbackWrapper(() => {
2511
2113
  handlers.forEach((h) => h());
@@ -2526,7 +2128,7 @@ function getNestedCSSRulePositions(rule) {
2526
2128
  const index = rules.indexOf(childRule);
2527
2129
  pos.unshift(index);
2528
2130
  }
2529
- else if (childRule.parentStyleSheet) {
2131
+ else {
2530
2132
  const rules = Array.from(childRule.parentStyleSheet.cssRules);
2531
2133
  const index = rules.indexOf(childRule);
2532
2134
  pos.unshift(index);
@@ -2535,33 +2137,18 @@ function getNestedCSSRulePositions(rule) {
2535
2137
  }
2536
2138
  return recurse(rule, positions);
2537
2139
  }
2538
- function getIdAndStyleId(sheet, mirror, styleMirror) {
2539
- let id, styleId;
2540
- if (!sheet)
2541
- return {};
2542
- if (sheet.ownerNode)
2543
- id = mirror.getId(sheet.ownerNode);
2544
- else
2545
- styleId = styleMirror.getId(sheet);
2546
- return {
2547
- styleId,
2548
- id,
2549
- };
2550
- }
2551
- function initStyleSheetObserver({ styleSheetRuleCb, mirror, stylesheetManager }, { win }) {
2140
+ function initStyleSheetObserver({ styleSheetRuleCb, mirror }, { win }) {
2552
2141
  if (!win.CSSStyleSheet || !win.CSSStyleSheet.prototype) {
2553
- return () => {
2554
- };
2142
+ return () => { };
2555
2143
  }
2556
2144
  const insertRule = win.CSSStyleSheet.prototype.insertRule;
2557
2145
  win.CSSStyleSheet.prototype.insertRule = new Proxy(insertRule, {
2558
2146
  apply: callbackWrapper((target, thisArg, argumentsList) => {
2559
2147
  const [rule, index] = argumentsList;
2560
- const { id, styleId } = getIdAndStyleId(thisArg, mirror, stylesheetManager.styleMirror);
2561
- if ((id && id !== -1) || (styleId && styleId !== -1)) {
2148
+ const id = mirror.getId(thisArg.ownerNode);
2149
+ if (id !== -1) {
2562
2150
  styleSheetRuleCb({
2563
2151
  id,
2564
- styleId,
2565
2152
  adds: [{ rule, index }],
2566
2153
  });
2567
2154
  }
@@ -2572,53 +2159,16 @@ function initStyleSheetObserver({ styleSheetRuleCb, mirror, stylesheetManager },
2572
2159
  win.CSSStyleSheet.prototype.deleteRule = new Proxy(deleteRule, {
2573
2160
  apply: callbackWrapper((target, thisArg, argumentsList) => {
2574
2161
  const [index] = argumentsList;
2575
- const { id, styleId } = getIdAndStyleId(thisArg, mirror, stylesheetManager.styleMirror);
2576
- if ((id && id !== -1) || (styleId && styleId !== -1)) {
2162
+ const id = mirror.getId(thisArg.ownerNode);
2163
+ if (id !== -1) {
2577
2164
  styleSheetRuleCb({
2578
2165
  id,
2579
- styleId,
2580
2166
  removes: [{ index }],
2581
2167
  });
2582
2168
  }
2583
2169
  return target.apply(thisArg, argumentsList);
2584
2170
  }),
2585
2171
  });
2586
- let replace;
2587
- if (win.CSSStyleSheet.prototype.replace) {
2588
- replace = win.CSSStyleSheet.prototype.replace;
2589
- win.CSSStyleSheet.prototype.replace = new Proxy(replace, {
2590
- apply: callbackWrapper((target, thisArg, argumentsList) => {
2591
- const [text] = argumentsList;
2592
- const { id, styleId } = getIdAndStyleId(thisArg, mirror, stylesheetManager.styleMirror);
2593
- if ((id && id !== -1) || (styleId && styleId !== -1)) {
2594
- styleSheetRuleCb({
2595
- id,
2596
- styleId,
2597
- replace: text,
2598
- });
2599
- }
2600
- return target.apply(thisArg, argumentsList);
2601
- }),
2602
- });
2603
- }
2604
- let replaceSync;
2605
- if (win.CSSStyleSheet.prototype.replaceSync) {
2606
- replaceSync = win.CSSStyleSheet.prototype.replaceSync;
2607
- win.CSSStyleSheet.prototype.replaceSync = new Proxy(replaceSync, {
2608
- apply: callbackWrapper((target, thisArg, argumentsList) => {
2609
- const [text] = argumentsList;
2610
- const { id, styleId } = getIdAndStyleId(thisArg, mirror, stylesheetManager.styleMirror);
2611
- if ((id && id !== -1) || (styleId && styleId !== -1)) {
2612
- styleSheetRuleCb({
2613
- id,
2614
- styleId,
2615
- replaceSync: text,
2616
- });
2617
- }
2618
- return target.apply(thisArg, argumentsList);
2619
- }),
2620
- });
2621
- }
2622
2172
  const supportedNestedCSSRuleTypes = {};
2623
2173
  if (canMonkeyPatchNestedCSSRule('CSSGroupingRule')) {
2624
2174
  supportedNestedCSSRuleTypes.CSSGroupingRule = win.CSSGroupingRule;
@@ -2643,11 +2193,10 @@ function initStyleSheetObserver({ styleSheetRuleCb, mirror, stylesheetManager },
2643
2193
  type.prototype.insertRule = new Proxy(unmodifiedFunctions[typeKey].insertRule, {
2644
2194
  apply: callbackWrapper((target, thisArg, argumentsList) => {
2645
2195
  const [rule, index] = argumentsList;
2646
- const { id, styleId } = getIdAndStyleId(thisArg.parentStyleSheet, mirror, stylesheetManager.styleMirror);
2647
- if ((id && id !== -1) || (styleId && styleId !== -1)) {
2196
+ const id = mirror.getId(thisArg.parentStyleSheet.ownerNode);
2197
+ if (id !== -1) {
2648
2198
  styleSheetRuleCb({
2649
2199
  id,
2650
- styleId,
2651
2200
  adds: [
2652
2201
  {
2653
2202
  rule,
@@ -2665,11 +2214,10 @@ function initStyleSheetObserver({ styleSheetRuleCb, mirror, stylesheetManager },
2665
2214
  type.prototype.deleteRule = new Proxy(unmodifiedFunctions[typeKey].deleteRule, {
2666
2215
  apply: callbackWrapper((target, thisArg, argumentsList) => {
2667
2216
  const [index] = argumentsList;
2668
- const { id, styleId } = getIdAndStyleId(thisArg.parentStyleSheet, mirror, stylesheetManager.styleMirror);
2669
- if ((id && id !== -1) || (styleId && styleId !== -1)) {
2217
+ const id = mirror.getId(thisArg.parentStyleSheet.ownerNode);
2218
+ if (id !== -1) {
2670
2219
  styleSheetRuleCb({
2671
2220
  id,
2672
- styleId,
2673
2221
  removes: [
2674
2222
  { index: [...getNestedCSSRulePositions(thisArg), index] },
2675
2223
  ],
@@ -2682,74 +2230,22 @@ function initStyleSheetObserver({ styleSheetRuleCb, mirror, stylesheetManager },
2682
2230
  return callbackWrapper(() => {
2683
2231
  win.CSSStyleSheet.prototype.insertRule = insertRule;
2684
2232
  win.CSSStyleSheet.prototype.deleteRule = deleteRule;
2685
- replace && (win.CSSStyleSheet.prototype.replace = replace);
2686
- replaceSync && (win.CSSStyleSheet.prototype.replaceSync = replaceSync);
2687
2233
  Object.entries(supportedNestedCSSRuleTypes).forEach(([typeKey, type]) => {
2688
2234
  type.prototype.insertRule = unmodifiedFunctions[typeKey].insertRule;
2689
2235
  type.prototype.deleteRule = unmodifiedFunctions[typeKey].deleteRule;
2690
2236
  });
2691
2237
  });
2692
2238
  }
2693
- function initAdoptedStyleSheetObserver({ mirror, stylesheetManager, }, host) {
2694
- var _a, _b, _c;
2695
- let hostId = null;
2696
- if (host.nodeName === '#document')
2697
- hostId = mirror.getId(host);
2698
- else
2699
- hostId = mirror.getId(host.host);
2700
- const patchTarget = host.nodeName === '#document'
2701
- ? (_a = host.defaultView) === null || _a === void 0 ? void 0 : _a.Document
2702
- : (_c = (_b = host.ownerDocument) === null || _b === void 0 ? void 0 : _b.defaultView) === null || _c === void 0 ? void 0 : _c.ShadowRoot;
2703
- const originalPropertyDescriptor = Object.getOwnPropertyDescriptor(patchTarget === null || patchTarget === void 0 ? void 0 : patchTarget.prototype, 'adoptedStyleSheets');
2704
- if (hostId === null ||
2705
- hostId === -1 ||
2706
- !patchTarget ||
2707
- !originalPropertyDescriptor)
2708
- return () => {
2709
- };
2710
- Object.defineProperty(host, 'adoptedStyleSheets', {
2711
- configurable: originalPropertyDescriptor.configurable,
2712
- enumerable: originalPropertyDescriptor.enumerable,
2713
- get() {
2714
- var _a;
2715
- return (_a = originalPropertyDescriptor.get) === null || _a === void 0 ? void 0 : _a.call(this);
2716
- },
2717
- set(sheets) {
2718
- var _a;
2719
- const result = (_a = originalPropertyDescriptor.set) === null || _a === void 0 ? void 0 : _a.call(this, sheets);
2720
- if (hostId !== null && hostId !== -1) {
2721
- try {
2722
- stylesheetManager.adoptStyleSheets(sheets, hostId);
2723
- }
2724
- catch (e) {
2725
- }
2726
- }
2727
- return result;
2728
- },
2729
- });
2730
- return callbackWrapper(() => {
2731
- Object.defineProperty(host, 'adoptedStyleSheets', {
2732
- configurable: originalPropertyDescriptor.configurable,
2733
- enumerable: originalPropertyDescriptor.enumerable,
2734
- get: originalPropertyDescriptor.get,
2735
- set: originalPropertyDescriptor.set,
2736
- });
2737
- });
2738
- }
2739
- function initStyleDeclarationObserver({ styleDeclarationCb, mirror, ignoreCSSAttributes, stylesheetManager, }, { win }) {
2239
+ function initStyleDeclarationObserver({ styleDeclarationCb, mirror }, { win }) {
2740
2240
  const setProperty = win.CSSStyleDeclaration.prototype.setProperty;
2741
2241
  win.CSSStyleDeclaration.prototype.setProperty = new Proxy(setProperty, {
2742
2242
  apply: callbackWrapper((target, thisArg, argumentsList) => {
2743
- var _a;
2243
+ var _a, _b;
2744
2244
  const [property, value, priority] = argumentsList;
2745
- if (ignoreCSSAttributes.has(property)) {
2746
- return setProperty.apply(thisArg, [property, value, priority]);
2747
- }
2748
- const { id, styleId } = getIdAndStyleId((_a = thisArg.parentRule) === null || _a === void 0 ? void 0 : _a.parentStyleSheet, mirror, stylesheetManager.styleMirror);
2749
- if ((id && id !== -1) || (styleId && styleId !== -1)) {
2245
+ const id = mirror.getId((_b = (_a = thisArg.parentRule) === null || _a === void 0 ? void 0 : _a.parentStyleSheet) === null || _b === void 0 ? void 0 : _b.ownerNode);
2246
+ if (id !== -1) {
2750
2247
  styleDeclarationCb({
2751
2248
  id,
2752
- styleId,
2753
2249
  set: {
2754
2250
  property,
2755
2251
  value,
@@ -2764,16 +2260,12 @@ function initStyleDeclarationObserver({ styleDeclarationCb, mirror, ignoreCSSAtt
2764
2260
  const removeProperty = win.CSSStyleDeclaration.prototype.removeProperty;
2765
2261
  win.CSSStyleDeclaration.prototype.removeProperty = new Proxy(removeProperty, {
2766
2262
  apply: callbackWrapper((target, thisArg, argumentsList) => {
2767
- var _a;
2263
+ var _a, _b;
2768
2264
  const [property] = argumentsList;
2769
- if (ignoreCSSAttributes.has(property)) {
2770
- return removeProperty.apply(thisArg, [property]);
2771
- }
2772
- const { id, styleId } = getIdAndStyleId((_a = thisArg.parentRule) === null || _a === void 0 ? void 0 : _a.parentStyleSheet, mirror, stylesheetManager.styleMirror);
2773
- if ((id && id !== -1) || (styleId && styleId !== -1)) {
2265
+ const id = mirror.getId((_b = (_a = thisArg.parentRule) === null || _a === void 0 ? void 0 : _a.parentStyleSheet) === null || _b === void 0 ? void 0 : _b.ownerNode);
2266
+ if (id !== -1) {
2774
2267
  styleDeclarationCb({
2775
2268
  id,
2776
- styleId,
2777
2269
  remove: {
2778
2270
  property,
2779
2271
  },
@@ -2788,29 +2280,27 @@ function initStyleDeclarationObserver({ styleDeclarationCb, mirror, ignoreCSSAtt
2788
2280
  win.CSSStyleDeclaration.prototype.removeProperty = removeProperty;
2789
2281
  });
2790
2282
  }
2791
- function initMediaInteractionObserver({ mediaInteractionCb, blockClass, blockSelector, unblockSelector, mirror, sampling, doc, }) {
2792
- const handler = callbackWrapper((type) => throttle$1(callbackWrapper((event) => {
2283
+ function initMediaInteractionObserver({ mediaInteractionCb, blockClass, blockSelector, unblockSelector, mirror, sampling, }) {
2284
+ const handler = (type) => throttle$1(callbackWrapper((event) => {
2793
2285
  const target = getEventTarget(event);
2794
2286
  if (!target ||
2795
- isBlocked(target, blockClass, blockSelector, unblockSelector, true)) {
2287
+ isBlocked(target, blockClass, blockSelector, unblockSelector)) {
2796
2288
  return;
2797
2289
  }
2798
- const { currentTime, volume, muted, playbackRate } = target;
2290
+ const { currentTime, volume, muted } = target;
2799
2291
  mediaInteractionCb({
2800
2292
  type,
2801
2293
  id: mirror.getId(target),
2802
2294
  currentTime,
2803
2295
  volume,
2804
2296
  muted,
2805
- playbackRate,
2806
2297
  });
2807
- }), sampling.media || 500));
2298
+ }), sampling.media || 500);
2808
2299
  const handlers = [
2809
- on('play', handler(0), doc),
2810
- on('pause', handler(1), doc),
2811
- on('seeked', handler(2), doc),
2812
- on('volumechange', handler(3), doc),
2813
- on('ratechange', handler(4), doc),
2300
+ on('play', handler(0)),
2301
+ on('pause', handler(1)),
2302
+ on('seeked', handler(2)),
2303
+ on('volumechange', handler(3)),
2814
2304
  ];
2815
2305
  return callbackWrapper(() => {
2816
2306
  handlers.forEach((h) => h());
@@ -2819,8 +2309,7 @@ function initMediaInteractionObserver({ mediaInteractionCb, blockClass, blockSel
2819
2309
  function initFontObserver({ fontCb, doc }) {
2820
2310
  const win = doc.defaultView;
2821
2311
  if (!win) {
2822
- return () => {
2823
- };
2312
+ return () => { };
2824
2313
  }
2825
2314
  const handlers = [];
2826
2315
  const fontMap = new WeakMap();
@@ -2833,19 +2322,20 @@ function initFontObserver({ fontCb, doc }) {
2833
2322
  descriptors,
2834
2323
  fontSource: typeof source === 'string'
2835
2324
  ? source
2836
- : JSON.stringify(Array.from(new Uint8Array(source))),
2325
+ :
2326
+ JSON.stringify(Array.from(new Uint8Array(source))),
2837
2327
  });
2838
2328
  return fontFace;
2839
2329
  };
2840
2330
  const restoreHandler = patch(doc.fonts, 'add', function (original) {
2841
2331
  return function (fontFace) {
2842
- setTimeout(callbackWrapper(() => {
2332
+ setTimeout(() => {
2843
2333
  const p = fontMap.get(fontFace);
2844
2334
  if (p) {
2845
2335
  fontCb(p);
2846
2336
  fontMap.delete(fontFace);
2847
2337
  }
2848
- }), 0);
2338
+ }, 0);
2849
2339
  return original.apply(this, [fontFace]);
2850
2340
  };
2851
2341
  });
@@ -2857,59 +2347,8 @@ function initFontObserver({ fontCb, doc }) {
2857
2347
  handlers.forEach((h) => h());
2858
2348
  });
2859
2349
  }
2860
- function initSelectionObserver(param) {
2861
- const { doc, mirror, blockClass, blockSelector, unblockSelector, selectionCb, } = param;
2862
- let collapsed = true;
2863
- const updateSelection = callbackWrapper(() => {
2864
- const selection = doc.getSelection();
2865
- if (!selection || (collapsed && (selection === null || selection === void 0 ? void 0 : selection.isCollapsed)))
2866
- return;
2867
- collapsed = selection.isCollapsed || false;
2868
- const ranges = [];
2869
- const count = selection.rangeCount || 0;
2870
- for (let i = 0; i < count; i++) {
2871
- const range = selection.getRangeAt(i);
2872
- const { startContainer, startOffset, endContainer, endOffset } = range;
2873
- const blocked = isBlocked(startContainer, blockClass, blockSelector, unblockSelector, true) ||
2874
- isBlocked(endContainer, blockClass, blockSelector, unblockSelector, true);
2875
- if (blocked)
2876
- continue;
2877
- ranges.push({
2878
- start: mirror.getId(startContainer),
2879
- startOffset,
2880
- end: mirror.getId(endContainer),
2881
- endOffset,
2882
- });
2883
- }
2884
- selectionCb({ ranges });
2885
- });
2886
- updateSelection();
2887
- return on('selectionchange', updateSelection);
2888
- }
2889
- function initCustomElementObserver({ doc, customElementCb, }) {
2890
- const win = doc.defaultView;
2891
- if (!win || !win.customElements) {
2892
- return () => {
2893
- };
2894
- }
2895
- const restoreHandler = patch(win.customElements, 'define', function (original) {
2896
- return function (name, constructor, options) {
2897
- try {
2898
- customElementCb({
2899
- define: {
2900
- name,
2901
- },
2902
- });
2903
- }
2904
- catch (e) {
2905
- }
2906
- return original.apply(this, [name, constructor, options]);
2907
- };
2908
- });
2909
- return restoreHandler;
2910
- }
2911
2350
  function mergeHooks(o, hooks) {
2912
- const { mutationCb, mousemoveCb, mouseInteractionCb, scrollCb, viewportResizeCb, inputCb, mediaInteractionCb, styleSheetRuleCb, styleDeclarationCb, canvasMutationCb, fontCb, selectionCb, customElementCb, } = o;
2351
+ const { mutationCb, mousemoveCb, mouseInteractionCb, scrollCb, viewportResizeCb, inputCb, mediaInteractionCb, styleSheetRuleCb, styleDeclarationCb, canvasMutationCb, fontCb, } = o;
2913
2352
  o.mutationCb = (...p) => {
2914
2353
  if (hooks.mutation) {
2915
2354
  hooks.mutation(...p);
@@ -2976,46 +2415,25 @@ function mergeHooks(o, hooks) {
2976
2415
  }
2977
2416
  fontCb(...p);
2978
2417
  };
2979
- o.selectionCb = (...p) => {
2980
- if (hooks.selection) {
2981
- hooks.selection(...p);
2982
- }
2983
- selectionCb(...p);
2984
- };
2985
- o.customElementCb = (...c) => {
2986
- if (hooks.customElement) {
2987
- hooks.customElement(...c);
2988
- }
2989
- customElementCb(...c);
2990
- };
2991
2418
  }
2992
2419
  function initObservers(o, hooks = {}) {
2993
2420
  const currentWindow = o.doc.defaultView;
2994
2421
  if (!currentWindow) {
2995
- return () => {
2996
- };
2422
+ return () => { };
2997
2423
  }
2998
2424
  mergeHooks(o, hooks);
2999
2425
  const mutationObserver = initMutationObserver(o, o.doc);
3000
2426
  const mousemoveHandler = initMoveObserver(o);
3001
2427
  const mouseInteractionHandler = initMouseInteractionObserver(o);
3002
2428
  const scrollHandler = initScrollObserver(o);
3003
- const viewportResizeHandler = initViewportResizeObserver(o, {
3004
- win: currentWindow,
3005
- });
2429
+ const viewportResizeHandler = initViewportResizeObserver(o);
3006
2430
  const inputHandler = initInputObserver(o);
3007
2431
  const mediaInteractionHandler = initMediaInteractionObserver(o);
3008
2432
  const styleSheetObserver = initStyleSheetObserver(o, { win: currentWindow });
3009
- const adoptedStyleSheetObserver = initAdoptedStyleSheetObserver(o, o.doc);
3010
2433
  const styleDeclarationObserver = initStyleDeclarationObserver(o, {
3011
2434
  win: currentWindow,
3012
2435
  });
3013
- const fontObserver = o.collectFonts
3014
- ? initFontObserver(o)
3015
- : () => {
3016
- };
3017
- const selectionObserver = initSelectionObserver(o);
3018
- const customElementObserver = initCustomElementObserver(o);
2436
+ const fontObserver = o.collectFonts ? initFontObserver(o) : () => { };
3019
2437
  const pluginHandlers = [];
3020
2438
  for (const plugin of o.plugins) {
3021
2439
  pluginHandlers.push(plugin.observer(plugin.callback, currentWindow, plugin.options));
@@ -3029,12 +2447,13 @@ function initObservers(o, hooks = {}) {
3029
2447
  viewportResizeHandler();
3030
2448
  inputHandler();
3031
2449
  mediaInteractionHandler();
3032
- styleSheetObserver();
3033
- adoptedStyleSheetObserver();
3034
- styleDeclarationObserver();
2450
+ try {
2451
+ styleSheetObserver();
2452
+ styleDeclarationObserver();
2453
+ }
2454
+ catch (e) {
2455
+ }
3035
2456
  fontObserver();
3036
- selectionObserver();
3037
- customElementObserver();
3038
2457
  pluginHandlers.forEach((h) => h());
3039
2458
  });
3040
2459
  }
@@ -3048,88 +2467,13 @@ function canMonkeyPatchNestedCSSRule(prop) {
3048
2467
  'deleteRule' in window[prop].prototype);
3049
2468
  }
3050
2469
 
3051
- class CrossOriginIframeMirror {
3052
- constructor(generateIdFn) {
3053
- this.generateIdFn = generateIdFn;
3054
- this.iframeIdToRemoteIdMap = new WeakMap();
3055
- this.iframeRemoteIdToIdMap = new WeakMap();
3056
- }
3057
- getId(iframe, remoteId, idToRemoteMap, remoteToIdMap) {
3058
- const idToRemoteIdMap = idToRemoteMap || this.getIdToRemoteIdMap(iframe);
3059
- const remoteIdToIdMap = remoteToIdMap || this.getRemoteIdToIdMap(iframe);
3060
- let id = idToRemoteIdMap.get(remoteId);
3061
- if (!id) {
3062
- id = this.generateIdFn();
3063
- idToRemoteIdMap.set(remoteId, id);
3064
- remoteIdToIdMap.set(id, remoteId);
3065
- }
3066
- return id;
3067
- }
3068
- getIds(iframe, remoteId) {
3069
- const idToRemoteIdMap = this.getIdToRemoteIdMap(iframe);
3070
- const remoteIdToIdMap = this.getRemoteIdToIdMap(iframe);
3071
- return remoteId.map((id) => this.getId(iframe, id, idToRemoteIdMap, remoteIdToIdMap));
3072
- }
3073
- getRemoteId(iframe, id, map) {
3074
- const remoteIdToIdMap = map || this.getRemoteIdToIdMap(iframe);
3075
- if (typeof id !== 'number')
3076
- return id;
3077
- const remoteId = remoteIdToIdMap.get(id);
3078
- if (!remoteId)
3079
- return -1;
3080
- return remoteId;
3081
- }
3082
- getRemoteIds(iframe, ids) {
3083
- const remoteIdToIdMap = this.getRemoteIdToIdMap(iframe);
3084
- return ids.map((id) => this.getRemoteId(iframe, id, remoteIdToIdMap));
3085
- }
3086
- reset(iframe) {
3087
- if (!iframe) {
3088
- this.iframeIdToRemoteIdMap = new WeakMap();
3089
- this.iframeRemoteIdToIdMap = new WeakMap();
3090
- return;
3091
- }
3092
- this.iframeIdToRemoteIdMap.delete(iframe);
3093
- this.iframeRemoteIdToIdMap.delete(iframe);
3094
- }
3095
- getIdToRemoteIdMap(iframe) {
3096
- let idToRemoteIdMap = this.iframeIdToRemoteIdMap.get(iframe);
3097
- if (!idToRemoteIdMap) {
3098
- idToRemoteIdMap = new Map();
3099
- this.iframeIdToRemoteIdMap.set(iframe, idToRemoteIdMap);
3100
- }
3101
- return idToRemoteIdMap;
3102
- }
3103
- getRemoteIdToIdMap(iframe) {
3104
- let remoteIdToIdMap = this.iframeRemoteIdToIdMap.get(iframe);
3105
- if (!remoteIdToIdMap) {
3106
- remoteIdToIdMap = new Map();
3107
- this.iframeRemoteIdToIdMap.set(iframe, remoteIdToIdMap);
3108
- }
3109
- return remoteIdToIdMap;
3110
- }
3111
- }
3112
-
3113
2470
  class IframeManager {
3114
2471
  constructor(options) {
3115
2472
  this.iframes = new WeakMap();
3116
- this.crossOriginIframeMap = new WeakMap();
3117
- this.crossOriginIframeMirror = new CrossOriginIframeMirror(genId);
3118
- this.crossOriginIframeRootIdMap = new WeakMap();
3119
2473
  this.mutationCb = options.mutationCb;
3120
- this.wrappedEmit = options.wrappedEmit;
3121
- this.stylesheetManager = options.stylesheetManager;
3122
- this.recordCrossOriginIframes = options.recordCrossOriginIframes;
3123
- this.crossOriginIframeStyleMirror = new CrossOriginIframeMirror(this.stylesheetManager.styleMirror.generateId.bind(this.stylesheetManager.styleMirror));
3124
- this.mirror = options.mirror;
3125
- if (this.recordCrossOriginIframes) {
3126
- window.addEventListener('message', this.handleMessage.bind(this));
3127
- }
3128
2474
  }
3129
2475
  addIframe(iframeEl) {
3130
2476
  this.iframes.set(iframeEl, true);
3131
- if (iframeEl.contentWindow)
3132
- this.crossOriginIframeMap.set(iframeEl.contentWindow, iframeEl);
3133
2477
  }
3134
2478
  addLoadListener(cb) {
3135
2479
  this.loadListener = cb;
@@ -3139,7 +2483,7 @@ class IframeManager {
3139
2483
  this.mutationCb({
3140
2484
  adds: [
3141
2485
  {
3142
- parentId: this.mirror.getId(iframeEl),
2486
+ parentId: iframeEl.__sn.id,
3143
2487
  nextId: null,
3144
2488
  node: childSn,
3145
2489
  },
@@ -3150,239 +2494,49 @@ class IframeManager {
3150
2494
  isAttachIframe: true,
3151
2495
  });
3152
2496
  (_a = this.loadListener) === null || _a === void 0 ? void 0 : _a.call(this, iframeEl);
3153
- if (iframeEl.contentDocument &&
3154
- iframeEl.contentDocument.adoptedStyleSheets &&
3155
- iframeEl.contentDocument.adoptedStyleSheets.length > 0)
3156
- this.stylesheetManager.adoptStyleSheets(iframeEl.contentDocument.adoptedStyleSheets, this.mirror.getId(iframeEl.contentDocument));
3157
- }
3158
- handleMessage(message) {
3159
- const crossOriginMessageEvent = message;
3160
- if (crossOriginMessageEvent.data.type !== 'rrweb' ||
3161
- crossOriginMessageEvent.origin !== crossOriginMessageEvent.data.origin)
3162
- return;
3163
- const iframeSourceWindow = message.source;
3164
- if (!iframeSourceWindow)
3165
- return;
3166
- const iframeEl = this.crossOriginIframeMap.get(message.source);
3167
- if (!iframeEl)
3168
- return;
3169
- const transformedEvent = this.transformCrossOriginEvent(iframeEl, crossOriginMessageEvent.data.event);
3170
- if (transformedEvent)
3171
- this.wrappedEmit(transformedEvent, crossOriginMessageEvent.data.isCheckout);
3172
- }
3173
- transformCrossOriginEvent(iframeEl, e) {
3174
- var _a;
3175
- switch (e.type) {
3176
- case EventType.FullSnapshot: {
3177
- this.crossOriginIframeMirror.reset(iframeEl);
3178
- this.crossOriginIframeStyleMirror.reset(iframeEl);
3179
- this.replaceIdOnNode(e.data.node, iframeEl);
3180
- const rootId = e.data.node.id;
3181
- this.crossOriginIframeRootIdMap.set(iframeEl, rootId);
3182
- this.patchRootIdOnNode(e.data.node, rootId);
3183
- return {
3184
- timestamp: e.timestamp,
3185
- type: EventType.IncrementalSnapshot,
3186
- data: {
3187
- source: IncrementalSource.Mutation,
3188
- adds: [
3189
- {
3190
- parentId: this.mirror.getId(iframeEl),
3191
- nextId: null,
3192
- node: e.data.node,
3193
- },
3194
- ],
3195
- removes: [],
3196
- texts: [],
3197
- attributes: [],
3198
- isAttachIframe: true,
3199
- },
3200
- };
3201
- }
3202
- case EventType.Meta:
3203
- case EventType.Load:
3204
- case EventType.DomContentLoaded: {
3205
- return false;
3206
- }
3207
- case EventType.Plugin: {
3208
- return e;
3209
- }
3210
- case EventType.Custom: {
3211
- this.replaceIds(e.data.payload, iframeEl, ['id', 'parentId', 'previousId', 'nextId']);
3212
- return e;
3213
- }
3214
- case EventType.IncrementalSnapshot: {
3215
- switch (e.data.source) {
3216
- case IncrementalSource.Mutation: {
3217
- e.data.adds.forEach((n) => {
3218
- this.replaceIds(n, iframeEl, [
3219
- 'parentId',
3220
- 'nextId',
3221
- 'previousId',
3222
- ]);
3223
- this.replaceIdOnNode(n.node, iframeEl);
3224
- const rootId = this.crossOriginIframeRootIdMap.get(iframeEl);
3225
- rootId && this.patchRootIdOnNode(n.node, rootId);
3226
- });
3227
- e.data.removes.forEach((n) => {
3228
- this.replaceIds(n, iframeEl, ['parentId', 'id']);
3229
- });
3230
- e.data.attributes.forEach((n) => {
3231
- this.replaceIds(n, iframeEl, ['id']);
3232
- });
3233
- e.data.texts.forEach((n) => {
3234
- this.replaceIds(n, iframeEl, ['id']);
3235
- });
3236
- return e;
3237
- }
3238
- case IncrementalSource.Drag:
3239
- case IncrementalSource.TouchMove:
3240
- case IncrementalSource.MouseMove: {
3241
- e.data.positions.forEach((p) => {
3242
- this.replaceIds(p, iframeEl, ['id']);
3243
- });
3244
- return e;
3245
- }
3246
- case IncrementalSource.ViewportResize: {
3247
- return false;
3248
- }
3249
- case IncrementalSource.MediaInteraction:
3250
- case IncrementalSource.MouseInteraction:
3251
- case IncrementalSource.Scroll:
3252
- case IncrementalSource.CanvasMutation:
3253
- case IncrementalSource.Input: {
3254
- this.replaceIds(e.data, iframeEl, ['id']);
3255
- return e;
3256
- }
3257
- case IncrementalSource.StyleSheetRule:
3258
- case IncrementalSource.StyleDeclaration: {
3259
- this.replaceIds(e.data, iframeEl, ['id']);
3260
- this.replaceStyleIds(e.data, iframeEl, ['styleId']);
3261
- return e;
3262
- }
3263
- case IncrementalSource.Font: {
3264
- return e;
3265
- }
3266
- case IncrementalSource.Selection: {
3267
- e.data.ranges.forEach((range) => {
3268
- this.replaceIds(range, iframeEl, ['start', 'end']);
3269
- });
3270
- return e;
3271
- }
3272
- case IncrementalSource.AdoptedStyleSheet: {
3273
- this.replaceIds(e.data, iframeEl, ['id']);
3274
- this.replaceStyleIds(e.data, iframeEl, ['styleIds']);
3275
- (_a = e.data.styles) === null || _a === void 0 ? void 0 : _a.forEach((style) => {
3276
- this.replaceStyleIds(style, iframeEl, ['styleId']);
3277
- });
3278
- return e;
3279
- }
3280
- }
3281
- }
3282
- }
3283
- return false;
3284
- }
3285
- replace(iframeMirror, obj, iframeEl, keys) {
3286
- for (const key of keys) {
3287
- if (!Array.isArray(obj[key]) && typeof obj[key] !== 'number')
3288
- continue;
3289
- if (Array.isArray(obj[key])) {
3290
- obj[key] = iframeMirror.getIds(iframeEl, obj[key]);
3291
- }
3292
- else {
3293
- obj[key] = iframeMirror.getId(iframeEl, obj[key]);
3294
- }
3295
- }
3296
- return obj;
3297
- }
3298
- replaceIds(obj, iframeEl, keys) {
3299
- return this.replace(this.crossOriginIframeMirror, obj, iframeEl, keys);
3300
- }
3301
- replaceStyleIds(obj, iframeEl, keys) {
3302
- return this.replace(this.crossOriginIframeStyleMirror, obj, iframeEl, keys);
3303
- }
3304
- replaceIdOnNode(node, iframeEl) {
3305
- this.replaceIds(node, iframeEl, ['id', 'rootId']);
3306
- if ('childNodes' in node) {
3307
- node.childNodes.forEach((child) => {
3308
- this.replaceIdOnNode(child, iframeEl);
3309
- });
3310
- }
3311
- }
3312
- patchRootIdOnNode(node, rootId) {
3313
- if (node.type !== NodeType$1.Document && !node.rootId)
3314
- node.rootId = rootId;
3315
- if ('childNodes' in node) {
3316
- node.childNodes.forEach((child) => {
3317
- this.patchRootIdOnNode(child, rootId);
3318
- });
3319
- }
3320
2497
  }
3321
2498
  }
3322
2499
 
3323
2500
  class ShadowDomManager {
3324
2501
  constructor(options) {
3325
- this.shadowDoms = new WeakSet();
3326
- this.restoreHandlers = [];
2502
+ this.restorePatches = [];
3327
2503
  this.mutationCb = options.mutationCb;
3328
2504
  this.scrollCb = options.scrollCb;
3329
2505
  this.bypassOptions = options.bypassOptions;
3330
2506
  this.mirror = options.mirror;
3331
- this.init();
3332
- }
3333
- init() {
3334
- this.reset();
3335
- this.patchAttachShadow(Element, document);
3336
- }
3337
- addShadowRoot(shadowRoot, doc) {
3338
- if (!isNativeShadowDom(shadowRoot))
3339
- return;
3340
- if (this.shadowDoms.has(shadowRoot))
3341
- return;
3342
- this.shadowDoms.add(shadowRoot);
3343
- const observer = initMutationObserver(Object.assign(Object.assign({}, this.bypassOptions), { doc, mutationCb: this.mutationCb, mirror: this.mirror, shadowDomManager: this }), shadowRoot);
3344
- this.restoreHandlers.push(() => observer.disconnect());
3345
- this.restoreHandlers.push(initScrollObserver(Object.assign(Object.assign({}, this.bypassOptions), { scrollCb: this.scrollCb, doc: shadowRoot, mirror: this.mirror })));
3346
- setTimeout(() => {
3347
- if (shadowRoot.adoptedStyleSheets &&
3348
- shadowRoot.adoptedStyleSheets.length > 0)
3349
- this.bypassOptions.stylesheetManager.adoptStyleSheets(shadowRoot.adoptedStyleSheets, this.mirror.getId(shadowRoot.host));
3350
- this.restoreHandlers.push(initAdoptedStyleSheetObserver({
3351
- mirror: this.mirror,
3352
- stylesheetManager: this.bypassOptions.stylesheetManager,
3353
- }, shadowRoot));
3354
- }, 0);
3355
- }
3356
- observeAttachShadow(iframeElement) {
3357
- if (!iframeElement.contentWindow || !iframeElement.contentDocument)
3358
- return;
3359
- this.patchAttachShadow(iframeElement.contentWindow.Element, iframeElement.contentDocument);
3360
- }
3361
- patchAttachShadow(element, doc) {
3362
2507
  const manager = this;
3363
- this.restoreHandlers.push(patch(element.prototype, 'attachShadow', function (original) {
3364
- return function (option) {
3365
- const shadowRoot = original.call(this, option);
3366
- if (this.shadowRoot && inDom(this))
3367
- manager.addShadowRoot(this.shadowRoot, doc);
2508
+ this.restorePatches.push(patch(HTMLElement.prototype, 'attachShadow', function (original) {
2509
+ return function () {
2510
+ const shadowRoot = original.apply(this, arguments);
2511
+ if (this.shadowRoot)
2512
+ manager.addShadowRoot(this.shadowRoot, this.ownerDocument);
3368
2513
  return shadowRoot;
3369
2514
  };
3370
2515
  }));
3371
2516
  }
2517
+ addShadowRoot(shadowRoot, doc) {
2518
+ initMutationObserver(Object.assign(Object.assign({}, this.bypassOptions), { doc, mutationCb: this.mutationCb, mirror: this.mirror, shadowDomManager: this }), shadowRoot);
2519
+ initScrollObserver(Object.assign(Object.assign({}, this.bypassOptions), { scrollCb: this.scrollCb, doc: shadowRoot, mirror: this.mirror }));
2520
+ }
2521
+ observeAttachShadow(iframeElement) {
2522
+ if (iframeElement.contentWindow) {
2523
+ const manager = this;
2524
+ this.restorePatches.push(patch(iframeElement.contentWindow.HTMLElement.prototype, 'attachShadow', function (original) {
2525
+ return function () {
2526
+ const shadowRoot = original.apply(this, arguments);
2527
+ if (this.shadowRoot)
2528
+ manager.addShadowRoot(this.shadowRoot, iframeElement.contentDocument);
2529
+ return shadowRoot;
2530
+ };
2531
+ }));
2532
+ }
2533
+ }
3372
2534
  reset() {
3373
- this.restoreHandlers.forEach((handler) => {
3374
- try {
3375
- handler();
3376
- }
3377
- catch (e) {
3378
- }
3379
- });
3380
- this.restoreHandlers = [];
3381
- this.shadowDoms = new WeakSet();
2535
+ this.restorePatches.forEach((restorePatch) => restorePatch());
3382
2536
  }
3383
2537
  }
3384
2538
 
3385
- /*! *****************************************************************************
2539
+ /******************************************************************************
3386
2540
  Copyright (c) Microsoft Corporation.
3387
2541
 
3388
2542
  Permission to use, copy, modify, and/or distribute this software for any
@@ -3409,19 +2563,85 @@ function __rest(s, e) {
3409
2563
  return t;
3410
2564
  }
3411
2565
 
3412
- function __awaiter(thisArg, _arguments, P, generator) {
3413
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3414
- return new (P || (P = Promise))(function (resolve, reject) {
3415
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
3416
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
3417
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
3418
- step((generator = generator.apply(thisArg, _arguments || [])).next());
3419
- });
2566
+ function initCanvas2DMutationObserver(cb, win, blockClass, unblockSelector, blockSelector, mirror) {
2567
+ const handlers = [];
2568
+ const props2D = Object.getOwnPropertyNames(win.CanvasRenderingContext2D.prototype);
2569
+ for (const prop of props2D) {
2570
+ try {
2571
+ if (typeof win.CanvasRenderingContext2D.prototype[prop] !== 'function') {
2572
+ continue;
2573
+ }
2574
+ const restoreHandler = patch(win.CanvasRenderingContext2D.prototype, prop, function (original) {
2575
+ return function (...args) {
2576
+ if (!isBlocked(this.canvas, blockClass, blockSelector, unblockSelector)) {
2577
+ setTimeout(() => {
2578
+ const recordArgs = [...args];
2579
+ if (prop === 'drawImage') {
2580
+ if (recordArgs[0] &&
2581
+ recordArgs[0] instanceof HTMLCanvasElement) {
2582
+ const canvas = recordArgs[0];
2583
+ const ctx = canvas.getContext('2d');
2584
+ let imgd = ctx === null || ctx === void 0 ? void 0 : ctx.getImageData(0, 0, canvas.width, canvas.height);
2585
+ let pix = imgd === null || imgd === void 0 ? void 0 : imgd.data;
2586
+ recordArgs[0] = JSON.stringify(pix);
2587
+ }
2588
+ }
2589
+ cb(this.canvas, {
2590
+ type: CanvasContext['2D'],
2591
+ property: prop,
2592
+ args: recordArgs,
2593
+ });
2594
+ }, 0);
2595
+ }
2596
+ return original.apply(this, args);
2597
+ };
2598
+ });
2599
+ handlers.push(restoreHandler);
2600
+ }
2601
+ catch (_a) {
2602
+ const hookHandler = hookSetter(win.CanvasRenderingContext2D.prototype, prop, {
2603
+ set(v) {
2604
+ cb(this.canvas, {
2605
+ type: CanvasContext['2D'],
2606
+ property: prop,
2607
+ args: [v],
2608
+ setter: true,
2609
+ });
2610
+ },
2611
+ });
2612
+ handlers.push(hookHandler);
2613
+ }
2614
+ }
2615
+ return () => {
2616
+ handlers.forEach((h) => h());
2617
+ };
2618
+ }
2619
+
2620
+ function initCanvasContextObserver(win, blockClass, blockSelector, unblockSelector) {
2621
+ const handlers = [];
2622
+ try {
2623
+ const restoreHandler = patch(win.HTMLCanvasElement.prototype, 'getContext', function (original) {
2624
+ return function (contextType, ...args) {
2625
+ if (!isBlocked(this, blockClass, blockSelector, unblockSelector)) {
2626
+ if (!('__context' in this))
2627
+ this.__context = contextType;
2628
+ }
2629
+ return original.apply(this, [contextType, ...args]);
2630
+ };
2631
+ });
2632
+ handlers.push(restoreHandler);
2633
+ }
2634
+ catch (_a) {
2635
+ console.error('failed to patch HTMLCanvasElement.prototype.getContext');
2636
+ }
2637
+ return () => {
2638
+ handlers.forEach((h) => h());
2639
+ };
3420
2640
  }
3421
2641
 
3422
2642
  /*
3423
- * base64-arraybuffer 1.0.1 <https://github.com/niklasvh/base64-arraybuffer>
3424
- * Copyright (c) 2021 Niklas von Hertzen <https://hertzen.com>
2643
+ * base64-arraybuffer 1.0.2 <https://github.com/niklasvh/base64-arraybuffer>
2644
+ * Copyright (c) 2022 Niklas von Hertzen <https://hertzen.com>
3425
2645
  * Released under MIT License
3426
2646
  */
3427
2647
  var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
@@ -3447,12 +2667,12 @@ var encode = function (arraybuffer) {
3447
2667
  return base64;
3448
2668
  };
3449
2669
 
3450
- const canvasVarMap = new Map();
2670
+ const webGLVarMap = new Map();
3451
2671
  function variableListFor(ctx, ctor) {
3452
- let contextMap = canvasVarMap.get(ctx);
2672
+ let contextMap = webGLVarMap.get(ctx);
3453
2673
  if (!contextMap) {
3454
2674
  contextMap = new Map();
3455
- canvasVarMap.set(ctx, contextMap);
2675
+ webGLVarMap.set(ctx, contextMap);
3456
2676
  }
3457
2677
  if (!contextMap.has(ctor)) {
3458
2678
  contextMap.set(ctor, []);
@@ -3521,148 +2741,48 @@ function serializeArg(value, win, ctx) {
3521
2741
  src,
3522
2742
  };
3523
2743
  }
3524
- else if (value instanceof HTMLCanvasElement) {
3525
- const name = 'HTMLImageElement';
3526
- const src = value.toDataURL();
3527
- return {
3528
- rr_type: name,
3529
- src,
3530
- };
3531
- }
3532
2744
  else if (value instanceof ImageData) {
3533
2745
  const name = value.constructor.name;
3534
2746
  return {
3535
- rr_type: name,
3536
- args: [serializeArg(value.data, win, ctx), value.width, value.height],
3537
- };
3538
- }
3539
- else if (isInstanceOfWebGLObject(value, win) || typeof value === 'object') {
3540
- const name = value.constructor.name;
3541
- const index = saveWebGLVar(value, win, ctx);
3542
- return {
3543
- rr_type: name,
3544
- index: index,
3545
- };
3546
- }
3547
- return value;
3548
- }
3549
- const serializeArgs = (args, win, ctx) => {
3550
- return [...args].map((arg) => serializeArg(arg, win, ctx));
3551
- };
3552
- const isInstanceOfWebGLObject = (value, win) => {
3553
- const webGLConstructorNames = [
3554
- 'WebGLActiveInfo',
3555
- 'WebGLBuffer',
3556
- 'WebGLFramebuffer',
3557
- 'WebGLProgram',
3558
- 'WebGLRenderbuffer',
3559
- 'WebGLShader',
3560
- 'WebGLShaderPrecisionFormat',
3561
- 'WebGLTexture',
3562
- 'WebGLUniformLocation',
3563
- 'WebGLVertexArrayObject',
3564
- 'WebGLVertexArrayObjectOES',
3565
- ];
3566
- const supportedWebGLConstructorNames = webGLConstructorNames.filter((name) => typeof win[name] === 'function');
3567
- return Boolean(supportedWebGLConstructorNames.find((name) => value instanceof win[name]));
3568
- };
3569
-
3570
- function initCanvas2DMutationObserver(cb, win, blockClass, blockSelector, unblockSelector) {
3571
- const handlers = [];
3572
- const props2D = Object.getOwnPropertyNames(win.CanvasRenderingContext2D.prototype);
3573
- for (const prop of props2D) {
3574
- try {
3575
- if (typeof win.CanvasRenderingContext2D.prototype[prop] !== 'function') {
3576
- continue;
3577
- }
3578
- const restoreHandler = patch(win.CanvasRenderingContext2D.prototype, prop, function (original) {
3579
- return function (...args) {
3580
- if (!isBlocked(this.canvas, blockClass, blockSelector, unblockSelector, true)) {
3581
- setTimeout(() => {
3582
- const recordArgs = serializeArgs([...args], win, this);
3583
- cb(this.canvas, {
3584
- type: CanvasContext['2D'],
3585
- property: prop,
3586
- args: recordArgs,
3587
- });
3588
- }, 0);
3589
- }
3590
- return original.apply(this, args);
3591
- };
3592
- });
3593
- handlers.push(restoreHandler);
3594
- }
3595
- catch (_a) {
3596
- const hookHandler = hookSetter(win.CanvasRenderingContext2D.prototype, prop, {
3597
- set(v) {
3598
- cb(this.canvas, {
3599
- type: CanvasContext['2D'],
3600
- property: prop,
3601
- args: [v],
3602
- setter: true,
3603
- });
3604
- },
3605
- });
3606
- handlers.push(hookHandler);
3607
- }
3608
- }
3609
- return () => {
3610
- handlers.forEach((h) => h());
3611
- };
3612
- }
3613
-
3614
- function getNormalizedContextName(contextType) {
3615
- return contextType === 'experimental-webgl' ? 'webgl' : contextType;
3616
- }
3617
- function initCanvasContextObserver(win, blockClass, blockSelector, unblockSelector, setPreserveDrawingBufferToTrue) {
3618
- const handlers = [];
3619
- try {
3620
- const restoreHandler = patch(win.HTMLCanvasElement.prototype, 'getContext', function (original) {
3621
- return function (contextType, ...args) {
3622
- if (!isBlocked(this, blockClass, blockSelector, unblockSelector, true)) {
3623
- const ctxName = getNormalizedContextName(contextType);
3624
- if (!('__context' in this))
3625
- this.__context = ctxName;
3626
- if (setPreserveDrawingBufferToTrue &&
3627
- ['webgl', 'webgl2'].includes(ctxName)) {
3628
- if (args[0] && typeof args[0] === 'object') {
3629
- const contextAttributes = args[0];
3630
- if (!contextAttributes.preserveDrawingBuffer) {
3631
- contextAttributes.preserveDrawingBuffer = true;
3632
- }
3633
- }
3634
- else {
3635
- args.splice(0, 1, {
3636
- preserveDrawingBuffer: true,
3637
- });
3638
- }
3639
- }
3640
- }
3641
- return original.apply(this, [contextType, ...args]);
3642
- };
3643
- });
3644
- handlers.push(restoreHandler);
2747
+ rr_type: name,
2748
+ args: [serializeArg(value.data, win, ctx), value.width, value.height],
2749
+ };
3645
2750
  }
3646
- catch (_a) {
3647
- console.error('failed to patch HTMLCanvasElement.prototype.getContext');
2751
+ else if (isInstanceOfWebGLObject(value, win) || typeof value === 'object') {
2752
+ const name = value.constructor.name;
2753
+ const index = saveWebGLVar(value, win, ctx);
2754
+ return {
2755
+ rr_type: name,
2756
+ index: index,
2757
+ };
3648
2758
  }
3649
- return () => {
3650
- handlers.forEach((h) => h());
3651
- };
2759
+ return value;
3652
2760
  }
2761
+ const serializeArgs = (args, win, ctx) => {
2762
+ return [...args].map((arg) => serializeArg(arg, win, ctx));
2763
+ };
2764
+ const isInstanceOfWebGLObject = (value, win) => {
2765
+ const webGLConstructorNames = [
2766
+ 'WebGLActiveInfo',
2767
+ 'WebGLBuffer',
2768
+ 'WebGLFramebuffer',
2769
+ 'WebGLProgram',
2770
+ 'WebGLRenderbuffer',
2771
+ 'WebGLShader',
2772
+ 'WebGLShaderPrecisionFormat',
2773
+ 'WebGLTexture',
2774
+ 'WebGLUniformLocation',
2775
+ 'WebGLVertexArrayObject',
2776
+ 'WebGLVertexArrayObjectOES',
2777
+ ];
2778
+ const supportedWebGLConstructorNames = webGLConstructorNames.filter((name) => typeof win[name] === 'function');
2779
+ return Boolean(supportedWebGLConstructorNames.find((name) => value instanceof win[name]));
2780
+ };
3653
2781
 
3654
- function patchGLPrototype(prototype, type, cb, blockClass, blockSelector, unblockSelector, mirror, win) {
2782
+ function patchGLPrototype(prototype, type, cb, blockClass, unblockSelector, blockSelector, mirror, win) {
3655
2783
  const handlers = [];
3656
2784
  const props = Object.getOwnPropertyNames(prototype);
3657
2785
  for (const prop of props) {
3658
- if ([
3659
- 'isContextLost',
3660
- 'canvas',
3661
- 'drawingBufferWidth',
3662
- 'drawingBufferHeight',
3663
- ].includes(prop)) {
3664
- continue;
3665
- }
3666
2786
  try {
3667
2787
  if (typeof prototype[prop] !== 'function') {
3668
2788
  continue;
@@ -3670,9 +2790,10 @@ function patchGLPrototype(prototype, type, cb, blockClass, blockSelector, unbloc
3670
2790
  const restoreHandler = patch(prototype, prop, function (original) {
3671
2791
  return function (...args) {
3672
2792
  const result = original.apply(this, args);
3673
- saveWebGLVar(result, win, this);
3674
- if (!isBlocked(this.canvas, blockClass, blockSelector, unblockSelector, true)) {
3675
- const recordArgs = serializeArgs([...args], win, this);
2793
+ saveWebGLVar(result, win, prototype);
2794
+ if (!isBlocked(this.canvas, blockClass, blockSelector, unblockSelector)) {
2795
+ const id = mirror.getId(this.canvas);
2796
+ const recordArgs = serializeArgs([...args], win, prototype);
3676
2797
  const mutation = {
3677
2798
  type,
3678
2799
  property: prop,
@@ -3712,64 +2833,7 @@ function initCanvasWebGLMutationObserver(cb, win, blockClass, blockSelector, unb
3712
2833
  };
3713
2834
  }
3714
2835
 
3715
- function decodeBase64(base64, enableUnicode) {
3716
- var binaryString = atob(base64);
3717
- if (enableUnicode) {
3718
- var binaryView = new Uint8Array(binaryString.length);
3719
- for (var i = 0, n = binaryString.length; i < n; ++i) {
3720
- binaryView[i] = binaryString.charCodeAt(i);
3721
- }
3722
- return String.fromCharCode.apply(null, new Uint16Array(binaryView.buffer));
3723
- }
3724
- return binaryString;
3725
- }
3726
-
3727
- function createURL(base64, sourcemapArg, enableUnicodeArg) {
3728
- var sourcemap = sourcemapArg === undefined ? null : sourcemapArg;
3729
- var enableUnicode = enableUnicodeArg === undefined ? false : enableUnicodeArg;
3730
- var source = decodeBase64(base64, enableUnicode);
3731
- var start = source.indexOf('\n', 10) + 1;
3732
- var body = source.substring(start) + (sourcemap ? '\/\/# sourceMappingURL=' + sourcemap : '');
3733
- var blob = new Blob([body], { type: 'application/javascript' });
3734
- return URL.createObjectURL(blob);
3735
- }
3736
-
3737
- function createBase64WorkerFactory(base64, sourcemapArg, enableUnicodeArg) {
3738
- var url;
3739
- return function WorkerFactory(options) {
3740
- url = url || createURL(base64, sourcemapArg, enableUnicodeArg);
3741
- return new Worker(url, options);
3742
- };
3743
- }
3744
-
3745
- var WorkerFactory = createBase64WorkerFactory('Lyogcm9sbHVwLXBsdWdpbi13ZWItd29ya2VyLWxvYWRlciAqLwooZnVuY3Rpb24gKCkgewogICAgJ3VzZSBzdHJpY3QnOwoKICAgIC8qISAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKg0KICAgIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLg0KDQogICAgUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgYW5kL29yIGRpc3RyaWJ1dGUgdGhpcyBzb2Z0d2FyZSBmb3IgYW55DQogICAgcHVycG9zZSB3aXRoIG9yIHdpdGhvdXQgZmVlIGlzIGhlcmVieSBncmFudGVkLg0KDQogICAgVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUyBJUyIgQU5EIFRIRSBBVVRIT1IgRElTQ0xBSU1TIEFMTCBXQVJSQU5USUVTIFdJVEgNCiAgICBSRUdBUkQgVE8gVEhJUyBTT0ZUV0FSRSBJTkNMVURJTkcgQUxMIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkNCiAgICBBTkQgRklUTkVTUy4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUiBCRSBMSUFCTEUgRk9SIEFOWSBTUEVDSUFMLCBESVJFQ1QsDQogICAgSU5ESVJFQ1QsIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSIFJFU1VMVElORyBGUk9NDQogICAgTE9TUyBPRiBVU0UsIERBVEEgT1IgUFJPRklUUywgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIE5FR0xJR0VOQ0UgT1INCiAgICBPVEhFUiBUT1JUSU9VUyBBQ1RJT04sIEFSSVNJTkcgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SDQogICAgUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS4NCiAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiAqLw0KDQogICAgZnVuY3Rpb24gX19hd2FpdGVyKHRoaXNBcmcsIF9hcmd1bWVudHMsIFAsIGdlbmVyYXRvcikgew0KICAgICAgICBmdW5jdGlvbiBhZG9wdCh2YWx1ZSkgeyByZXR1cm4gdmFsdWUgaW5zdGFuY2VvZiBQID8gdmFsdWUgOiBuZXcgUChmdW5jdGlvbiAocmVzb2x2ZSkgeyByZXNvbHZlKHZhbHVlKTsgfSk7IH0NCiAgICAgICAgcmV0dXJuIG5ldyAoUCB8fCAoUCA9IFByb21pc2UpKShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7DQogICAgICAgICAgICBmdW5jdGlvbiBmdWxmaWxsZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3IubmV4dCh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9DQogICAgICAgICAgICBmdW5jdGlvbiByZWplY3RlZCh2YWx1ZSkgeyB0cnkgeyBzdGVwKGdlbmVyYXRvclsidGhyb3ciXSh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9DQogICAgICAgICAgICBmdW5jdGlvbiBzdGVwKHJlc3VsdCkgeyByZXN1bHQuZG9uZSA/IHJlc29sdmUocmVzdWx0LnZhbHVlKSA6IGFkb3B0KHJlc3VsdC52YWx1ZSkudGhlbihmdWxmaWxsZWQsIHJlamVjdGVkKTsgfQ0KICAgICAgICAgICAgc3RlcCgoZ2VuZXJhdG9yID0gZ2VuZXJhdG9yLmFwcGx5KHRoaXNBcmcsIF9hcmd1bWVudHMgfHwgW10pKS5uZXh0KCkpOw0KICAgICAgICB9KTsNCiAgICB9CgogICAgLyoKICAgICAqIGJhc2U2NC1hcnJheWJ1ZmZlciAxLjAuMSA8aHR0cHM6Ly9naXRodWIuY29tL25pa2xhc3ZoL2Jhc2U2NC1hcnJheWJ1ZmZlcj4KICAgICAqIENvcHlyaWdodCAoYykgMjAyMSBOaWtsYXMgdm9uIEhlcnR6ZW4gPGh0dHBzOi8vaGVydHplbi5jb20+CiAgICAgKiBSZWxlYXNlZCB1bmRlciBNSVQgTGljZW5zZQogICAgICovCiAgICB2YXIgY2hhcnMgPSAnQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrLyc7CiAgICAvLyBVc2UgYSBsb29rdXAgdGFibGUgdG8gZmluZCB0aGUgaW5kZXguCiAgICB2YXIgbG9va3VwID0gdHlwZW9mIFVpbnQ4QXJyYXkgPT09ICd1bmRlZmluZWQnID8gW10gOiBuZXcgVWludDhBcnJheSgyNTYpOwogICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjaGFycy5sZW5ndGg7IGkrKykgewogICAgICAgIGxvb2t1cFtjaGFycy5jaGFyQ29kZUF0KGkpXSA9IGk7CiAgICB9CiAgICB2YXIgZW5jb2RlID0gZnVuY3Rpb24gKGFycmF5YnVmZmVyKSB7CiAgICAgICAgdmFyIGJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkoYXJyYXlidWZmZXIpLCBpLCBsZW4gPSBieXRlcy5sZW5ndGgsIGJhc2U2NCA9ICcnOwogICAgICAgIGZvciAoaSA9IDA7IGkgPCBsZW47IGkgKz0gMykgewogICAgICAgICAgICBiYXNlNjQgKz0gY2hhcnNbYnl0ZXNbaV0gPj4gMl07CiAgICAgICAgICAgIGJhc2U2NCArPSBjaGFyc1soKGJ5dGVzW2ldICYgMykgPDwgNCkgfCAoYnl0ZXNbaSArIDFdID4+IDQpXTsKICAgICAgICAgICAgYmFzZTY0ICs9IGNoYXJzWygoYnl0ZXNbaSArIDFdICYgMTUpIDw8IDIpIHwgKGJ5dGVzW2kgKyAyXSA+PiA2KV07CiAgICAgICAgICAgIGJhc2U2NCArPSBjaGFyc1tieXRlc1tpICsgMl0gJiA2M107CiAgICAgICAgfQogICAgICAgIGlmIChsZW4gJSAzID09PSAyKSB7CiAgICAgICAgICAgIGJhc2U2NCA9IGJhc2U2NC5zdWJzdHJpbmcoMCwgYmFzZTY0Lmxlbmd0aCAtIDEpICsgJz0nOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmIChsZW4gJSAzID09PSAxKSB7CiAgICAgICAgICAgIGJhc2U2NCA9IGJhc2U2NC5zdWJzdHJpbmcoMCwgYmFzZTY0Lmxlbmd0aCAtIDIpICsgJz09JzsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJhc2U2NDsKICAgIH07CgogICAgY29uc3QgbGFzdEJsb2JNYXAgPSBuZXcgTWFwKCk7DQogICAgY29uc3QgdHJhbnNwYXJlbnRCbG9iTWFwID0gbmV3IE1hcCgpOw0KICAgIGZ1bmN0aW9uIGdldFRyYW5zcGFyZW50QmxvYkZvcih3aWR0aCwgaGVpZ2h0LCBkYXRhVVJMT3B0aW9ucykgew0KICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkgew0KICAgICAgICAgICAgY29uc3QgaWQgPSBgJHt3aWR0aH0tJHtoZWlnaHR9YDsNCiAgICAgICAgICAgIGlmICgnT2Zmc2NyZWVuQ2FudmFzJyBpbiBnbG9iYWxUaGlzKSB7DQogICAgICAgICAgICAgICAgaWYgKHRyYW5zcGFyZW50QmxvYk1hcC5oYXMoaWQpKQ0KICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJhbnNwYXJlbnRCbG9iTWFwLmdldChpZCk7DQogICAgICAgICAgICAgICAgY29uc3Qgb2Zmc2NyZWVuID0gbmV3IE9mZnNjcmVlbkNhbnZhcyh3aWR0aCwgaGVpZ2h0KTsNCiAgICAgICAgICAgICAgICBvZmZzY3JlZW4uZ2V0Q29udGV4dCgnMmQnKTsNCiAgICAgICAgICAgICAgICBjb25zdCBibG9iID0geWllbGQgb2Zmc2NyZWVuLmNvbnZlcnRUb0Jsb2IoZGF0YVVSTE9wdGlvbnMpOw0KICAgICAgICAgICAgICAgIGNvbnN0IGFycmF5QnVmZmVyID0geWllbGQgYmxvYi5hcnJheUJ1ZmZlcigpOw0KICAgICAgICAgICAgICAgIGNvbnN0IGJhc2U2NCA9IGVuY29kZShhcnJheUJ1ZmZlcik7DQogICAgICAgICAgICAgICAgdHJhbnNwYXJlbnRCbG9iTWFwLnNldChpZCwgYmFzZTY0KTsNCiAgICAgICAgICAgICAgICByZXR1cm4gYmFzZTY0Ow0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgZWxzZSB7DQogICAgICAgICAgICAgICAgcmV0dXJuICcnOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9KTsNCiAgICB9DQogICAgY29uc3Qgd29ya2VyID0gc2VsZjsNCiAgICB3b3JrZXIub25tZXNzYWdlID0gZnVuY3Rpb24gKGUpIHsNCiAgICAgICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHsNCiAgICAgICAgICAgIGlmICgnT2Zmc2NyZWVuQ2FudmFzJyBpbiBnbG9iYWxUaGlzKSB7DQogICAgICAgICAgICAgICAgY29uc3QgeyBpZCwgYml0bWFwLCB3aWR0aCwgaGVpZ2h0LCBkYXRhVVJMT3B0aW9ucyB9ID0gZS5kYXRhOw0KICAgICAgICAgICAgICAgIGNvbnN0IHRyYW5zcGFyZW50QmFzZTY0ID0gZ2V0VHJhbnNwYXJlbnRCbG9iRm9yKHdpZHRoLCBoZWlnaHQsIGRhdGFVUkxPcHRpb25zKTsNCiAgICAgICAgICAgICAgICBjb25zdCBvZmZzY3JlZW4gPSBuZXcgT2Zmc2NyZWVuQ2FudmFzKHdpZHRoLCBoZWlnaHQpOw0KICAgICAgICAgICAgICAgIGNvbnN0IGN0eCA9IG9mZnNjcmVlbi5nZXRDb250ZXh0KCcyZCcpOw0KICAgICAgICAgICAgICAgIGN0eC5kcmF3SW1hZ2UoYml0bWFwLCAwLCAwKTsNCiAgICAgICAgICAgICAgICBiaXRtYXAuY2xvc2UoKTsNCiAgICAgICAgICAgICAgICBjb25zdCBibG9iID0geWllbGQgb2Zmc2NyZWVuLmNvbnZlcnRUb0Jsb2IoZGF0YVVSTE9wdGlvbnMpOw0KICAgICAgICAgICAgICAgIGNvbnN0IHR5cGUgPSBibG9iLnR5cGU7DQogICAgICAgICAgICAgICAgY29uc3QgYXJyYXlCdWZmZXIgPSB5aWVsZCBibG9iLmFycmF5QnVmZmVyKCk7DQogICAgICAgICAgICAgICAgY29uc3QgYmFzZTY0ID0gZW5jb2RlKGFycmF5QnVmZmVyKTsNCiAgICAgICAgICAgICAgICBpZiAoIWxhc3RCbG9iTWFwLmhhcyhpZCkgJiYgKHlpZWxkIHRyYW5zcGFyZW50QmFzZTY0KSA9PT0gYmFzZTY0KSB7DQogICAgICAgICAgICAgICAgICAgIGxhc3RCbG9iTWFwLnNldChpZCwgYmFzZTY0KTsNCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHdvcmtlci5wb3N0TWVzc2FnZSh7IGlkIH0pOw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICBpZiAobGFzdEJsb2JNYXAuZ2V0KGlkKSA9PT0gYmFzZTY0KQ0KICAgICAgICAgICAgICAgICAgICByZXR1cm4gd29ya2VyLnBvc3RNZXNzYWdlKHsgaWQgfSk7DQogICAgICAgICAgICAgICAgd29ya2VyLnBvc3RNZXNzYWdlKHsNCiAgICAgICAgICAgICAgICAgICAgaWQsDQogICAgICAgICAgICAgICAgICAgIHR5cGUsDQogICAgICAgICAgICAgICAgICAgIGJhc2U2NCwNCiAgICAgICAgICAgICAgICAgICAgd2lkdGgsDQogICAgICAgICAgICAgICAgICAgIGhlaWdodCwNCiAgICAgICAgICAgICAgICB9KTsNCiAgICAgICAgICAgICAgICBsYXN0QmxvYk1hcC5zZXQoaWQsIGJhc2U2NCk7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBlbHNlIHsNCiAgICAgICAgICAgICAgICByZXR1cm4gd29ya2VyLnBvc3RNZXNzYWdlKHsgaWQ6IGUuZGF0YS5pZCB9KTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfSk7DQogICAgfTsKCn0pKCk7Cgo=', null, false);
3746
-
3747
2836
  class CanvasManager {
3748
- constructor(options) {
3749
- this.pendingCanvasMutations = new Map();
3750
- this.rafStamps = { latestId: 0, invokeId: null };
3751
- this.frozen = false;
3752
- this.locked = false;
3753
- this.processMutation = (target, mutation) => {
3754
- const newFrame = this.rafStamps.invokeId &&
3755
- this.rafStamps.latestId !== this.rafStamps.invokeId;
3756
- if (newFrame || !this.rafStamps.invokeId)
3757
- this.rafStamps.invokeId = this.rafStamps.latestId;
3758
- if (!this.pendingCanvasMutations.has(target)) {
3759
- this.pendingCanvasMutations.set(target, []);
3760
- }
3761
- this.pendingCanvasMutations.get(target).push(mutation);
3762
- };
3763
- const { sampling = 'all', win, blockClass, blockSelector, unblockSelector, recordCanvas, dataURLOptions, } = options;
3764
- this.mutationCb = options.mutationCb;
3765
- this.mirror = options.mirror;
3766
- if (recordCanvas && sampling === 'all')
3767
- this.initCanvasMutationObserver(win, blockClass, blockSelector, unblockSelector);
3768
- if (recordCanvas && typeof sampling === 'number')
3769
- this.initCanvasFPSObserver(sampling, win, blockClass, blockSelector, unblockSelector, {
3770
- dataURLOptions,
3771
- });
3772
- }
3773
2837
  reset() {
3774
2838
  this.pendingCanvasMutations.clear();
3775
2839
  this.resetObservers && this.resetObservers();
@@ -3786,98 +2850,31 @@ class CanvasManager {
3786
2850
  unlock() {
3787
2851
  this.locked = false;
3788
2852
  }
3789
- initCanvasFPSObserver(fps, win, blockClass, blockSelector, unblockSelector, options) {
3790
- const canvasContextReset = initCanvasContextObserver(win, blockClass, blockSelector, unblockSelector, true);
3791
- const snapshotInProgressMap = new Map();
3792
- const worker = new WorkerFactory();
3793
- worker.onmessage = (e) => {
3794
- const { id } = e.data;
3795
- snapshotInProgressMap.set(id, false);
3796
- if (!('base64' in e.data))
3797
- return;
3798
- const { base64, type, width, height } = e.data;
3799
- this.mutationCb({
3800
- id,
3801
- type: CanvasContext['2D'],
3802
- commands: [
3803
- {
3804
- property: 'clearRect',
3805
- args: [0, 0, width, height],
3806
- },
3807
- {
3808
- property: 'drawImage',
3809
- args: [
3810
- {
3811
- rr_type: 'ImageBitmap',
3812
- args: [
3813
- {
3814
- rr_type: 'Blob',
3815
- data: [{ rr_type: 'ArrayBuffer', base64 }],
3816
- type,
3817
- },
3818
- ],
3819
- },
3820
- 0,
3821
- 0,
3822
- ],
3823
- },
3824
- ],
3825
- });
3826
- };
3827
- const timeBetweenSnapshots = 1000 / fps;
3828
- let lastSnapshotTime = 0;
3829
- let rafId;
3830
- const getCanvas = () => {
3831
- const matchedCanvas = [];
3832
- win.document.querySelectorAll('canvas').forEach((canvas) => {
3833
- if (!isBlocked(canvas, blockClass, blockSelector, unblockSelector, true)) {
3834
- matchedCanvas.push(canvas);
3835
- }
3836
- });
3837
- return matchedCanvas;
3838
- };
3839
- const takeCanvasSnapshots = (timestamp) => {
3840
- if (lastSnapshotTime &&
3841
- timestamp - lastSnapshotTime < timeBetweenSnapshots) {
3842
- rafId = requestAnimationFrame(takeCanvasSnapshots);
3843
- return;
2853
+ constructor(options) {
2854
+ this.pendingCanvasMutations = new Map();
2855
+ this.rafStamps = { latestId: 0, invokeId: null };
2856
+ this.frozen = false;
2857
+ this.locked = false;
2858
+ this.processMutation = function (target, mutation) {
2859
+ const newFrame = this.rafStamps.invokeId &&
2860
+ this.rafStamps.latestId !== this.rafStamps.invokeId;
2861
+ if (newFrame || !this.rafStamps.invokeId)
2862
+ this.rafStamps.invokeId = this.rafStamps.latestId;
2863
+ if (!this.pendingCanvasMutations.has(target)) {
2864
+ this.pendingCanvasMutations.set(target, []);
3844
2865
  }
3845
- lastSnapshotTime = timestamp;
3846
- getCanvas()
3847
- .forEach((canvas) => __awaiter(this, void 0, void 0, function* () {
3848
- var _a;
3849
- const id = this.mirror.getId(canvas);
3850
- if (snapshotInProgressMap.get(id))
3851
- return;
3852
- snapshotInProgressMap.set(id, true);
3853
- if (['webgl', 'webgl2'].includes(canvas.__context)) {
3854
- const context = canvas.getContext(canvas.__context);
3855
- if (((_a = context === null || context === void 0 ? void 0 : context.getContextAttributes()) === null || _a === void 0 ? void 0 : _a.preserveDrawingBuffer) === false) {
3856
- context.clear(context.COLOR_BUFFER_BIT);
3857
- }
3858
- }
3859
- const bitmap = yield createImageBitmap(canvas);
3860
- worker.postMessage({
3861
- id,
3862
- bitmap,
3863
- width: canvas.width,
3864
- height: canvas.height,
3865
- dataURLOptions: options.dataURLOptions,
3866
- }, [bitmap]);
3867
- }));
3868
- rafId = requestAnimationFrame(takeCanvasSnapshots);
3869
- };
3870
- rafId = requestAnimationFrame(takeCanvasSnapshots);
3871
- this.resetObservers = () => {
3872
- canvasContextReset();
3873
- cancelAnimationFrame(rafId);
2866
+ this.pendingCanvasMutations.get(target).push(mutation);
3874
2867
  };
2868
+ this.mutationCb = options.mutationCb;
2869
+ this.mirror = options.mirror;
2870
+ if (options.recordCanvas === true)
2871
+ this.initCanvasMutationObserver(options.win, options.blockClass, options.blockSelector, options.unblockSelector);
3875
2872
  }
3876
- initCanvasMutationObserver(win, blockClass, blockSelector, unblockSelector) {
2873
+ initCanvasMutationObserver(win, blockClass, unblockSelector, blockSelector) {
3877
2874
  this.startRAFTimestamping();
3878
2875
  this.startPendingCanvasMutationFlusher();
3879
- const canvasContextReset = initCanvasContextObserver(win, blockClass, blockSelector, unblockSelector, false);
3880
- const canvas2DReset = initCanvas2DMutationObserver(this.processMutation.bind(this), win, blockClass, blockSelector, unblockSelector);
2876
+ const canvasContextReset = initCanvasContextObserver(win, blockClass, blockSelector, unblockSelector);
2877
+ const canvas2DReset = initCanvas2DMutationObserver(this.processMutation.bind(this), win, blockClass, blockSelector, unblockSelector, this.mirror);
3881
2878
  const canvasWebGL1and2Reset = initCanvasWebGLMutationObserver(this.processMutation.bind(this), win, blockClass, blockSelector, unblockSelector, this.mirror);
3882
2879
  this.resetObservers = () => {
3883
2880
  canvasContextReset();
@@ -3919,136 +2916,20 @@ class CanvasManager {
3919
2916
  }
3920
2917
  }
3921
2918
 
3922
- class StylesheetManager {
3923
- constructor(options) {
3924
- this.trackedLinkElements = new WeakSet();
3925
- this.styleMirror = new StyleSheetMirror();
3926
- this.mutationCb = options.mutationCb;
3927
- this.adoptedStyleSheetCb = options.adoptedStyleSheetCb;
3928
- }
3929
- attachLinkElement(linkEl, childSn) {
3930
- if ('_cssText' in childSn.attributes)
3931
- this.mutationCb({
3932
- adds: [],
3933
- removes: [],
3934
- texts: [],
3935
- attributes: [
3936
- {
3937
- id: childSn.id,
3938
- attributes: childSn
3939
- .attributes,
3940
- },
3941
- ],
3942
- });
3943
- this.trackLinkElement(linkEl);
3944
- }
3945
- trackLinkElement(linkEl) {
3946
- if (this.trackedLinkElements.has(linkEl))
3947
- return;
3948
- this.trackedLinkElements.add(linkEl);
3949
- this.trackStylesheetInLinkElement(linkEl);
3950
- }
3951
- adoptStyleSheets(sheets, hostId) {
3952
- if (sheets.length === 0)
3953
- return;
3954
- const adoptedStyleSheetData = {
3955
- id: hostId,
3956
- styleIds: [],
3957
- };
3958
- const styles = [];
3959
- for (const sheet of sheets) {
3960
- let styleId;
3961
- if (!this.styleMirror.has(sheet)) {
3962
- styleId = this.styleMirror.add(sheet);
3963
- const rules = Array.from(sheet.rules || CSSRule);
3964
- styles.push({
3965
- styleId,
3966
- rules: rules.map((r, index) => {
3967
- return {
3968
- rule: getCssRuleString(r),
3969
- index,
3970
- };
3971
- }),
3972
- });
3973
- }
3974
- else
3975
- styleId = this.styleMirror.getId(sheet);
3976
- adoptedStyleSheetData.styleIds.push(styleId);
3977
- }
3978
- if (styles.length > 0)
3979
- adoptedStyleSheetData.styles = styles;
3980
- this.adoptedStyleSheetCb(adoptedStyleSheetData);
3981
- }
3982
- reset() {
3983
- this.styleMirror.reset();
3984
- this.trackedLinkElements = new WeakSet();
3985
- }
3986
- trackStylesheetInLinkElement(linkEl) {
3987
- }
3988
- }
3989
-
3990
- class ProcessedNodeManager {
3991
- constructor() {
3992
- this.nodeMap = new WeakMap();
3993
- this.loop = true;
3994
- this.periodicallyClear();
3995
- }
3996
- periodicallyClear() {
3997
- requestAnimationFrame(() => {
3998
- this.clear();
3999
- if (this.loop)
4000
- this.periodicallyClear();
4001
- });
4002
- }
4003
- inOtherBuffer(node, thisBuffer) {
4004
- const buffers = this.nodeMap.get(node);
4005
- return (buffers && Array.from(buffers).some((buffer) => buffer !== thisBuffer));
4006
- }
4007
- add(node, buffer) {
4008
- this.nodeMap.set(node, (this.nodeMap.get(node) || new Set()).add(buffer));
4009
- }
4010
- clear() {
4011
- this.nodeMap = new WeakMap();
4012
- }
4013
- destroy() {
4014
- this.loop = false;
4015
- }
4016
- }
4017
-
4018
2919
  function wrapEvent(e) {
4019
- return Object.assign(Object.assign({}, e), { timestamp: nowTimestamp() });
2920
+ return Object.assign(Object.assign({}, e), { timestamp: Date.now() });
4020
2921
  }
4021
2922
  let wrappedEmit;
4022
2923
  let takeFullSnapshot;
4023
- let canvasManager;
4024
- let recording = false;
4025
2924
  const mirror = createMirror();
4026
2925
  function record(options = {}) {
4027
- const { emit, checkoutEveryNms, checkoutEveryNth, blockClass = 'rr-block', blockSelector = null, unblockSelector = null, ignoreClass = 'rr-ignore', ignoreSelector = null, maskAllText = false, maskTextClass = 'rr-mask', unmaskTextClass = null, maskTextSelector = null, unmaskTextSelector = null, inlineStylesheet = true, maskAllInputs, maskInputOptions: _maskInputOptions, slimDOMOptions: _slimDOMOptions, maskAttributeFn, maskInputFn, maskTextFn, hooks, packFn, sampling = {}, dataURLOptions = {}, mousemoveWait, recordCanvas = false, recordCrossOriginIframes = false, recordAfter = options.recordAfter === 'DOMContentLoaded'
4028
- ? options.recordAfter
4029
- : 'load', userTriggeredOnInput = false, collectFonts = false, inlineImages = false, plugins, keepIframeSrcFn = () => false, ignoreCSSAttributes = new Set([]), errorHandler, onMutation, } = options;
4030
- registerErrorHandler(errorHandler);
4031
- const inEmittingFrame = recordCrossOriginIframes
4032
- ? window.parent === window
4033
- : true;
4034
- let passEmitsToParent = false;
4035
- if (!inEmittingFrame) {
4036
- try {
4037
- if (window.parent.document) {
4038
- passEmitsToParent = false;
4039
- }
4040
- }
4041
- catch (e) {
4042
- passEmitsToParent = true;
4043
- }
4044
- }
4045
- if (inEmittingFrame && !emit) {
2926
+ const { emit, checkoutEveryNms, checkoutEveryNth, blockClass = 'rr-block', blockSelector = null, unblockSelector = null, ignoreClass = 'rr-ignore', ignoreSelector = null, maskTextClass = 'rr-mask', maskTextSelector = null, maskInputSelector = null, unmaskTextSelector = null, unmaskInputSelector = null, inlineStylesheet = true, maskAllText = false, maskAllInputs, maskInputOptions: _maskInputOptions, slimDOMOptions: _slimDOMOptions, maskInputFn, maskTextFn, hooks, packFn, sampling = {}, mousemoveWait, recordCanvas = false, userTriggeredOnInput = false, collectFonts = false, inlineImages = false, plugins, keepIframeSrcFn = () => false, onMutation, } = options;
2927
+ if (!emit) {
4046
2928
  throw new Error('emit function is required');
4047
2929
  }
4048
2930
  if (mousemoveWait !== undefined && sampling.mousemove === undefined) {
4049
2931
  sampling.mousemove = mousemoveWait;
4050
2932
  }
4051
- mirror.reset();
4052
2933
  const maskInputOptions = maskAllInputs === true
4053
2934
  ? {
4054
2935
  color: true,
@@ -4097,8 +2978,7 @@ function record(options = {}) {
4097
2978
  e = plugin.eventProcessor(e);
4098
2979
  }
4099
2980
  }
4100
- if (packFn &&
4101
- !passEmitsToParent) {
2981
+ if (packFn) {
4102
2982
  e = packFn(e);
4103
2983
  }
4104
2984
  return e;
@@ -4111,18 +2991,7 @@ function record(options = {}) {
4111
2991
  e.data.source === IncrementalSource.Mutation)) {
4112
2992
  mutationBuffers.forEach((buf) => buf.unfreeze());
4113
2993
  }
4114
- if (inEmittingFrame) {
4115
- emit === null || emit === void 0 ? void 0 : emit(eventProcessor(e), isCheckout);
4116
- }
4117
- else if (passEmitsToParent) {
4118
- const message = {
4119
- type: 'rrweb',
4120
- event: eventProcessor(e),
4121
- origin: window.location.origin,
4122
- isCheckout,
4123
- };
4124
- window.parent.postMessage(message, '*');
4125
- }
2994
+ emit(eventProcessor(e), isCheckout);
4126
2995
  if (e.type === EventType.FullSnapshot) {
4127
2996
  lastFullSnapshotEvent = e;
4128
2997
  incrementalSnapshotCount = 0;
@@ -4155,31 +3024,10 @@ function record(options = {}) {
4155
3024
  type: EventType.IncrementalSnapshot,
4156
3025
  data: Object.assign({ source: IncrementalSource.CanvasMutation }, p),
4157
3026
  }));
4158
- const wrappedAdoptedStyleSheetEmit = (a) => wrappedEmit(wrapEvent({
4159
- type: EventType.IncrementalSnapshot,
4160
- data: Object.assign({ source: IncrementalSource.AdoptedStyleSheet }, a),
4161
- }));
4162
- const stylesheetManager = new StylesheetManager({
4163
- mutationCb: wrappedMutationEmit,
4164
- adoptedStyleSheetCb: wrappedAdoptedStyleSheetEmit,
4165
- });
4166
3027
  const iframeManager = new IframeManager({
4167
- mirror,
4168
3028
  mutationCb: wrappedMutationEmit,
4169
- stylesheetManager: stylesheetManager,
4170
- recordCrossOriginIframes,
4171
- wrappedEmit,
4172
3029
  });
4173
- for (const plugin of plugins || []) {
4174
- if (plugin.getMirror)
4175
- plugin.getMirror({
4176
- nodeMirror: mirror,
4177
- crossOriginIframeMirror: iframeManager.crossOriginIframeMirror,
4178
- crossOriginIframeStyleMirror: iframeManager.crossOriginIframeStyleMirror,
4179
- });
4180
- }
4181
- const processedNodeManager = new ProcessedNodeManager();
4182
- canvasManager = new CanvasManager({
3030
+ const canvasManager = new CanvasManager({
4183
3031
  recordCanvas,
4184
3032
  mutationCb: wrappedCanvasMutationEmit,
4185
3033
  win: window,
@@ -4187,8 +3035,6 @@ function record(options = {}) {
4187
3035
  blockSelector,
4188
3036
  unblockSelector,
4189
3037
  mirror,
4190
- sampling: sampling.canvas,
4191
- dataURLOptions,
4192
3038
  });
4193
3039
  const shadowDomManager = new ShadowDomManager({
4194
3040
  mutationCb: wrappedMutationEmit,
@@ -4198,15 +3044,14 @@ function record(options = {}) {
4198
3044
  blockClass,
4199
3045
  blockSelector,
4200
3046
  unblockSelector,
4201
- maskAllText,
4202
3047
  maskTextClass,
4203
- unmaskTextClass,
4204
3048
  maskTextSelector,
4205
3049
  unmaskTextSelector,
3050
+ maskInputSelector,
3051
+ unmaskInputSelector,
4206
3052
  inlineStylesheet,
3053
+ maskAllText,
4207
3054
  maskInputOptions,
4208
- dataURLOptions,
4209
- maskAttributeFn,
4210
3055
  maskTextFn,
4211
3056
  maskInputFn,
4212
3057
  recordCanvas,
@@ -4214,14 +3059,12 @@ function record(options = {}) {
4214
3059
  sampling,
4215
3060
  slimDOMOptions,
4216
3061
  iframeManager,
4217
- stylesheetManager,
4218
3062
  canvasManager,
4219
- keepIframeSrcFn,
4220
- processedNodeManager,
4221
3063
  },
4222
3064
  mirror,
4223
3065
  });
4224
3066
  takeFullSnapshot = (isCheckout = false) => {
3067
+ var _a, _b, _c, _d;
4225
3068
  wrappedEmit(wrapEvent({
4226
3069
  type: EventType.Meta,
4227
3070
  data: {
@@ -4230,35 +3073,27 @@ function record(options = {}) {
4230
3073
  height: getWindowHeight(),
4231
3074
  },
4232
3075
  }), isCheckout);
4233
- stylesheetManager.reset();
4234
- shadowDomManager.init();
4235
3076
  mutationBuffers.forEach((buf) => buf.lock());
4236
- const node = snapshot(document, {
4237
- mirror,
3077
+ const [node, idNodeMap] = snapshot(document, {
4238
3078
  blockClass,
4239
3079
  blockSelector,
4240
3080
  unblockSelector,
4241
- maskAllText,
4242
3081
  maskTextClass,
4243
- unmaskTextClass,
4244
3082
  maskTextSelector,
4245
3083
  unmaskTextSelector,
3084
+ maskInputSelector,
3085
+ unmaskInputSelector,
4246
3086
  inlineStylesheet,
3087
+ maskAllText,
4247
3088
  maskAllInputs: maskInputOptions,
4248
- maskAttributeFn,
4249
- maskInputFn,
4250
3089
  maskTextFn,
4251
3090
  slimDOM: slimDOMOptions,
4252
- dataURLOptions,
4253
3091
  recordCanvas,
4254
3092
  inlineImages,
4255
3093
  onSerialize: (n) => {
4256
- if (isSerializedIframe(n, mirror)) {
3094
+ if (isIframeINode(n)) {
4257
3095
  iframeManager.addIframe(n);
4258
3096
  }
4259
- if (isSerializedStylesheet(n, mirror)) {
4260
- stylesheetManager.trackLinkElement(n);
4261
- }
4262
3097
  if (hasShadowRoot(n)) {
4263
3098
  shadowDomManager.addShadowRoot(n.shadowRoot, document);
4264
3099
  }
@@ -4267,27 +3102,42 @@ function record(options = {}) {
4267
3102
  iframeManager.attachIframe(iframe, childSn);
4268
3103
  shadowDomManager.observeAttachShadow(iframe);
4269
3104
  },
4270
- onStylesheetLoad: (linkEl, childSn) => {
4271
- stylesheetManager.attachLinkElement(linkEl, childSn);
4272
- },
4273
3105
  keepIframeSrcFn,
4274
3106
  });
4275
3107
  if (!node) {
4276
3108
  return console.warn('Failed to snapshot the document');
4277
3109
  }
3110
+ mirror.map = idNodeMap;
4278
3111
  wrappedEmit(wrapEvent({
4279
3112
  type: EventType.FullSnapshot,
4280
3113
  data: {
4281
3114
  node,
4282
- initialOffset: getWindowScroll(window),
3115
+ initialOffset: {
3116
+ left: window.pageXOffset !== undefined
3117
+ ? window.pageXOffset
3118
+ : (document === null || document === void 0 ? void 0 : document.documentElement.scrollLeft) ||
3119
+ ((_b = (_a = document === null || document === void 0 ? void 0 : document.body) === null || _a === void 0 ? void 0 : _a.parentElement) === null || _b === void 0 ? void 0 : _b.scrollLeft) ||
3120
+ (document === null || document === void 0 ? void 0 : document.body.scrollLeft) ||
3121
+ 0,
3122
+ top: window.pageYOffset !== undefined
3123
+ ? window.pageYOffset
3124
+ : (document === null || document === void 0 ? void 0 : document.documentElement.scrollTop) ||
3125
+ ((_d = (_c = document === null || document === void 0 ? void 0 : document.body) === null || _c === void 0 ? void 0 : _c.parentElement) === null || _d === void 0 ? void 0 : _d.scrollTop) ||
3126
+ (document === null || document === void 0 ? void 0 : document.body.scrollTop) ||
3127
+ 0,
3128
+ },
4283
3129
  },
4284
- }), isCheckout);
3130
+ }));
4285
3131
  mutationBuffers.forEach((buf) => buf.unlock());
4286
- if (document.adoptedStyleSheets && document.adoptedStyleSheets.length > 0)
4287
- stylesheetManager.adoptStyleSheets(document.adoptedStyleSheets, mirror.getId(document));
4288
3132
  };
4289
3133
  try {
4290
3134
  const handlers = [];
3135
+ handlers.push(on('DOMContentLoaded', () => {
3136
+ wrappedEmit(wrapEvent({
3137
+ type: EventType.DomContentLoaded,
3138
+ data: {},
3139
+ }));
3140
+ }));
4291
3141
  const observe = (doc) => {
4292
3142
  var _a;
4293
3143
  return callbackWrapper(initObservers)({
@@ -4330,26 +3180,14 @@ function record(options = {}) {
4330
3180
  type: EventType.IncrementalSnapshot,
4331
3181
  data: Object.assign({ source: IncrementalSource.Font }, p),
4332
3182
  })),
4333
- selectionCb: (p) => {
4334
- wrappedEmit(wrapEvent({
4335
- type: EventType.IncrementalSnapshot,
4336
- data: Object.assign({ source: IncrementalSource.Selection }, p),
4337
- }));
4338
- },
4339
- customElementCb: (c) => {
4340
- wrappedEmit(wrapEvent({
4341
- type: EventType.IncrementalSnapshot,
4342
- data: Object.assign({ source: IncrementalSource.CustomElement }, c),
4343
- }));
4344
- },
4345
3183
  blockClass,
4346
3184
  ignoreClass,
4347
3185
  ignoreSelector,
4348
- maskAllText,
4349
3186
  maskTextClass,
4350
- unmaskTextClass,
4351
3187
  maskTextSelector,
4352
3188
  unmaskTextSelector,
3189
+ maskInputSelector,
3190
+ unmaskInputSelector,
4353
3191
  maskInputOptions,
4354
3192
  inlineStylesheet,
4355
3193
  sampling,
@@ -4358,21 +3196,16 @@ function record(options = {}) {
4358
3196
  userTriggeredOnInput,
4359
3197
  collectFonts,
4360
3198
  doc,
4361
- maskAttributeFn,
3199
+ maskAllText,
4362
3200
  maskInputFn,
4363
3201
  maskTextFn,
4364
- keepIframeSrcFn,
4365
3202
  blockSelector,
4366
3203
  unblockSelector,
4367
3204
  slimDOMOptions,
4368
- dataURLOptions,
4369
3205
  mirror,
4370
3206
  iframeManager,
4371
- stylesheetManager,
4372
3207
  shadowDomManager,
4373
- processedNodeManager,
4374
3208
  canvasManager,
4375
- ignoreCSSAttributes,
4376
3209
  plugins: ((_a = plugins === null || plugins === void 0 ? void 0 : plugins.filter((p) => p.observer)) === null || _a === void 0 ? void 0 : _a.map((p) => ({
4377
3210
  observer: p.observer,
4378
3211
  options: p.options,
@@ -4397,35 +3230,22 @@ function record(options = {}) {
4397
3230
  const init = () => {
4398
3231
  takeFullSnapshot();
4399
3232
  handlers.push(observe(document));
4400
- recording = true;
4401
3233
  };
4402
3234
  if (document.readyState === 'interactive' ||
4403
3235
  document.readyState === 'complete') {
4404
3236
  init();
4405
3237
  }
4406
3238
  else {
4407
- handlers.push(on('DOMContentLoaded', () => {
4408
- wrappedEmit(wrapEvent({
4409
- type: EventType.DomContentLoaded,
4410
- data: {},
4411
- }));
4412
- if (recordAfter === 'DOMContentLoaded')
4413
- init();
4414
- }));
4415
3239
  handlers.push(on('load', () => {
4416
3240
  wrappedEmit(wrapEvent({
4417
3241
  type: EventType.Load,
4418
3242
  data: {},
4419
3243
  }));
4420
- if (recordAfter === 'load')
4421
- init();
3244
+ init();
4422
3245
  }, window));
4423
3246
  }
4424
3247
  return () => {
4425
3248
  handlers.forEach((h) => h());
4426
- processedNodeManager.destroy();
4427
- recording = false;
4428
- unregisterErrorHandler();
4429
3249
  };
4430
3250
  }
4431
3251
  catch (error) {
@@ -4433,7 +3253,7 @@ function record(options = {}) {
4433
3253
  }
4434
3254
  }
4435
3255
  record.addCustomEvent = (tag, payload) => {
4436
- if (!recording) {
3256
+ if (!wrappedEmit) {
4437
3257
  throw new Error('please add custom event after start recording');
4438
3258
  }
4439
3259
  wrappedEmit(wrapEvent({
@@ -4448,7 +3268,7 @@ record.freezePage = () => {
4448
3268
  mutationBuffers.forEach((buf) => buf.freeze());
4449
3269
  };
4450
3270
  record.takeFullSnapshot = (isCheckout) => {
4451
- if (!recording) {
3271
+ if (!takeFullSnapshot) {
4452
3272
  throw new Error('please take full snapshot after start recording');
4453
3273
  }
4454
3274
  takeFullSnapshot(isCheckout);
@@ -4944,25 +3764,27 @@ const handleDomListener = (
4944
3764
 
4945
3765
  /** Get the base DOM breadcrumb. */
4946
3766
  function getBaseDomBreadcrumb(target, message) {
4947
- const nodeId = record.mirror.getId(target);
4948
- const node = nodeId && record.mirror.getNode(nodeId);
4949
- const meta = node && record.mirror.getMeta(node);
4950
- const element = meta && isElement(meta) ? meta : null;
3767
+ // `__sn` property is the serialized node created by rrweb
3768
+ const serializedNode = target && isRrwebNode(target) && target.__sn.type === NodeType.Element ? target.__sn : null;
4951
3769
 
4952
3770
  return {
4953
3771
  message,
4954
- data: element
3772
+ data: serializedNode
4955
3773
  ? {
4956
- nodeId,
3774
+ nodeId: serializedNode.id,
4957
3775
  node: {
4958
- id: nodeId,
4959
- tagName: element.tagName,
4960
- textContent: Array.from(element.childNodes)
4961
- .map((node) => node.type === NodeType.Text && node.textContent)
4962
- .filter(Boolean) // filter out empty values
4963
- .map(text => (text ).trim())
4964
- .join(''),
4965
- attributes: getAttributesToRecord(element.attributes),
3776
+ id: serializedNode.id,
3777
+ tagName: serializedNode.tagName,
3778
+ textContent: target
3779
+ ? Array.from(target.childNodes)
3780
+ .map(
3781
+ (node) => '__sn' in node && node.__sn.type === NodeType.Text && node.__sn.textContent,
3782
+ )
3783
+ .filter(Boolean) // filter out empty values
3784
+ .map(text => (text ).trim())
3785
+ .join('')
3786
+ : '',
3787
+ attributes: getAttributesToRecord(serializedNode.attributes),
4966
3788
  },
4967
3789
  }
4968
3790
  : {},
@@ -4999,8 +3821,8 @@ function getDomTarget(handlerData) {
4999
3821
  return { target, message };
5000
3822
  }
5001
3823
 
5002
- function isElement(node) {
5003
- return node.type === NodeType.Element;
3824
+ function isRrwebNode(node) {
3825
+ return '__sn' in node;
5004
3826
  }
5005
3827
 
5006
3828
  /** Handle keyboard events & create breadcrumbs. */
@@ -5738,6 +4560,7 @@ function makeSession(session) {
5738
4560
  const lastActivity = session.lastActivity || now;
5739
4561
  const segmentId = session.segmentId || 0;
5740
4562
  const sampled = session.sampled;
4563
+ const shouldRefresh = typeof session.shouldRefresh === 'boolean' ? session.shouldRefresh : true;
5741
4564
  const previousSessionId = session.previousSessionId;
5742
4565
 
5743
4566
  return {
@@ -5746,6 +4569,7 @@ function makeSession(session) {
5746
4569
  lastActivity,
5747
4570
  segmentId,
5748
4571
  sampled,
4572
+ shouldRefresh,
5749
4573
  previousSessionId,
5750
4574
  };
5751
4575
  }
@@ -5840,19 +4664,46 @@ function isSessionExpired(session, timeouts, targetTime = +new Date()) {
5840
4664
  );
5841
4665
  }
5842
4666
 
5843
- /** If the session should be refreshed or not. */
5844
- function shouldRefreshSession(session, timeouts) {
4667
+ /**
4668
+ * Check a session, and either return it or a refreshed version of it.
4669
+ * The refreshed version may be unsampled.
4670
+ * You can check if the session has changed by comparing the session IDs.
4671
+ */
4672
+ function maybeRefreshSession(
4673
+ session,
4674
+ {
4675
+ timeouts,
4676
+ traceInternals,
4677
+ }
4678
+
4679
+ ,
4680
+ sessionOptions,
4681
+ ) {
5845
4682
  // If not expired, all good, just keep the session
5846
4683
  if (!isSessionExpired(session, timeouts)) {
5847
- return false;
4684
+ return session;
5848
4685
  }
5849
4686
 
5850
- // If we are buffering & haven't ever flushed yet, always continue
5851
- if (session.sampled === 'buffer' && session.segmentId === 0) {
5852
- return false;
4687
+ const isBuffering = session.sampled === 'buffer';
4688
+
4689
+ // If we are buffering & the session may be refreshed, just return it
4690
+ if (isBuffering && session.shouldRefresh) {
4691
+ return session;
4692
+ }
4693
+
4694
+ // If we are buffering & the session may not be refreshed (=it was converted to session previously already)
4695
+ // We return an unsampled new session
4696
+ if (isBuffering) {
4697
+ logInfoNextTick('[Replay] Session should not be refreshed', traceInternals);
4698
+ return makeSession({ sampled: false });
5853
4699
  }
5854
4700
 
5855
- return true;
4701
+ // Else, we are not buffering, and the session is expired, so we need to create a new one
4702
+ logInfoNextTick('[Replay] Session has expired, creating new one...', traceInternals);
4703
+
4704
+ const newSession = createSession(sessionOptions, { previousSessionId: session.id });
4705
+
4706
+ return newSession;
5856
4707
  }
5857
4708
 
5858
4709
  /**
@@ -5860,29 +4711,25 @@ function shouldRefreshSession(session, timeouts) {
5860
4711
  * Returns a session that may be unsampled.
5861
4712
  */
5862
4713
  function loadOrCreateSession(
4714
+ currentSession,
5863
4715
  {
5864
4716
  timeouts,
5865
4717
  traceInternals,
5866
- previousSessionId,
5867
4718
  }
5868
4719
 
5869
4720
  ,
5870
4721
  sessionOptions,
5871
4722
  ) {
5872
- const existingSession = sessionOptions.stickySession && fetchSession(traceInternals);
4723
+ // If session exists and is passed, use it instead of always hitting session storage
4724
+ const existingSession = currentSession || (sessionOptions.stickySession && fetchSession(traceInternals));
5873
4725
 
5874
4726
  // No session exists yet, just create a new one
5875
4727
  if (!existingSession) {
5876
- logInfoNextTick('[Replay] Creating new session', traceInternals);
5877
- return createSession(sessionOptions, { previousSessionId });
4728
+ logInfoNextTick('[Replay] Created new session', traceInternals);
4729
+ return createSession(sessionOptions);
5878
4730
  }
5879
4731
 
5880
- if (!shouldRefreshSession(existingSession, timeouts)) {
5881
- return existingSession;
5882
- }
5883
-
5884
- logInfoNextTick('[Replay] Session in sessionStorage is expired, creating new one...');
5885
- return createSession(sessionOptions, { previousSessionId: existingSession.id });
4732
+ return maybeRefreshSession(existingSession, { timeouts, traceInternals }, sessionOptions);
5886
4733
  }
5887
4734
 
5888
4735
  function isCustomEvent(event) {
@@ -7780,7 +6627,9 @@ function createLargestContentfulPaint(
7780
6627
  data: {
7781
6628
  value, // LCP "duration" in ms
7782
6629
  size,
7783
- nodeId: record.mirror.getId(entry.element),
6630
+ // Not sure why this errors, Node should be correct (Argument of type 'Node' is not assignable to parameter of type 'INode')
6631
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
6632
+ nodeId: record.mirror.getId(entry.element ),
7784
6633
  },
7785
6634
  };
7786
6635
  }
@@ -8474,7 +7323,7 @@ class ReplayContainer {
8474
7323
  * Initializes the plugin based on sampling configuration. Should not be
8475
7324
  * called outside of constructor.
8476
7325
  */
8477
- initializeSampling(previousSessionId) {
7326
+ initializeSampling() {
8478
7327
  const { errorSampleRate, sessionSampleRate } = this._options;
8479
7328
 
8480
7329
  // If neither sample rate is > 0, then do nothing - user will need to call one of
@@ -8485,7 +7334,7 @@ class ReplayContainer {
8485
7334
 
8486
7335
  // Otherwise if there is _any_ sample rate set, try to load an existing
8487
7336
  // session, or create a new one.
8488
- this._initializeSessionForSampling(previousSessionId);
7337
+ this._initializeSessionForSampling();
8489
7338
 
8490
7339
  if (!this.session) {
8491
7340
  // This should not happen, something wrong has occurred
@@ -8530,6 +7379,7 @@ class ReplayContainer {
8530
7379
  logInfoNextTick('[Replay] Starting replay in session mode', this._options._experiments.traceInternals);
8531
7380
 
8532
7381
  const session = loadOrCreateSession(
7382
+ this.session,
8533
7383
  {
8534
7384
  timeouts: this.timeouts,
8535
7385
  traceInternals: this._options._experiments.traceInternals,
@@ -8559,6 +7409,7 @@ class ReplayContainer {
8559
7409
  logInfoNextTick('[Replay] Starting replay in buffer mode', this._options._experiments.traceInternals);
8560
7410
 
8561
7411
  const session = loadOrCreateSession(
7412
+ this.session,
8562
7413
  {
8563
7414
  timeouts: this.timeouts,
8564
7415
  traceInternals: this._options._experiments.traceInternals,
@@ -8626,18 +7477,15 @@ class ReplayContainer {
8626
7477
  return;
8627
7478
  }
8628
7479
 
8629
- // We can't move `_isEnabled` after awaiting a flush, otherwise we can
8630
- // enter into an infinite loop when `stop()` is called while flushing.
8631
- this._isEnabled = false;
8632
-
8633
7480
  try {
8634
7481
  logInfo(
8635
- `[Replay] Stopping Replay${reason ? ` triggered by ${reason}` : ''} ${new Date().toISOString()} ${
8636
- this._isEnabled
8637
- }`,
7482
+ `[Replay] Stopping Replay${reason ? ` triggered by ${reason}` : ''}`,
8638
7483
  this._options._experiments.traceInternals,
8639
7484
  );
8640
7485
 
7486
+ // We can't move `_isEnabled` after awaiting a flush, otherwise we can
7487
+ // enter into an infinite loop when `stop()` is called while flushing.
7488
+ this._isEnabled = false;
8641
7489
  this._removeListeners();
8642
7490
  this.stopRecording();
8643
7491
 
@@ -8731,6 +7579,16 @@ class ReplayContainer {
8731
7579
 
8732
7580
  // Once this session ends, we do not want to refresh it
8733
7581
  if (this.session) {
7582
+ this.session.shouldRefresh = false;
7583
+
7584
+ // It's possible that the session lifespan is > max session lifespan
7585
+ // because we have been buffering beyond max session lifespan (we ignore
7586
+ // expiration given that `shouldRefresh` is true). Since we flip
7587
+ // `shouldRefresh`, the session could be considered expired due to
7588
+ // lifespan, which is not what we want. Update session start date to be
7589
+ // the current timestamp, so that session is not considered to be
7590
+ // expired. This means that max replay duration can be MAX_SESSION_LIFE +
7591
+ // (length of buffer), which we are ok with.
8734
7592
  this._updateUserActivity(activityTime);
8735
7593
  this._updateSessionActivity(activityTime);
8736
7594
  this._maybeSaveSession();
@@ -8982,7 +7840,6 @@ class ReplayContainer {
8982
7840
 
8983
7841
  // Need to set as enabled before we start recording, as `record()` can trigger a flush with a new checkout
8984
7842
  this._isEnabled = true;
8985
- this._isPaused = false;
8986
7843
 
8987
7844
  this.startRecording();
8988
7845
  }
@@ -8999,16 +7856,16 @@ class ReplayContainer {
8999
7856
  /**
9000
7857
  * Loads (or refreshes) the current session.
9001
7858
  */
9002
- _initializeSessionForSampling(previousSessionId) {
7859
+ _initializeSessionForSampling() {
9003
7860
  // Whenever there is _any_ error sample rate, we always allow buffering
9004
7861
  // Because we decide on sampling when an error occurs, we need to buffer at all times if sampling for errors
9005
7862
  const allowBuffering = this._options.errorSampleRate > 0;
9006
7863
 
9007
7864
  const session = loadOrCreateSession(
7865
+ this.session,
9008
7866
  {
9009
7867
  timeouts: this.timeouts,
9010
7868
  traceInternals: this._options._experiments.traceInternals,
9011
- previousSessionId,
9012
7869
  },
9013
7870
  {
9014
7871
  stickySession: this._options.stickySession,
@@ -9033,27 +7890,36 @@ class ReplayContainer {
9033
7890
 
9034
7891
  const currentSession = this.session;
9035
7892
 
9036
- if (shouldRefreshSession(currentSession, this.timeouts)) {
9037
- void this._refreshSession(currentSession);
7893
+ const newSession = maybeRefreshSession(
7894
+ currentSession,
7895
+ {
7896
+ timeouts: this.timeouts,
7897
+ traceInternals: this._options._experiments.traceInternals,
7898
+ },
7899
+ {
7900
+ stickySession: Boolean(this._options.stickySession),
7901
+ sessionSampleRate: this._options.sessionSampleRate,
7902
+ allowBuffering: this._options.errorSampleRate > 0,
7903
+ },
7904
+ );
7905
+
7906
+ const isNew = newSession.id !== currentSession.id;
7907
+
7908
+ // If session was newly created (i.e. was not loaded from storage), then
7909
+ // enable flag to create the root replay
7910
+ if (isNew) {
7911
+ this.setInitialState();
7912
+ this.session = newSession;
7913
+ }
7914
+
7915
+ if (!this.session.sampled) {
7916
+ void this.stop({ reason: 'session not refreshed' });
9038
7917
  return false;
9039
7918
  }
9040
7919
 
9041
7920
  return true;
9042
7921
  }
9043
7922
 
9044
- /**
9045
- * Refresh a session with a new one.
9046
- * This stops the current session (without forcing a flush, as that would never work since we are expired),
9047
- * and then does a new sampling based on the refreshed session.
9048
- */
9049
- async _refreshSession(session) {
9050
- if (!this._isEnabled) {
9051
- return;
9052
- }
9053
- await this.stop({ reason: 'refresh session' });
9054
- this.initializeSampling(session.id);
9055
- }
9056
-
9057
7923
  /**
9058
7924
  * Adds listeners to record events for the replay
9059
7925
  */
@@ -9310,9 +8176,7 @@ class ReplayContainer {
9310
8176
  * Should never be called directly, only by `flush`
9311
8177
  */
9312
8178
  async _runFlush() {
9313
- const replayId = this.getSessionId();
9314
-
9315
- if (!this.session || !this.eventBuffer || !replayId) {
8179
+ if (!this.session || !this.eventBuffer) {
9316
8180
  (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) && logger.error('[Replay] No session or eventBuffer found to flush.');
9317
8181
  return;
9318
8182
  }
@@ -9332,15 +8196,13 @@ class ReplayContainer {
9332
8196
  return;
9333
8197
  }
9334
8198
 
9335
- // if this changed in the meanwhile, e.g. because the session was refreshed or similar, we abort here
9336
- if (replayId !== this.getSessionId()) {
9337
- return;
9338
- }
9339
-
9340
8199
  try {
9341
8200
  // This uses the data from the eventBuffer, so we need to call this before `finish()
9342
8201
  this._updateInitialTimestampFromEventBuffer();
9343
8202
 
8203
+ // Note this empties the event buffer regardless of outcome of sending replay
8204
+ const recordingData = await this.eventBuffer.finish();
8205
+
9344
8206
  const timestamp = Date.now();
9345
8207
 
9346
8208
  // Check total duration again, to avoid sending outdated stuff
@@ -9350,14 +8212,14 @@ class ReplayContainer {
9350
8212
  throw new Error('Session is too long, not sending replay');
9351
8213
  }
9352
8214
 
8215
+ // NOTE: Copy values from instance members, as it's possible they could
8216
+ // change before the flush finishes.
8217
+ const replayId = this.session.id;
9353
8218
  const eventContext = this._popEventContext();
9354
8219
  // Always increment segmentId regardless of outcome of sending replay
9355
8220
  const segmentId = this.session.segmentId++;
9356
8221
  this._maybeSaveSession();
9357
8222
 
9358
- // Note this empties the event buffer regardless of outcome of sending replay
9359
- const recordingData = await this.eventBuffer.finish();
9360
-
9361
8223
  await sendReplay({
9362
8224
  replayId,
9363
8225
  recordingData,
@@ -9564,6 +8426,8 @@ function getPrivacyOptions({
9564
8426
  // We are making the decision to make text and input selectors the same
9565
8427
  maskTextSelector: maskSelector,
9566
8428
  unmaskTextSelector: unmaskSelector,
8429
+ maskInputSelector: maskSelector,
8430
+ unmaskInputSelector: unmaskSelector,
9567
8431
 
9568
8432
  blockSelector: getOption(
9569
8433
  block,
@@ -9599,39 +8463,6 @@ function isElectronNodeRenderer() {
9599
8463
  return typeof process !== 'undefined' && (process ).type === 'renderer';
9600
8464
  }
9601
8465
 
9602
- /**
9603
- * Masks an attribute if necessary, otherwise return attribute value as-is.
9604
- */
9605
- function maskAttribute({
9606
- el,
9607
- key,
9608
- maskAttributes,
9609
- maskAllText,
9610
- privacyOptions,
9611
- value,
9612
- }) {
9613
- // We only mask attributes if `maskAllText` is true
9614
- if (!maskAllText) {
9615
- return value;
9616
- }
9617
-
9618
- // unmaskTextSelector takes precendence
9619
- if (privacyOptions.unmaskTextSelector && el.matches(privacyOptions.unmaskTextSelector)) {
9620
- return value;
9621
- }
9622
-
9623
- if (
9624
- maskAttributes.includes(key) ||
9625
- // Need to mask `value` attribute for `<input>` if it's a button-like
9626
- // type
9627
- (key === 'value' && el.tagName === 'INPUT' && ['submit', 'button'].includes(el.getAttribute('type') || ''))
9628
- ) {
9629
- return value.replace(/[\S]/g, '*');
9630
- }
9631
-
9632
- return value;
9633
- }
9634
-
9635
8466
  const MEDIA_SELECTORS =
9636
8467
  'img,image,svg,video,object,picture,embed,map,audio,link[rel="icon"],link[rel="apple-touch-icon"]';
9637
8468
 
@@ -9690,7 +8521,6 @@ class Replay {
9690
8521
  networkResponseHeaders = [],
9691
8522
 
9692
8523
  mask = [],
9693
- maskAttributes = ['title', 'placeholder'],
9694
8524
  unmask = [],
9695
8525
  block = [],
9696
8526
  unblock = [],
@@ -9714,36 +8544,25 @@ class Replay {
9714
8544
  } = {}) {
9715
8545
  this.name = Replay.id;
9716
8546
 
9717
- const privacyOptions = getPrivacyOptions({
9718
- mask,
9719
- unmask,
9720
- block,
9721
- unblock,
9722
- ignore,
9723
- blockClass,
9724
- blockSelector,
9725
- maskTextClass,
9726
- maskTextSelector,
9727
- ignoreClass,
9728
- });
9729
-
9730
8547
  this._recordingOptions = {
9731
8548
  maskAllInputs,
9732
8549
  maskAllText,
9733
8550
  maskInputOptions: { ...(maskInputOptions || {}), password: true },
9734
8551
  maskTextFn: maskFn,
9735
8552
  maskInputFn: maskFn,
9736
- maskAttributeFn: (key, value, el) =>
9737
- maskAttribute({
9738
- maskAttributes,
9739
- maskAllText,
9740
- privacyOptions,
9741
- key,
9742
- value,
9743
- el,
9744
- }),
9745
8553
 
9746
- ...privacyOptions,
8554
+ ...getPrivacyOptions({
8555
+ mask,
8556
+ unmask,
8557
+ block,
8558
+ unblock,
8559
+ ignore,
8560
+ blockClass,
8561
+ blockSelector,
8562
+ maskTextClass,
8563
+ maskTextSelector,
8564
+ ignoreClass,
8565
+ }),
9747
8566
 
9748
8567
  // Our defaults
9749
8568
  slimDOMOptions: 'all',
@@ -9753,16 +8572,6 @@ class Replay {
9753
8572
  // collect fonts, but be aware that `sentry.io` needs to be an allowed
9754
8573
  // origin for playback
9755
8574
  collectFonts: true,
9756
- errorHandler: (err) => {
9757
- try {
9758
- // @ts-ignore Set this so that replay SDK can ignore errors originating from rrweb
9759
- err.__rrweb__ = true;
9760
- } catch (e) {
9761
- // avoid any potential hazards here
9762
- }
9763
- // return true to suppress throwing the error inside of rrweb
9764
- return true;
9765
- },
9766
8575
  };
9767
8576
 
9768
8577
  this._initialOptions = {