From 3255a99b643006d9e1951edd6d206f2a67b776ac Mon Sep 17 00:00:00 2001 From: Eoghan Murray Date: Mon, 22 Apr 2024 18:51:10 +0100 Subject: [PATCH] Don't rename attrs of assets which will be refused according to initial recording config, i.e. the origins don't match. Should make the 'refused' status redundant --- packages/rrweb-snapshot/src/snapshot.ts | 26 ++++++++++++++++- packages/rrweb-snapshot/src/utils.ts | 28 +++++++++++++++++++ packages/rrweb-snapshot/test/snapshot.test.ts | 4 +++ 3 files changed, 57 insertions(+), 1 deletion(-) diff --git a/packages/rrweb-snapshot/src/snapshot.ts b/packages/rrweb-snapshot/src/snapshot.ts index 536bb75b0f..2eef27e81a 100644 --- a/packages/rrweb-snapshot/src/snapshot.ts +++ b/packages/rrweb-snapshot/src/snapshot.ts @@ -16,6 +16,7 @@ import { elementNode, asset, DataURLOptions, + captureAssetsParam, } from '@rrweb/types'; import { Mirror, @@ -29,6 +30,7 @@ import { toLowerCase, extractFileExtension, isAttributeCapturable, + shouldIgnoreAsset, } from './utils'; let _id = 1; @@ -462,6 +464,7 @@ function serializeNode( * @deprecated please use `captureAssets` instead */ inlineImages?: boolean; + captureAssets?: captureAssetsParam; recordCanvas: boolean; keepIframeSrcFn: KeepIframeSrcFn; /** @@ -489,6 +492,10 @@ function serializeNode( maskInputFn, dataURLOptions = {}, inlineImages, + captureAssets = { + objectURLs: true, + origins: false, + }, recordCanvas, keepIframeSrcFn, newlyAddedElement = false, @@ -528,6 +535,7 @@ function serializeNode( maskInputFn, dataURLOptions, inlineImages, + captureAssets, recordCanvas, keepIframeSrcFn, newlyAddedElement, @@ -630,6 +638,7 @@ function serializeElementNode( * @deprecated please use `captureAssets` instead */ inlineImages?: boolean; + captureAssets?: captureAssetsParam; recordCanvas: boolean; keepIframeSrcFn: KeepIframeSrcFn; /** @@ -655,6 +664,10 @@ function serializeElementNode( maskInputFn, dataURLOptions = {}, inlineImages, + captureAssets = { + objectURLs: true, + origins: false, + }, recordCanvas, keepIframeSrcFn, newlyAddedElement = false, @@ -681,7 +694,8 @@ function serializeElementNode( value && typeof value === 'string' && onAssetDetected && - isAttributeCapturable(n, attr.name) + isAttributeCapturable(n, attr.name) && + !shouldIgnoreAsset(attr.value, captureAssets) ) { assets.push({ element: n, @@ -1015,6 +1029,7 @@ export function serializeNodeWithId( * @deprecated please use `captureAssets` instead */ inlineImages?: boolean; + captureAssets?: captureAssetsParam; recordCanvas?: boolean; preserveWhiteSpace?: boolean; onSerialize?: (n: Node) => unknown; @@ -1052,6 +1067,10 @@ export function serializeNodeWithId( slimDOMOptions, dataURLOptions = {}, inlineImages = false, + captureAssets = { + objectURLs: true, + origins: false, + }, recordCanvas = false, onSerialize, onIframeLoad, @@ -1091,6 +1110,7 @@ export function serializeNodeWithId( maskInputFn, dataURLOptions, inlineImages, + captureAssets, recordCanvas, keepIframeSrcFn, newlyAddedElement, @@ -1167,6 +1187,7 @@ export function serializeNodeWithId( slimDOMOptions, dataURLOptions, inlineImages, + captureAssets, recordCanvas, preserveWhiteSpace, onSerialize, @@ -1246,6 +1267,7 @@ export function serializeNodeWithId( slimDOMOptions, dataURLOptions, inlineImages, + captureAssets, recordCanvas, preserveWhiteSpace, onSerialize, @@ -1298,6 +1320,7 @@ export function serializeNodeWithId( slimDOMOptions, dataURLOptions, inlineImages, + captureAssets, recordCanvas, preserveWhiteSpace, onSerialize, @@ -1341,6 +1364,7 @@ function snapshot( * @deprecated please use `captureAssets` instead */ inlineImages?: boolean; + captureAssets?: captureAssetsParam; recordCanvas?: boolean; preserveWhiteSpace?: boolean; onSerialize?: (n: Node) => unknown; diff --git a/packages/rrweb-snapshot/src/utils.ts b/packages/rrweb-snapshot/src/utils.ts index 8bac271fea..ae990c978e 100644 --- a/packages/rrweb-snapshot/src/utils.ts +++ b/packages/rrweb-snapshot/src/utils.ts @@ -9,6 +9,7 @@ import { documentTypeNode, textNode, elementNode, + captureAssetsParam, } from '@rrweb/types'; export function isElement(n: Node): n is Element { @@ -406,3 +407,30 @@ export function isAttributeCapturable(n: Element, attribute: string): boolean { } return acceptedAttributesSet.has(attribute); } + +export function shouldIgnoreAsset( + url: string, + config: captureAssetsParam, +): boolean { + const originsToIgnore = ['data:']; + const urlIsBlob = url.startsWith(`blob:${window.location.origin}/`); + + // Check if url is a blob and we should ignore blobs + if (urlIsBlob) return !config.objectURLs; + + // Check if url matches any ignorable origins + for (const origin of originsToIgnore) { + if (url.startsWith(origin)) return true; + } + + // Check the origins + const captureOrigins = config.origins; + if (typeof captureOrigins === 'boolean') { + return !captureOrigins; + } else if (Array.isArray(captureOrigins)) { + const urlOrigin = new URL(url).origin; + return !captureOrigins.includes(urlOrigin); + } + + return false; +} diff --git a/packages/rrweb-snapshot/test/snapshot.test.ts b/packages/rrweb-snapshot/test/snapshot.test.ts index bf77a0dd2b..f6f4a23c32 100644 --- a/packages/rrweb-snapshot/test/snapshot.test.ts +++ b/packages/rrweb-snapshot/test/snapshot.test.ts @@ -277,6 +277,10 @@ describe('onAssetDetected callback', () => { slimDOMOptions: {}, newlyAddedElement: false, inlineImages: false, + captureAssets: { + objectURLs: true, + origins: ['https://example.com'], + }, onAssetDetected, }); };