* Handle keydown event * @param event - KeyboardEvent
(event: KeyboardEvent)
| 298 | * @param event - KeyboardEvent |
| 299 | */ |
| 300 | private handleKeyDown(event: KeyboardEvent): void { |
| 301 | if (this.isDisposed) return; |
| 302 | |
| 303 | // Ignore keydown events during composition |
| 304 | // Note: Some browsers send keyCode 229 for all keys during composition |
| 305 | if (this.isComposing || event.isComposing || event.keyCode === 229) { |
| 306 | return; |
| 307 | } |
| 308 | |
| 309 | // Emit onKey event first (before any processing) |
| 310 | if (this.onKeyCallback) { |
| 311 | this.onKeyCallback({ key: event.key, domEvent: event }); |
| 312 | } |
| 313 | |
| 314 | // Check custom key event handler |
| 315 | if (this.customKeyEventHandler) { |
| 316 | const handled = this.customKeyEventHandler(event); |
| 317 | if (handled) { |
| 318 | // Custom handler consumed the event |
| 319 | event.preventDefault(); |
| 320 | return; |
| 321 | } |
| 322 | } |
| 323 | |
| 324 | // Allow Ctrl+V and Cmd+V to trigger paste event (don't preventDefault) |
| 325 | if ((event.ctrlKey || event.metaKey) && event.code === 'KeyV') { |
| 326 | // Let the browser's native paste event fire |
| 327 | return; |
| 328 | } |
| 329 | |
| 330 | // Allow Cmd+C for copy (on Mac, Cmd+C should copy, not send interrupt) |
| 331 | // SelectionManager handles the actual copying |
| 332 | // Note: Ctrl+C on all platforms sends interrupt signal (0x03) |
| 333 | if (event.metaKey && event.code === 'KeyC') { |
| 334 | // Let browser/SelectionManager handle copy |
| 335 | return; |
| 336 | } |
| 337 | |
| 338 | // For printable characters without modifiers, send the character directly |
| 339 | // This handles: a-z, A-Z (with shift), 0-9, punctuation, etc. |
| 340 | if (this.isPrintableCharacter(event)) { |
| 341 | event.preventDefault(); |
| 342 | this.onDataCallback(event.key); |
| 343 | return; |
| 344 | } |
| 345 | |
| 346 | // Map the physical key code |
| 347 | const key = this.mapKeyCode(event.code); |
| 348 | if (key === null) { |
| 349 | // Unknown key - ignore it |
| 350 | return; |
| 351 | } |
| 352 | |
| 353 | // Extract modifiers |
| 354 | const mods = this.extractModifiers(event); |
| 355 | |
| 356 | // Handle simple special keys that produce standard sequences |
| 357 | if (mods === Mods.NONE || mods === Mods.SHIFT) { |
nothing calls this directly
no test coverage detected