@posthog/rrweb-record 0.0.28 → 0.0.30
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/dist/rrweb-record.cjs +177 -94
- package/dist/rrweb-record.cjs.map +1 -1
- package/dist/rrweb-record.js +177 -94
- package/dist/rrweb-record.js.map +1 -1
- package/dist/rrweb-record.umd.cjs +176 -94
- package/dist/rrweb-record.umd.cjs.map +2 -2
- package/dist/rrweb-record.umd.min.cjs +35 -35
- package/dist/rrweb-record.umd.min.cjs.map +3 -3
- package/package.json +1 -1
|
@@ -251,6 +251,91 @@ function isShadowRoot(n2) {
|
|
|
251
251
|
function isNativeShadowDom(shadowRoot2) {
|
|
252
252
|
return Object.prototype.toString.call(shadowRoot2) === "[object ShadowRoot]";
|
|
253
253
|
}
|
|
254
|
+
function fixBrowserCompatibilityIssuesInCSS(cssText) {
|
|
255
|
+
if (cssText.includes(" background-clip: text;") && !cssText.includes(" -webkit-background-clip: text;")) {
|
|
256
|
+
cssText = cssText.replace(
|
|
257
|
+
/\sbackground-clip:\s*text;/g,
|
|
258
|
+
" -webkit-background-clip: text; background-clip: text;"
|
|
259
|
+
);
|
|
260
|
+
}
|
|
261
|
+
return cssText;
|
|
262
|
+
}
|
|
263
|
+
function escapeImportStatement(rule2) {
|
|
264
|
+
const { cssText } = rule2;
|
|
265
|
+
if (cssText.split('"').length < 3) return cssText;
|
|
266
|
+
const statement = ["@import", `url(${JSON.stringify(rule2.href)})`];
|
|
267
|
+
if (rule2.layerName === "") {
|
|
268
|
+
statement.push(`layer`);
|
|
269
|
+
} else if (rule2.layerName) {
|
|
270
|
+
statement.push(`layer(${rule2.layerName})`);
|
|
271
|
+
}
|
|
272
|
+
if (rule2.supportsText) {
|
|
273
|
+
statement.push(`supports(${rule2.supportsText})`);
|
|
274
|
+
}
|
|
275
|
+
if (rule2.media.length) {
|
|
276
|
+
statement.push(rule2.media.mediaText);
|
|
277
|
+
}
|
|
278
|
+
return statement.join(" ") + ";";
|
|
279
|
+
}
|
|
280
|
+
function stringifyStylesheet(s2) {
|
|
281
|
+
try {
|
|
282
|
+
const rules2 = s2.rules || s2.cssRules;
|
|
283
|
+
if (!rules2) {
|
|
284
|
+
return null;
|
|
285
|
+
}
|
|
286
|
+
let sheetHref = s2.href;
|
|
287
|
+
if (!sheetHref && s2.ownerNode) {
|
|
288
|
+
sheetHref = s2.ownerNode.baseURI;
|
|
289
|
+
}
|
|
290
|
+
const stringifiedRules = Array.from(
|
|
291
|
+
rules2,
|
|
292
|
+
(rule2) => stringifyRule(rule2, sheetHref)
|
|
293
|
+
).join("");
|
|
294
|
+
return fixBrowserCompatibilityIssuesInCSS(stringifiedRules);
|
|
295
|
+
} catch (error) {
|
|
296
|
+
return null;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
function stringifyRule(rule2, sheetHref) {
|
|
300
|
+
var _a2;
|
|
301
|
+
if (isCSSImportRule(rule2)) {
|
|
302
|
+
let importStringified;
|
|
303
|
+
try {
|
|
304
|
+
importStringified = // for same-origin stylesheets,
|
|
305
|
+
// we can access the imported stylesheet rules directly
|
|
306
|
+
stringifyStylesheet(rule2.styleSheet) || // work around browser issues with the raw string `@import url(...)` statement
|
|
307
|
+
escapeImportStatement(rule2);
|
|
308
|
+
} catch (error) {
|
|
309
|
+
importStringified = rule2.cssText;
|
|
310
|
+
}
|
|
311
|
+
try {
|
|
312
|
+
if (importStringified && ((_a2 = rule2.styleSheet) == null ? void 0 : _a2.href)) {
|
|
313
|
+
return absolutifyURLs(importStringified, rule2.styleSheet.href);
|
|
314
|
+
}
|
|
315
|
+
} catch (e) {
|
|
316
|
+
}
|
|
317
|
+
return importStringified;
|
|
318
|
+
} else {
|
|
319
|
+
let ruleStringified = rule2.cssText;
|
|
320
|
+
if (isCSSStyleRule(rule2) && rule2.selectorText.includes(":")) {
|
|
321
|
+
ruleStringified = fixSafariColons(ruleStringified);
|
|
322
|
+
}
|
|
323
|
+
if (sheetHref) {
|
|
324
|
+
return absolutifyURLs(ruleStringified, sheetHref);
|
|
325
|
+
}
|
|
326
|
+
return ruleStringified;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
function fixSafariColons(cssStringified) {
|
|
330
|
+
const regex = /(\[(?:[\w-]+)[^\\])(:(?:[\w-]+)\])/gm;
|
|
331
|
+
return cssStringified.replace(regex, "$1\\$2");
|
|
332
|
+
}
|
|
333
|
+
function isCSSImportRule(rule2) {
|
|
334
|
+
return "styleSheet" in rule2;
|
|
335
|
+
}
|
|
336
|
+
function isCSSStyleRule(rule2) {
|
|
337
|
+
return "selectorText" in rule2;
|
|
338
|
+
}
|
|
254
339
|
class Mirror {
|
|
255
340
|
constructor() {
|
|
256
341
|
__publicField$1(this, "idNodeMap", /* @__PURE__ */ new Map());
|
|
@@ -374,91 +459,6 @@ function extractFileExtension(path, baseURL) {
|
|
|
374
459
|
const match = url.pathname.match(regex);
|
|
375
460
|
return (_a2 = match == null ? void 0 : match[1]) != null ? _a2 : null;
|
|
376
461
|
}
|
|
377
|
-
function fixBrowserCompatibilityIssuesInCSS(cssText) {
|
|
378
|
-
if (cssText.includes(" background-clip: text;") && !cssText.includes(" -webkit-background-clip: text;")) {
|
|
379
|
-
cssText = cssText.replace(
|
|
380
|
-
/\sbackground-clip:\s*text;/g,
|
|
381
|
-
" -webkit-background-clip: text; background-clip: text;"
|
|
382
|
-
);
|
|
383
|
-
}
|
|
384
|
-
return cssText;
|
|
385
|
-
}
|
|
386
|
-
function escapeImportStatement(rule2) {
|
|
387
|
-
const { cssText } = rule2;
|
|
388
|
-
if (cssText.split('"').length < 3) return cssText;
|
|
389
|
-
const statement = ["@import", `url(${JSON.stringify(rule2.href)})`];
|
|
390
|
-
if (rule2.layerName === "") {
|
|
391
|
-
statement.push(`layer`);
|
|
392
|
-
} else if (rule2.layerName) {
|
|
393
|
-
statement.push(`layer(${rule2.layerName})`);
|
|
394
|
-
}
|
|
395
|
-
if (rule2.supportsText) {
|
|
396
|
-
statement.push(`supports(${rule2.supportsText})`);
|
|
397
|
-
}
|
|
398
|
-
if (rule2.media.length) {
|
|
399
|
-
statement.push(rule2.media.mediaText);
|
|
400
|
-
}
|
|
401
|
-
return statement.join(" ") + ";";
|
|
402
|
-
}
|
|
403
|
-
function stringifyStylesheet(s2) {
|
|
404
|
-
try {
|
|
405
|
-
const rules2 = s2.rules || s2.cssRules;
|
|
406
|
-
if (!rules2) {
|
|
407
|
-
return null;
|
|
408
|
-
}
|
|
409
|
-
let sheetHref = s2.href;
|
|
410
|
-
if (!sheetHref && s2.ownerNode) {
|
|
411
|
-
sheetHref = s2.ownerNode.baseURI;
|
|
412
|
-
}
|
|
413
|
-
const stringifiedRules = Array.from(
|
|
414
|
-
rules2,
|
|
415
|
-
(rule2) => stringifyRule(rule2, sheetHref)
|
|
416
|
-
).join("");
|
|
417
|
-
return fixBrowserCompatibilityIssuesInCSS(stringifiedRules);
|
|
418
|
-
} catch (error) {
|
|
419
|
-
return null;
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
function stringifyRule(rule2, sheetHref) {
|
|
423
|
-
var _a2;
|
|
424
|
-
if (isCSSImportRule(rule2)) {
|
|
425
|
-
let importStringified;
|
|
426
|
-
try {
|
|
427
|
-
importStringified = // for same-origin stylesheets,
|
|
428
|
-
// we can access the imported stylesheet rules directly
|
|
429
|
-
stringifyStylesheet(rule2.styleSheet) || // work around browser issues with the raw string `@import url(...)` statement
|
|
430
|
-
escapeImportStatement(rule2);
|
|
431
|
-
} catch (error) {
|
|
432
|
-
importStringified = rule2.cssText;
|
|
433
|
-
}
|
|
434
|
-
try {
|
|
435
|
-
if (importStringified && ((_a2 = rule2.styleSheet) == null ? void 0 : _a2.href)) {
|
|
436
|
-
return absolutifyURLs(importStringified, rule2.styleSheet.href);
|
|
437
|
-
}
|
|
438
|
-
} catch (e) {
|
|
439
|
-
}
|
|
440
|
-
return importStringified;
|
|
441
|
-
} else {
|
|
442
|
-
let ruleStringified = rule2.cssText;
|
|
443
|
-
if (isCSSStyleRule(rule2) && rule2.selectorText.includes(":")) {
|
|
444
|
-
ruleStringified = fixSafariColons(ruleStringified);
|
|
445
|
-
}
|
|
446
|
-
if (sheetHref) {
|
|
447
|
-
return absolutifyURLs(ruleStringified, sheetHref);
|
|
448
|
-
}
|
|
449
|
-
return ruleStringified;
|
|
450
|
-
}
|
|
451
|
-
}
|
|
452
|
-
function fixSafariColons(cssStringified) {
|
|
453
|
-
const regex = /(\[(?:[\w-]+)[^\\])(:(?:[\w-]+)\])/gm;
|
|
454
|
-
return cssStringified.replace(regex, "$1\\$2");
|
|
455
|
-
}
|
|
456
|
-
function isCSSImportRule(rule2) {
|
|
457
|
-
return "styleSheet" in rule2;
|
|
458
|
-
}
|
|
459
|
-
function isCSSStyleRule(rule2) {
|
|
460
|
-
return "selectorText" in rule2;
|
|
461
|
-
}
|
|
462
462
|
function extractOrigin(url) {
|
|
463
463
|
let origin = "";
|
|
464
464
|
if (url.indexOf("//") > -1) {
|
|
@@ -507,6 +507,36 @@ function absolutifyURLs(cssText, href) {
|
|
|
507
507
|
}
|
|
508
508
|
);
|
|
509
509
|
}
|
|
510
|
+
const STRIPED_PLACEHOLDER_SVG = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgogIDxkZWZzPgogICAgPHBhdHRlcm4gaWQ9InN0cmlwZXMiIHBhdHRlcm5Vbml0cz0idXNlclNwYWNlT25Vc2UiIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiI+CiAgICAgIDxyZWN0IHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgZmlsbD0iYmxhY2siLz4KICAgICAgPHBhdGggZD0iTTggMEgxNkwwIDE2VjhMOCAwWiIgZmlsbD0iIzJEMkQyRCIvPgogICAgICA8cGF0aCBkPSJNMTYgOFYxNkg4TDE2IDhaIiBmaWxsPSIjMkQyRDJEIi8+CiAgICA8L3BhdHRlcm4+CiAgPC9kZWZzPgogIDxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjc3RyaXBlcykiLz4KPC9zdmc+Cg==";
|
|
511
|
+
const MAX_IMAGE_DIMENSION_FOR_RECOMPRESSION = 4096;
|
|
512
|
+
function recompressBase64Image(img, dataURL, type, quality) {
|
|
513
|
+
if (!img.complete || img.naturalWidth === 0) {
|
|
514
|
+
return dataURL;
|
|
515
|
+
}
|
|
516
|
+
if (img.naturalWidth > MAX_IMAGE_DIMENSION_FOR_RECOMPRESSION || img.naturalHeight > MAX_IMAGE_DIMENSION_FOR_RECOMPRESSION) {
|
|
517
|
+
return dataURL;
|
|
518
|
+
}
|
|
519
|
+
try {
|
|
520
|
+
const canvas = document.createElement("canvas");
|
|
521
|
+
canvas.width = img.naturalWidth;
|
|
522
|
+
canvas.height = img.naturalHeight;
|
|
523
|
+
const ctx = canvas.getContext("2d");
|
|
524
|
+
if (!ctx) {
|
|
525
|
+
return dataURL;
|
|
526
|
+
}
|
|
527
|
+
ctx.drawImage(img, 0, 0);
|
|
528
|
+
const recompressed = canvas.toDataURL(type || "image/webp", quality != null ? quality : 0.4);
|
|
529
|
+
return recompressed;
|
|
530
|
+
} catch (err) {
|
|
531
|
+
return dataURL;
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
function checkDataURLSize(dataURL, maxLength) {
|
|
535
|
+
if (!maxLength || dataURL.length <= maxLength) {
|
|
536
|
+
return dataURL;
|
|
537
|
+
}
|
|
538
|
+
return STRIPED_PLACEHOLDER_SVG;
|
|
539
|
+
}
|
|
510
540
|
let _id = 1;
|
|
511
541
|
const tagNameRegex = new RegExp("[^a-z0-9-_:]");
|
|
512
542
|
const IGNORED_NODE = -2;
|
|
@@ -605,12 +635,32 @@ function getHref(doc, customHref) {
|
|
|
605
635
|
a2.setAttribute("href", customHref);
|
|
606
636
|
return a2.href;
|
|
607
637
|
}
|
|
608
|
-
function transformAttribute(doc, tagName, name, value) {
|
|
638
|
+
function transformAttribute(doc, tagName, name, value, element, dataURLOptions) {
|
|
609
639
|
if (!value) {
|
|
610
640
|
return value;
|
|
611
641
|
}
|
|
612
642
|
if (name === "src" || name === "href" && !(tagName === "use" && value[0] === "#")) {
|
|
613
|
-
|
|
643
|
+
const transformedValue = absoluteToDoc(doc, value);
|
|
644
|
+
if (tagName === "img" && transformedValue.startsWith("data:") && element) {
|
|
645
|
+
const img = element;
|
|
646
|
+
let processedDataURL = transformedValue;
|
|
647
|
+
if ((dataURLOptions == null ? void 0 : dataURLOptions.type) || (dataURLOptions == null ? void 0 : dataURLOptions.quality) !== void 0) {
|
|
648
|
+
processedDataURL = recompressBase64Image(
|
|
649
|
+
img,
|
|
650
|
+
transformedValue,
|
|
651
|
+
dataURLOptions.type,
|
|
652
|
+
dataURLOptions.quality
|
|
653
|
+
);
|
|
654
|
+
}
|
|
655
|
+
if (dataURLOptions == null ? void 0 : dataURLOptions.maxBase64ImageLength) {
|
|
656
|
+
processedDataURL = checkDataURLSize(
|
|
657
|
+
processedDataURL,
|
|
658
|
+
dataURLOptions.maxBase64ImageLength
|
|
659
|
+
);
|
|
660
|
+
}
|
|
661
|
+
return processedDataURL;
|
|
662
|
+
}
|
|
663
|
+
return transformedValue;
|
|
614
664
|
} else if (name === "xlink:href" && value[0] !== "#") {
|
|
615
665
|
return absoluteToDoc(doc, value);
|
|
616
666
|
} else if (name === "background" && (tagName === "table" || tagName === "td" || tagName === "th")) {
|
|
@@ -901,7 +951,9 @@ function serializeElementNode(n2, options) {
|
|
|
901
951
|
doc,
|
|
902
952
|
tagName,
|
|
903
953
|
toLowerCase(attr.name),
|
|
904
|
-
attr.value
|
|
954
|
+
attr.value,
|
|
955
|
+
n2,
|
|
956
|
+
dataURLOptions
|
|
905
957
|
);
|
|
906
958
|
}
|
|
907
959
|
}
|
|
@@ -10178,7 +10230,9 @@ class MutationBuffer {
|
|
|
10178
10230
|
this.doc,
|
|
10179
10231
|
toLowerCase(target.tagName),
|
|
10180
10232
|
toLowerCase(attributeName),
|
|
10181
|
-
value
|
|
10233
|
+
value,
|
|
10234
|
+
target,
|
|
10235
|
+
this.dataURLOptions
|
|
10182
10236
|
);
|
|
10183
10237
|
if (attributeName === "style") {
|
|
10184
10238
|
if (!this.unattachedDoc) {
|
|
@@ -10337,6 +10391,11 @@ class MutationBuffer {
|
|
|
10337
10391
|
this.shadowDomManager.reset();
|
|
10338
10392
|
this.canvasManager.reset();
|
|
10339
10393
|
}
|
|
10394
|
+
destroy() {
|
|
10395
|
+
while (this.mapRemoves.length) {
|
|
10396
|
+
this.mirror.removeNodeFromMap(this.mapRemoves.shift());
|
|
10397
|
+
}
|
|
10398
|
+
}
|
|
10340
10399
|
}
|
|
10341
10400
|
function deepDelete(addsSet, n2) {
|
|
10342
10401
|
addsSet.delete(n2);
|
|
@@ -11381,6 +11440,7 @@ function initObservers(o2, hooks = {}) {
|
|
|
11381
11440
|
);
|
|
11382
11441
|
}
|
|
11383
11442
|
return callbackWrapper(() => {
|
|
11443
|
+
mutationBuffers.forEach((b) => b.destroy());
|
|
11384
11444
|
mutationBuffers.forEach((b) => b.reset());
|
|
11385
11445
|
mutationObserver == null ? void 0 : mutationObserver.disconnect();
|
|
11386
11446
|
mousemoveHandler();
|
|
@@ -11718,6 +11778,8 @@ class IframeManager {
|
|
|
11718
11778
|
contentWindow.removeEventListener("message", handler);
|
|
11719
11779
|
});
|
|
11720
11780
|
this.nestedIframeListeners.clear();
|
|
11781
|
+
this.crossOriginIframeMirror.reset();
|
|
11782
|
+
this.crossOriginIframeStyleMirror.reset();
|
|
11721
11783
|
}
|
|
11722
11784
|
}
|
|
11723
11785
|
class ShadowDomManager {
|
|
@@ -12174,6 +12236,8 @@ class CanvasManager {
|
|
|
12174
12236
|
__publicField(this, "resetObservers");
|
|
12175
12237
|
__publicField(this, "frozen", false);
|
|
12176
12238
|
__publicField(this, "locked", false);
|
|
12239
|
+
__publicField(this, "rafIdTimestamp", null);
|
|
12240
|
+
__publicField(this, "rafIdFlush", null);
|
|
12177
12241
|
__publicField(this, "processMutation", (target, mutation) => {
|
|
12178
12242
|
const newFrame = this.rafStamps.invokeId && this.rafStamps.latestId !== this.rafStamps.invokeId;
|
|
12179
12243
|
if (newFrame || !this.rafStamps.invokeId)
|
|
@@ -12208,6 +12272,14 @@ class CanvasManager {
|
|
|
12208
12272
|
reset() {
|
|
12209
12273
|
this.pendingCanvasMutations.clear();
|
|
12210
12274
|
this.resetObservers && this.resetObservers();
|
|
12275
|
+
if (this.rafIdTimestamp !== null) {
|
|
12276
|
+
cancelAnimationFrame(this.rafIdTimestamp);
|
|
12277
|
+
this.rafIdTimestamp = null;
|
|
12278
|
+
}
|
|
12279
|
+
if (this.rafIdFlush !== null) {
|
|
12280
|
+
cancelAnimationFrame(this.rafIdFlush);
|
|
12281
|
+
this.rafIdFlush = null;
|
|
12282
|
+
}
|
|
12211
12283
|
}
|
|
12212
12284
|
freeze() {
|
|
12213
12285
|
this.frozen = true;
|
|
@@ -12358,14 +12430,16 @@ class CanvasManager {
|
|
|
12358
12430
|
};
|
|
12359
12431
|
}
|
|
12360
12432
|
startPendingCanvasMutationFlusher() {
|
|
12361
|
-
|
|
12433
|
+
this.rafIdFlush = requestAnimationFrame(
|
|
12434
|
+
() => this.flushPendingCanvasMutations()
|
|
12435
|
+
);
|
|
12362
12436
|
}
|
|
12363
12437
|
startRAFTimestamping() {
|
|
12364
12438
|
const setLatestRAFTimestamp = (timestamp) => {
|
|
12365
12439
|
this.rafStamps.latestId = timestamp;
|
|
12366
|
-
requestAnimationFrame(setLatestRAFTimestamp);
|
|
12440
|
+
this.rafIdTimestamp = requestAnimationFrame(setLatestRAFTimestamp);
|
|
12367
12441
|
};
|
|
12368
|
-
requestAnimationFrame(setLatestRAFTimestamp);
|
|
12442
|
+
this.rafIdTimestamp = requestAnimationFrame(setLatestRAFTimestamp);
|
|
12369
12443
|
}
|
|
12370
12444
|
flushPendingCanvasMutations() {
|
|
12371
12445
|
this.pendingCanvasMutations.forEach(
|
|
@@ -12374,7 +12448,9 @@ class CanvasManager {
|
|
|
12374
12448
|
this.flushPendingCanvasMutationFor(canvas, id);
|
|
12375
12449
|
}
|
|
12376
12450
|
);
|
|
12377
|
-
|
|
12451
|
+
this.rafIdFlush = requestAnimationFrame(
|
|
12452
|
+
() => this.flushPendingCanvasMutations()
|
|
12453
|
+
);
|
|
12378
12454
|
}
|
|
12379
12455
|
flushPendingCanvasMutationFor(canvas, id) {
|
|
12380
12456
|
if (this.frozen || this.locked) {
|
|
@@ -12509,7 +12585,7 @@ function record(options = {}) {
|
|
|
12509
12585
|
hooks,
|
|
12510
12586
|
packFn,
|
|
12511
12587
|
sampling = {},
|
|
12512
|
-
dataURLOptions = {},
|
|
12588
|
+
dataURLOptions: _dataURLOptions = {},
|
|
12513
12589
|
mousemoveWait,
|
|
12514
12590
|
recordDOM = true,
|
|
12515
12591
|
recordCanvas = false,
|
|
@@ -12524,6 +12600,11 @@ function record(options = {}) {
|
|
|
12524
12600
|
errorHandler: errorHandler2
|
|
12525
12601
|
} = options;
|
|
12526
12602
|
registerErrorHandler(errorHandler2);
|
|
12603
|
+
const dataURLOptions = __spreadValues({
|
|
12604
|
+
type: "image/webp",
|
|
12605
|
+
quality: 0.4,
|
|
12606
|
+
maxBase64ImageLength: 1048576
|
|
12607
|
+
}, _dataURLOptions);
|
|
12527
12608
|
const inEmittingFrame = recordCrossOriginIframes ? window.parent === window : true;
|
|
12528
12609
|
let passEmitsToParent = false;
|
|
12529
12610
|
if (!inEmittingFrame) {
|
|
@@ -12940,6 +13021,7 @@ function record(options = {}) {
|
|
|
12940
13021
|
processedNodeManager.destroy();
|
|
12941
13022
|
iframeManager.removeLoadListener();
|
|
12942
13023
|
iframeManager.destroy();
|
|
13024
|
+
mirror.reset();
|
|
12943
13025
|
recording = false;
|
|
12944
13026
|
unregisterErrorHandler();
|
|
12945
13027
|
};
|