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