From cb2a3d0a3d0da6c7b650340d8b5d2b05146b7909 Mon Sep 17 00:00:00 2001 From: Billy Vong Date: Thu, 14 Dec 2023 11:21:25 -0330 Subject: [PATCH] feat(canvas): Bind `mutationCb` outside of `getCanvasManager` (#141) From what I can tell, `record` ends up getting bundled separate from `getCanvasManager` in user-land code and canvas mutation events end up not being transmitted because `_wrappedEmit` does not get set and it will hold the wrong `mirror` reference. --- packages/rrweb/src/record/index.ts | 77 ++++++++++++++++++------------ 1 file changed, 47 insertions(+), 30 deletions(-) diff --git a/packages/rrweb/src/record/index.ts b/packages/rrweb/src/record/index.ts index 2df25f6ec2..c7c7a1e678 100644 --- a/packages/rrweb/src/record/index.ts +++ b/packages/rrweb/src/record/index.ts @@ -326,16 +326,17 @@ function record( const processedNodeManager = new ProcessedNodeManager(); - const canvasManager: CanvasManagerInterface = getCanvasManager - ? getCanvasManager({ - recordCanvas, - blockClass, - blockSelector, - unblockSelector, - sampling: sampling['canvas'], - dataURLOptions, - }) - : new CanvasManagerNoop(); + const canvasManager: CanvasManagerInterface = _getCanvasManager( + getCanvasManager, + { + recordCanvas, + blockClass, + blockSelector, + unblockSelector, + sampling: sampling['canvas'], + dataURLOptions, + }, + ); const shadowDomManager: ShadowDomManagerInterface = typeof __RRWEB_EXCLUDE_SHADOW_DOM__ === 'boolean' && @@ -693,27 +694,43 @@ record.takeFullSnapshot = takeFullSnapshot; export default record; -const wrappedCanvasMutationEmit = (p: canvasMutationParam) => - wrappedEmit( - wrapEvent({ - type: EventType.IncrementalSnapshot, - data: { - source: IncrementalSource.CanvasMutation, - ...p, - }, - }), - ); +type PrivateOptions = 'mutationCb' | 'win' | 'mirror'; +type PublicGetCanvasManagerOptions = Omit< + CanvasManagerConstructorOptions, + PrivateOptions +>; + +interface PrivateGetCanvasManagerOptions + extends PublicGetCanvasManagerOptions, + Pick {} + +function _getCanvasManager( + getCanvasManagerFn: + | undefined + | ((options: PrivateGetCanvasManagerOptions) => CanvasManagerInterface), + options: PublicGetCanvasManagerOptions, +) { + return getCanvasManagerFn + ? getCanvasManagerFn({ + ...options, + mirror, + win: window, + mutationCb: (p: canvasMutationParam) => + wrappedEmit( + wrapEvent({ + type: EventType.IncrementalSnapshot, + data: { + source: IncrementalSource.CanvasMutation, + ...p, + }, + }), + ), + }) + : new CanvasManagerNoop(); +} export function getCanvasManager( - options: Omit< - CanvasManagerConstructorOptions, - 'mutationCb' | 'win' | 'mirror' - >, + options: PublicGetCanvasManagerOptions, ): CanvasManagerInterface { - return new CanvasManager({ - ...options, - mutationCb: wrappedCanvasMutationEmit, - win: window, - mirror, - }); + return new CanvasManager(options as CanvasManagerConstructorOptions); }