import EventEmitter from "./events.js"; import HookEvent from "./hook.js"; class History extends EventEmitter { constructor(ctx) { super(); this.ctx = ctx; this.window = this.ctx.window; this.History = this.window.History; this.history = this.window.history; this.historyProto = this.History ? this.History.prototype : {}; this.pushState = this.historyProto.pushState; this.replaceState = this.historyProto.replaceState; this.go = this.historyProto.go; this.back = this.historyProto.back; this.forward = this.historyProto.forward; }; override() { this.overridePushState(); this.overrideReplaceState(); this.overrideGo(); this.overrideForward(); this.overrideBack(); }; overridePushState() { this.ctx.override(this.historyProto, 'pushState', (target, that, args) => { if (2 > args.length) return target.apply(that, args); let [ state, title, url = '' ] = args; const event = new HookEvent({ state, title, url }, target, that); this.emit('pushState', event); if (event.intercepted) return event.returnValue; return event.target.call(event.that, event.data.state, event.data.title, event.data.url); }); }; overrideReplaceState() { this.ctx.override(this.historyProto, 'replaceState', (target, that, args) => { if (2 > args.length) return target.apply(that, args); let [ state, title, url = '' ] = args; const event = new HookEvent({ state, title, url }, target, that); this.emit('replaceState', event); if (event.intercepted) return event.returnValue; return event.target.call(event.that, event.data.state, event.data.title, event.data.url); }); }; overrideGo() { this.ctx.override(this.historyProto, 'go', (target, that, [ delta ]) => { const event = new HookEvent({ delta }, target, that); this.emit('go', event); if (event.intercepted) return event.returnValue; return event.target.call(event.that, event.data.delta); }); }; overrideForward() { this.ctx.override(this.historyProto, 'forward', (target, that) => { const event = new HookEvent(null, target, that); this.emit('forward', event); if (event.intercepted) return event.returnValue; return event.target.call(event.that); }); }; overrideBack() { this.ctx.override(this.historyProto, 'back', (target, that) => { const event = new HookEvent(null, target, that); this.emit('back', event); if (event.intercepted) return event.returnValue; return event.target.call(event.that); }); }; }; export default History;