@etsoo/shared
Version:
TypeScript shared utilities and functions
148 lines (147 loc) • 3.74 kB
JavaScript
"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;