@elementor/frontend-handlers 4.0.0-547 → 4.0.0-549
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/index.js +32 -41
- package/dist/index.mjs +32 -41
- package/package.json +1 -1
- package/src/__tests__/index.test.ts +47 -1
- package/src/init.ts +0 -3
- package/src/lifecycle-events.ts +46 -49
package/dist/index.js
CHANGED
|
@@ -79,8 +79,7 @@ var unregisterBySelector = ({ selector, id }) => {
|
|
|
79
79
|
};
|
|
80
80
|
|
|
81
81
|
// src/lifecycle-events.ts
|
|
82
|
-
var
|
|
83
|
-
var unmountElementSelectorCallbacks = /* @__PURE__ */ new Map();
|
|
82
|
+
var unmountCallbacks = /* @__PURE__ */ new WeakMap();
|
|
84
83
|
var ELEMENT_RENDERED_EVENT_NAME = "elementor/element/rendered";
|
|
85
84
|
var ELEMENT_DESTROYED_EVENT_NAME = "elementor/element/destroyed";
|
|
86
85
|
var dispatchDestroyedEvent = (params) => {
|
|
@@ -96,10 +95,11 @@ var onElementRender = ({
|
|
|
96
95
|
elementType,
|
|
97
96
|
elementId
|
|
98
97
|
}) => {
|
|
98
|
+
cleanupOnUnmount(element);
|
|
99
99
|
const controller = new AbortController();
|
|
100
100
|
const manualUnmount = [];
|
|
101
101
|
const dispatchRenderedEvent = () => {
|
|
102
|
-
onElementSelectorRender({ element,
|
|
102
|
+
onElementSelectorRender({ element, controller });
|
|
103
103
|
element.dispatchEvent(
|
|
104
104
|
new CustomEvent(ELEMENT_RENDERED_EVENT_NAME, {
|
|
105
105
|
bubbles: true,
|
|
@@ -121,6 +121,7 @@ var onElementRender = ({
|
|
|
121
121
|
if (!elementTypeHandlers.has(elementType)) {
|
|
122
122
|
return;
|
|
123
123
|
}
|
|
124
|
+
setUnmountEntry({ element, controller, manualUnmount });
|
|
124
125
|
Array.from(elementTypeHandlers.get(elementType)?.values() ?? []).forEach((handler) => {
|
|
125
126
|
const settings = element.getAttribute("data-e-settings");
|
|
126
127
|
const listenToChildren = (elementTypes) => ({
|
|
@@ -146,24 +147,18 @@ var onElementRender = ({
|
|
|
146
147
|
manualUnmount.push(unmount);
|
|
147
148
|
}
|
|
148
149
|
});
|
|
149
|
-
if (!unmountElementTypeCallbacks.has(elementType)) {
|
|
150
|
-
unmountElementTypeCallbacks.set(elementType, /* @__PURE__ */ new Map());
|
|
151
|
-
}
|
|
152
|
-
unmountElementTypeCallbacks.get(elementType)?.set(elementId, () => {
|
|
153
|
-
controller.abort();
|
|
154
|
-
manualUnmount.forEach((callback) => callback());
|
|
155
|
-
});
|
|
156
150
|
};
|
|
157
151
|
var onElementSelectorRender = ({
|
|
158
152
|
element,
|
|
159
|
-
elementId,
|
|
160
153
|
controller
|
|
161
154
|
}) => {
|
|
155
|
+
let requiresCleanup = false;
|
|
156
|
+
const manualUnmount = [];
|
|
162
157
|
Array.from(elementSelectorHandlers.entries() ?? []).forEach(([selector, handlers]) => {
|
|
163
158
|
if (!element.matches(selector)) {
|
|
164
159
|
return;
|
|
165
160
|
}
|
|
166
|
-
|
|
161
|
+
requiresCleanup = true;
|
|
167
162
|
Array.from(handlers.values() ?? []).forEach((handler) => {
|
|
168
163
|
const settings = element.getAttribute("data-e-settings");
|
|
169
164
|
const unmount = handler({
|
|
@@ -175,43 +170,40 @@ var onElementSelectorRender = ({
|
|
|
175
170
|
manualUnmount.push(unmount);
|
|
176
171
|
}
|
|
177
172
|
});
|
|
178
|
-
if (!manualUnmount.length) {
|
|
179
|
-
return;
|
|
180
|
-
}
|
|
181
|
-
if (!unmountElementSelectorCallbacks.get(elementId)) {
|
|
182
|
-
unmountElementSelectorCallbacks.set(elementId, /* @__PURE__ */ new Map());
|
|
183
|
-
}
|
|
184
|
-
unmountElementSelectorCallbacks.get(elementId)?.set(selector, () => {
|
|
185
|
-
controller.abort();
|
|
186
|
-
manualUnmount.forEach((callback) => callback());
|
|
187
|
-
});
|
|
188
173
|
});
|
|
174
|
+
if (requiresCleanup) {
|
|
175
|
+
setUnmountEntry({ element, controller, manualUnmount });
|
|
176
|
+
}
|
|
189
177
|
};
|
|
190
178
|
var onElementDestroy = ({
|
|
191
179
|
elementType,
|
|
192
180
|
elementId,
|
|
193
181
|
element
|
|
194
182
|
}) => {
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
if (element) {
|
|
198
|
-
dispatchDestroyedEvent({ element, elementType, elementId });
|
|
199
|
-
}
|
|
200
|
-
if (unmount) {
|
|
201
|
-
unmount();
|
|
202
|
-
}
|
|
203
|
-
if (unmountSelector?.size) {
|
|
204
|
-
Array.from(unmountSelector.values()).forEach((selectorUnmount) => {
|
|
205
|
-
selectorUnmount();
|
|
206
|
-
});
|
|
183
|
+
if (!element) {
|
|
184
|
+
return;
|
|
207
185
|
}
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
186
|
+
cleanupOnUnmount(element);
|
|
187
|
+
dispatchDestroyedEvent({ element, elementType, elementId });
|
|
188
|
+
};
|
|
189
|
+
var setUnmountEntry = ({
|
|
190
|
+
element,
|
|
191
|
+
controller,
|
|
192
|
+
manualUnmount
|
|
193
|
+
}) => {
|
|
194
|
+
const existingEntry = unmountCallbacks.get(element);
|
|
195
|
+
if (existingEntry) {
|
|
196
|
+
existingEntry.manualUnmount.push(...manualUnmount);
|
|
197
|
+
} else {
|
|
198
|
+
unmountCallbacks.set(element, { controller, manualUnmount });
|
|
212
199
|
}
|
|
213
|
-
|
|
214
|
-
|
|
200
|
+
};
|
|
201
|
+
var cleanupOnUnmount = (element) => {
|
|
202
|
+
const entry = unmountCallbacks.get(element);
|
|
203
|
+
if (entry) {
|
|
204
|
+
entry.controller.abort();
|
|
205
|
+
entry.manualUnmount.forEach((callback) => callback());
|
|
206
|
+
unmountCallbacks.delete(element);
|
|
215
207
|
}
|
|
216
208
|
};
|
|
217
209
|
|
|
@@ -220,7 +212,6 @@ function init() {
|
|
|
220
212
|
window.addEventListener("elementor/element/render", (_event) => {
|
|
221
213
|
const event = _event;
|
|
222
214
|
const { id, type, element } = event.detail;
|
|
223
|
-
onElementDestroy({ elementType: type, elementId: id });
|
|
224
215
|
onElementRender({ element, elementType: type, elementId: id });
|
|
225
216
|
});
|
|
226
217
|
window.addEventListener("elementor/element/destroy", (_event) => {
|
package/dist/index.mjs
CHANGED
|
@@ -49,8 +49,7 @@ var unregisterBySelector = ({ selector, id }) => {
|
|
|
49
49
|
};
|
|
50
50
|
|
|
51
51
|
// src/lifecycle-events.ts
|
|
52
|
-
var
|
|
53
|
-
var unmountElementSelectorCallbacks = /* @__PURE__ */ new Map();
|
|
52
|
+
var unmountCallbacks = /* @__PURE__ */ new WeakMap();
|
|
54
53
|
var ELEMENT_RENDERED_EVENT_NAME = "elementor/element/rendered";
|
|
55
54
|
var ELEMENT_DESTROYED_EVENT_NAME = "elementor/element/destroyed";
|
|
56
55
|
var dispatchDestroyedEvent = (params) => {
|
|
@@ -66,10 +65,11 @@ var onElementRender = ({
|
|
|
66
65
|
elementType,
|
|
67
66
|
elementId
|
|
68
67
|
}) => {
|
|
68
|
+
cleanupOnUnmount(element);
|
|
69
69
|
const controller = new AbortController();
|
|
70
70
|
const manualUnmount = [];
|
|
71
71
|
const dispatchRenderedEvent = () => {
|
|
72
|
-
onElementSelectorRender({ element,
|
|
72
|
+
onElementSelectorRender({ element, controller });
|
|
73
73
|
element.dispatchEvent(
|
|
74
74
|
new CustomEvent(ELEMENT_RENDERED_EVENT_NAME, {
|
|
75
75
|
bubbles: true,
|
|
@@ -91,6 +91,7 @@ var onElementRender = ({
|
|
|
91
91
|
if (!elementTypeHandlers.has(elementType)) {
|
|
92
92
|
return;
|
|
93
93
|
}
|
|
94
|
+
setUnmountEntry({ element, controller, manualUnmount });
|
|
94
95
|
Array.from(elementTypeHandlers.get(elementType)?.values() ?? []).forEach((handler) => {
|
|
95
96
|
const settings = element.getAttribute("data-e-settings");
|
|
96
97
|
const listenToChildren = (elementTypes) => ({
|
|
@@ -116,24 +117,18 @@ var onElementRender = ({
|
|
|
116
117
|
manualUnmount.push(unmount);
|
|
117
118
|
}
|
|
118
119
|
});
|
|
119
|
-
if (!unmountElementTypeCallbacks.has(elementType)) {
|
|
120
|
-
unmountElementTypeCallbacks.set(elementType, /* @__PURE__ */ new Map());
|
|
121
|
-
}
|
|
122
|
-
unmountElementTypeCallbacks.get(elementType)?.set(elementId, () => {
|
|
123
|
-
controller.abort();
|
|
124
|
-
manualUnmount.forEach((callback) => callback());
|
|
125
|
-
});
|
|
126
120
|
};
|
|
127
121
|
var onElementSelectorRender = ({
|
|
128
122
|
element,
|
|
129
|
-
elementId,
|
|
130
123
|
controller
|
|
131
124
|
}) => {
|
|
125
|
+
let requiresCleanup = false;
|
|
126
|
+
const manualUnmount = [];
|
|
132
127
|
Array.from(elementSelectorHandlers.entries() ?? []).forEach(([selector, handlers]) => {
|
|
133
128
|
if (!element.matches(selector)) {
|
|
134
129
|
return;
|
|
135
130
|
}
|
|
136
|
-
|
|
131
|
+
requiresCleanup = true;
|
|
137
132
|
Array.from(handlers.values() ?? []).forEach((handler) => {
|
|
138
133
|
const settings = element.getAttribute("data-e-settings");
|
|
139
134
|
const unmount = handler({
|
|
@@ -145,43 +140,40 @@ var onElementSelectorRender = ({
|
|
|
145
140
|
manualUnmount.push(unmount);
|
|
146
141
|
}
|
|
147
142
|
});
|
|
148
|
-
if (!manualUnmount.length) {
|
|
149
|
-
return;
|
|
150
|
-
}
|
|
151
|
-
if (!unmountElementSelectorCallbacks.get(elementId)) {
|
|
152
|
-
unmountElementSelectorCallbacks.set(elementId, /* @__PURE__ */ new Map());
|
|
153
|
-
}
|
|
154
|
-
unmountElementSelectorCallbacks.get(elementId)?.set(selector, () => {
|
|
155
|
-
controller.abort();
|
|
156
|
-
manualUnmount.forEach((callback) => callback());
|
|
157
|
-
});
|
|
158
143
|
});
|
|
144
|
+
if (requiresCleanup) {
|
|
145
|
+
setUnmountEntry({ element, controller, manualUnmount });
|
|
146
|
+
}
|
|
159
147
|
};
|
|
160
148
|
var onElementDestroy = ({
|
|
161
149
|
elementType,
|
|
162
150
|
elementId,
|
|
163
151
|
element
|
|
164
152
|
}) => {
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
if (element) {
|
|
168
|
-
dispatchDestroyedEvent({ element, elementType, elementId });
|
|
169
|
-
}
|
|
170
|
-
if (unmount) {
|
|
171
|
-
unmount();
|
|
172
|
-
}
|
|
173
|
-
if (unmountSelector?.size) {
|
|
174
|
-
Array.from(unmountSelector.values()).forEach((selectorUnmount) => {
|
|
175
|
-
selectorUnmount();
|
|
176
|
-
});
|
|
153
|
+
if (!element) {
|
|
154
|
+
return;
|
|
177
155
|
}
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
156
|
+
cleanupOnUnmount(element);
|
|
157
|
+
dispatchDestroyedEvent({ element, elementType, elementId });
|
|
158
|
+
};
|
|
159
|
+
var setUnmountEntry = ({
|
|
160
|
+
element,
|
|
161
|
+
controller,
|
|
162
|
+
manualUnmount
|
|
163
|
+
}) => {
|
|
164
|
+
const existingEntry = unmountCallbacks.get(element);
|
|
165
|
+
if (existingEntry) {
|
|
166
|
+
existingEntry.manualUnmount.push(...manualUnmount);
|
|
167
|
+
} else {
|
|
168
|
+
unmountCallbacks.set(element, { controller, manualUnmount });
|
|
182
169
|
}
|
|
183
|
-
|
|
184
|
-
|
|
170
|
+
};
|
|
171
|
+
var cleanupOnUnmount = (element) => {
|
|
172
|
+
const entry = unmountCallbacks.get(element);
|
|
173
|
+
if (entry) {
|
|
174
|
+
entry.controller.abort();
|
|
175
|
+
entry.manualUnmount.forEach((callback) => callback());
|
|
176
|
+
unmountCallbacks.delete(element);
|
|
185
177
|
}
|
|
186
178
|
};
|
|
187
179
|
|
|
@@ -190,7 +182,6 @@ function init() {
|
|
|
190
182
|
window.addEventListener("elementor/element/render", (_event) => {
|
|
191
183
|
const event = _event;
|
|
192
184
|
const { id, type, element } = event.detail;
|
|
193
|
-
onElementDestroy({ elementType: type, elementId: id });
|
|
194
185
|
onElementRender({ element, elementType: type, elementId: id });
|
|
195
186
|
});
|
|
196
187
|
window.addEventListener("elementor/element/destroy", (_event) => {
|
package/package.json
CHANGED
|
@@ -232,7 +232,7 @@ describe( 'Frontend Handlers', () => {
|
|
|
232
232
|
|
|
233
233
|
window.dispatchEvent(
|
|
234
234
|
new CustomEvent( 'elementor/element/destroy', {
|
|
235
|
-
detail: { id: ELEMENT_ID, type: WIDGET_ELEMENT_TYPE },
|
|
235
|
+
detail: { id: ELEMENT_ID, type: WIDGET_ELEMENT_TYPE, element },
|
|
236
236
|
} )
|
|
237
237
|
);
|
|
238
238
|
|
|
@@ -686,6 +686,52 @@ describe( 'Frontend Handlers', () => {
|
|
|
686
686
|
expect( callbackCounts.get( PARENT_1_ID ) ).toBe( 1 );
|
|
687
687
|
expect( callbackCounts.get( PARENT_2_ID ) ).toBe( 1 );
|
|
688
688
|
} );
|
|
689
|
+
|
|
690
|
+
it( 'should not abort handlers of first element when rendering second element with same ID', () => {
|
|
691
|
+
// Arrange
|
|
692
|
+
const SHARED_ID = 'shared-internal-id';
|
|
693
|
+
let element1Signal: AbortSignal | undefined;
|
|
694
|
+
let element2Signal: AbortSignal | undefined;
|
|
695
|
+
|
|
696
|
+
const element1 = document.createElement( 'div' );
|
|
697
|
+
element1.setAttribute( 'data-e-type', WIDGET_ELEMENT_TYPE );
|
|
698
|
+
element1.setAttribute( 'data-id', SHARED_ID );
|
|
699
|
+
document.body.appendChild( element1 );
|
|
700
|
+
|
|
701
|
+
const element2 = document.createElement( 'div' );
|
|
702
|
+
element2.setAttribute( 'data-e-type', WIDGET_ELEMENT_TYPE );
|
|
703
|
+
element2.setAttribute( 'data-id', SHARED_ID );
|
|
704
|
+
document.body.appendChild( element2 );
|
|
705
|
+
|
|
706
|
+
register( {
|
|
707
|
+
elementType: WIDGET_ELEMENT_TYPE,
|
|
708
|
+
id: HANDLER_IDS.handler_1,
|
|
709
|
+
callback: ( { element, signal } ) => {
|
|
710
|
+
if ( element === element1 ) {
|
|
711
|
+
element1Signal = signal;
|
|
712
|
+
} else if ( element === element2 ) {
|
|
713
|
+
element2Signal = signal;
|
|
714
|
+
}
|
|
715
|
+
return undefined;
|
|
716
|
+
},
|
|
717
|
+
} );
|
|
718
|
+
|
|
719
|
+
// Act - Render elements
|
|
720
|
+
window.dispatchEvent(
|
|
721
|
+
new CustomEvent( 'elementor/element/render', {
|
|
722
|
+
detail: { id: SHARED_ID, type: WIDGET_ELEMENT_TYPE, element: element1 },
|
|
723
|
+
} )
|
|
724
|
+
);
|
|
725
|
+
window.dispatchEvent(
|
|
726
|
+
new CustomEvent( 'elementor/element/render', {
|
|
727
|
+
detail: { id: SHARED_ID, type: WIDGET_ELEMENT_TYPE, element: element2 },
|
|
728
|
+
} )
|
|
729
|
+
);
|
|
730
|
+
|
|
731
|
+
// Assert - Both signals should be active (not aborted)
|
|
732
|
+
expect( element1Signal?.aborted ).toBe( false );
|
|
733
|
+
expect( element2Signal?.aborted ).toBe( false );
|
|
734
|
+
} );
|
|
689
735
|
} );
|
|
690
736
|
|
|
691
737
|
describe( 'DOMContentLoaded Initialization', () => {
|
package/src/init.ts
CHANGED
|
@@ -5,9 +5,6 @@ export function init() {
|
|
|
5
5
|
const event = _event as CustomEvent< { id: string; type: string; element: Element } >;
|
|
6
6
|
const { id, type, element } = event.detail;
|
|
7
7
|
|
|
8
|
-
// Ensure the "destroy" event was not triggered before the render event.
|
|
9
|
-
onElementDestroy( { elementType: type, elementId: id } );
|
|
10
|
-
|
|
11
8
|
onElementRender( { element, elementType: type, elementId: id } );
|
|
12
9
|
} );
|
|
13
10
|
|
package/src/lifecycle-events.ts
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { elementSelectorHandlers, elementTypeHandlers } from './handlers-registry';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
type UnmountEntry = {
|
|
4
|
+
controller: AbortController;
|
|
5
|
+
manualUnmount: ( () => void )[];
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
const unmountCallbacks = new WeakMap< Element, UnmountEntry >();
|
|
5
9
|
|
|
6
10
|
const ELEMENT_RENDERED_EVENT_NAME = 'elementor/element/rendered';
|
|
7
11
|
const ELEMENT_DESTROYED_EVENT_NAME = 'elementor/element/destroyed';
|
|
@@ -30,11 +34,13 @@ export const onElementRender = ( {
|
|
|
30
34
|
elementType: string;
|
|
31
35
|
elementId: string;
|
|
32
36
|
} ) => {
|
|
37
|
+
cleanupOnUnmount( element );
|
|
38
|
+
|
|
33
39
|
const controller = new AbortController();
|
|
34
40
|
const manualUnmount: ( () => void )[] = [];
|
|
35
41
|
|
|
36
42
|
const dispatchRenderedEvent = () => {
|
|
37
|
-
onElementSelectorRender( { element,
|
|
43
|
+
onElementSelectorRender( { element, controller } );
|
|
38
44
|
|
|
39
45
|
element.dispatchEvent(
|
|
40
46
|
new CustomEvent( ELEMENT_RENDERED_EVENT_NAME, {
|
|
@@ -61,6 +67,8 @@ export const onElementRender = ( {
|
|
|
61
67
|
return;
|
|
62
68
|
}
|
|
63
69
|
|
|
70
|
+
setUnmountEntry( { element, controller, manualUnmount } );
|
|
71
|
+
|
|
64
72
|
Array.from( elementTypeHandlers.get( elementType )?.values() ?? [] ).forEach( ( handler ) => {
|
|
65
73
|
const settings = element.getAttribute( 'data-e-settings' );
|
|
66
74
|
|
|
@@ -92,33 +100,24 @@ export const onElementRender = ( {
|
|
|
92
100
|
manualUnmount.push( unmount );
|
|
93
101
|
}
|
|
94
102
|
} );
|
|
95
|
-
|
|
96
|
-
if ( ! unmountElementTypeCallbacks.has( elementType ) ) {
|
|
97
|
-
unmountElementTypeCallbacks.set( elementType, new Map() );
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
unmountElementTypeCallbacks.get( elementType )?.set( elementId, () => {
|
|
101
|
-
controller.abort();
|
|
102
|
-
|
|
103
|
-
manualUnmount.forEach( ( callback ) => callback() );
|
|
104
|
-
} );
|
|
105
103
|
};
|
|
106
104
|
|
|
107
105
|
export const onElementSelectorRender = ( {
|
|
108
106
|
element,
|
|
109
|
-
elementId,
|
|
110
107
|
controller,
|
|
111
108
|
}: {
|
|
112
109
|
element: Element;
|
|
113
|
-
elementId: string;
|
|
114
110
|
controller: AbortController;
|
|
115
111
|
} ) => {
|
|
112
|
+
let requiresCleanup = false;
|
|
113
|
+
const manualUnmount: ( () => void )[] = [];
|
|
114
|
+
|
|
116
115
|
Array.from( elementSelectorHandlers.entries() ?? [] ).forEach( ( [ selector, handlers ] ) => {
|
|
117
116
|
if ( ! element.matches( selector ) ) {
|
|
118
117
|
return;
|
|
119
118
|
}
|
|
120
119
|
|
|
121
|
-
|
|
120
|
+
requiresCleanup = true;
|
|
122
121
|
|
|
123
122
|
Array.from( handlers.values() ?? [] ).forEach( ( handler ) => {
|
|
124
123
|
const settings = element.getAttribute( 'data-e-settings' );
|
|
@@ -133,21 +132,11 @@ export const onElementSelectorRender = ( {
|
|
|
133
132
|
manualUnmount.push( unmount );
|
|
134
133
|
}
|
|
135
134
|
} );
|
|
136
|
-
|
|
137
|
-
if ( ! manualUnmount.length ) {
|
|
138
|
-
return;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
if ( ! unmountElementSelectorCallbacks.get( elementId ) ) {
|
|
142
|
-
unmountElementSelectorCallbacks.set( elementId, new Map() );
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
unmountElementSelectorCallbacks.get( elementId )?.set( selector, () => {
|
|
146
|
-
controller.abort();
|
|
147
|
-
|
|
148
|
-
manualUnmount.forEach( ( callback ) => callback() );
|
|
149
|
-
} );
|
|
150
135
|
} );
|
|
136
|
+
|
|
137
|
+
if ( requiresCleanup ) {
|
|
138
|
+
setUnmountEntry( { element, controller, manualUnmount } );
|
|
139
|
+
}
|
|
151
140
|
};
|
|
152
141
|
|
|
153
142
|
export const onElementDestroy = ( {
|
|
@@ -159,31 +148,39 @@ export const onElementDestroy = ( {
|
|
|
159
148
|
elementId: string;
|
|
160
149
|
element?: Element;
|
|
161
150
|
} ) => {
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
if ( element ) {
|
|
166
|
-
dispatchDestroyedEvent( { element, elementType, elementId } );
|
|
151
|
+
if ( ! element ) {
|
|
152
|
+
return;
|
|
167
153
|
}
|
|
168
154
|
|
|
169
|
-
|
|
170
|
-
unmount();
|
|
171
|
-
}
|
|
155
|
+
cleanupOnUnmount( element );
|
|
172
156
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
selectorUnmount();
|
|
176
|
-
} );
|
|
177
|
-
}
|
|
157
|
+
dispatchDestroyedEvent( { element, elementType, elementId } );
|
|
158
|
+
};
|
|
178
159
|
|
|
179
|
-
|
|
180
|
-
|
|
160
|
+
const setUnmountEntry = ( {
|
|
161
|
+
element,
|
|
162
|
+
controller,
|
|
163
|
+
manualUnmount,
|
|
164
|
+
}: {
|
|
165
|
+
element: Element;
|
|
166
|
+
controller: AbortController;
|
|
167
|
+
manualUnmount: ( () => void )[];
|
|
168
|
+
} ) => {
|
|
169
|
+
const existingEntry = unmountCallbacks.get( element );
|
|
181
170
|
|
|
182
|
-
if (
|
|
183
|
-
|
|
171
|
+
if ( existingEntry ) {
|
|
172
|
+
existingEntry.manualUnmount.push( ...manualUnmount );
|
|
173
|
+
} else {
|
|
174
|
+
unmountCallbacks.set( element, { controller, manualUnmount } );
|
|
184
175
|
}
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
const cleanupOnUnmount = ( element: Element ) => {
|
|
179
|
+
const entry = unmountCallbacks.get( element );
|
|
185
180
|
|
|
186
|
-
if (
|
|
187
|
-
|
|
181
|
+
if ( entry ) {
|
|
182
|
+
entry.controller.abort();
|
|
183
|
+
entry.manualUnmount.forEach( ( callback ) => callback() );
|
|
184
|
+
unmountCallbacks.delete( element );
|
|
188
185
|
}
|
|
189
186
|
};
|