123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799 |
- /*
- * Copyright (c) 2021-2022, Andreas Kling <andreas@ladybird.org>
- *
- * SPDX-License-Identifier: BSD-2-Clause
- */
- #include <AK/CharacterTypes.h>
- #include <LibUnicode/CharacterTypes.h>
- #include <LibWeb/Bindings/Intrinsics.h>
- #include <LibWeb/Bindings/KeyboardEventPrototype.h>
- #include <LibWeb/UIEvents/EventNames.h>
- #include <LibWeb/UIEvents/KeyboardEvent.h>
- namespace Web::UIEvents {
- JS_DEFINE_ALLOCATOR(KeyboardEvent);
- // https://www.w3.org/TR/uievents/#determine-keydown-keyup-keyCode
- static unsigned long determine_key_code(KeyCode platform_key, u32 code_point)
- {
- // If input key when pressed without modifiers would insert a numerical character (0-9), return the ASCII code of that numerical character.
- if (is_ascii_digit(code_point))
- return code_point;
- switch (platform_key) {
- case KeyCode::Key_ExclamationPoint:
- return static_cast<unsigned long>('1');
- case KeyCode::Key_AtSign:
- return static_cast<unsigned long>('2');
- case KeyCode::Key_Hashtag:
- return static_cast<unsigned long>('3');
- case KeyCode::Key_Dollar:
- return static_cast<unsigned long>('4');
- case KeyCode::Key_Percent:
- return static_cast<unsigned long>('5');
- case KeyCode::Key_Circumflex:
- return static_cast<unsigned long>('6');
- case KeyCode::Key_Ampersand:
- return static_cast<unsigned long>('7');
- case KeyCode::Key_Asterisk:
- return static_cast<unsigned long>('8');
- case KeyCode::Key_LeftParen:
- return static_cast<unsigned long>('9');
- case KeyCode::Key_RightParen:
- return static_cast<unsigned long>('0');
- default:
- break;
- }
- // If input key when pressed without modifiers would insert a lower case character in the a-z alphabetical range, return the ASCII code of the upper case equivalent.
- if (is_ascii_lower_alpha(code_point))
- return to_ascii_uppercase(code_point);
- // If the key’s function, as determined in an implementation-specific way, corresponds to one of the keys in the §8.3.3 Fixed virtual key codes table, return the corresponding key code.
- // https://www.w3.org/TR/uievents/#fixed-virtual-key-codes
- switch (platform_key) {
- case KeyCode::Key_Backspace:
- return 8;
- case KeyCode::Key_Tab:
- return 9;
- case KeyCode::Key_Return:
- return 13;
- case KeyCode::Key_LeftShift:
- case KeyCode::Key_RightShift:
- return 16;
- case KeyCode::Key_LeftControl:
- case KeyCode::Key_RightControl:
- return 17;
- case KeyCode::Key_LeftAlt:
- case KeyCode::Key_RightAlt:
- return 18;
- case KeyCode::Key_CapsLock:
- return 20;
- case KeyCode::Key_Escape:
- return 27;
- case KeyCode::Key_Space:
- return 32;
- case KeyCode::Key_PageUp:
- return 33;
- case KeyCode::Key_PageDown:
- return 34;
- case KeyCode::Key_End:
- return 35;
- case KeyCode::Key_Home:
- return 36;
- case KeyCode::Key_Left:
- return 37;
- case KeyCode::Key_Up:
- return 38;
- case KeyCode::Key_Right:
- return 39;
- case KeyCode::Key_Down:
- return 40;
- default:
- break;
- }
- // https://www.w3.org/TR/uievents/#optionally-fixed-virtual-key-codes
- switch (platform_key) {
- case KeyCode::Key_Semicolon:
- case KeyCode::Key_Colon:
- return 186;
- case KeyCode::Key_Equal:
- case KeyCode::Key_Plus:
- return 187;
- case KeyCode::Key_Comma:
- case KeyCode::Key_LessThan:
- return 188;
- case KeyCode::Key_Minus:
- case KeyCode::Key_Underscore:
- return 189;
- case KeyCode::Key_Period:
- case KeyCode::Key_GreaterThan:
- return 190;
- case KeyCode::Key_Slash:
- case KeyCode::Key_QuestionMark:
- return 191;
- case KeyCode::Key_Backtick:
- case KeyCode::Key_Tilde:
- return 192;
- case KeyCode::Key_LeftBracket:
- case KeyCode::Key_LeftBrace:
- return 219;
- case KeyCode::Key_Backslash:
- case KeyCode::Key_Pipe:
- return 220;
- case KeyCode::Key_RightBracket:
- case KeyCode::Key_RightBrace:
- return 221;
- case KeyCode::Key_Apostrophe:
- case KeyCode::Key_DoubleQuote:
- return 222;
- default:
- break;
- }
- // Return the virtual key code from the operating system.
- return platform_key;
- }
- // https://www.w3.org/TR/uievents/#dom-keyboardevent-charcode
- static u32 determine_char_code(FlyString const& event_name, u32 code_point)
- {
- // charCode holds a character value, for keypress events which generate character input. The value is the Unicode
- // reference number (code point) of that character (e.g. event.charCode = event.key.charCodeAt(0) for printable
- // characters). For keydown or keyup events, the value of charCode is 0.
- if (event_name == UIEvents::EventNames::keypress) {
- if (Unicode::code_point_is_printable(code_point))
- return code_point;
- }
- return 0;
- }
- // 3. Named key Attribute Values, https://www.w3.org/TR/uievents-key/#named-key-attribute-values
- static ErrorOr<Optional<String>> get_event_named_key(KeyCode platform_key)
- {
- switch (platform_key) {
- // 3.1. Special Keys, https://www.w3.org/TR/uievents-key/#keys-special
- case KeyCode::Key_Invalid:
- return "Unidentified"_string;
- // 3.2. Modifier Keys, https://www.w3.org/TR/uievents-key/#keys-modifier
- case KeyCode::Key_LeftAlt:
- case KeyCode::Key_RightAlt:
- return "Alt"_string;
- case KeyCode::Key_AltGr:
- return "AltGraph"_string;
- case KeyCode::Key_CapsLock:
- return "CapsLock"_string;
- case KeyCode::Key_LeftControl:
- case KeyCode::Key_RightControl:
- return "Control"_string;
- // FIXME: Fn
- // FIXME: FnLock
- case KeyCode::Key_LeftSuper:
- case KeyCode::Key_RightSuper:
- return "Meta"_string;
- case KeyCode::Key_NumLock:
- return "NumLock"_string;
- case KeyCode::Key_ScrollLock:
- return "ScrollLock"_string;
- case KeyCode::Key_LeftShift:
- case KeyCode::Key_RightShift:
- return "Shift"_string;
- // 3.3. Whitespace Keys, https://www.w3.org/TR/uievents-key/#keys-whitespace
- case KeyCode::Key_Return:
- return "Enter"_string;
- case KeyCode::Key_Tab:
- return "Tab"_string;
- case KeyCode::Key_Space:
- return " "_string;
- // 3.4. Navigation Keys, https://www.w3.org/TR/uievents-key/#keys-navigation
- case KeyCode::Key_Down:
- return "ArrowDown"_string;
- case KeyCode::Key_Left:
- return "ArrowLeft"_string;
- case KeyCode::Key_Right:
- return "ArrowRight"_string;
- case KeyCode::Key_Up:
- return "ArrowUp"_string;
- case KeyCode::Key_End:
- return "End"_string;
- case KeyCode::Key_Home:
- return "Home"_string;
- case KeyCode::Key_PageDown:
- return "PageDown"_string;
- case KeyCode::Key_PageUp:
- return "PageUp"_string;
- // 3.5. Editing Keys, https://www.w3.org/TR/uievents-key/#keys-editing
- case KeyCode::Key_Backspace:
- return "Backspace"_string;
- case KeyCode::Key_Delete:
- return "Delete"_string;
- case KeyCode::Key_Insert:
- return "Insert"_string;
- // 3.6. UI Keys, https://www.w3.org/TR/uievents-key/#keys-ui
- case KeyCode::Key_Menu:
- return "ContextMenu"_string;
- case KeyCode::Key_Escape:
- return "Escape"_string;
- // FIXME: Help
- // FIXME: Pause
- // 3.7. Device Keys, https://www.w3.org/TR/uievents-key/#keys-device
- case KeyCode::Key_PrintScreen:
- return "PrintScreen"_string;
- // 3.9. General-Purpose Function Keys, https://www.w3.org/TR/uievents-key/#keys-function
- case KeyCode::Key_F1:
- return "F1"_string;
- case KeyCode::Key_F2:
- return "F2"_string;
- case KeyCode::Key_F3:
- return "F3"_string;
- case KeyCode::Key_F4:
- return "F4"_string;
- case KeyCode::Key_F5:
- return "F5"_string;
- case KeyCode::Key_F6:
- return "F6"_string;
- case KeyCode::Key_F7:
- return "F7"_string;
- case KeyCode::Key_F8:
- return "F8"_string;
- case KeyCode::Key_F9:
- return "F9"_string;
- case KeyCode::Key_F10:
- return "F10"_string;
- case KeyCode::Key_F11:
- return "F11"_string;
- case KeyCode::Key_F12:
- return "F12"_string;
- default:
- break;
- }
- return OptionalNone {};
- }
- // 2.1. Unicode Values, https://www.w3.org/TR/uievents-key/#keys-unicode
- static ErrorOr<Optional<String>> get_event_key_string(u32 code_point)
- {
- auto is_non_control_character = [&]() {
- // A non-control character is any valid Unicode character except those that are part of the "Other, Control"
- // ("Cc") General Category.
- return !Unicode::code_point_has_control_general_category(code_point);
- };
- // A key string is a string containing a 0 or 1 non-control characters ("base" characters) followed by 0 or more
- // combining characters. The string MUST be in Normalized Form C (NFC) as described in [UAX15].
- // FIXME: Our key events are currently set up to provide one code point at a time. We will need to handle multi-
- // code point events and NFC normalize that string.
- if (is_non_control_character())
- return String::from_code_point(code_point);
- return OptionalNone {};
- }
- // 2.2. Selecting key Attribute Values, https://www.w3.org/TR/uievents-key/#selecting-key-attribute-values
- static ErrorOr<String> get_event_key(KeyCode platform_key, u32 code_point)
- {
- // 1. Let key be a DOMString initially set to "Unidentified".
- // NOTE: We return "Unidentified" at the end to avoid needlessly allocating it here.
- // 2. If there exists an appropriate named key attribute value for this key event, then
- // AD-HOC: Key_Invalid would be interpreted as "Unidentified" here. But we also use Key_Invalid for key presses that
- // are not on a standard US keyboard. If such a key would generate a valid key string below, let's allow that
- // to happen; otherwise, we will still return "Unidentified" at the end.
- if (platform_key != KeyCode::Key_Invalid) {
- if (auto named_key = TRY(get_event_named_key(platform_key)); named_key.has_value()) {
- // 1. Set key to that named key attribute value.
- return named_key.release_value();
- }
- }
- // 3. Else, if the key event generates a valid key string, then
- if (auto key_string = TRY(get_event_key_string(code_point)); key_string.has_value()) {
- // 1. Set key to that key string value.
- return key_string.release_value();
- }
- // FIXME: 4. Else, if the key event has any modifier keys other than glyph modifier keys, then
- // FIXME: 1. Set key to the key string that would have been generated by this event if it had been typed with all
- // modifer keys removed except for glyph modifier keys.
- // 5. Return key as the key attribute value for this key event.
- return "Unidentified"_string;
- }
- // 3. Keyboard Event code Value Tables, https://www.w3.org/TR/uievents-code/#code-value-tables
- static ErrorOr<String> get_event_code(KeyCode platform_key, unsigned modifiers)
- {
- // 3.4. Numpad Section, https://www.w3.org/TR/uievents-code/#key-numpad-section
- if ((modifiers & Mod_Keypad) != 0) {
- switch (platform_key) {
- case KeyCode::Key_0:
- return "Numpad0"_string;
- case KeyCode::Key_1:
- return "Numpad1"_string;
- case KeyCode::Key_2:
- return "Numpad2"_string;
- case KeyCode::Key_3:
- return "Numpad3"_string;
- case KeyCode::Key_4:
- return "Numpad4"_string;
- case KeyCode::Key_5:
- return "Numpad5"_string;
- case KeyCode::Key_6:
- return "Numpad6"_string;
- case KeyCode::Key_7:
- return "Numpad7"_string;
- case KeyCode::Key_8:
- return "Numpad8"_string;
- case KeyCode::Key_9:
- return "Numpad9"_string;
- case KeyCode::Key_Plus:
- return "NumpadAdd"_string;
- case KeyCode::Key_Comma:
- return "NumpadComma"_string;
- case KeyCode::Key_Period:
- case KeyCode::Key_Delete:
- return "NumpadDecimal"_string;
- case KeyCode::Key_Slash:
- return "NumpadDivide"_string;
- case KeyCode::Key_Return:
- return "NumpadEnter"_string;
- case KeyCode::Key_Asterisk:
- return "NumpadMultiply"_string;
- case KeyCode::Key_Minus:
- return "NumpadSubtract"_string;
- case KeyCode::Key_Equal:
- return "NumpadEqual"_string;
- case KeyCode::Key_Hashtag:
- return "NumpadHash"_string;
- case KeyCode::Key_LeftParen:
- return "NumpadParenLeft"_string;
- case KeyCode::Key_RightParen:
- return "NumpadParenRight"_string;
- default:
- break;
- }
- }
- switch (platform_key) {
- // 3.1.1. Writing System Keys, https://www.w3.org/TR/uievents-code/#key-alphanumeric-writing-system
- case KeyCode::Key_Backtick:
- case KeyCode::Key_Tilde:
- return "Backquote"_string;
- case KeyCode::Key_Backslash:
- case KeyCode::Key_Pipe:
- return "Backslash"_string;
- case KeyCode::Key_LeftBrace:
- case KeyCode::Key_LeftBracket:
- return "BracketLeft"_string;
- case KeyCode::Key_RightBrace:
- case KeyCode::Key_RightBracket:
- return "BracketRight"_string;
- case KeyCode::Key_Comma:
- case KeyCode::Key_LessThan:
- return "Comma"_string;
- case KeyCode::Key_0:
- case KeyCode::Key_RightParen:
- return "Digit0"_string;
- case KeyCode::Key_1:
- case KeyCode::Key_ExclamationPoint:
- return "Digit1"_string;
- case KeyCode::Key_2:
- case KeyCode::Key_AtSign:
- return "Digit2"_string;
- case KeyCode::Key_3:
- case KeyCode::Key_Hashtag:
- return "Digit3"_string;
- case KeyCode::Key_4:
- case KeyCode::Key_Dollar:
- return "Digit4"_string;
- case KeyCode::Key_5:
- case KeyCode::Key_Percent:
- return "Digit5"_string;
- case KeyCode::Key_6:
- case KeyCode::Key_Circumflex:
- return "Digit6"_string;
- case KeyCode::Key_7:
- case KeyCode::Key_Ampersand:
- return "Digit7"_string;
- case KeyCode::Key_8:
- case KeyCode::Key_Asterisk:
- return "Digit8"_string;
- case KeyCode::Key_9:
- case KeyCode::Key_LeftParen:
- return "Digit9"_string;
- case KeyCode::Key_Equal:
- case KeyCode::Key_Plus:
- return "Equal"_string;
- // FIXME: IntlBackslash
- // FIXME: IntlRo
- // FIXME: IntlYen
- case KeyCode::Key_A:
- return "KeyA"_string;
- case KeyCode::Key_B:
- return "KeyB"_string;
- case KeyCode::Key_C:
- return "KeyC"_string;
- case KeyCode::Key_D:
- return "KeyD"_string;
- case KeyCode::Key_E:
- return "KeyE"_string;
- case KeyCode::Key_F:
- return "KeyF"_string;
- case KeyCode::Key_G:
- return "KeyG"_string;
- case KeyCode::Key_H:
- return "KeyH"_string;
- case KeyCode::Key_I:
- return "KeyI"_string;
- case KeyCode::Key_J:
- return "KeyJ"_string;
- case KeyCode::Key_K:
- return "KeyK"_string;
- case KeyCode::Key_L:
- return "KeyL"_string;
- case KeyCode::Key_M:
- return "KeyM"_string;
- case KeyCode::Key_N:
- return "KeyN"_string;
- case KeyCode::Key_O:
- return "KeyO"_string;
- case KeyCode::Key_P:
- return "KeyP"_string;
- case KeyCode::Key_Q:
- return "KeyQ"_string;
- case KeyCode::Key_R:
- return "KeyR"_string;
- case KeyCode::Key_S:
- return "KeyS"_string;
- case KeyCode::Key_T:
- return "KeyT"_string;
- case KeyCode::Key_U:
- return "KeyU"_string;
- case KeyCode::Key_V:
- return "KeyV"_string;
- case KeyCode::Key_W:
- return "KeyW"_string;
- case KeyCode::Key_X:
- return "KeyX"_string;
- case KeyCode::Key_Y:
- return "KeyY"_string;
- case KeyCode::Key_Z:
- return "KeyZ"_string;
- case KeyCode::Key_Minus:
- case KeyCode::Key_Underscore:
- return "Minus"_string;
- case KeyCode::Key_Period:
- case KeyCode::Key_GreaterThan:
- return "Period"_string;
- case KeyCode::Key_Apostrophe:
- case KeyCode::Key_DoubleQuote:
- return "Quote"_string;
- case KeyCode::Key_Semicolon:
- case KeyCode::Key_Colon:
- return "Semicolon"_string;
- case KeyCode::Key_Slash:
- case KeyCode::Key_QuestionMark:
- return "Slash"_string;
- // 3.1.2. Functional Keys, https://www.w3.org/TR/uievents-code/#key-alphanumeric-functional
- case KeyCode::Key_LeftAlt:
- return "AltLeft"_string;
- case KeyCode::Key_RightAlt:
- return "AltRight"_string;
- case KeyCode::Key_AltGr:
- return "AltGraph"_string;
- case KeyCode::Key_Backspace:
- return "Backspace"_string;
- case KeyCode::Key_CapsLock:
- return "CapsLock"_string;
- case KeyCode::Key_Menu:
- return "ContextMenu"_string;
- case KeyCode::Key_LeftControl:
- return "ControlLeft"_string;
- case KeyCode::Key_RightControl:
- return "ControlRight"_string;
- case KeyCode::Key_Return:
- return "Enter"_string;
- case KeyCode::Key_LeftSuper:
- return "MetaLeft"_string;
- case KeyCode::Key_RightSuper:
- return "MetaRight"_string;
- case KeyCode::Key_LeftShift:
- return "ShiftLeft"_string;
- case KeyCode::Key_RightShift:
- return "ShiftRight"_string;
- case KeyCode::Key_Space:
- return "Space"_string;
- case KeyCode::Key_Tab:
- return "Tab"_string;
- // 3.2. Control Pad Section, https://www.w3.org/TR/uievents-code/#key-controlpad-section
- case KeyCode::Key_Delete:
- return "Delete"_string;
- case KeyCode::Key_End:
- return "End"_string;
- // FIXME: Help
- case KeyCode::Key_Home:
- return "Home"_string;
- case KeyCode::Key_Insert:
- return "Insert"_string;
- case KeyCode::Key_PageDown:
- return "PageDown"_string;
- case KeyCode::Key_PageUp:
- return "PageUp"_string;
- // 3.3. Arrow Pad Section, https://www.w3.org/TR/uievents-code/#key-arrowpad-section
- case KeyCode::Key_Down:
- return "ArrowDown"_string;
- case KeyCode::Key_Left:
- return "ArrowLeft"_string;
- case KeyCode::Key_Right:
- return "ArrowRight"_string;
- case KeyCode::Key_Up:
- return "ArrowUp"_string;
- // 3.4. Numpad Section, https://www.w3.org/TR/uievents-code/#key-numpad-section
- case KeyCode::Key_NumLock:
- return "NumLock"_string;
- // 3.5. Function Section, https://www.w3.org/TR/uievents-code/#key-function-section
- case KeyCode::Key_Escape:
- return "Escape"_string;
- case KeyCode::Key_F1:
- return "F1"_string;
- case KeyCode::Key_F2:
- return "F2"_string;
- case KeyCode::Key_F3:
- return "F3"_string;
- case KeyCode::Key_F4:
- return "F4"_string;
- case KeyCode::Key_F5:
- return "F5"_string;
- case KeyCode::Key_F6:
- return "F6"_string;
- case KeyCode::Key_F7:
- return "F7"_string;
- case KeyCode::Key_F8:
- return "F8"_string;
- case KeyCode::Key_F9:
- return "F9"_string;
- case KeyCode::Key_F10:
- return "F10"_string;
- case KeyCode::Key_F11:
- return "F11"_string;
- case KeyCode::Key_F12:
- return "F12"_string;
- case KeyCode::Key_PrintScreen:
- case KeyCode::Key_SysRq:
- return "PrintScreen"_string;
- case KeyCode::Key_ScrollLock:
- return "ScrollLock"_string;
- case KeyCode::Key_PauseBreak:
- return "Pause"_string;
- // 3.6. Media Section, https://www.w3.org/TR/uievents-code/#media-keys
- case KeyCode::Key_BrowserSearch:
- return "BrowserSearch"_string;
- case KeyCode::Key_BrowserFavorites:
- return "BrowserFavorites"_string;
- case KeyCode::Key_BrowserHome:
- return "BrowserHome"_string;
- case KeyCode::Key_PreviousTrack:
- return "PreviousTrack"_string;
- case KeyCode::Key_BrowserBack:
- return "BrowserBack"_string;
- case KeyCode::Key_BrowserForward:
- return "BrowserForward"_string;
- case KeyCode::Key_BrowserRefresh:
- return "BrowserRefresh"_string;
- case KeyCode::Key_BrowserStop:
- return "BrowserStop"_string;
- case KeyCode::Key_VolumeDown:
- return "AudioVolumeDown"_string;
- case KeyCode::Key_VolumeUp:
- return "AudioVolumeUp"_string;
- case KeyCode::Key_Wake:
- return "WakeUp"_string;
- case KeyCode::Key_Sleep:
- return "Sleep"_string;
- case KeyCode::Key_NextTrack:
- return "NextTrack"_string;
- case KeyCode::Key_MediaSelect:
- return "MediaSelect"_string;
- case KeyCode::Key_Email:
- return "LaunchMail"_string;
- case KeyCode::Key_Power:
- return "Power"_string;
- case KeyCode::Key_Stop:
- return "MediaStop"_string;
- case KeyCode::Key_PlayPause:
- return "MediaPlayPause"_string;
- case KeyCode::Key_Mute:
- return "AudioVolumeMute"_string;
- case KeyCode::Key_Calculator:
- return "LaunchApp2"_string;
- case KeyCode::Key_MyComputer:
- return "LaunchApp1"_string;
- // FIXME: Are these correct?
- case KeyCode::Key_LeftGUI:
- return "LaunchApp2"_string;
- case KeyCode::Key_RightGUI:
- case KeyCode::Key_Apps:
- return "LaunchApp1"_string;
- // 3.7. Legacy, Non-Standard and Special Keys, https://www.w3.org/TR/uievents-code/#key-legacy
- case KeyCode::Key_Invalid:
- return "Unidentified"_string;
- }
- VERIFY_NOT_REACHED();
- }
- // 5.6.2. Keyboard Event Key Location, https://www.w3.org/TR/uievents/#events-keyboard-key-location
- static DOMKeyLocation get_event_location(KeyCode platform_key, unsigned modifiers)
- {
- if ((modifiers & Mod_Keypad) != 0)
- return DOMKeyLocation::Numpad;
- switch (platform_key) {
- case KeyCode::Key_LeftAlt:
- case KeyCode::Key_LeftControl:
- case KeyCode::Key_LeftShift:
- case KeyCode::Key_LeftSuper:
- return DOMKeyLocation::Left;
- case KeyCode::Key_RightAlt:
- case KeyCode::Key_RightControl:
- case KeyCode::Key_RightShift:
- case KeyCode::Key_RightSuper:
- return DOMKeyLocation::Right;
- default:
- break;
- }
- return DOMKeyLocation::Standard;
- }
- JS::NonnullGCPtr<KeyboardEvent> KeyboardEvent::create_from_platform_event(JS::Realm& realm, FlyString const& event_name, KeyCode platform_key, unsigned modifiers, u32 code_point)
- {
- auto event_key = MUST(get_event_key(platform_key, code_point));
- auto event_code = MUST(get_event_code(platform_key, modifiers));
- auto key_code = determine_key_code(platform_key, code_point);
- auto char_code = determine_char_code(event_name, code_point);
- KeyboardEventInit event_init {};
- event_init.key = move(event_key);
- event_init.code = move(event_code);
- event_init.location = to_underlying(get_event_location(platform_key, modifiers));
- event_init.ctrl_key = modifiers & Mod_Ctrl;
- event_init.shift_key = modifiers & Mod_Shift;
- event_init.alt_key = modifiers & Mod_Alt;
- event_init.meta_key = modifiers & Mod_Super;
- event_init.repeat = false;
- event_init.is_composing = false;
- event_init.key_code = key_code;
- event_init.char_code = char_code;
- event_init.bubbles = true;
- event_init.cancelable = true;
- event_init.composed = true;
- auto event = KeyboardEvent::create(realm, event_name, event_init);
- event->set_is_trusted(true);
- return event;
- }
- bool KeyboardEvent::get_modifier_state(String const& key_arg) const
- {
- if (key_arg == "Control")
- return m_ctrl_key;
- if (key_arg == "Shift")
- return m_shift_key;
- if (key_arg == "Alt")
- return m_alt_key;
- if (key_arg == "Meta")
- return m_meta_key;
- if (key_arg == "AltGraph")
- return m_modifier_alt_graph;
- if (key_arg == "CapsLock")
- return m_modifier_caps_lock;
- if (key_arg == "Fn")
- return m_modifier_fn;
- if (key_arg == "FnLock")
- return m_modifier_fn_lock;
- if (key_arg == "Hyper")
- return m_modifier_hyper;
- if (key_arg == "NumLock")
- return m_modifier_num_lock;
- if (key_arg == "ScrollLock")
- return m_modifier_scroll_lock;
- if (key_arg == "Super")
- return m_modifier_super;
- if (key_arg == "Symbol")
- return m_modifier_symbol;
- if (key_arg == "SymbolLock")
- return m_modifier_symbol_lock;
- return false;
- }
- // https://w3c.github.io/uievents/#dom-keyboardevent-initkeyboardevent
- void KeyboardEvent::init_keyboard_event(String const& type, bool bubbles, bool cancelable, HTML::Window* view, String const& key, WebIDL::UnsignedLong location, bool ctrl_key, bool alt_key, bool shift_key, bool meta_key)
- {
- // Initializes attributes of a KeyboardEvent object. This method has the same behavior as UIEvent.initUIEvent().
- // The value of detail remains undefined.
- // 1. If this’s dispatch flag is set, then return.
- if (dispatched())
- return;
- // 2. Initialize this with type, bubbles, and cancelable.
- initialize_event(type, bubbles, cancelable);
- // Implementation Defined: Initialise other values.
- m_view = view;
- m_key = key;
- m_location = location;
- m_ctrl_key = ctrl_key;
- m_alt_key = alt_key;
- m_shift_key = shift_key;
- m_meta_key = meta_key;
- }
- JS::NonnullGCPtr<KeyboardEvent> KeyboardEvent::create(JS::Realm& realm, FlyString const& event_name, KeyboardEventInit const& event_init)
- {
- return realm.heap().allocate<KeyboardEvent>(realm, realm, event_name, event_init);
- }
- WebIDL::ExceptionOr<JS::NonnullGCPtr<KeyboardEvent>> KeyboardEvent::construct_impl(JS::Realm& realm, FlyString const& event_name, KeyboardEventInit const& event_init)
- {
- return create(realm, event_name, event_init);
- }
- KeyboardEvent::KeyboardEvent(JS::Realm& realm, FlyString const& event_name, KeyboardEventInit const& event_init)
- : UIEvent(realm, event_name, event_init)
- , m_key(event_init.key)
- , m_code(event_init.code)
- , m_location(event_init.location)
- , m_ctrl_key(event_init.ctrl_key)
- , m_shift_key(event_init.shift_key)
- , m_alt_key(event_init.alt_key)
- , m_meta_key(event_init.meta_key)
- , m_modifier_alt_graph(event_init.modifier_alt_graph)
- , m_modifier_caps_lock(event_init.modifier_caps_lock)
- , m_modifier_fn(event_init.modifier_fn)
- , m_modifier_fn_lock(event_init.modifier_fn_lock)
- , m_modifier_hyper(event_init.modifier_hyper)
- , m_modifier_num_lock(event_init.modifier_num_lock)
- , m_modifier_scroll_lock(event_init.modifier_scroll_lock)
- , m_modifier_super(event_init.modifier_super)
- , m_modifier_symbol(event_init.modifier_symbol)
- , m_modifier_symbol_lock(event_init.modifier_symbol_lock)
- , m_repeat(event_init.repeat)
- , m_is_composing(event_init.is_composing)
- , m_key_code(event_init.key_code)
- , m_char_code(event_init.char_code)
- {
- }
- KeyboardEvent::~KeyboardEvent() = default;
- void KeyboardEvent::initialize(JS::Realm& realm)
- {
- Base::initialize(realm);
- WEB_SET_PROTOTYPE_FOR_INTERFACE(KeyboardEvent);
- }
- }
|