Skip to content

Fix dialog closedby and requestClose() #10954

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

Draft
wants to merge 12 commits into
base: main
Choose a base branch
from

Conversation

lukewarlow
Copy link
Member

@lukewarlow lukewarlow commented Jan 27, 2025

Update dialog to minimally handle open attribute mutations

We define two new algorithms for dialog:

  1. Dialog cleanup steps which:

    1. Removes dialog from the document's open dialogs list
    2. Destroy close watcher (if the dialog has no open attribute)
  2. Dialog setup steps which:

    1. Creates the dialog's close watcher.
    2. Adds dialog to the document's open dialogs list.

We also define attribute change steps and HTML element insertion steps for the dialog element.

We call dialog cleanup steps when:

a) An open dialog is removed from the document
b) A dialog has its open attribute removed

We call dialog setup steps when:

a) An open dialog is inserted into the document
b) A dialog has an open attribute added to it

This fixes spec issues that can lead to assertions being hit but also incorrect behaviour. This also fixes closedby not working as expected for initially open dialogs.

Fixes #10953 and #10982

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


/interactive-elements.html ( diff )

@lukewarlow lukewarlow marked this pull request as draft January 27, 2025 20:18
@lukewarlow lukewarlow force-pushed the remove-dialog-open-clear-list branch from b33a63f to 21886e7 Compare January 27, 2025 20:28
@lukewarlow lukewarlow changed the title Remove dialog from open dialogs list when open attribute removed Add attribute changed steps to dialog element Jan 27, 2025
@lukewarlow lukewarlow marked this pull request as ready for review January 27, 2025 20:31
@domenic
Copy link
Member

domenic commented Jan 28, 2025

This test would also pass if we removed the assert, i.e. fixed the regression introduced recently.

Marking "do not merge yet" until we get more clarity in #10953 as to what the right path forward is.

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.

Removing "do not merge yet" as I'm convinced by the arguments in #10953, but of course we still need to check all the boxes to merge.

For the tests box, could you point to more tests that enforce this behavior that aren't crash tests? Since assertions are actually comments; they don't cause crashes.

@domenic domenic added topic: dialog The <dialog> element and removed do not merge yet Pull request must not be merged per rationale in comment labels Jan 30, 2025
@lukewarlow
Copy link
Member Author

I've opened web-platform-tests/wpt#50393 which fails in a browser which follows the current spec:

  • I tested by locally modifiying chrome to use an ordered list for the open dialogs list, and removed the attribute changed set. In that build both the escape case and the click outside case result in the dialog being closed when it shouldn't be.

@lukewarlow lukewarlow force-pushed the remove-dialog-open-clear-list branch from 6cc5176 to 1eca429 Compare February 1, 2025 19:08
@lukewarlow
Copy link
Member Author

Have rebased with Keith's changes hopefully it's where its needed as of the new model.

I think this just needs Implementer interest. I believe whatwg needs someone appointed by the projects to provide a position, so me for WebKit and Keith for Firefox wouldn't be enough. (Cc @smaug---- and @annevk )

@lukewarlow
Copy link
Member Author

Per https://issues.chromium.org/issues/384549097 I've changed the new assertion within set the dialog close watcher to be an early return as it's possible that this scenario happens in legitimate cases (see the issue for more detail).

@lukewarlow lukewarlow force-pushed the remove-dialog-open-clear-list branch from 645374f to 376c837 Compare February 3, 2025 12:23
@mfreed7
Copy link
Contributor

mfreed7 commented Feb 7, 2025

FYI, see comments at #10953 (comment) and after.

source Outdated
@@ -62178,6 +62210,9 @@ interface <dfn interface>HTMLDialogElement</dfn> : <span>HTMLElement</span> {
element <var>dialog</var>:</p>

<ol>
<li><p>If <span>dialog</span>'s <span data-x="dialog-close-watcher">close watcher</span> is not
Copy link
Member Author

Choose a reason for hiding this comment

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

Need to work out if we actually still need this. It's in Chromium atm but based on other changes may no longer be needed (instead can be replaced with an assert)

@lukewarlow lukewarlow marked this pull request as ready for review February 12, 2025 12:31
@lukewarlow
Copy link
Member Author

This has been updated to account for changes per discussions at whatnot, above and in the Chromium CL.

TLDR we now handle adding the open attribute and removing it slightly more gracefully. This should fix various assertions being hit aswell as requestClose being broken.

I've left open dialogs list as a list in spec despite it being a set in Chromium, the various assertions should ensure this isn't an observable difference (happy to make that change if it's desired?).

@lukewarlow
Copy link
Member Author

Pending approval from a second implementor this should be ready to go (aside from editorial remarks).

Though it would be good for @mfreed7 to check my homework.

@mfreed7
Copy link
Contributor

mfreed7 commented Feb 13, 2025

Pending approval from a second implementor this should be ready to go (aside from editorial remarks).

Though it would be good for @mfreed7 to check my homework.

Thanks for updating this!

So as I'm working on the Chromium changes, I've got another CL going that (I think) better handles the additional case that a <dialog open> is removed and inserted into the document. The general idea would be to remove the dialog from the open dialogs list and kill its closewatcher when the dialog is removed from the doc, and vice versa. I'm still working on it, but I do think there might still be some cases that this PR doesn't cover. Perhaps let me get that CL into working shape and then I can come back here and reconcile it with this PR?

@lukewarlow
Copy link
Member Author

So as I'm working on the Chromium changes, I've got another CL going that (I think) better handles the additional case that a is removed and inserted into the document. The general idea would be to remove the dialog from the open dialogs list and kill its closewatcher when the dialog is removed from the doc, and vice versa. I'm still working on it, but I do think there might still be some cases that this PR doesn't cover. Perhaps let me get that CL into working shape and then I can come back here and reconcile it with this PR?

Feel free to give me a shout if you want to explain what you think I'm missing and I can probably work out the missing piece myself.

gecko-dev-updater pushed a commit to marco-c/gecko-dev-wordified that referenced this pull request Mar 1, 2025
…atcher when removed, a=testonly

Automatic update from web-platform-tests
Handle the open dialogs list and close watcher when removed

See more discussion here:

  whatwg/html#10954

In particular, this comment should summarize the end-state after this
CL lands:

  whatwg/html#10954 (comment)

Essentially, the spec says to remove a dialog from the open dialogs
list when the dialog is removed from the document:

https://html.spec.whatwg.org/multipage/interactive-elements.html#dom-dialog-requestclose:~:text=Remove%20removedNode%20from%20removedNode%27s%20node%20document%27s%20open%20dialogs%20list

But it does not say what to do when a dialog is inserted into the
document that has the `open` attribute, however. It also doesn't
correctly handle the distinction between connected and disconnected
dialogs. This CL adds insertion steps that re-add dialogs to the open
dialogs list, and re-create the close watcher. Plus tests. Lots of
tests.

Bug: 376516550
Change-Id: Ie70d63287e26c4e5f4a0a200205f78e914e6a220
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6259116
Reviewed-by: Joey Arhar <jarharchromium.org>
Commit-Queue: Joey Arhar <jarharchromium.org>
Auto-Submit: Mason Freed <masonfchromium.org>
Cr-Commit-Position: refs/heads/main{#1422181}

--

wpt-commits: 68c405e14856d3a9f9264adc8b3df6de42af3fe3
wpt-pr: 50813

UltraBlame original commit: 6c706603ebb5d32380772ecf94a07ea845636f88
gecko-dev-updater pushed a commit to marco-c/gecko-dev-comments-removed that referenced this pull request Mar 1, 2025
…atcher when removed, a=testonly

Automatic update from web-platform-tests
Handle the open dialogs list and close watcher when removed

See more discussion here:

  whatwg/html#10954

In particular, this comment should summarize the end-state after this
CL lands:

  whatwg/html#10954 (comment)

Essentially, the spec says to remove a dialog from the open dialogs
list when the dialog is removed from the document:

https://html.spec.whatwg.org/multipage/interactive-elements.html#dom-dialog-requestclose:~:text=Remove%20removedNode%20from%20removedNode%27s%20node%20document%27s%20open%20dialogs%20list

But it does not say what to do when a dialog is inserted into the
document that has the `open` attribute, however. It also doesn't
correctly handle the distinction between connected and disconnected
dialogs. This CL adds insertion steps that re-add dialogs to the open
dialogs list, and re-create the close watcher. Plus tests. Lots of
tests.

Bug: 376516550
Change-Id: Ie70d63287e26c4e5f4a0a200205f78e914e6a220
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6259116
Reviewed-by: Joey Arhar <jarharchromium.org>
Commit-Queue: Joey Arhar <jarharchromium.org>
Auto-Submit: Mason Freed <masonfchromium.org>
Cr-Commit-Position: refs/heads/main{#1422181}

--

wpt-commits: 68c405e14856d3a9f9264adc8b3df6de42af3fe3
wpt-pr: 50813

UltraBlame original commit: 6c706603ebb5d32380772ecf94a07ea845636f88
gecko-dev-updater pushed a commit to marco-c/gecko-dev-wordified-and-comments-removed that referenced this pull request Mar 1, 2025
…atcher when removed, a=testonly

Automatic update from web-platform-tests
Handle the open dialogs list and close watcher when removed

See more discussion here:

  whatwg/html#10954

In particular, this comment should summarize the end-state after this
CL lands:

  whatwg/html#10954 (comment)

Essentially, the spec says to remove a dialog from the open dialogs
list when the dialog is removed from the document:

https://html.spec.whatwg.org/multipage/interactive-elements.html#dom-dialog-requestclose:~:text=Remove%20removedNode%20from%20removedNode%27s%20node%20document%27s%20open%20dialogs%20list

But it does not say what to do when a dialog is inserted into the
document that has the `open` attribute, however. It also doesn't
correctly handle the distinction between connected and disconnected
dialogs. This CL adds insertion steps that re-add dialogs to the open
dialogs list, and re-create the close watcher. Plus tests. Lots of
tests.

Bug: 376516550
Change-Id: Ie70d63287e26c4e5f4a0a200205f78e914e6a220
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6259116
Reviewed-by: Joey Arhar <jarharchromium.org>
Commit-Queue: Joey Arhar <jarharchromium.org>
Auto-Submit: Mason Freed <masonfchromium.org>
Cr-Commit-Position: refs/heads/main{#1422181}

--

wpt-commits: 68c405e14856d3a9f9264adc8b3df6de42af3fe3
wpt-pr: 50813

UltraBlame original commit: 6c706603ebb5d32380772ecf94a07ea845636f88
jamienicol pushed a commit to jamienicol/gecko that referenced this pull request Mar 5, 2025
…atcher when removed, a=testonly

Automatic update from web-platform-tests
Handle the open dialogs list and close watcher when removed

See more discussion here:

  whatwg/html#10954

In particular, this comment should summarize the end-state after this
CL lands:

  whatwg/html#10954 (comment)

Essentially, the spec says to remove a dialog from the open dialogs
list when the dialog is removed from the document:

https://html.spec.whatwg.org/multipage/interactive-elements.html#dom-dialog-requestclose:~:text=Remove%20removedNode%20from%20removedNode%27s%20node%20document%27s%20open%20dialogs%20list

But it does not say what to do when a dialog is inserted into the
document that has the `open` attribute, however. It also doesn't
correctly handle the distinction between connected and disconnected
dialogs. This CL adds insertion steps that re-add dialogs to the open
dialogs list, and re-create the close watcher. Plus tests. Lots of
tests.

Bug: 376516550
Change-Id: Ie70d63287e26c4e5f4a0a200205f78e914e6a220
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6259116
Reviewed-by: Joey Arhar <jarhar@chromium.org>
Commit-Queue: Joey Arhar <jarhar@chromium.org>
Auto-Submit: Mason Freed <masonf@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1422181}

--

wpt-commits: 68c405e14856d3a9f9264adc8b3df6de42af3fe3
wpt-pr: 50813
@annevk
Copy link
Member

annevk commented Mar 7, 2025

@mfreed7 said that if this PR landed first #10657 would need changes, but that PR landed first. So this PR will have to account for that.

When the dialogs open attribute is removed:

1. Remove dialog from the document's open dialogs list.
2. Destroy and nullify dialog's close watcher

This also adds an assertion to the start of
'set the dialog close watcher' that dialog's close watcher is null.
@lukewarlow
Copy link
Member Author

I just looked into this and I think we don't actually need any changes here. This is because of a difference in spec layout vs chromium impl. In chrome the RemovedFrom and InsertedInto methods are invoked and the then there's early returns for state preserving atomic move operations. However, the spec went a different approach and defined separate moving steps.

Because we don't have moving steps defined for dialog, nothing happens to it which is expected.

@mfreed7 @domfarolino does this make sense to you or am I missing something?

@lukewarlow lukewarlow force-pushed the remove-dialog-open-clear-list branch from be43034 to b5cc2c5 Compare March 7, 2025 15:53
@mfreed7
Copy link
Contributor

mfreed7 commented Mar 7, 2025

I just looked into this and I think we don't actually need any changes here. This is because of a difference in spec layout vs chromium impl. In chrome the RemovedFrom and InsertedInto methods are invoked and the then there's early returns for state preserving atomic move operations. However, the spec went a different approach and defined separate moving steps.

Because we don't have moving steps defined for dialog, nothing happens to it which is expected.

That sounds right to me. I just wanted to highlight it since I did have to handle this case in code, and assumed it would therefore have spec impact. I'm not the moveBefore expert, so I'll defer to @domfarolino. But fingers crossed that nothing needs to change here.

glandium pushed a commit to mozilla-firefox/firefox that referenced this pull request Apr 1, 2025
…atcher when removed, a=testonly

Automatic update from web-platform-tests
Handle the open dialogs list and close watcher when removed

See more discussion here:

  whatwg/html#10954

In particular, this comment should summarize the end-state after this
CL lands:

  whatwg/html#10954 (comment)

Essentially, the spec says to remove a dialog from the open dialogs
list when the dialog is removed from the document:

https://html.spec.whatwg.org/multipage/interactive-elements.html#dom-dialog-requestclose:~:text=Remove%20removedNode%20from%20removedNode%27s%20node%20document%27s%20open%20dialogs%20list

But it does not say what to do when a dialog is inserted into the
document that has the `open` attribute, however. It also doesn't
correctly handle the distinction between connected and disconnected
dialogs. This CL adds insertion steps that re-add dialogs to the open
dialogs list, and re-create the close watcher. Plus tests. Lots of
tests.

Bug: 376516550
Change-Id: Ie70d63287e26c4e5f4a0a200205f78e914e6a220
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6259116
Reviewed-by: Joey Arhar <jarhar@chromium.org>
Commit-Queue: Joey Arhar <jarhar@chromium.org>
Auto-Submit: Mason Freed <masonf@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1422181}

--

wpt-commits: 68c405e14856d3a9f9264adc8b3df6de42af3fe3
wpt-pr: 50813
@lukewarlow lukewarlow marked this pull request as draft April 15, 2025 19:16
@lukewarlow lukewarlow changed the title Update dialog to minimally handle open attribute mutations Fix dialog closedby and requestClose() Apr 17, 2025
Dialog setup steps:

- Move set the dialog close watcher to step 1
- Add early return when dialog is not connected as a new step 2 (before adding to dialog light dismiss list).

Dialog cleanup steps:

- Remove assertion
- Remove disposing of close watcher.

Dialog attribute change steps:

- Remove connected check from steps 3 and 4.

Dialog insertion steps:

- Remove connected check added in previous commit.
@lukewarlow lukewarlow force-pushed the remove-dialog-open-clear-list branch from 4ff2d61 to 90282be Compare April 17, 2025 10:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
topic: dialog The <dialog> element
Development

Successfully merging this pull request may close these issues.

Missing attribute changed steps for dialog can cause assertions to be hit
5 participants