127 lines
2.6 KiB
JavaScript
127 lines
2.6 KiB
JavaScript
module.exports = LocationHistory
|
|
|
|
function LocationHistory () {
|
|
if (!new.target) return new LocationHistory()
|
|
this._history = []
|
|
this._forward = []
|
|
this._pending = false
|
|
}
|
|
|
|
LocationHistory.prototype.url = function () {
|
|
return this.current() && this.current().url
|
|
}
|
|
|
|
LocationHistory.prototype.current = function () {
|
|
return this._history[this._history.length - 1]
|
|
}
|
|
|
|
LocationHistory.prototype.go = function (page, cb) {
|
|
if (!cb) cb = noop
|
|
if (this._pending) return cb(null)
|
|
|
|
console.log('go', page)
|
|
|
|
this.clearForward()
|
|
this._go(page, cb)
|
|
}
|
|
|
|
LocationHistory.prototype.back = function (cb) {
|
|
var self = this
|
|
if (!cb) cb = noop
|
|
if (self._history.length <= 1 || self._pending) return cb(null)
|
|
|
|
var page = self._history.pop()
|
|
self._unload(page, done)
|
|
|
|
function done (err) {
|
|
if (err) return cb(err)
|
|
self._forward.push(page)
|
|
self._load(self.current(), cb)
|
|
}
|
|
}
|
|
|
|
LocationHistory.prototype.hasBack = function () {
|
|
return this._history.length > 1
|
|
}
|
|
|
|
LocationHistory.prototype.forward = function (cb) {
|
|
if (!cb) cb = noop
|
|
if (this._forward.length === 0 || this._pending) return cb(null)
|
|
|
|
var page = this._forward.pop()
|
|
this._go(page, cb)
|
|
}
|
|
|
|
LocationHistory.prototype.hasForward = function () {
|
|
return this._forward.length > 0
|
|
}
|
|
|
|
LocationHistory.prototype.clearForward = function (url) {
|
|
if (url == null) {
|
|
this._forward = []
|
|
} else {
|
|
console.log(this._forward)
|
|
console.log(url)
|
|
this._forward = this._forward.filter(function (page) {
|
|
return page.url !== url
|
|
})
|
|
}
|
|
}
|
|
|
|
LocationHistory.prototype.backToFirst = function (cb) {
|
|
var self = this
|
|
if (!cb) cb = noop
|
|
if (self._history.length <= 1) return cb(null)
|
|
|
|
self.back(function (err) {
|
|
if (err) return cb(err)
|
|
self.backToFirst(cb)
|
|
})
|
|
}
|
|
|
|
LocationHistory.prototype._go = function (page, cb) {
|
|
var self = this
|
|
if (!cb) cb = noop
|
|
|
|
self._unload(self.current(), done1)
|
|
|
|
function done1 (err) {
|
|
if (err) return cb(err)
|
|
self._load(page, done2)
|
|
}
|
|
|
|
function done2 (err) {
|
|
if (err) return cb(err)
|
|
self._history.push(page)
|
|
cb(null)
|
|
}
|
|
}
|
|
|
|
LocationHistory.prototype._load = function (page, cb) {
|
|
var self = this
|
|
self._pending = true
|
|
|
|
if (page && page.onbeforeload) page.onbeforeload(done)
|
|
else done(null)
|
|
|
|
function done (err) {
|
|
self._pending = false
|
|
cb(err)
|
|
}
|
|
}
|
|
|
|
LocationHistory.prototype._unload = function (page, cb) {
|
|
var self = this
|
|
self._pending = true
|
|
|
|
if (page && page.onbeforeunload) page.onbeforeunload(done)
|
|
else done(null)
|
|
|
|
function done (err) {
|
|
self._pending = false
|
|
cb(err)
|
|
}
|
|
}
|
|
|
|
function noop () {}
|