move maskInputValue to rrweb-snapshot (#83)
More info: https://github.com/rrweb-io/rrweb/pull/602#discussion_r660434998
This commit is contained in:
@@ -8,9 +8,10 @@ import {
|
||||
MaskInputOptions,
|
||||
SlimDOMOptions,
|
||||
MaskTextFn,
|
||||
MaskInputFn,
|
||||
KeepIframeSrcFn,
|
||||
} from './types';
|
||||
import { isElement, isShadowRoot } from './utils';
|
||||
import { isElement, isShadowRoot, maskInputValue } from './utils';
|
||||
|
||||
let _id = 1;
|
||||
const tagNameRegex = RegExp('[^a-z0-9-_:]');
|
||||
@@ -348,6 +349,7 @@ function serializeNode(
|
||||
inlineStylesheet: boolean;
|
||||
maskInputOptions: MaskInputOptions;
|
||||
maskTextFn: MaskTextFn | undefined;
|
||||
maskInputFn: MaskInputFn | undefined;
|
||||
recordCanvas: boolean;
|
||||
keepIframeSrcFn: KeepIframeSrcFn;
|
||||
},
|
||||
@@ -361,13 +363,14 @@ function serializeNode(
|
||||
inlineStylesheet,
|
||||
maskInputOptions = {},
|
||||
maskTextFn,
|
||||
maskInputFn,
|
||||
recordCanvas,
|
||||
keepIframeSrcFn,
|
||||
} = options;
|
||||
// Only record root id when document object is not the base document
|
||||
let rootId: number | undefined;
|
||||
if (((doc as unknown) as INode).__sn) {
|
||||
const docId = ((doc as unknown) as INode).__sn.id;
|
||||
if ((doc as unknown as INode).__sn) {
|
||||
const docId = (doc as unknown as INode).__sn.id;
|
||||
rootId = docId === 1 ? undefined : docId;
|
||||
}
|
||||
switch (n.nodeType) {
|
||||
@@ -443,11 +446,13 @@ function serializeNode(
|
||||
attributes.type !== 'button' &&
|
||||
value
|
||||
) {
|
||||
attributes.value =
|
||||
maskInputOptions[attributes.type as keyof MaskInputOptions] ||
|
||||
maskInputOptions[tagName as keyof MaskInputOptions]
|
||||
? '*'.repeat(value.length)
|
||||
: value;
|
||||
attributes.value = maskInputValue({
|
||||
type: attributes.type,
|
||||
tagName,
|
||||
value,
|
||||
maskInputOptions,
|
||||
maskInputFn,
|
||||
});
|
||||
} else if ((n as HTMLInputElement).checked) {
|
||||
attributes.checked = (n as HTMLInputElement).checked;
|
||||
}
|
||||
@@ -650,6 +655,7 @@ export function serializeNodeWithId(
|
||||
inlineStylesheet: boolean;
|
||||
maskInputOptions?: MaskInputOptions;
|
||||
maskTextFn: MaskTextFn | undefined;
|
||||
maskInputFn: MaskInputFn | undefined;
|
||||
slimDOMOptions: SlimDOMOptions;
|
||||
keepIframeSrcFn?: KeepIframeSrcFn;
|
||||
recordCanvas?: boolean;
|
||||
@@ -670,6 +676,7 @@ export function serializeNodeWithId(
|
||||
inlineStylesheet = true,
|
||||
maskInputOptions = {},
|
||||
maskTextFn,
|
||||
maskInputFn,
|
||||
slimDOMOptions,
|
||||
recordCanvas = false,
|
||||
onSerialize,
|
||||
@@ -687,6 +694,7 @@ export function serializeNodeWithId(
|
||||
inlineStylesheet,
|
||||
maskInputOptions,
|
||||
maskTextFn,
|
||||
maskInputFn,
|
||||
recordCanvas,
|
||||
keepIframeSrcFn,
|
||||
});
|
||||
@@ -750,6 +758,7 @@ export function serializeNodeWithId(
|
||||
inlineStylesheet,
|
||||
maskInputOptions,
|
||||
maskTextFn,
|
||||
maskInputFn,
|
||||
slimDOMOptions,
|
||||
recordCanvas,
|
||||
preserveWhiteSpace,
|
||||
@@ -801,6 +810,7 @@ export function serializeNodeWithId(
|
||||
inlineStylesheet,
|
||||
maskInputOptions,
|
||||
maskTextFn,
|
||||
maskInputFn,
|
||||
slimDOMOptions,
|
||||
recordCanvas,
|
||||
preserveWhiteSpace,
|
||||
@@ -832,6 +842,7 @@ function snapshot(
|
||||
inlineStylesheet?: boolean;
|
||||
maskAllInputs?: boolean | MaskInputOptions;
|
||||
maskTextFn?: MaskTextFn;
|
||||
maskInputFn?: MaskTextFn;
|
||||
slimDOM?: boolean | SlimDOMOptions;
|
||||
recordCanvas?: boolean;
|
||||
preserveWhiteSpace?: boolean;
|
||||
@@ -850,6 +861,7 @@ function snapshot(
|
||||
recordCanvas = false,
|
||||
maskAllInputs = false,
|
||||
maskTextFn,
|
||||
maskInputFn,
|
||||
slimDOM = false,
|
||||
preserveWhiteSpace,
|
||||
onSerialize,
|
||||
@@ -913,6 +925,7 @@ function snapshot(
|
||||
inlineStylesheet,
|
||||
maskInputOptions,
|
||||
maskTextFn,
|
||||
maskInputFn,
|
||||
slimDOMOptions,
|
||||
recordCanvas,
|
||||
preserveWhiteSpace,
|
||||
|
||||
@@ -108,5 +108,6 @@ export type SlimDOMOptions = Partial<{
|
||||
}>;
|
||||
|
||||
export type MaskTextFn = (text: string) => string;
|
||||
export type MaskInputFn = (text: string) => string;
|
||||
|
||||
export type KeepIframeSrcFn = (src: string) => boolean;
|
||||
|
||||
29
src/utils.ts
29
src/utils.ts
@@ -1,4 +1,4 @@
|
||||
import { INode } from './types';
|
||||
import { INode, MaskInputFn, MaskInputOptions } from './types';
|
||||
|
||||
export function isElement(n: Node | INode): n is Element {
|
||||
return n.nodeType === n.ELEMENT_NODE;
|
||||
@@ -8,3 +8,30 @@ export function isShadowRoot(n: Node): n is ShadowRoot {
|
||||
const host: Element | null = (n as ShadowRoot)?.host;
|
||||
return Boolean(host && host.shadowRoot && host.shadowRoot === n);
|
||||
}
|
||||
|
||||
export function maskInputValue({
|
||||
maskInputOptions,
|
||||
tagName,
|
||||
type,
|
||||
value,
|
||||
maskInputFn,
|
||||
}: {
|
||||
maskInputOptions: MaskInputOptions;
|
||||
tagName: string;
|
||||
type: string | number | boolean | null;
|
||||
value: string | null;
|
||||
maskInputFn?: MaskInputFn;
|
||||
}): string {
|
||||
let text = value || '';
|
||||
if (
|
||||
maskInputOptions[tagName.toLowerCase() as keyof MaskInputOptions] ||
|
||||
maskInputOptions[type as keyof MaskInputOptions]
|
||||
) {
|
||||
if (maskInputFn) {
|
||||
text = maskInputFn(text);
|
||||
} else {
|
||||
text = '*'.repeat(text.length);
|
||||
}
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
4
typings/snapshot.d.ts
vendored
4
typings/snapshot.d.ts
vendored
@@ -1,4 +1,4 @@
|
||||
import { serializedNodeWithId, INode, idNodeMap, MaskInputOptions, SlimDOMOptions, MaskTextFn, KeepIframeSrcFn } from './types';
|
||||
import { serializedNodeWithId, INode, idNodeMap, MaskInputOptions, SlimDOMOptions, MaskTextFn, MaskInputFn, KeepIframeSrcFn } from './types';
|
||||
export declare const IGNORED_NODE = -2;
|
||||
export declare function absoluteToStylesheet(cssText: string | null, href: string): string;
|
||||
export declare function absoluteToDoc(doc: Document, attributeValue: string): string;
|
||||
@@ -16,6 +16,7 @@ export declare function serializeNodeWithId(n: Node | INode, options: {
|
||||
inlineStylesheet: boolean;
|
||||
maskInputOptions?: MaskInputOptions;
|
||||
maskTextFn: MaskTextFn | undefined;
|
||||
maskInputFn: MaskInputFn | undefined;
|
||||
slimDOMOptions: SlimDOMOptions;
|
||||
keepIframeSrcFn?: KeepIframeSrcFn;
|
||||
recordCanvas?: boolean;
|
||||
@@ -32,6 +33,7 @@ declare function snapshot(n: Document, options?: {
|
||||
inlineStylesheet?: boolean;
|
||||
maskAllInputs?: boolean | MaskInputOptions;
|
||||
maskTextFn?: MaskTextFn;
|
||||
maskInputFn?: MaskTextFn;
|
||||
slimDOM?: boolean | SlimDOMOptions;
|
||||
recordCanvas?: boolean;
|
||||
preserveWhiteSpace?: boolean;
|
||||
|
||||
1
typings/types.d.ts
vendored
1
typings/types.d.ts
vendored
@@ -88,4 +88,5 @@ export declare type SlimDOMOptions = Partial<{
|
||||
headMetaVerification: boolean;
|
||||
}>;
|
||||
export declare type MaskTextFn = (text: string) => string;
|
||||
export declare type MaskInputFn = (text: string) => string;
|
||||
export declare type KeepIframeSrcFn = (src: string) => boolean;
|
||||
|
||||
9
typings/utils.d.ts
vendored
9
typings/utils.d.ts
vendored
@@ -1,3 +1,10 @@
|
||||
import { INode } from './types';
|
||||
import { INode, MaskInputFn, MaskInputOptions } from './types';
|
||||
export declare function isElement(n: Node | INode): n is Element;
|
||||
export declare function isShadowRoot(n: Node): n is ShadowRoot;
|
||||
export declare function maskInputValue({ maskInputOptions, tagName, type, value, maskInputFn, }: {
|
||||
maskInputOptions: MaskInputOptions;
|
||||
tagName: string;
|
||||
type: string | number | boolean | null;
|
||||
value: string | null;
|
||||
maskInputFn?: MaskInputFn;
|
||||
}): string;
|
||||
|
||||
Reference in New Issue
Block a user