@elementor/editor-canvas 4.2.0-beta2 → 4.3.0-1001

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/dist/index.d.mts +1 -1
  2. package/dist/index.d.ts +1 -1
  3. package/dist/index.js +449 -1319
  4. package/dist/index.mjs +314 -1197
  5. package/package.json +22 -22
  6. package/src/index.ts +1 -1
  7. package/src/legacy/__tests__/init-legacy-views.test.ts +1 -1
  8. package/src/mcp/canvas-mcp.ts +4 -2
  9. package/src/mcp/resources/__tests__/available-widgets-resource.test.ts +85 -0
  10. package/src/mcp/resources/__tests__/dynamic-tags-resource.test.ts +27 -37
  11. package/src/mcp/resources/__tests__/widgets-schema-resource.test.ts +82 -74
  12. package/src/mcp/resources/available-widgets-resource.ts +35 -41
  13. package/src/mcp/resources/best-practices-resource.ts +34 -0
  14. package/src/mcp/resources/dynamic-tags-resource.ts +28 -29
  15. package/src/mcp/resources/widgets-schema-resource.ts +37 -177
  16. package/src/mcp/tools/build-composition/tool.ts +107 -218
  17. package/src/sync/element-added-event.ts +8 -0
  18. package/src/utils/__tests__/grid-outline-utils.test.ts +39 -0
  19. package/src/utils/grid-outline-utils.ts +13 -2
  20. package/src/composition-builder/__tests__/composition-builder.test.ts +0 -352
  21. package/src/composition-builder/composition-builder.ts +0 -350
  22. package/src/composition-builder/utils/__tests__/required-children-enforcer.test.ts +0 -79
  23. package/src/composition-builder/utils/__tests__/required-default-child-tags.test.ts +0 -35
  24. package/src/composition-builder/utils/required-children-enforcer.ts +0 -56
  25. package/src/composition-builder/utils/required-default-child-tags.ts +0 -22
  26. package/src/mcp/resources/best-practices.ts +0 -159
  27. package/src/mcp/resources/build-llm-guidance.ts +0 -110
  28. package/src/mcp/tools/build-composition/__tests__/xml-leaf-wrapper.test.ts +0 -117
  29. package/src/mcp/tools/build-composition/prompt.ts +0 -167
  30. package/src/mcp/tools/build-composition/schema.ts +0 -42
  31. package/src/mcp/tools/build-composition/xml-leaf-wrapper.ts +0 -68
  32. package/src/mcp/utils/__tests__/get-composition-target-container.test.ts +0 -59
  33. 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 import_editor_props = require("@elementor/editor-props");
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://styles/best-practices";
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-widget-schemas",
85
+ input: { summary: true }
86
+ });
87
+ return (data.data?.widgets ?? []).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 cache = (0, import_editor_elements2.getWidgetsCache)() || {};
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: availableWidgets.map((widgetType) => ({
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
- const widgetData = (0, import_editor_elements2.getWidgetsCache)()?.[widgetType];
283
- if (!widgetData) {
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 baseSettingsKeys = Object.keys(widgetData?.base_settings ?? {});
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 import_http_client = require("@elementor/http-client");
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, import_http_client.httpService)().post(
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 import_editor_mcp6 = require("@elementor/editor-mcp");
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 import_editor_elements5 = require("@elementor/editor-elements");
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 import_editor_elements3 = require("@elementor/editor-elements");
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: toPx(computedStyle.columnGap),
526
- rowGap: toPx(computedStyle.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)(import_editor_elements3.ELEMENT_STYLE_CHANGE_EVENT), (0, import_editor_v1_adapters2.windowEvent)(DEVICE_MODE_CHANGE_EVENT)],
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 import_editor_elements4 = require("@elementor/editor-elements");
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, import_editor_elements4.useElementEditorSettings)(id);
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, import_editor_elements5.useSelectedElement)();
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, import_editor_elements5.getElements)().filter((el) => isV4Element(el.view?.el?.dataset)).map((element) => ({
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 import_editor_props2 = require("@elementor/editor-props");
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, import_editor_props2.isTransformable)(value)) {
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 import_editor_props3 = require("@elementor/editor-props");
1390
+ var import_editor_props2 = require("@elementor/editor-props");
1585
1391
  var maybeEnqueueFontFromStyleProp = (propType, propValue, enqueue) => {
1586
- if (!(0, import_editor_props3.isTransformable)(propValue) || propValue.disabled) {
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, import_editor_props3.getPropSchemaFromCache)(typeKey);
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 import_editor_elements6 = require("@elementor/editor-elements");
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, import_editor_elements6.getAllDescendants)(element).some((item) => getElementType(item) === type);
1822
+ return (0, import_editor_elements4.getAllDescendants)(element).some((item) => getElementType(item) === type);
2017
1823
  }
2018
1824
  function hasElementTypes(element, types) {
2019
- return (0, import_editor_elements6.getAllDescendants)(element).some((item) => {
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 import_editor_elements10 = require("@elementor/editor-elements");
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 import_editor_elements8 = require("@elementor/editor-elements");
2695
+ var import_editor_elements6 = require("@elementor/editor-elements");
2930
2696
 
2931
2697
  // src/legacy/create-pending-element.ts
2932
- var import_editor_elements7 = require("@elementor/editor-elements");
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, import_editor_elements7.generateElementId)();
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, import_editor_elements7.addModelToParent)(parentContainer.id, model, options);
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, import_editor_elements7.findModelInDocument)(childId);
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, import_editor_elements7.getContainer)(childId) ?? pendingContainer;
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, import_editor_elements7.getContainer)(childId);
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(import_editor_elements8.ELEMENT_STYLE_CHANGE_EVENT));
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 import_editor_elements9 = require("@elementor/editor-elements");
3487
- var import_editor_props5 = require("@elementor/editor-props");
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 import_editor_props4 = require("@elementor/editor-props");
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([import_editor_props4.htmlV3PropTypeUtil.key, import_editor_props4.stringPropTypeUtil.key]);
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 import_editor_props4.htmlV3PropTypeUtil.isValid(rawValue) || import_editor_props4.stringPropTypeUtil.isValid(rawValue);
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, import_editor_elements9.getElementType)(this.type)?.propsSchema;
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 = import_editor_props5.htmlV3PropTypeUtil.extract(propValue);
3874
- return import_editor_props5.stringPropTypeUtil.extract(extracted?.content ?? null) ?? "";
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, import_editor_props5.parseHtmlChildren)(html);
3880
- const valueToSave = import_editor_props5.htmlV3PropTypeUtil.create({
3881
- content: parsed.content ? import_editor_props5.stringPropTypeUtil.create(parsed.content) : null,
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, import_editor_elements9.getElementLabel)(this.id),
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 = [import_editor_props5.htmlV3PropTypeUtil.key, import_editor_props5.stringPropTypeUtil.key];
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, import_editor_elements9.getContainer)(this.id),
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 import_editor_props5.stringPropTypeUtil.extract(this.getSetting(tagSettingKey) ?? null) ?? import_editor_props5.stringPropTypeUtil.extract(tagPropType?.default ?? null) ?? null;
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, import_editor_elements9.getElementType)(this.type)?.propsSchema;
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, import_editor_elements10.getWidgetsCache)() ?? {};
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, import_editor_elements10.getWidgetsCache)() ?? {})[type];
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 import_editor_props6 = require("@elementor/editor-props");
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: import_editor_props6.htmlV3PropTypeUtil.create({
4185
- content: import_editor_props6.stringPropTypeUtil.create(`Tab ${position}`),
3950
+ paragraph: import_editor_props5.htmlV3PropTypeUtil.create({
3951
+ content: import_editor_props5.stringPropTypeUtil.create(`Tab ${position}`),
4186
3952
  children: []
4187
3953
  })
4188
3954
  }
@@ -4195,68 +3961,85 @@ function initTabsModelExtensions() {
4195
3961
  }
4196
3962
 
4197
3963
  // src/mcp/canvas-mcp.ts
4198
- var import_editor_props11 = require("@elementor/editor-props");
3964
+ var import_editor_props9 = require("@elementor/editor-props");
4199
3965
 
4200
3966
  // src/mcp/resources/available-widgets-resource.ts
4201
- var import_editor_v1_adapters15 = require("@elementor/editor-v1-adapters");
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 initAvailableWidgetsResource = (reg) => {
4205
- const { resource, sendResourceUpdated } = reg;
4206
- const buildContents = (uri, filterFunction = () => true) => {
4207
- const widgets = getAvailableWidgets().filter(filterFunction);
4208
- return {
4209
- contents: [
4210
- {
4211
- uri,
4212
- mimeType: "application/json",
4213
- text: JSON.stringify(widgets, null, 2)
4214
- }
4215
- ]
4216
- };
4217
- };
4218
- const notifyResourcesUpdated = () => {
4219
- sendResourceUpdated({
4220
- uri: AVAILABLE_WIDGETS_URI,
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 () => {
3972
+ const { data } = await (0, import_http_client3.httpService)().post(MCP_PROXY_URL2, {
3973
+ tool: "list-widget-schemas",
3974
+ input: { summary: true }
3975
+ });
3976
+ return data.data?.widgets ?? [];
3977
+ };
3978
+ var buildContents = async (uri) => {
3979
+ const widgets = await fetchWidgets();
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, (w) => w.version === "v4")
3998
+ async () => buildContents(AVAILABLE_WIDGETS_URI_V4)
4235
3999
  );
4236
4000
  resource(
4237
4001
  "available-widgets",
4238
4002
  AVAILABLE_WIDGETS_URI,
4239
4003
  {
4240
- description: "All registered widget types with v3/v4 version metadata and description."
4004
+ description: "All registered v4 widget types with description."
4241
4005
  },
4242
4006
  async () => buildContents(AVAILABLE_WIDGETS_URI)
4243
4007
  );
4244
- const eventName = (0, import_editor_v1_adapters15.v1ReadyEvent)().name;
4245
- const onV1Ready = () => {
4246
- const widgets = getAvailableWidgets();
4247
- if (widgets.length === 0) {
4248
- return;
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
- window.removeEventListener(eventName, onV1Ready);
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 import_editor_elements11 = require("@elementor/editor-elements");
4259
- var import_editor_v1_adapters16 = require("@elementor/editor-v1-adapters");
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, import_editor_v1_adapters16.__privateListenTo)(
4055
+ (0, import_editor_v1_adapters15.__privateListenTo)(
4273
4056
  [
4274
- (0, import_editor_v1_adapters16.commandEndEvent)("document/elements/create"),
4275
- (0, import_editor_v1_adapters16.commandEndEvent)("document/elements/delete"),
4276
- (0, import_editor_v1_adapters16.commandEndEvent)("document/elements/move"),
4277
- (0, import_editor_v1_adapters16.commandEndEvent)("document/elements/copy"),
4278
- (0, import_editor_v1_adapters16.commandEndEvent)("document/elements/paste"),
4279
- (0, import_editor_v1_adapters16.commandEndEvent)("editor/documents/attach-preview"),
4280
- (0, import_editor_v1_adapters16.commandEndEvent)("editor/documents/switch")
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, import_editor_elements11.getWidgetsCache)()?.[widgetType]?.atomic_props_schema) {
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 import_editor_props7 = require("@elementor/editor-props");
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 settingsSchema = (propsSchema) => {
4417
- return Object.fromEntries(
4418
- Object.entries(propsSchema ?? {}).filter(([key]) => !OMITTED_DYNAMIC_SETTING_KEYS.includes(key)).map(([key, propType]) => [key, import_editor_props7.Schema.propTypeToJsonSchema(propType)])
4419
- );
4420
- };
4421
- var buildDynamicTagsList = () => {
4422
- return Object.values(getAtomicDynamicTags()).map((tag) => ({
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
- contents: [
4440
- {
4441
- uri: uri.href,
4442
- mimeType: "application/json",
4443
- text: JSON.stringify(buildDynamicTagsList())
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 import_editor_v1_adapters18 = require("@elementor/editor-v1-adapters");
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, import_editor_v1_adapters18.__privateListenTo)(
4473
- [(0, import_editor_v1_adapters18.commandEndEvent)("editor/documents/switch"), (0, import_editor_v1_adapters18.commandEndEvent)("editor/documents/attach-preview")],
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 import_editor_v1_adapters19 = require("@elementor/editor-v1-adapters");
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, import_editor_v1_adapters19.__privateListenTo)(
4325
+ (0, import_editor_v1_adapters17.__privateListenTo)(
4609
4326
  [
4610
- (0, import_editor_v1_adapters19.commandEndEvent)("editor/documents/switch"),
4611
- (0, import_editor_v1_adapters19.commandEndEvent)("editor/documents/attach-preview"),
4612
- (0, import_editor_v1_adapters19.commandEndEvent)("document/elements/settings")
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 import_editor_elements12 = require("@elementor/editor-elements");
4621
- var import_editor_v1_adapters20 = require("@elementor/editor-v1-adapters");
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, import_editor_v1_adapters20.__privateListenTo)(
4369
+ (0, import_editor_v1_adapters18.__privateListenTo)(
4653
4370
  [
4654
- (0, import_editor_v1_adapters20.commandEndEvent)("document/elements/select"),
4655
- (0, import_editor_v1_adapters20.commandEndEvent)("document/elements/deselect-all"),
4656
- (0, import_editor_v1_adapters20.commandEndEvent)("document/elements/settings")
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, import_editor_elements12.getSelectedElements)();
4408
+ const elements = (0, import_editor_elements10.getSelectedElements)();
4692
4409
  if (elements.length !== 1) {
4693
4410
  return createEmptySelectedElementPayload();
4694
4411
  }
4695
- const container = (0, import_editor_elements12.getContainer)(elements[0].id);
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, import_editor_elements12.getWidgetsCache)()?.[widgetType]?.atomic_props_schema) {
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, import_editor_elements12.getWidgetsCache)()?.[widgetType] : null;
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 import_editor_documents3 = require("@elementor/editor-documents");
4767
- var import_editor_elements16 = require("@elementor/editor-elements");
4768
- var import_editor_mcp3 = require("@elementor/editor-mcp");
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/composition-builder/composition-builder.ts
4771
- var import_editor_elements15 = require("@elementor/editor-elements");
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 import_editor_elements14 = require("@elementor/editor-elements");
4775
- var import_editor_props8 = require("@elementor/editor-props");
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 import_editor_v1_adapters21 = require("@elementor/editor-v1-adapters");
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 import_editor_elements13 = require("@elementor/editor-elements");
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, import_editor_elements13.getWidgetsCache)()?.[elementType]?.atomic_props_schema;
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, import_editor_elements13.getWidgetsCache)()?.[elementType]?.atomic_props_schema;
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 import_editor_props8.Schema.adjustLlmPropValueSchema(value, {
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, import_editor_elements14.getElementStyles)(elementId) || {};
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, import_editor_props8.getPropSchemaFromCache)(propertyRawSchema.key);
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, import_editor_elements14.createElementStyle)({
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, import_editor_elements14.updateElementStyle)({
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, import_editor_elements14.getWidgetsCache)()?.[elementType]?.atomic_props_schema;
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 } = import_editor_props8.Schema.validatePropValue(elementPropSchema[propertyName], propertyValue);
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, import_editor_elements14.updateElementSettings)({
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, import_editor_v1_adapters21.__privateRunCommandSync)("document/save/set-is-modified", { status: true }, { internal: true });
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 import_editor_mcp4 = require("@elementor/editor-mcp");
4851
+ var import_editor_mcp2 = require("@elementor/editor-mcp");
5726
4852
  var CONFIGURE_ELEMENT_GUIDE_URI = "elementor://canvas/tools/configure-element-guide";
5727
- var generatePrompt2 = () => {
5728
- const configureElementToolPrompt = (0, import_editor_mcp4.toolPrompts)("configure-element");
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 = generatePrompt2();
4962
+ var CONFIGURE_ELEMENT_GUIDE_TEXT = generatePrompt();
5837
4963
 
5838
4964
  // src/mcp/tools/configure-element/schema.ts
5839
- var import_schema3 = require("@elementor/schema");
5840
- var inputSchema2 = {
5841
- propertiesToChange: import_schema3.z.record(
5842
- import_schema3.z.string().describe("The property name."),
5843
- import_schema3.z.any().describe(`PropValue, refer to [${WIDGET_SCHEMA_URI}] by correct type, as appears in elementType`),
5844
- import_schema3.z.any()
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: import_schema3.z.record(
5847
- import_schema3.z.string().describe('A CSS property name, e.g. "color", "margin-top".'),
5848
- import_schema3.z.string().nullable().describe(
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: import_schema3.z.string().describe("The type of the element to retrieve the schema"),
5855
- elementId: import_schema3.z.string().describe("The unique id of the element to configure")
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 outputSchema2 = {
5858
- success: import_schema3.z.boolean().describe(
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: generatePrompt2() }]
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: inputSchema2,
5882
- outputSchema: outputSchema2,
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, import_editor_elements17.getWidgetsCache)()?.[elementType];
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, import_editor_elements17.getContainer)(elementId);
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 (!import_editor_props9.Schema.isPropKeyConfigurable(propertyName)) {
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, import_editor_mcp5.dispatchMcpStylesAppliedEvent)({ styleValue });
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 import_editor_elements18 = require("@elementor/editor-elements");
5988
- var import_editor_props10 = require("@elementor/editor-props");
5989
- var import_schema5 = require("@elementor/schema");
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: import_schema5.z.string()
5117
+ elementId: import_schema4.z.string()
5992
5118
  };
5993
- var outputSchema3 = {
5994
- properties: import_schema5.z.record(import_schema5.z.string(), import_schema5.z.any()).describe("A record mapping PropTypes to their corresponding PropValues"),
5995
- style: import_schema5.z.record(import_schema5.z.string(), import_schema5.z.any()).describe("A record mapping StyleSchema properties to their corresponding PropValues"),
5996
- childElements: import_schema5.z.array(
5997
- import_schema5.z.object({
5998
- id: import_schema5.z.string(),
5999
- elementType: import_schema5.z.string(),
6000
- childElements: import_schema5.z.array(import_schema5.z.any()).describe("An array of child element IDs, when applicable, same structure recursively")
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: outputSchema3,
5146
+ outputSchema: outputSchema2,
6021
5147
  handler: async ({ elementId }) => {
6022
- const element = (0, import_editor_elements18.getContainer)(elementId);
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, import_editor_elements18.getWidgetsCache)()?.[elementType];
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, import_editor_elements18.getWidgetsCache)()?.[elementType]?.atomic_props_schema;
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
- import_editor_props10.Schema.configurableKeys(propSchema).forEach((key) => {
5171
+ import_editor_props8.Schema.configurableKeys(propSchema).forEach((key) => {
6046
5172
  propValues[key] = structuredClone(elementRawSettings.get(key));
6047
5173
  });
6048
- const elementStyles = (0, import_editor_elements18.getElementStyles)(elementId) || {};
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
- import_editor_props11.Schema.setDynamicTagNamesResolver(getDynamicTagNamesByCategories);
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
- initBuildCompositionsTool(reg);
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 import_editor_elements19 = require("@elementor/editor-elements");
5331
+ var import_editor_elements16 = require("@elementor/editor-elements");
6205
5332
  var import_editor_notifications3 = require("@elementor/editor-notifications");
6206
- var import_editor_v1_adapters22 = require("@elementor/editor-v1-adapters");
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, import_editor_v1_adapters22.blockCommand)({
5336
+ (0, import_editor_v1_adapters21.blockCommand)({
6210
5337
  command: "document/elements/paste",
6211
5338
  condition: blockLinkInLinkPaste
6212
5339
  });
6213
- (0, import_editor_v1_adapters22.blockCommand)({
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, import_editor_elements19.isElementAnchored)(src.id) || !!(0, import_editor_elements19.getAnchoredDescendantId)(src.id) : false;
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, import_editor_elements19.isElementAnchored)(target.id) || !!(0, import_editor_elements19.getAnchoredAncestorId)(target.id) : false;
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 import_editor_elements22 = require("@elementor/editor-elements");
6288
- var import_editor_props13 = require("@elementor/editor-props");
6289
- var import_editor_v1_adapters24 = require("@elementor/editor-v1-adapters");
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 import_editor_elements20 = require("@elementor/editor-elements");
6293
- var import_editor_props12 = require("@elementor/editor-props");
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 === import_editor_props12.CLASSES_PROP_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, import_editor_elements20.getWidgetsCache)();
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, import_editor_elements20.getElementLabel)(containers[0].id);
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 import_editor_elements21 = require("@elementor/editor-elements");
5461
+ var import_editor_elements18 = require("@elementor/editor-elements");
6335
5462
  var import_editor_styles_repository4 = require("@elementor/editor-styles-repository");
6336
- var import_editor_v1_adapters23 = require("@elementor/editor-v1-adapters");
5463
+ var import_editor_v1_adapters22 = require("@elementor/editor-v1-adapters");
6337
5464
  var import_i18n6 = require("@wordpress/i18n");
6338
- var undoablePasteElementStyle = () => (0, import_editor_v1_adapters23.undoable)(
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, import_editor_elements21.getElementStyles)(container.id);
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, import_editor_elements21.updateElementStyle)({
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, import_editor_elements21.createElementStyle)({
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, import_editor_elements21.deleteElementStyle)(container.id, revertData.styleId);
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, import_editor_elements21.createElementStyle)({
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, import_editor_v1_adapters24.blockCommand)({
5541
+ (0, import_editor_v1_adapters23.blockCommand)({
6415
5542
  command: "document/elements/paste-style",
6416
5543
  condition: hasAtomicWidgets
6417
5544
  });
6418
- (0, import_editor_v1_adapters24.__privateListenTo)(
6419
- (0, import_editor_v1_adapters24.commandStartEvent)("document/elements/paste-style"),
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, import_editor_elements22.getContainer)(clipboardElement.id);
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, import_editor_elements22.getElementSetting)(clipboardContainer.id, classesProp);
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, import_editor_elements22.getElementSetting)(container.id, classesProp);
6460
- const currentClasses = import_editor_props13.classesPropTypeUtil.extract(classesSetting) ?? [];
6461
- const newClasses = import_editor_props13.classesPropTypeUtil.create(Array.from(/* @__PURE__ */ new Set([...classes, ...currentClasses])));
6462
- (0, import_editor_elements22.updateElementSettings)({
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 import_editor_v1_adapters26 = require("@elementor/editor-v1-adapters");
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 import_editor_elements23 = require("@elementor/editor-elements");
5600
+ var import_editor_elements20 = require("@elementor/editor-elements");
6474
5601
  var import_editor_styles_repository5 = require("@elementor/editor-styles-repository");
6475
- var import_editor_v1_adapters25 = require("@elementor/editor-v1-adapters");
5602
+ var import_editor_v1_adapters24 = require("@elementor/editor-v1-adapters");
6476
5603
  var import_i18n7 = require("@wordpress/i18n");
6477
- var undoableResetElementStyle = () => (0, import_editor_v1_adapters25.undoable)(
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, import_editor_elements23.getElementStyles)(elementId);
5609
+ const containerStyles = (0, import_editor_elements20.getElementStyles)(elementId);
6483
5610
  Object.keys(containerStyles ?? {}).forEach(
6484
- (styleId) => (0, import_editor_elements23.deleteElementStyle)(elementId, styleId)
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, import_editor_elements23.createElementStyle)({
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, import_editor_v1_adapters26.blockCommand)({
5648
+ (0, import_editor_v1_adapters25.blockCommand)({
6522
5649
  command: "document/elements/reset-style",
6523
5650
  condition: hasAtomicWidgets
6524
5651
  });
6525
- (0, import_editor_v1_adapters26.__privateListenTo)(
6526
- (0, import_editor_v1_adapters26.commandStartEvent)("document/elements/reset-style"),
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, import_editor_mcp6.getMCPByDomain)("canvas", {
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 import_editor_v1_adapters27 = require("@elementor/editor-v1-adapters");
5802
+ var import_editor_v1_adapters26 = require("@elementor/editor-v1-adapters");
6676
5803
  function useCanvasDocument() {
6677
- return (0, import_editor_v1_adapters27.__privateUseListenTo)((0, import_editor_v1_adapters27.commandEndEvent)("editor/documents/attach-preview"), () => (0, import_editor_v1_adapters27.getCanvasIframeDocument)());
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 import_editor_elements24 = require("@elementor/editor-elements");
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, import_editor_elements24.getContainer)(elementId)?.view;
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,