@elementor/editor-canvas 4.2.0-beta2 → 4.3.0-1000
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 +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +448 -1318
- package/dist/index.mjs +313 -1196
- package/package.json +22 -22
- package/src/index.ts +1 -1
- package/src/legacy/__tests__/init-legacy-views.test.ts +1 -1
- package/src/mcp/canvas-mcp.ts +4 -2
- package/src/mcp/resources/__tests__/available-widgets-resource.test.ts +76 -0
- package/src/mcp/resources/__tests__/dynamic-tags-resource.test.ts +27 -37
- package/src/mcp/resources/__tests__/widgets-schema-resource.test.ts +79 -76
- package/src/mcp/resources/available-widgets-resource.ts +31 -40
- package/src/mcp/resources/best-practices-resource.ts +34 -0
- package/src/mcp/resources/dynamic-tags-resource.ts +28 -29
- package/src/mcp/resources/widgets-schema-resource.ts +34 -177
- package/src/mcp/tools/build-composition/tool.ts +107 -218
- package/src/sync/element-added-event.ts +8 -0
- package/src/utils/__tests__/grid-outline-utils.test.ts +39 -0
- package/src/utils/grid-outline-utils.ts +13 -2
- package/src/composition-builder/__tests__/composition-builder.test.ts +0 -352
- package/src/composition-builder/composition-builder.ts +0 -350
- package/src/composition-builder/utils/__tests__/required-children-enforcer.test.ts +0 -79
- package/src/composition-builder/utils/__tests__/required-default-child-tags.test.ts +0 -35
- package/src/composition-builder/utils/required-children-enforcer.ts +0 -56
- package/src/composition-builder/utils/required-default-child-tags.ts +0 -22
- package/src/mcp/resources/best-practices.ts +0 -159
- package/src/mcp/resources/build-llm-guidance.ts +0 -110
- package/src/mcp/tools/build-composition/__tests__/xml-leaf-wrapper.test.ts +0 -117
- package/src/mcp/tools/build-composition/prompt.ts +0 -167
- package/src/mcp/tools/build-composition/schema.ts +0 -42
- package/src/mcp/tools/build-composition/xml-leaf-wrapper.ts +0 -68
- package/src/mcp/utils/__tests__/get-composition-target-container.test.ts +0 -59
- package/src/mcp/utils/get-composition-target-container.ts +0 -15
package/dist/index.js
CHANGED
|
@@ -71,203 +71,37 @@ module.exports = __toCommonJS(index_exports);
|
|
|
71
71
|
var import_editor_v1_adapters = require("@elementor/editor-v1-adapters");
|
|
72
72
|
|
|
73
73
|
// src/mcp/resources/widgets-schema-resource.ts
|
|
74
|
-
var import_editor_elements2 = require("@elementor/editor-elements");
|
|
75
74
|
var import_editor_mcp = require("@elementor/editor-mcp");
|
|
76
|
-
var
|
|
77
|
-
|
|
78
|
-
// src/mcp/utils/element-data-util.ts
|
|
79
|
-
var import_editor_elements = require("@elementor/editor-elements");
|
|
80
|
-
function hasV3Controls(controls) {
|
|
81
|
-
return typeof controls === "object" && controls !== null && Object.keys(controls).length > 0;
|
|
82
|
-
}
|
|
83
|
-
function isWidgetAvailableForLLM(config) {
|
|
84
|
-
if (!config) {
|
|
85
|
-
return false;
|
|
86
|
-
}
|
|
87
|
-
if (config.meta?.llm_support === false) {
|
|
88
|
-
return false;
|
|
89
|
-
}
|
|
90
|
-
if (config.title === "Component") {
|
|
91
|
-
return false;
|
|
92
|
-
}
|
|
93
|
-
if (config.atomic_props_schema) {
|
|
94
|
-
return true;
|
|
95
|
-
}
|
|
96
|
-
return hasV3Controls(config.controls);
|
|
97
|
-
}
|
|
98
|
-
function getWidgetVersion(config) {
|
|
99
|
-
return config?.atomic_props_schema ? "v4" : "v3";
|
|
100
|
-
}
|
|
101
|
-
function getAvailableWidgets() {
|
|
102
|
-
const cache = (0, import_editor_elements.getWidgetsCache)() ?? {};
|
|
103
|
-
return Object.keys(cache).filter((widgetType) => isWidgetAvailableForLLM(cache[widgetType])).sort().map((widgetType) => {
|
|
104
|
-
const config = cache[widgetType];
|
|
105
|
-
const description = typeof config?.meta?.description === "string" ? config.meta.description : void 0;
|
|
106
|
-
return {
|
|
107
|
-
type: widgetType,
|
|
108
|
-
version: getWidgetVersion(config),
|
|
109
|
-
...description && { description }
|
|
110
|
-
};
|
|
111
|
-
});
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// src/composition-builder/utils/required-default-child-tags.ts
|
|
115
|
-
function getRequiredDefaultChildTemplates(elementConfig) {
|
|
116
|
-
const defaultChildren = elementConfig?.default_children;
|
|
117
|
-
if (!Array.isArray(defaultChildren)) {
|
|
118
|
-
return [];
|
|
119
|
-
}
|
|
120
|
-
return defaultChildren.filter((child) => child?.meta?.required ?? false);
|
|
121
|
-
}
|
|
122
|
-
function getRequiredDefaultChildTypes(elementConfig) {
|
|
123
|
-
return getRequiredDefaultChildTemplates(elementConfig).map((child) => child.widgetType ?? child.elType ?? "").filter((type) => Boolean(type));
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
// src/mcp/resources/build-llm-guidance.ts
|
|
127
|
-
var DEFAULT_STYLES_INSTRUCTION = "These are the default styles applied to the widget. Override only when necessary.";
|
|
128
|
-
var DEFAULT_SETTINGS_INSTRUCTION = "These are the default settings applied to the widget. Omit them from elementConfig unless the user explicitly asks to change them.";
|
|
129
|
-
var BASE_SETTING_PROP_HINT = "Has a widget default \u2014 omit unless user explicitly requests a change. See llm_guidance.default_settings.";
|
|
130
|
-
function mergeInstructions(existing, additional) {
|
|
131
|
-
if (typeof existing === "string" && existing.length > 0) {
|
|
132
|
-
return `${existing} ${additional}`;
|
|
133
|
-
}
|
|
134
|
-
return additional;
|
|
135
|
-
}
|
|
136
|
-
function enrichPropertiesWithBaseSettingsHints(properties, baseSettingsKeys) {
|
|
137
|
-
if (!baseSettingsKeys.length) {
|
|
138
|
-
return properties;
|
|
139
|
-
}
|
|
140
|
-
const enriched = { ...properties };
|
|
141
|
-
for (const key of baseSettingsKeys) {
|
|
142
|
-
const propSchema = enriched[key];
|
|
143
|
-
if (!propSchema) {
|
|
144
|
-
continue;
|
|
145
|
-
}
|
|
146
|
-
enriched[key] = {
|
|
147
|
-
...propSchema,
|
|
148
|
-
description: propSchema.description ? `${propSchema.description} ${BASE_SETTING_PROP_HINT}` : BASE_SETTING_PROP_HINT
|
|
149
|
-
};
|
|
150
|
-
}
|
|
151
|
-
return enriched;
|
|
152
|
-
}
|
|
153
|
-
function buildLlmGuidance(widgetData, widgetType, allWidgets) {
|
|
154
|
-
const defaultStyles = {};
|
|
155
|
-
const baseStyleSchema = widgetData?.base_styles;
|
|
156
|
-
if (baseStyleSchema) {
|
|
157
|
-
Object.values(baseStyleSchema).forEach((stylePropType) => {
|
|
158
|
-
stylePropType.variants.forEach((variant) => {
|
|
159
|
-
Object.assign(defaultStyles, variant.props);
|
|
160
|
-
});
|
|
161
|
-
});
|
|
162
|
-
}
|
|
163
|
-
const baseSettings = widgetData?.base_settings ?? {};
|
|
164
|
-
const hasDefaultStyles = Object.keys(defaultStyles).length > 0;
|
|
165
|
-
const hasDefaultSettings = Object.keys(baseSettings).length > 0;
|
|
166
|
-
const llmGuidance = {
|
|
167
|
-
can_have_children: !!widgetData?.meta?.is_container
|
|
168
|
-
};
|
|
169
|
-
if (hasDefaultStyles) {
|
|
170
|
-
llmGuidance.instructions = DEFAULT_STYLES_INSTRUCTION;
|
|
171
|
-
llmGuidance.default_styles = defaultStyles;
|
|
172
|
-
}
|
|
173
|
-
if (hasDefaultSettings) {
|
|
174
|
-
llmGuidance.instructions = mergeInstructions(llmGuidance.instructions, DEFAULT_SETTINGS_INSTRUCTION);
|
|
175
|
-
llmGuidance.default_settings = baseSettings;
|
|
176
|
-
}
|
|
177
|
-
const allowedChildTypes = widgetData.allowed_child_types;
|
|
178
|
-
const allowedParents = Object.entries(allWidgets).filter(([, parentConfig]) => parentConfig.allowed_child_types?.includes(widgetType)).map(([parentType]) => parentType);
|
|
179
|
-
if (allowedChildTypes?.length || allowedParents.length) {
|
|
180
|
-
llmGuidance.nesting = {
|
|
181
|
-
...allowedChildTypes?.length ? { allowed_child_types: allowedChildTypes } : {},
|
|
182
|
-
...allowedParents.length ? { allowed_parents: allowedParents } : {}
|
|
183
|
-
};
|
|
184
|
-
}
|
|
185
|
-
const requiredDirectChildTags = getRequiredDefaultChildTypes(widgetData);
|
|
186
|
-
if (requiredDirectChildTags.length) {
|
|
187
|
-
llmGuidance.required_direct_children = requiredDirectChildTags;
|
|
188
|
-
}
|
|
189
|
-
return llmGuidance;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
// src/mcp/resources/widgets-schema-resource.ts
|
|
193
|
-
var V3_LAYOUT_CONTROL_TYPES = /* @__PURE__ */ new Set(["section", "tab", "tabs"]);
|
|
194
|
-
function extractV3ControlsMetadata(controls) {
|
|
195
|
-
if (!hasV3Controls(controls)) {
|
|
196
|
-
return {};
|
|
197
|
-
}
|
|
198
|
-
const result = {};
|
|
199
|
-
for (const [controlKey, raw] of Object.entries(controls)) {
|
|
200
|
-
if (!raw || typeof raw !== "object") {
|
|
201
|
-
continue;
|
|
202
|
-
}
|
|
203
|
-
const control = raw;
|
|
204
|
-
const controlType = typeof control.type === "string" ? control.type : void 0;
|
|
205
|
-
if (controlType && V3_LAYOUT_CONTROL_TYPES.has(controlType)) {
|
|
206
|
-
continue;
|
|
207
|
-
}
|
|
208
|
-
const entry = {};
|
|
209
|
-
if (Object.prototype.hasOwnProperty.call(control, "default")) {
|
|
210
|
-
entry.default = control.default;
|
|
211
|
-
}
|
|
212
|
-
if (controlType) {
|
|
213
|
-
entry.type = controlType;
|
|
214
|
-
}
|
|
215
|
-
if (Object.prototype.hasOwnProperty.call(control, "options") && control.options !== void 0) {
|
|
216
|
-
const options = control.options;
|
|
217
|
-
if (options && typeof options === "object" && !Array.isArray(options)) {
|
|
218
|
-
entry.options = Object.keys(options);
|
|
219
|
-
} else {
|
|
220
|
-
entry.options = options;
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
result[controlKey] = entry;
|
|
224
|
-
}
|
|
225
|
-
return result;
|
|
226
|
-
}
|
|
75
|
+
var import_http_client = require("@elementor/http-client");
|
|
227
76
|
var CANVAS_SERVER_NAME = "editor-canvas";
|
|
228
77
|
var WIDGET_SCHEMA_URI = "elementor://widgets/schema/{widgetType}";
|
|
229
78
|
var WIDGET_SCHEMA_FULL_URI = `${CANVAS_SERVER_NAME}_${WIDGET_SCHEMA_URI}`;
|
|
230
|
-
var BEST_PRACTICES_URI = "elementor://
|
|
79
|
+
var BEST_PRACTICES_URI = "elementor://style/best-practices";
|
|
231
80
|
var BEST_PRACTICES_FULL_URI = `${CANVAS_SERVER_NAME}_${BEST_PRACTICES_URI}`;
|
|
81
|
+
var MCP_PROXY_URL = "elementor/v1/mcp-proxy";
|
|
82
|
+
var listWidgetTypes = async () => {
|
|
83
|
+
const { data } = await (0, import_http_client.httpService)().post(MCP_PROXY_URL, {
|
|
84
|
+
tool: "list-widgets",
|
|
85
|
+
input: {}
|
|
86
|
+
});
|
|
87
|
+
return (data.data ?? []).map((widget) => widget.type);
|
|
88
|
+
};
|
|
89
|
+
var fetchWidgetSchema = async (widgetType) => {
|
|
90
|
+
const { data } = await (0, import_http_client.httpService)().post(MCP_PROXY_URL, {
|
|
91
|
+
tool: "get-widget-schema",
|
|
92
|
+
input: { widget_type: widgetType }
|
|
93
|
+
});
|
|
94
|
+
return data.data ?? {};
|
|
95
|
+
};
|
|
232
96
|
var initWidgetsSchemaResource = (reg) => {
|
|
233
97
|
const { resource } = reg;
|
|
234
|
-
resource(
|
|
235
|
-
"styles-best-practices",
|
|
236
|
-
BEST_PRACTICES_URI,
|
|
237
|
-
{
|
|
238
|
-
description: "Styling best practices"
|
|
239
|
-
},
|
|
240
|
-
async () => {
|
|
241
|
-
return {
|
|
242
|
-
contents: [
|
|
243
|
-
{
|
|
244
|
-
uri: BEST_PRACTICES_URI,
|
|
245
|
-
text: `# Styling best practices
|
|
246
|
-
Prefer using "em" and "rem" values for text-related sizes, padding and spacing. Use percentages for dynamic sizing relative to parent containers.
|
|
247
|
-
This flexboxes are by default "flex" with "stretch" alignment. To ensure proper layout, define the "justify-content" and "align-items" as in the schema.
|
|
248
|
-
|
|
249
|
-
Styling is provided as raw CSS. The css string must follow standard CSS syntax, with properties and values separated by semicolons, no selectors, or nesting rules allowed.
|
|
250
|
-
|
|
251
|
-
** CRITICAL - VARIABLES **
|
|
252
|
-
When using global variables, ensure that the variables are defined in the ${"elementor://global-variables"} resource.
|
|
253
|
-
Variables from the user context ARE NOT SUPPORTED AND WILL RESOLVE IN ERROR.
|
|
254
|
-
|
|
255
|
-
`
|
|
256
|
-
}
|
|
257
|
-
]
|
|
258
|
-
};
|
|
259
|
-
}
|
|
260
|
-
);
|
|
261
98
|
resource(
|
|
262
99
|
"widget-schema-by-type",
|
|
263
100
|
new import_editor_mcp.ResourceTemplate(WIDGET_SCHEMA_URI, {
|
|
264
|
-
list: () => {
|
|
265
|
-
const
|
|
266
|
-
const availableWidgets = Object.keys(cache).filter(
|
|
267
|
-
(widgetType) => isWidgetAvailableForLLM(cache[widgetType])
|
|
268
|
-
);
|
|
101
|
+
list: async () => {
|
|
102
|
+
const widgetTypes = await listWidgetTypes();
|
|
269
103
|
return {
|
|
270
|
-
resources:
|
|
104
|
+
resources: widgetTypes.map((widgetType) => ({
|
|
271
105
|
uri: `elementor://widgets/schema/${widgetType}`,
|
|
272
106
|
name: "Widget schema for " + widgetType
|
|
273
107
|
}))
|
|
@@ -279,52 +113,16 @@ Variables from the user context ARE NOT SUPPORTED AND WILL RESOLVE IN ERROR.
|
|
|
279
113
|
},
|
|
280
114
|
async (uri, variables) => {
|
|
281
115
|
const widgetType = typeof variables.widgetType === "string" ? variables.widgetType : variables.widgetType?.[0];
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
throw new Error(`No prop schema found for element type: ${widgetType}`);
|
|
285
|
-
}
|
|
286
|
-
const propSchema = widgetData.atomic_props_schema;
|
|
287
|
-
if (!propSchema) {
|
|
288
|
-
if (!hasV3Controls(widgetData.controls)) {
|
|
289
|
-
throw new Error(`No prop schema found for element type: ${widgetType}`);
|
|
290
|
-
}
|
|
291
|
-
const controlMetadata = extractV3ControlsMetadata(widgetData.controls);
|
|
292
|
-
return {
|
|
293
|
-
contents: [
|
|
294
|
-
{
|
|
295
|
-
uri: uri.toString(),
|
|
296
|
-
mimeType: "application/json",
|
|
297
|
-
text: JSON.stringify({
|
|
298
|
-
widget_version: "v3",
|
|
299
|
-
message: "This widget exists in the editor but has no atomic props schema (V4). Use control_metadata as non-authoritative hints from legacy controls.",
|
|
300
|
-
fields_note: "All settings are optional; there is no JSON schema for this widget type.",
|
|
301
|
-
properties: controlMetadata
|
|
302
|
-
})
|
|
303
|
-
}
|
|
304
|
-
]
|
|
305
|
-
};
|
|
116
|
+
if (!widgetType) {
|
|
117
|
+
throw new Error("No widget type provided.");
|
|
306
118
|
}
|
|
307
|
-
const
|
|
308
|
-
const asJson = enrichPropertiesWithBaseSettingsHints(
|
|
309
|
-
Object.fromEntries(
|
|
310
|
-
Object.entries(propSchema).filter(([key, propType]) => import_editor_props.Schema.isPropKeyConfigurable(key, propType)).map(([key, propType]) => [key, import_editor_props.Schema.propTypeToJsonSchema(propType)])
|
|
311
|
-
),
|
|
312
|
-
baseSettingsKeys
|
|
313
|
-
);
|
|
314
|
-
const description = typeof widgetData?.meta?.description === "string" ? widgetData.meta.description : void 0;
|
|
315
|
-
const allWidgets = (0, import_editor_elements2.getWidgetsCache)() || {};
|
|
316
|
-
const llmGuidance = buildLlmGuidance(widgetData, widgetType, allWidgets);
|
|
119
|
+
const schema2 = await fetchWidgetSchema(widgetType);
|
|
317
120
|
return {
|
|
318
121
|
contents: [
|
|
319
122
|
{
|
|
320
123
|
uri: uri.toString(),
|
|
321
124
|
mimeType: "application/json",
|
|
322
|
-
text: JSON.stringify(
|
|
323
|
-
type: "object",
|
|
324
|
-
properties: asJson,
|
|
325
|
-
description,
|
|
326
|
-
llm_guidance: llmGuidance
|
|
327
|
-
})
|
|
125
|
+
text: JSON.stringify(schema2)
|
|
328
126
|
}
|
|
329
127
|
]
|
|
330
128
|
};
|
|
@@ -379,11 +177,11 @@ var initBreakpointsResource = (reg) => {
|
|
|
379
177
|
};
|
|
380
178
|
|
|
381
179
|
// src/mcp/utils/convert-css-to-atomic.ts
|
|
382
|
-
var
|
|
180
|
+
var import_http_client2 = require("@elementor/http-client");
|
|
383
181
|
var CSS_TO_ATOMIC_URL = "elementor/v1/css-to-atomic";
|
|
384
182
|
var SINGLE_BLOCK_KEY = "default";
|
|
385
183
|
var convertBlocks = async (blocks) => {
|
|
386
|
-
const { data } = await (0,
|
|
184
|
+
const { data } = await (0, import_http_client2.httpService)().post(
|
|
387
185
|
CSS_TO_ATOMIC_URL,
|
|
388
186
|
{ blocks }
|
|
389
187
|
);
|
|
@@ -397,7 +195,7 @@ var convertCssToAtomic = async (style) => {
|
|
|
397
195
|
|
|
398
196
|
// src/init.tsx
|
|
399
197
|
var import_editor = require("@elementor/editor");
|
|
400
|
-
var
|
|
198
|
+
var import_editor_mcp4 = require("@elementor/editor-mcp");
|
|
401
199
|
|
|
402
200
|
// src/components/classes-rename.tsx
|
|
403
201
|
var import_react = require("react");
|
|
@@ -443,7 +241,7 @@ var renameClass = (oldClassName, newClassName) => {
|
|
|
443
241
|
|
|
444
242
|
// src/components/elements-overlays.tsx
|
|
445
243
|
var React7 = __toESM(require("react"));
|
|
446
|
-
var
|
|
244
|
+
var import_editor_elements3 = require("@elementor/editor-elements");
|
|
447
245
|
var import_editor_v1_adapters3 = require("@elementor/editor-v1-adapters");
|
|
448
246
|
|
|
449
247
|
// src/components/grid-outline/grid-empty-cell-positioner.tsx
|
|
@@ -514,7 +312,7 @@ function useMutationsListener({ element, onChange }) {
|
|
|
514
312
|
|
|
515
313
|
// src/hooks/use-grid-tracks.ts
|
|
516
314
|
var import_react4 = require("react");
|
|
517
|
-
var
|
|
315
|
+
var import_editor_elements = require("@elementor/editor-elements");
|
|
518
316
|
var import_editor_v1_adapters2 = require("@elementor/editor-v1-adapters");
|
|
519
317
|
|
|
520
318
|
// src/utils/grid-outline-utils.ts
|
|
@@ -522,8 +320,8 @@ function toGridTracks(computedStyle) {
|
|
|
522
320
|
return {
|
|
523
321
|
columns: parseTrackList(computedStyle.gridTemplateColumns),
|
|
524
322
|
rows: parseTrackList(computedStyle.gridTemplateRows),
|
|
525
|
-
columnGap:
|
|
526
|
-
rowGap:
|
|
323
|
+
columnGap: resolveGapPx(computedStyle.columnGap, computedStyle.width),
|
|
324
|
+
rowGap: resolveGapPx(computedStyle.rowGap, computedStyle.height),
|
|
527
325
|
padding: {
|
|
528
326
|
top: toPx(computedStyle.paddingTop),
|
|
529
327
|
right: toPx(computedStyle.paddingRight),
|
|
@@ -598,6 +396,14 @@ function toPx(value) {
|
|
|
598
396
|
const parsed = parseFloat(value);
|
|
599
397
|
return Number.isFinite(parsed) ? parsed : 0;
|
|
600
398
|
}
|
|
399
|
+
function resolveGapPx(value, referenceSize) {
|
|
400
|
+
if (value.trim().endsWith("%")) {
|
|
401
|
+
const percent = parseFloat(value);
|
|
402
|
+
const reference = parseFloat(referenceSize);
|
|
403
|
+
return Number.isFinite(percent) && Number.isFinite(reference) ? percent / 100 * reference : 0;
|
|
404
|
+
}
|
|
405
|
+
return toPx(value);
|
|
406
|
+
}
|
|
601
407
|
|
|
602
408
|
// src/hooks/use-grid-children.ts
|
|
603
409
|
var import_react3 = require("react");
|
|
@@ -652,7 +458,7 @@ var DEVICE_MODE_CHANGE_EVENT = "elementor/device-mode/change";
|
|
|
652
458
|
function useGridTracks(element, rect) {
|
|
653
459
|
const [tracks, setTracks] = (0, import_react4.useState)(EMPTY);
|
|
654
460
|
const trigger = (0, import_editor_v1_adapters2.__privateUseListenTo)(
|
|
655
|
-
[(0, import_editor_v1_adapters2.windowEvent)(
|
|
461
|
+
[(0, import_editor_v1_adapters2.windowEvent)(import_editor_elements.ELEMENT_STYLE_CHANGE_EVENT), (0, import_editor_v1_adapters2.windowEvent)(DEVICE_MODE_CHANGE_EVENT)],
|
|
656
462
|
() => ({})
|
|
657
463
|
);
|
|
658
464
|
const childrenTrigger = useGridChildren(element);
|
|
@@ -869,7 +675,7 @@ var GridEmptyCellPositioner = ({ element }) => {
|
|
|
869
675
|
|
|
870
676
|
// src/components/grid-outline/grid-outline-overlay.tsx
|
|
871
677
|
var React6 = __toESM(require("react"));
|
|
872
|
-
var
|
|
678
|
+
var import_editor_elements2 = require("@elementor/editor-elements");
|
|
873
679
|
var import_ui2 = require("@elementor/ui");
|
|
874
680
|
var import_react11 = require("@floating-ui/react");
|
|
875
681
|
|
|
@@ -1158,7 +964,7 @@ function GridOutline({ element, tracks, width, height }) {
|
|
|
1158
964
|
|
|
1159
965
|
// src/components/grid-outline/grid-outline-overlay.tsx
|
|
1160
966
|
var GridOutlineOverlay = ({ element, id, isSelected }) => {
|
|
1161
|
-
const settings = (0,
|
|
967
|
+
const settings = (0, import_editor_elements2.useElementEditorSettings)(id);
|
|
1162
968
|
const enabled = settings?.grid_outline;
|
|
1163
969
|
const rect = useElementRect(element);
|
|
1164
970
|
const tracks = useGridTracks(element, rect);
|
|
@@ -1201,7 +1007,7 @@ var overlayRegistry = [
|
|
|
1201
1007
|
}
|
|
1202
1008
|
];
|
|
1203
1009
|
function ElementsOverlays() {
|
|
1204
|
-
const selected = (0,
|
|
1010
|
+
const selected = (0, import_editor_elements3.useSelectedElement)();
|
|
1205
1011
|
const elements = useElementsDom();
|
|
1206
1012
|
const currentEditMode = (0, import_editor_v1_adapters3.useEditMode)();
|
|
1207
1013
|
const isEditMode = currentEditMode === "edit";
|
|
@@ -1231,7 +1037,7 @@ function useElementsDom() {
|
|
|
1231
1037
|
return (0, import_editor_v1_adapters3.__privateUseListenTo)(
|
|
1232
1038
|
[(0, import_editor_v1_adapters3.windowEvent)("elementor/editor/element-rendered"), (0, import_editor_v1_adapters3.windowEvent)("elementor/editor/element-destroyed")],
|
|
1233
1039
|
() => {
|
|
1234
|
-
return (0,
|
|
1040
|
+
return (0, import_editor_elements3.getElements)().filter((el) => isV4Element(el.view?.el?.dataset)).map((element) => ({
|
|
1235
1041
|
id: element.id,
|
|
1236
1042
|
domElement: element.view?.getDomElement?.()?.get?.(0),
|
|
1237
1043
|
isGlobal: element.model.get("isGlobal") ?? false,
|
|
@@ -1485,7 +1291,7 @@ var import_editor_styles = require("@elementor/editor-styles");
|
|
|
1485
1291
|
var import_editor_v1_adapters8 = require("@elementor/editor-v1-adapters");
|
|
1486
1292
|
|
|
1487
1293
|
// src/renderers/create-props-resolver.ts
|
|
1488
|
-
var
|
|
1294
|
+
var import_editor_props = require("@elementor/editor-props");
|
|
1489
1295
|
|
|
1490
1296
|
// src/renderers/multi-props.ts
|
|
1491
1297
|
var isMultiProps = (propValue) => {
|
|
@@ -1523,7 +1329,7 @@ function createPropsResolver({ transformers, schema: initialSchema, onPropResolv
|
|
|
1523
1329
|
if (value === null || value === void 0) {
|
|
1524
1330
|
return null;
|
|
1525
1331
|
}
|
|
1526
|
-
if (!(0,
|
|
1332
|
+
if (!(0, import_editor_props.isTransformable)(value)) {
|
|
1527
1333
|
return value;
|
|
1528
1334
|
}
|
|
1529
1335
|
if (depth > TRANSFORM_DEPTH_LIMIT) {
|
|
@@ -1581,13 +1387,13 @@ function createPropsResolver({ transformers, schema: initialSchema, onPropResolv
|
|
|
1581
1387
|
}
|
|
1582
1388
|
|
|
1583
1389
|
// src/renderers/enqueue-font-from-style-prop.ts
|
|
1584
|
-
var
|
|
1390
|
+
var import_editor_props2 = require("@elementor/editor-props");
|
|
1585
1391
|
var maybeEnqueueFontFromStyleProp = (propType, propValue, enqueue) => {
|
|
1586
|
-
if (!(0,
|
|
1392
|
+
if (!(0, import_editor_props2.isTransformable)(propValue) || propValue.disabled) {
|
|
1587
1393
|
return;
|
|
1588
1394
|
}
|
|
1589
1395
|
const typeKey = propType.kind === "union" ? propValue.$$type : propType.key;
|
|
1590
|
-
const propTypeUtil = (0,
|
|
1396
|
+
const propTypeUtil = (0, import_editor_props2.getPropSchemaFromCache)(typeKey);
|
|
1591
1397
|
if (!propTypeUtil || !("getEnqueueFontFamily" in propTypeUtil) || typeof propTypeUtil.getEnqueueFontFamily !== "function") {
|
|
1592
1398
|
return;
|
|
1593
1399
|
}
|
|
@@ -1983,7 +1789,7 @@ var import_editor_v1_adapters11 = require("@elementor/editor-v1-adapters");
|
|
|
1983
1789
|
var import_i18n = require("@wordpress/i18n");
|
|
1984
1790
|
|
|
1985
1791
|
// src/form-structure/utils.ts
|
|
1986
|
-
var
|
|
1792
|
+
var import_editor_elements4 = require("@elementor/editor-elements");
|
|
1987
1793
|
var FORM_ELEMENT_TYPE = "e-form";
|
|
1988
1794
|
var FORM_FIELD_ELEMENT_TYPES = /* @__PURE__ */ new Set([
|
|
1989
1795
|
"e-form-input",
|
|
@@ -2013,10 +1819,10 @@ function isWithinForm(element) {
|
|
|
2013
1819
|
return isElementWithinFormSelector(element);
|
|
2014
1820
|
}
|
|
2015
1821
|
function hasElementType(element, type) {
|
|
2016
|
-
return (0,
|
|
1822
|
+
return (0, import_editor_elements4.getAllDescendants)(element).some((item) => getElementType(item) === type);
|
|
2017
1823
|
}
|
|
2018
1824
|
function hasElementTypes(element, types) {
|
|
2019
|
-
return (0,
|
|
1825
|
+
return (0, import_editor_elements4.getAllDescendants)(element).some((item) => {
|
|
2020
1826
|
const itemType = getElementType(item);
|
|
2021
1827
|
return itemType ? types.has(itemType) : false;
|
|
2022
1828
|
});
|
|
@@ -2048,46 +1854,6 @@ function clipboardRootsAreAtomicForms(elements) {
|
|
|
2048
1854
|
}
|
|
2049
1855
|
return elements.every((el) => getClipboardElementType(el) === FORM_ELEMENT_TYPE);
|
|
2050
1856
|
}
|
|
2051
|
-
function hasFormAncestor(node) {
|
|
2052
|
-
return node.closest(FORM_ELEMENT_TYPE) !== null;
|
|
2053
|
-
}
|
|
2054
|
-
function collectFormAncestorErrors(xml) {
|
|
2055
|
-
const errors = [];
|
|
2056
|
-
for (const node of xml.querySelectorAll("*")) {
|
|
2057
|
-
if (!FORM_FIELD_ELEMENT_TYPES.has(node.tagName.toLowerCase())) {
|
|
2058
|
-
continue;
|
|
2059
|
-
}
|
|
2060
|
-
if (hasFormAncestor(node)) {
|
|
2061
|
-
continue;
|
|
2062
|
-
}
|
|
2063
|
-
const id = node.getAttribute("configuration-id");
|
|
2064
|
-
errors.push(
|
|
2065
|
-
`<${node.tagName}${id ? ` configuration-id="${id}"` : ""}> must be nested inside <e-form> (any ancestor depth is allowed).`
|
|
2066
|
-
);
|
|
2067
|
-
}
|
|
2068
|
-
return errors;
|
|
2069
|
-
}
|
|
2070
|
-
function collectSubmitButtonErrors(xml) {
|
|
2071
|
-
const errors = [];
|
|
2072
|
-
for (const form of xml.querySelectorAll("e-form")) {
|
|
2073
|
-
const submitButtons = form.querySelectorAll("e-form-submit-button");
|
|
2074
|
-
if (submitButtons.length === 0) {
|
|
2075
|
-
errors.push(`<e-form> has no <e-form-submit-button>.`);
|
|
2076
|
-
} else if (submitButtons.length > 1) {
|
|
2077
|
-
errors.push(`<e-form> has ${submitButtons.length} submit buttons \u2014 only 1 is allowed.`);
|
|
2078
|
-
}
|
|
2079
|
-
}
|
|
2080
|
-
return errors;
|
|
2081
|
-
}
|
|
2082
|
-
function collectEmptyMessageErrors(xml) {
|
|
2083
|
-
const errors = [];
|
|
2084
|
-
for (const node of xml.querySelectorAll("e-form-success-message, e-form-error-message")) {
|
|
2085
|
-
if (node.children.length === 0) {
|
|
2086
|
-
errors.push(`<${node.tagName}> must have at least one child element (e.g. <e-atomic-paragraph>).`);
|
|
2087
|
-
}
|
|
2088
|
-
}
|
|
2089
|
-
return errors;
|
|
2090
|
-
}
|
|
2091
1857
|
|
|
2092
1858
|
// src/form-structure/enforce-form-ancestor-commands.ts
|
|
2093
1859
|
var FORM_FIELDS_OUTSIDE_ALERT = {
|
|
@@ -2797,7 +2563,7 @@ function initStyleTransformers() {
|
|
|
2797
2563
|
}
|
|
2798
2564
|
|
|
2799
2565
|
// src/legacy/init-legacy-views.ts
|
|
2800
|
-
var
|
|
2566
|
+
var import_editor_elements8 = require("@elementor/editor-elements");
|
|
2801
2567
|
var import_editor_v1_adapters14 = require("@elementor/editor-v1-adapters");
|
|
2802
2568
|
|
|
2803
2569
|
// src/renderers/create-dom-renderer.ts
|
|
@@ -2926,25 +2692,25 @@ function createElementViewClassDeclaration() {
|
|
|
2926
2692
|
}
|
|
2927
2693
|
|
|
2928
2694
|
// src/legacy/create-nested-templated-element-type.ts
|
|
2929
|
-
var
|
|
2695
|
+
var import_editor_elements6 = require("@elementor/editor-elements");
|
|
2930
2696
|
|
|
2931
2697
|
// src/legacy/create-pending-element.ts
|
|
2932
|
-
var
|
|
2698
|
+
var import_editor_elements5 = require("@elementor/editor-elements");
|
|
2933
2699
|
function createPendingElement(wrapperView, data, options = {}) {
|
|
2934
2700
|
const parentContainer = wrapperView.getContainer();
|
|
2935
2701
|
const model = { ...data };
|
|
2936
2702
|
if (!model.id) {
|
|
2937
|
-
model.id = (0,
|
|
2703
|
+
model.id = (0, import_editor_elements5.generateElementId)();
|
|
2938
2704
|
}
|
|
2939
2705
|
if (!model.elements) {
|
|
2940
2706
|
model.elements = [];
|
|
2941
2707
|
}
|
|
2942
|
-
const added = (0,
|
|
2708
|
+
const added = (0, import_editor_elements5.addModelToParent)(parentContainer.id, model, options);
|
|
2943
2709
|
if (!added) {
|
|
2944
2710
|
return void 0;
|
|
2945
2711
|
}
|
|
2946
2712
|
const childId = model.id;
|
|
2947
|
-
const childModel = (0,
|
|
2713
|
+
const childModel = (0, import_editor_elements5.findModelInDocument)(childId);
|
|
2948
2714
|
if (!childModel) {
|
|
2949
2715
|
return void 0;
|
|
2950
2716
|
}
|
|
@@ -2955,7 +2721,7 @@ function createPendingElement(wrapperView, data, options = {}) {
|
|
|
2955
2721
|
model: childModel,
|
|
2956
2722
|
view: void 0,
|
|
2957
2723
|
lookup() {
|
|
2958
|
-
return (0,
|
|
2724
|
+
return (0, import_editor_elements5.getContainer)(childId) ?? pendingContainer;
|
|
2959
2725
|
}
|
|
2960
2726
|
};
|
|
2961
2727
|
wrapperView.once("render", () => {
|
|
@@ -2968,7 +2734,7 @@ function createPendingElement(wrapperView, data, options = {}) {
|
|
|
2968
2734
|
}
|
|
2969
2735
|
function selectChildWhenWrapperRenders(wrapperView, childId) {
|
|
2970
2736
|
wrapperView.once("render", () => {
|
|
2971
|
-
const childContainer = (0,
|
|
2737
|
+
const childContainer = (0, import_editor_elements5.getContainer)(childId);
|
|
2972
2738
|
if (childContainer?.model?.trigger) {
|
|
2973
2739
|
childContainer.model.trigger("request:edit");
|
|
2974
2740
|
return;
|
|
@@ -3235,7 +3001,7 @@ function createNestedTemplatedElementView({
|
|
|
3235
3001
|
this._initAlpine();
|
|
3236
3002
|
});
|
|
3237
3003
|
this.model.trigger("render:complete");
|
|
3238
|
-
window.dispatchEvent(new CustomEvent(
|
|
3004
|
+
window.dispatchEvent(new CustomEvent(import_editor_elements6.ELEMENT_STYLE_CHANGE_EVENT));
|
|
3239
3005
|
},
|
|
3240
3006
|
async _renderTemplate() {
|
|
3241
3007
|
const model = this.model;
|
|
@@ -3483,8 +3249,8 @@ var import_client = require("react-dom/client");
|
|
|
3483
3249
|
|
|
3484
3250
|
// src/legacy/replacements/inline-editing/inline-editing-elements.tsx
|
|
3485
3251
|
var React11 = __toESM(require("react"));
|
|
3486
|
-
var
|
|
3487
|
-
var
|
|
3252
|
+
var import_editor_elements7 = require("@elementor/editor-elements");
|
|
3253
|
+
var import_editor_props4 = require("@elementor/editor-props");
|
|
3488
3254
|
var import_editor_v1_adapters13 = require("@elementor/editor-v1-adapters");
|
|
3489
3255
|
var import_i18n3 = require("@wordpress/i18n");
|
|
3490
3256
|
|
|
@@ -3761,11 +3527,11 @@ var InlineEditingToolbar = ({ anchor, editor, id }) => {
|
|
|
3761
3527
|
};
|
|
3762
3528
|
|
|
3763
3529
|
// src/legacy/replacements/inline-editing/inline-editing-eligibility.ts
|
|
3764
|
-
var
|
|
3530
|
+
var import_editor_props3 = require("@elementor/editor-props");
|
|
3765
3531
|
var hasKey = (propType) => {
|
|
3766
3532
|
return "key" in propType;
|
|
3767
3533
|
};
|
|
3768
|
-
var TEXT_PROP_TYPE_KEYS = /* @__PURE__ */ new Set([
|
|
3534
|
+
var TEXT_PROP_TYPE_KEYS = /* @__PURE__ */ new Set([import_editor_props3.htmlV3PropTypeUtil.key, import_editor_props3.stringPropTypeUtil.key]);
|
|
3769
3535
|
var isCoreTextPropTypeKey = (key) => {
|
|
3770
3536
|
return TEXT_PROP_TYPE_KEYS.has(key);
|
|
3771
3537
|
};
|
|
@@ -3785,7 +3551,7 @@ var isInlineEditingAllowed = ({ rawValue, propTypeFromSchema }) => {
|
|
|
3785
3551
|
if (rawValue === null || rawValue === void 0) {
|
|
3786
3552
|
return isAllowedBySchema(propTypeFromSchema);
|
|
3787
3553
|
}
|
|
3788
|
-
return
|
|
3554
|
+
return import_editor_props3.htmlV3PropTypeUtil.isValid(rawValue) || import_editor_props3.stringPropTypeUtil.isValid(rawValue);
|
|
3789
3555
|
};
|
|
3790
3556
|
|
|
3791
3557
|
// src/legacy/replacements/inline-editing/inline-editing-elements.tsx
|
|
@@ -3859,7 +3625,7 @@ var InlineEditingReplacement = class extends ReplacementBase {
|
|
|
3859
3625
|
return INLINE_EDITING_PROPERTY_PER_TYPE[this.type] ?? "";
|
|
3860
3626
|
}
|
|
3861
3627
|
getInlineEditablePropType() {
|
|
3862
|
-
const propSchema = (0,
|
|
3628
|
+
const propSchema = (0, import_editor_elements7.getElementType)(this.type)?.propsSchema;
|
|
3863
3629
|
const propertyName = this.getInlineEditablePropertyName();
|
|
3864
3630
|
return propSchema?.[propertyName] ?? null;
|
|
3865
3631
|
}
|
|
@@ -3870,15 +3636,15 @@ var InlineEditingReplacement = class extends ReplacementBase {
|
|
|
3870
3636
|
}
|
|
3871
3637
|
getExtractedContentValue() {
|
|
3872
3638
|
const propValue = this.getInlineEditablePropValue();
|
|
3873
|
-
const extracted =
|
|
3874
|
-
return
|
|
3639
|
+
const extracted = import_editor_props4.htmlV3PropTypeUtil.extract(propValue);
|
|
3640
|
+
return import_editor_props4.stringPropTypeUtil.extract(extracted?.content ?? null) ?? "";
|
|
3875
3641
|
}
|
|
3876
3642
|
setContentValue(value) {
|
|
3877
3643
|
const settingKey = this.getInlineEditablePropertyName();
|
|
3878
3644
|
const html = value || "";
|
|
3879
|
-
const parsed = (0,
|
|
3880
|
-
const valueToSave =
|
|
3881
|
-
content: parsed.content ?
|
|
3645
|
+
const parsed = (0, import_editor_props4.parseHtmlChildren)(html);
|
|
3646
|
+
const valueToSave = import_editor_props4.htmlV3PropTypeUtil.create({
|
|
3647
|
+
content: parsed.content ? import_editor_props4.stringPropTypeUtil.create(parsed.content) : null,
|
|
3882
3648
|
children: parsed.children
|
|
3883
3649
|
});
|
|
3884
3650
|
(0, import_editor_v1_adapters13.undoable)(
|
|
@@ -3893,7 +3659,7 @@ var InlineEditingReplacement = class extends ReplacementBase {
|
|
|
3893
3659
|
}
|
|
3894
3660
|
},
|
|
3895
3661
|
{
|
|
3896
|
-
title: (0,
|
|
3662
|
+
title: (0, import_editor_elements7.getElementLabel)(this.id),
|
|
3897
3663
|
// translators: %s is the name of the property that was edited.
|
|
3898
3664
|
subtitle: (0, import_i18n3.__)("%s edited", "elementor").replace(
|
|
3899
3665
|
"%s",
|
|
@@ -3909,7 +3675,7 @@ var InlineEditingReplacement = class extends ReplacementBase {
|
|
|
3909
3675
|
return null;
|
|
3910
3676
|
}
|
|
3911
3677
|
if (propType.kind === "union") {
|
|
3912
|
-
const textKeys = [
|
|
3678
|
+
const textKeys = [import_editor_props4.htmlV3PropTypeUtil.key, import_editor_props4.stringPropTypeUtil.key];
|
|
3913
3679
|
for (const key of textKeys) {
|
|
3914
3680
|
if (propType.prop_types[key]) {
|
|
3915
3681
|
return key;
|
|
@@ -3926,7 +3692,7 @@ var InlineEditingReplacement = class extends ReplacementBase {
|
|
|
3926
3692
|
(0, import_editor_v1_adapters13.__privateRunCommandSync)(
|
|
3927
3693
|
"document/elements/set-settings",
|
|
3928
3694
|
{
|
|
3929
|
-
container: (0,
|
|
3695
|
+
container: (0, import_editor_elements7.getContainer)(this.id),
|
|
3930
3696
|
settings: {
|
|
3931
3697
|
[key]: value
|
|
3932
3698
|
}
|
|
@@ -3938,10 +3704,10 @@ var InlineEditingReplacement = class extends ReplacementBase {
|
|
|
3938
3704
|
getExpectedTag() {
|
|
3939
3705
|
const tagPropType = this.getTagPropType();
|
|
3940
3706
|
const tagSettingKey = "tag";
|
|
3941
|
-
return
|
|
3707
|
+
return import_editor_props4.stringPropTypeUtil.extract(this.getSetting(tagSettingKey) ?? null) ?? import_editor_props4.stringPropTypeUtil.extract(tagPropType?.default ?? null) ?? null;
|
|
3942
3708
|
}
|
|
3943
3709
|
getTagPropType() {
|
|
3944
|
-
const propsSchema = (0,
|
|
3710
|
+
const propsSchema = (0, import_editor_elements7.getElementType)(this.type)?.propsSchema;
|
|
3945
3711
|
if (!propsSchema?.tag) {
|
|
3946
3712
|
return null;
|
|
3947
3713
|
}
|
|
@@ -4104,7 +3870,7 @@ function registerElementType(type, elementTypeGenerator) {
|
|
|
4104
3870
|
}
|
|
4105
3871
|
function initLegacyViews() {
|
|
4106
3872
|
(0, import_editor_v1_adapters14.__privateListenTo)((0, import_editor_v1_adapters14.v1ReadyEvent)(), () => {
|
|
4107
|
-
const widgetsCache = (0,
|
|
3873
|
+
const widgetsCache = (0, import_editor_elements8.getWidgetsCache)() ?? {};
|
|
4108
3874
|
const renderer = createDomRenderer();
|
|
4109
3875
|
registerProPromotionTypes(widgetsCache);
|
|
4110
3876
|
Object.keys(widgetsCache).forEach((type) => {
|
|
@@ -4113,7 +3879,7 @@ function initLegacyViews() {
|
|
|
4113
3879
|
});
|
|
4114
3880
|
}
|
|
4115
3881
|
function registerElementInLegacyManager(type, renderer) {
|
|
4116
|
-
const element = ((0,
|
|
3882
|
+
const element = ((0, import_editor_elements8.getWidgetsCache)() ?? {})[type];
|
|
4117
3883
|
if (!element?.atomic) {
|
|
4118
3884
|
return;
|
|
4119
3885
|
}
|
|
@@ -4165,7 +3931,7 @@ function createNestedTemplatedType(type, renderer, element) {
|
|
|
4165
3931
|
}
|
|
4166
3932
|
|
|
4167
3933
|
// src/legacy/tabs-model-extensions.ts
|
|
4168
|
-
var
|
|
3934
|
+
var import_editor_props5 = require("@elementor/editor-props");
|
|
4169
3935
|
var tabModelExtensions = {
|
|
4170
3936
|
modifyDefaultChildren(elements) {
|
|
4171
3937
|
if (!Array.isArray(elements) || elements.length === 0) {
|
|
@@ -4181,8 +3947,8 @@ var tabModelExtensions = {
|
|
|
4181
3947
|
...paragraphElement,
|
|
4182
3948
|
settings: {
|
|
4183
3949
|
...paragraphElement.settings,
|
|
4184
|
-
paragraph:
|
|
4185
|
-
content:
|
|
3950
|
+
paragraph: import_editor_props5.htmlV3PropTypeUtil.create({
|
|
3951
|
+
content: import_editor_props5.stringPropTypeUtil.create(`Tab ${position}`),
|
|
4186
3952
|
children: []
|
|
4187
3953
|
})
|
|
4188
3954
|
}
|
|
@@ -4195,43 +3961,41 @@ function initTabsModelExtensions() {
|
|
|
4195
3961
|
}
|
|
4196
3962
|
|
|
4197
3963
|
// src/mcp/canvas-mcp.ts
|
|
4198
|
-
var
|
|
3964
|
+
var import_editor_props9 = require("@elementor/editor-props");
|
|
4199
3965
|
|
|
4200
3966
|
// src/mcp/resources/available-widgets-resource.ts
|
|
4201
|
-
var
|
|
3967
|
+
var import_http_client3 = require("@elementor/http-client");
|
|
3968
|
+
var MCP_PROXY_URL2 = "elementor/v1/mcp-proxy";
|
|
4202
3969
|
var AVAILABLE_WIDGETS_URI = "elementor://context/available-widgets";
|
|
4203
3970
|
var AVAILABLE_WIDGETS_URI_V4 = "elementor://context/available-widgets/v4";
|
|
4204
|
-
var
|
|
4205
|
-
const {
|
|
4206
|
-
|
|
4207
|
-
|
|
4208
|
-
|
|
4209
|
-
|
|
4210
|
-
|
|
4211
|
-
|
|
4212
|
-
|
|
4213
|
-
|
|
4214
|
-
|
|
4215
|
-
|
|
4216
|
-
|
|
4217
|
-
|
|
4218
|
-
|
|
4219
|
-
|
|
4220
|
-
|
|
4221
|
-
...buildContents(AVAILABLE_WIDGETS_URI)
|
|
4222
|
-
});
|
|
4223
|
-
sendResourceUpdated({
|
|
4224
|
-
uri: AVAILABLE_WIDGETS_URI_V4,
|
|
4225
|
-
...buildContents(AVAILABLE_WIDGETS_URI_V4, (w) => w.version === "v4")
|
|
4226
|
-
});
|
|
3971
|
+
var fetchWidgets = async (version) => {
|
|
3972
|
+
const { data } = await (0, import_http_client3.httpService)().post(MCP_PROXY_URL2, {
|
|
3973
|
+
tool: "list-widgets",
|
|
3974
|
+
input: version ? { version } : {}
|
|
3975
|
+
});
|
|
3976
|
+
return data.data ?? [];
|
|
3977
|
+
};
|
|
3978
|
+
var buildContents = async (uri, version) => {
|
|
3979
|
+
const widgets = await fetchWidgets(version);
|
|
3980
|
+
return {
|
|
3981
|
+
contents: [
|
|
3982
|
+
{
|
|
3983
|
+
uri,
|
|
3984
|
+
mimeType: "application/json",
|
|
3985
|
+
text: JSON.stringify(widgets, null, 2)
|
|
3986
|
+
}
|
|
3987
|
+
]
|
|
4227
3988
|
};
|
|
3989
|
+
};
|
|
3990
|
+
var initAvailableWidgetsResource = (reg) => {
|
|
3991
|
+
const { resource } = reg;
|
|
4228
3992
|
resource(
|
|
4229
3993
|
"available-widgets-v4",
|
|
4230
3994
|
AVAILABLE_WIDGETS_URI_V4,
|
|
4231
3995
|
{
|
|
4232
3996
|
description: "All registered v4 version widgets"
|
|
4233
3997
|
},
|
|
4234
|
-
async () => buildContents(AVAILABLE_WIDGETS_URI_V4,
|
|
3998
|
+
async () => buildContents(AVAILABLE_WIDGETS_URI_V4, "v4")
|
|
4235
3999
|
);
|
|
4236
4000
|
resource(
|
|
4237
4001
|
"available-widgets",
|
|
@@ -4241,22 +4005,41 @@ var initAvailableWidgetsResource = (reg) => {
|
|
|
4241
4005
|
},
|
|
4242
4006
|
async () => buildContents(AVAILABLE_WIDGETS_URI)
|
|
4243
4007
|
);
|
|
4244
|
-
|
|
4245
|
-
|
|
4246
|
-
|
|
4247
|
-
|
|
4248
|
-
|
|
4008
|
+
};
|
|
4009
|
+
|
|
4010
|
+
// src/mcp/resources/best-practices-resource.ts
|
|
4011
|
+
var import_http_client4 = require("@elementor/http-client");
|
|
4012
|
+
var MCP_PROXY_URL3 = "elementor/v1/mcp-proxy";
|
|
4013
|
+
var BEST_PRACTICES_URI2 = "elementor://style/best-practices";
|
|
4014
|
+
var initBestPracticesResource = (reg) => {
|
|
4015
|
+
const { resource } = reg;
|
|
4016
|
+
resource(
|
|
4017
|
+
"style-best-practices",
|
|
4018
|
+
BEST_PRACTICES_URI2,
|
|
4019
|
+
{
|
|
4020
|
+
description: "Design quality guidelines for avoiding generic AI output: typography, color strategy, spacing, motion, and visual hierarchy best practices.",
|
|
4021
|
+
mimeType: "text/markdown"
|
|
4022
|
+
},
|
|
4023
|
+
async (uri) => {
|
|
4024
|
+
const { data } = await (0, import_http_client4.httpService)().get(MCP_PROXY_URL3, {
|
|
4025
|
+
params: { uri: uri.href }
|
|
4026
|
+
});
|
|
4027
|
+
return {
|
|
4028
|
+
contents: [
|
|
4029
|
+
{
|
|
4030
|
+
uri: uri.href,
|
|
4031
|
+
mimeType: "text/markdown",
|
|
4032
|
+
text: data.data
|
|
4033
|
+
}
|
|
4034
|
+
]
|
|
4035
|
+
};
|
|
4249
4036
|
}
|
|
4250
|
-
|
|
4251
|
-
notifyResourcesUpdated();
|
|
4252
|
-
};
|
|
4253
|
-
window.addEventListener(eventName, onV1Ready);
|
|
4254
|
-
onV1Ready();
|
|
4037
|
+
);
|
|
4255
4038
|
};
|
|
4256
4039
|
|
|
4257
4040
|
// src/mcp/resources/document-structure-resource.ts
|
|
4258
|
-
var
|
|
4259
|
-
var
|
|
4041
|
+
var import_editor_elements9 = require("@elementor/editor-elements");
|
|
4042
|
+
var import_editor_v1_adapters15 = require("@elementor/editor-v1-adapters");
|
|
4260
4043
|
var DOCUMENT_STRUCTURE_URI = "elementor://document/structure";
|
|
4261
4044
|
var initDocumentStructureResource = (reg) => {
|
|
4262
4045
|
const { resource, sendResourceUpdated } = reg;
|
|
@@ -4269,15 +4052,15 @@ var initDocumentStructureResource = (reg) => {
|
|
|
4269
4052
|
sendResourceUpdated({ uri: DOCUMENT_STRUCTURE_URI });
|
|
4270
4053
|
}
|
|
4271
4054
|
};
|
|
4272
|
-
(0,
|
|
4055
|
+
(0, import_editor_v1_adapters15.__privateListenTo)(
|
|
4273
4056
|
[
|
|
4274
|
-
(0,
|
|
4275
|
-
(0,
|
|
4276
|
-
(0,
|
|
4277
|
-
(0,
|
|
4278
|
-
(0,
|
|
4279
|
-
(0,
|
|
4280
|
-
(0,
|
|
4057
|
+
(0, import_editor_v1_adapters15.commandEndEvent)("document/elements/create"),
|
|
4058
|
+
(0, import_editor_v1_adapters15.commandEndEvent)("document/elements/delete"),
|
|
4059
|
+
(0, import_editor_v1_adapters15.commandEndEvent)("document/elements/move"),
|
|
4060
|
+
(0, import_editor_v1_adapters15.commandEndEvent)("document/elements/copy"),
|
|
4061
|
+
(0, import_editor_v1_adapters15.commandEndEvent)("document/elements/paste"),
|
|
4062
|
+
(0, import_editor_v1_adapters15.commandEndEvent)("editor/documents/attach-preview"),
|
|
4063
|
+
(0, import_editor_v1_adapters15.commandEndEvent)("editor/documents/switch")
|
|
4281
4064
|
],
|
|
4282
4065
|
updateDocumentStructure
|
|
4283
4066
|
);
|
|
@@ -4320,7 +4103,7 @@ function resolveElementVersion(element) {
|
|
|
4320
4103
|
return "v4";
|
|
4321
4104
|
}
|
|
4322
4105
|
const widgetType = element.model?.attributes?.widgetType;
|
|
4323
|
-
if (widgetType && (0,
|
|
4106
|
+
if (widgetType && (0, import_editor_elements9.getWidgetsCache)()?.[widgetType]?.atomic_props_schema) {
|
|
4324
4107
|
return "v4";
|
|
4325
4108
|
}
|
|
4326
4109
|
return "v3";
|
|
@@ -4347,84 +4130,15 @@ function extractElementData(element) {
|
|
|
4347
4130
|
}
|
|
4348
4131
|
|
|
4349
4132
|
// src/mcp/resources/dynamic-tags-resource.ts
|
|
4350
|
-
var
|
|
4351
|
-
|
|
4352
|
-
// src/mcp/utils/resolve-dynamic-tag.ts
|
|
4353
|
-
var import_editor_v1_adapters17 = require("@elementor/editor-v1-adapters");
|
|
4354
|
-
var DYNAMIC_PROP_TYPE_KEY = "dynamic";
|
|
4355
|
-
var OMITTED_DYNAMIC_SETTING_KEYS = ["fallback"];
|
|
4356
|
-
var getAtomicDynamicTags = () => {
|
|
4357
|
-
const config = (0, import_editor_v1_adapters17.getElementorConfig)();
|
|
4358
|
-
return config.atomicDynamicTags?.tags ?? {};
|
|
4359
|
-
};
|
|
4360
|
-
var getDynamicTagNamesByCategories = (categories) => {
|
|
4361
|
-
if (!categories.length) {
|
|
4362
|
-
return [];
|
|
4363
|
-
}
|
|
4364
|
-
const wanted = new Set(categories);
|
|
4365
|
-
return Object.values(getAtomicDynamicTags()).filter((tag) => tag.categories?.some((category) => wanted.has(category))).map((tag) => tag.name);
|
|
4366
|
-
};
|
|
4367
|
-
var dynamicTagLLMResolver = (value) => {
|
|
4368
|
-
const input = value ?? {};
|
|
4369
|
-
const tag = input.name ? getAtomicDynamicTags()[input.name] : void 0;
|
|
4370
|
-
if (!tag) {
|
|
4371
|
-
return {
|
|
4372
|
-
$$type: DYNAMIC_PROP_TYPE_KEY,
|
|
4373
|
-
value: { name: input.name ?? "", group: "", settings: {} }
|
|
4374
|
-
};
|
|
4375
|
-
}
|
|
4376
|
-
return {
|
|
4377
|
-
$$type: DYNAMIC_PROP_TYPE_KEY,
|
|
4378
|
-
value: {
|
|
4379
|
-
name: tag.name,
|
|
4380
|
-
group: tag.group,
|
|
4381
|
-
settings: buildStrictSettings(tag.props_schema ?? {}, input.settings ?? {})
|
|
4382
|
-
}
|
|
4383
|
-
};
|
|
4384
|
-
};
|
|
4385
|
-
var buildStrictSettings = (schema2, provided) => {
|
|
4386
|
-
const settings = {};
|
|
4387
|
-
for (const [key, propType] of Object.entries(schema2)) {
|
|
4388
|
-
if (OMITTED_DYNAMIC_SETTING_KEYS.includes(key)) {
|
|
4389
|
-
continue;
|
|
4390
|
-
}
|
|
4391
|
-
const resolved = provided[key] !== void 0 ? wrapSettingValue(provided[key], propType) : defaultSettingValue(propType);
|
|
4392
|
-
if (resolved !== void 0 && resolved !== null) {
|
|
4393
|
-
settings[key] = resolved;
|
|
4394
|
-
}
|
|
4395
|
-
}
|
|
4396
|
-
return settings;
|
|
4397
|
-
};
|
|
4398
|
-
var wrapSettingValue = (raw, propType) => {
|
|
4399
|
-
if (raw !== null && typeof raw === "object") {
|
|
4400
|
-
return raw;
|
|
4401
|
-
}
|
|
4402
|
-
return propType.key ? { $$type: propType.key, value: raw } : raw;
|
|
4403
|
-
};
|
|
4404
|
-
var defaultSettingValue = (propType) => {
|
|
4405
|
-
if (propType.initial_value !== null && propType.initial_value !== void 0) {
|
|
4406
|
-
return propType.initial_value;
|
|
4407
|
-
}
|
|
4408
|
-
if (propType.default !== null && propType.default !== void 0) {
|
|
4409
|
-
return wrapSettingValue(propType.default, propType);
|
|
4410
|
-
}
|
|
4411
|
-
return void 0;
|
|
4412
|
-
};
|
|
4413
|
-
|
|
4414
|
-
// src/mcp/resources/dynamic-tags-resource.ts
|
|
4133
|
+
var import_http_client5 = require("@elementor/http-client");
|
|
4415
4134
|
var DYNAMIC_TAGS_URI = "elementor://dynamic-tags";
|
|
4416
|
-
var
|
|
4417
|
-
|
|
4418
|
-
|
|
4419
|
-
|
|
4420
|
-
}
|
|
4421
|
-
|
|
4422
|
-
return
|
|
4423
|
-
name: tag.name,
|
|
4424
|
-
label: tag.label,
|
|
4425
|
-
categories: tag.categories,
|
|
4426
|
-
settings: settingsSchema(tag.props_schema)
|
|
4427
|
-
}));
|
|
4135
|
+
var MCP_PROXY_URL4 = "elementor/v1/mcp-proxy";
|
|
4136
|
+
var fetchDynamicTags = async () => {
|
|
4137
|
+
const { data } = await (0, import_http_client5.httpService)().post(MCP_PROXY_URL4, {
|
|
4138
|
+
tool: "list-dynamic-tags",
|
|
4139
|
+
input: {}
|
|
4140
|
+
});
|
|
4141
|
+
return data.data ?? [];
|
|
4428
4142
|
};
|
|
4429
4143
|
var initDynamicTagsResource = (reg) => {
|
|
4430
4144
|
const { resource } = reg;
|
|
@@ -4435,20 +4149,23 @@ var initDynamicTagsResource = (reg) => {
|
|
|
4435
4149
|
description: `List of available dynamic tags. To bind a property to a dynamic source, set its value to { "$$type": "dynamic", "value": { "name": <tag name>, "settings": { ... } } } using a tag whose name appears in that property's allowed list, and populate "settings" per the tag entry here.`,
|
|
4436
4150
|
mimeType: "application/json"
|
|
4437
4151
|
},
|
|
4438
|
-
async (uri) =>
|
|
4439
|
-
|
|
4440
|
-
|
|
4441
|
-
|
|
4442
|
-
|
|
4443
|
-
|
|
4444
|
-
|
|
4445
|
-
|
|
4446
|
-
|
|
4152
|
+
async (uri) => {
|
|
4153
|
+
const tags = await fetchDynamicTags();
|
|
4154
|
+
return {
|
|
4155
|
+
contents: [
|
|
4156
|
+
{
|
|
4157
|
+
uri: uri.href,
|
|
4158
|
+
mimeType: "application/json",
|
|
4159
|
+
text: JSON.stringify(tags)
|
|
4160
|
+
}
|
|
4161
|
+
]
|
|
4162
|
+
};
|
|
4163
|
+
}
|
|
4447
4164
|
);
|
|
4448
4165
|
};
|
|
4449
4166
|
|
|
4450
4167
|
// src/mcp/resources/editor-state-resource.ts
|
|
4451
|
-
var
|
|
4168
|
+
var import_editor_v1_adapters16 = require("@elementor/editor-v1-adapters");
|
|
4452
4169
|
var CURRENTLY_VIEWED_SCREEN = "The user is currently viewing the Elementor editor";
|
|
4453
4170
|
var PAGE_CONTENT_CHARACTER_LIMIT = 500;
|
|
4454
4171
|
var PREVIEW_TEXT_NODE_MIN_LENGTH = 2;
|
|
@@ -4469,8 +4186,8 @@ var initEditorStateResource = (reg) => {
|
|
|
4469
4186
|
lastSerializedState = serialized;
|
|
4470
4187
|
sendResourceUpdated({ uri: EDITOR_STATE_URI });
|
|
4471
4188
|
};
|
|
4472
|
-
(0,
|
|
4473
|
-
[(0,
|
|
4189
|
+
(0, import_editor_v1_adapters16.__privateListenTo)(
|
|
4190
|
+
[(0, import_editor_v1_adapters16.commandEndEvent)("editor/documents/switch"), (0, import_editor_v1_adapters16.commandEndEvent)("editor/documents/attach-preview")],
|
|
4474
4191
|
notifyIfChanged
|
|
4475
4192
|
);
|
|
4476
4193
|
lastSerializedState = JSON.stringify(buildState());
|
|
@@ -4544,7 +4261,7 @@ function getPageTitle() {
|
|
|
4544
4261
|
}
|
|
4545
4262
|
|
|
4546
4263
|
// src/mcp/resources/general-context-resource.ts
|
|
4547
|
-
var
|
|
4264
|
+
var import_editor_v1_adapters17 = require("@elementor/editor-v1-adapters");
|
|
4548
4265
|
var GENERAL_CONTEXT_URI = "elementor://context/general";
|
|
4549
4266
|
var initGeneralContextResource = (reg) => {
|
|
4550
4267
|
const { resource, sendResourceUpdated } = reg;
|
|
@@ -4605,11 +4322,11 @@ var initGeneralContextResource = (reg) => {
|
|
|
4605
4322
|
};
|
|
4606
4323
|
}
|
|
4607
4324
|
);
|
|
4608
|
-
(0,
|
|
4325
|
+
(0, import_editor_v1_adapters17.__privateListenTo)(
|
|
4609
4326
|
[
|
|
4610
|
-
(0,
|
|
4611
|
-
(0,
|
|
4612
|
-
(0,
|
|
4327
|
+
(0, import_editor_v1_adapters17.commandEndEvent)("editor/documents/switch"),
|
|
4328
|
+
(0, import_editor_v1_adapters17.commandEndEvent)("editor/documents/attach-preview"),
|
|
4329
|
+
(0, import_editor_v1_adapters17.commandEndEvent)("document/elements/settings")
|
|
4613
4330
|
],
|
|
4614
4331
|
pushUpdateIfChanged
|
|
4615
4332
|
);
|
|
@@ -4617,8 +4334,8 @@ var initGeneralContextResource = (reg) => {
|
|
|
4617
4334
|
};
|
|
4618
4335
|
|
|
4619
4336
|
// src/mcp/resources/selected-element-resource.ts
|
|
4620
|
-
var
|
|
4621
|
-
var
|
|
4337
|
+
var import_editor_elements10 = require("@elementor/editor-elements");
|
|
4338
|
+
var import_editor_v1_adapters18 = require("@elementor/editor-v1-adapters");
|
|
4622
4339
|
var SELECTED_ELEMENT_URI = "elementor://context/selected-element";
|
|
4623
4340
|
var initSelectedElementResource = (reg) => {
|
|
4624
4341
|
const { resource, sendResourceUpdated } = reg;
|
|
@@ -4649,11 +4366,11 @@ var initSelectedElementResource = (reg) => {
|
|
|
4649
4366
|
}
|
|
4650
4367
|
publishIfChanged(readSelectionFromEditor());
|
|
4651
4368
|
};
|
|
4652
|
-
(0,
|
|
4369
|
+
(0, import_editor_v1_adapters18.__privateListenTo)(
|
|
4653
4370
|
[
|
|
4654
|
-
(0,
|
|
4655
|
-
(0,
|
|
4656
|
-
(0,
|
|
4371
|
+
(0, import_editor_v1_adapters18.commandEndEvent)("document/elements/select"),
|
|
4372
|
+
(0, import_editor_v1_adapters18.commandEndEvent)("document/elements/deselect-all"),
|
|
4373
|
+
(0, import_editor_v1_adapters18.commandEndEvent)("document/elements/settings")
|
|
4657
4374
|
],
|
|
4658
4375
|
onCommand
|
|
4659
4376
|
);
|
|
@@ -4688,11 +4405,11 @@ function createEmptySelectedElementPayload() {
|
|
|
4688
4405
|
};
|
|
4689
4406
|
}
|
|
4690
4407
|
function readSelectionFromEditor() {
|
|
4691
|
-
const elements = (0,
|
|
4408
|
+
const elements = (0, import_editor_elements10.getSelectedElements)();
|
|
4692
4409
|
if (elements.length !== 1) {
|
|
4693
4410
|
return createEmptySelectedElementPayload();
|
|
4694
4411
|
}
|
|
4695
|
-
const container = (0,
|
|
4412
|
+
const container = (0, import_editor_elements10.getContainer)(elements[0].id);
|
|
4696
4413
|
return buildPayloadFromContainer(container);
|
|
4697
4414
|
}
|
|
4698
4415
|
function buildPayloadFromContainer(container) {
|
|
@@ -4715,7 +4432,7 @@ function resolveElementVersion2(container, widgetType) {
|
|
|
4715
4432
|
if (container.model?.config?.atomic) {
|
|
4716
4433
|
return "v4";
|
|
4717
4434
|
}
|
|
4718
|
-
if (widgetType && (0,
|
|
4435
|
+
if (widgetType && (0, import_editor_elements10.getWidgetsCache)()?.[widgetType]?.atomic_props_schema) {
|
|
4719
4436
|
return "v4";
|
|
4720
4437
|
}
|
|
4721
4438
|
return "v3";
|
|
@@ -4725,7 +4442,7 @@ function getElementProperties(container, widgetType) {
|
|
|
4725
4442
|
if (!settings || typeof settings !== "object") {
|
|
4726
4443
|
return null;
|
|
4727
4444
|
}
|
|
4728
|
-
const widgetConfig = widgetType ? (0,
|
|
4445
|
+
const widgetConfig = widgetType ? (0, import_editor_elements10.getWidgetsCache)()?.[widgetType] : null;
|
|
4729
4446
|
const controls = widgetConfig?.controls;
|
|
4730
4447
|
const filtered = {};
|
|
4731
4448
|
for (const [key, value] of Object.entries(settings)) {
|
|
@@ -4763,18 +4480,106 @@ function getElementDisplayName(container) {
|
|
|
4763
4480
|
}
|
|
4764
4481
|
|
|
4765
4482
|
// src/mcp/tools/build-composition/tool.ts
|
|
4766
|
-
var
|
|
4767
|
-
var
|
|
4768
|
-
var
|
|
4483
|
+
var import_editor_documents2 = require("@elementor/editor-documents");
|
|
4484
|
+
var import_editor_elements11 = require("@elementor/editor-elements");
|
|
4485
|
+
var import_http_client6 = require("@elementor/http-client");
|
|
4486
|
+
var import_schema = require("@elementor/schema");
|
|
4487
|
+
var MCP_PROXY_URL5 = "elementor/v1/mcp-proxy";
|
|
4488
|
+
var initBuildCompositionTool = (reg) => {
|
|
4489
|
+
const { addTool } = reg;
|
|
4490
|
+
addTool({
|
|
4491
|
+
name: "build-composition",
|
|
4492
|
+
description: "Build a V4 element composition on the Elementor canvas via the server-side MCP ability. Pass the raw XML tags directly as xmlStructure \u2014 do NOT wrap the value in <![CDATA[ ... ]]>, code fences, or quotes. The document is saved as a draft. Reload the editor after calling this tool to see the result.",
|
|
4493
|
+
schema: {
|
|
4494
|
+
xmlStructure: import_schema.z.string().describe(
|
|
4495
|
+
'Valid XML structure with custom Elementor widget tags. Every element MUST have a unique configuration-id attribute (e.g. <e-heading configuration-id="hero-title"></e-heading>). No attributes, classes, IDs, or text nodes in XML. Pass raw XML \u2014 do not wrap in CDATA.'
|
|
4496
|
+
),
|
|
4497
|
+
elementConfig: import_schema.z.record(
|
|
4498
|
+
import_schema.z.string().describe("configuration-id"),
|
|
4499
|
+
import_schema.z.record(import_schema.z.string().describe("property name"), import_schema.z.any().describe("PropValue"))
|
|
4500
|
+
).optional().describe("Map configuration-id \u2192 widget PropValues ($$type + value)."),
|
|
4501
|
+
style: import_schema.z.record(
|
|
4502
|
+
import_schema.z.string().describe("configuration-id"),
|
|
4503
|
+
import_schema.z.record(import_schema.z.string().describe("CSS property name"), import_schema.z.string().describe("CSS value"))
|
|
4504
|
+
).optional().describe(
|
|
4505
|
+
"Map configuration-id \u2192 raw CSS declarations (property \u2192 value strings; no selectors). Server converts to native styles; unconvertible declarations become the element custom CSS."
|
|
4506
|
+
),
|
|
4507
|
+
parentId: import_schema.z.string().optional().describe("ID of the parent container. Omit or pass 'document' to insert at document root."),
|
|
4508
|
+
dryRun: import_schema.z.boolean().optional().describe("If true, validate and return the resolved tree without persisting.")
|
|
4509
|
+
},
|
|
4510
|
+
outputSchema: {
|
|
4511
|
+
rootElementIds: import_schema.z.array(import_schema.z.string()),
|
|
4512
|
+
previewUrl: import_schema.z.string(),
|
|
4513
|
+
version: import_schema.z.string(),
|
|
4514
|
+
resolvedXml: import_schema.z.string(),
|
|
4515
|
+
llmInstructions: import_schema.z.string(),
|
|
4516
|
+
warnings: import_schema.z.array(import_schema.z.string()).optional()
|
|
4517
|
+
},
|
|
4518
|
+
handler: async ({ xmlStructure, elementConfig, style, parentId, dryRun }) => {
|
|
4519
|
+
const document2 = (0, import_editor_documents2.getCurrentDocument)();
|
|
4520
|
+
if (!document2?.id) {
|
|
4521
|
+
throw new Error("No active document found.");
|
|
4522
|
+
}
|
|
4523
|
+
try {
|
|
4524
|
+
const { data } = await (0, import_http_client6.httpService)().post(MCP_PROXY_URL5, {
|
|
4525
|
+
tool: "build-composition",
|
|
4526
|
+
input: {
|
|
4527
|
+
post_id: document2.id,
|
|
4528
|
+
xml_structure: xmlStructure,
|
|
4529
|
+
element_config: elementConfig ?? {},
|
|
4530
|
+
style: style ?? {},
|
|
4531
|
+
parent_id: parentId ?? "document",
|
|
4532
|
+
dry_run: dryRun ?? false
|
|
4533
|
+
}
|
|
4534
|
+
});
|
|
4535
|
+
if (!dryRun) {
|
|
4536
|
+
await (0, import_editor_documents2.reloadCurrentDocument)();
|
|
4537
|
+
const [firstRootId] = data.data.root_element_ids;
|
|
4538
|
+
if (firstRootId) {
|
|
4539
|
+
(0, import_editor_elements11.selectElement)(firstRootId);
|
|
4540
|
+
(0, import_editor_elements11.getContainer)(firstRootId)?.view?.el?.scrollIntoView({
|
|
4541
|
+
behavior: "smooth",
|
|
4542
|
+
block: "center"
|
|
4543
|
+
});
|
|
4544
|
+
}
|
|
4545
|
+
}
|
|
4546
|
+
return {
|
|
4547
|
+
rootElementIds: data.data.root_element_ids,
|
|
4548
|
+
previewUrl: data.data.preview_url,
|
|
4549
|
+
version: data.data.version,
|
|
4550
|
+
resolvedXml: data.data.resolved_xml,
|
|
4551
|
+
llmInstructions: data.data.llm_instructions,
|
|
4552
|
+
warnings: data.data.warnings
|
|
4553
|
+
};
|
|
4554
|
+
} catch (error) {
|
|
4555
|
+
throw new Error(getErrorMessage(error));
|
|
4556
|
+
}
|
|
4557
|
+
}
|
|
4558
|
+
});
|
|
4559
|
+
};
|
|
4560
|
+
function getErrorMessage(error) {
|
|
4561
|
+
if (error instanceof import_http_client6.AxiosError) {
|
|
4562
|
+
const data = error.response?.data;
|
|
4563
|
+
if (data?.message) {
|
|
4564
|
+
return data.code ? `${data.code}: ${data.message}` : data.message;
|
|
4565
|
+
}
|
|
4566
|
+
}
|
|
4567
|
+
if (error instanceof Error) {
|
|
4568
|
+
return error.message;
|
|
4569
|
+
}
|
|
4570
|
+
return "build-composition failed with an unknown error.";
|
|
4571
|
+
}
|
|
4769
4572
|
|
|
4770
|
-
// src/
|
|
4771
|
-
var
|
|
4573
|
+
// src/mcp/tools/configure-element/tool.ts
|
|
4574
|
+
var import_editor_elements14 = require("@elementor/editor-elements");
|
|
4575
|
+
var import_editor_mcp3 = require("@elementor/editor-mcp");
|
|
4576
|
+
var import_editor_props7 = require("@elementor/editor-props");
|
|
4772
4577
|
|
|
4773
4578
|
// src/mcp/utils/do-update-element-property.ts
|
|
4774
|
-
var
|
|
4775
|
-
var
|
|
4579
|
+
var import_editor_elements13 = require("@elementor/editor-elements");
|
|
4580
|
+
var import_editor_props6 = require("@elementor/editor-props");
|
|
4776
4581
|
var import_editor_styles4 = require("@elementor/editor-styles");
|
|
4777
|
-
var
|
|
4582
|
+
var import_editor_v1_adapters20 = require("@elementor/editor-v1-adapters");
|
|
4778
4583
|
|
|
4779
4584
|
// src/mcp/utils/merge-custom-css.ts
|
|
4780
4585
|
var CUSTOM_CSS_SEPARATOR = "\n";
|
|
@@ -4791,7 +4596,7 @@ var readStoredCustomCssText = (raw) => {
|
|
|
4791
4596
|
};
|
|
4792
4597
|
|
|
4793
4598
|
// src/mcp/utils/resolve-canonical-prop-name.ts
|
|
4794
|
-
var
|
|
4599
|
+
var import_editor_elements12 = require("@elementor/editor-elements");
|
|
4795
4600
|
function buildAliasToCanonicalMap(schema2) {
|
|
4796
4601
|
const aliasToCanonical = {};
|
|
4797
4602
|
for (const [canonical, propType] of Object.entries(schema2)) {
|
|
@@ -4808,14 +4613,14 @@ function buildAliasToCanonicalMap(schema2) {
|
|
|
4808
4613
|
return aliasToCanonical;
|
|
4809
4614
|
}
|
|
4810
4615
|
function resolveCanonicalPropName(elementType, propertyName) {
|
|
4811
|
-
const schema2 = (0,
|
|
4616
|
+
const schema2 = (0, import_editor_elements12.getWidgetsCache)()?.[elementType]?.atomic_props_schema;
|
|
4812
4617
|
if (!schema2 || schema2[propertyName]) {
|
|
4813
4618
|
return propertyName;
|
|
4814
4619
|
}
|
|
4815
4620
|
return buildAliasToCanonicalMap(schema2)[propertyName] ?? propertyName;
|
|
4816
4621
|
}
|
|
4817
4622
|
function resolveCanonicalPropKeys(elementType, props) {
|
|
4818
|
-
const schema2 = (0,
|
|
4623
|
+
const schema2 = (0, import_editor_elements12.getWidgetsCache)()?.[elementType]?.atomic_props_schema;
|
|
4819
4624
|
if (!schema2) {
|
|
4820
4625
|
return { ...props };
|
|
4821
4626
|
}
|
|
@@ -4842,6 +4647,68 @@ function resolveCanonicalPropKeys(elementType, props) {
|
|
|
4842
4647
|
return resolved;
|
|
4843
4648
|
}
|
|
4844
4649
|
|
|
4650
|
+
// src/mcp/utils/resolve-dynamic-tag.ts
|
|
4651
|
+
var import_editor_v1_adapters19 = require("@elementor/editor-v1-adapters");
|
|
4652
|
+
var DYNAMIC_PROP_TYPE_KEY = "dynamic";
|
|
4653
|
+
var OMITTED_DYNAMIC_SETTING_KEYS = ["fallback"];
|
|
4654
|
+
var getAtomicDynamicTags = () => {
|
|
4655
|
+
const config = (0, import_editor_v1_adapters19.getElementorConfig)();
|
|
4656
|
+
return config.atomicDynamicTags?.tags ?? {};
|
|
4657
|
+
};
|
|
4658
|
+
var getDynamicTagNamesByCategories = (categories) => {
|
|
4659
|
+
if (!categories.length) {
|
|
4660
|
+
return [];
|
|
4661
|
+
}
|
|
4662
|
+
const wanted = new Set(categories);
|
|
4663
|
+
return Object.values(getAtomicDynamicTags()).filter((tag) => tag.categories?.some((category) => wanted.has(category))).map((tag) => tag.name);
|
|
4664
|
+
};
|
|
4665
|
+
var dynamicTagLLMResolver = (value) => {
|
|
4666
|
+
const input = value ?? {};
|
|
4667
|
+
const tag = input.name ? getAtomicDynamicTags()[input.name] : void 0;
|
|
4668
|
+
if (!tag) {
|
|
4669
|
+
return {
|
|
4670
|
+
$$type: DYNAMIC_PROP_TYPE_KEY,
|
|
4671
|
+
value: { name: input.name ?? "", group: "", settings: {} }
|
|
4672
|
+
};
|
|
4673
|
+
}
|
|
4674
|
+
return {
|
|
4675
|
+
$$type: DYNAMIC_PROP_TYPE_KEY,
|
|
4676
|
+
value: {
|
|
4677
|
+
name: tag.name,
|
|
4678
|
+
group: tag.group,
|
|
4679
|
+
settings: buildStrictSettings(tag.props_schema ?? {}, input.settings ?? {})
|
|
4680
|
+
}
|
|
4681
|
+
};
|
|
4682
|
+
};
|
|
4683
|
+
var buildStrictSettings = (schema2, provided) => {
|
|
4684
|
+
const settings = {};
|
|
4685
|
+
for (const [key, propType] of Object.entries(schema2)) {
|
|
4686
|
+
if (OMITTED_DYNAMIC_SETTING_KEYS.includes(key)) {
|
|
4687
|
+
continue;
|
|
4688
|
+
}
|
|
4689
|
+
const resolved = provided[key] !== void 0 ? wrapSettingValue(provided[key], propType) : defaultSettingValue(propType);
|
|
4690
|
+
if (resolved !== void 0 && resolved !== null) {
|
|
4691
|
+
settings[key] = resolved;
|
|
4692
|
+
}
|
|
4693
|
+
}
|
|
4694
|
+
return settings;
|
|
4695
|
+
};
|
|
4696
|
+
var wrapSettingValue = (raw, propType) => {
|
|
4697
|
+
if (raw !== null && typeof raw === "object") {
|
|
4698
|
+
return raw;
|
|
4699
|
+
}
|
|
4700
|
+
return propType.key ? { $$type: propType.key, value: raw } : raw;
|
|
4701
|
+
};
|
|
4702
|
+
var defaultSettingValue = (propType) => {
|
|
4703
|
+
if (propType.initial_value !== null && propType.initial_value !== void 0) {
|
|
4704
|
+
return propType.initial_value;
|
|
4705
|
+
}
|
|
4706
|
+
if (propType.default !== null && propType.default !== void 0) {
|
|
4707
|
+
return wrapSettingValue(propType.default, propType);
|
|
4708
|
+
}
|
|
4709
|
+
return void 0;
|
|
4710
|
+
};
|
|
4711
|
+
|
|
4845
4712
|
// src/mcp/utils/do-update-element-property.ts
|
|
4846
4713
|
var LOCAL_STYLE_META = {
|
|
4847
4714
|
breakpoint: "desktop",
|
|
@@ -4849,7 +4716,7 @@ var LOCAL_STYLE_META = {
|
|
|
4849
4716
|
};
|
|
4850
4717
|
function resolvePropValue(value, forceKey) {
|
|
4851
4718
|
const Utils = window.elementorV2.editorVariables.Utils;
|
|
4852
|
-
return
|
|
4719
|
+
return import_editor_props6.Schema.adjustLlmPropValueSchema(value, {
|
|
4853
4720
|
forceKey,
|
|
4854
4721
|
transformers: {
|
|
4855
4722
|
...Utils.globalVariablesLLMResolvers,
|
|
@@ -4861,7 +4728,7 @@ var doUpdateElementProperty = (params) => {
|
|
|
4861
4728
|
const { elementId, propertyValue, elementType, customCssWriteMode = "replace" } = params;
|
|
4862
4729
|
const propertyName = params.propertyName === "_styles" ? params.propertyName : resolveCanonicalPropName(elementType, params.propertyName);
|
|
4863
4730
|
if (propertyName === "_styles") {
|
|
4864
|
-
const elementStyles = (0,
|
|
4731
|
+
const elementStyles = (0, import_editor_elements13.getElementStyles)(elementId) || {};
|
|
4865
4732
|
const propertyMapValue = propertyValue;
|
|
4866
4733
|
const styleSchema = (0, import_editor_styles4.getStylesSchema)();
|
|
4867
4734
|
const transformedStyleValues = Object.fromEntries(
|
|
@@ -4908,7 +4775,7 @@ var doUpdateElementProperty = (params) => {
|
|
|
4908
4775
|
}
|
|
4909
4776
|
if (propertyRawSchema.kind === "plain") {
|
|
4910
4777
|
if (typeof propertyMapValue[stylePropName] !== "object") {
|
|
4911
|
-
const propUtil = (0,
|
|
4778
|
+
const propUtil = (0, import_editor_props6.getPropSchemaFromCache)(propertyRawSchema.key);
|
|
4912
4779
|
if (propUtil) {
|
|
4913
4780
|
const plainValue = propUtil.create(propertyMapValue[stylePropName]);
|
|
4914
4781
|
propertyMapValue[stylePropName] = plainValue;
|
|
@@ -4918,7 +4785,7 @@ var doUpdateElementProperty = (params) => {
|
|
|
4918
4785
|
});
|
|
4919
4786
|
delete transformedStyleValues.custom_css;
|
|
4920
4787
|
if (!localStyle) {
|
|
4921
|
-
(0,
|
|
4788
|
+
(0, import_editor_elements13.createElementStyle)({
|
|
4922
4789
|
elementId,
|
|
4923
4790
|
...typeof customCss !== "undefined" ? { custom_css: customCss } : {},
|
|
4924
4791
|
classesProp: "classes",
|
|
@@ -4932,7 +4799,7 @@ var doUpdateElementProperty = (params) => {
|
|
|
4932
4799
|
}
|
|
4933
4800
|
});
|
|
4934
4801
|
} else {
|
|
4935
|
-
(0,
|
|
4802
|
+
(0, import_editor_elements13.updateElementStyle)({
|
|
4936
4803
|
elementId,
|
|
4937
4804
|
styleId: localStyle.id,
|
|
4938
4805
|
meta: {
|
|
@@ -4947,7 +4814,7 @@ var doUpdateElementProperty = (params) => {
|
|
|
4947
4814
|
}
|
|
4948
4815
|
return;
|
|
4949
4816
|
}
|
|
4950
|
-
const elementPropSchema = (0,
|
|
4817
|
+
const elementPropSchema = (0, import_editor_elements13.getWidgetsCache)()?.[elementType]?.atomic_props_schema;
|
|
4951
4818
|
if (!elementPropSchema) {
|
|
4952
4819
|
throw new Error(`No prop schema found for element type: ${elementType}`);
|
|
4953
4820
|
}
|
|
@@ -4961,7 +4828,7 @@ var doUpdateElementProperty = (params) => {
|
|
|
4961
4828
|
}
|
|
4962
4829
|
const propKey = elementPropSchema[propertyName].key;
|
|
4963
4830
|
const value = resolvePropValue(propertyValue, propKey);
|
|
4964
|
-
const { valid, jsonSchema } =
|
|
4831
|
+
const { valid, jsonSchema } = import_editor_props6.Schema.validatePropValue(elementPropSchema[propertyName], propertyValue);
|
|
4965
4832
|
if (!valid) {
|
|
4966
4833
|
throw new Error(
|
|
4967
4834
|
`Invalid PropValue for elementId: ${elementId}. PropKey: ${propKey}, PropValue: ${JSON.stringify(
|
|
@@ -4970,762 +4837,21 @@ var doUpdateElementProperty = (params) => {
|
|
|
4970
4837
|
Expected Schema: ${jsonSchema}`
|
|
4971
4838
|
);
|
|
4972
4839
|
}
|
|
4973
|
-
(0,
|
|
4840
|
+
(0, import_editor_elements13.updateElementSettings)({
|
|
4974
4841
|
id: elementId,
|
|
4975
4842
|
props: {
|
|
4976
4843
|
[propertyName]: value
|
|
4977
4844
|
},
|
|
4978
4845
|
withHistory: false
|
|
4979
4846
|
});
|
|
4980
|
-
(0,
|
|
4981
|
-
};
|
|
4982
|
-
|
|
4983
|
-
// src/composition-builder/utils/required-children-enforcer.ts
|
|
4984
|
-
var REQUIRED_CHILD_SCHEMA_HINT = "Use the widget schema resource; under llm_guidance.required_direct_children for V4 widgets.";
|
|
4985
|
-
var RequiredChildrenEnforcer = class {
|
|
4986
|
-
elementType;
|
|
4987
|
-
requiredTemplates;
|
|
4988
|
-
constructor(elementType, widgetsCache) {
|
|
4989
|
-
this.elementType = elementType;
|
|
4990
|
-
this.requiredTemplates = getRequiredDefaultChildTemplates(widgetsCache[elementType]);
|
|
4991
|
-
}
|
|
4992
|
-
enforce(xml) {
|
|
4993
|
-
if (this.requiredTemplates.length === 0) {
|
|
4994
|
-
return;
|
|
4995
|
-
}
|
|
4996
|
-
const errors = [];
|
|
4997
|
-
for (const rootNode of Array.from(xml.children)) {
|
|
4998
|
-
this.collectMissingRequiredErrors(rootNode, errors);
|
|
4999
|
-
}
|
|
5000
|
-
if (errors.length) {
|
|
5001
|
-
throw new Error(`${errors.join("\n")}
|
|
5002
|
-
${REQUIRED_CHILD_SCHEMA_HINT}`);
|
|
5003
|
-
}
|
|
5004
|
-
}
|
|
5005
|
-
collectMissingRequiredErrors(node, errors) {
|
|
5006
|
-
if (node.tagName === this.elementType) {
|
|
5007
|
-
const existingChildTags = new Set(Array.from(node.children).map((child) => child.tagName));
|
|
5008
|
-
const missingTags = this.requiredTemplates.map((child) => child.widgetType ?? child.elType ?? "").filter((type) => type && !existingChildTags.has(type));
|
|
5009
|
-
if (missingTags.length) {
|
|
5010
|
-
const configurationId = node.getAttribute("configuration-id");
|
|
5011
|
-
const location2 = configurationId ? `<${node.tagName} configuration-id="${configurationId}">` : `<${node.tagName}>`;
|
|
5012
|
-
errors.push(
|
|
5013
|
-
`${location2} Missing required direct child element tag(s): ${missingTags.join(", ")}.`
|
|
5014
|
-
);
|
|
5015
|
-
}
|
|
5016
|
-
}
|
|
5017
|
-
for (const childNode of Array.from(node.children)) {
|
|
5018
|
-
this.collectMissingRequiredErrors(childNode, errors);
|
|
5019
|
-
}
|
|
5020
|
-
}
|
|
5021
|
-
};
|
|
5022
|
-
|
|
5023
|
-
// src/composition-builder/composition-builder.ts
|
|
5024
|
-
var CREATE_ELEMENT_INVALID_CONTAINER_MESSAGE = "createElement did not return an element container with a model.";
|
|
5025
|
-
var CompositionBuilder = class _CompositionBuilder {
|
|
5026
|
-
elementConfig = {};
|
|
5027
|
-
elementStylesConfig = {};
|
|
5028
|
-
elementCustomCSS = {};
|
|
5029
|
-
rootContainers = [];
|
|
5030
|
-
api = {
|
|
5031
|
-
createElement: import_editor_elements15.createElement,
|
|
5032
|
-
deleteElement: import_editor_elements15.deleteElement,
|
|
5033
|
-
getWidgetsCache: import_editor_elements15.getWidgetsCache,
|
|
5034
|
-
generateElementId: import_editor_elements15.generateElementId,
|
|
5035
|
-
getContainer: import_editor_elements15.getContainer,
|
|
5036
|
-
doUpdateElementProperty
|
|
5037
|
-
};
|
|
5038
|
-
xml;
|
|
5039
|
-
static fromXMLString(xmlString, api = {}) {
|
|
5040
|
-
const parser = new DOMParser();
|
|
5041
|
-
const xmlDoc = parser.parseFromString(xmlString, "application/xml");
|
|
5042
|
-
const errorNode = xmlDoc.querySelector("parsererror");
|
|
5043
|
-
if (errorNode) {
|
|
5044
|
-
throw new Error("Failed to parse XML string: " + errorNode.textContent);
|
|
5045
|
-
}
|
|
5046
|
-
return new _CompositionBuilder({
|
|
5047
|
-
xml: xmlDoc,
|
|
5048
|
-
api
|
|
5049
|
-
});
|
|
5050
|
-
}
|
|
5051
|
-
constructor(opts) {
|
|
5052
|
-
const { api = {}, elementConfig = {}, stylesConfig = {}, customCSS = {}, xml } = opts;
|
|
5053
|
-
this.xml = xml;
|
|
5054
|
-
Object.assign(this.api, api);
|
|
5055
|
-
this.setElementConfig(elementConfig);
|
|
5056
|
-
this.setStylesConfig(stylesConfig);
|
|
5057
|
-
this.setCustomCSS(customCSS);
|
|
5058
|
-
}
|
|
5059
|
-
setElementConfig(config) {
|
|
5060
|
-
this.elementConfig = config;
|
|
5061
|
-
}
|
|
5062
|
-
setStylesConfig(config) {
|
|
5063
|
-
this.elementStylesConfig = config;
|
|
5064
|
-
}
|
|
5065
|
-
setCustomCSS(config) {
|
|
5066
|
-
this.elementCustomCSS = config;
|
|
5067
|
-
}
|
|
5068
|
-
getXML() {
|
|
5069
|
-
return this.xml;
|
|
5070
|
-
}
|
|
5071
|
-
buildModelTree(node, widgetsCache) {
|
|
5072
|
-
const elementTag = node.tagName;
|
|
5073
|
-
const isWidget = widgetsCache[elementTag]?.elType === "widget";
|
|
5074
|
-
const id = this.api.generateElementId();
|
|
5075
|
-
const children = Array.from(node.children).map((child) => this.buildModelTree(child, widgetsCache));
|
|
5076
|
-
node.setAttribute("id", id);
|
|
5077
|
-
const base = {
|
|
5078
|
-
id,
|
|
5079
|
-
skipDefaultChildren: true,
|
|
5080
|
-
elements: children,
|
|
5081
|
-
editor_settings: {
|
|
5082
|
-
title: node.getAttribute("configuration-id") ?? void 0
|
|
5083
|
-
},
|
|
5084
|
-
elType: "widget"
|
|
5085
|
-
};
|
|
5086
|
-
if (isWidget) {
|
|
5087
|
-
return { ...base, elType: "widget", widgetType: elementTag };
|
|
5088
|
-
}
|
|
5089
|
-
return { ...base, elType: elementTag };
|
|
5090
|
-
}
|
|
5091
|
-
async awaitViewRender(element) {
|
|
5092
|
-
const view = element.view;
|
|
5093
|
-
if (view?._currentRenderPromise instanceof Promise) {
|
|
5094
|
-
await view._currentRenderPromise;
|
|
5095
|
-
} else {
|
|
5096
|
-
await Promise.resolve();
|
|
5097
|
-
}
|
|
5098
|
-
}
|
|
5099
|
-
validateChildTypes(node, widgetsCache) {
|
|
5100
|
-
const errors = [];
|
|
5101
|
-
const allowedChildTypes = widgetsCache[node.tagName]?.allowed_child_types;
|
|
5102
|
-
if (allowedChildTypes?.length) {
|
|
5103
|
-
for (const child of Array.from(node.children)) {
|
|
5104
|
-
if (!allowedChildTypes.includes(child.tagName)) {
|
|
5105
|
-
errors.push(
|
|
5106
|
-
`"${child.tagName}" is not allowed as a child of "${node.tagName}". Allowed: ${allowedChildTypes.join(", ")}`
|
|
5107
|
-
);
|
|
5108
|
-
}
|
|
5109
|
-
}
|
|
5110
|
-
}
|
|
5111
|
-
for (const child of Array.from(node.children)) {
|
|
5112
|
-
errors.push(...this.validateChildTypes(child, widgetsCache));
|
|
5113
|
-
}
|
|
5114
|
-
return errors;
|
|
5115
|
-
}
|
|
5116
|
-
matchNodeByConfigId(configId) {
|
|
5117
|
-
const node = this.xml.querySelector(`[configuration-id="${configId}"]`);
|
|
5118
|
-
if (!node) {
|
|
5119
|
-
throw new Error(`Configuration id "${configId}" does not have target node.`);
|
|
5120
|
-
}
|
|
5121
|
-
const id = node.getAttribute("id");
|
|
5122
|
-
if (!id) {
|
|
5123
|
-
throw new Error(`Node with configuration id "${configId}" does not have element id.`);
|
|
5124
|
-
}
|
|
5125
|
-
const element = this.api.getContainer(id);
|
|
5126
|
-
if (!element) {
|
|
5127
|
-
throw new Error(`Element with id "${id}" not found but should exist.`);
|
|
5128
|
-
}
|
|
5129
|
-
return {
|
|
5130
|
-
element,
|
|
5131
|
-
node
|
|
5132
|
-
};
|
|
5133
|
-
}
|
|
5134
|
-
async applyProperties() {
|
|
5135
|
-
const configErrors = [];
|
|
5136
|
-
const styleErrors = [];
|
|
5137
|
-
const allConfigIds = /* @__PURE__ */ new Set([
|
|
5138
|
-
...Object.keys(this.elementConfig),
|
|
5139
|
-
...Object.keys(this.elementStylesConfig),
|
|
5140
|
-
...Object.keys(this.elementCustomCSS)
|
|
5141
|
-
]);
|
|
5142
|
-
for (const configId of allConfigIds) {
|
|
5143
|
-
let element, node;
|
|
5144
|
-
try {
|
|
5145
|
-
({ element, node } = this.matchNodeByConfigId(configId));
|
|
5146
|
-
} catch (matchErr) {
|
|
5147
|
-
const msg = matchErr.message;
|
|
5148
|
-
if (this.elementConfig[configId]) {
|
|
5149
|
-
configErrors.push(msg);
|
|
5150
|
-
}
|
|
5151
|
-
if (this.elementStylesConfig[configId] || this.elementCustomCSS[configId]) {
|
|
5152
|
-
styleErrors.push(msg);
|
|
5153
|
-
}
|
|
5154
|
-
continue;
|
|
5155
|
-
}
|
|
5156
|
-
const config = this.elementConfig[configId];
|
|
5157
|
-
if (config) {
|
|
5158
|
-
for (const [propertyName, propertyValue] of Object.entries(config)) {
|
|
5159
|
-
try {
|
|
5160
|
-
this.api.doUpdateElementProperty({
|
|
5161
|
-
elementId: element.id,
|
|
5162
|
-
propertyName,
|
|
5163
|
-
propertyValue,
|
|
5164
|
-
elementType: node.tagName
|
|
5165
|
-
});
|
|
5166
|
-
} catch (error) {
|
|
5167
|
-
configErrors.push(error.message);
|
|
5168
|
-
}
|
|
5169
|
-
}
|
|
5170
|
-
}
|
|
5171
|
-
const styleConfig = this.elementStylesConfig[configId];
|
|
5172
|
-
const hasInvalidStyles = false;
|
|
5173
|
-
if (styleConfig) {
|
|
5174
|
-
const validStylesPropValues = {};
|
|
5175
|
-
for (const [styleName, stylePropValue] of Object.entries(styleConfig)) {
|
|
5176
|
-
if (styleName === "$intention") {
|
|
5177
|
-
continue;
|
|
5178
|
-
} else {
|
|
5179
|
-
validStylesPropValues[styleName] = stylePropValue;
|
|
5180
|
-
}
|
|
5181
|
-
}
|
|
5182
|
-
if (Object.keys(validStylesPropValues).length > 0) {
|
|
5183
|
-
try {
|
|
5184
|
-
this.api.doUpdateElementProperty({
|
|
5185
|
-
elementId: element.id,
|
|
5186
|
-
propertyName: "_styles",
|
|
5187
|
-
propertyValue: validStylesPropValues,
|
|
5188
|
-
elementType: node.tagName
|
|
5189
|
-
});
|
|
5190
|
-
} catch (error) {
|
|
5191
|
-
styleErrors.push(String(error));
|
|
5192
|
-
}
|
|
5193
|
-
}
|
|
5194
|
-
}
|
|
5195
|
-
const intentionCss = typeof styleConfig?.$intention === "string" ? styleConfig.$intention.trim() : "";
|
|
5196
|
-
const fallbackCss = hasInvalidStyles && intentionCss ? intentionCss : "";
|
|
5197
|
-
const mergedCustomCss = mergeCustomCssText(this.elementCustomCSS[configId], fallbackCss);
|
|
5198
|
-
if (mergedCustomCss) {
|
|
5199
|
-
try {
|
|
5200
|
-
this.api.doUpdateElementProperty({
|
|
5201
|
-
elementId: element.id,
|
|
5202
|
-
propertyName: "_styles",
|
|
5203
|
-
propertyValue: { custom_css: mergedCustomCss },
|
|
5204
|
-
elementType: node.tagName
|
|
5205
|
-
});
|
|
5206
|
-
} catch (cssErr) {
|
|
5207
|
-
styleErrors.push(String(cssErr));
|
|
5208
|
-
}
|
|
5209
|
-
}
|
|
5210
|
-
await this.awaitViewRender(element);
|
|
5211
|
-
}
|
|
5212
|
-
return { configErrors, styleErrors };
|
|
5213
|
-
}
|
|
5214
|
-
async build(rootContainer) {
|
|
5215
|
-
const widgetsCache = this.api.getWidgetsCache() || {};
|
|
5216
|
-
new Set(this.xml.querySelectorAll("*")).forEach((node) => {
|
|
5217
|
-
if (!widgetsCache[node.tagName]) {
|
|
5218
|
-
throw new Error(`Unknown widget type: ${node.tagName}`);
|
|
5219
|
-
}
|
|
5220
|
-
});
|
|
5221
|
-
const typesWithRequiredChildren = Object.keys(widgetsCache).filter(
|
|
5222
|
-
(elementType) => getRequiredDefaultChildTemplates(widgetsCache[elementType]).length > 0
|
|
5223
|
-
);
|
|
5224
|
-
typesWithRequiredChildren.forEach((elementType) => {
|
|
5225
|
-
new RequiredChildrenEnforcer(elementType, widgetsCache).enforce(this.xml);
|
|
5226
|
-
});
|
|
5227
|
-
const childTypeErrors = [];
|
|
5228
|
-
for (const rootChild of Array.from(this.xml.children)) {
|
|
5229
|
-
childTypeErrors.push(...this.validateChildTypes(rootChild, widgetsCache));
|
|
5230
|
-
}
|
|
5231
|
-
if (childTypeErrors.length) {
|
|
5232
|
-
throw new Error(`Invalid element structure:
|
|
5233
|
-
${childTypeErrors.join("\n")}`);
|
|
5234
|
-
}
|
|
5235
|
-
const formErrors = [
|
|
5236
|
-
...collectFormAncestorErrors(this.xml),
|
|
5237
|
-
...collectSubmitButtonErrors(this.xml),
|
|
5238
|
-
...collectEmptyMessageErrors(this.xml)
|
|
5239
|
-
];
|
|
5240
|
-
const children = Array.from(this.xml.children);
|
|
5241
|
-
for (const childNode of children) {
|
|
5242
|
-
const modelTree = this.buildModelTree(childNode, widgetsCache);
|
|
5243
|
-
try {
|
|
5244
|
-
const newElement = this.api.createElement({
|
|
5245
|
-
container: rootContainer,
|
|
5246
|
-
model: modelTree,
|
|
5247
|
-
options: { useHistory: false }
|
|
5248
|
-
});
|
|
5249
|
-
if (!newElement?.model) {
|
|
5250
|
-
throw new Error(CREATE_ELEMENT_INVALID_CONTAINER_MESSAGE);
|
|
5251
|
-
}
|
|
5252
|
-
this.rootContainers.push(newElement);
|
|
5253
|
-
await this.awaitViewRender(newElement);
|
|
5254
|
-
} catch (e) {
|
|
5255
|
-
const attempToRestoreInvalidContainer = this.api.getContainer(modelTree.id);
|
|
5256
|
-
if (attempToRestoreInvalidContainer) {
|
|
5257
|
-
this.api.deleteElement({ container: attempToRestoreInvalidContainer });
|
|
5258
|
-
}
|
|
5259
|
-
throw e;
|
|
5260
|
-
}
|
|
5261
|
-
}
|
|
5262
|
-
const { configErrors, styleErrors } = await this.applyProperties();
|
|
5263
|
-
if (typeof window !== "undefined") {
|
|
5264
|
-
const targetWindow = window.top || window;
|
|
5265
|
-
targetWindow.dispatchEvent(
|
|
5266
|
-
new CustomEvent("elementor/composition/built", {
|
|
5267
|
-
detail: { rootContainers: this.rootContainers.map((c) => c.id) }
|
|
5268
|
-
})
|
|
5269
|
-
);
|
|
5270
|
-
}
|
|
5271
|
-
return {
|
|
5272
|
-
configErrors,
|
|
5273
|
-
styleErrors,
|
|
5274
|
-
formErrors,
|
|
5275
|
-
rootContainers: [...this.rootContainers]
|
|
5276
|
-
};
|
|
5277
|
-
}
|
|
5278
|
-
};
|
|
5279
|
-
|
|
5280
|
-
// src/utils/tracking.ts
|
|
5281
|
-
var import_events = require("@elementor/events");
|
|
5282
|
-
var trackCanvasEvent = (data) => {
|
|
5283
|
-
(0, import_events.trackEvent)(data);
|
|
5284
|
-
};
|
|
5285
|
-
|
|
5286
|
-
// src/mcp/utils/get-composition-target-container.ts
|
|
5287
|
-
var import_editor_documents2 = require("@elementor/editor-documents");
|
|
5288
|
-
function getCompositionTargetContainer(documentContainer, documentType) {
|
|
5289
|
-
const firstChild = documentContainer.children?.[0];
|
|
5290
|
-
if (documentType === import_editor_documents2.COMPONENT_DOCUMENT_TYPE && firstChild) {
|
|
5291
|
-
return firstChild;
|
|
5292
|
-
}
|
|
5293
|
-
return documentContainer;
|
|
5294
|
-
}
|
|
5295
|
-
|
|
5296
|
-
// src/mcp/tools/build-composition/prompt.ts
|
|
5297
|
-
var import_editor_mcp2 = require("@elementor/editor-mcp");
|
|
5298
|
-
var BUILD_COMPOSITIONS_GUIDE_URI = "elementor://canvas/tools/build-compositions-guide";
|
|
5299
|
-
var generatePrompt = () => {
|
|
5300
|
-
const buildCompositionsToolPrompt = (0, import_editor_mcp2.toolPrompts)("build-compositions");
|
|
5301
|
-
buildCompositionsToolPrompt.description(`
|
|
5302
|
-
# RESOURCES (Read before use)
|
|
5303
|
-
- [elementor://global-classes] - Check FIRST for reusable classes
|
|
5304
|
-
- [elementor://global-variables] - ONLY use variables defined here
|
|
5305
|
-
- [${AVAILABLE_WIDGETS_URI}/v4]
|
|
5306
|
-
|
|
5307
|
-
# TOOL SUPPORT
|
|
5308
|
-
This tool support v4 elements only
|
|
5309
|
-
|
|
5310
|
-
# WORKFLOW
|
|
5311
|
-
1. Check/create global classes via "manage-global-classes" tool
|
|
5312
|
-
2. Build composition (THIS TOOL) - minimal inline styles
|
|
5313
|
-
3. Apply classes via "apply-global-class" tool
|
|
5314
|
-
|
|
5315
|
-
# XML STRUCTURE
|
|
5316
|
-
- Use widget tags: \`<e-button configuration-id="btn1"></e-button>\`
|
|
5317
|
-
- Containers: "e-flexbox", "e-div-block", "e-tabs"
|
|
5318
|
-
- Every element needs unique "configuration-id"
|
|
5319
|
-
- No attributes, classes, IDs, or text nodes in XML
|
|
5320
|
-
|
|
5321
|
-
## NESTED ELEMENTS
|
|
5322
|
-
Some elements have internal tree structures (nesting). When using these elements, you MUST build the FULL tree in XML.
|
|
5323
|
-
- Check \`llm_guidance.nesting\` in widget schemas for structure requirements
|
|
5324
|
-
- \`llm_guidance.required_direct_children\` lists element types that must appear as direct child tags in XML (from widget defaults)
|
|
5325
|
-
- \`allowed_child_types\` lists which element types can be nested inside
|
|
5326
|
-
- \`allowed_parents\` lists which element types this element can be placed inside
|
|
5327
|
-
|
|
5328
|
-
# CONFIGURATION
|
|
5329
|
-
- Map configuration-id \u2192 elementConfig (props) + style (raw CSS declarations)
|
|
5330
|
-
- elementConfig PropValues require \`$$type\` matching schema
|
|
5331
|
-
- style is raw CSS (property \u2192 value strings); the server converts it to native styles and stores any unconvertible declarations as the element custom CSS
|
|
5332
|
-
- NO LINKS in configuration
|
|
5333
|
-
- Retry on errors up to 10x
|
|
5334
|
-
- Check \`llm_guidance.default_settings\` in widget schemas \u2014 omit only keys listed there from elementConfig unless the user explicitly asks to change them
|
|
5335
|
-
|
|
5336
|
-
# DYNAMIC TAGS
|
|
5337
|
-
- A value can be made dynamic wherever its schema exposes a \`"$$type": "dynamic"\` variant. This may be the property root OR a NESTED field (e.g. an image's \`src\`, not the whole \`image\`).
|
|
5338
|
-
- Put the dynamic object EXACTLY at that node, in place of the static variant. The variant's \`name\` lists the allowed tags; read [${DYNAMIC_TAGS_URI}] for each tag's settings schema.
|
|
5339
|
-
- Provide at that node: \`{ "$$type": "dynamic", "value": { "name": "<allowed tag>", "settings": { ... } } }\`
|
|
5340
|
-
- Example (image): \`{ "$$type": "image", "value": { "src": { "$$type": "dynamic", "value": { "name": "<image tag>", "settings": { ... } } } } }\`
|
|
5341
|
-
- Do NOT send \`group\` (it is resolved automatically). Populate \`settings\` strictly per the tag's schema; use \`{}\` only when it has none.
|
|
5342
|
-
|
|
5343
|
-
Note about configuration ids: These names are visible to the end-user, make sure they make sense, related and relevant.
|
|
5344
|
-
|
|
5345
|
-
# DESIGN PHILOSOPHY: CONTEXT-DRIVEN CREATIVITY
|
|
5346
|
-
|
|
5347
|
-
**Use the user's context aggressively.** Business type, brand personality, target audience, and purpose should drive every design decision. A law firm needs gravitas; a children's app needs playfulness. Don't default to generic.
|
|
5348
|
-
|
|
5349
|
-
## SIZING: DEFAULT IS NO SIZE (CRITICAL)
|
|
5350
|
-
|
|
5351
|
-
**DO NOT specify height or width unless you have a specific visual reason.**
|
|
5352
|
-
|
|
5353
|
-
Flexbox and CSS already handle sizing automatically:
|
|
5354
|
-
- Containers grow to fit their content
|
|
5355
|
-
- Flex children distribute space via flex properties, not width/height
|
|
5356
|
-
- Text elements size to their content
|
|
5357
|
-
|
|
5358
|
-
WHEN TO SPECIFY SIZE:
|
|
5359
|
-
- min-height on ROOT section for viewport-spanning hero (use min-height, NOT height)
|
|
5360
|
-
- max-width for contained content areas (e.g., max-width: 60rem)
|
|
5361
|
-
- Explicit aspect ratios for media containers
|
|
5362
|
-
|
|
5363
|
-
NEVER SPECIFY:
|
|
5364
|
-
- height on nested containers (causes overflow)
|
|
5365
|
-
- width on flex children (use flex-basis or gap instead)
|
|
5366
|
-
- 100vh on anything except root-level sections
|
|
5367
|
-
- Any size "just to be safe" - if unsure, OMIT IT
|
|
5368
|
-
|
|
5369
|
-
vh units are VIEWPORT-relative. Nested 100vh inside 100vh = 200vh overflow.
|
|
5370
|
-
|
|
5371
|
-
GOOD: \`<e-flexbox>content naturally sizes</e-flexbox>\`
|
|
5372
|
-
BAD: \`<e-flexbox style="height:100vh"><e-div-block style="height:100vh">overflow</e-div-block></e-flexbox>\`
|
|
5373
|
-
|
|
5374
|
-
## Layout Variety (Break the Template)
|
|
5375
|
-
- AVOID: Full-width 100vh hero \u2192 three columns \u2192 testimonials \u2192 CTA (every AI does this)
|
|
5376
|
-
- VARY heights: Use auto-height sections with generous padding (6rem+). Let content breathe
|
|
5377
|
-
- VARY widths: Not everything spans full width. Use contained sections (max-width: 960px) mixed with edge-to-edge
|
|
5378
|
-
- ASYMMETRIC grids: 2:1, 1:3, offset layouts. Avoid equal column widths
|
|
5379
|
-
- Negative space as design element: Large margins create focus and sophistication
|
|
5380
|
-
- Break alignment intentionally: Offset headings, overlapping elements, broken grids
|
|
5381
|
-
|
|
5382
|
-
## Visual Depth & Effects
|
|
5383
|
-
- Layer elements: Overlapping cards, text over images, floating elements
|
|
5384
|
-
- Subtle shadows with color tint (not pure black): \`box-shadow: 0 20px 60px rgba(<brand-color-here>, 0.15)\`
|
|
5385
|
-
- Gradient overlays on images for text readability
|
|
5386
|
-
- Border radius variation: Mix sharp (0) and soft (1rem+) corners purposefully
|
|
5387
|
-
- Backdrop blur for glassmorphism where appropriate
|
|
5388
|
-
- Micro-interactions via CSS: hover transforms, transitions (0.3s ease)
|
|
5389
|
-
|
|
5390
|
-
## Typography with Character
|
|
5391
|
-
- Display fonts for headlines (from user's brand or contextually appropriate)
|
|
5392
|
-
- Size contrast: 4rem+ headlines vs 1rem body. Make hierarchy unmistakable
|
|
5393
|
-
- Letter-spacing: Tight for large headlines (-0.02em), loose for small caps (0.1em)
|
|
5394
|
-
- Line-height: Tight for headlines (1.1), generous for body (1.6-1.8)
|
|
5395
|
-
- Text decoration: Underlines, highlights, gradient text for emphasis
|
|
5396
|
-
|
|
5397
|
-
## Color with Purpose
|
|
5398
|
-
- Extract palette from user context (brand colors, industry norms, mood)
|
|
5399
|
-
- 60-30-10 rule: dominant, secondary, accent
|
|
5400
|
-
- Tinted neutrals over pure grays: warm (#faf8f5, #2d2a26) or cool (#f5f7fa, #1e2430)
|
|
5401
|
-
- Color blocking: Large colored sections create visual rhythm
|
|
5402
|
-
- Gradient directions: Diagonal (135deg, 225deg) feel more dynamic than vertical
|
|
5403
|
-
|
|
5404
|
-
## Spacing Strategy
|
|
5405
|
-
- Section padding: 6rem-10rem vertical, creating breathing room
|
|
5406
|
-
- Rhythm variation: Tight groups (2rem) with generous gaps between (6rem)
|
|
5407
|
-
- Use rem/em exclusively for responsive scaling
|
|
5408
|
-
- Generous padding on CTAs: min 1rem 2.5rem
|
|
5409
|
-
|
|
5410
|
-
# HARD CONSTRAINTS
|
|
5411
|
-
- Variables ONLY from [elementor://global-variables] (others throw errors)
|
|
5412
|
-
- Avoid SVG widgets unless assets are pre-uploaded
|
|
5413
|
-
- Check \`llm_guidance\` in widget schemas (\`default_styles\`, nesting, required children)
|
|
5414
|
-
|
|
5415
|
-
# PARAMETERS
|
|
5416
|
-
- **xmlStructure**: Valid XML with configuration-id attributes
|
|
5417
|
-
- **elementConfig**: configuration-id \u2192 widget PropValues
|
|
5418
|
-
- **style**: configuration-id \u2192 raw CSS declarations (property \u2192 value strings; no selectors)
|
|
5419
|
-
`);
|
|
5420
|
-
buildCompositionsToolPrompt.example(`
|
|
5421
|
-
Section with heading + button (NO explicit heights - content sizes naturally):
|
|
5422
|
-
{
|
|
5423
|
-
xmlStructure: "<e-flexbox configuration-id="Main Section"><e-heading configuration-id="Section Title"></e-heading><e-button configuration-id="Call to Action"></e-button></e-flexbox>",
|
|
5424
|
-
elementConfig: {
|
|
5425
|
-
"section1": { "tag": { "$$type": "string", "value": "section" } }
|
|
5426
|
-
},
|
|
5427
|
-
style: {
|
|
5428
|
-
"Section Title": {
|
|
5429
|
-
"padding": "6rem 4rem",
|
|
5430
|
-
"background": "linear-gradient(135deg, #faf8f5 0%, #f0ebe4 100%)",
|
|
5431
|
-
"font-size": "3.5rem",
|
|
5432
|
-
"color": "#2d2a26"
|
|
5433
|
-
}
|
|
5434
|
-
}
|
|
5435
|
-
}
|
|
5436
|
-
Note: No height/width specified on any element - flexbox handles layout automatically.
|
|
5437
|
-
`);
|
|
5438
|
-
buildCompositionsToolPrompt.parameter(
|
|
5439
|
-
"xmlStructure",
|
|
5440
|
-
`Valid XML structure with custom elementor tags and configuration-id attributes.`
|
|
5441
|
-
);
|
|
5442
|
-
buildCompositionsToolPrompt.parameter("elementConfig", `Record mapping configuration IDs to widget PropValues.`);
|
|
5443
|
-
buildCompositionsToolPrompt.parameter(
|
|
5444
|
-
"style",
|
|
5445
|
-
`Record mapping configuration IDs to raw CSS declarations (property \u2192 value strings).`
|
|
5446
|
-
);
|
|
5447
|
-
buildCompositionsToolPrompt.instruction(
|
|
5448
|
-
`Element IDs in the returned XML represent actual widgets. Use these IDs for subsequent styling or configuration changes.`
|
|
5449
|
-
);
|
|
5450
|
-
return buildCompositionsToolPrompt.prompt();
|
|
5451
|
-
};
|
|
5452
|
-
|
|
5453
|
-
// src/mcp/tools/build-composition/schema.ts
|
|
5454
|
-
var import_schema = require("@elementor/schema");
|
|
5455
|
-
var inputSchema = {
|
|
5456
|
-
xmlStructure: import_schema.z.string().describe("The XML structure representing the composition to be built"),
|
|
5457
|
-
elementConfig: import_schema.z.record(
|
|
5458
|
-
import_schema.z.string().describe("The configuration id"),
|
|
5459
|
-
import_schema.z.record(
|
|
5460
|
-
import_schema.z.string().describe("property name"),
|
|
5461
|
-
import_schema.z.any().describe(`The PropValue for the property, refer to ${WIDGET_SCHEMA_URI}`)
|
|
5462
|
-
)
|
|
5463
|
-
).describe("A record mapping element IDs to their configuration objects. REQUIRED"),
|
|
5464
|
-
style: import_schema.z.record(
|
|
5465
|
-
import_schema.z.string().describe("The configuration id"),
|
|
5466
|
-
import_schema.z.record(
|
|
5467
|
-
import_schema.z.string().describe('A CSS property name, e.g. "color", "padding".'),
|
|
5468
|
-
import_schema.z.string().describe('A CSS value, e.g. "6rem 4rem", "#2d2a26".')
|
|
5469
|
-
)
|
|
5470
|
-
).describe(
|
|
5471
|
-
"A record mapping element configuration IDs to their raw CSS declarations (property\u2192value). Converted to native styles server-side; any declaration that cannot be converted is stored as the element custom CSS."
|
|
5472
|
-
).default({})
|
|
5473
|
-
};
|
|
5474
|
-
var outputSchema = {
|
|
5475
|
-
errors: import_schema.z.string().describe("Error message if the composition building failed").optional(),
|
|
5476
|
-
xmlStructure: import_schema.z.string().describe(
|
|
5477
|
-
"The built XML structure as a string. Must use this XML after completion of building the composition, it contains real IDs."
|
|
5478
|
-
).optional(),
|
|
5479
|
-
llm_instructions: import_schema.z.string().describe("Instructions what to do next, Important to follow these instructions!").optional()
|
|
5480
|
-
};
|
|
5481
|
-
|
|
5482
|
-
// src/mcp/tools/build-composition/xml-leaf-wrapper.ts
|
|
5483
|
-
var DIV_BLOCK_TAG = "e-div-block";
|
|
5484
|
-
var ZERO_SPACING = {
|
|
5485
|
-
$$type: "size",
|
|
5486
|
-
value: {
|
|
5487
|
-
size: {
|
|
5488
|
-
$$type: "number",
|
|
5489
|
-
value: 0
|
|
5490
|
-
},
|
|
5491
|
-
unit: {
|
|
5492
|
-
$$type: "string",
|
|
5493
|
-
value: "px"
|
|
5494
|
-
}
|
|
5495
|
-
}
|
|
5496
|
-
};
|
|
5497
|
-
function adaptLeafRootParams(params) {
|
|
5498
|
-
const doc = new DOMParser().parseFromString(params.xmlStructure, "application/xml");
|
|
5499
|
-
const rootElement = doc.documentElement;
|
|
5500
|
-
if (!isLeafWidget(rootElement.tagName, params.widgetsCache)) {
|
|
5501
|
-
return params;
|
|
5502
|
-
}
|
|
5503
|
-
const wrapperConfigId = getDivBlockWrapperConfigId(params.widgetsCache);
|
|
5504
|
-
return {
|
|
5505
|
-
...params,
|
|
5506
|
-
xmlStructure: serializeWrapped(doc, rootElement, wrapperConfigId),
|
|
5507
|
-
stylesConfig: {
|
|
5508
|
-
...params.stylesConfig,
|
|
5509
|
-
[wrapperConfigId]: {
|
|
5510
|
-
margin: ZERO_SPACING,
|
|
5511
|
-
padding: ZERO_SPACING,
|
|
5512
|
-
...params.stylesConfig[wrapperConfigId]
|
|
5513
|
-
}
|
|
5514
|
-
}
|
|
5515
|
-
};
|
|
5516
|
-
}
|
|
5517
|
-
function getDivBlockWrapperConfigId(widgetsCache) {
|
|
5518
|
-
return widgetsCache[DIV_BLOCK_TAG]?.title ?? DIV_BLOCK_TAG;
|
|
5519
|
-
}
|
|
5520
|
-
function isLeafWidget(tagName, widgetsCache) {
|
|
5521
|
-
return widgetsCache[tagName]?.elType === "widget";
|
|
5522
|
-
}
|
|
5523
|
-
function serializeWrapped(doc, rootElement, wrapperConfigId) {
|
|
5524
|
-
const wrapper = doc.createElement(DIV_BLOCK_TAG);
|
|
5525
|
-
wrapper.setAttribute("configuration-id", wrapperConfigId);
|
|
5526
|
-
wrapper.appendChild(rootElement.cloneNode(true));
|
|
5527
|
-
const wrappedDoc = new DOMParser().parseFromString(`<${DIV_BLOCK_TAG} />`, "application/xml");
|
|
5528
|
-
wrappedDoc.replaceChild(wrapper, wrappedDoc.documentElement);
|
|
5529
|
-
return new XMLSerializer().serializeToString(wrappedDoc);
|
|
5530
|
-
}
|
|
5531
|
-
|
|
5532
|
-
// src/mcp/tools/build-composition/tool.ts
|
|
5533
|
-
var ELEMENT_ADDED_EVENT = "elementor/canvas/element-added";
|
|
5534
|
-
var initBuildCompositionsTool = (reg) => {
|
|
5535
|
-
const { addTool, resource } = reg;
|
|
5536
|
-
resource(
|
|
5537
|
-
"build-compositions-guide",
|
|
5538
|
-
BUILD_COMPOSITIONS_GUIDE_URI,
|
|
5539
|
-
{
|
|
5540
|
-
title: "Build Compositions Guide",
|
|
5541
|
-
description: "Detailed guide for using the build-compositions tool",
|
|
5542
|
-
mimeType: "text/plain"
|
|
5543
|
-
},
|
|
5544
|
-
async (uri) => ({
|
|
5545
|
-
contents: [{ uri: uri.href, mimeType: "text/plain", text: generatePrompt() }]
|
|
5546
|
-
})
|
|
5547
|
-
);
|
|
5548
|
-
addTool({
|
|
5549
|
-
name: "build-compositions",
|
|
5550
|
-
description: "Build V4 element compositions on the Elementor canvas. Read the guide resource before use.",
|
|
5551
|
-
schema: inputSchema,
|
|
5552
|
-
requiredResources: [
|
|
5553
|
-
{ description: "Build compositions guide", uri: BUILD_COMPOSITIONS_GUIDE_URI },
|
|
5554
|
-
{ description: "Widgets schema", uri: WIDGET_SCHEMA_URI },
|
|
5555
|
-
{ description: "Global Classes", uri: "elementor://global-classes" },
|
|
5556
|
-
{ description: "Global Variables", uri: "elementor://global-variables" },
|
|
5557
|
-
{ description: "Styles best practices", uri: BEST_PRACTICES_URI },
|
|
5558
|
-
{ description: "Available widgets for this tool", uri: AVAILABLE_WIDGETS_URI_V4 },
|
|
5559
|
-
{ description: "Dynamic tags catalog", uri: DYNAMIC_TAGS_URI }
|
|
5560
|
-
],
|
|
5561
|
-
outputSchema,
|
|
5562
|
-
handler: async (rawParams) => {
|
|
5563
|
-
assertCompositionXmlUsesV4WidgetsOnly(rawParams.xmlStructure);
|
|
5564
|
-
const { stylesConfig: convertedStyles, customCSS } = await convertCompositionStyles(rawParams.style);
|
|
5565
|
-
const { xmlStructure, elementConfig, stylesConfig } = adaptLeafRootParams({
|
|
5566
|
-
...rawParams,
|
|
5567
|
-
stylesConfig: convertedStyles,
|
|
5568
|
-
widgetsCache: (0, import_editor_elements16.getWidgetsCache)() ?? {}
|
|
5569
|
-
});
|
|
5570
|
-
let generatedXML = "";
|
|
5571
|
-
const errors = [];
|
|
5572
|
-
const rootContainers = [];
|
|
5573
|
-
const documentContainer = (0, import_editor_elements16.getContainer)("document");
|
|
5574
|
-
const currentDocument = (0, import_editor_documents3.getCurrentDocument)();
|
|
5575
|
-
const targetContainer = getCompositionTargetContainer(documentContainer, currentDocument?.type.value);
|
|
5576
|
-
try {
|
|
5577
|
-
const compositionBuilder = CompositionBuilder.fromXMLString(xmlStructure, {
|
|
5578
|
-
createElement: import_editor_elements16.createElement,
|
|
5579
|
-
deleteElement: import_editor_elements16.deleteElement,
|
|
5580
|
-
getWidgetsCache: import_editor_elements16.getWidgetsCache
|
|
5581
|
-
});
|
|
5582
|
-
compositionBuilder.setElementConfig(elementConfig);
|
|
5583
|
-
compositionBuilder.setStylesConfig(stylesConfig);
|
|
5584
|
-
compositionBuilder.setCustomCSS(customCSS);
|
|
5585
|
-
const {
|
|
5586
|
-
configErrors,
|
|
5587
|
-
formErrors,
|
|
5588
|
-
rootContainers: generatedRootContainers
|
|
5589
|
-
} = await compositionBuilder.build(targetContainer);
|
|
5590
|
-
rootContainers.push(...generatedRootContainers);
|
|
5591
|
-
generatedXML = new XMLSerializer().serializeToString(compositionBuilder.getXML());
|
|
5592
|
-
rootContainers.forEach((container) => {
|
|
5593
|
-
const elementData = container.model?.toJSON();
|
|
5594
|
-
if (elementData) {
|
|
5595
|
-
onElementAdded(elementData);
|
|
5596
|
-
}
|
|
5597
|
-
});
|
|
5598
|
-
Object.values(stylesConfig).forEach((styleValue) => {
|
|
5599
|
-
(0, import_editor_mcp3.dispatchMcpStylesAppliedEvent)({ styleValue });
|
|
5600
|
-
});
|
|
5601
|
-
if (configErrors.length) {
|
|
5602
|
-
errors.push(...configErrors.map((msg) => new Error(msg)));
|
|
5603
|
-
}
|
|
5604
|
-
if (formErrors.length) {
|
|
5605
|
-
errors.push(...formErrors.map((msg) => new Error(msg)));
|
|
5606
|
-
}
|
|
5607
|
-
} catch (error) {
|
|
5608
|
-
errors.push(error);
|
|
5609
|
-
}
|
|
5610
|
-
if (errors.length) {
|
|
5611
|
-
rootContainers.forEach((rootContainer) => {
|
|
5612
|
-
(0, import_editor_elements16.deleteElement)({
|
|
5613
|
-
container: rootContainer,
|
|
5614
|
-
options: { useHistory: false }
|
|
5615
|
-
});
|
|
5616
|
-
});
|
|
5617
|
-
const errorMessages = errors.map((e) => {
|
|
5618
|
-
if (typeof e === "string") {
|
|
5619
|
-
return e;
|
|
5620
|
-
}
|
|
5621
|
-
if (e instanceof Error) {
|
|
5622
|
-
return e.message || String(e);
|
|
5623
|
-
}
|
|
5624
|
-
if (typeof e === "object" && e !== null) {
|
|
5625
|
-
return JSON.stringify(e);
|
|
5626
|
-
}
|
|
5627
|
-
return String(e);
|
|
5628
|
-
}).filter(
|
|
5629
|
-
(msg) => msg && msg.trim() !== "" && msg !== "{}" && msg !== "null" && msg !== "undefined"
|
|
5630
|
-
);
|
|
5631
|
-
if (errorMessages.length === 0) {
|
|
5632
|
-
throw new Error(
|
|
5633
|
-
"Failed to build composition: Unknown error occurred. No error details available."
|
|
5634
|
-
);
|
|
5635
|
-
}
|
|
5636
|
-
const errorText = `Failed to build composition with the following errors:
|
|
5637
|
-
|
|
5638
|
-
${errorMessages.join(
|
|
5639
|
-
"\n\n"
|
|
5640
|
-
)}`;
|
|
5641
|
-
throw new Error(errorText);
|
|
5642
|
-
}
|
|
5643
|
-
return {
|
|
5644
|
-
xmlStructure: generatedXML,
|
|
5645
|
-
errors: errors?.length ? errors.map((e) => typeof e === "string" ? e : e.message).join("\n\n") : void 0,
|
|
5646
|
-
llm_instructions: `The composition was built successfully with element IDs embedded in the XML.
|
|
5647
|
-
|
|
5648
|
-
**CRITICAL NEXT STEPS** (Follow in order):
|
|
5649
|
-
1. **Apply Global Classes**: Use "apply-global-class" tool to apply the global classes you created BEFORE building this composition
|
|
5650
|
-
- Check the created element IDs in the returned XML
|
|
5651
|
-
- Apply semantic classes (heading-primary, button-cta, etc.) to appropriate elements
|
|
5652
|
-
|
|
5653
|
-
2. **Fine-tune if needed**: Use "configure-element" tool only for element-specific adjustments that don't warrant global classes
|
|
5654
|
-
|
|
5655
|
-
Remember: Global classes ensure design consistency and reusability. Don't skip applying them!
|
|
5656
|
-
`
|
|
5657
|
-
};
|
|
5658
|
-
}
|
|
5659
|
-
});
|
|
4847
|
+
(0, import_editor_v1_adapters20.__privateRunCommandSync)("document/save/set-is-modified", { status: true }, { internal: true });
|
|
5660
4848
|
};
|
|
5661
|
-
async function convertCompositionStyles(style) {
|
|
5662
|
-
const stylesConfig = {};
|
|
5663
|
-
const customCSS = {};
|
|
5664
|
-
if (!style || Object.keys(style).length === 0) {
|
|
5665
|
-
return { stylesConfig, customCSS };
|
|
5666
|
-
}
|
|
5667
|
-
const results = await convertStyleBlocksToAtomic(style);
|
|
5668
|
-
for (const [configId, { props, customCss }] of Object.entries(results)) {
|
|
5669
|
-
stylesConfig[configId] = props;
|
|
5670
|
-
if (customCss) {
|
|
5671
|
-
customCSS[configId] = customCss;
|
|
5672
|
-
}
|
|
5673
|
-
}
|
|
5674
|
-
return { stylesConfig, customCSS };
|
|
5675
|
-
}
|
|
5676
|
-
function assertCompositionXmlUsesV4WidgetsOnly(xmlStructure) {
|
|
5677
|
-
const doc = new DOMParser().parseFromString(xmlStructure, "application/xml");
|
|
5678
|
-
if (doc.querySelector("parsererror")) {
|
|
5679
|
-
throw new Error("Failed to parse XML string: " + doc);
|
|
5680
|
-
}
|
|
5681
|
-
const widgetsCache = (0, import_editor_elements16.getWidgetsCache)() ?? {};
|
|
5682
|
-
for (const node of doc.querySelectorAll("*")) {
|
|
5683
|
-
const type = node.tagName;
|
|
5684
|
-
const widgetData = widgetsCache[type];
|
|
5685
|
-
if (!widgetData) {
|
|
5686
|
-
continue;
|
|
5687
|
-
}
|
|
5688
|
-
if (widgetData.elType !== "widget") {
|
|
5689
|
-
continue;
|
|
5690
|
-
}
|
|
5691
|
-
if (!isWidgetAvailableForLLM(widgetData) || !widgetData.atomic_props_schema) {
|
|
5692
|
-
throw new Error(`This tool does not support element type: ${type}`);
|
|
5693
|
-
}
|
|
5694
|
-
}
|
|
5695
|
-
}
|
|
5696
|
-
function onElementAdded(element) {
|
|
5697
|
-
const elType = element.elType ?? "";
|
|
5698
|
-
const widgetType = element.widgetType ?? "";
|
|
5699
|
-
const elementName = elType === "widget" ? widgetType : elType;
|
|
5700
|
-
trackCanvasEvent({
|
|
5701
|
-
eventName: "add_element",
|
|
5702
|
-
executed_by: "mcp_tool",
|
|
5703
|
-
element_name: elementName,
|
|
5704
|
-
element_type: elType,
|
|
5705
|
-
widget_type: widgetType
|
|
5706
|
-
});
|
|
5707
|
-
const event = {
|
|
5708
|
-
element,
|
|
5709
|
-
executedBy: "mcp_tool"
|
|
5710
|
-
};
|
|
5711
|
-
window.dispatchEvent(new CustomEvent(ELEMENT_ADDED_EVENT, { detail: event }));
|
|
5712
|
-
if (element.elements?.length) {
|
|
5713
|
-
element.elements?.forEach((childElement) => {
|
|
5714
|
-
onElementAdded(childElement);
|
|
5715
|
-
});
|
|
5716
|
-
}
|
|
5717
|
-
}
|
|
5718
|
-
|
|
5719
|
-
// src/mcp/tools/configure-element/tool.ts
|
|
5720
|
-
var import_editor_elements17 = require("@elementor/editor-elements");
|
|
5721
|
-
var import_editor_mcp5 = require("@elementor/editor-mcp");
|
|
5722
|
-
var import_editor_props9 = require("@elementor/editor-props");
|
|
5723
4849
|
|
|
5724
4850
|
// src/mcp/tools/configure-element/prompt.ts
|
|
5725
|
-
var
|
|
4851
|
+
var import_editor_mcp2 = require("@elementor/editor-mcp");
|
|
5726
4852
|
var CONFIGURE_ELEMENT_GUIDE_URI = "elementor://canvas/tools/configure-element-guide";
|
|
5727
|
-
var
|
|
5728
|
-
const configureElementToolPrompt = (0,
|
|
4853
|
+
var generatePrompt = () => {
|
|
4854
|
+
const configureElementToolPrompt = (0, import_editor_mcp2.toolPrompts)("configure-element");
|
|
5729
4855
|
configureElementToolPrompt.description(`
|
|
5730
4856
|
Configure an existing element on the page.
|
|
5731
4857
|
|
|
@@ -5833,29 +4959,29 @@ NO Advanced tab. Never mention Advanced tab.
|
|
|
5833
4959
|
`);
|
|
5834
4960
|
return configureElementToolPrompt.prompt();
|
|
5835
4961
|
};
|
|
5836
|
-
var CONFIGURE_ELEMENT_GUIDE_TEXT =
|
|
4962
|
+
var CONFIGURE_ELEMENT_GUIDE_TEXT = generatePrompt();
|
|
5837
4963
|
|
|
5838
4964
|
// src/mcp/tools/configure-element/schema.ts
|
|
5839
|
-
var
|
|
5840
|
-
var
|
|
5841
|
-
propertiesToChange:
|
|
5842
|
-
|
|
5843
|
-
|
|
5844
|
-
|
|
4965
|
+
var import_schema2 = require("@elementor/schema");
|
|
4966
|
+
var inputSchema = {
|
|
4967
|
+
propertiesToChange: import_schema2.z.record(
|
|
4968
|
+
import_schema2.z.string().describe("The property name."),
|
|
4969
|
+
import_schema2.z.any().describe(`PropValue, refer to [${WIDGET_SCHEMA_URI}] by correct type, as appears in elementType`),
|
|
4970
|
+
import_schema2.z.any()
|
|
5845
4971
|
).describe("An object record containing property names and their new values to be set on the element"),
|
|
5846
|
-
style:
|
|
5847
|
-
|
|
5848
|
-
|
|
4972
|
+
style: import_schema2.z.record(
|
|
4973
|
+
import_schema2.z.string().describe('A CSS property name, e.g. "color", "margin-top".'),
|
|
4974
|
+
import_schema2.z.string().nullable().describe(
|
|
5849
4975
|
'A CSS value, e.g. "red", "10px", "1px solid #000". Use null to reset the property to its default.'
|
|
5850
4976
|
)
|
|
5851
4977
|
).describe(
|
|
5852
4978
|
"Raw CSS declarations as a flat property\u2192value map. Converted to native styles server-side; any declaration that cannot be converted is stored as the element custom CSS. A null value resets that property to its default."
|
|
5853
4979
|
).default({}),
|
|
5854
|
-
elementType:
|
|
5855
|
-
elementId:
|
|
4980
|
+
elementType: import_schema2.z.string().describe("The type of the element to retrieve the schema"),
|
|
4981
|
+
elementId: import_schema2.z.string().describe("The unique id of the element to configure")
|
|
5856
4982
|
};
|
|
5857
|
-
var
|
|
5858
|
-
success:
|
|
4983
|
+
var outputSchema = {
|
|
4984
|
+
success: import_schema2.z.boolean().describe(
|
|
5859
4985
|
"Whether the configuration change was successful, only if propertyName and propertyValue are provided"
|
|
5860
4986
|
)
|
|
5861
4987
|
};
|
|
@@ -5872,27 +4998,27 @@ var initConfigureElementTool = (reg) => {
|
|
|
5872
4998
|
mimeType: "text/plain"
|
|
5873
4999
|
},
|
|
5874
5000
|
async (uri) => ({
|
|
5875
|
-
contents: [{ uri: uri.href, mimeType: "text/plain", text:
|
|
5001
|
+
contents: [{ uri: uri.href, mimeType: "text/plain", text: generatePrompt() }]
|
|
5876
5002
|
})
|
|
5877
5003
|
);
|
|
5878
5004
|
addTool({
|
|
5879
5005
|
name: "configure-element",
|
|
5880
5006
|
description: "Configure an existing V4 element's properties and styles. Read the guide resource before use.",
|
|
5881
|
-
schema:
|
|
5882
|
-
outputSchema
|
|
5007
|
+
schema: inputSchema,
|
|
5008
|
+
outputSchema,
|
|
5883
5009
|
requiredResources: [
|
|
5884
5010
|
{ description: "Widgets schema", uri: WIDGET_SCHEMA_URI },
|
|
5885
5011
|
{ description: "Configure element guide", uri: CONFIGURE_ELEMENT_GUIDE_URI },
|
|
5886
5012
|
{ description: "Dynamic tags catalog", uri: DYNAMIC_TAGS_URI }
|
|
5887
5013
|
],
|
|
5888
5014
|
handler: async ({ elementId, propertiesToChange, elementType, style }) => {
|
|
5889
|
-
const widgetData = (0,
|
|
5015
|
+
const widgetData = (0, import_editor_elements14.getWidgetsCache)()?.[elementType];
|
|
5890
5016
|
if (!widgetData) {
|
|
5891
5017
|
throw new Error(
|
|
5892
5018
|
`Unknown element type: ${elementType}. Check the available-widgets resource for valid types.`
|
|
5893
5019
|
);
|
|
5894
5020
|
}
|
|
5895
|
-
const container = (0,
|
|
5021
|
+
const container = (0, import_editor_elements14.getContainer)(elementId);
|
|
5896
5022
|
if (!container) {
|
|
5897
5023
|
throw new Error(`Element with id ${elementId} not found`);
|
|
5898
5024
|
}
|
|
@@ -5908,7 +5034,7 @@ var initConfigureElementTool = (reg) => {
|
|
|
5908
5034
|
const propertiesToUpdate = resolveCanonicalPropKeys(elementType, propertiesToChange);
|
|
5909
5035
|
const toUpdate = Object.entries(propertiesToUpdate);
|
|
5910
5036
|
for (const [propertyName, propertyValue] of toUpdate) {
|
|
5911
|
-
if (!
|
|
5037
|
+
if (!import_editor_props7.Schema.isPropKeyConfigurable(propertyName)) {
|
|
5912
5038
|
throw new Error(`Not allowed to update ${propertyName}`);
|
|
5913
5039
|
}
|
|
5914
5040
|
try {
|
|
@@ -5957,7 +5083,7 @@ async function applyStyleFromCss(opts) {
|
|
|
5957
5083
|
propertyValue: styleValue,
|
|
5958
5084
|
customCssWriteMode: "merge-with-stored"
|
|
5959
5085
|
});
|
|
5960
|
-
(0,
|
|
5086
|
+
(0, import_editor_mcp3.dispatchMcpStylesAppliedEvent)({ styleValue });
|
|
5961
5087
|
} catch (error) {
|
|
5962
5088
|
throw new Error(
|
|
5963
5089
|
createUpdateErrorMessage({
|
|
@@ -5984,20 +5110,20 @@ Provide styling as raw CSS via the "style" parameter (a flat map of CSS property
|
|
|
5984
5110
|
}
|
|
5985
5111
|
|
|
5986
5112
|
// src/mcp/tools/get-element-config/tool.ts
|
|
5987
|
-
var
|
|
5988
|
-
var
|
|
5989
|
-
var
|
|
5113
|
+
var import_editor_elements15 = require("@elementor/editor-elements");
|
|
5114
|
+
var import_editor_props8 = require("@elementor/editor-props");
|
|
5115
|
+
var import_schema4 = require("@elementor/schema");
|
|
5990
5116
|
var schema = {
|
|
5991
|
-
elementId:
|
|
5117
|
+
elementId: import_schema4.z.string()
|
|
5992
5118
|
};
|
|
5993
|
-
var
|
|
5994
|
-
properties:
|
|
5995
|
-
style:
|
|
5996
|
-
childElements:
|
|
5997
|
-
|
|
5998
|
-
id:
|
|
5999
|
-
elementType:
|
|
6000
|
-
childElements:
|
|
5119
|
+
var outputSchema2 = {
|
|
5120
|
+
properties: import_schema4.z.record(import_schema4.z.string(), import_schema4.z.any()).describe("A record mapping PropTypes to their corresponding PropValues"),
|
|
5121
|
+
style: import_schema4.z.record(import_schema4.z.string(), import_schema4.z.any()).describe("A record mapping StyleSchema properties to their corresponding PropValues"),
|
|
5122
|
+
childElements: import_schema4.z.array(
|
|
5123
|
+
import_schema4.z.object({
|
|
5124
|
+
id: import_schema4.z.string(),
|
|
5125
|
+
elementType: import_schema4.z.string(),
|
|
5126
|
+
childElements: import_schema4.z.array(import_schema4.z.any()).describe("An array of child element IDs, when applicable, same structure recursively")
|
|
6001
5127
|
})
|
|
6002
5128
|
).describe("An array of child element IDs, when applicable, with recursive structure")
|
|
6003
5129
|
};
|
|
@@ -6017,14 +5143,14 @@ var initGetElementConfigTool = (reg) => {
|
|
|
6017
5143
|
name: "get-element-configuration-values",
|
|
6018
5144
|
description: "Retrieve the element's configuration PropValues for a specific element by unique ID.",
|
|
6019
5145
|
schema,
|
|
6020
|
-
outputSchema:
|
|
5146
|
+
outputSchema: outputSchema2,
|
|
6021
5147
|
handler: async ({ elementId }) => {
|
|
6022
|
-
const element = (0,
|
|
5148
|
+
const element = (0, import_editor_elements15.getContainer)(elementId);
|
|
6023
5149
|
if (!element) {
|
|
6024
5150
|
throw new Error(`Element with ID ${elementId} not found.`);
|
|
6025
5151
|
}
|
|
6026
5152
|
const elementType = element.model.get("widgetType") || element.model.get("elType") || "";
|
|
6027
|
-
const widgetData = (0,
|
|
5153
|
+
const widgetData = (0, import_editor_elements15.getWidgetsCache)()?.[elementType];
|
|
6028
5154
|
if (!widgetData) {
|
|
6029
5155
|
throw new Error(
|
|
6030
5156
|
`Unknown element type: ${elementType}. Check the available-widgets resource for valid types.`
|
|
@@ -6036,16 +5162,16 @@ var initGetElementConfigTool = (reg) => {
|
|
|
6036
5162
|
);
|
|
6037
5163
|
}
|
|
6038
5164
|
const elementRawSettings = element.settings;
|
|
6039
|
-
const propSchema = (0,
|
|
5165
|
+
const propSchema = (0, import_editor_elements15.getWidgetsCache)()?.[elementType]?.atomic_props_schema;
|
|
6040
5166
|
if (!elementRawSettings || !propSchema) {
|
|
6041
5167
|
throw new Error(`No settings or prop schema found for element ID: ${elementId}`);
|
|
6042
5168
|
}
|
|
6043
5169
|
const propValues = {};
|
|
6044
5170
|
const stylePropValues = {};
|
|
6045
|
-
|
|
5171
|
+
import_editor_props8.Schema.configurableKeys(propSchema).forEach((key) => {
|
|
6046
5172
|
propValues[key] = structuredClone(elementRawSettings.get(key));
|
|
6047
5173
|
});
|
|
6048
|
-
const elementStyles = (0,
|
|
5174
|
+
const elementStyles = (0, import_editor_elements15.getElementStyles)(elementId) || {};
|
|
6049
5175
|
const localStyle = Object.values(elementStyles).find((style) => style.label === "local");
|
|
6050
5176
|
if (localStyle) {
|
|
6051
5177
|
const defaultVariant = localStyle.variants.find(
|
|
@@ -6078,7 +5204,7 @@ var initGetElementConfigTool = (reg) => {
|
|
|
6078
5204
|
|
|
6079
5205
|
// src/mcp/canvas-mcp.ts
|
|
6080
5206
|
var initCanvasMcp = (reg) => {
|
|
6081
|
-
|
|
5207
|
+
import_editor_props9.Schema.setDynamicTagNamesResolver(getDynamicTagNamesByCategories);
|
|
6082
5208
|
initWidgetsSchemaResource(reg);
|
|
6083
5209
|
initAvailableWidgetsResource(reg);
|
|
6084
5210
|
initDocumentStructureResource(reg);
|
|
@@ -6086,9 +5212,10 @@ var initCanvasMcp = (reg) => {
|
|
|
6086
5212
|
initSelectedElementResource(reg);
|
|
6087
5213
|
initEditorStateResource(reg);
|
|
6088
5214
|
initGeneralContextResource(reg);
|
|
6089
|
-
|
|
5215
|
+
initBestPracticesResource(reg);
|
|
6090
5216
|
initGetElementConfigTool(reg);
|
|
6091
5217
|
initConfigureElementTool(reg);
|
|
5218
|
+
initBuildCompositionTool(reg);
|
|
6092
5219
|
initBreakpointsResource(reg);
|
|
6093
5220
|
};
|
|
6094
5221
|
|
|
@@ -6201,16 +5328,16 @@ Note: The "size" property controls image resolution/loading, not visual size. Se
|
|
|
6201
5328
|
`;
|
|
6202
5329
|
|
|
6203
5330
|
// src/prevent-link-in-link-commands.ts
|
|
6204
|
-
var
|
|
5331
|
+
var import_editor_elements16 = require("@elementor/editor-elements");
|
|
6205
5332
|
var import_editor_notifications3 = require("@elementor/editor-notifications");
|
|
6206
|
-
var
|
|
5333
|
+
var import_editor_v1_adapters21 = require("@elementor/editor-v1-adapters");
|
|
6207
5334
|
var import_i18n4 = require("@wordpress/i18n");
|
|
6208
5335
|
function initLinkInLinkPrevention() {
|
|
6209
|
-
(0,
|
|
5336
|
+
(0, import_editor_v1_adapters21.blockCommand)({
|
|
6210
5337
|
command: "document/elements/paste",
|
|
6211
5338
|
condition: blockLinkInLinkPaste
|
|
6212
5339
|
});
|
|
6213
|
-
(0,
|
|
5340
|
+
(0, import_editor_v1_adapters21.blockCommand)({
|
|
6214
5341
|
command: "document/elements/move",
|
|
6215
5342
|
condition: blockLinkInLinkMove
|
|
6216
5343
|
});
|
|
@@ -6272,25 +5399,25 @@ function shouldBlock(sourceElements, targetElements) {
|
|
|
6272
5399
|
return false;
|
|
6273
5400
|
}
|
|
6274
5401
|
const isSourceContainsAnAnchor = sourceElements.some((src) => {
|
|
6275
|
-
return src?.id ? (0,
|
|
5402
|
+
return src?.id ? (0, import_editor_elements16.isElementAnchored)(src.id) || !!(0, import_editor_elements16.getAnchoredDescendantId)(src.id) : false;
|
|
6276
5403
|
});
|
|
6277
5404
|
if (!isSourceContainsAnAnchor) {
|
|
6278
5405
|
return false;
|
|
6279
5406
|
}
|
|
6280
5407
|
const isTargetContainsAnAnchor = targetElements.some((target) => {
|
|
6281
|
-
return target?.id ? (0,
|
|
5408
|
+
return target?.id ? (0, import_editor_elements16.isElementAnchored)(target.id) || !!(0, import_editor_elements16.getAnchoredAncestorId)(target.id) : false;
|
|
6282
5409
|
});
|
|
6283
5410
|
return isTargetContainsAnAnchor;
|
|
6284
5411
|
}
|
|
6285
5412
|
|
|
6286
5413
|
// src/style-commands/paste-style.ts
|
|
6287
|
-
var
|
|
6288
|
-
var
|
|
6289
|
-
var
|
|
5414
|
+
var import_editor_elements19 = require("@elementor/editor-elements");
|
|
5415
|
+
var import_editor_props11 = require("@elementor/editor-props");
|
|
5416
|
+
var import_editor_v1_adapters23 = require("@elementor/editor-v1-adapters");
|
|
6290
5417
|
|
|
6291
5418
|
// src/utils/command-utils.ts
|
|
6292
|
-
var
|
|
6293
|
-
var
|
|
5419
|
+
var import_editor_elements17 = require("@elementor/editor-elements");
|
|
5420
|
+
var import_editor_props10 = require("@elementor/editor-props");
|
|
6294
5421
|
var import_i18n5 = require("@wordpress/i18n");
|
|
6295
5422
|
function hasAtomicWidgets(args) {
|
|
6296
5423
|
const { containers = [args.container] } = args;
|
|
@@ -6308,13 +5435,13 @@ function getClassesProp(container) {
|
|
|
6308
5435
|
return null;
|
|
6309
5436
|
}
|
|
6310
5437
|
const [propKey] = Object.entries(propsSchema).find(
|
|
6311
|
-
([, propType]) => propType.kind === "plain" && propType.key ===
|
|
5438
|
+
([, propType]) => propType.kind === "plain" && propType.key === import_editor_props10.CLASSES_PROP_KEY
|
|
6312
5439
|
) ?? [];
|
|
6313
5440
|
return propKey ?? null;
|
|
6314
5441
|
}
|
|
6315
5442
|
function getContainerSchema(container) {
|
|
6316
5443
|
const type = container?.model.get("widgetType") || container?.model.get("elType");
|
|
6317
|
-
const widgetsCache = (0,
|
|
5444
|
+
const widgetsCache = (0, import_editor_elements17.getWidgetsCache)();
|
|
6318
5445
|
const elementType = widgetsCache?.[type];
|
|
6319
5446
|
return elementType?.atomic_props_schema ?? null;
|
|
6320
5447
|
}
|
|
@@ -6327,15 +5454,15 @@ function getClipboardElements(storageKey = "clipboard") {
|
|
|
6327
5454
|
}
|
|
6328
5455
|
}
|
|
6329
5456
|
function getTitleForContainers(containers) {
|
|
6330
|
-
return containers.length > 1 ? (0, import_i18n5.__)("Elements", "elementor") : (0,
|
|
5457
|
+
return containers.length > 1 ? (0, import_i18n5.__)("Elements", "elementor") : (0, import_editor_elements17.getElementLabel)(containers[0].id);
|
|
6331
5458
|
}
|
|
6332
5459
|
|
|
6333
5460
|
// src/style-commands/undoable-actions/paste-element-style.ts
|
|
6334
|
-
var
|
|
5461
|
+
var import_editor_elements18 = require("@elementor/editor-elements");
|
|
6335
5462
|
var import_editor_styles_repository4 = require("@elementor/editor-styles-repository");
|
|
6336
|
-
var
|
|
5463
|
+
var import_editor_v1_adapters22 = require("@elementor/editor-v1-adapters");
|
|
6337
5464
|
var import_i18n6 = require("@wordpress/i18n");
|
|
6338
|
-
var undoablePasteElementStyle = () => (0,
|
|
5465
|
+
var undoablePasteElementStyle = () => (0, import_editor_v1_adapters22.undoable)(
|
|
6339
5466
|
{
|
|
6340
5467
|
do: ({ containers, newStyle }) => {
|
|
6341
5468
|
return containers.map((container) => {
|
|
@@ -6344,7 +5471,7 @@ var undoablePasteElementStyle = () => (0, import_editor_v1_adapters23.undoable)(
|
|
|
6344
5471
|
if (!classesProp) {
|
|
6345
5472
|
return null;
|
|
6346
5473
|
}
|
|
6347
|
-
const originalStyles = (0,
|
|
5474
|
+
const originalStyles = (0, import_editor_elements18.getElementStyles)(container.id);
|
|
6348
5475
|
const [styleId, styleDef] = Object.entries(originalStyles ?? {})[0] ?? [];
|
|
6349
5476
|
const originalStyle = Object.keys(styleDef ?? {}).length ? styleDef : null;
|
|
6350
5477
|
const revertData = {
|
|
@@ -6353,7 +5480,7 @@ var undoablePasteElementStyle = () => (0, import_editor_v1_adapters23.undoable)(
|
|
|
6353
5480
|
};
|
|
6354
5481
|
if (styleId) {
|
|
6355
5482
|
newStyle.variants.forEach(({ meta, props, custom_css: customCss }) => {
|
|
6356
|
-
(0,
|
|
5483
|
+
(0, import_editor_elements18.updateElementStyle)({
|
|
6357
5484
|
elementId,
|
|
6358
5485
|
styleId,
|
|
6359
5486
|
meta,
|
|
@@ -6364,7 +5491,7 @@ var undoablePasteElementStyle = () => (0, import_editor_v1_adapters23.undoable)(
|
|
|
6364
5491
|
} else {
|
|
6365
5492
|
const [firstVariant] = newStyle.variants;
|
|
6366
5493
|
const additionalVariants = newStyle.variants.slice(1);
|
|
6367
|
-
revertData.styleId = (0,
|
|
5494
|
+
revertData.styleId = (0, import_editor_elements18.createElementStyle)({
|
|
6368
5495
|
elementId,
|
|
6369
5496
|
classesProp,
|
|
6370
5497
|
label: import_editor_styles_repository4.ELEMENTS_STYLES_RESERVED_LABEL,
|
|
@@ -6382,7 +5509,7 @@ var undoablePasteElementStyle = () => (0, import_editor_v1_adapters23.undoable)(
|
|
|
6382
5509
|
return;
|
|
6383
5510
|
}
|
|
6384
5511
|
if (!revertData.originalStyle) {
|
|
6385
|
-
(0,
|
|
5512
|
+
(0, import_editor_elements18.deleteElementStyle)(container.id, revertData.styleId);
|
|
6386
5513
|
return;
|
|
6387
5514
|
}
|
|
6388
5515
|
const classesProp = getClassesProp(container);
|
|
@@ -6391,7 +5518,7 @@ var undoablePasteElementStyle = () => (0, import_editor_v1_adapters23.undoable)(
|
|
|
6391
5518
|
}
|
|
6392
5519
|
const [firstVariant] = revertData.originalStyle.variants;
|
|
6393
5520
|
const additionalVariants = revertData.originalStyle.variants.slice(1);
|
|
6394
|
-
(0,
|
|
5521
|
+
(0, import_editor_elements18.createElementStyle)({
|
|
6395
5522
|
elementId: container.id,
|
|
6396
5523
|
classesProp,
|
|
6397
5524
|
label: import_editor_styles_repository4.ELEMENTS_STYLES_RESERVED_LABEL,
|
|
@@ -6411,12 +5538,12 @@ var undoablePasteElementStyle = () => (0, import_editor_v1_adapters23.undoable)(
|
|
|
6411
5538
|
// src/style-commands/paste-style.ts
|
|
6412
5539
|
function initPasteStyleCommand() {
|
|
6413
5540
|
const pasteElementStyleCommand = undoablePasteElementStyle();
|
|
6414
|
-
(0,
|
|
5541
|
+
(0, import_editor_v1_adapters23.blockCommand)({
|
|
6415
5542
|
command: "document/elements/paste-style",
|
|
6416
5543
|
condition: hasAtomicWidgets
|
|
6417
5544
|
});
|
|
6418
|
-
(0,
|
|
6419
|
-
(0,
|
|
5545
|
+
(0, import_editor_v1_adapters23.__privateListenTo)(
|
|
5546
|
+
(0, import_editor_v1_adapters23.commandStartEvent)("document/elements/paste-style"),
|
|
6420
5547
|
(e) => pasteStyles(e.args, pasteElementStyleCommand)
|
|
6421
5548
|
);
|
|
6422
5549
|
}
|
|
@@ -6428,7 +5555,7 @@ function pasteStyles(args, pasteLocalStyle) {
|
|
|
6428
5555
|
}
|
|
6429
5556
|
const clipboardElements = getClipboardElements(storageKey);
|
|
6430
5557
|
const [clipboardElement] = clipboardElements ?? [];
|
|
6431
|
-
const clipboardContainer = (0,
|
|
5558
|
+
const clipboardContainer = (0, import_editor_elements19.getContainer)(clipboardElement.id);
|
|
6432
5559
|
if (!clipboardElement || !clipboardContainer || !isAtomicWidget(clipboardContainer)) {
|
|
6433
5560
|
return;
|
|
6434
5561
|
}
|
|
@@ -6447,7 +5574,7 @@ function getClassesWithoutLocalStyle(clipboardContainer, style) {
|
|
|
6447
5574
|
if (!classesProp) {
|
|
6448
5575
|
return [];
|
|
6449
5576
|
}
|
|
6450
|
-
const classesSetting = (0,
|
|
5577
|
+
const classesSetting = (0, import_editor_elements19.getElementSetting)(clipboardContainer.id, classesProp);
|
|
6451
5578
|
return classesSetting?.value.filter((styleId) => styleId !== style?.id) ?? [];
|
|
6452
5579
|
}
|
|
6453
5580
|
function pasteClasses(containers, classes) {
|
|
@@ -6456,10 +5583,10 @@ function pasteClasses(containers, classes) {
|
|
|
6456
5583
|
if (!classesProp) {
|
|
6457
5584
|
return;
|
|
6458
5585
|
}
|
|
6459
|
-
const classesSetting = (0,
|
|
6460
|
-
const currentClasses =
|
|
6461
|
-
const newClasses =
|
|
6462
|
-
(0,
|
|
5586
|
+
const classesSetting = (0, import_editor_elements19.getElementSetting)(container.id, classesProp);
|
|
5587
|
+
const currentClasses = import_editor_props11.classesPropTypeUtil.extract(classesSetting) ?? [];
|
|
5588
|
+
const newClasses = import_editor_props11.classesPropTypeUtil.create(Array.from(/* @__PURE__ */ new Set([...classes, ...currentClasses])));
|
|
5589
|
+
(0, import_editor_elements19.updateElementSettings)({
|
|
6463
5590
|
id: container.id,
|
|
6464
5591
|
props: { [classesProp]: newClasses }
|
|
6465
5592
|
});
|
|
@@ -6467,21 +5594,21 @@ function pasteClasses(containers, classes) {
|
|
|
6467
5594
|
}
|
|
6468
5595
|
|
|
6469
5596
|
// src/style-commands/reset-style.ts
|
|
6470
|
-
var
|
|
5597
|
+
var import_editor_v1_adapters25 = require("@elementor/editor-v1-adapters");
|
|
6471
5598
|
|
|
6472
5599
|
// src/style-commands/undoable-actions/reset-element-style.ts
|
|
6473
|
-
var
|
|
5600
|
+
var import_editor_elements20 = require("@elementor/editor-elements");
|
|
6474
5601
|
var import_editor_styles_repository5 = require("@elementor/editor-styles-repository");
|
|
6475
|
-
var
|
|
5602
|
+
var import_editor_v1_adapters24 = require("@elementor/editor-v1-adapters");
|
|
6476
5603
|
var import_i18n7 = require("@wordpress/i18n");
|
|
6477
|
-
var undoableResetElementStyle = () => (0,
|
|
5604
|
+
var undoableResetElementStyle = () => (0, import_editor_v1_adapters24.undoable)(
|
|
6478
5605
|
{
|
|
6479
5606
|
do: ({ containers }) => {
|
|
6480
5607
|
return containers.map((container) => {
|
|
6481
5608
|
const elementId = container.model.get("id");
|
|
6482
|
-
const containerStyles = (0,
|
|
5609
|
+
const containerStyles = (0, import_editor_elements20.getElementStyles)(elementId);
|
|
6483
5610
|
Object.keys(containerStyles ?? {}).forEach(
|
|
6484
|
-
(styleId) => (0,
|
|
5611
|
+
(styleId) => (0, import_editor_elements20.deleteElementStyle)(elementId, styleId)
|
|
6485
5612
|
);
|
|
6486
5613
|
return containerStyles;
|
|
6487
5614
|
});
|
|
@@ -6497,7 +5624,7 @@ var undoableResetElementStyle = () => (0, import_editor_v1_adapters25.undoable)(
|
|
|
6497
5624
|
Object.entries(containerStyles ?? {}).forEach(([styleId, style]) => {
|
|
6498
5625
|
const [firstVariant] = style.variants;
|
|
6499
5626
|
const additionalVariants = style.variants.slice(1);
|
|
6500
|
-
(0,
|
|
5627
|
+
(0, import_editor_elements20.createElementStyle)({
|
|
6501
5628
|
elementId,
|
|
6502
5629
|
classesProp,
|
|
6503
5630
|
styleId,
|
|
@@ -6518,12 +5645,12 @@ var undoableResetElementStyle = () => (0, import_editor_v1_adapters25.undoable)(
|
|
|
6518
5645
|
// src/style-commands/reset-style.ts
|
|
6519
5646
|
function initResetStyleCommand() {
|
|
6520
5647
|
const resetElementStyles = undoableResetElementStyle();
|
|
6521
|
-
(0,
|
|
5648
|
+
(0, import_editor_v1_adapters25.blockCommand)({
|
|
6522
5649
|
command: "document/elements/reset-style",
|
|
6523
5650
|
condition: hasAtomicWidgets
|
|
6524
5651
|
});
|
|
6525
|
-
(0,
|
|
6526
|
-
(0,
|
|
5652
|
+
(0, import_editor_v1_adapters25.__privateListenTo)(
|
|
5653
|
+
(0, import_editor_v1_adapters25.commandStartEvent)("document/elements/reset-style"),
|
|
6527
5654
|
(e) => resetStyles(e.args, resetElementStyles)
|
|
6528
5655
|
);
|
|
6529
5656
|
}
|
|
@@ -6569,7 +5696,7 @@ function init() {
|
|
|
6569
5696
|
component: ClassesRename
|
|
6570
5697
|
});
|
|
6571
5698
|
initCanvasMcp(
|
|
6572
|
-
(0,
|
|
5699
|
+
(0, import_editor_mcp4.getMCPByDomain)("canvas", {
|
|
6573
5700
|
instructions: `Everything related to V4 ( Atomic ) canvas.
|
|
6574
5701
|
# Canvas workflow for new compositions
|
|
6575
5702
|
- Configure elements settings and styles
|
|
@@ -6672,9 +5799,9 @@ function getRectClipPath(rect, viewport) {
|
|
|
6672
5799
|
}
|
|
6673
5800
|
|
|
6674
5801
|
// src/hooks/use-canvas-document.ts
|
|
6675
|
-
var
|
|
5802
|
+
var import_editor_v1_adapters26 = require("@elementor/editor-v1-adapters");
|
|
6676
5803
|
function useCanvasDocument() {
|
|
6677
|
-
return (0,
|
|
5804
|
+
return (0, import_editor_v1_adapters26.__privateUseListenTo)((0, import_editor_v1_adapters26.commandEndEvent)("editor/documents/attach-preview"), () => (0, import_editor_v1_adapters26.getCanvasIframeDocument)());
|
|
6678
5805
|
}
|
|
6679
5806
|
|
|
6680
5807
|
// src/hooks/use-escape-on-canvas.ts
|
|
@@ -6697,10 +5824,10 @@ function useEscapeOnCanvas(canvasDocument, onEscape) {
|
|
|
6697
5824
|
}
|
|
6698
5825
|
|
|
6699
5826
|
// src/utils/after-render.ts
|
|
6700
|
-
var
|
|
5827
|
+
var import_editor_elements21 = require("@elementor/editor-elements");
|
|
6701
5828
|
function doAfterRender(elementIds, callback) {
|
|
6702
5829
|
const pending = elementIds.map((elementId) => {
|
|
6703
|
-
const view = (0,
|
|
5830
|
+
const view = (0, import_editor_elements21.getContainer)(elementId)?.view;
|
|
6704
5831
|
if (!view || !hasDoAfterRender(view)) {
|
|
6705
5832
|
return void 0;
|
|
6706
5833
|
}
|
|
@@ -6715,6 +5842,9 @@ function doAfterRender(elementIds, callback) {
|
|
|
6715
5842
|
function hasDoAfterRender(view) {
|
|
6716
5843
|
return typeof view?._doAfterRender === "function";
|
|
6717
5844
|
}
|
|
5845
|
+
|
|
5846
|
+
// src/sync/element-added-event.ts
|
|
5847
|
+
var ELEMENT_ADDED_EVENT = "elementor/canvas/element-added";
|
|
6718
5848
|
// Annotate the CommonJS export names for ESM import in node:
|
|
6719
5849
|
0 && (module.exports = {
|
|
6720
5850
|
BREAKPOINTS_SCHEMA_FULL_URI,
|