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