@etsoo/shared 1.1.24 → 1.1.27

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 CHANGED
@@ -34,6 +34,16 @@ Etsoo implmented Color
34
34
  |toLabValue|To Lab value|
35
35
  |toRGBColor|To RGB color string|
36
36
 
37
+ ## EventClass
38
+ Etsoo implmented abstract Event Class
39
+
40
+ |Name|Description|
41
+ |---:|---|
42
+ |hasEvents|Has specific type and callback events|
43
+ |off|Remove specific type and callback event|
44
+ |on|Add event listener|
45
+ |trigger|Trigger event|
46
+
37
47
  ## Keyboard
38
48
  Keyboard keys and codes
39
49
 
@@ -44,6 +54,23 @@ Keyboard keys and codes
44
54
 
45
55
  |isTypingContent|Is typing content or press command key|
46
56
 
57
+ ## EHistory
58
+ ETSOO Extended abstract history class
59
+
60
+ |Name|Description|
61
+ |---:|---|
62
+ |index|Current index|
63
+ |length|States length|
64
+ |state|Current state|
65
+ |states|States|
66
+
67
+ |back|Back to the previous state|
68
+ |clear|Clear all states but keep event listeners|
69
+ |forward|Forward to the next state|
70
+ |go|Go to the specific state|
71
+ |pushState|Adds an entry to the history stack|
72
+ |replaceState|Modifies the current history entry|
73
+
47
74
  ## DataTypes
48
75
  Data type definitions and type safe functions
49
76
 
@@ -1,6 +1,13 @@
1
1
  import { EColor } from '../src/types/EColor';
2
2
  import { ColorUtils } from '../src/ColorUtils';
3
3
 
4
+ test('Tests for format', () => {
5
+ expect(EColor.format('transparent')).toBe('transparent');
6
+ expect(EColor.format('RED')).toBe('red');
7
+ expect(EColor.format('RGB(226, 24, 33)', true)).toBe('#e21821');
8
+ expect(EColor.format('RGB(226, 24, 33)')).toBe('RGB(226, 24, 33)');
9
+ });
10
+
4
11
  test('Tests for parse', () => {
5
12
  // Arrange & act
6
13
  const colorShort = EColor.parse('#000');
@@ -0,0 +1,81 @@
1
+ import {
2
+ EHistory,
3
+ EHistoryEventData,
4
+ EHistoryEventType
5
+ } from '../src/types/EHistory';
6
+ import { EventBase } from '../src/types/EventClass';
7
+
8
+ // Extended for tests
9
+ class LHistoryEvent extends EventBase<EHistoryEventType, EHistoryEventData> {}
10
+ class LHistory extends EHistory<number, EHistoryEventData> {
11
+ protected createEvent(type: EHistoryEventType, index: number) {
12
+ return new LHistoryEvent(this, type, { index });
13
+ }
14
+ }
15
+
16
+ test('Tests for history', () => {
17
+ const history = new LHistory();
18
+ expect(history.index).toBe(-1);
19
+ history.pushState(1);
20
+ history.pushState(2);
21
+ history.pushState(3);
22
+ expect(history.states).toStrictEqual([1, 2, 3]);
23
+ expect(history.index).toBe(2);
24
+ history.back();
25
+ history.pushState(4);
26
+ expect(history.index).toBe(2);
27
+ expect(history.states).toStrictEqual([1, 2, 4]);
28
+ history.go(-2);
29
+ expect(history.state).toBe(1);
30
+ history.forward();
31
+ expect(history.index).toBe(1);
32
+ history.replaceState(0);
33
+ expect(history.state).toBe(0);
34
+ history.clear();
35
+ expect(history.length).toBe(0);
36
+ });
37
+
38
+ test('Tests for events', () => {
39
+ const navigatorFn = jest.fn();
40
+ const navigatorStopFn = jest.fn((event: LHistoryEvent) => {
41
+ event.stopImmediatePropagation();
42
+ });
43
+ const clearFn = jest.fn();
44
+ const pushFn = jest.fn();
45
+ const replaceFn = jest.fn();
46
+
47
+ const history = new LHistory();
48
+
49
+ history.on({
50
+ clear: clearFn,
51
+ push: pushFn,
52
+ replace: replaceFn,
53
+ navigate: navigatorFn
54
+ });
55
+ history.on('navigate', navigatorFn);
56
+ history.on('navigate', navigatorFn, { capture: true, once: true });
57
+
58
+ history.clear();
59
+ expect(clearFn).toBeCalled();
60
+
61
+ history.pushState(1);
62
+ expect(pushFn).toBeCalled();
63
+
64
+ history.replaceState(11);
65
+ expect(replaceFn).toBeCalled();
66
+
67
+ history.pushState(2);
68
+ history.back();
69
+ expect(navigatorFn).toBeCalledTimes(3);
70
+
71
+ history.forward();
72
+ // Once handler was removed
73
+ expect(navigatorFn).toBeCalledTimes(5);
74
+
75
+ history.on('navigate', navigatorStopFn, { capture: true });
76
+ history.go(-1);
77
+ expect(navigatorStopFn).toBeCalled();
78
+
79
+ // Previous handler stopped propagation
80
+ expect(navigatorFn).toBeCalledTimes(5);
81
+ });
@@ -2,9 +2,11 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.NumberUtils = void 0;
4
4
  Number.prototype.toExact = function (precision) {
5
- if (precision == null || precision < 1)
6
- precision = 4;
7
- const p = Math.pow(10, precision !== null && precision !== void 0 ? precision : 4);
5
+ if (precision == null || precision < 0)
6
+ precision = 2;
7
+ if (precision === 0)
8
+ return Math.round(this);
9
+ const p = Math.pow(10, precision);
8
10
  return Math.round(this * p) / p;
9
11
  };
10
12
  var NumberUtils;
@@ -13,6 +13,13 @@ export declare class EColor {
13
13
  * @returns Adjusted value
14
14
  */
15
15
  static adjust(value: number, adjust?: number): number;
16
+ /**
17
+ * Format color
18
+ * @param input Input color text
19
+ * @param hexColor Format as Hex color
20
+ * @returns Result
21
+ */
22
+ static format(input: string | undefined | null, hexColor?: boolean): string | undefined;
16
23
  /**
17
24
  * HEX string to integer value
18
25
  * @param hex HEX string
@@ -32,6 +32,24 @@ class EColor {
32
32
  return value % 255;
33
33
  return value;
34
34
  }
35
+ /**
36
+ * Format color
37
+ * @param input Input color text
38
+ * @param hexColor Format as Hex color
39
+ * @returns Result
40
+ */
41
+ static format(input, hexColor) {
42
+ // Null
43
+ if (input == null)
44
+ return undefined;
45
+ // Like transparent, black, red
46
+ if (/^[a-zA-Z]+$/gi.test(input))
47
+ return input.toLowerCase();
48
+ const color = EColor.parse(input);
49
+ if (color == null)
50
+ return undefined;
51
+ return hexColor ? color.toHEXColor() : color.toRGBColor();
52
+ }
35
53
  /**
36
54
  * HEX string to integer value
37
55
  * @param hex HEX string
@@ -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,101 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EHistory = void 0;
4
+ const EventClass_1 = require("./EventClass");
5
+ /**
6
+ * ETSOO Extended abstract history class
7
+ */
8
+ class EHistory extends EventClass_1.EventClass {
9
+ constructor() {
10
+ super(...arguments);
11
+ // Index
12
+ this._index = -1;
13
+ /**
14
+ * States
15
+ */
16
+ this.states = [];
17
+ }
18
+ /**
19
+ * States length
20
+ */
21
+ get length() {
22
+ return this.states.length;
23
+ }
24
+ /**
25
+ * Get current state index
26
+ */
27
+ get index() {
28
+ return this._index;
29
+ }
30
+ /**
31
+ * Get current state
32
+ */
33
+ get state() {
34
+ if (this._index === -1)
35
+ return undefined;
36
+ return this.states[this._index];
37
+ }
38
+ /**
39
+ * Back to the previous state
40
+ */
41
+ back() {
42
+ this.go(-1);
43
+ }
44
+ /**
45
+ * Clear all states but keep event listeners
46
+ */
47
+ clear() {
48
+ // https://stackoverflow.com/questions/1232040/how-do-i-empty-an-array-in-javascript
49
+ this.states.length = 0;
50
+ this._index = -1;
51
+ this.trigger(this.createEvent('clear', this._index));
52
+ }
53
+ /**
54
+ * Forward to the next state
55
+ */
56
+ forward() {
57
+ this.go(1);
58
+ }
59
+ /**
60
+ * Go to the specific state
61
+ * @param delta A negative value moves backwards, a positive value moves forwards
62
+ */
63
+ go(delta) {
64
+ // No data
65
+ if (this._index === -1)
66
+ return undefined;
67
+ // New index
68
+ const newIndex = this._index + delta;
69
+ // Not in the range
70
+ if (newIndex < 0 || newIndex >= this.length)
71
+ return undefined;
72
+ // Update the index
73
+ this._index = newIndex;
74
+ // Trigger event
75
+ this.trigger(this.createEvent('navigate', newIndex));
76
+ }
77
+ /**
78
+ * Adds an entry to the history stack
79
+ * @param state State
80
+ */
81
+ pushState(state) {
82
+ if (this._index >= 0) {
83
+ // Remove states after the index
84
+ this.states.splice(this._index + 1);
85
+ }
86
+ this.states.push(state);
87
+ this._index++;
88
+ this.trigger(this.createEvent('push', this._index));
89
+ }
90
+ /**
91
+ * Modifies the current history entry
92
+ * @param state State
93
+ */
94
+ replaceState(state) {
95
+ if (this._index === -1)
96
+ return;
97
+ this.states[this._index] = state;
98
+ this.trigger(this.createEvent('replace', this._index));
99
+ }
100
+ }
101
+ exports.EHistory = EHistory;
@@ -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,159 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EventClass = exports.EventBase = void 0;
4
+ /**
5
+ * Abstract event base class
6
+ * T for type
7
+ * D for data
8
+ */
9
+ class EventBase {
10
+ /**
11
+ * Constructor
12
+ * @param type Type
13
+ */
14
+ constructor(target, type, data) {
15
+ this.target = target;
16
+ this.type = type;
17
+ this.data = data;
18
+ this._propagationStopped = false;
19
+ this._timeStamp = Date.now();
20
+ }
21
+ /**
22
+ * stopImmediatePropagation called
23
+ */
24
+ get propagationStopped() {
25
+ return this._propagationStopped;
26
+ }
27
+ /**
28
+ * Time stamp
29
+ */
30
+ get timeStamp() {
31
+ return this._timeStamp;
32
+ }
33
+ /**
34
+ * Prevent all other listeners from being called
35
+ */
36
+ stopImmediatePropagation() {
37
+ this._propagationStopped = true;
38
+ }
39
+ }
40
+ exports.EventBase = EventBase;
41
+ /**
42
+ * Event class
43
+ * T for type
44
+ * D for data
45
+ */
46
+ class EventClass {
47
+ constructor() {
48
+ // Listeners
49
+ this.listeners = new Map();
50
+ }
51
+ /**
52
+ * Has specific type and callback events
53
+ * @param type Type
54
+ * @param callback Callback
55
+ * @returns Result
56
+ */
57
+ hasEvents(type, callback) {
58
+ const items = this.listeners.get(type);
59
+ if (items == null || items.length === 0)
60
+ return false;
61
+ if (callback) {
62
+ return items.some((item) => item[0] == callback);
63
+ }
64
+ return true;
65
+ }
66
+ /**
67
+ * Remove specific type and callback event
68
+ * @param type Type
69
+ * @param callback Callback
70
+ */
71
+ off(type, callback) {
72
+ if (callback == null) {
73
+ this.listeners.delete(type);
74
+ return;
75
+ }
76
+ const items = this.listeners.get(type);
77
+ if (items == null)
78
+ return;
79
+ for (let i = items.length - 1; i >= 0; i--) {
80
+ if (items[i][0] == callback) {
81
+ items.splice(i, 1);
82
+ }
83
+ }
84
+ }
85
+ /**
86
+ * Add events
87
+ * @param type Type
88
+ * @param callback Callback
89
+ * @param options Options
90
+ */
91
+ on(type, callback, options) {
92
+ var _a, _b;
93
+ if (typeof type === 'object') {
94
+ for (const key in type) {
95
+ const item = key;
96
+ const itemCallback = (_a = type[item]) !== null && _a !== void 0 ? _a : callback;
97
+ if (itemCallback)
98
+ this.on(item, itemCallback, options);
99
+ }
100
+ return;
101
+ }
102
+ if (callback == null)
103
+ return;
104
+ this.listeners.has(type) || this.listeners.set(type, []);
105
+ (_b = this.listeners.get(type)) === null || _b === void 0 ? void 0 : _b.push([callback, options]);
106
+ }
107
+ /**
108
+ * Trigger event
109
+ * @param event Event
110
+ */
111
+ trigger(event) {
112
+ const items = this.listeners.get(event.type);
113
+ if (items == null)
114
+ return;
115
+ // Len
116
+ const len = items.length;
117
+ if (len === 0)
118
+ return;
119
+ // Need to be removed indicies
120
+ const indicies = [];
121
+ // Capture items first
122
+ let stopped = false;
123
+ for (let c = 0; c < len; c++) {
124
+ const item = items[c];
125
+ const [callback, options] = item;
126
+ if (options == null || !options.capture)
127
+ continue;
128
+ callback(event);
129
+ if (options.once) {
130
+ indicies.push(c);
131
+ }
132
+ if (event.propagationStopped) {
133
+ stopped = true;
134
+ break;
135
+ }
136
+ }
137
+ if (!stopped) {
138
+ for (let c = 0; c < len; c++) {
139
+ const item = items[c];
140
+ const [callback, options] = item;
141
+ if (options === null || options === void 0 ? void 0 : options.capture)
142
+ continue;
143
+ callback(event);
144
+ if (options === null || options === void 0 ? void 0 : options.once) {
145
+ indicies.push(c);
146
+ }
147
+ if (event.propagationStopped) {
148
+ stopped = true;
149
+ break;
150
+ }
151
+ }
152
+ }
153
+ // Remove all once handlers
154
+ for (let i = indicies.length - 1; i >= 0; i--) {
155
+ items.splice(indicies[i], 1);
156
+ }
157
+ }
158
+ }
159
+ exports.EventClass = EventClass;
@@ -1,7 +1,9 @@
1
1
  Number.prototype.toExact = function (precision) {
2
- if (precision == null || precision < 1)
3
- precision = 4;
4
- const p = Math.pow(10, precision !== null && precision !== void 0 ? precision : 4);
2
+ if (precision == null || precision < 0)
3
+ precision = 2;
4
+ if (precision === 0)
5
+ return Math.round(this);
6
+ const p = Math.pow(10, precision);
5
7
  return Math.round(this * p) / p;
6
8
  };
7
9
  export var NumberUtils;
@@ -13,6 +13,13 @@ export declare class EColor {
13
13
  * @returns Adjusted value
14
14
  */
15
15
  static adjust(value: number, adjust?: number): number;
16
+ /**
17
+ * Format color
18
+ * @param input Input color text
19
+ * @param hexColor Format as Hex color
20
+ * @returns Result
21
+ */
22
+ static format(input: string | undefined | null, hexColor?: boolean): string | undefined;
16
23
  /**
17
24
  * HEX string to integer value
18
25
  * @param hex HEX string
@@ -29,6 +29,24 @@ export class EColor {
29
29
  return value % 255;
30
30
  return value;
31
31
  }
32
+ /**
33
+ * Format color
34
+ * @param input Input color text
35
+ * @param hexColor Format as Hex color
36
+ * @returns Result
37
+ */
38
+ static format(input, hexColor) {
39
+ // Null
40
+ if (input == null)
41
+ return undefined;
42
+ // Like transparent, black, red
43
+ if (/^[a-zA-Z]+$/gi.test(input))
44
+ return input.toLowerCase();
45
+ const color = EColor.parse(input);
46
+ if (color == null)
47
+ return undefined;
48
+ return hexColor ? color.toHEXColor() : color.toRGBColor();
49
+ }
32
50
  /**
33
51
  * HEX string to integer value
34
52
  * @param hex HEX string