commit d84b12db85d887e9b15a381112a428bb4af06487
parent f335211ab3db662d7c04f5e5cc92526f2e55fb25
Author: Mason Freed <masonf@chromium.org>
Date: Thu, 6 Nov 2025 21:34:39 +0000
Bug 1997717 [wpt PR 55807] - Implement mousedown-drag-mouseup menu behavior [3/4], a=testonly
Automatic update from web-platform-tests
Implement mousedown-drag-mouseup menu behavior [3/4]
This implements the same behavior we have in customizable-<select>, for
the menu elements. Clicking the mouse on a menuitem that triggers a
sub-menu, then dragging into the sub-menu, then releasing the mouse on
an item in that sub-menu now selects that item.
Bug: 406566432,453209085
Change-Id: I0e5aef5412a100dff4d9e6638371fda3742b6162
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7068555
Commit-Queue: Mason Freed <masonf@chromium.org>
Reviewed-by: Dominic Farolino <dom@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1538873}
--
wpt-commits: 607bde086236db9ec100bed541734327e9d37e46
wpt-pr: 55807
Diffstat:
2 files changed, 55 insertions(+), 10 deletions(-)
diff --git a/testing/web-platform/tests/html/semantics/menu/tentative/menubar-invoke-menulist.html b/testing/web-platform/tests/html/semantics/menu/tentative/menubar-invoke-menulist.html
@@ -143,18 +143,15 @@ test(() => {
assert_false(menulist.matches(":popover-open"),
"menulist no longer matches :popover-open");
- // Being an invoker for a sub-menu causes checkability to stop.
+ // Being checkable causes sub-menu functionality to stop.
checkableMenuitem.command = "toggle-menu";
checkableMenuitem.commandForElement = menulist;
checkableMenuitem.click();
- assert_false(checkableMenuitem.checked,
- "checkable menu item that invokes a menu does not become checked");
- assert_true(menulist.matches(":popover-open"),
- "menulist matches :popover-open");
+ assert_true(checkableMenuitem.checked,
+ "checkable menu item that invokes a menu becomes checked");
+ assert_false(menulist.matches(":popover-open"), "menulist is not open");
checkableMenuitem.click();
- assert_false(checkableMenuitem.checked,
- "checkable menu item is still not checked");
- assert_false(menulist.matches(":popover-open"),
- "menulist no longer matches :popover-open");
+ assert_false(checkableMenuitem.checked, "checkable menu item unchecks");
+ assert_false(menulist.matches(":popover-open"), "menulist still not open");
}, "Checkable menuitems can still invoke menulist popovers");
</script>
diff --git a/testing/web-platform/tests/html/semantics/menu/tentative/menuitem-activate.html b/testing/web-platform/tests/html/semantics/menu/tentative/menuitem-activate.html
@@ -3,7 +3,9 @@
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-actions.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
+<script src="../../popovers/resources/popover-utils.js"></script>
<link rel=author href=mailto:dom@chromium.org>
<link rel=help href=https://open-ui.org/components/menu.explainer>
@@ -14,6 +16,7 @@
<menulist id=mainmenu>
<menuitem id=mainmenuitem command=toggle-menu commandfor=submenu>Toggle menu</menuitem>
<menuitem id=mainmenuitem2 command=toggle-popover commandfor=popover>Show popover</menuitem>
+ <menuitem id=normalmenuitem>Normal item</menuitem>
</menulist>
<menulist id=submenu>
@@ -101,7 +104,7 @@ promise_test(async (t) => {
// Close the second, "sub", menu within the popover by just clicking off of
// it.
- await test_driver.click(menuinpopoveritem1);
+ await test_driver.click(menuinpopoveritem2);
assert_false(menuinpopover2.matches(":popover-open"),
"menu 2 in popover closes");
assert_true(popoverwithmenu.matches(":popover-open"),
@@ -110,4 +113,49 @@ promise_test(async (t) => {
"menu in popover remains open");
}, 'Menulist inside a popover works correctly; does not get accidentally ' +
'dismissed by opening submenus');
+
+promise_test(async (t) => {
+ assert_false(mainmenu.matches(":popover-open"), "mainmenu popover starts closed");
+ let clickCount = 0;
+ normalmenuitem.addEventListener('click',() => (++clickCount));
+ const actions = new test_driver.Actions();
+ await actions.addPointer('mouse', 'mouse')
+ .pointerMove(0, 0, {origin: menubarmenuitem})
+ .pointerDown()
+ .send();
+ await waitForRender();
+ assert_true(mainmenu.matches(":popover-open"), "mainmenu popover should be open while mouse is down");
+ assert_equals(clickCount,0, "no clicks yet");
+ await actions.pointerMove(0, 0, {origin: normalmenuitem})
+ .pointerUp()
+ .send();
+ await waitForRender();
+ assert_false(mainmenu.matches(":popover-open"), "mainmenu popover should be closed");
+ // TODO: Menu items should fire an event when they are selected.
+ // The `click` event is not enough, because one won't be fired here.
+ // assert_equals(clickCount,1, "the sub-menu item should have been clicked");
+}, 'A mousedown-drag-mouseup gesture on a normal menuitem picks the item');
+
+promise_test(async (t) => {
+ assert_false(mainmenu.matches(":popover-open"), "mainmenu popover starts closed");
+ assert_false(submenu.matches(":popover-open"), "submenu popover starts closed");
+ const actions = new test_driver.Actions();
+ await actions.addPointer('mouse', 'mouse')
+ .pointerMove(0, 0, {origin: menubarmenuitem})
+ .pointerDown()
+ .send();
+ await waitForRender();
+ assert_true(mainmenu.matches(":popover-open"), "mainmenu popover should be open while mouse is down");
+ assert_false(submenu.matches(":popover-open"), "submenu shouldn't be open yet");
+ await actions.pointerMove(0, 0, {origin: mainmenuitem})
+ .pointerUp()
+ .send();
+ await waitForRender();
+ assert_true(mainmenu.matches(":popover-open"), "mainmenu popover should remain open, because submenu chosen");
+ assert_true(submenu.matches(":popover-open"), "submenu popover should be open");
+ menubarmenuitem.click(); // Cleanup.
+ await waitForRender();
+ assert_false(mainmenu.matches(":popover-open"), "mainmenu popover should be closed");
+ assert_false(submenu.matches(":popover-open"), "submenu popover should be closed");
+}, 'A mousedown-drag-mouseup gesture on a submenu item leaves both menus open');
</script>