UNPKG

iportal

Version:

web-portal

123 lines (111 loc) 3.43 kB
'use strict' import { Application } from '../Application' import { TransformProptey } from './proptey' import { PopState } from '../types' class TransformHistory extends TransformProptey { public history: number = 0 public historyIndex: number = history.length public historyDirection: number = 0 private backoutCount: number = 0 private silentObserver: number | undefined = undefined constructor (app: Application) { super(app) this.bindHistoryState() } private bindHistoryState () { addEventListener('load', () => { addEventListener('popstate', (event: PopStateEvent) => { this.popstate(event.state) clearInterval(this.silentObserver) }, false) }, false) } private obserSilent () { this.silentObserver = setInterval(() => { if (history.state?.id !== this.id) { this.popstate(history.state) } }, 100) as unknown as number } public popstate (state: PopState) { const { historyIndex = 0 } = state ?? {} if (historyIndex === this.historyIndex) { this.historyDirection = 0 } else if (historyIndex > this.historyIndex) { this.historyDirection = 1 } else { this.historyDirection = -1 } this.historyIndex = historyIndex this.back(state) } public pushState (id = '', title = '', search = location.search, param = '') { id = encodeURIComponent(id) const length = history.length history.pushState({ id, title, time: Date.now(), search, historyIndex: length }, title, location.pathname + search + '#' + id + '/' + param) this.historyIndex = length + 1 this.historyDirection = 1 if (this.silentObserver === undefined) { this.obserSilent() } } public replaceState (id = '', title = '', search = location.search, param = '') { id = encodeURIComponent(id) const length = history.length history.replaceState({ id, title, time: Date.now(), search, historyIndex: length }, title, location.pathname + search + '#' + id + '/' + param) this.historyIndex = length this.historyDirection = 1 } public async back (state?: PopState) { const options = this.options const route = state || history.state || this.app.route const id = decodeURIComponent(route.id) || options.index || 'frameworks' const search = route.search const module = await this.app.get(id) if (!module) return /** * 如果设置了单向锁,且回退时模块层级为 0 时 * 阻止返回,并发送事件 */ if (this.checkSingleLock()) { this.backoutCount++ if (this.options.holdBack?.(this.backoutCount) === true) { this.pushState(id, module.config.title, search) this.app.trigger('exit', { backoutCount: this.backoutCount }) } return } else { this.backoutCount = 0 } const inLevel = module.config.level ?? 0 const outLever = this.module.config.level ?? 0 if (options.singleFlow && module.config.level !== 0 && inLevel >= outLever) { return history.back() } this.app.transform.to(id, search, -1) this.app.trigger('back', { id, module }) } public checkSingleLock (): boolean { return this.options.singleLock && this.module.config.level === 0 && this.historyDirection === -1 ? true : false } } export { TransformHistory }