-
-
Notifications
You must be signed in to change notification settings - Fork 14
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
Support back button blocking #14
Comments
Hm, yes, I don't think there's a good way to do this now. I wonder what kind of APIs do other routing libs have for this. As a workaround, you could try to hack into div(
child <-- SplitRender(router.currentPageSignal)....
) You could try replacing {
var maybeLastPage: Option[Page] = None
router.currentPageSignal.map { nextPage =>
val actualNextPage = if (okToExit) nextPage else {
val prevPage = maybeLastPage.get
js.setTimeout(0){ router.pushState(prevPage) } // pretend that the user didn't press the back button - keeps the router's internal state consistent with this hack.
prevPage
}
maybeLastPage = Some(nextPage)
actualNextPage
}
} Basically, we can't prevent the popState event, so we will prevent the propagation of that event into the rendering stage, sort of. This is incredibly hacky so I don't know how well it will work (e.g. you might want to filter out redundant events), but I don't think there is another way. onBeforeOnload will not be called unless you do a full page refresh, and the whole point of frontend routers like Waypoint is to avoid such refreshes. |
Thanks for your suggestion, I can see that there is no way to prevent the popState event. Last time I tried something similar to this, but the problem with router.pushState is it will mess up the browser history when the user hits forward instead of back (popState fires for forward as well). I think if we can't prevent the popState event no matter what, can you support a function to undo the popState event when we call it manually? I mean something to replace router.pushState in your above code but still keep the browser history instead of pushing another state. |
Indeed, this kind of hack can break the forward button, especially in more complex navigation sequences. To fix this properly, I think we'd need to implement something like this. I haven't looked at it in detail yet. I think it's something along the lines of undoing the undesirable navigation post-factum. The trick is, to undo it, you need to know whether to issue a history.back() or history.forward() command, and for that, you need to know whether the user pressed the back button (in which case you need to call history.forward to undo it) or did some other kind of navigation (in which case you need to call history.back to undo it), and for that you need to add sequential indexes to page state sent to the history API. And, all of that would need to happen in the router, prior to these shenanigans being exposed to the rendering logic. Ok I know the above is a rather incomprehensible word salad, it's mostly a hint for myself about where to pick up when I eventually get to this. |
Thanks! I am awaiting for this. |
Hi, I am using Waypoint, and my use case requires the browser shows up a warning message when the user navigates out of page. Normally, I would do it like this:
dom.windowEvents.onBeforeUnload.map(_.returnValue = "") --> Observer.empty
However, it does not work when I go back after calling Waypoint router pushState. This is because Waypoint does not unload dom elements, so onBeforeUnload does not trigger. I attempted to tweak popStateEvent, however, it was kinda tricky because when onPopState triggers, the browser history has already changed, so I have to manually undo the pop state when the user decides not to leave page.
Could you please consider some support for this use case?
The text was updated successfully, but these errors were encountered: