Implement new/revised popover=hint behavior#59237
Conversation
|
Azure Pipelines: Successfully started running 1 pipeline(s). |
See this discussion for more context: whatwg/html#12304 whatwg/html#12345 This CL implements a simplified behavioral model for popover=hint and popover=auto, cleanly separating the autoRootedPopoverStack from the hintRootedPopoverStack and introducing a `hintStackParent` to track where the hint stack branches off the auto stack. The new behavior resolves the following inconsistencies (gated behind the `PopoverHintNewBehavior` experimental runtime flag): 1. Opening a hint popover will not hide unrelated auto popovers. 2. Opening a hint popover closes only other non-ancestor hint popovers. 3. Clicking outside consistently closes both auto and hint popovers. 4. Hiding an auto popover closes only its child popovers. 5. Opening an auto popover inside a hint popover is disallowed and will fail. A new WPT test (`popover-hint-hierarchy.html`) is added to explicitly assert these 5 rules, and existing popover WPTs are updated to reflect the new behavior. A virtual test suite (`popover-hint-old-behavior`) is also added to continue testing the legacy behavior. I'm not sure how to best handle the changed tests (and I guess the new test too) in the context of a spec PR that is forthcoming. I'd like to be able to publish (as a WPT PR at least) the changes, to help with the PR effort. Suggestions appreciated. A note about the diff: I made all of the feature flag checks look like `if (!feature enabled) {` in the hopes that the old code would show as unchanged in the diff, but gerrit's diff algorithm isn't great. It's at least a little better like this than if I put the new code first, so I left it. Bug: 4990199 Change-Id: I41d8d96be71ba60ec5e7aa640c935258d1e33431 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7727959 Auto-Submit: Mason Freed <masonf@chromium.org> Reviewed-by: David Baron <dbaron@chromium.org> Commit-Queue: David Baron <dbaron@chromium.org> Cr-Commit-Position: refs/heads/main@{#1615186}
c20a11f to
3995ae4
Compare
wpt-pr-bot
left a comment
There was a problem hiding this comment.
The review process for this patch is being conducted in the Chromium project.
|
Azure Pipelines: Successfully started running 1 pipeline(s). |
1 similar comment
|
Azure Pipelines: Successfully started running 1 pipeline(s). |
|
@jakearchibald are you able to review this change? |
|
Yeah, I'm planning to go through it today |
There was a problem hiding this comment.
Looks good so far! Just needs to cater for the newer stuff:
- Auto can be within hint (but it downgrades).
showPopoverwithin the hide/show of a popover should throw/no-op.
I think you mentioned there was a test here somewhere that tested incorrect behaviour… well… I failed to find it. Hah!
| // this is "weirdness 5" from https://github.com/whatwg/html/issues/12304 | ||
| promise_test(async (t) => { | ||
| t.add_cleanup(hideAll); | ||
|
|
||
| hint1.showPopover(); | ||
| assertOpen('initial',hint1); | ||
|
|
||
| // Imperative | ||
| assert_throws_dom('InvalidStateError', () => { | ||
| auto1.showPopover({source: hint1}); | ||
| }, 'Opening auto popover inside hint popover is not allowed'); | ||
| assertOpen('after show',hint1); | ||
|
|
||
| // Declarative | ||
| const invoker = document.createElement('button'); | ||
| invoker.popoverTargetElement = auto1; | ||
| t.add_cleanup(() => invoker.remove()); | ||
| hint1.appendChild(invoker); | ||
| await clickOn(invoker); | ||
| assertOpen('after click',hint1); | ||
| }, 'Opening an auto popover inside a hint popover is disallowed and will fail.'); |
There was a problem hiding this comment.
You may have already done this, but in case it helps…
| // this is "weirdness 5" from https://github.com/whatwg/html/issues/12304 | |
| promise_test(async (t) => { | |
| t.add_cleanup(hideAll); | |
| hint1.showPopover(); | |
| assertOpen('initial',hint1); | |
| // Imperative | |
| assert_throws_dom('InvalidStateError', () => { | |
| auto1.showPopover({source: hint1}); | |
| }, 'Opening auto popover inside hint popover is not allowed'); | |
| assertOpen('after show',hint1); | |
| // Declarative | |
| const invoker = document.createElement('button'); | |
| invoker.popoverTargetElement = auto1; | |
| t.add_cleanup(() => invoker.remove()); | |
| hint1.appendChild(invoker); | |
| await clickOn(invoker); | |
| assertOpen('after click',hint1); | |
| }, 'Opening an auto popover inside a hint popover is disallowed and will fail.'); | |
| // this is "weirdness 5" from https://github.com/whatwg/html/issues/12304 | |
| promise_test(async (t) => { | |
| t.add_cleanup(hideAll); | |
| auto1.showPopover(); | |
| hint1.showPopover({source: auto1}); | |
| assertOpen('initial', auto1, hint1); | |
| auto2.showPopover({source: hint1}); | |
| assertOpen('auto opened inside hint', auto1, hint1, auto2); | |
| hint2.showPopover({source: hint1}); | |
| assertOpen('auto exhibits hint-like behavior', auto1, hint1, hint2); | |
| }, 'Auto popovers opened inside hint popovers are downgraded to hint behaviors'); |
| <div> | ||
| <div popover="hint">Hint | ||
| <div popover>Nested auto (note - never visible, since inside display:none subtree)</div> | ||
| </div> | ||
| <script> | ||
| test(() => { | ||
| const hint = getPopovers()[0]; | ||
| const auto = getPopovers()[1]; | ||
| hint.showPopover(); | ||
| assertState([true,false]); | ||
| auto.showPopover(); | ||
| assertState([false,true]); | ||
| auto.hidePopover(); | ||
| assert_throws_dom('InvalidStateError', () => { | ||
| auto.showPopover(); | ||
| }); | ||
| assertState([true,false]); | ||
| hint.hidePopover(); | ||
| assertState([false,false]); | ||
| },'If a popover=auto is shown, it should hide any open popover=hint, including if the popover=hint is an ancestral popover of the popover=auto. (You can\'t nest a popover=auto inside a popover=hint)'); | ||
| </script> | ||
| </div> |
There was a problem hiding this comment.
| <div> | |
| <div popover="hint">Hint | |
| <div popover>Nested auto</div> | |
| </div> | |
| <script> | |
| test(() => { | |
| const hint = getPopovers()[0]; | |
| const auto = getPopovers()[1]; | |
| hint.showPopover(); | |
| assertState([true,false]); | |
| auto.showPopover(); | |
| assertState([true,true]); | |
| hint.hidePopover(); | |
| assertState([false,false]); | |
| },'If a popover=auto is shown within a popover=hint, it should be shown'); | |
| </script> | |
| </div> |
There was a problem hiding this comment.
Need to cater for 'auto' being allowed inside 'hint'. Watch out for stuff outside tests too, like "Improperly nested".
|
@mfreed7 To address the review, you can push some extra commits on this branch. The changes will propagate back to |
Co-authored-by: Jake Archibald <jaffathecake@gmail.com>
Co-authored-by: Jake Archibald <jaffathecake@gmail.com>
I'm guessing they will then create additional havoc with the dependent patches that change the same tests, but I guess we'll see! |
|
Can we land this? |
- Showing a hint popover doesn't hide auto popovers. - Showing a hint popover hides non-parent hint popovers. - Clicking outside popovers consistently hides them. - Hiding an auto popover does not hide unrelated hint popovers. - Showing an auto popover as a child of a hint popover downgrades the auto popover to a hint. - Showing a popover during the show or hide of another popover is no longer allowed. Tests: web-platform-tests/wpt#59237. Fixes #12304, fixes #12346 fixes #12355, and fixes #12356.
jgraham
left a comment
There was a problem hiding this comment.
From an Interop point of view, this is approved by the vendors who are affected by the change, so it's fine to land.
Thanks! @jonathan-j-lee, do you happen to know how long it takes Chromium's infra to upload the next in the series? I'd love to get all of those landed, so that we can make sure the final collection looks good to everyone. It's pretty difficult to do that as-is. |
|
I've paused @chromium-wpt-export-bot because of crashes related to |
Thanks @jonathan-j-lee. It also seems like the importer is borked because of the changes made during the review of this PR: https://crbug.com/513412137. |
See this discussion for more context:
whatwg/html#12304
whatwg/html#12345
This CL implements a simplified behavioral model for popover=hint and
popover=auto, cleanly separating the autoRootedPopoverStack from the
hintRootedPopoverStack and introducing a
hintStackParentto trackwhere the hint stack branches off the auto stack.
The new behavior resolves the following inconsistencies (gated behind
the
PopoverHintNewBehaviorexperimental runtime flag):popovers.
will fail.
A new WPT test (
popover-hint-hierarchy.html) is added to explicitlyassert these 5 rules, and existing popover WPTs are updated to reflect
the new behavior. A virtual test suite (
popover-hint-old-behavior)is also added to continue testing the legacy behavior. I'm not sure
how to best handle the changed tests (and I guess the new test too)
in the context of a spec PR that is forthcoming. I'd like to be able
to publish (as a WPT PR at least) the changes, to help with the PR
effort. Suggestions appreciated.
A note about the diff: I made all of the feature flag checks look like
if (!feature enabled) {in the hopes that the old code would showas unchanged in the diff, but gerrit's diff algorithm isn't great.
It's at least a little better like this than if I put the new code
first, so I left it.
Bug: 4990199
Change-Id: I41d8d96be71ba60ec5e7aa640c935258d1e33431
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7727959
Auto-Submit: Mason Freed <masonf@chromium.org>
Reviewed-by: David Baron <dbaron@chromium.org>
Commit-Queue: David Baron <dbaron@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1615186}