gloo icon indicating copy to clipboard operation
gloo copied to clipboard

`KeyboardEvent.key` parsing

Open richard-uk1 opened this issue 5 years ago • 4 comments

Summary

Add a crate to parse the KeyboardEvent.key field.

Motivation

If you're writing a game or similar, you may want to handle raw keyboard events. The key event is a string, meaning that the names of the special keys are not discoverable. By parsing it into an enum, we make them discoverable, while also making the key cheaper to copy, except for the Unknown degenerate case.

It seems like a good candidate for inclusion in gloo since it doesn't make any design decisions (it's just parsing the ECMAScript spec), but it's quite a lot of work to implement.

Detailed Explanation

The enum would look like (modulo bikeshedding)

enum Key {
    Visible(char),
    Alt,
    Ctrl,
    Backspace,
    // ...
    Unknown(String),
}

and would be parsed like


impl Key {
    fn from_js(raw: &str) -> Self {
        match raw {
            "Backspace" => Key::Backspace,
            // ....
            maybe_char => {
                let mut maybe_char_iter = maybe_char.chars();
                let first = maybe_char_iter.next();
                if let Some(ch) = first {
                    if maybe_char_iter.next().is_some() {
                        Key::Unknown(raw.to_string())
                    } else {
                        Key::Visible(ch)
                    }
                } else {
                    Key::Unknown(raw.to_string())
                }
            }
        }
    }
}

Drawbacks, Rationale, and Alternatives

Possible drawbacks

  • It could possibly be slower than working directly with strings, although it would be cheaper to clone/etc unless you are in the degenerate "Unknown" case.

  • Maybe no-one will use it

The alternative is to not do this.

Unresolved Questions

  • Should the name of the "Visible" case be short, e.g. K, to be more concise?
  • Which char methods should we implement?
  • Should we convert non-visible characters (like Backspace) to their char code (e.g. char::from_u32(8))

richard-uk1 avatar Jul 03 '19 13:07 richard-uk1

I think this should be exposed as part of https://github.com/rustwasm/gloo/issues/43

Should the name of the "Visible" case be short, e.g. K, to be more concise?

I don't think it should be shortened as far as K, but maybe Key or Char would be okay.

Should we convert non-visible characters (like Backspace) to their char code (e.g. char::from_u32(8))

I think it's reasonable to provide a to_char_code method on Key which would work for all of the keys.

Pauan avatar Jul 03 '19 15:07 Pauan

The keyboard-types crate already handles this; would it be a good idea to use that?

Liamolucko avatar Aug 27 '21 00:08 Liamolucko

The keyboard-types crate already handles this; would it be a good idea to use that?

It seems that that crate could be used. Do you have an exposed gloo API in mind?

ranile avatar Aug 27 '21 09:08 ranile

The keyboard-types crate already handles this; would it be a good idea to use that?

This crate, at least for Code, is pretty incomplete. It follows the standard, but browsers in practice use slightly different values and entirely new values for some keys. Examples being: HangulMode, Hanja, Cancel, OSLeft, OSRight, LaunchMediaPlayer and NumpadChangeSign. Also F13 to F24 are missing (which the standard allows but doesn't explicitly list).

So I'd say it probably makes sense to use the crate, but there needs to be a PR to make it usable with real world browsers.

CryZe avatar Aug 27 '21 09:08 CryZe