Warning:
This wiki has been archived and is now read-only.

Legacy key events

From WEBAPPS
Jump to: navigation, search

WebAppsDOM3Events ⇨ Legacy key events

Based on an email by Hallvord R. M. Steen of Opera.

Introduction

The specification of key events describes processing of input from keyboard devices. Key events rely on hardware support and DOM applications should not assume that any specific keys will be available, meaning they should be designed so that no information or command can be accessed only through generating a key event.

On many operating system, the system will handle character mappings but on devices where such mappings are not available an implementation may include its own conversion tables and for example decide to send ENTER key events with key code 13 if a joystick-type control in a mobile phone UI is pressed down.

Key input normally has a default action, e.g. inserting text. The default action of a key depends on what sort of element has focus, for example if focus is in a TEXTAREA the default action of the ENTER key is to insert a line break. If focus is on a link, the default action for ENTER usually is to follow the link. What the default action for a certain key is can not be determined from an event listener. The default action can be prevented by calling the event.preventDefault() method or returning false from an event handler, but implementations MAY make this configurable and let the user specify either globally or on a per-key basis that event listeners are not allowed to override the defaults.

Input Method Editors

Input method editors or IMEs are frequently used to type for example Chinese, Japanese and Korean characters. An active IME captures all keypresses and processes them to determine what character the user wants to insert.

A keypress may be fired to indicate the start of IME composition. In that case the key code is 229. keyup events and keydown events may be fired during IME composition.

Depending on the IME and its settings, most keys will either initiate, contribute to or finish the conversion process. For example, with the standard Microsoft Japanese IME active in Hiragana mode, pressing the "K" key will start a conversion process. Pressing "U" will contribute to it and the IME will show the Hiragana "ku" character. Pressing Enter will complete the conversion and insert the character into the document.

In this specification, the expression "input used for IME character creation" means input the IME is processing to transform into the actual output character(s). The expression "IME character insertion" means the insertion that occurs when the IME is done and the user confirms the generated characters to insert them into the text.

Note that IMEs can also insert text without any key events occurring at all, e.g. with handwriting recognition or on-screen keyboards.

Key Types

Some key types defined by ranges of Microsoft Windows virtual key codes:

  • Alphanumerical keys: all keys with key codes in the ranges 48-57 and 65-90.
  • function keys: keys with key code in range 112 - 135
  • dead keys: keys that are used to add accents to the next key that is typed. One example is an U+00A8 DIARESIS key. On many keyboard layouts, dead keys are in the OEM range and their placement and key codes vary by keyboard layout. It is not possible to specify virtual key codes for them and the implementation must query the system whether the key that was pressed was a dead key or not.
  • navigation keys: keys with key code in range 33 - 40 (arrows, Home/End, page navigation)

Relationship Between Event Types

There are two types of key events:

  • Hardware reference events. The keydown and keyup events report that a key was pressed down and released. These events include keyboard reference information but do not confirm what character(s) if any will be inserted. Keyboard reference codes are hardware-, software-, locale- and system-dependent, but implementations should map as many keys as possible to virtual key codes as defined below.
  • Text insertion events. The keypress and textInput events include complete information about the character the input is generating, if any, taking into account shift states, previous dead keys and other contextual information required to decide what character will be inserted by a key press. The textInput event also shows what character(s) were generated by an active input method editor. The keypress event MUST NOT fire when an IME is processing the input for conversion.

textInput event is defined in DOM Level 3 Events. If it is fired, it must happen after a keypress event.

All keys fire the hardware reference events. What other events are fired depends on the type of key that is pressed and response from the event listeners. Typically, alphanumerical keys and punctuation keys fire text insertion events while control keys and navigation keys do not. Dead keys may fire text insertion events if pressed twice or followed by a space.

Key Code Calculation for Hardware Reference Events

The key code for keydown / keyup events is calculated as follows:

  1. If input is a numerical character (0-9), return the ASCII code of the character.
  2. If input is a lower case character (not limited to English a-z), return the ASCII code of the upper case equivalent. [TODO#1]
  3. Look up key code in table of Microsoft Windows virtual key codes, return it if found. [NOTE#2]
  4. Read virtual key code from system if possible. [TODO#2]
  5. If no key code was found, return 0.

Processing of Keypress Events

When a key is pressed, and the keydown event has been processed an implementation must behave as if it implemented this algorithm when firing keypress events:

  • If the keypress follows a keydown event on the same key and the earlier keydown event had its default action cancelled, terminate this algorithm. [NOTE#1]
  • If the input is key input used for IME character creation, terminate this algorithm. [TODO#3]
  • If the key does not cause text input and is not the Escape key (i.e. if the key is not is an alphanumerical key, a punctuation key, a repeated press of a dead key or the Escape key), terminate this algorithm.
  • Set event meta key properties (shiftKey, ctrlKey, altKey, metaKey) depending on what meta keys are pressed, if any
  • For backwards compatibility reasons the character code property has two different names. Define charCode and keyCode, set both to the decimal value of the unicode reference number of the corresponding character.
  • Fire the event. If it was not cancelled with event.preventDefault() proceed to fire a textInput event.
  • If the same keystroke inserts several characters, fire one keypress event for each
  • If the key is held down, repeatedly fire one keydown event and one or more keypress events at a rate determined by the system's repeat key interval setting

Notes

  1. follow Firefox or IE on what to do if keydown's preventDefault() was called? Test results:
    • IE, Safari: fire keydown, keyup. No text insertion. (Above text standardises this)
    • Firefox: fires keydown, keypress (does not insert text), keyup (and apparently web content relies on this)
    • Opera: ignores preventDefault() on keydown, does not insert text if preventDefault() is called on keypress
  1. Microsoft virtual key codes included below. Since step 1 and 2 of this algorithm handle alphanumerical keys, this step will mainly deal with punctuation characters. Their placements and virtual key codes vary greatly between keyboard layouts on Windows. The reason key codes for punctuation characters are so weird in a typical MSIE implementation are that they are usually placed on the keys Microsoft defines as "OEM keys". These are numbered OEM 1 - OEM 7 (with another OEM_102 on some layouts) plus OEM_COMMA, OEM_PERIOD, OEM_PLUS and OEM_MINUS.

However, different keyboard layouts change what OEM reference a certain key has! So the letter "ø" on a Norwegian keyboard is considered an OEM_3 key (code 192) but on EN-US layout the very same key is called OEM_1 and has code 186. Thus, even striking the *very same* key gives different virtual key codes on different keyboard layouts. Neither are those virtual key codes mapped to actual input: typing the *very same* character on different keyboard layouts can produce different key codes because these keys are associated with different "OEM" keys under the hood.

OEM_COMMA, OEM_PERIOD, OEM_PLUS, OEM_MINUS are obviously meant to map to the corresponding punctuation on most keyboards, but even this is not consistently applied. For example, on a Norwegian keyboard layout the + character is on the OEM_PLUS key and returns the virtual key code 187 but on the Icelandic layout + is on the OEM_2 key and returns its virtual key code 191.

There is no really consistent way to figure out how this should work for any OS and device. The assignment of keys to virtual key codes in Microsoft's OEM range is too chaotic to emulate, and not useful to authors. The way forward would be to specify explicit keyCode/charCode values for the following keys that never change with keyboard layouts:

  • Backspace
  • Tab
  • Caps Lock
  • Shift
  • Control
  • Alt
  • Enter

And those punctuation characters that are meant to not change virtual codes between keyboard layouts:

  • Period (.)
  • Comma (,)
  • Plus (+)
  • Minus (-)
  • Decimal key (on numpad)
  • Space

Then leave other punctuation characters implementation dependent and inform script authors that they should listen to keypress or textInput events to reliably detect those.

To Do

  1. note that IE does NOT take the upper-case value of certain non-English character (for example ø/Ø on Norwegian keyboards). I believe

doing so makes the model cleaner and is unlikely to cause compatibility problems - this needs investigation though. Here we also probably need to specify some specific algorithm for upper/lower-casing characters?

  1. Step 4 of this algorithm is incomplete, probably needs to specify how to get a virtual key from system? The issue step 4 is trying to solve is: If a given key, say the I key is mapped to something else, say "Hiragana I" keydown/keyup will still have the key code of an upper-case I in reference implementations but not according to this algorithm without some magic in step 4. Hence we need to fall back to reading virtual key codes from the system in step 4, but how to do this exactly is underspecified and will probably vary between operating systems.
  2. If the IME is NOT in the middle of a conversion, keys that do not initiate a conversion in that IME (such as ESC and Enter) *do* fire keypress events. Is the text clear enough?
  3. dead keys pressed twice fire two keypress events. Dead keys followed by space fire keydown space, keypress for the dead key's accent, keyup space (!). Dead keys are currently a bit underspecified in the above text.

Useful Links on Windows Key Handling

Keycodes and Keys in the Microsoft Virtual Keys Implementation

Key name or letter KeyCode Fires keypress Notes
LBUTTON 1 Mouse button constant, not necessarily relevant to key API
RBUTTON 2 Mouse button constant, not necessarily relevant to key API
CANCEL 3 Control-break processing
MBUTTON 4 Mouse button constant, not necessarily relevant to key API
Backspace 8 No
TAB 9 Yes If tab moves focus, its keyup may occur on a different element.
CLEAR 12
Enter/return 13 Yes
SHIFT 16 No
CONTROL 17 No
Alt 18 No
PAUSE 19 No
Caps Lock 20 No
ESCAPE 27 Yes
SPACE 32 Yes
Page Up 33 No
Page Down 34 No
END 35 No
HOME 36 No
LEFT 37 No
UP 38 No
RIGHT 39 No
DOWN 40 No
SELECT 41
PRINT 42
EXECUTE 43
Print Screen 44 No
INSERT 45 No
DELETE 46 No
HELP 47
0 48 Yes ASCII reference value of corresponding character
1 49 Yes ASCII reference value of corresponding character
2 50 Yes ASCII reference value of corresponding character
3 51 Yes ASCII reference value of corresponding character
4 52 Yes ASCII reference value of corresponding character
5 53 Yes ASCII reference value of corresponding character
6 54 Yes ASCII reference value of corresponding character
7 55 Yes ASCII reference value of corresponding character
8 56 Yes ASCII reference value of corresponding character
9 57 Yes ASCII reference value of corresponding character
A 65 Yes ASCII reference value of corresponding character
B 66 Yes ASCII reference value of corresponding character
C 67 Yes ASCII reference value of corresponding character
D 68 Yes ASCII reference value of corresponding character
E 69 Yes ASCII reference value of corresponding character
F 70 Yes ASCII reference value of corresponding character
G 71 Yes ASCII reference value of corresponding character
H 72 Yes ASCII reference value of corresponding character
I 73 Yes ASCII reference value of corresponding character
J 74 Yes ASCII reference value of corresponding character
K 75 Yes ASCII reference value of corresponding character
L 76 Yes ASCII reference value of corresponding character
M 77 Yes ASCII reference value of corresponding character
N 78 Yes ASCII reference value of corresponding character
O 79 Yes ASCII reference value of corresponding character
P 80 Yes ASCII reference value of corresponding character
Q 81 Yes ASCII reference value of corresponding character
R 82 Yes ASCII reference value of corresponding character
S 83 Yes ASCII reference value of corresponding character
T 84 Yes ASCII reference value of corresponding character
U 85 Yes ASCII reference value of corresponding character
V 86 Yes ASCII reference value of corresponding character
W 87 Yes ASCII reference value of corresponding character
X 88 Yes ASCII reference value of corresponding character
Y 89 Yes ASCII reference value of corresponding character
Z 90 Yes ASCII reference value of corresponding character
LWIN 91 No
RWIN 92 No
APPS 93
NUMPAD0 96 Yes
NUMPAD1 97 Yes
NUMPAD2 98 Yes
NUMPAD3 99 Yes
NUMPAD4 100 Yes
NUMPAD5 101 Yes
NUMPAD6 102 Yes
NUMPAD7 103 Yes
NUMPAD8 104 Yes
NUMPAD9 105 Yes
MULTIPLY 106 Yes These codes are for the keys on the “numpad” only
ADD 107 Yes These codes are for the keys on the “numpad” only
SEPARATOR 108 Yes These codes are for the keys on the “numpad” only
SUBTRACT 109 Yes These codes are for the keys on the “numpad” only
DECIMAL 110 Yes These codes are for the keys on the “numpad” only
DIVIDE 111 Yes These codes are for the keys on the “numpad” only
F1 112 No
F2 113 No
F3 114 No
F4 115 No
F5 116 No
F6 117 No
F7 118 No
F8 119 No
F9 120 No
F10 121 No
F11 122 No
F12 123 No
F13 124 No
F14 125 No
F15 126 No
F16 127 No
F17 128 No
F18 129 No
F19 130 No
F20 131 No
F21 132 No
F22 133 No
F23 134 No
F24 135 No
NUMLOCK 144 No
Scroll Lock 145 No
LSHIFT 160 Used in some internal Windows APIs to distinguish right and left control keys.

Not relevant for key events.

RSHIFT 161 Used in some internal Windows APIs to distinguish right and left control keys.

Not relevant for key events.

LCONTROL 162 Used in some internal Windows APIs to distinguish right and left control keys.

Not relevant for key events.

RCONTROL 163 Used in some internal Windows APIs to distinguish right and left control keys.

Not relevant for key events.

LMENU 164 Used in some internal Windows APIs to distinguish right and left control keys.

Not relevant for key events.

RMENU 165 Used in some internal Windows APIs to distinguish right and left control keys.

Not relevant for key events.

 ; 186 Yes This mapping varies with keyboard layouts. Given values are en-us layout.
 : 186 Yes This mapping varies with keyboard layouts. Given values are en-us layout.
+ 187 Yes This mapping varies with keyboard layouts. Given values are en-us layout.
= 187 Yes This mapping varies with keyboard layouts. Given values are en-us layout.
, 188 Yes This mapping varies with keyboard layouts. Given values are en-us layout.
< 188 Yes This mapping varies with keyboard layouts. Given values are en-us layout.
_ 189 Yes This mapping varies with keyboard layouts. Given values are en-us layout.
. 190 Yes This mapping varies with keyboard layouts. Given values are en-us layout.
> 190 Yes This mapping varies with keyboard layouts. Given values are en-us layout.
 ? 191 Yes This mapping varies with keyboard layouts. Given values are en-us layout.
/ 191 Yes This mapping varies with keyboard layouts. Given values are en-us layout.
` 192 Yes This mapping varies with keyboard layouts. Given values are en-us layout.
~ 192 Yes This mapping varies with keyboard layouts. Given values are en-us layout.
[ 219 Yes This mapping varies with keyboard layouts. Given values are en-us layout.
{ 219 Yes This mapping varies with keyboard layouts. Given values are en-us layout.
\ 220 Yes This mapping varies with keyboard layouts. Given values are en-us layout.
220 Yes This mapping varies with keyboard layouts. Given values are en-us layout.
] 221 Yes This mapping varies with keyboard layouts. Given values are en-us layout.
} 221 Yes This mapping varies with keyboard layouts. Given values are en-us layout.
' 222 Yes This mapping varies with keyboard layouts. Given values are en-us layout.
222 Yes This mapping varies with keyboard layouts. Given values are en-us layout.
PROCESSKEY 229
ATTN 246
CRSEL 247
EXSEL 248
EREOF 249
PLAY 250
ZOOM 251
NONAME 252
PA1 253
OEM_CLEAR 254
Fn 255 No Laptop “Fn” key