Skip to content

Commit

Permalink
LibWeb: Only fire keypress events if the key press produced a character
Browse files Browse the repository at this point in the history
For example, pressing just the shift key should not producde a keypress
event.
  • Loading branch information
trflynn89 authored and awesomekling committed Oct 9, 2024
1 parent 3925317 commit 448754d
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 4 deletions.
5 changes: 5 additions & 0 deletions Tests/LibWeb/Text/expected/UIEvents/KeyEvent-keypress.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
keydown A
keypress A
keydown Shift
keydown B
keypress B
18 changes: 18 additions & 0 deletions Tests/LibWeb/Text/input/UIEvents/KeyEvent-keypress.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<input id="input" />
<script src="../include.js"></script>
<script>
test(() => {
let input = document.getElementById("input");

input.addEventListener("keydown", e => {
println(`keydown ${e.key}`);
});
input.addEventListener("keypress", e => {
println(`keypress ${e.key}`);
});

internals.sendText(input, "A");
internals.sendKey(input, "LeftShift");
internals.sendText(input, "B");
});
</script>
15 changes: 15 additions & 0 deletions Userland/Libraries/LibUnicode/CharacterTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,16 @@ bool code_point_has_control_general_category(u32 code_point)
return code_point_has_general_category(code_point, U_CONTROL_CHAR);
}

bool code_point_has_letter_general_category(u32 code_point)
{
return code_point_has_general_category(code_point, GENERAL_CATEGORY_LETTER);
}

bool code_point_has_number_general_category(u32 code_point)
{
return code_point_has_general_category(code_point, GENERAL_CATEGORY_NUMBER);
}

bool code_point_has_punctuation_general_category(u32 code_point)
{
return code_point_has_general_category(code_point, GENERAL_CATEGORY_PUNCTUATION);
Expand All @@ -128,6 +138,11 @@ bool code_point_has_space_separator_general_category(u32 code_point)
return code_point_has_general_category(code_point, U_SPACE_SEPARATOR);
}

bool code_point_has_symbol_general_category(u32 code_point)
{
return code_point_has_general_category(code_point, GENERAL_CATEGORY_SYMBOL);
}

static constexpr Property PROPERTY_ANY = UCHAR_BINARY_LIMIT + 1;
static constexpr Property PROPERTY_ASCII = UCHAR_BINARY_LIMIT + 2;
static constexpr Property PROPERTY_ASSIGNED = UCHAR_BINARY_LIMIT + 3;
Expand Down
3 changes: 3 additions & 0 deletions Userland/Libraries/LibUnicode/CharacterTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,12 @@ Optional<GeneralCategory> general_category_from_string(StringView);
bool code_point_has_general_category(u32 code_point, GeneralCategory general_category);

bool code_point_has_control_general_category(u32 code_point);
bool code_point_has_letter_general_category(u32 code_point);
bool code_point_has_number_general_category(u32 code_point);
bool code_point_has_punctuation_general_category(u32 code_point);
bool code_point_has_separator_general_category(u32 code_point);
bool code_point_has_space_separator_general_category(u32 code_point);
bool code_point_has_symbol_general_category(u32 code_point);

Optional<Property> property_from_string(StringView);
bool code_point_has_property(u32 code_point, Property property);
Expand Down
25 changes: 21 additions & 4 deletions Userland/Libraries/LibWeb/Page/EventHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* SPDX-License-Identifier: BSD-2-Clause
*/

#include <LibUnicode/CharacterTypes.h>
#include <LibUnicode/Segmenter.h>
#include <LibWeb/DOM/Range.h>
#include <LibWeb/DOM/Text.h>
Expand Down Expand Up @@ -836,6 +837,18 @@ EventResult EventHandler::fire_keyboard_event(FlyString const& event_name, HTML:
return target->dispatch_event(event) ? EventResult::Accepted : EventResult::Cancelled;
}

// https://w3c.github.io/uievents/#unicode-character-categories
static bool produces_character_value(u32 code_point)
{
// A subset of the General Category values that are defined for each Unicode code point. This subset contains all
// the Letter (Ll, Lm, Lo, Lt, Lu), Number (Nd, Nl, No), Punctuation (Pc, Pd, Pe, Pf, Pi, Po, Ps) and Symbol (Sc,
// Sk, Sm, So) category values.
return Unicode::code_point_has_letter_general_category(code_point)
|| Unicode::code_point_has_number_general_category(code_point)
|| Unicode::code_point_has_punctuation_general_category(code_point)
|| Unicode::code_point_has_symbol_general_category(code_point);
}

EventResult EventHandler::handle_keydown(UIEvents::KeyCode key, u32 modifiers, u32 code_point)
{
if (!m_navigable->active_document())
Expand All @@ -847,10 +860,14 @@ EventResult EventHandler::handle_keydown(UIEvents::KeyCode key, u32 modifiers, u
if (dispatch_result != EventResult::Accepted)
return dispatch_result;

// FIXME: Work out and implement the difference between this and keydown.
dispatch_result = fire_keyboard_event(UIEvents::EventNames::keypress, m_navigable, key, modifiers, code_point);
if (dispatch_result != EventResult::Accepted)
return dispatch_result;
// https://w3c.github.io/uievents/#event-type-keypress
// If supported by a user agent, this event MUST be dispatched when a key is pressed down, if and only if that key
// normally produces a character value.
if (produces_character_value(code_point)) {
dispatch_result = fire_keyboard_event(UIEvents::EventNames::keypress, m_navigable, key, modifiers, code_point);
if (dispatch_result != EventResult::Accepted)
return dispatch_result;
}

JS::NonnullGCPtr<DOM::Document> document = *m_navigable->active_document();

Expand Down

0 comments on commit 448754d

Please sign in to comment.