@elementor/editor-elements 3.33.0-99 → 3.35.0-325

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.
Files changed (50) hide show
  1. package/dist/index.d.mts +200 -99
  2. package/dist/index.d.ts +200 -99
  3. package/dist/index.js +1161 -394
  4. package/dist/index.js.map +1 -1
  5. package/dist/index.mjs +1158 -401
  6. package/dist/index.mjs.map +1 -1
  7. package/package.json +7 -5
  8. package/src/errors.ts +10 -0
  9. package/src/hooks/use-element-children.ts +12 -12
  10. package/src/hooks/use-element-editor-settings.ts +12 -0
  11. package/src/hooks/use-element-interactions.ts +25 -0
  12. package/src/hooks/use-element-setting.ts +1 -1
  13. package/src/hooks/use-selected-element.ts +2 -2
  14. package/src/index.ts +38 -27
  15. package/src/mcp/elements-tool.ts +345 -0
  16. package/src/mcp/handlers/common-style-utils.ts +23 -0
  17. package/src/mcp/handlers/create-element.ts +96 -0
  18. package/src/mcp/handlers/create-style.ts +42 -0
  19. package/src/mcp/handlers/delete-element.ts +17 -0
  20. package/src/mcp/handlers/delete-style.ts +22 -0
  21. package/src/mcp/handlers/deselect-element.ts +21 -0
  22. package/src/mcp/handlers/duplicate-element.ts +22 -0
  23. package/src/mcp/handlers/get-element-props.ts +28 -0
  24. package/src/mcp/handlers/get-element-schema.ts +17 -0
  25. package/src/mcp/handlers/get-selected.ts +5 -0
  26. package/src/mcp/handlers/get-styles.ts +26 -0
  27. package/src/mcp/handlers/list-available-types.ts +27 -0
  28. package/src/mcp/handlers/move-element.ts +30 -0
  29. package/src/mcp/handlers/select-element.ts +25 -0
  30. package/src/mcp/handlers/update-props.ts +22 -0
  31. package/src/mcp/handlers/update-styles.ts +45 -0
  32. package/src/mcp/index.ts +9 -0
  33. package/src/sync/delete-element.ts +8 -2
  34. package/src/sync/drop-element.ts +30 -0
  35. package/src/sync/duplicate-elements.ts +3 -4
  36. package/src/sync/get-current-document-container.ts +1 -1
  37. package/src/sync/get-element-editor-settings.ts +8 -0
  38. package/src/sync/get-element-interactions.ts +15 -0
  39. package/src/sync/get-element-label.ts +6 -1
  40. package/src/sync/get-element-type.ts +28 -0
  41. package/src/sync/get-elements.ts +1 -1
  42. package/src/sync/get-widgets-cache.ts +4 -3
  43. package/src/sync/move-elements.ts +9 -1
  44. package/src/sync/remove-elements.ts +11 -0
  45. package/src/sync/replace-element.ts +50 -12
  46. package/src/sync/types.ts +32 -3
  47. package/src/sync/update-element-editor-settings.ts +28 -0
  48. package/src/sync/update-element-interactions.ts +32 -0
  49. package/src/types.ts +16 -1
  50. package/src/hooks/use-element-type.ts +0 -35
package/dist/index.js CHANGED
@@ -26,41 +26,51 @@ __export(index_exports, {
26
26
  createElements: () => createElements,
27
27
  deleteElement: () => deleteElement,
28
28
  deleteElementStyle: () => deleteElementStyle,
29
+ dropElement: () => dropElement,
29
30
  duplicateElement: () => duplicateElement,
30
31
  duplicateElements: () => duplicateElements,
31
32
  generateElementId: () => generateElementId,
32
33
  getAnchoredAncestorId: () => getAnchoredAncestorId,
33
34
  getAnchoredDescendantId: () => getAnchoredDescendantId,
34
35
  getContainer: () => getContainer,
36
+ getCurrentDocumentContainer: () => getCurrentDocumentContainer,
35
37
  getCurrentDocumentId: () => getCurrentDocumentId,
38
+ getElementEditorSettings: () => getElementEditorSettings,
39
+ getElementInteractions: () => getElementInteractions,
36
40
  getElementLabel: () => getElementLabel,
37
41
  getElementSetting: () => getElementSetting,
38
42
  getElementSettings: () => getElementSettings,
39
43
  getElementStyles: () => getElementStyles,
44
+ getElementType: () => getElementType,
40
45
  getElements: () => getElements,
41
46
  getLinkInLinkRestriction: () => getLinkInLinkRestriction,
42
47
  getSelectedElements: () => getSelectedElements,
43
48
  getWidgetsCache: () => getWidgetsCache,
49
+ initElementsMcp: () => initMcp,
44
50
  isElementAnchored: () => isElementAnchored,
45
51
  moveElement: () => moveElement,
46
52
  moveElements: () => moveElements,
53
+ playElementInteractions: () => playElementInteractions,
47
54
  removeElements: () => removeElements,
48
55
  replaceElement: () => replaceElement,
49
56
  selectElement: () => selectElement,
50
57
  shouldCreateNewLocalStyle: () => shouldCreateNewLocalStyle,
51
58
  styleRerenderEvents: () => styleRerenderEvents,
59
+ updateElementEditorSettings: () => updateElementEditorSettings,
60
+ updateElementInteractions: () => updateElementInteractions,
52
61
  updateElementSettings: () => updateElementSettings,
53
62
  updateElementStyle: () => updateElementStyle,
54
63
  useElementChildren: () => useElementChildren,
64
+ useElementEditorSettings: () => useElementEditorSettings,
65
+ useElementInteractions: () => useElementInteractions,
55
66
  useElementSetting: () => useElementSetting,
56
67
  useElementSettings: () => useElementSettings,
57
- useElementType: () => useElementType,
58
68
  useParentElement: () => useParentElement,
59
69
  useSelectedElement: () => useSelectedElement
60
70
  });
61
71
  module.exports = __toCommonJS(index_exports);
62
72
 
63
- // src/hooks/use-element-setting.ts
73
+ // src/hooks/use-element-children.ts
64
74
  var import_editor_v1_adapters2 = require("@elementor/editor-v1-adapters");
65
75
 
66
76
  // src/sync/get-container.ts
@@ -78,6 +88,53 @@ var selectElement = (elementId) => {
78
88
  }
79
89
  };
80
90
 
91
+ // src/hooks/use-element-children.ts
92
+ function useElementChildren(elementId, childrenTypes) {
93
+ return (0, import_editor_v1_adapters2.__privateUseListenTo)(
94
+ [
95
+ (0, import_editor_v1_adapters2.v1ReadyEvent)(),
96
+ (0, import_editor_v1_adapters2.commandEndEvent)("document/elements/create"),
97
+ (0, import_editor_v1_adapters2.commandEndEvent)("document/elements/delete"),
98
+ (0, import_editor_v1_adapters2.commandEndEvent)("document/elements/update"),
99
+ (0, import_editor_v1_adapters2.commandEndEvent)("document/elements/set-settings")
100
+ ],
101
+ () => {
102
+ const container = getContainer(elementId);
103
+ const elementChildren = Object.entries(childrenTypes).reduce((acc, [parentType, childType]) => {
104
+ const parent = container?.children?.findRecursive?.(
105
+ ({ model }) => model.get("elType") === parentType
106
+ );
107
+ const children = parent?.children ?? [];
108
+ acc[childType] = children.filter(({ model }) => model.get("elType") === childType).map(({ id }) => ({ id }));
109
+ return acc;
110
+ }, {});
111
+ return elementChildren;
112
+ },
113
+ [elementId]
114
+ );
115
+ }
116
+
117
+ // src/hooks/use-element-editor-settings.ts
118
+ var import_editor_v1_adapters3 = require("@elementor/editor-v1-adapters");
119
+
120
+ // src/sync/get-element-editor-settings.ts
121
+ function getElementEditorSettings(elementId) {
122
+ const container = getContainer(elementId);
123
+ return container?.model.get("editor_settings") ?? {};
124
+ }
125
+
126
+ // src/hooks/use-element-editor-settings.ts
127
+ var useElementEditorSettings = (elementId) => {
128
+ return (0, import_editor_v1_adapters3.__privateUseListenTo)(
129
+ (0, import_editor_v1_adapters3.windowEvent)("elementor/element/update_editor_settings"),
130
+ () => getElementEditorSettings(elementId),
131
+ [elementId]
132
+ );
133
+ };
134
+
135
+ // src/hooks/use-element-setting.ts
136
+ var import_editor_v1_adapters4 = require("@elementor/editor-v1-adapters");
137
+
81
138
  // src/sync/get-element-setting.ts
82
139
  var getElementSetting = (elementId, settingKey) => {
83
140
  const container = getContainer(elementId);
@@ -89,15 +146,15 @@ var getElementSettings = (elementId, settingKey) => {
89
146
 
90
147
  // src/hooks/use-element-setting.ts
91
148
  var useElementSetting = (elementId, settingKey) => {
92
- return (0, import_editor_v1_adapters2.__privateUseListenTo)(
93
- (0, import_editor_v1_adapters2.commandEndEvent)("document/elements/set-settings"),
149
+ return (0, import_editor_v1_adapters4.__privateUseListenTo)(
150
+ (0, import_editor_v1_adapters4.commandEndEvent)("document/elements/set-settings"),
94
151
  () => getElementSetting(elementId, settingKey),
95
152
  [elementId, settingKey]
96
153
  );
97
154
  };
98
155
  var useElementSettings = (elementId, settingKeys) => {
99
- return (0, import_editor_v1_adapters2.__privateUseListenTo)(
100
- (0, import_editor_v1_adapters2.commandEndEvent)("document/elements/set-settings"),
156
+ return (0, import_editor_v1_adapters4.__privateUseListenTo)(
157
+ (0, import_editor_v1_adapters4.commandEndEvent)("document/elements/set-settings"),
101
158
  () => settingKeys.reduce((settings, key) => {
102
159
  const value = getElementSetting(elementId, key);
103
160
  if (value !== null) {
@@ -105,49 +162,61 @@ var useElementSettings = (elementId, settingKeys) => {
105
162
  }
106
163
  return settings;
107
164
  }, {}),
108
- [elementId, ...settingKeys]
165
+ [elementId, settingKeys.join(",")]
109
166
  );
110
167
  };
111
168
 
112
- // src/hooks/use-element-type.ts
113
- var import_editor_v1_adapters3 = require("@elementor/editor-v1-adapters");
114
-
115
- // src/sync/get-widgets-cache.ts
116
- function getWidgetsCache() {
117
- const extendedWindow = window;
118
- return extendedWindow?.elementor?.widgetsCache || null;
119
- }
120
-
121
- // src/hooks/use-element-type.ts
122
- function useElementType(type) {
123
- return (0, import_editor_v1_adapters3.__privateUseListenTo)(
124
- (0, import_editor_v1_adapters3.commandEndEvent)("editor/documents/load"),
169
+ // src/hooks/use-parent-element.ts
170
+ var import_editor_v1_adapters5 = require("@elementor/editor-v1-adapters");
171
+ function useParentElement(elementId) {
172
+ return (0, import_editor_v1_adapters5.__privateUseListenTo)(
173
+ [(0, import_editor_v1_adapters5.commandEndEvent)("document/elements/create")],
125
174
  () => {
126
- if (!type) {
127
- return null;
128
- }
129
- const widgetsCache = getWidgetsCache();
130
- const elementType = widgetsCache?.[type];
131
- if (!elementType?.atomic_controls) {
175
+ if (!elementId) {
132
176
  return null;
133
177
  }
134
- if (!elementType?.atomic_props_schema) {
178
+ const extendedWindow = window;
179
+ const element = extendedWindow?.elementor?.getContainer?.(elementId);
180
+ if (!element) {
135
181
  return null;
136
182
  }
137
- return {
138
- key: type,
139
- controls: elementType.atomic_controls,
140
- propsSchema: elementType.atomic_props_schema,
141
- dependenciesPerTargetMapping: elementType.dependencies_per_target_mapping ?? {},
142
- title: elementType.title
143
- };
183
+ return element.parent;
144
184
  },
145
- [type]
185
+ [elementId]
146
186
  );
147
187
  }
148
188
 
149
189
  // src/hooks/use-selected-element.ts
150
- var import_editor_v1_adapters4 = require("@elementor/editor-v1-adapters");
190
+ var import_editor_v1_adapters6 = require("@elementor/editor-v1-adapters");
191
+
192
+ // src/sync/get-widgets-cache.ts
193
+ function getWidgetsCache() {
194
+ const extendedWindow = window;
195
+ return extendedWindow?.elementor?.widgetsCache || null;
196
+ }
197
+
198
+ // src/sync/get-element-type.ts
199
+ function getElementType(type) {
200
+ if (!type) {
201
+ return null;
202
+ }
203
+ const widgetsCache = getWidgetsCache();
204
+ const elementType = widgetsCache?.[type];
205
+ if (!elementType?.atomic_controls) {
206
+ return null;
207
+ }
208
+ if (!elementType?.atomic_props_schema) {
209
+ return null;
210
+ }
211
+ return {
212
+ key: type,
213
+ controls: elementType.atomic_controls,
214
+ propsSchema: elementType.atomic_props_schema,
215
+ dependenciesPerTargetMapping: elementType.dependencies_per_target_mapping ?? {},
216
+ title: elementType.title,
217
+ styleStates: elementType.atomic_style_states ?? []
218
+ };
219
+ }
151
220
 
152
221
  // src/sync/get-selected-elements.ts
153
222
  function getSelectedElements() {
@@ -167,72 +236,23 @@ function getSelectedElements() {
167
236
 
168
237
  // src/hooks/use-selected-element.ts
169
238
  function useSelectedElement() {
170
- const elements = (0, import_editor_v1_adapters4.__privateUseListenTo)(
239
+ const elements = (0, import_editor_v1_adapters6.__privateUseListenTo)(
171
240
  [
172
- (0, import_editor_v1_adapters4.commandEndEvent)("document/elements/select"),
173
- (0, import_editor_v1_adapters4.commandEndEvent)("document/elements/deselect"),
174
- (0, import_editor_v1_adapters4.commandEndEvent)("document/elements/select-all"),
175
- (0, import_editor_v1_adapters4.commandEndEvent)("document/elements/deselect-all")
241
+ (0, import_editor_v1_adapters6.commandEndEvent)("document/elements/select"),
242
+ (0, import_editor_v1_adapters6.commandEndEvent)("document/elements/deselect"),
243
+ (0, import_editor_v1_adapters6.commandEndEvent)("document/elements/select-all"),
244
+ (0, import_editor_v1_adapters6.commandEndEvent)("document/elements/deselect-all")
176
245
  ],
177
246
  getSelectedElements
178
247
  );
179
248
  const [element] = elements;
180
- const elementType = useElementType(element?.type);
249
+ const elementType = getElementType(element?.type);
181
250
  if (elements.length !== 1 || !elementType) {
182
251
  return { element: null, elementType: null };
183
252
  }
184
253
  return { element, elementType };
185
254
  }
186
255
 
187
- // src/hooks/use-parent-element.ts
188
- var import_editor_v1_adapters5 = require("@elementor/editor-v1-adapters");
189
- function useParentElement(elementId) {
190
- return (0, import_editor_v1_adapters5.__privateUseListenTo)(
191
- [(0, import_editor_v1_adapters5.commandEndEvent)("document/elements/create")],
192
- () => {
193
- if (!elementId) {
194
- return null;
195
- }
196
- const extendedWindow = window;
197
- const element = extendedWindow?.elementor?.getContainer?.(elementId);
198
- if (!element) {
199
- return null;
200
- }
201
- return element.parent;
202
- },
203
- [elementId]
204
- );
205
- }
206
-
207
- // src/hooks/use-element-children.ts
208
- var import_editor_v1_adapters6 = require("@elementor/editor-v1-adapters");
209
- function useElementChildren(elementId, childrenTypes) {
210
- return (0, import_editor_v1_adapters6.__privateUseListenTo)(
211
- [
212
- (0, import_editor_v1_adapters6.v1ReadyEvent)(),
213
- (0, import_editor_v1_adapters6.commandEndEvent)("document/elements/create"),
214
- (0, import_editor_v1_adapters6.commandEndEvent)("document/elements/delete"),
215
- (0, import_editor_v1_adapters6.commandEndEvent)("document/elements/update"),
216
- (0, import_editor_v1_adapters6.commandEndEvent)("document/elements/set-settings")
217
- ],
218
- () => {
219
- const container = getContainer(elementId);
220
- const elementChildren = childrenTypes.reduce((acc, type) => {
221
- acc[type] = [];
222
- return acc;
223
- }, {});
224
- container?.children?.forEachRecursive?.(({ model, id }) => {
225
- const elType = model.get("elType");
226
- if (elType && elType in elementChildren) {
227
- elementChildren[elType].push({ id });
228
- }
229
- });
230
- return elementChildren;
231
- },
232
- [elementId]
233
- );
234
- }
235
-
236
256
  // src/sync/create-element.ts
237
257
  var import_editor_v1_adapters7 = require("@elementor/editor-v1-adapters");
238
258
  function createElement({ containerId, model, options }) {
@@ -247,152 +267,33 @@ function createElement({ containerId, model, options }) {
247
267
  });
248
268
  }
249
269
 
270
+ // src/sync/create-elements.ts
271
+ var import_editor_v1_adapters9 = require("@elementor/editor-v1-adapters");
272
+ var import_i18n = require("@wordpress/i18n");
273
+
250
274
  // src/sync/delete-element.ts
251
275
  var import_editor_v1_adapters8 = require("@elementor/editor-v1-adapters");
252
- function deleteElement({ elementId, options = {} }) {
276
+ function deleteElement({
277
+ elementId,
278
+ options = {}
279
+ }) {
253
280
  const container = getContainer(elementId);
254
281
  if (!container) {
255
282
  throw new Error(`Element with ID "${elementId}" not found`);
256
283
  }
257
- (0, import_editor_v1_adapters8.__privateRunCommand)("document/elements/delete", {
284
+ return (0, import_editor_v1_adapters8.__privateRunCommand)("document/elements/delete", {
258
285
  container,
259
286
  options
260
287
  });
261
288
  }
262
289
 
263
- // src/sync/move-element.ts
264
- function moveElement({ elementId, targetContainerId, options = {} }) {
265
- const container = getContainer(elementId);
266
- const target = getContainer(targetContainerId);
267
- if (!container) {
268
- throw new Error(`Element with ID "${elementId}" not found`);
269
- }
270
- if (!target) {
271
- throw new Error(`Target container with ID "${targetContainerId}" not found`);
272
- }
273
- const modelToRecreate = container.model.toJSON();
274
- deleteElement({
275
- elementId,
276
- // prevent inner history from being created
277
- options: { ...options, useHistory: false }
278
- });
279
- const newContainer = createElement({
280
- containerId: targetContainerId,
281
- model: modelToRecreate,
282
- // prevent inner history from being created
283
- options: { edit: false, ...options, useHistory: false }
284
- });
285
- return newContainer;
286
- }
287
-
288
- // src/sync/move-elements.ts
289
- var import_editor_v1_adapters9 = require("@elementor/editor-v1-adapters");
290
- var import_i18n = require("@wordpress/i18n");
291
- var moveElements = ({
292
- moves: movesToMake,
293
- title,
294
- subtitle = (0, import_i18n.__)("Elements moved", "elementor")
295
- }) => {
296
- const undoableMove = (0, import_editor_v1_adapters9.undoable)(
297
- {
298
- do: ({ moves }) => {
299
- const movedElements = [];
300
- moves.forEach((move) => {
301
- const { elementId } = move;
302
- const sourceContainer = getContainer(elementId);
303
- if (!sourceContainer) {
304
- throw new Error(`Element with ID "${elementId}" not found`);
305
- }
306
- const originalContainerId = sourceContainer.parent?.id || "";
307
- const originalIndex = sourceContainer.parent?.children?.indexOf(sourceContainer) ?? -1;
308
- const originalPosition = {
309
- elementId,
310
- originalContainerId,
311
- originalIndex
312
- };
313
- const element = moveElement({
314
- ...move,
315
- options: { ...move.options, useHistory: false }
316
- });
317
- movedElements.push({
318
- elementId,
319
- originalPosition,
320
- move,
321
- element
322
- });
323
- });
324
- return { movedElements };
325
- },
326
- undo: (_, { movedElements }) => {
327
- [...movedElements].reverse().forEach(({ originalPosition }) => {
328
- const { elementId, originalContainerId, originalIndex } = originalPosition;
329
- moveElement({
330
- elementId,
331
- targetContainerId: originalContainerId,
332
- options: {
333
- useHistory: false,
334
- at: originalIndex >= 0 ? originalIndex : void 0
335
- }
336
- });
337
- });
338
- },
339
- redo: (_, { movedElements }) => {
340
- const newMovedElements = [];
341
- movedElements.forEach(({ move, originalPosition }) => {
342
- const element = moveElement({
343
- ...move,
344
- options: { ...move.options, useHistory: false }
345
- });
346
- newMovedElements.push({
347
- elementId: move.elementId,
348
- originalPosition,
349
- move,
350
- element
351
- });
352
- });
353
- return { movedElements: newMovedElements };
354
- }
355
- },
356
- {
357
- title,
358
- subtitle
359
- }
360
- );
361
- return undoableMove({ moves: movesToMake });
362
- };
363
-
364
- // src/sync/duplicate-element.ts
365
- function duplicateElement({ elementId, options = {} }) {
366
- const elementToDuplicate = getContainer(elementId);
367
- if (!elementToDuplicate) {
368
- throw new Error(`Element with ID "${elementId}" not found`);
369
- }
370
- if (!elementToDuplicate.parent) {
371
- throw new Error(`Element with ID "${elementId}" has no parent container`);
372
- }
373
- const parentContainer = elementToDuplicate.parent;
374
- const elementModel = elementToDuplicate.model.toJSON();
375
- const currentIndex = elementToDuplicate.view?._index ?? 0;
376
- const insertPosition = options.clone !== false ? currentIndex + 1 : void 0;
377
- return createElement({
378
- containerId: parentContainer.id,
379
- model: elementModel,
380
- options: {
381
- at: insertPosition,
382
- ...options
383
- }
384
- });
385
- }
386
-
387
290
  // src/sync/create-elements.ts
388
- var import_editor_v1_adapters10 = require("@elementor/editor-v1-adapters");
389
- var import_i18n2 = require("@wordpress/i18n");
390
291
  var createElements = ({
391
292
  elements,
392
293
  title,
393
- subtitle = (0, import_i18n2.__)("Item added", "elementor")
294
+ subtitle = (0, import_i18n.__)("Item added", "elementor")
394
295
  }) => {
395
- const undoableCreate = (0, import_editor_v1_adapters10.undoable)(
296
+ const undoableCreate = (0, import_editor_v1_adapters9.undoable)(
396
297
  {
397
298
  do: ({ elements: elementsParam }) => {
398
299
  const createdElements = [];
@@ -450,24 +351,60 @@ var createElements = ({
450
351
  return undoableCreate({ elements });
451
352
  };
452
353
 
453
- // src/sync/duplicate-elements.ts
454
- var import_editor_v1_adapters11 = require("@elementor/editor-v1-adapters");
455
- var import_i18n3 = require("@wordpress/i18n");
456
- var duplicateElements = ({
457
- elementIds,
458
- title,
459
- subtitle = (0, import_i18n3.__)("Item duplicated", "elementor"),
460
- onCreate
461
- }) => {
462
- const undoableDuplicate = (0, import_editor_v1_adapters11.undoable)(
463
- {
464
- do: ({ elementIds: elementIdsToDuplicate }) => {
465
- const duplicatedElements = elementIdsToDuplicate.reduce((acc, elementId) => {
466
- const originalContainer = getContainer(elementId);
467
- if (originalContainer?.parent) {
468
- const duplicatedElement = duplicateElement({
469
- elementId,
470
- options: { useHistory: false, clone: true }
354
+ // src/sync/drop-element.ts
355
+ var import_editor_v1_adapters10 = require("@elementor/editor-v1-adapters");
356
+ function dropElement({ containerId, model, options }) {
357
+ const container = getContainer(containerId);
358
+ if (!container) {
359
+ throw new Error(`Container with ID "${containerId}" not found`);
360
+ }
361
+ return (0, import_editor_v1_adapters10.__privateRunCommandSync)("preview/drop", {
362
+ container,
363
+ model,
364
+ options
365
+ });
366
+ }
367
+
368
+ // src/sync/duplicate-element.ts
369
+ function duplicateElement({ elementId, options = {} }) {
370
+ const elementToDuplicate = getContainer(elementId);
371
+ if (!elementToDuplicate) {
372
+ throw new Error(`Element with ID "${elementId}" not found`);
373
+ }
374
+ if (!elementToDuplicate.parent) {
375
+ throw new Error(`Element with ID "${elementId}" has no parent container`);
376
+ }
377
+ const parentContainer = elementToDuplicate.parent;
378
+ const elementModel = elementToDuplicate.model.toJSON();
379
+ const currentIndex = elementToDuplicate.view?._index ?? 0;
380
+ const insertPosition = options.clone !== false ? currentIndex + 1 : void 0;
381
+ return createElement({
382
+ containerId: parentContainer.id,
383
+ model: elementModel,
384
+ options: {
385
+ at: insertPosition,
386
+ ...options
387
+ }
388
+ });
389
+ }
390
+
391
+ // src/sync/duplicate-elements.ts
392
+ var import_editor_v1_adapters11 = require("@elementor/editor-v1-adapters");
393
+ var import_i18n2 = require("@wordpress/i18n");
394
+ var duplicateElements = ({
395
+ elementIds,
396
+ title,
397
+ subtitle = (0, import_i18n2.__)("Item duplicated", "elementor")
398
+ }) => {
399
+ const undoableDuplicate = (0, import_editor_v1_adapters11.undoable)(
400
+ {
401
+ do: ({ elementIds: elementIdsToDuplicate }) => {
402
+ const duplicatedElements = elementIdsToDuplicate.reduce((acc, elementId) => {
403
+ const originalContainer = getContainer(elementId);
404
+ if (originalContainer?.parent) {
405
+ const duplicatedElement = duplicateElement({
406
+ elementId,
407
+ options: { useHistory: false, clone: true }
471
408
  });
472
409
  acc.push({
473
410
  id: duplicatedElement.id,
@@ -480,7 +417,7 @@ var duplicateElements = ({
480
417
  }
481
418
  return acc;
482
419
  }, []);
483
- return { duplicatedElements: onCreate?.(duplicatedElements) ?? duplicatedElements };
420
+ return { duplicatedElements };
484
421
  },
485
422
  undo: (_, { duplicatedElements }) => {
486
423
  [...duplicatedElements].reverse().forEach(({ id }) => {
@@ -513,7 +450,7 @@ var duplicateElements = ({
513
450
  }
514
451
  return acc;
515
452
  }, []);
516
- return { duplicatedElements: onCreate?.(duplicatedElements) ?? duplicatedElements };
453
+ return { duplicatedElements };
517
454
  }
518
455
  },
519
456
  {
@@ -524,15 +461,203 @@ var duplicateElements = ({
524
461
  return undoableDuplicate({ elementIds });
525
462
  };
526
463
 
527
- // src/sync/remove-elements.ts
464
+ // src/sync/generate-element-id.ts
465
+ var generateElementId = () => {
466
+ const extendedWindow = window;
467
+ return extendedWindow.elementorCommon?.helpers?.getUniqueId?.() ?? `el-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
468
+ };
469
+
470
+ // src/sync/get-current-document-container.ts
471
+ function getCurrentDocumentContainer() {
472
+ const extendedWindow = window;
473
+ return extendedWindow.elementor?.documents?.getCurrent?.()?.container ?? null;
474
+ }
475
+
476
+ // src/sync/get-current-document-id.ts
477
+ function getCurrentDocumentId() {
478
+ const extendedWindow = window;
479
+ return extendedWindow.elementor?.documents?.getCurrentId?.() ?? null;
480
+ }
481
+
482
+ // src/errors.ts
483
+ var import_utils = require("@elementor/utils");
484
+ var ElementNotFoundError = (0, import_utils.createError)({
485
+ code: "element_not_found",
486
+ message: "Element not found."
487
+ });
488
+ var StyleNotFoundError = (0, import_utils.createError)({
489
+ code: "style_not_found",
490
+ message: "Style not found."
491
+ });
492
+ var ElementTypeNotExistsError = (0, import_utils.createError)({
493
+ code: "element_type_not_exists",
494
+ message: "Element type does not exist."
495
+ });
496
+ var ElementLabelNotExistsError = (0, import_utils.createError)({
497
+ code: "element_label_not_exists",
498
+ message: "Element label does not exist."
499
+ });
500
+ var ElementParentNotFoundError = (0, import_utils.createError)({
501
+ code: "element_parent_not_found",
502
+ message: "Element parent not found."
503
+ });
504
+ var ElementIndexNotFoundError = (0, import_utils.createError)({
505
+ code: "element_index_not_found",
506
+ message: "Element index not found."
507
+ });
508
+
509
+ // src/sync/get-element-label.ts
510
+ function getElementLabel(elementId) {
511
+ if (!elementId) {
512
+ elementId = getSelectedElements()?.[0]?.id;
513
+ }
514
+ const container = getContainer(elementId);
515
+ const type = container?.model.get("widgetType") || container?.model.get("elType");
516
+ if (!type) {
517
+ throw new ElementTypeNotExistsError({ context: { elementId } });
518
+ }
519
+ const label = getWidgetsCache()?.[type]?.title;
520
+ if (!label) {
521
+ throw new ElementLabelNotExistsError({ context: { elementType: type } });
522
+ }
523
+ return label;
524
+ }
525
+
526
+ // src/sync/get-element-styles.ts
527
+ var getElementStyles = (elementID) => {
528
+ const container = getContainer(elementID);
529
+ return container?.model.get("styles") || null;
530
+ };
531
+
532
+ // src/sync/get-elements.ts
533
+ function getElements(root) {
534
+ const container = root ? getContainer(root) : getCurrentDocumentContainer();
535
+ if (!container) {
536
+ return [];
537
+ }
538
+ const children = [...container.model.get("elements") ?? []].flatMap(
539
+ (childModel) => getElements(childModel.get("id"))
540
+ );
541
+ return [container, ...children];
542
+ }
543
+
544
+ // src/sync/move-element.ts
545
+ function moveElement({ elementId, targetContainerId, options = {} }) {
546
+ const container = getContainer(elementId);
547
+ const target = getContainer(targetContainerId);
548
+ if (!container) {
549
+ throw new Error(`Element with ID "${elementId}" not found`);
550
+ }
551
+ if (!target) {
552
+ throw new Error(`Target container with ID "${targetContainerId}" not found`);
553
+ }
554
+ const modelToRecreate = container.model.toJSON();
555
+ deleteElement({
556
+ elementId,
557
+ // prevent inner history from being created
558
+ options: { ...options, useHistory: false }
559
+ });
560
+ const newContainer = createElement({
561
+ containerId: targetContainerId,
562
+ model: modelToRecreate,
563
+ // prevent inner history from being created
564
+ options: { edit: false, ...options, useHistory: false }
565
+ });
566
+ return newContainer;
567
+ }
568
+
569
+ // src/sync/move-elements.ts
528
570
  var import_editor_v1_adapters12 = require("@elementor/editor-v1-adapters");
571
+ var import_i18n3 = require("@wordpress/i18n");
572
+ var moveElements = ({
573
+ moves: movesToMake,
574
+ title,
575
+ subtitle = (0, import_i18n3.__)("Elements moved", "elementor"),
576
+ onMoveElements,
577
+ onRestoreElements
578
+ }) => {
579
+ const undoableMove = (0, import_editor_v1_adapters12.undoable)(
580
+ {
581
+ do: ({ moves }) => {
582
+ const movedElements = [];
583
+ onMoveElements?.();
584
+ moves.forEach((move) => {
585
+ const { elementId } = move;
586
+ const sourceContainer = getContainer(elementId);
587
+ if (!sourceContainer) {
588
+ throw new Error(`Element with ID "${elementId}" not found`);
589
+ }
590
+ const originalContainerId = sourceContainer.parent?.id || "";
591
+ const originalIndex = sourceContainer.parent?.children?.indexOf(sourceContainer) ?? -1;
592
+ const originalPosition = {
593
+ elementId,
594
+ originalContainerId,
595
+ originalIndex
596
+ };
597
+ const element = moveElement({
598
+ ...move,
599
+ options: { ...move.options, useHistory: false }
600
+ });
601
+ movedElements.push({
602
+ elementId,
603
+ originalPosition,
604
+ move,
605
+ element
606
+ });
607
+ });
608
+ return { movedElements };
609
+ },
610
+ undo: (_, { movedElements }) => {
611
+ onRestoreElements?.();
612
+ [...movedElements].reverse().forEach(({ originalPosition }) => {
613
+ const { elementId, originalContainerId, originalIndex } = originalPosition;
614
+ moveElement({
615
+ elementId,
616
+ targetContainerId: originalContainerId,
617
+ options: {
618
+ useHistory: false,
619
+ at: originalIndex >= 0 ? originalIndex : void 0
620
+ }
621
+ });
622
+ });
623
+ },
624
+ redo: (_, { movedElements }) => {
625
+ const newMovedElements = [];
626
+ onMoveElements?.();
627
+ movedElements.forEach(({ move, originalPosition }) => {
628
+ const element = moveElement({
629
+ ...move,
630
+ options: { ...move.options, useHistory: false }
631
+ });
632
+ newMovedElements.push({
633
+ elementId: move.elementId,
634
+ originalPosition,
635
+ move,
636
+ element
637
+ });
638
+ });
639
+ return { movedElements: newMovedElements };
640
+ }
641
+ },
642
+ {
643
+ title,
644
+ subtitle
645
+ }
646
+ );
647
+ return undoableMove({ moves: movesToMake });
648
+ };
649
+
650
+ // src/sync/remove-elements.ts
651
+ var import_editor_v1_adapters13 = require("@elementor/editor-v1-adapters");
529
652
  var import_i18n4 = require("@wordpress/i18n");
530
653
  var removeElements = ({
531
654
  elementIds,
532
655
  title,
533
- subtitle = (0, import_i18n4.__)("Item removed", "elementor")
656
+ subtitle = (0, import_i18n4.__)("Item removed", "elementor"),
657
+ onRemoveElements,
658
+ onRestoreElements
534
659
  }) => {
535
- const undoableRemove = (0, import_editor_v1_adapters12.undoable)(
660
+ const undoableRemove = (0, import_editor_v1_adapters13.undoable)(
536
661
  {
537
662
  do: ({ elementIds: elementIdsParam }) => {
538
663
  const removedElements = [];
@@ -550,6 +675,7 @@ var removeElements = ({
550
675
  });
551
676
  }
552
677
  });
678
+ onRemoveElements?.();
553
679
  elementIdsParam.forEach((elementId) => {
554
680
  deleteElement({
555
681
  elementId,
@@ -559,6 +685,7 @@ var removeElements = ({
559
685
  return { elementIds: elementIdsParam, removedElements };
560
686
  },
561
687
  undo: (_, { removedElements }) => {
688
+ onRestoreElements?.();
562
689
  [...removedElements].reverse().forEach(({ model, parent, at }) => {
563
690
  if (parent && model) {
564
691
  createElement({
@@ -570,6 +697,7 @@ var removeElements = ({
570
697
  });
571
698
  },
572
699
  redo: (_, { elementIds: originalElementIds, removedElements }) => {
700
+ onRemoveElements?.();
573
701
  originalElementIds.forEach((elementId) => {
574
702
  deleteElement({
575
703
  elementId,
@@ -587,71 +715,65 @@ var removeElements = ({
587
715
  return undoableRemove({ elementIds });
588
716
  };
589
717
 
590
- // src/sync/get-element-styles.ts
591
- var getElementStyles = (elementID) => {
592
- const container = getContainer(elementID);
593
- return container?.model.get("styles") || null;
718
+ // src/sync/replace-element.ts
719
+ var replaceElement = ({ currentElement, newElement, withHistory = true }) => {
720
+ const { containerId, index } = getNewElementLocation(currentElement, newElement);
721
+ createElement({
722
+ containerId,
723
+ model: newElement,
724
+ options: { at: index, useHistory: withHistory }
725
+ });
726
+ deleteElement({ elementId: currentElement.id, options: { useHistory: withHistory } });
594
727
  };
595
-
596
- // src/errors.ts
597
- var import_utils = require("@elementor/utils");
598
- var ElementNotFoundError = (0, import_utils.createError)({
599
- code: "element_not_found",
600
- message: "Element not found."
601
- });
602
- var StyleNotFoundError = (0, import_utils.createError)({
603
- code: "style_not_found",
604
- message: "Style not found."
605
- });
606
- var ElementTypeNotExistsError = (0, import_utils.createError)({
607
- code: "element_type_not_exists",
608
- message: "Element type does not exist."
609
- });
610
- var ElementLabelNotExistsError = (0, import_utils.createError)({
611
- code: "element_label_not_exists",
612
- message: "Element label does not exist."
613
- });
614
-
615
- // src/sync/get-element-label.ts
616
- function getElementLabel(elementId) {
617
- const container = getContainer(elementId);
618
- const type = container?.model.get("widgetType") || container?.model.get("elType");
619
- if (!type) {
620
- throw new ElementTypeNotExistsError({ context: { elementId } });
728
+ function getNewElementLocation(currentElement, newElement) {
729
+ let location;
730
+ const currentElementContainer = getContainer(currentElement.id);
731
+ if (!currentElementContainer) {
732
+ throw new ElementNotFoundError({ context: { elementId: currentElement.id } });
621
733
  }
622
- const label = getWidgetsCache()?.[type]?.title;
623
- if (!label) {
624
- throw new ElementLabelNotExistsError({ context: { elementType: type } });
734
+ const parent = currentElementContainer.parent;
735
+ if (!parent) {
736
+ throw new ElementParentNotFoundError({ context: { elementId: currentElement.id } });
625
737
  }
626
- return label;
738
+ const elementIndex = currentElementContainer.view?._index ?? 0;
739
+ if (elementIndex === void 0 || elementIndex === -1) {
740
+ throw new ElementIndexNotFoundError({ context: { elementId: currentElement.id } });
741
+ }
742
+ location = { containerId: parent.id, index: elementIndex };
743
+ if (parent.id === "document" && newElement.elType === "widget") {
744
+ location = createWrapperForWidget(parent.id, elementIndex);
745
+ }
746
+ return location;
627
747
  }
628
-
629
- // src/sync/get-current-document-container.ts
630
- function getCurrentDocumentContainer() {
631
- const extendedWindow = window;
632
- return extendedWindow.elementor?.documents?.getCurrent?.()?.container ?? null;
748
+ function createWrapperForWidget(parentId, elementIndex) {
749
+ const container = createElement({
750
+ containerId: parentId,
751
+ model: { elType: "container" },
752
+ options: { at: elementIndex, useHistory: false }
753
+ });
754
+ return { containerId: container.id, index: 0 };
633
755
  }
634
756
 
635
- // src/sync/get-elements.ts
636
- function getElements(root) {
637
- const container = root ? getContainer(root) : getCurrentDocumentContainer();
638
- if (!container) {
639
- return [];
757
+ // src/sync/update-element-editor-settings.ts
758
+ var import_editor_v1_adapters14 = require("@elementor/editor-v1-adapters");
759
+ var updateElementEditorSettings = ({
760
+ elementId,
761
+ settings
762
+ }) => {
763
+ const element = getContainer(elementId);
764
+ if (!element) {
765
+ throw new Error(`Element with id ${elementId} not found`);
640
766
  }
641
- const children = [...container.model.get("elements") ?? []].flatMap(
642
- (childModel) => getElements(childModel.get("id"))
643
- );
644
- return [container, ...children];
645
- }
646
-
647
- // src/sync/get-current-document-id.ts
648
- function getCurrentDocumentId() {
649
- const extendedWindow = window;
650
- return extendedWindow.elementor?.documents?.getCurrentId?.() ?? null;
767
+ const editorSettings = element.model.get("editor_settings") ?? {};
768
+ element.model.set("editor_settings", { ...editorSettings, ...settings });
769
+ setDocumentModifiedStatus(true);
770
+ };
771
+ function setDocumentModifiedStatus(status) {
772
+ (0, import_editor_v1_adapters14.__privateRunCommandSync)("document/save/set-is-modified", { status }, { internal: true });
651
773
  }
652
774
 
653
775
  // src/sync/update-element-settings.ts
654
- var import_editor_v1_adapters13 = require("@elementor/editor-v1-adapters");
776
+ var import_editor_v1_adapters15 = require("@elementor/editor-v1-adapters");
655
777
  var updateElementSettings = ({ id, props, withHistory = true }) => {
656
778
  const container = getContainer(id);
657
779
  const args = {
@@ -659,45 +781,105 @@ var updateElementSettings = ({ id, props, withHistory = true }) => {
659
781
  settings: { ...props }
660
782
  };
661
783
  if (withHistory) {
662
- (0, import_editor_v1_adapters13.__privateRunCommandSync)("document/elements/settings", args);
784
+ (0, import_editor_v1_adapters15.__privateRunCommandSync)("document/elements/settings", args);
663
785
  } else {
664
- (0, import_editor_v1_adapters13.__privateRunCommandSync)("document/elements/set-settings", args, { internal: true });
786
+ (0, import_editor_v1_adapters15.__privateRunCommandSync)("document/elements/set-settings", args, { internal: true });
665
787
  }
666
788
  };
667
789
 
668
- // src/sync/generate-element-id.ts
669
- var generateElementId = () => {
670
- const extendedWindow = window;
671
- return extendedWindow.elementorCommon?.helpers?.getUniqueId?.() ?? `el-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
672
- };
673
-
674
- // src/sync/replace-element.ts
675
- var replaceElement = ({ currentElement, newElement, withHistory = true }) => {
676
- const parent = getContainer(currentElement.id)?.parent;
677
- if (!parent) {
678
- throw new Error(`Parent not found for element ${currentElement.id}. Cannot replace element.`);
790
+ // src/link-restriction.ts
791
+ function getLinkInLinkRestriction(elementId) {
792
+ const anchoredDescendantId = getAnchoredDescendantId(elementId);
793
+ if (anchoredDescendantId) {
794
+ return {
795
+ shouldRestrict: true,
796
+ reason: "descendant",
797
+ elementId: anchoredDescendantId
798
+ };
679
799
  }
680
- const elementIndex = parent.children?.findIndex((child) => child.id === currentElement.id);
681
- if (elementIndex === void 0 || elementIndex === -1) {
682
- throw new Error(`Element ${currentElement.id} not found in parent container. Cannot replace element.`);
800
+ const ancestor = getAnchoredAncestorId(elementId);
801
+ if (ancestor) {
802
+ return {
803
+ shouldRestrict: true,
804
+ reason: "ancestor",
805
+ elementId: ancestor
806
+ };
683
807
  }
684
- createElement({
685
- containerId: parent.id,
686
- model: newElement,
687
- options: { at: elementIndex, useHistory: withHistory }
688
- });
689
- deleteElement({ elementId: currentElement.id, options: { useHistory: withHistory } });
690
- };
808
+ return {
809
+ shouldRestrict: false
810
+ };
811
+ }
812
+ function getAnchoredDescendantId(elementId) {
813
+ const element = getElementDOM(elementId);
814
+ if (!element) {
815
+ return null;
816
+ }
817
+ for (const childAnchorElement of Array.from(element.querySelectorAll("a"))) {
818
+ const childElementId = findElementIdOf(childAnchorElement);
819
+ if (childElementId !== elementId) {
820
+ return childElementId;
821
+ }
822
+ }
823
+ return null;
824
+ }
825
+ function getAnchoredAncestorId(elementId) {
826
+ const element = getElementDOM(elementId);
827
+ if (!element || element.parentElement === null) {
828
+ return null;
829
+ }
830
+ const parentAnchor = element.parentElement.closest("a");
831
+ return parentAnchor ? findElementIdOf(parentAnchor) : null;
832
+ }
833
+ function isElementAnchored(elementId) {
834
+ const element = getElementDOM(elementId);
835
+ if (!element) {
836
+ return false;
837
+ }
838
+ if (isAnchorTag(element.tagName)) {
839
+ return true;
840
+ }
841
+ return doesElementContainAnchor(element);
842
+ }
843
+ function doesElementContainAnchor(element) {
844
+ for (const child of element.children) {
845
+ if (isElementorElement(child)) {
846
+ continue;
847
+ }
848
+ if (isAnchorTag(child.tagName)) {
849
+ return true;
850
+ }
851
+ if (doesElementContainAnchor(child)) {
852
+ return true;
853
+ }
854
+ }
855
+ return false;
856
+ }
857
+ function findElementIdOf(element) {
858
+ return element.closest("[data-id]")?.dataset.id || null;
859
+ }
860
+ function getElementDOM(id) {
861
+ try {
862
+ return getContainer(id)?.view?.el || null;
863
+ } catch {
864
+ return null;
865
+ }
866
+ }
867
+ function isAnchorTag(tagName) {
868
+ return tagName.toLowerCase() === "a";
869
+ }
870
+ function isElementorElement(element) {
871
+ return element.hasAttribute("data-id");
872
+ }
691
873
 
692
874
  // src/styles/consts.ts
693
- var import_editor_v1_adapters14 = require("@elementor/editor-v1-adapters");
875
+ var import_editor_v1_adapters16 = require("@elementor/editor-v1-adapters");
694
876
  var ELEMENT_STYLE_CHANGE_EVENT = "elementor/editor-v2/editor-elements/style";
695
877
  var styleRerenderEvents = [
696
- (0, import_editor_v1_adapters14.commandEndEvent)("document/elements/create"),
697
- (0, import_editor_v1_adapters14.commandEndEvent)("document/elements/duplicate"),
698
- (0, import_editor_v1_adapters14.commandEndEvent)("document/elements/import"),
699
- (0, import_editor_v1_adapters14.commandEndEvent)("document/elements/paste"),
700
- (0, import_editor_v1_adapters14.windowEvent)(ELEMENT_STYLE_CHANGE_EVENT)
878
+ (0, import_editor_v1_adapters16.commandEndEvent)("document/elements/create"),
879
+ (0, import_editor_v1_adapters16.commandEndEvent)("document/elements/duplicate"),
880
+ (0, import_editor_v1_adapters16.commandEndEvent)("document/elements/import"),
881
+ (0, import_editor_v1_adapters16.commandEndEvent)("document/elements/paste"),
882
+ (0, import_editor_v1_adapters16.windowEvent)(ELEMENT_STYLE_CHANGE_EVENT)
701
883
  ];
702
884
 
703
885
  // src/styles/create-element-style.ts
@@ -706,7 +888,7 @@ var import_editor_styles = require("@elementor/editor-styles");
706
888
 
707
889
  // src/styles/mutate-element-styles.ts
708
890
  var import_editor_props = require("@elementor/editor-props");
709
- var import_editor_v1_adapters15 = require("@elementor/editor-v1-adapters");
891
+ var import_editor_v1_adapters17 = require("@elementor/editor-v1-adapters");
710
892
  function mutateElementStyles(elementId, mutator) {
711
893
  const container = getContainer(elementId);
712
894
  if (!container) {
@@ -762,7 +944,7 @@ function getClassesProps(container) {
762
944
  }
763
945
  function notifyChanges() {
764
946
  dispatchChangeEvent();
765
- (0, import_editor_v1_adapters15.__privateRunCommandSync)("document/save/set-is-modified", { status: true }, { internal: true });
947
+ (0, import_editor_v1_adapters17.__privateRunCommandSync)("document/save/set-is-modified", { status: true }, { internal: true });
766
948
  }
767
949
  function dispatchChangeEvent() {
768
950
  window.dispatchEvent(new CustomEvent(ELEMENT_STYLE_CHANGE_EVENT));
@@ -814,6 +996,14 @@ function shouldCreateNewLocalStyle(payload) {
814
996
  return !payload?.styleId && !payload?.provider;
815
997
  }
816
998
 
999
+ // src/styles/delete-element-style.ts
1000
+ function deleteElementStyle(elementId, styleId) {
1001
+ mutateElementStyles(elementId, (styles) => {
1002
+ delete styles[styleId];
1003
+ return styles;
1004
+ });
1005
+ }
1006
+
817
1007
  // src/styles/update-element-style.ts
818
1008
  var import_editor_props3 = require("@elementor/editor-props");
819
1009
  var import_editor_styles2 = require("@elementor/editor-styles");
@@ -835,96 +1025,663 @@ function updateElementStyle(args) {
835
1025
  });
836
1026
  }
837
1027
 
838
- // src/styles/delete-element-style.ts
839
- function deleteElementStyle(elementId, styleId) {
840
- mutateElementStyles(elementId, (styles) => {
841
- delete styles[styleId];
842
- return styles;
1028
+ // src/hooks/use-element-interactions.ts
1029
+ var import_react = require("react");
1030
+ var import_editor_v1_adapters18 = require("@elementor/editor-v1-adapters");
1031
+
1032
+ // src/sync/get-element-interactions.ts
1033
+ function getElementInteractions(elementId) {
1034
+ const container = getContainer(elementId);
1035
+ const interactions = container?.model?.get("interactions");
1036
+ if (typeof interactions === "string") {
1037
+ return JSON.parse(interactions);
1038
+ }
1039
+ return interactions;
1040
+ }
1041
+
1042
+ // src/hooks/use-element-interactions.ts
1043
+ var useElementInteractions = (elementId) => {
1044
+ const [interactions, setInteractions] = (0, import_react.useState)(() => {
1045
+ const initial = getElementInteractions(elementId);
1046
+ return initial ?? { version: 1, items: [] };
843
1047
  });
1048
+ (0, import_editor_v1_adapters18.__privateUseListenTo)(
1049
+ (0, import_editor_v1_adapters18.windowEvent)("elementor/element/update_interactions"),
1050
+ () => {
1051
+ const newInteractions = getElementInteractions(elementId);
1052
+ setInteractions(newInteractions ?? { version: 1, items: [] });
1053
+ },
1054
+ [elementId]
1055
+ );
1056
+ return interactions;
1057
+ };
1058
+
1059
+ // src/sync/update-element-interactions.ts
1060
+ var import_editor_v1_adapters19 = require("@elementor/editor-v1-adapters");
1061
+ var updateElementInteractions = ({
1062
+ elementId,
1063
+ interactions
1064
+ }) => {
1065
+ const element = getContainer(elementId);
1066
+ if (!element) {
1067
+ throw new Error(`Element with id ${elementId} not found`);
1068
+ }
1069
+ element.model.set("interactions", interactions);
1070
+ window.dispatchEvent(new CustomEvent("elementor/element/update_interactions"));
1071
+ setDocumentModifiedStatus2(true);
1072
+ };
1073
+ var playElementInteractions = (elementId, animationId) => {
1074
+ window.top?.dispatchEvent(new CustomEvent("atomic/play_interactions", { detail: { elementId, animationId } }));
1075
+ };
1076
+ function setDocumentModifiedStatus2(status) {
1077
+ (0, import_editor_v1_adapters19.__privateRunCommandSync)("document/save/set-is-modified", { status }, { internal: true });
844
1078
  }
845
1079
 
846
- // src/link-restriction.ts
847
- function getLinkInLinkRestriction(elementId) {
848
- const anchoredDescendantId = getAnchoredDescendantId(elementId);
849
- if (anchoredDescendantId) {
850
- return {
851
- shouldRestrict: true,
852
- reason: "descendant",
853
- elementId: anchoredDescendantId
854
- };
1080
+ // src/mcp/index.ts
1081
+ var import_editor_mcp2 = require("@elementor/editor-mcp");
1082
+
1083
+ // src/mcp/elements-tool.ts
1084
+ var import_editor_mcp = require("@elementor/editor-mcp");
1085
+ var import_schema = require("@elementor/schema");
1086
+
1087
+ // src/mcp/handlers/create-element.ts
1088
+ function handleCreateElement({
1089
+ elementType,
1090
+ containerId,
1091
+ props = {},
1092
+ styles
1093
+ }) {
1094
+ let container = containerId === "document" ? getCurrentDocumentContainer() : getContainer(containerId);
1095
+ if (!container) {
1096
+ if (containerId === "document") {
1097
+ throw new Error("Document container not found. Please ensure the editor is initialized.");
1098
+ }
1099
+ throw new Error(`Container with ID "${containerId}" not found`);
855
1100
  }
856
- const ancestor = getAnchoredAncestorId(elementId);
857
- if (ancestor) {
858
- return {
859
- shouldRestrict: true,
860
- reason: "ancestor",
861
- elementId: ancestor
1101
+ const containerElType = container.model.get("elType");
1102
+ const isDocument = container.id === "document" || containerElType === "document";
1103
+ if (isDocument) {
1104
+ const containerModel = {
1105
+ elType: "e-div-block"
862
1106
  };
1107
+ const createdContainer = createElement({
1108
+ containerId: container.id,
1109
+ model: containerModel,
1110
+ options: { useHistory: true }
1111
+ });
1112
+ createElementStyle({
1113
+ elementId: createdContainer.id,
1114
+ classesProp: "classes",
1115
+ label: "local",
1116
+ meta: { breakpoint: "desktop", state: null },
1117
+ props: {
1118
+ display: { $$type: "string", value: "flex" },
1119
+ "flex-direction": { $$type: "string", value: "row" },
1120
+ "flex-wrap": { $$type: "string", value: "wrap" }
1121
+ }
1122
+ });
1123
+ container = getContainer(createdContainer.id);
1124
+ if (!container) {
1125
+ throw new Error("Failed to create container for widget. Cannot create widgets directly in the document.");
1126
+ }
1127
+ }
1128
+ const actualContainerId = container.id;
1129
+ const elementTypeData = getElementType(elementType);
1130
+ if (!elementTypeData) {
1131
+ throw new Error(`Element type "${elementType}" not found or is not atomic`);
1132
+ }
1133
+ const model = {
1134
+ widgetType: elementType,
1135
+ elType: "widget",
1136
+ settings: props
1137
+ };
1138
+ const createdElement = createElement({
1139
+ containerId: actualContainerId,
1140
+ model,
1141
+ options: { useHistory: true }
1142
+ });
1143
+ if (styles) {
1144
+ createElementStyle({
1145
+ elementId: createdElement.id,
1146
+ classesProp: "classes",
1147
+ label: "local",
1148
+ meta: { breakpoint: "desktop", state: null },
1149
+ props: styles
1150
+ });
863
1151
  }
864
1152
  return {
865
- shouldRestrict: false
1153
+ elementId: createdElement.id,
1154
+ type: elementType
866
1155
  };
867
1156
  }
868
- function getAnchoredDescendantId(elementId) {
869
- const element = getElementDOM(elementId);
870
- if (!element) {
1157
+
1158
+ // src/mcp/handlers/common-style-utils.ts
1159
+ var VALID_BREAKPOINTS = [
1160
+ "widescreen",
1161
+ "desktop",
1162
+ "laptop",
1163
+ "tablet_extra",
1164
+ "tablet",
1165
+ "mobile_extra",
1166
+ "mobile"
1167
+ ];
1168
+ function resolveBreakpointId(breakpoint) {
1169
+ if (breakpoint === null) {
871
1170
  return null;
872
1171
  }
873
- for (const childAnchorElement of Array.from(element.querySelectorAll("a"))) {
874
- const childElementId = findElementIdOf(childAnchorElement);
875
- if (childElementId !== elementId) {
876
- return childElementId;
877
- }
1172
+ if (VALID_BREAKPOINTS.includes(breakpoint)) {
1173
+ return breakpoint;
878
1174
  }
879
- return null;
1175
+ return "desktop";
880
1176
  }
881
- function getAnchoredAncestorId(elementId) {
882
- const element = getElementDOM(elementId);
883
- if (!element || element.parentElement === null) {
884
- return null;
1177
+
1178
+ // src/mcp/handlers/create-style.ts
1179
+ function handleCreateStyle({
1180
+ elementId,
1181
+ styleId,
1182
+ classesProp = "classes",
1183
+ label = "local",
1184
+ styles,
1185
+ breakpoint = "desktop",
1186
+ state = null,
1187
+ customCss = null
1188
+ }) {
1189
+ const resolvedBreakpoint = resolveBreakpointId(breakpoint);
1190
+ const resolvedState = state === null || state === void 0 ? null : state;
1191
+ const createdStyleId = createElementStyle({
1192
+ styleId,
1193
+ elementId,
1194
+ classesProp,
1195
+ label,
1196
+ meta: { breakpoint: resolvedBreakpoint, state: resolvedState },
1197
+ props: styles,
1198
+ custom_css: customCss
1199
+ });
1200
+ return { styleId: createdStyleId };
1201
+ }
1202
+
1203
+ // src/mcp/handlers/delete-element.ts
1204
+ function handleDeleteElement(elementId) {
1205
+ const container = getContainer(elementId);
1206
+ if (!container) {
1207
+ throw new Error(`Element with ID "${elementId}" not found`);
885
1208
  }
886
- const parentAnchor = element.parentElement.closest("a");
887
- return parentAnchor ? findElementIdOf(parentAnchor) : null;
1209
+ deleteElement({
1210
+ elementId,
1211
+ options: { useHistory: true }
1212
+ });
1213
+ return { success: true };
888
1214
  }
889
- function isElementAnchored(elementId) {
890
- const element = getElementDOM(elementId);
891
- if (!element) {
892
- return false;
1215
+
1216
+ // src/mcp/handlers/delete-style.ts
1217
+ function handleDeleteStyle({ elementId, styleId }) {
1218
+ const elementStyles = getElementStyles(elementId);
1219
+ if (!elementStyles) {
1220
+ throw new Error(`Element with ID "${elementId}" has no styles.`);
893
1221
  }
894
- if (isAnchorTag(element.tagName)) {
895
- return true;
1222
+ const resolvedStyleId = styleId || Object.keys(elementStyles)[0];
1223
+ if (!resolvedStyleId) {
1224
+ throw new Error(`Element with ID "${elementId}" has no styles to delete.`);
896
1225
  }
897
- return doesElementContainAnchor(element);
1226
+ deleteElementStyle(elementId, resolvedStyleId);
1227
+ return { success: true };
898
1228
  }
899
- function doesElementContainAnchor(element) {
900
- for (const child of element.children) {
901
- if (isElementorElement(child)) {
902
- continue;
903
- }
904
- if (isAnchorTag(child.tagName)) {
905
- return true;
1229
+
1230
+ // src/mcp/handlers/deselect-element.ts
1231
+ var import_editor_v1_adapters20 = require("@elementor/editor-v1-adapters");
1232
+ function handleDeselectElement(elementId) {
1233
+ const container = getContainer(elementId);
1234
+ if (!container) {
1235
+ throw new Error(`Element with ID "${elementId}" not found`);
1236
+ }
1237
+ (0, import_editor_v1_adapters20.__privateRunCommand)("document/elements/deselect", { container });
1238
+ return { success: true };
1239
+ }
1240
+ function handleDeselectAllElements() {
1241
+ (0, import_editor_v1_adapters20.__privateRunCommand)("document/elements/deselect-all", {});
1242
+ return { success: true };
1243
+ }
1244
+
1245
+ // src/mcp/handlers/duplicate-element.ts
1246
+ function handleDuplicateElement(elementId) {
1247
+ const container = getContainer(elementId);
1248
+ if (!container) {
1249
+ throw new Error(`Element with ID "${elementId}" not found`);
1250
+ }
1251
+ const duplicatedElement = duplicateElement({
1252
+ elementId,
1253
+ options: { useHistory: true }
1254
+ });
1255
+ const type = duplicatedElement.model.get("widgetType") || duplicatedElement.model.get("elType") || "";
1256
+ return {
1257
+ elementId: duplicatedElement.id,
1258
+ type
1259
+ };
1260
+ }
1261
+
1262
+ // src/mcp/handlers/get-element-props.ts
1263
+ function handleGetElementProps(elementId) {
1264
+ const container = getContainer(elementId);
1265
+ if (!container) {
1266
+ throw new Error(`Element with ID "${elementId}" not found`);
1267
+ }
1268
+ const type = container.model.get("widgetType") || container.model.get("elType");
1269
+ if (!type) {
1270
+ throw new Error(`Element with ID "${elementId}" has no type`);
1271
+ }
1272
+ const elementType = getElementType(type);
1273
+ if (!elementType) {
1274
+ throw new Error(`Element type "${type}" is not atomic`);
1275
+ }
1276
+ const propsSchema = elementType.propsSchema;
1277
+ const propKeys = Object.keys(propsSchema);
1278
+ return getElementSettings(elementId, propKeys);
1279
+ }
1280
+
1281
+ // src/mcp/handlers/get-element-schema.ts
1282
+ var import_editor_styles3 = require("@elementor/editor-styles");
1283
+ function handleGetElementSchema(elementType) {
1284
+ const elementTypeData = getElementType(elementType);
1285
+ if (!elementTypeData) {
1286
+ throw new Error(`Element type "${elementType}" not found or is not atomic`);
1287
+ }
1288
+ return { ...elementTypeData, stylesSchema: (0, import_editor_styles3.getStylesSchema)() };
1289
+ }
1290
+
1291
+ // src/mcp/handlers/get-selected.ts
1292
+ function handleGetSelected() {
1293
+ return getSelectedElements();
1294
+ }
1295
+
1296
+ // src/mcp/handlers/get-styles.ts
1297
+ function handleGetStyles(elementId) {
1298
+ const styles = getElementStyles(elementId);
1299
+ if (!styles) {
1300
+ return null;
1301
+ }
1302
+ return Object.fromEntries(
1303
+ Object.entries(styles).map(([id, style]) => [
1304
+ id,
1305
+ {
1306
+ id: style.id,
1307
+ label: style.label,
1308
+ type: style.type,
1309
+ variants: style.variants.map((variant) => ({
1310
+ meta: variant.meta,
1311
+ props: variant.props,
1312
+ custom_css: variant.custom_css
1313
+ }))
1314
+ }
1315
+ ])
1316
+ );
1317
+ }
1318
+
1319
+ // src/mcp/handlers/list-available-types.ts
1320
+ function handleListAvailableTypes() {
1321
+ const widgetsCache = getWidgetsCache();
1322
+ if (!widgetsCache) {
1323
+ return [];
1324
+ }
1325
+ const availableTypes = [];
1326
+ Object.entries(widgetsCache).forEach(([type, config]) => {
1327
+ if (config?.atomic_controls && config?.atomic_props_schema) {
1328
+ availableTypes.push({
1329
+ type,
1330
+ title: config.title || type
1331
+ });
906
1332
  }
907
- if (doesElementContainAnchor(child)) {
908
- return true;
1333
+ });
1334
+ return availableTypes;
1335
+ }
1336
+
1337
+ // src/mcp/handlers/move-element.ts
1338
+ function handleMoveElement({
1339
+ elementId,
1340
+ targetContainerId
1341
+ }) {
1342
+ const container = getContainer(elementId);
1343
+ if (!container) {
1344
+ throw new Error(`Element with ID "${elementId}" not found`);
1345
+ }
1346
+ const targetContainer = getContainer(targetContainerId);
1347
+ if (!targetContainer) {
1348
+ throw new Error(`Target container with ID "${targetContainerId}" not found`);
1349
+ }
1350
+ moveElement({
1351
+ elementId,
1352
+ targetContainerId,
1353
+ options: { useHistory: true }
1354
+ });
1355
+ return { success: true };
1356
+ }
1357
+
1358
+ // src/mcp/handlers/select-element.ts
1359
+ function handleSelectElement(elementId) {
1360
+ const container = getContainer(elementId);
1361
+ if (!container) {
1362
+ throw new Error(`Element with ID "${elementId}" not found`);
1363
+ }
1364
+ selectElement(elementId);
1365
+ return { success: true };
1366
+ }
1367
+ function handleSelectMultipleElements(elementIds) {
1368
+ elementIds.forEach((elementId) => {
1369
+ const container = getContainer(elementId);
1370
+ if (container) {
1371
+ selectElement(elementId);
909
1372
  }
1373
+ });
1374
+ return { success: true };
1375
+ }
1376
+
1377
+ // src/mcp/handlers/update-props.ts
1378
+ function handleUpdateProps({ elementId, props }) {
1379
+ const container = getContainer(elementId);
1380
+ if (!container) {
1381
+ throw new Error(`Element with ID "${elementId}" not found`);
910
1382
  }
911
- return false;
1383
+ updateElementSettings({
1384
+ id: elementId,
1385
+ props,
1386
+ withHistory: true
1387
+ });
1388
+ return { success: true };
912
1389
  }
913
- function findElementIdOf(element) {
914
- return element.closest("[data-id]")?.dataset.id || null;
1390
+
1391
+ // src/mcp/handlers/update-styles.ts
1392
+ function handleUpdateStyles({
1393
+ elementId,
1394
+ styleId,
1395
+ styles,
1396
+ breakpoint = "desktop",
1397
+ state = null
1398
+ }) {
1399
+ const resolvedBreakpoint = resolveBreakpointId(breakpoint);
1400
+ const resolvedState = state === null || state === void 0 ? null : state;
1401
+ const elementStyles = getElementStyles(elementId);
1402
+ if (!elementStyles) {
1403
+ throw new Error(`Element with ID "${elementId}" has no styles. Create a style first.`);
1404
+ }
1405
+ const resolvedStyleId = styleId || Object.keys(elementStyles)[0];
1406
+ if (!resolvedStyleId) {
1407
+ throw new Error(`Element with ID "${elementId}" has no styles. Create a style first.`);
1408
+ }
1409
+ updateElementStyle({
1410
+ elementId,
1411
+ styleId: resolvedStyleId,
1412
+ meta: { breakpoint: resolvedBreakpoint, state: resolvedState },
1413
+ props: styles
1414
+ });
1415
+ return { success: true };
915
1416
  }
916
- function getElementDOM(id) {
1417
+
1418
+ // src/mcp/elements-tool.ts
1419
+ var actionEnum = import_schema.z.enum([
1420
+ "get-element-schema",
1421
+ "get-element-props",
1422
+ "create-element",
1423
+ "update-props",
1424
+ "create-style",
1425
+ "get-styles",
1426
+ "update-styles",
1427
+ "delete-style",
1428
+ "delete",
1429
+ "duplicate",
1430
+ "move",
1431
+ "select",
1432
+ "deselect",
1433
+ "deselect-all",
1434
+ "get-selected",
1435
+ "list-available-types"
1436
+ ]);
1437
+ var schema = {
1438
+ action: actionEnum.describe("The element operation to perform."),
1439
+ elementId: import_schema.z.string().optional().describe("The ID of the target element"),
1440
+ elementIds: import_schema.z.array(import_schema.z.string()).optional().describe("Array of element IDs for multi-element operations"),
1441
+ elementType: import_schema.z.string().optional().describe(
1442
+ "The type of element to create. Must be an atomic element type (required for create-element and get-element-schema actions)"
1443
+ ),
1444
+ props: import_schema.z.record(import_schema.z.any()).optional().describe("Props object for creating or updating an element. Must match the element type's propsSchema."),
1445
+ containerId: import_schema.z.string().optional().describe(
1446
+ 'Parent container ID for element creation or move operations. Use "document" if parent is the document root.'
1447
+ ),
1448
+ targetContainerId: import_schema.z.string().optional().describe("Target container ID for move operations"),
1449
+ styles: import_schema.z.record(import_schema.z.any()).optional().describe(
1450
+ "Styles object for creating or updating element styles. Must match the element type's stylesSchema."
1451
+ ),
1452
+ styleId: import_schema.z.string().optional().describe(
1453
+ "Style definition ID for style operations. If not provided, the first available style will be used (for update/delete)."
1454
+ ),
1455
+ breakpoint: import_schema.z.string().optional().describe('Breakpoint for style operations (e.g., "desktop", "tablet", "mobile"). Defaults to "desktop".'),
1456
+ state: import_schema.z.string().optional().describe('State for style operations (e.g., "hover", "active", or null). Defaults to null.'),
1457
+ classesProp: import_schema.z.string().optional().describe('Classes property name for create-style action. Defaults to "classes".'),
1458
+ label: import_schema.z.string().optional().describe('Label for create-style action. Defaults to "local".'),
1459
+ custom_css: import_schema.z.object({ raw: import_schema.z.string() }).optional().describe("Custom CSS object with raw CSS string for create-style action.")
1460
+ };
1461
+ function routeAction(params) {
917
1462
  try {
918
- return getContainer(id)?.view?.el || null;
919
- } catch {
920
- return null;
1463
+ switch (params.action) {
1464
+ case "get-element-schema":
1465
+ if (!params.elementType) {
1466
+ throw new Error("elementType is required for get-element-schema action");
1467
+ }
1468
+ return handleGetElementSchema(params.elementType);
1469
+ case "get-element-props":
1470
+ if (!params.elementId) {
1471
+ throw new Error("elementId is required for get-element-props action");
1472
+ }
1473
+ return handleGetElementProps(params.elementId);
1474
+ case "create-element":
1475
+ if (!params.elementType) {
1476
+ throw new Error("elementType is required for create-element action");
1477
+ }
1478
+ if (!params.containerId) {
1479
+ throw new Error("containerId is required for create-element action");
1480
+ }
1481
+ return handleCreateElement({
1482
+ elementType: params.elementType,
1483
+ containerId: params.containerId,
1484
+ props: params.props,
1485
+ styles: params.styles
1486
+ });
1487
+ case "update-props":
1488
+ if (!params.elementId) {
1489
+ throw new Error("elementId is required for update-props action");
1490
+ }
1491
+ if (!params.props) {
1492
+ throw new Error("props is required for update-props action");
1493
+ }
1494
+ return handleUpdateProps({
1495
+ elementId: params.elementId,
1496
+ props: params.props
1497
+ });
1498
+ case "create-style":
1499
+ if (!params.elementId) {
1500
+ throw new Error("elementId is required for create-style action");
1501
+ }
1502
+ if (!params.styles) {
1503
+ throw new Error("styles is required for create-style action");
1504
+ }
1505
+ return handleCreateStyle({
1506
+ elementId: params.elementId,
1507
+ styleId: params.styleId,
1508
+ classesProp: params.classesProp,
1509
+ label: params.label,
1510
+ styles: params.styles,
1511
+ breakpoint: params.breakpoint,
1512
+ state: params.state,
1513
+ customCss: params.custom_css
1514
+ });
1515
+ case "get-styles":
1516
+ if (!params.elementId) {
1517
+ throw new Error("elementId is required for get-styles action");
1518
+ }
1519
+ return handleGetStyles(params.elementId);
1520
+ case "update-styles":
1521
+ if (!params.elementId) {
1522
+ throw new Error("elementId is required for update-styles action");
1523
+ }
1524
+ if (!params.styles) {
1525
+ throw new Error("styles is required for update-styles action");
1526
+ }
1527
+ return handleUpdateStyles({
1528
+ elementId: params.elementId,
1529
+ styleId: params.styleId,
1530
+ styles: params.styles,
1531
+ breakpoint: params.breakpoint,
1532
+ state: params.state
1533
+ });
1534
+ case "delete-style":
1535
+ if (!params.elementId) {
1536
+ throw new Error("elementId is required for delete-style action");
1537
+ }
1538
+ return handleDeleteStyle({
1539
+ elementId: params.elementId,
1540
+ styleId: params.styleId
1541
+ });
1542
+ case "delete":
1543
+ if (!params.elementId) {
1544
+ throw new Error("elementId is required for delete action");
1545
+ }
1546
+ return handleDeleteElement(params.elementId);
1547
+ case "duplicate":
1548
+ if (!params.elementId) {
1549
+ throw new Error("elementId is required for duplicate action");
1550
+ }
1551
+ return handleDuplicateElement(params.elementId);
1552
+ case "move":
1553
+ if (!params.elementId) {
1554
+ throw new Error("elementId is required for move action");
1555
+ }
1556
+ if (!params.targetContainerId) {
1557
+ throw new Error("targetContainerId is required for move action");
1558
+ }
1559
+ return handleMoveElement({
1560
+ elementId: params.elementId,
1561
+ targetContainerId: params.targetContainerId
1562
+ });
1563
+ case "select":
1564
+ if (params.elementIds && params.elementIds.length > 0) {
1565
+ return handleSelectMultipleElements(params.elementIds);
1566
+ }
1567
+ if (!params.elementId) {
1568
+ throw new Error("elementId or elementIds is required for select action");
1569
+ }
1570
+ return handleSelectElement(params.elementId);
1571
+ case "deselect":
1572
+ if (!params.elementId) {
1573
+ throw new Error("elementId is required for deselect action");
1574
+ }
1575
+ return handleDeselectElement(params.elementId);
1576
+ case "deselect-all":
1577
+ return handleDeselectAllElements();
1578
+ case "get-selected":
1579
+ return handleGetSelected();
1580
+ case "list-available-types":
1581
+ return handleListAvailableTypes();
1582
+ default:
1583
+ throw new Error(`Unknown action: ${params.action}`);
1584
+ }
1585
+ } catch (error) {
1586
+ const errorMessage = error instanceof Error ? error.message : String(error);
1587
+ throw new Error(`Failed to execute action "${params.action}": ${errorMessage}`);
921
1588
  }
922
1589
  }
923
- function isAnchorTag(tagName) {
924
- return tagName.toLowerCase() === "a";
1590
+ function initElementsTool() {
1591
+ (0, import_editor_mcp.getMCPByDomain)("elements").addTool({
1592
+ name: "elements",
1593
+ schema,
1594
+ description: `This tool manages individual Elementor atomic elements (v4).
1595
+
1596
+ **When to use this tool:**
1597
+
1598
+ Use this tool to create, update, delete, duplicate, move, and select individual atomic elements, as well as retrieve their schemas and current props.
1599
+
1600
+ **Available actions:**
1601
+
1602
+ - \`list-available-types\`: List all available atomic element types.
1603
+ - \`get-element-schema\`: Get the propsSchema and controls for an element type. Required before creating elements of a new type.
1604
+ - \`get-element-props\`: Get the current prop values for an existing element.
1605
+ - \`create-element\`: Create a new atomic element with specified props and styles (Important to match props and styles by the schema, use get-element-schema to get the schema first).
1606
+ - \`update-props\`: Update props for an existing element.
1607
+ - \`create-style\`: Create a new style definition for an element.
1608
+ - \`get-styles\`: Get all style definitions for an element.
1609
+ - \`update-styles\`: Update styles for an existing element's style variant.
1610
+ - \`delete-style\`: Delete a style definition from an element.
1611
+ - \`delete\`: Delete an element.
1612
+ - \`duplicate\`: Duplicate an existing element.
1613
+ - \`move\`: Move an element to a different container.
1614
+ - \`select\`: Select one or more elements.
1615
+ - \`deselect\`: Deselect a specific element.
1616
+ - \`deselect-all\`: Deselect all selected elements.
1617
+ - \`get-selected\`: Get currently selected elements.
1618
+
1619
+ **Constraints:**
1620
+
1621
+ - Before creating an element of a certain type for the first time, you MUST call \`get-element-schema\` to retrieve its schema.
1622
+ - You can only update props for existing elements.
1623
+ - All props must match the element type's propsSchema keys.
1624
+ - Element types must be atomic (have atomic_controls and atomic_props_schema).
1625
+ - Container IDs must exist and be valid before create/move operations.
1626
+
1627
+ ** Must do with every operation **
1628
+ As of the user can ask in multiple ways the creation of the element, you need to first get the list of available types with "list-available-types" action.
1629
+ After getting it, convert to the most relevant type that the user requested and if this is not clear, request for user input.
1630
+ After finding out the proper type, get the schema for it with "get-element-schema" action.
1631
+
1632
+ ** Styles and Settings propUtils **
1633
+ Getting the schema is important as it introduces the propUtils for the styles and settings.
1634
+ You can use the propUtils to create, update, delete, and get the values of the styles and settings.
1635
+ Settings exists in the result of the get-element-schema action -> propsSchema.
1636
+ Styles exists in the result of the get-element-schema action -> stylesSchema.
1637
+
1638
+ **Examples:**
1639
+
1640
+ Get schema for heading element:
1641
+ \`\`\`json
1642
+ { "action": "get-element-schema", "elementType": "e-heading" }
1643
+ \`\`\`
1644
+
1645
+ Create a heading element:
1646
+ \`\`\`json
1647
+ { "action": "create-element", "elementType": "e-heading", "containerId": "document", "props": { "title": { $$type: "string", "value": "Hello World" } } }
1648
+ \`\`\`
1649
+
1650
+ Update element props:
1651
+ \`\`\`json
1652
+ { "action": "update-props", "elementId": "abc123", "props": { "title": "Updated Title" } }
1653
+ \`\`\`
1654
+
1655
+ Create element style:
1656
+ \`\`\`json
1657
+ { "action": "create-style", "elementId": "abc123", "styles": { "padding": "20px", "margin": "10px" } }
1658
+ \`\`\`
1659
+
1660
+ Get element styles:
1661
+ \`\`\`json
1662
+ { "action": "get-styles", "elementId": "abc123" }
1663
+ \`\`\`
1664
+
1665
+ Update element styles:
1666
+ \`\`\`json
1667
+ { "action": "update-styles", "elementId": "abc123", "styles": { "padding": "20px", "margin": "10px" } }
1668
+ \`\`\`
1669
+
1670
+ Delete element style:
1671
+ \`\`\`json
1672
+ { "action": "delete-style", "elementId": "abc123", "styleId": "style-id-123" }
1673
+ \`\`\``,
1674
+ handler: async (params) => {
1675
+ return routeAction(params);
1676
+ }
1677
+ });
925
1678
  }
926
- function isElementorElement(element) {
927
- return element.hasAttribute("data-id");
1679
+
1680
+ // src/mcp/index.ts
1681
+ function initMcp() {
1682
+ const { setMCPDescription } = (0, import_editor_mcp2.getMCPByDomain)("elements");
1683
+ setMCPDescription("Tools for managing atomic elements in Elementor v4 editor");
1684
+ initElementsTool();
928
1685
  }
929
1686
  // Annotate the CommonJS export names for ESM import in node:
930
1687
  0 && (module.exports = {
@@ -934,35 +1691,45 @@ function isElementorElement(element) {
934
1691
  createElements,
935
1692
  deleteElement,
936
1693
  deleteElementStyle,
1694
+ dropElement,
937
1695
  duplicateElement,
938
1696
  duplicateElements,
939
1697
  generateElementId,
940
1698
  getAnchoredAncestorId,
941
1699
  getAnchoredDescendantId,
942
1700
  getContainer,
1701
+ getCurrentDocumentContainer,
943
1702
  getCurrentDocumentId,
1703
+ getElementEditorSettings,
1704
+ getElementInteractions,
944
1705
  getElementLabel,
945
1706
  getElementSetting,
946
1707
  getElementSettings,
947
1708
  getElementStyles,
1709
+ getElementType,
948
1710
  getElements,
949
1711
  getLinkInLinkRestriction,
950
1712
  getSelectedElements,
951
1713
  getWidgetsCache,
1714
+ initElementsMcp,
952
1715
  isElementAnchored,
953
1716
  moveElement,
954
1717
  moveElements,
1718
+ playElementInteractions,
955
1719
  removeElements,
956
1720
  replaceElement,
957
1721
  selectElement,
958
1722
  shouldCreateNewLocalStyle,
959
1723
  styleRerenderEvents,
1724
+ updateElementEditorSettings,
1725
+ updateElementInteractions,
960
1726
  updateElementSettings,
961
1727
  updateElementStyle,
962
1728
  useElementChildren,
1729
+ useElementEditorSettings,
1730
+ useElementInteractions,
963
1731
  useElementSetting,
964
1732
  useElementSettings,
965
- useElementType,
966
1733
  useParentElement,
967
1734
  useSelectedElement
968
1735
  });