Pārlūkot izejas kodu

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 9 mēneši atpakaļ
vecāks
revīzija
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)