1 | import * as React from 'react';
|
2 |
|
3 |
|
4 |
|
5 |
|
6 | export default function useEventEmitter(listen) {
|
7 | const listenRef = React.useRef(listen);
|
8 | React.useEffect(() => {
|
9 | listenRef.current = listen;
|
10 | });
|
11 | const listeners = React.useRef(Object.create(null));
|
12 | const create = React.useCallback(target => {
|
13 | const removeListener = (type, callback) => {
|
14 | const callbacks = listeners.current[type] ? listeners.current[type][target] : undefined;
|
15 |
|
16 | if (!callbacks) {
|
17 | return;
|
18 | }
|
19 |
|
20 | const index = callbacks.indexOf(callback);
|
21 |
|
22 | if (index > -1) {
|
23 | callbacks.splice(index, 1);
|
24 | }
|
25 | };
|
26 |
|
27 | const addListener = (type, callback) => {
|
28 | listeners.current[type] = listeners.current[type] || {};
|
29 | listeners.current[type][target] = listeners.current[type][target] || [];
|
30 | listeners.current[type][target].push(callback);
|
31 | let removed = false;
|
32 | return () => {
|
33 |
|
34 | if (!removed) {
|
35 | removed = true;
|
36 | removeListener(type, callback);
|
37 | }
|
38 | };
|
39 | };
|
40 |
|
41 | return {
|
42 | addListener,
|
43 | removeListener
|
44 | };
|
45 | }, []);
|
46 | const emit = React.useCallback(_ref => {
|
47 | var _items$target, _listenRef$current;
|
48 |
|
49 | let {
|
50 | type,
|
51 | data,
|
52 | target,
|
53 | canPreventDefault
|
54 | } = _ref;
|
55 | const items = listeners.current[type] || {};
|
56 |
|
57 | const callbacks = target !== undefined ? (_items$target = items[target]) === null || _items$target === void 0 ? void 0 : _items$target.slice() : [].concat(...Object.keys(items).map(t => items[t])).filter((cb, i, self) => self.lastIndexOf(cb) === i);
|
58 | const event = {
|
59 | get type() {
|
60 | return type;
|
61 | }
|
62 |
|
63 | };
|
64 |
|
65 | if (target !== undefined) {
|
66 | Object.defineProperty(event, 'target', {
|
67 | enumerable: true,
|
68 |
|
69 | get() {
|
70 | return target;
|
71 | }
|
72 |
|
73 | });
|
74 | }
|
75 |
|
76 | if (data !== undefined) {
|
77 | Object.defineProperty(event, 'data', {
|
78 | enumerable: true,
|
79 |
|
80 | get() {
|
81 | return data;
|
82 | }
|
83 |
|
84 | });
|
85 | }
|
86 |
|
87 | if (canPreventDefault) {
|
88 | let defaultPrevented = false;
|
89 | Object.defineProperties(event, {
|
90 | defaultPrevented: {
|
91 | enumerable: true,
|
92 |
|
93 | get() {
|
94 | return defaultPrevented;
|
95 | }
|
96 |
|
97 | },
|
98 | preventDefault: {
|
99 | enumerable: true,
|
100 |
|
101 | value() {
|
102 | defaultPrevented = true;
|
103 | }
|
104 |
|
105 | }
|
106 | });
|
107 | }
|
108 |
|
109 | (_listenRef$current = listenRef.current) === null || _listenRef$current === void 0 ? void 0 : _listenRef$current.call(listenRef, event);
|
110 | callbacks === null || callbacks === void 0 ? void 0 : callbacks.forEach(cb => cb(event));
|
111 | return event;
|
112 | }, []);
|
113 | return React.useMemo(() => ({
|
114 | create,
|
115 | emit
|
116 | }), [create, emit]);
|
117 | }
|
118 |
|
\ | No newline at end of file |