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,
|
MaskInputOptions,
|
||||||
SlimDOMOptions,
|
SlimDOMOptions,
|
||||||
MaskTextFn,
|
MaskTextFn,
|
||||||
|
MaskInputFn,
|
||||||
KeepIframeSrcFn,
|
KeepIframeSrcFn,
|
||||||
} from './types';
|
} from './types';
|
||||||
import { isElement, isShadowRoot } from './utils';
|
import { isElement, isShadowRoot, maskInputValue } from './utils';
|
||||||
|
|
||||||
let _id = 1;
|
let _id = 1;
|
||||||
const tagNameRegex = RegExp('[^a-z0-9-_:]');
|
const tagNameRegex = RegExp('[^a-z0-9-_:]');
|
||||||
@@ -348,6 +349,7 @@ function serializeNode(
|
|||||||
inlineStylesheet: boolean;
|
inlineStylesheet: boolean;
|
||||||
maskInputOptions: MaskInputOptions;
|
maskInputOptions: MaskInputOptions;
|
||||||
maskTextFn: MaskTextFn | undefined;
|
maskTextFn: MaskTextFn | undefined;
|
||||||
|
maskInputFn: MaskInputFn | undefined;
|
||||||
recordCanvas: boolean;
|
recordCanvas: boolean;
|
||||||
keepIframeSrcFn: KeepIframeSrcFn;
|
keepIframeSrcFn: KeepIframeSrcFn;
|
||||||
},
|
},
|
||||||
@@ -361,13 +363,14 @@ function serializeNode(
|
|||||||
inlineStylesheet,
|
inlineStylesheet,
|
||||||
maskInputOptions = {},
|
maskInputOptions = {},
|
||||||
maskTextFn,
|
maskTextFn,
|
||||||
|
maskInputFn,
|
||||||
recordCanvas,
|
recordCanvas,
|
||||||
keepIframeSrcFn,
|
keepIframeSrcFn,
|
||||||
} = options;
|
} = options;
|
||||||
// Only record root id when document object is not the base document
|
// Only record root id when document object is not the base document
|
||||||
let rootId: number | undefined;
|
let rootId: number | undefined;
|
||||||
if (((doc as unknown) as INode).__sn) {
|
if ((doc as unknown as INode).__sn) {
|
||||||
const docId = ((doc as unknown) as INode).__sn.id;
|
const docId = (doc as unknown as INode).__sn.id;
|
||||||
rootId = docId === 1 ? undefined : docId;
|
rootId = docId === 1 ? undefined : docId;
|
||||||
}
|
}
|
||||||
switch (n.nodeType) {
|
switch (n.nodeType) {
|
||||||
@@ -443,11 +446,13 @@ function serializeNode(
|
|||||||
attributes.type !== 'button' &&
|
attributes.type !== 'button' &&
|
||||||
value
|
value
|
||||||
) {
|
) {
|
||||||
attributes.value =
|
attributes.value = maskInputValue({
|
||||||
maskInputOptions[attributes.type as keyof MaskInputOptions] ||
|
type: attributes.type,
|
||||||
maskInputOptions[tagName as keyof MaskInputOptions]
|
tagName,
|
||||||
? '*'.repeat(value.length)
|
value,
|
||||||
: value;
|
maskInputOptions,
|
||||||
|
maskInputFn,
|
||||||
|
});
|
||||||
} else if ((n as HTMLInputElement).checked) {
|
} else if ((n as HTMLInputElement).checked) {
|
||||||
attributes.checked = (n as HTMLInputElement).checked;
|
attributes.checked = (n as HTMLInputElement).checked;
|
||||||
}
|
}
|
||||||
@@ -650,6 +655,7 @@ export function serializeNodeWithId(
|
|||||||
inlineStylesheet: boolean;
|
inlineStylesheet: boolean;
|
||||||
maskInputOptions?: MaskInputOptions;
|
maskInputOptions?: MaskInputOptions;
|
||||||
maskTextFn: MaskTextFn | undefined;
|
maskTextFn: MaskTextFn | undefined;
|
||||||
|
maskInputFn: MaskInputFn | undefined;
|
||||||
slimDOMOptions: SlimDOMOptions;
|
slimDOMOptions: SlimDOMOptions;
|
||||||
keepIframeSrcFn?: KeepIframeSrcFn;
|
keepIframeSrcFn?: KeepIframeSrcFn;
|
||||||
recordCanvas?: boolean;
|
recordCanvas?: boolean;
|
||||||
@@ -670,6 +676,7 @@ export function serializeNodeWithId(
|
|||||||
inlineStylesheet = true,
|
inlineStylesheet = true,
|
||||||
maskInputOptions = {},
|
maskInputOptions = {},
|
||||||
maskTextFn,
|
maskTextFn,
|
||||||
|
maskInputFn,
|
||||||
slimDOMOptions,
|
slimDOMOptions,
|
||||||
recordCanvas = false,
|
recordCanvas = false,
|
||||||
onSerialize,
|
onSerialize,
|
||||||
@@ -687,6 +694,7 @@ export function serializeNodeWithId(
|
|||||||
inlineStylesheet,
|
inlineStylesheet,
|
||||||
maskInputOptions,
|
maskInputOptions,
|
||||||
maskTextFn,
|
maskTextFn,
|
||||||
|
maskInputFn,
|
||||||
recordCanvas,
|
recordCanvas,
|
||||||
keepIframeSrcFn,
|
keepIframeSrcFn,
|
||||||
});
|
});
|
||||||
@@ -750,6 +758,7 @@ export function serializeNodeWithId(
|
|||||||
inlineStylesheet,
|
inlineStylesheet,
|
||||||
maskInputOptions,
|
maskInputOptions,
|
||||||
maskTextFn,
|
maskTextFn,
|
||||||
|
maskInputFn,
|
||||||
slimDOMOptions,
|
slimDOMOptions,
|
||||||
recordCanvas,
|
recordCanvas,
|
||||||
preserveWhiteSpace,
|
preserveWhiteSpace,
|
||||||
@@ -801,6 +810,7 @@ export function serializeNodeWithId(
|
|||||||
inlineStylesheet,
|
inlineStylesheet,
|
||||||
maskInputOptions,
|
maskInputOptions,
|
||||||
maskTextFn,
|
maskTextFn,
|
||||||
|
maskInputFn,
|
||||||
slimDOMOptions,
|
slimDOMOptions,
|
||||||
recordCanvas,
|
recordCanvas,
|
||||||
preserveWhiteSpace,
|
preserveWhiteSpace,
|
||||||
@@ -832,6 +842,7 @@ function snapshot(
|
|||||||
inlineStylesheet?: boolean;
|
inlineStylesheet?: boolean;
|
||||||
maskAllInputs?: boolean | MaskInputOptions;
|
maskAllInputs?: boolean | MaskInputOptions;
|
||||||
maskTextFn?: MaskTextFn;
|
maskTextFn?: MaskTextFn;
|
||||||
|
maskInputFn?: MaskTextFn;
|
||||||
slimDOM?: boolean | SlimDOMOptions;
|
slimDOM?: boolean | SlimDOMOptions;
|
||||||
recordCanvas?: boolean;
|
recordCanvas?: boolean;
|
||||||
preserveWhiteSpace?: boolean;
|
preserveWhiteSpace?: boolean;
|
||||||
@@ -850,6 +861,7 @@ function snapshot(
|
|||||||
recordCanvas = false,
|
recordCanvas = false,
|
||||||
maskAllInputs = false,
|
maskAllInputs = false,
|
||||||
maskTextFn,
|
maskTextFn,
|
||||||
|
maskInputFn,
|
||||||
slimDOM = false,
|
slimDOM = false,
|
||||||
preserveWhiteSpace,
|
preserveWhiteSpace,
|
||||||
onSerialize,
|
onSerialize,
|
||||||
@@ -913,6 +925,7 @@ function snapshot(
|
|||||||
inlineStylesheet,
|
inlineStylesheet,
|
||||||
maskInputOptions,
|
maskInputOptions,
|
||||||
maskTextFn,
|
maskTextFn,
|
||||||
|
maskInputFn,
|
||||||
slimDOMOptions,
|
slimDOMOptions,
|
||||||
recordCanvas,
|
recordCanvas,
|
||||||
preserveWhiteSpace,
|
preserveWhiteSpace,
|
||||||
|
|||||||
@@ -108,5 +108,6 @@ export type SlimDOMOptions = Partial<{
|
|||||||
}>;
|
}>;
|
||||||
|
|
||||||
export type MaskTextFn = (text: string) => string;
|
export type MaskTextFn = (text: string) => string;
|
||||||
|
export type MaskInputFn = (text: string) => string;
|
||||||
|
|
||||||
export type KeepIframeSrcFn = (src: string) => boolean;
|
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 {
|
export function isElement(n: Node | INode): n is Element {
|
||||||
return n.nodeType === n.ELEMENT_NODE;
|
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;
|
const host: Element | null = (n as ShadowRoot)?.host;
|
||||||
return Boolean(host && host.shadowRoot && host.shadowRoot === n);
|
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 const IGNORED_NODE = -2;
|
||||||
export declare function absoluteToStylesheet(cssText: string | null, href: string): string;
|
export declare function absoluteToStylesheet(cssText: string | null, href: string): string;
|
||||||
export declare function absoluteToDoc(doc: Document, attributeValue: 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;
|
inlineStylesheet: boolean;
|
||||||
maskInputOptions?: MaskInputOptions;
|
maskInputOptions?: MaskInputOptions;
|
||||||
maskTextFn: MaskTextFn | undefined;
|
maskTextFn: MaskTextFn | undefined;
|
||||||
|
maskInputFn: MaskInputFn | undefined;
|
||||||
slimDOMOptions: SlimDOMOptions;
|
slimDOMOptions: SlimDOMOptions;
|
||||||
keepIframeSrcFn?: KeepIframeSrcFn;
|
keepIframeSrcFn?: KeepIframeSrcFn;
|
||||||
recordCanvas?: boolean;
|
recordCanvas?: boolean;
|
||||||
@@ -32,6 +33,7 @@ declare function snapshot(n: Document, options?: {
|
|||||||
inlineStylesheet?: boolean;
|
inlineStylesheet?: boolean;
|
||||||
maskAllInputs?: boolean | MaskInputOptions;
|
maskAllInputs?: boolean | MaskInputOptions;
|
||||||
maskTextFn?: MaskTextFn;
|
maskTextFn?: MaskTextFn;
|
||||||
|
maskInputFn?: MaskTextFn;
|
||||||
slimDOM?: boolean | SlimDOMOptions;
|
slimDOM?: boolean | SlimDOMOptions;
|
||||||
recordCanvas?: boolean;
|
recordCanvas?: boolean;
|
||||||
preserveWhiteSpace?: 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;
|
headMetaVerification: boolean;
|
||||||
}>;
|
}>;
|
||||||
export declare type MaskTextFn = (text: string) => string;
|
export declare type MaskTextFn = (text: string) => string;
|
||||||
|
export declare type MaskInputFn = (text: string) => string;
|
||||||
export declare type KeepIframeSrcFn = (src: string) => boolean;
|
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 isElement(n: Node | INode): n is Element;
|
||||||
export declare function isShadowRoot(n: Node): n is ShadowRoot;
|
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