Skip to content

Commit

Permalink
Revert "inlineImages: Setting of image.crossOrigin is not always ne…
Browse files Browse the repository at this point in the history
…cessary (rrweb-io#1468)"

This reverts commit 4014305.
  • Loading branch information
vincent-psarga committed Jun 5, 2024
1 parent 4014305 commit fa5a3fd
Show file tree
Hide file tree
Showing 8 changed files with 117 additions and 95 deletions.
6 changes: 0 additions & 6 deletions .changeset/inlineImage-maybeNot-crossOrigin.md

This file was deleted.

27 changes: 8 additions & 19 deletions packages/rrweb-snapshot/src/snapshot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -747,9 +747,8 @@ function serializeElementNode(
canvasCtx = canvasService.getContext('2d');
}
const image = n as HTMLImageElement;
const imageSrc: string =
image.currentSrc || image.getAttribute('src') || '<unknown-src>';
const priorCrossOrigin = image.crossOrigin;
const oldValue = image.crossOrigin;
image.crossOrigin = 'anonymous';
const recordInlineImage = () => {
image.removeEventListener('load', recordInlineImage);
try {
Expand All @@ -761,23 +760,13 @@ function serializeElementNode(
dataURLOptions.quality,
);
} catch (err) {
if (image.crossOrigin !== 'anonymous') {
image.crossOrigin = 'anonymous';
if (image.complete && image.naturalWidth !== 0)
recordInlineImage(); // too early due to image reload
else image.addEventListener('load', recordInlineImage);
return;
} else {
console.warn(
`Cannot inline img src=${imageSrc}! Error: ${err as string}`,
);
}
}
if (image.crossOrigin === 'anonymous') {
priorCrossOrigin
? (attributes.crossOrigin = priorCrossOrigin)
: image.removeAttribute('crossorigin');
console.warn(
`Cannot inline img src=${image.currentSrc}! Error: ${err as string}`,
);
}
oldValue
? (attributes.crossOrigin = oldValue)
: image.removeAttribute('crossorigin');
};
// The image content may not have finished loading yet.
if (image.complete && image.naturalWidth !== 0) recordInlineImage();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,6 @@ exports[`integration tests [html file]: mask-text.html 1`] = `
exports[`integration tests [html file]: picture.html 1`] = `
"<html xmlns=\\"http://www.w3.org/1999/xhtml\\"><head></head><body>
<picture>
<!-- these are 404 - not sure if that's intentional -->
<source type=\\"image/webp\\" srcset=\\"http://localhost:3030/assets/img/characters/robot.webp\\" />
<img src=\\"http://localhost:3030/assets/img/characters/robot.png\\" />
</picture>
Expand Down
1 change: 0 additions & 1 deletion packages/rrweb-snapshot/test/html/picture.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<picture>
<!-- these are 404 - not sure if that's intentional -->
<source type="image/webp" srcset="assets/img/characters/robot.webp" />
<img src="assets/img/characters/robot.png" />
</picture>
Expand Down
Binary file not shown.
65 changes: 7 additions & 58 deletions packages/rrweb-snapshot/test/integration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import * as puppeteer from 'puppeteer';
import * as rollup from 'rollup';
import * as typescript from 'rollup-plugin-typescript2';
import * as assert from 'assert';
import { waitForRAF, getServerURL } from './utils';
import { waitForRAF } from './utils';

const _typescript = typescript as unknown as () => rollup.Plugin;

Expand Down Expand Up @@ -209,63 +209,12 @@ iframe.contentDocument.querySelector('center').clientHeight
inlineImages: true,
inlineStylesheet: false
})`);
// don't wait, as we want to ensure that the same-origin image can be inlined immediately
const bodyChildren = (await page.evaluate(`
snapshot.childNodes[0].childNodes[1].childNodes.filter((cn) => cn.type === 2);
`)) as any[];
expect(bodyChildren[1]).toEqual(
expect.objectContaining({
tagName: 'img',
attributes: {
src: expect.stringMatching(/images\/robot.png$/),
alt: 'This is a robot',
rr_dataURL: expect.stringMatching(/^data:image\/webp;base64,/),
},
}),
);
});

it('correctly saves cross-origin images offline', async () => {
const page: puppeteer.Page = await browser.newPage();

await page.goto('about:blank', {
waitUntil: 'load',
});
await page.setContent(
`
<html xmlns="http://www.w3.org/1999/xhtml">
<body>
<img src="${getServerURL(
server,
)}/images/rrweb-favicon-20x20.png" alt="CORS restricted but has access-control-allow-origin: *" />
</body>
</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); // need a small wait, as after the crossOrigin="anonymous" change, the snapshot triggers a reload of the image (after which, the snapshot is mutated)
const bodyChildren = (await page.evaluate(`
snapshot.childNodes[0].childNodes[1].childNodes.filter((cn) => cn.type === 2);
`)) as any[];
expect(bodyChildren[0]).toEqual(
expect.objectContaining({
tagName: 'img',
attributes: {
src: getServerURL(server) + '/images/rrweb-favicon-20x20.png',
alt: 'CORS restricted but has access-control-allow-origin: *',
rr_dataURL: expect.stringMatching(/^data:image\/webp;base64,/),
},
}),
);
await waitForRAF(page);
const snapshot = (await page.evaluate(
'JSON.stringify(snapshot, null, 2);',
)) as string;
assert(snapshot.includes('"rr_dataURL"'));
assert(snapshot.includes('data:image/webp;base64,'));
});

it('correctly saves blob:images offline', async () => {
Expand Down
10 changes: 0 additions & 10 deletions packages/rrweb-snapshot/test/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import * as puppeteer from 'puppeteer';
import * as http from 'http';

export async function waitForRAF(page: puppeteer.Page) {
return await page.evaluate(() => {
Expand All @@ -10,12 +9,3 @@ export async function waitForRAF(page: puppeteer.Page) {
});
});
}

export function getServerURL(server: http.Server): string {
const address = server.address();
if (address && typeof address !== 'string') {
return `http://localhost:${address.port}`;
} else {
return `${address}`;
}
}
102 changes: 102 additions & 0 deletions packages/rrweb/test/__snapshots__/integration.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -12777,6 +12777,40 @@ exports[`record integration tests should record images inside iframe with blob u
}
]
}
},
{
\\"type\\": 3,
\\"data\\": {
\\"source\\": 0,
\\"texts\\": [],
\\"attributes\\": [
{
\\"id\\": 41,
\\"attributes\\": {
\\"crossorigin\\": \\"anonymous\\"
}
}
],
\\"removes\\": [],
\\"adds\\": []
}
},
{
\\"type\\": 3,
\\"data\\": {
\\"source\\": 0,
\\"texts\\": [],
\\"attributes\\": [
{
\\"id\\": 41,
\\"attributes\\": {
\\"crossorigin\\": null
}
}
],
\\"removes\\": [],
\\"adds\\": []
}
}
]"
`;
Expand Down Expand Up @@ -13211,6 +13245,40 @@ exports[`record integration tests should record images inside iframe with blob u
}
]
}
},
{
\\"type\\": 3,
\\"data\\": {
\\"source\\": 0,
\\"texts\\": [],
\\"attributes\\": [
{
\\"id\\": 47,
\\"attributes\\": {
\\"crossorigin\\": \\"anonymous\\"
}
}
],
\\"removes\\": [],
\\"adds\\": []
}
},
{
\\"type\\": 3,
\\"data\\": {
\\"source\\": 0,
\\"texts\\": [],
\\"attributes\\": [
{
\\"id\\": 47,
\\"attributes\\": {
\\"crossorigin\\": null
}
}
],
\\"removes\\": [],
\\"adds\\": []
}
}
]"
`;
Expand Down Expand Up @@ -13418,6 +13486,40 @@ exports[`record integration tests should record images with blob url 1`] = `
}
]
}
},
{
\\"type\\": 3,
\\"data\\": {
\\"source\\": 0,
\\"texts\\": [],
\\"attributes\\": [
{
\\"id\\": 24,
\\"attributes\\": {
\\"crossorigin\\": \\"anonymous\\"
}
}
],
\\"removes\\": [],
\\"adds\\": []
}
},
{
\\"type\\": 3,
\\"data\\": {
\\"source\\": 0,
\\"texts\\": [],
\\"attributes\\": [
{
\\"id\\": 24,
\\"attributes\\": {
\\"crossorigin\\": null
}
}
],
\\"removes\\": [],
\\"adds\\": []
}
}
]"
`;
Expand Down

0 comments on commit fa5a3fd

Please sign in to comment.