refactoring observer options (#826)

This commit is contained in:
yz-yu
2022-02-05 14:35:33 +08:00
committed by GitHub
parent ef0e3317e2
commit c5b4096293
10 changed files with 202 additions and 363 deletions

View File

@@ -2,26 +2,21 @@ import {
INode, INode,
serializeNodeWithId, serializeNodeWithId,
transformAttribute, transformAttribute,
MaskInputOptions,
SlimDOMOptions,
IGNORED_NODE, IGNORED_NODE,
isShadowRoot, isShadowRoot,
needMaskingText, needMaskingText,
maskInputValue, maskInputValue,
MaskTextFn,
MaskInputFn,
} from 'rrweb-snapshot'; } from 'rrweb-snapshot';
import { import {
mutationRecord, mutationRecord,
blockClass,
maskTextClass,
mutationCallBack,
textCursor, textCursor,
attributeCursor, attributeCursor,
removedNodeMutation, removedNodeMutation,
addedNodeMutation, addedNodeMutation,
Mirror, Mirror,
styleAttributeValue, styleAttributeValue,
observerParam,
MutationBufferParam,
} from '../types'; } from '../types';
import { import {
isBlocked, isBlocked,
@@ -30,9 +25,6 @@ import {
isIframeINode, isIframeINode,
hasShadowRoot, hasShadowRoot,
} from '../utils'; } from '../utils';
import { IframeManager } from './iframe-manager';
import { CanvasManager } from './observers/canvas/canvas-manager';
import { ShadowDomManager } from './shadow-dom-manager';
type DoubleLinkedListNode = { type DoubleLinkedListNode = {
previous: DoubleLinkedListNode | null; previous: DoubleLinkedListNode | null;
@@ -163,61 +155,47 @@ export default class MutationBuffer {
private movedSet = new Set<Node>(); private movedSet = new Set<Node>();
private droppedSet = new Set<Node>(); private droppedSet = new Set<Node>();
private emissionCallback: mutationCallBack; private mutationCb: observerParam['mutationCb'];
private blockClass: blockClass; private blockClass: observerParam['blockClass'];
private blockSelector: string | null; private blockSelector: observerParam['blockSelector'];
private maskTextClass: maskTextClass; private maskTextClass: observerParam['maskTextClass'];
private maskTextSelector: string | null; private maskTextSelector: observerParam['maskTextSelector'];
private inlineStylesheet: boolean; private inlineStylesheet: observerParam['inlineStylesheet'];
private maskInputOptions: MaskInputOptions; private maskInputOptions: observerParam['maskInputOptions'];
private maskTextFn: MaskTextFn | undefined; private maskTextFn: observerParam['maskTextFn'];
private maskInputFn: MaskInputFn | undefined; private maskInputFn: observerParam['maskInputFn'];
private recordCanvas: boolean; private recordCanvas: observerParam['recordCanvas'];
private inlineImages: boolean; private inlineImages: observerParam['inlineImages'];
private slimDOMOptions: SlimDOMOptions; private slimDOMOptions: observerParam['slimDOMOptions'];
private doc: Document; private doc: observerParam['doc'];
private mirror: observerParam['mirror'];
private iframeManager: observerParam['iframeManager'];
private shadowDomManager: observerParam['shadowDomManager'];
private canvasManager: observerParam['canvasManager'];
private mirror: Mirror; public init(options: MutationBufferParam) {
private iframeManager: IframeManager; ([
private shadowDomManager: ShadowDomManager; 'mutationCb',
private canvasManager: CanvasManager; 'blockClass',
'blockSelector',
public init( 'maskTextClass',
cb: mutationCallBack, 'maskTextSelector',
blockClass: blockClass, 'inlineStylesheet',
blockSelector: string | null, 'maskInputOptions',
maskTextClass: maskTextClass, 'maskTextFn',
maskTextSelector: string | null, 'maskInputFn',
inlineStylesheet: boolean, 'recordCanvas',
maskInputOptions: MaskInputOptions, 'inlineImages',
maskTextFn: MaskTextFn | undefined, 'slimDOMOptions',
maskInputFn: MaskInputFn | undefined, 'doc',
recordCanvas: boolean, 'mirror',
inlineImages: boolean, 'iframeManager',
slimDOMOptions: SlimDOMOptions, 'shadowDomManager',
doc: Document, 'canvasManager',
mirror: Mirror, ] as const).forEach((key) => {
iframeManager: IframeManager, // just a type trick, the runtime result is correct
shadowDomManager: ShadowDomManager, this[key] = options[key] as never;
canvasManager: CanvasManager, });
) {
this.blockClass = blockClass;
this.blockSelector = blockSelector;
this.maskTextClass = maskTextClass;
this.maskTextSelector = maskTextSelector;
this.inlineStylesheet = inlineStylesheet;
this.maskInputOptions = maskInputOptions;
this.maskTextFn = maskTextFn;
this.maskInputFn = maskInputFn;
this.recordCanvas = recordCanvas;
this.inlineImages = inlineImages;
this.slimDOMOptions = slimDOMOptions;
this.emissionCallback = cb;
this.doc = doc;
this.mirror = mirror;
this.iframeManager = iframeManager;
this.shadowDomManager = shadowDomManager;
this.canvasManager = canvasManager;
} }
public freeze() { public freeze() {
@@ -441,7 +419,7 @@ export default class MutationBuffer {
this.droppedSet = new Set<Node>(); this.droppedSet = new Set<Node>();
this.movedMap = {}; this.movedMap = {};
this.emissionCallback(payload); this.mutationCb(payload);
}; };
private processMutation = (m: mutationRecord) => { private processMutation = (m: mutationRecord) => {

View File

@@ -1,11 +1,4 @@
import { import { INode, MaskInputOptions, maskInputValue } from 'rrweb-snapshot';
INode,
MaskInputOptions,
SlimDOMOptions,
maskInputValue,
MaskInputFn,
MaskTextFn,
} from 'rrweb-snapshot';
import { FontFaceSet } from 'css-font-loading-module'; import { FontFaceSet } from 'css-font-loading-module';
import { import {
throttle, throttle,
@@ -31,25 +24,19 @@ import {
inputValue, inputValue,
inputCallback, inputCallback,
hookResetter, hookResetter,
blockClass,
maskTextClass,
IncrementalSource, IncrementalSource,
hooksParam, hooksParam,
Arguments, Arguments,
mediaInteractionCallback, mediaInteractionCallback,
MediaInteractions, MediaInteractions,
SamplingStrategy,
canvasMutationCallback, canvasMutationCallback,
fontCallback, fontCallback,
fontParam, fontParam,
Mirror,
styleDeclarationCallback, styleDeclarationCallback,
IWindow, IWindow,
MutationBufferParam,
} from '../types'; } from '../types';
import MutationBuffer from './mutation'; import MutationBuffer from './mutation';
import { IframeManager } from './iframe-manager';
import { ShadowDomManager } from './shadow-dom-manager';
import { CanvasManager } from './observers/canvas/canvas-manager';
type WindowWithStoredMutationObserver = IWindow & { type WindowWithStoredMutationObserver = IWindow & {
__rrMutationObserver?: MutationObserver; __rrMutationObserver?: MutationObserver;
@@ -87,47 +74,13 @@ function getEventTarget(event: Event): EventTarget | null {
} }
export function initMutationObserver( export function initMutationObserver(
cb: mutationCallBack, options: MutationBufferParam,
doc: Document,
blockClass: blockClass,
blockSelector: string | null,
maskTextClass: maskTextClass,
maskTextSelector: string | null,
inlineStylesheet: boolean,
maskInputOptions: MaskInputOptions,
maskTextFn: MaskTextFn | undefined,
maskInputFn: MaskInputFn | undefined,
recordCanvas: boolean,
inlineImages: boolean,
slimDOMOptions: SlimDOMOptions,
mirror: Mirror,
iframeManager: IframeManager,
shadowDomManager: ShadowDomManager,
canvasManager: CanvasManager,
rootEl: Node, rootEl: Node,
): MutationObserver { ): MutationObserver {
const mutationBuffer = new MutationBuffer(); const mutationBuffer = new MutationBuffer();
mutationBuffers.push(mutationBuffer); mutationBuffers.push(mutationBuffer);
// see mutation.ts for details // see mutation.ts for details
mutationBuffer.init( mutationBuffer.init(options);
cb,
blockClass,
blockSelector,
maskTextClass,
maskTextSelector,
inlineStylesheet,
maskInputOptions,
maskTextFn,
maskInputFn,
recordCanvas,
inlineImages,
slimDOMOptions,
doc,
mirror,
iframeManager,
shadowDomManager,
canvasManager,
);
let mutationObserverCtor = let mutationObserverCtor =
window.MutationObserver || window.MutationObserver ||
/** /**
@@ -167,12 +120,12 @@ export function initMutationObserver(
return observer; return observer;
} }
function initMoveObserver( function initMoveObserver({
cb: mousemoveCallBack, mousemoveCb,
sampling: SamplingStrategy, sampling,
doc: Document, doc,
mirror: Mirror, mirror,
): listenerHandler { }: observerParam): listenerHandler {
if (sampling.mousemove === false) { if (sampling.mousemove === false) {
return () => {}; return () => {};
} }
@@ -194,7 +147,7 @@ function initMoveObserver(
| IncrementalSource.Drag, | IncrementalSource.Drag,
) => { ) => {
const totalOffset = Date.now() - timeBaseline!; const totalOffset = Date.now() - timeBaseline!;
cb( mousemoveCb(
positions.map((p) => { positions.map((p) => {
p.timeOffset -= totalOffset; p.timeOffset -= totalOffset;
return p; return p;
@@ -246,13 +199,13 @@ function initMoveObserver(
}; };
} }
function initMouseInteractionObserver( function initMouseInteractionObserver({
cb: mouseInteractionCallBack, mouseInteractionCb,
doc: Document, doc,
mirror: Mirror, mirror,
blockClass: blockClass, blockClass,
sampling: SamplingStrategy, sampling,
): listenerHandler { }: observerParam): listenerHandler {
if (sampling.mouseInteraction === false) { if (sampling.mouseInteraction === false) {
return () => {}; return () => {};
} }
@@ -275,7 +228,7 @@ function initMouseInteractionObserver(
} }
const id = mirror.getId(target as INode); const id = mirror.getId(target as INode);
const { clientX, clientY } = e; const { clientX, clientY } = e;
cb({ mouseInteractionCb({
type: MouseInteractions[eventKey], type: MouseInteractions[eventKey],
id, id,
x: clientX, x: clientX,
@@ -300,13 +253,16 @@ function initMouseInteractionObserver(
}; };
} }
export function initScrollObserver( export function initScrollObserver({
cb: scrollCallback, scrollCb,
doc: Document, doc,
mirror: Mirror, mirror,
blockClass: blockClass, blockClass,
sampling: SamplingStrategy, sampling,
): listenerHandler { }: Pick<
observerParam,
'scrollCb' | 'doc' | 'mirror' | 'blockClass' | 'sampling'
>): listenerHandler {
const updatePosition = throttle<UIEvent>((evt) => { const updatePosition = throttle<UIEvent>((evt) => {
const target = getEventTarget(evt); const target = getEventTarget(evt);
if (!target || isBlocked(target as Node, blockClass)) { if (!target || isBlocked(target as Node, blockClass)) {
@@ -315,13 +271,13 @@ export function initScrollObserver(
const id = mirror.getId(target as INode); const id = mirror.getId(target as INode);
if (target === doc) { if (target === doc) {
const scrollEl = (doc.scrollingElement || doc.documentElement)!; const scrollEl = (doc.scrollingElement || doc.documentElement)!;
cb({ scrollCb({
id, id,
x: scrollEl.scrollLeft, x: scrollEl.scrollLeft,
y: scrollEl.scrollTop, y: scrollEl.scrollTop,
}); });
} else { } else {
cb({ scrollCb({
id, id,
x: (target as HTMLElement).scrollLeft, x: (target as HTMLElement).scrollLeft,
y: (target as HTMLElement).scrollTop, y: (target as HTMLElement).scrollTop,
@@ -331,16 +287,16 @@ export function initScrollObserver(
return on('scroll', updatePosition, doc); return on('scroll', updatePosition, doc);
} }
function initViewportResizeObserver( function initViewportResizeObserver({
cb: viewportResizeCallback, viewportResizeCb,
): listenerHandler { }: observerParam): listenerHandler {
let lastH = -1; let lastH = -1;
let lastW = -1; let lastW = -1;
const updateDimension = throttle(() => { const updateDimension = throttle(() => {
const height = getWindowHeight(); const height = getWindowHeight();
const width = getWindowWidth(); const width = getWindowWidth();
if (lastH !== height || lastW !== width) { if (lastH !== height || lastW !== width) {
cb({ viewportResizeCb({
width: Number(width), width: Number(width),
height: Number(height), height: Number(height),
}); });
@@ -362,17 +318,17 @@ function wrapEventWithUserTriggeredFlag(
export const INPUT_TAGS = ['INPUT', 'TEXTAREA', 'SELECT']; export const INPUT_TAGS = ['INPUT', 'TEXTAREA', 'SELECT'];
const lastInputValueMap: WeakMap<EventTarget, inputValue> = new WeakMap(); const lastInputValueMap: WeakMap<EventTarget, inputValue> = new WeakMap();
function initInputObserver( function initInputObserver({
cb: inputCallback, inputCb,
doc: Document, doc,
mirror: Mirror, mirror,
blockClass: blockClass, blockClass,
ignoreClass: string, ignoreClass,
maskInputOptions: MaskInputOptions, maskInputOptions,
maskInputFn: MaskInputFn | undefined, maskInputFn,
sampling: SamplingStrategy, sampling,
userTriggeredOnInput: boolean, userTriggeredOnInput,
): listenerHandler { }: observerParam): listenerHandler {
function eventHandler(event: Event) { function eventHandler(event: Event) {
let target = getEventTarget(event); let target = getEventTarget(event);
const userTriggered = event.isTrusted; const userTriggered = event.isTrusted;
@@ -451,7 +407,7 @@ function initInputObserver(
) { ) {
lastInputValueMap.set(target, v); lastInputValueMap.set(target, v);
const id = mirror.getId(target as INode); const id = mirror.getId(target as INode);
cb({ inputCb({
...v, ...v,
id, id,
}); });
@@ -531,9 +487,8 @@ function getNestedCSSRulePositions(rule: CSSRule): number[] {
} }
function initStyleSheetObserver( function initStyleSheetObserver(
cb: styleSheetRuleCallback, { styleSheetRuleCb, mirror }: observerParam,
win: IWindow, { win }: { win: IWindow },
mirror: Mirror,
): listenerHandler { ): listenerHandler {
const insertRule = win.CSSStyleSheet.prototype.insertRule; const insertRule = win.CSSStyleSheet.prototype.insertRule;
win.CSSStyleSheet.prototype.insertRule = function ( win.CSSStyleSheet.prototype.insertRule = function (
@@ -542,7 +497,7 @@ function initStyleSheetObserver(
) { ) {
const id = mirror.getId(this.ownerNode as INode); const id = mirror.getId(this.ownerNode as INode);
if (id !== -1) { if (id !== -1) {
cb({ styleSheetRuleCb({
id, id,
adds: [{ rule, index }], adds: [{ rule, index }],
}); });
@@ -554,7 +509,7 @@ function initStyleSheetObserver(
win.CSSStyleSheet.prototype.deleteRule = function (index: number) { win.CSSStyleSheet.prototype.deleteRule = function (index: number) {
const id = mirror.getId(this.ownerNode as INode); const id = mirror.getId(this.ownerNode as INode);
if (id !== -1) { if (id !== -1) {
cb({ styleSheetRuleCb({
id, id,
removes: [{ index }], removes: [{ index }],
}); });
@@ -599,7 +554,7 @@ function initStyleSheetObserver(
type.prototype.insertRule = function (rule: string, index?: number) { type.prototype.insertRule = function (rule: string, index?: number) {
const id = mirror.getId(this.parentStyleSheet.ownerNode as INode); const id = mirror.getId(this.parentStyleSheet.ownerNode as INode);
if (id !== -1) { if (id !== -1) {
cb({ styleSheetRuleCb({
id, id,
adds: [ adds: [
{ {
@@ -618,7 +573,7 @@ function initStyleSheetObserver(
type.prototype.deleteRule = function (index: number) { type.prototype.deleteRule = function (index: number) {
const id = mirror.getId(this.parentStyleSheet.ownerNode as INode); const id = mirror.getId(this.parentStyleSheet.ownerNode as INode);
if (id !== -1) { if (id !== -1) {
cb({ styleSheetRuleCb({
id, id,
removes: [{ index: [...getNestedCSSRulePositions(this), index] }], removes: [{ index: [...getNestedCSSRulePositions(this), index] }],
}); });
@@ -638,9 +593,8 @@ function initStyleSheetObserver(
} }
function initStyleDeclarationObserver( function initStyleDeclarationObserver(
cb: styleDeclarationCallback, { styleDeclarationCb, mirror }: observerParam,
win: IWindow, { win }: { win: IWindow },
mirror: Mirror,
): listenerHandler { ): listenerHandler {
const setProperty = win.CSSStyleDeclaration.prototype.setProperty; const setProperty = win.CSSStyleDeclaration.prototype.setProperty;
win.CSSStyleDeclaration.prototype.setProperty = function ( win.CSSStyleDeclaration.prototype.setProperty = function (
@@ -653,7 +607,7 @@ function initStyleDeclarationObserver(
(this.parentRule?.parentStyleSheet?.ownerNode as unknown) as INode, (this.parentRule?.parentStyleSheet?.ownerNode as unknown) as INode,
); );
if (id !== -1) { if (id !== -1) {
cb({ styleDeclarationCb({
id, id,
set: { set: {
property, property,
@@ -675,7 +629,7 @@ function initStyleDeclarationObserver(
(this.parentRule?.parentStyleSheet?.ownerNode as unknown) as INode, (this.parentRule?.parentStyleSheet?.ownerNode as unknown) as INode,
); );
if (id !== -1) { if (id !== -1) {
cb({ styleDeclarationCb({
id, id,
remove: { remove: {
property, property,
@@ -692,12 +646,12 @@ function initStyleDeclarationObserver(
}; };
} }
function initMediaInteractionObserver( function initMediaInteractionObserver({
mediaInteractionCb: mediaInteractionCallback, mediaInteractionCb,
blockClass: blockClass, blockClass,
mirror: Mirror, mirror,
sampling: SamplingStrategy, sampling,
): listenerHandler { }: observerParam): listenerHandler {
const handler = (type: MediaInteractions) => const handler = (type: MediaInteractions) =>
throttle((event: Event) => { throttle((event: Event) => {
const target = getEventTarget(event); const target = getEventTarget(event);
@@ -724,7 +678,7 @@ function initMediaInteractionObserver(
}; };
} }
function initFontObserver(cb: fontCallback, doc: Document): listenerHandler { function initFontObserver({ fontCb, doc }: observerParam): listenerHandler {
const win = doc.defaultView as IWindow; const win = doc.defaultView as IWindow;
if (!win) { if (!win) {
return () => {}; return () => {};
@@ -759,7 +713,7 @@ function initFontObserver(cb: fontCallback, doc: Document): listenerHandler {
setTimeout(() => { setTimeout(() => {
const p = fontMap.get(fontFace); const p = fontMap.get(fontFace);
if (p) { if (p) {
cb(p); fontCb(p);
fontMap.delete(fontFace); fontMap.delete(fontFace);
} }
}, 0); }, 0);
@@ -869,78 +823,19 @@ export function initObservers(
} }
mergeHooks(o, hooks); mergeHooks(o, hooks);
const mutationObserver = initMutationObserver( const mutationObserver = initMutationObserver(o, o.doc);
o.mutationCb, const mousemoveHandler = initMoveObserver(o);
o.doc, const mouseInteractionHandler = initMouseInteractionObserver(o);
o.blockClass, const scrollHandler = initScrollObserver(o);
o.blockSelector, const viewportResizeHandler = initViewportResizeObserver(o);
o.maskTextClass, const inputHandler = initInputObserver(o);
o.maskTextSelector, const mediaInteractionHandler = initMediaInteractionObserver(o);
o.inlineStylesheet,
o.maskInputOptions,
o.maskTextFn,
o.maskInputFn,
o.recordCanvas,
o.inlineImages,
o.slimDOMOptions,
o.mirror,
o.iframeManager,
o.shadowDomManager,
o.canvasManager,
o.doc,
);
const mousemoveHandler = initMoveObserver(
o.mousemoveCb,
o.sampling,
o.doc,
o.mirror,
);
const mouseInteractionHandler = initMouseInteractionObserver(
o.mouseInteractionCb,
o.doc,
o.mirror,
o.blockClass,
o.sampling,
);
const scrollHandler = initScrollObserver(
o.scrollCb,
o.doc,
o.mirror,
o.blockClass,
o.sampling,
);
const viewportResizeHandler = initViewportResizeObserver(o.viewportResizeCb);
const inputHandler = initInputObserver(
o.inputCb,
o.doc,
o.mirror,
o.blockClass,
o.ignoreClass,
o.maskInputOptions,
o.maskInputFn,
o.sampling,
o.userTriggeredOnInput,
);
const mediaInteractionHandler = initMediaInteractionObserver(
o.mediaInteractionCb,
o.blockClass,
o.mirror,
o.sampling,
);
const styleSheetObserver = initStyleSheetObserver( const styleSheetObserver = initStyleSheetObserver(o, { win: currentWindow });
o.styleSheetRuleCb, const styleDeclarationObserver = initStyleDeclarationObserver(o, {
currentWindow, win: currentWindow,
o.mirror, });
); const fontObserver = o.collectFonts ? initFontObserver(o) : () => {};
const styleDeclarationObserver = initStyleDeclarationObserver(
o.styleDeclarationCb,
currentWindow,
o.mirror,
);
const fontObserver = o.collectFonts
? initFontObserver(o.fontCb, o.doc)
: () => {};
// plugins // plugins
const pluginHandlers: listenerHandler[] = []; const pluginHandlers: listenerHandler[] = [];
for (const plugin of o.plugins) { for (const plugin of o.plugins) {

View File

@@ -1,36 +1,17 @@
import { import {
mutationCallBack, mutationCallBack,
blockClass,
maskTextClass,
Mirror, Mirror,
scrollCallback, scrollCallback,
MutationBufferParam,
SamplingStrategy, SamplingStrategy,
} from '../types'; } from '../types';
import {
MaskInputOptions,
SlimDOMOptions,
MaskTextFn,
MaskInputFn,
} from 'rrweb-snapshot';
import { IframeManager } from './iframe-manager';
import { initMutationObserver, initScrollObserver } from './observer'; import { initMutationObserver, initScrollObserver } from './observer';
import { CanvasManager } from './observers/canvas/canvas-manager';
type BypassOptions = { type BypassOptions = Omit<
blockClass: blockClass; MutationBufferParam,
blockSelector: string | null; 'doc' | 'mutationCb' | 'mirror' | 'shadowDomManager'
maskTextClass: maskTextClass; > & {
maskTextSelector: string | null;
inlineStylesheet: boolean;
maskInputOptions: MaskInputOptions;
maskTextFn: MaskTextFn | undefined;
maskInputFn: MaskInputFn | undefined;
recordCanvas: boolean;
inlineImages: boolean;
sampling: SamplingStrategy; sampling: SamplingStrategy;
slimDOMOptions: SlimDOMOptions;
iframeManager: IframeManager;
canvasManager: CanvasManager;
}; };
export class ShadowDomManager { export class ShadowDomManager {
@@ -53,33 +34,22 @@ export class ShadowDomManager {
public addShadowRoot(shadowRoot: ShadowRoot, doc: Document) { public addShadowRoot(shadowRoot: ShadowRoot, doc: Document) {
initMutationObserver( initMutationObserver(
this.mutationCb, {
doc, ...this.bypassOptions,
this.bypassOptions.blockClass, doc,
this.bypassOptions.blockSelector, mutationCb: this.mutationCb,
this.bypassOptions.maskTextClass, mirror: this.mirror,
this.bypassOptions.maskTextSelector, shadowDomManager: this,
this.bypassOptions.inlineStylesheet, },
this.bypassOptions.maskInputOptions,
this.bypassOptions.maskTextFn,
this.bypassOptions.maskInputFn,
this.bypassOptions.recordCanvas,
this.bypassOptions.inlineImages,
this.bypassOptions.slimDOMOptions,
this.mirror,
this.bypassOptions.iframeManager,
this,
this.bypassOptions.canvasManager,
shadowRoot, shadowRoot,
); );
initScrollObserver( initScrollObserver({
this.scrollCb, ...this.bypassOptions,
scrollCb: this.scrollCb,
// https://gist.github.com/praveenpuglia/0832da687ed5a5d7a0907046c9ef1813 // https://gist.github.com/praveenpuglia/0832da687ed5a5d7a0907046c9ef1813
// scroll is not allowed to pass the boundary, so we need to listen the shadow document // scroll is not allowed to pass the boundary, so we need to listen the shadow document
(shadowRoot as unknown) as Document, doc: (shadowRoot as unknown) as Document,
this.mirror, mirror: this.mirror,
this.bypassOptions.blockClass, });
this.bypassOptions.sampling,
);
} }
} }

View File

@@ -277,6 +277,27 @@ export type observerParam = {
}>; }>;
}; };
export type MutationBufferParam = Pick<
observerParam,
| 'mutationCb'
| 'blockClass'
| 'blockSelector'
| 'maskTextClass'
| 'maskTextSelector'
| 'inlineStylesheet'
| 'maskInputOptions'
| 'maskTextFn'
| 'maskInputFn'
| 'recordCanvas'
| 'inlineImages'
| 'slimDOMOptions'
| 'doc'
| 'mirror'
| 'iframeManager'
| 'shadowDomManager'
| 'canvasManager'
>;
export type hooksParam = { export type hooksParam = {
mutation?: mutationCallBack; mutation?: mutationCallBack;
mousemove?: mousemoveCallBack; mousemove?: mousemoveCallBack;
@@ -406,7 +427,7 @@ export type SerializedWebGlArg =
} }
| { | {
rr_type: string; rr_type: string;
args: Array<SerializedWebGlArg>; args: SerializedWebGlArg[];
} }
| { | {
rr_type: string; rr_type: string;

View File

@@ -21,7 +21,10 @@
"no-empty": false, "no-empty": false,
"max-classes-per-file": false, "max-classes-per-file": false,
"semicolon": false, "semicolon": false,
"trailing-comma": false "trailing-comma": false,
"curly": false,
"no-namespace": false,
"interface-name": false
}, },
"rulesDirectory": [] "rulesDirectory": []
} }

View File

@@ -1,8 +1,4 @@
import { MaskInputOptions, SlimDOMOptions, MaskTextFn, MaskInputFn } from 'rrweb-snapshot'; import { mutationRecord, MutationBufferParam } from '../types';
import { mutationRecord, blockClass, maskTextClass, mutationCallBack, Mirror } from '../types';
import { IframeManager } from './iframe-manager';
import { CanvasManager } from './observers/canvas/canvas-manager';
import { ShadowDomManager } from './shadow-dom-manager';
export default class MutationBuffer { export default class MutationBuffer {
private frozen; private frozen;
private locked; private locked;
@@ -14,7 +10,7 @@ export default class MutationBuffer {
private addedSet; private addedSet;
private movedSet; private movedSet;
private droppedSet; private droppedSet;
private emissionCallback; private mutationCb;
private blockClass; private blockClass;
private blockSelector; private blockSelector;
private maskTextClass; private maskTextClass;
@@ -31,7 +27,7 @@ export default class MutationBuffer {
private iframeManager; private iframeManager;
private shadowDomManager; private shadowDomManager;
private canvasManager; private canvasManager;
init(cb: mutationCallBack, blockClass: blockClass, blockSelector: string | null, maskTextClass: maskTextClass, maskTextSelector: string | null, inlineStylesheet: boolean, maskInputOptions: MaskInputOptions, maskTextFn: MaskTextFn | undefined, maskInputFn: MaskInputFn | undefined, recordCanvas: boolean, inlineImages: boolean, slimDOMOptions: SlimDOMOptions, doc: Document, mirror: Mirror, iframeManager: IframeManager, shadowDomManager: ShadowDomManager, canvasManager: CanvasManager): void; init(options: MutationBufferParam): void;
freeze(): void; freeze(): void;
unfreeze(): void; unfreeze(): void;
isFrozen(): boolean; isFrozen(): boolean;

View File

@@ -1,11 +1,7 @@
import { MaskInputOptions, SlimDOMOptions, MaskInputFn, MaskTextFn } from 'rrweb-snapshot'; import { observerParam, listenerHandler, hooksParam, MutationBufferParam } from '../types';
import { mutationCallBack, observerParam, listenerHandler, scrollCallback, blockClass, maskTextClass, hooksParam, SamplingStrategy, Mirror } from '../types';
import MutationBuffer from './mutation'; import MutationBuffer from './mutation';
import { IframeManager } from './iframe-manager';
import { ShadowDomManager } from './shadow-dom-manager';
import { CanvasManager } from './observers/canvas/canvas-manager';
export declare const mutationBuffers: MutationBuffer[]; export declare const mutationBuffers: MutationBuffer[];
export declare function initMutationObserver(cb: mutationCallBack, doc: Document, blockClass: blockClass, blockSelector: string | null, maskTextClass: maskTextClass, maskTextSelector: string | null, inlineStylesheet: boolean, maskInputOptions: MaskInputOptions, maskTextFn: MaskTextFn | undefined, maskInputFn: MaskInputFn | undefined, recordCanvas: boolean, inlineImages: boolean, slimDOMOptions: SlimDOMOptions, mirror: Mirror, iframeManager: IframeManager, shadowDomManager: ShadowDomManager, canvasManager: CanvasManager, rootEl: Node): MutationObserver; export declare function initMutationObserver(options: MutationBufferParam, rootEl: Node): MutationObserver;
export declare function initScrollObserver(cb: scrollCallback, doc: Document, mirror: Mirror, blockClass: blockClass, sampling: SamplingStrategy): listenerHandler; export declare function initScrollObserver({ scrollCb, doc, mirror, blockClass, sampling, }: Pick<observerParam, 'scrollCb' | 'doc' | 'mirror' | 'blockClass' | 'sampling'>): listenerHandler;
export declare const INPUT_TAGS: string[]; export declare const INPUT_TAGS: string[];
export declare function initObservers(o: observerParam, hooks?: hooksParam): listenerHandler; export declare function initObservers(o: observerParam, hooks?: hooksParam): listenerHandler;

View File

@@ -1,37 +1,32 @@
import { import { blockClass, canvasMutationCallback, IWindow, Mirror } from '../../../types';
blockClass,
canvasMutationCallback,
IWindow,
Mirror,
} from '../../../types';
export declare type RafStamps = { export declare type RafStamps = {
latestId: number; latestId: number;
invokeId: number | null; invokeId: number | null;
}; };
export declare class CanvasManager { export declare class CanvasManager {
private pendingCanvasMutations; private pendingCanvasMutations;
private rafStamps; private rafStamps;
private mirror; private mirror;
private mutationCb; private mutationCb;
private resetObservers; private resetObservers;
private frozen; private frozen;
private locked; private locked;
reset(): void; reset(): void;
freeze(): void; freeze(): void;
unfreeze(): void; unfreeze(): void;
lock(): void; lock(): void;
unlock(): void; unlock(): void;
constructor(options: { constructor(options: {
recordCanvas: boolean | number; recordCanvas: boolean | number;
mutationCb: canvasMutationCallback; mutationCb: canvasMutationCallback;
win: IWindow; win: IWindow;
blockClass: blockClass; blockClass: blockClass;
mirror: Mirror; mirror: Mirror;
}); });
private processMutation; private processMutation;
private initCanvasMutationObserver; private initCanvasMutationObserver;
private startPendingCanvasMutationFlusher; private startPendingCanvasMutationFlusher;
private startRAFTimestamping; private startRAFTimestamping;
flushPendingCanvasMutations(): void; flushPendingCanvasMutations(): void;
flushPendingCanvasMutationFor(canvas: HTMLCanvasElement, id: number): void; flushPendingCanvasMutationFor(canvas: HTMLCanvasElement, id: number): void;
} }

View File

@@ -1,22 +1,6 @@
import { mutationCallBack, blockClass, maskTextClass, Mirror, scrollCallback, SamplingStrategy } from '../types'; import { mutationCallBack, Mirror, scrollCallback, MutationBufferParam, SamplingStrategy } from '../types';
import { MaskInputOptions, SlimDOMOptions, MaskTextFn, MaskInputFn } from 'rrweb-snapshot'; declare type BypassOptions = Omit<MutationBufferParam, 'doc' | 'mutationCb' | 'mirror' | 'shadowDomManager'> & {
import { IframeManager } from './iframe-manager';
import { CanvasManager } from './observers/canvas/canvas-manager';
declare type BypassOptions = {
blockClass: blockClass;
blockSelector: string | null;
maskTextClass: maskTextClass;
maskTextSelector: string | null;
inlineStylesheet: boolean;
maskInputOptions: MaskInputOptions;
maskTextFn: MaskTextFn | undefined;
maskInputFn: MaskInputFn | undefined;
recordCanvas: boolean;
inlineImages: boolean;
sampling: SamplingStrategy; sampling: SamplingStrategy;
slimDOMOptions: SlimDOMOptions;
iframeManager: IframeManager;
canvasManager: CanvasManager;
}; };
export declare class ShadowDomManager { export declare class ShadowDomManager {
private mutationCb; private mutationCb;

View File

@@ -196,6 +196,7 @@ export declare type observerParam = {
options: unknown; options: unknown;
}>; }>;
}; };
export declare type MutationBufferParam = Pick<observerParam, 'mutationCb' | 'blockClass' | 'blockSelector' | 'maskTextClass' | 'maskTextSelector' | 'inlineStylesheet' | 'maskInputOptions' | 'maskTextFn' | 'maskInputFn' | 'recordCanvas' | 'inlineImages' | 'slimDOMOptions' | 'doc' | 'mirror' | 'iframeManager' | 'shadowDomManager' | 'canvasManager'>;
export declare type hooksParam = { export declare type hooksParam = {
mutation?: mutationCallBack; mutation?: mutationCallBack;
mousemove?: mousemoveCallBack; mousemove?: mousemoveCallBack;
@@ -299,7 +300,7 @@ export declare type SerializedWebGlArg = {
src: string; src: string;
} | { } | {
rr_type: string; rr_type: string;
args: Array<SerializedWebGlArg>; args: SerializedWebGlArg[];
} | { } | {
rr_type: string; rr_type: string;
index: number; index: number;