فهرست منبع

LibWeb: Fire keydown and keypress events sooner

Fire the events before handling any close requests or selection changes.
Pages must have an opportunity to cancel the events.
Timothy Flynn 10 ماه پیش
والد
کامیت
3925317c11

+ 10 - 0
Tests/LibWeb/Text/expected/UIEvents/KeyEvent-cancelled.txt

@@ -0,0 +1,10 @@
+keydown A
+cancel keydown
+You can't change me!
+keydown B
+keypress B
+cancel keypress
+You can't change me!
+keydown C
+keypress C
+C

+ 46 - 0
Tests/LibWeb/Text/input/UIEvents/KeyEvent-cancelled.html

@@ -0,0 +1,46 @@
+<input id="input" />
+<script src="../include.js"></script>
+<script>
+    test(() => {
+        let input = document.getElementById("input");
+        input.value = "You can't change me!";
+
+        input.focus();
+        input.select();
+
+        let shouldCancelKeyDown = false;
+        let shouldCancelKeyPress = false;
+
+        input.addEventListener("keydown", e => {
+            println(`keydown ${e.key}`);
+
+            if (shouldCancelKeyDown) {
+                println("cancel keydown");
+                e.preventDefault();
+            }
+        });
+        input.addEventListener("keypress", e => {
+            println(`keypress ${e.key}`);
+
+            if (shouldCancelKeyPress) {
+                println("cancel keypress");
+                e.preventDefault();
+            }
+        });
+
+        shouldCancelKeyDown = true;
+        shouldCancelKeyPress = false;
+        internals.sendText(input, "A");
+        println(input.value);
+
+        shouldCancelKeyDown = false;
+        shouldCancelKeyPress = true;
+        internals.sendText(input, "B");
+        println(input.value);
+
+        shouldCancelKeyDown = false;
+        shouldCancelKeyPress = false;
+        internals.sendText(input, "C");
+        println(input.value);
+    });
+</script>

+ 10 - 6
Userland/Libraries/LibWeb/Page/EventHandler.cpp

@@ -843,6 +843,15 @@ EventResult EventHandler::handle_keydown(UIEvents::KeyCode key, u32 modifiers, u
     if (!m_navigable->active_document()->is_fully_active())
         return EventResult::Dropped;
 
+    auto dispatch_result = fire_keyboard_event(UIEvents::EventNames::keydown, m_navigable, key, modifiers, code_point);
+    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;
+
     JS::NonnullGCPtr<DOM::Document> document = *m_navigable->active_document();
 
     if (key == UIEvents::KeyCode::Key_Tab) {
@@ -905,10 +914,6 @@ EventResult EventHandler::handle_keydown(UIEvents::KeyCode key, u32 modifiers, u
             return EventResult::Handled;
     }
 
-    auto dispatch_result = fire_keyboard_event(UIEvents::EventNames::keydown, m_navigable, key, modifiers, code_point);
-    if (dispatch_result != EventResult::Accepted)
-        return dispatch_result;
-
     if (document->cursor_position()) {
         auto& node = *document->cursor_position()->node();
 
@@ -1073,8 +1078,7 @@ EventResult EventHandler::handle_keydown(UIEvents::KeyCode key, u32 modifiers, u
         break;
     }
 
-    // FIXME: Work out and implement the difference between this and keydown.
-    return fire_keyboard_event(UIEvents::EventNames::keypress, m_navigable, key, modifiers, code_point);
+    return EventResult::Accepted;
 }
 
 EventResult EventHandler::handle_keyup(UIEvents::KeyCode key, u32 modifiers, u32 code_point)