Skip to content

When unload confirmation dialog set, always disconnects from room no matter if unload is cancelled #71

@WebCoder49

Description

@WebCoder49

Checklist

Describe the bug
When the following JavaScript is used (not on WebKit (e.g. GNOME Web, Safari) - there it doesn't work) to display a confirmation dialog letting the user proceed with or cancel the unload (e.g. saying "This page is asking you to confirm that you want to leave — information you’ve entered may not be saved." in Firefox)...

window.addEventListener("beforeunload", function(evt) {
    evt.returnValue = true;
    evt.preventDefault();
});
// or set the beforeunload property to a function returning true

...y-webrtc deletes the current user from the awareness states and disconnects from the room before the dialog appears, and thus whether or not the user goes ahead with the unload. This code likely needs to be changed:

y-webrtc/src/y-webrtc.js

Lines 367 to 375 in c411f1d

this._beforeUnloadHandler = () => {
awarenessProtocol.removeAwarenessStates(this.awareness, [doc.clientID], 'window unload')
rooms.forEach(room => {
room.disconnect()
})
}
if (typeof window !== 'undefined') {
window.addEventListener('beforeunload', this._beforeUnloadHandler)

To Reproduce
Steps to reproduce the behavior:

  1. Use a project with y-webrtc, e.g. the one in the docs, or my project pre-workaround (it makes the users present clear but is much more complicated; run with yarn run dev).
  2. Add this to the JavaScript:
    window.addEventListener("beforeunload", function(evt) {
        evt.returnValue = true;
        evt.preventDefault();
    });
  3. Try to reload / click the back button.
  4. See the page unload confirmation dialog.
  5. Cancel the confirmation dialog.
  6. See that edits no longer sync, and if awareness is visible the client has been deleted from it.

Expected behavior
This disconnection occurs after the confirmation dialog has been closed, and only if unloading has not been cancelled.

Screenshots
Not necessary

Environment Information

  • Browser / Node.js: Firefox 140.0.2 and Chromium 140.0.7339.80
  • Yjs version and the versions of the y-* modules you are using: yjs v13.6.27, y-webrtc v10.3.0

Additional context

  • The following code is a hacky workaround which completely cancels auto-session-closure and leaves a several-second wait until peers remove the closed client from awareness due to timeout: not ideal, but avoids this bug:
    // HACK: Depends on the private API of y-webrtc which may change in any patch version!
    // Don't close session when leave page since confirmation to leave
    // may have been cancelled
    provider.key.then(() => {
        window.removeEventListener("beforeunload", provider.room._beforeUnloadHandler);
    });
  • Moving the handler to the unload event rather than beforeunload doesn't work for me on Firefox (gives the same effect as if the handler was just removed as in the workaround above); the unload event is deprecated anyway.
  • Perhaps the fix could make immediate removal-from-awareness also be supported on WebKit (e.g. GNOME Web, Safari), which it isn't now because WebKit doesn't support the beforeunload event
  • I'm a sponsor 💖
  • This issue is a blocker for my project.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions