Skip to content

Commit

Permalink
Revert "keep 2d canvas serialization at lower resolution"
Browse files Browse the repository at this point in the history
This reverts commit 937d4fc.
  • Loading branch information
Vadman97 committed Oct 1, 2024
1 parent 937d4fc commit 953c8d1
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 96 deletions.
59 changes: 32 additions & 27 deletions packages/rrweb-snapshot/src/snapshot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import {
type serializedElementNodeWithId,
type mediaAttributes,
type PrivacySettingOption,
type CanvasSamplingStrategy,
} from './types';
import {
Mirror,
Expand All @@ -33,7 +32,6 @@ import {
absolutifyURLs,
markCssSplits,
isElementSrcBlocked,
snapshot2DCanvas,
} from './utils';
import dom from '@rrweb/utils';

Expand Down Expand Up @@ -406,7 +404,6 @@ function serializeNode(
dataURLOptions?: DataURLOptions;
inlineImages: boolean;
recordCanvas: boolean;
canvasSampling: CanvasSamplingStrategy;
keepIframeSrcFn: KeepIframeSrcFn;
/**
* `newlyAddedElement: true` skips scrollTop and scrollLeft check
Expand All @@ -429,9 +426,9 @@ function serializeNode(
maskTextClass,
maskTextFn,
maskInputFn,
dataURLOptions = {},
inlineImages,
recordCanvas,
canvasSampling,
keepIframeSrcFn,
newlyAddedElement = false,
cssCaptured = false,
Expand Down Expand Up @@ -470,7 +467,7 @@ function serializeNode(
maskInputOptions,
maskInputFn,
maskTextClass,
canvasSampling,
dataURLOptions,
inlineImages,
recordCanvas,
keepIframeSrcFn,
Expand Down Expand Up @@ -592,9 +589,9 @@ function serializeElementNode(
maskInputOptions: MaskInputOptions;
maskInputFn: MaskInputFn | undefined;
maskTextClass: string | RegExp;
dataURLOptions?: DataURLOptions;
inlineImages: boolean;
recordCanvas: boolean;
canvasSampling: CanvasSamplingStrategy;
keepIframeSrcFn: KeepIframeSrcFn;
/**
* `newlyAddedElement: true` skips scrollTop and scrollLeft check
Expand All @@ -612,9 +609,9 @@ function serializeElementNode(
maskInputOptions = {},
maskInputFn,
maskTextClass,
dataURLOptions = {},
inlineImages,
recordCanvas,
canvasSampling,
keepIframeSrcFn,
newlyAddedElement = false,
privacySetting,
Expand Down Expand Up @@ -712,23 +709,29 @@ function serializeElementNode(
if ((n as ICanvas).__context === '2d') {
// only record this on 2d canvas
if (!is2DCanvasBlank(n as HTMLCanvasElement)) {
attributes.rr_dataURL = snapshot2DCanvas(
n as HTMLCanvasElement,
canvasSampling,
/** Start of Highlight Code
* Avoid capturing non-blank 2d canvas here - defer to canvas-manager.ts for better performance
attributes.rr_dataURL = (n as HTMLCanvasElement).toDataURL(
dataURLOptions.type,
dataURLOptions.quality,
);
End of Highlight Code **/
}
} else if (!('__context' in n)) {
// context is unknown, better not call getContext to trigger it
const canvasDataURL = snapshot2DCanvas(
n as HTMLCanvasElement,
canvasSampling,
const canvasDataURL = (n as HTMLCanvasElement).toDataURL(
dataURLOptions.type,
dataURLOptions.quality,
);

// create blank canvas of same dimensions
const blankCanvas = doc.createElement('canvas');
blankCanvas.width = (n as HTMLCanvasElement).width;
blankCanvas.height = (n as HTMLCanvasElement).height;
const blankCanvasDataURL = snapshot2DCanvas(blankCanvas, canvasSampling);
const blankCanvasDataURL = blankCanvas.toDataURL(
dataURLOptions.type,
dataURLOptions.quality,
);

// no need to save dataURL if it's the same as blank canvas
if (canvasDataURL !== blankCanvasDataURL) {
Expand Down Expand Up @@ -758,9 +761,9 @@ function serializeElementNode(
canvasService!.width = image.naturalWidth;
canvasService!.height = image.naturalHeight;
canvasCtx!.drawImage(image, 0, 0);
attributes.rr_dataURL = snapshot2DCanvas(
canvasService!,
canvasSampling,
attributes.rr_dataURL = canvasService!.toDataURL(
dataURLOptions.type,
dataURLOptions.quality,
);
} catch (err) {
if (image.crossOrigin !== 'anonymous') {
Expand Down Expand Up @@ -863,7 +866,10 @@ function serializeElementNode(
blankCanvas.width = (n as HTMLCanvasElement).width;
blankCanvas.height = (n as HTMLCanvasElement).height;

attributes.rr_dataURL = snapshot2DCanvas(blankCanvas, canvasSampling);
attributes.rr_dataURL = blankCanvas.toDataURL(
dataURLOptions.type,
dataURLOptions.quality,
);
}
}

Expand Down Expand Up @@ -999,10 +1005,10 @@ export function serializeNodeWithId(
maskTextFn: MaskTextFn | undefined;
maskInputFn: MaskInputFn | undefined;
slimDOMOptions: SlimDOMOptions;
dataURLOptions?: DataURLOptions;
keepIframeSrcFn?: KeepIframeSrcFn;
inlineImages?: boolean;
recordCanvas?: boolean;
canvasSampling?: CanvasSamplingStrategy;
preserveWhiteSpace?: boolean;
onSerialize?: (n: Node) => unknown;
onIframeLoad?: (
Expand Down Expand Up @@ -1032,9 +1038,9 @@ export function serializeNodeWithId(
maskTextFn,
maskInputFn,
slimDOMOptions,
dataURLOptions = {},
inlineImages = false,
recordCanvas = false,
canvasSampling = {},
onSerialize,
onIframeLoad,
iframeLoadTimeout = 5000,
Expand Down Expand Up @@ -1070,9 +1076,9 @@ export function serializeNodeWithId(
maskTextClass,
maskTextFn,
maskInputFn,
dataURLOptions,
inlineImages,
recordCanvas,
canvasSampling,
keepIframeSrcFn,
newlyAddedElement,
cssCaptured,
Expand Down Expand Up @@ -1165,9 +1171,9 @@ export function serializeNodeWithId(
maskTextFn,
maskInputFn,
slimDOMOptions,
dataURLOptions,
inlineImages,
recordCanvas,
canvasSampling,
preserveWhiteSpace,
onSerialize,
onIframeLoad,
Expand Down Expand Up @@ -1242,9 +1248,9 @@ export function serializeNodeWithId(
maskTextFn,
maskInputFn,
slimDOMOptions,
dataURLOptions,
inlineImages,
recordCanvas,
canvasSampling,
preserveWhiteSpace,
onSerialize,
onIframeLoad,
Expand Down Expand Up @@ -1295,9 +1301,9 @@ export function serializeNodeWithId(
maskTextFn,
maskInputFn,
slimDOMOptions,
dataURLOptions,
inlineImages,
recordCanvas,
canvasSampling,
preserveWhiteSpace,
onSerialize,
onIframeLoad,
Expand Down Expand Up @@ -1339,7 +1345,6 @@ function snapshot(
dataURLOptions?: DataURLOptions;
inlineImages?: boolean;
recordCanvas?: boolean;
canvasSampling?: CanvasSamplingStrategy;
preserveWhiteSpace?: boolean;
onSerialize?: (n: Node) => unknown;
onIframeLoad?: (
Expand All @@ -1365,11 +1370,11 @@ function snapshot(
inlineStylesheet = true,
inlineImages = false,
recordCanvas = false,
canvasSampling = {},
maskAllInputs = false,
maskTextFn,
maskInputFn,
slimDOM = false,
dataURLOptions,
preserveWhiteSpace,
onSerialize,
onIframeLoad,
Expand Down Expand Up @@ -1435,9 +1440,9 @@ function snapshot(
maskTextFn,
maskInputFn,
slimDOMOptions,
dataURLOptions,
inlineImages,
recordCanvas,
canvasSampling,
preserveWhiteSpace,
onSerialize,
onIframeLoad,
Expand Down
20 changes: 0 additions & 20 deletions packages/rrweb-snapshot/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -227,23 +227,3 @@ export type BuildCache = {
};

export type PrivacySettingOption = 'strict' | 'default' | 'none';

export type CanvasSamplingStrategy = Partial<{
/**
* A scaling to apply to canvas shapshotting. Adjusts the resolution at which
* canvases are recorded by this multiple.
*/
resizeFactor: number;
/**
* The maximum dimension to take canvas snapshots at.
* This setting takes precedence over resizeFactor if the resulting image size
* from the resizeFactor calculation is larger than this value.
* Eg: set to 600 to ensure that the canvas is saved with images no larger than 600px
* in either dimension (while preserving the original canvas aspect ratio).
*/
maxSnapshotDimension: number;
/**
* Adjust the quality of the canvas blob serialization.
*/
dataURLOptions: DataURLOptions;
}>;
50 changes: 9 additions & 41 deletions packages/rrweb-snapshot/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import type {
documentTypeNode,
textNode,
elementNode,
CanvasSamplingStrategy,
} from './types';
import dom from '@rrweb/utils';
import { NodeType } from './types';
Expand Down Expand Up @@ -248,14 +247,14 @@ export function createMirror(): Mirror {
/* Start of Highlight Code */
// overwritten from rrweb
export function maskInputValue({
element,
maskInputOptions,
tagName,
type,
value,
overwriteRecord,
maskInputFn,
}: {
element,
maskInputOptions,
tagName,
type,
value,
overwriteRecord,
maskInputFn,
}: {
element: HTMLElement;
maskInputOptions: MaskInputOptions;
tagName: string;
Expand All @@ -271,7 +270,7 @@ export function maskInputValue({
maskInputOptions,
tagName,
type,
overwriteRecord,
overwriteRecord
})
) {
if (maskInputFn) {
Expand Down Expand Up @@ -590,35 +589,4 @@ export const maskedInputType = ({
);
};

export const resizeCanvas = (
canvas: HTMLCanvasElement,
sampling: CanvasSamplingStrategy,
) => {
let scale = sampling.resizeFactor || 1;
if (sampling.maxSnapshotDimension) {
const maxDim = Math.max(canvas.width, canvas.height);
scale = Math.min(scale, sampling.maxSnapshotDimension / maxDim);
}
const width = canvas.width * scale;
const height = canvas.height * scale;
return { width, height };
};

export const snapshot2DCanvas = (
canvas: HTMLCanvasElement,
sampling: CanvasSamplingStrategy,
) => {
const { width, height } = resizeCanvas(canvas, sampling);
const resizedCanvas = document.createElement('canvas');
const resizedContext = resizedCanvas.getContext('2d');
if (resizedContext === null) return '';
resizedCanvas.width = width;
resizedCanvas.height = height;
resizedContext.drawImage(canvas, 0, 0, width, height);
return resizedCanvas.toDataURL(
sampling.dataURLOptions?.type ?? 'image/webp',
sampling.dataURLOptions?.quality ?? 0.9,
);
};

/* End of Highlight Code */
3 changes: 2 additions & 1 deletion packages/rrweb/src/record/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,7 @@ function record<T = eventWithTime>(
maskTextSelector,
inlineStylesheet,
maskInputOptions,
dataURLOptions,
maskTextFn,
maskInputFn,
recordCanvas,
Expand Down Expand Up @@ -399,8 +400,8 @@ function record<T = eventWithTime>(
maskTextFn,
maskInputFn,
slimDOM: slimDOMOptions,
dataURLOptions,
recordCanvas,
canvasSampling: sampling.canvas,
inlineImages,
privacySetting,
onSerialize: (n) => {
Expand Down
12 changes: 6 additions & 6 deletions packages/rrweb/src/record/mutation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,10 +183,10 @@ export default class MutationBuffer {
private maskInputFn: observerParam['maskInputFn'];
private keepIframeSrcFn: observerParam['keepIframeSrcFn'];
private recordCanvas: observerParam['recordCanvas'];
private sampling: observerParam['sampling'];
private inlineImages: observerParam['inlineImages'];
private privacySetting: observerParam['privacySetting'];
private slimDOMOptions: observerParam['slimDOMOptions'];
private dataURLOptions: observerParam['dataURLOptions'];
private doc: observerParam['doc'];
private mirror: observerParam['mirror'];
private iframeManager: observerParam['iframeManager'];
Expand All @@ -210,10 +210,10 @@ export default class MutationBuffer {
'maskInputFn',
'keepIframeSrcFn',
'recordCanvas',
'sampling',
'inlineImages',
'privacySetting',
'slimDOMOptions',
'dataURLOptions',
'doc',
'mirror',
'iframeManager',
Expand Down Expand Up @@ -329,8 +329,8 @@ export default class MutationBuffer {
maskTextFn: this.maskTextFn,
maskInputFn: this.maskInputFn,
slimDOMOptions: this.slimDOMOptions,
dataURLOptions: this.dataURLOptions,
recordCanvas: this.recordCanvas,
canvasSampling: this.sampling?.canvas,
inlineImages: this.inlineImages,
privacySetting: this.privacySetting,
onSerialize: (currentN) => {
Expand Down Expand Up @@ -474,7 +474,7 @@ export default class MutationBuffer {
!highlightOverwriteRecord &&
value
) {
value = obfuscateText(value);
value = obfuscateText(value);
}
return {
id: this.mirror.getId(n),
Expand Down Expand Up @@ -653,8 +653,8 @@ export default class MutationBuffer {
if (tagName === 'INPUT') {
const node = m.target as HTMLInputElement;
if (node.type === 'password') {
item.attributes['value'] = '*'.repeat(node.value.length);
break;
item.attributes['value'] = '*'.repeat(node.value.length);
break;
}
}
/* End Highlight Code */
Expand Down
Loading

0 comments on commit 953c8d1

Please sign in to comment.