From c2f7e56ec7e56dd366ae806fc67f33acff42bafa Mon Sep 17 00:00:00 2001 From: Alfie Jones Date: Wed, 22 May 2024 09:34:01 +0100 Subject: [PATCH 1/5] fix: replace document.createElement with doc.createElement in rrweb-snapshot code --- packages/rrweb-snapshot/src/rebuild.ts | 2 +- packages/rrweb-snapshot/src/snapshot.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/rrweb-snapshot/src/rebuild.ts b/packages/rrweb-snapshot/src/rebuild.ts index 7c6ed948e6..2cb554cbfa 100644 --- a/packages/rrweb-snapshot/src/rebuild.ts +++ b/packages/rrweb-snapshot/src/rebuild.ts @@ -294,7 +294,7 @@ function buildNode( const value = specialAttributes[name]; // handle internal attributes if (tagName === 'canvas' && name === 'rr_dataURL') { - const image = document.createElement('img'); + const image = doc.createElement('img'); image.onload = () => { const ctx = (node as HTMLCanvasElement).getContext('2d'); if (ctx) { diff --git a/packages/rrweb-snapshot/src/snapshot.ts b/packages/rrweb-snapshot/src/snapshot.ts index 81dc2133a0..a0fc24921a 100644 --- a/packages/rrweb-snapshot/src/snapshot.ts +++ b/packages/rrweb-snapshot/src/snapshot.ts @@ -726,7 +726,7 @@ function serializeElementNode( ); // create blank canvas of same dimensions - const blankCanvas = document.createElement('canvas'); + const blankCanvas = doc.createElement('canvas'); blankCanvas.width = (n as HTMLCanvasElement).width; blankCanvas.height = (n as HTMLCanvasElement).height; const blankCanvasDataURL = blankCanvas.toDataURL( From cc075536df19212039d9aff2a1f1a9d8a1b9bd62 Mon Sep 17 00:00:00 2001 From: Alfie Jones Date: Wed, 22 May 2024 09:37:19 +0100 Subject: [PATCH 2/5] docs: Added changelog for removing global document references --- .changeset/proud-clocks-hope.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/proud-clocks-hope.md diff --git a/.changeset/proud-clocks-hope.md b/.changeset/proud-clocks-hope.md new file mode 100644 index 0000000000..f700b1618c --- /dev/null +++ b/.changeset/proud-clocks-hope.md @@ -0,0 +1,5 @@ +--- +"rrweb-snapshot": patch +--- + +fix: Removed global document references From 91b54d045fe1b303e28e91bf9b1a5f0ab580a3e8 Mon Sep 17 00:00:00 2001 From: Alfie Jones Date: Wed, 22 May 2024 11:02:22 +0100 Subject: [PATCH 3/5] chore: running prettier --- .changeset/eleven-bobcats-peel.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.changeset/eleven-bobcats-peel.md b/.changeset/eleven-bobcats-peel.md index 75f7263e1f..e3dbcf911e 100644 --- a/.changeset/eleven-bobcats-peel.md +++ b/.changeset/eleven-bobcats-peel.md @@ -1,6 +1,6 @@ --- -'rrweb-snapshot': patch -'rrweb': patch +"rrweb-snapshot": patch +"rrweb": patch --- better support for coexistence with older libraries (e.g. MooTools & Prototype.js) which modify the in-built `Array.from` function From 60c6d6e97b271dc5fb39c23744fc16868dd2f92c Mon Sep 17 00:00:00 2001 From: Eoghan Murray Date: Tue, 4 Jun 2024 11:49:48 +0100 Subject: [PATCH 4/5] Add a test to ensure that we don't regress to using `document` in place of the passed in `doc` --- packages/rrweb-snapshot/test/snapshot.test.ts | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/packages/rrweb-snapshot/test/snapshot.test.ts b/packages/rrweb-snapshot/test/snapshot.test.ts index aa4bb428ee..7c930c3929 100644 --- a/packages/rrweb-snapshot/test/snapshot.test.ts +++ b/packages/rrweb-snapshot/test/snapshot.test.ts @@ -7,6 +7,7 @@ import { serializeNodeWithId, _isBlockedElement, } from '../src/snapshot'; +import snapshot from '../src/snapshot'; import { serializedNodeWithId, elementNode } from '../src/types'; import { Mirror } from '../src/utils'; @@ -257,3 +258,27 @@ describe('form', () => { expect(sel?.childNodes).toEqual([]); // shouldn't be stored in childNodes while in transit }); }); + +describe('jsdom snapshot', () => { + const render = (html: string): Document => { + document.write(html); + return document; + }; + + it("doesn't rely on global browser objects", () => { + // this test is incomplete in terms of coverage, + // but the idea being that we are checking that all features use the + // passed-in `doc` object rather than the global `document` + // (which is only present in browsers) + // in any case, supporting jsdom is not a primary goal + + const doc = render(`

Hello world

`); + const sn = snapshot(doc, { + // JSDOM Error: Not implemented: HTMLCanvasElement.prototype.toDataURL (without installing the canvas npm package) + //recordCanvas: true, + }); + expect(sn).toMatchObject({ + type: 0, + }); + }); +}); From 6869ab4b989225fc86aa6e3d54d0be06d2047b2c Mon Sep 17 00:00:00 2001 From: Eoghan Murray Date: Tue, 4 Jun 2024 12:02:58 +0100 Subject: [PATCH 5/5] Update proud-clocks-hope.md Update patch text with my best understanding --- .changeset/proud-clocks-hope.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/proud-clocks-hope.md b/.changeset/proud-clocks-hope.md index f700b1618c..692b2081d0 100644 --- a/.changeset/proud-clocks-hope.md +++ b/.changeset/proud-clocks-hope.md @@ -2,4 +2,4 @@ "rrweb-snapshot": patch --- -fix: Removed global document references +(when `recordCanvas: true`): ensure we use doc.createElement instead of document.createElement to allow use in non-browser e.g. jsdom environments