@forcecalendar/interface 1.0.26 → 1.0.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 +9 -0
- package/dist/force-calendar-interface.esm.js +217 -112
- package/dist/force-calendar-interface.esm.js.map +1 -1
- package/dist/force-calendar-interface.umd.js +11 -11
- package/dist/force-calendar-interface.umd.js.map +1 -1
- package/package.json +3 -1
- package/src/components/EventForm.js +180 -176
- package/src/components/ForceCalendar.js +414 -392
- package/src/core/BaseComponent.js +146 -144
- package/src/core/EventBus.js +197 -197
- package/src/core/StateManager.js +405 -399
- package/src/index.js +3 -3
- package/src/renderers/BaseViewRenderer.js +195 -192
- package/src/renderers/DayViewRenderer.js +133 -118
- package/src/renderers/MonthViewRenderer.js +74 -72
- package/src/renderers/WeekViewRenderer.js +118 -96
- package/src/utils/DOMUtils.js +277 -277
- package/src/utils/DateUtils.js +164 -164
- package/src/utils/StyleUtils.js +286 -249
package/src/core/EventBus.js
CHANGED
|
@@ -6,227 +6,227 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
class EventBus {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
constructor() {
|
|
10
|
+
this.events = new Map();
|
|
11
|
+
this.wildcardHandlers = new Set();
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Subscribe to an event
|
|
16
|
+
* @param {string} eventName - Event name or pattern (supports wildcards)
|
|
17
|
+
* @param {Function} handler - Event handler function
|
|
18
|
+
* @param {Object} options - Subscription options
|
|
19
|
+
* @returns {Function} Unsubscribe function
|
|
20
|
+
*/
|
|
21
|
+
on(eventName, handler, options = {}) {
|
|
22
|
+
const { once = false, priority = 0 } = options;
|
|
23
|
+
|
|
24
|
+
// Handle wildcard subscriptions
|
|
25
|
+
if (eventName.includes('*')) {
|
|
26
|
+
const subscription = { pattern: eventName, handler, once, priority };
|
|
27
|
+
this.wildcardHandlers.add(subscription);
|
|
28
|
+
return () => this.wildcardHandlers.delete(subscription);
|
|
12
29
|
}
|
|
13
30
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
* @param {Function} handler - Event handler function
|
|
18
|
-
* @param {Object} options - Subscription options
|
|
19
|
-
* @returns {Function} Unsubscribe function
|
|
20
|
-
*/
|
|
21
|
-
on(eventName, handler, options = {}) {
|
|
22
|
-
const { once = false, priority = 0 } = options;
|
|
23
|
-
|
|
24
|
-
// Handle wildcard subscriptions
|
|
25
|
-
if (eventName.includes('*')) {
|
|
26
|
-
const subscription = { pattern: eventName, handler, once, priority };
|
|
27
|
-
this.wildcardHandlers.add(subscription);
|
|
28
|
-
return () => this.wildcardHandlers.delete(subscription);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
// Regular event subscription
|
|
32
|
-
if (!this.events.has(eventName)) {
|
|
33
|
-
this.events.set(eventName, []);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const subscription = { handler, once, priority };
|
|
37
|
-
const handlers = this.events.get(eventName);
|
|
38
|
-
handlers.push(subscription);
|
|
39
|
-
handlers.sort((a, b) => b.priority - a.priority);
|
|
40
|
-
|
|
41
|
-
// Return unsubscribe function
|
|
42
|
-
return () => {
|
|
43
|
-
const index = handlers.indexOf(subscription);
|
|
44
|
-
if (index > -1) {
|
|
45
|
-
handlers.splice(index, 1);
|
|
46
|
-
}
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Subscribe to an event that fires only once
|
|
52
|
-
*/
|
|
53
|
-
once(eventName, handler, options = {}) {
|
|
54
|
-
return this.on(eventName, handler, { ...options, once: true });
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Unsubscribe from an event
|
|
59
|
-
*/
|
|
60
|
-
off(eventName, handler) {
|
|
61
|
-
// Handle wildcard pattern removal
|
|
62
|
-
if (eventName.includes('*')) {
|
|
63
|
-
for (const sub of this.wildcardHandlers) {
|
|
64
|
-
if (sub.pattern === eventName && sub.handler === handler) {
|
|
65
|
-
this.wildcardHandlers.delete(sub);
|
|
66
|
-
return;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
return;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
if (!this.events.has(eventName)) return;
|
|
73
|
-
|
|
74
|
-
const handlers = this.events.get(eventName);
|
|
75
|
-
const index = handlers.findIndex(sub => sub.handler === handler);
|
|
76
|
-
if (index > -1) {
|
|
77
|
-
handlers.splice(index, 1);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
if (handlers.length === 0) {
|
|
81
|
-
this.events.delete(eventName);
|
|
82
|
-
}
|
|
31
|
+
// Regular event subscription
|
|
32
|
+
if (!this.events.has(eventName)) {
|
|
33
|
+
this.events.set(eventName, []);
|
|
83
34
|
}
|
|
84
35
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
36
|
+
const subscription = { handler, once, priority };
|
|
37
|
+
const handlers = this.events.get(eventName);
|
|
38
|
+
handlers.push(subscription);
|
|
39
|
+
handlers.sort((a, b) => b.priority - a.priority);
|
|
40
|
+
|
|
41
|
+
// Return unsubscribe function
|
|
42
|
+
return () => {
|
|
43
|
+
const index = handlers.indexOf(subscription);
|
|
44
|
+
if (index > -1) {
|
|
45
|
+
handlers.splice(index, 1);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Subscribe to an event that fires only once
|
|
52
|
+
*/
|
|
53
|
+
once(eventName, handler, options = {}) {
|
|
54
|
+
return this.on(eventName, handler, { ...options, once: true });
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Unsubscribe from an event
|
|
59
|
+
*/
|
|
60
|
+
off(eventName, handler) {
|
|
61
|
+
// Handle wildcard pattern removal
|
|
62
|
+
if (eventName.includes('*')) {
|
|
63
|
+
for (const sub of this.wildcardHandlers) {
|
|
64
|
+
if (sub.pattern === eventName && sub.handler === handler) {
|
|
65
|
+
this.wildcardHandlers.delete(sub);
|
|
66
|
+
return;
|
|
94
67
|
}
|
|
68
|
+
}
|
|
69
|
+
return;
|
|
95
70
|
}
|
|
96
71
|
|
|
97
|
-
|
|
98
|
-
* Remove all handlers (regular and wildcard) for a specific handler function
|
|
99
|
-
* Useful for cleanup when a component is destroyed
|
|
100
|
-
* @param {Function} handler - Handler function to remove
|
|
101
|
-
*/
|
|
102
|
-
offAll(handler) {
|
|
103
|
-
// Remove from regular events
|
|
104
|
-
for (const [eventName, handlers] of this.events) {
|
|
105
|
-
const index = handlers.findIndex(sub => sub.handler === handler);
|
|
106
|
-
if (index > -1) {
|
|
107
|
-
handlers.splice(index, 1);
|
|
108
|
-
}
|
|
109
|
-
if (handlers.length === 0) {
|
|
110
|
-
this.events.delete(eventName);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
72
|
+
if (!this.events.has(eventName)) return;
|
|
113
73
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
}
|
|
119
|
-
}
|
|
74
|
+
const handlers = this.events.get(eventName);
|
|
75
|
+
const index = handlers.findIndex(sub => sub.handler === handler);
|
|
76
|
+
if (index > -1) {
|
|
77
|
+
handlers.splice(index, 1);
|
|
120
78
|
}
|
|
121
79
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
* @param {string} eventName - Event name
|
|
125
|
-
* @param {*} data - Event data
|
|
126
|
-
* @returns {Promise} Resolves when all handlers complete
|
|
127
|
-
*/
|
|
128
|
-
async emit(eventName, data) {
|
|
129
|
-
const promises = [];
|
|
130
|
-
|
|
131
|
-
// Handle direct subscriptions
|
|
132
|
-
if (this.events.has(eventName)) {
|
|
133
|
-
const handlers = [...this.events.get(eventName)];
|
|
134
|
-
|
|
135
|
-
for (const subscription of handlers) {
|
|
136
|
-
const { handler, once } = subscription;
|
|
137
|
-
|
|
138
|
-
if (once) {
|
|
139
|
-
this.off(eventName, handler);
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
try {
|
|
143
|
-
const result = handler(data, eventName);
|
|
144
|
-
if (result instanceof Promise) {
|
|
145
|
-
promises.push(result);
|
|
146
|
-
}
|
|
147
|
-
} catch (error) {
|
|
148
|
-
console.error(`Error in event handler for ${eventName}:`, error);
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
// Handle wildcard subscriptions (copy Set to avoid mutation during iteration)
|
|
154
|
-
const toRemove = [];
|
|
155
|
-
for (const subscription of [...this.wildcardHandlers]) {
|
|
156
|
-
if (this.matchesPattern(eventName, subscription.pattern)) {
|
|
157
|
-
const { handler, once } = subscription;
|
|
158
|
-
|
|
159
|
-
if (once) {
|
|
160
|
-
toRemove.push(subscription);
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
try {
|
|
164
|
-
const result = handler(data, eventName);
|
|
165
|
-
if (result instanceof Promise) {
|
|
166
|
-
promises.push(result);
|
|
167
|
-
}
|
|
168
|
-
} catch (error) {
|
|
169
|
-
console.error(`Error in wildcard handler for ${eventName}:`, error);
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
// Remove one-time handlers after iteration
|
|
174
|
-
toRemove.forEach(sub => this.wildcardHandlers.delete(sub));
|
|
175
|
-
|
|
176
|
-
return Promise.all(promises);
|
|
80
|
+
if (handlers.length === 0) {
|
|
81
|
+
this.events.delete(eventName);
|
|
177
82
|
}
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Remove all wildcard handlers matching a pattern
|
|
87
|
+
* @param {string} pattern - Pattern to match (e.g., 'event:*')
|
|
88
|
+
*/
|
|
89
|
+
offWildcard(pattern) {
|
|
90
|
+
for (const sub of [...this.wildcardHandlers]) {
|
|
91
|
+
if (sub.pattern === pattern) {
|
|
92
|
+
this.wildcardHandlers.delete(sub);
|
|
93
|
+
}
|
|
185
94
|
}
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Remove all handlers (regular and wildcard) for a specific handler function
|
|
99
|
+
* Useful for cleanup when a component is destroyed
|
|
100
|
+
* @param {Function} handler - Handler function to remove
|
|
101
|
+
*/
|
|
102
|
+
offAll(handler) {
|
|
103
|
+
// Remove from regular events
|
|
104
|
+
for (const [eventName, handlers] of this.events) {
|
|
105
|
+
const index = handlers.findIndex(sub => sub.handler === handler);
|
|
106
|
+
if (index > -1) {
|
|
107
|
+
handlers.splice(index, 1);
|
|
108
|
+
}
|
|
109
|
+
if (handlers.length === 0) {
|
|
110
|
+
this.events.delete(eventName);
|
|
111
|
+
}
|
|
193
112
|
}
|
|
194
113
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
114
|
+
// Remove from wildcard handlers
|
|
115
|
+
for (const sub of [...this.wildcardHandlers]) {
|
|
116
|
+
if (sub.handler === handler) {
|
|
117
|
+
this.wildcardHandlers.delete(sub);
|
|
118
|
+
}
|
|
200
119
|
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Emit an event
|
|
124
|
+
* @param {string} eventName - Event name
|
|
125
|
+
* @param {*} data - Event data
|
|
126
|
+
* @returns {Promise} Resolves when all handlers complete
|
|
127
|
+
*/
|
|
128
|
+
async emit(eventName, data) {
|
|
129
|
+
const promises = [];
|
|
130
|
+
|
|
131
|
+
// Handle direct subscriptions
|
|
132
|
+
if (this.events.has(eventName)) {
|
|
133
|
+
const handlers = [...this.events.get(eventName)];
|
|
134
|
+
|
|
135
|
+
for (const subscription of handlers) {
|
|
136
|
+
const { handler, once } = subscription;
|
|
137
|
+
|
|
138
|
+
if (once) {
|
|
139
|
+
this.off(eventName, handler);
|
|
140
|
+
}
|
|
201
141
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
142
|
+
try {
|
|
143
|
+
const result = handler(data, eventName);
|
|
144
|
+
if (result instanceof Promise) {
|
|
145
|
+
promises.push(result);
|
|
146
|
+
}
|
|
147
|
+
} catch (error) {
|
|
148
|
+
console.error(`Error in event handler for ${eventName}:`, error);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
207
151
|
}
|
|
208
152
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
}
|
|
153
|
+
// Handle wildcard subscriptions (copy Set to avoid mutation during iteration)
|
|
154
|
+
const toRemove = [];
|
|
155
|
+
for (const subscription of [...this.wildcardHandlers]) {
|
|
156
|
+
if (this.matchesPattern(eventName, subscription.pattern)) {
|
|
157
|
+
const { handler, once } = subscription;
|
|
215
158
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
*/
|
|
219
|
-
getTotalHandlerCount() {
|
|
220
|
-
let count = this.wildcardHandlers.size;
|
|
221
|
-
for (const handlers of this.events.values()) {
|
|
222
|
-
count += handlers.length;
|
|
159
|
+
if (once) {
|
|
160
|
+
toRemove.push(subscription);
|
|
223
161
|
}
|
|
224
|
-
|
|
162
|
+
|
|
163
|
+
try {
|
|
164
|
+
const result = handler(data, eventName);
|
|
165
|
+
if (result instanceof Promise) {
|
|
166
|
+
promises.push(result);
|
|
167
|
+
}
|
|
168
|
+
} catch (error) {
|
|
169
|
+
console.error(`Error in wildcard handler for ${eventName}:`, error);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
// Remove one-time handlers after iteration
|
|
174
|
+
toRemove.forEach(sub => this.wildcardHandlers.delete(sub));
|
|
175
|
+
|
|
176
|
+
return Promise.all(promises);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Check if event name matches a pattern
|
|
181
|
+
*/
|
|
182
|
+
matchesPattern(eventName, pattern) {
|
|
183
|
+
const regex = new RegExp('^' + pattern.replace(/\*/g, '.*') + '$');
|
|
184
|
+
return regex.test(eventName);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Clear all event subscriptions
|
|
189
|
+
*/
|
|
190
|
+
clear() {
|
|
191
|
+
this.events.clear();
|
|
192
|
+
this.wildcardHandlers.clear();
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Get all registered event names
|
|
197
|
+
*/
|
|
198
|
+
getEventNames() {
|
|
199
|
+
return Array.from(this.events.keys());
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Get handler count for an event
|
|
204
|
+
*/
|
|
205
|
+
getHandlerCount(eventName) {
|
|
206
|
+
return this.events.has(eventName) ? this.events.get(eventName).length : 0;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Get wildcard handler count
|
|
211
|
+
*/
|
|
212
|
+
getWildcardHandlerCount() {
|
|
213
|
+
return this.wildcardHandlers.size;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Get total handler count (for debugging/monitoring)
|
|
218
|
+
*/
|
|
219
|
+
getTotalHandlerCount() {
|
|
220
|
+
let count = this.wildcardHandlers.size;
|
|
221
|
+
for (const handlers of this.events.values()) {
|
|
222
|
+
count += handlers.length;
|
|
225
223
|
}
|
|
224
|
+
return count;
|
|
225
|
+
}
|
|
226
226
|
}
|
|
227
227
|
|
|
228
228
|
// Create singleton instance
|
|
229
229
|
const eventBus = new EventBus();
|
|
230
230
|
|
|
231
231
|
// Export both the class and singleton
|
|
232
|
-
export { EventBus, eventBus as default };
|
|
232
|
+
export { EventBus, eventBus as default };
|