@elementor/editor-canvas 4.2.0-beta1 → 4.3.0-1000

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/dist/index.d.mts +1 -1
  2. package/dist/index.d.ts +1 -1
  3. package/dist/index.js +484 -1282
  4. package/dist/index.mjs +350 -1161
  5. package/package.json +22 -22
  6. package/src/__tests__/parse-xml.ts +2 -0
  7. package/src/components/__tests__/elements-overlays.test.tsx +7 -0
  8. package/src/components/elements-overlays.tsx +13 -10
  9. package/src/components/grid-outline/__tests__/grid-outline-overlay.test.tsx +13 -15
  10. package/src/components/grid-outline/grid-outline-overlay.tsx +3 -4
  11. package/src/components/outline-overlay.tsx +9 -2
  12. package/src/form-structure/__tests__/form-structure-utils.test.ts +218 -0
  13. package/src/form-structure/enforce-form-ancestor-commands.ts +11 -4
  14. package/src/form-structure/utils.ts +47 -0
  15. package/src/index.ts +1 -1
  16. package/src/legacy/__tests__/init-legacy-views.test.ts +1 -1
  17. package/src/mcp/canvas-mcp.ts +4 -2
  18. package/src/mcp/resources/__tests__/available-widgets-resource.test.ts +76 -0
  19. package/src/mcp/resources/__tests__/dynamic-tags-resource.test.ts +27 -37
  20. package/src/mcp/resources/__tests__/widgets-schema-resource.test.ts +79 -76
  21. package/src/mcp/resources/available-widgets-resource.ts +31 -40
  22. package/src/mcp/resources/best-practices-resource.ts +34 -0
  23. package/src/mcp/resources/dynamic-tags-resource.ts +28 -29
  24. package/src/mcp/resources/widgets-schema-resource.ts +34 -177
  25. package/src/mcp/tools/build-composition/tool.ts +108 -212
  26. package/src/sync/element-added-event.ts +8 -0
  27. package/src/types/element-overlay.ts +2 -0
  28. package/src/utils/__tests__/grid-outline-utils.test.ts +39 -0
  29. package/src/utils/__tests__/outline-offset-utils.test.ts +39 -0
  30. package/src/utils/grid-outline-utils.ts +13 -2
  31. package/src/utils/outline-offset-utils.ts +11 -0
  32. package/src/composition-builder/__tests__/composition-builder.test.ts +0 -352
  33. package/src/composition-builder/composition-builder.ts +0 -338
  34. package/src/composition-builder/utils/__tests__/required-children-enforcer.test.ts +0 -79
  35. package/src/composition-builder/utils/__tests__/required-default-child-tags.test.ts +0 -35
  36. package/src/composition-builder/utils/required-children-enforcer.ts +0 -56
  37. package/src/composition-builder/utils/required-default-child-tags.ts +0 -22
  38. package/src/mcp/resources/best-practices.ts +0 -159
  39. package/src/mcp/resources/build-llm-guidance.ts +0 -110
  40. package/src/mcp/tools/build-composition/__tests__/xml-leaf-wrapper.test.ts +0 -117
  41. package/src/mcp/tools/build-composition/prompt.ts +0 -167
  42. package/src/mcp/tools/build-composition/schema.ts +0 -42
  43. package/src/mcp/tools/build-composition/xml-leaf-wrapper.ts +0 -68
  44. package/src/mcp/utils/__tests__/get-composition-target-container.test.ts +0 -59
  45. 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-widgets",
85
+ input: {}
86
+ });
87
+ return (data.data ?? []).map((widget) => widget.type);
88
+ };
89
+ var fetchWidgetSchema = async (widgetType) => {
90
+ const { data } = await (0, import_http_client.httpService)().post(MCP_PROXY_URL, {
91
+ tool: "get-widget-schema",
92
+ input: { widget_type: widgetType }
93
+ });
94
+ return data.data ?? {};
95
+ };
232
96
  var initWidgetsSchemaResource = (reg) => {
233
97
  const { resource } = reg;
234
- resource(
235
- "styles-best-practices",
236
- BEST_PRACTICES_URI,
237
- {
238
- description: "Styling best practices"
239
- },
240
- async () => {
241
- return {
242
- contents: [
243
- {
244
- uri: BEST_PRACTICES_URI,
245
- text: `# Styling best practices
246
- Prefer using "em" and "rem" values for text-related sizes, padding and spacing. Use percentages for dynamic sizing relative to parent containers.
247
- This flexboxes are by default "flex" with "stretch" alignment. To ensure proper layout, define the "justify-content" and "align-items" as in the schema.
248
-
249
- Styling is provided as raw CSS. The css string must follow standard CSS syntax, with properties and values separated by semicolons, no selectors, or nesting rules allowed.
250
-
251
- ** CRITICAL - VARIABLES **
252
- When using global variables, ensure that the variables are defined in the ${"elementor://global-variables"} resource.
253
- Variables from the user context ARE NOT SUPPORTED AND WILL RESOLVE IN ERROR.
254
-
255
- `
256
- }
257
- ]
258
- };
259
- }
260
- );
261
98
  resource(
262
99
  "widget-schema-by-type",
263
100
  new import_editor_mcp.ResourceTemplate(WIDGET_SCHEMA_URI, {
264
- list: () => {
265
- const 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,8 +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");
873
- var import_editor_props2 = require("@elementor/editor-props");
678
+ var import_editor_elements2 = require("@elementor/editor-elements");
874
679
  var import_ui2 = require("@elementor/ui");
875
680
  var import_react11 = require("@floating-ui/react");
876
681
 
@@ -971,6 +776,16 @@ var useHasOverlapping = () => {
971
776
  return hasOverlapping;
972
777
  };
973
778
 
779
+ // src/utils/outline-offset-utils.ts
780
+ var THIN_ELEMENT_MAX_HEIGHT_PX = 1;
781
+ var SMALLER_OUTLINE_OFFSET_WIDGET_TYPES = /* @__PURE__ */ new Set(["e-form-input"]);
782
+ function shouldUseSmallerOutlineOffset(element, widgetType) {
783
+ if (element.offsetHeight <= THIN_ELEMENT_MAX_HEIGHT_PX) {
784
+ return true;
785
+ }
786
+ return widgetType !== void 0 && SMALLER_OUTLINE_OFFSET_WIDGET_TYPES.has(widgetType);
787
+ }
788
+
974
789
  // src/components/outline-overlay.tsx
975
790
  var CANVAS_WRAPPER_ID = "elementor-preview-responsive-wrapper";
976
791
  var OverlayBox = (0, import_ui.styled)(import_ui.Box, {
@@ -982,12 +797,18 @@ var OverlayBox = (0, import_ui.styled)(import_ui.Box, {
982
797
  pointerEvents: "none"
983
798
  })
984
799
  );
985
- var OutlineOverlay = ({ element, isSelected, id, isGlobal = false }) => {
800
+ var OutlineOverlay = ({
801
+ element,
802
+ isSelected,
803
+ id,
804
+ isGlobal = false,
805
+ widgetType
806
+ }) => {
986
807
  const { context, floating, isVisible } = useFloatingOnElement({ element, isSelected });
987
808
  const { getFloatingProps, getReferenceProps } = (0, import_react9.useInteractions)([(0, import_react9.useHover)(context)]);
988
809
  const hasOverlapping = useHasOverlapping();
989
810
  useBindReactPropsToElement(element, getReferenceProps);
990
- const isSmallerOffset = element.offsetHeight <= 1;
811
+ const isSmallerOffset = shouldUseSmallerOutlineOffset(element, widgetType);
991
812
  return isVisible && !hasOverlapping && /* @__PURE__ */ React.createElement(import_react9.FloatingPortal, { id: CANVAS_WRAPPER_ID }, /* @__PURE__ */ React.createElement(
992
813
  OverlayBox,
993
814
  {
@@ -1143,8 +964,8 @@ function GridOutline({ element, tracks, width, height }) {
1143
964
 
1144
965
  // src/components/grid-outline/grid-outline-overlay.tsx
1145
966
  var GridOutlineOverlay = ({ element, id, isSelected }) => {
1146
- const { settings } = (0, import_editor_elements4.useSelectedElementSettings)();
1147
- const enabled = import_editor_props2.booleanPropTypeUtil.extract(settings?.grid_outline);
967
+ const settings = (0, import_editor_elements2.useElementEditorSettings)(id);
968
+ const enabled = settings?.grid_outline;
1148
969
  const rect = useElementRect(element);
1149
970
  const tracks = useGridTracks(element, rect);
1150
971
  const { floating } = useFloatingOnElement({ element, isSelected });
@@ -1167,9 +988,10 @@ var GridOutlineOverlay = ({ element, id, isSelected }) => {
1167
988
  };
1168
989
 
1169
990
  // src/components/elements-overlays.tsx
991
+ var hasGridStyleDisplay = (element) => {
992
+ return element.computedStyleMap().get("display")?.toString() === "grid";
993
+ };
1170
994
  var ELEMENTS_DATA_ATTR = "atomic";
1171
- var E_GRID_TYPE = "e-grid";
1172
- var isGridElement = (element) => [element.dataset.eType, element.dataset.element_type].includes(E_GRID_TYPE);
1173
995
  var overlayRegistry = [
1174
996
  {
1175
997
  component: OutlineOverlay,
@@ -1177,15 +999,15 @@ var overlayRegistry = [
1177
999
  },
1178
1000
  {
1179
1001
  component: GridEmptyCellPositioner,
1180
- shouldRender: ({ element }) => isGridElement(element)
1002
+ shouldRender: ({ element }) => hasGridStyleDisplay(element)
1181
1003
  },
1182
1004
  {
1183
1005
  component: GridOutlineOverlay,
1184
- shouldRender: ({ element, isSelected }) => isSelected && isGridElement(element)
1006
+ shouldRender: ({ isSelected, element }) => isSelected && hasGridStyleDisplay(element)
1185
1007
  }
1186
1008
  ];
1187
1009
  function ElementsOverlays() {
1188
- const selected = (0, import_editor_elements5.useSelectedElement)();
1010
+ const selected = (0, import_editor_elements3.useSelectedElement)();
1189
1011
  const elements = useElementsDom();
1190
1012
  const currentEditMode = (0, import_editor_v1_adapters3.useEditMode)();
1191
1013
  const isEditMode = currentEditMode === "edit";
@@ -1194,17 +1016,18 @@ function ElementsOverlays() {
1194
1016
  if (!isActive) {
1195
1017
  return null;
1196
1018
  }
1197
- return elements.map(({ id, domElement, isGlobal }) => {
1019
+ return elements.map(({ id, domElement, isGlobal, widgetType }) => {
1198
1020
  const isSelected = selected.element?.id === id;
1199
1021
  return overlayRegistry.map(
1200
- ({ shouldRender, component: Overlay }, index) => shouldRender({ id, element: domElement, isSelected }) && /* @__PURE__ */ React7.createElement(
1022
+ ({ shouldRender, component: Overlay }, index) => shouldRender({ id, element: domElement, isSelected, widgetType }) && /* @__PURE__ */ React7.createElement(
1201
1023
  Overlay,
1202
1024
  {
1203
1025
  key: `${id}-${index}`,
1204
1026
  id,
1205
1027
  element: domElement,
1206
1028
  isSelected,
1207
- isGlobal
1029
+ isGlobal,
1030
+ widgetType
1208
1031
  }
1209
1032
  )
1210
1033
  );
@@ -1214,10 +1037,11 @@ function useElementsDom() {
1214
1037
  return (0, import_editor_v1_adapters3.__privateUseListenTo)(
1215
1038
  [(0, import_editor_v1_adapters3.windowEvent)("elementor/editor/element-rendered"), (0, import_editor_v1_adapters3.windowEvent)("elementor/editor/element-destroyed")],
1216
1039
  () => {
1217
- 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) => ({
1218
1041
  id: element.id,
1219
1042
  domElement: element.view?.getDomElement?.()?.get?.(0),
1220
- isGlobal: element.model.get("isGlobal") ?? false
1043
+ isGlobal: element.model.get("isGlobal") ?? false,
1044
+ widgetType: element.model.get("widgetType")
1221
1045
  })).filter((item) => !!item.domElement);
1222
1046
  }
1223
1047
  );
@@ -1467,7 +1291,7 @@ var import_editor_styles = require("@elementor/editor-styles");
1467
1291
  var import_editor_v1_adapters8 = require("@elementor/editor-v1-adapters");
1468
1292
 
1469
1293
  // src/renderers/create-props-resolver.ts
1470
- var import_editor_props3 = require("@elementor/editor-props");
1294
+ var import_editor_props = require("@elementor/editor-props");
1471
1295
 
1472
1296
  // src/renderers/multi-props.ts
1473
1297
  var isMultiProps = (propValue) => {
@@ -1505,7 +1329,7 @@ function createPropsResolver({ transformers, schema: initialSchema, onPropResolv
1505
1329
  if (value === null || value === void 0) {
1506
1330
  return null;
1507
1331
  }
1508
- if (!(0, import_editor_props3.isTransformable)(value)) {
1332
+ if (!(0, import_editor_props.isTransformable)(value)) {
1509
1333
  return value;
1510
1334
  }
1511
1335
  if (depth > TRANSFORM_DEPTH_LIMIT) {
@@ -1563,13 +1387,13 @@ function createPropsResolver({ transformers, schema: initialSchema, onPropResolv
1563
1387
  }
1564
1388
 
1565
1389
  // src/renderers/enqueue-font-from-style-prop.ts
1566
- var import_editor_props4 = require("@elementor/editor-props");
1390
+ var import_editor_props2 = require("@elementor/editor-props");
1567
1391
  var maybeEnqueueFontFromStyleProp = (propType, propValue, enqueue) => {
1568
- if (!(0, import_editor_props4.isTransformable)(propValue) || propValue.disabled) {
1392
+ if (!(0, import_editor_props2.isTransformable)(propValue) || propValue.disabled) {
1569
1393
  return;
1570
1394
  }
1571
1395
  const typeKey = propType.kind === "union" ? propValue.$$type : propType.key;
1572
- const propTypeUtil = (0, import_editor_props4.getPropSchemaFromCache)(typeKey);
1396
+ const propTypeUtil = (0, import_editor_props2.getPropSchemaFromCache)(typeKey);
1573
1397
  if (!propTypeUtil || !("getEnqueueFontFamily" in propTypeUtil) || typeof propTypeUtil.getEnqueueFontFamily !== "function") {
1574
1398
  return;
1575
1399
  }
@@ -1965,7 +1789,7 @@ var import_editor_v1_adapters11 = require("@elementor/editor-v1-adapters");
1965
1789
  var import_i18n = require("@wordpress/i18n");
1966
1790
 
1967
1791
  // src/form-structure/utils.ts
1968
- var import_editor_elements6 = require("@elementor/editor-elements");
1792
+ var import_editor_elements4 = require("@elementor/editor-elements");
1969
1793
  var FORM_ELEMENT_TYPE = "e-form";
1970
1794
  var FORM_FIELD_ELEMENT_TYPES = /* @__PURE__ */ new Set([
1971
1795
  "e-form-input",
@@ -1995,10 +1819,10 @@ function isWithinForm(element) {
1995
1819
  return isElementWithinFormSelector(element);
1996
1820
  }
1997
1821
  function hasElementType(element, type) {
1998
- 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);
1999
1823
  }
2000
1824
  function hasElementTypes(element, types) {
2001
- return (0, import_editor_elements6.getAllDescendants)(element).some((item) => {
1825
+ return (0, import_editor_elements4.getAllDescendants)(element).some((item) => {
2002
1826
  const itemType = getElementType(item);
2003
1827
  return itemType ? types.has(itemType) : false;
2004
1828
  });
@@ -2056,7 +1880,8 @@ function blockFormFieldCreate(args) {
2056
1880
  if (!elementType || !FORM_FIELD_ELEMENT_TYPES.has(elementType)) {
2057
1881
  return false;
2058
1882
  }
2059
- if (!isWithinForm(args.container)) {
1883
+ const containers = args.containers ?? [args.container];
1884
+ if (containers.some((container) => !isWithinForm(container))) {
2060
1885
  handleBlockedFormField();
2061
1886
  return true;
2062
1887
  }
@@ -2064,10 +1889,10 @@ function blockFormFieldCreate(args) {
2064
1889
  }
2065
1890
  function blockFormFieldMove(args) {
2066
1891
  const { containers = [args.container], target } = args;
2067
- const hasFormFieldElement = containers.some(
2068
- (container) => container ? hasElementTypes(container, FORM_FIELD_ELEMENT_TYPES) : false
1892
+ const hasLooseFormFields = containers.some(
1893
+ (container) => container ? !hasElementType(container, FORM_ELEMENT_TYPE) && hasElementTypes(container, FORM_FIELD_ELEMENT_TYPES) : false
2069
1894
  );
2070
- if (hasFormFieldElement && !isWithinForm(target) && !movedContainersIncludeAtomicFormRoot(containers)) {
1895
+ if (hasLooseFormFields && !isWithinForm(target) && !movedContainersIncludeAtomicFormRoot(containers)) {
2071
1896
  handleBlockedFormField();
2072
1897
  return true;
2073
1898
  }
@@ -2738,7 +2563,7 @@ function initStyleTransformers() {
2738
2563
  }
2739
2564
 
2740
2565
  // src/legacy/init-legacy-views.ts
2741
- var import_editor_elements10 = require("@elementor/editor-elements");
2566
+ var import_editor_elements8 = require("@elementor/editor-elements");
2742
2567
  var import_editor_v1_adapters14 = require("@elementor/editor-v1-adapters");
2743
2568
 
2744
2569
  // src/renderers/create-dom-renderer.ts
@@ -2867,25 +2692,25 @@ function createElementViewClassDeclaration() {
2867
2692
  }
2868
2693
 
2869
2694
  // src/legacy/create-nested-templated-element-type.ts
2870
- var import_editor_elements8 = require("@elementor/editor-elements");
2695
+ var import_editor_elements6 = require("@elementor/editor-elements");
2871
2696
 
2872
2697
  // src/legacy/create-pending-element.ts
2873
- var import_editor_elements7 = require("@elementor/editor-elements");
2698
+ var import_editor_elements5 = require("@elementor/editor-elements");
2874
2699
  function createPendingElement(wrapperView, data, options = {}) {
2875
2700
  const parentContainer = wrapperView.getContainer();
2876
2701
  const model = { ...data };
2877
2702
  if (!model.id) {
2878
- model.id = (0, import_editor_elements7.generateElementId)();
2703
+ model.id = (0, import_editor_elements5.generateElementId)();
2879
2704
  }
2880
2705
  if (!model.elements) {
2881
2706
  model.elements = [];
2882
2707
  }
2883
- const added = (0, import_editor_elements7.addModelToParent)(parentContainer.id, model, options);
2708
+ const added = (0, import_editor_elements5.addModelToParent)(parentContainer.id, model, options);
2884
2709
  if (!added) {
2885
2710
  return void 0;
2886
2711
  }
2887
2712
  const childId = model.id;
2888
- const childModel = (0, import_editor_elements7.findModelInDocument)(childId);
2713
+ const childModel = (0, import_editor_elements5.findModelInDocument)(childId);
2889
2714
  if (!childModel) {
2890
2715
  return void 0;
2891
2716
  }
@@ -2896,7 +2721,7 @@ function createPendingElement(wrapperView, data, options = {}) {
2896
2721
  model: childModel,
2897
2722
  view: void 0,
2898
2723
  lookup() {
2899
- return (0, import_editor_elements7.getContainer)(childId) ?? pendingContainer;
2724
+ return (0, import_editor_elements5.getContainer)(childId) ?? pendingContainer;
2900
2725
  }
2901
2726
  };
2902
2727
  wrapperView.once("render", () => {
@@ -2909,7 +2734,7 @@ function createPendingElement(wrapperView, data, options = {}) {
2909
2734
  }
2910
2735
  function selectChildWhenWrapperRenders(wrapperView, childId) {
2911
2736
  wrapperView.once("render", () => {
2912
- const childContainer = (0, import_editor_elements7.getContainer)(childId);
2737
+ const childContainer = (0, import_editor_elements5.getContainer)(childId);
2913
2738
  if (childContainer?.model?.trigger) {
2914
2739
  childContainer.model.trigger("request:edit");
2915
2740
  return;
@@ -3176,7 +3001,7 @@ function createNestedTemplatedElementView({
3176
3001
  this._initAlpine();
3177
3002
  });
3178
3003
  this.model.trigger("render:complete");
3179
- window.dispatchEvent(new CustomEvent(import_editor_elements8.ELEMENT_STYLE_CHANGE_EVENT));
3004
+ window.dispatchEvent(new CustomEvent(import_editor_elements6.ELEMENT_STYLE_CHANGE_EVENT));
3180
3005
  },
3181
3006
  async _renderTemplate() {
3182
3007
  const model = this.model;
@@ -3424,8 +3249,8 @@ var import_client = require("react-dom/client");
3424
3249
 
3425
3250
  // src/legacy/replacements/inline-editing/inline-editing-elements.tsx
3426
3251
  var React11 = __toESM(require("react"));
3427
- var import_editor_elements9 = require("@elementor/editor-elements");
3428
- var import_editor_props6 = require("@elementor/editor-props");
3252
+ var import_editor_elements7 = require("@elementor/editor-elements");
3253
+ var import_editor_props4 = require("@elementor/editor-props");
3429
3254
  var import_editor_v1_adapters13 = require("@elementor/editor-v1-adapters");
3430
3255
  var import_i18n3 = require("@wordpress/i18n");
3431
3256
 
@@ -3702,11 +3527,11 @@ var InlineEditingToolbar = ({ anchor, editor, id }) => {
3702
3527
  };
3703
3528
 
3704
3529
  // src/legacy/replacements/inline-editing/inline-editing-eligibility.ts
3705
- var import_editor_props5 = require("@elementor/editor-props");
3530
+ var import_editor_props3 = require("@elementor/editor-props");
3706
3531
  var hasKey = (propType) => {
3707
3532
  return "key" in propType;
3708
3533
  };
3709
- var TEXT_PROP_TYPE_KEYS = /* @__PURE__ */ new Set([import_editor_props5.htmlV3PropTypeUtil.key, import_editor_props5.stringPropTypeUtil.key]);
3534
+ var TEXT_PROP_TYPE_KEYS = /* @__PURE__ */ new Set([import_editor_props3.htmlV3PropTypeUtil.key, import_editor_props3.stringPropTypeUtil.key]);
3710
3535
  var isCoreTextPropTypeKey = (key) => {
3711
3536
  return TEXT_PROP_TYPE_KEYS.has(key);
3712
3537
  };
@@ -3726,7 +3551,7 @@ var isInlineEditingAllowed = ({ rawValue, propTypeFromSchema }) => {
3726
3551
  if (rawValue === null || rawValue === void 0) {
3727
3552
  return isAllowedBySchema(propTypeFromSchema);
3728
3553
  }
3729
- return import_editor_props5.htmlV3PropTypeUtil.isValid(rawValue) || import_editor_props5.stringPropTypeUtil.isValid(rawValue);
3554
+ return import_editor_props3.htmlV3PropTypeUtil.isValid(rawValue) || import_editor_props3.stringPropTypeUtil.isValid(rawValue);
3730
3555
  };
3731
3556
 
3732
3557
  // src/legacy/replacements/inline-editing/inline-editing-elements.tsx
@@ -3800,7 +3625,7 @@ var InlineEditingReplacement = class extends ReplacementBase {
3800
3625
  return INLINE_EDITING_PROPERTY_PER_TYPE[this.type] ?? "";
3801
3626
  }
3802
3627
  getInlineEditablePropType() {
3803
- const propSchema = (0, import_editor_elements9.getElementType)(this.type)?.propsSchema;
3628
+ const propSchema = (0, import_editor_elements7.getElementType)(this.type)?.propsSchema;
3804
3629
  const propertyName = this.getInlineEditablePropertyName();
3805
3630
  return propSchema?.[propertyName] ?? null;
3806
3631
  }
@@ -3811,15 +3636,15 @@ var InlineEditingReplacement = class extends ReplacementBase {
3811
3636
  }
3812
3637
  getExtractedContentValue() {
3813
3638
  const propValue = this.getInlineEditablePropValue();
3814
- const extracted = import_editor_props6.htmlV3PropTypeUtil.extract(propValue);
3815
- return import_editor_props6.stringPropTypeUtil.extract(extracted?.content ?? null) ?? "";
3639
+ const extracted = import_editor_props4.htmlV3PropTypeUtil.extract(propValue);
3640
+ return import_editor_props4.stringPropTypeUtil.extract(extracted?.content ?? null) ?? "";
3816
3641
  }
3817
3642
  setContentValue(value) {
3818
3643
  const settingKey = this.getInlineEditablePropertyName();
3819
3644
  const html = value || "";
3820
- const parsed = (0, import_editor_props6.parseHtmlChildren)(html);
3821
- const valueToSave = import_editor_props6.htmlV3PropTypeUtil.create({
3822
- content: parsed.content ? import_editor_props6.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,
3823
3648
  children: parsed.children
3824
3649
  });
3825
3650
  (0, import_editor_v1_adapters13.undoable)(
@@ -3834,7 +3659,7 @@ var InlineEditingReplacement = class extends ReplacementBase {
3834
3659
  }
3835
3660
  },
3836
3661
  {
3837
- title: (0, import_editor_elements9.getElementLabel)(this.id),
3662
+ title: (0, import_editor_elements7.getElementLabel)(this.id),
3838
3663
  // translators: %s is the name of the property that was edited.
3839
3664
  subtitle: (0, import_i18n3.__)("%s edited", "elementor").replace(
3840
3665
  "%s",
@@ -3850,7 +3675,7 @@ var InlineEditingReplacement = class extends ReplacementBase {
3850
3675
  return null;
3851
3676
  }
3852
3677
  if (propType.kind === "union") {
3853
- const textKeys = [import_editor_props6.htmlV3PropTypeUtil.key, import_editor_props6.stringPropTypeUtil.key];
3678
+ const textKeys = [import_editor_props4.htmlV3PropTypeUtil.key, import_editor_props4.stringPropTypeUtil.key];
3854
3679
  for (const key of textKeys) {
3855
3680
  if (propType.prop_types[key]) {
3856
3681
  return key;
@@ -3867,7 +3692,7 @@ var InlineEditingReplacement = class extends ReplacementBase {
3867
3692
  (0, import_editor_v1_adapters13.__privateRunCommandSync)(
3868
3693
  "document/elements/set-settings",
3869
3694
  {
3870
- container: (0, import_editor_elements9.getContainer)(this.id),
3695
+ container: (0, import_editor_elements7.getContainer)(this.id),
3871
3696
  settings: {
3872
3697
  [key]: value
3873
3698
  }
@@ -3879,10 +3704,10 @@ var InlineEditingReplacement = class extends ReplacementBase {
3879
3704
  getExpectedTag() {
3880
3705
  const tagPropType = this.getTagPropType();
3881
3706
  const tagSettingKey = "tag";
3882
- return import_editor_props6.stringPropTypeUtil.extract(this.getSetting(tagSettingKey) ?? null) ?? import_editor_props6.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;
3883
3708
  }
3884
3709
  getTagPropType() {
3885
- const propsSchema = (0, import_editor_elements9.getElementType)(this.type)?.propsSchema;
3710
+ const propsSchema = (0, import_editor_elements7.getElementType)(this.type)?.propsSchema;
3886
3711
  if (!propsSchema?.tag) {
3887
3712
  return null;
3888
3713
  }
@@ -4045,7 +3870,7 @@ function registerElementType(type, elementTypeGenerator) {
4045
3870
  }
4046
3871
  function initLegacyViews() {
4047
3872
  (0, import_editor_v1_adapters14.__privateListenTo)((0, import_editor_v1_adapters14.v1ReadyEvent)(), () => {
4048
- const widgetsCache = (0, import_editor_elements10.getWidgetsCache)() ?? {};
3873
+ const widgetsCache = (0, import_editor_elements8.getWidgetsCache)() ?? {};
4049
3874
  const renderer = createDomRenderer();
4050
3875
  registerProPromotionTypes(widgetsCache);
4051
3876
  Object.keys(widgetsCache).forEach((type) => {
@@ -4054,7 +3879,7 @@ function initLegacyViews() {
4054
3879
  });
4055
3880
  }
4056
3881
  function registerElementInLegacyManager(type, renderer) {
4057
- const element = ((0, import_editor_elements10.getWidgetsCache)() ?? {})[type];
3882
+ const element = ((0, import_editor_elements8.getWidgetsCache)() ?? {})[type];
4058
3883
  if (!element?.atomic) {
4059
3884
  return;
4060
3885
  }
@@ -4106,7 +3931,7 @@ function createNestedTemplatedType(type, renderer, element) {
4106
3931
  }
4107
3932
 
4108
3933
  // src/legacy/tabs-model-extensions.ts
4109
- var import_editor_props7 = require("@elementor/editor-props");
3934
+ var import_editor_props5 = require("@elementor/editor-props");
4110
3935
  var tabModelExtensions = {
4111
3936
  modifyDefaultChildren(elements) {
4112
3937
  if (!Array.isArray(elements) || elements.length === 0) {
@@ -4122,8 +3947,8 @@ var tabModelExtensions = {
4122
3947
  ...paragraphElement,
4123
3948
  settings: {
4124
3949
  ...paragraphElement.settings,
4125
- paragraph: import_editor_props7.htmlV3PropTypeUtil.create({
4126
- content: import_editor_props7.stringPropTypeUtil.create(`Tab ${position}`),
3950
+ paragraph: import_editor_props5.htmlV3PropTypeUtil.create({
3951
+ content: import_editor_props5.stringPropTypeUtil.create(`Tab ${position}`),
4127
3952
  children: []
4128
3953
  })
4129
3954
  }
@@ -4136,43 +3961,41 @@ function initTabsModelExtensions() {
4136
3961
  }
4137
3962
 
4138
3963
  // src/mcp/canvas-mcp.ts
4139
- var import_editor_props12 = require("@elementor/editor-props");
3964
+ var import_editor_props9 = require("@elementor/editor-props");
4140
3965
 
4141
3966
  // src/mcp/resources/available-widgets-resource.ts
4142
- 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";
4143
3969
  var AVAILABLE_WIDGETS_URI = "elementor://context/available-widgets";
4144
3970
  var AVAILABLE_WIDGETS_URI_V4 = "elementor://context/available-widgets/v4";
4145
- var initAvailableWidgetsResource = (reg) => {
4146
- const { resource, sendResourceUpdated } = reg;
4147
- const buildContents = (uri, filterFunction = () => true) => {
4148
- const widgets = getAvailableWidgets().filter(filterFunction);
4149
- return {
4150
- contents: [
4151
- {
4152
- uri,
4153
- mimeType: "application/json",
4154
- text: JSON.stringify(widgets, null, 2)
4155
- }
4156
- ]
4157
- };
4158
- };
4159
- const notifyResourcesUpdated = () => {
4160
- sendResourceUpdated({
4161
- uri: AVAILABLE_WIDGETS_URI,
4162
- ...buildContents(AVAILABLE_WIDGETS_URI)
4163
- });
4164
- sendResourceUpdated({
4165
- uri: AVAILABLE_WIDGETS_URI_V4,
4166
- ...buildContents(AVAILABLE_WIDGETS_URI_V4, (w) => w.version === "v4")
4167
- });
3971
+ var fetchWidgets = async (version) => {
3972
+ const { data } = await (0, import_http_client3.httpService)().post(MCP_PROXY_URL2, {
3973
+ tool: "list-widgets",
3974
+ input: version ? { version } : {}
3975
+ });
3976
+ return data.data ?? [];
3977
+ };
3978
+ var buildContents = async (uri, version) => {
3979
+ const widgets = await fetchWidgets(version);
3980
+ return {
3981
+ contents: [
3982
+ {
3983
+ uri,
3984
+ mimeType: "application/json",
3985
+ text: JSON.stringify(widgets, null, 2)
3986
+ }
3987
+ ]
4168
3988
  };
3989
+ };
3990
+ var initAvailableWidgetsResource = (reg) => {
3991
+ const { resource } = reg;
4169
3992
  resource(
4170
3993
  "available-widgets-v4",
4171
3994
  AVAILABLE_WIDGETS_URI_V4,
4172
3995
  {
4173
3996
  description: "All registered v4 version widgets"
4174
3997
  },
4175
- async () => buildContents(AVAILABLE_WIDGETS_URI_V4, (w) => w.version === "v4")
3998
+ async () => buildContents(AVAILABLE_WIDGETS_URI_V4, "v4")
4176
3999
  );
4177
4000
  resource(
4178
4001
  "available-widgets",
@@ -4182,22 +4005,41 @@ var initAvailableWidgetsResource = (reg) => {
4182
4005
  },
4183
4006
  async () => buildContents(AVAILABLE_WIDGETS_URI)
4184
4007
  );
4185
- const eventName = (0, import_editor_v1_adapters15.v1ReadyEvent)().name;
4186
- const onV1Ready = () => {
4187
- const widgets = getAvailableWidgets();
4188
- if (widgets.length === 0) {
4189
- 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
+ };
4190
4036
  }
4191
- window.removeEventListener(eventName, onV1Ready);
4192
- notifyResourcesUpdated();
4193
- };
4194
- window.addEventListener(eventName, onV1Ready);
4195
- onV1Ready();
4037
+ );
4196
4038
  };
4197
4039
 
4198
4040
  // src/mcp/resources/document-structure-resource.ts
4199
- var import_editor_elements11 = require("@elementor/editor-elements");
4200
- 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");
4201
4043
  var DOCUMENT_STRUCTURE_URI = "elementor://document/structure";
4202
4044
  var initDocumentStructureResource = (reg) => {
4203
4045
  const { resource, sendResourceUpdated } = reg;
@@ -4210,15 +4052,15 @@ var initDocumentStructureResource = (reg) => {
4210
4052
  sendResourceUpdated({ uri: DOCUMENT_STRUCTURE_URI });
4211
4053
  }
4212
4054
  };
4213
- (0, import_editor_v1_adapters16.__privateListenTo)(
4055
+ (0, import_editor_v1_adapters15.__privateListenTo)(
4214
4056
  [
4215
- (0, import_editor_v1_adapters16.commandEndEvent)("document/elements/create"),
4216
- (0, import_editor_v1_adapters16.commandEndEvent)("document/elements/delete"),
4217
- (0, import_editor_v1_adapters16.commandEndEvent)("document/elements/move"),
4218
- (0, import_editor_v1_adapters16.commandEndEvent)("document/elements/copy"),
4219
- (0, import_editor_v1_adapters16.commandEndEvent)("document/elements/paste"),
4220
- (0, import_editor_v1_adapters16.commandEndEvent)("editor/documents/attach-preview"),
4221
- (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")
4222
4064
  ],
4223
4065
  updateDocumentStructure
4224
4066
  );
@@ -4261,7 +4103,7 @@ function resolveElementVersion(element) {
4261
4103
  return "v4";
4262
4104
  }
4263
4105
  const widgetType = element.model?.attributes?.widgetType;
4264
- if (widgetType && (0, import_editor_elements11.getWidgetsCache)()?.[widgetType]?.atomic_props_schema) {
4106
+ if (widgetType && (0, import_editor_elements9.getWidgetsCache)()?.[widgetType]?.atomic_props_schema) {
4265
4107
  return "v4";
4266
4108
  }
4267
4109
  return "v3";
@@ -4288,84 +4130,15 @@ function extractElementData(element) {
4288
4130
  }
4289
4131
 
4290
4132
  // src/mcp/resources/dynamic-tags-resource.ts
4291
- var import_editor_props8 = require("@elementor/editor-props");
4292
-
4293
- // src/mcp/utils/resolve-dynamic-tag.ts
4294
- var import_editor_v1_adapters17 = require("@elementor/editor-v1-adapters");
4295
- var DYNAMIC_PROP_TYPE_KEY = "dynamic";
4296
- var OMITTED_DYNAMIC_SETTING_KEYS = ["fallback"];
4297
- var getAtomicDynamicTags = () => {
4298
- const config = (0, import_editor_v1_adapters17.getElementorConfig)();
4299
- return config.atomicDynamicTags?.tags ?? {};
4300
- };
4301
- var getDynamicTagNamesByCategories = (categories) => {
4302
- if (!categories.length) {
4303
- return [];
4304
- }
4305
- const wanted = new Set(categories);
4306
- return Object.values(getAtomicDynamicTags()).filter((tag) => tag.categories?.some((category) => wanted.has(category))).map((tag) => tag.name);
4307
- };
4308
- var dynamicTagLLMResolver = (value) => {
4309
- const input = value ?? {};
4310
- const tag = input.name ? getAtomicDynamicTags()[input.name] : void 0;
4311
- if (!tag) {
4312
- return {
4313
- $$type: DYNAMIC_PROP_TYPE_KEY,
4314
- value: { name: input.name ?? "", group: "", settings: {} }
4315
- };
4316
- }
4317
- return {
4318
- $$type: DYNAMIC_PROP_TYPE_KEY,
4319
- value: {
4320
- name: tag.name,
4321
- group: tag.group,
4322
- settings: buildStrictSettings(tag.props_schema ?? {}, input.settings ?? {})
4323
- }
4324
- };
4325
- };
4326
- var buildStrictSettings = (schema2, provided) => {
4327
- const settings = {};
4328
- for (const [key, propType] of Object.entries(schema2)) {
4329
- if (OMITTED_DYNAMIC_SETTING_KEYS.includes(key)) {
4330
- continue;
4331
- }
4332
- const resolved = provided[key] !== void 0 ? wrapSettingValue(provided[key], propType) : defaultSettingValue(propType);
4333
- if (resolved !== void 0 && resolved !== null) {
4334
- settings[key] = resolved;
4335
- }
4336
- }
4337
- return settings;
4338
- };
4339
- var wrapSettingValue = (raw, propType) => {
4340
- if (raw !== null && typeof raw === "object") {
4341
- return raw;
4342
- }
4343
- return propType.key ? { $$type: propType.key, value: raw } : raw;
4344
- };
4345
- var defaultSettingValue = (propType) => {
4346
- if (propType.initial_value !== null && propType.initial_value !== void 0) {
4347
- return propType.initial_value;
4348
- }
4349
- if (propType.default !== null && propType.default !== void 0) {
4350
- return wrapSettingValue(propType.default, propType);
4351
- }
4352
- return void 0;
4353
- };
4354
-
4355
- // src/mcp/resources/dynamic-tags-resource.ts
4133
+ var import_http_client5 = require("@elementor/http-client");
4356
4134
  var DYNAMIC_TAGS_URI = "elementor://dynamic-tags";
4357
- var settingsSchema = (propsSchema) => {
4358
- return Object.fromEntries(
4359
- Object.entries(propsSchema ?? {}).filter(([key]) => !OMITTED_DYNAMIC_SETTING_KEYS.includes(key)).map(([key, propType]) => [key, import_editor_props8.Schema.propTypeToJsonSchema(propType)])
4360
- );
4361
- };
4362
- var buildDynamicTagsList = () => {
4363
- return Object.values(getAtomicDynamicTags()).map((tag) => ({
4364
- name: tag.name,
4365
- label: tag.label,
4366
- categories: tag.categories,
4367
- settings: settingsSchema(tag.props_schema)
4368
- }));
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 ?? [];
4369
4142
  };
4370
4143
  var initDynamicTagsResource = (reg) => {
4371
4144
  const { resource } = reg;
@@ -4376,20 +4149,23 @@ var initDynamicTagsResource = (reg) => {
4376
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.`,
4377
4150
  mimeType: "application/json"
4378
4151
  },
4379
- async (uri) => ({
4380
- contents: [
4381
- {
4382
- uri: uri.href,
4383
- mimeType: "application/json",
4384
- text: JSON.stringify(buildDynamicTagsList())
4385
- }
4386
- ]
4387
- })
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
+ }
4388
4164
  );
4389
4165
  };
4390
4166
 
4391
4167
  // src/mcp/resources/editor-state-resource.ts
4392
- var import_editor_v1_adapters18 = require("@elementor/editor-v1-adapters");
4168
+ var import_editor_v1_adapters16 = require("@elementor/editor-v1-adapters");
4393
4169
  var CURRENTLY_VIEWED_SCREEN = "The user is currently viewing the Elementor editor";
4394
4170
  var PAGE_CONTENT_CHARACTER_LIMIT = 500;
4395
4171
  var PREVIEW_TEXT_NODE_MIN_LENGTH = 2;
@@ -4410,8 +4186,8 @@ var initEditorStateResource = (reg) => {
4410
4186
  lastSerializedState = serialized;
4411
4187
  sendResourceUpdated({ uri: EDITOR_STATE_URI });
4412
4188
  };
4413
- (0, import_editor_v1_adapters18.__privateListenTo)(
4414
- [(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")],
4415
4191
  notifyIfChanged
4416
4192
  );
4417
4193
  lastSerializedState = JSON.stringify(buildState());
@@ -4485,7 +4261,7 @@ function getPageTitle() {
4485
4261
  }
4486
4262
 
4487
4263
  // src/mcp/resources/general-context-resource.ts
4488
- var import_editor_v1_adapters19 = require("@elementor/editor-v1-adapters");
4264
+ var import_editor_v1_adapters17 = require("@elementor/editor-v1-adapters");
4489
4265
  var GENERAL_CONTEXT_URI = "elementor://context/general";
4490
4266
  var initGeneralContextResource = (reg) => {
4491
4267
  const { resource, sendResourceUpdated } = reg;
@@ -4546,11 +4322,11 @@ var initGeneralContextResource = (reg) => {
4546
4322
  };
4547
4323
  }
4548
4324
  );
4549
- (0, import_editor_v1_adapters19.__privateListenTo)(
4325
+ (0, import_editor_v1_adapters17.__privateListenTo)(
4550
4326
  [
4551
- (0, import_editor_v1_adapters19.commandEndEvent)("editor/documents/switch"),
4552
- (0, import_editor_v1_adapters19.commandEndEvent)("editor/documents/attach-preview"),
4553
- (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")
4554
4330
  ],
4555
4331
  pushUpdateIfChanged
4556
4332
  );
@@ -4558,9 +4334,9 @@ var initGeneralContextResource = (reg) => {
4558
4334
  };
4559
4335
 
4560
4336
  // src/mcp/resources/selected-element-resource.ts
4561
- var import_editor_elements12 = require("@elementor/editor-elements");
4562
- var import_editor_v1_adapters20 = require("@elementor/editor-v1-adapters");
4563
- var SELECTED_ELEMENT_URI = "elementor://context/selected-element";
4337
+ var import_editor_elements10 = require("@elementor/editor-elements");
4338
+ var import_editor_v1_adapters18 = require("@elementor/editor-v1-adapters");
4339
+ var SELECTED_ELEMENT_URI = "elementor://context/selected-element";
4564
4340
  var initSelectedElementResource = (reg) => {
4565
4341
  const { resource, sendResourceUpdated } = reg;
4566
4342
  let currentPayloadText = null;
@@ -4590,11 +4366,11 @@ var initSelectedElementResource = (reg) => {
4590
4366
  }
4591
4367
  publishIfChanged(readSelectionFromEditor());
4592
4368
  };
4593
- (0, import_editor_v1_adapters20.__privateListenTo)(
4369
+ (0, import_editor_v1_adapters18.__privateListenTo)(
4594
4370
  [
4595
- (0, import_editor_v1_adapters20.commandEndEvent)("document/elements/select"),
4596
- (0, import_editor_v1_adapters20.commandEndEvent)("document/elements/deselect-all"),
4597
- (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")
4598
4374
  ],
4599
4375
  onCommand
4600
4376
  );
@@ -4629,11 +4405,11 @@ function createEmptySelectedElementPayload() {
4629
4405
  };
4630
4406
  }
4631
4407
  function readSelectionFromEditor() {
4632
- const elements = (0, import_editor_elements12.getSelectedElements)();
4408
+ const elements = (0, import_editor_elements10.getSelectedElements)();
4633
4409
  if (elements.length !== 1) {
4634
4410
  return createEmptySelectedElementPayload();
4635
4411
  }
4636
- const container = (0, import_editor_elements12.getContainer)(elements[0].id);
4412
+ const container = (0, import_editor_elements10.getContainer)(elements[0].id);
4637
4413
  return buildPayloadFromContainer(container);
4638
4414
  }
4639
4415
  function buildPayloadFromContainer(container) {
@@ -4656,7 +4432,7 @@ function resolveElementVersion2(container, widgetType) {
4656
4432
  if (container.model?.config?.atomic) {
4657
4433
  return "v4";
4658
4434
  }
4659
- if (widgetType && (0, import_editor_elements12.getWidgetsCache)()?.[widgetType]?.atomic_props_schema) {
4435
+ if (widgetType && (0, import_editor_elements10.getWidgetsCache)()?.[widgetType]?.atomic_props_schema) {
4660
4436
  return "v4";
4661
4437
  }
4662
4438
  return "v3";
@@ -4666,7 +4442,7 @@ function getElementProperties(container, widgetType) {
4666
4442
  if (!settings || typeof settings !== "object") {
4667
4443
  return null;
4668
4444
  }
4669
- const widgetConfig = widgetType ? (0, import_editor_elements12.getWidgetsCache)()?.[widgetType] : null;
4445
+ const widgetConfig = widgetType ? (0, import_editor_elements10.getWidgetsCache)()?.[widgetType] : null;
4670
4446
  const controls = widgetConfig?.controls;
4671
4447
  const filtered = {};
4672
4448
  for (const [key, value] of Object.entries(settings)) {
@@ -4704,18 +4480,106 @@ function getElementDisplayName(container) {
4704
4480
  }
4705
4481
 
4706
4482
  // src/mcp/tools/build-composition/tool.ts
4707
- var import_editor_documents3 = require("@elementor/editor-documents");
4708
- var import_editor_elements16 = require("@elementor/editor-elements");
4709
- 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
+ }
4710
4572
 
4711
- // src/composition-builder/composition-builder.ts
4712
- 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");
4713
4577
 
4714
4578
  // src/mcp/utils/do-update-element-property.ts
4715
- var import_editor_elements14 = require("@elementor/editor-elements");
4716
- var import_editor_props9 = require("@elementor/editor-props");
4579
+ var import_editor_elements13 = require("@elementor/editor-elements");
4580
+ var import_editor_props6 = require("@elementor/editor-props");
4717
4581
  var import_editor_styles4 = require("@elementor/editor-styles");
4718
- var import_editor_v1_adapters21 = require("@elementor/editor-v1-adapters");
4582
+ var import_editor_v1_adapters20 = require("@elementor/editor-v1-adapters");
4719
4583
 
4720
4584
  // src/mcp/utils/merge-custom-css.ts
4721
4585
  var CUSTOM_CSS_SEPARATOR = "\n";
@@ -4732,7 +4596,7 @@ var readStoredCustomCssText = (raw) => {
4732
4596
  };
4733
4597
 
4734
4598
  // src/mcp/utils/resolve-canonical-prop-name.ts
4735
- var import_editor_elements13 = require("@elementor/editor-elements");
4599
+ var import_editor_elements12 = require("@elementor/editor-elements");
4736
4600
  function buildAliasToCanonicalMap(schema2) {
4737
4601
  const aliasToCanonical = {};
4738
4602
  for (const [canonical, propType] of Object.entries(schema2)) {
@@ -4749,14 +4613,14 @@ function buildAliasToCanonicalMap(schema2) {
4749
4613
  return aliasToCanonical;
4750
4614
  }
4751
4615
  function resolveCanonicalPropName(elementType, propertyName) {
4752
- const schema2 = (0, import_editor_elements13.getWidgetsCache)()?.[elementType]?.atomic_props_schema;
4616
+ const schema2 = (0, import_editor_elements12.getWidgetsCache)()?.[elementType]?.atomic_props_schema;
4753
4617
  if (!schema2 || schema2[propertyName]) {
4754
4618
  return propertyName;
4755
4619
  }
4756
4620
  return buildAliasToCanonicalMap(schema2)[propertyName] ?? propertyName;
4757
4621
  }
4758
4622
  function resolveCanonicalPropKeys(elementType, props) {
4759
- const schema2 = (0, import_editor_elements13.getWidgetsCache)()?.[elementType]?.atomic_props_schema;
4623
+ const schema2 = (0, import_editor_elements12.getWidgetsCache)()?.[elementType]?.atomic_props_schema;
4760
4624
  if (!schema2) {
4761
4625
  return { ...props };
4762
4626
  }
@@ -4783,6 +4647,68 @@ function resolveCanonicalPropKeys(elementType, props) {
4783
4647
  return resolved;
4784
4648
  }
4785
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
+
4786
4712
  // src/mcp/utils/do-update-element-property.ts
4787
4713
  var LOCAL_STYLE_META = {
4788
4714
  breakpoint: "desktop",
@@ -4790,7 +4716,7 @@ var LOCAL_STYLE_META = {
4790
4716
  };
4791
4717
  function resolvePropValue(value, forceKey) {
4792
4718
  const Utils = window.elementorV2.editorVariables.Utils;
4793
- return import_editor_props9.Schema.adjustLlmPropValueSchema(value, {
4719
+ return import_editor_props6.Schema.adjustLlmPropValueSchema(value, {
4794
4720
  forceKey,
4795
4721
  transformers: {
4796
4722
  ...Utils.globalVariablesLLMResolvers,
@@ -4802,7 +4728,7 @@ var doUpdateElementProperty = (params) => {
4802
4728
  const { elementId, propertyValue, elementType, customCssWriteMode = "replace" } = params;
4803
4729
  const propertyName = params.propertyName === "_styles" ? params.propertyName : resolveCanonicalPropName(elementType, params.propertyName);
4804
4730
  if (propertyName === "_styles") {
4805
- const elementStyles = (0, import_editor_elements14.getElementStyles)(elementId) || {};
4731
+ const elementStyles = (0, import_editor_elements13.getElementStyles)(elementId) || {};
4806
4732
  const propertyMapValue = propertyValue;
4807
4733
  const styleSchema = (0, import_editor_styles4.getStylesSchema)();
4808
4734
  const transformedStyleValues = Object.fromEntries(
@@ -4849,7 +4775,7 @@ var doUpdateElementProperty = (params) => {
4849
4775
  }
4850
4776
  if (propertyRawSchema.kind === "plain") {
4851
4777
  if (typeof propertyMapValue[stylePropName] !== "object") {
4852
- const propUtil = (0, import_editor_props9.getPropSchemaFromCache)(propertyRawSchema.key);
4778
+ const propUtil = (0, import_editor_props6.getPropSchemaFromCache)(propertyRawSchema.key);
4853
4779
  if (propUtil) {
4854
4780
  const plainValue = propUtil.create(propertyMapValue[stylePropName]);
4855
4781
  propertyMapValue[stylePropName] = plainValue;
@@ -4859,7 +4785,7 @@ var doUpdateElementProperty = (params) => {
4859
4785
  });
4860
4786
  delete transformedStyleValues.custom_css;
4861
4787
  if (!localStyle) {
4862
- (0, import_editor_elements14.createElementStyle)({
4788
+ (0, import_editor_elements13.createElementStyle)({
4863
4789
  elementId,
4864
4790
  ...typeof customCss !== "undefined" ? { custom_css: customCss } : {},
4865
4791
  classesProp: "classes",
@@ -4873,7 +4799,7 @@ var doUpdateElementProperty = (params) => {
4873
4799
  }
4874
4800
  });
4875
4801
  } else {
4876
- (0, import_editor_elements14.updateElementStyle)({
4802
+ (0, import_editor_elements13.updateElementStyle)({
4877
4803
  elementId,
4878
4804
  styleId: localStyle.id,
4879
4805
  meta: {
@@ -4888,7 +4814,7 @@ var doUpdateElementProperty = (params) => {
4888
4814
  }
4889
4815
  return;
4890
4816
  }
4891
- const elementPropSchema = (0, import_editor_elements14.getWidgetsCache)()?.[elementType]?.atomic_props_schema;
4817
+ const elementPropSchema = (0, import_editor_elements13.getWidgetsCache)()?.[elementType]?.atomic_props_schema;
4892
4818
  if (!elementPropSchema) {
4893
4819
  throw new Error(`No prop schema found for element type: ${elementType}`);
4894
4820
  }
@@ -4902,7 +4828,7 @@ var doUpdateElementProperty = (params) => {
4902
4828
  }
4903
4829
  const propKey = elementPropSchema[propertyName].key;
4904
4830
  const value = resolvePropValue(propertyValue, propKey);
4905
- const { valid, jsonSchema } = import_editor_props9.Schema.validatePropValue(elementPropSchema[propertyName], propertyValue);
4831
+ const { valid, jsonSchema } = import_editor_props6.Schema.validatePropValue(elementPropSchema[propertyName], propertyValue);
4906
4832
  if (!valid) {
4907
4833
  throw new Error(
4908
4834
  `Invalid PropValue for elementId: ${elementId}. PropKey: ${propKey}, PropValue: ${JSON.stringify(
@@ -4911,749 +4837,21 @@ var doUpdateElementProperty = (params) => {
4911
4837
  Expected Schema: ${jsonSchema}`
4912
4838
  );
4913
4839
  }
4914
- (0, import_editor_elements14.updateElementSettings)({
4840
+ (0, import_editor_elements13.updateElementSettings)({
4915
4841
  id: elementId,
4916
4842
  props: {
4917
4843
  [propertyName]: value
4918
4844
  },
4919
4845
  withHistory: false
4920
4846
  });
4921
- (0, import_editor_v1_adapters21.__privateRunCommandSync)("document/save/set-is-modified", { status: true }, { internal: true });
4922
- };
4923
-
4924
- // src/composition-builder/utils/required-children-enforcer.ts
4925
- var REQUIRED_CHILD_SCHEMA_HINT = "Use the widget schema resource; under llm_guidance.required_direct_children for V4 widgets.";
4926
- var RequiredChildrenEnforcer = class {
4927
- elementType;
4928
- requiredTemplates;
4929
- constructor(elementType, widgetsCache) {
4930
- this.elementType = elementType;
4931
- this.requiredTemplates = getRequiredDefaultChildTemplates(widgetsCache[elementType]);
4932
- }
4933
- enforce(xml) {
4934
- if (this.requiredTemplates.length === 0) {
4935
- return;
4936
- }
4937
- const errors = [];
4938
- for (const rootNode of Array.from(xml.children)) {
4939
- this.collectMissingRequiredErrors(rootNode, errors);
4940
- }
4941
- if (errors.length) {
4942
- throw new Error(`${errors.join("\n")}
4943
- ${REQUIRED_CHILD_SCHEMA_HINT}`);
4944
- }
4945
- }
4946
- collectMissingRequiredErrors(node, errors) {
4947
- if (node.tagName === this.elementType) {
4948
- const existingChildTags = new Set(Array.from(node.children).map((child) => child.tagName));
4949
- const missingTags = this.requiredTemplates.map((child) => child.widgetType ?? child.elType ?? "").filter((type) => type && !existingChildTags.has(type));
4950
- if (missingTags.length) {
4951
- const configurationId = node.getAttribute("configuration-id");
4952
- const location2 = configurationId ? `<${node.tagName} configuration-id="${configurationId}">` : `<${node.tagName}>`;
4953
- errors.push(
4954
- `${location2} Missing required direct child element tag(s): ${missingTags.join(", ")}.`
4955
- );
4956
- }
4957
- }
4958
- for (const childNode of Array.from(node.children)) {
4959
- this.collectMissingRequiredErrors(childNode, errors);
4960
- }
4961
- }
4847
+ (0, import_editor_v1_adapters20.__privateRunCommandSync)("document/save/set-is-modified", { status: true }, { internal: true });
4962
4848
  };
4963
4849
 
4964
- // src/composition-builder/composition-builder.ts
4965
- var CREATE_ELEMENT_INVALID_CONTAINER_MESSAGE = "createElement did not return an element container with a model.";
4966
- var CompositionBuilder = class _CompositionBuilder {
4967
- elementConfig = {};
4968
- elementStylesConfig = {};
4969
- elementCustomCSS = {};
4970
- rootContainers = [];
4971
- api = {
4972
- createElement: import_editor_elements15.createElement,
4973
- deleteElement: import_editor_elements15.deleteElement,
4974
- getWidgetsCache: import_editor_elements15.getWidgetsCache,
4975
- generateElementId: import_editor_elements15.generateElementId,
4976
- getContainer: import_editor_elements15.getContainer,
4977
- doUpdateElementProperty
4978
- };
4979
- xml;
4980
- static fromXMLString(xmlString, api = {}) {
4981
- const parser = new DOMParser();
4982
- const xmlDoc = parser.parseFromString(xmlString, "application/xml");
4983
- const errorNode = xmlDoc.querySelector("parsererror");
4984
- if (errorNode) {
4985
- throw new Error("Failed to parse XML string: " + errorNode.textContent);
4986
- }
4987
- return new _CompositionBuilder({
4988
- xml: xmlDoc,
4989
- api
4990
- });
4991
- }
4992
- constructor(opts) {
4993
- const { api = {}, elementConfig = {}, stylesConfig = {}, customCSS = {}, xml } = opts;
4994
- this.xml = xml;
4995
- Object.assign(this.api, api);
4996
- this.setElementConfig(elementConfig);
4997
- this.setStylesConfig(stylesConfig);
4998
- this.setCustomCSS(customCSS);
4999
- }
5000
- setElementConfig(config) {
5001
- this.elementConfig = config;
5002
- }
5003
- setStylesConfig(config) {
5004
- this.elementStylesConfig = config;
5005
- }
5006
- setCustomCSS(config) {
5007
- this.elementCustomCSS = config;
5008
- }
5009
- getXML() {
5010
- return this.xml;
5011
- }
5012
- buildModelTree(node, widgetsCache) {
5013
- const elementTag = node.tagName;
5014
- const isWidget = widgetsCache[elementTag]?.elType === "widget";
5015
- const id = this.api.generateElementId();
5016
- const children = Array.from(node.children).map((child) => this.buildModelTree(child, widgetsCache));
5017
- node.setAttribute("id", id);
5018
- const base = {
5019
- id,
5020
- skipDefaultChildren: true,
5021
- elements: children,
5022
- editor_settings: {
5023
- title: node.getAttribute("configuration-id") ?? void 0
5024
- },
5025
- elType: "widget"
5026
- };
5027
- if (isWidget) {
5028
- return { ...base, elType: "widget", widgetType: elementTag };
5029
- }
5030
- return { ...base, elType: elementTag };
5031
- }
5032
- async awaitViewRender(element) {
5033
- const view = element.view;
5034
- if (view?._currentRenderPromise instanceof Promise) {
5035
- await view._currentRenderPromise;
5036
- } else {
5037
- await Promise.resolve();
5038
- }
5039
- }
5040
- validateChildTypes(node, widgetsCache) {
5041
- const errors = [];
5042
- const allowedChildTypes = widgetsCache[node.tagName]?.allowed_child_types;
5043
- if (allowedChildTypes?.length) {
5044
- for (const child of Array.from(node.children)) {
5045
- if (!allowedChildTypes.includes(child.tagName)) {
5046
- errors.push(
5047
- `"${child.tagName}" is not allowed as a child of "${node.tagName}". Allowed: ${allowedChildTypes.join(", ")}`
5048
- );
5049
- }
5050
- }
5051
- }
5052
- for (const child of Array.from(node.children)) {
5053
- errors.push(...this.validateChildTypes(child, widgetsCache));
5054
- }
5055
- return errors;
5056
- }
5057
- matchNodeByConfigId(configId) {
5058
- const node = this.xml.querySelector(`[configuration-id="${configId}"]`);
5059
- if (!node) {
5060
- throw new Error(`Configuration id "${configId}" does not have target node.`);
5061
- }
5062
- const id = node.getAttribute("id");
5063
- if (!id) {
5064
- throw new Error(`Node with configuration id "${configId}" does not have element id.`);
5065
- }
5066
- const element = this.api.getContainer(id);
5067
- if (!element) {
5068
- throw new Error(`Element with id "${id}" not found but should exist.`);
5069
- }
5070
- return {
5071
- element,
5072
- node
5073
- };
5074
- }
5075
- async applyProperties() {
5076
- const configErrors = [];
5077
- const styleErrors = [];
5078
- const allConfigIds = /* @__PURE__ */ new Set([
5079
- ...Object.keys(this.elementConfig),
5080
- ...Object.keys(this.elementStylesConfig),
5081
- ...Object.keys(this.elementCustomCSS)
5082
- ]);
5083
- for (const configId of allConfigIds) {
5084
- let element, node;
5085
- try {
5086
- ({ element, node } = this.matchNodeByConfigId(configId));
5087
- } catch (matchErr) {
5088
- const msg = matchErr.message;
5089
- if (this.elementConfig[configId]) {
5090
- configErrors.push(msg);
5091
- }
5092
- if (this.elementStylesConfig[configId] || this.elementCustomCSS[configId]) {
5093
- styleErrors.push(msg);
5094
- }
5095
- continue;
5096
- }
5097
- const config = this.elementConfig[configId];
5098
- if (config) {
5099
- for (const [propertyName, propertyValue] of Object.entries(config)) {
5100
- try {
5101
- this.api.doUpdateElementProperty({
5102
- elementId: element.id,
5103
- propertyName,
5104
- propertyValue,
5105
- elementType: node.tagName
5106
- });
5107
- } catch (error) {
5108
- configErrors.push(error.message);
5109
- }
5110
- }
5111
- }
5112
- const styleConfig = this.elementStylesConfig[configId];
5113
- const hasInvalidStyles = false;
5114
- if (styleConfig) {
5115
- const validStylesPropValues = {};
5116
- for (const [styleName, stylePropValue] of Object.entries(styleConfig)) {
5117
- if (styleName === "$intention") {
5118
- continue;
5119
- } else {
5120
- validStylesPropValues[styleName] = stylePropValue;
5121
- }
5122
- }
5123
- if (Object.keys(validStylesPropValues).length > 0) {
5124
- try {
5125
- this.api.doUpdateElementProperty({
5126
- elementId: element.id,
5127
- propertyName: "_styles",
5128
- propertyValue: validStylesPropValues,
5129
- elementType: node.tagName
5130
- });
5131
- } catch (error) {
5132
- styleErrors.push(String(error));
5133
- }
5134
- }
5135
- }
5136
- const intentionCss = typeof styleConfig?.$intention === "string" ? styleConfig.$intention.trim() : "";
5137
- const fallbackCss = hasInvalidStyles && intentionCss ? intentionCss : "";
5138
- const mergedCustomCss = mergeCustomCssText(this.elementCustomCSS[configId], fallbackCss);
5139
- if (mergedCustomCss) {
5140
- try {
5141
- this.api.doUpdateElementProperty({
5142
- elementId: element.id,
5143
- propertyName: "_styles",
5144
- propertyValue: { custom_css: mergedCustomCss },
5145
- elementType: node.tagName
5146
- });
5147
- } catch (cssErr) {
5148
- styleErrors.push(String(cssErr));
5149
- }
5150
- }
5151
- await this.awaitViewRender(element);
5152
- }
5153
- return { configErrors, styleErrors };
5154
- }
5155
- async build(rootContainer) {
5156
- const widgetsCache = this.api.getWidgetsCache() || {};
5157
- new Set(this.xml.querySelectorAll("*")).forEach((node) => {
5158
- if (!widgetsCache[node.tagName]) {
5159
- throw new Error(`Unknown widget type: ${node.tagName}`);
5160
- }
5161
- });
5162
- const typesWithRequiredChildren = Object.keys(widgetsCache).filter(
5163
- (elementType) => getRequiredDefaultChildTemplates(widgetsCache[elementType]).length > 0
5164
- );
5165
- typesWithRequiredChildren.forEach((elementType) => {
5166
- new RequiredChildrenEnforcer(elementType, widgetsCache).enforce(this.xml);
5167
- });
5168
- const childTypeErrors = [];
5169
- for (const rootChild of Array.from(this.xml.children)) {
5170
- childTypeErrors.push(...this.validateChildTypes(rootChild, widgetsCache));
5171
- }
5172
- if (childTypeErrors.length) {
5173
- throw new Error(`Invalid element structure:
5174
- ${childTypeErrors.join("\n")}`);
5175
- }
5176
- const children = Array.from(this.xml.children);
5177
- for (const childNode of children) {
5178
- const modelTree = this.buildModelTree(childNode, widgetsCache);
5179
- try {
5180
- const newElement = this.api.createElement({
5181
- container: rootContainer,
5182
- model: modelTree,
5183
- options: { useHistory: false }
5184
- });
5185
- if (!newElement?.model) {
5186
- throw new Error(CREATE_ELEMENT_INVALID_CONTAINER_MESSAGE);
5187
- }
5188
- this.rootContainers.push(newElement);
5189
- await this.awaitViewRender(newElement);
5190
- } catch (e) {
5191
- const attempToRestoreInvalidContainer = this.api.getContainer(modelTree.id);
5192
- if (attempToRestoreInvalidContainer) {
5193
- this.api.deleteElement({ container: attempToRestoreInvalidContainer });
5194
- }
5195
- throw e;
5196
- }
5197
- }
5198
- const { configErrors, styleErrors } = await this.applyProperties();
5199
- if (typeof window !== "undefined") {
5200
- const targetWindow = window.top || window;
5201
- targetWindow.dispatchEvent(
5202
- new CustomEvent("elementor/composition/built", {
5203
- detail: { rootContainers: this.rootContainers.map((c) => c.id) }
5204
- })
5205
- );
5206
- }
5207
- return {
5208
- configErrors,
5209
- styleErrors,
5210
- rootContainers: [...this.rootContainers]
5211
- };
5212
- }
5213
- };
5214
-
5215
- // src/utils/tracking.ts
5216
- var import_events = require("@elementor/events");
5217
- var trackCanvasEvent = (data) => {
5218
- (0, import_events.trackEvent)(data);
5219
- };
5220
-
5221
- // src/mcp/utils/get-composition-target-container.ts
5222
- var import_editor_documents2 = require("@elementor/editor-documents");
5223
- function getCompositionTargetContainer(documentContainer, documentType) {
5224
- const firstChild = documentContainer.children?.[0];
5225
- if (documentType === import_editor_documents2.COMPONENT_DOCUMENT_TYPE && firstChild) {
5226
- return firstChild;
5227
- }
5228
- return documentContainer;
5229
- }
5230
-
5231
- // src/mcp/tools/build-composition/prompt.ts
5232
- var import_editor_mcp2 = require("@elementor/editor-mcp");
5233
- var BUILD_COMPOSITIONS_GUIDE_URI = "elementor://canvas/tools/build-compositions-guide";
5234
- var generatePrompt = () => {
5235
- const buildCompositionsToolPrompt = (0, import_editor_mcp2.toolPrompts)("build-compositions");
5236
- buildCompositionsToolPrompt.description(`
5237
- # RESOURCES (Read before use)
5238
- - [elementor://global-classes] - Check FIRST for reusable classes
5239
- - [elementor://global-variables] - ONLY use variables defined here
5240
- - [${AVAILABLE_WIDGETS_URI}/v4]
5241
-
5242
- # TOOL SUPPORT
5243
- This tool support v4 elements only
5244
-
5245
- # WORKFLOW
5246
- 1. Check/create global classes via "manage-global-classes" tool
5247
- 2. Build composition (THIS TOOL) - minimal inline styles
5248
- 3. Apply classes via "apply-global-class" tool
5249
-
5250
- # XML STRUCTURE
5251
- - Use widget tags: \`<e-button configuration-id="btn1"></e-button>\`
5252
- - Containers: "e-flexbox", "e-div-block", "e-tabs"
5253
- - Every element needs unique "configuration-id"
5254
- - No attributes, classes, IDs, or text nodes in XML
5255
-
5256
- ## NESTED ELEMENTS
5257
- Some elements have internal tree structures (nesting). When using these elements, you MUST build the FULL tree in XML.
5258
- - Check \`llm_guidance.nesting\` in widget schemas for structure requirements
5259
- - \`llm_guidance.required_direct_children\` lists element types that must appear as direct child tags in XML (from widget defaults)
5260
- - \`allowed_child_types\` lists which element types can be nested inside
5261
- - \`allowed_parents\` lists which element types this element can be placed inside
5262
-
5263
- # CONFIGURATION
5264
- - Map configuration-id \u2192 elementConfig (props) + style (raw CSS declarations)
5265
- - elementConfig PropValues require \`$$type\` matching schema
5266
- - 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
5267
- - NO LINKS in configuration
5268
- - Retry on errors up to 10x
5269
- - Check \`llm_guidance.default_settings\` in widget schemas \u2014 omit only keys listed there from elementConfig unless the user explicitly asks to change them
5270
-
5271
- # DYNAMIC TAGS
5272
- - 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\`).
5273
- - 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.
5274
- - Provide at that node: \`{ "$$type": "dynamic", "value": { "name": "<allowed tag>", "settings": { ... } } }\`
5275
- - Example (image): \`{ "$$type": "image", "value": { "src": { "$$type": "dynamic", "value": { "name": "<image tag>", "settings": { ... } } } } }\`
5276
- - Do NOT send \`group\` (it is resolved automatically). Populate \`settings\` strictly per the tag's schema; use \`{}\` only when it has none.
5277
-
5278
- Note about configuration ids: These names are visible to the end-user, make sure they make sense, related and relevant.
5279
-
5280
- # DESIGN PHILOSOPHY: CONTEXT-DRIVEN CREATIVITY
5281
-
5282
- **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.
5283
-
5284
- ## SIZING: DEFAULT IS NO SIZE (CRITICAL)
5285
-
5286
- **DO NOT specify height or width unless you have a specific visual reason.**
5287
-
5288
- Flexbox and CSS already handle sizing automatically:
5289
- - Containers grow to fit their content
5290
- - Flex children distribute space via flex properties, not width/height
5291
- - Text elements size to their content
5292
-
5293
- WHEN TO SPECIFY SIZE:
5294
- - min-height on ROOT section for viewport-spanning hero (use min-height, NOT height)
5295
- - max-width for contained content areas (e.g., max-width: 60rem)
5296
- - Explicit aspect ratios for media containers
5297
-
5298
- NEVER SPECIFY:
5299
- - height on nested containers (causes overflow)
5300
- - width on flex children (use flex-basis or gap instead)
5301
- - 100vh on anything except root-level sections
5302
- - Any size "just to be safe" - if unsure, OMIT IT
5303
-
5304
- vh units are VIEWPORT-relative. Nested 100vh inside 100vh = 200vh overflow.
5305
-
5306
- GOOD: \`<e-flexbox>content naturally sizes</e-flexbox>\`
5307
- BAD: \`<e-flexbox style="height:100vh"><e-div-block style="height:100vh">overflow</e-div-block></e-flexbox>\`
5308
-
5309
- ## Layout Variety (Break the Template)
5310
- - AVOID: Full-width 100vh hero \u2192 three columns \u2192 testimonials \u2192 CTA (every AI does this)
5311
- - VARY heights: Use auto-height sections with generous padding (6rem+). Let content breathe
5312
- - VARY widths: Not everything spans full width. Use contained sections (max-width: 960px) mixed with edge-to-edge
5313
- - ASYMMETRIC grids: 2:1, 1:3, offset layouts. Avoid equal column widths
5314
- - Negative space as design element: Large margins create focus and sophistication
5315
- - Break alignment intentionally: Offset headings, overlapping elements, broken grids
5316
-
5317
- ## Visual Depth & Effects
5318
- - Layer elements: Overlapping cards, text over images, floating elements
5319
- - Subtle shadows with color tint (not pure black): \`box-shadow: 0 20px 60px rgba(<brand-color-here>, 0.15)\`
5320
- - Gradient overlays on images for text readability
5321
- - Border radius variation: Mix sharp (0) and soft (1rem+) corners purposefully
5322
- - Backdrop blur for glassmorphism where appropriate
5323
- - Micro-interactions via CSS: hover transforms, transitions (0.3s ease)
5324
-
5325
- ## Typography with Character
5326
- - Display fonts for headlines (from user's brand or contextually appropriate)
5327
- - Size contrast: 4rem+ headlines vs 1rem body. Make hierarchy unmistakable
5328
- - Letter-spacing: Tight for large headlines (-0.02em), loose for small caps (0.1em)
5329
- - Line-height: Tight for headlines (1.1), generous for body (1.6-1.8)
5330
- - Text decoration: Underlines, highlights, gradient text for emphasis
5331
-
5332
- ## Color with Purpose
5333
- - Extract palette from user context (brand colors, industry norms, mood)
5334
- - 60-30-10 rule: dominant, secondary, accent
5335
- - Tinted neutrals over pure grays: warm (#faf8f5, #2d2a26) or cool (#f5f7fa, #1e2430)
5336
- - Color blocking: Large colored sections create visual rhythm
5337
- - Gradient directions: Diagonal (135deg, 225deg) feel more dynamic than vertical
5338
-
5339
- ## Spacing Strategy
5340
- - Section padding: 6rem-10rem vertical, creating breathing room
5341
- - Rhythm variation: Tight groups (2rem) with generous gaps between (6rem)
5342
- - Use rem/em exclusively for responsive scaling
5343
- - Generous padding on CTAs: min 1rem 2.5rem
5344
-
5345
- # HARD CONSTRAINTS
5346
- - Variables ONLY from [elementor://global-variables] (others throw errors)
5347
- - Avoid SVG widgets unless assets are pre-uploaded
5348
- - Check \`llm_guidance\` in widget schemas (\`default_styles\`, nesting, required children)
5349
-
5350
- # PARAMETERS
5351
- - **xmlStructure**: Valid XML with configuration-id attributes
5352
- - **elementConfig**: configuration-id \u2192 widget PropValues
5353
- - **style**: configuration-id \u2192 raw CSS declarations (property \u2192 value strings; no selectors)
5354
- `);
5355
- buildCompositionsToolPrompt.example(`
5356
- Section with heading + button (NO explicit heights - content sizes naturally):
5357
- {
5358
- 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>",
5359
- elementConfig: {
5360
- "section1": { "tag": { "$$type": "string", "value": "section" } }
5361
- },
5362
- style: {
5363
- "Section Title": {
5364
- "padding": "6rem 4rem",
5365
- "background": "linear-gradient(135deg, #faf8f5 0%, #f0ebe4 100%)",
5366
- "font-size": "3.5rem",
5367
- "color": "#2d2a26"
5368
- }
5369
- }
5370
- }
5371
- Note: No height/width specified on any element - flexbox handles layout automatically.
5372
- `);
5373
- buildCompositionsToolPrompt.parameter(
5374
- "xmlStructure",
5375
- `Valid XML structure with custom elementor tags and configuration-id attributes.`
5376
- );
5377
- buildCompositionsToolPrompt.parameter("elementConfig", `Record mapping configuration IDs to widget PropValues.`);
5378
- buildCompositionsToolPrompt.parameter(
5379
- "style",
5380
- `Record mapping configuration IDs to raw CSS declarations (property \u2192 value strings).`
5381
- );
5382
- buildCompositionsToolPrompt.instruction(
5383
- `Element IDs in the returned XML represent actual widgets. Use these IDs for subsequent styling or configuration changes.`
5384
- );
5385
- return buildCompositionsToolPrompt.prompt();
5386
- };
5387
-
5388
- // src/mcp/tools/build-composition/schema.ts
5389
- var import_schema = require("@elementor/schema");
5390
- var inputSchema = {
5391
- xmlStructure: import_schema.z.string().describe("The XML structure representing the composition to be built"),
5392
- elementConfig: import_schema.z.record(
5393
- import_schema.z.string().describe("The configuration id"),
5394
- import_schema.z.record(
5395
- import_schema.z.string().describe("property name"),
5396
- import_schema.z.any().describe(`The PropValue for the property, refer to ${WIDGET_SCHEMA_URI}`)
5397
- )
5398
- ).describe("A record mapping element IDs to their configuration objects. REQUIRED"),
5399
- style: import_schema.z.record(
5400
- import_schema.z.string().describe("The configuration id"),
5401
- import_schema.z.record(
5402
- import_schema.z.string().describe('A CSS property name, e.g. "color", "padding".'),
5403
- import_schema.z.string().describe('A CSS value, e.g. "6rem 4rem", "#2d2a26".')
5404
- )
5405
- ).describe(
5406
- "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."
5407
- ).default({})
5408
- };
5409
- var outputSchema = {
5410
- errors: import_schema.z.string().describe("Error message if the composition building failed").optional(),
5411
- xmlStructure: import_schema.z.string().describe(
5412
- "The built XML structure as a string. Must use this XML after completion of building the composition, it contains real IDs."
5413
- ).optional(),
5414
- llm_instructions: import_schema.z.string().describe("Instructions what to do next, Important to follow these instructions!").optional()
5415
- };
5416
-
5417
- // src/mcp/tools/build-composition/xml-leaf-wrapper.ts
5418
- var DIV_BLOCK_TAG = "e-div-block";
5419
- var ZERO_SPACING = {
5420
- $$type: "size",
5421
- value: {
5422
- size: {
5423
- $$type: "number",
5424
- value: 0
5425
- },
5426
- unit: {
5427
- $$type: "string",
5428
- value: "px"
5429
- }
5430
- }
5431
- };
5432
- function adaptLeafRootParams(params) {
5433
- const doc = new DOMParser().parseFromString(params.xmlStructure, "application/xml");
5434
- const rootElement = doc.documentElement;
5435
- if (!isLeafWidget(rootElement.tagName, params.widgetsCache)) {
5436
- return params;
5437
- }
5438
- const wrapperConfigId = getDivBlockWrapperConfigId(params.widgetsCache);
5439
- return {
5440
- ...params,
5441
- xmlStructure: serializeWrapped(doc, rootElement, wrapperConfigId),
5442
- stylesConfig: {
5443
- ...params.stylesConfig,
5444
- [wrapperConfigId]: {
5445
- margin: ZERO_SPACING,
5446
- padding: ZERO_SPACING,
5447
- ...params.stylesConfig[wrapperConfigId]
5448
- }
5449
- }
5450
- };
5451
- }
5452
- function getDivBlockWrapperConfigId(widgetsCache) {
5453
- return widgetsCache[DIV_BLOCK_TAG]?.title ?? DIV_BLOCK_TAG;
5454
- }
5455
- function isLeafWidget(tagName, widgetsCache) {
5456
- return widgetsCache[tagName]?.elType === "widget";
5457
- }
5458
- function serializeWrapped(doc, rootElement, wrapperConfigId) {
5459
- const wrapper = doc.createElement(DIV_BLOCK_TAG);
5460
- wrapper.setAttribute("configuration-id", wrapperConfigId);
5461
- wrapper.appendChild(rootElement.cloneNode(true));
5462
- const wrappedDoc = new DOMParser().parseFromString(`<${DIV_BLOCK_TAG} />`, "application/xml");
5463
- wrappedDoc.replaceChild(wrapper, wrappedDoc.documentElement);
5464
- return new XMLSerializer().serializeToString(wrappedDoc);
5465
- }
5466
-
5467
- // src/mcp/tools/build-composition/tool.ts
5468
- var ELEMENT_ADDED_EVENT = "elementor/canvas/element-added";
5469
- var initBuildCompositionsTool = (reg) => {
5470
- const { addTool, resource } = reg;
5471
- resource(
5472
- "build-compositions-guide",
5473
- BUILD_COMPOSITIONS_GUIDE_URI,
5474
- {
5475
- title: "Build Compositions Guide",
5476
- description: "Detailed guide for using the build-compositions tool",
5477
- mimeType: "text/plain"
5478
- },
5479
- async (uri) => ({
5480
- contents: [{ uri: uri.href, mimeType: "text/plain", text: generatePrompt() }]
5481
- })
5482
- );
5483
- addTool({
5484
- name: "build-compositions",
5485
- description: "Build V4 element compositions on the Elementor canvas. Read the guide resource before use.",
5486
- schema: inputSchema,
5487
- requiredResources: [
5488
- { description: "Build compositions guide", uri: BUILD_COMPOSITIONS_GUIDE_URI },
5489
- { description: "Widgets schema", uri: WIDGET_SCHEMA_URI },
5490
- { description: "Global Classes", uri: "elementor://global-classes" },
5491
- { description: "Global Variables", uri: "elementor://global-variables" },
5492
- { description: "Styles best practices", uri: BEST_PRACTICES_URI },
5493
- { description: "Available widgets for this tool", uri: AVAILABLE_WIDGETS_URI_V4 },
5494
- { description: "Dynamic tags catalog", uri: DYNAMIC_TAGS_URI }
5495
- ],
5496
- outputSchema,
5497
- handler: async (rawParams) => {
5498
- assertCompositionXmlUsesV4WidgetsOnly(rawParams.xmlStructure);
5499
- const { stylesConfig: convertedStyles, customCSS } = await convertCompositionStyles(rawParams.style);
5500
- const { xmlStructure, elementConfig, stylesConfig } = adaptLeafRootParams({
5501
- ...rawParams,
5502
- stylesConfig: convertedStyles,
5503
- widgetsCache: (0, import_editor_elements16.getWidgetsCache)() ?? {}
5504
- });
5505
- let generatedXML = "";
5506
- const errors = [];
5507
- const rootContainers = [];
5508
- const documentContainer = (0, import_editor_elements16.getContainer)("document");
5509
- const currentDocument = (0, import_editor_documents3.getCurrentDocument)();
5510
- const targetContainer = getCompositionTargetContainer(documentContainer, currentDocument?.type.value);
5511
- try {
5512
- const compositionBuilder = CompositionBuilder.fromXMLString(xmlStructure, {
5513
- createElement: import_editor_elements16.createElement,
5514
- deleteElement: import_editor_elements16.deleteElement,
5515
- getWidgetsCache: import_editor_elements16.getWidgetsCache
5516
- });
5517
- compositionBuilder.setElementConfig(elementConfig);
5518
- compositionBuilder.setStylesConfig(stylesConfig);
5519
- compositionBuilder.setCustomCSS(customCSS);
5520
- const { configErrors, rootContainers: generatedRootContainers } = await compositionBuilder.build(targetContainer);
5521
- rootContainers.push(...generatedRootContainers);
5522
- generatedXML = new XMLSerializer().serializeToString(compositionBuilder.getXML());
5523
- rootContainers.forEach((container) => {
5524
- const elementData = container.model?.toJSON();
5525
- if (elementData) {
5526
- onElementAdded(elementData);
5527
- }
5528
- });
5529
- Object.values(stylesConfig).forEach((styleValue) => {
5530
- (0, import_editor_mcp3.dispatchMcpStylesAppliedEvent)({ styleValue });
5531
- });
5532
- if (configErrors.length) {
5533
- errors.push(...configErrors.map((msg) => new Error(msg)));
5534
- }
5535
- } catch (error) {
5536
- errors.push(error);
5537
- }
5538
- if (errors.length) {
5539
- rootContainers.forEach((rootContainer) => {
5540
- (0, import_editor_elements16.deleteElement)({
5541
- container: rootContainer,
5542
- options: { useHistory: false }
5543
- });
5544
- });
5545
- const errorMessages = errors.map((e) => {
5546
- if (typeof e === "string") {
5547
- return e;
5548
- }
5549
- if (e instanceof Error) {
5550
- return e.message || String(e);
5551
- }
5552
- if (typeof e === "object" && e !== null) {
5553
- return JSON.stringify(e);
5554
- }
5555
- return String(e);
5556
- }).filter(
5557
- (msg) => msg && msg.trim() !== "" && msg !== "{}" && msg !== "null" && msg !== "undefined"
5558
- );
5559
- if (errorMessages.length === 0) {
5560
- throw new Error(
5561
- "Failed to build composition: Unknown error occurred. No error details available."
5562
- );
5563
- }
5564
- const errorText = `Failed to build composition with the following errors:
5565
-
5566
- ${errorMessages.join(
5567
- "\n\n"
5568
- )}`;
5569
- throw new Error(errorText);
5570
- }
5571
- return {
5572
- xmlStructure: generatedXML,
5573
- errors: errors?.length ? errors.map((e) => typeof e === "string" ? e : e.message).join("\n\n") : void 0,
5574
- llm_instructions: `The composition was built successfully with element IDs embedded in the XML.
5575
-
5576
- **CRITICAL NEXT STEPS** (Follow in order):
5577
- 1. **Apply Global Classes**: Use "apply-global-class" tool to apply the global classes you created BEFORE building this composition
5578
- - Check the created element IDs in the returned XML
5579
- - Apply semantic classes (heading-primary, button-cta, etc.) to appropriate elements
5580
-
5581
- 2. **Fine-tune if needed**: Use "configure-element" tool only for element-specific adjustments that don't warrant global classes
5582
-
5583
- Remember: Global classes ensure design consistency and reusability. Don't skip applying them!
5584
- `
5585
- };
5586
- }
5587
- });
5588
- };
5589
- async function convertCompositionStyles(style) {
5590
- const stylesConfig = {};
5591
- const customCSS = {};
5592
- if (!style || Object.keys(style).length === 0) {
5593
- return { stylesConfig, customCSS };
5594
- }
5595
- const results = await convertStyleBlocksToAtomic(style);
5596
- for (const [configId, { props, customCss }] of Object.entries(results)) {
5597
- stylesConfig[configId] = props;
5598
- if (customCss) {
5599
- customCSS[configId] = customCss;
5600
- }
5601
- }
5602
- return { stylesConfig, customCSS };
5603
- }
5604
- function assertCompositionXmlUsesV4WidgetsOnly(xmlStructure) {
5605
- const doc = new DOMParser().parseFromString(xmlStructure, "application/xml");
5606
- if (doc.querySelector("parsererror")) {
5607
- throw new Error("Failed to parse XML string: " + doc);
5608
- }
5609
- const widgetsCache = (0, import_editor_elements16.getWidgetsCache)() ?? {};
5610
- for (const node of doc.querySelectorAll("*")) {
5611
- const type = node.tagName;
5612
- const widgetData = widgetsCache[type];
5613
- if (!widgetData) {
5614
- continue;
5615
- }
5616
- if (widgetData.elType !== "widget") {
5617
- continue;
5618
- }
5619
- if (!isWidgetAvailableForLLM(widgetData) || !widgetData.atomic_props_schema) {
5620
- throw new Error(`This tool does not support element type: ${type}`);
5621
- }
5622
- }
5623
- }
5624
- function onElementAdded(element) {
5625
- const elType = element.elType ?? "";
5626
- const widgetType = element.widgetType ?? "";
5627
- const elementName = elType === "widget" ? widgetType : elType;
5628
- trackCanvasEvent({
5629
- eventName: "add_element",
5630
- executed_by: "mcp_tool",
5631
- element_name: elementName,
5632
- element_type: elType,
5633
- widget_type: widgetType
5634
- });
5635
- const event = {
5636
- element,
5637
- executedBy: "mcp_tool"
5638
- };
5639
- window.dispatchEvent(new CustomEvent(ELEMENT_ADDED_EVENT, { detail: event }));
5640
- if (element.elements?.length) {
5641
- element.elements?.forEach((childElement) => {
5642
- onElementAdded(childElement);
5643
- });
5644
- }
5645
- }
5646
-
5647
- // src/mcp/tools/configure-element/tool.ts
5648
- var import_editor_elements17 = require("@elementor/editor-elements");
5649
- var import_editor_mcp5 = require("@elementor/editor-mcp");
5650
- var import_editor_props10 = require("@elementor/editor-props");
5651
-
5652
4850
  // src/mcp/tools/configure-element/prompt.ts
5653
- var import_editor_mcp4 = require("@elementor/editor-mcp");
4851
+ var import_editor_mcp2 = require("@elementor/editor-mcp");
5654
4852
  var CONFIGURE_ELEMENT_GUIDE_URI = "elementor://canvas/tools/configure-element-guide";
5655
- var generatePrompt2 = () => {
5656
- const configureElementToolPrompt = (0, import_editor_mcp4.toolPrompts)("configure-element");
4853
+ var generatePrompt = () => {
4854
+ const configureElementToolPrompt = (0, import_editor_mcp2.toolPrompts)("configure-element");
5657
4855
  configureElementToolPrompt.description(`
5658
4856
  Configure an existing element on the page.
5659
4857
 
@@ -5761,29 +4959,29 @@ NO Advanced tab. Never mention Advanced tab.
5761
4959
  `);
5762
4960
  return configureElementToolPrompt.prompt();
5763
4961
  };
5764
- var CONFIGURE_ELEMENT_GUIDE_TEXT = generatePrompt2();
4962
+ var CONFIGURE_ELEMENT_GUIDE_TEXT = generatePrompt();
5765
4963
 
5766
4964
  // src/mcp/tools/configure-element/schema.ts
5767
- var import_schema3 = require("@elementor/schema");
5768
- var inputSchema2 = {
5769
- propertiesToChange: import_schema3.z.record(
5770
- import_schema3.z.string().describe("The property name."),
5771
- import_schema3.z.any().describe(`PropValue, refer to [${WIDGET_SCHEMA_URI}] by correct type, as appears in elementType`),
5772
- 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()
5773
4971
  ).describe("An object record containing property names and their new values to be set on the element"),
5774
- style: import_schema3.z.record(
5775
- import_schema3.z.string().describe('A CSS property name, e.g. "color", "margin-top".'),
5776
- 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(
5777
4975
  'A CSS value, e.g. "red", "10px", "1px solid #000". Use null to reset the property to its default.'
5778
4976
  )
5779
4977
  ).describe(
5780
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."
5781
4979
  ).default({}),
5782
- elementType: import_schema3.z.string().describe("The type of the element to retrieve the schema"),
5783
- 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")
5784
4982
  };
5785
- var outputSchema2 = {
5786
- success: import_schema3.z.boolean().describe(
4983
+ var outputSchema = {
4984
+ success: import_schema2.z.boolean().describe(
5787
4985
  "Whether the configuration change was successful, only if propertyName and propertyValue are provided"
5788
4986
  )
5789
4987
  };
@@ -5800,27 +4998,27 @@ var initConfigureElementTool = (reg) => {
5800
4998
  mimeType: "text/plain"
5801
4999
  },
5802
5000
  async (uri) => ({
5803
- contents: [{ uri: uri.href, mimeType: "text/plain", text: generatePrompt2() }]
5001
+ contents: [{ uri: uri.href, mimeType: "text/plain", text: generatePrompt() }]
5804
5002
  })
5805
5003
  );
5806
5004
  addTool({
5807
5005
  name: "configure-element",
5808
5006
  description: "Configure an existing V4 element's properties and styles. Read the guide resource before use.",
5809
- schema: inputSchema2,
5810
- outputSchema: outputSchema2,
5007
+ schema: inputSchema,
5008
+ outputSchema,
5811
5009
  requiredResources: [
5812
5010
  { description: "Widgets schema", uri: WIDGET_SCHEMA_URI },
5813
5011
  { description: "Configure element guide", uri: CONFIGURE_ELEMENT_GUIDE_URI },
5814
5012
  { description: "Dynamic tags catalog", uri: DYNAMIC_TAGS_URI }
5815
5013
  ],
5816
5014
  handler: async ({ elementId, propertiesToChange, elementType, style }) => {
5817
- const widgetData = (0, import_editor_elements17.getWidgetsCache)()?.[elementType];
5015
+ const widgetData = (0, import_editor_elements14.getWidgetsCache)()?.[elementType];
5818
5016
  if (!widgetData) {
5819
5017
  throw new Error(
5820
5018
  `Unknown element type: ${elementType}. Check the available-widgets resource for valid types.`
5821
5019
  );
5822
5020
  }
5823
- const container = (0, import_editor_elements17.getContainer)(elementId);
5021
+ const container = (0, import_editor_elements14.getContainer)(elementId);
5824
5022
  if (!container) {
5825
5023
  throw new Error(`Element with id ${elementId} not found`);
5826
5024
  }
@@ -5836,7 +5034,7 @@ var initConfigureElementTool = (reg) => {
5836
5034
  const propertiesToUpdate = resolveCanonicalPropKeys(elementType, propertiesToChange);
5837
5035
  const toUpdate = Object.entries(propertiesToUpdate);
5838
5036
  for (const [propertyName, propertyValue] of toUpdate) {
5839
- if (!import_editor_props10.Schema.isPropKeyConfigurable(propertyName)) {
5037
+ if (!import_editor_props7.Schema.isPropKeyConfigurable(propertyName)) {
5840
5038
  throw new Error(`Not allowed to update ${propertyName}`);
5841
5039
  }
5842
5040
  try {
@@ -5885,7 +5083,7 @@ async function applyStyleFromCss(opts) {
5885
5083
  propertyValue: styleValue,
5886
5084
  customCssWriteMode: "merge-with-stored"
5887
5085
  });
5888
- (0, import_editor_mcp5.dispatchMcpStylesAppliedEvent)({ styleValue });
5086
+ (0, import_editor_mcp3.dispatchMcpStylesAppliedEvent)({ styleValue });
5889
5087
  } catch (error) {
5890
5088
  throw new Error(
5891
5089
  createUpdateErrorMessage({
@@ -5912,20 +5110,20 @@ Provide styling as raw CSS via the "style" parameter (a flat map of CSS property
5912
5110
  }
5913
5111
 
5914
5112
  // src/mcp/tools/get-element-config/tool.ts
5915
- var import_editor_elements18 = require("@elementor/editor-elements");
5916
- var import_editor_props11 = require("@elementor/editor-props");
5917
- 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");
5918
5116
  var schema = {
5919
- elementId: import_schema5.z.string()
5117
+ elementId: import_schema4.z.string()
5920
5118
  };
5921
- var outputSchema3 = {
5922
- properties: import_schema5.z.record(import_schema5.z.string(), import_schema5.z.any()).describe("A record mapping PropTypes to their corresponding PropValues"),
5923
- style: import_schema5.z.record(import_schema5.z.string(), import_schema5.z.any()).describe("A record mapping StyleSchema properties to their corresponding PropValues"),
5924
- childElements: import_schema5.z.array(
5925
- import_schema5.z.object({
5926
- id: import_schema5.z.string(),
5927
- elementType: import_schema5.z.string(),
5928
- 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")
5929
5127
  })
5930
5128
  ).describe("An array of child element IDs, when applicable, with recursive structure")
5931
5129
  };
@@ -5945,14 +5143,14 @@ var initGetElementConfigTool = (reg) => {
5945
5143
  name: "get-element-configuration-values",
5946
5144
  description: "Retrieve the element's configuration PropValues for a specific element by unique ID.",
5947
5145
  schema,
5948
- outputSchema: outputSchema3,
5146
+ outputSchema: outputSchema2,
5949
5147
  handler: async ({ elementId }) => {
5950
- const element = (0, import_editor_elements18.getContainer)(elementId);
5148
+ const element = (0, import_editor_elements15.getContainer)(elementId);
5951
5149
  if (!element) {
5952
5150
  throw new Error(`Element with ID ${elementId} not found.`);
5953
5151
  }
5954
5152
  const elementType = element.model.get("widgetType") || element.model.get("elType") || "";
5955
- const widgetData = (0, import_editor_elements18.getWidgetsCache)()?.[elementType];
5153
+ const widgetData = (0, import_editor_elements15.getWidgetsCache)()?.[elementType];
5956
5154
  if (!widgetData) {
5957
5155
  throw new Error(
5958
5156
  `Unknown element type: ${elementType}. Check the available-widgets resource for valid types.`
@@ -5964,16 +5162,16 @@ var initGetElementConfigTool = (reg) => {
5964
5162
  );
5965
5163
  }
5966
5164
  const elementRawSettings = element.settings;
5967
- const propSchema = (0, import_editor_elements18.getWidgetsCache)()?.[elementType]?.atomic_props_schema;
5165
+ const propSchema = (0, import_editor_elements15.getWidgetsCache)()?.[elementType]?.atomic_props_schema;
5968
5166
  if (!elementRawSettings || !propSchema) {
5969
5167
  throw new Error(`No settings or prop schema found for element ID: ${elementId}`);
5970
5168
  }
5971
5169
  const propValues = {};
5972
5170
  const stylePropValues = {};
5973
- import_editor_props11.Schema.configurableKeys(propSchema).forEach((key) => {
5171
+ import_editor_props8.Schema.configurableKeys(propSchema).forEach((key) => {
5974
5172
  propValues[key] = structuredClone(elementRawSettings.get(key));
5975
5173
  });
5976
- const elementStyles = (0, import_editor_elements18.getElementStyles)(elementId) || {};
5174
+ const elementStyles = (0, import_editor_elements15.getElementStyles)(elementId) || {};
5977
5175
  const localStyle = Object.values(elementStyles).find((style) => style.label === "local");
5978
5176
  if (localStyle) {
5979
5177
  const defaultVariant = localStyle.variants.find(
@@ -6006,7 +5204,7 @@ var initGetElementConfigTool = (reg) => {
6006
5204
 
6007
5205
  // src/mcp/canvas-mcp.ts
6008
5206
  var initCanvasMcp = (reg) => {
6009
- import_editor_props12.Schema.setDynamicTagNamesResolver(getDynamicTagNamesByCategories);
5207
+ import_editor_props9.Schema.setDynamicTagNamesResolver(getDynamicTagNamesByCategories);
6010
5208
  initWidgetsSchemaResource(reg);
6011
5209
  initAvailableWidgetsResource(reg);
6012
5210
  initDocumentStructureResource(reg);
@@ -6014,9 +5212,10 @@ var initCanvasMcp = (reg) => {
6014
5212
  initSelectedElementResource(reg);
6015
5213
  initEditorStateResource(reg);
6016
5214
  initGeneralContextResource(reg);
6017
- initBuildCompositionsTool(reg);
5215
+ initBestPracticesResource(reg);
6018
5216
  initGetElementConfigTool(reg);
6019
5217
  initConfigureElementTool(reg);
5218
+ initBuildCompositionTool(reg);
6020
5219
  initBreakpointsResource(reg);
6021
5220
  };
6022
5221
 
@@ -6129,16 +5328,16 @@ Note: The "size" property controls image resolution/loading, not visual size. Se
6129
5328
  `;
6130
5329
 
6131
5330
  // src/prevent-link-in-link-commands.ts
6132
- var import_editor_elements19 = require("@elementor/editor-elements");
5331
+ var import_editor_elements16 = require("@elementor/editor-elements");
6133
5332
  var import_editor_notifications3 = require("@elementor/editor-notifications");
6134
- var import_editor_v1_adapters22 = require("@elementor/editor-v1-adapters");
5333
+ var import_editor_v1_adapters21 = require("@elementor/editor-v1-adapters");
6135
5334
  var import_i18n4 = require("@wordpress/i18n");
6136
5335
  function initLinkInLinkPrevention() {
6137
- (0, import_editor_v1_adapters22.blockCommand)({
5336
+ (0, import_editor_v1_adapters21.blockCommand)({
6138
5337
  command: "document/elements/paste",
6139
5338
  condition: blockLinkInLinkPaste
6140
5339
  });
6141
- (0, import_editor_v1_adapters22.blockCommand)({
5340
+ (0, import_editor_v1_adapters21.blockCommand)({
6142
5341
  command: "document/elements/move",
6143
5342
  condition: blockLinkInLinkMove
6144
5343
  });
@@ -6200,25 +5399,25 @@ function shouldBlock(sourceElements, targetElements) {
6200
5399
  return false;
6201
5400
  }
6202
5401
  const isSourceContainsAnAnchor = sourceElements.some((src) => {
6203
- 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;
6204
5403
  });
6205
5404
  if (!isSourceContainsAnAnchor) {
6206
5405
  return false;
6207
5406
  }
6208
5407
  const isTargetContainsAnAnchor = targetElements.some((target) => {
6209
- 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;
6210
5409
  });
6211
5410
  return isTargetContainsAnAnchor;
6212
5411
  }
6213
5412
 
6214
5413
  // src/style-commands/paste-style.ts
6215
- var import_editor_elements22 = require("@elementor/editor-elements");
6216
- var import_editor_props14 = require("@elementor/editor-props");
6217
- 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");
6218
5417
 
6219
5418
  // src/utils/command-utils.ts
6220
- var import_editor_elements20 = require("@elementor/editor-elements");
6221
- var import_editor_props13 = require("@elementor/editor-props");
5419
+ var import_editor_elements17 = require("@elementor/editor-elements");
5420
+ var import_editor_props10 = require("@elementor/editor-props");
6222
5421
  var import_i18n5 = require("@wordpress/i18n");
6223
5422
  function hasAtomicWidgets(args) {
6224
5423
  const { containers = [args.container] } = args;
@@ -6236,13 +5435,13 @@ function getClassesProp(container) {
6236
5435
  return null;
6237
5436
  }
6238
5437
  const [propKey] = Object.entries(propsSchema).find(
6239
- ([, propType]) => propType.kind === "plain" && propType.key === import_editor_props13.CLASSES_PROP_KEY
5438
+ ([, propType]) => propType.kind === "plain" && propType.key === import_editor_props10.CLASSES_PROP_KEY
6240
5439
  ) ?? [];
6241
5440
  return propKey ?? null;
6242
5441
  }
6243
5442
  function getContainerSchema(container) {
6244
5443
  const type = container?.model.get("widgetType") || container?.model.get("elType");
6245
- const widgetsCache = (0, import_editor_elements20.getWidgetsCache)();
5444
+ const widgetsCache = (0, import_editor_elements17.getWidgetsCache)();
6246
5445
  const elementType = widgetsCache?.[type];
6247
5446
  return elementType?.atomic_props_schema ?? null;
6248
5447
  }
@@ -6255,15 +5454,15 @@ function getClipboardElements(storageKey = "clipboard") {
6255
5454
  }
6256
5455
  }
6257
5456
  function getTitleForContainers(containers) {
6258
- 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);
6259
5458
  }
6260
5459
 
6261
5460
  // src/style-commands/undoable-actions/paste-element-style.ts
6262
- var import_editor_elements21 = require("@elementor/editor-elements");
5461
+ var import_editor_elements18 = require("@elementor/editor-elements");
6263
5462
  var import_editor_styles_repository4 = require("@elementor/editor-styles-repository");
6264
- var import_editor_v1_adapters23 = require("@elementor/editor-v1-adapters");
5463
+ var import_editor_v1_adapters22 = require("@elementor/editor-v1-adapters");
6265
5464
  var import_i18n6 = require("@wordpress/i18n");
6266
- var undoablePasteElementStyle = () => (0, import_editor_v1_adapters23.undoable)(
5465
+ var undoablePasteElementStyle = () => (0, import_editor_v1_adapters22.undoable)(
6267
5466
  {
6268
5467
  do: ({ containers, newStyle }) => {
6269
5468
  return containers.map((container) => {
@@ -6272,7 +5471,7 @@ var undoablePasteElementStyle = () => (0, import_editor_v1_adapters23.undoable)(
6272
5471
  if (!classesProp) {
6273
5472
  return null;
6274
5473
  }
6275
- const originalStyles = (0, import_editor_elements21.getElementStyles)(container.id);
5474
+ const originalStyles = (0, import_editor_elements18.getElementStyles)(container.id);
6276
5475
  const [styleId, styleDef] = Object.entries(originalStyles ?? {})[0] ?? [];
6277
5476
  const originalStyle = Object.keys(styleDef ?? {}).length ? styleDef : null;
6278
5477
  const revertData = {
@@ -6281,7 +5480,7 @@ var undoablePasteElementStyle = () => (0, import_editor_v1_adapters23.undoable)(
6281
5480
  };
6282
5481
  if (styleId) {
6283
5482
  newStyle.variants.forEach(({ meta, props, custom_css: customCss }) => {
6284
- (0, import_editor_elements21.updateElementStyle)({
5483
+ (0, import_editor_elements18.updateElementStyle)({
6285
5484
  elementId,
6286
5485
  styleId,
6287
5486
  meta,
@@ -6292,7 +5491,7 @@ var undoablePasteElementStyle = () => (0, import_editor_v1_adapters23.undoable)(
6292
5491
  } else {
6293
5492
  const [firstVariant] = newStyle.variants;
6294
5493
  const additionalVariants = newStyle.variants.slice(1);
6295
- revertData.styleId = (0, import_editor_elements21.createElementStyle)({
5494
+ revertData.styleId = (0, import_editor_elements18.createElementStyle)({
6296
5495
  elementId,
6297
5496
  classesProp,
6298
5497
  label: import_editor_styles_repository4.ELEMENTS_STYLES_RESERVED_LABEL,
@@ -6310,7 +5509,7 @@ var undoablePasteElementStyle = () => (0, import_editor_v1_adapters23.undoable)(
6310
5509
  return;
6311
5510
  }
6312
5511
  if (!revertData.originalStyle) {
6313
- (0, import_editor_elements21.deleteElementStyle)(container.id, revertData.styleId);
5512
+ (0, import_editor_elements18.deleteElementStyle)(container.id, revertData.styleId);
6314
5513
  return;
6315
5514
  }
6316
5515
  const classesProp = getClassesProp(container);
@@ -6319,7 +5518,7 @@ var undoablePasteElementStyle = () => (0, import_editor_v1_adapters23.undoable)(
6319
5518
  }
6320
5519
  const [firstVariant] = revertData.originalStyle.variants;
6321
5520
  const additionalVariants = revertData.originalStyle.variants.slice(1);
6322
- (0, import_editor_elements21.createElementStyle)({
5521
+ (0, import_editor_elements18.createElementStyle)({
6323
5522
  elementId: container.id,
6324
5523
  classesProp,
6325
5524
  label: import_editor_styles_repository4.ELEMENTS_STYLES_RESERVED_LABEL,
@@ -6339,12 +5538,12 @@ var undoablePasteElementStyle = () => (0, import_editor_v1_adapters23.undoable)(
6339
5538
  // src/style-commands/paste-style.ts
6340
5539
  function initPasteStyleCommand() {
6341
5540
  const pasteElementStyleCommand = undoablePasteElementStyle();
6342
- (0, import_editor_v1_adapters24.blockCommand)({
5541
+ (0, import_editor_v1_adapters23.blockCommand)({
6343
5542
  command: "document/elements/paste-style",
6344
5543
  condition: hasAtomicWidgets
6345
5544
  });
6346
- (0, import_editor_v1_adapters24.__privateListenTo)(
6347
- (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"),
6348
5547
  (e) => pasteStyles(e.args, pasteElementStyleCommand)
6349
5548
  );
6350
5549
  }
@@ -6356,7 +5555,7 @@ function pasteStyles(args, pasteLocalStyle) {
6356
5555
  }
6357
5556
  const clipboardElements = getClipboardElements(storageKey);
6358
5557
  const [clipboardElement] = clipboardElements ?? [];
6359
- const clipboardContainer = (0, import_editor_elements22.getContainer)(clipboardElement.id);
5558
+ const clipboardContainer = (0, import_editor_elements19.getContainer)(clipboardElement.id);
6360
5559
  if (!clipboardElement || !clipboardContainer || !isAtomicWidget(clipboardContainer)) {
6361
5560
  return;
6362
5561
  }
@@ -6375,7 +5574,7 @@ function getClassesWithoutLocalStyle(clipboardContainer, style) {
6375
5574
  if (!classesProp) {
6376
5575
  return [];
6377
5576
  }
6378
- const classesSetting = (0, import_editor_elements22.getElementSetting)(clipboardContainer.id, classesProp);
5577
+ const classesSetting = (0, import_editor_elements19.getElementSetting)(clipboardContainer.id, classesProp);
6379
5578
  return classesSetting?.value.filter((styleId) => styleId !== style?.id) ?? [];
6380
5579
  }
6381
5580
  function pasteClasses(containers, classes) {
@@ -6384,10 +5583,10 @@ function pasteClasses(containers, classes) {
6384
5583
  if (!classesProp) {
6385
5584
  return;
6386
5585
  }
6387
- const classesSetting = (0, import_editor_elements22.getElementSetting)(container.id, classesProp);
6388
- const currentClasses = import_editor_props14.classesPropTypeUtil.extract(classesSetting) ?? [];
6389
- const newClasses = import_editor_props14.classesPropTypeUtil.create(Array.from(/* @__PURE__ */ new Set([...classes, ...currentClasses])));
6390
- (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)({
6391
5590
  id: container.id,
6392
5591
  props: { [classesProp]: newClasses }
6393
5592
  });
@@ -6395,21 +5594,21 @@ function pasteClasses(containers, classes) {
6395
5594
  }
6396
5595
 
6397
5596
  // src/style-commands/reset-style.ts
6398
- var import_editor_v1_adapters26 = require("@elementor/editor-v1-adapters");
5597
+ var import_editor_v1_adapters25 = require("@elementor/editor-v1-adapters");
6399
5598
 
6400
5599
  // src/style-commands/undoable-actions/reset-element-style.ts
6401
- var import_editor_elements23 = require("@elementor/editor-elements");
5600
+ var import_editor_elements20 = require("@elementor/editor-elements");
6402
5601
  var import_editor_styles_repository5 = require("@elementor/editor-styles-repository");
6403
- var import_editor_v1_adapters25 = require("@elementor/editor-v1-adapters");
5602
+ var import_editor_v1_adapters24 = require("@elementor/editor-v1-adapters");
6404
5603
  var import_i18n7 = require("@wordpress/i18n");
6405
- var undoableResetElementStyle = () => (0, import_editor_v1_adapters25.undoable)(
5604
+ var undoableResetElementStyle = () => (0, import_editor_v1_adapters24.undoable)(
6406
5605
  {
6407
5606
  do: ({ containers }) => {
6408
5607
  return containers.map((container) => {
6409
5608
  const elementId = container.model.get("id");
6410
- const containerStyles = (0, import_editor_elements23.getElementStyles)(elementId);
5609
+ const containerStyles = (0, import_editor_elements20.getElementStyles)(elementId);
6411
5610
  Object.keys(containerStyles ?? {}).forEach(
6412
- (styleId) => (0, import_editor_elements23.deleteElementStyle)(elementId, styleId)
5611
+ (styleId) => (0, import_editor_elements20.deleteElementStyle)(elementId, styleId)
6413
5612
  );
6414
5613
  return containerStyles;
6415
5614
  });
@@ -6425,7 +5624,7 @@ var undoableResetElementStyle = () => (0, import_editor_v1_adapters25.undoable)(
6425
5624
  Object.entries(containerStyles ?? {}).forEach(([styleId, style]) => {
6426
5625
  const [firstVariant] = style.variants;
6427
5626
  const additionalVariants = style.variants.slice(1);
6428
- (0, import_editor_elements23.createElementStyle)({
5627
+ (0, import_editor_elements20.createElementStyle)({
6429
5628
  elementId,
6430
5629
  classesProp,
6431
5630
  styleId,
@@ -6446,12 +5645,12 @@ var undoableResetElementStyle = () => (0, import_editor_v1_adapters25.undoable)(
6446
5645
  // src/style-commands/reset-style.ts
6447
5646
  function initResetStyleCommand() {
6448
5647
  const resetElementStyles = undoableResetElementStyle();
6449
- (0, import_editor_v1_adapters26.blockCommand)({
5648
+ (0, import_editor_v1_adapters25.blockCommand)({
6450
5649
  command: "document/elements/reset-style",
6451
5650
  condition: hasAtomicWidgets
6452
5651
  });
6453
- (0, import_editor_v1_adapters26.__privateListenTo)(
6454
- (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"),
6455
5654
  (e) => resetStyles(e.args, resetElementStyles)
6456
5655
  );
6457
5656
  }
@@ -6497,7 +5696,7 @@ function init() {
6497
5696
  component: ClassesRename
6498
5697
  });
6499
5698
  initCanvasMcp(
6500
- (0, import_editor_mcp6.getMCPByDomain)("canvas", {
5699
+ (0, import_editor_mcp4.getMCPByDomain)("canvas", {
6501
5700
  instructions: `Everything related to V4 ( Atomic ) canvas.
6502
5701
  # Canvas workflow for new compositions
6503
5702
  - Configure elements settings and styles
@@ -6600,9 +5799,9 @@ function getRectClipPath(rect, viewport) {
6600
5799
  }
6601
5800
 
6602
5801
  // src/hooks/use-canvas-document.ts
6603
- var import_editor_v1_adapters27 = require("@elementor/editor-v1-adapters");
5802
+ var import_editor_v1_adapters26 = require("@elementor/editor-v1-adapters");
6604
5803
  function useCanvasDocument() {
6605
- 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)());
6606
5805
  }
6607
5806
 
6608
5807
  // src/hooks/use-escape-on-canvas.ts
@@ -6625,10 +5824,10 @@ function useEscapeOnCanvas(canvasDocument, onEscape) {
6625
5824
  }
6626
5825
 
6627
5826
  // src/utils/after-render.ts
6628
- var import_editor_elements24 = require("@elementor/editor-elements");
5827
+ var import_editor_elements21 = require("@elementor/editor-elements");
6629
5828
  function doAfterRender(elementIds, callback) {
6630
5829
  const pending = elementIds.map((elementId) => {
6631
- const view = (0, import_editor_elements24.getContainer)(elementId)?.view;
5830
+ const view = (0, import_editor_elements21.getContainer)(elementId)?.view;
6632
5831
  if (!view || !hasDoAfterRender(view)) {
6633
5832
  return void 0;
6634
5833
  }
@@ -6643,6 +5842,9 @@ function doAfterRender(elementIds, callback) {
6643
5842
  function hasDoAfterRender(view) {
6644
5843
  return typeof view?._doAfterRender === "function";
6645
5844
  }
5845
+
5846
+ // src/sync/element-added-event.ts
5847
+ var ELEMENT_ADDED_EVENT = "elementor/canvas/element-added";
6646
5848
  // Annotate the CommonJS export names for ESM import in node:
6647
5849
  0 && (module.exports = {
6648
5850
  BREAKPOINTS_SCHEMA_FULL_URI,