diff --git a/.changeset/small-olives-arrive.md b/.changeset/small-olives-arrive.md new file mode 100644 index 0000000000..36bacbc168 --- /dev/null +++ b/.changeset/small-olives-arrive.md @@ -0,0 +1,5 @@ +--- +'rrweb-snapshot': patch +--- + +Fix: [#1172](https://github.com/rrweb-io/rrweb/issues/1172) don't replace original onload function of Images diff --git a/packages/rrweb-snapshot/src/snapshot.ts b/packages/rrweb-snapshot/src/snapshot.ts index 4b88464fd3..dd0bef968a 100644 --- a/packages/rrweb-snapshot/src/snapshot.ts +++ b/packages/rrweb-snapshot/src/snapshot.ts @@ -736,6 +736,7 @@ function serializeElementNode( const oldValue = image.crossOrigin; image.crossOrigin = 'anonymous'; const recordInlineImage = () => { + image.removeEventListener('load', recordInlineImage); try { canvasService!.width = image.naturalWidth; canvasService!.height = image.naturalHeight; @@ -755,7 +756,7 @@ function serializeElementNode( }; // The image content may not have finished loading yet. if (image.complete && image.naturalWidth !== 0) recordInlineImage(); - else image.onload = recordInlineImage; + else image.addEventListener('load', recordInlineImage); } // media elements if (tagName === 'audio' || tagName === 'video') { diff --git a/packages/rrweb-snapshot/test/html/picture-with-inline-onload.html b/packages/rrweb-snapshot/test/html/picture-with-inline-onload.html new file mode 100644 index 0000000000..cc0fed38ef --- /dev/null +++ b/packages/rrweb-snapshot/test/html/picture-with-inline-onload.html @@ -0,0 +1,10 @@ + +
+
+
+
diff --git a/packages/rrweb-snapshot/test/integration.test.ts b/packages/rrweb-snapshot/test/integration.test.ts
index c937726071..dcc6a3ec0b 100644
--- a/packages/rrweb-snapshot/test/integration.test.ts
+++ b/packages/rrweb-snapshot/test/integration.test.ts
@@ -303,6 +303,28 @@ iframe.contentDocument.querySelector('center').clientHeight
)) as string;
assert(snapshot.includes('-webkit-background-clip: text;'));
});
+
+ it('images with inline onload should work', async () => {
+ const page: puppeteer.Page = await browser.newPage();
+
+ await page.goto(
+ 'http://localhost:3030/html/picture-with-inline-onload.html',
+ {
+ waitUntil: 'load',
+ },
+ );
+ await page.waitForSelector('img', { timeout: 1000 });
+ await page.evaluate(`${code}var snapshot = rrweb.snapshot(document, {
+ dataURLOptions: { type: "image/webp", quality: 0.8 },
+ inlineImages: true,
+ inlineStylesheet: false
+ })`);
+ await waitForRAF(page);
+ const fnName = (await page.evaluate(
+ 'document.querySelector("img").onload.name',
+ )) as string;
+ assert(fnName === 'onload');
+ });
});
describe('iframe integration tests', function (this: ISuite) {