Skip to content
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

Add keyboard service #647

Merged
merged 6 commits into from
Sep 27, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,7 @@ Implemented:
* `ConsoleService`
* `FetchService`
* `WebSocketService`
* `KeyboardService`

```rust
use yew::services::{ConsoleService, TimeoutService};
Expand Down
88 changes: 88 additions & 0 deletions src/services/keyboard.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
//! Service to register key press event listeners on elements.
use crate::callback::Callback;
use stdweb::web::event::{KeyDownEvent, KeyPressEvent, KeyUpEvent};
use stdweb::web::{EventListenerHandle, IEventTarget};

/// Service for registering callbacks on elements to get keystrokes from the user.
///
/// # Note
/// Elements that natively support keyboard input (input or textarea) can set an
/// `onkeypress` or `oninput` attribute within the html macro. You **should** use those events instead of
/// locating the element and registering it with this service.
///
/// This service is for adding key event listeners to elements that don't support these attributes,
/// like the `document` or `<canvas>` elements for example.
pub struct KeyboardService {}

/// Handle to the key event listener.
///
/// When it goes out of scope, the listener will be removed from the element.
pub struct KeyListenerHandle(Option<EventListenerHandle>);

impl KeyboardService {
/// Registers a callback that listens to KeyPressEvents on a provided element.
///
/// # Documentation
/// [keypress event](https://developer.mozilla.org/en-US/docs/Web/API/Document/keypress_event)
///
/// # Warning
/// This API has been deprecated in the HTML standard and it is not recommended for use in new projects.
/// Consult with the browser compatibility chart in the linked MDN documentation.
pub fn register_key_press<T: IEventTarget>(
element: &T,
callback: Callback<KeyPressEvent>,
) -> KeyListenerHandle {
let handle = element.add_event_listener(move |event: KeyPressEvent| {
callback.emit(event);
});
KeyListenerHandle(Some(handle))
}

/// Registers a callback that listens to KeyDownEvents on a provided element.
///
/// # Documentation
/// [keydown event](https://developer.mozilla.org/en-US/docs/Web/API/Document/keydown_event)
///
/// # Note
/// This browser feature is relatively new and is set to replace keypress events.
/// Not all browsers may support it completely.
/// Consult with the browser compatibility chart in the linked MDN documentation.
pub fn register_key_down<T: IEventTarget>(
element: &T,
callback: Callback<KeyDownEvent>,
) -> KeyListenerHandle {
let handle = element.add_event_listener(move |event: KeyDownEvent| {
callback.emit(event);
});
KeyListenerHandle(Some(handle))
}

/// Registers a callback that listens to KeyUpEvents on a provided element.
///
/// # Documentation
/// [keyup event](https://developer.mozilla.org/en-US/docs/Web/API/Document/keyup_event)
///
/// # Note
/// This browser feature is relatively new and is set to replace keypress events.
/// Not all browsers may support it completely.
/// Consult with the browser compatibility chart in the linked MDN documentation.
pub fn register_key_up<T: IEventTarget>(
element: &T,
callback: Callback<KeyUpEvent>,
) -> KeyListenerHandle {
let handle = element.add_event_listener(move |event: KeyUpEvent| {
callback.emit(event);
});
KeyListenerHandle(Some(handle))
}
}

impl Drop for KeyListenerHandle {
fn drop(&mut self) {
if let Some(handle) = self.0.take() {
handle.remove()
} else {
panic!("Tried to drop KeyListenerHandle twice")
}
}
}
1 change: 1 addition & 0 deletions src/services/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ pub mod console;
pub mod dialog;
pub mod fetch;
pub mod interval;
pub mod keyboard;
pub mod reader;
pub mod render;
pub mod resize;
Expand Down