Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Close dialog elements when the open attribute is removed #10124

Open
wants to merge 9 commits into
base: main
Choose a base branch
from

Conversation

josepharhar
Copy link
Contributor

@josepharhar josepharhar commented Feb 5, 2024

Fixes #5802

This patch adds attribute change steps to run the dialog closing steps whenever the open attribute is removed in order to prevent a bad state where the dialog is hidden but modal which renders the rest of the page inert.

(See WHATWG Working Mode: Changes for more details.)


/form-control-infrastructure.html ( diff )
/interactive-elements.html ( diff )

Fixes whatwg#5802

This patch adds attribute change steps to run the dialog closing steps
whenever the open attribute is removed in order to prevent a bad state
where the dialog is hidden but modal which renders the rest of the page
inert.
Copy link
Member

@domenic domenic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very excited to see you tackle this! I hope other implementers are interested and that it's web-compatible. Pinging @emilio @zcorpan @annevk @nt1m for their thoughts.

source Outdated
return.</p></li>

<li><p>If <var>value</var> is null, then <span>close the dialog</span> given
<var>element</var>.</p></li>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This won't work, because it will return in step 1, because the open attribute has already been removed.

I guess we need to factor out steps 3-9 into a separate algorithm. Maybe "process open attribute removal"?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whoops I forgot that, I added a parameter to close in chromium. I just added it here. What do you think?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's slightly harder to understand than factoring out the steps would be, but I don't feel too strongly. (Thanks for updating the algorithm declaration style while you were there!)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I factored out the steps into a separate algorithm

source Outdated Show resolved Hide resolved
source Outdated Show resolved Hide resolved
@domenic domenic self-assigned this Feb 6, 2024
@josepharhar
Copy link
Contributor Author

I hope other implementers are interested and that it's web-compatible.

I will ship this behind a flag, and I will let yall know if any issues come up. I don't have a usecounter for it but I don't see why this change would be a problem.

Copy link
Member

@domenic domenic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally LGTM. I'll agenda+ this in the hopes of getting quick feedback.

source Outdated
return.</p></li>

<li><p>If <var>value</var> is null, then <span>close the dialog</span> given
<var>element</var>.</p></li>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's slightly harder to understand than factoring out the steps would be, but I don't feel too strongly. (Thanks for updating the algorithm declaration style while you were there!)

source Outdated Show resolved Hide resolved
@domenic domenic added the agenda+ To be discussed at a triage meeting label Feb 7, 2024
@annevk
Copy link
Member

annevk commented Feb 8, 2024

Seems reasonable modulo web compatibility. @lukewarlow might also be interested in this.

source Outdated Show resolved Hide resolved
Copy link
Contributor

@keithamus keithamus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a web developer (currently using <dialog> quite a bit), I'd be interested in seeing this change. (I've raised https://phabricator.services.mozilla.com/D201076 for Firefox).

source Outdated Show resolved Hide resolved
@past past removed the agenda+ To be discussed at a triage meeting label Feb 8, 2024
source Outdated
<p>To <dfn>close the dialog</dfn> given a <code>dialog</code> element <var>subject</var> and a
string or null <var>result</var>:</p>

<ol>
<li><p>If the <span>is modal</span> flag of <var>subject</var> is true, then <span>request an
element to be removed from the top layer</span> given <var>subject</var>.</p></li>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(github doesn't seem to let me add comment in the right place outside the PR changes)
Don't "focusing steps" possibly end up firing an event at problematic time.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the best thing would either be to not focus the previously focused element in this case, or to post a task/microtask to focus that element. Thoughts? @domenic @keithamus

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dbaron too if you have thoughts

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Related for popovers: #10129

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer to schedule a task. We should avoid losing focus on the document if we can help it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Scheduling a task sounds good to me too

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@smaug---- what do you think of scheduling a task?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made it schedule a task to focus for this case

chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this pull request Feb 9, 2024
https: //github.com/whatwg/html/pull/10124#discussion_r1483640232
Change-Id: Iab20699b345d96a8cffc83f7e7e44f4a03feb833
@lukewarlow
Copy link
Member

This feels like a big win for developers and having looked at the changes I don't think it's likely to cause any issues. Especially because it's unlikely developers will be relying on this behaviour (seems like its always undesirable)

@mfreed7
Copy link
Contributor

mfreed7 commented Nov 19, 2024

Any updates on this PR? It's mildly related to #10737 inasmuch as the close watcher logic is a little weirder (implementation-wise) when the open attribute can just be yanked off without calling close(). @josepharhar did you happen to try shipping the new behavior to see about web compat? (I'm happy to try, if there's consensus that this PR's behavior is desirable.)

@josepharhar
Copy link
Contributor Author

@josepharhar did you happen to try shipping the new behavior to see about web compat? (I'm happy to try, if there's consensus that this PR's behavior is desirable.)

No, I haven't shipped this yet.

I'm still waiting for feedback from @smaug---- in this thread: #10124 (comment)
It sounds like posting a task to focus is the right thing to do so far, so perhaps I'll just do that.

@domenic domenic mentioned this pull request Dec 11, 2024
5 tasks
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this pull request Jan 6, 2025
When the dialog's open attribute is removed which closes the dialog, we
should make the focus async in order to prevent more script from running
inside attribute removal.

Context: whatwg/html#10124 (comment)

Bug: 3419353
Change-Id: I1b76f003e04b802b1868b427a0faddf5f19a3c5e
aarongable pushed a commit to chromium/chromium that referenced this pull request Jan 6, 2025
When the dialog's open attribute is removed which closes the dialog, we
should make the focus async in order to prevent more script from running
inside attribute removal.

Context: whatwg/html#10124 (comment)

Bug: 341935362
Change-Id: I1b76f003e04b802b1868b427a0faddf5f19a3c5e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6085725
Reviewed-by: Di Zhang <[email protected]>
Commit-Queue: Joey Arhar <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1402551}
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this pull request Jan 6, 2025
When the dialog's open attribute is removed which closes the dialog, we
should make the focus async in order to prevent more script from running
inside attribute removal.

Context: whatwg/html#10124 (comment)

Bug: 3419353
Change-Id: I1b76f003e04b802b1868b427a0faddf5f19a3c5e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6085725
Reviewed-by: Di Zhang <[email protected]>
Commit-Queue: Joey Arhar <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1402551}
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this pull request Jan 6, 2025
When the dialog's open attribute is removed which closes the dialog, we
should make the focus async in order to prevent more script from running
inside attribute removal.

Context: whatwg/html#10124 (comment)

Bug: 3419353
Change-Id: I1b76f003e04b802b1868b427a0faddf5f19a3c5e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6085725
Reviewed-by: Di Zhang <[email protected]>
Commit-Queue: Joey Arhar <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1402551}
i3roly pushed a commit to i3roly/firefox-dynasty that referenced this pull request Jan 10, 2025
…en attribute, a=testonly

Automatic update from web-platform-tests
Make dialog focus async when removing open attribute

When the dialog's open attribute is removed which closes the dialog, we
should make the focus async in order to prevent more script from running
inside attribute removal.

Context: whatwg/html#10124 (comment)

Bug: 341935362
Change-Id: I1b76f003e04b802b1868b427a0faddf5f19a3c5e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6085725
Reviewed-by: Di Zhang <[email protected]>
Commit-Queue: Joey Arhar <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1402551}

--

wpt-commits: 58fd4f845204b88a3ae42b72b613a66e84cbb9f8
wpt-pr: 49929
moz-v2v-gh pushed a commit to mozilla/gecko-dev that referenced this pull request Jan 10, 2025
…en attribute, a=testonly

Automatic update from web-platform-tests
Make dialog focus async when removing open attribute

When the dialog's open attribute is removed which closes the dialog, we
should make the focus async in order to prevent more script from running
inside attribute removal.

Context: whatwg/html#10124 (comment)

Bug: 341935362
Change-Id: I1b76f003e04b802b1868b427a0faddf5f19a3c5e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6085725
Reviewed-by: Di Zhang <[email protected]>
Commit-Queue: Joey Arhar <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1402551}

--

wpt-commits: 58fd4f845204b88a3ae42b72b613a66e84cbb9f8
wpt-pr: 49929
sadym-chromium pushed a commit to web-platform-tests/wpt that referenced this pull request Jan 14, 2025
When the dialog's open attribute is removed which closes the dialog, we
should make the focus async in order to prevent more script from running
inside attribute removal.

Context: whatwg/html#10124 (comment)

Bug: 3419353
Change-Id: I1b76f003e04b802b1868b427a0faddf5f19a3c5e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6085725
Reviewed-by: Di Zhang <[email protected]>
Commit-Queue: Joey Arhar <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1402551}
gecko-dev-updater pushed a commit to marco-c/gecko-dev-wordified-and-comments-removed that referenced this pull request Jan 16, 2025
…en attribute, a=testonly

Automatic update from web-platform-tests
Make dialog focus async when removing open attribute

When the dialog's open attribute is removed which closes the dialog, we
should make the focus async in order to prevent more script from running
inside attribute removal.

Context: whatwg/html#10124 (comment)

Bug: 341935362
Change-Id: I1b76f003e04b802b1868b427a0faddf5f19a3c5e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6085725
Reviewed-by: Di Zhang <dizhanggchromium.org>
Commit-Queue: Joey Arhar <jarharchromium.org>
Cr-Commit-Position: refs/heads/main{#1402551}

--

wpt-commits: 58fd4f845204b88a3ae42b72b613a66e84cbb9f8
wpt-pr: 49929

UltraBlame original commit: 17e5e580ddfe60cd7d062ca9cbe0722342cc5638
gecko-dev-updater pushed a commit to marco-c/gecko-dev-comments-removed that referenced this pull request Jan 16, 2025
…en attribute, a=testonly

Automatic update from web-platform-tests
Make dialog focus async when removing open attribute

When the dialog's open attribute is removed which closes the dialog, we
should make the focus async in order to prevent more script from running
inside attribute removal.

Context: whatwg/html#10124 (comment)

Bug: 341935362
Change-Id: I1b76f003e04b802b1868b427a0faddf5f19a3c5e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6085725
Reviewed-by: Di Zhang <dizhanggchromium.org>
Commit-Queue: Joey Arhar <jarharchromium.org>
Cr-Commit-Position: refs/heads/main{#1402551}

--

wpt-commits: 58fd4f845204b88a3ae42b72b613a66e84cbb9f8
wpt-pr: 49929

UltraBlame original commit: 17e5e580ddfe60cd7d062ca9cbe0722342cc5638
gecko-dev-updater pushed a commit to marco-c/gecko-dev-wordified that referenced this pull request Jan 16, 2025
…en attribute, a=testonly

Automatic update from web-platform-tests
Make dialog focus async when removing open attribute

When the dialog's open attribute is removed which closes the dialog, we
should make the focus async in order to prevent more script from running
inside attribute removal.

Context: whatwg/html#10124 (comment)

Bug: 341935362
Change-Id: I1b76f003e04b802b1868b427a0faddf5f19a3c5e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6085725
Reviewed-by: Di Zhang <dizhanggchromium.org>
Commit-Queue: Joey Arhar <jarharchromium.org>
Cr-Commit-Position: refs/heads/main{#1402551}

--

wpt-commits: 58fd4f845204b88a3ae42b72b613a66e84cbb9f8
wpt-pr: 49929

UltraBlame original commit: 17e5e580ddfe60cd7d062ca9cbe0722342cc5638
@lukewarlow
Copy link
Member

lukewarlow commented Jan 27, 2025

Are there any updates on this change? It's possible that this is actually required by the spec (and definitely seems to be required by some tests) due to the recent closedby attribute additions.

Specifically the assertion on step 13 that the open dialogs list doesn't already contain this isn't always true without this change.

Edit: See #10953 and #10954 for a minimal attempt to fix this issue.

@josepharhar
Copy link
Contributor Author

From WHATNOT:

  • we should look at popover to decide whether to fire the synchronous beforetoggle event or not in this case (we probably shouldn't)
  • there might be some other focus fixup thing that changes the focused element when the open attribute is removed. it might be better to just not focus the previously focused element at all. would also be good to look at popover to see what it does

@josepharhar
Copy link
Contributor Author

Based on the last comment, I removed the focusing of the previous element completely in the case that the open attribute is removed.

As for toggle/beforetoggle events, I looked at removing the popover attribute from an open popover and I actually found that all browsers fire a beforetoggle event, and chrome fires both a beforetoggle and a toggle: https://codepen.io/jarhar/pen/VYwYjKb

Assuming that firing events during attribute removal is a bad thing, I still think that we should not fire beforetoggle events. I haven't made any changes to toggle events in this PR yet.

@lukewarlow
Copy link
Member

Slightly concerning that chrome behaves different to Firefox for those events on popover? I wonder which is correct per spec?

@mfreed7
Copy link
Contributor

mfreed7 commented Feb 14, 2025

Based on the last comment, I removed the focusing of the previous element completely in the case that the open attribute is removed.

Awesome, thanks!

For others, see some discussion starting at this comment. It sounds like the discussion is trending in this direction, but isn't quite concluded yet. Please chime in there if you have opinions.

Assuming that firing events during attribute removal is a bad thing, I still think that we should not fire beforetoggle events. I haven't made any changes to toggle events in this PR yet.

Can you clarify why firing events while changing attributes is a bad thing? This is materially different from removing elements from the tree, and I think it might be ok? E.g. we do this when changing the tabindex attribute today, for focus events. Or for the details element, removing the open attribute.

I added more cases to your test case, see here: https://jsbin.com/jayocud/edit?html,output

Results by engine:

Blink WebKit Gecko
popover beforetoggle (sync) fired fired fired
popover toggle (async) fired not fired not fired
details beforetoggle (sync) not fired not fired not fired
details toggle (async) fired fired fired
tabindex removal blur event (sync) fired fired fired

(I guess nobody has shipped details beforetoggle?) Anyway, since we do fire the async toggle event for <details> I don't see why we wouldn't fire it for popover also. And given the other sync and async events we're currently firing for the removal of other attributes, I don't see why it's an issue here. I think we should fire both toggle and beforetoggle for the removal of the popover attribute. And both events for the removal of the <dialog> open attribute, in the same way.

@keithamus
Copy link
Contributor

(I guess nobody has shipped details beforetoggle?)

beforetoggle on details hasn't been specced yet. Refs #9743.

@mfreed7
Copy link
Contributor

mfreed7 commented Feb 14, 2025

(I guess nobody has shipped details beforetoggle?)

beforetoggle on details hasn't been specced yet. Refs #9743.

Right. Thanks for the reminder and pointer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

Successfully merging this pull request may close these issues.

Dialog should be better-behaved on misuse, probably
8 participants