Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
isBlocked factors in the selector
  • Loading branch information
dbseel committed May 11, 2022
commit 83c1866e44d1793e1e7f0630b87ea05fa6e0297a
1 change: 1 addition & 0 deletions packages/rrweb/src/record/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ function record<T = eventWithTime>(
mutationCb: wrappedCanvasMutationEmit,
win: window,
blockClass,
blockSelector,
mirror,
sampling: sampling.canvas,
});
Expand Down
10 changes: 5 additions & 5 deletions packages/rrweb/src/record/mutation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ export default class MutationBuffer {
switch (m.type) {
case 'characterData': {
const value = m.target.textContent;
if (!isBlocked(m.target, this.blockClass) && value !== m.oldValue) {
if (!isBlocked(m.target, this.blockClass, this.blockSelector) && value !== m.oldValue) {
this.texts.push({
value:
needMaskingText(
Expand Down Expand Up @@ -461,7 +461,7 @@ export default class MutationBuffer {
maskInputFn: this.maskInputFn,
});
}
if (isBlocked(m.target, this.blockClass) || value === m.oldValue) {
if (isBlocked(m.target, this.blockClass, this.blockSelector) || value === m.oldValue) {
return;
}
let item: attributeCursor | undefined = this.attributes.find(
Expand Down Expand Up @@ -525,7 +525,7 @@ export default class MutationBuffer {
? this.mirror.getId(m.target.host)
: this.mirror.getId(m.target);
if (
isBlocked(m.target, this.blockClass) ||
isBlocked(m.target, this.blockClass, this.blockSelector) ||
isIgnored(n, this.mirror) ||
!isSerialized(n, this.mirror)
) {
Expand Down Expand Up @@ -573,7 +573,7 @@ export default class MutationBuffer {

private genAdds = (n: Node, target?: Node) => {
// parent was blocked, so we can ignore this node
if (target && isBlocked(target, this.blockClass)) {
if (target && isBlocked(target, this.blockClass, this.blockSelector)) {
return;
}

Expand All @@ -596,7 +596,7 @@ export default class MutationBuffer {

// if this node is blocked `serializeNode` will turn it into a placeholder element
// but we have to remove it's children otherwise they will be added as placeholders too
if (!isBlocked(n, this.blockClass))
if (!isBlocked(n, this.blockClass, this.blockSelector))
(n as Node).childNodes.forEach((childN) => this.genAdds(childN));
};
}
Expand Down
14 changes: 9 additions & 5 deletions packages/rrweb/src/record/observer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ function initMouseInteractionObserver({
doc,
mirror,
blockClass,
blockSelector,
sampling,
}: observerParam): listenerHandler {
if (sampling.mouseInteraction === false) {
Expand All @@ -221,7 +222,7 @@ function initMouseInteractionObserver({
const getHandler = (eventKey: keyof typeof MouseInteractions) => {
return (event: MouseEvent | TouchEvent) => {
const target = getEventTarget(event) as Node;
if (isBlocked(target, blockClass)) {
if (isBlocked(target, blockClass, blockSelector)) {
return;
}
const e = isTouchEvent(event) ? event.changedTouches[0] : event;
Expand Down Expand Up @@ -260,14 +261,15 @@ export function initScrollObserver({
doc,
mirror,
blockClass,
blockSelector,
sampling,
}: Pick<
observerParam,
'scrollCb' | 'doc' | 'mirror' | 'blockClass' | 'sampling'
'scrollCb' | 'doc' | 'mirror' | 'blockClass' | 'blockSelector' | 'sampling'
>): listenerHandler {
const updatePosition = throttle<UIEvent>((evt) => {
const target = getEventTarget(evt);
if (!target || isBlocked(target as Node, blockClass)) {
if (!target || isBlocked(target as Node, blockClass, blockSelector)) {
return;
}
const id = mirror.getId(target as Node);
Expand Down Expand Up @@ -325,6 +327,7 @@ function initInputObserver({
doc,
mirror,
blockClass,
blockSelector,
ignoreClass,
maskInputOptions,
maskInputFn,
Expand All @@ -344,7 +347,7 @@ function initInputObserver({
!target ||
!(target as Element).tagName ||
INPUT_TAGS.indexOf((target as Element).tagName) < 0 ||
isBlocked(target as Node, blockClass)
isBlocked(target as Node, blockClass, blockSelector)
) {
return;
}
Expand Down Expand Up @@ -647,13 +650,14 @@ function initStyleDeclarationObserver(
function initMediaInteractionObserver({
mediaInteractionCb,
blockClass,
blockSelector,
mirror,
sampling,
}: observerParam): listenerHandler {
const handler = (type: MediaInteractions) =>
throttle((event: Event) => {
const target = getEventTarget(event);
if (!target || isBlocked(target as Node, blockClass)) {
if (!target || isBlocked(target as Node, blockClass, blockSelector)) {
return;
}
const { currentTime, volume, muted } = target as HTMLMediaElement;
Expand Down
3 changes: 2 additions & 1 deletion packages/rrweb/src/record/observers/canvas/2d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export default function initCanvas2DMutationObserver(
cb: canvasManagerMutationCallback,
win: IWindow,
blockClass: blockClass,
blockSelector: string | null,
mirror: Mirror,
): listenerHandler {
const handlers: listenerHandler[] = [];
Expand All @@ -36,7 +37,7 @@ export default function initCanvas2DMutationObserver(
this: CanvasRenderingContext2D,
...args: Array<unknown>
) {
if (!isBlocked(this.canvas, blockClass)) {
if (!isBlocked(this.canvas, blockClass, blockSelector)) {
// Using setTimeout as toDataURL can be heavy
// and we'd rather not block the main thread
setTimeout(() => {
Expand Down
15 changes: 10 additions & 5 deletions packages/rrweb/src/record/observers/canvas/canvas-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,17 +59,18 @@ export class CanvasManager {
mutationCb: canvasMutationCallback;
win: IWindow;
blockClass: blockClass;
blockSelector: string | null,
mirror: Mirror;
sampling?: 'all' | number;
}) {
const { sampling = 'all', win, blockClass, recordCanvas } = options;
const { sampling = 'all', win, blockClass, blockSelector, recordCanvas } = options;
this.mutationCb = options.mutationCb;
this.mirror = options.mirror;

if (recordCanvas && sampling === 'all')
this.initCanvasMutationObserver(win, blockClass);
this.initCanvasMutationObserver(win, blockClass, blockSelector);
if (recordCanvas && typeof sampling === 'number')
this.initCanvasFPSObserver(sampling, win, blockClass);
this.initCanvasFPSObserver(sampling, win, blockClass, blockSelector);
}

private processMutation: canvasManagerMutationCallback = function (
Expand All @@ -93,8 +94,9 @@ export class CanvasManager {
fps: number,
win: IWindow,
blockClass: blockClass,
blockSelector: string | null,
) {
const canvasContextReset = initCanvasContextObserver(win, blockClass);
const canvasContextReset = initCanvasContextObserver(win, blockClass, blockSelector);
const snapshotInProgressMap: Map<number, boolean> = new Map();
const worker = new ImageBitmapDataURLWorker() as ImageBitmapDataURLRequestWorker;
worker.onmessage = (e) => {
Expand Down Expand Up @@ -197,22 +199,25 @@ export class CanvasManager {
private initCanvasMutationObserver(
win: IWindow,
blockClass: blockClass,
blockSelector: string | null,
): void {
this.startRAFTimestamping();
this.startPendingCanvasMutationFlusher();

const canvasContextReset = initCanvasContextObserver(win, blockClass);
const canvasContextReset = initCanvasContextObserver(win, blockClass, blockSelector);
const canvas2DReset = initCanvas2DMutationObserver(
this.processMutation.bind(this),
win,
blockClass,
blockSelector,
this.mirror,
);

const canvasWebGL1and2Reset = initCanvasWebGLMutationObserver(
this.processMutation.bind(this),
win,
blockClass,
blockSelector,
this.mirror,
);

Expand Down
3 changes: 2 additions & 1 deletion packages/rrweb/src/record/observers/canvas/canvas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { isBlocked, patch } from '../../../utils';
export default function initCanvasContextObserver(
win: IWindow,
blockClass: blockClass,
blockSelector: string | null,
): listenerHandler {
const handlers: listenerHandler[] = [];
try {
Expand All @@ -17,7 +18,7 @@ export default function initCanvasContextObserver(
contextType: string,
...args: Array<unknown>
) {
if (!isBlocked(this, blockClass)) {
if (!isBlocked(this, blockClass, blockSelector)) {
if (!('__context' in this))
(this as ICanvas).__context = contextType;
}
Expand Down
6 changes: 5 additions & 1 deletion packages/rrweb/src/record/observers/canvas/webgl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ function patchGLPrototype(
type: CanvasContext,
cb: canvasManagerMutationCallback,
blockClass: blockClass,
blockSelector: string | null,
mirror: Mirror,
win: IWindow,
): listenerHandler[] {
Expand All @@ -31,7 +32,7 @@ function patchGLPrototype(
return function (this: typeof prototype, ...args: Array<unknown>) {
const result = original.apply(this, args);
saveWebGLVar(result, win, prototype);
if (!isBlocked(this.canvas, blockClass)) {
if (!isBlocked(this.canvas, blockClass, blockSelector)) {
const id = mirror.getId(this.canvas);

const recordArgs = serializeArgs([...args], win, prototype);
Expand Down Expand Up @@ -71,6 +72,7 @@ export default function initCanvasWebGLMutationObserver(
cb: canvasManagerMutationCallback,
win: IWindow,
blockClass: blockClass,
blockSelector: string | null,
mirror: Mirror,
): listenerHandler {
const handlers: listenerHandler[] = [];
Expand All @@ -81,6 +83,7 @@ export default function initCanvasWebGLMutationObserver(
CanvasContext.WebGL,
cb,
blockClass,
blockSelector,
mirror,
win,
),
Expand All @@ -93,6 +96,7 @@ export default function initCanvasWebGLMutationObserver(
CanvasContext.WebGL2,
cb,
blockClass,
blockSelector,
mirror,
win,
),
Expand Down
12 changes: 8 additions & 4 deletions packages/rrweb/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ export function getWindowWidth(): number {
);
}

export function isBlocked(node: Node | null, blockClass: blockClass): boolean {
export function isBlocked(node: Node | null, blockClass: blockClass, blockSelector: string | null): boolean {
if (!node) {
return false;
}
Expand All @@ -204,13 +204,17 @@ export function isBlocked(node: Node | null, blockClass: blockClass): boolean {
}
});
}
return needBlock || isBlocked(node.parentNode, blockClass);
if (blockSelector) {
needBlock = (node as HTMLElement).matches(blockSelector);
}

return needBlock || isBlocked(node.parentNode, blockClass, blockSelector);
}
if (node.nodeType === node.TEXT_NODE) {
// check parent node since text node do not have class name
return isBlocked(node.parentNode, blockClass);
return isBlocked(node.parentNode, blockClass, blockSelector);
}
return isBlocked(node.parentNode, blockClass);
return isBlocked(node.parentNode, blockClass, blockSelector);
}

export function isSerialized(n: Node, mirror: Mirror): boolean {
Expand Down
2 changes: 1 addition & 1 deletion packages/rrweb/typings/record/observer.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ import { observerParam, listenerHandler, hooksParam, MutationBufferParam } from
import MutationBuffer from './mutation';
export declare const mutationBuffers: MutationBuffer[];
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 function initScrollObserver({ scrollCb, doc, mirror, blockClass, blockSelector, sampling, }: Pick<observerParam, 'scrollCb' | 'doc' | 'mirror' | 'blockClass' | 'blockSelector' | 'sampling'>): listenerHandler;
export declare const INPUT_TAGS: string[];
export declare function initObservers(o: observerParam, hooks?: hooksParam): listenerHandler;
2 changes: 1 addition & 1 deletion packages/rrweb/typings/utils.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export declare function patch(source: {
}, name: string, replacement: (...args: any[]) => any): () => void;
export declare function getWindowHeight(): number;
export declare function getWindowWidth(): number;
export declare function isBlocked(node: Node | null, blockClass: blockClass): boolean;
export declare function isBlocked(node: Node | null, blockClass: blockClass, blockSelector: string | null): boolean;
export declare function isSerialized(n: Node, mirror: Mirror): boolean;
export declare function isIgnored(n: Node, mirror: Mirror): boolean;
export declare function isAncestorRemoved(target: Node, mirror: Mirror): boolean;
Expand Down