From b7715dcfbfa081cb81daa90f4063e93e5047b169 Mon Sep 17 00:00:00 2001 From: Eduardo San Martin Morote Date: Tue, 16 Jul 2019 19:39:49 +0200 Subject: [PATCH] fix(hash): correctly place query if placed before hash (#2851) Fixes #2125 Closes #2262 --- src/history/hash.js | 81 ++++++++++++++++++++++--------------- test/e2e/specs/hash-mode.js | 12 ++++++ 2 files changed, 61 insertions(+), 32 deletions(-) diff --git a/src/history/hash.js b/src/history/hash.js index 16c94db0e..210fae6a2 100644 --- a/src/history/hash.js +++ b/src/history/hash.js @@ -28,38 +28,49 @@ export class HashHistory extends History { setupScroll() } - window.addEventListener(supportsPushState ? 'popstate' : 'hashchange', () => { - const current = this.current - if (!ensureSlash()) { - return - } - this.transitionTo(getHash(), route => { - if (supportsScroll) { - handleScroll(this.router, route, current, true) - } - if (!supportsPushState) { - replaceHash(route.fullPath) + window.addEventListener( + supportsPushState ? 'popstate' : 'hashchange', + () => { + const current = this.current + if (!ensureSlash()) { + return } - }) - }) + this.transitionTo(getHash(), route => { + if (supportsScroll) { + handleScroll(this.router, route, current, true) + } + if (!supportsPushState) { + replaceHash(route.fullPath) + } + }) + } + ) } push (location: RawLocation, onComplete?: Function, onAbort?: Function) { const { current: fromRoute } = this - this.transitionTo(location, route => { - pushHash(route.fullPath) - handleScroll(this.router, route, fromRoute, false) - onComplete && onComplete(route) - }, onAbort) + this.transitionTo( + location, + route => { + pushHash(route.fullPath) + handleScroll(this.router, route, fromRoute, false) + onComplete && onComplete(route) + }, + onAbort + ) } replace (location: RawLocation, onComplete?: Function, onAbort?: Function) { const { current: fromRoute } = this - this.transitionTo(location, route => { - replaceHash(route.fullPath) - handleScroll(this.router, route, fromRoute, false) - onComplete && onComplete(route) - }, onAbort) + this.transitionTo( + location, + route => { + replaceHash(route.fullPath) + handleScroll(this.router, route, fromRoute, false) + onComplete && onComplete(route) + }, + onAbort + ) } go (n: number) { @@ -81,9 +92,7 @@ export class HashHistory extends History { function checkFallback (base) { const location = getLocation(base) if (!/^\/#/.test(location)) { - window.location.replace( - cleanPath(base + '/#' + location) - ) + window.location.replace(cleanPath(base + '/#' + location)) return true } } @@ -112,10 +121,13 @@ export function getHash (): string { const searchIndex = href.indexOf('?') if (searchIndex < 0) { const hashIndex = href.indexOf('#') - if (hashIndex > -1) href = decodeURI(href.slice(0, hashIndex)) + href.slice(hashIndex) - else href = decodeURI(href) + if (hashIndex > -1) { + href = decodeURI(href.slice(0, hashIndex)) + href.slice(hashIndex) + } else href = decodeURI(href) } else { - if (searchIndex > -1) href = decodeURI(href.slice(0, searchIndex)) + href.slice(searchIndex) + if (searchIndex > -1) { + href = decodeURI(href.slice(0, searchIndex)) + href.slice(searchIndex) + } } return href @@ -123,9 +135,14 @@ export function getHash (): string { function getUrl (path) { const href = window.location.href - const i = href.indexOf('#') - const base = i >= 0 ? href.slice(0, i) : href - return `${base}#${path}` + const hashPos = href.indexOf('#') + let base = hashPos > -1 ? href.slice(0, hashPos) : href + + const searchPos = base.indexOf('?') + const query = searchPos > -1 ? base.slice(searchPos) : '' + base = query ? base.slice(0, searchPos) : base + + return `${base}#${path + query}` } function pushHash (path) { diff --git a/test/e2e/specs/hash-mode.js b/test/e2e/specs/hash-mode.js index be5df7d14..6ca546214 100644 --- a/test/e2e/specs/hash-mode.js +++ b/test/e2e/specs/hash-mode.js @@ -57,6 +57,18 @@ module.exports = { .waitForElementVisible('#app', 1000) .assert.containsText('.view', 'unicode: ñ') .assert.containsText('#query-t', '%') + + // correctly placing query + // https://github.com/vuejs/vue-router/issues/2125 + .url('http://localhost:8080/hash-mode/?key=foo') + .waitForElementVisible('#app', 1000) + .assert.urlEquals('http://localhost:8080/hash-mode/#/?key=foo') + .url('http://localhost:8080/hash-mode?key=foo') + .waitForElementVisible('#app', 1000) + .assert.urlEquals('http://localhost:8080/hash-mode/#/?key=foo') + .url('http://localhost:8080/hash-mode?key=foo#other') + .waitForElementVisible('#app', 1000) + .assert.urlEquals('http://localhost:8080/hash-mode/#/other?key=foo') .end() } }