UNPKG

@etsoo/shared

Version:

TypeScript shared utilities and functions

148 lines (147 loc) 3.74 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.EHistory = exports.EHistoryNavigateEvent = exports.EHistoryEvent = void 0; const EventClass_1 = require("./EventClass"); /** * ETSOO Extended history event */ class EHistoryEvent extends EventClass_1.EventBase { } exports.EHistoryEvent = EHistoryEvent; /** * ETSOO Extended history navigate event */ class EHistoryNavigateEvent extends EventClass_1.EventBase { constructor(target, data) { super(target, "navigate", data); } } exports.EHistoryNavigateEvent = EHistoryNavigateEvent; /** * ETSOO Extended abstract history class */ class EHistory extends EventClass_1.EventClass { /** * States length */ get length() { return this.states.length; } /** * Get current state index */ get index() { return this._index; } /** * Get current state */ get state() { if (this._index === -1) return undefined; return this.states[this._index]; } /** * Constructor * @param maxDepth Max depth of the history */ constructor(maxDepth = 20) { super(); this.maxDepth = maxDepth; // Index this._index = -1; /** * States */ this.states = []; } /** * Back to the previous state */ back() { this.go(-1); } /** * Clear all states but keep event listeners */ clear() { // https://stackoverflow.com/questions/1232040/how-do-i-empty-an-array-in-javascript this.states.length = 0; this._index = -1; this.trigger(this.createEvent("clear", this._index)); } /** * Create event * @param type Type * @param index Current index */ createEvent(type, index) { return new EHistoryEvent(this, type, { index }); } createNavigateEvent(index, delta) { return new EHistoryNavigateEvent(this, { index, delta }); } /** * Forward to the next state */ forward() { this.go(1); } /** * Get [undo, redo] status */ getStatus() { if (this.length < 2) return [false, false]; if (this._index <= 0) return [false, true]; if (this._index + 1 >= this.length) return [true, false]; return [true, true]; } /** * Go to the specific state * @param delta A negative value moves backwards, a positive value moves forwards */ go(delta) { // No data if (this._index === -1) return undefined; // New index const newIndex = this._index + delta; // Not in the range if (newIndex < 0 || newIndex >= this.length) return undefined; // Update the index this._index = newIndex; // Trigger event this.trigger(this.createNavigateEvent(newIndex, delta)); } /** * Adds an entry to the history stack * @param state State */ pushState(state) { if (this._index >= 0) { // Remove states after the index this.states.splice(this._index + 1); } this.states.push(state); this._index++; if (this.length > this.maxDepth) { this.states.shift(); } this.trigger(this.createEvent("push", this._index)); } /** * Modifies the current history entry * @param state State */ replaceState(state) { if (this._index === -1) return; this.states[this._index] = state; this.trigger(this.createEvent("replace", this._index)); } } exports.EHistory = EHistory;