@posthog/rrweb-snapshot 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/index.d.cts +5 -1
- package/dist/index.d.ts +5 -1
- package/dist/rrweb-snapshot.cjs +167 -113
- package/dist/rrweb-snapshot.cjs.map +1 -1
- package/dist/rrweb-snapshot.js +167 -113
- package/dist/rrweb-snapshot.js.map +1 -1
- package/dist/rrweb-snapshot.umd.cjs +167 -113
- package/dist/rrweb-snapshot.umd.cjs.map +4 -4
- package/dist/rrweb-snapshot.umd.min.cjs +23 -23
- package/dist/rrweb-snapshot.umd.min.cjs.map +4 -4
- package/package.json +1 -1
|
@@ -247,6 +247,91 @@ function isShadowRoot(n) {
|
|
|
247
247
|
function isNativeShadowDom(shadowRoot2) {
|
|
248
248
|
return Object.prototype.toString.call(shadowRoot2) === "[object ShadowRoot]";
|
|
249
249
|
}
|
|
250
|
+
function fixBrowserCompatibilityIssuesInCSS(cssText) {
|
|
251
|
+
if (cssText.includes(" background-clip: text;") && !cssText.includes(" -webkit-background-clip: text;")) {
|
|
252
|
+
cssText = cssText.replace(
|
|
253
|
+
/\sbackground-clip:\s*text;/g,
|
|
254
|
+
" -webkit-background-clip: text; background-clip: text;"
|
|
255
|
+
);
|
|
256
|
+
}
|
|
257
|
+
return cssText;
|
|
258
|
+
}
|
|
259
|
+
function escapeImportStatement(rule2) {
|
|
260
|
+
const { cssText } = rule2;
|
|
261
|
+
if (cssText.split('"').length < 3) return cssText;
|
|
262
|
+
const statement = ["@import", `url(${JSON.stringify(rule2.href)})`];
|
|
263
|
+
if (rule2.layerName === "") {
|
|
264
|
+
statement.push(`layer`);
|
|
265
|
+
} else if (rule2.layerName) {
|
|
266
|
+
statement.push(`layer(${rule2.layerName})`);
|
|
267
|
+
}
|
|
268
|
+
if (rule2.supportsText) {
|
|
269
|
+
statement.push(`supports(${rule2.supportsText})`);
|
|
270
|
+
}
|
|
271
|
+
if (rule2.media.length) {
|
|
272
|
+
statement.push(rule2.media.mediaText);
|
|
273
|
+
}
|
|
274
|
+
return statement.join(" ") + ";";
|
|
275
|
+
}
|
|
276
|
+
function stringifyStylesheet(s) {
|
|
277
|
+
try {
|
|
278
|
+
const rules = s.rules || s.cssRules;
|
|
279
|
+
if (!rules) {
|
|
280
|
+
return null;
|
|
281
|
+
}
|
|
282
|
+
let sheetHref = s.href;
|
|
283
|
+
if (!sheetHref && s.ownerNode) {
|
|
284
|
+
sheetHref = s.ownerNode.baseURI;
|
|
285
|
+
}
|
|
286
|
+
const stringifiedRules = Array.from(
|
|
287
|
+
rules,
|
|
288
|
+
(rule2) => stringifyRule(rule2, sheetHref)
|
|
289
|
+
).join("");
|
|
290
|
+
return fixBrowserCompatibilityIssuesInCSS(stringifiedRules);
|
|
291
|
+
} catch (error) {
|
|
292
|
+
return null;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
function stringifyRule(rule2, sheetHref) {
|
|
296
|
+
var _a;
|
|
297
|
+
if (isCSSImportRule(rule2)) {
|
|
298
|
+
let importStringified;
|
|
299
|
+
try {
|
|
300
|
+
importStringified = // for same-origin stylesheets,
|
|
301
|
+
// we can access the imported stylesheet rules directly
|
|
302
|
+
stringifyStylesheet(rule2.styleSheet) || // work around browser issues with the raw string `@import url(...)` statement
|
|
303
|
+
escapeImportStatement(rule2);
|
|
304
|
+
} catch (error) {
|
|
305
|
+
importStringified = rule2.cssText;
|
|
306
|
+
}
|
|
307
|
+
try {
|
|
308
|
+
if (importStringified && ((_a = rule2.styleSheet) == null ? void 0 : _a.href)) {
|
|
309
|
+
return absolutifyURLs(importStringified, rule2.styleSheet.href);
|
|
310
|
+
}
|
|
311
|
+
} catch (e) {
|
|
312
|
+
}
|
|
313
|
+
return importStringified;
|
|
314
|
+
} else {
|
|
315
|
+
let ruleStringified = rule2.cssText;
|
|
316
|
+
if (isCSSStyleRule(rule2) && rule2.selectorText.includes(":")) {
|
|
317
|
+
ruleStringified = fixSafariColons(ruleStringified);
|
|
318
|
+
}
|
|
319
|
+
if (sheetHref) {
|
|
320
|
+
return absolutifyURLs(ruleStringified, sheetHref);
|
|
321
|
+
}
|
|
322
|
+
return ruleStringified;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
function fixSafariColons(cssStringified) {
|
|
326
|
+
const regex = /(\[(?:[\w-]+)[^\\])(:(?:[\w-]+)\])/gm;
|
|
327
|
+
return cssStringified.replace(regex, "$1\\$2");
|
|
328
|
+
}
|
|
329
|
+
function isCSSImportRule(rule2) {
|
|
330
|
+
return "styleSheet" in rule2;
|
|
331
|
+
}
|
|
332
|
+
function isCSSStyleRule(rule2) {
|
|
333
|
+
return "selectorText" in rule2;
|
|
334
|
+
}
|
|
250
335
|
class Mirror {
|
|
251
336
|
constructor() {
|
|
252
337
|
__publicField(this, "idNodeMap", /* @__PURE__ */ new Map());
|
|
@@ -382,91 +467,6 @@ function extractFileExtension(path, baseURL) {
|
|
|
382
467
|
const match = url.pathname.match(regex);
|
|
383
468
|
return (_a = match == null ? void 0 : match[1]) != null ? _a : null;
|
|
384
469
|
}
|
|
385
|
-
function fixBrowserCompatibilityIssuesInCSS(cssText) {
|
|
386
|
-
if (cssText.includes(" background-clip: text;") && !cssText.includes(" -webkit-background-clip: text;")) {
|
|
387
|
-
cssText = cssText.replace(
|
|
388
|
-
/\sbackground-clip:\s*text;/g,
|
|
389
|
-
" -webkit-background-clip: text; background-clip: text;"
|
|
390
|
-
);
|
|
391
|
-
}
|
|
392
|
-
return cssText;
|
|
393
|
-
}
|
|
394
|
-
function escapeImportStatement(rule2) {
|
|
395
|
-
const { cssText } = rule2;
|
|
396
|
-
if (cssText.split('"').length < 3) return cssText;
|
|
397
|
-
const statement = ["@import", `url(${JSON.stringify(rule2.href)})`];
|
|
398
|
-
if (rule2.layerName === "") {
|
|
399
|
-
statement.push(`layer`);
|
|
400
|
-
} else if (rule2.layerName) {
|
|
401
|
-
statement.push(`layer(${rule2.layerName})`);
|
|
402
|
-
}
|
|
403
|
-
if (rule2.supportsText) {
|
|
404
|
-
statement.push(`supports(${rule2.supportsText})`);
|
|
405
|
-
}
|
|
406
|
-
if (rule2.media.length) {
|
|
407
|
-
statement.push(rule2.media.mediaText);
|
|
408
|
-
}
|
|
409
|
-
return statement.join(" ") + ";";
|
|
410
|
-
}
|
|
411
|
-
function stringifyStylesheet(s) {
|
|
412
|
-
try {
|
|
413
|
-
const rules = s.rules || s.cssRules;
|
|
414
|
-
if (!rules) {
|
|
415
|
-
return null;
|
|
416
|
-
}
|
|
417
|
-
let sheetHref = s.href;
|
|
418
|
-
if (!sheetHref && s.ownerNode) {
|
|
419
|
-
sheetHref = s.ownerNode.baseURI;
|
|
420
|
-
}
|
|
421
|
-
const stringifiedRules = Array.from(
|
|
422
|
-
rules,
|
|
423
|
-
(rule2) => stringifyRule(rule2, sheetHref)
|
|
424
|
-
).join("");
|
|
425
|
-
return fixBrowserCompatibilityIssuesInCSS(stringifiedRules);
|
|
426
|
-
} catch (error) {
|
|
427
|
-
return null;
|
|
428
|
-
}
|
|
429
|
-
}
|
|
430
|
-
function stringifyRule(rule2, sheetHref) {
|
|
431
|
-
var _a;
|
|
432
|
-
if (isCSSImportRule(rule2)) {
|
|
433
|
-
let importStringified;
|
|
434
|
-
try {
|
|
435
|
-
importStringified = // for same-origin stylesheets,
|
|
436
|
-
// we can access the imported stylesheet rules directly
|
|
437
|
-
stringifyStylesheet(rule2.styleSheet) || // work around browser issues with the raw string `@import url(...)` statement
|
|
438
|
-
escapeImportStatement(rule2);
|
|
439
|
-
} catch (error) {
|
|
440
|
-
importStringified = rule2.cssText;
|
|
441
|
-
}
|
|
442
|
-
try {
|
|
443
|
-
if (importStringified && ((_a = rule2.styleSheet) == null ? void 0 : _a.href)) {
|
|
444
|
-
return absolutifyURLs(importStringified, rule2.styleSheet.href);
|
|
445
|
-
}
|
|
446
|
-
} catch (e) {
|
|
447
|
-
}
|
|
448
|
-
return importStringified;
|
|
449
|
-
} else {
|
|
450
|
-
let ruleStringified = rule2.cssText;
|
|
451
|
-
if (isCSSStyleRule(rule2) && rule2.selectorText.includes(":")) {
|
|
452
|
-
ruleStringified = fixSafariColons(ruleStringified);
|
|
453
|
-
}
|
|
454
|
-
if (sheetHref) {
|
|
455
|
-
return absolutifyURLs(ruleStringified, sheetHref);
|
|
456
|
-
}
|
|
457
|
-
return ruleStringified;
|
|
458
|
-
}
|
|
459
|
-
}
|
|
460
|
-
function fixSafariColons(cssStringified) {
|
|
461
|
-
const regex = /(\[(?:[\w-]+)[^\\])(:(?:[\w-]+)\])/gm;
|
|
462
|
-
return cssStringified.replace(regex, "$1\\$2");
|
|
463
|
-
}
|
|
464
|
-
function isCSSImportRule(rule2) {
|
|
465
|
-
return "styleSheet" in rule2;
|
|
466
|
-
}
|
|
467
|
-
function isCSSStyleRule(rule2) {
|
|
468
|
-
return "selectorText" in rule2;
|
|
469
|
-
}
|
|
470
470
|
function extractOrigin(url) {
|
|
471
471
|
let origin = "";
|
|
472
472
|
if (url.indexOf("//") > -1) {
|
|
@@ -515,6 +515,36 @@ function absolutifyURLs(cssText, href) {
|
|
|
515
515
|
}
|
|
516
516
|
);
|
|
517
517
|
}
|
|
518
|
+
const STRIPED_PLACEHOLDER_SVG = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgogIDxkZWZzPgogICAgPHBhdHRlcm4gaWQ9InN0cmlwZXMiIHBhdHRlcm5Vbml0cz0idXNlclNwYWNlT25Vc2UiIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiI+CiAgICAgIDxyZWN0IHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgZmlsbD0iYmxhY2siLz4KICAgICAgPHBhdGggZD0iTTggMEgxNkwwIDE2VjhMOCAwWiIgZmlsbD0iIzJEMkQyRCIvPgogICAgICA8cGF0aCBkPSJNMTYgOFYxNkg4TDE2IDhaIiBmaWxsPSIjMkQyRDJEIi8+CiAgICA8L3BhdHRlcm4+CiAgPC9kZWZzPgogIDxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjc3RyaXBlcykiLz4KPC9zdmc+Cg==";
|
|
519
|
+
const MAX_IMAGE_DIMENSION_FOR_RECOMPRESSION = 4096;
|
|
520
|
+
function recompressBase64Image(img, dataURL, type, quality) {
|
|
521
|
+
if (!img.complete || img.naturalWidth === 0) {
|
|
522
|
+
return dataURL;
|
|
523
|
+
}
|
|
524
|
+
if (img.naturalWidth > MAX_IMAGE_DIMENSION_FOR_RECOMPRESSION || img.naturalHeight > MAX_IMAGE_DIMENSION_FOR_RECOMPRESSION) {
|
|
525
|
+
return dataURL;
|
|
526
|
+
}
|
|
527
|
+
try {
|
|
528
|
+
const canvas = document.createElement("canvas");
|
|
529
|
+
canvas.width = img.naturalWidth;
|
|
530
|
+
canvas.height = img.naturalHeight;
|
|
531
|
+
const ctx = canvas.getContext("2d");
|
|
532
|
+
if (!ctx) {
|
|
533
|
+
return dataURL;
|
|
534
|
+
}
|
|
535
|
+
ctx.drawImage(img, 0, 0);
|
|
536
|
+
const recompressed = canvas.toDataURL(type || "image/webp", quality != null ? quality : 0.4);
|
|
537
|
+
return recompressed;
|
|
538
|
+
} catch (err) {
|
|
539
|
+
return dataURL;
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
function checkDataURLSize(dataURL, maxLength) {
|
|
543
|
+
if (!maxLength || dataURL.length <= maxLength) {
|
|
544
|
+
return dataURL;
|
|
545
|
+
}
|
|
546
|
+
return STRIPED_PLACEHOLDER_SVG;
|
|
547
|
+
}
|
|
518
548
|
let _id = 1;
|
|
519
549
|
const tagNameRegex = new RegExp("[^a-z0-9-_:]");
|
|
520
550
|
const IGNORED_NODE = -2;
|
|
@@ -613,12 +643,32 @@ function getHref(doc, customHref) {
|
|
|
613
643
|
a.setAttribute("href", customHref);
|
|
614
644
|
return a.href;
|
|
615
645
|
}
|
|
616
|
-
function transformAttribute(doc, tagName, name, value) {
|
|
646
|
+
function transformAttribute(doc, tagName, name, value, element, dataURLOptions) {
|
|
617
647
|
if (!value) {
|
|
618
648
|
return value;
|
|
619
649
|
}
|
|
620
650
|
if (name === "src" || name === "href" && !(tagName === "use" && value[0] === "#")) {
|
|
621
|
-
|
|
651
|
+
const transformedValue = absoluteToDoc(doc, value);
|
|
652
|
+
if (tagName === "img" && transformedValue.startsWith("data:") && element) {
|
|
653
|
+
const img = element;
|
|
654
|
+
let processedDataURL = transformedValue;
|
|
655
|
+
if ((dataURLOptions == null ? void 0 : dataURLOptions.type) || (dataURLOptions == null ? void 0 : dataURLOptions.quality) !== void 0) {
|
|
656
|
+
processedDataURL = recompressBase64Image(
|
|
657
|
+
img,
|
|
658
|
+
transformedValue,
|
|
659
|
+
dataURLOptions.type,
|
|
660
|
+
dataURLOptions.quality
|
|
661
|
+
);
|
|
662
|
+
}
|
|
663
|
+
if (dataURLOptions == null ? void 0 : dataURLOptions.maxBase64ImageLength) {
|
|
664
|
+
processedDataURL = checkDataURLSize(
|
|
665
|
+
processedDataURL,
|
|
666
|
+
dataURLOptions.maxBase64ImageLength
|
|
667
|
+
);
|
|
668
|
+
}
|
|
669
|
+
return processedDataURL;
|
|
670
|
+
}
|
|
671
|
+
return transformedValue;
|
|
622
672
|
} else if (name === "xlink:href" && value[0] !== "#") {
|
|
623
673
|
return absoluteToDoc(doc, value);
|
|
624
674
|
} else if (name === "background" && (tagName === "table" || tagName === "td" || tagName === "th")) {
|
|
@@ -909,7 +959,9 @@ function serializeElementNode(n, options) {
|
|
|
909
959
|
doc,
|
|
910
960
|
tagName,
|
|
911
961
|
toLowerCase(attr.name),
|
|
912
|
-
attr.value
|
|
962
|
+
attr.value,
|
|
963
|
+
n,
|
|
964
|
+
dataURLOptions
|
|
913
965
|
);
|
|
914
966
|
}
|
|
915
967
|
}
|
|
@@ -1438,15 +1490,6 @@ function visitSnapshot(node2, onVisit) {
|
|
|
1438
1490
|
function cleanupSnapshot() {
|
|
1439
1491
|
_id = 1;
|
|
1440
1492
|
}
|
|
1441
|
-
var NodeType = /* @__PURE__ */ ((NodeType2) => {
|
|
1442
|
-
NodeType2[NodeType2["Document"] = 0] = "Document";
|
|
1443
|
-
NodeType2[NodeType2["DocumentType"] = 1] = "DocumentType";
|
|
1444
|
-
NodeType2[NodeType2["Element"] = 2] = "Element";
|
|
1445
|
-
NodeType2[NodeType2["Text"] = 3] = "Text";
|
|
1446
|
-
NodeType2[NodeType2["CDATA"] = 4] = "CDATA";
|
|
1447
|
-
NodeType2[NodeType2["Comment"] = 5] = "Comment";
|
|
1448
|
-
return NodeType2;
|
|
1449
|
-
})(NodeType || {});
|
|
1450
1493
|
const MEDIA_SELECTOR = /(max|min)-device-(width|height)/;
|
|
1451
1494
|
const MEDIA_SELECTOR_GLOBAL = new RegExp(MEDIA_SELECTOR.source, "g");
|
|
1452
1495
|
const mediaSelectorPlugin = {
|
|
@@ -5367,6 +5410,15 @@ function requireSafeParse() {
|
|
|
5367
5410
|
}
|
|
5368
5411
|
var safeParseExports = requireSafeParse();
|
|
5369
5412
|
const safeParser = /* @__PURE__ */ getDefaultExportFromCjs(safeParseExports);
|
|
5413
|
+
var NodeType = /* @__PURE__ */ ((NodeType2) => {
|
|
5414
|
+
NodeType2[NodeType2["Document"] = 0] = "Document";
|
|
5415
|
+
NodeType2[NodeType2["DocumentType"] = 1] = "DocumentType";
|
|
5416
|
+
NodeType2[NodeType2["Element"] = 2] = "Element";
|
|
5417
|
+
NodeType2[NodeType2["Text"] = 3] = "Text";
|
|
5418
|
+
NodeType2[NodeType2["CDATA"] = 4] = "CDATA";
|
|
5419
|
+
NodeType2[NodeType2["Comment"] = 5] = "Comment";
|
|
5420
|
+
return NodeType2;
|
|
5421
|
+
})(NodeType || {});
|
|
5370
5422
|
var postcssExports = requirePostcss();
|
|
5371
5423
|
const postcss = /* @__PURE__ */ getDefaultExportFromCjs(postcssExports);
|
|
5372
5424
|
postcss.stringify;
|
|
@@ -5393,22 +5445,6 @@ postcss.Input;
|
|
|
5393
5445
|
postcss.Rule;
|
|
5394
5446
|
postcss.Root;
|
|
5395
5447
|
postcss.Node;
|
|
5396
|
-
function adaptCssForReplay(cssText, cache) {
|
|
5397
|
-
const cachedStyle = cache == null ? void 0 : cache.stylesWithHoverClass.get(cssText);
|
|
5398
|
-
if (cachedStyle) return cachedStyle;
|
|
5399
|
-
let result2 = cssText;
|
|
5400
|
-
try {
|
|
5401
|
-
const ast = postcss([
|
|
5402
|
-
mediaSelectorPlugin,
|
|
5403
|
-
pseudoClassPlugin
|
|
5404
|
-
]).process(cssText, { parser: safeParser });
|
|
5405
|
-
result2 = ast.css;
|
|
5406
|
-
} catch (error) {
|
|
5407
|
-
console.warn("Failed to adapt css for replay", error);
|
|
5408
|
-
}
|
|
5409
|
-
cache == null ? void 0 : cache.stylesWithHoverClass.set(cssText, result2);
|
|
5410
|
-
return result2;
|
|
5411
|
-
}
|
|
5412
5448
|
const tagMap = {
|
|
5413
5449
|
script: "noscript",
|
|
5414
5450
|
// camel case svg element tag names
|
|
@@ -5456,6 +5492,22 @@ function getTagName(n) {
|
|
|
5456
5492
|
}
|
|
5457
5493
|
return tagName;
|
|
5458
5494
|
}
|
|
5495
|
+
function adaptCssForReplay(cssText, cache) {
|
|
5496
|
+
const cachedStyle = cache == null ? void 0 : cache.stylesWithHoverClass.get(cssText);
|
|
5497
|
+
if (cachedStyle) return cachedStyle;
|
|
5498
|
+
let result2 = cssText;
|
|
5499
|
+
try {
|
|
5500
|
+
const ast = postcss([
|
|
5501
|
+
mediaSelectorPlugin,
|
|
5502
|
+
pseudoClassPlugin
|
|
5503
|
+
]).process(cssText, { parser: safeParser });
|
|
5504
|
+
result2 = ast.css;
|
|
5505
|
+
} catch (error) {
|
|
5506
|
+
console.warn("Failed to adapt css for replay", error);
|
|
5507
|
+
}
|
|
5508
|
+
cache == null ? void 0 : cache.stylesWithHoverClass.set(cssText, result2);
|
|
5509
|
+
return result2;
|
|
5510
|
+
}
|
|
5459
5511
|
function createCache() {
|
|
5460
5512
|
const stylesWithHoverClass = /* @__PURE__ */ new Map();
|
|
5461
5513
|
return {
|
|
@@ -5779,6 +5831,7 @@ exports.NodeType = NodeType;
|
|
|
5779
5831
|
exports.absolutifyURLs = absolutifyURLs;
|
|
5780
5832
|
exports.adaptCssForReplay = adaptCssForReplay;
|
|
5781
5833
|
exports.buildNodeWithSN = buildNodeWithSN;
|
|
5834
|
+
exports.checkDataURLSize = checkDataURLSize;
|
|
5782
5835
|
exports.classMatchesRegex = classMatchesRegex;
|
|
5783
5836
|
exports.cleanupSnapshot = cleanupSnapshot;
|
|
5784
5837
|
exports.createCache = createCache;
|
|
@@ -5799,6 +5852,7 @@ exports.isShadowRoot = isShadowRoot;
|
|
|
5799
5852
|
exports.maskInputValue = maskInputValue;
|
|
5800
5853
|
exports.needMaskingText = needMaskingText;
|
|
5801
5854
|
exports.rebuild = rebuild;
|
|
5855
|
+
exports.recompressBase64Image = recompressBase64Image;
|
|
5802
5856
|
exports.serializeNodeWithId = serializeNodeWithId;
|
|
5803
5857
|
exports.snapshot = snapshot;
|
|
5804
5858
|
exports.stringifyRule = stringifyRule;
|