From 7bfebf68aad9b4fca33a348160dea3150ea07730 Mon Sep 17 00:00:00 2001 From: Colin Maxfield Date: Fri, 17 May 2024 11:32:02 -0400 Subject: [PATCH] Replace Array.from with clean implementation (#1464) This work is to try to provide support where rrweb might be included in applications with various tools that might override Array.from so that the 2nd parameter (the map function) will always work for rrweb. Co-authored-by: Michael Dellanoce --- .changeset/eleven-bobcats-peel.md | 6 ++++++ packages/rrweb/src/record/index.ts | 14 ++++++++++++++ packages/rrweb/src/types.ts | 1 + 3 files changed, 21 insertions(+) create mode 100644 .changeset/eleven-bobcats-peel.md diff --git a/.changeset/eleven-bobcats-peel.md b/.changeset/eleven-bobcats-peel.md new file mode 100644 index 0000000000..75f7263e1f --- /dev/null +++ b/.changeset/eleven-bobcats-peel.md @@ -0,0 +1,6 @@ +--- +'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 diff --git a/packages/rrweb/src/record/index.ts b/packages/rrweb/src/record/index.ts index 7be978199d..484a8a7ecb 100644 --- a/packages/rrweb/src/record/index.ts +++ b/packages/rrweb/src/record/index.ts @@ -46,6 +46,20 @@ let takeFullSnapshot!: (isCheckout?: boolean) => void; let canvasManager!: CanvasManager; let recording = false; +// Multiple tools (i.e. MooTools, Prototype.js) override Array.from and drop support for the 2nd parameter +// Try to pull a clean implementation from a newly created iframe +try { + if (Array.from([1], (x) => x * 2)[0] !== 2) { + const cleanFrame = document.createElement('iframe'); + document.body.appendChild(cleanFrame); + // eslint-disable-next-line @typescript-eslint/unbound-method -- Array.from is static and doesn't rely on binding + Array.from = cleanFrame.contentWindow?.Array.from || Array.from; + document.body.removeChild(cleanFrame); + } +} catch (err) { + console.debug('Unable to override Array.from', err); +} + const mirror = createMirror(); function record( options: recordOptions = {}, diff --git a/packages/rrweb/src/types.ts b/packages/rrweb/src/types.ts index 10ffb62b43..03c9a59fdc 100644 --- a/packages/rrweb/src/types.ts +++ b/packages/rrweb/src/types.ts @@ -207,6 +207,7 @@ export type missingNodeMap = { declare global { interface Window { FontFace: typeof FontFace; + Array: typeof Array; } }