Skip to content

Commit

Permalink
fix: preserve history state when reloading
Browse files Browse the repository at this point in the history
  • Loading branch information
posva committed Feb 26, 2020
1 parent 8fdd9c5 commit a4ec3e2
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 3 deletions.
1 change: 1 addition & 0 deletions examples/basic/app.js
Expand Up @@ -48,6 +48,7 @@ new Vue({
<a :href="props.href" @click="props.navigate">{{ props.route.path }} (with v-slot).</a>
</li>
</router-link>
<li><router-link to="/foo" replace>/foo (replace)</router-link></li>
</ul>
<button id="navigate-btn" @click="navigateAndIncrement">On Success</button>
<pre id="counter">{{ n }}</pre>
Expand Down
6 changes: 5 additions & 1 deletion src/util/scroll.js
Expand Up @@ -3,6 +3,7 @@
import type Router from '../index'
import { assert } from './warn'
import { getStateKey, setStateKey } from './state-key'
import { extend } from './misc'

const positionStore = Object.create(null)

Expand All @@ -14,7 +15,10 @@ export function setupScroll () {
// location.host contains the port and location.hostname doesn't
const protocolAndPath = window.location.protocol + '//' + window.location.host
const absolutePath = window.location.href.replace(protocolAndPath, '')
window.history.replaceState({ key: getStateKey() }, '', absolutePath)
// preserve existing history state as it could be overriden by the user
const stateCopy = extend({}, window.history.state)
stateCopy.key = getStateKey()
window.history.replaceState(stateCopy, '', absolutePath)
window.addEventListener('popstate', e => {
saveScrollPosition()
if (e.state && e.state.key) {
Expand Down
4 changes: 2 additions & 2 deletions test/e2e/specs/basic.js
Expand Up @@ -9,8 +9,8 @@ module.exports = {
browser
.url('http://localhost:8080/basic/')
.waitForElementVisible('#app', 1000)
.assert.count('li', 8)
.assert.count('li a', 8)
.assert.count('li', 9)
.assert.count('li a', 9)
// assert correct href with base
.assert.attributeContains('li:nth-child(1) a', 'href', '/basic/')
.assert.attributeContains('li:nth-child(2) a', 'href', '/basic/foo')
Expand Down
56 changes: 56 additions & 0 deletions test/e2e/specs/history-state.js
@@ -0,0 +1,56 @@
const bsStatus = require('../browserstack-send-status')

module.exports = {
...bsStatus(),

'@tags': ['history'],

'history state': function (browser) {
browser
.url('http://localhost:8080/scroll-behavior/')
.waitForElementVisible('#app', 1000)

.execute(function () {
window.scrollTo(0, 100)
const key = window.history.state.key
window.history.replaceState({ key, foo: 'foo' }, '', window.location.pathname)
})
.url('http://localhost:8080/scroll-behavior/')
.waitForElementVisible('#app', 1000)
.assert.evaluate(function () {
return window.history.state.foo === 'foo'
}, null, 'keeps existing state when reloading')

// check on navigation
.url('http://localhost:8080/basic/')
.click('li:nth-child(2) a')
.assert.urlEquals('http://localhost:8080/basic/foo')
.execute(function () {
window.scrollTo(0, 100)
const key = window.history.state.key
window.history.replaceState({ key, foo: 'foo' }, '', window.location.pathname)
})
.click('li:nth-child(3) a')
.assert.urlEquals('http://localhost:8080/basic/bar')
.execute(function () {
window.history.back()
})
.assert.evaluate(function () {
return window.history.state.foo === 'foo'
}, null, 'keeps existing state when navigating back')
.click('li:nth-child(3) a')
.assert.urlEquals('http://localhost:8080/basic/bar')
.execute(function () {
window.scrollTo(0, 100)
const key = window.history.state.key
window.history.replaceState({ key, bar: 'bar' }, '', window.location.pathname)
})
.click('li:nth-child(9) a')
.assert.urlEquals('http://localhost:8080/basic/foo')
.assert.evaluate(function () {
return window.history.state.bar === 'bar'
}, null, 'keeps existing state when replacing')

.end()
}
}

0 comments on commit a4ec3e2

Please sign in to comment.