refactoring observer options (#826)
This commit is contained in:
@@ -2,26 +2,21 @@ import {
|
||||
INode,
|
||||
serializeNodeWithId,
|
||||
transformAttribute,
|
||||
MaskInputOptions,
|
||||
SlimDOMOptions,
|
||||
IGNORED_NODE,
|
||||
isShadowRoot,
|
||||
needMaskingText,
|
||||
maskInputValue,
|
||||
MaskTextFn,
|
||||
MaskInputFn,
|
||||
} from 'rrweb-snapshot';
|
||||
import {
|
||||
mutationRecord,
|
||||
blockClass,
|
||||
maskTextClass,
|
||||
mutationCallBack,
|
||||
textCursor,
|
||||
attributeCursor,
|
||||
removedNodeMutation,
|
||||
addedNodeMutation,
|
||||
Mirror,
|
||||
styleAttributeValue,
|
||||
observerParam,
|
||||
MutationBufferParam,
|
||||
} from '../types';
|
||||
import {
|
||||
isBlocked,
|
||||
@@ -30,9 +25,6 @@ import {
|
||||
isIframeINode,
|
||||
hasShadowRoot,
|
||||
} from '../utils';
|
||||
import { IframeManager } from './iframe-manager';
|
||||
import { CanvasManager } from './observers/canvas/canvas-manager';
|
||||
import { ShadowDomManager } from './shadow-dom-manager';
|
||||
|
||||
type DoubleLinkedListNode = {
|
||||
previous: DoubleLinkedListNode | null;
|
||||
@@ -163,61 +155,47 @@ export default class MutationBuffer {
|
||||
private movedSet = new Set<Node>();
|
||||
private droppedSet = new Set<Node>();
|
||||
|
||||
private emissionCallback: mutationCallBack;
|
||||
private blockClass: blockClass;
|
||||
private blockSelector: string | null;
|
||||
private maskTextClass: maskTextClass;
|
||||
private maskTextSelector: string | null;
|
||||
private inlineStylesheet: boolean;
|
||||
private maskInputOptions: MaskInputOptions;
|
||||
private maskTextFn: MaskTextFn | undefined;
|
||||
private maskInputFn: MaskInputFn | undefined;
|
||||
private recordCanvas: boolean;
|
||||
private inlineImages: boolean;
|
||||
private slimDOMOptions: SlimDOMOptions;
|
||||
private doc: Document;
|
||||
private mutationCb: observerParam['mutationCb'];
|
||||
private blockClass: observerParam['blockClass'];
|
||||
private blockSelector: observerParam['blockSelector'];
|
||||
private maskTextClass: observerParam['maskTextClass'];
|
||||
private maskTextSelector: observerParam['maskTextSelector'];
|
||||
private inlineStylesheet: observerParam['inlineStylesheet'];
|
||||
private maskInputOptions: observerParam['maskInputOptions'];
|
||||
private maskTextFn: observerParam['maskTextFn'];
|
||||
private maskInputFn: observerParam['maskInputFn'];
|
||||
private recordCanvas: observerParam['recordCanvas'];
|
||||
private inlineImages: observerParam['inlineImages'];
|
||||
private slimDOMOptions: observerParam['slimDOMOptions'];
|
||||
private doc: observerParam['doc'];
|
||||
private mirror: observerParam['mirror'];
|
||||
private iframeManager: observerParam['iframeManager'];
|
||||
private shadowDomManager: observerParam['shadowDomManager'];
|
||||
private canvasManager: observerParam['canvasManager'];
|
||||
|
||||
private mirror: Mirror;
|
||||
private iframeManager: IframeManager;
|
||||
private shadowDomManager: ShadowDomManager;
|
||||
private canvasManager: CanvasManager;
|
||||
|
||||
public 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,
|
||||
) {
|
||||
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 init(options: MutationBufferParam) {
|
||||
([
|
||||
'mutationCb',
|
||||
'blockClass',
|
||||
'blockSelector',
|
||||
'maskTextClass',
|
||||
'maskTextSelector',
|
||||
'inlineStylesheet',
|
||||
'maskInputOptions',
|
||||
'maskTextFn',
|
||||
'maskInputFn',
|
||||
'recordCanvas',
|
||||
'inlineImages',
|
||||
'slimDOMOptions',
|
||||
'doc',
|
||||
'mirror',
|
||||
'iframeManager',
|
||||
'shadowDomManager',
|
||||
'canvasManager',
|
||||
] as const).forEach((key) => {
|
||||
// just a type trick, the runtime result is correct
|
||||
this[key] = options[key] as never;
|
||||
});
|
||||
}
|
||||
|
||||
public freeze() {
|
||||
@@ -441,7 +419,7 @@ export default class MutationBuffer {
|
||||
this.droppedSet = new Set<Node>();
|
||||
this.movedMap = {};
|
||||
|
||||
this.emissionCallback(payload);
|
||||
this.mutationCb(payload);
|
||||
};
|
||||
|
||||
private processMutation = (m: mutationRecord) => {
|
||||
|
||||
@@ -1,11 +1,4 @@
|
||||
import {
|
||||
INode,
|
||||
MaskInputOptions,
|
||||
SlimDOMOptions,
|
||||
maskInputValue,
|
||||
MaskInputFn,
|
||||
MaskTextFn,
|
||||
} from 'rrweb-snapshot';
|
||||
import { INode, MaskInputOptions, maskInputValue } from 'rrweb-snapshot';
|
||||
import { FontFaceSet } from 'css-font-loading-module';
|
||||
import {
|
||||
throttle,
|
||||
@@ -31,25 +24,19 @@ import {
|
||||
inputValue,
|
||||
inputCallback,
|
||||
hookResetter,
|
||||
blockClass,
|
||||
maskTextClass,
|
||||
IncrementalSource,
|
||||
hooksParam,
|
||||
Arguments,
|
||||
mediaInteractionCallback,
|
||||
MediaInteractions,
|
||||
SamplingStrategy,
|
||||
canvasMutationCallback,
|
||||
fontCallback,
|
||||
fontParam,
|
||||
Mirror,
|
||||
styleDeclarationCallback,
|
||||
IWindow,
|
||||
MutationBufferParam,
|
||||
} from '../types';
|
||||
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 & {
|
||||
__rrMutationObserver?: MutationObserver;
|
||||
@@ -87,47 +74,13 @@ function getEventTarget(event: Event): EventTarget | null {
|
||||
}
|
||||
|
||||
export 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,
|
||||
options: MutationBufferParam,
|
||||
rootEl: Node,
|
||||
): MutationObserver {
|
||||
const mutationBuffer = new MutationBuffer();
|
||||
mutationBuffers.push(mutationBuffer);
|
||||
// see mutation.ts for details
|
||||
mutationBuffer.init(
|
||||
cb,
|
||||
blockClass,
|
||||
blockSelector,
|
||||
maskTextClass,
|
||||
maskTextSelector,
|
||||
inlineStylesheet,
|
||||
maskInputOptions,
|
||||
maskTextFn,
|
||||
maskInputFn,
|
||||
recordCanvas,
|
||||
inlineImages,
|
||||
slimDOMOptions,
|
||||
doc,
|
||||
mirror,
|
||||
iframeManager,
|
||||
shadowDomManager,
|
||||
canvasManager,
|
||||
);
|
||||
mutationBuffer.init(options);
|
||||
let mutationObserverCtor =
|
||||
window.MutationObserver ||
|
||||
/**
|
||||
@@ -167,12 +120,12 @@ export function initMutationObserver(
|
||||
return observer;
|
||||
}
|
||||
|
||||
function initMoveObserver(
|
||||
cb: mousemoveCallBack,
|
||||
sampling: SamplingStrategy,
|
||||
doc: Document,
|
||||
mirror: Mirror,
|
||||
): listenerHandler {
|
||||
function initMoveObserver({
|
||||
mousemoveCb,
|
||||
sampling,
|
||||
doc,
|
||||
mirror,
|
||||
}: observerParam): listenerHandler {
|
||||
if (sampling.mousemove === false) {
|
||||
return () => {};
|
||||
}
|
||||
@@ -194,7 +147,7 @@ function initMoveObserver(
|
||||
| IncrementalSource.Drag,
|
||||
) => {
|
||||
const totalOffset = Date.now() - timeBaseline!;
|
||||
cb(
|
||||
mousemoveCb(
|
||||
positions.map((p) => {
|
||||
p.timeOffset -= totalOffset;
|
||||
return p;
|
||||
@@ -246,13 +199,13 @@ function initMoveObserver(
|
||||
};
|
||||
}
|
||||
|
||||
function initMouseInteractionObserver(
|
||||
cb: mouseInteractionCallBack,
|
||||
doc: Document,
|
||||
mirror: Mirror,
|
||||
blockClass: blockClass,
|
||||
sampling: SamplingStrategy,
|
||||
): listenerHandler {
|
||||
function initMouseInteractionObserver({
|
||||
mouseInteractionCb,
|
||||
doc,
|
||||
mirror,
|
||||
blockClass,
|
||||
sampling,
|
||||
}: observerParam): listenerHandler {
|
||||
if (sampling.mouseInteraction === false) {
|
||||
return () => {};
|
||||
}
|
||||
@@ -275,7 +228,7 @@ function initMouseInteractionObserver(
|
||||
}
|
||||
const id = mirror.getId(target as INode);
|
||||
const { clientX, clientY } = e;
|
||||
cb({
|
||||
mouseInteractionCb({
|
||||
type: MouseInteractions[eventKey],
|
||||
id,
|
||||
x: clientX,
|
||||
@@ -300,13 +253,16 @@ function initMouseInteractionObserver(
|
||||
};
|
||||
}
|
||||
|
||||
export function initScrollObserver(
|
||||
cb: scrollCallback,
|
||||
doc: Document,
|
||||
mirror: Mirror,
|
||||
blockClass: blockClass,
|
||||
sampling: SamplingStrategy,
|
||||
): listenerHandler {
|
||||
export function initScrollObserver({
|
||||
scrollCb,
|
||||
doc,
|
||||
mirror,
|
||||
blockClass,
|
||||
sampling,
|
||||
}: Pick<
|
||||
observerParam,
|
||||
'scrollCb' | 'doc' | 'mirror' | 'blockClass' | 'sampling'
|
||||
>): listenerHandler {
|
||||
const updatePosition = throttle<UIEvent>((evt) => {
|
||||
const target = getEventTarget(evt);
|
||||
if (!target || isBlocked(target as Node, blockClass)) {
|
||||
@@ -315,13 +271,13 @@ export function initScrollObserver(
|
||||
const id = mirror.getId(target as INode);
|
||||
if (target === doc) {
|
||||
const scrollEl = (doc.scrollingElement || doc.documentElement)!;
|
||||
cb({
|
||||
scrollCb({
|
||||
id,
|
||||
x: scrollEl.scrollLeft,
|
||||
y: scrollEl.scrollTop,
|
||||
});
|
||||
} else {
|
||||
cb({
|
||||
scrollCb({
|
||||
id,
|
||||
x: (target as HTMLElement).scrollLeft,
|
||||
y: (target as HTMLElement).scrollTop,
|
||||
@@ -331,16 +287,16 @@ export function initScrollObserver(
|
||||
return on('scroll', updatePosition, doc);
|
||||
}
|
||||
|
||||
function initViewportResizeObserver(
|
||||
cb: viewportResizeCallback,
|
||||
): listenerHandler {
|
||||
function initViewportResizeObserver({
|
||||
viewportResizeCb,
|
||||
}: observerParam): listenerHandler {
|
||||
let lastH = -1;
|
||||
let lastW = -1;
|
||||
const updateDimension = throttle(() => {
|
||||
const height = getWindowHeight();
|
||||
const width = getWindowWidth();
|
||||
if (lastH !== height || lastW !== width) {
|
||||
cb({
|
||||
viewportResizeCb({
|
||||
width: Number(width),
|
||||
height: Number(height),
|
||||
});
|
||||
@@ -362,17 +318,17 @@ function wrapEventWithUserTriggeredFlag(
|
||||
|
||||
export const INPUT_TAGS = ['INPUT', 'TEXTAREA', 'SELECT'];
|
||||
const lastInputValueMap: WeakMap<EventTarget, inputValue> = new WeakMap();
|
||||
function initInputObserver(
|
||||
cb: inputCallback,
|
||||
doc: Document,
|
||||
mirror: Mirror,
|
||||
blockClass: blockClass,
|
||||
ignoreClass: string,
|
||||
maskInputOptions: MaskInputOptions,
|
||||
maskInputFn: MaskInputFn | undefined,
|
||||
sampling: SamplingStrategy,
|
||||
userTriggeredOnInput: boolean,
|
||||
): listenerHandler {
|
||||
function initInputObserver({
|
||||
inputCb,
|
||||
doc,
|
||||
mirror,
|
||||
blockClass,
|
||||
ignoreClass,
|
||||
maskInputOptions,
|
||||
maskInputFn,
|
||||
sampling,
|
||||
userTriggeredOnInput,
|
||||
}: observerParam): listenerHandler {
|
||||
function eventHandler(event: Event) {
|
||||
let target = getEventTarget(event);
|
||||
const userTriggered = event.isTrusted;
|
||||
@@ -451,7 +407,7 @@ function initInputObserver(
|
||||
) {
|
||||
lastInputValueMap.set(target, v);
|
||||
const id = mirror.getId(target as INode);
|
||||
cb({
|
||||
inputCb({
|
||||
...v,
|
||||
id,
|
||||
});
|
||||
@@ -531,9 +487,8 @@ function getNestedCSSRulePositions(rule: CSSRule): number[] {
|
||||
}
|
||||
|
||||
function initStyleSheetObserver(
|
||||
cb: styleSheetRuleCallback,
|
||||
win: IWindow,
|
||||
mirror: Mirror,
|
||||
{ styleSheetRuleCb, mirror }: observerParam,
|
||||
{ win }: { win: IWindow },
|
||||
): listenerHandler {
|
||||
const insertRule = win.CSSStyleSheet.prototype.insertRule;
|
||||
win.CSSStyleSheet.prototype.insertRule = function (
|
||||
@@ -542,7 +497,7 @@ function initStyleSheetObserver(
|
||||
) {
|
||||
const id = mirror.getId(this.ownerNode as INode);
|
||||
if (id !== -1) {
|
||||
cb({
|
||||
styleSheetRuleCb({
|
||||
id,
|
||||
adds: [{ rule, index }],
|
||||
});
|
||||
@@ -554,7 +509,7 @@ function initStyleSheetObserver(
|
||||
win.CSSStyleSheet.prototype.deleteRule = function (index: number) {
|
||||
const id = mirror.getId(this.ownerNode as INode);
|
||||
if (id !== -1) {
|
||||
cb({
|
||||
styleSheetRuleCb({
|
||||
id,
|
||||
removes: [{ index }],
|
||||
});
|
||||
@@ -599,7 +554,7 @@ function initStyleSheetObserver(
|
||||
type.prototype.insertRule = function (rule: string, index?: number) {
|
||||
const id = mirror.getId(this.parentStyleSheet.ownerNode as INode);
|
||||
if (id !== -1) {
|
||||
cb({
|
||||
styleSheetRuleCb({
|
||||
id,
|
||||
adds: [
|
||||
{
|
||||
@@ -618,7 +573,7 @@ function initStyleSheetObserver(
|
||||
type.prototype.deleteRule = function (index: number) {
|
||||
const id = mirror.getId(this.parentStyleSheet.ownerNode as INode);
|
||||
if (id !== -1) {
|
||||
cb({
|
||||
styleSheetRuleCb({
|
||||
id,
|
||||
removes: [{ index: [...getNestedCSSRulePositions(this), index] }],
|
||||
});
|
||||
@@ -638,9 +593,8 @@ function initStyleSheetObserver(
|
||||
}
|
||||
|
||||
function initStyleDeclarationObserver(
|
||||
cb: styleDeclarationCallback,
|
||||
win: IWindow,
|
||||
mirror: Mirror,
|
||||
{ styleDeclarationCb, mirror }: observerParam,
|
||||
{ win }: { win: IWindow },
|
||||
): listenerHandler {
|
||||
const setProperty = win.CSSStyleDeclaration.prototype.setProperty;
|
||||
win.CSSStyleDeclaration.prototype.setProperty = function (
|
||||
@@ -653,7 +607,7 @@ function initStyleDeclarationObserver(
|
||||
(this.parentRule?.parentStyleSheet?.ownerNode as unknown) as INode,
|
||||
);
|
||||
if (id !== -1) {
|
||||
cb({
|
||||
styleDeclarationCb({
|
||||
id,
|
||||
set: {
|
||||
property,
|
||||
@@ -675,7 +629,7 @@ function initStyleDeclarationObserver(
|
||||
(this.parentRule?.parentStyleSheet?.ownerNode as unknown) as INode,
|
||||
);
|
||||
if (id !== -1) {
|
||||
cb({
|
||||
styleDeclarationCb({
|
||||
id,
|
||||
remove: {
|
||||
property,
|
||||
@@ -692,12 +646,12 @@ function initStyleDeclarationObserver(
|
||||
};
|
||||
}
|
||||
|
||||
function initMediaInteractionObserver(
|
||||
mediaInteractionCb: mediaInteractionCallback,
|
||||
blockClass: blockClass,
|
||||
mirror: Mirror,
|
||||
sampling: SamplingStrategy,
|
||||
): listenerHandler {
|
||||
function initMediaInteractionObserver({
|
||||
mediaInteractionCb,
|
||||
blockClass,
|
||||
mirror,
|
||||
sampling,
|
||||
}: observerParam): listenerHandler {
|
||||
const handler = (type: MediaInteractions) =>
|
||||
throttle((event: 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;
|
||||
if (!win) {
|
||||
return () => {};
|
||||
@@ -759,7 +713,7 @@ function initFontObserver(cb: fontCallback, doc: Document): listenerHandler {
|
||||
setTimeout(() => {
|
||||
const p = fontMap.get(fontFace);
|
||||
if (p) {
|
||||
cb(p);
|
||||
fontCb(p);
|
||||
fontMap.delete(fontFace);
|
||||
}
|
||||
}, 0);
|
||||
@@ -869,78 +823,19 @@ export function initObservers(
|
||||
}
|
||||
|
||||
mergeHooks(o, hooks);
|
||||
const mutationObserver = initMutationObserver(
|
||||
o.mutationCb,
|
||||
o.doc,
|
||||
o.blockClass,
|
||||
o.blockSelector,
|
||||
o.maskTextClass,
|
||||
o.maskTextSelector,
|
||||
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 mutationObserver = initMutationObserver(o, o.doc);
|
||||
const mousemoveHandler = initMoveObserver(o);
|
||||
const mouseInteractionHandler = initMouseInteractionObserver(o);
|
||||
const scrollHandler = initScrollObserver(o);
|
||||
const viewportResizeHandler = initViewportResizeObserver(o);
|
||||
const inputHandler = initInputObserver(o);
|
||||
const mediaInteractionHandler = initMediaInteractionObserver(o);
|
||||
|
||||
const styleSheetObserver = initStyleSheetObserver(
|
||||
o.styleSheetRuleCb,
|
||||
currentWindow,
|
||||
o.mirror,
|
||||
);
|
||||
const styleDeclarationObserver = initStyleDeclarationObserver(
|
||||
o.styleDeclarationCb,
|
||||
currentWindow,
|
||||
o.mirror,
|
||||
);
|
||||
const fontObserver = o.collectFonts
|
||||
? initFontObserver(o.fontCb, o.doc)
|
||||
: () => {};
|
||||
const styleSheetObserver = initStyleSheetObserver(o, { win: currentWindow });
|
||||
const styleDeclarationObserver = initStyleDeclarationObserver(o, {
|
||||
win: currentWindow,
|
||||
});
|
||||
const fontObserver = o.collectFonts ? initFontObserver(o) : () => {};
|
||||
// plugins
|
||||
const pluginHandlers: listenerHandler[] = [];
|
||||
for (const plugin of o.plugins) {
|
||||
|
||||
@@ -1,36 +1,17 @@
|
||||
import {
|
||||
mutationCallBack,
|
||||
blockClass,
|
||||
maskTextClass,
|
||||
Mirror,
|
||||
scrollCallback,
|
||||
MutationBufferParam,
|
||||
SamplingStrategy,
|
||||
} from '../types';
|
||||
import {
|
||||
MaskInputOptions,
|
||||
SlimDOMOptions,
|
||||
MaskTextFn,
|
||||
MaskInputFn,
|
||||
} from 'rrweb-snapshot';
|
||||
import { IframeManager } from './iframe-manager';
|
||||
import { initMutationObserver, initScrollObserver } from './observer';
|
||||
import { CanvasManager } from './observers/canvas/canvas-manager';
|
||||
|
||||
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;
|
||||
type BypassOptions = Omit<
|
||||
MutationBufferParam,
|
||||
'doc' | 'mutationCb' | 'mirror' | 'shadowDomManager'
|
||||
> & {
|
||||
sampling: SamplingStrategy;
|
||||
slimDOMOptions: SlimDOMOptions;
|
||||
iframeManager: IframeManager;
|
||||
canvasManager: CanvasManager;
|
||||
};
|
||||
|
||||
export class ShadowDomManager {
|
||||
@@ -53,33 +34,22 @@ export class ShadowDomManager {
|
||||
|
||||
public addShadowRoot(shadowRoot: ShadowRoot, doc: Document) {
|
||||
initMutationObserver(
|
||||
this.mutationCb,
|
||||
doc,
|
||||
this.bypassOptions.blockClass,
|
||||
this.bypassOptions.blockSelector,
|
||||
this.bypassOptions.maskTextClass,
|
||||
this.bypassOptions.maskTextSelector,
|
||||
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,
|
||||
{
|
||||
...this.bypassOptions,
|
||||
doc,
|
||||
mutationCb: this.mutationCb,
|
||||
mirror: this.mirror,
|
||||
shadowDomManager: this,
|
||||
},
|
||||
shadowRoot,
|
||||
);
|
||||
initScrollObserver(
|
||||
this.scrollCb,
|
||||
initScrollObserver({
|
||||
...this.bypassOptions,
|
||||
scrollCb: this.scrollCb,
|
||||
// https://gist.github.com/praveenpuglia/0832da687ed5a5d7a0907046c9ef1813
|
||||
// scroll is not allowed to pass the boundary, so we need to listen the shadow document
|
||||
(shadowRoot as unknown) as Document,
|
||||
this.mirror,
|
||||
this.bypassOptions.blockClass,
|
||||
this.bypassOptions.sampling,
|
||||
);
|
||||
doc: (shadowRoot as unknown) as Document,
|
||||
mirror: this.mirror,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 = {
|
||||
mutation?: mutationCallBack;
|
||||
mousemove?: mousemoveCallBack;
|
||||
@@ -406,7 +427,7 @@ export type SerializedWebGlArg =
|
||||
}
|
||||
| {
|
||||
rr_type: string;
|
||||
args: Array<SerializedWebGlArg>;
|
||||
args: SerializedWebGlArg[];
|
||||
}
|
||||
| {
|
||||
rr_type: string;
|
||||
|
||||
@@ -21,7 +21,10 @@
|
||||
"no-empty": false,
|
||||
"max-classes-per-file": false,
|
||||
"semicolon": false,
|
||||
"trailing-comma": false
|
||||
"trailing-comma": false,
|
||||
"curly": false,
|
||||
"no-namespace": false,
|
||||
"interface-name": false
|
||||
},
|
||||
"rulesDirectory": []
|
||||
}
|
||||
|
||||
10
packages/rrweb/typings/record/mutation.d.ts
vendored
10
packages/rrweb/typings/record/mutation.d.ts
vendored
@@ -1,8 +1,4 @@
|
||||
import { MaskInputOptions, SlimDOMOptions, MaskTextFn, MaskInputFn } from 'rrweb-snapshot';
|
||||
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';
|
||||
import { mutationRecord, MutationBufferParam } from '../types';
|
||||
export default class MutationBuffer {
|
||||
private frozen;
|
||||
private locked;
|
||||
@@ -14,7 +10,7 @@ export default class MutationBuffer {
|
||||
private addedSet;
|
||||
private movedSet;
|
||||
private droppedSet;
|
||||
private emissionCallback;
|
||||
private mutationCb;
|
||||
private blockClass;
|
||||
private blockSelector;
|
||||
private maskTextClass;
|
||||
@@ -31,7 +27,7 @@ export default class MutationBuffer {
|
||||
private iframeManager;
|
||||
private shadowDomManager;
|
||||
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;
|
||||
unfreeze(): void;
|
||||
isFrozen(): boolean;
|
||||
|
||||
10
packages/rrweb/typings/record/observer.d.ts
vendored
10
packages/rrweb/typings/record/observer.d.ts
vendored
@@ -1,11 +1,7 @@
|
||||
import { MaskInputOptions, SlimDOMOptions, MaskInputFn, MaskTextFn } from 'rrweb-snapshot';
|
||||
import { mutationCallBack, observerParam, listenerHandler, scrollCallback, blockClass, maskTextClass, hooksParam, SamplingStrategy, Mirror } from '../types';
|
||||
import { observerParam, listenerHandler, hooksParam, MutationBufferParam } from '../types';
|
||||
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 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 initScrollObserver(cb: scrollCallback, doc: Document, mirror: Mirror, blockClass: blockClass, sampling: SamplingStrategy): listenerHandler;
|
||||
export declare function initMutationObserver(options: MutationBufferParam, rootEl: Node): MutationObserver;
|
||||
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 function initObservers(o: observerParam, hooks?: hooksParam): listenerHandler;
|
||||
|
||||
@@ -1,37 +1,32 @@
|
||||
import {
|
||||
blockClass,
|
||||
canvasMutationCallback,
|
||||
IWindow,
|
||||
Mirror,
|
||||
} from '../../../types';
|
||||
import { blockClass, canvasMutationCallback, IWindow, Mirror } from '../../../types';
|
||||
export declare type RafStamps = {
|
||||
latestId: number;
|
||||
invokeId: number | null;
|
||||
latestId: number;
|
||||
invokeId: number | null;
|
||||
};
|
||||
export declare class CanvasManager {
|
||||
private pendingCanvasMutations;
|
||||
private rafStamps;
|
||||
private mirror;
|
||||
private mutationCb;
|
||||
private resetObservers;
|
||||
private frozen;
|
||||
private locked;
|
||||
reset(): void;
|
||||
freeze(): void;
|
||||
unfreeze(): void;
|
||||
lock(): void;
|
||||
unlock(): void;
|
||||
constructor(options: {
|
||||
recordCanvas: boolean | number;
|
||||
mutationCb: canvasMutationCallback;
|
||||
win: IWindow;
|
||||
blockClass: blockClass;
|
||||
mirror: Mirror;
|
||||
});
|
||||
private processMutation;
|
||||
private initCanvasMutationObserver;
|
||||
private startPendingCanvasMutationFlusher;
|
||||
private startRAFTimestamping;
|
||||
flushPendingCanvasMutations(): void;
|
||||
flushPendingCanvasMutationFor(canvas: HTMLCanvasElement, id: number): void;
|
||||
private pendingCanvasMutations;
|
||||
private rafStamps;
|
||||
private mirror;
|
||||
private mutationCb;
|
||||
private resetObservers;
|
||||
private frozen;
|
||||
private locked;
|
||||
reset(): void;
|
||||
freeze(): void;
|
||||
unfreeze(): void;
|
||||
lock(): void;
|
||||
unlock(): void;
|
||||
constructor(options: {
|
||||
recordCanvas: boolean | number;
|
||||
mutationCb: canvasMutationCallback;
|
||||
win: IWindow;
|
||||
blockClass: blockClass;
|
||||
mirror: Mirror;
|
||||
});
|
||||
private processMutation;
|
||||
private initCanvasMutationObserver;
|
||||
private startPendingCanvasMutationFlusher;
|
||||
private startRAFTimestamping;
|
||||
flushPendingCanvasMutations(): void;
|
||||
flushPendingCanvasMutationFor(canvas: HTMLCanvasElement, id: number): void;
|
||||
}
|
||||
|
||||
@@ -1,22 +1,6 @@
|
||||
import { mutationCallBack, blockClass, maskTextClass, Mirror, scrollCallback, SamplingStrategy } from '../types';
|
||||
import { MaskInputOptions, SlimDOMOptions, MaskTextFn, MaskInputFn } from 'rrweb-snapshot';
|
||||
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;
|
||||
import { mutationCallBack, Mirror, scrollCallback, MutationBufferParam, SamplingStrategy } from '../types';
|
||||
declare type BypassOptions = Omit<MutationBufferParam, 'doc' | 'mutationCb' | 'mirror' | 'shadowDomManager'> & {
|
||||
sampling: SamplingStrategy;
|
||||
slimDOMOptions: SlimDOMOptions;
|
||||
iframeManager: IframeManager;
|
||||
canvasManager: CanvasManager;
|
||||
};
|
||||
export declare class ShadowDomManager {
|
||||
private mutationCb;
|
||||
|
||||
3
packages/rrweb/typings/types.d.ts
vendored
3
packages/rrweb/typings/types.d.ts
vendored
@@ -196,6 +196,7 @@ export declare type observerParam = {
|
||||
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 = {
|
||||
mutation?: mutationCallBack;
|
||||
mousemove?: mousemoveCallBack;
|
||||
@@ -299,7 +300,7 @@ export declare type SerializedWebGlArg = {
|
||||
src: string;
|
||||
} | {
|
||||
rr_type: string;
|
||||
args: Array<SerializedWebGlArg>;
|
||||
args: SerializedWebGlArg[];
|
||||
} | {
|
||||
rr_type: string;
|
||||
index: number;
|
||||
|
||||
Reference in New Issue
Block a user