mirror of
https://github.com/mofeng-git/One-KVM.git
synced 2026-03-16 16:07:07 +08:00
init
This commit is contained in:
176
web/src/lib/charToHid.ts
Normal file
176
web/src/lib/charToHid.ts
Normal file
@@ -0,0 +1,176 @@
|
||||
// Character to JavaScript keyCode mapping for text paste functionality
|
||||
// Maps printable ASCII characters to JavaScript keyCodes that the backend expects
|
||||
// The backend (keymap.rs) will convert these JS keyCodes to USB HID keycodes
|
||||
|
||||
export interface CharKeyMapping {
|
||||
keyCode: number // JavaScript keyCode (same as KeyboardEvent.keyCode)
|
||||
shift: boolean // Whether Shift modifier is needed
|
||||
}
|
||||
|
||||
// US QWERTY keyboard layout mapping
|
||||
// Maps characters to their JavaScript keyCode and whether Shift is required
|
||||
const charToKeyMap: Record<string, CharKeyMapping> = {
|
||||
// Lowercase letters (no shift) - JS keyCodes 65-90
|
||||
a: { keyCode: 65, shift: false },
|
||||
b: { keyCode: 66, shift: false },
|
||||
c: { keyCode: 67, shift: false },
|
||||
d: { keyCode: 68, shift: false },
|
||||
e: { keyCode: 69, shift: false },
|
||||
f: { keyCode: 70, shift: false },
|
||||
g: { keyCode: 71, shift: false },
|
||||
h: { keyCode: 72, shift: false },
|
||||
i: { keyCode: 73, shift: false },
|
||||
j: { keyCode: 74, shift: false },
|
||||
k: { keyCode: 75, shift: false },
|
||||
l: { keyCode: 76, shift: false },
|
||||
m: { keyCode: 77, shift: false },
|
||||
n: { keyCode: 78, shift: false },
|
||||
o: { keyCode: 79, shift: false },
|
||||
p: { keyCode: 80, shift: false },
|
||||
q: { keyCode: 81, shift: false },
|
||||
r: { keyCode: 82, shift: false },
|
||||
s: { keyCode: 83, shift: false },
|
||||
t: { keyCode: 84, shift: false },
|
||||
u: { keyCode: 85, shift: false },
|
||||
v: { keyCode: 86, shift: false },
|
||||
w: { keyCode: 87, shift: false },
|
||||
x: { keyCode: 88, shift: false },
|
||||
y: { keyCode: 89, shift: false },
|
||||
z: { keyCode: 90, shift: false },
|
||||
|
||||
// Uppercase letters (with shift) - same keyCodes, just with Shift
|
||||
A: { keyCode: 65, shift: true },
|
||||
B: { keyCode: 66, shift: true },
|
||||
C: { keyCode: 67, shift: true },
|
||||
D: { keyCode: 68, shift: true },
|
||||
E: { keyCode: 69, shift: true },
|
||||
F: { keyCode: 70, shift: true },
|
||||
G: { keyCode: 71, shift: true },
|
||||
H: { keyCode: 72, shift: true },
|
||||
I: { keyCode: 73, shift: true },
|
||||
J: { keyCode: 74, shift: true },
|
||||
K: { keyCode: 75, shift: true },
|
||||
L: { keyCode: 76, shift: true },
|
||||
M: { keyCode: 77, shift: true },
|
||||
N: { keyCode: 78, shift: true },
|
||||
O: { keyCode: 79, shift: true },
|
||||
P: { keyCode: 80, shift: true },
|
||||
Q: { keyCode: 81, shift: true },
|
||||
R: { keyCode: 82, shift: true },
|
||||
S: { keyCode: 83, shift: true },
|
||||
T: { keyCode: 84, shift: true },
|
||||
U: { keyCode: 85, shift: true },
|
||||
V: { keyCode: 86, shift: true },
|
||||
W: { keyCode: 87, shift: true },
|
||||
X: { keyCode: 88, shift: true },
|
||||
Y: { keyCode: 89, shift: true },
|
||||
Z: { keyCode: 90, shift: true },
|
||||
|
||||
// Numbers (no shift) - JS keyCodes 48-57
|
||||
'0': { keyCode: 48, shift: false },
|
||||
'1': { keyCode: 49, shift: false },
|
||||
'2': { keyCode: 50, shift: false },
|
||||
'3': { keyCode: 51, shift: false },
|
||||
'4': { keyCode: 52, shift: false },
|
||||
'5': { keyCode: 53, shift: false },
|
||||
'6': { keyCode: 54, shift: false },
|
||||
'7': { keyCode: 55, shift: false },
|
||||
'8': { keyCode: 56, shift: false },
|
||||
'9': { keyCode: 57, shift: false },
|
||||
|
||||
// Shifted number row symbols (US layout)
|
||||
')': { keyCode: 48, shift: true }, // Shift + 0
|
||||
'!': { keyCode: 49, shift: true }, // Shift + 1
|
||||
'@': { keyCode: 50, shift: true }, // Shift + 2
|
||||
'#': { keyCode: 51, shift: true }, // Shift + 3
|
||||
$: { keyCode: 52, shift: true }, // Shift + 4
|
||||
'%': { keyCode: 53, shift: true }, // Shift + 5
|
||||
'^': { keyCode: 54, shift: true }, // Shift + 6
|
||||
'&': { keyCode: 55, shift: true }, // Shift + 7
|
||||
'*': { keyCode: 56, shift: true }, // Shift + 8
|
||||
'(': { keyCode: 57, shift: true }, // Shift + 9
|
||||
|
||||
// Punctuation and symbols (no shift) - US layout JS keyCodes
|
||||
'-': { keyCode: 189, shift: false }, // Minus
|
||||
'=': { keyCode: 187, shift: false }, // Equal
|
||||
'[': { keyCode: 219, shift: false }, // Left bracket
|
||||
']': { keyCode: 221, shift: false }, // Right bracket
|
||||
'\\': { keyCode: 220, shift: false }, // Backslash
|
||||
';': { keyCode: 186, shift: false }, // Semicolon
|
||||
"'": { keyCode: 222, shift: false }, // Apostrophe/Quote
|
||||
'`': { keyCode: 192, shift: false }, // Grave/Backtick
|
||||
',': { keyCode: 188, shift: false }, // Comma
|
||||
'.': { keyCode: 190, shift: false }, // Period
|
||||
'/': { keyCode: 191, shift: false }, // Slash
|
||||
|
||||
// Shifted punctuation and symbols (US layout)
|
||||
_: { keyCode: 189, shift: true }, // Shift + Minus = Underscore
|
||||
'+': { keyCode: 187, shift: true }, // Shift + Equal = Plus
|
||||
'{': { keyCode: 219, shift: true }, // Shift + [ = {
|
||||
'}': { keyCode: 221, shift: true }, // Shift + ] = }
|
||||
'|': { keyCode: 220, shift: true }, // Shift + \ = |
|
||||
':': { keyCode: 186, shift: true }, // Shift + ; = :
|
||||
'"': { keyCode: 222, shift: true }, // Shift + ' = "
|
||||
'~': { keyCode: 192, shift: true }, // Shift + ` = ~
|
||||
'<': { keyCode: 188, shift: true }, // Shift + , = <
|
||||
'>': { keyCode: 190, shift: true }, // Shift + . = >
|
||||
'?': { keyCode: 191, shift: true }, // Shift + / = ?
|
||||
|
||||
// Whitespace and control characters
|
||||
' ': { keyCode: 32, shift: false }, // Space
|
||||
'\t': { keyCode: 9, shift: false }, // Tab
|
||||
'\n': { keyCode: 13, shift: false }, // Enter (LF)
|
||||
'\r': { keyCode: 13, shift: false }, // Enter (CR)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the JavaScript keyCode and modifier state for a character
|
||||
* @param char - Single character to convert
|
||||
* @returns CharKeyMapping or null if character is not mappable
|
||||
*/
|
||||
export function charToKey(char: string): CharKeyMapping | null {
|
||||
if (char.length !== 1) return null
|
||||
return charToKeyMap[char] || null
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a character can be typed via HID
|
||||
* @param char - Single character to check
|
||||
*/
|
||||
export function isTypableChar(char: string): boolean {
|
||||
return char.length === 1 && char in charToKeyMap
|
||||
}
|
||||
|
||||
/**
|
||||
* Get statistics about text typeability
|
||||
* @param text - Text to analyze
|
||||
* @returns Object with total, typable, and untypable character counts
|
||||
*/
|
||||
export function analyzeText(text: string): {
|
||||
total: number
|
||||
typable: number
|
||||
untypable: number
|
||||
untypableChars: string[]
|
||||
} {
|
||||
const untypableChars: string[] = []
|
||||
let typable = 0
|
||||
let untypable = 0
|
||||
|
||||
for (const char of text) {
|
||||
if (isTypableChar(char)) {
|
||||
typable++
|
||||
} else {
|
||||
untypable++
|
||||
if (!untypableChars.includes(char)) {
|
||||
untypableChars.push(char)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
total: text.length,
|
||||
typable,
|
||||
untypable,
|
||||
untypableChars,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user