@josepharhar noticed that for <dialog>
, dialogEl.close()
does not trigger the cancel
event. Only a proper user-driven close signal will trigger a cancel
event.
I tend to think the CloseWatcher
design is more useful for developers: if you have code like
dialog.oncancel = e => {
if (userHasUnsavedData) {
e.preventDefault();
}
};
dialog.querySelector(".close-button").onclick = () => dialog.close();
you probably would be surprised that clicking .close-button
skips your unsaved-data check in the cancel
event, and instead goes straight to the close
event. You're forced to duplicate the unsaved-data check inside the onclick
handler, which is silly.
However, symmetry between <dialog>
and CloseWatcher
is very important, to avoid web developer confusion. That's why we're using the close
/cancel
event names in the first place.
My proposal is that we provide both behaviors:
-
closeWatcher.close()
behaves like dialog.close()
, and goes straight to the close
event.
-
closeWatcher.bikeshed()
behaves as if a close signal has been sent, doing both cancel
+ close
.
Naming for the cancel
+ close
variant remains the tricky problem. I like signalClose()
(meaning "send the close signal as if the user did"), but per #13 @annevk and @smaug---- did not. Some options:
cancelAndClose()
close({ withCancel: true })
- Rename the whole "close signals" concept to something like "close command" or "close triggers", and then go with
closeCommand()
or triggerClose()
or something like that.
- Come up with some verb that is meant to indicate "the whole process of closing, which might possibly be canceled": e.g.
exit()
, shutdown()
.
The first two options seem nice and straightforward, but they have the minor drawback of making the cancel
-and-close
version more verbose, and demoting it to feeling second-class. (Whereas, per my above reasoning, I think it's actually the more likely behavior.) The latter two options are trickier but maybe worthwhile?
We can also consider porting whatever we come up with here to <dialog>
.