@elementor/frontend-handlers 4.1.0-778 → 4.1.0-779

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 CHANGED
@@ -212,6 +212,10 @@ var cleanupOnUnmount = (element) => {
212
212
  };
213
213
 
214
214
  // src/init.ts
215
+ var ATOMIC_SELECTOR = "[data-e-type]";
216
+ var domMutationObserverStarted = false;
217
+ var pendingMutationNodes = /* @__PURE__ */ new Set();
218
+ var pendingMutationsRafId = 0;
215
219
  function init() {
216
220
  window.addEventListener("elementor/element/render", (_event) => {
217
221
  const event = _event;
@@ -223,15 +227,79 @@ function init() {
223
227
  const { id, type, element } = event.detail;
224
228
  onElementDestroy({ elementType: type, elementId: id, element });
225
229
  });
226
- document.addEventListener("DOMContentLoaded", () => {
227
- document.querySelectorAll("[data-e-type]").forEach((element) => {
228
- const el = element;
229
- const { eType, id } = el.dataset;
230
- if (!eType || !id) {
231
- return;
230
+ const bootDomHandlers = () => {
231
+ scanDocumentForAtomicElements();
232
+ startObservingDomForNewAtomicElements();
233
+ };
234
+ document.addEventListener("DOMContentLoaded", bootDomHandlers);
235
+ if ("loading" !== document.readyState) {
236
+ bootDomHandlers();
237
+ }
238
+ }
239
+ function triggerAtomicRender(atom) {
240
+ const eType = atom.dataset.eType;
241
+ const id = atom.dataset.id;
242
+ if (!eType || !id) {
243
+ return;
244
+ }
245
+ onElementRender({ element: atom, elementType: eType, elementId: id });
246
+ }
247
+ function collectAtomicElementsInSubtree(root) {
248
+ const found = [];
249
+ if (root.matches(ATOMIC_SELECTOR)) {
250
+ found.push(root);
251
+ }
252
+ root.querySelectorAll(ATOMIC_SELECTOR).forEach((el) => {
253
+ found.push(el);
254
+ });
255
+ return found;
256
+ }
257
+ function scanDocumentForAtomicElements() {
258
+ document.querySelectorAll(ATOMIC_SELECTOR).forEach((el) => {
259
+ const atom = el;
260
+ const { eType, id } = atom.dataset;
261
+ if (!eType || !id) {
262
+ return;
263
+ }
264
+ triggerAtomicRender(atom);
265
+ });
266
+ }
267
+ function startObservingDomForNewAtomicElements() {
268
+ if (domMutationObserverStarted || "undefined" === typeof MutationObserver) {
269
+ return;
270
+ }
271
+ domMutationObserverStarted = true;
272
+ const observer = new MutationObserver((mutations) => {
273
+ for (const mutation of mutations) {
274
+ mutation.addedNodes.forEach((node) => {
275
+ pendingMutationNodes.add(node);
276
+ });
277
+ }
278
+ queueProcessPendingMutationNodes();
279
+ });
280
+ observer.observe(document.documentElement, {
281
+ childList: true,
282
+ subtree: true
283
+ });
284
+ }
285
+ function queueProcessPendingMutationNodes() {
286
+ if (pendingMutationsRafId || !pendingMutationNodes.size) {
287
+ return;
288
+ }
289
+ pendingMutationsRafId = requestAnimationFrame(() => {
290
+ pendingMutationsRafId = 0;
291
+ const roots = Array.from(pendingMutationNodes);
292
+ pendingMutationNodes.clear();
293
+ const atoms = /* @__PURE__ */ new Set();
294
+ for (const node of roots) {
295
+ if (Node.ELEMENT_NODE !== node.nodeType) {
296
+ continue;
232
297
  }
233
- onElementRender({ element: el, elementType: eType, elementId: id });
234
- });
298
+ collectAtomicElementsInSubtree(node).forEach((atom) => {
299
+ atoms.add(atom);
300
+ });
301
+ }
302
+ atoms.forEach((atom) => triggerAtomicRender(atom));
235
303
  });
236
304
  }
237
305
  // Annotate the CommonJS export names for ESM import in node:
package/dist/index.mjs CHANGED
@@ -182,6 +182,10 @@ var cleanupOnUnmount = (element) => {
182
182
  };
183
183
 
184
184
  // src/init.ts
185
+ var ATOMIC_SELECTOR = "[data-e-type]";
186
+ var domMutationObserverStarted = false;
187
+ var pendingMutationNodes = /* @__PURE__ */ new Set();
188
+ var pendingMutationsRafId = 0;
185
189
  function init() {
186
190
  window.addEventListener("elementor/element/render", (_event) => {
187
191
  const event = _event;
@@ -193,15 +197,79 @@ function init() {
193
197
  const { id, type, element } = event.detail;
194
198
  onElementDestroy({ elementType: type, elementId: id, element });
195
199
  });
196
- document.addEventListener("DOMContentLoaded", () => {
197
- document.querySelectorAll("[data-e-type]").forEach((element) => {
198
- const el = element;
199
- const { eType, id } = el.dataset;
200
- if (!eType || !id) {
201
- return;
200
+ const bootDomHandlers = () => {
201
+ scanDocumentForAtomicElements();
202
+ startObservingDomForNewAtomicElements();
203
+ };
204
+ document.addEventListener("DOMContentLoaded", bootDomHandlers);
205
+ if ("loading" !== document.readyState) {
206
+ bootDomHandlers();
207
+ }
208
+ }
209
+ function triggerAtomicRender(atom) {
210
+ const eType = atom.dataset.eType;
211
+ const id = atom.dataset.id;
212
+ if (!eType || !id) {
213
+ return;
214
+ }
215
+ onElementRender({ element: atom, elementType: eType, elementId: id });
216
+ }
217
+ function collectAtomicElementsInSubtree(root) {
218
+ const found = [];
219
+ if (root.matches(ATOMIC_SELECTOR)) {
220
+ found.push(root);
221
+ }
222
+ root.querySelectorAll(ATOMIC_SELECTOR).forEach((el) => {
223
+ found.push(el);
224
+ });
225
+ return found;
226
+ }
227
+ function scanDocumentForAtomicElements() {
228
+ document.querySelectorAll(ATOMIC_SELECTOR).forEach((el) => {
229
+ const atom = el;
230
+ const { eType, id } = atom.dataset;
231
+ if (!eType || !id) {
232
+ return;
233
+ }
234
+ triggerAtomicRender(atom);
235
+ });
236
+ }
237
+ function startObservingDomForNewAtomicElements() {
238
+ if (domMutationObserverStarted || "undefined" === typeof MutationObserver) {
239
+ return;
240
+ }
241
+ domMutationObserverStarted = true;
242
+ const observer = new MutationObserver((mutations) => {
243
+ for (const mutation of mutations) {
244
+ mutation.addedNodes.forEach((node) => {
245
+ pendingMutationNodes.add(node);
246
+ });
247
+ }
248
+ queueProcessPendingMutationNodes();
249
+ });
250
+ observer.observe(document.documentElement, {
251
+ childList: true,
252
+ subtree: true
253
+ });
254
+ }
255
+ function queueProcessPendingMutationNodes() {
256
+ if (pendingMutationsRafId || !pendingMutationNodes.size) {
257
+ return;
258
+ }
259
+ pendingMutationsRafId = requestAnimationFrame(() => {
260
+ pendingMutationsRafId = 0;
261
+ const roots = Array.from(pendingMutationNodes);
262
+ pendingMutationNodes.clear();
263
+ const atoms = /* @__PURE__ */ new Set();
264
+ for (const node of roots) {
265
+ if (Node.ELEMENT_NODE !== node.nodeType) {
266
+ continue;
202
267
  }
203
- onElementRender({ element: el, elementType: eType, elementId: id });
204
- });
268
+ collectAtomicElementsInSubtree(node).forEach((atom) => {
269
+ atoms.add(atom);
270
+ });
271
+ }
272
+ atoms.forEach((atom) => triggerAtomicRender(atom));
205
273
  });
206
274
  }
207
275
  export {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@elementor/frontend-handlers",
3
3
  "description": "Elementor Frontend Handlers",
4
- "version": "4.1.0-778",
4
+ "version": "4.1.0-779",
5
5
  "private": false,
6
6
  "author": "Elementor Team",
7
7
  "homepage": "https://elementor.com/",
package/src/init.ts CHANGED
@@ -1,5 +1,11 @@
1
1
  import { onElementDestroy, onElementRender } from './lifecycle-events';
2
2
 
3
+ const ATOMIC_SELECTOR = '[data-e-type]';
4
+
5
+ let domMutationObserverStarted = false;
6
+ const pendingMutationNodes = new Set< Node >();
7
+ let pendingMutationsRafId = 0;
8
+
3
9
  export function init() {
4
10
  window.addEventListener( 'elementor/element/render', ( _event ) => {
5
11
  const event = _event as CustomEvent< { id: string; type: string; element: Element } >;
@@ -15,17 +21,102 @@ export function init() {
15
21
  onElementDestroy( { elementType: type, elementId: id, element } );
16
22
  } );
17
23
 
18
- // 'elementor/element/render' doesn't fire on the frontend
19
- document.addEventListener( 'DOMContentLoaded', () => {
20
- document.querySelectorAll( '[data-e-type]' ).forEach( ( element ) => {
21
- const el = element as HTMLElement;
22
- const { eType, id } = el.dataset;
24
+ const bootDomHandlers = () => {
25
+ scanDocumentForAtomicElements();
26
+ startObservingDomForNewAtomicElements();
27
+ };
28
+
29
+ document.addEventListener( 'DOMContentLoaded', bootDomHandlers );
30
+
31
+ if ( 'loading' !== document.readyState ) {
32
+ bootDomHandlers();
33
+ }
34
+ }
35
+
36
+ function triggerAtomicRender( atom: HTMLElement ) {
37
+ const eType = atom.dataset.eType;
38
+ const id = atom.dataset.id;
39
+
40
+ if ( ! eType || ! id ) {
41
+ return;
42
+ }
43
+
44
+ onElementRender( { element: atom, elementType: eType, elementId: id } );
45
+ }
46
+
47
+ function collectAtomicElementsInSubtree( root: Element ): HTMLElement[] {
48
+ const found: HTMLElement[] = [];
49
+
50
+ if ( root.matches( ATOMIC_SELECTOR ) ) {
51
+ found.push( root as HTMLElement );
52
+ }
53
+
54
+ root.querySelectorAll( ATOMIC_SELECTOR ).forEach( ( el ) => {
55
+ found.push( el as HTMLElement );
56
+ } );
57
+
58
+ return found;
59
+ }
60
+
61
+ function scanDocumentForAtomicElements() {
62
+ document.querySelectorAll( ATOMIC_SELECTOR ).forEach( ( el ) => {
63
+ const atom = el as HTMLElement;
64
+ const { eType, id } = atom.dataset;
65
+
66
+ if ( ! eType || ! id ) {
67
+ return;
68
+ }
23
69
 
24
- if ( ! eType || ! id ) {
25
- return;
70
+ triggerAtomicRender( atom );
71
+ } );
72
+ }
73
+
74
+ function startObservingDomForNewAtomicElements() {
75
+ if ( domMutationObserverStarted || 'undefined' === typeof MutationObserver ) {
76
+ return;
77
+ }
78
+
79
+ domMutationObserverStarted = true;
80
+
81
+ const observer = new MutationObserver( ( mutations ) => {
82
+ for ( const mutation of mutations ) {
83
+ mutation.addedNodes.forEach( ( node ) => {
84
+ pendingMutationNodes.add( node );
85
+ } );
86
+ }
87
+
88
+ queueProcessPendingMutationNodes();
89
+ } );
90
+
91
+ observer.observe( document.documentElement, {
92
+ childList: true,
93
+ subtree: true,
94
+ } );
95
+ }
96
+
97
+ function queueProcessPendingMutationNodes() {
98
+ if ( pendingMutationsRafId || ! pendingMutationNodes.size ) {
99
+ return;
100
+ }
101
+
102
+ pendingMutationsRafId = requestAnimationFrame( () => {
103
+ pendingMutationsRafId = 0;
104
+
105
+ const roots = Array.from( pendingMutationNodes );
106
+ pendingMutationNodes.clear();
107
+
108
+ const atoms = new Set< HTMLElement >();
109
+
110
+ for ( const node of roots ) {
111
+ if ( Node.ELEMENT_NODE !== node.nodeType ) {
112
+ continue;
26
113
  }
27
114
 
28
- onElementRender( { element: el, elementType: eType, elementId: id } );
29
- } );
115
+ collectAtomicElementsInSubtree( node as Element ).forEach( ( atom ) => {
116
+ atoms.add( atom );
117
+ } );
118
+ }
119
+
120
+ atoms.forEach( ( atom ) => triggerAtomicRender( atom ) );
30
121
  } );
31
122
  }