فهرست منبع

LibWeb: Dispatch click events using the correct button/buttons

We were generating click events always using the primary mouse button
instead of the provided button, and with the buttons field set to that
provided button.
Timothy Flynn 10 ماه پیش
والد
کامیت
dd5a0361f2

+ 4 - 0
Tests/LibWeb/Text/expected/UIEvents/mouse-events.txt

@@ -8,6 +8,10 @@ mouseout target.id=(inner) currentTarget.id=(inner), relatedTarget.id=(outer)
 mouseout target.id=(inner) currentTarget.id=(outer), relatedTarget.id=(outer)
 mouseleave target.id=(inner) currentTarget.id=(inner), relatedTarget.id=(outer)
 mouseover target.id=(outer) currentTarget.id=(outer), relatedTarget.id=(inner)
+> click #outer
+click target.id=(outer) currentTarget.id=(outer), button=0
+> auxclick #outer
+auxclick target.id=(outer) currentTarget.id=(outer), button=1
 > click document.body
 mouseout target.id=(outer) currentTarget.id=(outer), relatedTarget.id=(body)
 mouseleave target.id=(outer) currentTarget.id=(outer), relatedTarget.id=(body)

+ 29 - 1
Tests/LibWeb/Text/input/UIEvents/mouse-events.html

@@ -34,17 +34,26 @@ function handleMouseEnter(e) {
 function handleMouseLeave(e) {
     println(`mouseleave target.id=(${e.target.id}) currentTarget.id=(${e.currentTarget.id}), relatedTarget.id=(${e.relatedTarget.id})`);
 }
-
+function handleClick(e) {
+    println(`click target.id=(${e.target.id}) currentTarget.id=(${e.currentTarget.id}), button=${e.button}`);
+}
+function handleAuxClick(e) {
+    println(`auxclick target.id=(${e.target.id}) currentTarget.id=(${e.currentTarget.id}), button=${e.button}`);
+}
 
 outer.onmouseover = handleMouseOver;
 outer.onmouseout = handleMouseOut;
 outer.onmouseenter = handleMouseEnter;
 outer.onmouseleave = handleMouseLeave;
+outer.onclick = handleClick;
+outer.onauxclick = handleAuxClick;
 
 inner.onmouseover = handleMouseOver;
 inner.onmouseout = handleMouseOut;
 inner.onmouseenter = handleMouseEnter;
 inner.onmouseleave = handleMouseLeave;
+inner.onclick = handleClick;
+inner.onauxclick = handleAuxClick;
 
 const clickOnBody = () => {
     return new Promise(resolve => {
@@ -53,6 +62,21 @@ const clickOnBody = () => {
     });
 }
 
+const clickOnOuterBox = (button) => {
+    return new Promise((resolve, reject) => {
+        if (button == 0) {
+            document.body.onclick = () => { resolve(); };
+            internals.click(80, 80);
+        } else if (button == 1) {
+            document.body.onauxclick = () => { resolve(); };
+            internals.middleClick(80, 80);
+        } else {
+            println(`Unimplemented button click: ${button}`);
+            reject();
+        }
+    });
+};
+
 asyncTest(async done => {
     // First move the mouse outside #outer to populate the MouseEvent.relatedTarget property
     internals.movePointerTo(150, 150);
@@ -60,6 +84,10 @@ asyncTest(async done => {
     internals.movePointerTo(10, 10);
     println("> move pointer over #outer");
     internals.movePointerTo(60, 60);
+    println("> click #outer");
+    await clickOnOuterBox(0);
+    println("> auxclick #outer");
+    await clickOnOuterBox(1);
     println("> click document.body");
     await clickOnBody();
     done();

+ 3 - 3
Userland/Libraries/LibWeb/Page/EventHandler.cpp

@@ -297,13 +297,13 @@ EventResult EventHandler::handle_mouseup(CSSPixelPoint viewport_position, CSSPix
             bool run_activation_behavior = false;
             if (node.ptr() == m_mousedown_target) {
                 if (button == UIEvents::MouseButton::Primary) {
-                    run_activation_behavior = node->dispatch_event(UIEvents::MouseEvent::create_from_platform_event(node->realm(), UIEvents::EventNames::click, screen_position, page_offset, client_offset, offset, {}, 1, button, modifiers).release_value_but_fixme_should_propagate_errors());
+                    run_activation_behavior = node->dispatch_event(UIEvents::MouseEvent::create_from_platform_event(node->realm(), UIEvents::EventNames::click, screen_position, page_offset, client_offset, offset, {}, button, buttons, modifiers).release_value_but_fixme_should_propagate_errors());
                 } else if (button == UIEvents::MouseButton::Middle) {
-                    run_activation_behavior = node->dispatch_event(UIEvents::MouseEvent::create_from_platform_event(node->realm(), UIEvents::EventNames::auxclick, screen_position, page_offset, client_offset, offset, {}, 1, button, modifiers).release_value_but_fixme_should_propagate_errors());
+                    run_activation_behavior = node->dispatch_event(UIEvents::MouseEvent::create_from_platform_event(node->realm(), UIEvents::EventNames::auxclick, screen_position, page_offset, client_offset, offset, {}, button, buttons, modifiers).release_value_but_fixme_should_propagate_errors());
                 } else if (button == UIEvents::MouseButton::Secondary) {
                     // Allow the user to bypass custom context menus by holding shift, like Firefox.
                     if ((modifiers & UIEvents::Mod_Shift) == 0)
-                        run_activation_behavior = node->dispatch_event(UIEvents::MouseEvent::create_from_platform_event(node->realm(), UIEvents::EventNames::contextmenu, screen_position, page_offset, client_offset, offset, {}, 1, button, modifiers).release_value_but_fixme_should_propagate_errors());
+                        run_activation_behavior = node->dispatch_event(UIEvents::MouseEvent::create_from_platform_event(node->realm(), UIEvents::EventNames::contextmenu, screen_position, page_offset, client_offset, offset, {}, button, buttons, modifiers).release_value_but_fixme_should_propagate_errors());
                     else
                         run_activation_behavior = true;
                 }