Skip to content

Commit b687427

Browse files
authored
refactor: use close event to prevent client-side dialog from closing (#7871)
1 parent 612fac0 commit b687427

File tree

1 file changed

+22
-15
lines changed
  • vaadin-dialog-flow-parent/vaadin-dialog-flow/src/main/java/com/vaadin/flow/component/dialog

1 file changed

+22
-15
lines changed

vaadin-dialog-flow-parent/vaadin-dialog-flow/src/main/java/com/vaadin/flow/component/dialog/Dialog.java

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -890,10 +890,9 @@ public void setVisible(boolean visible) {
890890
}
891891

892892
/**
893-
* Registers event listeners on the dialog's overlay that prevent it from
894-
* closing itself on outside click and escape press. Instead, the event
895-
* listeners delegate to the server-side {@link #handleClientClose()}
896-
* method. This serves two purposes:
893+
* Registers a close listener for the dialog's overlay to prevent it from
894+
* closing itself. Instead, the event listener delegates to the server-side
895+
* {@link #handleClientClose()} method. This serves two purposes:
897896
* <ul>
898897
* <li>Prevent the client dialog from closing if a custom close action
899898
* listener is registered</li>
@@ -903,17 +902,25 @@ public void setVisible(boolean visible) {
903902
* </ul>
904903
*/
905904
private void registerClientCloseHandler() {
906-
//@formatter:off
907-
getElement().executeJs("const listener = (e) => {"
908-
+ " if (e.type == 'vaadin-overlay-escape-press' && !this.noCloseOnEsc ||"
909-
+ " e.type == 'vaadin-overlay-outside-click' && !this.noCloseOnOutsideClick) {"
910-
+ " e.preventDefault();"
911-
+ " this.$server.handleClientClose();"
912-
+ " }"
913-
+ "};"
914-
+ "this.$.overlay.addEventListener('vaadin-overlay-outside-click', listener);"
915-
+ "this.$.overlay.addEventListener('vaadin-overlay-escape-press', listener);");
916-
//@formatter:on
905+
// The web component dispatches the close event first on its overlay and
906+
// then globally on the document. To allow other tools, such as Copilot,
907+
// to prevent closing overlays through a global listener, we first
908+
// listen for the close event on the overlay, and then add a one-time
909+
// listener on the document. Only if the event was not prevented after
910+
// being dispatched on the document, we prevent it ourselves and
911+
// delegate closing to the server-side. Do not register the listener on
912+
// the document directly, as that would leak memory.
913+
getElement().executeJs(
914+
"""
915+
this.$.overlay.addEventListener('vaadin-overlay-close', () => {
916+
document.addEventListener('vaadin-overlay-close', (e) => {
917+
if (!e.defaultPrevented && e.detail.overlay === this.$.overlay) {
918+
e.preventDefault();
919+
this.$server.handleClientClose();
920+
}
921+
}, { once: true });
922+
});
923+
""");
917924
}
918925

919926
@ClientCallable

0 commit comments

Comments
 (0)