redoc/src/services/HistoryService.ts

65 lines
1.4 KiB
TypeScript
Raw Normal View History

2017-10-12 00:01:37 +03:00
import { bind, debounce } from 'decko';
import { EventEmitter } from 'eventemitter3';
const EVENT = 'hashchange';
function isSameHash(a: string, b: string): boolean {
return a === b || '#' + a === b || a === '#' + b;
}
class _HistoryService {
private causedHashChange: boolean = false;
private _emiter;
constructor() {
this._emiter = new EventEmitter();
this.bind();
}
get hash(): string {
return window.location.hash;
}
subscribe(cb): () => void {
const emmiter = this._emiter.addListener(EVENT, cb);
return () => emmiter.removeListener(EVENT, cb);
}
emit = () => {
if (this.causedHashChange) {
this.causedHashChange = false;
return;
}
this._emiter.emit(EVENT, this.hash);
};
bind() {
window.addEventListener('hashchange', this.emit, false);
}
dispose() {
window.removeEventListener('hashchange', this.emit);
this.causedHashChange = false;
}
@bind
@debounce
update(hash: string | null, rewriteHistory: boolean = false) {
if (hash == null || isSameHash(hash, this.hash)) return;
if (rewriteHistory) {
window.history.replaceState(null, '', window.location.href.split('#')[0] + '#' + hash);
return;
}
this.causedHashChange = true;
window.location.hash = hash;
}
}
export const HistoryService = new _HistoryService();
if (module.hot) {
module.hot.dispose(() => {
HistoryService.dispose();
});
}