@etsoo/shared 1.1.25 → 1.1.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -2
- package/__tests__/ColorUtils.ts +7 -0
- package/__tests__/EHistory.ts +81 -0
- package/lib/cjs/types/EColor.d.ts +7 -0
- package/lib/cjs/types/EColor.js +18 -0
- package/lib/cjs/types/EHistory.d.ts +69 -0
- package/lib/cjs/types/EHistory.js +101 -0
- package/lib/cjs/types/EventClass.d.ts +104 -0
- package/lib/cjs/types/EventClass.js +159 -0
- package/lib/mjs/types/EColor.d.ts +7 -0
- package/lib/mjs/types/EColor.js +18 -0
- package/lib/mjs/types/EHistory.d.ts +69 -0
- package/lib/mjs/types/EHistory.js +97 -0
- package/lib/mjs/types/EventClass.d.ts +104 -0
- package/lib/mjs/types/EventClass.js +154 -0
- package/package.json +1 -1
- package/src/types/EColor.ts +19 -0
- package/src/types/EHistory.ts +134 -0
- package/src/types/EventClass.ts +253 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { EventBase, EventClass } from './EventClass';
|
|
2
|
+
/**
|
|
3
|
+
* ETSOO Extended history event type
|
|
4
|
+
*/
|
|
5
|
+
export declare type EHistoryEventType = 'navigate' | 'push' | 'replace' | 'clear';
|
|
6
|
+
/**
|
|
7
|
+
* ETSOO Extended history event data
|
|
8
|
+
*/
|
|
9
|
+
export interface EHistoryEventData {
|
|
10
|
+
/**
|
|
11
|
+
* Current index
|
|
12
|
+
*/
|
|
13
|
+
index: number;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* ETSOO Extended abstract history class
|
|
17
|
+
*/
|
|
18
|
+
export declare abstract class EHistory<T, D extends EHistoryEventData> extends EventClass<EHistoryEventType, D> {
|
|
19
|
+
private _index;
|
|
20
|
+
/**
|
|
21
|
+
* States
|
|
22
|
+
*/
|
|
23
|
+
readonly states: T[];
|
|
24
|
+
/**
|
|
25
|
+
* States length
|
|
26
|
+
*/
|
|
27
|
+
get length(): number;
|
|
28
|
+
/**
|
|
29
|
+
* Get current state index
|
|
30
|
+
*/
|
|
31
|
+
get index(): number;
|
|
32
|
+
/**
|
|
33
|
+
* Get current state
|
|
34
|
+
*/
|
|
35
|
+
get state(): T | undefined;
|
|
36
|
+
/**
|
|
37
|
+
* Back to the previous state
|
|
38
|
+
*/
|
|
39
|
+
back(): void;
|
|
40
|
+
/**
|
|
41
|
+
* Clear all states but keep event listeners
|
|
42
|
+
*/
|
|
43
|
+
clear(): void;
|
|
44
|
+
/**
|
|
45
|
+
* Create event
|
|
46
|
+
* @param type Type
|
|
47
|
+
* @param index Current index
|
|
48
|
+
*/
|
|
49
|
+
protected abstract createEvent(type: EHistoryEventType, index: number): EventBase<EHistoryEventType, D>;
|
|
50
|
+
/**
|
|
51
|
+
* Forward to the next state
|
|
52
|
+
*/
|
|
53
|
+
forward(): void;
|
|
54
|
+
/**
|
|
55
|
+
* Go to the specific state
|
|
56
|
+
* @param delta A negative value moves backwards, a positive value moves forwards
|
|
57
|
+
*/
|
|
58
|
+
go(delta: number): undefined;
|
|
59
|
+
/**
|
|
60
|
+
* Adds an entry to the history stack
|
|
61
|
+
* @param state State
|
|
62
|
+
*/
|
|
63
|
+
pushState(state: T): void;
|
|
64
|
+
/**
|
|
65
|
+
* Modifies the current history entry
|
|
66
|
+
* @param state State
|
|
67
|
+
*/
|
|
68
|
+
replaceState(state: T): void;
|
|
69
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { EventClass } from './EventClass';
|
|
2
|
+
/**
|
|
3
|
+
* ETSOO Extended abstract history class
|
|
4
|
+
*/
|
|
5
|
+
export class EHistory extends EventClass {
|
|
6
|
+
constructor() {
|
|
7
|
+
super(...arguments);
|
|
8
|
+
// Index
|
|
9
|
+
this._index = -1;
|
|
10
|
+
/**
|
|
11
|
+
* States
|
|
12
|
+
*/
|
|
13
|
+
this.states = [];
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* States length
|
|
17
|
+
*/
|
|
18
|
+
get length() {
|
|
19
|
+
return this.states.length;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Get current state index
|
|
23
|
+
*/
|
|
24
|
+
get index() {
|
|
25
|
+
return this._index;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Get current state
|
|
29
|
+
*/
|
|
30
|
+
get state() {
|
|
31
|
+
if (this._index === -1)
|
|
32
|
+
return undefined;
|
|
33
|
+
return this.states[this._index];
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Back to the previous state
|
|
37
|
+
*/
|
|
38
|
+
back() {
|
|
39
|
+
this.go(-1);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Clear all states but keep event listeners
|
|
43
|
+
*/
|
|
44
|
+
clear() {
|
|
45
|
+
// https://stackoverflow.com/questions/1232040/how-do-i-empty-an-array-in-javascript
|
|
46
|
+
this.states.length = 0;
|
|
47
|
+
this._index = -1;
|
|
48
|
+
this.trigger(this.createEvent('clear', this._index));
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Forward to the next state
|
|
52
|
+
*/
|
|
53
|
+
forward() {
|
|
54
|
+
this.go(1);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Go to the specific state
|
|
58
|
+
* @param delta A negative value moves backwards, a positive value moves forwards
|
|
59
|
+
*/
|
|
60
|
+
go(delta) {
|
|
61
|
+
// No data
|
|
62
|
+
if (this._index === -1)
|
|
63
|
+
return undefined;
|
|
64
|
+
// New index
|
|
65
|
+
const newIndex = this._index + delta;
|
|
66
|
+
// Not in the range
|
|
67
|
+
if (newIndex < 0 || newIndex >= this.length)
|
|
68
|
+
return undefined;
|
|
69
|
+
// Update the index
|
|
70
|
+
this._index = newIndex;
|
|
71
|
+
// Trigger event
|
|
72
|
+
this.trigger(this.createEvent('navigate', newIndex));
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Adds an entry to the history stack
|
|
76
|
+
* @param state State
|
|
77
|
+
*/
|
|
78
|
+
pushState(state) {
|
|
79
|
+
if (this._index >= 0) {
|
|
80
|
+
// Remove states after the index
|
|
81
|
+
this.states.splice(this._index + 1);
|
|
82
|
+
}
|
|
83
|
+
this.states.push(state);
|
|
84
|
+
this._index++;
|
|
85
|
+
this.trigger(this.createEvent('push', this._index));
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Modifies the current history entry
|
|
89
|
+
* @param state State
|
|
90
|
+
*/
|
|
91
|
+
replaceState(state) {
|
|
92
|
+
if (this._index === -1)
|
|
93
|
+
return;
|
|
94
|
+
this.states[this._index] = state;
|
|
95
|
+
this.trigger(this.createEvent('replace', this._index));
|
|
96
|
+
}
|
|
97
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Abstract event base class
|
|
3
|
+
* T for type
|
|
4
|
+
* D for data
|
|
5
|
+
*/
|
|
6
|
+
export declare abstract class EventBase<T extends string, D> {
|
|
7
|
+
readonly target: EventClass<T, D>;
|
|
8
|
+
readonly type: T;
|
|
9
|
+
readonly data: D;
|
|
10
|
+
private _propagationStopped;
|
|
11
|
+
/**
|
|
12
|
+
* stopImmediatePropagation called
|
|
13
|
+
*/
|
|
14
|
+
get propagationStopped(): boolean;
|
|
15
|
+
private _timeStamp;
|
|
16
|
+
/**
|
|
17
|
+
* Time stamp
|
|
18
|
+
*/
|
|
19
|
+
get timeStamp(): number;
|
|
20
|
+
/**
|
|
21
|
+
* Constructor
|
|
22
|
+
* @param type Type
|
|
23
|
+
*/
|
|
24
|
+
constructor(target: EventClass<T, D>, type: T, data: D);
|
|
25
|
+
/**
|
|
26
|
+
* Prevent all other listeners from being called
|
|
27
|
+
*/
|
|
28
|
+
stopImmediatePropagation(): void;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Event options
|
|
32
|
+
*/
|
|
33
|
+
interface EventOptions {
|
|
34
|
+
/**
|
|
35
|
+
* A boolean value indicating that events of this type will be dispatched first
|
|
36
|
+
*/
|
|
37
|
+
capture?: boolean;
|
|
38
|
+
/**
|
|
39
|
+
* A boolean value indicating that the listener should be invoked at most once after being added
|
|
40
|
+
*/
|
|
41
|
+
once?: boolean;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Event class callback
|
|
45
|
+
* T for type
|
|
46
|
+
* D for data
|
|
47
|
+
*/
|
|
48
|
+
export declare type EventClassCallback<T extends string, D> = (event: EventBase<T, D>) => void;
|
|
49
|
+
/**
|
|
50
|
+
* Event class collection definition
|
|
51
|
+
* T for type
|
|
52
|
+
* D for data
|
|
53
|
+
*/
|
|
54
|
+
export declare type EventClassCollection<T extends string, D> = {
|
|
55
|
+
[key in T]?: EventClassCallback<T, D>;
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Event class
|
|
59
|
+
* T for type
|
|
60
|
+
* D for data
|
|
61
|
+
*/
|
|
62
|
+
export declare abstract class EventClass<T extends string, D> {
|
|
63
|
+
private readonly listeners;
|
|
64
|
+
/**
|
|
65
|
+
* Has specific type events
|
|
66
|
+
* @param type Type
|
|
67
|
+
*/
|
|
68
|
+
hasEvents(type: T): boolean;
|
|
69
|
+
/**
|
|
70
|
+
* Has specific type and callback events
|
|
71
|
+
* @param type Type
|
|
72
|
+
* @param callback Callback
|
|
73
|
+
*/
|
|
74
|
+
hasEvents(type: T, callback: EventClassCallback<T, D>): boolean;
|
|
75
|
+
/**
|
|
76
|
+
* Remove all specific type events
|
|
77
|
+
* @param type Type
|
|
78
|
+
*/
|
|
79
|
+
off(type: T): void;
|
|
80
|
+
/**
|
|
81
|
+
* Remove specific type and callback event
|
|
82
|
+
* @param type Type
|
|
83
|
+
* @param callback Callback
|
|
84
|
+
*/
|
|
85
|
+
off(type: T, callback: EventClassCallback<T, D>): void;
|
|
86
|
+
/**
|
|
87
|
+
* Add event listeners
|
|
88
|
+
* @param collection Collection of events
|
|
89
|
+
*/
|
|
90
|
+
on(collection: EventClassCollection<T, D>): void;
|
|
91
|
+
/**
|
|
92
|
+
* Add event listener
|
|
93
|
+
* @param type Type
|
|
94
|
+
* @param callback Callback
|
|
95
|
+
* @param options Options
|
|
96
|
+
*/
|
|
97
|
+
on(type: T, callback: EventClassCallback<T, D>, options?: EventOptions): void;
|
|
98
|
+
/**
|
|
99
|
+
* Trigger event
|
|
100
|
+
* @param event Event
|
|
101
|
+
*/
|
|
102
|
+
trigger(event: EventBase<T, D>): void;
|
|
103
|
+
}
|
|
104
|
+
export {};
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Abstract event base class
|
|
3
|
+
* T for type
|
|
4
|
+
* D for data
|
|
5
|
+
*/
|
|
6
|
+
export class EventBase {
|
|
7
|
+
/**
|
|
8
|
+
* Constructor
|
|
9
|
+
* @param type Type
|
|
10
|
+
*/
|
|
11
|
+
constructor(target, type, data) {
|
|
12
|
+
this.target = target;
|
|
13
|
+
this.type = type;
|
|
14
|
+
this.data = data;
|
|
15
|
+
this._propagationStopped = false;
|
|
16
|
+
this._timeStamp = Date.now();
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* stopImmediatePropagation called
|
|
20
|
+
*/
|
|
21
|
+
get propagationStopped() {
|
|
22
|
+
return this._propagationStopped;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Time stamp
|
|
26
|
+
*/
|
|
27
|
+
get timeStamp() {
|
|
28
|
+
return this._timeStamp;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Prevent all other listeners from being called
|
|
32
|
+
*/
|
|
33
|
+
stopImmediatePropagation() {
|
|
34
|
+
this._propagationStopped = true;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Event class
|
|
39
|
+
* T for type
|
|
40
|
+
* D for data
|
|
41
|
+
*/
|
|
42
|
+
export class EventClass {
|
|
43
|
+
constructor() {
|
|
44
|
+
// Listeners
|
|
45
|
+
this.listeners = new Map();
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Has specific type and callback events
|
|
49
|
+
* @param type Type
|
|
50
|
+
* @param callback Callback
|
|
51
|
+
* @returns Result
|
|
52
|
+
*/
|
|
53
|
+
hasEvents(type, callback) {
|
|
54
|
+
const items = this.listeners.get(type);
|
|
55
|
+
if (items == null || items.length === 0)
|
|
56
|
+
return false;
|
|
57
|
+
if (callback) {
|
|
58
|
+
return items.some((item) => item[0] == callback);
|
|
59
|
+
}
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Remove specific type and callback event
|
|
64
|
+
* @param type Type
|
|
65
|
+
* @param callback Callback
|
|
66
|
+
*/
|
|
67
|
+
off(type, callback) {
|
|
68
|
+
if (callback == null) {
|
|
69
|
+
this.listeners.delete(type);
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
const items = this.listeners.get(type);
|
|
73
|
+
if (items == null)
|
|
74
|
+
return;
|
|
75
|
+
for (let i = items.length - 1; i >= 0; i--) {
|
|
76
|
+
if (items[i][0] == callback) {
|
|
77
|
+
items.splice(i, 1);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Add events
|
|
83
|
+
* @param type Type
|
|
84
|
+
* @param callback Callback
|
|
85
|
+
* @param options Options
|
|
86
|
+
*/
|
|
87
|
+
on(type, callback, options) {
|
|
88
|
+
var _a, _b;
|
|
89
|
+
if (typeof type === 'object') {
|
|
90
|
+
for (const key in type) {
|
|
91
|
+
const item = key;
|
|
92
|
+
const itemCallback = (_a = type[item]) !== null && _a !== void 0 ? _a : callback;
|
|
93
|
+
if (itemCallback)
|
|
94
|
+
this.on(item, itemCallback, options);
|
|
95
|
+
}
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
if (callback == null)
|
|
99
|
+
return;
|
|
100
|
+
this.listeners.has(type) || this.listeners.set(type, []);
|
|
101
|
+
(_b = this.listeners.get(type)) === null || _b === void 0 ? void 0 : _b.push([callback, options]);
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Trigger event
|
|
105
|
+
* @param event Event
|
|
106
|
+
*/
|
|
107
|
+
trigger(event) {
|
|
108
|
+
const items = this.listeners.get(event.type);
|
|
109
|
+
if (items == null)
|
|
110
|
+
return;
|
|
111
|
+
// Len
|
|
112
|
+
const len = items.length;
|
|
113
|
+
if (len === 0)
|
|
114
|
+
return;
|
|
115
|
+
// Need to be removed indicies
|
|
116
|
+
const indicies = [];
|
|
117
|
+
// Capture items first
|
|
118
|
+
let stopped = false;
|
|
119
|
+
for (let c = 0; c < len; c++) {
|
|
120
|
+
const item = items[c];
|
|
121
|
+
const [callback, options] = item;
|
|
122
|
+
if (options == null || !options.capture)
|
|
123
|
+
continue;
|
|
124
|
+
callback(event);
|
|
125
|
+
if (options.once) {
|
|
126
|
+
indicies.push(c);
|
|
127
|
+
}
|
|
128
|
+
if (event.propagationStopped) {
|
|
129
|
+
stopped = true;
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
if (!stopped) {
|
|
134
|
+
for (let c = 0; c < len; c++) {
|
|
135
|
+
const item = items[c];
|
|
136
|
+
const [callback, options] = item;
|
|
137
|
+
if (options === null || options === void 0 ? void 0 : options.capture)
|
|
138
|
+
continue;
|
|
139
|
+
callback(event);
|
|
140
|
+
if (options === null || options === void 0 ? void 0 : options.once) {
|
|
141
|
+
indicies.push(c);
|
|
142
|
+
}
|
|
143
|
+
if (event.propagationStopped) {
|
|
144
|
+
stopped = true;
|
|
145
|
+
break;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
// Remove all once handlers
|
|
150
|
+
for (let i = indicies.length - 1; i >= 0; i--) {
|
|
151
|
+
items.splice(indicies[i], 1);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
package/package.json
CHANGED
package/src/types/EColor.ts
CHANGED
|
@@ -15,6 +15,25 @@ export class EColor {
|
|
|
15
15
|
return value;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
/**
|
|
19
|
+
* Format color
|
|
20
|
+
* @param input Input color text
|
|
21
|
+
* @param hexColor Format as Hex color
|
|
22
|
+
* @returns Result
|
|
23
|
+
*/
|
|
24
|
+
static format(input: string | undefined | null, hexColor?: boolean) {
|
|
25
|
+
// Null
|
|
26
|
+
if (input == null) return undefined;
|
|
27
|
+
|
|
28
|
+
// Like transparent, black, red
|
|
29
|
+
if (/^[a-zA-Z]+$/gi.test(input)) return input.toLowerCase();
|
|
30
|
+
|
|
31
|
+
const color = EColor.parse(input);
|
|
32
|
+
if (color == null) return undefined;
|
|
33
|
+
|
|
34
|
+
return hexColor ? color.toHEXColor() : color.toRGBColor();
|
|
35
|
+
}
|
|
36
|
+
|
|
18
37
|
/**
|
|
19
38
|
* HEX string to integer value
|
|
20
39
|
* @param hex HEX string
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { EventBase, EventClass } from './EventClass';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* ETSOO Extended history event type
|
|
5
|
+
*/
|
|
6
|
+
export type EHistoryEventType = 'navigate' | 'push' | 'replace' | 'clear';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* ETSOO Extended history event data
|
|
10
|
+
*/
|
|
11
|
+
export interface EHistoryEventData {
|
|
12
|
+
/**
|
|
13
|
+
* Current index
|
|
14
|
+
*/
|
|
15
|
+
index: number;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* ETSOO Extended abstract history class
|
|
20
|
+
*/
|
|
21
|
+
export abstract class EHistory<
|
|
22
|
+
T,
|
|
23
|
+
D extends EHistoryEventData
|
|
24
|
+
> extends EventClass<EHistoryEventType, D> {
|
|
25
|
+
// Index
|
|
26
|
+
private _index: number = -1;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* States
|
|
30
|
+
*/
|
|
31
|
+
readonly states: T[] = [];
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* States length
|
|
35
|
+
*/
|
|
36
|
+
get length() {
|
|
37
|
+
return this.states.length;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Get current state index
|
|
42
|
+
*/
|
|
43
|
+
get index() {
|
|
44
|
+
return this._index;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Get current state
|
|
49
|
+
*/
|
|
50
|
+
get state() {
|
|
51
|
+
if (this._index === -1) return undefined;
|
|
52
|
+
return this.states[this._index];
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Back to the previous state
|
|
57
|
+
*/
|
|
58
|
+
back() {
|
|
59
|
+
this.go(-1);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Clear all states but keep event listeners
|
|
64
|
+
*/
|
|
65
|
+
clear() {
|
|
66
|
+
// https://stackoverflow.com/questions/1232040/how-do-i-empty-an-array-in-javascript
|
|
67
|
+
this.states.length = 0;
|
|
68
|
+
this._index = -1;
|
|
69
|
+
this.trigger(this.createEvent('clear', this._index));
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Create event
|
|
74
|
+
* @param type Type
|
|
75
|
+
* @param index Current index
|
|
76
|
+
*/
|
|
77
|
+
protected abstract createEvent(
|
|
78
|
+
type: EHistoryEventType,
|
|
79
|
+
index: number
|
|
80
|
+
): EventBase<EHistoryEventType, D>;
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Forward to the next state
|
|
84
|
+
*/
|
|
85
|
+
forward() {
|
|
86
|
+
this.go(1);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Go to the specific state
|
|
91
|
+
* @param delta A negative value moves backwards, a positive value moves forwards
|
|
92
|
+
*/
|
|
93
|
+
go(delta: number) {
|
|
94
|
+
// No data
|
|
95
|
+
if (this._index === -1) return undefined;
|
|
96
|
+
|
|
97
|
+
// New index
|
|
98
|
+
const newIndex = this._index + delta;
|
|
99
|
+
|
|
100
|
+
// Not in the range
|
|
101
|
+
if (newIndex < 0 || newIndex >= this.length) return undefined;
|
|
102
|
+
|
|
103
|
+
// Update the index
|
|
104
|
+
this._index = newIndex;
|
|
105
|
+
|
|
106
|
+
// Trigger event
|
|
107
|
+
this.trigger(this.createEvent('navigate', newIndex));
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Adds an entry to the history stack
|
|
112
|
+
* @param state State
|
|
113
|
+
*/
|
|
114
|
+
pushState(state: T) {
|
|
115
|
+
if (this._index >= 0) {
|
|
116
|
+
// Remove states after the index
|
|
117
|
+
this.states.splice(this._index + 1);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
this.states.push(state);
|
|
121
|
+
this._index++;
|
|
122
|
+
this.trigger(this.createEvent('push', this._index));
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Modifies the current history entry
|
|
127
|
+
* @param state State
|
|
128
|
+
*/
|
|
129
|
+
replaceState(state: T) {
|
|
130
|
+
if (this._index === -1) return;
|
|
131
|
+
this.states[this._index] = state;
|
|
132
|
+
this.trigger(this.createEvent('replace', this._index));
|
|
133
|
+
}
|
|
134
|
+
}
|