redoc/src/services/HistoryService.ts

78 lines
1.5 KiB
TypeScript
Raw Normal View History

2017-10-12 00:01:37 +03:00
import { bind, debounce } from 'decko';
import { EventEmitter } from 'eventemitter3';
import { IS_BROWSER } from '../utils/';
2017-10-12 00:01:37 +03:00
const EVENT = 'hashchange';
2018-08-17 14:50:58 +03:00
export class HistoryService {
2017-10-12 00:01:37 +03:00
private _emiter;
constructor() {
this._emiter = new EventEmitter();
this.bind();
}
2018-08-17 14:50:58 +03:00
get currentId(): string {
return IS_BROWSER ? decodeURIComponent(window.location.hash.substring(1)) : '';
2018-08-17 14:50:58 +03:00
}
linkForId(id: string) {
2018-08-17 15:01:18 +03:00
if (!id) {
return '';
}
2018-08-17 14:50:58 +03:00
return '#' + id;
2017-10-12 00:01:37 +03:00
}
subscribe(cb): () => void {
const emmiter = this._emiter.addListener(EVENT, cb);
return () => emmiter.removeListener(EVENT, cb);
}
emit = () => {
2018-08-17 14:50:58 +03:00
this._emiter.emit(EVENT, this.currentId);
2017-10-12 00:01:37 +03:00
};
bind() {
if (IS_BROWSER) {
window.addEventListener('hashchange', this.emit, false);
}
2017-10-12 00:01:37 +03:00
}
dispose() {
if (IS_BROWSER) {
window.removeEventListener('hashchange', this.emit);
}
2017-10-12 00:01:37 +03:00
}
@bind
@debounce
2018-08-17 14:50:58 +03:00
replace(id: string | null, rewriteHistory: boolean = false) {
if (!IS_BROWSER) {
2018-01-22 21:30:53 +03:00
return;
}
2018-08-17 14:50:58 +03:00
2018-08-17 15:01:18 +03:00
if (id == null || id === this.currentId) {
2017-10-12 00:01:37 +03:00
return;
}
2018-08-17 14:50:58 +03:00
if (rewriteHistory) {
window.history.replaceState(
null,
'',
window.location.href.split('#')[0] + this.linkForId(id),
);
return;
}
2018-08-17 14:50:58 +03:00
window.history.pushState(null, '', window.location.href.split('#')[0] + this.linkForId(id));
2018-08-17 15:01:18 +03:00
this.emit();
2017-10-12 00:01:37 +03:00
}
}
2018-08-17 14:50:58 +03:00
export const history = new HistoryService();
2017-10-12 00:01:37 +03:00
if (module.hot) {
module.hot.dispose(() => {
2018-08-17 14:50:58 +03:00
history.dispose();
2017-10-12 00:01:37 +03:00
});
}