2021-09-27 23:22:21 +02:00
/*
2022-08-08 22:29:40 +02:00
* Copyright ( c ) 2021 - 2022 , Andreas Kling < kling @ serenityos . org >
2021-09-27 23:22:21 +02:00
*
* SPDX - License - Identifier : BSD - 2 - Clause
*/
# include <AK/CharacterTypes.h>
2022-09-25 18:06:11 -06:00
# include <LibWeb/Bindings/Intrinsics.h>
2021-09-27 23:22:21 +02:00
# include <LibWeb/UIEvents/KeyboardEvent.h>
namespace Web : : UIEvents {
// 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 ;
// 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_Shift :
return 16 ;
case KeyCode : : Key_Control :
return 17 ;
case KeyCode : : Key_Alt :
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 ;
}
// Return the virtual key code from the operating system.
return platform_key ;
}
2023-01-08 19:23:00 -05:00
KeyboardEvent * KeyboardEvent : : create_from_platform_event ( JS : : Realm & realm , DeprecatedFlyString const & event_name , KeyCode platform_key , unsigned modifiers , u32 code_point )
2021-09-27 23:22:21 +02:00
{
// FIXME: Figure out what these should actually contain.
2022-12-04 18:02:33 +00:00
DeprecatedString event_key = key_code_to_string ( platform_key ) ;
DeprecatedString event_code = " FIXME " ;
2021-09-27 23:22:21 +02:00
auto key_code = determine_key_code ( platform_key , code_point ) ;
2021-10-01 20:25:37 +03:00
KeyboardEventInit event_init { } ;
event_init . key = move ( event_key ) ;
event_init . code = move ( event_code ) ;
event_init . location = 0 ;
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 = false ;
event_init . repeat = false ;
event_init . is_composing = false ;
event_init . key_code = key_code ;
event_init . char_code = code_point ;
event_init . bubbles = true ;
event_init . cancelable = true ;
event_init . composed = true ;
2022-09-25 18:06:11 -06:00
return KeyboardEvent : : create ( realm , event_name , event_init ) ;
}
2022-12-04 18:02:33 +00:00
bool KeyboardEvent : : get_modifier_state ( DeprecatedString const & key_arg )
2021-09-27 23:22:21 +02:00
{
if ( key_arg = = " Alt " )
return m_alt_key ;
if ( key_arg = = " Control " )
return m_ctrl_key ;
if ( key_arg = = " Shift " )
return m_shift_key ;
if ( key_arg = = " Meta " )
return m_meta_key ;
return false ;
}
2022-08-08 22:29:40 +02:00
2023-01-08 19:23:00 -05:00
KeyboardEvent * KeyboardEvent : : create ( JS : : Realm & realm , DeprecatedFlyString const & event_name , KeyboardEventInit const & event_init )
2022-08-08 22:29:40 +02:00
{
2023-01-28 13:39:44 -05:00
return realm . heap ( ) . allocate < KeyboardEvent > ( realm , realm , event_name , event_init ) . release_allocated_value_but_fixme_should_propagate_errors ( ) ;
2022-08-08 22:29:40 +02:00
}
2023-01-08 19:23:00 -05:00
KeyboardEvent * KeyboardEvent : : construct_impl ( JS : : Realm & realm , DeprecatedFlyString const & event_name , KeyboardEventInit const & event_init )
2022-08-08 22:29:40 +02:00
{
2022-09-25 18:06:11 -06:00
return create ( realm , event_name , event_init ) ;
2022-08-08 22:29:40 +02:00
}
2023-01-08 19:23:00 -05:00
KeyboardEvent : : KeyboardEvent ( JS : : Realm & realm , DeprecatedFlyString const & event_name , KeyboardEventInit const & event_init )
2022-09-25 18:06:11 -06:00
: UIEvent ( realm , event_name , event_init )
2022-08-08 22:29:40 +02:00
, 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_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 ;
2023-01-28 12:33:35 -05:00
JS : : ThrowCompletionOr < void > KeyboardEvent : : initialize ( JS : : Realm & realm )
2023-01-10 06:28:20 -05:00
{
2023-01-28 12:33:35 -05:00
MUST_OR_THROW_OOM ( Base : : initialize ( realm ) ) ;
2023-01-10 06:28:20 -05:00
set_prototype ( & Bindings : : ensure_web_prototype < Bindings : : KeyboardEventPrototype > ( realm , " KeyboardEvent " ) ) ;
2023-01-28 12:33:35 -05:00
return { } ;
2023-01-10 06:28:20 -05:00
}
2021-09-27 23:22:21 +02:00
}