@oinone/kunlun-event 6.2.0
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/dist/oinone-kunlun-event.esm.js +15 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/src/bus/abstract/AbstractEventConsumer.d.ts +17 -0
- package/dist/types/src/bus/abstract/AbstractEventEngine.d.ts +21 -0
- package/dist/types/src/bus/abstract/AbstractEventProducer.d.ts +15 -0
- package/dist/types/src/bus/abstract/index.d.ts +2 -0
- package/dist/types/src/bus/bus/basic.d.ts +12 -0
- package/dist/types/src/bus/bus/html-event.d.ts +6 -0
- package/dist/types/src/bus/bus/html-keyboard-event.d.ts +6 -0
- package/dist/types/src/bus/bus/index.d.ts +18 -0
- package/dist/types/src/bus/hook/consumer.d.ts +1 -0
- package/dist/types/src/bus/hook/index.d.ts +2 -0
- package/dist/types/src/bus/hook/producer.d.ts +1 -0
- package/dist/types/src/bus/index.d.ts +5 -0
- package/dist/types/src/bus/operator/consumer.d.ts +11 -0
- package/dist/types/src/bus/operator/index.d.ts +2 -0
- package/dist/types/src/bus/operator/producer.d.ts +10 -0
- package/dist/types/src/bus/spi/consumer.d.ts +8 -0
- package/dist/types/src/bus/spi/index.d.ts +2 -0
- package/dist/types/src/bus/spi/producer.d.ts +8 -0
- package/dist/types/src/bus/typing/basic.d.ts +64 -0
- package/dist/types/src/bus/typing/category.d.ts +5 -0
- package/dist/types/src/bus/typing/index.d.ts +3 -0
- package/dist/types/src/bus/typing/keyboard.d.ts +16 -0
- package/dist/types/src/effects/effectbox.d.ts +3 -0
- package/dist/types/src/effects/fieldEffects.d.ts +61 -0
- package/dist/types/src/effects/index.d.ts +2 -0
- package/dist/types/src/effects/viewEffects.d.ts +69 -0
- package/dist/types/src/helper.d.ts +14 -0
- package/dist/types/src/html-event/basic/AbstractHTMLEventProducer.d.ts +7 -0
- package/dist/types/src/html-event/basic/HTMLEventConsumer.d.ts +4 -0
- package/dist/types/src/html-event/basic/HTMLEventProducer.d.ts +5 -0
- package/dist/types/src/html-event/basic/index.d.ts +3 -0
- package/dist/types/src/html-event/index.d.ts +2 -0
- package/dist/types/src/html-event/keyboard/HTMLKeyboardEventConsumer.d.ts +14 -0
- package/dist/types/src/html-event/keyboard/HTMLKeyboardEventProducer.d.ts +16 -0
- package/dist/types/src/html-event/keyboard/index.d.ts +2 -0
- package/dist/types/src/index.d.ts +6 -0
- package/dist/types/src/lifecycle/heart.d.ts +75 -0
- package/dist/types/src/lifecycle/index.d.ts +2 -0
- package/dist/types/src/lifecycle/lifecycle.d.ts +7 -0
- package/dist/types/src/typing/index.d.ts +1 -0
- package/dist/types/src/typing/lifecycle.d.ts +92 -0
- package/index.ts +1 -0
- package/package.json +19 -0
- package/rollup.config.js +4 -0
- package/src/bus/abstract/AbstractEventConsumer.ts +79 -0
- package/src/bus/abstract/AbstractEventEngine.ts +79 -0
- package/src/bus/abstract/AbstractEventProducer.ts +64 -0
- package/src/bus/abstract/index.ts +2 -0
- package/src/bus/bus/basic.ts +124 -0
- package/src/bus/bus/html-event.ts +43 -0
- package/src/bus/bus/html-keyboard-event.ts +46 -0
- package/src/bus/bus/index.ts +46 -0
- package/src/bus/hook/consumer.ts +1 -0
- package/src/bus/hook/index.ts +2 -0
- package/src/bus/hook/producer.ts +1 -0
- package/src/bus/index.ts +5 -0
- package/src/bus/operator/consumer.ts +83 -0
- package/src/bus/operator/index.ts +2 -0
- package/src/bus/operator/producer.ts +56 -0
- package/src/bus/spi/consumer.ts +34 -0
- package/src/bus/spi/index.ts +2 -0
- package/src/bus/spi/producer.ts +27 -0
- package/src/bus/typing/basic.ts +126 -0
- package/src/bus/typing/category.ts +6 -0
- package/src/bus/typing/index.ts +3 -0
- package/src/bus/typing/keyboard.ts +21 -0
- package/src/effects/effectbox.ts +22 -0
- package/src/effects/fieldEffects.ts +99 -0
- package/src/effects/index.ts +2 -0
- package/src/effects/viewEffects.ts +111 -0
- package/src/helper.ts +31 -0
- package/src/html-event/basic/AbstractHTMLEventProducer.ts +30 -0
- package/src/html-event/basic/HTMLEventConsumer.ts +26 -0
- package/src/html-event/basic/HTMLEventProducer.ts +10 -0
- package/src/html-event/basic/index.ts +3 -0
- package/src/html-event/index.ts +2 -0
- package/src/html-event/keyboard/HTMLKeyboardEventConsumer.ts +160 -0
- package/src/html-event/keyboard/HTMLKeyboardEventProducer.ts +72 -0
- package/src/html-event/keyboard/index.ts +2 -0
- package/src/index.ts +6 -0
- package/src/lifecycle/heart.ts +160 -0
- package/src/lifecycle/index.ts +2 -0
- package/src/lifecycle/lifecycle.ts +29 -0
- package/src/typing/index.ts +1 -0
- package/src/typing/lifecycle.ts +104 -0
package/src/helper.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
const isType = <T>(type: string | string[]) => (obj: unknown): obj is T => getType(obj) === `[object ${type}]`;
|
|
2
|
+
const getType = (obj: any) => Object.prototype.toString.call(obj);
|
|
3
|
+
const isFn = (val: any): val is Function => typeof val === 'function';
|
|
4
|
+
const isArr = Array.isArray;
|
|
5
|
+
const isPlainObj = isType<object>('Object');
|
|
6
|
+
const isStr = isType<string>('String');
|
|
7
|
+
const isBool = isType<boolean>('Boolean');
|
|
8
|
+
const isNum = isType<number>('Number');
|
|
9
|
+
const isMap = (val: any): val is Map<any, any> => val && val instanceof Map;
|
|
10
|
+
const isSet = (val: any): val is Set<any> => val && val instanceof Set;
|
|
11
|
+
const isWeakMap = (val: any): val is WeakMap<any, any> => val && val instanceof WeakMap;
|
|
12
|
+
const isWeakSet = (val: any): val is WeakSet<any> => val && val instanceof WeakSet;
|
|
13
|
+
const isNumberLike = (index: any): index is number => isNum(index) || /^\d+$/.test(index);
|
|
14
|
+
const isObj = (val: unknown): val is object => typeof val === 'object';
|
|
15
|
+
const isRegExp = isType<RegExp>('RegExp');
|
|
16
|
+
|
|
17
|
+
export {
|
|
18
|
+
isFn,
|
|
19
|
+
isArr,
|
|
20
|
+
isPlainObj,
|
|
21
|
+
isStr,
|
|
22
|
+
isBool,
|
|
23
|
+
isNum,
|
|
24
|
+
isMap,
|
|
25
|
+
isSet,
|
|
26
|
+
isWeakMap,
|
|
27
|
+
isWeakSet,
|
|
28
|
+
isNumberLike,
|
|
29
|
+
isObj,
|
|
30
|
+
isRegExp
|
|
31
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { AbstractEventProducer, EventCategoryType, EventMessage, EventProducer, EventProducerOptions } from '../../bus';
|
|
2
|
+
|
|
3
|
+
export abstract class AbstractHTMLEventProducer<
|
|
4
|
+
K extends keyof HTMLElementEventMap,
|
|
5
|
+
EV extends HTMLElementEventMap[K] = HTMLElementEventMap[K]
|
|
6
|
+
> extends AbstractEventProducer<K, HTMLElementEventMap[K]> {
|
|
7
|
+
protected constructor(
|
|
8
|
+
category: EventCategoryType,
|
|
9
|
+
type: K,
|
|
10
|
+
options?: EventProducerOptions<K, HTMLElementEventMap[K]>
|
|
11
|
+
) {
|
|
12
|
+
super(category, type, options);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
protected $$convert(self: EventProducer<K, EV>, ev: EV): EventMessage<EV> | undefined {
|
|
16
|
+
return {
|
|
17
|
+
category: this.category,
|
|
18
|
+
type: this.type,
|
|
19
|
+
origin: ev
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
protected $$start() {
|
|
24
|
+
document.addEventListener(this.type, this.publish.bind(this));
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
protected $$stop() {
|
|
28
|
+
document.removeEventListener(this.type, this.publish.bind(this));
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AbstractEventConsumer,
|
|
3
|
+
EventCategory,
|
|
4
|
+
EventConsumerConfig,
|
|
5
|
+
EventConsumerConstructor,
|
|
6
|
+
EventConsumerFunction,
|
|
7
|
+
EventConsumerOptions,
|
|
8
|
+
EventMessage,
|
|
9
|
+
registerEventConsumer
|
|
10
|
+
} from '../../bus';
|
|
11
|
+
|
|
12
|
+
export class HTMLEventConsumer<
|
|
13
|
+
K extends keyof HTMLElementEventMap,
|
|
14
|
+
M extends EventMessage<HTMLElementEventMap[K]> = EventMessage<HTMLElementEventMap[K]>,
|
|
15
|
+
C extends EventConsumerConfig = EventConsumerConfig
|
|
16
|
+
> extends AbstractEventConsumer<K, HTMLElementEventMap[K], HTMLElementEventMap[K], M, C> {
|
|
17
|
+
public constructor(
|
|
18
|
+
type: K,
|
|
19
|
+
consumer: EventConsumerFunction<K, HTMLElementEventMap[K], HTMLElementEventMap[K], M, C>,
|
|
20
|
+
options?: EventConsumerOptions<HTMLElementEventMap[K], HTMLElementEventMap[K], M, C>
|
|
21
|
+
) {
|
|
22
|
+
super(EventCategory.html, type, consumer, options);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
registerEventConsumer({ category: EventCategory.html }, HTMLEventConsumer as EventConsumerConstructor);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { EventCategory, EventProducerConstructor, EventProducerOptions, registerEventProducer } from '../../bus';
|
|
2
|
+
import { AbstractHTMLEventProducer } from './AbstractHTMLEventProducer';
|
|
3
|
+
|
|
4
|
+
export class HTMLEventProducer<K extends keyof HTMLElementEventMap> extends AbstractHTMLEventProducer<K> {
|
|
5
|
+
public constructor(type: K, options?: EventProducerOptions<K, HTMLElementEventMap[K]>) {
|
|
6
|
+
super(EventCategory.html, type, options);
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
registerEventProducer({ category: EventCategory.html }, HTMLEventProducer as EventProducerConstructor);
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { useEnv } from '@oinone/kunlun-environment';
|
|
2
|
+
import {
|
|
3
|
+
AbstractEventConsumer,
|
|
4
|
+
EventCategory,
|
|
5
|
+
EventCategoryType,
|
|
6
|
+
EventConsumerConstructor,
|
|
7
|
+
EventConsumerFunction,
|
|
8
|
+
EventConsumerOptions,
|
|
9
|
+
EventConsumerScope,
|
|
10
|
+
HTMLKeyboardEventConsumerConfig,
|
|
11
|
+
KeyboardEventMessage,
|
|
12
|
+
KeyboardTypes,
|
|
13
|
+
registerEventConsumer
|
|
14
|
+
} from '../../bus';
|
|
15
|
+
|
|
16
|
+
type KeyboardEventConsumerOptions = EventConsumerOptions<
|
|
17
|
+
KeyboardEvent,
|
|
18
|
+
KeyboardEvent,
|
|
19
|
+
KeyboardEventMessage,
|
|
20
|
+
HTMLKeyboardEventConsumerConfig
|
|
21
|
+
>;
|
|
22
|
+
|
|
23
|
+
class AbstractKeyboardEventConsumer extends AbstractEventConsumer<
|
|
24
|
+
string,
|
|
25
|
+
KeyboardEvent,
|
|
26
|
+
KeyboardEvent,
|
|
27
|
+
KeyboardEventMessage,
|
|
28
|
+
HTMLKeyboardEventConsumerConfig
|
|
29
|
+
> {
|
|
30
|
+
public constructor(
|
|
31
|
+
category: EventCategoryType,
|
|
32
|
+
type: string,
|
|
33
|
+
consumer: EventConsumerFunction<
|
|
34
|
+
string,
|
|
35
|
+
KeyboardEvent,
|
|
36
|
+
KeyboardEvent,
|
|
37
|
+
KeyboardEventMessage,
|
|
38
|
+
HTMLKeyboardEventConsumerConfig
|
|
39
|
+
>,
|
|
40
|
+
options?: KeyboardEventConsumerOptions
|
|
41
|
+
) {
|
|
42
|
+
super(category, type, consumer, options);
|
|
43
|
+
this.initConfig();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
protected initConfig(): void {
|
|
47
|
+
const { config } = this;
|
|
48
|
+
if (config.scope == null) {
|
|
49
|
+
config.scope = EventConsumerScope.view;
|
|
50
|
+
}
|
|
51
|
+
if (config.ctrl === undefined) {
|
|
52
|
+
config.ctrl = false;
|
|
53
|
+
}
|
|
54
|
+
if (config.shift === undefined) {
|
|
55
|
+
config.shift = false;
|
|
56
|
+
}
|
|
57
|
+
if (config.alt === undefined) {
|
|
58
|
+
config.alt = false;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
protected $$filter(ev: KeyboardEvent, message: KeyboardEventMessage) {
|
|
63
|
+
const { scope, ctrl, alt, shift } = this.config;
|
|
64
|
+
let isTrigger = false;
|
|
65
|
+
switch (scope) {
|
|
66
|
+
case EventConsumerScope.global:
|
|
67
|
+
case EventConsumerScope.current:
|
|
68
|
+
isTrigger = true;
|
|
69
|
+
break;
|
|
70
|
+
case EventConsumerScope.view: {
|
|
71
|
+
const { el } = this;
|
|
72
|
+
if (!el) {
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
const { x: clientX, y: clientY } = el.getBoundingClientRect();
|
|
76
|
+
const env = useEnv();
|
|
77
|
+
const clickVisibleArea = env.clickVisibleArea[0];
|
|
78
|
+
if (clickVisibleArea) {
|
|
79
|
+
const { el: visibleEl, x, y, ex, ey } = clickVisibleArea;
|
|
80
|
+
if (visibleEl) {
|
|
81
|
+
if (visibleEl.contains(el)) {
|
|
82
|
+
isTrigger = true;
|
|
83
|
+
}
|
|
84
|
+
} else if (x <= clientX && clientX <= ex && y <= clientY && clientY <= ey) {
|
|
85
|
+
isTrigger = true;
|
|
86
|
+
break;
|
|
87
|
+
}
|
|
88
|
+
} else {
|
|
89
|
+
// fixme @zbh 20241216 此处逻辑无法闭合,暂时不启用
|
|
90
|
+
// for (const visibleArea of env.visibleArea.values()) {
|
|
91
|
+
// const { x, y, ex, ey } = visibleArea;
|
|
92
|
+
// if (x <= clientX && clientX <= ex && y <= clientY && clientY <= ey) {
|
|
93
|
+
// isTrigger = true;
|
|
94
|
+
// break;
|
|
95
|
+
// }
|
|
96
|
+
// }
|
|
97
|
+
// if (!isTrigger) {
|
|
98
|
+
// const { x, y, ex, ey } = env.contentVisibleArea;
|
|
99
|
+
// if (x <= clientX && clientX <= ex && y <= clientY && clientY <= ey) {
|
|
100
|
+
// isTrigger = true;
|
|
101
|
+
// break;
|
|
102
|
+
// }
|
|
103
|
+
// }
|
|
104
|
+
}
|
|
105
|
+
break;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
if (!isTrigger) {
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
if (ctrl != null && ctrl !== message.ctrl) {
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
if (shift != null && shift !== message.shift) {
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
if (alt != null && alt !== message.alt) {
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export class HTMLKeyboardEventConsumer extends AbstractKeyboardEventConsumer {
|
|
125
|
+
public constructor(
|
|
126
|
+
type: string,
|
|
127
|
+
consumer: EventConsumerFunction<
|
|
128
|
+
string,
|
|
129
|
+
KeyboardEvent,
|
|
130
|
+
KeyboardEvent,
|
|
131
|
+
KeyboardEventMessage,
|
|
132
|
+
HTMLKeyboardEventConsumerConfig
|
|
133
|
+
>,
|
|
134
|
+
options?: KeyboardEventConsumerOptions
|
|
135
|
+
) {
|
|
136
|
+
super(EventCategory.html, type, consumer, options);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export class KeyboardEventConsumer extends AbstractKeyboardEventConsumer {
|
|
141
|
+
public constructor(
|
|
142
|
+
type: string,
|
|
143
|
+
consumer: EventConsumerFunction<
|
|
144
|
+
string,
|
|
145
|
+
KeyboardEvent,
|
|
146
|
+
KeyboardEvent,
|
|
147
|
+
KeyboardEventMessage,
|
|
148
|
+
HTMLKeyboardEventConsumerConfig
|
|
149
|
+
>,
|
|
150
|
+
options?: KeyboardEventConsumerOptions
|
|
151
|
+
) {
|
|
152
|
+
super(EventCategory.keyboard, type, consumer, options);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
registerEventConsumer(
|
|
157
|
+
{ category: EventCategory.html, type: KeyboardTypes },
|
|
158
|
+
HTMLKeyboardEventConsumer as EventConsumerConstructor
|
|
159
|
+
);
|
|
160
|
+
registerEventConsumer({ category: EventCategory.keyboard }, KeyboardEventConsumer as EventConsumerConstructor);
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { KeyboardEventHelper } from '@oinone/kunlun-shared';
|
|
2
|
+
import {
|
|
3
|
+
EventCategory,
|
|
4
|
+
EventProducer,
|
|
5
|
+
EventProducerConstructor,
|
|
6
|
+
EventProducerOptions,
|
|
7
|
+
KeyboardEventMessage,
|
|
8
|
+
KeyboardType,
|
|
9
|
+
KeyboardTypes,
|
|
10
|
+
registerEventProducer
|
|
11
|
+
} from '../../bus';
|
|
12
|
+
import { AbstractHTMLEventProducer } from '../basic';
|
|
13
|
+
|
|
14
|
+
abstract class AbstractHTMLKeyboardEventProducer<K extends KeyboardType> extends AbstractHTMLEventProducer<
|
|
15
|
+
K,
|
|
16
|
+
KeyboardEvent
|
|
17
|
+
> {
|
|
18
|
+
protected $$convert(self: EventProducer<K, KeyboardEvent>, ev: KeyboardEvent): KeyboardEventMessage | undefined {
|
|
19
|
+
const helper = KeyboardEventHelper.newInstance(ev);
|
|
20
|
+
if (helper.isStateKey()) {
|
|
21
|
+
return undefined;
|
|
22
|
+
}
|
|
23
|
+
return {
|
|
24
|
+
category: this.category,
|
|
25
|
+
type: this.type,
|
|
26
|
+
origin: ev,
|
|
27
|
+
code: ev.code,
|
|
28
|
+
key: ev.key,
|
|
29
|
+
ctrl: helper.isPressCtrl(),
|
|
30
|
+
alt: helper.isPressAlt(),
|
|
31
|
+
shift: helper.isPressShift()
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export class HTMLKeyboardEventProducer<K extends KeyboardType> extends AbstractHTMLKeyboardEventProducer<K> {
|
|
37
|
+
public constructor(type: K, options?: EventProducerOptions<K, KeyboardEvent>) {
|
|
38
|
+
super(EventCategory.html, type, options);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export class KeyboardEventProducer<K extends KeyboardType> extends AbstractHTMLKeyboardEventProducer<K> {
|
|
43
|
+
public constructor(type: K, options?: EventProducerOptions<K, KeyboardEvent>) {
|
|
44
|
+
super(EventCategory.keyboard, type, options);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
protected $$convert(self: EventProducer<K, KeyboardEvent>, ev: KeyboardEvent): KeyboardEventMessage | undefined {
|
|
48
|
+
const message = super.$$convert(self, ev);
|
|
49
|
+
if (message) {
|
|
50
|
+
message.type = ev.key;
|
|
51
|
+
}
|
|
52
|
+
return message;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
protected onKeydown(ev: KeyboardEvent) {
|
|
56
|
+
this.publish(ev);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
protected $$start() {
|
|
60
|
+
document.addEventListener('keydown', this.onKeydown.bind(this));
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
protected $$stop() {
|
|
64
|
+
document.removeEventListener('keydown', this.onKeydown.bind(this));
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
registerEventProducer(
|
|
69
|
+
{ category: EventCategory.html, type: KeyboardTypes },
|
|
70
|
+
HTMLKeyboardEventProducer as EventProducerConstructor
|
|
71
|
+
);
|
|
72
|
+
registerEventProducer({ category: EventCategory.keyboard }, KeyboardEventProducer as EventProducerConstructor);
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { isStr } from '../helper';
|
|
2
|
+
import { LifeCycle } from './lifecycle';
|
|
3
|
+
import { LifeCycleTypes, RegistryType } from '../typing';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* HeartLifeCycles = [{
|
|
7
|
+
* registryType: Field,
|
|
8
|
+
* type: onFieldChange,
|
|
9
|
+
* pattern: {
|
|
10
|
+
* identifier: displayName
|
|
11
|
+
* lifes: [LifeCycle]
|
|
12
|
+
* }
|
|
13
|
+
* }]
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
type HeartLifeCycles = {
|
|
17
|
+
type: LifeCycleTypes;
|
|
18
|
+
registryType: RegistryType;
|
|
19
|
+
pattern: {
|
|
20
|
+
identifier: string;
|
|
21
|
+
lifes: LifeCycle[];
|
|
22
|
+
}[];
|
|
23
|
+
}[];
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* 操作生命周期的api
|
|
27
|
+
*/
|
|
28
|
+
class LifeCycleHeart {
|
|
29
|
+
private static lifeCycles: HeartLifeCycles = [];
|
|
30
|
+
|
|
31
|
+
private static heartType: RegistryType | null = null;
|
|
32
|
+
|
|
33
|
+
static initialize(lifeCycles: HeartLifeCycles) {
|
|
34
|
+
this.lifeCycles = lifeCycles;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
private static getLifeCycleIndex(type: LifeCycleTypes) {
|
|
38
|
+
return this.lifeCycles.findIndex((l) => l.type === type);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
static getLifeCycle() {
|
|
42
|
+
return this.lifeCycles;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
static getLifeCycleByType(type: LifeCycleTypes) {
|
|
46
|
+
const index = this.getLifeCycleIndex(type);
|
|
47
|
+
|
|
48
|
+
if (index >= 0) {
|
|
49
|
+
return this.lifeCycles[index];
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* 设置生命周期的注册类型,
|
|
57
|
+
*
|
|
58
|
+
* @param {registryType} RegistryType 类型
|
|
59
|
+
*/
|
|
60
|
+
static setType(registryType: RegistryType) {
|
|
61
|
+
this.heartType = registryType;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* 设置生命周期
|
|
66
|
+
* 调用该函数之前要先调用 `setType` 设置注册类型
|
|
67
|
+
*
|
|
68
|
+
* @param {type} LifeCycleTypes 生命周期的类型
|
|
69
|
+
* @param {identifier} string 唯一标识符
|
|
70
|
+
* @param {lifeCycle} LifeCycle 生命周期的实例
|
|
71
|
+
*
|
|
72
|
+
*/
|
|
73
|
+
static setLifeCycle(type: LifeCycleTypes, identifier: string, lifeCycle: LifeCycle) {
|
|
74
|
+
if (!isStr(type) || !isStr(identifier) || !(lifeCycle instanceof LifeCycle)) {
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (!this.heartType) {
|
|
79
|
+
throw new Error(`set fail, use "LifeCycleHeart.setType(type)" first, then call "setLifeCycle"`);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const index = this.getLifeCycleIndex(type);
|
|
83
|
+
|
|
84
|
+
if (index >= 0) {
|
|
85
|
+
if (identifier) {
|
|
86
|
+
this.lifeCycles[index].pattern.push({
|
|
87
|
+
identifier,
|
|
88
|
+
lifes: [lifeCycle]
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
} else {
|
|
92
|
+
this.lifeCycles.push({
|
|
93
|
+
type,
|
|
94
|
+
registryType: this.heartType,
|
|
95
|
+
pattern: [
|
|
96
|
+
{
|
|
97
|
+
identifier,
|
|
98
|
+
lifes: [lifeCycle]
|
|
99
|
+
}
|
|
100
|
+
]
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
this.heartType = null;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* 触发生命周期的回调函数
|
|
109
|
+
*
|
|
110
|
+
* @param {type} LifeCycleTypes 生命周期的类型
|
|
111
|
+
* @param {identifier} string 唯一标识符
|
|
112
|
+
* @param {ctx} Context 当前「视图/字段/Action」的上下文
|
|
113
|
+
*/
|
|
114
|
+
static publish<C = any>(type: LifeCycleTypes, identifier: string, ctx: C) {
|
|
115
|
+
if (!type || !identifier || !ctx) {
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const index = this.getLifeCycleIndex(type);
|
|
120
|
+
|
|
121
|
+
if (index >= 0 && identifier) {
|
|
122
|
+
const pattern = this.lifeCycles[index].pattern.find((p) => p.identifier === identifier);
|
|
123
|
+
if (pattern) {
|
|
124
|
+
pattern.lifes.forEach((l) => {
|
|
125
|
+
l.notify(ctx);
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* @deprecated 销毁生命周期
|
|
133
|
+
*
|
|
134
|
+
* @param {identifier} string 唯一标识符
|
|
135
|
+
*/
|
|
136
|
+
static disposeLifeCycle(identifier: string) {
|
|
137
|
+
// this.lifeCycles.forEach((life) => {
|
|
138
|
+
// const index = life.pattern.findIndex((l) => l.identifier === identifier);
|
|
139
|
+
// if (index >= 0) {
|
|
140
|
+
// life.pattern.splice(index, 1);
|
|
141
|
+
// }
|
|
142
|
+
// });
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* 销毁生命周期
|
|
147
|
+
*
|
|
148
|
+
* @param {identifier} string 唯一标识符
|
|
149
|
+
*/
|
|
150
|
+
static dispose(identifier: string) {
|
|
151
|
+
this.lifeCycles.forEach((life) => {
|
|
152
|
+
const index = life.pattern.findIndex((l) => l.identifier === identifier);
|
|
153
|
+
if (index >= 0) {
|
|
154
|
+
life.pattern.splice(index, 1);
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export { LifeCycleHeart };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { isFn } from '../helper';
|
|
2
|
+
|
|
3
|
+
type LifeCyclePayload<Context = any> = (context: Context) => void;
|
|
4
|
+
|
|
5
|
+
class LifeCycle<Context = any> {
|
|
6
|
+
private listener!: LifeCyclePayload<Context>;
|
|
7
|
+
|
|
8
|
+
constructor(callback?: (ctx: Context) => void) {
|
|
9
|
+
if (!isFn(callback)) {
|
|
10
|
+
throw new Error('life cycle callback must be function');
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
this.listener = this.buildListener(callback);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
private buildListener(callback?: Function): LifeCyclePayload {
|
|
17
|
+
return (ctx?: Context) => {
|
|
18
|
+
if (isFn(callback)) {
|
|
19
|
+
callback(ctx);
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
public notify(ctx: Context) {
|
|
25
|
+
this.listener.call(ctx, ctx);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export { LifeCycle };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './lifecycle';
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
export enum RegistryType {
|
|
2
|
+
FIELD = 'Field',
|
|
3
|
+
VIEW = 'View',
|
|
4
|
+
ACTION = 'Action'
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export enum LifeCycleTypes {
|
|
8
|
+
/**
|
|
9
|
+
* View LifeCycle
|
|
10
|
+
* */
|
|
11
|
+
|
|
12
|
+
ON_VIEW_BEFORE_CREATED = 'onViewBeforeCreated', // 创建之前
|
|
13
|
+
ON_VIEW_CREATED = 'onViewCreated', // 创建成功
|
|
14
|
+
ON_VIEW_BEFORE_MOUNT = 'onViewBeforeMount', // 挂载前
|
|
15
|
+
ON_VIEW_MOUNTED = 'onViewMounted', // 挂载成功
|
|
16
|
+
ON_VIEW_BEFORE_UPDATE = 'onViewBeforeUpdate', // 修改前
|
|
17
|
+
ON_VIEW_UPDATED = 'onViewUpdated', // 修改后
|
|
18
|
+
ON_VIEW_ACTIVATED = 'onViewActivated',
|
|
19
|
+
ON_VIEW_BEFORE_UNMOUNT = 'onViewBeforeUnmount', // 销毁前
|
|
20
|
+
ON_VIEW_UNMOUNTED = 'onViewUnmounted', // 销毁
|
|
21
|
+
|
|
22
|
+
ON_VIEW_SUBMIT = 'onViewSubmit', // 提交数据
|
|
23
|
+
ON_VIEW_SUBMIT_START = 'onViewSubmitStart', // 数据提交前
|
|
24
|
+
ON_VIEW_SUBMIT_END = 'onViewSubmitEnd', // 数据提交后
|
|
25
|
+
ON_VIEW_SUBMIT_SUCCESS = 'onViewSubmitSuccess', // 数据提交成功
|
|
26
|
+
ON_VIEW_SUBMIT_FAILED = 'onViewSubmitFailed', // 数据提交失败
|
|
27
|
+
|
|
28
|
+
ON_VIEW_VALIDATE_START = 'onViewValidateStart', // 字段校验前
|
|
29
|
+
ON_VIEW_VALIDATE_SUCCESS = 'onViewValidateSuccess', // 字段校验成功
|
|
30
|
+
ON_VIEW_VALIDATE_FAILED = 'onViewValidateFailed', // 字段校验失败
|
|
31
|
+
ON_VIEW_VALIDATE_END = 'onViewValidateEnd', // 字段校验结束
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Field LifeCycle
|
|
35
|
+
* */
|
|
36
|
+
|
|
37
|
+
ON_FIELD_BEFORE_CREATED = 'onFieldBeforeCreated', // 创建之前
|
|
38
|
+
ON_FIELD_CREATED = 'onFieldCreated', // 创建成功
|
|
39
|
+
ON_FIELD_BEFORE_MOUNT = 'onFieldBeforeMount', // 挂载前
|
|
40
|
+
ON_FIELD_MOUNTED = 'onFieldMounted', // 挂载成功
|
|
41
|
+
ON_FIELD_BEFORE_UPDATE = 'onFieldBeforeUpdate', // 修改前
|
|
42
|
+
ON_FIELD_UPDATED = 'onFieldUpdated', // 修改后
|
|
43
|
+
ON_FIELD_ACTIVATED = 'onFieldActivated',
|
|
44
|
+
ON_FIELD_BEFORE_UNMOUNT = 'onFieldBeforeUnmount', // 销毁前
|
|
45
|
+
ON_FIELD_UNMOUNTED = 'onFieldUnmounted', // 销毁
|
|
46
|
+
|
|
47
|
+
ON_FIELD_FOCUS = 'onFieldFocus', // 字段获取焦点
|
|
48
|
+
ON_FIELD_CHANGE = 'onFieldChange', // 字段数据发生了改变
|
|
49
|
+
ON_FIELD_BLUR = 'onFieldBlur', // 字段失焦
|
|
50
|
+
|
|
51
|
+
ON_FIELD_VALIDATE_START = 'onFieldValidateStart', // 字段校验前
|
|
52
|
+
ON_FIELD_VALIDATE_SUCCESS = 'onFieldValidateSuccess', // 字段校验成功
|
|
53
|
+
ON_FIELD_VALIDATE_FAILED = 'onFieldValidateFailed', // 字段校验失败
|
|
54
|
+
ON_FIELD_VALIDATE_END = 'onFieldValidateEnd' // 字段校验结束
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* View internal event
|
|
59
|
+
*/
|
|
60
|
+
export enum ViewEventNames {
|
|
61
|
+
viewBeforeCreated = LifeCycleTypes.ON_VIEW_BEFORE_CREATED,
|
|
62
|
+
viewCreated = LifeCycleTypes.ON_VIEW_CREATED,
|
|
63
|
+
viewBeforeMount = LifeCycleTypes.ON_VIEW_BEFORE_MOUNT,
|
|
64
|
+
viewMounted = LifeCycleTypes.ON_VIEW_MOUNTED,
|
|
65
|
+
viewBeforeUpdate = LifeCycleTypes.ON_VIEW_BEFORE_UPDATE,
|
|
66
|
+
viewUpdated = LifeCycleTypes.ON_VIEW_UPDATED,
|
|
67
|
+
viewActivated = LifeCycleTypes.ON_VIEW_ACTIVATED,
|
|
68
|
+
viewBeforeUnmount = LifeCycleTypes.ON_VIEW_BEFORE_UNMOUNT,
|
|
69
|
+
viewUnmounted = LifeCycleTypes.ON_VIEW_UNMOUNTED,
|
|
70
|
+
viewSubmit = LifeCycleTypes.ON_VIEW_SUBMIT,
|
|
71
|
+
viewSubmitStart = LifeCycleTypes.ON_VIEW_SUBMIT_START,
|
|
72
|
+
viewSubmitEnd = LifeCycleTypes.ON_VIEW_SUBMIT_END,
|
|
73
|
+
viewSubmitSuccess = LifeCycleTypes.ON_VIEW_SUBMIT_SUCCESS,
|
|
74
|
+
viewSubmitFailed = LifeCycleTypes.ON_VIEW_SUBMIT_FAILED,
|
|
75
|
+
viewValidateStart = LifeCycleTypes.ON_VIEW_VALIDATE_START,
|
|
76
|
+
viewValidateSuccess = LifeCycleTypes.ON_VIEW_VALIDATE_SUCCESS,
|
|
77
|
+
viewValidateFailed = LifeCycleTypes.ON_VIEW_VALIDATE_FAILED,
|
|
78
|
+
viewValidateEnd = LifeCycleTypes.ON_VIEW_VALIDATE_END
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export type ViewEventName = keyof typeof ViewEventNames;
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Field internal event
|
|
85
|
+
*/
|
|
86
|
+
export enum FieldEventNames {
|
|
87
|
+
beforeCreated = LifeCycleTypes.ON_FIELD_BEFORE_CREATED,
|
|
88
|
+
created = LifeCycleTypes.ON_FIELD_CREATED,
|
|
89
|
+
beforeMount = LifeCycleTypes.ON_FIELD_BEFORE_MOUNT,
|
|
90
|
+
mount = LifeCycleTypes.ON_FIELD_MOUNTED,
|
|
91
|
+
beforeUpdate = LifeCycleTypes.ON_FIELD_BEFORE_UPDATE,
|
|
92
|
+
updated = LifeCycleTypes.ON_VIEW_UPDATED,
|
|
93
|
+
beforeUnmount = LifeCycleTypes.ON_FIELD_BEFORE_UNMOUNT,
|
|
94
|
+
unmounted = LifeCycleTypes.ON_FIELD_UNMOUNTED,
|
|
95
|
+
focus = LifeCycleTypes.ON_FIELD_FOCUS,
|
|
96
|
+
change = LifeCycleTypes.ON_FIELD_CHANGE,
|
|
97
|
+
blur = LifeCycleTypes.ON_FIELD_BLUR,
|
|
98
|
+
validateStart = LifeCycleTypes.ON_FIELD_VALIDATE_START,
|
|
99
|
+
validateSuccess = LifeCycleTypes.ON_FIELD_VALIDATE_SUCCESS,
|
|
100
|
+
validateFailed = LifeCycleTypes.ON_FIELD_VALIDATE_FAILED,
|
|
101
|
+
validateEnd = LifeCycleTypes.ON_FIELD_VALIDATE_END
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export type FieldEventName = keyof typeof FieldEventNames;
|