-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: masking inputs on change when maskAllInputs:false
#61
Changes from all commits
e812910
2ba61fa
f433d2a
8aee828
136c45d
7033081
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,6 +9,54 @@ export function isShadowRoot(n: Node): n is ShadowRoot { | |
return Boolean(host && host.shadowRoot && host.shadowRoot === n); | ||
} | ||
|
||
interface IsInputTypeMasked { | ||
maskInputOptions: MaskInputOptions; | ||
tagName: string; | ||
type: string | number | boolean | null; | ||
} | ||
|
||
/** | ||
* Check `maskInputOptions` if the element, based on tag name and `type` attribute, should be masked. | ||
* If `<input>` has no `type`, default to using `type="text"`. | ||
*/ | ||
function isInputTypeMasked({ | ||
maskInputOptions, | ||
tagName, | ||
type, | ||
}: IsInputTypeMasked) { | ||
return ( | ||
maskInputOptions[tagName.toLowerCase() as keyof MaskInputOptions] || | ||
maskInputOptions[type as keyof MaskInputOptions] || | ||
// Default to "text" option for inputs without a "type" attribute defined | ||
(tagName === 'input' && !type && maskInputOptions['text']) | ||
); | ||
} | ||
|
||
interface HasInputMaskOptions extends IsInputTypeMasked { | ||
maskInputSelector: string | null; | ||
} | ||
|
||
/** | ||
* Determine if there are masking options configured and if `maskInputValue` needs to be called | ||
*/ | ||
export function hasInputMaskOptions({ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same question here |
||
tagName, | ||
type, | ||
maskInputOptions, | ||
maskInputSelector, | ||
}: HasInputMaskOptions) { | ||
return ( | ||
maskInputSelector || isInputTypeMasked({ maskInputOptions, tagName, type }) | ||
); | ||
} | ||
|
||
interface MaskInputValue extends HasInputMaskOptions { | ||
input: HTMLElement; | ||
unmaskInputSelector: string | null; | ||
value: string | null; | ||
maskInputFn?: MaskInputFn; | ||
} | ||
|
||
export function maskInputValue({ | ||
input, | ||
maskInputSelector, | ||
|
@@ -18,26 +66,15 @@ export function maskInputValue({ | |
type, | ||
value, | ||
maskInputFn, | ||
}: { | ||
input: HTMLElement; | ||
maskInputSelector: string | null; | ||
unmaskInputSelector: string | null; | ||
maskInputOptions: MaskInputOptions; | ||
tagName: string; | ||
type: string | number | boolean | null; | ||
value: string | null; | ||
maskInputFn?: MaskInputFn; | ||
}): string { | ||
}: MaskInputValue): string { | ||
let text = value || ''; | ||
|
||
if (unmaskInputSelector && input.matches(unmaskInputSelector)) { | ||
return text; | ||
} | ||
|
||
if ( | ||
maskInputOptions[tagName.toLowerCase() as keyof MaskInputOptions] || | ||
maskInputOptions[type as keyof MaskInputOptions] || | ||
(tagName === 'input' && !type && maskInputOptions['text']) || // For inputs without a "type" attribute defined | ||
isInputTypeMasked({ maskInputOptions, tagName, type }) || | ||
(maskInputSelector && input.matches(maskInputSelector)) | ||
) { | ||
if (maskInputFn) { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,21 @@ | ||
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({ input, maskInputSelector, unmaskInputSelector, maskInputOptions, tagName, type, value, maskInputFn, }: { | ||
input: HTMLElement; | ||
maskInputSelector: string | null; | ||
unmaskInputSelector: string | null; | ||
interface IsInputTypeMasked { | ||
maskInputOptions: MaskInputOptions; | ||
tagName: string; | ||
type: string | number | boolean | null; | ||
} | ||
interface HasInputMaskOptions extends IsInputTypeMasked { | ||
maskInputSelector: string | null; | ||
} | ||
export declare function hasInputMaskOptions({ tagName, type, maskInputOptions, maskInputSelector, }: HasInputMaskOptions): string | boolean | undefined; | ||
interface MaskInputValue extends HasInputMaskOptions { | ||
input: HTMLElement; | ||
unmaskInputSelector: string | null; | ||
value: string | null; | ||
maskInputFn?: MaskInputFn; | ||
}): string; | ||
} | ||
export declare function maskInputValue({ input, maskInputSelector, unmaskInputSelector, maskInputOptions, tagName, type, value, maskInputFn, }: MaskInputValue): string; | ||
export declare function is2DCanvasBlank(canvas: HTMLCanvasElement): boolean; | ||
export {}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
import { | ||
INode, | ||
MaskInputOptions, | ||
hasInputMaskOptions, | ||
maskInputValue, | ||
} from '@sentry-internal/rrweb-snapshot'; | ||
import { FontFaceSet } from 'css-font-loading-module'; | ||
|
@@ -365,15 +365,18 @@ function initInputObserver({ | |
) { | ||
return; | ||
} | ||
|
||
let text = (target as HTMLInputElement).value; | ||
let isChecked = false; | ||
if (type === 'radio' || type === 'checkbox') { | ||
isChecked = (target as HTMLInputElement).checked; | ||
} else if ( | ||
maskInputOptions[ | ||
(target as Element).tagName.toLowerCase() as keyof MaskInputOptions | ||
] || | ||
maskInputOptions[type as keyof MaskInputOptions] | ||
hasInputMaskOptions({ | ||
maskInputOptions, | ||
maskInputSelector, | ||
tagName: (target as HTMLElement).tagName, | ||
type, | ||
}) | ||
Comment on lines
+374
to
+379
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Previous PR I had removed this condition, but that meant it was calling There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That makes sense to me |
||
) { | ||
text = maskInputValue({ | ||
input: target as HTMLElement, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm probably missing something but why does this function not simply return a boolean? I checked usages and it seems like it's only used in if conditions anyway. I guess we wouldn't need the interface then either.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm? It does return a boolean... are the parens throwing you off? (prettier added them)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lol, sorry - it does of course. Yup, mistook the param type as the return type. Weekend here I come 😅