From 4edb90f44b95794d337ee0f6861c151e29640524 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9ry=20Debongnie?= Date: Wed, 4 Sep 2019 13:41:05 +0200 Subject: [PATCH] [FIX] router: properly handle popstate It was not correct, the url was changed multiple times and back navigation was broken. Also, note that there are no tests because the history api is not available in jsdom. --- src/router/Router.ts | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/router/Router.ts b/src/router/Router.ts index e774341a..9d45025e 100644 --- a/src/router/Router.ts +++ b/src/router/Router.ts @@ -95,7 +95,7 @@ export class Router { //-------------------------------------------------------------------------- async start() { - (this as any)._listener = () => this._navigate(this.currentPath()); + (this as any)._listener = ev => this._navigate(this.currentPath(), ev); window.addEventListener("popstate", (this as any)._listener); if (this.mode === "hash") { window.addEventListener("hashchange", (this as any)._listener); @@ -115,13 +115,16 @@ export class Router { const path = this.destToPath(to); return this._navigate(path); } - async _navigate(path: string): Promise { + async _navigate(path: string, ev?: any): Promise { const initialName = this.currentRouteName; const initialParams = this.currentParams; const result = await this.matchAndApplyRules(path); if (result.type === "match") { const finalPath = this.routeToPath(result.route, result.params); - this.setUrlFromPath(finalPath); + const isPopStateEvent = ev && ev instanceof PopStateEvent; + if (!isPopStateEvent) { + this.setUrlFromPath(finalPath); + } this.currentRoute = result.route; this.currentParams = result.params; } else if (result.type === "nomatch") { @@ -151,8 +154,11 @@ export class Router { //-------------------------------------------------------------------------- private setUrlFromPath(path: string) { - const url = location.origin + path; - window.history.pushState({}, path, url); + const separator = this.mode === "hash" ? "/" : ""; + const url = location.origin + separator + path; + if (url !== window.location.href) { + window.history.pushState({}, path, url); + } } private validateDestination(dest: Destination) {