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