From 591d9b350a7544925bd49e97a042e64c9cfbd807 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 3d8aa4b104..f433e53095 100644 --- a/packages/rrweb/src/record/index.ts +++ b/packages/rrweb/src/record/index.ts @@ -68,6 +68,20 @@ let _wrappedEmit: | ((e: eventWithTime, isCheckout?: boolean) => void); let _takeFullSnapshot: undefined | ((isCheckout?: boolean) => void); +// 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); +} + export const mirror = createMirror(); function record( diff --git a/packages/rrweb/src/types.ts b/packages/rrweb/src/types.ts index c64c3d723e..5186dcbf32 100644 --- a/packages/rrweb/src/types.ts +++ b/packages/rrweb/src/types.ts @@ -234,6 +234,7 @@ export type missingNodeMap = { declare global { interface Window { FontFace: typeof FontFace; + Array: typeof Array; } }