@forcecalendar/interface 1.0.16 → 1.0.17
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/force-calendar-interface.esm.js +79 -20
- package/dist/force-calendar-interface.esm.js.map +1 -1
- package/dist/force-calendar-interface.umd.js +33 -33
- package/dist/force-calendar-interface.umd.js.map +1 -1
- package/package.json +1 -1
- package/src/components/EventForm.js +15 -10
- package/src/core/EventBus.js +66 -0
- package/src/core/StateManager.js +44 -3
package/package.json
CHANGED
|
@@ -300,16 +300,16 @@ export class EventForm extends BaseComponent {
|
|
|
300
300
|
if (e.target === this) this.close();
|
|
301
301
|
});
|
|
302
302
|
|
|
303
|
-
// Close on Escape key -
|
|
304
|
-
if (this.
|
|
305
|
-
|
|
303
|
+
// Close on Escape key - only add once to prevent memory leaks
|
|
304
|
+
if (!this._keydownListenerAdded) {
|
|
305
|
+
this._handleKeyDown = (e) => {
|
|
306
|
+
if (e.key === 'Escape' && this.hasAttribute('open')) {
|
|
307
|
+
this.close();
|
|
308
|
+
}
|
|
309
|
+
};
|
|
310
|
+
window.addEventListener('keydown', this._handleKeyDown);
|
|
311
|
+
this._keydownListenerAdded = true;
|
|
306
312
|
}
|
|
307
|
-
this._handleKeyDown = (e) => {
|
|
308
|
-
if (e.key === 'Escape' && this.hasAttribute('open')) {
|
|
309
|
-
this.close();
|
|
310
|
-
}
|
|
311
|
-
};
|
|
312
|
-
window.addEventListener('keydown', this._handleKeyDown);
|
|
313
313
|
}
|
|
314
314
|
|
|
315
315
|
updateColorSelection() {
|
|
@@ -410,7 +410,12 @@ export class EventForm extends BaseComponent {
|
|
|
410
410
|
if (this._cleanupFocusTrap) {
|
|
411
411
|
this._cleanupFocusTrap();
|
|
412
412
|
}
|
|
413
|
-
window
|
|
413
|
+
// Clean up window listener
|
|
414
|
+
if (this._handleKeyDown) {
|
|
415
|
+
window.removeEventListener('keydown', this._handleKeyDown);
|
|
416
|
+
this._handleKeyDown = null;
|
|
417
|
+
this._keydownListenerAdded = false;
|
|
418
|
+
}
|
|
414
419
|
}
|
|
415
420
|
}
|
|
416
421
|
|
package/src/core/EventBus.js
CHANGED
|
@@ -58,6 +58,17 @@ class EventBus {
|
|
|
58
58
|
* Unsubscribe from an event
|
|
59
59
|
*/
|
|
60
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
|
+
|
|
61
72
|
if (!this.events.has(eventName)) return;
|
|
62
73
|
|
|
63
74
|
const handlers = this.events.get(eventName);
|
|
@@ -71,6 +82,43 @@ class EventBus {
|
|
|
71
82
|
}
|
|
72
83
|
}
|
|
73
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
|
+
}
|
|
94
|
+
}
|
|
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
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Remove from wildcard handlers
|
|
115
|
+
for (const sub of [...this.wildcardHandlers]) {
|
|
116
|
+
if (sub.handler === handler) {
|
|
117
|
+
this.wildcardHandlers.delete(sub);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
74
122
|
/**
|
|
75
123
|
* Emit an event
|
|
76
124
|
* @param {string} eventName - Event name
|
|
@@ -157,6 +205,24 @@ class EventBus {
|
|
|
157
205
|
getHandlerCount(eventName) {
|
|
158
206
|
return this.events.has(eventName) ? this.events.get(eventName).length : 0;
|
|
159
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;
|
|
223
|
+
}
|
|
224
|
+
return count;
|
|
225
|
+
}
|
|
160
226
|
}
|
|
161
227
|
|
|
162
228
|
// Create singleton instance
|
package/src/core/StateManager.js
CHANGED
|
@@ -85,13 +85,50 @@ class StateManager {
|
|
|
85
85
|
return this.state;
|
|
86
86
|
}
|
|
87
87
|
|
|
88
|
-
subscribe(callback) {
|
|
88
|
+
subscribe(callback, subscriberId = null) {
|
|
89
89
|
this.subscribers.add(callback);
|
|
90
|
-
|
|
90
|
+
|
|
91
|
+
// Track subscriber ID for debugging/cleanup
|
|
92
|
+
if (subscriberId) {
|
|
93
|
+
if (!this._subscriberIds) {
|
|
94
|
+
this._subscriberIds = new Map();
|
|
95
|
+
}
|
|
96
|
+
this._subscriberIds.set(subscriberId, callback);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return () => this.unsubscribe(callback, subscriberId);
|
|
91
100
|
}
|
|
92
101
|
|
|
93
|
-
unsubscribe(callback) {
|
|
102
|
+
unsubscribe(callback, subscriberId = null) {
|
|
94
103
|
this.subscribers.delete(callback);
|
|
104
|
+
|
|
105
|
+
// Clean up ID tracking
|
|
106
|
+
if (subscriberId && this._subscriberIds) {
|
|
107
|
+
this._subscriberIds.delete(subscriberId);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Unsubscribe by subscriber ID
|
|
113
|
+
* @param {string} subscriberId - ID used when subscribing
|
|
114
|
+
*/
|
|
115
|
+
unsubscribeById(subscriberId) {
|
|
116
|
+
if (!this._subscriberIds) return false;
|
|
117
|
+
|
|
118
|
+
const callback = this._subscriberIds.get(subscriberId);
|
|
119
|
+
if (callback) {
|
|
120
|
+
this.subscribers.delete(callback);
|
|
121
|
+
this._subscriberIds.delete(subscriberId);
|
|
122
|
+
return true;
|
|
123
|
+
}
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Get subscriber count (for debugging/monitoring)
|
|
129
|
+
*/
|
|
130
|
+
getSubscriberCount() {
|
|
131
|
+
return this.subscribers.size;
|
|
95
132
|
}
|
|
96
133
|
|
|
97
134
|
notifySubscribers(oldState, newState) {
|
|
@@ -362,6 +399,10 @@ class StateManager {
|
|
|
362
399
|
// Destroy
|
|
363
400
|
destroy() {
|
|
364
401
|
this.subscribers.clear();
|
|
402
|
+
if (this._subscriberIds) {
|
|
403
|
+
this._subscriberIds.clear();
|
|
404
|
+
this._subscriberIds = null;
|
|
405
|
+
}
|
|
365
406
|
this.state = null;
|
|
366
407
|
this.calendar = null;
|
|
367
408
|
}
|