HashHistory
class HashHistory extends History{
constructor(router,base,fallback){
super(router,base)
if(fallback && checkFallBack(this.base)){
return
}
ensureSlash()
}
setupListeners(){
if(this.listeners.length > 0){
return
}
const router = this.router
const expectScroll = router.options.scrollBehavior
const supportsScroll = supportsPushState && expectScroll
if(supportsScroll){
this.listeners.push(setupScroll())
}
const handleRoutingEvent = () => {
const current = this.current
if(!ensureSlash()){
return
}
this.transitionTo(getHash(),route => {
if(supportsScroll){
handleScroll(this.router,route,current,true)
}
if(!supportsPushState){
replaceHash(route.fullPath)
}
})
}
const eventType = supportsPushState ? 'popstate' : 'hashchange'
window.addEventListener(eventType,handleRoutingEvent)
this.listeners.push(() => {
window.removeEventListener(eventType,handleRoutingEvent)
})
}
push(location,onComplete,onAbort){
const { current: fromRoute} = this
this.transitionTo(location,route => {
pushHash(route.fullPath)
handleScroll(this.router,route,fromRoute,false)
onComplete && onComplete(route)
},onAbort)
}
replace(location,onComplete,onAbort){
const { current: fromRoute } = this
this.transitionTo(location,route => {
replaceHash(route.fullPath)
handleScroll(this.router,route,fromRoute,false)
onComplete && onComplete(route)
},onAbort)
}
go(n){
window.history.go(n)
}
ensureURL(push){
const current = this.current.fullPath
if(getHash() !== current)
push ? pushHahs(current) : replaceHash(current)
}
getCurrentLocation(){
return getHash()
}
}
checkFallBack
function checkFallBack(base){
const location = getLocation(base)
if(!/^\/#/.test(location)){
window.location.replace(cleanPath(base + '/#' + location))
return true
}
}
ensureSlash
function ensureSlash(){
const path = getHash()
if(path.charAt(0) === '/'){
return true
}
replaceHash('/'+hash)
return false
}
getHash
function getHash(){
let href = window.location.href
const index = href.indexOf('#')
if(index < 0) return ''
href = href.slice(index + 1)
return href
}
replaceHash
function replaceHash(path){
if(supportsPushState){
replaceState(path)
}else{
window.location.replace(getUrl(path))
}
}
getUrl
function getUrl(path){
const href = window.location.href
const i = href.indexOf('#')
const base = i >= 0 ? href.slice(0,i) : href
return `${base}#${path}`
}
pushHash
function pushHash(path){
if(supportsPushState){
pushState(getUrl(path))
}else{
window.location.hash = hash
}
}