@elementor/frontend-handlers 3.35.0-429 → 3.35.0-431
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 +28 -14
- package/dist/index.mjs +28 -14
- package/package.json +1 -1
- package/src/__tests__/index.test.ts +103 -3
- package/src/init.ts +3 -3
- package/src/lifecycle-events.ts +41 -14
package/dist/index.js
CHANGED
|
@@ -82,6 +82,15 @@ var unregisterBySelector = ({ selector, id }) => {
|
|
|
82
82
|
var unmountElementTypeCallbacks = /* @__PURE__ */ new Map();
|
|
83
83
|
var unmountElementSelectorCallbacks = /* @__PURE__ */ new Map();
|
|
84
84
|
var ELEMENT_RENDERED_EVENT_NAME = "elementor/element/rendered";
|
|
85
|
+
var ELEMENT_DESTROYED_EVENT_NAME = "elementor/element/destroyed";
|
|
86
|
+
var dispatchDestroyedEvent = (params) => {
|
|
87
|
+
params.element.dispatchEvent(
|
|
88
|
+
new CustomEvent(ELEMENT_DESTROYED_EVENT_NAME, {
|
|
89
|
+
bubbles: true,
|
|
90
|
+
detail: params
|
|
91
|
+
})
|
|
92
|
+
);
|
|
93
|
+
};
|
|
85
94
|
var onElementRender = ({
|
|
86
95
|
element,
|
|
87
96
|
elementType,
|
|
@@ -116,17 +125,15 @@ var onElementRender = ({
|
|
|
116
125
|
const settings = element.getAttribute("data-e-settings");
|
|
117
126
|
const listenToChildren = (elementTypes) => ({
|
|
118
127
|
render: (callback) => {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
(
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
{ signal: controller.signal }
|
|
129
|
-
);
|
|
128
|
+
const listener = (event) => {
|
|
129
|
+
const { elementType: childType } = event.detail;
|
|
130
|
+
if (!elementTypes.includes(childType)) {
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
callback();
|
|
134
|
+
};
|
|
135
|
+
element.addEventListener(ELEMENT_RENDERED_EVENT_NAME, listener, { signal: controller.signal });
|
|
136
|
+
element.addEventListener(ELEMENT_DESTROYED_EVENT_NAME, listener, { signal: controller.signal });
|
|
130
137
|
}
|
|
131
138
|
});
|
|
132
139
|
const unmount = handler({
|
|
@@ -180,9 +187,16 @@ var onElementSelectorRender = ({
|
|
|
180
187
|
});
|
|
181
188
|
});
|
|
182
189
|
};
|
|
183
|
-
var onElementDestroy = ({
|
|
190
|
+
var onElementDestroy = ({
|
|
191
|
+
elementType,
|
|
192
|
+
elementId,
|
|
193
|
+
element
|
|
194
|
+
}) => {
|
|
184
195
|
const unmount = unmountElementTypeCallbacks.get(elementType)?.get(elementId);
|
|
185
196
|
const unmountSelector = unmountElementSelectorCallbacks.get(elementId);
|
|
197
|
+
if (element) {
|
|
198
|
+
dispatchDestroyedEvent({ element, elementType, elementId });
|
|
199
|
+
}
|
|
186
200
|
if (unmount) {
|
|
187
201
|
unmount();
|
|
188
202
|
}
|
|
@@ -211,8 +225,8 @@ function init() {
|
|
|
211
225
|
});
|
|
212
226
|
window.addEventListener("elementor/element/destroy", (_event) => {
|
|
213
227
|
const event = _event;
|
|
214
|
-
const { id, type } = event.detail;
|
|
215
|
-
onElementDestroy({ elementType: type, elementId: id });
|
|
228
|
+
const { id, type, element } = event.detail;
|
|
229
|
+
onElementDestroy({ elementType: type, elementId: id, element });
|
|
216
230
|
});
|
|
217
231
|
document.addEventListener("DOMContentLoaded", () => {
|
|
218
232
|
document.querySelectorAll("[data-e-type]").forEach((element) => {
|
package/dist/index.mjs
CHANGED
|
@@ -52,6 +52,15 @@ var unregisterBySelector = ({ selector, id }) => {
|
|
|
52
52
|
var unmountElementTypeCallbacks = /* @__PURE__ */ new Map();
|
|
53
53
|
var unmountElementSelectorCallbacks = /* @__PURE__ */ new Map();
|
|
54
54
|
var ELEMENT_RENDERED_EVENT_NAME = "elementor/element/rendered";
|
|
55
|
+
var ELEMENT_DESTROYED_EVENT_NAME = "elementor/element/destroyed";
|
|
56
|
+
var dispatchDestroyedEvent = (params) => {
|
|
57
|
+
params.element.dispatchEvent(
|
|
58
|
+
new CustomEvent(ELEMENT_DESTROYED_EVENT_NAME, {
|
|
59
|
+
bubbles: true,
|
|
60
|
+
detail: params
|
|
61
|
+
})
|
|
62
|
+
);
|
|
63
|
+
};
|
|
55
64
|
var onElementRender = ({
|
|
56
65
|
element,
|
|
57
66
|
elementType,
|
|
@@ -86,17 +95,15 @@ var onElementRender = ({
|
|
|
86
95
|
const settings = element.getAttribute("data-e-settings");
|
|
87
96
|
const listenToChildren = (elementTypes) => ({
|
|
88
97
|
render: (callback) => {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
(
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
{ signal: controller.signal }
|
|
99
|
-
);
|
|
98
|
+
const listener = (event) => {
|
|
99
|
+
const { elementType: childType } = event.detail;
|
|
100
|
+
if (!elementTypes.includes(childType)) {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
callback();
|
|
104
|
+
};
|
|
105
|
+
element.addEventListener(ELEMENT_RENDERED_EVENT_NAME, listener, { signal: controller.signal });
|
|
106
|
+
element.addEventListener(ELEMENT_DESTROYED_EVENT_NAME, listener, { signal: controller.signal });
|
|
100
107
|
}
|
|
101
108
|
});
|
|
102
109
|
const unmount = handler({
|
|
@@ -150,9 +157,16 @@ var onElementSelectorRender = ({
|
|
|
150
157
|
});
|
|
151
158
|
});
|
|
152
159
|
};
|
|
153
|
-
var onElementDestroy = ({
|
|
160
|
+
var onElementDestroy = ({
|
|
161
|
+
elementType,
|
|
162
|
+
elementId,
|
|
163
|
+
element
|
|
164
|
+
}) => {
|
|
154
165
|
const unmount = unmountElementTypeCallbacks.get(elementType)?.get(elementId);
|
|
155
166
|
const unmountSelector = unmountElementSelectorCallbacks.get(elementId);
|
|
167
|
+
if (element) {
|
|
168
|
+
dispatchDestroyedEvent({ element, elementType, elementId });
|
|
169
|
+
}
|
|
156
170
|
if (unmount) {
|
|
157
171
|
unmount();
|
|
158
172
|
}
|
|
@@ -181,8 +195,8 @@ function init() {
|
|
|
181
195
|
});
|
|
182
196
|
window.addEventListener("elementor/element/destroy", (_event) => {
|
|
183
197
|
const event = _event;
|
|
184
|
-
const { id, type } = event.detail;
|
|
185
|
-
onElementDestroy({ elementType: type, elementId: id });
|
|
198
|
+
const { id, type, element } = event.detail;
|
|
199
|
+
onElementDestroy({ elementType: type, elementId: id, element });
|
|
186
200
|
});
|
|
187
201
|
document.addEventListener("DOMContentLoaded", () => {
|
|
188
202
|
document.querySelectorAll("[data-e-type]").forEach((element) => {
|
package/package.json
CHANGED
|
@@ -264,7 +264,7 @@ describe( 'Frontend Handlers', () => {
|
|
|
264
264
|
// Act
|
|
265
265
|
window.dispatchEvent(
|
|
266
266
|
new CustomEvent( 'elementor/element/destroy', {
|
|
267
|
-
detail: { id: ELEMENT_ID, type: WIDGET_ELEMENT_TYPE },
|
|
267
|
+
detail: { id: ELEMENT_ID, type: WIDGET_ELEMENT_TYPE, element },
|
|
268
268
|
} )
|
|
269
269
|
);
|
|
270
270
|
|
|
@@ -272,6 +272,50 @@ describe( 'Frontend Handlers', () => {
|
|
|
272
272
|
expect( unmountCallback ).toHaveBeenCalledTimes( 1 );
|
|
273
273
|
} );
|
|
274
274
|
|
|
275
|
+
it( 'should dispatch destroyed event when element is destroyed', () => {
|
|
276
|
+
// Arrange
|
|
277
|
+
const ELEMENT_ID = 'element-1';
|
|
278
|
+
const destroyedEventCallback = jest.fn();
|
|
279
|
+
|
|
280
|
+
register( {
|
|
281
|
+
elementType: WIDGET_ELEMENT_TYPE,
|
|
282
|
+
id: 'widget-handler',
|
|
283
|
+
callback: () => undefined,
|
|
284
|
+
} );
|
|
285
|
+
|
|
286
|
+
const element = document.createElement( 'div' );
|
|
287
|
+
element.setAttribute( 'data-e-type', WIDGET_ELEMENT_TYPE );
|
|
288
|
+
element.setAttribute( 'data-id', ELEMENT_ID );
|
|
289
|
+
document.body.appendChild( element );
|
|
290
|
+
|
|
291
|
+
window.dispatchEvent(
|
|
292
|
+
new CustomEvent( 'elementor/element/render', {
|
|
293
|
+
detail: { id: ELEMENT_ID, type: WIDGET_ELEMENT_TYPE, element },
|
|
294
|
+
} )
|
|
295
|
+
);
|
|
296
|
+
|
|
297
|
+
element.addEventListener( 'elementor/element/destroyed', destroyedEventCallback );
|
|
298
|
+
|
|
299
|
+
// Act
|
|
300
|
+
window.dispatchEvent(
|
|
301
|
+
new CustomEvent( 'elementor/element/destroy', {
|
|
302
|
+
detail: { id: ELEMENT_ID, type: WIDGET_ELEMENT_TYPE, element },
|
|
303
|
+
} )
|
|
304
|
+
);
|
|
305
|
+
|
|
306
|
+
// Assert
|
|
307
|
+
expect( destroyedEventCallback ).toHaveBeenCalledTimes( 1 );
|
|
308
|
+
expect( destroyedEventCallback ).toHaveBeenCalledWith(
|
|
309
|
+
expect.objectContaining( {
|
|
310
|
+
detail: expect.objectContaining( {
|
|
311
|
+
element,
|
|
312
|
+
elementType: WIDGET_ELEMENT_TYPE,
|
|
313
|
+
elementId: ELEMENT_ID,
|
|
314
|
+
} ),
|
|
315
|
+
} )
|
|
316
|
+
);
|
|
317
|
+
} );
|
|
318
|
+
|
|
275
319
|
it( 'should cleanup on re-render before new initialization', () => {
|
|
276
320
|
// Arrange
|
|
277
321
|
const ELEMENT_ID = 'element-1';
|
|
@@ -379,7 +423,7 @@ describe( 'Frontend Handlers', () => {
|
|
|
379
423
|
// Act
|
|
380
424
|
window.dispatchEvent(
|
|
381
425
|
new CustomEvent( 'elementor/element/destroy', {
|
|
382
|
-
detail: { id: ELEMENT_ID, type: WIDGET_ELEMENT_TYPE },
|
|
426
|
+
detail: { id: ELEMENT_ID, type: WIDGET_ELEMENT_TYPE, element },
|
|
383
427
|
} )
|
|
384
428
|
);
|
|
385
429
|
|
|
@@ -432,6 +476,62 @@ describe( 'Frontend Handlers', () => {
|
|
|
432
476
|
expect( childRenderCallback ).toHaveBeenCalledTimes( 1 );
|
|
433
477
|
} );
|
|
434
478
|
|
|
479
|
+
it( 'should trigger destroy callback when child of specified type is destroyed', () => {
|
|
480
|
+
// Arrange
|
|
481
|
+
const PARENT_ID = 'parent-1';
|
|
482
|
+
const CHILD_ID = 'child-1';
|
|
483
|
+
const childDestroyCallback = jest.fn();
|
|
484
|
+
|
|
485
|
+
register( {
|
|
486
|
+
elementType: PARENT_ELEMENT_TYPE,
|
|
487
|
+
id: 'parent-handler',
|
|
488
|
+
callback: ( { listenToChildren } ) => {
|
|
489
|
+
listenToChildren( [ CHILD_ELEMENT_TYPE ] ).render( childDestroyCallback );
|
|
490
|
+
return undefined;
|
|
491
|
+
},
|
|
492
|
+
} );
|
|
493
|
+
|
|
494
|
+
register( {
|
|
495
|
+
elementType: CHILD_ELEMENT_TYPE,
|
|
496
|
+
id: 'child-handler',
|
|
497
|
+
callback: () => undefined,
|
|
498
|
+
} );
|
|
499
|
+
|
|
500
|
+
const parent = document.createElement( 'div' );
|
|
501
|
+
parent.setAttribute( 'data-e-type', PARENT_ELEMENT_TYPE );
|
|
502
|
+
parent.setAttribute( 'data-id', PARENT_ID );
|
|
503
|
+
document.body.appendChild( parent );
|
|
504
|
+
|
|
505
|
+
const child = document.createElement( 'div' );
|
|
506
|
+
child.setAttribute( 'data-e-type', CHILD_ELEMENT_TYPE );
|
|
507
|
+
child.setAttribute( 'data-id', CHILD_ID );
|
|
508
|
+
parent.appendChild( child );
|
|
509
|
+
|
|
510
|
+
window.dispatchEvent(
|
|
511
|
+
new CustomEvent( 'elementor/element/render', {
|
|
512
|
+
detail: { id: PARENT_ID, type: PARENT_ELEMENT_TYPE, element: parent },
|
|
513
|
+
} )
|
|
514
|
+
);
|
|
515
|
+
|
|
516
|
+
window.dispatchEvent(
|
|
517
|
+
new CustomEvent( 'elementor/element/render', {
|
|
518
|
+
detail: { id: CHILD_ID, type: CHILD_ELEMENT_TYPE, element: child },
|
|
519
|
+
} )
|
|
520
|
+
);
|
|
521
|
+
|
|
522
|
+
childDestroyCallback.mockClear();
|
|
523
|
+
|
|
524
|
+
// Act
|
|
525
|
+
window.dispatchEvent(
|
|
526
|
+
new CustomEvent( 'elementor/element/destroy', {
|
|
527
|
+
detail: { id: CHILD_ID, type: CHILD_ELEMENT_TYPE, element: child },
|
|
528
|
+
} )
|
|
529
|
+
);
|
|
530
|
+
|
|
531
|
+
// Assert
|
|
532
|
+
expect( childDestroyCallback ).toHaveBeenCalledTimes( 1 );
|
|
533
|
+
} );
|
|
534
|
+
|
|
435
535
|
it( 'should not trigger callback for non-descendant elements', () => {
|
|
436
536
|
// Arrange
|
|
437
537
|
const PARENT_ID = 'parent-1';
|
|
@@ -509,7 +609,7 @@ describe( 'Frontend Handlers', () => {
|
|
|
509
609
|
// Destroy Parent (should remove listener)
|
|
510
610
|
window.dispatchEvent(
|
|
511
611
|
new CustomEvent( 'elementor/element/destroy', {
|
|
512
|
-
detail: { id: PARENT_ID, type: PARENT_ELEMENT_TYPE },
|
|
612
|
+
detail: { id: PARENT_ID, type: PARENT_ELEMENT_TYPE, element: parent },
|
|
513
613
|
} )
|
|
514
614
|
);
|
|
515
615
|
|
package/src/init.ts
CHANGED
|
@@ -12,10 +12,10 @@ export function init() {
|
|
|
12
12
|
} );
|
|
13
13
|
|
|
14
14
|
window.addEventListener( 'elementor/element/destroy', ( _event ) => {
|
|
15
|
-
const event = _event as CustomEvent< { id: string; type: string } >;
|
|
16
|
-
const { id, type } = event.detail;
|
|
15
|
+
const event = _event as CustomEvent< { id: string; type: string; element: Element } >;
|
|
16
|
+
const { id, type, element } = event.detail;
|
|
17
17
|
|
|
18
|
-
onElementDestroy( { elementType: type, elementId: id } );
|
|
18
|
+
onElementDestroy( { elementType: type, elementId: id, element } );
|
|
19
19
|
} );
|
|
20
20
|
|
|
21
21
|
// 'elementor/element/render' doesn't fire on the frontend
|
package/src/lifecycle-events.ts
CHANGED
|
@@ -4,6 +4,22 @@ const unmountElementTypeCallbacks: Map< string, Map< string, () => void > > = ne
|
|
|
4
4
|
const unmountElementSelectorCallbacks: Map< string, Map< string, () => void > > = new Map();
|
|
5
5
|
|
|
6
6
|
const ELEMENT_RENDERED_EVENT_NAME = 'elementor/element/rendered';
|
|
7
|
+
const ELEMENT_DESTROYED_EVENT_NAME = 'elementor/element/destroyed';
|
|
8
|
+
|
|
9
|
+
type LifecycleEventParams = {
|
|
10
|
+
element: Element;
|
|
11
|
+
elementType: string;
|
|
12
|
+
elementId: string;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const dispatchDestroyedEvent = ( params: LifecycleEventParams ) => {
|
|
16
|
+
params.element.dispatchEvent(
|
|
17
|
+
new CustomEvent( ELEMENT_DESTROYED_EVENT_NAME, {
|
|
18
|
+
bubbles: true,
|
|
19
|
+
detail: params,
|
|
20
|
+
} )
|
|
21
|
+
);
|
|
22
|
+
};
|
|
7
23
|
|
|
8
24
|
export const onElementRender = ( {
|
|
9
25
|
element,
|
|
@@ -50,19 +66,18 @@ export const onElementRender = ( {
|
|
|
50
66
|
|
|
51
67
|
const listenToChildren = ( elementTypes: string[] ) => ( {
|
|
52
68
|
render: ( callback: () => void ) => {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
);
|
|
69
|
+
const listener = ( event: Event ) => {
|
|
70
|
+
const { elementType: childType } = ( event as CustomEvent ).detail;
|
|
71
|
+
|
|
72
|
+
if ( ! elementTypes.includes( childType ) ) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
callback();
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
element.addEventListener( ELEMENT_RENDERED_EVENT_NAME, listener, { signal: controller.signal } );
|
|
80
|
+
element.addEventListener( ELEMENT_DESTROYED_EVENT_NAME, listener, { signal: controller.signal } );
|
|
66
81
|
},
|
|
67
82
|
} );
|
|
68
83
|
|
|
@@ -135,10 +150,22 @@ export const onElementSelectorRender = ( {
|
|
|
135
150
|
} );
|
|
136
151
|
};
|
|
137
152
|
|
|
138
|
-
export const onElementDestroy = ( {
|
|
153
|
+
export const onElementDestroy = ( {
|
|
154
|
+
elementType,
|
|
155
|
+
elementId,
|
|
156
|
+
element,
|
|
157
|
+
}: {
|
|
158
|
+
elementType: string;
|
|
159
|
+
elementId: string;
|
|
160
|
+
element?: Element;
|
|
161
|
+
} ) => {
|
|
139
162
|
const unmount = unmountElementTypeCallbacks.get( elementType )?.get( elementId );
|
|
140
163
|
const unmountSelector = unmountElementSelectorCallbacks.get( elementId );
|
|
141
164
|
|
|
165
|
+
if ( element ) {
|
|
166
|
+
dispatchDestroyedEvent( { element, elementType, elementId } );
|
|
167
|
+
}
|
|
168
|
+
|
|
142
169
|
if ( unmount ) {
|
|
143
170
|
unmount();
|
|
144
171
|
}
|