diff --git a/guide.zh_CN.md b/guide.zh_CN.md index 60a80fe32c..98e8e20573 100644 --- a/guide.zh_CN.md +++ b/guide.zh_CN.md @@ -156,7 +156,7 @@ setInterval(save, 10 * 1000); | inlineImages | false | 是否将图片内容记内联录制 | | collectFonts | false | 是否记录页面中的字体文件 | | userTriggeredOnInput | false | [什么是 `userTriggered`](https://github.com/rrweb-io/rrweb/pull/495) | -| window | window | | +| window | window | | | plugins | [] | 加载插件以获得额外的录制功能. [什么是插件?](./docs/recipes/plugin.zh_CN.md) | #### 隐私 diff --git a/packages/rrweb/src/record/index.ts b/packages/rrweb/src/record/index.ts index ef590e418e..de8c254fc8 100644 --- a/packages/rrweb/src/record/index.ts +++ b/packages/rrweb/src/record/index.ts @@ -94,46 +94,46 @@ function record( const maskInputOptions: MaskInputOptions = maskAllInputs === true ? { - color: true, - date: true, - 'datetime-local': true, - email: true, - month: true, - number: true, - range: true, - search: true, - tel: true, - text: true, - time: true, - url: true, - week: true, - textarea: true, - select: true, - password: true, - } + color: true, + date: true, + 'datetime-local': true, + email: true, + month: true, + number: true, + range: true, + search: true, + tel: true, + text: true, + time: true, + url: true, + week: true, + textarea: true, + select: true, + password: true, + } : _maskInputOptions !== undefined - ? _maskInputOptions - : { password: true }; + ? _maskInputOptions + : { password: true }; const slimDOMOptions: SlimDOMOptions = _slimDOMOptions === true || _slimDOMOptions === 'all' ? { - script: true, - comment: true, - headFavicon: true, - headWhitespace: true, - headMetaSocial: true, - headMetaRobots: true, - headMetaHttpEquiv: true, - headMetaVerification: true, - // the following are off for slimDOMOptions === true, - // as they destroy some (hidden) info: - headMetaAuthorship: _slimDOMOptions === 'all', - headMetaDescKeywords: _slimDOMOptions === 'all', - } + script: true, + comment: true, + headFavicon: true, + headWhitespace: true, + headMetaSocial: true, + headMetaRobots: true, + headMetaHttpEquiv: true, + headMetaVerification: true, + // the following are off for slimDOMOptions === true, + // as they destroy some (hidden) info: + headMetaAuthorship: _slimDOMOptions === 'all', + headMetaDescKeywords: _slimDOMOptions === 'all', + } : _slimDOMOptions - ? _slimDOMOptions - : {}; + ? _slimDOMOptions + : {}; polyfill(); @@ -353,16 +353,16 @@ function record( win.pageXOffset !== undefined ? win.pageXOffset : win.document?.documentElement.scrollLeft || - win.document?.body?.parentElement?.scrollLeft || - win.document?.body?.scrollLeft || - 0, + win.document?.body?.parentElement?.scrollLeft || + win.document?.body?.scrollLeft || + 0, top: win.pageYOffset !== undefined ? win.pageYOffset : win.document?.documentElement.scrollTop || - win.document?.body?.parentElement?.scrollTop || - win.document?.body?.scrollTop || - 0, + win.document?.body?.parentElement?.scrollTop || + win.document?.body?.scrollTop || + 0, }, }, }), @@ -370,7 +370,10 @@ function record( mutationBuffers.forEach((buf) => buf.unlock()); // generate & emit any mutations that happened during snapshotting, as can now apply against the newly built mirror // Some old browsers don't support adoptedStyleSheets. - if (win.document.adoptedStyleSheets && win.document.adoptedStyleSheets.length > 0) + if ( + win.document.adoptedStyleSheets && + win.document.adoptedStyleSheets.length > 0 + ) stylesheetManager.adoptStyleSheets( win.document.adoptedStyleSheets, mirror.getId(win.document), diff --git a/packages/rrweb/src/record/mutation.ts b/packages/rrweb/src/record/mutation.ts index 1c1e518f2a..f9b4f37c1b 100644 --- a/packages/rrweb/src/record/mutation.ts +++ b/packages/rrweb/src/record/mutation.ts @@ -318,7 +318,10 @@ export default class MutationBuffer { ); } if (hasShadowRoot(n)) { - this.shadowDomManager.addShadowRoot(n.shadowRoot, this.window.document); + this.shadowDomManager.addShadowRoot( + n.shadowRoot, + this.window.document, + ); } }, onIframeLoad: (iframe, childSn) => { diff --git a/packages/rrweb/src/record/observer.ts b/packages/rrweb/src/record/observer.ts index 37fa314106..3c58f2006e 100644 --- a/packages/rrweb/src/record/observer.ts +++ b/packages/rrweb/src/record/observer.ts @@ -103,7 +103,7 @@ export function initMutationObserver( if ( angularZoneSymbol && ((options.window as unknown) as Record)[ - angularZoneSymbol + angularZoneSymbol ] ) { mutationObserverCtor = ((options.window as unknown) as Record< @@ -187,8 +187,8 @@ function initMoveObserver({ typeof DragEvent !== 'undefined' && evt instanceof DragEvent ? IncrementalSource.Drag : evt instanceof MouseEvent - ? IncrementalSource.MouseMove - : IncrementalSource.TouchMove, + ? IncrementalSource.MouseMove + : IncrementalSource.TouchMove, ); }, threshold, @@ -221,7 +221,7 @@ function initMouseInteractionObserver({ } const disableMap: Record = sampling.mouseInteraction === true || - sampling.mouseInteraction === undefined + sampling.mouseInteraction === undefined ? {} : sampling.mouseInteraction; @@ -369,7 +369,7 @@ function initInputObserver({ isChecked = (target as HTMLInputElement).checked; } else if ( maskInputOptions[ - (target as Element).tagName.toLowerCase() as keyof MaskInputOptions + (target as Element).tagName.toLowerCase() as keyof MaskInputOptions ] || maskInputOptions[type as keyof MaskInputOptions] ) { @@ -1131,8 +1131,8 @@ export function initObservers( const fontObserver = o.collectFonts ? initFontObserver(o) : () => { - // - }; + // + }; const selectionObserver = initSelectionObserver(o); // plugins diff --git a/packages/rrweb/src/record/shadow-dom-manager.ts b/packages/rrweb/src/record/shadow-dom-manager.ts index 7704d44d83..7a1df8ec11 100644 --- a/packages/rrweb/src/record/shadow-dom-manager.ts +++ b/packages/rrweb/src/record/shadow-dom-manager.ts @@ -22,7 +22,7 @@ type BypassOptions = Omit< }; export class ShadowDomManager { - private win: IWindow + private win: IWindow; private shadowDoms = new WeakSet(); private mutationCb: mutationCallBack; private scrollCb: scrollCallback; @@ -31,7 +31,7 @@ export class ShadowDomManager { private restorePatches: (() => void)[] = []; constructor(options: { - win: IWindow, + win: IWindow; mutationCb: mutationCallBack; scrollCb: scrollCallback; bypassOptions: BypassOptions; diff --git a/packages/rrweb/src/types.ts b/packages/rrweb/src/types.ts index 36f6007ade..447cf9295a 100644 --- a/packages/rrweb/src/types.ts +++ b/packages/rrweb/src/types.ts @@ -102,9 +102,9 @@ export type mutationData = { export type mousemoveData = { source: - | IncrementalSource.MouseMove - | IncrementalSource.TouchMove - | IncrementalSource.Drag; + | IncrementalSource.MouseMove + | IncrementalSource.TouchMove + | IncrementalSource.Drag; positions: mousePosition[]; }; @@ -300,7 +300,7 @@ export type observerParam = { collectFonts: boolean; slimDOMOptions: SlimDOMOptions; dataURLOptions: DataURLOptions; - window: IWindow, + window: IWindow; doc: Document; mirror: Mirror; iframeManager: IframeManager; @@ -465,26 +465,26 @@ export enum CanvasContext { export type SerializedCanvasArg = | { - rr_type: 'ArrayBuffer'; - base64: string; // base64 - } + rr_type: 'ArrayBuffer'; + base64: string; // base64 + } | { - rr_type: 'Blob'; - data: Array; - type?: string; - } + rr_type: 'Blob'; + data: Array; + type?: string; + } | { - rr_type: string; - src: string; // url of image - } + rr_type: string; + src: string; // url of image + } | { - rr_type: string; - args: Array; - } + rr_type: string; + args: Array; + } | { - rr_type: string; - index: number; - }; + rr_type: string; + index: number; + }; export type CanvasArg = | SerializedCanvasArg @@ -569,14 +569,14 @@ export type canvasMutationCommand = { export type canvasMutationParam = | { - id: number; - type: CanvasContext; - commands: canvasMutationCommand[]; - } + id: number; + type: CanvasContext; + commands: canvasMutationCommand[]; + } | ({ - id: number; - type: CanvasContext; - } & canvasMutationCommand); + id: number; + type: CanvasContext; + } & canvasMutationCommand); export type canvasMutationWithType = { type: CanvasContext; @@ -599,15 +599,15 @@ export type ImageBitmapDataURLWorkerParams = { export type ImageBitmapDataURLWorkerResponse = | { - id: number; - } + id: number; + } | { - id: number; - type: string; - base64: string; - width: number; - height: number; - }; + id: number; + type: string; + base64: string; + width: number; + height: number; + }; export type fontParam = { family: string; @@ -725,13 +725,13 @@ export type playerConfig = { UNSAFE_replayCanvas: boolean; pauseAnimation?: boolean; mouseTail: - | boolean - | { - duration?: number; - lineCap?: string; - lineWidth?: number; - strokeStyle?: string; - }; + | boolean + | { + duration?: number; + lineCap?: string; + lineWidth?: number; + strokeStyle?: string; + }; unpackFn?: UnpackFn; useVirtualDom: boolean; plugins?: ReplayPlugin[]; diff --git a/packages/rrweb/src/utils.ts b/packages/rrweb/src/utils.ts index c64a31ea94..6fdee8cb6c 100644 --- a/packages/rrweb/src/utils.ts +++ b/packages/rrweb/src/utils.ts @@ -110,16 +110,16 @@ export function hookSetter( isRevoked ? d : { - set(value) { - // put hooked setter into event loop to avoid of set latency - setTimeout(() => { - d.set!.call(this, value); - }, 0); - if (original && original.set) { - original.set.call(this, value); - } + set(value) { + // put hooked setter into event loop to avoid of set latency + setTimeout(() => { + d.set!.call(this, value); + }, 0); + if (original && original.set) { + original.set.call(this, value); + } + }, }, - }, ); return () => hookSetter(target, key, original || {}, true); } @@ -170,7 +170,8 @@ export function patch( export function getWindowHeight(win: Window): number { return ( win.innerHeight || - (win.document.documentElement && win.document.documentElement.clientHeight) || + (win.document.documentElement && + win.document.documentElement.clientHeight) || (win.document.body && win.document.body.clientHeight) ); } @@ -178,7 +179,8 @@ export function getWindowHeight(win: Window): number { export function getWindowWidth(win: Window): number { return ( win.innerWidth || - (win.document.documentElement && win.document.documentElement.clientWidth) || + (win.document.documentElement && + win.document.documentElement.clientWidth) || (win.document.body && win.document.body.clientWidth) ); } @@ -371,10 +373,10 @@ export function isSerializedStylesheet( ): boolean { return Boolean( n.nodeName === 'LINK' && - n.nodeType === n.ELEMENT_NODE && - (n as HTMLElement).getAttribute && - (n as HTMLElement).getAttribute('rel') === 'stylesheet' && - mirror.getMeta(n), + n.nodeType === n.ELEMENT_NODE && + (n as HTMLElement).getAttribute && + (n as HTMLElement).getAttribute('rel') === 'stylesheet' && + mirror.getMeta(n), ); } @@ -444,7 +446,7 @@ export function uniqueTextMutations(mutations: textMutation[]): textMutation[] { const idSet = new Set(); const uniqueMutations: textMutation[] = []; - for (let i = mutations.length; i--;) { + for (let i = mutations.length; i--; ) { const mutation = mutations[i]; if (!idSet.has(mutation.id)) { uniqueMutations.push(mutation); diff --git a/packages/rrweb/test/record.test.ts b/packages/rrweb/test/record.test.ts index e7c3b0c63a..b5335a9a07 100644 --- a/packages/rrweb/test/record.test.ts +++ b/packages/rrweb/test/record.test.ts @@ -927,14 +927,13 @@ describe('be loaded from an iframe', function (this: ISuite) { }); expect(await ctx.page.evaluate('typeof rrweb')).toEqual('undefined'); - await ctx.page.type('input', 'a'); // ensuring that typing in outer gets recorded by inner rrweb + await ctx.page.type('input', 'a'); // ensuring that typing in outer gets recorded by inner rrweb expect(ctx.events.length).toEqual(5); expect( - ctx.events.filter( - (event: eventWithTime) => event.type === EventType.Meta, - ).length, + ctx.events.filter((event: eventWithTime) => event.type === EventType.Meta) + .length, ).toEqual(1); expect(