feat: support history mode
This commit is contained in:
parent
8741c746df
commit
f095eb888f
4 changed files with 92 additions and 20 deletions
|
|
@ -14,7 +14,7 @@ export class Compiler {
|
||||||
this.cacheTree = {}
|
this.cacheTree = {}
|
||||||
this.toc = []
|
this.toc = []
|
||||||
this.linkTarget = config.externalLinkTarget || '_blank'
|
this.linkTarget = config.externalLinkTarget || '_blank'
|
||||||
this.contentBase = getBasePath(config.base)
|
this.contentBase = getBasePath(config.basePath)
|
||||||
|
|
||||||
const renderer = this._initRenderer()
|
const renderer = this._initRenderer()
|
||||||
let compile
|
let compile
|
||||||
|
|
@ -44,7 +44,7 @@ export class Compiler {
|
||||||
|
|
||||||
_initRenderer () {
|
_initRenderer () {
|
||||||
const renderer = new marked.Renderer()
|
const renderer = new marked.Renderer()
|
||||||
const { linkTarget, router, toc } = this
|
const { linkTarget, router, toc, contentBase } = this
|
||||||
/**
|
/**
|
||||||
* render anchor tag
|
* render anchor tag
|
||||||
* @link https://github.com/chjj/marked#overriding-renderer-methods
|
* @link https://github.com/chjj/marked#overriding-renderer-methods
|
||||||
|
|
@ -102,7 +102,7 @@ export class Compiler {
|
||||||
const titleHTML = title ? ` title="${title}"` : ''
|
const titleHTML = title ? ` title="${title}"` : ''
|
||||||
|
|
||||||
if (!isAbsolutePath(href)) {
|
if (!isAbsolutePath(href)) {
|
||||||
url = getPath(this.contentBase, href)
|
url = getPath(contentBase, href)
|
||||||
}
|
}
|
||||||
|
|
||||||
return `<img src="${url}" data-origin="${href}" alt="${text}"${titleHTML}>`
|
return `<img src="${url}" data-origin="${href}" alt="${text}"${titleHTML}>`
|
||||||
|
|
@ -120,7 +120,7 @@ export class Compiler {
|
||||||
|
|
||||||
if (text) {
|
if (text) {
|
||||||
html = this.compile(text)
|
html = this.compile(text)
|
||||||
html = html.match(/<ul[^>]*>([\s\S]+)<\/ul>/g)[0]
|
html = html && html.match(/<ul[^>]*>([\s\S]+)<\/ul>/g)[0]
|
||||||
} else {
|
} else {
|
||||||
const tree = this.cacheTree[currentPath] || genTree(this.toc, level)
|
const tree = this.cacheTree[currentPath] || genTree(this.toc, level)
|
||||||
html = treeTpl(tree, '<ul>')
|
html = treeTpl(tree, '<ul>')
|
||||||
|
|
|
||||||
|
|
@ -18,10 +18,6 @@ export class History {
|
||||||
this.config = config
|
this.config = config
|
||||||
}
|
}
|
||||||
|
|
||||||
onchange (cb = noop) {
|
|
||||||
cb()
|
|
||||||
}
|
|
||||||
|
|
||||||
getFile (path) {
|
getFile (path) {
|
||||||
const { config } = this
|
const { config } = this
|
||||||
const base = getBasePath(config.basePath)
|
const base = getBasePath(config.basePath)
|
||||||
|
|
@ -34,6 +30,10 @@ export class History {
|
||||||
return path
|
return path
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onchange (cb = noop) {
|
||||||
|
cb()
|
||||||
|
}
|
||||||
|
|
||||||
getCurrentPath () {}
|
getCurrentPath () {}
|
||||||
|
|
||||||
normalize () {}
|
normalize () {}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,83 @@
|
||||||
import { History } from './base'
|
import { History } from './base'
|
||||||
|
import { merge, noop } from '../../util/core'
|
||||||
|
import { on } from '../../util/dom'
|
||||||
|
import { parseQuery, stringifyQuery, cleanPath } from '../util'
|
||||||
|
|
||||||
export class HTML5History extends History {
|
export class HTML5History extends History {
|
||||||
constructor (config) {
|
constructor (config) {
|
||||||
super(config)
|
super(config)
|
||||||
this.mode = 'history'
|
this.mode = 'history'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getCurrentPath () {
|
||||||
|
const base = this.config.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
|
||||||
|
}
|
||||||
|
|
||||||
|
onchange (cb = noop) {
|
||||||
|
on('click', e => {
|
||||||
|
const el = e.target.tagName === 'A'
|
||||||
|
? e.target
|
||||||
|
: e.target.parentNode
|
||||||
|
|
||||||
|
if (el.tagName === 'A' && !/_blank/.test(el.target)) {
|
||||||
|
e.preventDefault()
|
||||||
|
const url = el.href
|
||||||
|
window.history.pushState({ key: url }, '', url)
|
||||||
|
cb()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
on('popstate', cb)
|
||||||
|
}
|
||||||
|
|
||||||
|
normalize () {
|
||||||
|
let path = this.getCurrentPath()
|
||||||
|
|
||||||
|
path = path.replace('#', '?id=')
|
||||||
|
window.history.pushState({ key: path }, '', path)
|
||||||
|
|
||||||
|
return path
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse the url
|
||||||
|
* @param {string} [path=location.href]
|
||||||
|
* @return {object} { path, query }
|
||||||
|
*/
|
||||||
|
parse (path = location.href) {
|
||||||
|
let query = ''
|
||||||
|
|
||||||
|
const queryIndex = path.indexOf('?')
|
||||||
|
if (queryIndex >= 0) {
|
||||||
|
query = path.slice(queryIndex + 1)
|
||||||
|
path = path.slice(0, queryIndex)
|
||||||
|
}
|
||||||
|
|
||||||
|
const baseIndex = path.indexOf(location.origin)
|
||||||
|
if (baseIndex > -1) {
|
||||||
|
path = path.slice(baseIndex + location.origin.length)
|
||||||
|
}
|
||||||
|
|
||||||
|
return { path, query: parseQuery(query) }
|
||||||
|
}
|
||||||
|
|
||||||
|
toURL (path, params, currentRoute) {
|
||||||
|
const local = currentRoute && path[0] === '#'
|
||||||
|
const route = this.parse(path)
|
||||||
|
|
||||||
|
route.query = merge({}, route.query, params)
|
||||||
|
path = route.path + stringifyQuery(route.query)
|
||||||
|
path = path.replace(/\.md(\?)|\.md$/, '$1')
|
||||||
|
|
||||||
|
if (local) path = currentRoute + path
|
||||||
|
|
||||||
|
return cleanPath('/' + path)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,17 +6,14 @@ export const isMobile = document.body.clientWidth <= 600
|
||||||
|
|
||||||
export const inBrowser = typeof window !== 'undefined'
|
export const inBrowser = typeof window !== 'undefined'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see https://github.com/MoOx/pjax/blob/master/lib/is-supported.js
|
||||||
|
*/
|
||||||
export const supportsPushState = inBrowser && (function () {
|
export const supportsPushState = inBrowser && (function () {
|
||||||
const ua = window.navigator.userAgent
|
// Borrowed wholesale from https://github.com/defunkt/jquery-pjax
|
||||||
|
return window.history &&
|
||||||
if (
|
window.history.pushState &&
|
||||||
(ua.indexOf('Android 2.') !== -1 || ua.indexOf('Android 4.0') !== -1) &&
|
window.history.replaceState &&
|
||||||
ua.indexOf('Mobile Safari') !== -1 &&
|
// pushState isn’t reliable on iOS until 5.
|
||||||
ua.indexOf('Chrome') === -1 &&
|
!navigator.userAgent.match(/((iPod|iPhone|iPad).+\bOS\s+[1-4]\D|WebApps\/.+CFNetwork)/)
|
||||||
ua.indexOf('Windows Phone') === -1
|
|
||||||
) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return window.history && 'pushState' in window.history
|
|
||||||
})()
|
})()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue