7
7
idNodeMap ,
8
8
MaskInputOptions ,
9
9
SlimDOMOptions ,
10
+ MaskTextFn ,
10
11
} from './types' ;
11
12
import { isElement , isShadowRoot } from './utils' ;
12
13
@@ -206,6 +207,40 @@ export function _isBlockedElement(
206
207
return false ;
207
208
}
208
209
210
+ export function needMaskingText (
211
+ node : Node | null ,
212
+ maskTextClass : string | RegExp ,
213
+ maskTextSelector : string | null ,
214
+ ) : boolean {
215
+ if ( ! node ) {
216
+ return false ;
217
+ }
218
+ if ( node . nodeType === node . ELEMENT_NODE ) {
219
+ if ( typeof maskTextClass === 'string' ) {
220
+ if ( ( node as HTMLElement ) . classList . contains ( maskTextClass ) ) {
221
+ return true ;
222
+ }
223
+ } else {
224
+ ( node as HTMLElement ) . classList . forEach ( ( className ) => {
225
+ if ( maskTextClass . test ( className ) ) {
226
+ return true ;
227
+ }
228
+ } ) ;
229
+ }
230
+ if ( maskTextSelector ) {
231
+ if ( ( node as HTMLElement ) . matches ( maskTextSelector ) ) {
232
+ return true ;
233
+ }
234
+ }
235
+ return needMaskingText ( node . parentNode , maskTextClass , maskTextSelector ) ;
236
+ }
237
+ if ( node . nodeType === node . TEXT_NODE ) {
238
+ // check parent node since text node do not have class name
239
+ return needMaskingText ( node . parentNode , maskTextClass , maskTextSelector ) ;
240
+ }
241
+ return needMaskingText ( node . parentNode , maskTextClass , maskTextSelector ) ;
242
+ }
243
+
209
244
// https://stackoverflow.com/a/36155560
210
245
function onceIframeLoaded (
211
246
iframeEl : HTMLIFrameElement ,
@@ -259,17 +294,23 @@ function serializeNode(
259
294
doc : Document ;
260
295
blockClass : string | RegExp ;
261
296
blockSelector : string | null ;
297
+ maskTextClass : string | RegExp ;
298
+ maskTextSelector : string | null ;
262
299
inlineStylesheet : boolean ;
263
300
maskInputOptions : MaskInputOptions ;
301
+ maskTextFn : MaskTextFn | undefined ;
264
302
recordCanvas : boolean ;
265
303
} ,
266
304
) : serializedNode | false {
267
305
const {
268
306
doc,
269
307
blockClass,
270
308
blockSelector,
309
+ maskTextClass,
310
+ maskTextSelector,
271
311
inlineStylesheet,
272
312
maskInputOptions = { } ,
313
+ maskTextFn,
273
314
recordCanvas,
274
315
} = options ;
275
316
// Only record root id when document object is not the base document
@@ -412,12 +453,23 @@ function serializeNode(
412
453
n . parentNode && ( n . parentNode as HTMLElement ) . tagName ;
413
454
let textContent = ( n as Text ) . textContent ;
414
455
const isStyle = parentTagName === 'STYLE' ? true : undefined ;
456
+ const isScript = parentTagName === 'SCRIPT' ? true : undefined ;
415
457
if ( isStyle && textContent ) {
416
458
textContent = absoluteToStylesheet ( textContent , getHref ( ) ) ;
417
459
}
418
- if ( parentTagName === 'SCRIPT' ) {
460
+ if ( isScript ) {
419
461
textContent = 'SCRIPT_PLACEHOLDER' ;
420
462
}
463
+ if (
464
+ ! isStyle &&
465
+ ! isScript &&
466
+ needMaskingText ( n , maskTextClass , maskTextSelector ) &&
467
+ textContent
468
+ ) {
469
+ textContent = maskTextFn
470
+ ? maskTextFn ( textContent )
471
+ : textContent . replace ( / [ \S ] / g, '*' ) ;
472
+ }
421
473
return {
422
474
type : NodeType . Text ,
423
475
textContent : textContent || '' ,
@@ -540,9 +592,12 @@ export function serializeNodeWithId(
540
592
map : idNodeMap ;
541
593
blockClass : string | RegExp ;
542
594
blockSelector : string | null ;
595
+ maskTextClass : string | RegExp ;
596
+ maskTextSelector : string | null ;
543
597
skipChild : boolean ;
544
598
inlineStylesheet : boolean ;
545
599
maskInputOptions ?: MaskInputOptions ;
600
+ maskTextFn : MaskTextFn | undefined ;
546
601
slimDOMOptions : SlimDOMOptions ;
547
602
recordCanvas ?: boolean ;
548
603
preserveWhiteSpace ?: boolean ;
@@ -556,9 +611,12 @@ export function serializeNodeWithId(
556
611
map,
557
612
blockClass,
558
613
blockSelector,
614
+ maskTextClass,
615
+ maskTextSelector,
559
616
skipChild = false ,
560
617
inlineStylesheet = true ,
561
618
maskInputOptions = { } ,
619
+ maskTextFn,
562
620
slimDOMOptions,
563
621
recordCanvas = false ,
564
622
onSerialize,
@@ -570,8 +628,11 @@ export function serializeNodeWithId(
570
628
doc,
571
629
blockClass,
572
630
blockSelector,
631
+ maskTextClass,
632
+ maskTextSelector,
573
633
inlineStylesheet,
574
634
maskInputOptions,
635
+ maskTextFn,
575
636
recordCanvas,
576
637
} ) ;
577
638
if ( ! _serializedNode ) {
@@ -628,9 +689,12 @@ export function serializeNodeWithId(
628
689
map,
629
690
blockClass,
630
691
blockSelector,
692
+ maskTextClass,
693
+ maskTextSelector,
631
694
skipChild,
632
695
inlineStylesheet,
633
696
maskInputOptions,
697
+ maskTextFn,
634
698
slimDOMOptions,
635
699
recordCanvas,
636
700
preserveWhiteSpace,
@@ -675,9 +739,12 @@ export function serializeNodeWithId(
675
739
map,
676
740
blockClass,
677
741
blockSelector,
742
+ maskTextClass,
743
+ maskTextSelector,
678
744
skipChild : false ,
679
745
inlineStylesheet,
680
746
maskInputOptions,
747
+ maskTextFn,
681
748
slimDOMOptions,
682
749
recordCanvas,
683
750
preserveWhiteSpace,
@@ -702,11 +769,14 @@ function snapshot(
702
769
n : Document ,
703
770
options ?: {
704
771
blockClass ?: string | RegExp ;
772
+ blockSelector ?: string | null ;
773
+ maskTextClass ?: string | RegExp ;
774
+ maskTextSelector ?: string | null ;
705
775
inlineStylesheet ?: boolean ;
706
776
maskAllInputs ?: boolean | MaskInputOptions ;
777
+ maskTextFn ?: MaskTextFn ;
707
778
slimDOM ?: boolean | SlimDOMOptions ;
708
779
recordCanvas ?: boolean ;
709
- blockSelector ?: string | null ;
710
780
preserveWhiteSpace ?: boolean ;
711
781
onSerialize ?: ( n : INode ) => unknown ;
712
782
onIframeLoad ?: ( iframeINode : INode , node : serializedNodeWithId ) => unknown ;
@@ -715,10 +785,13 @@ function snapshot(
715
785
) : [ serializedNodeWithId | null , idNodeMap ] {
716
786
const {
717
787
blockClass = 'rr-block' ,
788
+ blockSelector = null ,
789
+ maskTextClass = 'rr-mask' ,
790
+ maskTextSelector = null ,
718
791
inlineStylesheet = true ,
719
792
recordCanvas = false ,
720
- blockSelector = null ,
721
793
maskAllInputs = false ,
794
+ maskTextFn,
722
795
slimDOM = false ,
723
796
preserveWhiteSpace,
724
797
onSerialize,
@@ -772,9 +845,12 @@ function snapshot(
772
845
map : idNodeMap ,
773
846
blockClass,
774
847
blockSelector,
848
+ maskTextClass,
849
+ maskTextSelector,
775
850
skipChild : false ,
776
851
inlineStylesheet,
777
852
maskInputOptions,
853
+ maskTextFn,
778
854
slimDOMOptions,
779
855
recordCanvas,
780
856
preserveWhiteSpace,
0 commit comments