Files
sousa-gecko/testing/web-platform/tests/html/semantics/menu/tentative/menu-safe-triangle.optional.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

102 lines
4.3 KiB
HTML

<!DOCTYPE html>
<title>Menu elements safe triangle behavior</title>
<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="../../interestfor/resources/invoker-utils.js"></script>
<link rel="author" title="L. David Baron" href="https://dbaron.org/">
<link rel="author" title="Google" href="http://www.google.com/">
<link rel="help" href="https://open-ui.org/components/menu.explainer">
<style>
menuitem { interest-delay: 0ms; }
</style>
<menubar>
<menuitem>File</menuitem>
<menuitem>Edit</menuitem>
<submenu>
<menuitem id="view-trigger">View</menuitem>
<menulist id="view-menu">
<menuitem>Full Screen</menuitem>
<submenu>
<menuitem id="zoom-trigger">Zoom</menuitem>
<menulist id="zoom-menu">
<menuitem>25%</menuitem>
<menuitem>50%</menuitem>
<menuitem>75%</menuitem>
<menuitem>90%</menuitem>
<menuitem>100%</menuitem>
<menuitem>110%</menuitem>
<menuitem>125%</menuitem>
<menuitem>150%</menuitem>
<menuitem>200%</menuitem>
</menulist>
</submenu>
</menulist>
</submenu>
<menuitem>Help</menuitem>
</menubar>
<script>
promise_test(async (t) => {
let view_item = document.getElementById("view-trigger");
let view_menu = document.getElementById("view-menu");
let zoom_item = document.getElementById("zoom-trigger");
let zoom_menu = document.getElementById("zoom-menu");
let full_screen_item = zoom_item.parentElement.previousElementSibling;
let actions = new test_driver.Actions();
assert_false(view_item.matches(":open"), "view menu closed before click");
await clickOn(view_item);
t.add_cleanup(async () => { await clickOn(view_item); });
assert_true(view_item.matches(":open"), "view menu open after click");
assert_false(zoom_item.matches(":open"), "zoom menu closed before hover");
await hoverOver(zoom_item);
assert_true(zoom_item.matches(":open"), "zoom menu open after hover");
let zoom_rect = zoom_item.getBoundingClientRect();
await hoverOver(full_screen_item);
assert_false(zoom_item.matches(":open"), "zoom menu closes after mouse move out of safe triangle");
assert_true(view_item.matches(":open"), "view menu still open after hover/dehover");
// TODO(https://crbug.com/406566432): We should also check that the view
// menu (which was opened by click) stays open when moving the pointer
// entirely out of it. That doesn't work right now, though.
}, 'moving mouse out of safe triangle lets menu close');
promise_test(async (t) => {
let view_item = document.getElementById("view-trigger");
let view_menu = document.getElementById("view-menu");
let zoom_item = document.getElementById("zoom-trigger");
let zoom_menu = document.getElementById("zoom-menu");
let actions = new test_driver.Actions();
view_menu.hidePopover();
assert_false(view_menu.matches(':popover-open'), 'view menu closed before click');
assert_false(view_item.matches(":open"), "view menu invoker closed before click");
await clickOn(view_item);
t.add_cleanup(async () => { view_menu.hidePopover() });
assert_true(view_item.matches(":open"), "view menu open after click");
assert_false(zoom_item.matches(":open"), "zoom menu closed before hover");
await hoverOver(zoom_item);
assert_true(zoom_item.matches(":open"), "zoom menu open after hover");
let zoom_rect = zoom_item.getBoundingClientRect();
let zoom_menu_rect = zoom_menu.getBoundingClientRect();
await actions.pointerMove(zoom_rect.x + zoom_rect.width * 0.9, zoom_rect.y + zoom_rect.height * 1.2, {}).send();
await waitForRender();
assert_true(zoom_item.matches(":open"), "zoom menu still open after mouse move in safe triangle");
assert_false(zoom_menu.matches(":hover"), "zoom menu not yet being hovered");
await actions.pointerMove(zoom_menu_rect.x + zoom_menu_rect.width / 2, zoom_rect.y + zoom_rect.height * 1.2, {}).send();
await waitForRender();
assert_true(zoom_item.matches(":open"), "zoom menu still open after mouse move into submenu");
assert_true(zoom_menu.matches(":hover"), "zoom menu now being hovered");
}, 'moving mouse within safe triangle keeps menu open');
</script>