-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
/
Copy pathhandleKeyboardEvent.ts
67 lines (54 loc) · 2.05 KB
/
handleKeyboardEvent.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import { htmlTreeAsString } from '@sentry/core';
import type { Breadcrumb } from '@sentry/core';
import type { ReplayContainer } from '../types';
import { createBreadcrumb } from '../util/createBreadcrumb';
import { getBaseDomBreadcrumb } from './handleDom';
import { addBreadcrumbEvent } from './util/addBreadcrumbEvent';
/** Handle keyboard events & create breadcrumbs. */
export function handleKeyboardEvent(replay: ReplayContainer, event: KeyboardEvent): void {
if (!replay.isEnabled()) {
return;
}
// Update user activity, but do not restart recording as it can create
// noisy/low-value replays (e.g. user comes back from idle, hits alt-tab, new
// session with a single "keydown" breadcrumb is created)
replay.updateUserActivity();
const breadcrumb = getKeyboardBreadcrumb(event);
if (!breadcrumb) {
return;
}
addBreadcrumbEvent(replay, breadcrumb);
}
/** exported only for tests */
export function getKeyboardBreadcrumb(event: KeyboardEvent): Breadcrumb | null {
const { metaKey, shiftKey, ctrlKey, altKey, key, target } = event;
// never capture for input fields
if (!target || isInputElement(target as HTMLElement) || !key) {
return null;
}
// Note: We do not consider shift here, as that means "uppercase"
const hasModifierKey = metaKey || ctrlKey || altKey;
const isCharacterKey = key.length === 1; // other keys like Escape, Tab, etc have a longer length
// Do not capture breadcrumb if only a word key is pressed
// This could leak e.g. user input
if (!hasModifierKey && isCharacterKey) {
return null;
}
const message = htmlTreeAsString(target, { maxStringLength: 200 }) || '<unknown>';
const baseBreadcrumb = getBaseDomBreadcrumb(target as Node, message);
return createBreadcrumb({
category: 'ui.keyDown',
message,
data: {
...baseBreadcrumb.data,
metaKey,
shiftKey,
ctrlKey,
altKey,
key,
},
});
}
function isInputElement(target: HTMLElement): boolean {
return target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.isContentEditable;
}