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