diff --git a/Tests/LibWeb/Text/expected/Editing/beforeinput-event.txt b/Tests/LibWeb/Text/expected/Editing/beforeinput-event.txt new file mode 100644 index 00000000000..e8842c4f473 --- /dev/null +++ b/Tests/LibWeb/Text/expected/Editing/beforeinput-event.txt @@ -0,0 +1,5 @@ +beforeinput data=(r) intputType=(insertText) +beforeinput data=(e) intputType=(insertText) +beforeinput data=(e) intputType=(insertText) +beforeinput data=(e) intputType=(insertText) +Text in input: reee diff --git a/Tests/LibWeb/Text/input/Editing/beforeinput-event.html b/Tests/LibWeb/Text/input/Editing/beforeinput-event.html new file mode 100644 index 00000000000..57a39b9f0de --- /dev/null +++ b/Tests/LibWeb/Text/input/Editing/beforeinput-event.html @@ -0,0 +1,24 @@ + + +
+ diff --git a/Userland/Libraries/LibWeb/Page/EventHandler.cpp b/Userland/Libraries/LibWeb/Page/EventHandler.cpp index a979633e1cd..1a66629be83 100644 --- a/Userland/Libraries/LibWeb/Page/EventHandler.cpp +++ b/Userland/Libraries/LibWeb/Page/EventHandler.cpp @@ -997,6 +997,8 @@ EventResult EventHandler::handle_keydown(UIEvents::KeyCode key, u32 modifiers, u auto& node = *document->cursor_position()->node(); if (key == UIEvents::KeyCode::Key_Backspace && node.is_editable()) { + FIRE(input_event(UIEvents::EventNames::beforeinput, UIEvents::InputTypes::deleteContentBackward, m_navigable, code_point)); + if (!document->decrement_cursor_position_offset()) { // FIXME: Move to the previous node and delete the last character there. return EventResult::Handled; @@ -1008,6 +1010,8 @@ EventResult EventHandler::handle_keydown(UIEvents::KeyCode key, u32 modifiers, u } if (key == UIEvents::KeyCode::Key_Delete && node.is_editable()) { + FIRE(input_event(UIEvents::EventNames::beforeinput, UIEvents::InputTypes::deleteContentForward, m_navigable, code_point)); + if (document->cursor_position()->offset_is_at_end_of_node()) { // FIXME: Move to the next node and delete the first character there. return EventResult::Handled; @@ -1089,6 +1093,7 @@ EventResult EventHandler::handle_keydown(UIEvents::KeyCode key, u32 modifiers, u } if (key == UIEvents::KeyCode::Key_Return && node.is_editable()) { + FIRE(input_event(UIEvents::EventNames::beforeinput, UIEvents::InputTypes::insertParagraph, m_navigable, code_point)); HTML::HTMLInputElement* input_element = nullptr; if (auto node = document->cursor_position()->node()) { if (node->is_text()) { @@ -1114,6 +1119,7 @@ EventResult EventHandler::handle_keydown(UIEvents::KeyCode key, u32 modifiers, u // FIXME: Text editing shortcut keys (copy/paste etc.) should be handled here. if (!should_ignore_keydown_event(code_point, modifiers) && node.is_editable()) { + FIRE(input_event(UIEvents::EventNames::beforeinput, UIEvents::InputTypes::insertText, m_navigable, code_point)); m_edit_event_handler->handle_insert(document, JS::NonnullGCPtr { *document->cursor_position() }, code_point); document->increment_cursor_position_offset(); FIRE(input_event(UIEvents::EventNames::input, UIEvents::InputTypes::insertText, m_navigable, code_point)); diff --git a/Userland/Libraries/LibWeb/UIEvents/EventNames.h b/Userland/Libraries/LibWeb/UIEvents/EventNames.h index 09b8d884597..779ef1ccdd1 100644 --- a/Userland/Libraries/LibWeb/UIEvents/EventNames.h +++ b/Userland/Libraries/LibWeb/UIEvents/EventNames.h @@ -16,6 +16,7 @@ namespace Web::UIEvents::EventNames { #define ENUMERATE_UI_EVENTS \ __ENUMERATE_UI_EVENT(auxclick) \ + __ENUMERATE_UI_EVENT(beforeinput) \ __ENUMERATE_UI_EVENT(click) \ __ENUMERATE_UI_EVENT(contextmenu) \ __ENUMERATE_UI_EVENT(dblclick) \ diff --git a/Userland/Libraries/LibWeb/UIEvents/InputEvent.cpp b/Userland/Libraries/LibWeb/UIEvents/InputEvent.cpp index b131693720b..3d4deb02ed7 100644 --- a/Userland/Libraries/LibWeb/UIEvents/InputEvent.cpp +++ b/Userland/Libraries/LibWeb/UIEvents/InputEvent.cpp @@ -14,7 +14,12 @@ JS_DEFINE_ALLOCATOR(InputEvent); JS::NonnullGCPtr InputEvent::create_from_platform_event(JS::Realm& realm, FlyString const& event_name, InputEventInit const& event_init) { - return realm.heap().allocate(realm, realm, event_name, event_init); + auto event = realm.heap().allocate(realm, realm, event_name, event_init); + event->set_bubbles(true); + if (event_name == "beforeinput"_fly_string) { + event->set_cancelable(true); + } + return event; } WebIDL::ExceptionOr> InputEvent::construct_impl(JS::Realm& realm, FlyString const& event_name, InputEventInit const& event_init)