mirror of
https://github.com/Redocly/redoc.git
synced 2025-01-31 18:14:07 +03:00
76 lines
1.6 KiB
TypeScript
76 lines
1.6 KiB
TypeScript
import { bind, debounce } from 'decko';
|
|
import { EventEmitter } from 'eventemitter3';
|
|
import { isBrowser } from '../utils/';
|
|
|
|
const EVENT = 'hashchange';
|
|
|
|
function isSameHash(a: string, b: string): boolean {
|
|
return a === b || '#' + a === b || a === '#' + b;
|
|
}
|
|
|
|
class IntHistoryService {
|
|
private causedHashChange: boolean = false;
|
|
private _emiter;
|
|
|
|
constructor() {
|
|
this._emiter = new EventEmitter();
|
|
this.bind();
|
|
}
|
|
|
|
get hash(): string {
|
|
return isBrowser ? 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() {
|
|
if (isBrowser) {
|
|
window.addEventListener('hashchange', this.emit, false);
|
|
}
|
|
}
|
|
|
|
dispose() {
|
|
if (isBrowser) {
|
|
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) {
|
|
if (isBrowser) {
|
|
window.history.replaceState(null, '', window.location.href.split('#')[0] + '#' + hash);
|
|
}
|
|
return;
|
|
}
|
|
this.causedHashChange = true;
|
|
if (isBrowser) {
|
|
window.location.hash = hash;
|
|
}
|
|
}
|
|
}
|
|
|
|
export const HistoryService = new IntHistoryService();
|
|
|
|
if (module.hot) {
|
|
module.hot.dispose(() => {
|
|
HistoryService.dispose();
|
|
});
|
|
}
|