Skip to content

Commit

Permalink
handle history mode fallback
Browse files Browse the repository at this point in the history
  • Loading branch information
yyx990803 committed Jul 23, 2016
1 parent 67e8cd8 commit 0112408
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 30 deletions.
23 changes: 21 additions & 2 deletions src/history/base.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
/* @flow */

import type VueRouter from '../index'
import { inBrowser } from '../util/dom'
import { runQueue } from '../util/async'
import { isSameRoute } from '../util/route'

export class History {
router: VueRouter;
base: ?string;
base: string;
current: Route;
pending: ?Route;
beforeHooks: Array<Function>;
Expand All @@ -15,7 +16,7 @@ export class History {

constructor (router: VueRouter, base: ?string) {
this.router = router
this.base = base
this.base = normalizeBae(base)
this.current = router.match(this.getLocation())
this.pending = null
this.beforeHooks = []
Expand Down Expand Up @@ -101,6 +102,24 @@ export class History {
}
}

function normalizeBae (base: ?string): string {
if (!base) {
if (inBrowser) {
// respect <base> tag
const baseEl = document.querySelector('base')
base = baseEl ? baseEl.getAttribute('href') : '/'
} else {
base = '/'
}
}
// make sure there's the starting slash
if (base.charAt(0) !== '/') {
base = '/' + base
}
// remove trailing slash
return base.replace(/\/$/, '')
}

function resolveQueue (
current: Array<RouteRecord>,
next: Array<RouteRecord>
Expand Down
20 changes: 18 additions & 2 deletions src/history/hash.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,16 @@

import type VueRouter from '../index'
import { History } from './base'
import { getLocation } from './html5'
import { cleanPath } from '../util/path'

export class HashHistory extends History {
constructor (router: VueRouter) {
super(router)
constructor (router: VueRouter, base: ?string, fallback: boolean) {
super(router, base)
// check history fallback deeplinking
if (fallback && this.checkFallback()) {
return
}
ensureSlash()
// possible redirect on start
if (getHash() !== this.current.fullPath) {
Expand All @@ -16,6 +22,16 @@ export class HashHistory extends History {
})
}

checkFallback () {
const location = getLocation(this.base)
if (!/^\/#/.test(location)) {
window.location.replace(
cleanPath(this.base + '/#' + location)
)
return true
}
}

onHashChange () {
if (!ensureSlash()) {
return
Expand Down
32 changes: 8 additions & 24 deletions src/history/html5.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
/* @flow */

import type VueRouter from '../index'
import { inBrowser } from '../util/dom'
import { cleanPath } from '../util/path'
import { History } from './base'

const genKey = () => String(Date.now())
let _key: string = genKey()

export class HTML5History extends History {
constructor (router: VueRouter, base: ?string) {
super(router, normalizeBae(base))
constructor (router: VueRouter) {
super(router)

// possible redirect on start
if (this.getLocation() !== this.current.fullPath) {
Expand Down Expand Up @@ -54,12 +53,7 @@ export class HTML5History extends History {
}

getLocation (): string {
const base = this.base
let path = window.location.pathname
if (base && path.indexOf(base) === 0) {
path = path.slice(base.length)
}
return path + window.location.search + window.location.hash
return getLocation(this.base)
}

handleScroll (from: Route, to: Route) {
Expand Down Expand Up @@ -95,22 +89,12 @@ export class HTML5History extends History {
}
}

function normalizeBae (base: ?string): string {
if (!base) {
if (inBrowser) {
// respect <base> tag
const baseEl = document.querySelector('base')
base = baseEl ? baseEl.getAttribute('href') : '/'
} else {
base = '/'
}
}
// make sure there's the starting slash
if (base.charAt(0) !== '/') {
base = '/' + base
export function getLocation (base: string): string {
let path = window.location.pathname
if (base && path.indexOf(base) === 0) {
path = path.slice(base.length)
}
// remove trailing slash
return base.replace(/\/$/, '')
return path + window.location.search + window.location.hash
}

function pushState (url: string, replace?: boolean) {
Expand Down
5 changes: 3 additions & 2 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ export default class VueRouter {
this.match = createMatcher(options.routes || [])

let mode = options.mode || 'hash'
if (mode === 'history' && !supportsHistory) {
let fallback = mode === 'history' && !supportsHistory
if (fallback) {
mode = 'hash'
}
if (!inBrowser) {
Expand All @@ -35,7 +36,7 @@ export default class VueRouter {
this.history = new HTML5History(this, options.base)
break
case 'hash':
this.history = new HashHistory(this)
this.history = new HashHistory(this, options.base, fallback)
break
case 'abstract':
this.history = new AbstractHistory(this)
Expand Down

0 comments on commit 0112408

Please sign in to comment.