@sentry/replay 7.72.0 → 7.73.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 +2202 -966
- package/cjs/index.js.map +1 -1
- package/esm/index.js +2203 -967
- 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/handleDom.d.ts +1 -2
- package/types/coreHandlers/handleDom.d.ts.map +1 -1
- package/types/integration.d.ts +1 -1
- package/types/integration.d.ts.map +1 -1
- package/types/types/replay.d.ts +6 -1
- package/types/types/replay.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/types-ts3.8/constants.d.ts +2 -0
- package/types-ts3.8/coreHandlers/handleDom.d.ts +1 -2
- package/types-ts3.8/integration.d.ts +1 -1
- package/types-ts3.8/types/replay.d.ts +6 -1
- package/types-ts3.8/util/getPrivacyOptions.d.ts +0 -2
- package/types-ts3.8/util/maskAttribute.d.ts +15 -0
package/cjs/index.js
CHANGED
|
@@ -63,44 +63,159 @@ var NodeType$1;
|
|
|
63
63
|
NodeType[NodeType["Comment"] = 5] = "Comment";
|
|
64
64
|
})(NodeType$1 || (NodeType$1 = {}));
|
|
65
65
|
|
|
66
|
-
function isElement(n) {
|
|
66
|
+
function isElement$1(n) {
|
|
67
67
|
return n.nodeType === n.ELEMENT_NODE;
|
|
68
68
|
}
|
|
69
69
|
function isShadowRoot(n) {
|
|
70
70
|
const host = n === null || n === void 0 ? void 0 : n.host;
|
|
71
|
-
return Boolean(host
|
|
71
|
+
return Boolean((host === null || host === void 0 ? void 0 : host.shadowRoot) === n);
|
|
72
72
|
}
|
|
73
|
-
function
|
|
74
|
-
|
|
75
|
-
|
|
73
|
+
function isNativeShadowDom(shadowRoot) {
|
|
74
|
+
return Object.prototype.toString.call(shadowRoot) === '[object ShadowRoot]';
|
|
75
|
+
}
|
|
76
|
+
function fixBrowserCompatibilityIssuesInCSS(cssText) {
|
|
77
|
+
if (cssText.includes(' background-clip: text;') &&
|
|
78
|
+
!cssText.includes(' -webkit-background-clip: text;')) {
|
|
79
|
+
cssText = cssText.replace(' background-clip: text;', ' -webkit-background-clip: text; background-clip: text;');
|
|
76
80
|
}
|
|
77
|
-
|
|
78
|
-
return (maskInputOptions[tagName.toLowerCase()] ||
|
|
79
|
-
(actualType && maskInputOptions[actualType]) ||
|
|
80
|
-
actualType === 'password' ||
|
|
81
|
-
(tagName === 'input' && !type && maskInputOptions['text']));
|
|
81
|
+
return cssText;
|
|
82
82
|
}
|
|
83
|
-
function
|
|
84
|
-
|
|
83
|
+
function escapeImportStatement(rule) {
|
|
84
|
+
const { cssText } = rule;
|
|
85
|
+
if (cssText.split('"').length < 3)
|
|
86
|
+
return cssText;
|
|
87
|
+
const statement = ['@import', `url(${JSON.stringify(rule.href)})`];
|
|
88
|
+
if (rule.layerName === '') {
|
|
89
|
+
statement.push(`layer`);
|
|
90
|
+
}
|
|
91
|
+
else if (rule.layerName) {
|
|
92
|
+
statement.push(`layer(${rule.layerName})`);
|
|
93
|
+
}
|
|
94
|
+
if (rule.supportsText) {
|
|
95
|
+
statement.push(`supports(${rule.supportsText})`);
|
|
96
|
+
}
|
|
97
|
+
if (rule.media.length) {
|
|
98
|
+
statement.push(rule.media.mediaText);
|
|
99
|
+
}
|
|
100
|
+
return statement.join(' ') + ';';
|
|
85
101
|
}
|
|
86
|
-
function
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
return
|
|
102
|
+
function stringifyStylesheet(s) {
|
|
103
|
+
try {
|
|
104
|
+
const rules = s.rules || s.cssRules;
|
|
105
|
+
return rules
|
|
106
|
+
? fixBrowserCompatibilityIssuesInCSS(Array.from(rules, stringifyRule).join(''))
|
|
107
|
+
: null;
|
|
90
108
|
}
|
|
91
|
-
|
|
92
|
-
|
|
109
|
+
catch (error) {
|
|
110
|
+
return null;
|
|
93
111
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
112
|
+
}
|
|
113
|
+
function stringifyRule(rule) {
|
|
114
|
+
let importStringified;
|
|
115
|
+
if (isCSSImportRule(rule)) {
|
|
116
|
+
try {
|
|
117
|
+
importStringified =
|
|
118
|
+
stringifyStylesheet(rule.styleSheet) ||
|
|
119
|
+
escapeImportStatement(rule);
|
|
98
120
|
}
|
|
99
|
-
|
|
100
|
-
|
|
121
|
+
catch (error) {
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
else if (isCSSStyleRule(rule) && rule.selectorText.includes(':')) {
|
|
125
|
+
return fixSafariColons(rule.cssText);
|
|
126
|
+
}
|
|
127
|
+
return importStringified || rule.cssText;
|
|
128
|
+
}
|
|
129
|
+
function fixSafariColons(cssStringified) {
|
|
130
|
+
const regex = /(\[(?:[\w-]+)[^\\])(:(?:[\w-]+)\])/gm;
|
|
131
|
+
return cssStringified.replace(regex, '$1\\$2');
|
|
132
|
+
}
|
|
133
|
+
function isCSSImportRule(rule) {
|
|
134
|
+
return 'styleSheet' in rule;
|
|
135
|
+
}
|
|
136
|
+
function isCSSStyleRule(rule) {
|
|
137
|
+
return 'selectorText' in rule;
|
|
138
|
+
}
|
|
139
|
+
class Mirror {
|
|
140
|
+
constructor() {
|
|
141
|
+
this.idNodeMap = new Map();
|
|
142
|
+
this.nodeMetaMap = new WeakMap();
|
|
143
|
+
}
|
|
144
|
+
getId(n) {
|
|
145
|
+
var _a;
|
|
146
|
+
if (!n)
|
|
147
|
+
return -1;
|
|
148
|
+
const id = (_a = this.getMeta(n)) === null || _a === void 0 ? void 0 : _a.id;
|
|
149
|
+
return id !== null && id !== void 0 ? id : -1;
|
|
150
|
+
}
|
|
151
|
+
getNode(id) {
|
|
152
|
+
return this.idNodeMap.get(id) || null;
|
|
153
|
+
}
|
|
154
|
+
getIds() {
|
|
155
|
+
return Array.from(this.idNodeMap.keys());
|
|
156
|
+
}
|
|
157
|
+
getMeta(n) {
|
|
158
|
+
return this.nodeMetaMap.get(n) || null;
|
|
159
|
+
}
|
|
160
|
+
removeNodeFromMap(n) {
|
|
161
|
+
const id = this.getId(n);
|
|
162
|
+
this.idNodeMap.delete(id);
|
|
163
|
+
if (n.childNodes) {
|
|
164
|
+
n.childNodes.forEach((childNode) => this.removeNodeFromMap(childNode));
|
|
101
165
|
}
|
|
102
166
|
}
|
|
103
|
-
|
|
167
|
+
has(id) {
|
|
168
|
+
return this.idNodeMap.has(id);
|
|
169
|
+
}
|
|
170
|
+
hasNode(node) {
|
|
171
|
+
return this.nodeMetaMap.has(node);
|
|
172
|
+
}
|
|
173
|
+
add(n, meta) {
|
|
174
|
+
const id = meta.id;
|
|
175
|
+
this.idNodeMap.set(id, n);
|
|
176
|
+
this.nodeMetaMap.set(n, meta);
|
|
177
|
+
}
|
|
178
|
+
replace(id, n) {
|
|
179
|
+
const oldNode = this.getNode(id);
|
|
180
|
+
if (oldNode) {
|
|
181
|
+
const meta = this.nodeMetaMap.get(oldNode);
|
|
182
|
+
if (meta)
|
|
183
|
+
this.nodeMetaMap.set(n, meta);
|
|
184
|
+
}
|
|
185
|
+
this.idNodeMap.set(id, n);
|
|
186
|
+
}
|
|
187
|
+
reset() {
|
|
188
|
+
this.idNodeMap = new Map();
|
|
189
|
+
this.nodeMetaMap = new WeakMap();
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
function createMirror() {
|
|
193
|
+
return new Mirror();
|
|
194
|
+
}
|
|
195
|
+
function shouldMaskInput({ maskInputOptions, tagName, type, }) {
|
|
196
|
+
if (tagName === 'OPTION') {
|
|
197
|
+
tagName = 'SELECT';
|
|
198
|
+
}
|
|
199
|
+
return Boolean(maskInputOptions[tagName.toLowerCase()] ||
|
|
200
|
+
(type && maskInputOptions[type]) ||
|
|
201
|
+
type === 'password' ||
|
|
202
|
+
(tagName === 'INPUT' && !type && maskInputOptions['text']));
|
|
203
|
+
}
|
|
204
|
+
function maskInputValue({ isMasked, element, value, maskInputFn, }) {
|
|
205
|
+
let text = value || '';
|
|
206
|
+
if (!isMasked) {
|
|
207
|
+
return text;
|
|
208
|
+
}
|
|
209
|
+
if (maskInputFn) {
|
|
210
|
+
text = maskInputFn(text, element);
|
|
211
|
+
}
|
|
212
|
+
return '*'.repeat(text.length);
|
|
213
|
+
}
|
|
214
|
+
function toLowerCase(str) {
|
|
215
|
+
return str.toLowerCase();
|
|
216
|
+
}
|
|
217
|
+
function toUpperCase(str) {
|
|
218
|
+
return str.toUpperCase();
|
|
104
219
|
}
|
|
105
220
|
const ORIGINAL_ATTRIBUTE_NAME = '__rrweb_original__';
|
|
106
221
|
function is2DCanvasBlank(canvas) {
|
|
@@ -126,11 +241,11 @@ function getInputType(element) {
|
|
|
126
241
|
return element.hasAttribute('data-rr-is-password')
|
|
127
242
|
? 'password'
|
|
128
243
|
: type
|
|
129
|
-
?
|
|
244
|
+
?
|
|
245
|
+
toLowerCase(type)
|
|
130
246
|
: null;
|
|
131
247
|
}
|
|
132
248
|
function getInputValue(el, tagName, type) {
|
|
133
|
-
typeof type === 'string' ? type.toLowerCase() : '';
|
|
134
249
|
if (tagName === 'INPUT' && (type === 'radio' || type === 'checkbox')) {
|
|
135
250
|
return el.getAttribute('value') || '';
|
|
136
251
|
}
|
|
@@ -140,9 +255,6 @@ function getInputValue(el, tagName, type) {
|
|
|
140
255
|
let _id = 1;
|
|
141
256
|
const tagNameRegex = new RegExp('[^a-z0-9-_:]');
|
|
142
257
|
const IGNORED_NODE = -2;
|
|
143
|
-
function defaultMaskFn(str) {
|
|
144
|
-
return str ? str.replace(/[\S]/g, '*') : '';
|
|
145
|
-
}
|
|
146
258
|
function genId() {
|
|
147
259
|
return _id++;
|
|
148
260
|
}
|
|
@@ -150,49 +262,12 @@ function getValidTagName(element) {
|
|
|
150
262
|
if (element instanceof HTMLFormElement) {
|
|
151
263
|
return 'form';
|
|
152
264
|
}
|
|
153
|
-
const processedTagName = element.tagName
|
|
265
|
+
const processedTagName = toLowerCase(element.tagName);
|
|
154
266
|
if (tagNameRegex.test(processedTagName)) {
|
|
155
267
|
return 'div';
|
|
156
268
|
}
|
|
157
269
|
return processedTagName;
|
|
158
270
|
}
|
|
159
|
-
function getCssRulesString(s) {
|
|
160
|
-
try {
|
|
161
|
-
const rules = s.rules || s.cssRules;
|
|
162
|
-
return rules ? Array.from(rules).map(getCssRuleString).join('') : null;
|
|
163
|
-
}
|
|
164
|
-
catch (error) {
|
|
165
|
-
return null;
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
function getCssRuleString(rule) {
|
|
169
|
-
let cssStringified = rule.cssText;
|
|
170
|
-
if (isCSSImportRule(rule)) {
|
|
171
|
-
try {
|
|
172
|
-
cssStringified = getCssRulesString(rule.styleSheet) || cssStringified;
|
|
173
|
-
}
|
|
174
|
-
catch (_a) {
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
return validateStringifiedCssRule(cssStringified);
|
|
178
|
-
}
|
|
179
|
-
function validateStringifiedCssRule(cssStringified) {
|
|
180
|
-
if (cssStringified.indexOf(':') > -1) {
|
|
181
|
-
const regex = /(\[(?:[\w-]+)[^\\])(:(?:[\w-]+)\])/gm;
|
|
182
|
-
return cssStringified.replace(regex, '$1\\$2');
|
|
183
|
-
}
|
|
184
|
-
return cssStringified;
|
|
185
|
-
}
|
|
186
|
-
function isCSSImportRule(rule) {
|
|
187
|
-
return 'styleSheet' in rule;
|
|
188
|
-
}
|
|
189
|
-
function stringifyStyleSheet(sheet) {
|
|
190
|
-
return sheet.cssRules
|
|
191
|
-
? Array.from(sheet.cssRules)
|
|
192
|
-
.map((rule) => rule.cssText ? validateStringifiedCssRule(rule.cssText) : '')
|
|
193
|
-
.join('')
|
|
194
|
-
: '';
|
|
195
|
-
}
|
|
196
271
|
function extractOrigin(url) {
|
|
197
272
|
let origin = '';
|
|
198
273
|
if (url.indexOf('//') > -1) {
|
|
@@ -207,7 +282,8 @@ function extractOrigin(url) {
|
|
|
207
282
|
let canvasService;
|
|
208
283
|
let canvasCtx;
|
|
209
284
|
const URL_IN_CSS_REF = /url\((?:(')([^']*)'|(")(.*?)"|([^)]*))\)/gm;
|
|
210
|
-
const
|
|
285
|
+
const URL_PROTOCOL_MATCH = /^(?:[a-z+]+:)?\/\//i;
|
|
286
|
+
const URL_WWW_MATCH = /^www\..*/i;
|
|
211
287
|
const DATA_URI = /^(data:)([^,]*),(.*)/i;
|
|
212
288
|
function absoluteToStylesheet(cssText, href) {
|
|
213
289
|
return (cssText || '').replace(URL_IN_CSS_REF, (origin, quote1, path1, quote2, path2, path3) => {
|
|
@@ -216,7 +292,7 @@ function absoluteToStylesheet(cssText, href) {
|
|
|
216
292
|
if (!filePath) {
|
|
217
293
|
return origin;
|
|
218
294
|
}
|
|
219
|
-
if (
|
|
295
|
+
if (URL_PROTOCOL_MATCH.test(filePath) || URL_WWW_MATCH.test(filePath)) {
|
|
220
296
|
return `url(${maybeQuote}${filePath}${maybeQuote})`;
|
|
221
297
|
}
|
|
222
298
|
if (DATA_URI.test(filePath)) {
|
|
@@ -251,7 +327,7 @@ function getAbsoluteSrcsetString(doc, attributeValue) {
|
|
|
251
327
|
let pos = 0;
|
|
252
328
|
function collectCharacters(regEx) {
|
|
253
329
|
let chars;
|
|
254
|
-
|
|
330
|
+
const match = regEx.exec(attributeValue.substring(pos));
|
|
255
331
|
if (match) {
|
|
256
332
|
chars = match[0];
|
|
257
333
|
pos += chars.length;
|
|
@@ -259,7 +335,7 @@ function getAbsoluteSrcsetString(doc, attributeValue) {
|
|
|
259
335
|
}
|
|
260
336
|
return '';
|
|
261
337
|
}
|
|
262
|
-
|
|
338
|
+
const output = [];
|
|
263
339
|
while (true) {
|
|
264
340
|
collectCharacters(SRCSET_COMMAS_OR_SPACES);
|
|
265
341
|
if (pos >= attributeValue.length) {
|
|
@@ -275,7 +351,7 @@ function getAbsoluteSrcsetString(doc, attributeValue) {
|
|
|
275
351
|
url = absoluteToDoc(doc, url);
|
|
276
352
|
let inParens = false;
|
|
277
353
|
while (true) {
|
|
278
|
-
|
|
354
|
+
const c = attributeValue.charAt(pos);
|
|
279
355
|
if (c === '') {
|
|
280
356
|
output.push((url + descriptorsStr).trim());
|
|
281
357
|
break;
|
|
@@ -318,13 +394,12 @@ function getHref() {
|
|
|
318
394
|
a.href = '';
|
|
319
395
|
return a.href;
|
|
320
396
|
}
|
|
321
|
-
function transformAttribute(doc,
|
|
397
|
+
function transformAttribute(doc, tagName, name, value, element, maskAttributeFn) {
|
|
322
398
|
if (!value) {
|
|
323
399
|
return value;
|
|
324
400
|
}
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
if (name === 'src' || name === 'href') {
|
|
401
|
+
if (name === 'src' ||
|
|
402
|
+
(name === 'href' && !(tagName === 'use' && value[0] === '#'))) {
|
|
328
403
|
return absoluteToDoc(doc, value);
|
|
329
404
|
}
|
|
330
405
|
else if (name === 'xlink:href' && value[0] !== '#') {
|
|
@@ -343,79 +418,113 @@ function transformAttribute(doc, element, _tagName, _name, value, maskAllText, u
|
|
|
343
418
|
else if (tagName === 'object' && name === 'data') {
|
|
344
419
|
return absoluteToDoc(doc, value);
|
|
345
420
|
}
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
return maskTextFn ? maskTextFn(value) : defaultMaskFn(value);
|
|
421
|
+
if (typeof maskAttributeFn === 'function') {
|
|
422
|
+
return maskAttributeFn(name, value, element);
|
|
349
423
|
}
|
|
350
424
|
return value;
|
|
351
425
|
}
|
|
352
|
-
function
|
|
353
|
-
|
|
354
|
-
return false;
|
|
355
|
-
}
|
|
356
|
-
return (['placeholder', 'title', 'aria-label'].indexOf(attribute) > -1 ||
|
|
357
|
-
(tagName === 'input' &&
|
|
358
|
-
attribute === 'value' &&
|
|
359
|
-
element.hasAttribute('type') &&
|
|
360
|
-
['submit', 'button'].indexOf(element.getAttribute('type').toLowerCase()) > -1));
|
|
426
|
+
function ignoreAttribute(tagName, name, _value) {
|
|
427
|
+
return (tagName === 'video' || tagName === 'audio') && name === 'autoplay';
|
|
361
428
|
}
|
|
362
429
|
function _isBlockedElement(element, blockClass, blockSelector, unblockSelector) {
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
if (typeof blockClass === 'string') {
|
|
367
|
-
if (element.classList.contains(blockClass)) {
|
|
368
|
-
return true;
|
|
430
|
+
try {
|
|
431
|
+
if (unblockSelector && element.matches(unblockSelector)) {
|
|
432
|
+
return false;
|
|
369
433
|
}
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
for (let eIndex = 0; eIndex < element.classList.length; eIndex++) {
|
|
373
|
-
const className = element.classList[eIndex];
|
|
374
|
-
if (blockClass.test(className)) {
|
|
434
|
+
if (typeof blockClass === 'string') {
|
|
435
|
+
if (element.classList.contains(blockClass)) {
|
|
375
436
|
return true;
|
|
376
437
|
}
|
|
377
438
|
}
|
|
439
|
+
else {
|
|
440
|
+
for (let eIndex = element.classList.length; eIndex--;) {
|
|
441
|
+
const className = element.classList[eIndex];
|
|
442
|
+
if (blockClass.test(className)) {
|
|
443
|
+
return true;
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
if (blockSelector) {
|
|
448
|
+
return element.matches(blockSelector);
|
|
449
|
+
}
|
|
378
450
|
}
|
|
379
|
-
|
|
380
|
-
return element.matches(blockSelector);
|
|
451
|
+
catch (e) {
|
|
381
452
|
}
|
|
382
453
|
return false;
|
|
383
454
|
}
|
|
384
|
-
function
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
if (node.nodeType !== node.ELEMENT_NODE) {
|
|
389
|
-
return needMaskingText(node.parentNode, maskTextClass, maskTextSelector, unmaskTextSelector, maskAllText);
|
|
390
|
-
}
|
|
391
|
-
if (unmaskTextSelector) {
|
|
392
|
-
if (node.matches(unmaskTextSelector) ||
|
|
393
|
-
node.closest(unmaskTextSelector)) {
|
|
394
|
-
return false;
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
if (maskAllText) {
|
|
398
|
-
return true;
|
|
399
|
-
}
|
|
400
|
-
if (typeof maskTextClass === 'string') {
|
|
401
|
-
if (node.classList.contains(maskTextClass)) {
|
|
455
|
+
function elementClassMatchesRegex(el, regex) {
|
|
456
|
+
for (let eIndex = el.classList.length; eIndex--;) {
|
|
457
|
+
const className = el.classList[eIndex];
|
|
458
|
+
if (regex.test(className)) {
|
|
402
459
|
return true;
|
|
403
460
|
}
|
|
404
461
|
}
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
462
|
+
return false;
|
|
463
|
+
}
|
|
464
|
+
function distanceToMatch(node, matchPredicate, limit = Infinity, distance = 0) {
|
|
465
|
+
if (!node)
|
|
466
|
+
return -1;
|
|
467
|
+
if (node.nodeType !== node.ELEMENT_NODE)
|
|
468
|
+
return -1;
|
|
469
|
+
if (distance > limit)
|
|
470
|
+
return -1;
|
|
471
|
+
if (matchPredicate(node))
|
|
472
|
+
return distance;
|
|
473
|
+
return distanceToMatch(node.parentNode, matchPredicate, limit, distance + 1);
|
|
474
|
+
}
|
|
475
|
+
function createMatchPredicate(className, selector) {
|
|
476
|
+
return (node) => {
|
|
477
|
+
const el = node;
|
|
478
|
+
if (el === null)
|
|
479
|
+
return false;
|
|
480
|
+
if (className) {
|
|
481
|
+
if (typeof className === 'string') {
|
|
482
|
+
if (el.matches(`.${className}`))
|
|
483
|
+
return true;
|
|
484
|
+
}
|
|
485
|
+
else if (elementClassMatchesRegex(el, className)) {
|
|
409
486
|
return true;
|
|
410
487
|
}
|
|
411
488
|
}
|
|
412
|
-
|
|
413
|
-
if (maskTextSelector) {
|
|
414
|
-
if (node.matches(maskTextSelector)) {
|
|
489
|
+
if (selector && el.matches(selector))
|
|
415
490
|
return true;
|
|
491
|
+
return false;
|
|
492
|
+
};
|
|
493
|
+
}
|
|
494
|
+
function needMaskingText(node, maskTextClass, maskTextSelector, unmaskTextClass, unmaskTextSelector, maskAllText) {
|
|
495
|
+
try {
|
|
496
|
+
const el = node.nodeType === node.ELEMENT_NODE
|
|
497
|
+
? node
|
|
498
|
+
: node.parentElement;
|
|
499
|
+
if (el === null)
|
|
500
|
+
return false;
|
|
501
|
+
let maskDistance = -1;
|
|
502
|
+
let unmaskDistance = -1;
|
|
503
|
+
if (maskAllText) {
|
|
504
|
+
unmaskDistance = distanceToMatch(el, createMatchPredicate(unmaskTextClass, unmaskTextSelector));
|
|
505
|
+
if (unmaskDistance < 0) {
|
|
506
|
+
return true;
|
|
507
|
+
}
|
|
508
|
+
maskDistance = distanceToMatch(el, createMatchPredicate(maskTextClass, maskTextSelector), unmaskDistance >= 0 ? unmaskDistance : Infinity);
|
|
416
509
|
}
|
|
510
|
+
else {
|
|
511
|
+
maskDistance = distanceToMatch(el, createMatchPredicate(maskTextClass, maskTextSelector));
|
|
512
|
+
if (maskDistance < 0) {
|
|
513
|
+
return false;
|
|
514
|
+
}
|
|
515
|
+
unmaskDistance = distanceToMatch(el, createMatchPredicate(unmaskTextClass, unmaskTextSelector), maskDistance >= 0 ? maskDistance : Infinity);
|
|
516
|
+
}
|
|
517
|
+
return maskDistance >= 0
|
|
518
|
+
? unmaskDistance >= 0
|
|
519
|
+
? maskDistance <= unmaskDistance
|
|
520
|
+
: true
|
|
521
|
+
: unmaskDistance >= 0
|
|
522
|
+
? false
|
|
523
|
+
: !!maskAllText;
|
|
524
|
+
}
|
|
525
|
+
catch (e) {
|
|
417
526
|
}
|
|
418
|
-
return
|
|
527
|
+
return !!maskAllText;
|
|
419
528
|
}
|
|
420
529
|
function onceIframeLoaded(iframeEl, listener, iframeLoadTimeout) {
|
|
421
530
|
const win = iframeEl.contentWindow;
|
|
@@ -449,18 +558,36 @@ function onceIframeLoaded(iframeEl, listener, iframeLoadTimeout) {
|
|
|
449
558
|
iframeEl.src === blankUrl ||
|
|
450
559
|
iframeEl.src === '') {
|
|
451
560
|
setTimeout(listener, 0);
|
|
452
|
-
return;
|
|
561
|
+
return iframeEl.addEventListener('load', listener);
|
|
453
562
|
}
|
|
454
563
|
iframeEl.addEventListener('load', listener);
|
|
455
564
|
}
|
|
456
|
-
function
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
565
|
+
function onceStylesheetLoaded(link, listener, styleSheetLoadTimeout) {
|
|
566
|
+
let fired = false;
|
|
567
|
+
let styleSheetLoaded;
|
|
568
|
+
try {
|
|
569
|
+
styleSheetLoaded = link.sheet;
|
|
570
|
+
}
|
|
571
|
+
catch (error) {
|
|
572
|
+
return;
|
|
463
573
|
}
|
|
574
|
+
if (styleSheetLoaded)
|
|
575
|
+
return;
|
|
576
|
+
const timer = setTimeout(() => {
|
|
577
|
+
if (!fired) {
|
|
578
|
+
listener();
|
|
579
|
+
fired = true;
|
|
580
|
+
}
|
|
581
|
+
}, styleSheetLoadTimeout);
|
|
582
|
+
link.addEventListener('load', () => {
|
|
583
|
+
clearTimeout(timer);
|
|
584
|
+
fired = true;
|
|
585
|
+
listener();
|
|
586
|
+
});
|
|
587
|
+
}
|
|
588
|
+
function serializeNode(n, options) {
|
|
589
|
+
const { doc, mirror, blockClass, blockSelector, unblockSelector, maskAllText, maskAttributeFn, maskTextClass, unmaskTextClass, maskTextSelector, unmaskTextSelector, inlineStylesheet, maskInputOptions = {}, maskTextFn, maskInputFn, dataURLOptions = {}, inlineImages, recordCanvas, keepIframeSrcFn, newlyAddedElement = false, } = options;
|
|
590
|
+
const rootId = getRootId(doc, mirror);
|
|
464
591
|
switch (n.nodeType) {
|
|
465
592
|
case n.DOCUMENT_NODE:
|
|
466
593
|
if (n.compatMode !== 'CSS1Compat') {
|
|
@@ -468,14 +595,12 @@ function serializeNode(n, options) {
|
|
|
468
595
|
type: NodeType$1.Document,
|
|
469
596
|
childNodes: [],
|
|
470
597
|
compatMode: n.compatMode,
|
|
471
|
-
rootId,
|
|
472
598
|
};
|
|
473
599
|
}
|
|
474
600
|
else {
|
|
475
601
|
return {
|
|
476
602
|
type: NodeType$1.Document,
|
|
477
603
|
childNodes: [],
|
|
478
|
-
rootId,
|
|
479
604
|
};
|
|
480
605
|
}
|
|
481
606
|
case n.DOCUMENT_TYPE_NODE:
|
|
@@ -487,202 +612,39 @@ function serializeNode(n, options) {
|
|
|
487
612
|
rootId,
|
|
488
613
|
};
|
|
489
614
|
case n.ELEMENT_NODE:
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
cssText = getCssRulesString(stylesheet);
|
|
505
|
-
}
|
|
506
|
-
if (cssText) {
|
|
507
|
-
delete attributes.rel;
|
|
508
|
-
delete attributes.href;
|
|
509
|
-
attributes._cssText = absoluteToStylesheet(cssText, stylesheet.href);
|
|
510
|
-
}
|
|
511
|
-
}
|
|
512
|
-
if (tagName === 'style' &&
|
|
513
|
-
n.sheet &&
|
|
514
|
-
!(n.innerText ||
|
|
515
|
-
n.textContent ||
|
|
516
|
-
'').trim().length) {
|
|
517
|
-
const cssText = getCssRulesString(n.sheet);
|
|
518
|
-
if (cssText) {
|
|
519
|
-
attributes._cssText = absoluteToStylesheet(cssText, getHref());
|
|
520
|
-
}
|
|
521
|
-
}
|
|
522
|
-
if (tagName === 'input' ||
|
|
523
|
-
tagName === 'textarea' ||
|
|
524
|
-
tagName === 'select' ||
|
|
525
|
-
tagName === 'option') {
|
|
526
|
-
const el = n;
|
|
527
|
-
const type = getInputType(el);
|
|
528
|
-
const value = getInputValue(el, tagName.toUpperCase(), type);
|
|
529
|
-
const checked = n.checked;
|
|
530
|
-
if (type !== 'submit' &&
|
|
531
|
-
type !== 'button' &&
|
|
532
|
-
value) {
|
|
533
|
-
attributes.value = maskInputValue({
|
|
534
|
-
input: el,
|
|
535
|
-
type,
|
|
536
|
-
tagName,
|
|
537
|
-
value,
|
|
538
|
-
maskInputSelector,
|
|
539
|
-
unmaskInputSelector,
|
|
540
|
-
maskInputOptions,
|
|
541
|
-
maskInputFn,
|
|
542
|
-
});
|
|
543
|
-
}
|
|
544
|
-
if (checked) {
|
|
545
|
-
attributes.checked = checked;
|
|
546
|
-
}
|
|
547
|
-
}
|
|
548
|
-
if (tagName === 'option') {
|
|
549
|
-
if (n.selected && !maskInputOptions['select']) {
|
|
550
|
-
attributes.selected = true;
|
|
551
|
-
}
|
|
552
|
-
else {
|
|
553
|
-
delete attributes.selected;
|
|
554
|
-
}
|
|
555
|
-
}
|
|
556
|
-
if (tagName === 'canvas' && recordCanvas) {
|
|
557
|
-
if (n.__context === '2d') {
|
|
558
|
-
if (!is2DCanvasBlank(n)) {
|
|
559
|
-
attributes.rr_dataURL = n.toDataURL(dataURLOptions.type, dataURLOptions.quality);
|
|
560
|
-
}
|
|
561
|
-
}
|
|
562
|
-
else if (!('__context' in n)) {
|
|
563
|
-
const canvasDataURL = n.toDataURL(dataURLOptions.type, dataURLOptions.quality);
|
|
564
|
-
const blankCanvas = document.createElement('canvas');
|
|
565
|
-
blankCanvas.width = n.width;
|
|
566
|
-
blankCanvas.height = n.height;
|
|
567
|
-
const blankCanvasDataURL = blankCanvas.toDataURL(dataURLOptions.type, dataURLOptions.quality);
|
|
568
|
-
if (canvasDataURL !== blankCanvasDataURL) {
|
|
569
|
-
attributes.rr_dataURL = canvasDataURL;
|
|
570
|
-
}
|
|
571
|
-
}
|
|
572
|
-
}
|
|
573
|
-
if (tagName === 'img' && inlineImages) {
|
|
574
|
-
if (!canvasService) {
|
|
575
|
-
canvasService = doc.createElement('canvas');
|
|
576
|
-
canvasCtx = canvasService.getContext('2d');
|
|
577
|
-
}
|
|
578
|
-
const image = n;
|
|
579
|
-
const oldValue = image.crossOrigin;
|
|
580
|
-
image.crossOrigin = 'anonymous';
|
|
581
|
-
const recordInlineImage = () => {
|
|
582
|
-
try {
|
|
583
|
-
canvasService.width = image.naturalWidth;
|
|
584
|
-
canvasService.height = image.naturalHeight;
|
|
585
|
-
canvasCtx.drawImage(image, 0, 0);
|
|
586
|
-
attributes.rr_dataURL = canvasService.toDataURL(dataURLOptions.type, dataURLOptions.quality);
|
|
587
|
-
}
|
|
588
|
-
catch (err) {
|
|
589
|
-
console.warn(`Cannot inline img src=${image.currentSrc}! Error: ${err}`);
|
|
590
|
-
}
|
|
591
|
-
oldValue
|
|
592
|
-
? (attributes.crossOrigin = oldValue)
|
|
593
|
-
: delete attributes.crossOrigin;
|
|
594
|
-
};
|
|
595
|
-
if (image.complete && image.naturalWidth !== 0)
|
|
596
|
-
recordInlineImage();
|
|
597
|
-
else
|
|
598
|
-
image.onload = recordInlineImage;
|
|
599
|
-
}
|
|
600
|
-
if (tagName === 'audio' || tagName === 'video') {
|
|
601
|
-
attributes.rr_mediaState = n.paused
|
|
602
|
-
? 'paused'
|
|
603
|
-
: 'played';
|
|
604
|
-
attributes.rr_mediaCurrentTime = n.currentTime;
|
|
605
|
-
}
|
|
606
|
-
if (n.scrollLeft) {
|
|
607
|
-
attributes.rr_scrollLeft = n.scrollLeft;
|
|
608
|
-
}
|
|
609
|
-
if (n.scrollTop) {
|
|
610
|
-
attributes.rr_scrollTop = n.scrollTop;
|
|
611
|
-
}
|
|
612
|
-
if (needBlock) {
|
|
613
|
-
const { width, height } = n.getBoundingClientRect();
|
|
614
|
-
attributes = {
|
|
615
|
-
class: attributes.class,
|
|
616
|
-
rr_width: `${width}px`,
|
|
617
|
-
rr_height: `${height}px`,
|
|
618
|
-
};
|
|
619
|
-
}
|
|
620
|
-
if (tagName === 'iframe' && !keepIframeSrcFn(attributes.src)) {
|
|
621
|
-
if (!n.contentDocument) {
|
|
622
|
-
attributes.rr_src = attributes.src;
|
|
623
|
-
}
|
|
624
|
-
delete attributes.src;
|
|
625
|
-
}
|
|
626
|
-
return {
|
|
627
|
-
type: NodeType$1.Element,
|
|
628
|
-
tagName,
|
|
629
|
-
attributes,
|
|
630
|
-
childNodes: [],
|
|
631
|
-
isSVG: isSVGElement(n) || undefined,
|
|
632
|
-
needBlock,
|
|
615
|
+
return serializeElementNode(n, {
|
|
616
|
+
doc,
|
|
617
|
+
blockClass,
|
|
618
|
+
blockSelector,
|
|
619
|
+
unblockSelector,
|
|
620
|
+
inlineStylesheet,
|
|
621
|
+
maskAttributeFn,
|
|
622
|
+
maskInputOptions,
|
|
623
|
+
maskInputFn,
|
|
624
|
+
dataURLOptions,
|
|
625
|
+
inlineImages,
|
|
626
|
+
recordCanvas,
|
|
627
|
+
keepIframeSrcFn,
|
|
628
|
+
newlyAddedElement,
|
|
633
629
|
rootId,
|
|
634
|
-
|
|
630
|
+
maskAllText,
|
|
631
|
+
maskTextClass,
|
|
632
|
+
unmaskTextClass,
|
|
633
|
+
maskTextSelector,
|
|
634
|
+
unmaskTextSelector,
|
|
635
|
+
});
|
|
635
636
|
case n.TEXT_NODE:
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
textContent = stringifyStyleSheet(n.parentNode.sheet);
|
|
646
|
-
}
|
|
647
|
-
}
|
|
648
|
-
catch (err) {
|
|
649
|
-
console.warn(`Cannot get CSS styles from text's parentNode. Error: ${err}`, n);
|
|
650
|
-
}
|
|
651
|
-
textContent = absoluteToStylesheet(textContent, getHref());
|
|
652
|
-
}
|
|
653
|
-
if (isScript) {
|
|
654
|
-
textContent = 'SCRIPT_PLACEHOLDER';
|
|
655
|
-
}
|
|
656
|
-
if (parentTagName === 'TEXTAREA' && textContent) {
|
|
657
|
-
textContent = '';
|
|
658
|
-
}
|
|
659
|
-
else if (parentTagName === 'OPTION' && textContent) {
|
|
660
|
-
const option = n.parentNode;
|
|
661
|
-
textContent = maskInputValue({
|
|
662
|
-
input: option,
|
|
663
|
-
type: null,
|
|
664
|
-
tagName: parentTagName,
|
|
665
|
-
value: textContent,
|
|
666
|
-
maskInputSelector,
|
|
667
|
-
unmaskInputSelector,
|
|
668
|
-
maskInputOptions,
|
|
669
|
-
maskInputFn,
|
|
670
|
-
});
|
|
671
|
-
}
|
|
672
|
-
else if (!isStyle &&
|
|
673
|
-
!isScript &&
|
|
674
|
-
needMaskingText(n, maskTextClass, maskTextSelector, unmaskTextSelector, maskAllText) &&
|
|
675
|
-
textContent) {
|
|
676
|
-
textContent = maskTextFn
|
|
677
|
-
? maskTextFn(textContent)
|
|
678
|
-
: defaultMaskFn(textContent);
|
|
679
|
-
}
|
|
680
|
-
return {
|
|
681
|
-
type: NodeType$1.Text,
|
|
682
|
-
textContent: textContent || '',
|
|
683
|
-
isStyle,
|
|
637
|
+
return serializeTextNode(n, {
|
|
638
|
+
maskAllText,
|
|
639
|
+
maskTextClass,
|
|
640
|
+
unmaskTextClass,
|
|
641
|
+
maskTextSelector,
|
|
642
|
+
unmaskTextSelector,
|
|
643
|
+
maskTextFn,
|
|
644
|
+
maskInputOptions,
|
|
645
|
+
maskInputFn,
|
|
684
646
|
rootId,
|
|
685
|
-
};
|
|
647
|
+
});
|
|
686
648
|
case n.CDATA_SECTION_NODE:
|
|
687
649
|
return {
|
|
688
650
|
type: NodeType$1.CDATA,
|
|
@@ -699,6 +661,225 @@ function serializeNode(n, options) {
|
|
|
699
661
|
return false;
|
|
700
662
|
}
|
|
701
663
|
}
|
|
664
|
+
function getRootId(doc, mirror) {
|
|
665
|
+
if (!mirror.hasNode(doc))
|
|
666
|
+
return undefined;
|
|
667
|
+
const docId = mirror.getId(doc);
|
|
668
|
+
return docId === 1 ? undefined : docId;
|
|
669
|
+
}
|
|
670
|
+
function serializeTextNode(n, options) {
|
|
671
|
+
var _a;
|
|
672
|
+
const { maskAllText, maskTextClass, unmaskTextClass, maskTextSelector, unmaskTextSelector, maskTextFn, maskInputOptions, maskInputFn, rootId, } = options;
|
|
673
|
+
const parentTagName = n.parentNode && n.parentNode.tagName;
|
|
674
|
+
let textContent = n.textContent;
|
|
675
|
+
const isStyle = parentTagName === 'STYLE' ? true : undefined;
|
|
676
|
+
const isScript = parentTagName === 'SCRIPT' ? true : undefined;
|
|
677
|
+
const isTextarea = parentTagName === 'TEXTAREA' ? true : undefined;
|
|
678
|
+
if (isStyle && textContent) {
|
|
679
|
+
try {
|
|
680
|
+
if (n.nextSibling || n.previousSibling) {
|
|
681
|
+
}
|
|
682
|
+
else if ((_a = n.parentNode.sheet) === null || _a === void 0 ? void 0 : _a.cssRules) {
|
|
683
|
+
textContent = stringifyStylesheet(n.parentNode.sheet);
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
catch (err) {
|
|
687
|
+
console.warn(`Cannot get CSS styles from text's parentNode. Error: ${err}`, n);
|
|
688
|
+
}
|
|
689
|
+
textContent = absoluteToStylesheet(textContent, getHref());
|
|
690
|
+
}
|
|
691
|
+
if (isScript) {
|
|
692
|
+
textContent = 'SCRIPT_PLACEHOLDER';
|
|
693
|
+
}
|
|
694
|
+
const forceMask = needMaskingText(n, maskTextClass, maskTextSelector, unmaskTextClass, unmaskTextSelector, maskAllText);
|
|
695
|
+
if (!isStyle && !isScript && !isTextarea && textContent && forceMask) {
|
|
696
|
+
textContent = maskTextFn
|
|
697
|
+
? maskTextFn(textContent)
|
|
698
|
+
: textContent.replace(/[\S]/g, '*');
|
|
699
|
+
}
|
|
700
|
+
if (isTextarea && textContent && (maskInputOptions.textarea || forceMask)) {
|
|
701
|
+
textContent = maskInputFn
|
|
702
|
+
? maskInputFn(textContent, n.parentNode)
|
|
703
|
+
: textContent.replace(/[\S]/g, '*');
|
|
704
|
+
}
|
|
705
|
+
if (parentTagName === 'OPTION' && textContent) {
|
|
706
|
+
const isInputMasked = shouldMaskInput({
|
|
707
|
+
type: null,
|
|
708
|
+
tagName: parentTagName,
|
|
709
|
+
maskInputOptions,
|
|
710
|
+
});
|
|
711
|
+
textContent = maskInputValue({
|
|
712
|
+
isMasked: needMaskingText(n, maskTextClass, maskTextSelector, unmaskTextClass, unmaskTextSelector, isInputMasked),
|
|
713
|
+
element: n,
|
|
714
|
+
value: textContent,
|
|
715
|
+
maskInputFn,
|
|
716
|
+
});
|
|
717
|
+
}
|
|
718
|
+
return {
|
|
719
|
+
type: NodeType$1.Text,
|
|
720
|
+
textContent: textContent || '',
|
|
721
|
+
isStyle,
|
|
722
|
+
rootId,
|
|
723
|
+
};
|
|
724
|
+
}
|
|
725
|
+
function serializeElementNode(n, options) {
|
|
726
|
+
const { doc, blockClass, blockSelector, unblockSelector, inlineStylesheet, maskInputOptions = {}, maskAttributeFn, maskInputFn, dataURLOptions = {}, inlineImages, recordCanvas, keepIframeSrcFn, newlyAddedElement = false, rootId, maskAllText, maskTextClass, unmaskTextClass, maskTextSelector, unmaskTextSelector, } = options;
|
|
727
|
+
const needBlock = _isBlockedElement(n, blockClass, blockSelector, unblockSelector);
|
|
728
|
+
const tagName = getValidTagName(n);
|
|
729
|
+
let attributes = {};
|
|
730
|
+
const len = n.attributes.length;
|
|
731
|
+
for (let i = 0; i < len; i++) {
|
|
732
|
+
const attr = n.attributes[i];
|
|
733
|
+
if (!ignoreAttribute(tagName, attr.name, attr.value)) {
|
|
734
|
+
attributes[attr.name] = transformAttribute(doc, tagName, toLowerCase(attr.name), attr.value, n, maskAttributeFn);
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
if (tagName === 'link' && inlineStylesheet) {
|
|
738
|
+
const stylesheet = Array.from(doc.styleSheets).find((s) => {
|
|
739
|
+
return s.href === n.href;
|
|
740
|
+
});
|
|
741
|
+
let cssText = null;
|
|
742
|
+
if (stylesheet) {
|
|
743
|
+
cssText = stringifyStylesheet(stylesheet);
|
|
744
|
+
}
|
|
745
|
+
if (cssText) {
|
|
746
|
+
delete attributes.rel;
|
|
747
|
+
delete attributes.href;
|
|
748
|
+
attributes._cssText = absoluteToStylesheet(cssText, stylesheet.href);
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
if (tagName === 'style' &&
|
|
752
|
+
n.sheet &&
|
|
753
|
+
!(n.innerText || n.textContent || '').trim().length) {
|
|
754
|
+
const cssText = stringifyStylesheet(n.sheet);
|
|
755
|
+
if (cssText) {
|
|
756
|
+
attributes._cssText = absoluteToStylesheet(cssText, getHref());
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
if (tagName === 'input' ||
|
|
760
|
+
tagName === 'textarea' ||
|
|
761
|
+
tagName === 'select' ||
|
|
762
|
+
tagName === 'option') {
|
|
763
|
+
const el = n;
|
|
764
|
+
const type = getInputType(el);
|
|
765
|
+
const value = getInputValue(el, toUpperCase(tagName), type);
|
|
766
|
+
const checked = el.checked;
|
|
767
|
+
if (type !== 'submit' && type !== 'button' && value) {
|
|
768
|
+
const forceMask = needMaskingText(el, maskTextClass, maskTextSelector, unmaskTextClass, unmaskTextSelector, shouldMaskInput({
|
|
769
|
+
type,
|
|
770
|
+
tagName: toUpperCase(tagName),
|
|
771
|
+
maskInputOptions,
|
|
772
|
+
}));
|
|
773
|
+
attributes.value = maskInputValue({
|
|
774
|
+
isMasked: forceMask,
|
|
775
|
+
element: el,
|
|
776
|
+
value,
|
|
777
|
+
maskInputFn,
|
|
778
|
+
});
|
|
779
|
+
}
|
|
780
|
+
if (checked) {
|
|
781
|
+
attributes.checked = checked;
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
if (tagName === 'option') {
|
|
785
|
+
if (n.selected && !maskInputOptions['select']) {
|
|
786
|
+
attributes.selected = true;
|
|
787
|
+
}
|
|
788
|
+
else {
|
|
789
|
+
delete attributes.selected;
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
if (tagName === 'canvas' && recordCanvas) {
|
|
793
|
+
if (n.__context === '2d') {
|
|
794
|
+
if (!is2DCanvasBlank(n)) {
|
|
795
|
+
attributes.rr_dataURL = n.toDataURL(dataURLOptions.type, dataURLOptions.quality);
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
else if (!('__context' in n)) {
|
|
799
|
+
const canvasDataURL = n.toDataURL(dataURLOptions.type, dataURLOptions.quality);
|
|
800
|
+
const blankCanvas = document.createElement('canvas');
|
|
801
|
+
blankCanvas.width = n.width;
|
|
802
|
+
blankCanvas.height = n.height;
|
|
803
|
+
const blankCanvasDataURL = blankCanvas.toDataURL(dataURLOptions.type, dataURLOptions.quality);
|
|
804
|
+
if (canvasDataURL !== blankCanvasDataURL) {
|
|
805
|
+
attributes.rr_dataURL = canvasDataURL;
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
if (tagName === 'img' && inlineImages) {
|
|
810
|
+
if (!canvasService) {
|
|
811
|
+
canvasService = doc.createElement('canvas');
|
|
812
|
+
canvasCtx = canvasService.getContext('2d');
|
|
813
|
+
}
|
|
814
|
+
const image = n;
|
|
815
|
+
const oldValue = image.crossOrigin;
|
|
816
|
+
image.crossOrigin = 'anonymous';
|
|
817
|
+
const recordInlineImage = () => {
|
|
818
|
+
image.removeEventListener('load', recordInlineImage);
|
|
819
|
+
try {
|
|
820
|
+
canvasService.width = image.naturalWidth;
|
|
821
|
+
canvasService.height = image.naturalHeight;
|
|
822
|
+
canvasCtx.drawImage(image, 0, 0);
|
|
823
|
+
attributes.rr_dataURL = canvasService.toDataURL(dataURLOptions.type, dataURLOptions.quality);
|
|
824
|
+
}
|
|
825
|
+
catch (err) {
|
|
826
|
+
console.warn(`Cannot inline img src=${image.currentSrc}! Error: ${err}`);
|
|
827
|
+
}
|
|
828
|
+
oldValue
|
|
829
|
+
? (attributes.crossOrigin = oldValue)
|
|
830
|
+
: image.removeAttribute('crossorigin');
|
|
831
|
+
};
|
|
832
|
+
if (image.complete && image.naturalWidth !== 0)
|
|
833
|
+
recordInlineImage();
|
|
834
|
+
else
|
|
835
|
+
image.addEventListener('load', recordInlineImage);
|
|
836
|
+
}
|
|
837
|
+
if (tagName === 'audio' || tagName === 'video') {
|
|
838
|
+
attributes.rr_mediaState = n.paused
|
|
839
|
+
? 'paused'
|
|
840
|
+
: 'played';
|
|
841
|
+
attributes.rr_mediaCurrentTime = n.currentTime;
|
|
842
|
+
}
|
|
843
|
+
if (!newlyAddedElement) {
|
|
844
|
+
if (n.scrollLeft) {
|
|
845
|
+
attributes.rr_scrollLeft = n.scrollLeft;
|
|
846
|
+
}
|
|
847
|
+
if (n.scrollTop) {
|
|
848
|
+
attributes.rr_scrollTop = n.scrollTop;
|
|
849
|
+
}
|
|
850
|
+
}
|
|
851
|
+
if (needBlock) {
|
|
852
|
+
const { width, height } = n.getBoundingClientRect();
|
|
853
|
+
attributes = {
|
|
854
|
+
class: attributes.class,
|
|
855
|
+
rr_width: `${width}px`,
|
|
856
|
+
rr_height: `${height}px`,
|
|
857
|
+
};
|
|
858
|
+
}
|
|
859
|
+
if (tagName === 'iframe' && !keepIframeSrcFn(attributes.src)) {
|
|
860
|
+
if (!n.contentDocument) {
|
|
861
|
+
attributes.rr_src = attributes.src;
|
|
862
|
+
}
|
|
863
|
+
delete attributes.src;
|
|
864
|
+
}
|
|
865
|
+
let isCustomElement;
|
|
866
|
+
try {
|
|
867
|
+
if (customElements.get(tagName))
|
|
868
|
+
isCustomElement = true;
|
|
869
|
+
}
|
|
870
|
+
catch (e) {
|
|
871
|
+
}
|
|
872
|
+
return {
|
|
873
|
+
type: NodeType$1.Element,
|
|
874
|
+
tagName,
|
|
875
|
+
attributes,
|
|
876
|
+
childNodes: [],
|
|
877
|
+
isSVG: isSVGElement(n) || undefined,
|
|
878
|
+
needBlock,
|
|
879
|
+
rootId,
|
|
880
|
+
isCustom: isCustomElement,
|
|
881
|
+
};
|
|
882
|
+
}
|
|
702
883
|
function lowerIfExists(maybeAttr) {
|
|
703
884
|
if (maybeAttr === undefined || maybeAttr === null) {
|
|
704
885
|
return '';
|
|
@@ -780,35 +961,37 @@ function slimDOMExcluded(sn, slimDOMOptions) {
|
|
|
780
961
|
return false;
|
|
781
962
|
}
|
|
782
963
|
function serializeNodeWithId(n, options) {
|
|
783
|
-
const { doc,
|
|
964
|
+
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;
|
|
784
965
|
let { preserveWhiteSpace = true } = options;
|
|
785
966
|
const _serializedNode = serializeNode(n, {
|
|
786
967
|
doc,
|
|
968
|
+
mirror,
|
|
787
969
|
blockClass,
|
|
788
970
|
blockSelector,
|
|
971
|
+
maskAllText,
|
|
789
972
|
unblockSelector,
|
|
790
973
|
maskTextClass,
|
|
974
|
+
unmaskTextClass,
|
|
791
975
|
maskTextSelector,
|
|
792
976
|
unmaskTextSelector,
|
|
793
977
|
inlineStylesheet,
|
|
794
|
-
maskInputSelector,
|
|
795
|
-
unmaskInputSelector,
|
|
796
|
-
maskAllText,
|
|
797
978
|
maskInputOptions,
|
|
979
|
+
maskAttributeFn,
|
|
798
980
|
maskTextFn,
|
|
799
981
|
maskInputFn,
|
|
800
982
|
dataURLOptions,
|
|
801
983
|
inlineImages,
|
|
802
984
|
recordCanvas,
|
|
803
985
|
keepIframeSrcFn,
|
|
986
|
+
newlyAddedElement,
|
|
804
987
|
});
|
|
805
988
|
if (!_serializedNode) {
|
|
806
989
|
console.warn(n, 'not serialized');
|
|
807
990
|
return null;
|
|
808
991
|
}
|
|
809
992
|
let id;
|
|
810
|
-
if (
|
|
811
|
-
id = n
|
|
993
|
+
if (mirror.hasNode(n)) {
|
|
994
|
+
id = mirror.getId(n);
|
|
812
995
|
}
|
|
813
996
|
else if (slimDOMExcluded(_serializedNode, slimDOMOptions) ||
|
|
814
997
|
(!preserveWhiteSpace &&
|
|
@@ -821,11 +1004,10 @@ function serializeNodeWithId(n, options) {
|
|
|
821
1004
|
id = genId();
|
|
822
1005
|
}
|
|
823
1006
|
const serializedNode = Object.assign(_serializedNode, { id });
|
|
824
|
-
n
|
|
1007
|
+
mirror.add(n, serializedNode);
|
|
825
1008
|
if (id === IGNORED_NODE) {
|
|
826
1009
|
return null;
|
|
827
1010
|
}
|
|
828
|
-
map[id] = n;
|
|
829
1011
|
if (onSerialize) {
|
|
830
1012
|
onSerialize(n);
|
|
831
1013
|
}
|
|
@@ -833,32 +1015,33 @@ function serializeNodeWithId(n, options) {
|
|
|
833
1015
|
if (serializedNode.type === NodeType$1.Element) {
|
|
834
1016
|
recordChild = recordChild && !serializedNode.needBlock;
|
|
835
1017
|
delete serializedNode.needBlock;
|
|
836
|
-
|
|
1018
|
+
const shadowRoot = n.shadowRoot;
|
|
1019
|
+
if (shadowRoot && isNativeShadowDom(shadowRoot))
|
|
837
1020
|
serializedNode.isShadowHost = true;
|
|
838
1021
|
}
|
|
839
1022
|
if ((serializedNode.type === NodeType$1.Document ||
|
|
840
1023
|
serializedNode.type === NodeType$1.Element) &&
|
|
841
1024
|
recordChild) {
|
|
842
1025
|
if (slimDOMOptions.headWhitespace &&
|
|
843
|
-
|
|
844
|
-
|
|
1026
|
+
serializedNode.type === NodeType$1.Element &&
|
|
1027
|
+
serializedNode.tagName === 'head') {
|
|
845
1028
|
preserveWhiteSpace = false;
|
|
846
1029
|
}
|
|
847
1030
|
const bypassOptions = {
|
|
848
1031
|
doc,
|
|
849
|
-
|
|
1032
|
+
mirror,
|
|
850
1033
|
blockClass,
|
|
851
1034
|
blockSelector,
|
|
1035
|
+
maskAllText,
|
|
852
1036
|
unblockSelector,
|
|
853
1037
|
maskTextClass,
|
|
1038
|
+
unmaskTextClass,
|
|
854
1039
|
maskTextSelector,
|
|
855
1040
|
unmaskTextSelector,
|
|
856
1041
|
skipChild,
|
|
857
1042
|
inlineStylesheet,
|
|
858
|
-
maskInputSelector,
|
|
859
|
-
unmaskInputSelector,
|
|
860
|
-
maskAllText,
|
|
861
1043
|
maskInputOptions,
|
|
1044
|
+
maskAttributeFn,
|
|
862
1045
|
maskTextFn,
|
|
863
1046
|
maskInputFn,
|
|
864
1047
|
slimDOMOptions,
|
|
@@ -869,6 +1052,8 @@ function serializeNodeWithId(n, options) {
|
|
|
869
1052
|
onSerialize,
|
|
870
1053
|
onIframeLoad,
|
|
871
1054
|
iframeLoadTimeout,
|
|
1055
|
+
onStylesheetLoad,
|
|
1056
|
+
stylesheetLoadTimeout,
|
|
872
1057
|
keepIframeSrcFn,
|
|
873
1058
|
};
|
|
874
1059
|
for (const childN of Array.from(n.childNodes)) {
|
|
@@ -877,17 +1062,20 @@ function serializeNodeWithId(n, options) {
|
|
|
877
1062
|
serializedNode.childNodes.push(serializedChildNode);
|
|
878
1063
|
}
|
|
879
1064
|
}
|
|
880
|
-
if (isElement(n) && n.shadowRoot) {
|
|
1065
|
+
if (isElement$1(n) && n.shadowRoot) {
|
|
881
1066
|
for (const childN of Array.from(n.shadowRoot.childNodes)) {
|
|
882
1067
|
const serializedChildNode = serializeNodeWithId(childN, bypassOptions);
|
|
883
1068
|
if (serializedChildNode) {
|
|
884
|
-
|
|
1069
|
+
isNativeShadowDom(n.shadowRoot) &&
|
|
1070
|
+
(serializedChildNode.isShadow = true);
|
|
885
1071
|
serializedNode.childNodes.push(serializedChildNode);
|
|
886
1072
|
}
|
|
887
1073
|
}
|
|
888
1074
|
}
|
|
889
1075
|
}
|
|
890
|
-
if (n.parentNode &&
|
|
1076
|
+
if (n.parentNode &&
|
|
1077
|
+
isShadowRoot(n.parentNode) &&
|
|
1078
|
+
isNativeShadowDom(n.parentNode)) {
|
|
891
1079
|
serializedNode.isShadow = true;
|
|
892
1080
|
}
|
|
893
1081
|
if (serializedNode.type === NodeType$1.Element &&
|
|
@@ -897,19 +1085,19 @@ function serializeNodeWithId(n, options) {
|
|
|
897
1085
|
if (iframeDoc && onIframeLoad) {
|
|
898
1086
|
const serializedIframeNode = serializeNodeWithId(iframeDoc, {
|
|
899
1087
|
doc: iframeDoc,
|
|
900
|
-
|
|
1088
|
+
mirror,
|
|
901
1089
|
blockClass,
|
|
902
1090
|
blockSelector,
|
|
903
1091
|
unblockSelector,
|
|
1092
|
+
maskAllText,
|
|
904
1093
|
maskTextClass,
|
|
1094
|
+
unmaskTextClass,
|
|
905
1095
|
maskTextSelector,
|
|
906
1096
|
unmaskTextSelector,
|
|
907
1097
|
skipChild: false,
|
|
908
1098
|
inlineStylesheet,
|
|
909
|
-
maskInputSelector,
|
|
910
|
-
unmaskInputSelector,
|
|
911
|
-
maskAllText,
|
|
912
1099
|
maskInputOptions,
|
|
1100
|
+
maskAttributeFn,
|
|
913
1101
|
maskTextFn,
|
|
914
1102
|
maskInputFn,
|
|
915
1103
|
slimDOMOptions,
|
|
@@ -920,6 +1108,8 @@ function serializeNodeWithId(n, options) {
|
|
|
920
1108
|
onSerialize,
|
|
921
1109
|
onIframeLoad,
|
|
922
1110
|
iframeLoadTimeout,
|
|
1111
|
+
onStylesheetLoad,
|
|
1112
|
+
stylesheetLoadTimeout,
|
|
923
1113
|
keepIframeSrcFn,
|
|
924
1114
|
});
|
|
925
1115
|
if (serializedIframeNode) {
|
|
@@ -928,11 +1118,50 @@ function serializeNodeWithId(n, options) {
|
|
|
928
1118
|
}
|
|
929
1119
|
}, iframeLoadTimeout);
|
|
930
1120
|
}
|
|
1121
|
+
if (serializedNode.type === NodeType$1.Element &&
|
|
1122
|
+
serializedNode.tagName === 'link' &&
|
|
1123
|
+
serializedNode.attributes.rel === 'stylesheet') {
|
|
1124
|
+
onceStylesheetLoaded(n, () => {
|
|
1125
|
+
if (onStylesheetLoad) {
|
|
1126
|
+
const serializedLinkNode = serializeNodeWithId(n, {
|
|
1127
|
+
doc,
|
|
1128
|
+
mirror,
|
|
1129
|
+
blockClass,
|
|
1130
|
+
blockSelector,
|
|
1131
|
+
unblockSelector,
|
|
1132
|
+
maskAllText,
|
|
1133
|
+
maskTextClass,
|
|
1134
|
+
unmaskTextClass,
|
|
1135
|
+
maskTextSelector,
|
|
1136
|
+
unmaskTextSelector,
|
|
1137
|
+
skipChild: false,
|
|
1138
|
+
inlineStylesheet,
|
|
1139
|
+
maskInputOptions,
|
|
1140
|
+
maskAttributeFn,
|
|
1141
|
+
maskTextFn,
|
|
1142
|
+
maskInputFn,
|
|
1143
|
+
slimDOMOptions,
|
|
1144
|
+
dataURLOptions,
|
|
1145
|
+
inlineImages,
|
|
1146
|
+
recordCanvas,
|
|
1147
|
+
preserveWhiteSpace,
|
|
1148
|
+
onSerialize,
|
|
1149
|
+
onIframeLoad,
|
|
1150
|
+
iframeLoadTimeout,
|
|
1151
|
+
onStylesheetLoad,
|
|
1152
|
+
stylesheetLoadTimeout,
|
|
1153
|
+
keepIframeSrcFn,
|
|
1154
|
+
});
|
|
1155
|
+
if (serializedLinkNode) {
|
|
1156
|
+
onStylesheetLoad(n, serializedLinkNode);
|
|
1157
|
+
}
|
|
1158
|
+
}
|
|
1159
|
+
}, stylesheetLoadTimeout);
|
|
1160
|
+
}
|
|
931
1161
|
return serializedNode;
|
|
932
1162
|
}
|
|
933
1163
|
function snapshot(n, options) {
|
|
934
|
-
const { blockClass = 'rr-block', blockSelector = null, unblockSelector = null, maskTextClass = 'rr-mask', maskTextSelector = null, unmaskTextSelector = null, inlineStylesheet = true, inlineImages = false, recordCanvas = false,
|
|
935
|
-
const idNodeMap = {};
|
|
1164
|
+
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 || {};
|
|
936
1165
|
const maskInputOptions = maskAllInputs === true
|
|
937
1166
|
? {
|
|
938
1167
|
color: true,
|
|
@@ -971,147 +1200,43 @@ function snapshot(n, options) {
|
|
|
971
1200
|
: slimDOM === false
|
|
972
1201
|
? {}
|
|
973
1202
|
: slimDOM;
|
|
974
|
-
return
|
|
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
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1203
|
+
return serializeNodeWithId(n, {
|
|
1204
|
+
doc: n,
|
|
1205
|
+
mirror,
|
|
1206
|
+
blockClass,
|
|
1207
|
+
blockSelector,
|
|
1208
|
+
unblockSelector,
|
|
1209
|
+
maskAllText,
|
|
1210
|
+
maskTextClass,
|
|
1211
|
+
unmaskTextClass,
|
|
1212
|
+
maskTextSelector,
|
|
1213
|
+
unmaskTextSelector,
|
|
1214
|
+
skipChild: false,
|
|
1215
|
+
inlineStylesheet,
|
|
1216
|
+
maskInputOptions,
|
|
1217
|
+
maskAttributeFn,
|
|
1218
|
+
maskTextFn,
|
|
1219
|
+
maskInputFn,
|
|
1220
|
+
slimDOMOptions,
|
|
1221
|
+
dataURLOptions,
|
|
1222
|
+
inlineImages,
|
|
1223
|
+
recordCanvas,
|
|
1224
|
+
preserveWhiteSpace,
|
|
1225
|
+
onSerialize,
|
|
1226
|
+
onIframeLoad,
|
|
1227
|
+
iframeLoadTimeout,
|
|
1228
|
+
onStylesheetLoad,
|
|
1229
|
+
stylesheetLoadTimeout,
|
|
1230
|
+
keepIframeSrcFn,
|
|
1231
|
+
newlyAddedElement: false,
|
|
1232
|
+
});
|
|
1004
1233
|
}
|
|
1005
|
-
function skipAttribute(tagName, attributeName, value) {
|
|
1006
|
-
return ((tagName === 'video' || tagName === 'audio') && attributeName === 'autoplay');
|
|
1007
|
-
}
|
|
1008
|
-
|
|
1009
|
-
var EventType;
|
|
1010
|
-
(function (EventType) {
|
|
1011
|
-
EventType[EventType["DomContentLoaded"] = 0] = "DomContentLoaded";
|
|
1012
|
-
EventType[EventType["Load"] = 1] = "Load";
|
|
1013
|
-
EventType[EventType["FullSnapshot"] = 2] = "FullSnapshot";
|
|
1014
|
-
EventType[EventType["IncrementalSnapshot"] = 3] = "IncrementalSnapshot";
|
|
1015
|
-
EventType[EventType["Meta"] = 4] = "Meta";
|
|
1016
|
-
EventType[EventType["Custom"] = 5] = "Custom";
|
|
1017
|
-
EventType[EventType["Plugin"] = 6] = "Plugin";
|
|
1018
|
-
})(EventType || (EventType = {}));
|
|
1019
|
-
var IncrementalSource;
|
|
1020
|
-
(function (IncrementalSource) {
|
|
1021
|
-
IncrementalSource[IncrementalSource["Mutation"] = 0] = "Mutation";
|
|
1022
|
-
IncrementalSource[IncrementalSource["MouseMove"] = 1] = "MouseMove";
|
|
1023
|
-
IncrementalSource[IncrementalSource["MouseInteraction"] = 2] = "MouseInteraction";
|
|
1024
|
-
IncrementalSource[IncrementalSource["Scroll"] = 3] = "Scroll";
|
|
1025
|
-
IncrementalSource[IncrementalSource["ViewportResize"] = 4] = "ViewportResize";
|
|
1026
|
-
IncrementalSource[IncrementalSource["Input"] = 5] = "Input";
|
|
1027
|
-
IncrementalSource[IncrementalSource["TouchMove"] = 6] = "TouchMove";
|
|
1028
|
-
IncrementalSource[IncrementalSource["MediaInteraction"] = 7] = "MediaInteraction";
|
|
1029
|
-
IncrementalSource[IncrementalSource["StyleSheetRule"] = 8] = "StyleSheetRule";
|
|
1030
|
-
IncrementalSource[IncrementalSource["CanvasMutation"] = 9] = "CanvasMutation";
|
|
1031
|
-
IncrementalSource[IncrementalSource["Font"] = 10] = "Font";
|
|
1032
|
-
IncrementalSource[IncrementalSource["Log"] = 11] = "Log";
|
|
1033
|
-
IncrementalSource[IncrementalSource["Drag"] = 12] = "Drag";
|
|
1034
|
-
IncrementalSource[IncrementalSource["StyleDeclaration"] = 13] = "StyleDeclaration";
|
|
1035
|
-
})(IncrementalSource || (IncrementalSource = {}));
|
|
1036
|
-
var MouseInteractions;
|
|
1037
|
-
(function (MouseInteractions) {
|
|
1038
|
-
MouseInteractions[MouseInteractions["MouseUp"] = 0] = "MouseUp";
|
|
1039
|
-
MouseInteractions[MouseInteractions["MouseDown"] = 1] = "MouseDown";
|
|
1040
|
-
MouseInteractions[MouseInteractions["Click"] = 2] = "Click";
|
|
1041
|
-
MouseInteractions[MouseInteractions["ContextMenu"] = 3] = "ContextMenu";
|
|
1042
|
-
MouseInteractions[MouseInteractions["DblClick"] = 4] = "DblClick";
|
|
1043
|
-
MouseInteractions[MouseInteractions["Focus"] = 5] = "Focus";
|
|
1044
|
-
MouseInteractions[MouseInteractions["Blur"] = 6] = "Blur";
|
|
1045
|
-
MouseInteractions[MouseInteractions["TouchStart"] = 7] = "TouchStart";
|
|
1046
|
-
MouseInteractions[MouseInteractions["TouchMove_Departed"] = 8] = "TouchMove_Departed";
|
|
1047
|
-
MouseInteractions[MouseInteractions["TouchEnd"] = 9] = "TouchEnd";
|
|
1048
|
-
MouseInteractions[MouseInteractions["TouchCancel"] = 10] = "TouchCancel";
|
|
1049
|
-
})(MouseInteractions || (MouseInteractions = {}));
|
|
1050
|
-
var CanvasContext;
|
|
1051
|
-
(function (CanvasContext) {
|
|
1052
|
-
CanvasContext[CanvasContext["2D"] = 0] = "2D";
|
|
1053
|
-
CanvasContext[CanvasContext["WebGL"] = 1] = "WebGL";
|
|
1054
|
-
CanvasContext[CanvasContext["WebGL2"] = 2] = "WebGL2";
|
|
1055
|
-
})(CanvasContext || (CanvasContext = {}));
|
|
1056
|
-
var MediaInteractions;
|
|
1057
|
-
(function (MediaInteractions) {
|
|
1058
|
-
MediaInteractions[MediaInteractions["Play"] = 0] = "Play";
|
|
1059
|
-
MediaInteractions[MediaInteractions["Pause"] = 1] = "Pause";
|
|
1060
|
-
MediaInteractions[MediaInteractions["Seeked"] = 2] = "Seeked";
|
|
1061
|
-
MediaInteractions[MediaInteractions["VolumeChange"] = 3] = "VolumeChange";
|
|
1062
|
-
})(MediaInteractions || (MediaInteractions = {}));
|
|
1063
|
-
var ReplayerEvents;
|
|
1064
|
-
(function (ReplayerEvents) {
|
|
1065
|
-
ReplayerEvents["Start"] = "start";
|
|
1066
|
-
ReplayerEvents["Pause"] = "pause";
|
|
1067
|
-
ReplayerEvents["Resume"] = "resume";
|
|
1068
|
-
ReplayerEvents["Resize"] = "resize";
|
|
1069
|
-
ReplayerEvents["Finish"] = "finish";
|
|
1070
|
-
ReplayerEvents["FullsnapshotRebuilded"] = "fullsnapshot-rebuilded";
|
|
1071
|
-
ReplayerEvents["LoadStylesheetStart"] = "load-stylesheet-start";
|
|
1072
|
-
ReplayerEvents["LoadStylesheetEnd"] = "load-stylesheet-end";
|
|
1073
|
-
ReplayerEvents["SkipStart"] = "skip-start";
|
|
1074
|
-
ReplayerEvents["SkipEnd"] = "skip-end";
|
|
1075
|
-
ReplayerEvents["MouseInteraction"] = "mouse-interaction";
|
|
1076
|
-
ReplayerEvents["EventCast"] = "event-cast";
|
|
1077
|
-
ReplayerEvents["CustomEvent"] = "custom-event";
|
|
1078
|
-
ReplayerEvents["Flush"] = "flush";
|
|
1079
|
-
ReplayerEvents["StateChange"] = "state-change";
|
|
1080
|
-
ReplayerEvents["PlayBack"] = "play-back";
|
|
1081
|
-
})(ReplayerEvents || (ReplayerEvents = {}));
|
|
1082
1234
|
|
|
1083
1235
|
function on(type, fn, target = document) {
|
|
1084
1236
|
const options = { capture: true, passive: true };
|
|
1085
1237
|
target.addEventListener(type, fn, options);
|
|
1086
1238
|
return () => target.removeEventListener(type, fn, options);
|
|
1087
1239
|
}
|
|
1088
|
-
function createMirror() {
|
|
1089
|
-
return {
|
|
1090
|
-
map: {},
|
|
1091
|
-
getId(n) {
|
|
1092
|
-
if (!n || !n.__sn) {
|
|
1093
|
-
return -1;
|
|
1094
|
-
}
|
|
1095
|
-
return n.__sn.id;
|
|
1096
|
-
},
|
|
1097
|
-
getNode(id) {
|
|
1098
|
-
return this.map[id] || null;
|
|
1099
|
-
},
|
|
1100
|
-
removeNodeFromMap(n) {
|
|
1101
|
-
const id = n.__sn && n.__sn.id;
|
|
1102
|
-
delete this.map[id];
|
|
1103
|
-
if (n.childNodes) {
|
|
1104
|
-
n.childNodes.forEach((child) => this.removeNodeFromMap(child));
|
|
1105
|
-
}
|
|
1106
|
-
},
|
|
1107
|
-
has(id) {
|
|
1108
|
-
return this.map.hasOwnProperty(id);
|
|
1109
|
-
},
|
|
1110
|
-
reset() {
|
|
1111
|
-
this.map = {};
|
|
1112
|
-
},
|
|
1113
|
-
};
|
|
1114
|
-
}
|
|
1115
1240
|
const DEPARTED_MIRROR_ACCESS_WARNING = 'Please stop import mirror directly. Instead of that,' +
|
|
1116
1241
|
'\r\n' +
|
|
1117
1242
|
'now you can use replayer.getMirror() to access the mirror instance of a replayer,' +
|
|
@@ -1151,14 +1276,13 @@ if (typeof window !== 'undefined' && window.Proxy && window.Reflect) {
|
|
|
1151
1276
|
function throttle$1(func, wait, options = {}) {
|
|
1152
1277
|
let timeout = null;
|
|
1153
1278
|
let previous = 0;
|
|
1154
|
-
return function (
|
|
1155
|
-
|
|
1279
|
+
return function (...args) {
|
|
1280
|
+
const now = Date.now();
|
|
1156
1281
|
if (!previous && options.leading === false) {
|
|
1157
1282
|
previous = now;
|
|
1158
1283
|
}
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
let args = arguments;
|
|
1284
|
+
const remaining = wait - (now - previous);
|
|
1285
|
+
const context = this;
|
|
1162
1286
|
if (remaining <= 0 || remaining > wait) {
|
|
1163
1287
|
if (timeout) {
|
|
1164
1288
|
clearTimeout(timeout);
|
|
@@ -1195,7 +1319,8 @@ function hookSetter(target, key, d, isRevoked, win = window) {
|
|
|
1195
1319
|
function patch(source, name, replacement) {
|
|
1196
1320
|
try {
|
|
1197
1321
|
if (!(name in source)) {
|
|
1198
|
-
return () => {
|
|
1322
|
+
return () => {
|
|
1323
|
+
};
|
|
1199
1324
|
}
|
|
1200
1325
|
const original = source[name];
|
|
1201
1326
|
const wrapped = replacement(original);
|
|
@@ -1214,9 +1339,36 @@ function patch(source, name, replacement) {
|
|
|
1214
1339
|
};
|
|
1215
1340
|
}
|
|
1216
1341
|
catch (_a) {
|
|
1217
|
-
return () => {
|
|
1342
|
+
return () => {
|
|
1343
|
+
};
|
|
1218
1344
|
}
|
|
1219
1345
|
}
|
|
1346
|
+
let nowTimestamp = Date.now;
|
|
1347
|
+
if (!(/[1-9][0-9]{12}/.test(Date.now().toString()))) {
|
|
1348
|
+
nowTimestamp = () => new Date().getTime();
|
|
1349
|
+
}
|
|
1350
|
+
function getWindowScroll(win) {
|
|
1351
|
+
var _a, _b, _c, _d, _e, _f;
|
|
1352
|
+
const doc = win.document;
|
|
1353
|
+
return {
|
|
1354
|
+
left: doc.scrollingElement
|
|
1355
|
+
? doc.scrollingElement.scrollLeft
|
|
1356
|
+
: win.pageXOffset !== undefined
|
|
1357
|
+
? win.pageXOffset
|
|
1358
|
+
: (doc === null || doc === void 0 ? void 0 : doc.documentElement.scrollLeft) ||
|
|
1359
|
+
((_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) ||
|
|
1360
|
+
((_c = doc === null || doc === void 0 ? void 0 : doc.body) === null || _c === void 0 ? void 0 : _c.scrollLeft) ||
|
|
1361
|
+
0,
|
|
1362
|
+
top: doc.scrollingElement
|
|
1363
|
+
? doc.scrollingElement.scrollTop
|
|
1364
|
+
: win.pageYOffset !== undefined
|
|
1365
|
+
? win.pageYOffset
|
|
1366
|
+
: (doc === null || doc === void 0 ? void 0 : doc.documentElement.scrollTop) ||
|
|
1367
|
+
((_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) ||
|
|
1368
|
+
((_f = doc === null || doc === void 0 ? void 0 : doc.body) === null || _f === void 0 ? void 0 : _f.scrollTop) ||
|
|
1369
|
+
0,
|
|
1370
|
+
};
|
|
1371
|
+
}
|
|
1220
1372
|
function getWindowHeight() {
|
|
1221
1373
|
return (window.innerHeight ||
|
|
1222
1374
|
(document.documentElement && document.documentElement.clientHeight) ||
|
|
@@ -1227,48 +1379,38 @@ function getWindowWidth() {
|
|
|
1227
1379
|
(document.documentElement && document.documentElement.clientWidth) ||
|
|
1228
1380
|
(document.body && document.body.clientWidth));
|
|
1229
1381
|
}
|
|
1230
|
-
function isBlocked(node, blockClass, blockSelector, unblockSelector) {
|
|
1382
|
+
function isBlocked(node, blockClass, blockSelector, unblockSelector, checkAncestors) {
|
|
1231
1383
|
if (!node) {
|
|
1232
1384
|
return false;
|
|
1233
1385
|
}
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
else {
|
|
1249
|
-
!needUnblock &&
|
|
1250
|
-
node.classList.forEach((className) => {
|
|
1251
|
-
if (blockClass.test(className)) {
|
|
1252
|
-
needBlock = true;
|
|
1253
|
-
}
|
|
1254
|
-
});
|
|
1255
|
-
}
|
|
1256
|
-
if (!needBlock && blockSelector) {
|
|
1257
|
-
needBlock = node.matches(blockSelector);
|
|
1258
|
-
}
|
|
1259
|
-
return ((!needUnblock && needBlock) ||
|
|
1260
|
-
isBlocked(node.parentNode, blockClass, blockSelector, unblockSelector));
|
|
1386
|
+
const el = node.nodeType === node.ELEMENT_NODE
|
|
1387
|
+
? node
|
|
1388
|
+
: node.parentElement;
|
|
1389
|
+
if (!el)
|
|
1390
|
+
return false;
|
|
1391
|
+
const blockedPredicate = createMatchPredicate(blockClass, blockSelector);
|
|
1392
|
+
if (!checkAncestors) {
|
|
1393
|
+
const isUnblocked = unblockSelector && el.matches(unblockSelector);
|
|
1394
|
+
return blockedPredicate(el) && !isUnblocked;
|
|
1395
|
+
}
|
|
1396
|
+
const blockDistance = distanceToMatch(el, blockedPredicate);
|
|
1397
|
+
let unblockDistance = -1;
|
|
1398
|
+
if (blockDistance < 0) {
|
|
1399
|
+
return false;
|
|
1261
1400
|
}
|
|
1262
|
-
if (
|
|
1263
|
-
|
|
1401
|
+
if (unblockSelector) {
|
|
1402
|
+
unblockDistance = distanceToMatch(el, createMatchPredicate(null, unblockSelector));
|
|
1264
1403
|
}
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
function isIgnored(n) {
|
|
1268
|
-
if ('__sn' in n) {
|
|
1269
|
-
return n.__sn.id === IGNORED_NODE;
|
|
1404
|
+
if (blockDistance > -1 && unblockDistance < 0) {
|
|
1405
|
+
return true;
|
|
1270
1406
|
}
|
|
1271
|
-
return
|
|
1407
|
+
return blockDistance < unblockDistance;
|
|
1408
|
+
}
|
|
1409
|
+
function isSerialized(n, mirror) {
|
|
1410
|
+
return mirror.getId(n) !== -1;
|
|
1411
|
+
}
|
|
1412
|
+
function isIgnored(n, mirror) {
|
|
1413
|
+
return mirror.getId(n) === IGNORED_NODE;
|
|
1272
1414
|
}
|
|
1273
1415
|
function isAncestorRemoved(target, mirror) {
|
|
1274
1416
|
if (isShadowRoot(target)) {
|
|
@@ -1287,7 +1429,7 @@ function isAncestorRemoved(target, mirror) {
|
|
|
1287
1429
|
}
|
|
1288
1430
|
return isAncestorRemoved(target.parentNode, mirror);
|
|
1289
1431
|
}
|
|
1290
|
-
function
|
|
1432
|
+
function legacy_isTouchEvent(event) {
|
|
1291
1433
|
return Boolean(event.changedTouches);
|
|
1292
1434
|
}
|
|
1293
1435
|
function polyfill(win = window) {
|
|
@@ -1300,8 +1442,9 @@ function polyfill(win = window) {
|
|
|
1300
1442
|
.forEach;
|
|
1301
1443
|
}
|
|
1302
1444
|
if (!Node.prototype.contains) {
|
|
1303
|
-
Node.prototype.contains =
|
|
1304
|
-
|
|
1445
|
+
Node.prototype.contains = (...args) => {
|
|
1446
|
+
let node = args[0];
|
|
1447
|
+
if (!(0 in args)) {
|
|
1305
1448
|
throw new TypeError('1 argument is required');
|
|
1306
1449
|
}
|
|
1307
1450
|
do {
|
|
@@ -1313,15 +1456,142 @@ function polyfill(win = window) {
|
|
|
1313
1456
|
};
|
|
1314
1457
|
}
|
|
1315
1458
|
}
|
|
1316
|
-
function
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
return
|
|
1459
|
+
function isSerializedIframe(n, mirror) {
|
|
1460
|
+
return Boolean(n.nodeName === 'IFRAME' && mirror.getMeta(n));
|
|
1461
|
+
}
|
|
1462
|
+
function isSerializedStylesheet(n, mirror) {
|
|
1463
|
+
return Boolean(n.nodeName === 'LINK' &&
|
|
1464
|
+
n.nodeType === n.ELEMENT_NODE &&
|
|
1465
|
+
n.getAttribute &&
|
|
1466
|
+
n.getAttribute('rel') === 'stylesheet' &&
|
|
1467
|
+
mirror.getMeta(n));
|
|
1321
1468
|
}
|
|
1322
1469
|
function hasShadowRoot(n) {
|
|
1323
1470
|
return Boolean(n === null || n === void 0 ? void 0 : n.shadowRoot);
|
|
1324
1471
|
}
|
|
1472
|
+
class StyleSheetMirror {
|
|
1473
|
+
constructor() {
|
|
1474
|
+
this.id = 1;
|
|
1475
|
+
this.styleIDMap = new WeakMap();
|
|
1476
|
+
this.idStyleMap = new Map();
|
|
1477
|
+
}
|
|
1478
|
+
getId(stylesheet) {
|
|
1479
|
+
var _a;
|
|
1480
|
+
return (_a = this.styleIDMap.get(stylesheet)) !== null && _a !== void 0 ? _a : -1;
|
|
1481
|
+
}
|
|
1482
|
+
has(stylesheet) {
|
|
1483
|
+
return this.styleIDMap.has(stylesheet);
|
|
1484
|
+
}
|
|
1485
|
+
add(stylesheet, id) {
|
|
1486
|
+
if (this.has(stylesheet))
|
|
1487
|
+
return this.getId(stylesheet);
|
|
1488
|
+
let newId;
|
|
1489
|
+
if (id === undefined) {
|
|
1490
|
+
newId = this.id++;
|
|
1491
|
+
}
|
|
1492
|
+
else
|
|
1493
|
+
newId = id;
|
|
1494
|
+
this.styleIDMap.set(stylesheet, newId);
|
|
1495
|
+
this.idStyleMap.set(newId, stylesheet);
|
|
1496
|
+
return newId;
|
|
1497
|
+
}
|
|
1498
|
+
getStyle(id) {
|
|
1499
|
+
return this.idStyleMap.get(id) || null;
|
|
1500
|
+
}
|
|
1501
|
+
reset() {
|
|
1502
|
+
this.styleIDMap = new WeakMap();
|
|
1503
|
+
this.idStyleMap = new Map();
|
|
1504
|
+
this.id = 1;
|
|
1505
|
+
}
|
|
1506
|
+
generateId() {
|
|
1507
|
+
return this.id++;
|
|
1508
|
+
}
|
|
1509
|
+
}
|
|
1510
|
+
function getShadowHost(n) {
|
|
1511
|
+
var _a, _b;
|
|
1512
|
+
let shadowHost = null;
|
|
1513
|
+
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 &&
|
|
1514
|
+
n.getRootNode().host)
|
|
1515
|
+
shadowHost = n.getRootNode().host;
|
|
1516
|
+
return shadowHost;
|
|
1517
|
+
}
|
|
1518
|
+
function getRootShadowHost(n) {
|
|
1519
|
+
let rootShadowHost = n;
|
|
1520
|
+
let shadowHost;
|
|
1521
|
+
while ((shadowHost = getShadowHost(rootShadowHost)))
|
|
1522
|
+
rootShadowHost = shadowHost;
|
|
1523
|
+
return rootShadowHost;
|
|
1524
|
+
}
|
|
1525
|
+
function shadowHostInDom(n) {
|
|
1526
|
+
const doc = n.ownerDocument;
|
|
1527
|
+
if (!doc)
|
|
1528
|
+
return false;
|
|
1529
|
+
const shadowHost = getRootShadowHost(n);
|
|
1530
|
+
return doc.contains(shadowHost);
|
|
1531
|
+
}
|
|
1532
|
+
function inDom(n) {
|
|
1533
|
+
const doc = n.ownerDocument;
|
|
1534
|
+
if (!doc)
|
|
1535
|
+
return false;
|
|
1536
|
+
return doc.contains(n) || shadowHostInDom(n);
|
|
1537
|
+
}
|
|
1538
|
+
|
|
1539
|
+
var EventType = /* @__PURE__ */ ((EventType2) => {
|
|
1540
|
+
EventType2[EventType2["DomContentLoaded"] = 0] = "DomContentLoaded";
|
|
1541
|
+
EventType2[EventType2["Load"] = 1] = "Load";
|
|
1542
|
+
EventType2[EventType2["FullSnapshot"] = 2] = "FullSnapshot";
|
|
1543
|
+
EventType2[EventType2["IncrementalSnapshot"] = 3] = "IncrementalSnapshot";
|
|
1544
|
+
EventType2[EventType2["Meta"] = 4] = "Meta";
|
|
1545
|
+
EventType2[EventType2["Custom"] = 5] = "Custom";
|
|
1546
|
+
EventType2[EventType2["Plugin"] = 6] = "Plugin";
|
|
1547
|
+
return EventType2;
|
|
1548
|
+
})(EventType || {});
|
|
1549
|
+
var IncrementalSource = /* @__PURE__ */ ((IncrementalSource2) => {
|
|
1550
|
+
IncrementalSource2[IncrementalSource2["Mutation"] = 0] = "Mutation";
|
|
1551
|
+
IncrementalSource2[IncrementalSource2["MouseMove"] = 1] = "MouseMove";
|
|
1552
|
+
IncrementalSource2[IncrementalSource2["MouseInteraction"] = 2] = "MouseInteraction";
|
|
1553
|
+
IncrementalSource2[IncrementalSource2["Scroll"] = 3] = "Scroll";
|
|
1554
|
+
IncrementalSource2[IncrementalSource2["ViewportResize"] = 4] = "ViewportResize";
|
|
1555
|
+
IncrementalSource2[IncrementalSource2["Input"] = 5] = "Input";
|
|
1556
|
+
IncrementalSource2[IncrementalSource2["TouchMove"] = 6] = "TouchMove";
|
|
1557
|
+
IncrementalSource2[IncrementalSource2["MediaInteraction"] = 7] = "MediaInteraction";
|
|
1558
|
+
IncrementalSource2[IncrementalSource2["StyleSheetRule"] = 8] = "StyleSheetRule";
|
|
1559
|
+
IncrementalSource2[IncrementalSource2["CanvasMutation"] = 9] = "CanvasMutation";
|
|
1560
|
+
IncrementalSource2[IncrementalSource2["Font"] = 10] = "Font";
|
|
1561
|
+
IncrementalSource2[IncrementalSource2["Log"] = 11] = "Log";
|
|
1562
|
+
IncrementalSource2[IncrementalSource2["Drag"] = 12] = "Drag";
|
|
1563
|
+
IncrementalSource2[IncrementalSource2["StyleDeclaration"] = 13] = "StyleDeclaration";
|
|
1564
|
+
IncrementalSource2[IncrementalSource2["Selection"] = 14] = "Selection";
|
|
1565
|
+
IncrementalSource2[IncrementalSource2["AdoptedStyleSheet"] = 15] = "AdoptedStyleSheet";
|
|
1566
|
+
IncrementalSource2[IncrementalSource2["CustomElement"] = 16] = "CustomElement";
|
|
1567
|
+
return IncrementalSource2;
|
|
1568
|
+
})(IncrementalSource || {});
|
|
1569
|
+
var MouseInteractions = /* @__PURE__ */ ((MouseInteractions2) => {
|
|
1570
|
+
MouseInteractions2[MouseInteractions2["MouseUp"] = 0] = "MouseUp";
|
|
1571
|
+
MouseInteractions2[MouseInteractions2["MouseDown"] = 1] = "MouseDown";
|
|
1572
|
+
MouseInteractions2[MouseInteractions2["Click"] = 2] = "Click";
|
|
1573
|
+
MouseInteractions2[MouseInteractions2["ContextMenu"] = 3] = "ContextMenu";
|
|
1574
|
+
MouseInteractions2[MouseInteractions2["DblClick"] = 4] = "DblClick";
|
|
1575
|
+
MouseInteractions2[MouseInteractions2["Focus"] = 5] = "Focus";
|
|
1576
|
+
MouseInteractions2[MouseInteractions2["Blur"] = 6] = "Blur";
|
|
1577
|
+
MouseInteractions2[MouseInteractions2["TouchStart"] = 7] = "TouchStart";
|
|
1578
|
+
MouseInteractions2[MouseInteractions2["TouchMove_Departed"] = 8] = "TouchMove_Departed";
|
|
1579
|
+
MouseInteractions2[MouseInteractions2["TouchEnd"] = 9] = "TouchEnd";
|
|
1580
|
+
MouseInteractions2[MouseInteractions2["TouchCancel"] = 10] = "TouchCancel";
|
|
1581
|
+
return MouseInteractions2;
|
|
1582
|
+
})(MouseInteractions || {});
|
|
1583
|
+
var PointerTypes = /* @__PURE__ */ ((PointerTypes2) => {
|
|
1584
|
+
PointerTypes2[PointerTypes2["Mouse"] = 0] = "Mouse";
|
|
1585
|
+
PointerTypes2[PointerTypes2["Pen"] = 1] = "Pen";
|
|
1586
|
+
PointerTypes2[PointerTypes2["Touch"] = 2] = "Touch";
|
|
1587
|
+
return PointerTypes2;
|
|
1588
|
+
})(PointerTypes || {});
|
|
1589
|
+
var CanvasContext = /* @__PURE__ */ ((CanvasContext2) => {
|
|
1590
|
+
CanvasContext2[CanvasContext2["2D"] = 0] = "2D";
|
|
1591
|
+
CanvasContext2[CanvasContext2["WebGL"] = 1] = "WebGL";
|
|
1592
|
+
CanvasContext2[CanvasContext2["WebGL2"] = 2] = "WebGL2";
|
|
1593
|
+
return CanvasContext2;
|
|
1594
|
+
})(CanvasContext || {});
|
|
1325
1595
|
|
|
1326
1596
|
function isNodeInLinkedList(n) {
|
|
1327
1597
|
return '__ln' in n;
|
|
@@ -1330,6 +1600,7 @@ class DoubleLinkedList {
|
|
|
1330
1600
|
constructor() {
|
|
1331
1601
|
this.length = 0;
|
|
1332
1602
|
this.head = null;
|
|
1603
|
+
this.tail = null;
|
|
1333
1604
|
}
|
|
1334
1605
|
get(position) {
|
|
1335
1606
|
if (position >= this.length) {
|
|
@@ -1375,6 +1646,9 @@ class DoubleLinkedList {
|
|
|
1375
1646
|
node.next = this.head;
|
|
1376
1647
|
this.head = node;
|
|
1377
1648
|
}
|
|
1649
|
+
if (node.next === null) {
|
|
1650
|
+
this.tail = node;
|
|
1651
|
+
}
|
|
1378
1652
|
this.length++;
|
|
1379
1653
|
}
|
|
1380
1654
|
removeNode(n) {
|
|
@@ -1387,12 +1661,18 @@ class DoubleLinkedList {
|
|
|
1387
1661
|
if (this.head) {
|
|
1388
1662
|
this.head.previous = null;
|
|
1389
1663
|
}
|
|
1664
|
+
else {
|
|
1665
|
+
this.tail = null;
|
|
1666
|
+
}
|
|
1390
1667
|
}
|
|
1391
1668
|
else {
|
|
1392
1669
|
current.previous.next = current.next;
|
|
1393
1670
|
if (current.next) {
|
|
1394
1671
|
current.next.previous = current.previous;
|
|
1395
1672
|
}
|
|
1673
|
+
else {
|
|
1674
|
+
this.tail = current.previous;
|
|
1675
|
+
}
|
|
1396
1676
|
}
|
|
1397
1677
|
if (n.__ln) {
|
|
1398
1678
|
delete n.__ln;
|
|
@@ -1401,9 +1681,6 @@ class DoubleLinkedList {
|
|
|
1401
1681
|
}
|
|
1402
1682
|
}
|
|
1403
1683
|
const moveKey = (id, parentId) => `${id}@${parentId}`;
|
|
1404
|
-
function isINode(n) {
|
|
1405
|
-
return '__sn' in n;
|
|
1406
|
-
}
|
|
1407
1684
|
class MutationBuffer {
|
|
1408
1685
|
constructor() {
|
|
1409
1686
|
this.frozen = false;
|
|
@@ -1425,6 +1702,7 @@ class MutationBuffer {
|
|
|
1425
1702
|
return;
|
|
1426
1703
|
}
|
|
1427
1704
|
const adds = [];
|
|
1705
|
+
const addedIds = new Set();
|
|
1428
1706
|
const addList = new DoubleLinkedList();
|
|
1429
1707
|
const getNextId = (n) => {
|
|
1430
1708
|
let ns = n;
|
|
@@ -1436,59 +1714,56 @@ class MutationBuffer {
|
|
|
1436
1714
|
return nextId;
|
|
1437
1715
|
};
|
|
1438
1716
|
const pushAdd = (n) => {
|
|
1439
|
-
|
|
1440
|
-
const shadowHost = n.getRootNode
|
|
1441
|
-
? (_a = n.getRootNode()) === null || _a === void 0 ? void 0 : _a.host
|
|
1442
|
-
: null;
|
|
1443
|
-
let rootShadowHost = shadowHost;
|
|
1444
|
-
while ((_c = (_b = rootShadowHost === null || rootShadowHost === void 0 ? void 0 : rootShadowHost.getRootNode) === null || _b === void 0 ? void 0 : _b.call(rootShadowHost)) === null || _c === void 0 ? void 0 : _c.host)
|
|
1445
|
-
rootShadowHost =
|
|
1446
|
-
((_e = (_d = rootShadowHost === null || rootShadowHost === void 0 ? void 0 : rootShadowHost.getRootNode) === null || _d === void 0 ? void 0 : _d.call(rootShadowHost)) === null || _e === void 0 ? void 0 : _e.host) ||
|
|
1447
|
-
null;
|
|
1448
|
-
const notInDoc = !this.doc.contains(n) &&
|
|
1449
|
-
(!rootShadowHost || !this.doc.contains(rootShadowHost));
|
|
1450
|
-
if (!n.parentNode || notInDoc) {
|
|
1717
|
+
if (!n.parentNode || !inDom(n)) {
|
|
1451
1718
|
return;
|
|
1452
1719
|
}
|
|
1453
1720
|
const parentId = isShadowRoot(n.parentNode)
|
|
1454
|
-
? this.mirror.getId(
|
|
1721
|
+
? this.mirror.getId(getShadowHost(n))
|
|
1455
1722
|
: this.mirror.getId(n.parentNode);
|
|
1456
1723
|
const nextId = getNextId(n);
|
|
1457
1724
|
if (parentId === -1 || nextId === -1) {
|
|
1458
1725
|
return addList.addNode(n);
|
|
1459
1726
|
}
|
|
1460
|
-
|
|
1727
|
+
const sn = serializeNodeWithId(n, {
|
|
1461
1728
|
doc: this.doc,
|
|
1462
|
-
|
|
1729
|
+
mirror: this.mirror,
|
|
1463
1730
|
blockClass: this.blockClass,
|
|
1464
1731
|
blockSelector: this.blockSelector,
|
|
1732
|
+
maskAllText: this.maskAllText,
|
|
1465
1733
|
unblockSelector: this.unblockSelector,
|
|
1466
1734
|
maskTextClass: this.maskTextClass,
|
|
1735
|
+
unmaskTextClass: this.unmaskTextClass,
|
|
1467
1736
|
maskTextSelector: this.maskTextSelector,
|
|
1468
1737
|
unmaskTextSelector: this.unmaskTextSelector,
|
|
1469
|
-
maskInputSelector: this.maskInputSelector,
|
|
1470
|
-
unmaskInputSelector: this.unmaskInputSelector,
|
|
1471
1738
|
skipChild: true,
|
|
1739
|
+
newlyAddedElement: true,
|
|
1472
1740
|
inlineStylesheet: this.inlineStylesheet,
|
|
1473
|
-
maskAllText: this.maskAllText,
|
|
1474
1741
|
maskInputOptions: this.maskInputOptions,
|
|
1742
|
+
maskAttributeFn: this.maskAttributeFn,
|
|
1475
1743
|
maskTextFn: this.maskTextFn,
|
|
1476
1744
|
maskInputFn: this.maskInputFn,
|
|
1477
1745
|
slimDOMOptions: this.slimDOMOptions,
|
|
1746
|
+
dataURLOptions: this.dataURLOptions,
|
|
1478
1747
|
recordCanvas: this.recordCanvas,
|
|
1479
1748
|
inlineImages: this.inlineImages,
|
|
1480
1749
|
onSerialize: (currentN) => {
|
|
1481
|
-
if (
|
|
1750
|
+
if (isSerializedIframe(currentN, this.mirror)) {
|
|
1482
1751
|
this.iframeManager.addIframe(currentN);
|
|
1483
1752
|
}
|
|
1753
|
+
if (isSerializedStylesheet(currentN, this.mirror)) {
|
|
1754
|
+
this.stylesheetManager.trackLinkElement(currentN);
|
|
1755
|
+
}
|
|
1484
1756
|
if (hasShadowRoot(n)) {
|
|
1485
|
-
this.shadowDomManager.addShadowRoot(n.shadowRoot,
|
|
1757
|
+
this.shadowDomManager.addShadowRoot(n.shadowRoot, this.doc);
|
|
1486
1758
|
}
|
|
1487
1759
|
},
|
|
1488
1760
|
onIframeLoad: (iframe, childSn) => {
|
|
1489
1761
|
this.iframeManager.attachIframe(iframe, childSn);
|
|
1490
1762
|
this.shadowDomManager.observeAttachShadow(iframe);
|
|
1491
1763
|
},
|
|
1764
|
+
onStylesheetLoad: (link, childSn) => {
|
|
1765
|
+
this.stylesheetManager.attachLinkElement(link, childSn);
|
|
1766
|
+
},
|
|
1492
1767
|
});
|
|
1493
1768
|
if (sn) {
|
|
1494
1769
|
adds.push({
|
|
@@ -1496,6 +1771,7 @@ class MutationBuffer {
|
|
|
1496
1771
|
nextId,
|
|
1497
1772
|
node: sn,
|
|
1498
1773
|
});
|
|
1774
|
+
addedIds.add(sn.id);
|
|
1499
1775
|
}
|
|
1500
1776
|
};
|
|
1501
1777
|
while (this.mapRemoves.length) {
|
|
@@ -1531,15 +1807,33 @@ class MutationBuffer {
|
|
|
1531
1807
|
}
|
|
1532
1808
|
}
|
|
1533
1809
|
if (!node) {
|
|
1534
|
-
|
|
1535
|
-
|
|
1810
|
+
let tailNode = addList.tail;
|
|
1811
|
+
while (tailNode) {
|
|
1812
|
+
const _node = tailNode;
|
|
1813
|
+
tailNode = tailNode.previous;
|
|
1536
1814
|
if (_node) {
|
|
1537
1815
|
const parentId = this.mirror.getId(_node.value.parentNode);
|
|
1538
1816
|
const nextId = getNextId(_node.value);
|
|
1539
|
-
if (
|
|
1817
|
+
if (nextId === -1)
|
|
1818
|
+
continue;
|
|
1819
|
+
else if (parentId !== -1) {
|
|
1540
1820
|
node = _node;
|
|
1541
1821
|
break;
|
|
1542
1822
|
}
|
|
1823
|
+
else {
|
|
1824
|
+
const unhandledNode = _node.value;
|
|
1825
|
+
if (unhandledNode.parentNode &&
|
|
1826
|
+
unhandledNode.parentNode.nodeType ===
|
|
1827
|
+
Node.DOCUMENT_FRAGMENT_NODE) {
|
|
1828
|
+
const shadowHost = unhandledNode.parentNode
|
|
1829
|
+
.host;
|
|
1830
|
+
const parentId = this.mirror.getId(shadowHost);
|
|
1831
|
+
if (parentId !== -1) {
|
|
1832
|
+
node = _node;
|
|
1833
|
+
break;
|
|
1834
|
+
}
|
|
1835
|
+
}
|
|
1836
|
+
}
|
|
1543
1837
|
}
|
|
1544
1838
|
}
|
|
1545
1839
|
}
|
|
@@ -1559,12 +1853,27 @@ class MutationBuffer {
|
|
|
1559
1853
|
id: this.mirror.getId(text.node),
|
|
1560
1854
|
value: text.value,
|
|
1561
1855
|
}))
|
|
1856
|
+
.filter((text) => !addedIds.has(text.id))
|
|
1562
1857
|
.filter((text) => this.mirror.has(text.id)),
|
|
1563
1858
|
attributes: this.attributes
|
|
1564
|
-
.map((attribute) =>
|
|
1565
|
-
|
|
1566
|
-
attributes
|
|
1567
|
-
|
|
1859
|
+
.map((attribute) => {
|
|
1860
|
+
const { attributes } = attribute;
|
|
1861
|
+
if (typeof attributes.style === 'string') {
|
|
1862
|
+
const diffAsStr = JSON.stringify(attribute.styleDiff);
|
|
1863
|
+
const unchangedAsStr = JSON.stringify(attribute._unchangedStyles);
|
|
1864
|
+
if (diffAsStr.length < attributes.style.length) {
|
|
1865
|
+
if ((diffAsStr + unchangedAsStr).split('var(').length ===
|
|
1866
|
+
attributes.style.split('var(').length) {
|
|
1867
|
+
attributes.style = attribute.styleDiff;
|
|
1868
|
+
}
|
|
1869
|
+
}
|
|
1870
|
+
}
|
|
1871
|
+
return {
|
|
1872
|
+
id: this.mirror.getId(attribute.node),
|
|
1873
|
+
attributes: attributes,
|
|
1874
|
+
};
|
|
1875
|
+
})
|
|
1876
|
+
.filter((attribute) => !addedIds.has(attribute.id))
|
|
1568
1877
|
.filter((attribute) => this.mirror.has(attribute.id)),
|
|
1569
1878
|
removes: this.removes,
|
|
1570
1879
|
adds,
|
|
@@ -1585,15 +1894,23 @@ class MutationBuffer {
|
|
|
1585
1894
|
this.mutationCb(payload);
|
|
1586
1895
|
};
|
|
1587
1896
|
this.processMutation = (m) => {
|
|
1588
|
-
if (isIgnored(m.target)) {
|
|
1897
|
+
if (isIgnored(m.target, this.mirror)) {
|
|
1589
1898
|
return;
|
|
1590
1899
|
}
|
|
1900
|
+
let unattachedDoc;
|
|
1901
|
+
try {
|
|
1902
|
+
unattachedDoc = document.implementation.createHTMLDocument();
|
|
1903
|
+
}
|
|
1904
|
+
catch (e) {
|
|
1905
|
+
unattachedDoc = this.doc;
|
|
1906
|
+
}
|
|
1591
1907
|
switch (m.type) {
|
|
1592
1908
|
case 'characterData': {
|
|
1593
1909
|
const value = m.target.textContent;
|
|
1594
|
-
if (!isBlocked(m.target, this.blockClass, this.blockSelector, this.unblockSelector) &&
|
|
1910
|
+
if (!isBlocked(m.target, this.blockClass, this.blockSelector, this.unblockSelector, false) &&
|
|
1911
|
+
value !== m.oldValue) {
|
|
1595
1912
|
this.texts.push({
|
|
1596
|
-
value: needMaskingText(m.target, this.maskTextClass, this.maskTextSelector, this.unmaskTextSelector, this.maskAllText) && value
|
|
1913
|
+
value: needMaskingText(m.target, this.maskTextClass, this.maskTextSelector, this.unmaskTextClass, this.unmaskTextSelector, this.maskAllText) && value
|
|
1597
1914
|
? this.maskTextFn
|
|
1598
1915
|
? this.maskTextFn(value)
|
|
1599
1916
|
: value.replace(/[\S]/g, '*')
|
|
@@ -1605,83 +1922,99 @@ class MutationBuffer {
|
|
|
1605
1922
|
}
|
|
1606
1923
|
case 'attributes': {
|
|
1607
1924
|
const target = m.target;
|
|
1608
|
-
let
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1925
|
+
let attributeName = m.attributeName;
|
|
1926
|
+
let value = m.target.getAttribute(attributeName);
|
|
1927
|
+
if (attributeName === 'value') {
|
|
1928
|
+
const type = getInputType(target);
|
|
1929
|
+
const tagName = target.tagName;
|
|
1930
|
+
value = getInputValue(target, tagName, type);
|
|
1931
|
+
const isInputMasked = shouldMaskInput({
|
|
1614
1932
|
maskInputOptions: this.maskInputOptions,
|
|
1615
|
-
tagName
|
|
1616
|
-
type
|
|
1933
|
+
tagName,
|
|
1934
|
+
type,
|
|
1935
|
+
});
|
|
1936
|
+
const forceMask = needMaskingText(m.target, this.maskTextClass, this.maskTextSelector, this.unmaskTextClass, this.unmaskTextSelector, isInputMasked);
|
|
1937
|
+
value = maskInputValue({
|
|
1938
|
+
isMasked: forceMask,
|
|
1939
|
+
element: target,
|
|
1617
1940
|
value,
|
|
1618
1941
|
maskInputFn: this.maskInputFn,
|
|
1619
1942
|
});
|
|
1620
1943
|
}
|
|
1621
|
-
if (isBlocked(m.target, this.blockClass, this.blockSelector, this.unblockSelector) ||
|
|
1944
|
+
if (isBlocked(m.target, this.blockClass, this.blockSelector, this.unblockSelector, false) ||
|
|
1945
|
+
value === m.oldValue) {
|
|
1622
1946
|
return;
|
|
1623
1947
|
}
|
|
1624
1948
|
let item = this.attributes.find((a) => a.node === m.target);
|
|
1949
|
+
if (target.tagName === 'IFRAME' &&
|
|
1950
|
+
attributeName === 'src' &&
|
|
1951
|
+
!this.keepIframeSrcFn(value)) {
|
|
1952
|
+
if (!target.contentDocument) {
|
|
1953
|
+
attributeName = 'rr_src';
|
|
1954
|
+
}
|
|
1955
|
+
else {
|
|
1956
|
+
return;
|
|
1957
|
+
}
|
|
1958
|
+
}
|
|
1625
1959
|
if (!item) {
|
|
1626
1960
|
item = {
|
|
1627
1961
|
node: m.target,
|
|
1628
1962
|
attributes: {},
|
|
1963
|
+
styleDiff: {},
|
|
1964
|
+
_unchangedStyles: {},
|
|
1629
1965
|
};
|
|
1630
1966
|
this.attributes.push(item);
|
|
1631
1967
|
}
|
|
1632
|
-
if (
|
|
1968
|
+
if (attributeName === 'type' &&
|
|
1633
1969
|
target.tagName === 'INPUT' &&
|
|
1634
1970
|
(m.oldValue || '').toLowerCase() === 'password') {
|
|
1635
1971
|
target.setAttribute('data-rr-is-password', 'true');
|
|
1636
1972
|
}
|
|
1637
|
-
if (
|
|
1638
|
-
|
|
1639
|
-
if (
|
|
1640
|
-
old.
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
item.attributes.style = {};
|
|
1645
|
-
}
|
|
1646
|
-
try {
|
|
1647
|
-
const styleObj = item.attributes.style;
|
|
1973
|
+
if (!ignoreAttribute(target.tagName, attributeName)) {
|
|
1974
|
+
item.attributes[attributeName] = transformAttribute(this.doc, toLowerCase(target.tagName), toLowerCase(attributeName), value, target, this.maskAttributeFn);
|
|
1975
|
+
if (attributeName === 'style') {
|
|
1976
|
+
const old = unattachedDoc.createElement('span');
|
|
1977
|
+
if (m.oldValue) {
|
|
1978
|
+
old.setAttribute('style', m.oldValue);
|
|
1979
|
+
}
|
|
1648
1980
|
for (const pname of Array.from(target.style)) {
|
|
1649
1981
|
const newValue = target.style.getPropertyValue(pname);
|
|
1650
1982
|
const newPriority = target.style.getPropertyPriority(pname);
|
|
1651
1983
|
if (newValue !== old.style.getPropertyValue(pname) ||
|
|
1652
1984
|
newPriority !== old.style.getPropertyPriority(pname)) {
|
|
1653
1985
|
if (newPriority === '') {
|
|
1654
|
-
|
|
1986
|
+
item.styleDiff[pname] = newValue;
|
|
1655
1987
|
}
|
|
1656
1988
|
else {
|
|
1657
|
-
|
|
1989
|
+
item.styleDiff[pname] = [newValue, newPriority];
|
|
1658
1990
|
}
|
|
1659
1991
|
}
|
|
1992
|
+
else {
|
|
1993
|
+
item._unchangedStyles[pname] = [newValue, newPriority];
|
|
1994
|
+
}
|
|
1660
1995
|
}
|
|
1661
1996
|
for (const pname of Array.from(old.style)) {
|
|
1662
1997
|
if (target.style.getPropertyValue(pname) === '') {
|
|
1663
|
-
|
|
1998
|
+
item.styleDiff[pname] = false;
|
|
1664
1999
|
}
|
|
1665
2000
|
}
|
|
1666
2001
|
}
|
|
1667
|
-
catch (error) {
|
|
1668
|
-
console.warn('[rrweb] Error when parsing update to style attribute:', error);
|
|
1669
|
-
}
|
|
1670
|
-
}
|
|
1671
|
-
else {
|
|
1672
|
-
const element = m.target;
|
|
1673
|
-
item.attributes[m.attributeName] = transformAttribute(this.doc, element, element.tagName, m.attributeName, value, this.maskAllText, this.unmaskTextSelector, this.maskTextFn);
|
|
1674
2002
|
}
|
|
1675
2003
|
break;
|
|
1676
2004
|
}
|
|
1677
2005
|
case 'childList': {
|
|
2006
|
+
if (isBlocked(m.target, this.blockClass, this.blockSelector, this.unblockSelector, true)) {
|
|
2007
|
+
return;
|
|
2008
|
+
}
|
|
1678
2009
|
m.addedNodes.forEach((n) => this.genAdds(n, m.target));
|
|
1679
2010
|
m.removedNodes.forEach((n) => {
|
|
1680
2011
|
const nodeId = this.mirror.getId(n);
|
|
1681
2012
|
const parentId = isShadowRoot(m.target)
|
|
1682
2013
|
? this.mirror.getId(m.target.host)
|
|
1683
2014
|
: this.mirror.getId(m.target);
|
|
1684
|
-
if (isBlocked(m.target, this.blockClass, this.blockSelector, this.unblockSelector) ||
|
|
2015
|
+
if (isBlocked(m.target, this.blockClass, this.blockSelector, this.unblockSelector, false) ||
|
|
2016
|
+
isIgnored(n, this.mirror) ||
|
|
2017
|
+
!isSerialized(n, this.mirror)) {
|
|
1685
2018
|
return;
|
|
1686
2019
|
}
|
|
1687
2020
|
if (this.addedSet.has(n)) {
|
|
@@ -1698,7 +2031,9 @@ class MutationBuffer {
|
|
|
1698
2031
|
this.removes.push({
|
|
1699
2032
|
parentId,
|
|
1700
2033
|
id: nodeId,
|
|
1701
|
-
isShadow: isShadowRoot(m.target)
|
|
2034
|
+
isShadow: isShadowRoot(m.target) && isNativeShadowDom(m.target)
|
|
2035
|
+
? true
|
|
2036
|
+
: undefined,
|
|
1702
2037
|
});
|
|
1703
2038
|
}
|
|
1704
2039
|
this.mapRemoves.push(n);
|
|
@@ -1708,28 +2043,36 @@ class MutationBuffer {
|
|
|
1708
2043
|
}
|
|
1709
2044
|
};
|
|
1710
2045
|
this.genAdds = (n, target) => {
|
|
1711
|
-
if (
|
|
2046
|
+
if (this.processedNodeManager.inOtherBuffer(n, this))
|
|
1712
2047
|
return;
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
2048
|
+
if (this.addedSet.has(n) || this.movedSet.has(n))
|
|
2049
|
+
return;
|
|
2050
|
+
if (this.mirror.hasNode(n)) {
|
|
2051
|
+
if (isIgnored(n, this.mirror)) {
|
|
1716
2052
|
return;
|
|
1717
2053
|
}
|
|
1718
2054
|
this.movedSet.add(n);
|
|
1719
2055
|
let targetId = null;
|
|
1720
|
-
if (target &&
|
|
1721
|
-
targetId =
|
|
2056
|
+
if (target && this.mirror.hasNode(target)) {
|
|
2057
|
+
targetId = this.mirror.getId(target);
|
|
1722
2058
|
}
|
|
1723
|
-
if (targetId) {
|
|
1724
|
-
this.movedMap[moveKey(
|
|
2059
|
+
if (targetId && targetId !== -1) {
|
|
2060
|
+
this.movedMap[moveKey(this.mirror.getId(n), targetId)] = true;
|
|
1725
2061
|
}
|
|
1726
2062
|
}
|
|
1727
2063
|
else {
|
|
1728
2064
|
this.addedSet.add(n);
|
|
1729
2065
|
this.droppedSet.delete(n);
|
|
1730
2066
|
}
|
|
1731
|
-
if (!isBlocked(n, this.blockClass, this.blockSelector, this.unblockSelector))
|
|
2067
|
+
if (!isBlocked(n, this.blockClass, this.blockSelector, this.unblockSelector, false)) {
|
|
1732
2068
|
n.childNodes.forEach((childN) => this.genAdds(childN));
|
|
2069
|
+
if (hasShadowRoot(n)) {
|
|
2070
|
+
n.shadowRoot.childNodes.forEach((childN) => {
|
|
2071
|
+
this.processedNodeManager.add(childN, this);
|
|
2072
|
+
this.genAdds(childN, n);
|
|
2073
|
+
});
|
|
2074
|
+
}
|
|
2075
|
+
}
|
|
1733
2076
|
};
|
|
1734
2077
|
}
|
|
1735
2078
|
init(options) {
|
|
@@ -1738,24 +2081,28 @@ class MutationBuffer {
|
|
|
1738
2081
|
'blockClass',
|
|
1739
2082
|
'blockSelector',
|
|
1740
2083
|
'unblockSelector',
|
|
2084
|
+
'maskAllText',
|
|
1741
2085
|
'maskTextClass',
|
|
2086
|
+
'unmaskTextClass',
|
|
1742
2087
|
'maskTextSelector',
|
|
1743
2088
|
'unmaskTextSelector',
|
|
1744
|
-
'maskInputSelector',
|
|
1745
|
-
'unmaskInputSelector',
|
|
1746
2089
|
'inlineStylesheet',
|
|
1747
|
-
'maskAllText',
|
|
1748
2090
|
'maskInputOptions',
|
|
2091
|
+
'maskAttributeFn',
|
|
1749
2092
|
'maskTextFn',
|
|
1750
2093
|
'maskInputFn',
|
|
2094
|
+
'keepIframeSrcFn',
|
|
1751
2095
|
'recordCanvas',
|
|
1752
2096
|
'inlineImages',
|
|
1753
2097
|
'slimDOMOptions',
|
|
2098
|
+
'dataURLOptions',
|
|
1754
2099
|
'doc',
|
|
1755
2100
|
'mirror',
|
|
1756
2101
|
'iframeManager',
|
|
2102
|
+
'stylesheetManager',
|
|
1757
2103
|
'shadowDomManager',
|
|
1758
2104
|
'canvasManager',
|
|
2105
|
+
'processedNodeManager',
|
|
1759
2106
|
].forEach((key) => {
|
|
1760
2107
|
this[key] = options[key];
|
|
1761
2108
|
});
|
|
@@ -1791,6 +2138,11 @@ function deepDelete(addsSet, n) {
|
|
|
1791
2138
|
n.childNodes.forEach((childN) => deepDelete(addsSet, childN));
|
|
1792
2139
|
}
|
|
1793
2140
|
function isParentRemoved(removes, n, mirror) {
|
|
2141
|
+
if (removes.length === 0)
|
|
2142
|
+
return false;
|
|
2143
|
+
return _isParentRemoved(removes, n, mirror);
|
|
2144
|
+
}
|
|
2145
|
+
function _isParentRemoved(removes, n, mirror) {
|
|
1794
2146
|
const { parentNode } = n;
|
|
1795
2147
|
if (!parentNode) {
|
|
1796
2148
|
return false;
|
|
@@ -1799,9 +2151,14 @@ function isParentRemoved(removes, n, mirror) {
|
|
|
1799
2151
|
if (removes.some((r) => r.id === parentId)) {
|
|
1800
2152
|
return true;
|
|
1801
2153
|
}
|
|
1802
|
-
return
|
|
2154
|
+
return _isParentRemoved(removes, parentNode, mirror);
|
|
1803
2155
|
}
|
|
1804
2156
|
function isAncestorInSet(set, n) {
|
|
2157
|
+
if (set.size === 0)
|
|
2158
|
+
return false;
|
|
2159
|
+
return _isAncestorInSet(set, n);
|
|
2160
|
+
}
|
|
2161
|
+
function _isAncestorInSet(set, n) {
|
|
1805
2162
|
const { parentNode } = n;
|
|
1806
2163
|
if (!parentNode) {
|
|
1807
2164
|
return false;
|
|
@@ -1809,23 +2166,32 @@ function isAncestorInSet(set, n) {
|
|
|
1809
2166
|
if (set.has(parentNode)) {
|
|
1810
2167
|
return true;
|
|
1811
2168
|
}
|
|
1812
|
-
return
|
|
2169
|
+
return _isAncestorInSet(set, parentNode);
|
|
1813
2170
|
}
|
|
1814
2171
|
|
|
2172
|
+
let errorHandler;
|
|
2173
|
+
function registerErrorHandler(handler) {
|
|
2174
|
+
errorHandler = handler;
|
|
2175
|
+
}
|
|
2176
|
+
function unregisterErrorHandler() {
|
|
2177
|
+
errorHandler = undefined;
|
|
2178
|
+
}
|
|
1815
2179
|
const callbackWrapper = (cb) => {
|
|
1816
|
-
|
|
2180
|
+
if (!errorHandler) {
|
|
2181
|
+
return cb;
|
|
2182
|
+
}
|
|
2183
|
+
const rrwebWrapped = ((...rest) => {
|
|
1817
2184
|
try {
|
|
1818
2185
|
return cb(...rest);
|
|
1819
2186
|
}
|
|
1820
2187
|
catch (error) {
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
catch (_a) {
|
|
2188
|
+
if (errorHandler && errorHandler(error) === true) {
|
|
2189
|
+
return () => {
|
|
2190
|
+
};
|
|
1825
2191
|
}
|
|
1826
2192
|
throw error;
|
|
1827
2193
|
}
|
|
1828
|
-
};
|
|
2194
|
+
});
|
|
1829
2195
|
return rrwebWrapped;
|
|
1830
2196
|
};
|
|
1831
2197
|
|
|
@@ -1842,7 +2208,8 @@ function getEventTarget(event) {
|
|
|
1842
2208
|
return event.path[0];
|
|
1843
2209
|
}
|
|
1844
2210
|
}
|
|
1845
|
-
catch (_a) {
|
|
2211
|
+
catch (_a) {
|
|
2212
|
+
}
|
|
1846
2213
|
return event && event.target;
|
|
1847
2214
|
}
|
|
1848
2215
|
function initMutationObserver(options, rootEl) {
|
|
@@ -1861,7 +2228,7 @@ function initMutationObserver(options, rootEl) {
|
|
|
1861
2228
|
if (options.onMutation && options.onMutation(mutations) === false) {
|
|
1862
2229
|
return;
|
|
1863
2230
|
}
|
|
1864
|
-
mutationBuffer.processMutations(mutations);
|
|
2231
|
+
mutationBuffer.processMutations.bind(mutationBuffer)(mutations);
|
|
1865
2232
|
}));
|
|
1866
2233
|
observer.observe(rootEl, {
|
|
1867
2234
|
attributes: true,
|
|
@@ -1875,7 +2242,8 @@ function initMutationObserver(options, rootEl) {
|
|
|
1875
2242
|
}
|
|
1876
2243
|
function initMoveObserver({ mousemoveCb, sampling, doc, mirror, }) {
|
|
1877
2244
|
if (sampling.mousemove === false) {
|
|
1878
|
-
return () => {
|
|
2245
|
+
return () => {
|
|
2246
|
+
};
|
|
1879
2247
|
}
|
|
1880
2248
|
const threshold = typeof sampling.mousemove === 'number' ? sampling.mousemove : 50;
|
|
1881
2249
|
const callbackThreshold = typeof sampling.mousemoveCallback === 'number'
|
|
@@ -1883,41 +2251,41 @@ function initMoveObserver({ mousemoveCb, sampling, doc, mirror, }) {
|
|
|
1883
2251
|
: 500;
|
|
1884
2252
|
let positions = [];
|
|
1885
2253
|
let timeBaseline;
|
|
1886
|
-
const wrappedCb = throttle$1((source) => {
|
|
2254
|
+
const wrappedCb = throttle$1(callbackWrapper((source) => {
|
|
1887
2255
|
const totalOffset = Date.now() - timeBaseline;
|
|
1888
|
-
|
|
2256
|
+
mousemoveCb(positions.map((p) => {
|
|
1889
2257
|
p.timeOffset -= totalOffset;
|
|
1890
2258
|
return p;
|
|
1891
2259
|
}), source);
|
|
1892
2260
|
positions = [];
|
|
1893
2261
|
timeBaseline = null;
|
|
1894
|
-
}, callbackThreshold);
|
|
1895
|
-
const updatePosition = throttle$1((evt) => {
|
|
2262
|
+
}), callbackThreshold);
|
|
2263
|
+
const updatePosition = callbackWrapper(throttle$1(callbackWrapper((evt) => {
|
|
1896
2264
|
const target = getEventTarget(evt);
|
|
1897
|
-
const { clientX, clientY } =
|
|
2265
|
+
const { clientX, clientY } = legacy_isTouchEvent(evt)
|
|
1898
2266
|
? evt.changedTouches[0]
|
|
1899
2267
|
: evt;
|
|
1900
2268
|
if (!timeBaseline) {
|
|
1901
|
-
timeBaseline =
|
|
2269
|
+
timeBaseline = nowTimestamp();
|
|
1902
2270
|
}
|
|
1903
2271
|
positions.push({
|
|
1904
2272
|
x: clientX,
|
|
1905
2273
|
y: clientY,
|
|
1906
2274
|
id: mirror.getId(target),
|
|
1907
|
-
timeOffset:
|
|
2275
|
+
timeOffset: nowTimestamp() - timeBaseline,
|
|
1908
2276
|
});
|
|
1909
2277
|
wrappedCb(typeof DragEvent !== 'undefined' && evt instanceof DragEvent
|
|
1910
2278
|
? IncrementalSource.Drag
|
|
1911
2279
|
: evt instanceof MouseEvent
|
|
1912
2280
|
? IncrementalSource.MouseMove
|
|
1913
2281
|
: IncrementalSource.TouchMove);
|
|
1914
|
-
}, threshold, {
|
|
2282
|
+
}), threshold, {
|
|
1915
2283
|
trailing: false,
|
|
1916
|
-
});
|
|
2284
|
+
}));
|
|
1917
2285
|
const handlers = [
|
|
1918
|
-
on('mousemove',
|
|
1919
|
-
on('touchmove',
|
|
1920
|
-
on('drag',
|
|
2286
|
+
on('mousemove', updatePosition, doc),
|
|
2287
|
+
on('touchmove', updatePosition, doc),
|
|
2288
|
+
on('drag', updatePosition, doc),
|
|
1921
2289
|
];
|
|
1922
2290
|
return callbackWrapper(() => {
|
|
1923
2291
|
handlers.forEach((h) => h());
|
|
@@ -1925,31 +2293,68 @@ function initMoveObserver({ mousemoveCb, sampling, doc, mirror, }) {
|
|
|
1925
2293
|
}
|
|
1926
2294
|
function initMouseInteractionObserver({ mouseInteractionCb, doc, mirror, blockClass, blockSelector, unblockSelector, sampling, }) {
|
|
1927
2295
|
if (sampling.mouseInteraction === false) {
|
|
1928
|
-
return () => {
|
|
2296
|
+
return () => {
|
|
2297
|
+
};
|
|
1929
2298
|
}
|
|
1930
2299
|
const disableMap = sampling.mouseInteraction === true ||
|
|
1931
2300
|
sampling.mouseInteraction === undefined
|
|
1932
2301
|
? {}
|
|
1933
2302
|
: sampling.mouseInteraction;
|
|
1934
2303
|
const handlers = [];
|
|
2304
|
+
let currentPointerType = null;
|
|
1935
2305
|
const getHandler = (eventKey) => {
|
|
1936
2306
|
return (event) => {
|
|
1937
2307
|
const target = getEventTarget(event);
|
|
1938
|
-
if (isBlocked(target, blockClass, blockSelector, unblockSelector)) {
|
|
2308
|
+
if (isBlocked(target, blockClass, blockSelector, unblockSelector, true)) {
|
|
1939
2309
|
return;
|
|
1940
2310
|
}
|
|
1941
|
-
|
|
2311
|
+
let pointerType = null;
|
|
2312
|
+
let thisEventKey = eventKey;
|
|
2313
|
+
if ('pointerType' in event) {
|
|
2314
|
+
switch (event.pointerType) {
|
|
2315
|
+
case 'mouse':
|
|
2316
|
+
pointerType = PointerTypes.Mouse;
|
|
2317
|
+
break;
|
|
2318
|
+
case 'touch':
|
|
2319
|
+
pointerType = PointerTypes.Touch;
|
|
2320
|
+
break;
|
|
2321
|
+
case 'pen':
|
|
2322
|
+
pointerType = PointerTypes.Pen;
|
|
2323
|
+
break;
|
|
2324
|
+
}
|
|
2325
|
+
if (pointerType === PointerTypes.Touch) {
|
|
2326
|
+
if (MouseInteractions[eventKey] === MouseInteractions.MouseDown) {
|
|
2327
|
+
thisEventKey = 'TouchStart';
|
|
2328
|
+
}
|
|
2329
|
+
else if (MouseInteractions[eventKey] === MouseInteractions.MouseUp) {
|
|
2330
|
+
thisEventKey = 'TouchEnd';
|
|
2331
|
+
}
|
|
2332
|
+
}
|
|
2333
|
+
else if (pointerType === PointerTypes.Pen) ;
|
|
2334
|
+
}
|
|
2335
|
+
else if (legacy_isTouchEvent(event)) {
|
|
2336
|
+
pointerType = PointerTypes.Touch;
|
|
2337
|
+
}
|
|
2338
|
+
if (pointerType !== null) {
|
|
2339
|
+
currentPointerType = pointerType;
|
|
2340
|
+
if ((thisEventKey.startsWith('Touch') &&
|
|
2341
|
+
pointerType === PointerTypes.Touch) ||
|
|
2342
|
+
(thisEventKey.startsWith('Mouse') &&
|
|
2343
|
+
pointerType === PointerTypes.Mouse)) {
|
|
2344
|
+
pointerType = null;
|
|
2345
|
+
}
|
|
2346
|
+
}
|
|
2347
|
+
else if (MouseInteractions[eventKey] === MouseInteractions.Click) {
|
|
2348
|
+
pointerType = currentPointerType;
|
|
2349
|
+
currentPointerType = null;
|
|
2350
|
+
}
|
|
2351
|
+
const e = legacy_isTouchEvent(event) ? event.changedTouches[0] : event;
|
|
1942
2352
|
if (!e) {
|
|
1943
2353
|
return;
|
|
1944
2354
|
}
|
|
1945
2355
|
const id = mirror.getId(target);
|
|
1946
2356
|
const { clientX, clientY } = e;
|
|
1947
|
-
callbackWrapper(mouseInteractionCb)({
|
|
1948
|
-
type: MouseInteractions[eventKey],
|
|
1949
|
-
id,
|
|
1950
|
-
x: clientX,
|
|
1951
|
-
y: clientY,
|
|
1952
|
-
});
|
|
2357
|
+
callbackWrapper(mouseInteractionCb)(Object.assign({ type: MouseInteractions[thisEventKey], id, x: clientX, y: clientY }, (pointerType !== null && { pointerType })));
|
|
1953
2358
|
};
|
|
1954
2359
|
};
|
|
1955
2360
|
Object.keys(MouseInteractions)
|
|
@@ -1957,8 +2362,19 @@ function initMouseInteractionObserver({ mouseInteractionCb, doc, mirror, blockCl
|
|
|
1957
2362
|
!key.endsWith('_Departed') &&
|
|
1958
2363
|
disableMap[key] !== false)
|
|
1959
2364
|
.forEach((eventKey) => {
|
|
1960
|
-
|
|
1961
|
-
const handler =
|
|
2365
|
+
let eventName = toLowerCase(eventKey);
|
|
2366
|
+
const handler = getHandler(eventKey);
|
|
2367
|
+
if (window.PointerEvent) {
|
|
2368
|
+
switch (MouseInteractions[eventKey]) {
|
|
2369
|
+
case MouseInteractions.MouseDown:
|
|
2370
|
+
case MouseInteractions.MouseUp:
|
|
2371
|
+
eventName = eventName.replace('mouse', 'pointer');
|
|
2372
|
+
break;
|
|
2373
|
+
case MouseInteractions.TouchStart:
|
|
2374
|
+
case MouseInteractions.TouchEnd:
|
|
2375
|
+
return;
|
|
2376
|
+
}
|
|
2377
|
+
}
|
|
1962
2378
|
handlers.push(on(eventName, handler, doc));
|
|
1963
2379
|
});
|
|
1964
2380
|
return callbackWrapper(() => {
|
|
@@ -1966,47 +2382,47 @@ function initMouseInteractionObserver({ mouseInteractionCb, doc, mirror, blockCl
|
|
|
1966
2382
|
});
|
|
1967
2383
|
}
|
|
1968
2384
|
function initScrollObserver({ scrollCb, doc, mirror, blockClass, blockSelector, unblockSelector, sampling, }) {
|
|
1969
|
-
const updatePosition = throttle$1((evt) => {
|
|
2385
|
+
const updatePosition = callbackWrapper(throttle$1(callbackWrapper((evt) => {
|
|
1970
2386
|
const target = getEventTarget(evt);
|
|
1971
2387
|
if (!target ||
|
|
1972
|
-
isBlocked(target, blockClass, blockSelector, unblockSelector)) {
|
|
2388
|
+
isBlocked(target, blockClass, blockSelector, unblockSelector, true)) {
|
|
1973
2389
|
return;
|
|
1974
2390
|
}
|
|
1975
2391
|
const id = mirror.getId(target);
|
|
1976
|
-
if (target === doc) {
|
|
1977
|
-
const
|
|
1978
|
-
|
|
2392
|
+
if (target === doc && doc.defaultView) {
|
|
2393
|
+
const scrollLeftTop = getWindowScroll(doc.defaultView);
|
|
2394
|
+
scrollCb({
|
|
1979
2395
|
id,
|
|
1980
|
-
x:
|
|
1981
|
-
y:
|
|
2396
|
+
x: scrollLeftTop.left,
|
|
2397
|
+
y: scrollLeftTop.top,
|
|
1982
2398
|
});
|
|
1983
2399
|
}
|
|
1984
2400
|
else {
|
|
1985
|
-
|
|
2401
|
+
scrollCb({
|
|
1986
2402
|
id,
|
|
1987
2403
|
x: target.scrollLeft,
|
|
1988
2404
|
y: target.scrollTop,
|
|
1989
2405
|
});
|
|
1990
2406
|
}
|
|
1991
|
-
}, sampling.scroll || 100);
|
|
1992
|
-
return on('scroll',
|
|
2407
|
+
}), sampling.scroll || 100));
|
|
2408
|
+
return on('scroll', updatePosition, doc);
|
|
1993
2409
|
}
|
|
1994
|
-
function initViewportResizeObserver({ viewportResizeCb, }) {
|
|
2410
|
+
function initViewportResizeObserver({ viewportResizeCb }, { win }) {
|
|
1995
2411
|
let lastH = -1;
|
|
1996
2412
|
let lastW = -1;
|
|
1997
|
-
const updateDimension = throttle$1(() => {
|
|
2413
|
+
const updateDimension = callbackWrapper(throttle$1(callbackWrapper(() => {
|
|
1998
2414
|
const height = getWindowHeight();
|
|
1999
2415
|
const width = getWindowWidth();
|
|
2000
2416
|
if (lastH !== height || lastW !== width) {
|
|
2001
|
-
|
|
2417
|
+
viewportResizeCb({
|
|
2002
2418
|
width: Number(width),
|
|
2003
2419
|
height: Number(height),
|
|
2004
2420
|
});
|
|
2005
2421
|
lastH = height;
|
|
2006
2422
|
lastW = width;
|
|
2007
2423
|
}
|
|
2008
|
-
}, 200);
|
|
2009
|
-
return on('resize',
|
|
2424
|
+
}), 200));
|
|
2425
|
+
return on('resize', updateDimension, win);
|
|
2010
2426
|
}
|
|
2011
2427
|
function wrapEventWithUserTriggeredFlag(v, enable) {
|
|
2012
2428
|
const value = Object.assign({}, v);
|
|
@@ -2016,47 +2432,42 @@ function wrapEventWithUserTriggeredFlag(v, enable) {
|
|
|
2016
2432
|
}
|
|
2017
2433
|
const INPUT_TAGS = ['INPUT', 'TEXTAREA', 'SELECT'];
|
|
2018
2434
|
const lastInputValueMap = new WeakMap();
|
|
2019
|
-
function initInputObserver({ inputCb, doc, mirror, blockClass, blockSelector, unblockSelector, ignoreClass, ignoreSelector,
|
|
2435
|
+
function initInputObserver({ inputCb, doc, mirror, blockClass, blockSelector, unblockSelector, ignoreClass, ignoreSelector, maskInputOptions, maskInputFn, sampling, userTriggeredOnInput, maskTextClass, unmaskTextClass, maskTextSelector, unmaskTextSelector, }) {
|
|
2020
2436
|
function eventHandler(event) {
|
|
2021
2437
|
let target = getEventTarget(event);
|
|
2022
|
-
const tagName = target && target.tagName;
|
|
2023
2438
|
const userTriggered = event.isTrusted;
|
|
2439
|
+
const tagName = target && toUpperCase(target.tagName);
|
|
2024
2440
|
if (tagName === 'OPTION')
|
|
2025
2441
|
target = target.parentElement;
|
|
2026
2442
|
if (!target ||
|
|
2027
2443
|
!tagName ||
|
|
2028
2444
|
INPUT_TAGS.indexOf(tagName) < 0 ||
|
|
2029
|
-
isBlocked(target, blockClass, blockSelector, unblockSelector)) {
|
|
2445
|
+
isBlocked(target, blockClass, blockSelector, unblockSelector, true)) {
|
|
2030
2446
|
return;
|
|
2031
2447
|
}
|
|
2032
2448
|
const el = target;
|
|
2033
|
-
const type = getInputType(el);
|
|
2034
2449
|
if (el.classList.contains(ignoreClass) ||
|
|
2035
2450
|
(ignoreSelector && el.matches(ignoreSelector))) {
|
|
2036
2451
|
return;
|
|
2037
2452
|
}
|
|
2453
|
+
const type = getInputType(target);
|
|
2038
2454
|
let text = getInputValue(el, tagName, type);
|
|
2039
2455
|
let isChecked = false;
|
|
2040
|
-
|
|
2041
|
-
isChecked = target.checked;
|
|
2042
|
-
}
|
|
2043
|
-
if (hasInputMaskOptions({
|
|
2456
|
+
const isInputMasked = shouldMaskInput({
|
|
2044
2457
|
maskInputOptions,
|
|
2045
|
-
maskInputSelector,
|
|
2046
2458
|
tagName,
|
|
2047
2459
|
type,
|
|
2048
|
-
})
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
maskInputSelector,
|
|
2053
|
-
unmaskInputSelector,
|
|
2054
|
-
tagName,
|
|
2055
|
-
type,
|
|
2056
|
-
value: text,
|
|
2057
|
-
maskInputFn,
|
|
2058
|
-
});
|
|
2460
|
+
});
|
|
2461
|
+
const forceMask = needMaskingText(target, maskTextClass, maskTextSelector, unmaskTextClass, unmaskTextSelector, isInputMasked);
|
|
2462
|
+
if (type === 'radio' || type === 'checkbox') {
|
|
2463
|
+
isChecked = target.checked;
|
|
2059
2464
|
}
|
|
2465
|
+
text = maskInputValue({
|
|
2466
|
+
isMasked: forceMask,
|
|
2467
|
+
element: target,
|
|
2468
|
+
value: text,
|
|
2469
|
+
maskInputFn,
|
|
2470
|
+
});
|
|
2060
2471
|
cbWithDedup(target, callbackWrapper(wrapEventWithUserTriggeredFlag)({ text, isChecked, userTriggered }, userTriggeredOnInput));
|
|
2061
2472
|
const name = target.name;
|
|
2062
2473
|
if (type === 'radio' && name && isChecked) {
|
|
@@ -2065,12 +2476,8 @@ function initInputObserver({ inputCb, doc, mirror, blockClass, blockSelector, un
|
|
|
2065
2476
|
.forEach((el) => {
|
|
2066
2477
|
if (el !== target) {
|
|
2067
2478
|
const text = maskInputValue({
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
maskInputSelector,
|
|
2071
|
-
unmaskInputSelector,
|
|
2072
|
-
tagName,
|
|
2073
|
-
type,
|
|
2479
|
+
isMasked: forceMask,
|
|
2480
|
+
element: el,
|
|
2074
2481
|
value: getInputValue(el, tagName, type),
|
|
2075
2482
|
maskInputFn,
|
|
2076
2483
|
});
|
|
@@ -2090,26 +2497,35 @@ function initInputObserver({ inputCb, doc, mirror, blockClass, blockSelector, un
|
|
|
2090
2497
|
lastInputValue.isChecked !== v.isChecked) {
|
|
2091
2498
|
lastInputValueMap.set(target, v);
|
|
2092
2499
|
const id = mirror.getId(target);
|
|
2093
|
-
inputCb(Object.assign(Object.assign({}, v), { id }));
|
|
2500
|
+
callbackWrapper(inputCb)(Object.assign(Object.assign({}, v), { id }));
|
|
2094
2501
|
}
|
|
2095
2502
|
}
|
|
2096
2503
|
const events = sampling.input === 'last' ? ['change'] : ['input', 'change'];
|
|
2097
2504
|
const handlers = events.map((eventName) => on(eventName, callbackWrapper(eventHandler), doc));
|
|
2098
|
-
const
|
|
2505
|
+
const currentWindow = doc.defaultView;
|
|
2506
|
+
if (!currentWindow) {
|
|
2507
|
+
return () => {
|
|
2508
|
+
handlers.forEach((h) => h());
|
|
2509
|
+
};
|
|
2510
|
+
}
|
|
2511
|
+
const propertyDescriptor = currentWindow.Object.getOwnPropertyDescriptor(currentWindow.HTMLInputElement.prototype, 'value');
|
|
2099
2512
|
const hookProperties = [
|
|
2100
|
-
[HTMLInputElement.prototype, 'value'],
|
|
2101
|
-
[HTMLInputElement.prototype, 'checked'],
|
|
2102
|
-
[HTMLSelectElement.prototype, 'value'],
|
|
2103
|
-
[HTMLTextAreaElement.prototype, 'value'],
|
|
2104
|
-
[HTMLSelectElement.prototype, 'selectedIndex'],
|
|
2105
|
-
[HTMLOptionElement.prototype, 'selected'],
|
|
2513
|
+
[currentWindow.HTMLInputElement.prototype, 'value'],
|
|
2514
|
+
[currentWindow.HTMLInputElement.prototype, 'checked'],
|
|
2515
|
+
[currentWindow.HTMLSelectElement.prototype, 'value'],
|
|
2516
|
+
[currentWindow.HTMLTextAreaElement.prototype, 'value'],
|
|
2517
|
+
[currentWindow.HTMLSelectElement.prototype, 'selectedIndex'],
|
|
2518
|
+
[currentWindow.HTMLOptionElement.prototype, 'selected'],
|
|
2106
2519
|
];
|
|
2107
2520
|
if (propertyDescriptor && propertyDescriptor.set) {
|
|
2108
2521
|
handlers.push(...hookProperties.map((p) => hookSetter(p[0], p[1], {
|
|
2109
2522
|
set() {
|
|
2110
|
-
callbackWrapper(eventHandler)({
|
|
2523
|
+
callbackWrapper(eventHandler)({
|
|
2524
|
+
target: this,
|
|
2525
|
+
isTrusted: false,
|
|
2526
|
+
});
|
|
2111
2527
|
},
|
|
2112
|
-
})));
|
|
2528
|
+
}, false, currentWindow)));
|
|
2113
2529
|
}
|
|
2114
2530
|
return callbackWrapper(() => {
|
|
2115
2531
|
handlers.forEach((h) => h());
|
|
@@ -2130,7 +2546,7 @@ function getNestedCSSRulePositions(rule) {
|
|
|
2130
2546
|
const index = rules.indexOf(childRule);
|
|
2131
2547
|
pos.unshift(index);
|
|
2132
2548
|
}
|
|
2133
|
-
else {
|
|
2549
|
+
else if (childRule.parentStyleSheet) {
|
|
2134
2550
|
const rules = Array.from(childRule.parentStyleSheet.cssRules);
|
|
2135
2551
|
const index = rules.indexOf(childRule);
|
|
2136
2552
|
pos.unshift(index);
|
|
@@ -2139,18 +2555,33 @@ function getNestedCSSRulePositions(rule) {
|
|
|
2139
2555
|
}
|
|
2140
2556
|
return recurse(rule, positions);
|
|
2141
2557
|
}
|
|
2142
|
-
function
|
|
2558
|
+
function getIdAndStyleId(sheet, mirror, styleMirror) {
|
|
2559
|
+
let id, styleId;
|
|
2560
|
+
if (!sheet)
|
|
2561
|
+
return {};
|
|
2562
|
+
if (sheet.ownerNode)
|
|
2563
|
+
id = mirror.getId(sheet.ownerNode);
|
|
2564
|
+
else
|
|
2565
|
+
styleId = styleMirror.getId(sheet);
|
|
2566
|
+
return {
|
|
2567
|
+
styleId,
|
|
2568
|
+
id,
|
|
2569
|
+
};
|
|
2570
|
+
}
|
|
2571
|
+
function initStyleSheetObserver({ styleSheetRuleCb, mirror, stylesheetManager }, { win }) {
|
|
2143
2572
|
if (!win.CSSStyleSheet || !win.CSSStyleSheet.prototype) {
|
|
2144
|
-
return () => {
|
|
2573
|
+
return () => {
|
|
2574
|
+
};
|
|
2145
2575
|
}
|
|
2146
2576
|
const insertRule = win.CSSStyleSheet.prototype.insertRule;
|
|
2147
2577
|
win.CSSStyleSheet.prototype.insertRule = new Proxy(insertRule, {
|
|
2148
2578
|
apply: callbackWrapper((target, thisArg, argumentsList) => {
|
|
2149
2579
|
const [rule, index] = argumentsList;
|
|
2150
|
-
const id =
|
|
2151
|
-
if (id !== -1) {
|
|
2580
|
+
const { id, styleId } = getIdAndStyleId(thisArg, mirror, stylesheetManager.styleMirror);
|
|
2581
|
+
if ((id && id !== -1) || (styleId && styleId !== -1)) {
|
|
2152
2582
|
styleSheetRuleCb({
|
|
2153
2583
|
id,
|
|
2584
|
+
styleId,
|
|
2154
2585
|
adds: [{ rule, index }],
|
|
2155
2586
|
});
|
|
2156
2587
|
}
|
|
@@ -2161,16 +2592,53 @@ function initStyleSheetObserver({ styleSheetRuleCb, mirror }, { win }) {
|
|
|
2161
2592
|
win.CSSStyleSheet.prototype.deleteRule = new Proxy(deleteRule, {
|
|
2162
2593
|
apply: callbackWrapper((target, thisArg, argumentsList) => {
|
|
2163
2594
|
const [index] = argumentsList;
|
|
2164
|
-
const id =
|
|
2165
|
-
if (id !== -1) {
|
|
2595
|
+
const { id, styleId } = getIdAndStyleId(thisArg, mirror, stylesheetManager.styleMirror);
|
|
2596
|
+
if ((id && id !== -1) || (styleId && styleId !== -1)) {
|
|
2166
2597
|
styleSheetRuleCb({
|
|
2167
2598
|
id,
|
|
2599
|
+
styleId,
|
|
2168
2600
|
removes: [{ index }],
|
|
2169
2601
|
});
|
|
2170
2602
|
}
|
|
2171
2603
|
return target.apply(thisArg, argumentsList);
|
|
2172
2604
|
}),
|
|
2173
2605
|
});
|
|
2606
|
+
let replace;
|
|
2607
|
+
if (win.CSSStyleSheet.prototype.replace) {
|
|
2608
|
+
replace = win.CSSStyleSheet.prototype.replace;
|
|
2609
|
+
win.CSSStyleSheet.prototype.replace = new Proxy(replace, {
|
|
2610
|
+
apply: callbackWrapper((target, thisArg, argumentsList) => {
|
|
2611
|
+
const [text] = argumentsList;
|
|
2612
|
+
const { id, styleId } = getIdAndStyleId(thisArg, mirror, stylesheetManager.styleMirror);
|
|
2613
|
+
if ((id && id !== -1) || (styleId && styleId !== -1)) {
|
|
2614
|
+
styleSheetRuleCb({
|
|
2615
|
+
id,
|
|
2616
|
+
styleId,
|
|
2617
|
+
replace: text,
|
|
2618
|
+
});
|
|
2619
|
+
}
|
|
2620
|
+
return target.apply(thisArg, argumentsList);
|
|
2621
|
+
}),
|
|
2622
|
+
});
|
|
2623
|
+
}
|
|
2624
|
+
let replaceSync;
|
|
2625
|
+
if (win.CSSStyleSheet.prototype.replaceSync) {
|
|
2626
|
+
replaceSync = win.CSSStyleSheet.prototype.replaceSync;
|
|
2627
|
+
win.CSSStyleSheet.prototype.replaceSync = new Proxy(replaceSync, {
|
|
2628
|
+
apply: callbackWrapper((target, thisArg, argumentsList) => {
|
|
2629
|
+
const [text] = argumentsList;
|
|
2630
|
+
const { id, styleId } = getIdAndStyleId(thisArg, mirror, stylesheetManager.styleMirror);
|
|
2631
|
+
if ((id && id !== -1) || (styleId && styleId !== -1)) {
|
|
2632
|
+
styleSheetRuleCb({
|
|
2633
|
+
id,
|
|
2634
|
+
styleId,
|
|
2635
|
+
replaceSync: text,
|
|
2636
|
+
});
|
|
2637
|
+
}
|
|
2638
|
+
return target.apply(thisArg, argumentsList);
|
|
2639
|
+
}),
|
|
2640
|
+
});
|
|
2641
|
+
}
|
|
2174
2642
|
const supportedNestedCSSRuleTypes = {};
|
|
2175
2643
|
if (canMonkeyPatchNestedCSSRule('CSSGroupingRule')) {
|
|
2176
2644
|
supportedNestedCSSRuleTypes.CSSGroupingRule = win.CSSGroupingRule;
|
|
@@ -2195,10 +2663,11 @@ function initStyleSheetObserver({ styleSheetRuleCb, mirror }, { win }) {
|
|
|
2195
2663
|
type.prototype.insertRule = new Proxy(unmodifiedFunctions[typeKey].insertRule, {
|
|
2196
2664
|
apply: callbackWrapper((target, thisArg, argumentsList) => {
|
|
2197
2665
|
const [rule, index] = argumentsList;
|
|
2198
|
-
const id =
|
|
2199
|
-
if (id !== -1) {
|
|
2666
|
+
const { id, styleId } = getIdAndStyleId(thisArg.parentStyleSheet, mirror, stylesheetManager.styleMirror);
|
|
2667
|
+
if ((id && id !== -1) || (styleId && styleId !== -1)) {
|
|
2200
2668
|
styleSheetRuleCb({
|
|
2201
2669
|
id,
|
|
2670
|
+
styleId,
|
|
2202
2671
|
adds: [
|
|
2203
2672
|
{
|
|
2204
2673
|
rule,
|
|
@@ -2216,10 +2685,11 @@ function initStyleSheetObserver({ styleSheetRuleCb, mirror }, { win }) {
|
|
|
2216
2685
|
type.prototype.deleteRule = new Proxy(unmodifiedFunctions[typeKey].deleteRule, {
|
|
2217
2686
|
apply: callbackWrapper((target, thisArg, argumentsList) => {
|
|
2218
2687
|
const [index] = argumentsList;
|
|
2219
|
-
const id =
|
|
2220
|
-
if (id !== -1) {
|
|
2688
|
+
const { id, styleId } = getIdAndStyleId(thisArg.parentStyleSheet, mirror, stylesheetManager.styleMirror);
|
|
2689
|
+
if ((id && id !== -1) || (styleId && styleId !== -1)) {
|
|
2221
2690
|
styleSheetRuleCb({
|
|
2222
2691
|
id,
|
|
2692
|
+
styleId,
|
|
2223
2693
|
removes: [
|
|
2224
2694
|
{ index: [...getNestedCSSRulePositions(thisArg), index] },
|
|
2225
2695
|
],
|
|
@@ -2232,22 +2702,74 @@ function initStyleSheetObserver({ styleSheetRuleCb, mirror }, { win }) {
|
|
|
2232
2702
|
return callbackWrapper(() => {
|
|
2233
2703
|
win.CSSStyleSheet.prototype.insertRule = insertRule;
|
|
2234
2704
|
win.CSSStyleSheet.prototype.deleteRule = deleteRule;
|
|
2705
|
+
replace && (win.CSSStyleSheet.prototype.replace = replace);
|
|
2706
|
+
replaceSync && (win.CSSStyleSheet.prototype.replaceSync = replaceSync);
|
|
2235
2707
|
Object.entries(supportedNestedCSSRuleTypes).forEach(([typeKey, type]) => {
|
|
2236
2708
|
type.prototype.insertRule = unmodifiedFunctions[typeKey].insertRule;
|
|
2237
2709
|
type.prototype.deleteRule = unmodifiedFunctions[typeKey].deleteRule;
|
|
2238
2710
|
});
|
|
2239
2711
|
});
|
|
2240
2712
|
}
|
|
2241
|
-
function
|
|
2713
|
+
function initAdoptedStyleSheetObserver({ mirror, stylesheetManager, }, host) {
|
|
2714
|
+
var _a, _b, _c;
|
|
2715
|
+
let hostId = null;
|
|
2716
|
+
if (host.nodeName === '#document')
|
|
2717
|
+
hostId = mirror.getId(host);
|
|
2718
|
+
else
|
|
2719
|
+
hostId = mirror.getId(host.host);
|
|
2720
|
+
const patchTarget = host.nodeName === '#document'
|
|
2721
|
+
? (_a = host.defaultView) === null || _a === void 0 ? void 0 : _a.Document
|
|
2722
|
+
: (_c = (_b = host.ownerDocument) === null || _b === void 0 ? void 0 : _b.defaultView) === null || _c === void 0 ? void 0 : _c.ShadowRoot;
|
|
2723
|
+
const originalPropertyDescriptor = Object.getOwnPropertyDescriptor(patchTarget === null || patchTarget === void 0 ? void 0 : patchTarget.prototype, 'adoptedStyleSheets');
|
|
2724
|
+
if (hostId === null ||
|
|
2725
|
+
hostId === -1 ||
|
|
2726
|
+
!patchTarget ||
|
|
2727
|
+
!originalPropertyDescriptor)
|
|
2728
|
+
return () => {
|
|
2729
|
+
};
|
|
2730
|
+
Object.defineProperty(host, 'adoptedStyleSheets', {
|
|
2731
|
+
configurable: originalPropertyDescriptor.configurable,
|
|
2732
|
+
enumerable: originalPropertyDescriptor.enumerable,
|
|
2733
|
+
get() {
|
|
2734
|
+
var _a;
|
|
2735
|
+
return (_a = originalPropertyDescriptor.get) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
2736
|
+
},
|
|
2737
|
+
set(sheets) {
|
|
2738
|
+
var _a;
|
|
2739
|
+
const result = (_a = originalPropertyDescriptor.set) === null || _a === void 0 ? void 0 : _a.call(this, sheets);
|
|
2740
|
+
if (hostId !== null && hostId !== -1) {
|
|
2741
|
+
try {
|
|
2742
|
+
stylesheetManager.adoptStyleSheets(sheets, hostId);
|
|
2743
|
+
}
|
|
2744
|
+
catch (e) {
|
|
2745
|
+
}
|
|
2746
|
+
}
|
|
2747
|
+
return result;
|
|
2748
|
+
},
|
|
2749
|
+
});
|
|
2750
|
+
return callbackWrapper(() => {
|
|
2751
|
+
Object.defineProperty(host, 'adoptedStyleSheets', {
|
|
2752
|
+
configurable: originalPropertyDescriptor.configurable,
|
|
2753
|
+
enumerable: originalPropertyDescriptor.enumerable,
|
|
2754
|
+
get: originalPropertyDescriptor.get,
|
|
2755
|
+
set: originalPropertyDescriptor.set,
|
|
2756
|
+
});
|
|
2757
|
+
});
|
|
2758
|
+
}
|
|
2759
|
+
function initStyleDeclarationObserver({ styleDeclarationCb, mirror, ignoreCSSAttributes, stylesheetManager, }, { win }) {
|
|
2242
2760
|
const setProperty = win.CSSStyleDeclaration.prototype.setProperty;
|
|
2243
2761
|
win.CSSStyleDeclaration.prototype.setProperty = new Proxy(setProperty, {
|
|
2244
2762
|
apply: callbackWrapper((target, thisArg, argumentsList) => {
|
|
2245
|
-
var _a
|
|
2763
|
+
var _a;
|
|
2246
2764
|
const [property, value, priority] = argumentsList;
|
|
2247
|
-
|
|
2248
|
-
|
|
2765
|
+
if (ignoreCSSAttributes.has(property)) {
|
|
2766
|
+
return setProperty.apply(thisArg, [property, value, priority]);
|
|
2767
|
+
}
|
|
2768
|
+
const { id, styleId } = getIdAndStyleId((_a = thisArg.parentRule) === null || _a === void 0 ? void 0 : _a.parentStyleSheet, mirror, stylesheetManager.styleMirror);
|
|
2769
|
+
if ((id && id !== -1) || (styleId && styleId !== -1)) {
|
|
2249
2770
|
styleDeclarationCb({
|
|
2250
2771
|
id,
|
|
2772
|
+
styleId,
|
|
2251
2773
|
set: {
|
|
2252
2774
|
property,
|
|
2253
2775
|
value,
|
|
@@ -2262,12 +2784,16 @@ function initStyleDeclarationObserver({ styleDeclarationCb, mirror }, { win }) {
|
|
|
2262
2784
|
const removeProperty = win.CSSStyleDeclaration.prototype.removeProperty;
|
|
2263
2785
|
win.CSSStyleDeclaration.prototype.removeProperty = new Proxy(removeProperty, {
|
|
2264
2786
|
apply: callbackWrapper((target, thisArg, argumentsList) => {
|
|
2265
|
-
var _a
|
|
2787
|
+
var _a;
|
|
2266
2788
|
const [property] = argumentsList;
|
|
2267
|
-
|
|
2268
|
-
|
|
2789
|
+
if (ignoreCSSAttributes.has(property)) {
|
|
2790
|
+
return removeProperty.apply(thisArg, [property]);
|
|
2791
|
+
}
|
|
2792
|
+
const { id, styleId } = getIdAndStyleId((_a = thisArg.parentRule) === null || _a === void 0 ? void 0 : _a.parentStyleSheet, mirror, stylesheetManager.styleMirror);
|
|
2793
|
+
if ((id && id !== -1) || (styleId && styleId !== -1)) {
|
|
2269
2794
|
styleDeclarationCb({
|
|
2270
2795
|
id,
|
|
2796
|
+
styleId,
|
|
2271
2797
|
remove: {
|
|
2272
2798
|
property,
|
|
2273
2799
|
},
|
|
@@ -2282,27 +2808,29 @@ function initStyleDeclarationObserver({ styleDeclarationCb, mirror }, { win }) {
|
|
|
2282
2808
|
win.CSSStyleDeclaration.prototype.removeProperty = removeProperty;
|
|
2283
2809
|
});
|
|
2284
2810
|
}
|
|
2285
|
-
function initMediaInteractionObserver({ mediaInteractionCb, blockClass, blockSelector, unblockSelector, mirror, sampling, }) {
|
|
2286
|
-
const handler = (type) => throttle$1(callbackWrapper((event) => {
|
|
2811
|
+
function initMediaInteractionObserver({ mediaInteractionCb, blockClass, blockSelector, unblockSelector, mirror, sampling, doc, }) {
|
|
2812
|
+
const handler = callbackWrapper((type) => throttle$1(callbackWrapper((event) => {
|
|
2287
2813
|
const target = getEventTarget(event);
|
|
2288
2814
|
if (!target ||
|
|
2289
|
-
isBlocked(target, blockClass, blockSelector, unblockSelector)) {
|
|
2815
|
+
isBlocked(target, blockClass, blockSelector, unblockSelector, true)) {
|
|
2290
2816
|
return;
|
|
2291
2817
|
}
|
|
2292
|
-
const { currentTime, volume, muted } = target;
|
|
2818
|
+
const { currentTime, volume, muted, playbackRate } = target;
|
|
2293
2819
|
mediaInteractionCb({
|
|
2294
2820
|
type,
|
|
2295
2821
|
id: mirror.getId(target),
|
|
2296
2822
|
currentTime,
|
|
2297
2823
|
volume,
|
|
2298
2824
|
muted,
|
|
2825
|
+
playbackRate,
|
|
2299
2826
|
});
|
|
2300
|
-
}), sampling.media || 500);
|
|
2827
|
+
}), sampling.media || 500));
|
|
2301
2828
|
const handlers = [
|
|
2302
|
-
on('play', handler(0)),
|
|
2303
|
-
on('pause', handler(1)),
|
|
2304
|
-
on('seeked', handler(2)),
|
|
2305
|
-
on('volumechange', handler(3)),
|
|
2829
|
+
on('play', handler(0), doc),
|
|
2830
|
+
on('pause', handler(1), doc),
|
|
2831
|
+
on('seeked', handler(2), doc),
|
|
2832
|
+
on('volumechange', handler(3), doc),
|
|
2833
|
+
on('ratechange', handler(4), doc),
|
|
2306
2834
|
];
|
|
2307
2835
|
return callbackWrapper(() => {
|
|
2308
2836
|
handlers.forEach((h) => h());
|
|
@@ -2311,7 +2839,8 @@ function initMediaInteractionObserver({ mediaInteractionCb, blockClass, blockSel
|
|
|
2311
2839
|
function initFontObserver({ fontCb, doc }) {
|
|
2312
2840
|
const win = doc.defaultView;
|
|
2313
2841
|
if (!win) {
|
|
2314
|
-
return () => {
|
|
2842
|
+
return () => {
|
|
2843
|
+
};
|
|
2315
2844
|
}
|
|
2316
2845
|
const handlers = [];
|
|
2317
2846
|
const fontMap = new WeakMap();
|
|
@@ -2324,20 +2853,19 @@ function initFontObserver({ fontCb, doc }) {
|
|
|
2324
2853
|
descriptors,
|
|
2325
2854
|
fontSource: typeof source === 'string'
|
|
2326
2855
|
? source
|
|
2327
|
-
:
|
|
2328
|
-
JSON.stringify(Array.from(new Uint8Array(source))),
|
|
2856
|
+
: JSON.stringify(Array.from(new Uint8Array(source))),
|
|
2329
2857
|
});
|
|
2330
2858
|
return fontFace;
|
|
2331
2859
|
};
|
|
2332
2860
|
const restoreHandler = patch(doc.fonts, 'add', function (original) {
|
|
2333
2861
|
return function (fontFace) {
|
|
2334
|
-
setTimeout(() => {
|
|
2862
|
+
setTimeout(callbackWrapper(() => {
|
|
2335
2863
|
const p = fontMap.get(fontFace);
|
|
2336
2864
|
if (p) {
|
|
2337
2865
|
fontCb(p);
|
|
2338
2866
|
fontMap.delete(fontFace);
|
|
2339
2867
|
}
|
|
2340
|
-
}, 0);
|
|
2868
|
+
}), 0);
|
|
2341
2869
|
return original.apply(this, [fontFace]);
|
|
2342
2870
|
};
|
|
2343
2871
|
});
|
|
@@ -2349,8 +2877,59 @@ function initFontObserver({ fontCb, doc }) {
|
|
|
2349
2877
|
handlers.forEach((h) => h());
|
|
2350
2878
|
});
|
|
2351
2879
|
}
|
|
2880
|
+
function initSelectionObserver(param) {
|
|
2881
|
+
const { doc, mirror, blockClass, blockSelector, unblockSelector, selectionCb, } = param;
|
|
2882
|
+
let collapsed = true;
|
|
2883
|
+
const updateSelection = callbackWrapper(() => {
|
|
2884
|
+
const selection = doc.getSelection();
|
|
2885
|
+
if (!selection || (collapsed && (selection === null || selection === void 0 ? void 0 : selection.isCollapsed)))
|
|
2886
|
+
return;
|
|
2887
|
+
collapsed = selection.isCollapsed || false;
|
|
2888
|
+
const ranges = [];
|
|
2889
|
+
const count = selection.rangeCount || 0;
|
|
2890
|
+
for (let i = 0; i < count; i++) {
|
|
2891
|
+
const range = selection.getRangeAt(i);
|
|
2892
|
+
const { startContainer, startOffset, endContainer, endOffset } = range;
|
|
2893
|
+
const blocked = isBlocked(startContainer, blockClass, blockSelector, unblockSelector, true) ||
|
|
2894
|
+
isBlocked(endContainer, blockClass, blockSelector, unblockSelector, true);
|
|
2895
|
+
if (blocked)
|
|
2896
|
+
continue;
|
|
2897
|
+
ranges.push({
|
|
2898
|
+
start: mirror.getId(startContainer),
|
|
2899
|
+
startOffset,
|
|
2900
|
+
end: mirror.getId(endContainer),
|
|
2901
|
+
endOffset,
|
|
2902
|
+
});
|
|
2903
|
+
}
|
|
2904
|
+
selectionCb({ ranges });
|
|
2905
|
+
});
|
|
2906
|
+
updateSelection();
|
|
2907
|
+
return on('selectionchange', updateSelection);
|
|
2908
|
+
}
|
|
2909
|
+
function initCustomElementObserver({ doc, customElementCb, }) {
|
|
2910
|
+
const win = doc.defaultView;
|
|
2911
|
+
if (!win || !win.customElements) {
|
|
2912
|
+
return () => {
|
|
2913
|
+
};
|
|
2914
|
+
}
|
|
2915
|
+
const restoreHandler = patch(win.customElements, 'define', function (original) {
|
|
2916
|
+
return function (name, constructor, options) {
|
|
2917
|
+
try {
|
|
2918
|
+
customElementCb({
|
|
2919
|
+
define: {
|
|
2920
|
+
name,
|
|
2921
|
+
},
|
|
2922
|
+
});
|
|
2923
|
+
}
|
|
2924
|
+
catch (e) {
|
|
2925
|
+
}
|
|
2926
|
+
return original.apply(this, [name, constructor, options]);
|
|
2927
|
+
};
|
|
2928
|
+
});
|
|
2929
|
+
return restoreHandler;
|
|
2930
|
+
}
|
|
2352
2931
|
function mergeHooks(o, hooks) {
|
|
2353
|
-
const { mutationCb, mousemoveCb, mouseInteractionCb, scrollCb, viewportResizeCb, inputCb, mediaInteractionCb, styleSheetRuleCb, styleDeclarationCb, canvasMutationCb, fontCb, } = o;
|
|
2932
|
+
const { mutationCb, mousemoveCb, mouseInteractionCb, scrollCb, viewportResizeCb, inputCb, mediaInteractionCb, styleSheetRuleCb, styleDeclarationCb, canvasMutationCb, fontCb, selectionCb, customElementCb, } = o;
|
|
2354
2933
|
o.mutationCb = (...p) => {
|
|
2355
2934
|
if (hooks.mutation) {
|
|
2356
2935
|
hooks.mutation(...p);
|
|
@@ -2417,25 +2996,46 @@ function mergeHooks(o, hooks) {
|
|
|
2417
2996
|
}
|
|
2418
2997
|
fontCb(...p);
|
|
2419
2998
|
};
|
|
2999
|
+
o.selectionCb = (...p) => {
|
|
3000
|
+
if (hooks.selection) {
|
|
3001
|
+
hooks.selection(...p);
|
|
3002
|
+
}
|
|
3003
|
+
selectionCb(...p);
|
|
3004
|
+
};
|
|
3005
|
+
o.customElementCb = (...c) => {
|
|
3006
|
+
if (hooks.customElement) {
|
|
3007
|
+
hooks.customElement(...c);
|
|
3008
|
+
}
|
|
3009
|
+
customElementCb(...c);
|
|
3010
|
+
};
|
|
2420
3011
|
}
|
|
2421
3012
|
function initObservers(o, hooks = {}) {
|
|
2422
3013
|
const currentWindow = o.doc.defaultView;
|
|
2423
3014
|
if (!currentWindow) {
|
|
2424
|
-
return () => {
|
|
3015
|
+
return () => {
|
|
3016
|
+
};
|
|
2425
3017
|
}
|
|
2426
3018
|
mergeHooks(o, hooks);
|
|
2427
3019
|
const mutationObserver = initMutationObserver(o, o.doc);
|
|
2428
3020
|
const mousemoveHandler = initMoveObserver(o);
|
|
2429
3021
|
const mouseInteractionHandler = initMouseInteractionObserver(o);
|
|
2430
3022
|
const scrollHandler = initScrollObserver(o);
|
|
2431
|
-
const viewportResizeHandler = initViewportResizeObserver(o
|
|
3023
|
+
const viewportResizeHandler = initViewportResizeObserver(o, {
|
|
3024
|
+
win: currentWindow,
|
|
3025
|
+
});
|
|
2432
3026
|
const inputHandler = initInputObserver(o);
|
|
2433
3027
|
const mediaInteractionHandler = initMediaInteractionObserver(o);
|
|
2434
3028
|
const styleSheetObserver = initStyleSheetObserver(o, { win: currentWindow });
|
|
3029
|
+
const adoptedStyleSheetObserver = initAdoptedStyleSheetObserver(o, o.doc);
|
|
2435
3030
|
const styleDeclarationObserver = initStyleDeclarationObserver(o, {
|
|
2436
3031
|
win: currentWindow,
|
|
2437
3032
|
});
|
|
2438
|
-
const fontObserver = o.collectFonts
|
|
3033
|
+
const fontObserver = o.collectFonts
|
|
3034
|
+
? initFontObserver(o)
|
|
3035
|
+
: () => {
|
|
3036
|
+
};
|
|
3037
|
+
const selectionObserver = initSelectionObserver(o);
|
|
3038
|
+
const customElementObserver = initCustomElementObserver(o);
|
|
2439
3039
|
const pluginHandlers = [];
|
|
2440
3040
|
for (const plugin of o.plugins) {
|
|
2441
3041
|
pluginHandlers.push(plugin.observer(plugin.callback, currentWindow, plugin.options));
|
|
@@ -2449,13 +3049,12 @@ function initObservers(o, hooks = {}) {
|
|
|
2449
3049
|
viewportResizeHandler();
|
|
2450
3050
|
inputHandler();
|
|
2451
3051
|
mediaInteractionHandler();
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
}
|
|
2456
|
-
catch (e) {
|
|
2457
|
-
}
|
|
3052
|
+
styleSheetObserver();
|
|
3053
|
+
adoptedStyleSheetObserver();
|
|
3054
|
+
styleDeclarationObserver();
|
|
2458
3055
|
fontObserver();
|
|
3056
|
+
selectionObserver();
|
|
3057
|
+
customElementObserver();
|
|
2459
3058
|
pluginHandlers.forEach((h) => h());
|
|
2460
3059
|
});
|
|
2461
3060
|
}
|
|
@@ -2469,13 +3068,88 @@ function canMonkeyPatchNestedCSSRule(prop) {
|
|
|
2469
3068
|
'deleteRule' in window[prop].prototype);
|
|
2470
3069
|
}
|
|
2471
3070
|
|
|
3071
|
+
class CrossOriginIframeMirror {
|
|
3072
|
+
constructor(generateIdFn) {
|
|
3073
|
+
this.generateIdFn = generateIdFn;
|
|
3074
|
+
this.iframeIdToRemoteIdMap = new WeakMap();
|
|
3075
|
+
this.iframeRemoteIdToIdMap = new WeakMap();
|
|
3076
|
+
}
|
|
3077
|
+
getId(iframe, remoteId, idToRemoteMap, remoteToIdMap) {
|
|
3078
|
+
const idToRemoteIdMap = idToRemoteMap || this.getIdToRemoteIdMap(iframe);
|
|
3079
|
+
const remoteIdToIdMap = remoteToIdMap || this.getRemoteIdToIdMap(iframe);
|
|
3080
|
+
let id = idToRemoteIdMap.get(remoteId);
|
|
3081
|
+
if (!id) {
|
|
3082
|
+
id = this.generateIdFn();
|
|
3083
|
+
idToRemoteIdMap.set(remoteId, id);
|
|
3084
|
+
remoteIdToIdMap.set(id, remoteId);
|
|
3085
|
+
}
|
|
3086
|
+
return id;
|
|
3087
|
+
}
|
|
3088
|
+
getIds(iframe, remoteId) {
|
|
3089
|
+
const idToRemoteIdMap = this.getIdToRemoteIdMap(iframe);
|
|
3090
|
+
const remoteIdToIdMap = this.getRemoteIdToIdMap(iframe);
|
|
3091
|
+
return remoteId.map((id) => this.getId(iframe, id, idToRemoteIdMap, remoteIdToIdMap));
|
|
3092
|
+
}
|
|
3093
|
+
getRemoteId(iframe, id, map) {
|
|
3094
|
+
const remoteIdToIdMap = map || this.getRemoteIdToIdMap(iframe);
|
|
3095
|
+
if (typeof id !== 'number')
|
|
3096
|
+
return id;
|
|
3097
|
+
const remoteId = remoteIdToIdMap.get(id);
|
|
3098
|
+
if (!remoteId)
|
|
3099
|
+
return -1;
|
|
3100
|
+
return remoteId;
|
|
3101
|
+
}
|
|
3102
|
+
getRemoteIds(iframe, ids) {
|
|
3103
|
+
const remoteIdToIdMap = this.getRemoteIdToIdMap(iframe);
|
|
3104
|
+
return ids.map((id) => this.getRemoteId(iframe, id, remoteIdToIdMap));
|
|
3105
|
+
}
|
|
3106
|
+
reset(iframe) {
|
|
3107
|
+
if (!iframe) {
|
|
3108
|
+
this.iframeIdToRemoteIdMap = new WeakMap();
|
|
3109
|
+
this.iframeRemoteIdToIdMap = new WeakMap();
|
|
3110
|
+
return;
|
|
3111
|
+
}
|
|
3112
|
+
this.iframeIdToRemoteIdMap.delete(iframe);
|
|
3113
|
+
this.iframeRemoteIdToIdMap.delete(iframe);
|
|
3114
|
+
}
|
|
3115
|
+
getIdToRemoteIdMap(iframe) {
|
|
3116
|
+
let idToRemoteIdMap = this.iframeIdToRemoteIdMap.get(iframe);
|
|
3117
|
+
if (!idToRemoteIdMap) {
|
|
3118
|
+
idToRemoteIdMap = new Map();
|
|
3119
|
+
this.iframeIdToRemoteIdMap.set(iframe, idToRemoteIdMap);
|
|
3120
|
+
}
|
|
3121
|
+
return idToRemoteIdMap;
|
|
3122
|
+
}
|
|
3123
|
+
getRemoteIdToIdMap(iframe) {
|
|
3124
|
+
let remoteIdToIdMap = this.iframeRemoteIdToIdMap.get(iframe);
|
|
3125
|
+
if (!remoteIdToIdMap) {
|
|
3126
|
+
remoteIdToIdMap = new Map();
|
|
3127
|
+
this.iframeRemoteIdToIdMap.set(iframe, remoteIdToIdMap);
|
|
3128
|
+
}
|
|
3129
|
+
return remoteIdToIdMap;
|
|
3130
|
+
}
|
|
3131
|
+
}
|
|
3132
|
+
|
|
2472
3133
|
class IframeManager {
|
|
2473
3134
|
constructor(options) {
|
|
2474
3135
|
this.iframes = new WeakMap();
|
|
3136
|
+
this.crossOriginIframeMap = new WeakMap();
|
|
3137
|
+
this.crossOriginIframeMirror = new CrossOriginIframeMirror(genId);
|
|
3138
|
+
this.crossOriginIframeRootIdMap = new WeakMap();
|
|
2475
3139
|
this.mutationCb = options.mutationCb;
|
|
3140
|
+
this.wrappedEmit = options.wrappedEmit;
|
|
3141
|
+
this.stylesheetManager = options.stylesheetManager;
|
|
3142
|
+
this.recordCrossOriginIframes = options.recordCrossOriginIframes;
|
|
3143
|
+
this.crossOriginIframeStyleMirror = new CrossOriginIframeMirror(this.stylesheetManager.styleMirror.generateId.bind(this.stylesheetManager.styleMirror));
|
|
3144
|
+
this.mirror = options.mirror;
|
|
3145
|
+
if (this.recordCrossOriginIframes) {
|
|
3146
|
+
window.addEventListener('message', this.handleMessage.bind(this));
|
|
3147
|
+
}
|
|
2476
3148
|
}
|
|
2477
3149
|
addIframe(iframeEl) {
|
|
2478
3150
|
this.iframes.set(iframeEl, true);
|
|
3151
|
+
if (iframeEl.contentWindow)
|
|
3152
|
+
this.crossOriginIframeMap.set(iframeEl.contentWindow, iframeEl);
|
|
2479
3153
|
}
|
|
2480
3154
|
addLoadListener(cb) {
|
|
2481
3155
|
this.loadListener = cb;
|
|
@@ -2485,7 +3159,7 @@ class IframeManager {
|
|
|
2485
3159
|
this.mutationCb({
|
|
2486
3160
|
adds: [
|
|
2487
3161
|
{
|
|
2488
|
-
parentId:
|
|
3162
|
+
parentId: this.mirror.getId(iframeEl),
|
|
2489
3163
|
nextId: null,
|
|
2490
3164
|
node: childSn,
|
|
2491
3165
|
},
|
|
@@ -2496,154 +3170,278 @@ class IframeManager {
|
|
|
2496
3170
|
isAttachIframe: true,
|
|
2497
3171
|
});
|
|
2498
3172
|
(_a = this.loadListener) === null || _a === void 0 ? void 0 : _a.call(this, iframeEl);
|
|
3173
|
+
if (iframeEl.contentDocument &&
|
|
3174
|
+
iframeEl.contentDocument.adoptedStyleSheets &&
|
|
3175
|
+
iframeEl.contentDocument.adoptedStyleSheets.length > 0)
|
|
3176
|
+
this.stylesheetManager.adoptStyleSheets(iframeEl.contentDocument.adoptedStyleSheets, this.mirror.getId(iframeEl.contentDocument));
|
|
3177
|
+
}
|
|
3178
|
+
handleMessage(message) {
|
|
3179
|
+
const crossOriginMessageEvent = message;
|
|
3180
|
+
if (crossOriginMessageEvent.data.type !== 'rrweb' ||
|
|
3181
|
+
crossOriginMessageEvent.origin !== crossOriginMessageEvent.data.origin)
|
|
3182
|
+
return;
|
|
3183
|
+
const iframeSourceWindow = message.source;
|
|
3184
|
+
if (!iframeSourceWindow)
|
|
3185
|
+
return;
|
|
3186
|
+
const iframeEl = this.crossOriginIframeMap.get(message.source);
|
|
3187
|
+
if (!iframeEl)
|
|
3188
|
+
return;
|
|
3189
|
+
const transformedEvent = this.transformCrossOriginEvent(iframeEl, crossOriginMessageEvent.data.event);
|
|
3190
|
+
if (transformedEvent)
|
|
3191
|
+
this.wrappedEmit(transformedEvent, crossOriginMessageEvent.data.isCheckout);
|
|
3192
|
+
}
|
|
3193
|
+
transformCrossOriginEvent(iframeEl, e) {
|
|
3194
|
+
var _a;
|
|
3195
|
+
switch (e.type) {
|
|
3196
|
+
case EventType.FullSnapshot: {
|
|
3197
|
+
this.crossOriginIframeMirror.reset(iframeEl);
|
|
3198
|
+
this.crossOriginIframeStyleMirror.reset(iframeEl);
|
|
3199
|
+
this.replaceIdOnNode(e.data.node, iframeEl);
|
|
3200
|
+
const rootId = e.data.node.id;
|
|
3201
|
+
this.crossOriginIframeRootIdMap.set(iframeEl, rootId);
|
|
3202
|
+
this.patchRootIdOnNode(e.data.node, rootId);
|
|
3203
|
+
return {
|
|
3204
|
+
timestamp: e.timestamp,
|
|
3205
|
+
type: EventType.IncrementalSnapshot,
|
|
3206
|
+
data: {
|
|
3207
|
+
source: IncrementalSource.Mutation,
|
|
3208
|
+
adds: [
|
|
3209
|
+
{
|
|
3210
|
+
parentId: this.mirror.getId(iframeEl),
|
|
3211
|
+
nextId: null,
|
|
3212
|
+
node: e.data.node,
|
|
3213
|
+
},
|
|
3214
|
+
],
|
|
3215
|
+
removes: [],
|
|
3216
|
+
texts: [],
|
|
3217
|
+
attributes: [],
|
|
3218
|
+
isAttachIframe: true,
|
|
3219
|
+
},
|
|
3220
|
+
};
|
|
3221
|
+
}
|
|
3222
|
+
case EventType.Meta:
|
|
3223
|
+
case EventType.Load:
|
|
3224
|
+
case EventType.DomContentLoaded: {
|
|
3225
|
+
return false;
|
|
3226
|
+
}
|
|
3227
|
+
case EventType.Plugin: {
|
|
3228
|
+
return e;
|
|
3229
|
+
}
|
|
3230
|
+
case EventType.Custom: {
|
|
3231
|
+
this.replaceIds(e.data.payload, iframeEl, ['id', 'parentId', 'previousId', 'nextId']);
|
|
3232
|
+
return e;
|
|
3233
|
+
}
|
|
3234
|
+
case EventType.IncrementalSnapshot: {
|
|
3235
|
+
switch (e.data.source) {
|
|
3236
|
+
case IncrementalSource.Mutation: {
|
|
3237
|
+
e.data.adds.forEach((n) => {
|
|
3238
|
+
this.replaceIds(n, iframeEl, [
|
|
3239
|
+
'parentId',
|
|
3240
|
+
'nextId',
|
|
3241
|
+
'previousId',
|
|
3242
|
+
]);
|
|
3243
|
+
this.replaceIdOnNode(n.node, iframeEl);
|
|
3244
|
+
const rootId = this.crossOriginIframeRootIdMap.get(iframeEl);
|
|
3245
|
+
rootId && this.patchRootIdOnNode(n.node, rootId);
|
|
3246
|
+
});
|
|
3247
|
+
e.data.removes.forEach((n) => {
|
|
3248
|
+
this.replaceIds(n, iframeEl, ['parentId', 'id']);
|
|
3249
|
+
});
|
|
3250
|
+
e.data.attributes.forEach((n) => {
|
|
3251
|
+
this.replaceIds(n, iframeEl, ['id']);
|
|
3252
|
+
});
|
|
3253
|
+
e.data.texts.forEach((n) => {
|
|
3254
|
+
this.replaceIds(n, iframeEl, ['id']);
|
|
3255
|
+
});
|
|
3256
|
+
return e;
|
|
3257
|
+
}
|
|
3258
|
+
case IncrementalSource.Drag:
|
|
3259
|
+
case IncrementalSource.TouchMove:
|
|
3260
|
+
case IncrementalSource.MouseMove: {
|
|
3261
|
+
e.data.positions.forEach((p) => {
|
|
3262
|
+
this.replaceIds(p, iframeEl, ['id']);
|
|
3263
|
+
});
|
|
3264
|
+
return e;
|
|
3265
|
+
}
|
|
3266
|
+
case IncrementalSource.ViewportResize: {
|
|
3267
|
+
return false;
|
|
3268
|
+
}
|
|
3269
|
+
case IncrementalSource.MediaInteraction:
|
|
3270
|
+
case IncrementalSource.MouseInteraction:
|
|
3271
|
+
case IncrementalSource.Scroll:
|
|
3272
|
+
case IncrementalSource.CanvasMutation:
|
|
3273
|
+
case IncrementalSource.Input: {
|
|
3274
|
+
this.replaceIds(e.data, iframeEl, ['id']);
|
|
3275
|
+
return e;
|
|
3276
|
+
}
|
|
3277
|
+
case IncrementalSource.StyleSheetRule:
|
|
3278
|
+
case IncrementalSource.StyleDeclaration: {
|
|
3279
|
+
this.replaceIds(e.data, iframeEl, ['id']);
|
|
3280
|
+
this.replaceStyleIds(e.data, iframeEl, ['styleId']);
|
|
3281
|
+
return e;
|
|
3282
|
+
}
|
|
3283
|
+
case IncrementalSource.Font: {
|
|
3284
|
+
return e;
|
|
3285
|
+
}
|
|
3286
|
+
case IncrementalSource.Selection: {
|
|
3287
|
+
e.data.ranges.forEach((range) => {
|
|
3288
|
+
this.replaceIds(range, iframeEl, ['start', 'end']);
|
|
3289
|
+
});
|
|
3290
|
+
return e;
|
|
3291
|
+
}
|
|
3292
|
+
case IncrementalSource.AdoptedStyleSheet: {
|
|
3293
|
+
this.replaceIds(e.data, iframeEl, ['id']);
|
|
3294
|
+
this.replaceStyleIds(e.data, iframeEl, ['styleIds']);
|
|
3295
|
+
(_a = e.data.styles) === null || _a === void 0 ? void 0 : _a.forEach((style) => {
|
|
3296
|
+
this.replaceStyleIds(style, iframeEl, ['styleId']);
|
|
3297
|
+
});
|
|
3298
|
+
return e;
|
|
3299
|
+
}
|
|
3300
|
+
}
|
|
3301
|
+
}
|
|
3302
|
+
}
|
|
3303
|
+
return false;
|
|
3304
|
+
}
|
|
3305
|
+
replace(iframeMirror, obj, iframeEl, keys) {
|
|
3306
|
+
for (const key of keys) {
|
|
3307
|
+
if (!Array.isArray(obj[key]) && typeof obj[key] !== 'number')
|
|
3308
|
+
continue;
|
|
3309
|
+
if (Array.isArray(obj[key])) {
|
|
3310
|
+
obj[key] = iframeMirror.getIds(iframeEl, obj[key]);
|
|
3311
|
+
}
|
|
3312
|
+
else {
|
|
3313
|
+
obj[key] = iframeMirror.getId(iframeEl, obj[key]);
|
|
3314
|
+
}
|
|
3315
|
+
}
|
|
3316
|
+
return obj;
|
|
3317
|
+
}
|
|
3318
|
+
replaceIds(obj, iframeEl, keys) {
|
|
3319
|
+
return this.replace(this.crossOriginIframeMirror, obj, iframeEl, keys);
|
|
3320
|
+
}
|
|
3321
|
+
replaceStyleIds(obj, iframeEl, keys) {
|
|
3322
|
+
return this.replace(this.crossOriginIframeStyleMirror, obj, iframeEl, keys);
|
|
3323
|
+
}
|
|
3324
|
+
replaceIdOnNode(node, iframeEl) {
|
|
3325
|
+
this.replaceIds(node, iframeEl, ['id', 'rootId']);
|
|
3326
|
+
if ('childNodes' in node) {
|
|
3327
|
+
node.childNodes.forEach((child) => {
|
|
3328
|
+
this.replaceIdOnNode(child, iframeEl);
|
|
3329
|
+
});
|
|
3330
|
+
}
|
|
3331
|
+
}
|
|
3332
|
+
patchRootIdOnNode(node, rootId) {
|
|
3333
|
+
if (node.type !== NodeType$1.Document && !node.rootId)
|
|
3334
|
+
node.rootId = rootId;
|
|
3335
|
+
if ('childNodes' in node) {
|
|
3336
|
+
node.childNodes.forEach((child) => {
|
|
3337
|
+
this.patchRootIdOnNode(child, rootId);
|
|
3338
|
+
});
|
|
3339
|
+
}
|
|
2499
3340
|
}
|
|
2500
3341
|
}
|
|
2501
3342
|
|
|
2502
3343
|
class ShadowDomManager {
|
|
2503
3344
|
constructor(options) {
|
|
2504
|
-
this.
|
|
3345
|
+
this.shadowDoms = new WeakSet();
|
|
3346
|
+
this.restoreHandlers = [];
|
|
2505
3347
|
this.mutationCb = options.mutationCb;
|
|
2506
3348
|
this.scrollCb = options.scrollCb;
|
|
2507
3349
|
this.bypassOptions = options.bypassOptions;
|
|
2508
3350
|
this.mirror = options.mirror;
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
manager.addShadowRoot(this.shadowRoot, this.ownerDocument);
|
|
2515
|
-
return shadowRoot;
|
|
2516
|
-
};
|
|
2517
|
-
}));
|
|
3351
|
+
this.init();
|
|
3352
|
+
}
|
|
3353
|
+
init() {
|
|
3354
|
+
this.reset();
|
|
3355
|
+
this.patchAttachShadow(Element, document);
|
|
2518
3356
|
}
|
|
2519
3357
|
addShadowRoot(shadowRoot, doc) {
|
|
2520
|
-
|
|
2521
|
-
|
|
3358
|
+
if (!isNativeShadowDom(shadowRoot))
|
|
3359
|
+
return;
|
|
3360
|
+
if (this.shadowDoms.has(shadowRoot))
|
|
3361
|
+
return;
|
|
3362
|
+
this.shadowDoms.add(shadowRoot);
|
|
3363
|
+
const observer = initMutationObserver(Object.assign(Object.assign({}, this.bypassOptions), { doc, mutationCb: this.mutationCb, mirror: this.mirror, shadowDomManager: this }), shadowRoot);
|
|
3364
|
+
this.restoreHandlers.push(() => observer.disconnect());
|
|
3365
|
+
this.restoreHandlers.push(initScrollObserver(Object.assign(Object.assign({}, this.bypassOptions), { scrollCb: this.scrollCb, doc: shadowRoot, mirror: this.mirror })));
|
|
3366
|
+
setTimeout(() => {
|
|
3367
|
+
if (shadowRoot.adoptedStyleSheets &&
|
|
3368
|
+
shadowRoot.adoptedStyleSheets.length > 0)
|
|
3369
|
+
this.bypassOptions.stylesheetManager.adoptStyleSheets(shadowRoot.adoptedStyleSheets, this.mirror.getId(shadowRoot.host));
|
|
3370
|
+
this.restoreHandlers.push(initAdoptedStyleSheetObserver({
|
|
3371
|
+
mirror: this.mirror,
|
|
3372
|
+
stylesheetManager: this.bypassOptions.stylesheetManager,
|
|
3373
|
+
}, shadowRoot));
|
|
3374
|
+
}, 0);
|
|
2522
3375
|
}
|
|
2523
3376
|
observeAttachShadow(iframeElement) {
|
|
2524
|
-
if (iframeElement.contentWindow)
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
3377
|
+
if (!iframeElement.contentWindow || !iframeElement.contentDocument)
|
|
3378
|
+
return;
|
|
3379
|
+
this.patchAttachShadow(iframeElement.contentWindow.Element, iframeElement.contentDocument);
|
|
3380
|
+
}
|
|
3381
|
+
patchAttachShadow(element, doc) {
|
|
3382
|
+
const manager = this;
|
|
3383
|
+
this.restoreHandlers.push(patch(element.prototype, 'attachShadow', function (original) {
|
|
3384
|
+
return function (option) {
|
|
3385
|
+
const shadowRoot = original.call(this, option);
|
|
3386
|
+
if (this.shadowRoot && inDom(this))
|
|
3387
|
+
manager.addShadowRoot(this.shadowRoot, doc);
|
|
3388
|
+
return shadowRoot;
|
|
3389
|
+
};
|
|
3390
|
+
}));
|
|
2535
3391
|
}
|
|
2536
3392
|
reset() {
|
|
2537
|
-
this.
|
|
3393
|
+
this.restoreHandlers.forEach((handler) => {
|
|
3394
|
+
try {
|
|
3395
|
+
handler();
|
|
3396
|
+
}
|
|
3397
|
+
catch (e) {
|
|
3398
|
+
}
|
|
3399
|
+
});
|
|
3400
|
+
this.restoreHandlers = [];
|
|
3401
|
+
this.shadowDoms = new WeakSet();
|
|
2538
3402
|
}
|
|
2539
3403
|
}
|
|
2540
3404
|
|
|
2541
|
-
|
|
3405
|
+
/*! *****************************************************************************
|
|
2542
3406
|
Copyright (c) Microsoft Corporation.
|
|
2543
3407
|
|
|
2544
3408
|
Permission to use, copy, modify, and/or distribute this software for any
|
|
2545
3409
|
purpose with or without fee is hereby granted.
|
|
2546
3410
|
|
|
2547
3411
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
2548
|
-
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
2549
|
-
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
2550
|
-
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
2551
|
-
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
2552
|
-
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
2553
|
-
PERFORMANCE OF THIS SOFTWARE.
|
|
2554
|
-
***************************************************************************** */
|
|
2555
|
-
|
|
2556
|
-
function __rest(s, e) {
|
|
2557
|
-
var t = {};
|
|
2558
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
2559
|
-
t[p] = s[p];
|
|
2560
|
-
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
2561
|
-
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
2562
|
-
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
2563
|
-
t[p[i]] = s[p[i]];
|
|
2564
|
-
}
|
|
2565
|
-
return t;
|
|
2566
|
-
}
|
|
2567
|
-
|
|
2568
|
-
function initCanvas2DMutationObserver(cb, win, blockClass, unblockSelector, blockSelector, mirror) {
|
|
2569
|
-
const handlers = [];
|
|
2570
|
-
const props2D = Object.getOwnPropertyNames(win.CanvasRenderingContext2D.prototype);
|
|
2571
|
-
for (const prop of props2D) {
|
|
2572
|
-
try {
|
|
2573
|
-
if (typeof win.CanvasRenderingContext2D.prototype[prop] !== 'function') {
|
|
2574
|
-
continue;
|
|
2575
|
-
}
|
|
2576
|
-
const restoreHandler = patch(win.CanvasRenderingContext2D.prototype, prop, function (original) {
|
|
2577
|
-
return function (...args) {
|
|
2578
|
-
if (!isBlocked(this.canvas, blockClass, blockSelector, unblockSelector)) {
|
|
2579
|
-
setTimeout(() => {
|
|
2580
|
-
const recordArgs = [...args];
|
|
2581
|
-
if (prop === 'drawImage') {
|
|
2582
|
-
if (recordArgs[0] &&
|
|
2583
|
-
recordArgs[0] instanceof HTMLCanvasElement) {
|
|
2584
|
-
const canvas = recordArgs[0];
|
|
2585
|
-
const ctx = canvas.getContext('2d');
|
|
2586
|
-
let imgd = ctx === null || ctx === void 0 ? void 0 : ctx.getImageData(0, 0, canvas.width, canvas.height);
|
|
2587
|
-
let pix = imgd === null || imgd === void 0 ? void 0 : imgd.data;
|
|
2588
|
-
recordArgs[0] = JSON.stringify(pix);
|
|
2589
|
-
}
|
|
2590
|
-
}
|
|
2591
|
-
cb(this.canvas, {
|
|
2592
|
-
type: CanvasContext['2D'],
|
|
2593
|
-
property: prop,
|
|
2594
|
-
args: recordArgs,
|
|
2595
|
-
});
|
|
2596
|
-
}, 0);
|
|
2597
|
-
}
|
|
2598
|
-
return original.apply(this, args);
|
|
2599
|
-
};
|
|
2600
|
-
});
|
|
2601
|
-
handlers.push(restoreHandler);
|
|
2602
|
-
}
|
|
2603
|
-
catch (_a) {
|
|
2604
|
-
const hookHandler = hookSetter(win.CanvasRenderingContext2D.prototype, prop, {
|
|
2605
|
-
set(v) {
|
|
2606
|
-
cb(this.canvas, {
|
|
2607
|
-
type: CanvasContext['2D'],
|
|
2608
|
-
property: prop,
|
|
2609
|
-
args: [v],
|
|
2610
|
-
setter: true,
|
|
2611
|
-
});
|
|
2612
|
-
},
|
|
2613
|
-
});
|
|
2614
|
-
handlers.push(hookHandler);
|
|
3412
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
3413
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
3414
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
3415
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
3416
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
3417
|
+
PERFORMANCE OF THIS SOFTWARE.
|
|
3418
|
+
***************************************************************************** */
|
|
3419
|
+
|
|
3420
|
+
function __rest(s, e) {
|
|
3421
|
+
var t = {};
|
|
3422
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
3423
|
+
t[p] = s[p];
|
|
3424
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
3425
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
3426
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
3427
|
+
t[p[i]] = s[p[i]];
|
|
2615
3428
|
}
|
|
2616
|
-
|
|
2617
|
-
return () => {
|
|
2618
|
-
handlers.forEach((h) => h());
|
|
2619
|
-
};
|
|
3429
|
+
return t;
|
|
2620
3430
|
}
|
|
2621
3431
|
|
|
2622
|
-
function
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
}
|
|
2631
|
-
return original.apply(this, [contextType, ...args]);
|
|
2632
|
-
};
|
|
2633
|
-
});
|
|
2634
|
-
handlers.push(restoreHandler);
|
|
2635
|
-
}
|
|
2636
|
-
catch (_a) {
|
|
2637
|
-
console.error('failed to patch HTMLCanvasElement.prototype.getContext');
|
|
2638
|
-
}
|
|
2639
|
-
return () => {
|
|
2640
|
-
handlers.forEach((h) => h());
|
|
2641
|
-
};
|
|
3432
|
+
function __awaiter(thisArg, _arguments, P, generator) {
|
|
3433
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3434
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
3435
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
3436
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
3437
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
3438
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
3439
|
+
});
|
|
2642
3440
|
}
|
|
2643
3441
|
|
|
2644
3442
|
/*
|
|
2645
|
-
* base64-arraybuffer 1.0.
|
|
2646
|
-
* Copyright (c)
|
|
3443
|
+
* base64-arraybuffer 1.0.1 <https://github.com/niklasvh/base64-arraybuffer>
|
|
3444
|
+
* Copyright (c) 2021 Niklas von Hertzen <https://hertzen.com>
|
|
2647
3445
|
* Released under MIT License
|
|
2648
3446
|
*/
|
|
2649
3447
|
var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
|
@@ -2669,12 +3467,12 @@ var encode = function (arraybuffer) {
|
|
|
2669
3467
|
return base64;
|
|
2670
3468
|
};
|
|
2671
3469
|
|
|
2672
|
-
const
|
|
3470
|
+
const canvasVarMap = new Map();
|
|
2673
3471
|
function variableListFor(ctx, ctor) {
|
|
2674
|
-
let contextMap =
|
|
3472
|
+
let contextMap = canvasVarMap.get(ctx);
|
|
2675
3473
|
if (!contextMap) {
|
|
2676
3474
|
contextMap = new Map();
|
|
2677
|
-
|
|
3475
|
+
canvasVarMap.set(ctx, contextMap);
|
|
2678
3476
|
}
|
|
2679
3477
|
if (!contextMap.has(ctor)) {
|
|
2680
3478
|
contextMap.set(ctor, []);
|
|
@@ -2743,6 +3541,14 @@ function serializeArg(value, win, ctx) {
|
|
|
2743
3541
|
src,
|
|
2744
3542
|
};
|
|
2745
3543
|
}
|
|
3544
|
+
else if (value instanceof HTMLCanvasElement) {
|
|
3545
|
+
const name = 'HTMLImageElement';
|
|
3546
|
+
const src = value.toDataURL();
|
|
3547
|
+
return {
|
|
3548
|
+
rr_type: name,
|
|
3549
|
+
src,
|
|
3550
|
+
};
|
|
3551
|
+
}
|
|
2746
3552
|
else if (value instanceof ImageData) {
|
|
2747
3553
|
const name = value.constructor.name;
|
|
2748
3554
|
return {
|
|
@@ -2781,10 +3587,102 @@ const isInstanceOfWebGLObject = (value, win) => {
|
|
|
2781
3587
|
return Boolean(supportedWebGLConstructorNames.find((name) => value instanceof win[name]));
|
|
2782
3588
|
};
|
|
2783
3589
|
|
|
2784
|
-
function
|
|
3590
|
+
function initCanvas2DMutationObserver(cb, win, blockClass, blockSelector, unblockSelector) {
|
|
3591
|
+
const handlers = [];
|
|
3592
|
+
const props2D = Object.getOwnPropertyNames(win.CanvasRenderingContext2D.prototype);
|
|
3593
|
+
for (const prop of props2D) {
|
|
3594
|
+
try {
|
|
3595
|
+
if (typeof win.CanvasRenderingContext2D.prototype[prop] !== 'function') {
|
|
3596
|
+
continue;
|
|
3597
|
+
}
|
|
3598
|
+
const restoreHandler = patch(win.CanvasRenderingContext2D.prototype, prop, function (original) {
|
|
3599
|
+
return function (...args) {
|
|
3600
|
+
if (!isBlocked(this.canvas, blockClass, blockSelector, unblockSelector, true)) {
|
|
3601
|
+
setTimeout(() => {
|
|
3602
|
+
const recordArgs = serializeArgs([...args], win, this);
|
|
3603
|
+
cb(this.canvas, {
|
|
3604
|
+
type: CanvasContext['2D'],
|
|
3605
|
+
property: prop,
|
|
3606
|
+
args: recordArgs,
|
|
3607
|
+
});
|
|
3608
|
+
}, 0);
|
|
3609
|
+
}
|
|
3610
|
+
return original.apply(this, args);
|
|
3611
|
+
};
|
|
3612
|
+
});
|
|
3613
|
+
handlers.push(restoreHandler);
|
|
3614
|
+
}
|
|
3615
|
+
catch (_a) {
|
|
3616
|
+
const hookHandler = hookSetter(win.CanvasRenderingContext2D.prototype, prop, {
|
|
3617
|
+
set(v) {
|
|
3618
|
+
cb(this.canvas, {
|
|
3619
|
+
type: CanvasContext['2D'],
|
|
3620
|
+
property: prop,
|
|
3621
|
+
args: [v],
|
|
3622
|
+
setter: true,
|
|
3623
|
+
});
|
|
3624
|
+
},
|
|
3625
|
+
});
|
|
3626
|
+
handlers.push(hookHandler);
|
|
3627
|
+
}
|
|
3628
|
+
}
|
|
3629
|
+
return () => {
|
|
3630
|
+
handlers.forEach((h) => h());
|
|
3631
|
+
};
|
|
3632
|
+
}
|
|
3633
|
+
|
|
3634
|
+
function getNormalizedContextName(contextType) {
|
|
3635
|
+
return contextType === 'experimental-webgl' ? 'webgl' : contextType;
|
|
3636
|
+
}
|
|
3637
|
+
function initCanvasContextObserver(win, blockClass, blockSelector, unblockSelector, setPreserveDrawingBufferToTrue) {
|
|
3638
|
+
const handlers = [];
|
|
3639
|
+
try {
|
|
3640
|
+
const restoreHandler = patch(win.HTMLCanvasElement.prototype, 'getContext', function (original) {
|
|
3641
|
+
return function (contextType, ...args) {
|
|
3642
|
+
if (!isBlocked(this, blockClass, blockSelector, unblockSelector, true)) {
|
|
3643
|
+
const ctxName = getNormalizedContextName(contextType);
|
|
3644
|
+
if (!('__context' in this))
|
|
3645
|
+
this.__context = ctxName;
|
|
3646
|
+
if (setPreserveDrawingBufferToTrue &&
|
|
3647
|
+
['webgl', 'webgl2'].includes(ctxName)) {
|
|
3648
|
+
if (args[0] && typeof args[0] === 'object') {
|
|
3649
|
+
const contextAttributes = args[0];
|
|
3650
|
+
if (!contextAttributes.preserveDrawingBuffer) {
|
|
3651
|
+
contextAttributes.preserveDrawingBuffer = true;
|
|
3652
|
+
}
|
|
3653
|
+
}
|
|
3654
|
+
else {
|
|
3655
|
+
args.splice(0, 1, {
|
|
3656
|
+
preserveDrawingBuffer: true,
|
|
3657
|
+
});
|
|
3658
|
+
}
|
|
3659
|
+
}
|
|
3660
|
+
}
|
|
3661
|
+
return original.apply(this, [contextType, ...args]);
|
|
3662
|
+
};
|
|
3663
|
+
});
|
|
3664
|
+
handlers.push(restoreHandler);
|
|
3665
|
+
}
|
|
3666
|
+
catch (_a) {
|
|
3667
|
+
console.error('failed to patch HTMLCanvasElement.prototype.getContext');
|
|
3668
|
+
}
|
|
3669
|
+
return () => {
|
|
3670
|
+
handlers.forEach((h) => h());
|
|
3671
|
+
};
|
|
3672
|
+
}
|
|
3673
|
+
|
|
3674
|
+
function patchGLPrototype(prototype, type, cb, blockClass, blockSelector, unblockSelector, mirror, win) {
|
|
2785
3675
|
const handlers = [];
|
|
2786
3676
|
const props = Object.getOwnPropertyNames(prototype);
|
|
2787
3677
|
for (const prop of props) {
|
|
3678
|
+
if ([
|
|
3679
|
+
'isContextLost',
|
|
3680
|
+
'canvas',
|
|
3681
|
+
'drawingBufferWidth',
|
|
3682
|
+
'drawingBufferHeight',
|
|
3683
|
+
].includes(prop)) {
|
|
3684
|
+
continue;
|
|
3685
|
+
}
|
|
2788
3686
|
try {
|
|
2789
3687
|
if (typeof prototype[prop] !== 'function') {
|
|
2790
3688
|
continue;
|
|
@@ -2792,10 +3690,10 @@ function patchGLPrototype(prototype, type, cb, blockClass, unblockSelector, bloc
|
|
|
2792
3690
|
const restoreHandler = patch(prototype, prop, function (original) {
|
|
2793
3691
|
return function (...args) {
|
|
2794
3692
|
const result = original.apply(this, args);
|
|
2795
|
-
saveWebGLVar(result, win,
|
|
2796
|
-
if (
|
|
2797
|
-
|
|
2798
|
-
const recordArgs = serializeArgs([...args], win,
|
|
3693
|
+
saveWebGLVar(result, win, this);
|
|
3694
|
+
if ('tagName' in this.canvas &&
|
|
3695
|
+
!isBlocked(this.canvas, blockClass, blockSelector, unblockSelector, true)) {
|
|
3696
|
+
const recordArgs = serializeArgs([...args], win, this);
|
|
2799
3697
|
const mutation = {
|
|
2800
3698
|
type,
|
|
2801
3699
|
property: prop,
|
|
@@ -2835,6 +3733,38 @@ function initCanvasWebGLMutationObserver(cb, win, blockClass, blockSelector, unb
|
|
|
2835
3733
|
};
|
|
2836
3734
|
}
|
|
2837
3735
|
|
|
3736
|
+
function decodeBase64(base64, enableUnicode) {
|
|
3737
|
+
var binaryString = atob(base64);
|
|
3738
|
+
if (enableUnicode) {
|
|
3739
|
+
var binaryView = new Uint8Array(binaryString.length);
|
|
3740
|
+
for (var i = 0, n = binaryString.length; i < n; ++i) {
|
|
3741
|
+
binaryView[i] = binaryString.charCodeAt(i);
|
|
3742
|
+
}
|
|
3743
|
+
return String.fromCharCode.apply(null, new Uint16Array(binaryView.buffer));
|
|
3744
|
+
}
|
|
3745
|
+
return binaryString;
|
|
3746
|
+
}
|
|
3747
|
+
|
|
3748
|
+
function createURL(base64, sourcemapArg, enableUnicodeArg) {
|
|
3749
|
+
var sourcemap = sourcemapArg === undefined ? null : sourcemapArg;
|
|
3750
|
+
var enableUnicode = enableUnicodeArg === undefined ? false : enableUnicodeArg;
|
|
3751
|
+
var source = decodeBase64(base64, enableUnicode);
|
|
3752
|
+
var start = source.indexOf('\n', 10) + 1;
|
|
3753
|
+
var body = source.substring(start) + (sourcemap ? '\/\/# sourceMappingURL=' + sourcemap : '');
|
|
3754
|
+
var blob = new Blob([body], { type: 'application/javascript' });
|
|
3755
|
+
return URL.createObjectURL(blob);
|
|
3756
|
+
}
|
|
3757
|
+
|
|
3758
|
+
function createBase64WorkerFactory(base64, sourcemapArg, enableUnicodeArg) {
|
|
3759
|
+
var url;
|
|
3760
|
+
return function WorkerFactory(options) {
|
|
3761
|
+
url = url || createURL(base64, sourcemapArg, enableUnicodeArg);
|
|
3762
|
+
return new Worker(url, options);
|
|
3763
|
+
};
|
|
3764
|
+
}
|
|
3765
|
+
|
|
3766
|
+
var WorkerFactory = createBase64WorkerFactory('Lyogcm9sbHVwLXBsdWdpbi13ZWItd29ya2VyLWxvYWRlciAqLwooZnVuY3Rpb24gKCkgewogICAgJ3VzZSBzdHJpY3QnOwoKICAgIC8qISAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKg0KICAgIENvcHlyaWdodCAoYykgTWljcm9zb2Z0IENvcnBvcmF0aW9uLg0KDQogICAgUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgYW5kL29yIGRpc3RyaWJ1dGUgdGhpcyBzb2Z0d2FyZSBmb3IgYW55DQogICAgcHVycG9zZSB3aXRoIG9yIHdpdGhvdXQgZmVlIGlzIGhlcmVieSBncmFudGVkLg0KDQogICAgVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUyBJUyIgQU5EIFRIRSBBVVRIT1IgRElTQ0xBSU1TIEFMTCBXQVJSQU5USUVTIFdJVEgNCiAgICBSRUdBUkQgVE8gVEhJUyBTT0ZUV0FSRSBJTkNMVURJTkcgQUxMIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkNCiAgICBBTkQgRklUTkVTUy4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUiBCRSBMSUFCTEUgRk9SIEFOWSBTUEVDSUFMLCBESVJFQ1QsDQogICAgSU5ESVJFQ1QsIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSIFJFU1VMVElORyBGUk9NDQogICAgTE9TUyBPRiBVU0UsIERBVEEgT1IgUFJPRklUUywgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIE5FR0xJR0VOQ0UgT1INCiAgICBPVEhFUiBUT1JUSU9VUyBBQ1RJT04sIEFSSVNJTkcgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SDQogICAgUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS4NCiAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiAqLw0KDQogICAgZnVuY3Rpb24gX19hd2FpdGVyKHRoaXNBcmcsIF9hcmd1bWVudHMsIFAsIGdlbmVyYXRvcikgew0KICAgICAgICBmdW5jdGlvbiBhZG9wdCh2YWx1ZSkgeyByZXR1cm4gdmFsdWUgaW5zdGFuY2VvZiBQID8gdmFsdWUgOiBuZXcgUChmdW5jdGlvbiAocmVzb2x2ZSkgeyByZXNvbHZlKHZhbHVlKTsgfSk7IH0NCiAgICAgICAgcmV0dXJuIG5ldyAoUCB8fCAoUCA9IFByb21pc2UpKShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7DQogICAgICAgICAgICBmdW5jdGlvbiBmdWxmaWxsZWQodmFsdWUpIHsgdHJ5IHsgc3RlcChnZW5lcmF0b3IubmV4dCh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9DQogICAgICAgICAgICBmdW5jdGlvbiByZWplY3RlZCh2YWx1ZSkgeyB0cnkgeyBzdGVwKGdlbmVyYXRvclsidGhyb3ciXSh2YWx1ZSkpOyB9IGNhdGNoIChlKSB7IHJlamVjdChlKTsgfSB9DQogICAgICAgICAgICBmdW5jdGlvbiBzdGVwKHJlc3VsdCkgeyByZXN1bHQuZG9uZSA/IHJlc29sdmUocmVzdWx0LnZhbHVlKSA6IGFkb3B0KHJlc3VsdC52YWx1ZSkudGhlbihmdWxmaWxsZWQsIHJlamVjdGVkKTsgfQ0KICAgICAgICAgICAgc3RlcCgoZ2VuZXJhdG9yID0gZ2VuZXJhdG9yLmFwcGx5KHRoaXNBcmcsIF9hcmd1bWVudHMgfHwgW10pKS5uZXh0KCkpOw0KICAgICAgICB9KTsNCiAgICB9CgogICAgLyoKICAgICAqIGJhc2U2NC1hcnJheWJ1ZmZlciAxLjAuMSA8aHR0cHM6Ly9naXRodWIuY29tL25pa2xhc3ZoL2Jhc2U2NC1hcnJheWJ1ZmZlcj4KICAgICAqIENvcHlyaWdodCAoYykgMjAyMSBOaWtsYXMgdm9uIEhlcnR6ZW4gPGh0dHBzOi8vaGVydHplbi5jb20+CiAgICAgKiBSZWxlYXNlZCB1bmRlciBNSVQgTGljZW5zZQogICAgICovCiAgICB2YXIgY2hhcnMgPSAnQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrLyc7CiAgICAvLyBVc2UgYSBsb29rdXAgdGFibGUgdG8gZmluZCB0aGUgaW5kZXguCiAgICB2YXIgbG9va3VwID0gdHlwZW9mIFVpbnQ4QXJyYXkgPT09ICd1bmRlZmluZWQnID8gW10gOiBuZXcgVWludDhBcnJheSgyNTYpOwogICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjaGFycy5sZW5ndGg7IGkrKykgewogICAgICAgIGxvb2t1cFtjaGFycy5jaGFyQ29kZUF0KGkpXSA9IGk7CiAgICB9CiAgICB2YXIgZW5jb2RlID0gZnVuY3Rpb24gKGFycmF5YnVmZmVyKSB7CiAgICAgICAgdmFyIGJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkoYXJyYXlidWZmZXIpLCBpLCBsZW4gPSBieXRlcy5sZW5ndGgsIGJhc2U2NCA9ICcnOwogICAgICAgIGZvciAoaSA9IDA7IGkgPCBsZW47IGkgKz0gMykgewogICAgICAgICAgICBiYXNlNjQgKz0gY2hhcnNbYnl0ZXNbaV0gPj4gMl07CiAgICAgICAgICAgIGJhc2U2NCArPSBjaGFyc1soKGJ5dGVzW2ldICYgMykgPDwgNCkgfCAoYnl0ZXNbaSArIDFdID4+IDQpXTsKICAgICAgICAgICAgYmFzZTY0ICs9IGNoYXJzWygoYnl0ZXNbaSArIDFdICYgMTUpIDw8IDIpIHwgKGJ5dGVzW2kgKyAyXSA+PiA2KV07CiAgICAgICAgICAgIGJhc2U2NCArPSBjaGFyc1tieXRlc1tpICsgMl0gJiA2M107CiAgICAgICAgfQogICAgICAgIGlmIChsZW4gJSAzID09PSAyKSB7CiAgICAgICAgICAgIGJhc2U2NCA9IGJhc2U2NC5zdWJzdHJpbmcoMCwgYmFzZTY0Lmxlbmd0aCAtIDEpICsgJz0nOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmIChsZW4gJSAzID09PSAxKSB7CiAgICAgICAgICAgIGJhc2U2NCA9IGJhc2U2NC5zdWJzdHJpbmcoMCwgYmFzZTY0Lmxlbmd0aCAtIDIpICsgJz09JzsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGJhc2U2NDsKICAgIH07CgogICAgY29uc3QgbGFzdEJsb2JNYXAgPSBuZXcgTWFwKCk7DQogICAgY29uc3QgdHJhbnNwYXJlbnRCbG9iTWFwID0gbmV3IE1hcCgpOw0KICAgIGZ1bmN0aW9uIGdldFRyYW5zcGFyZW50QmxvYkZvcih3aWR0aCwgaGVpZ2h0LCBkYXRhVVJMT3B0aW9ucykgew0KICAgICAgICByZXR1cm4gX19hd2FpdGVyKHRoaXMsIHZvaWQgMCwgdm9pZCAwLCBmdW5jdGlvbiogKCkgew0KICAgICAgICAgICAgY29uc3QgaWQgPSBgJHt3aWR0aH0tJHtoZWlnaHR9YDsNCiAgICAgICAgICAgIGlmICgnT2Zmc2NyZWVuQ2FudmFzJyBpbiBnbG9iYWxUaGlzKSB7DQogICAgICAgICAgICAgICAgaWYgKHRyYW5zcGFyZW50QmxvYk1hcC5oYXMoaWQpKQ0KICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJhbnNwYXJlbnRCbG9iTWFwLmdldChpZCk7DQogICAgICAgICAgICAgICAgY29uc3Qgb2Zmc2NyZWVuID0gbmV3IE9mZnNjcmVlbkNhbnZhcyh3aWR0aCwgaGVpZ2h0KTsNCiAgICAgICAgICAgICAgICBvZmZzY3JlZW4uZ2V0Q29udGV4dCgnMmQnKTsNCiAgICAgICAgICAgICAgICBjb25zdCBibG9iID0geWllbGQgb2Zmc2NyZWVuLmNvbnZlcnRUb0Jsb2IoZGF0YVVSTE9wdGlvbnMpOw0KICAgICAgICAgICAgICAgIGNvbnN0IGFycmF5QnVmZmVyID0geWllbGQgYmxvYi5hcnJheUJ1ZmZlcigpOw0KICAgICAgICAgICAgICAgIGNvbnN0IGJhc2U2NCA9IGVuY29kZShhcnJheUJ1ZmZlcik7DQogICAgICAgICAgICAgICAgdHJhbnNwYXJlbnRCbG9iTWFwLnNldChpZCwgYmFzZTY0KTsNCiAgICAgICAgICAgICAgICByZXR1cm4gYmFzZTY0Ow0KICAgICAgICAgICAgfQ0KICAgICAgICAgICAgZWxzZSB7DQogICAgICAgICAgICAgICAgcmV0dXJuICcnOw0KICAgICAgICAgICAgfQ0KICAgICAgICB9KTsNCiAgICB9DQogICAgY29uc3Qgd29ya2VyID0gc2VsZjsNCiAgICB3b3JrZXIub25tZXNzYWdlID0gZnVuY3Rpb24gKGUpIHsNCiAgICAgICAgcmV0dXJuIF9fYXdhaXRlcih0aGlzLCB2b2lkIDAsIHZvaWQgMCwgZnVuY3Rpb24qICgpIHsNCiAgICAgICAgICAgIGlmICgnT2Zmc2NyZWVuQ2FudmFzJyBpbiBnbG9iYWxUaGlzKSB7DQogICAgICAgICAgICAgICAgY29uc3QgeyBpZCwgYml0bWFwLCB3aWR0aCwgaGVpZ2h0LCBkYXRhVVJMT3B0aW9ucyB9ID0gZS5kYXRhOw0KICAgICAgICAgICAgICAgIGNvbnN0IHRyYW5zcGFyZW50QmFzZTY0ID0gZ2V0VHJhbnNwYXJlbnRCbG9iRm9yKHdpZHRoLCBoZWlnaHQsIGRhdGFVUkxPcHRpb25zKTsNCiAgICAgICAgICAgICAgICBjb25zdCBvZmZzY3JlZW4gPSBuZXcgT2Zmc2NyZWVuQ2FudmFzKHdpZHRoLCBoZWlnaHQpOw0KICAgICAgICAgICAgICAgIGNvbnN0IGN0eCA9IG9mZnNjcmVlbi5nZXRDb250ZXh0KCcyZCcpOw0KICAgICAgICAgICAgICAgIGN0eC5kcmF3SW1hZ2UoYml0bWFwLCAwLCAwKTsNCiAgICAgICAgICAgICAgICBiaXRtYXAuY2xvc2UoKTsNCiAgICAgICAgICAgICAgICBjb25zdCBibG9iID0geWllbGQgb2Zmc2NyZWVuLmNvbnZlcnRUb0Jsb2IoZGF0YVVSTE9wdGlvbnMpOw0KICAgICAgICAgICAgICAgIGNvbnN0IHR5cGUgPSBibG9iLnR5cGU7DQogICAgICAgICAgICAgICAgY29uc3QgYXJyYXlCdWZmZXIgPSB5aWVsZCBibG9iLmFycmF5QnVmZmVyKCk7DQogICAgICAgICAgICAgICAgY29uc3QgYmFzZTY0ID0gZW5jb2RlKGFycmF5QnVmZmVyKTsNCiAgICAgICAgICAgICAgICBpZiAoIWxhc3RCbG9iTWFwLmhhcyhpZCkgJiYgKHlpZWxkIHRyYW5zcGFyZW50QmFzZTY0KSA9PT0gYmFzZTY0KSB7DQogICAgICAgICAgICAgICAgICAgIGxhc3RCbG9iTWFwLnNldChpZCwgYmFzZTY0KTsNCiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHdvcmtlci5wb3N0TWVzc2FnZSh7IGlkIH0pOw0KICAgICAgICAgICAgICAgIH0NCiAgICAgICAgICAgICAgICBpZiAobGFzdEJsb2JNYXAuZ2V0KGlkKSA9PT0gYmFzZTY0KQ0KICAgICAgICAgICAgICAgICAgICByZXR1cm4gd29ya2VyLnBvc3RNZXNzYWdlKHsgaWQgfSk7DQogICAgICAgICAgICAgICAgd29ya2VyLnBvc3RNZXNzYWdlKHsNCiAgICAgICAgICAgICAgICAgICAgaWQsDQogICAgICAgICAgICAgICAgICAgIHR5cGUsDQogICAgICAgICAgICAgICAgICAgIGJhc2U2NCwNCiAgICAgICAgICAgICAgICAgICAgd2lkdGgsDQogICAgICAgICAgICAgICAgICAgIGhlaWdodCwNCiAgICAgICAgICAgICAgICB9KTsNCiAgICAgICAgICAgICAgICBsYXN0QmxvYk1hcC5zZXQoaWQsIGJhc2U2NCk7DQogICAgICAgICAgICB9DQogICAgICAgICAgICBlbHNlIHsNCiAgICAgICAgICAgICAgICByZXR1cm4gd29ya2VyLnBvc3RNZXNzYWdlKHsgaWQ6IGUuZGF0YS5pZCB9KTsNCiAgICAgICAgICAgIH0NCiAgICAgICAgfSk7DQogICAgfTsKCn0pKCk7Cgo=', null, false);
|
|
3767
|
+
|
|
2838
3768
|
class CanvasManager {
|
|
2839
3769
|
reset() {
|
|
2840
3770
|
this.pendingCanvasMutations.clear();
|
|
@@ -2857,7 +3787,7 @@ class CanvasManager {
|
|
|
2857
3787
|
this.rafStamps = { latestId: 0, invokeId: null };
|
|
2858
3788
|
this.frozen = false;
|
|
2859
3789
|
this.locked = false;
|
|
2860
|
-
this.processMutation =
|
|
3790
|
+
this.processMutation = (target, mutation) => {
|
|
2861
3791
|
const newFrame = this.rafStamps.invokeId &&
|
|
2862
3792
|
this.rafStamps.latestId !== this.rafStamps.invokeId;
|
|
2863
3793
|
if (newFrame || !this.rafStamps.invokeId)
|
|
@@ -2867,16 +3797,108 @@ class CanvasManager {
|
|
|
2867
3797
|
}
|
|
2868
3798
|
this.pendingCanvasMutations.get(target).push(mutation);
|
|
2869
3799
|
};
|
|
3800
|
+
const { sampling = 'all', win, blockClass, blockSelector, unblockSelector, recordCanvas, dataURLOptions, } = options;
|
|
2870
3801
|
this.mutationCb = options.mutationCb;
|
|
2871
3802
|
this.mirror = options.mirror;
|
|
2872
|
-
if (
|
|
2873
|
-
this.initCanvasMutationObserver(
|
|
3803
|
+
if (recordCanvas && sampling === 'all')
|
|
3804
|
+
this.initCanvasMutationObserver(win, blockClass, blockSelector, unblockSelector);
|
|
3805
|
+
if (recordCanvas && typeof sampling === 'number')
|
|
3806
|
+
this.initCanvasFPSObserver(sampling, win, blockClass, blockSelector, unblockSelector, {
|
|
3807
|
+
dataURLOptions,
|
|
3808
|
+
});
|
|
3809
|
+
}
|
|
3810
|
+
initCanvasFPSObserver(fps, win, blockClass, blockSelector, unblockSelector, options) {
|
|
3811
|
+
const canvasContextReset = initCanvasContextObserver(win, blockClass, blockSelector, unblockSelector, true);
|
|
3812
|
+
const snapshotInProgressMap = new Map();
|
|
3813
|
+
const worker = new WorkerFactory();
|
|
3814
|
+
worker.onmessage = (e) => {
|
|
3815
|
+
const { id } = e.data;
|
|
3816
|
+
snapshotInProgressMap.set(id, false);
|
|
3817
|
+
if (!('base64' in e.data))
|
|
3818
|
+
return;
|
|
3819
|
+
const { base64, type, width, height } = e.data;
|
|
3820
|
+
this.mutationCb({
|
|
3821
|
+
id,
|
|
3822
|
+
type: CanvasContext['2D'],
|
|
3823
|
+
commands: [
|
|
3824
|
+
{
|
|
3825
|
+
property: 'clearRect',
|
|
3826
|
+
args: [0, 0, width, height],
|
|
3827
|
+
},
|
|
3828
|
+
{
|
|
3829
|
+
property: 'drawImage',
|
|
3830
|
+
args: [
|
|
3831
|
+
{
|
|
3832
|
+
rr_type: 'ImageBitmap',
|
|
3833
|
+
args: [
|
|
3834
|
+
{
|
|
3835
|
+
rr_type: 'Blob',
|
|
3836
|
+
data: [{ rr_type: 'ArrayBuffer', base64 }],
|
|
3837
|
+
type,
|
|
3838
|
+
},
|
|
3839
|
+
],
|
|
3840
|
+
},
|
|
3841
|
+
0,
|
|
3842
|
+
0,
|
|
3843
|
+
],
|
|
3844
|
+
},
|
|
3845
|
+
],
|
|
3846
|
+
});
|
|
3847
|
+
};
|
|
3848
|
+
const timeBetweenSnapshots = 1000 / fps;
|
|
3849
|
+
let lastSnapshotTime = 0;
|
|
3850
|
+
let rafId;
|
|
3851
|
+
const getCanvas = () => {
|
|
3852
|
+
const matchedCanvas = [];
|
|
3853
|
+
win.document.querySelectorAll('canvas').forEach((canvas) => {
|
|
3854
|
+
if (!isBlocked(canvas, blockClass, blockSelector, unblockSelector, true)) {
|
|
3855
|
+
matchedCanvas.push(canvas);
|
|
3856
|
+
}
|
|
3857
|
+
});
|
|
3858
|
+
return matchedCanvas;
|
|
3859
|
+
};
|
|
3860
|
+
const takeCanvasSnapshots = (timestamp) => {
|
|
3861
|
+
if (lastSnapshotTime &&
|
|
3862
|
+
timestamp - lastSnapshotTime < timeBetweenSnapshots) {
|
|
3863
|
+
rafId = requestAnimationFrame(takeCanvasSnapshots);
|
|
3864
|
+
return;
|
|
3865
|
+
}
|
|
3866
|
+
lastSnapshotTime = timestamp;
|
|
3867
|
+
getCanvas()
|
|
3868
|
+
.forEach((canvas) => __awaiter(this, void 0, void 0, function* () {
|
|
3869
|
+
var _a;
|
|
3870
|
+
const id = this.mirror.getId(canvas);
|
|
3871
|
+
if (snapshotInProgressMap.get(id))
|
|
3872
|
+
return;
|
|
3873
|
+
snapshotInProgressMap.set(id, true);
|
|
3874
|
+
if (['webgl', 'webgl2'].includes(canvas.__context)) {
|
|
3875
|
+
const context = canvas.getContext(canvas.__context);
|
|
3876
|
+
if (((_a = context === null || context === void 0 ? void 0 : context.getContextAttributes()) === null || _a === void 0 ? void 0 : _a.preserveDrawingBuffer) === false) {
|
|
3877
|
+
context.clear(context.COLOR_BUFFER_BIT);
|
|
3878
|
+
}
|
|
3879
|
+
}
|
|
3880
|
+
const bitmap = yield createImageBitmap(canvas);
|
|
3881
|
+
worker.postMessage({
|
|
3882
|
+
id,
|
|
3883
|
+
bitmap,
|
|
3884
|
+
width: canvas.width,
|
|
3885
|
+
height: canvas.height,
|
|
3886
|
+
dataURLOptions: options.dataURLOptions,
|
|
3887
|
+
}, [bitmap]);
|
|
3888
|
+
}));
|
|
3889
|
+
rafId = requestAnimationFrame(takeCanvasSnapshots);
|
|
3890
|
+
};
|
|
3891
|
+
rafId = requestAnimationFrame(takeCanvasSnapshots);
|
|
3892
|
+
this.resetObservers = () => {
|
|
3893
|
+
canvasContextReset();
|
|
3894
|
+
cancelAnimationFrame(rafId);
|
|
3895
|
+
};
|
|
2874
3896
|
}
|
|
2875
|
-
initCanvasMutationObserver(win, blockClass,
|
|
3897
|
+
initCanvasMutationObserver(win, blockClass, blockSelector, unblockSelector) {
|
|
2876
3898
|
this.startRAFTimestamping();
|
|
2877
3899
|
this.startPendingCanvasMutationFlusher();
|
|
2878
|
-
const canvasContextReset = initCanvasContextObserver(win, blockClass, blockSelector, unblockSelector);
|
|
2879
|
-
const canvas2DReset = initCanvas2DMutationObserver(this.processMutation.bind(this), win, blockClass, blockSelector, unblockSelector
|
|
3900
|
+
const canvasContextReset = initCanvasContextObserver(win, blockClass, blockSelector, unblockSelector, false);
|
|
3901
|
+
const canvas2DReset = initCanvas2DMutationObserver(this.processMutation.bind(this), win, blockClass, blockSelector, unblockSelector);
|
|
2880
3902
|
const canvasWebGL1and2Reset = initCanvasWebGLMutationObserver(this.processMutation.bind(this), win, blockClass, blockSelector, unblockSelector, this.mirror);
|
|
2881
3903
|
this.resetObservers = () => {
|
|
2882
3904
|
canvasContextReset();
|
|
@@ -2918,20 +3940,133 @@ class CanvasManager {
|
|
|
2918
3940
|
}
|
|
2919
3941
|
}
|
|
2920
3942
|
|
|
3943
|
+
class StylesheetManager {
|
|
3944
|
+
constructor(options) {
|
|
3945
|
+
this.trackedLinkElements = new WeakSet();
|
|
3946
|
+
this.styleMirror = new StyleSheetMirror();
|
|
3947
|
+
this.mutationCb = options.mutationCb;
|
|
3948
|
+
this.adoptedStyleSheetCb = options.adoptedStyleSheetCb;
|
|
3949
|
+
}
|
|
3950
|
+
attachLinkElement(linkEl, childSn) {
|
|
3951
|
+
if ('_cssText' in childSn.attributes)
|
|
3952
|
+
this.mutationCb({
|
|
3953
|
+
adds: [],
|
|
3954
|
+
removes: [],
|
|
3955
|
+
texts: [],
|
|
3956
|
+
attributes: [
|
|
3957
|
+
{
|
|
3958
|
+
id: childSn.id,
|
|
3959
|
+
attributes: childSn
|
|
3960
|
+
.attributes,
|
|
3961
|
+
},
|
|
3962
|
+
],
|
|
3963
|
+
});
|
|
3964
|
+
this.trackLinkElement(linkEl);
|
|
3965
|
+
}
|
|
3966
|
+
trackLinkElement(linkEl) {
|
|
3967
|
+
if (this.trackedLinkElements.has(linkEl))
|
|
3968
|
+
return;
|
|
3969
|
+
this.trackedLinkElements.add(linkEl);
|
|
3970
|
+
this.trackStylesheetInLinkElement(linkEl);
|
|
3971
|
+
}
|
|
3972
|
+
adoptStyleSheets(sheets, hostId) {
|
|
3973
|
+
if (sheets.length === 0)
|
|
3974
|
+
return;
|
|
3975
|
+
const adoptedStyleSheetData = {
|
|
3976
|
+
id: hostId,
|
|
3977
|
+
styleIds: [],
|
|
3978
|
+
};
|
|
3979
|
+
const styles = [];
|
|
3980
|
+
for (const sheet of sheets) {
|
|
3981
|
+
let styleId;
|
|
3982
|
+
if (!this.styleMirror.has(sheet)) {
|
|
3983
|
+
styleId = this.styleMirror.add(sheet);
|
|
3984
|
+
styles.push({
|
|
3985
|
+
styleId,
|
|
3986
|
+
rules: Array.from(sheet.rules || CSSRule, (r, index) => ({
|
|
3987
|
+
rule: stringifyRule(r),
|
|
3988
|
+
index,
|
|
3989
|
+
})),
|
|
3990
|
+
});
|
|
3991
|
+
}
|
|
3992
|
+
else
|
|
3993
|
+
styleId = this.styleMirror.getId(sheet);
|
|
3994
|
+
adoptedStyleSheetData.styleIds.push(styleId);
|
|
3995
|
+
}
|
|
3996
|
+
if (styles.length > 0)
|
|
3997
|
+
adoptedStyleSheetData.styles = styles;
|
|
3998
|
+
this.adoptedStyleSheetCb(adoptedStyleSheetData);
|
|
3999
|
+
}
|
|
4000
|
+
reset() {
|
|
4001
|
+
this.styleMirror.reset();
|
|
4002
|
+
this.trackedLinkElements = new WeakSet();
|
|
4003
|
+
}
|
|
4004
|
+
trackStylesheetInLinkElement(linkEl) {
|
|
4005
|
+
}
|
|
4006
|
+
}
|
|
4007
|
+
|
|
4008
|
+
class ProcessedNodeManager {
|
|
4009
|
+
constructor() {
|
|
4010
|
+
this.nodeMap = new WeakMap();
|
|
4011
|
+
this.loop = true;
|
|
4012
|
+
this.periodicallyClear();
|
|
4013
|
+
}
|
|
4014
|
+
periodicallyClear() {
|
|
4015
|
+
requestAnimationFrame(() => {
|
|
4016
|
+
this.clear();
|
|
4017
|
+
if (this.loop)
|
|
4018
|
+
this.periodicallyClear();
|
|
4019
|
+
});
|
|
4020
|
+
}
|
|
4021
|
+
inOtherBuffer(node, thisBuffer) {
|
|
4022
|
+
const buffers = this.nodeMap.get(node);
|
|
4023
|
+
return (buffers && Array.from(buffers).some((buffer) => buffer !== thisBuffer));
|
|
4024
|
+
}
|
|
4025
|
+
add(node, buffer) {
|
|
4026
|
+
this.nodeMap.set(node, (this.nodeMap.get(node) || new Set()).add(buffer));
|
|
4027
|
+
}
|
|
4028
|
+
clear() {
|
|
4029
|
+
this.nodeMap = new WeakMap();
|
|
4030
|
+
}
|
|
4031
|
+
destroy() {
|
|
4032
|
+
this.loop = false;
|
|
4033
|
+
}
|
|
4034
|
+
}
|
|
4035
|
+
|
|
2921
4036
|
function wrapEvent(e) {
|
|
2922
|
-
return Object.assign(Object.assign({}, e), { timestamp:
|
|
4037
|
+
return Object.assign(Object.assign({}, e), { timestamp: nowTimestamp() });
|
|
2923
4038
|
}
|
|
2924
4039
|
let wrappedEmit;
|
|
2925
4040
|
let takeFullSnapshot;
|
|
4041
|
+
let canvasManager;
|
|
4042
|
+
let recording = false;
|
|
2926
4043
|
const mirror = createMirror();
|
|
2927
4044
|
function record(options = {}) {
|
|
2928
|
-
const { emit, checkoutEveryNms, checkoutEveryNth, blockClass = 'rr-block', blockSelector = null, unblockSelector = null, ignoreClass = 'rr-ignore', ignoreSelector = null, maskTextClass = 'rr-mask',
|
|
2929
|
-
|
|
4045
|
+
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'
|
|
4046
|
+
? options.recordAfter
|
|
4047
|
+
: 'load', userTriggeredOnInput = false, collectFonts = false, inlineImages = false, plugins, keepIframeSrcFn = () => false, ignoreCSSAttributes = new Set([]), errorHandler, onMutation, } = options;
|
|
4048
|
+
registerErrorHandler(errorHandler);
|
|
4049
|
+
const inEmittingFrame = recordCrossOriginIframes
|
|
4050
|
+
? window.parent === window
|
|
4051
|
+
: true;
|
|
4052
|
+
let passEmitsToParent = false;
|
|
4053
|
+
if (!inEmittingFrame) {
|
|
4054
|
+
try {
|
|
4055
|
+
if (window.parent.document) {
|
|
4056
|
+
passEmitsToParent = false;
|
|
4057
|
+
}
|
|
4058
|
+
}
|
|
4059
|
+
catch (e) {
|
|
4060
|
+
passEmitsToParent = true;
|
|
4061
|
+
}
|
|
4062
|
+
}
|
|
4063
|
+
if (inEmittingFrame && !emit) {
|
|
2930
4064
|
throw new Error('emit function is required');
|
|
2931
4065
|
}
|
|
2932
4066
|
if (mousemoveWait !== undefined && sampling.mousemove === undefined) {
|
|
2933
4067
|
sampling.mousemove = mousemoveWait;
|
|
2934
4068
|
}
|
|
4069
|
+
mirror.reset();
|
|
2935
4070
|
const maskInputOptions = maskAllInputs === true
|
|
2936
4071
|
? {
|
|
2937
4072
|
color: true,
|
|
@@ -2980,7 +4115,8 @@ function record(options = {}) {
|
|
|
2980
4115
|
e = plugin.eventProcessor(e);
|
|
2981
4116
|
}
|
|
2982
4117
|
}
|
|
2983
|
-
if (packFn
|
|
4118
|
+
if (packFn &&
|
|
4119
|
+
!passEmitsToParent) {
|
|
2984
4120
|
e = packFn(e);
|
|
2985
4121
|
}
|
|
2986
4122
|
return e;
|
|
@@ -2993,7 +4129,18 @@ function record(options = {}) {
|
|
|
2993
4129
|
e.data.source === IncrementalSource.Mutation)) {
|
|
2994
4130
|
mutationBuffers.forEach((buf) => buf.unfreeze());
|
|
2995
4131
|
}
|
|
2996
|
-
|
|
4132
|
+
if (inEmittingFrame) {
|
|
4133
|
+
emit === null || emit === void 0 ? void 0 : emit(eventProcessor(e), isCheckout);
|
|
4134
|
+
}
|
|
4135
|
+
else if (passEmitsToParent) {
|
|
4136
|
+
const message = {
|
|
4137
|
+
type: 'rrweb',
|
|
4138
|
+
event: eventProcessor(e),
|
|
4139
|
+
origin: window.location.origin,
|
|
4140
|
+
isCheckout,
|
|
4141
|
+
};
|
|
4142
|
+
window.parent.postMessage(message, '*');
|
|
4143
|
+
}
|
|
2997
4144
|
if (e.type === EventType.FullSnapshot) {
|
|
2998
4145
|
lastFullSnapshotEvent = e;
|
|
2999
4146
|
incrementalSnapshotCount = 0;
|
|
@@ -3026,10 +4173,31 @@ function record(options = {}) {
|
|
|
3026
4173
|
type: EventType.IncrementalSnapshot,
|
|
3027
4174
|
data: Object.assign({ source: IncrementalSource.CanvasMutation }, p),
|
|
3028
4175
|
}));
|
|
4176
|
+
const wrappedAdoptedStyleSheetEmit = (a) => wrappedEmit(wrapEvent({
|
|
4177
|
+
type: EventType.IncrementalSnapshot,
|
|
4178
|
+
data: Object.assign({ source: IncrementalSource.AdoptedStyleSheet }, a),
|
|
4179
|
+
}));
|
|
4180
|
+
const stylesheetManager = new StylesheetManager({
|
|
4181
|
+
mutationCb: wrappedMutationEmit,
|
|
4182
|
+
adoptedStyleSheetCb: wrappedAdoptedStyleSheetEmit,
|
|
4183
|
+
});
|
|
3029
4184
|
const iframeManager = new IframeManager({
|
|
4185
|
+
mirror,
|
|
3030
4186
|
mutationCb: wrappedMutationEmit,
|
|
4187
|
+
stylesheetManager: stylesheetManager,
|
|
4188
|
+
recordCrossOriginIframes,
|
|
4189
|
+
wrappedEmit,
|
|
3031
4190
|
});
|
|
3032
|
-
const
|
|
4191
|
+
for (const plugin of plugins || []) {
|
|
4192
|
+
if (plugin.getMirror)
|
|
4193
|
+
plugin.getMirror({
|
|
4194
|
+
nodeMirror: mirror,
|
|
4195
|
+
crossOriginIframeMirror: iframeManager.crossOriginIframeMirror,
|
|
4196
|
+
crossOriginIframeStyleMirror: iframeManager.crossOriginIframeStyleMirror,
|
|
4197
|
+
});
|
|
4198
|
+
}
|
|
4199
|
+
const processedNodeManager = new ProcessedNodeManager();
|
|
4200
|
+
canvasManager = new CanvasManager({
|
|
3033
4201
|
recordCanvas,
|
|
3034
4202
|
mutationCb: wrappedCanvasMutationEmit,
|
|
3035
4203
|
win: window,
|
|
@@ -3037,6 +4205,8 @@ function record(options = {}) {
|
|
|
3037
4205
|
blockSelector,
|
|
3038
4206
|
unblockSelector,
|
|
3039
4207
|
mirror,
|
|
4208
|
+
sampling: sampling.canvas,
|
|
4209
|
+
dataURLOptions,
|
|
3040
4210
|
});
|
|
3041
4211
|
const shadowDomManager = new ShadowDomManager({
|
|
3042
4212
|
mutationCb: wrappedMutationEmit,
|
|
@@ -3046,14 +4216,15 @@ function record(options = {}) {
|
|
|
3046
4216
|
blockClass,
|
|
3047
4217
|
blockSelector,
|
|
3048
4218
|
unblockSelector,
|
|
4219
|
+
maskAllText,
|
|
3049
4220
|
maskTextClass,
|
|
4221
|
+
unmaskTextClass,
|
|
3050
4222
|
maskTextSelector,
|
|
3051
4223
|
unmaskTextSelector,
|
|
3052
|
-
maskInputSelector,
|
|
3053
|
-
unmaskInputSelector,
|
|
3054
4224
|
inlineStylesheet,
|
|
3055
|
-
maskAllText,
|
|
3056
4225
|
maskInputOptions,
|
|
4226
|
+
dataURLOptions,
|
|
4227
|
+
maskAttributeFn,
|
|
3057
4228
|
maskTextFn,
|
|
3058
4229
|
maskInputFn,
|
|
3059
4230
|
recordCanvas,
|
|
@@ -3061,12 +4232,14 @@ function record(options = {}) {
|
|
|
3061
4232
|
sampling,
|
|
3062
4233
|
slimDOMOptions,
|
|
3063
4234
|
iframeManager,
|
|
4235
|
+
stylesheetManager,
|
|
3064
4236
|
canvasManager,
|
|
4237
|
+
keepIframeSrcFn,
|
|
4238
|
+
processedNodeManager,
|
|
3065
4239
|
},
|
|
3066
4240
|
mirror,
|
|
3067
4241
|
});
|
|
3068
4242
|
takeFullSnapshot = (isCheckout = false) => {
|
|
3069
|
-
var _a, _b, _c, _d;
|
|
3070
4243
|
wrappedEmit(wrapEvent({
|
|
3071
4244
|
type: EventType.Meta,
|
|
3072
4245
|
data: {
|
|
@@ -3075,27 +4248,35 @@ function record(options = {}) {
|
|
|
3075
4248
|
height: getWindowHeight(),
|
|
3076
4249
|
},
|
|
3077
4250
|
}), isCheckout);
|
|
4251
|
+
stylesheetManager.reset();
|
|
4252
|
+
shadowDomManager.init();
|
|
3078
4253
|
mutationBuffers.forEach((buf) => buf.lock());
|
|
3079
|
-
const
|
|
4254
|
+
const node = snapshot(document, {
|
|
4255
|
+
mirror,
|
|
3080
4256
|
blockClass,
|
|
3081
4257
|
blockSelector,
|
|
3082
4258
|
unblockSelector,
|
|
4259
|
+
maskAllText,
|
|
3083
4260
|
maskTextClass,
|
|
4261
|
+
unmaskTextClass,
|
|
3084
4262
|
maskTextSelector,
|
|
3085
4263
|
unmaskTextSelector,
|
|
3086
|
-
maskInputSelector,
|
|
3087
|
-
unmaskInputSelector,
|
|
3088
4264
|
inlineStylesheet,
|
|
3089
|
-
maskAllText,
|
|
3090
4265
|
maskAllInputs: maskInputOptions,
|
|
4266
|
+
maskAttributeFn,
|
|
4267
|
+
maskInputFn,
|
|
3091
4268
|
maskTextFn,
|
|
3092
4269
|
slimDOM: slimDOMOptions,
|
|
4270
|
+
dataURLOptions,
|
|
3093
4271
|
recordCanvas,
|
|
3094
4272
|
inlineImages,
|
|
3095
4273
|
onSerialize: (n) => {
|
|
3096
|
-
if (
|
|
4274
|
+
if (isSerializedIframe(n, mirror)) {
|
|
3097
4275
|
iframeManager.addIframe(n);
|
|
3098
4276
|
}
|
|
4277
|
+
if (isSerializedStylesheet(n, mirror)) {
|
|
4278
|
+
stylesheetManager.trackLinkElement(n);
|
|
4279
|
+
}
|
|
3099
4280
|
if (hasShadowRoot(n)) {
|
|
3100
4281
|
shadowDomManager.addShadowRoot(n.shadowRoot, document);
|
|
3101
4282
|
}
|
|
@@ -3104,42 +4285,27 @@ function record(options = {}) {
|
|
|
3104
4285
|
iframeManager.attachIframe(iframe, childSn);
|
|
3105
4286
|
shadowDomManager.observeAttachShadow(iframe);
|
|
3106
4287
|
},
|
|
4288
|
+
onStylesheetLoad: (linkEl, childSn) => {
|
|
4289
|
+
stylesheetManager.attachLinkElement(linkEl, childSn);
|
|
4290
|
+
},
|
|
3107
4291
|
keepIframeSrcFn,
|
|
3108
4292
|
});
|
|
3109
4293
|
if (!node) {
|
|
3110
4294
|
return console.warn('Failed to snapshot the document');
|
|
3111
4295
|
}
|
|
3112
|
-
mirror.map = idNodeMap;
|
|
3113
4296
|
wrappedEmit(wrapEvent({
|
|
3114
4297
|
type: EventType.FullSnapshot,
|
|
3115
4298
|
data: {
|
|
3116
4299
|
node,
|
|
3117
|
-
initialOffset:
|
|
3118
|
-
left: window.pageXOffset !== undefined
|
|
3119
|
-
? window.pageXOffset
|
|
3120
|
-
: (document === null || document === void 0 ? void 0 : document.documentElement.scrollLeft) ||
|
|
3121
|
-
((_b = (_a = document === null || document === void 0 ? void 0 : document.body) === null || _a === void 0 ? void 0 : _a.parentElement) === null || _b === void 0 ? void 0 : _b.scrollLeft) ||
|
|
3122
|
-
(document === null || document === void 0 ? void 0 : document.body.scrollLeft) ||
|
|
3123
|
-
0,
|
|
3124
|
-
top: window.pageYOffset !== undefined
|
|
3125
|
-
? window.pageYOffset
|
|
3126
|
-
: (document === null || document === void 0 ? void 0 : document.documentElement.scrollTop) ||
|
|
3127
|
-
((_d = (_c = document === null || document === void 0 ? void 0 : document.body) === null || _c === void 0 ? void 0 : _c.parentElement) === null || _d === void 0 ? void 0 : _d.scrollTop) ||
|
|
3128
|
-
(document === null || document === void 0 ? void 0 : document.body.scrollTop) ||
|
|
3129
|
-
0,
|
|
3130
|
-
},
|
|
4300
|
+
initialOffset: getWindowScroll(window),
|
|
3131
4301
|
},
|
|
3132
|
-
}));
|
|
4302
|
+
}), isCheckout);
|
|
3133
4303
|
mutationBuffers.forEach((buf) => buf.unlock());
|
|
4304
|
+
if (document.adoptedStyleSheets && document.adoptedStyleSheets.length > 0)
|
|
4305
|
+
stylesheetManager.adoptStyleSheets(document.adoptedStyleSheets, mirror.getId(document));
|
|
3134
4306
|
};
|
|
3135
4307
|
try {
|
|
3136
4308
|
const handlers = [];
|
|
3137
|
-
handlers.push(on('DOMContentLoaded', () => {
|
|
3138
|
-
wrappedEmit(wrapEvent({
|
|
3139
|
-
type: EventType.DomContentLoaded,
|
|
3140
|
-
data: {},
|
|
3141
|
-
}));
|
|
3142
|
-
}));
|
|
3143
4309
|
const observe = (doc) => {
|
|
3144
4310
|
var _a;
|
|
3145
4311
|
return callbackWrapper(initObservers)({
|
|
@@ -3182,14 +4348,26 @@ function record(options = {}) {
|
|
|
3182
4348
|
type: EventType.IncrementalSnapshot,
|
|
3183
4349
|
data: Object.assign({ source: IncrementalSource.Font }, p),
|
|
3184
4350
|
})),
|
|
4351
|
+
selectionCb: (p) => {
|
|
4352
|
+
wrappedEmit(wrapEvent({
|
|
4353
|
+
type: EventType.IncrementalSnapshot,
|
|
4354
|
+
data: Object.assign({ source: IncrementalSource.Selection }, p),
|
|
4355
|
+
}));
|
|
4356
|
+
},
|
|
4357
|
+
customElementCb: (c) => {
|
|
4358
|
+
wrappedEmit(wrapEvent({
|
|
4359
|
+
type: EventType.IncrementalSnapshot,
|
|
4360
|
+
data: Object.assign({ source: IncrementalSource.CustomElement }, c),
|
|
4361
|
+
}));
|
|
4362
|
+
},
|
|
3185
4363
|
blockClass,
|
|
3186
4364
|
ignoreClass,
|
|
3187
4365
|
ignoreSelector,
|
|
4366
|
+
maskAllText,
|
|
3188
4367
|
maskTextClass,
|
|
4368
|
+
unmaskTextClass,
|
|
3189
4369
|
maskTextSelector,
|
|
3190
4370
|
unmaskTextSelector,
|
|
3191
|
-
maskInputSelector,
|
|
3192
|
-
unmaskInputSelector,
|
|
3193
4371
|
maskInputOptions,
|
|
3194
4372
|
inlineStylesheet,
|
|
3195
4373
|
sampling,
|
|
@@ -3198,16 +4376,21 @@ function record(options = {}) {
|
|
|
3198
4376
|
userTriggeredOnInput,
|
|
3199
4377
|
collectFonts,
|
|
3200
4378
|
doc,
|
|
3201
|
-
|
|
4379
|
+
maskAttributeFn,
|
|
3202
4380
|
maskInputFn,
|
|
3203
4381
|
maskTextFn,
|
|
4382
|
+
keepIframeSrcFn,
|
|
3204
4383
|
blockSelector,
|
|
3205
4384
|
unblockSelector,
|
|
3206
4385
|
slimDOMOptions,
|
|
4386
|
+
dataURLOptions,
|
|
3207
4387
|
mirror,
|
|
3208
4388
|
iframeManager,
|
|
4389
|
+
stylesheetManager,
|
|
3209
4390
|
shadowDomManager,
|
|
4391
|
+
processedNodeManager,
|
|
3210
4392
|
canvasManager,
|
|
4393
|
+
ignoreCSSAttributes,
|
|
3211
4394
|
plugins: ((_a = plugins === null || plugins === void 0 ? void 0 : plugins.filter((p) => p.observer)) === null || _a === void 0 ? void 0 : _a.map((p) => ({
|
|
3212
4395
|
observer: p.observer,
|
|
3213
4396
|
options: p.options,
|
|
@@ -3232,22 +4415,35 @@ function record(options = {}) {
|
|
|
3232
4415
|
const init = () => {
|
|
3233
4416
|
takeFullSnapshot();
|
|
3234
4417
|
handlers.push(observe(document));
|
|
4418
|
+
recording = true;
|
|
3235
4419
|
};
|
|
3236
4420
|
if (document.readyState === 'interactive' ||
|
|
3237
4421
|
document.readyState === 'complete') {
|
|
3238
4422
|
init();
|
|
3239
4423
|
}
|
|
3240
4424
|
else {
|
|
4425
|
+
handlers.push(on('DOMContentLoaded', () => {
|
|
4426
|
+
wrappedEmit(wrapEvent({
|
|
4427
|
+
type: EventType.DomContentLoaded,
|
|
4428
|
+
data: {},
|
|
4429
|
+
}));
|
|
4430
|
+
if (recordAfter === 'DOMContentLoaded')
|
|
4431
|
+
init();
|
|
4432
|
+
}));
|
|
3241
4433
|
handlers.push(on('load', () => {
|
|
3242
4434
|
wrappedEmit(wrapEvent({
|
|
3243
4435
|
type: EventType.Load,
|
|
3244
4436
|
data: {},
|
|
3245
4437
|
}));
|
|
3246
|
-
|
|
4438
|
+
if (recordAfter === 'load')
|
|
4439
|
+
init();
|
|
3247
4440
|
}, window));
|
|
3248
4441
|
}
|
|
3249
4442
|
return () => {
|
|
3250
4443
|
handlers.forEach((h) => h());
|
|
4444
|
+
processedNodeManager.destroy();
|
|
4445
|
+
recording = false;
|
|
4446
|
+
unregisterErrorHandler();
|
|
3251
4447
|
};
|
|
3252
4448
|
}
|
|
3253
4449
|
catch (error) {
|
|
@@ -3255,7 +4451,7 @@ function record(options = {}) {
|
|
|
3255
4451
|
}
|
|
3256
4452
|
}
|
|
3257
4453
|
record.addCustomEvent = (tag, payload) => {
|
|
3258
|
-
if (!
|
|
4454
|
+
if (!recording) {
|
|
3259
4455
|
throw new Error('please add custom event after start recording');
|
|
3260
4456
|
}
|
|
3261
4457
|
wrappedEmit(wrapEvent({
|
|
@@ -3270,7 +4466,7 @@ record.freezePage = () => {
|
|
|
3270
4466
|
mutationBuffers.forEach((buf) => buf.freeze());
|
|
3271
4467
|
};
|
|
3272
4468
|
record.takeFullSnapshot = (isCheckout) => {
|
|
3273
|
-
if (!
|
|
4469
|
+
if (!recording) {
|
|
3274
4470
|
throw new Error('please take full snapshot after start recording');
|
|
3275
4471
|
}
|
|
3276
4472
|
takeFullSnapshot(isCheckout);
|
|
@@ -3766,27 +4962,25 @@ const handleDomListener = (
|
|
|
3766
4962
|
|
|
3767
4963
|
/** Get the base DOM breadcrumb. */
|
|
3768
4964
|
function getBaseDomBreadcrumb(target, message) {
|
|
3769
|
-
|
|
3770
|
-
const
|
|
4965
|
+
const nodeId = record.mirror.getId(target);
|
|
4966
|
+
const node = nodeId && record.mirror.getNode(nodeId);
|
|
4967
|
+
const meta = node && record.mirror.getMeta(node);
|
|
4968
|
+
const element = meta && isElement(meta) ? meta : null;
|
|
3771
4969
|
|
|
3772
4970
|
return {
|
|
3773
4971
|
message,
|
|
3774
|
-
data:
|
|
4972
|
+
data: element
|
|
3775
4973
|
? {
|
|
3776
|
-
nodeId
|
|
4974
|
+
nodeId,
|
|
3777
4975
|
node: {
|
|
3778
|
-
id:
|
|
3779
|
-
tagName:
|
|
3780
|
-
textContent:
|
|
3781
|
-
|
|
3782
|
-
|
|
3783
|
-
|
|
3784
|
-
|
|
3785
|
-
|
|
3786
|
-
.map(text => (text ).trim())
|
|
3787
|
-
.join('')
|
|
3788
|
-
: '',
|
|
3789
|
-
attributes: getAttributesToRecord(serializedNode.attributes),
|
|
4976
|
+
id: nodeId,
|
|
4977
|
+
tagName: element.tagName,
|
|
4978
|
+
textContent: Array.from(element.childNodes)
|
|
4979
|
+
.map((node) => node.type === NodeType.Text && node.textContent)
|
|
4980
|
+
.filter(Boolean) // filter out empty values
|
|
4981
|
+
.map(text => (text ).trim())
|
|
4982
|
+
.join(''),
|
|
4983
|
+
attributes: getAttributesToRecord(element.attributes),
|
|
3790
4984
|
},
|
|
3791
4985
|
}
|
|
3792
4986
|
: {},
|
|
@@ -3823,8 +5017,8 @@ function getDomTarget(handlerData) {
|
|
|
3823
5017
|
return { target, message };
|
|
3824
5018
|
}
|
|
3825
5019
|
|
|
3826
|
-
function
|
|
3827
|
-
return
|
|
5020
|
+
function isElement(node) {
|
|
5021
|
+
return node.type === NodeType.Element;
|
|
3828
5022
|
}
|
|
3829
5023
|
|
|
3830
5024
|
/** Handle keyboard events & create breadcrumbs. */
|
|
@@ -5139,16 +6333,7 @@ function shouldFilterRequest(replay, url) {
|
|
|
5139
6333
|
return false;
|
|
5140
6334
|
}
|
|
5141
6335
|
|
|
5142
|
-
return
|
|
5143
|
-
}
|
|
5144
|
-
|
|
5145
|
-
/**
|
|
5146
|
-
* Checks wether a given URL belongs to the configured Sentry DSN.
|
|
5147
|
-
*/
|
|
5148
|
-
function _isSentryRequest(url) {
|
|
5149
|
-
const client = core.getCurrentHub().getClient();
|
|
5150
|
-
const dsn = client && client.getDsn();
|
|
5151
|
-
return dsn ? url.includes(dsn.host) : false;
|
|
6336
|
+
return core.isSentryRequestUrl(url, core.getCurrentHub());
|
|
5152
6337
|
}
|
|
5153
6338
|
|
|
5154
6339
|
/** Add a performance entry breadcrumb */
|
|
@@ -6663,9 +7848,7 @@ function createLargestContentfulPaint(
|
|
|
6663
7848
|
data: {
|
|
6664
7849
|
value, // LCP "duration" in ms
|
|
6665
7850
|
size,
|
|
6666
|
-
|
|
6667
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
6668
|
-
nodeId: record.mirror.getId(entry.element ),
|
|
7851
|
+
nodeId: record.mirror.getId(entry.element),
|
|
6669
7852
|
},
|
|
6670
7853
|
};
|
|
6671
7854
|
}
|
|
@@ -8462,8 +9645,6 @@ function getPrivacyOptions({
|
|
|
8462
9645
|
// We are making the decision to make text and input selectors the same
|
|
8463
9646
|
maskTextSelector: maskSelector,
|
|
8464
9647
|
unmaskTextSelector: unmaskSelector,
|
|
8465
|
-
maskInputSelector: maskSelector,
|
|
8466
|
-
unmaskInputSelector: unmaskSelector,
|
|
8467
9648
|
|
|
8468
9649
|
blockSelector: getOption(
|
|
8469
9650
|
block,
|
|
@@ -8499,6 +9680,39 @@ function isElectronNodeRenderer() {
|
|
|
8499
9680
|
return typeof process !== 'undefined' && (process ).type === 'renderer';
|
|
8500
9681
|
}
|
|
8501
9682
|
|
|
9683
|
+
/**
|
|
9684
|
+
* Masks an attribute if necessary, otherwise return attribute value as-is.
|
|
9685
|
+
*/
|
|
9686
|
+
function maskAttribute({
|
|
9687
|
+
el,
|
|
9688
|
+
key,
|
|
9689
|
+
maskAttributes,
|
|
9690
|
+
maskAllText,
|
|
9691
|
+
privacyOptions,
|
|
9692
|
+
value,
|
|
9693
|
+
}) {
|
|
9694
|
+
// We only mask attributes if `maskAllText` is true
|
|
9695
|
+
if (!maskAllText) {
|
|
9696
|
+
return value;
|
|
9697
|
+
}
|
|
9698
|
+
|
|
9699
|
+
// unmaskTextSelector takes precendence
|
|
9700
|
+
if (privacyOptions.unmaskTextSelector && el.matches(privacyOptions.unmaskTextSelector)) {
|
|
9701
|
+
return value;
|
|
9702
|
+
}
|
|
9703
|
+
|
|
9704
|
+
if (
|
|
9705
|
+
maskAttributes.includes(key) ||
|
|
9706
|
+
// Need to mask `value` attribute for `<input>` if it's a button-like
|
|
9707
|
+
// type
|
|
9708
|
+
(key === 'value' && el.tagName === 'INPUT' && ['submit', 'button'].includes(el.getAttribute('type') || ''))
|
|
9709
|
+
) {
|
|
9710
|
+
return value.replace(/[\S]/g, '*');
|
|
9711
|
+
}
|
|
9712
|
+
|
|
9713
|
+
return value;
|
|
9714
|
+
}
|
|
9715
|
+
|
|
8502
9716
|
const MEDIA_SELECTORS =
|
|
8503
9717
|
'img,image,svg,video,object,picture,embed,map,audio,link[rel="icon"],link[rel="apple-touch-icon"]';
|
|
8504
9718
|
|
|
@@ -8558,6 +9772,7 @@ class Replay {
|
|
|
8558
9772
|
networkResponseHeaders = [],
|
|
8559
9773
|
|
|
8560
9774
|
mask = [],
|
|
9775
|
+
maskAttributes = ['title', 'placeholder'],
|
|
8561
9776
|
unmask = [],
|
|
8562
9777
|
block = [],
|
|
8563
9778
|
unblock = [],
|
|
@@ -8581,25 +9796,36 @@ class Replay {
|
|
|
8581
9796
|
} = {}) {
|
|
8582
9797
|
this.name = Replay.id;
|
|
8583
9798
|
|
|
9799
|
+
const privacyOptions = getPrivacyOptions({
|
|
9800
|
+
mask,
|
|
9801
|
+
unmask,
|
|
9802
|
+
block,
|
|
9803
|
+
unblock,
|
|
9804
|
+
ignore,
|
|
9805
|
+
blockClass,
|
|
9806
|
+
blockSelector,
|
|
9807
|
+
maskTextClass,
|
|
9808
|
+
maskTextSelector,
|
|
9809
|
+
ignoreClass,
|
|
9810
|
+
});
|
|
9811
|
+
|
|
8584
9812
|
this._recordingOptions = {
|
|
8585
9813
|
maskAllInputs,
|
|
8586
9814
|
maskAllText,
|
|
8587
9815
|
maskInputOptions: { ...(maskInputOptions || {}), password: true },
|
|
8588
9816
|
maskTextFn: maskFn,
|
|
8589
9817
|
maskInputFn: maskFn,
|
|
9818
|
+
maskAttributeFn: (key, value, el) =>
|
|
9819
|
+
maskAttribute({
|
|
9820
|
+
maskAttributes,
|
|
9821
|
+
maskAllText,
|
|
9822
|
+
privacyOptions,
|
|
9823
|
+
key,
|
|
9824
|
+
value,
|
|
9825
|
+
el,
|
|
9826
|
+
}),
|
|
8590
9827
|
|
|
8591
|
-
...
|
|
8592
|
-
mask,
|
|
8593
|
-
unmask,
|
|
8594
|
-
block,
|
|
8595
|
-
unblock,
|
|
8596
|
-
ignore,
|
|
8597
|
-
blockClass,
|
|
8598
|
-
blockSelector,
|
|
8599
|
-
maskTextClass,
|
|
8600
|
-
maskTextSelector,
|
|
8601
|
-
ignoreClass,
|
|
8602
|
-
}),
|
|
9828
|
+
...privacyOptions,
|
|
8603
9829
|
|
|
8604
9830
|
// Our defaults
|
|
8605
9831
|
slimDOMOptions: 'all',
|
|
@@ -8609,6 +9835,16 @@ class Replay {
|
|
|
8609
9835
|
// collect fonts, but be aware that `sentry.io` needs to be an allowed
|
|
8610
9836
|
// origin for playback
|
|
8611
9837
|
collectFonts: true,
|
|
9838
|
+
errorHandler: (err) => {
|
|
9839
|
+
try {
|
|
9840
|
+
// @ts-expect-error Set this so that replay SDK can ignore errors originating from rrweb
|
|
9841
|
+
err.__rrweb__ = true;
|
|
9842
|
+
} catch (e) {
|
|
9843
|
+
// avoid any potential hazards here
|
|
9844
|
+
}
|
|
9845
|
+
// return true to suppress throwing the error inside of rrweb
|
|
9846
|
+
return true;
|
|
9847
|
+
},
|
|
8612
9848
|
};
|
|
8613
9849
|
|
|
8614
9850
|
this._initialOptions = {
|