Files
sousa-gecko/testing/web-platform/tests/html/semantics/menu/tentative/focus-menu-elements-nested-arrowoperations.html
T
David Baron 8e3514c1dc Bug 2051000 [wpt PR 60939] - Convert menu element structure from command=toggle-menu to DOM nesting., a=testonly
Automatic update from web-platform-tests
Convert menu element structure from command=toggle-menu to DOM nesting.

This makes the changes discussed in
https://github.com/openui/open-ui/issues/1456 and elsewhere to convert
the nesting structure for menu elements from using command=toggle-menu
on menus to represent submenu relationships to using DOM nesting to
represent submenus.

This introduces a <submenu> element that can be used where a <menuitem>
would be, containing two children, the <menuitem> and the associated
<menulist>.  It removes the toggle-menu command, but still allows
<menulist> elements (which are implicitly popovers) that are not inside
a <submenu> to be invoked with a toggle-popover command or the
popovertarget attribute.

This the main change is converting markup that looks like this:

  <menubar>
    <menuitem command=toggle-menu commandfor=file-menu>File</menu>
  </menubar>

  <menulist id=file-menu>
    <menuitem>New</menu>
    <menuitem>Open</menu>
  </menulist>

into this:

  <menubar>
    <submenu>
      <menuitem>File</menuitem>
      <menulist>
        <menuitem>New</menu>
        <menuitem>Open</menu>
      </menulist>
    </submenu>
  </menubar>

The other common pattern that is still permitted (except that it was
previously using the toggle-menu command instead of toggle-popover) is:

  <button command=toggle-popover commandfor=actions-menu>Actions</button>
  <menulist id=actions-menu>
    <menuitem>Go</menuitem>
  </menulist>

Bug: 406566432
Change-Id: If955cb8d3c76f02fca85161a9df3ec182505b1df
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7997301
Reviewed-by: Joey Arhar <jarhar@chromium.org>
Commit-Queue: David Baron <dbaron@chromium.org>
Reviewed-by: David Grogan <dgrogan@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1653560}

--

wpt-commits: aecb1ec9c88346b62e167119b4dab8d8892b6240
wpt-pr: 60939
2026-07-10 09:20:07 +00:00

114 lines
4.2 KiB
HTML

<!DOCTYPE html>
<meta name="timeout" content="long">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<link rel=author href=mailto:dizhangg@chromium.org>
<link rel=help href=https://open-ui.org/components/menu.explainer>
<style>
/* TODO: Remove CSS rule when it is defined in UA style sheet. */
menulist {
position-area: bottom span-right;
position: absolute;
}
.nested {
position-area: right span-bottom;
}
</style>
<div id="container">
<menubar>
<submenu>
<menuitem id="a">Commands A</menuitem>
<menulist id="menulist1">
<menuitem id="d">Command D</menuitem>
</menulist>
</submenu>
<submenu>
<menuitem id="b">Commands B</menuitem>
<menulist id="menulist2">
<menuitem id="e" command="show-popover" commandfor="menulist4">Command E</menuitem>
<menuitem id="f" command="toggle-popover" commandfor="menulist4">Command F</menuitem>
<submenu>
<menuitem id="g">Commands G</menuitem>
<menulist id="menulist3" class="nested">
<menuitem id="h">Command H</menuitem>
<menuitem id="i">Command I</menuitem>
</menulist>
</submenu>
</menulist>
</submenu>
<menuitem id="c">Commands C</menuitem>
</menubar>
</div>
<menulist id="menulist4" class="nested">
<menuitem id="j">Command J</menuitem>
<menuitem id="k">Command K</menuitem>
</menulist>
<script>
const ArrowLeft = '\uE012';
const ArrowUp = '\uE013';
const ArrowRight = '\uE014';
const ArrowDown = '\uE015';
async function navigateMenus() {
await test_driver.click(a);
assert_equals(document.activeElement, a);
await test_driver.send_keys(document.activeElement, ArrowDown);
assert_equals(document.activeElement, d);
await test_driver.send_keys(document.activeElement, ArrowRight);
assert_equals(document.activeElement, b);
await test_driver.send_keys(document.activeElement, ArrowDown);
assert_equals(document.activeElement, e);
await test_driver.send_keys(document.activeElement, ArrowDown);
assert_equals(document.activeElement, f);
await test_driver.send_keys(document.activeElement, ArrowDown);
assert_equals(document.activeElement, g);
await test_driver.send_keys(document.activeElement, ArrowRight);
assert_equals(document.activeElement, h);
await test_driver.send_keys(document.activeElement, ArrowDown);
assert_equals(document.activeElement, i);
await test_driver.send_keys(document.activeElement, ArrowRight);
assert_equals(document.activeElement, c);
await test_driver.send_keys(document.activeElement, ArrowLeft);
assert_equals(document.activeElement, b);
await test_driver.send_keys(document.activeElement, ArrowDown);
assert_equals(document.activeElement, e);
await test_driver.send_keys(document.activeElement, ArrowRight);
assert_equals(document.activeElement, c, "show-popover does not create special submenu relationship");
await test_driver.send_keys(document.activeElement, ArrowLeft);
assert_equals(document.activeElement, b);
await test_driver.send_keys(document.activeElement, ArrowDown);
await test_driver.send_keys(document.activeElement, ArrowDown);
assert_equals(document.activeElement, f);
await test_driver.send_keys(document.activeElement, ArrowRight);
assert_equals(document.activeElement, c, "toggle-popover does not create special submenu relationship");
}
promise_test(async (t) => {
await navigateMenus();
}, 'Should use arrow keys to move between menuitems in menulist invoked from menubar.');
promise_test(async (t) => {
container.setAttribute('popover','auto');
container.showPopover();
await navigateMenus();
container.removeAttribute('popover');
}, 'Should use arrow keys to move between menuitems in menulist invoked from menubar inside a popover without closing the popover.');
promise_test(async (t) => {
document.querySelectorAll("menulist").forEach((menulist) => {
menulist.addEventListener('beforetoggle', () => menulist.hidePopover());
});
a.focus();
await navigateMenus();
}, 'Should use arrow keys to move between menuitems: Hide popover on beforetoggle should still work.');
</script>