Skip to main content

kozan_core/events/
keyboard_event.rs

1//! Keyboard DOM events — Chrome: `blink/core/dom/events/keyboard_event.h`.
2//!
3//! DOM-level keyboard events dispatched through the tree.
4//! The `EventHandler` converts `input::KeyboardEvent` → `KeyDownEvent` / `KeyUpEvent`.
5
6use crate::input::{KeyCode, Modifiers};
7use kozan_macros::Event;
8
9/// DOM `keydown` event — fired when a key is pressed.
10///
11/// Chrome: `KeyboardEvent` with type `"keydown"`.
12#[derive(Debug, Clone, Event)]
13#[event(bubbles, cancelable)]
14#[non_exhaustive]
15pub struct KeyDownEvent {
16    /// Physical key code — which key was pressed.
17    pub key: KeyCode,
18    /// Modifier keys held during the key press.
19    pub modifiers: Modifiers,
20    /// Text input produced by this key press (if any).
21    pub text: Option<String>,
22}
23
24/// DOM `keyup` event — fired when a key is released.
25///
26/// Chrome: `KeyboardEvent` with type `"keyup"`.
27#[derive(Debug, Clone, Event)]
28#[event(bubbles)]
29#[non_exhaustive]
30pub struct KeyUpEvent {
31    /// Physical key code — which key was released.
32    pub key: KeyCode,
33    /// Modifier keys held during the key release.
34    pub modifiers: Modifiers,
35}
36
37#[cfg(test)]
38mod tests {
39    use super::*;
40    use crate::events::{Bubbles, Cancelable, Event};
41
42    #[test]
43    fn keydown_bubbles_and_cancelable() {
44        let evt = KeyDownEvent {
45            key: KeyCode::Enter,
46            modifiers: Modifiers::EMPTY,
47            text: Some("\n".to_string()),
48        };
49        assert_eq!(evt.bubbles(), Bubbles::Yes);
50        assert_eq!(evt.cancelable(), Cancelable::Yes);
51    }
52
53    #[test]
54    fn keyup_bubbles_not_cancelable() {
55        let evt = KeyUpEvent {
56            key: KeyCode::KeyA,
57            modifiers: Modifiers::EMPTY,
58        };
59        assert_eq!(evt.bubbles(), Bubbles::Yes);
60        assert_eq!(evt.cancelable(), Cancelable::No);
61    }
62
63    #[test]
64    fn keydown_as_any_downcast() {
65        let evt = KeyDownEvent {
66            key: KeyCode::KeyC,
67            modifiers: Modifiers::EMPTY.with_ctrl(),
68            text: None,
69        };
70        let any = evt.as_any();
71        let downcasted = any.downcast_ref::<KeyDownEvent>().unwrap();
72        assert_eq!(downcasted.key, KeyCode::KeyC);
73        assert!(downcasted.modifiers.ctrl());
74    }
75}