@elementor/editor-canvas 4.1.0 → 4.2.0-839
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +22 -4
- package/dist/index.d.ts +22 -4
- package/dist/index.js +773 -137
- package/dist/index.mjs +730 -86
- package/package.json +18 -18
- package/src/__tests__/settings-props-resolver.test.ts +3 -0
- package/src/composition-builder/composition-builder.ts +5 -5
- package/src/form-structure/utils.ts +4 -0
- package/src/hooks/__tests__/use-style-items.test.ts +55 -0
- package/src/hooks/use-style-items.ts +12 -14
- package/src/index.ts +2 -0
- package/src/init-settings-transformers.ts +4 -0
- package/src/init-style-transformers.ts +2 -0
- package/src/legacy/create-nested-templated-element-type.ts +11 -2
- package/src/legacy/create-pending-element.ts +74 -0
- package/src/legacy/create-templated-element-type.ts +2 -2
- package/src/legacy/types.ts +9 -1
- package/src/mcp/canvas-mcp.ts +8 -0
- package/src/mcp/resources/available-widgets-resource.ts +67 -0
- package/src/mcp/resources/document-structure-resource.ts +51 -36
- package/src/mcp/resources/editor-state-resource.ts +122 -0
- package/src/mcp/resources/general-context-resource.ts +99 -0
- package/src/mcp/resources/selected-element-resource.ts +217 -0
- package/src/mcp/resources/widgets-schema-resource.ts +74 -14
- package/src/mcp/tools/build-composition/prompt.ts +6 -0
- package/src/mcp/tools/build-composition/tool.ts +26 -0
- package/src/mcp/tools/configure-element/prompt.ts +6 -6
- package/src/mcp/tools/configure-element/schema.ts +1 -1
- package/src/mcp/tools/configure-element/tool.ts +12 -0
- package/src/mcp/tools/get-element-config/tool.ts +13 -3
- package/src/mcp/utils/do-update-element-property.ts +1 -1
- package/src/mcp/utils/element-data-util.ts +46 -0
- package/src/mcp/utils/validate-input.ts +1 -1
- package/src/sync/global-styles-imported-event.ts +8 -0
- package/src/transformers/settings/date-range-transformer.ts +12 -0
- package/src/transformers/settings/time-range-transformer.ts +12 -0
- package/src/transformers/shared/image-src-transformer.ts +2 -0
- package/src/transformers/shared/image-transformer.ts +4 -1
- package/src/transformers/styles/span-transformer.ts +5 -0
- package/src/utils/after-render.ts +26 -0
- package/src/mcp/utils/generate-available-tags.ts +0 -23
package/dist/index.mjs
CHANGED
|
@@ -45,12 +45,81 @@ var initBreakpointsResource = (reg) => {
|
|
|
45
45
|
};
|
|
46
46
|
|
|
47
47
|
// src/mcp/resources/widgets-schema-resource.ts
|
|
48
|
-
import { getWidgetsCache } from "@elementor/editor-elements";
|
|
48
|
+
import { getWidgetsCache as getWidgetsCache2 } from "@elementor/editor-elements";
|
|
49
49
|
import { ResourceTemplate } from "@elementor/editor-mcp";
|
|
50
50
|
import {
|
|
51
51
|
Schema
|
|
52
52
|
} from "@elementor/editor-props";
|
|
53
53
|
import { getStylesSchema } from "@elementor/editor-styles";
|
|
54
|
+
|
|
55
|
+
// src/mcp/utils/element-data-util.ts
|
|
56
|
+
import { getWidgetsCache } from "@elementor/editor-elements";
|
|
57
|
+
function hasV3Controls(controls) {
|
|
58
|
+
return typeof controls === "object" && controls !== null && Object.keys(controls).length > 0;
|
|
59
|
+
}
|
|
60
|
+
function isWidgetAvailableForLLM(config) {
|
|
61
|
+
if (!config) {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
if (config.meta?.llm_support === false) {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
if (config.atomic_props_schema) {
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
return hasV3Controls(config.controls);
|
|
71
|
+
}
|
|
72
|
+
function getWidgetVersion(config) {
|
|
73
|
+
return config?.atomic_props_schema ? "v4" : "v3";
|
|
74
|
+
}
|
|
75
|
+
function getAvailableWidgets() {
|
|
76
|
+
const cache = getWidgetsCache() ?? {};
|
|
77
|
+
return Object.keys(cache).filter((widgetType) => isWidgetAvailableForLLM(cache[widgetType])).sort().map((widgetType) => {
|
|
78
|
+
const config = cache[widgetType];
|
|
79
|
+
const description = typeof config?.meta?.description === "string" ? config.meta.description : void 0;
|
|
80
|
+
return {
|
|
81
|
+
type: widgetType,
|
|
82
|
+
version: getWidgetVersion(config),
|
|
83
|
+
...description && { description }
|
|
84
|
+
};
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// src/mcp/resources/widgets-schema-resource.ts
|
|
89
|
+
var V3_LAYOUT_CONTROL_TYPES = /* @__PURE__ */ new Set(["section", "tab", "tabs"]);
|
|
90
|
+
function extractV3ControlsMetadata(controls) {
|
|
91
|
+
if (!hasV3Controls(controls)) {
|
|
92
|
+
return {};
|
|
93
|
+
}
|
|
94
|
+
const result = {};
|
|
95
|
+
for (const [controlKey, raw] of Object.entries(controls)) {
|
|
96
|
+
if (!raw || typeof raw !== "object") {
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
const control = raw;
|
|
100
|
+
const controlType = typeof control.type === "string" ? control.type : void 0;
|
|
101
|
+
if (controlType && V3_LAYOUT_CONTROL_TYPES.has(controlType)) {
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
const entry = {};
|
|
105
|
+
if (Object.prototype.hasOwnProperty.call(control, "default")) {
|
|
106
|
+
entry.default = control.default;
|
|
107
|
+
}
|
|
108
|
+
if (controlType) {
|
|
109
|
+
entry.type = controlType;
|
|
110
|
+
}
|
|
111
|
+
if (Object.prototype.hasOwnProperty.call(control, "options") && control.options !== void 0) {
|
|
112
|
+
const options = control.options;
|
|
113
|
+
if (options && typeof options === "object" && !Array.isArray(options)) {
|
|
114
|
+
entry.options = Object.keys(options);
|
|
115
|
+
} else {
|
|
116
|
+
entry.options = options;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
result[controlKey] = entry;
|
|
120
|
+
}
|
|
121
|
+
return result;
|
|
122
|
+
}
|
|
54
123
|
var WIDGET_SCHEMA_URI = "elementor://widgets/schema/{widgetType}";
|
|
55
124
|
var STYLE_SCHEMA_URI = "elementor://styles/schema/{category}";
|
|
56
125
|
var BEST_PRACTICES_URI = "elementor://styles/best-practices";
|
|
@@ -98,7 +167,7 @@ Variables from the user context ARE NOT SUPPORTED AND WILL RESOLVE IN ERROR.
|
|
|
98
167
|
}
|
|
99
168
|
}),
|
|
100
169
|
{
|
|
101
|
-
description: "Common styles schema for the specified category"
|
|
170
|
+
description: "Common styles schema for the specified category (applicable for V4 elements only)"
|
|
102
171
|
},
|
|
103
172
|
async (uri, variables) => {
|
|
104
173
|
const category = typeof variables.category === "string" ? variables.category : variables.category?.[0];
|
|
@@ -124,9 +193,9 @@ Variables from the user context ARE NOT SUPPORTED AND WILL RESOLVE IN ERROR.
|
|
|
124
193
|
"widget-schema-by-type",
|
|
125
194
|
new ResourceTemplate(WIDGET_SCHEMA_URI, {
|
|
126
195
|
list: () => {
|
|
127
|
-
const cache =
|
|
128
|
-
const availableWidgets = Object.keys(cache
|
|
129
|
-
(widgetType) => cache[widgetType]
|
|
196
|
+
const cache = getWidgetsCache2() || {};
|
|
197
|
+
const availableWidgets = Object.keys(cache).filter(
|
|
198
|
+
(widgetType) => isWidgetAvailableForLLM(cache[widgetType])
|
|
130
199
|
);
|
|
131
200
|
return {
|
|
132
201
|
resources: availableWidgets.map((widgetType) => ({
|
|
@@ -141,20 +210,34 @@ Variables from the user context ARE NOT SUPPORTED AND WILL RESOLVE IN ERROR.
|
|
|
141
210
|
},
|
|
142
211
|
async (uri, variables) => {
|
|
143
212
|
const widgetType = typeof variables.widgetType === "string" ? variables.widgetType : variables.widgetType?.[0];
|
|
144
|
-
const widgetData =
|
|
145
|
-
|
|
146
|
-
if (!propSchema || !widgetData) {
|
|
213
|
+
const widgetData = getWidgetsCache2()?.[widgetType];
|
|
214
|
+
if (!widgetData) {
|
|
147
215
|
throw new Error(`No prop schema found for element type: ${widgetType}`);
|
|
148
216
|
}
|
|
217
|
+
const propSchema = widgetData.atomic_props_schema;
|
|
218
|
+
if (!propSchema) {
|
|
219
|
+
if (!hasV3Controls(widgetData.controls)) {
|
|
220
|
+
throw new Error(`No prop schema found for element type: ${widgetType}`);
|
|
221
|
+
}
|
|
222
|
+
const controlMetadata = extractV3ControlsMetadata(widgetData.controls);
|
|
223
|
+
return {
|
|
224
|
+
contents: [
|
|
225
|
+
{
|
|
226
|
+
uri: uri.toString(),
|
|
227
|
+
mimeType: "application/json",
|
|
228
|
+
text: JSON.stringify({
|
|
229
|
+
widget_version: "v3",
|
|
230
|
+
message: "This widget exists in the editor but has no atomic props schema (V4). Use control_metadata as non-authoritative hints from legacy controls.",
|
|
231
|
+
fields_note: "All settings are optional; there is no JSON schema for this widget type.",
|
|
232
|
+
properties: controlMetadata
|
|
233
|
+
})
|
|
234
|
+
}
|
|
235
|
+
]
|
|
236
|
+
};
|
|
237
|
+
}
|
|
149
238
|
const asJson = Object.fromEntries(
|
|
150
|
-
Object.entries(propSchema).map(([key, propType]) => [
|
|
151
|
-
key,
|
|
152
|
-
Schema.propTypeToJsonSchema(propType)
|
|
153
|
-
])
|
|
239
|
+
Object.entries(propSchema).filter(([key, propType]) => Schema.isPropKeyConfigurable(key, propType)).map(([key, propType]) => [key, Schema.propTypeToJsonSchema(propType)])
|
|
154
240
|
);
|
|
155
|
-
Schema.nonConfigurablePropKeys.forEach((key) => {
|
|
156
|
-
delete asJson[key];
|
|
157
|
-
});
|
|
158
241
|
const description = typeof widgetData?.meta?.description === "string" ? widgetData.meta.description : void 0;
|
|
159
242
|
const defaultStyles = {};
|
|
160
243
|
const baseStyleSchema = widgetData?.base_styles;
|
|
@@ -174,7 +257,7 @@ Variables from the user context ARE NOT SUPPORTED AND WILL RESOLVE IN ERROR.
|
|
|
174
257
|
llmGuidance.default_styles = defaultStyles;
|
|
175
258
|
}
|
|
176
259
|
const allowedChildTypes = widgetData.allowed_child_types;
|
|
177
|
-
const allWidgets =
|
|
260
|
+
const allWidgets = getWidgetsCache2() || {};
|
|
178
261
|
const allowedParents = Object.entries(allWidgets).filter(([, parentConfig]) => parentConfig.allowed_child_types?.includes(widgetType)).map(([parentType]) => parentType);
|
|
179
262
|
if (allowedChildTypes?.length || allowedParents.length) {
|
|
180
263
|
llmGuidance.nesting = {
|
|
@@ -1049,8 +1132,9 @@ function createProviderSubscriber2({ provider, renderStyles, setStyleItems, getC
|
|
|
1049
1132
|
...style,
|
|
1050
1133
|
cssName: provider.actions.resolveCssName(style.id)
|
|
1051
1134
|
}));
|
|
1052
|
-
|
|
1053
|
-
|
|
1135
|
+
const breakpointSplit = breakToBreakpoints(changedStyles);
|
|
1136
|
+
return renderStyles({ styles: breakpointSplit, signal }).then((rendered) => {
|
|
1137
|
+
updateCacheItems(cache, changedIds, rendered);
|
|
1054
1138
|
return getOrderedItems(cache);
|
|
1055
1139
|
});
|
|
1056
1140
|
}
|
|
@@ -1107,19 +1191,14 @@ function getChangedStyleIds(previous, current) {
|
|
|
1107
1191
|
function getOrderedItems(cache) {
|
|
1108
1192
|
return cache.orderedIds.map((id) => cache.itemsById.get(id)).filter((items) => items !== void 0).flat();
|
|
1109
1193
|
}
|
|
1110
|
-
function updateCacheItems(cache, changedItems) {
|
|
1194
|
+
function updateCacheItems(cache, changedIds, changedItems) {
|
|
1195
|
+
for (const id of changedIds) {
|
|
1196
|
+
cache.itemsById.delete(id);
|
|
1197
|
+
}
|
|
1111
1198
|
for (const item of changedItems) {
|
|
1112
|
-
const existing = cache.itemsById.get(item.id);
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
if (idx >= 0) {
|
|
1116
|
-
existing[idx] = item;
|
|
1117
|
-
} else {
|
|
1118
|
-
existing.push(item);
|
|
1119
|
-
}
|
|
1120
|
-
} else {
|
|
1121
|
-
cache.itemsById.set(item.id, [item]);
|
|
1122
|
-
}
|
|
1199
|
+
const existing = cache.itemsById.get(item.id) || [];
|
|
1200
|
+
existing.push(item);
|
|
1201
|
+
cache.itemsById.set(item.id, existing);
|
|
1123
1202
|
}
|
|
1124
1203
|
}
|
|
1125
1204
|
function rebuildCache(cache, allStyles, items) {
|
|
@@ -1178,7 +1257,11 @@ var FORM_FIELD_ELEMENT_TYPES = /* @__PURE__ */ new Set([
|
|
|
1178
1257
|
"e-form-label",
|
|
1179
1258
|
"e-form-checkbox",
|
|
1180
1259
|
"e-form-submit-button",
|
|
1181
|
-
"e-form-select"
|
|
1260
|
+
"e-form-select",
|
|
1261
|
+
"e-form-radio-button",
|
|
1262
|
+
"e-form-file-upload",
|
|
1263
|
+
"e-form-date-picker",
|
|
1264
|
+
"e-form-time-picker"
|
|
1182
1265
|
]);
|
|
1183
1266
|
function getArgsElementType(args) {
|
|
1184
1267
|
return args.model?.widgetType || args.model?.elType;
|
|
@@ -1393,6 +1476,17 @@ function createClassesTransformer() {
|
|
|
1393
1476
|
});
|
|
1394
1477
|
}
|
|
1395
1478
|
|
|
1479
|
+
// src/transformers/settings/date-range-transformer.ts
|
|
1480
|
+
var dateRangeTransformer = createTransformer((value) => {
|
|
1481
|
+
if (!value || Object.keys(value).length === 0) {
|
|
1482
|
+
return null;
|
|
1483
|
+
}
|
|
1484
|
+
return {
|
|
1485
|
+
min: value.min || null,
|
|
1486
|
+
max: value.max || null
|
|
1487
|
+
};
|
|
1488
|
+
});
|
|
1489
|
+
|
|
1396
1490
|
// src/transformers/settings/date-time-transformer.ts
|
|
1397
1491
|
var dateTimeTransformer = createTransformer((values) => {
|
|
1398
1492
|
return values.map((value) => {
|
|
@@ -1427,10 +1521,22 @@ var queryTransformer = createTransformer(({ id }) => {
|
|
|
1427
1521
|
return id ?? null;
|
|
1428
1522
|
});
|
|
1429
1523
|
|
|
1524
|
+
// src/transformers/settings/time-range-transformer.ts
|
|
1525
|
+
var timeRangeTransformer = createTransformer((value) => {
|
|
1526
|
+
if (!value || Object.keys(value).length === 0) {
|
|
1527
|
+
return null;
|
|
1528
|
+
}
|
|
1529
|
+
return {
|
|
1530
|
+
min: value.min || null,
|
|
1531
|
+
max: value.max || null
|
|
1532
|
+
};
|
|
1533
|
+
});
|
|
1534
|
+
|
|
1430
1535
|
// src/transformers/shared/image-src-transformer.ts
|
|
1431
1536
|
var imageSrcTransformer = createTransformer((value) => ({
|
|
1432
1537
|
id: value.id ?? null,
|
|
1433
|
-
url: value.url ?? null
|
|
1538
|
+
url: value.url ?? null,
|
|
1539
|
+
alt: value.alt ?? null
|
|
1434
1540
|
}));
|
|
1435
1541
|
|
|
1436
1542
|
// src/transformers/shared/image-transformer.ts
|
|
@@ -1438,7 +1544,7 @@ import { getMediaAttachment } from "@elementor/wp-media";
|
|
|
1438
1544
|
var imageTransformer = createTransformer(async (value) => {
|
|
1439
1545
|
const { src, size: size2 } = value;
|
|
1440
1546
|
if (!src?.id) {
|
|
1441
|
-
return src?.url ? { src: src.url } : null;
|
|
1547
|
+
return src?.url ? { src: src.url, alt: src.alt ?? "" } : null;
|
|
1442
1548
|
}
|
|
1443
1549
|
const attachment = await getMediaAttachment({ id: src.id });
|
|
1444
1550
|
const sizedAttachment = attachment?.sizes?.[size2 ?? ""];
|
|
@@ -1446,14 +1552,16 @@ var imageTransformer = createTransformer(async (value) => {
|
|
|
1446
1552
|
return {
|
|
1447
1553
|
src: sizedAttachment.url,
|
|
1448
1554
|
height: sizedAttachment.height,
|
|
1449
|
-
width: sizedAttachment.width
|
|
1555
|
+
width: sizedAttachment.width,
|
|
1556
|
+
alt: attachment.alt
|
|
1450
1557
|
};
|
|
1451
1558
|
}
|
|
1452
1559
|
if (attachment) {
|
|
1453
1560
|
return {
|
|
1454
1561
|
src: attachment.url,
|
|
1455
1562
|
height: attachment.height,
|
|
1456
|
-
width: attachment.width
|
|
1563
|
+
width: attachment.width,
|
|
1564
|
+
alt: attachment.alt
|
|
1457
1565
|
};
|
|
1458
1566
|
}
|
|
1459
1567
|
return null;
|
|
@@ -1540,7 +1648,7 @@ var videoSrcTransformer = createTransformer(async (value) => {
|
|
|
1540
1648
|
|
|
1541
1649
|
// src/init-settings-transformers.ts
|
|
1542
1650
|
function initSettingsTransformers() {
|
|
1543
|
-
settingsTransformersRegistry.register("classes", createClassesTransformer()).register("link", linkTransformer).register("query", queryTransformer).register("image", imageTransformer).register("image-src", imageSrcTransformer).register("svg-src", svgSrcTransformer).register("video-src", videoSrcTransformer).register("attributes", attributesTransformer).register("date-time", dateTimeTransformer).register("html-v2", htmlV2Transformer).register("html-v3", htmlV3Transformer).registerFallback(plainTransformer);
|
|
1651
|
+
settingsTransformersRegistry.register("classes", createClassesTransformer()).register("link", linkTransformer).register("query", queryTransformer).register("image", imageTransformer).register("image-src", imageSrcTransformer).register("svg-src", svgSrcTransformer).register("video-src", videoSrcTransformer).register("attributes", attributesTransformer).register("date-time", dateTimeTransformer).register("html-v2", htmlV2Transformer).register("html-v3", htmlV3Transformer).register("date-range", dateRangeTransformer).register("time-range", timeRangeTransformer).registerFallback(plainTransformer);
|
|
1544
1652
|
}
|
|
1545
1653
|
|
|
1546
1654
|
// src/transformers/styles/background-color-overlay-transformer.ts
|
|
@@ -1745,6 +1853,11 @@ var sizeTransformer = createTransformer((value) => {
|
|
|
1745
1853
|
return value.unit === "custom" ? value.size : `${value.size}${value.unit}`;
|
|
1746
1854
|
});
|
|
1747
1855
|
|
|
1856
|
+
// src/transformers/styles/span-transformer.ts
|
|
1857
|
+
var spanTransformer = createTransformer((value) => {
|
|
1858
|
+
return value || 0 === value ? "span " + value : null;
|
|
1859
|
+
});
|
|
1860
|
+
|
|
1748
1861
|
// src/transformers/styles/stroke-transformer.ts
|
|
1749
1862
|
var strokeTransformer = createTransformer((value) => {
|
|
1750
1863
|
const parsed = {
|
|
@@ -1851,7 +1964,7 @@ function initStyleTransformers() {
|
|
|
1851
1964
|
["block-start", "block-end", "inline-start", "inline-end"],
|
|
1852
1965
|
({ propKey, key }) => `${propKey}-${key}`
|
|
1853
1966
|
)
|
|
1854
|
-
).register("filter", filterTransformer).register("backdrop-filter", filterTransformer).register("box-shadow", createCombineArrayTransformer(",")).register("background", backgroundTransformer).register("background-overlay", backgroundOverlayTransformer).register("background-color-overlay", backgroundColorOverlayTransformer).register("background-image-overlay", backgroundImageOverlayTransformer).register("background-gradient-overlay", backgroundGradientOverlayTransformer).register("gradient-color-stop", createCombineArrayTransformer(",")).register("color-stop", colorStopTransformer).register("background-image-position-offset", positionTransformer).register("background-image-size-scale", backgroundImageSizeScaleTransformer).register("image-src", imageSrcTransformer).register("image", imageTransformer).register("object-position", positionTransformer).register("transform-origin", transformOriginTransformer).register("perspective-origin", perspectiveOriginTransformer).register("transform-move", transformMoveTransformer).register("transform-scale", transformScaleTransformer).register("transform-rotate", transformRotateTransformer).register("transform-skew", transformSkewTransformer).register("transform-functions", transformFunctionsTransformer).register(
|
|
1967
|
+
).register("filter", filterTransformer).register("backdrop-filter", filterTransformer).register("box-shadow", createCombineArrayTransformer(",")).register("background", backgroundTransformer).register("background-overlay", backgroundOverlayTransformer).register("background-color-overlay", backgroundColorOverlayTransformer).register("background-image-overlay", backgroundImageOverlayTransformer).register("background-gradient-overlay", backgroundGradientOverlayTransformer).register("gradient-color-stop", createCombineArrayTransformer(",")).register("color-stop", colorStopTransformer).register("background-image-position-offset", positionTransformer).register("background-image-size-scale", backgroundImageSizeScaleTransformer).register("image-src", imageSrcTransformer).register("image", imageTransformer).register("object-position", positionTransformer).register("span", spanTransformer).register("transform-origin", transformOriginTransformer).register("perspective-origin", perspectiveOriginTransformer).register("transform-move", transformMoveTransformer).register("transform-scale", transformScaleTransformer).register("transform-rotate", transformRotateTransformer).register("transform-skew", transformSkewTransformer).register("transform-functions", transformFunctionsTransformer).register(
|
|
1855
1968
|
"transform",
|
|
1856
1969
|
createMultiPropsTransformer(
|
|
1857
1970
|
["transform-functions", "transform-origin", "perspective", "perspective-origin"],
|
|
@@ -1876,7 +1989,7 @@ function initStyleTransformers() {
|
|
|
1876
1989
|
}
|
|
1877
1990
|
|
|
1878
1991
|
// src/legacy/init-legacy-views.ts
|
|
1879
|
-
import { getWidgetsCache as
|
|
1992
|
+
import { getWidgetsCache as getWidgetsCache3 } from "@elementor/editor-elements";
|
|
1880
1993
|
import { __privateListenTo, v1ReadyEvent as v1ReadyEvent2 } from "@elementor/editor-v1-adapters";
|
|
1881
1994
|
|
|
1882
1995
|
// src/renderers/create-dom-renderer.ts
|
|
@@ -2007,6 +2120,60 @@ function createElementViewClassDeclaration() {
|
|
|
2007
2120
|
// src/legacy/create-nested-templated-element-type.ts
|
|
2008
2121
|
import { ELEMENT_STYLE_CHANGE_EVENT } from "@elementor/editor-elements";
|
|
2009
2122
|
|
|
2123
|
+
// src/legacy/create-pending-element.ts
|
|
2124
|
+
import {
|
|
2125
|
+
addModelToParent,
|
|
2126
|
+
findModelInDocument,
|
|
2127
|
+
generateElementId,
|
|
2128
|
+
getContainer
|
|
2129
|
+
} from "@elementor/editor-elements";
|
|
2130
|
+
function createPendingElement(wrapperView, data, options = {}) {
|
|
2131
|
+
const parentContainer = wrapperView.getContainer();
|
|
2132
|
+
const model = { ...data };
|
|
2133
|
+
if (!model.id) {
|
|
2134
|
+
model.id = generateElementId();
|
|
2135
|
+
}
|
|
2136
|
+
if (!model.elements) {
|
|
2137
|
+
model.elements = [];
|
|
2138
|
+
}
|
|
2139
|
+
const added = addModelToParent(parentContainer.id, model, options);
|
|
2140
|
+
if (!added) {
|
|
2141
|
+
return void 0;
|
|
2142
|
+
}
|
|
2143
|
+
const childId = model.id;
|
|
2144
|
+
const childModel = findModelInDocument(childId);
|
|
2145
|
+
if (!childModel) {
|
|
2146
|
+
return void 0;
|
|
2147
|
+
}
|
|
2148
|
+
const pendingContainer = {
|
|
2149
|
+
id: childId,
|
|
2150
|
+
settings: { get: () => ({}), set: () => ({}), toJSON: () => ({}) },
|
|
2151
|
+
parent: parentContainer,
|
|
2152
|
+
model: childModel,
|
|
2153
|
+
view: void 0,
|
|
2154
|
+
lookup() {
|
|
2155
|
+
return getContainer(childId) ?? pendingContainer;
|
|
2156
|
+
}
|
|
2157
|
+
};
|
|
2158
|
+
wrapperView.once("render", () => {
|
|
2159
|
+
wrapperView.model?.trigger?.("navigator:add", childModel, options);
|
|
2160
|
+
});
|
|
2161
|
+
if (options.edit !== false) {
|
|
2162
|
+
selectChildWhenWrapperRenders(wrapperView, childId);
|
|
2163
|
+
}
|
|
2164
|
+
return { getContainer: () => pendingContainer };
|
|
2165
|
+
}
|
|
2166
|
+
function selectChildWhenWrapperRenders(wrapperView, childId) {
|
|
2167
|
+
wrapperView.once("render", () => {
|
|
2168
|
+
const childContainer = getContainer(childId);
|
|
2169
|
+
if (childContainer?.model?.trigger) {
|
|
2170
|
+
childContainer.model.trigger("request:edit");
|
|
2171
|
+
return;
|
|
2172
|
+
}
|
|
2173
|
+
wrapperView.model?.trigger?.("request:edit");
|
|
2174
|
+
});
|
|
2175
|
+
}
|
|
2176
|
+
|
|
2010
2177
|
// src/legacy/twig-rendering-utils.ts
|
|
2011
2178
|
function setupTwigRenderer({ renderer, element }) {
|
|
2012
2179
|
const templateKey = element.twig_main_template;
|
|
@@ -2224,6 +2391,7 @@ function createNestedTemplatedElementView({
|
|
|
2224
2391
|
const AtomicElementBaseView = legacyWindow.elementor.modules.elements.views.createAtomicElementBase(type);
|
|
2225
2392
|
const parentRenderChildren = AtomicElementBaseView.prototype._renderChildren;
|
|
2226
2393
|
const parentOpenEditingPanel = AtomicElementBaseView.prototype._openEditingPanel;
|
|
2394
|
+
const parentAddElement = AtomicElementBaseView.prototype.addElement;
|
|
2227
2395
|
return AtomicElementBaseView.extend({
|
|
2228
2396
|
_abortController: null,
|
|
2229
2397
|
_lastResolvedSettingsHash: null,
|
|
@@ -2331,7 +2499,6 @@ function createNestedTemplatedElementView({
|
|
|
2331
2499
|
Array.from(newEl.attributes).forEach((attr) => {
|
|
2332
2500
|
targetEl.setAttribute(attr.name, attr.value);
|
|
2333
2501
|
});
|
|
2334
|
-
targetEl.setAttribute("draggable", "true");
|
|
2335
2502
|
targetEl.innerHTML = overlayHTML + newEl.innerHTML;
|
|
2336
2503
|
if (needsTagSwap) {
|
|
2337
2504
|
oldEl.replaceWith(targetEl);
|
|
@@ -2423,6 +2590,12 @@ function createNestedTemplatedElementView({
|
|
|
2423
2590
|
_openEditingPanel(options) {
|
|
2424
2591
|
this._doAfterRender(() => parentOpenEditingPanel.call(this, options));
|
|
2425
2592
|
},
|
|
2593
|
+
addElement(data, options) {
|
|
2594
|
+
if (this.isRendered) {
|
|
2595
|
+
return parentAddElement.call(this, data, options);
|
|
2596
|
+
}
|
|
2597
|
+
return createPendingElement(this, data, options);
|
|
2598
|
+
},
|
|
2426
2599
|
getInteractionId() {
|
|
2427
2600
|
const originId = this.model.get("originId");
|
|
2428
2601
|
const id = this.model.get("id");
|
|
@@ -2499,7 +2672,7 @@ import { createRoot } from "react-dom/client";
|
|
|
2499
2672
|
|
|
2500
2673
|
// src/legacy/replacements/inline-editing/inline-editing-elements.tsx
|
|
2501
2674
|
import * as React6 from "react";
|
|
2502
|
-
import { getContainer, getElementLabel, getElementType as getElementType2 } from "@elementor/editor-elements";
|
|
2675
|
+
import { getContainer as getContainer2, getElementLabel, getElementType as getElementType2 } from "@elementor/editor-elements";
|
|
2503
2676
|
import {
|
|
2504
2677
|
htmlV3PropTypeUtil as htmlV3PropTypeUtil2,
|
|
2505
2678
|
parseHtmlChildren,
|
|
@@ -2946,7 +3119,7 @@ var InlineEditingReplacement = class extends ReplacementBase {
|
|
|
2946
3119
|
runCommandSync(
|
|
2947
3120
|
"document/elements/set-settings",
|
|
2948
3121
|
{
|
|
2949
|
-
container:
|
|
3122
|
+
container: getContainer2(this.id),
|
|
2950
3123
|
settings: {
|
|
2951
3124
|
[key]: value
|
|
2952
3125
|
}
|
|
@@ -3121,7 +3294,7 @@ function registerElementType(type, elementTypeGenerator) {
|
|
|
3121
3294
|
}
|
|
3122
3295
|
function initLegacyViews() {
|
|
3123
3296
|
__privateListenTo(v1ReadyEvent2(), () => {
|
|
3124
|
-
const widgetsCache =
|
|
3297
|
+
const widgetsCache = getWidgetsCache3() ?? {};
|
|
3125
3298
|
const legacyWindow = window;
|
|
3126
3299
|
const renderer = createDomRenderer();
|
|
3127
3300
|
registerProPromotionTypes(widgetsCache);
|
|
@@ -3207,7 +3380,67 @@ function initTabsModelExtensions() {
|
|
|
3207
3380
|
registerModelExtensions("e-tab", tabModelExtensions);
|
|
3208
3381
|
}
|
|
3209
3382
|
|
|
3383
|
+
// src/mcp/resources/available-widgets-resource.ts
|
|
3384
|
+
import { v1ReadyEvent as v1ReadyEvent3 } from "@elementor/editor-v1-adapters";
|
|
3385
|
+
var AVAILABLE_WIDGETS_URI = "elementor://context/available-widgets";
|
|
3386
|
+
var AVAILABLE_WIDGETS_URI_V4 = "elementor://context/available-widgets/v4";
|
|
3387
|
+
var initAvailableWidgetsResource = (reg) => {
|
|
3388
|
+
const { resource, sendResourceUpdated } = reg;
|
|
3389
|
+
const buildContents = (uri, filterFunction = () => true) => {
|
|
3390
|
+
const widgets = getAvailableWidgets().filter(filterFunction);
|
|
3391
|
+
return {
|
|
3392
|
+
contents: [
|
|
3393
|
+
{
|
|
3394
|
+
uri,
|
|
3395
|
+
mimeType: "application/json",
|
|
3396
|
+
text: JSON.stringify(widgets, null, 2)
|
|
3397
|
+
}
|
|
3398
|
+
]
|
|
3399
|
+
};
|
|
3400
|
+
};
|
|
3401
|
+
const notifyResourcesUpdated = () => {
|
|
3402
|
+
sendResourceUpdated({
|
|
3403
|
+
uri: AVAILABLE_WIDGETS_URI,
|
|
3404
|
+
...buildContents(AVAILABLE_WIDGETS_URI)
|
|
3405
|
+
});
|
|
3406
|
+
sendResourceUpdated({
|
|
3407
|
+
uri: AVAILABLE_WIDGETS_URI_V4,
|
|
3408
|
+
...buildContents(AVAILABLE_WIDGETS_URI_V4, (w) => w.version === "v4")
|
|
3409
|
+
});
|
|
3410
|
+
};
|
|
3411
|
+
resource(
|
|
3412
|
+
"available-widgets-v4",
|
|
3413
|
+
AVAILABLE_WIDGETS_URI_V4,
|
|
3414
|
+
{
|
|
3415
|
+
description: "All registered v4 version widgets"
|
|
3416
|
+
},
|
|
3417
|
+
async () => buildContents(AVAILABLE_WIDGETS_URI_V4, (w) => w.version === "v4")
|
|
3418
|
+
);
|
|
3419
|
+
resource(
|
|
3420
|
+
"available-widgets",
|
|
3421
|
+
AVAILABLE_WIDGETS_URI,
|
|
3422
|
+
{
|
|
3423
|
+
description: "All registered widget types with v3/v4 version metadata and description."
|
|
3424
|
+
},
|
|
3425
|
+
async () => buildContents(AVAILABLE_WIDGETS_URI)
|
|
3426
|
+
);
|
|
3427
|
+
const eventName = v1ReadyEvent3().name;
|
|
3428
|
+
const onV1Ready = () => {
|
|
3429
|
+
const widgets = getAvailableWidgets();
|
|
3430
|
+
if (widgets.length === 0) {
|
|
3431
|
+
return;
|
|
3432
|
+
}
|
|
3433
|
+
window.removeEventListener(eventName, onV1Ready);
|
|
3434
|
+
notifyResourcesUpdated();
|
|
3435
|
+
};
|
|
3436
|
+
window.addEventListener(eventName, onV1Ready);
|
|
3437
|
+
onV1Ready();
|
|
3438
|
+
};
|
|
3439
|
+
|
|
3210
3440
|
// src/mcp/resources/document-structure-resource.ts
|
|
3441
|
+
import {
|
|
3442
|
+
getWidgetsCache as getWidgetsCache4
|
|
3443
|
+
} from "@elementor/editor-elements";
|
|
3211
3444
|
import { __privateListenTo as listenTo, commandEndEvent as commandEndEvent4 } from "@elementor/editor-v1-adapters";
|
|
3212
3445
|
var DOCUMENT_STRUCTURE_URI = "elementor://document/structure";
|
|
3213
3446
|
var initDocumentStructureResource = (reg) => {
|
|
@@ -3228,7 +3461,8 @@ var initDocumentStructureResource = (reg) => {
|
|
|
3228
3461
|
commandEndEvent4("document/elements/move"),
|
|
3229
3462
|
commandEndEvent4("document/elements/copy"),
|
|
3230
3463
|
commandEndEvent4("document/elements/paste"),
|
|
3231
|
-
commandEndEvent4("editor/documents/attach-preview")
|
|
3464
|
+
commandEndEvent4("editor/documents/attach-preview"),
|
|
3465
|
+
commandEndEvent4("editor/documents/switch")
|
|
3232
3466
|
],
|
|
3233
3467
|
updateDocumentStructure
|
|
3234
3468
|
);
|
|
@@ -3258,9 +3492,7 @@ function getDocumentStructure() {
|
|
|
3258
3492
|
return { error: "No active document found" };
|
|
3259
3493
|
}
|
|
3260
3494
|
const containers = document2.container?.children || [];
|
|
3261
|
-
const elements = containers.map(
|
|
3262
|
-
(container) => extractElementData(container)
|
|
3263
|
-
);
|
|
3495
|
+
const elements = containers.map((container) => extractElementData(container));
|
|
3264
3496
|
return {
|
|
3265
3497
|
documentId: document2.id,
|
|
3266
3498
|
documentType: document2.config.type,
|
|
@@ -3268,6 +3500,16 @@ function getDocumentStructure() {
|
|
|
3268
3500
|
elements: elements.filter((el) => el !== null)
|
|
3269
3501
|
};
|
|
3270
3502
|
}
|
|
3503
|
+
function resolveElementVersion(element) {
|
|
3504
|
+
if (element.model?.config?.atomic) {
|
|
3505
|
+
return "v4";
|
|
3506
|
+
}
|
|
3507
|
+
const widgetType = element.model?.attributes?.widgetType;
|
|
3508
|
+
if (widgetType && getWidgetsCache4()?.[widgetType]?.atomic_props_schema) {
|
|
3509
|
+
return "v4";
|
|
3510
|
+
}
|
|
3511
|
+
return "v3";
|
|
3512
|
+
}
|
|
3271
3513
|
function extractElementData(element) {
|
|
3272
3514
|
if (!element || !element.model) {
|
|
3273
3515
|
return null;
|
|
@@ -3276,7 +3518,8 @@ function extractElementData(element) {
|
|
|
3276
3518
|
const result = {
|
|
3277
3519
|
id: model.id,
|
|
3278
3520
|
elType: model.elType,
|
|
3279
|
-
widgetType: model.widgetType || void 0
|
|
3521
|
+
widgetType: model.widgetType || void 0,
|
|
3522
|
+
version: resolveElementVersion(element)
|
|
3280
3523
|
};
|
|
3281
3524
|
const title = model.title || element.model?.editor_settings?.title;
|
|
3282
3525
|
if (title) {
|
|
@@ -3288,28 +3531,346 @@ function extractElementData(element) {
|
|
|
3288
3531
|
return result;
|
|
3289
3532
|
}
|
|
3290
3533
|
|
|
3534
|
+
// src/mcp/resources/editor-state-resource.ts
|
|
3535
|
+
import { __privateListenTo as listenTo2, commandEndEvent as commandEndEvent5 } from "@elementor/editor-v1-adapters";
|
|
3536
|
+
var CURRENTLY_VIEWED_SCREEN = "The user is currently viewing the Elementor editor";
|
|
3537
|
+
var PAGE_CONTENT_CHARACTER_LIMIT = 500;
|
|
3538
|
+
var PREVIEW_TEXT_NODE_MIN_LENGTH = 2;
|
|
3539
|
+
var EDITOR_STATE_URI = "elementor://context/editor-state";
|
|
3540
|
+
var initEditorStateResource = (reg) => {
|
|
3541
|
+
const { resource, sendResourceUpdated } = reg;
|
|
3542
|
+
let lastSerializedState = "";
|
|
3543
|
+
const buildState = () => ({
|
|
3544
|
+
currentlyViewedScreen: CURRENTLY_VIEWED_SCREEN,
|
|
3545
|
+
pageContent: getPageContentFromPreview(),
|
|
3546
|
+
pageTitle: getPageTitle()
|
|
3547
|
+
});
|
|
3548
|
+
const notifyIfChanged = () => {
|
|
3549
|
+
const serialized = JSON.stringify(buildState());
|
|
3550
|
+
if (serialized === lastSerializedState) {
|
|
3551
|
+
return;
|
|
3552
|
+
}
|
|
3553
|
+
lastSerializedState = serialized;
|
|
3554
|
+
sendResourceUpdated({ uri: EDITOR_STATE_URI });
|
|
3555
|
+
};
|
|
3556
|
+
listenTo2(
|
|
3557
|
+
[commandEndEvent5("editor/documents/switch"), commandEndEvent5("editor/documents/attach-preview")],
|
|
3558
|
+
notifyIfChanged
|
|
3559
|
+
);
|
|
3560
|
+
lastSerializedState = JSON.stringify(buildState());
|
|
3561
|
+
resource(
|
|
3562
|
+
"editor-state",
|
|
3563
|
+
EDITOR_STATE_URI,
|
|
3564
|
+
{
|
|
3565
|
+
description: "Editor page title, preview text snapshot, and viewed screen label."
|
|
3566
|
+
},
|
|
3567
|
+
async () => {
|
|
3568
|
+
return {
|
|
3569
|
+
contents: [
|
|
3570
|
+
{
|
|
3571
|
+
uri: EDITOR_STATE_URI,
|
|
3572
|
+
text: JSON.stringify(buildState(), null, 2)
|
|
3573
|
+
}
|
|
3574
|
+
]
|
|
3575
|
+
};
|
|
3576
|
+
}
|
|
3577
|
+
);
|
|
3578
|
+
};
|
|
3579
|
+
function getPageContentFromPreview() {
|
|
3580
|
+
try {
|
|
3581
|
+
const root = window.elementor?.$previewContents?.[0];
|
|
3582
|
+
if (!root) {
|
|
3583
|
+
return null;
|
|
3584
|
+
}
|
|
3585
|
+
const content = [];
|
|
3586
|
+
const clone = root.cloneNode(true);
|
|
3587
|
+
clone.querySelectorAll(".elementor-editor-element-settings, #elementor-add-new-section").forEach((el) => {
|
|
3588
|
+
el.remove();
|
|
3589
|
+
});
|
|
3590
|
+
const walk = (node, insideElementorElement = false) => {
|
|
3591
|
+
const isInside = node.classList?.contains("elementor-element") || insideElementorElement;
|
|
3592
|
+
if (node.nodeType === Node.TEXT_NODE && isInside) {
|
|
3593
|
+
const text2 = node.textContent?.trim().replace(/\s+/g, " ");
|
|
3594
|
+
if (text2 && text2.length > PREVIEW_TEXT_NODE_MIN_LENGTH) {
|
|
3595
|
+
content.push(text2);
|
|
3596
|
+
}
|
|
3597
|
+
} else {
|
|
3598
|
+
node.childNodes.forEach((child) => {
|
|
3599
|
+
walk(child, isInside);
|
|
3600
|
+
});
|
|
3601
|
+
}
|
|
3602
|
+
};
|
|
3603
|
+
walk(clone);
|
|
3604
|
+
const text = content.join(" ");
|
|
3605
|
+
if (text.length > PAGE_CONTENT_CHARACTER_LIMIT) {
|
|
3606
|
+
return text.slice(0, PAGE_CONTENT_CHARACTER_LIMIT) + "...";
|
|
3607
|
+
}
|
|
3608
|
+
return text;
|
|
3609
|
+
} catch {
|
|
3610
|
+
return null;
|
|
3611
|
+
}
|
|
3612
|
+
}
|
|
3613
|
+
function getPageTitle() {
|
|
3614
|
+
try {
|
|
3615
|
+
const extendedWindow = window;
|
|
3616
|
+
const currentDocument = extendedWindow.elementor?.documents?.getCurrent?.();
|
|
3617
|
+
const postTitle = currentDocument?.config?.settings?.post_title;
|
|
3618
|
+
if (postTitle) {
|
|
3619
|
+
return postTitle;
|
|
3620
|
+
}
|
|
3621
|
+
let title = document.title || "Page";
|
|
3622
|
+
title = title.split(/\s*[‹»|–—-]\s*/)[0];
|
|
3623
|
+
const trimmed = title.trim();
|
|
3624
|
+
return trimmed || "Page";
|
|
3625
|
+
} catch {
|
|
3626
|
+
return "Page";
|
|
3627
|
+
}
|
|
3628
|
+
}
|
|
3629
|
+
|
|
3630
|
+
// src/mcp/resources/general-context-resource.ts
|
|
3631
|
+
import { __privateListenTo as listenTo3, commandEndEvent as commandEndEvent6 } from "@elementor/editor-v1-adapters";
|
|
3632
|
+
var GENERAL_CONTEXT_URI = "elementor://context/general";
|
|
3633
|
+
var initGeneralContextResource = (reg) => {
|
|
3634
|
+
const { resource, sendResourceUpdated } = reg;
|
|
3635
|
+
let lastSerializedPayload = null;
|
|
3636
|
+
const getPageTitle2 = () => {
|
|
3637
|
+
const extendedWindow = window;
|
|
3638
|
+
const title = extendedWindow.elementor?.documents?.getCurrent?.()?.config?.settings?.post_title;
|
|
3639
|
+
if (!title?.trim()) {
|
|
3640
|
+
return null;
|
|
3641
|
+
}
|
|
3642
|
+
return title;
|
|
3643
|
+
};
|
|
3644
|
+
const buildPayload = () => {
|
|
3645
|
+
const extendedWindow = window;
|
|
3646
|
+
const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
3647
|
+
const postParam = new URLSearchParams(location.search).get("post");
|
|
3648
|
+
const parsedPostId = postParam ? Number(postParam) : null;
|
|
3649
|
+
const postId = parsedPostId !== null && Number.isFinite(parsedPostId) ? parsedPostId : null;
|
|
3650
|
+
const pageTitle = getPageTitle2();
|
|
3651
|
+
const urlObject = new URL(window.location.href);
|
|
3652
|
+
const pageUrl = urlObject.pathname + urlObject.search;
|
|
3653
|
+
const pageName = pageTitle || "Elementor Editor";
|
|
3654
|
+
const plugins = extendedWindow.angieConfig?.plugins;
|
|
3655
|
+
return {
|
|
3656
|
+
timezone,
|
|
3657
|
+
postId,
|
|
3658
|
+
currentPage: {
|
|
3659
|
+
pageName,
|
|
3660
|
+
pageTitle,
|
|
3661
|
+
pageUrl
|
|
3662
|
+
},
|
|
3663
|
+
...plugins && { plugins }
|
|
3664
|
+
};
|
|
3665
|
+
};
|
|
3666
|
+
const pushUpdateIfChanged = () => {
|
|
3667
|
+
const serialized = JSON.stringify(buildPayload());
|
|
3668
|
+
if (serialized === lastSerializedPayload) {
|
|
3669
|
+
return;
|
|
3670
|
+
}
|
|
3671
|
+
lastSerializedPayload = serialized;
|
|
3672
|
+
sendResourceUpdated({ uri: GENERAL_CONTEXT_URI });
|
|
3673
|
+
};
|
|
3674
|
+
resource(
|
|
3675
|
+
"general-context",
|
|
3676
|
+
GENERAL_CONTEXT_URI,
|
|
3677
|
+
{
|
|
3678
|
+
description: "General context: timezone, post id, and current page."
|
|
3679
|
+
},
|
|
3680
|
+
async () => {
|
|
3681
|
+
return {
|
|
3682
|
+
contents: [
|
|
3683
|
+
{
|
|
3684
|
+
uri: GENERAL_CONTEXT_URI,
|
|
3685
|
+
mimeType: "application/json",
|
|
3686
|
+
text: JSON.stringify(buildPayload(), null, 2)
|
|
3687
|
+
}
|
|
3688
|
+
]
|
|
3689
|
+
};
|
|
3690
|
+
}
|
|
3691
|
+
);
|
|
3692
|
+
listenTo3(
|
|
3693
|
+
[
|
|
3694
|
+
commandEndEvent6("editor/documents/switch"),
|
|
3695
|
+
commandEndEvent6("editor/documents/attach-preview"),
|
|
3696
|
+
commandEndEvent6("document/elements/settings")
|
|
3697
|
+
],
|
|
3698
|
+
pushUpdateIfChanged
|
|
3699
|
+
);
|
|
3700
|
+
pushUpdateIfChanged();
|
|
3701
|
+
};
|
|
3702
|
+
|
|
3703
|
+
// src/mcp/resources/selected-element-resource.ts
|
|
3704
|
+
import { getContainer as getContainer3, getSelectedElements, getWidgetsCache as getWidgetsCache5 } from "@elementor/editor-elements";
|
|
3705
|
+
import {
|
|
3706
|
+
__privateListenTo as listenTo4,
|
|
3707
|
+
commandEndEvent as commandEndEvent7
|
|
3708
|
+
} from "@elementor/editor-v1-adapters";
|
|
3709
|
+
var SELECTED_ELEMENT_URI = "elementor://context/selected-element";
|
|
3710
|
+
var initSelectedElementResource = (reg) => {
|
|
3711
|
+
const { resource, sendResourceUpdated } = reg;
|
|
3712
|
+
let currentPayloadText = null;
|
|
3713
|
+
const publishIfChanged = (payload) => {
|
|
3714
|
+
const nextText = JSON.stringify(payload);
|
|
3715
|
+
if (nextText !== currentPayloadText) {
|
|
3716
|
+
currentPayloadText = nextText;
|
|
3717
|
+
sendResourceUpdated({ uri: SELECTED_ELEMENT_URI });
|
|
3718
|
+
}
|
|
3719
|
+
};
|
|
3720
|
+
const onCommand = (e) => {
|
|
3721
|
+
if (e.type !== "command") {
|
|
3722
|
+
return;
|
|
3723
|
+
}
|
|
3724
|
+
const commandEvent = e;
|
|
3725
|
+
if (commandEvent.command === "document/elements/deselect-all") {
|
|
3726
|
+
publishIfChanged(createEmptySelectedElementPayload());
|
|
3727
|
+
return;
|
|
3728
|
+
}
|
|
3729
|
+
if (commandEvent.command !== "document/elements/select" && commandEvent.command !== "document/elements/settings") {
|
|
3730
|
+
return;
|
|
3731
|
+
}
|
|
3732
|
+
const { container } = commandEvent.args || {};
|
|
3733
|
+
if (container?.id) {
|
|
3734
|
+
publishIfChanged(buildPayloadFromContainer(container));
|
|
3735
|
+
return;
|
|
3736
|
+
}
|
|
3737
|
+
publishIfChanged(readSelectionFromEditor());
|
|
3738
|
+
};
|
|
3739
|
+
listenTo4(
|
|
3740
|
+
[
|
|
3741
|
+
commandEndEvent7("document/elements/select"),
|
|
3742
|
+
commandEndEvent7("document/elements/deselect-all"),
|
|
3743
|
+
commandEndEvent7("document/elements/settings")
|
|
3744
|
+
],
|
|
3745
|
+
onCommand
|
|
3746
|
+
);
|
|
3747
|
+
publishIfChanged(readSelectionFromEditor());
|
|
3748
|
+
resource(
|
|
3749
|
+
"selected-element",
|
|
3750
|
+
SELECTED_ELEMENT_URI,
|
|
3751
|
+
{
|
|
3752
|
+
description: "Currently selected Elementor element context."
|
|
3753
|
+
},
|
|
3754
|
+
async () => {
|
|
3755
|
+
return {
|
|
3756
|
+
contents: [
|
|
3757
|
+
{
|
|
3758
|
+
uri: SELECTED_ELEMENT_URI,
|
|
3759
|
+
text: JSON.stringify(readSelectionFromEditor(), null, 2)
|
|
3760
|
+
}
|
|
3761
|
+
]
|
|
3762
|
+
};
|
|
3763
|
+
}
|
|
3764
|
+
);
|
|
3765
|
+
};
|
|
3766
|
+
function createEmptySelectedElementPayload() {
|
|
3767
|
+
return {
|
|
3768
|
+
elementDisplayName: null,
|
|
3769
|
+
elementType: null,
|
|
3770
|
+
properties: null,
|
|
3771
|
+
selectedElementId: null,
|
|
3772
|
+
selectedParentId: null,
|
|
3773
|
+
version: null,
|
|
3774
|
+
widgetType: null
|
|
3775
|
+
};
|
|
3776
|
+
}
|
|
3777
|
+
function readSelectionFromEditor() {
|
|
3778
|
+
const elements = getSelectedElements();
|
|
3779
|
+
if (elements.length !== 1) {
|
|
3780
|
+
return createEmptySelectedElementPayload();
|
|
3781
|
+
}
|
|
3782
|
+
const container = getContainer3(elements[0].id);
|
|
3783
|
+
return buildPayloadFromContainer(container);
|
|
3784
|
+
}
|
|
3785
|
+
function buildPayloadFromContainer(container) {
|
|
3786
|
+
if (!container?.id) {
|
|
3787
|
+
return createEmptySelectedElementPayload();
|
|
3788
|
+
}
|
|
3789
|
+
const widgetType = container.model.get("widgetType") ?? null;
|
|
3790
|
+
const elementType = container.type ?? "widget";
|
|
3791
|
+
return {
|
|
3792
|
+
elementDisplayName: getElementDisplayName(container),
|
|
3793
|
+
elementType,
|
|
3794
|
+
properties: getElementProperties(container, widgetType),
|
|
3795
|
+
selectedElementId: container.id,
|
|
3796
|
+
selectedParentId: container.parent?.id ?? null,
|
|
3797
|
+
version: resolveElementVersion2(container, widgetType),
|
|
3798
|
+
widgetType
|
|
3799
|
+
};
|
|
3800
|
+
}
|
|
3801
|
+
function resolveElementVersion2(container, widgetType) {
|
|
3802
|
+
if (container.model?.config?.atomic) {
|
|
3803
|
+
return "v4";
|
|
3804
|
+
}
|
|
3805
|
+
if (widgetType && getWidgetsCache5()?.[widgetType]?.atomic_props_schema) {
|
|
3806
|
+
return "v4";
|
|
3807
|
+
}
|
|
3808
|
+
return "v3";
|
|
3809
|
+
}
|
|
3810
|
+
function getElementProperties(container, widgetType) {
|
|
3811
|
+
const settings = container.settings?.toJSON?.();
|
|
3812
|
+
if (!settings || typeof settings !== "object") {
|
|
3813
|
+
return null;
|
|
3814
|
+
}
|
|
3815
|
+
const widgetConfig = widgetType ? getWidgetsCache5()?.[widgetType] : null;
|
|
3816
|
+
const controls = widgetConfig?.controls;
|
|
3817
|
+
const filtered = {};
|
|
3818
|
+
for (const [key, value] of Object.entries(settings)) {
|
|
3819
|
+
if (value === void 0 || value === null || value === "") {
|
|
3820
|
+
continue;
|
|
3821
|
+
}
|
|
3822
|
+
const controlDefault = controls?.[key]?.default;
|
|
3823
|
+
if (controlDefault !== void 0 && JSON.stringify(value) === JSON.stringify(controlDefault)) {
|
|
3824
|
+
continue;
|
|
3825
|
+
}
|
|
3826
|
+
filtered[key] = value;
|
|
3827
|
+
}
|
|
3828
|
+
return Object.keys(filtered).length > 0 ? filtered : null;
|
|
3829
|
+
}
|
|
3830
|
+
function getElementDisplayName(container) {
|
|
3831
|
+
try {
|
|
3832
|
+
if (container.label) {
|
|
3833
|
+
return container.label;
|
|
3834
|
+
}
|
|
3835
|
+
const widgetType = container.model?.get?.("widgetType");
|
|
3836
|
+
if (widgetType) {
|
|
3837
|
+
const capitalizedType = widgetType.charAt(0).toUpperCase() + widgetType.slice(1);
|
|
3838
|
+
return capitalizedType.replace(/-/g, " ");
|
|
3839
|
+
}
|
|
3840
|
+
if (container.type === "container") {
|
|
3841
|
+
return "Container";
|
|
3842
|
+
}
|
|
3843
|
+
if (container.type === "section") {
|
|
3844
|
+
return "Section";
|
|
3845
|
+
}
|
|
3846
|
+
return `Element ${container.id}`;
|
|
3847
|
+
} catch {
|
|
3848
|
+
return `Element ${container.id}`;
|
|
3849
|
+
}
|
|
3850
|
+
}
|
|
3851
|
+
|
|
3291
3852
|
// src/mcp/tools/build-composition/tool.ts
|
|
3292
3853
|
import { getCurrentDocument } from "@elementor/editor-documents";
|
|
3293
3854
|
import {
|
|
3294
3855
|
createElement as createElement8,
|
|
3295
3856
|
deleteElement,
|
|
3296
|
-
getContainer as
|
|
3297
|
-
getWidgetsCache as
|
|
3857
|
+
getContainer as getContainer5,
|
|
3858
|
+
getWidgetsCache as getWidgetsCache9
|
|
3298
3859
|
} from "@elementor/editor-elements";
|
|
3299
3860
|
|
|
3300
3861
|
// src/composition-builder/composition-builder.ts
|
|
3301
3862
|
import {
|
|
3302
3863
|
createElement as createElement7,
|
|
3303
|
-
generateElementId,
|
|
3304
|
-
getContainer as
|
|
3305
|
-
getWidgetsCache as
|
|
3864
|
+
generateElementId as generateElementId2,
|
|
3865
|
+
getContainer as getContainer4,
|
|
3866
|
+
getWidgetsCache as getWidgetsCache8
|
|
3306
3867
|
} from "@elementor/editor-elements";
|
|
3307
3868
|
|
|
3308
3869
|
// src/mcp/utils/do-update-element-property.ts
|
|
3309
3870
|
import {
|
|
3310
3871
|
createElementStyle,
|
|
3311
3872
|
getElementStyles,
|
|
3312
|
-
getWidgetsCache as
|
|
3873
|
+
getWidgetsCache as getWidgetsCache6,
|
|
3313
3874
|
updateElementSettings,
|
|
3314
3875
|
updateElementStyle
|
|
3315
3876
|
} from "@elementor/editor-elements";
|
|
@@ -3402,7 +3963,7 @@ var doUpdateElementProperty = (params) => {
|
|
|
3402
3963
|
}
|
|
3403
3964
|
return;
|
|
3404
3965
|
}
|
|
3405
|
-
const elementPropSchema =
|
|
3966
|
+
const elementPropSchema = getWidgetsCache6()?.[elementType]?.atomic_props_schema;
|
|
3406
3967
|
if (!elementPropSchema) {
|
|
3407
3968
|
throw new Error(`No prop schema found for element type: ${elementType}`);
|
|
3408
3969
|
}
|
|
@@ -3426,7 +3987,7 @@ var doUpdateElementProperty = (params) => {
|
|
|
3426
3987
|
};
|
|
3427
3988
|
|
|
3428
3989
|
// src/mcp/utils/validate-input.ts
|
|
3429
|
-
import { getWidgetsCache as
|
|
3990
|
+
import { getWidgetsCache as getWidgetsCache7 } from "@elementor/editor-elements";
|
|
3430
3991
|
import { Schema as Schema3 } from "@elementor/editor-props";
|
|
3431
3992
|
import { getStylesSchema as getStylesSchema4 } from "@elementor/editor-styles";
|
|
3432
3993
|
var _widgetsSchema = null;
|
|
@@ -3434,7 +3995,7 @@ var validateInput = {
|
|
|
3434
3995
|
get widgetsSchema() {
|
|
3435
3996
|
if (!_widgetsSchema) {
|
|
3436
3997
|
const schema2 = {};
|
|
3437
|
-
const cache =
|
|
3998
|
+
const cache = getWidgetsCache7();
|
|
3438
3999
|
if (!cache) {
|
|
3439
4000
|
return {};
|
|
3440
4001
|
}
|
|
@@ -3461,7 +4022,7 @@ var validateInput = {
|
|
|
3461
4022
|
if (!propSchema) {
|
|
3462
4023
|
errors.push(`Property "${propName}" is not defined in the schema.`);
|
|
3463
4024
|
hasInvalidKey = true;
|
|
3464
|
-
} else if (!Schema3.isPropKeyConfigurable(propName)) {
|
|
4025
|
+
} else if (!Schema3.isPropKeyConfigurable(propName, propSchema)) {
|
|
3465
4026
|
errors.push(`Property "${propName}" is not configurable.`);
|
|
3466
4027
|
} else {
|
|
3467
4028
|
const { valid } = Schema3.validatePropValue(propSchema, propValue);
|
|
@@ -3514,13 +4075,13 @@ var validateInput = {
|
|
|
3514
4075
|
var CompositionBuilder = class _CompositionBuilder {
|
|
3515
4076
|
elementConfig = {};
|
|
3516
4077
|
elementStylesConfig = {};
|
|
3517
|
-
|
|
4078
|
+
elementCustomCSS = {};
|
|
3518
4079
|
rootContainers = [];
|
|
3519
4080
|
api = {
|
|
3520
4081
|
createElement: createElement7,
|
|
3521
|
-
getWidgetsCache:
|
|
3522
|
-
generateElementId,
|
|
3523
|
-
getContainer:
|
|
4082
|
+
getWidgetsCache: getWidgetsCache8,
|
|
4083
|
+
generateElementId: generateElementId2,
|
|
4084
|
+
getContainer: getContainer4,
|
|
3524
4085
|
doUpdateElementProperty
|
|
3525
4086
|
};
|
|
3526
4087
|
xml;
|
|
@@ -3551,7 +4112,7 @@ var CompositionBuilder = class _CompositionBuilder {
|
|
|
3551
4112
|
this.elementStylesConfig = config;
|
|
3552
4113
|
}
|
|
3553
4114
|
setCustomCSS(config) {
|
|
3554
|
-
this.
|
|
4115
|
+
this.elementCustomCSS = config;
|
|
3555
4116
|
}
|
|
3556
4117
|
getXML() {
|
|
3557
4118
|
return this.xml;
|
|
@@ -3631,7 +4192,7 @@ var CompositionBuilder = class _CompositionBuilder {
|
|
|
3631
4192
|
const allConfigIds = /* @__PURE__ */ new Set([
|
|
3632
4193
|
...Object.keys(this.elementConfig),
|
|
3633
4194
|
...Object.keys(this.elementStylesConfig),
|
|
3634
|
-
...Object.keys(this.
|
|
4195
|
+
...Object.keys(this.elementCustomCSS)
|
|
3635
4196
|
]);
|
|
3636
4197
|
for (const configId of allConfigIds) {
|
|
3637
4198
|
let element, node;
|
|
@@ -3642,7 +4203,7 @@ var CompositionBuilder = class _CompositionBuilder {
|
|
|
3642
4203
|
if (this.elementConfig[configId]) {
|
|
3643
4204
|
configErrors.push(msg);
|
|
3644
4205
|
}
|
|
3645
|
-
if (this.elementStylesConfig[configId] || this.
|
|
4206
|
+
if (this.elementStylesConfig[configId] || this.elementCustomCSS[configId]) {
|
|
3646
4207
|
styleErrors.push(msg);
|
|
3647
4208
|
}
|
|
3648
4209
|
continue;
|
|
@@ -3692,7 +4253,7 @@ var CompositionBuilder = class _CompositionBuilder {
|
|
|
3692
4253
|
}
|
|
3693
4254
|
}
|
|
3694
4255
|
}
|
|
3695
|
-
const customCSS = this.
|
|
4256
|
+
const customCSS = this.elementCustomCSS[configId];
|
|
3696
4257
|
if (customCSS) {
|
|
3697
4258
|
try {
|
|
3698
4259
|
this.api.doUpdateElementProperty({
|
|
@@ -3763,6 +4324,10 @@ var generatePrompt = () => {
|
|
|
3763
4324
|
# RESOURCES (Read before use)
|
|
3764
4325
|
- [elementor://global-classes] - Check FIRST for reusable classes
|
|
3765
4326
|
- [elementor://global-variables] - ONLY use variables defined here
|
|
4327
|
+
- [${AVAILABLE_WIDGETS_URI}/v4]
|
|
4328
|
+
|
|
4329
|
+
# TOOL SUPPORT
|
|
4330
|
+
This tool support v4 elements only
|
|
3766
4331
|
|
|
3767
4332
|
# WORKFLOW
|
|
3768
4333
|
1. Check/create global classes via "create-global-class" tool
|
|
@@ -3944,24 +4509,26 @@ var initBuildCompositionsTool = (reg) => {
|
|
|
3944
4509
|
{ description: "Styles schema", uri: STYLE_SCHEMA_URI },
|
|
3945
4510
|
{ description: "Global Classes", uri: "elementor://global-classes" },
|
|
3946
4511
|
{ description: "Global Variables", uri: "elementor://global-variables" },
|
|
3947
|
-
{ description: "Styles best practices", uri: BEST_PRACTICES_URI }
|
|
4512
|
+
{ description: "Styles best practices", uri: BEST_PRACTICES_URI },
|
|
4513
|
+
{ description: "Available widgets for this tool", uri: AVAILABLE_WIDGETS_URI_V4 }
|
|
3948
4514
|
],
|
|
3949
4515
|
outputSchema,
|
|
3950
4516
|
modelPreferences: {
|
|
3951
4517
|
hints: [{ name: "claude-sonnet-4-5" }]
|
|
3952
4518
|
},
|
|
3953
4519
|
handler: async (params) => {
|
|
4520
|
+
assertCompositionXmlUsesV4WidgetsOnly(params.xmlStructure);
|
|
3954
4521
|
const { xmlStructure, elementConfig, stylesConfig, customCSS } = params;
|
|
3955
4522
|
let generatedXML = "";
|
|
3956
4523
|
const errors = [];
|
|
3957
4524
|
const rootContainers = [];
|
|
3958
|
-
const documentContainer =
|
|
4525
|
+
const documentContainer = getContainer5("document");
|
|
3959
4526
|
const currentDocument = getCurrentDocument();
|
|
3960
4527
|
const targetContainer = getCompositionTargetContainer(documentContainer, currentDocument?.type.value);
|
|
3961
4528
|
try {
|
|
3962
4529
|
const compositionBuilder = CompositionBuilder.fromXMLString(xmlStructure, {
|
|
3963
4530
|
createElement: createElement8,
|
|
3964
|
-
getWidgetsCache:
|
|
4531
|
+
getWidgetsCache: getWidgetsCache9
|
|
3965
4532
|
});
|
|
3966
4533
|
compositionBuilder.setElementConfig(elementConfig);
|
|
3967
4534
|
compositionBuilder.setStylesConfig(stylesConfig);
|
|
@@ -4038,6 +4605,31 @@ Remember: Global classes ensure design consistency and reusability. Don't skip a
|
|
|
4038
4605
|
}
|
|
4039
4606
|
});
|
|
4040
4607
|
};
|
|
4608
|
+
function assertCompositionXmlUsesV4WidgetsOnly(xmlStructure) {
|
|
4609
|
+
const doc = new DOMParser().parseFromString(xmlStructure, "application/xml");
|
|
4610
|
+
if (doc.querySelector("parsererror")) {
|
|
4611
|
+
throw new Error("Failed to parse XML string: " + doc);
|
|
4612
|
+
}
|
|
4613
|
+
const widgetsCache = getWidgetsCache9() ?? {};
|
|
4614
|
+
for (const node of doc.querySelectorAll("*")) {
|
|
4615
|
+
const type = node.tagName;
|
|
4616
|
+
const widgetData = widgetsCache[type];
|
|
4617
|
+
if (!widgetData) {
|
|
4618
|
+
continue;
|
|
4619
|
+
}
|
|
4620
|
+
if (widgetData.elType !== "widget") {
|
|
4621
|
+
continue;
|
|
4622
|
+
}
|
|
4623
|
+
if (!widgetData.atomic_props_schema) {
|
|
4624
|
+
throw new Error(
|
|
4625
|
+
`This tool does not support V3 elements. Please use the elementor-v3-mcp tools instead for element type: ${type}`
|
|
4626
|
+
);
|
|
4627
|
+
}
|
|
4628
|
+
}
|
|
4629
|
+
}
|
|
4630
|
+
|
|
4631
|
+
// src/mcp/tools/configure-element/tool.ts
|
|
4632
|
+
import { getWidgetsCache as getWidgetsCache10 } from "@elementor/editor-elements";
|
|
4041
4633
|
|
|
4042
4634
|
// src/mcp/tools/configure-element/prompt.ts
|
|
4043
4635
|
var configureElementToolPrompt = `Configure an existing element on the page.
|
|
@@ -4049,11 +4641,11 @@ var configureElementToolPrompt = `Configure an existing element on the page.
|
|
|
4049
4641
|
2. [${STYLE_SCHEMA_URI}]
|
|
4050
4642
|
Required to understand the styles schema for the widgets. All widgets share the same styles schema, grouped by categories.
|
|
4051
4643
|
Use this resource to understand which style properties are available for each element, and how to structure the "stylePropertiesToChange" parameter.
|
|
4052
|
-
3. If not sure about the PropValues schema, you can use the "get-element-configuration-values" tool to
|
|
4644
|
+
3. If not sure about the PropValues schema, you can use the "get-element-configuration-values" tool to retrieve the current PropValues configuration of the element.
|
|
4053
4645
|
|
|
4054
4646
|
Before using this tool, check the definitions of the elements PropTypes at the resource "widget-schema-by-type" at editor-canvas__elementor://widgets/schema/{widgetType}
|
|
4055
4647
|
All widgets share a common _style property for styling, which uses the common styles schema.
|
|
4056
|
-
|
|
4648
|
+
Retrieve and check the common styles schema at the resource list "styles-schema" at editor-canvas__elementor://styles/schema/{category}
|
|
4057
4649
|
|
|
4058
4650
|
# Parameters
|
|
4059
4651
|
- propertiesToChange: An object containing the properties to change, with their new values. MANDATORY. When updating a style only, provide an empty object.
|
|
@@ -4082,19 +4674,19 @@ PropValue structure:
|
|
|
4082
4674
|
}
|
|
4083
4675
|
|
|
4084
4676
|
<IMPORTANT>
|
|
4085
|
-
ALWAYS MAKE SURE you have the PropType schemas for the element you are configuring, and the common-styles schema for styling. If you are not sure,
|
|
4677
|
+
ALWAYS MAKE SURE you have the PropType schemas for the element you are configuring, and the common-styles schema for styling. If you are not sure, retrieve the schema from the resources mentioned above.
|
|
4086
4678
|
</IMPORTANT>
|
|
4087
4679
|
|
|
4088
4680
|
You can use multiple property changes at once by providing multiple entries in the propertiesToChange object, including _style alongside non-style props.
|
|
4089
4681
|
Some properties are nested, use the root property name, then objects with nested values inside, as the complete schema suggests.
|
|
4090
4682
|
|
|
4091
|
-
Make sure you have the "widget-schema-by-type" resource available to
|
|
4092
|
-
Make sure you have to "styles-schema" resources available to
|
|
4683
|
+
Make sure you have the "widget-schema-by-type" resource available to retrieve the PropType schema for the element type you are configuring.
|
|
4684
|
+
Make sure you have to "styles-schema" resources available to retrieve the common styles schema.
|
|
4093
4685
|
|
|
4094
4686
|
# How to configure elements
|
|
4095
4687
|
We use a dedicated PropType Schema for configuring elements, including styles. When you configure an element, you must use the EXACT PropType Value as defined in the schema.
|
|
4096
4688
|
For styleProperties, use the style schema provided, as it also uses the PropType format.
|
|
4097
|
-
For all non-primitive types, provide the key property as defined in the schema as $$type in the generated
|
|
4689
|
+
For all non-primitive types, provide the key property as defined in the schema as $$type in the generated object, as it is MANDATORY for parsing.
|
|
4098
4690
|
|
|
4099
4691
|
Use the EXACT "PROP-TYPE" Schema given, and ALWAYS include the "key" property from the original configuration for every property you are changing.
|
|
4100
4692
|
|
|
@@ -4150,7 +4742,7 @@ var inputSchema2 = {
|
|
|
4150
4742
|
z2.any().describe(`The style PropValue, refer to [${STYLE_SCHEMA_URI}] how to generate values`),
|
|
4151
4743
|
z2.any()
|
|
4152
4744
|
).describe("An object record containing style property names and their new values to be set on the element").default({}),
|
|
4153
|
-
elementType: z2.string().describe("The type of the element to
|
|
4745
|
+
elementType: z2.string().describe("The type of the element to retrieve the schema"),
|
|
4154
4746
|
elementId: z2.string().describe("The unique id of the element to configure")
|
|
4155
4747
|
};
|
|
4156
4748
|
var outputSchema2 = {
|
|
@@ -4177,6 +4769,17 @@ var initConfigureElementTool = (reg) => {
|
|
|
4177
4769
|
speedPriority: 0.7
|
|
4178
4770
|
},
|
|
4179
4771
|
handler: ({ elementId, propertiesToChange, elementType, stylePropertiesToChange }) => {
|
|
4772
|
+
const widgetData = getWidgetsCache10()?.[elementType];
|
|
4773
|
+
if (!widgetData) {
|
|
4774
|
+
throw new Error(
|
|
4775
|
+
`Unknown element type: ${elementType}. Check the available-widgets resource for valid types.`
|
|
4776
|
+
);
|
|
4777
|
+
}
|
|
4778
|
+
if (!widgetData.atomic_props_schema) {
|
|
4779
|
+
throw new Error(
|
|
4780
|
+
`This tool does not support V3 elements. Please use the elementor-v3-mcp tools instead for element type: ${elementType}`
|
|
4781
|
+
);
|
|
4782
|
+
}
|
|
4180
4783
|
const toUpdate = Object.entries(propertiesToChange);
|
|
4181
4784
|
const { valid, errors } = validateInput.validatePropSchema(elementType, propertiesToChange);
|
|
4182
4785
|
const { valid: stylesValid, errors: stylesErrors } = validateInput.validateStyles(
|
|
@@ -4258,7 +4861,7 @@ Check the styles schema at the resource [${STYLE_SCHEMA_URI.replace(
|
|
|
4258
4861
|
}
|
|
4259
4862
|
|
|
4260
4863
|
// src/mcp/tools/get-element-config/tool.ts
|
|
4261
|
-
import { getContainer as
|
|
4864
|
+
import { getContainer as getContainer6, getElementStyles as getElementStyles2, getWidgetsCache as getWidgetsCache11 } from "@elementor/editor-elements";
|
|
4262
4865
|
import { Schema as Schema4 } from "@elementor/editor-props";
|
|
4263
4866
|
import { z as z3 } from "@elementor/schema";
|
|
4264
4867
|
var schema = {
|
|
@@ -4297,12 +4900,24 @@ var initGetElementConfigTool = (reg) => {
|
|
|
4297
4900
|
speedPriority: 0.9
|
|
4298
4901
|
},
|
|
4299
4902
|
handler: async ({ elementId }) => {
|
|
4300
|
-
const element =
|
|
4903
|
+
const element = getContainer6(elementId);
|
|
4301
4904
|
if (!element) {
|
|
4302
4905
|
throw new Error(`Element with ID ${elementId} not found.`);
|
|
4303
4906
|
}
|
|
4907
|
+
const elementType = element.model.get("widgetType") || element.model.get("elType") || "";
|
|
4908
|
+
const widgetData = getWidgetsCache11()?.[elementType];
|
|
4909
|
+
if (!widgetData) {
|
|
4910
|
+
throw new Error(
|
|
4911
|
+
`Unknown element type: ${elementType}. Check the available-widgets resource for valid types.`
|
|
4912
|
+
);
|
|
4913
|
+
}
|
|
4914
|
+
if (!widgetData.atomic_props_schema) {
|
|
4915
|
+
throw new Error(
|
|
4916
|
+
`This tool does not support V3 elements. Please use the elementor-v3-mcp tools instead for element type: ${elementType}`
|
|
4917
|
+
);
|
|
4918
|
+
}
|
|
4304
4919
|
const elementRawSettings = element.settings;
|
|
4305
|
-
const propSchema =
|
|
4920
|
+
const propSchema = getWidgetsCache11()?.[elementType]?.atomic_props_schema;
|
|
4306
4921
|
if (!elementRawSettings || !propSchema) {
|
|
4307
4922
|
throw new Error(`No settings or prop schema found for element ID: ${elementId}`);
|
|
4308
4923
|
}
|
|
@@ -4354,7 +4969,11 @@ var initCanvasMcp = (reg) => {
|
|
|
4354
4969
|
`
|
|
4355
4970
|
);
|
|
4356
4971
|
initWidgetsSchemaResource(reg);
|
|
4972
|
+
initAvailableWidgetsResource(reg);
|
|
4357
4973
|
initDocumentStructureResource(reg);
|
|
4974
|
+
initSelectedElementResource(reg);
|
|
4975
|
+
initEditorStateResource(reg);
|
|
4976
|
+
initGeneralContextResource(reg);
|
|
4358
4977
|
initBuildCompositionsTool(reg);
|
|
4359
4978
|
initGetElementConfigTool(reg);
|
|
4360
4979
|
initConfigureElementTool(reg);
|
|
@@ -4561,16 +5180,16 @@ function shouldBlock(sourceElements, targetElements) {
|
|
|
4561
5180
|
}
|
|
4562
5181
|
|
|
4563
5182
|
// src/style-commands/paste-style.ts
|
|
4564
|
-
import { getContainer as
|
|
5183
|
+
import { getContainer as getContainer7, getElementSetting, updateElementSettings as updateElementSettings2 } from "@elementor/editor-elements";
|
|
4565
5184
|
import { classesPropTypeUtil } from "@elementor/editor-props";
|
|
4566
5185
|
import {
|
|
4567
|
-
__privateListenTo as
|
|
5186
|
+
__privateListenTo as listenTo5,
|
|
4568
5187
|
blockCommand as blockCommand4,
|
|
4569
5188
|
commandStartEvent
|
|
4570
5189
|
} from "@elementor/editor-v1-adapters";
|
|
4571
5190
|
|
|
4572
5191
|
// src/utils/command-utils.ts
|
|
4573
|
-
import { getElementLabel as getElementLabel2, getWidgetsCache as
|
|
5192
|
+
import { getElementLabel as getElementLabel2, getWidgetsCache as getWidgetsCache12 } from "@elementor/editor-elements";
|
|
4574
5193
|
import { CLASSES_PROP_KEY } from "@elementor/editor-props";
|
|
4575
5194
|
import { __ as __5 } from "@wordpress/i18n";
|
|
4576
5195
|
function hasAtomicWidgets(args) {
|
|
@@ -4595,7 +5214,7 @@ function getClassesProp(container) {
|
|
|
4595
5214
|
}
|
|
4596
5215
|
function getContainerSchema(container) {
|
|
4597
5216
|
const type = container?.model.get("widgetType") || container?.model.get("elType");
|
|
4598
|
-
const widgetsCache =
|
|
5217
|
+
const widgetsCache = getWidgetsCache12();
|
|
4599
5218
|
const elementType = widgetsCache?.[type];
|
|
4600
5219
|
return elementType?.atomic_props_schema ?? null;
|
|
4601
5220
|
}
|
|
@@ -4701,7 +5320,7 @@ function initPasteStyleCommand() {
|
|
|
4701
5320
|
command: "document/elements/paste-style",
|
|
4702
5321
|
condition: hasAtomicWidgets
|
|
4703
5322
|
});
|
|
4704
|
-
|
|
5323
|
+
listenTo5(
|
|
4705
5324
|
commandStartEvent("document/elements/paste-style"),
|
|
4706
5325
|
(e) => pasteStyles(e.args, pasteElementStyleCommand)
|
|
4707
5326
|
);
|
|
@@ -4714,7 +5333,7 @@ function pasteStyles(args, pasteLocalStyle) {
|
|
|
4714
5333
|
}
|
|
4715
5334
|
const clipboardElements = getClipboardElements(storageKey);
|
|
4716
5335
|
const [clipboardElement] = clipboardElements ?? [];
|
|
4717
|
-
const clipboardContainer =
|
|
5336
|
+
const clipboardContainer = getContainer7(clipboardElement.id);
|
|
4718
5337
|
if (!clipboardElement || !clipboardContainer || !isAtomicWidget(clipboardContainer)) {
|
|
4719
5338
|
return;
|
|
4720
5339
|
}
|
|
@@ -4754,7 +5373,7 @@ function pasteClasses(containers, classes) {
|
|
|
4754
5373
|
|
|
4755
5374
|
// src/style-commands/reset-style.ts
|
|
4756
5375
|
import {
|
|
4757
|
-
__privateListenTo as
|
|
5376
|
+
__privateListenTo as listenTo6,
|
|
4758
5377
|
blockCommand as blockCommand5,
|
|
4759
5378
|
commandStartEvent as commandStartEvent2
|
|
4760
5379
|
} from "@elementor/editor-v1-adapters";
|
|
@@ -4812,7 +5431,7 @@ function initResetStyleCommand() {
|
|
|
4812
5431
|
command: "document/elements/reset-style",
|
|
4813
5432
|
condition: hasAtomicWidgets
|
|
4814
5433
|
});
|
|
4815
|
-
|
|
5434
|
+
listenTo6(
|
|
4816
5435
|
commandStartEvent2("document/elements/reset-style"),
|
|
4817
5436
|
(e) => resetStyles(e.args, resetElementStyles)
|
|
4818
5437
|
);
|
|
@@ -4910,9 +5529,33 @@ var getLegacyPanelElementView = ({ settings, ...rest }) => {
|
|
|
4910
5529
|
});
|
|
4911
5530
|
return { model: elementModel };
|
|
4912
5531
|
};
|
|
5532
|
+
|
|
5533
|
+
// src/sync/global-styles-imported-event.ts
|
|
5534
|
+
var GLOBAL_STYLES_IMPORTED_EVENT = "elementor/global-styles/imported";
|
|
5535
|
+
|
|
5536
|
+
// src/utils/after-render.ts
|
|
5537
|
+
import { getContainer as getContainer8 } from "@elementor/editor-elements";
|
|
5538
|
+
function doAfterRender(elementIds, callback) {
|
|
5539
|
+
const pending = elementIds.map((elementId) => {
|
|
5540
|
+
const view = getContainer8(elementId)?.view;
|
|
5541
|
+
if (!view || !hasDoAfterRender(view)) {
|
|
5542
|
+
return void 0;
|
|
5543
|
+
}
|
|
5544
|
+
return new Promise((resolve) => view._doAfterRender(resolve));
|
|
5545
|
+
}).filter(Boolean);
|
|
5546
|
+
if (pending.length > 0) {
|
|
5547
|
+
Promise.all(pending).then(() => callback(elementIds));
|
|
5548
|
+
} else {
|
|
5549
|
+
callback(elementIds);
|
|
5550
|
+
}
|
|
5551
|
+
}
|
|
5552
|
+
function hasDoAfterRender(view) {
|
|
5553
|
+
return typeof view?._doAfterRender === "function";
|
|
5554
|
+
}
|
|
4913
5555
|
export {
|
|
4914
5556
|
BREAKPOINTS_SCHEMA_URI,
|
|
4915
5557
|
DOCUMENT_STRUCTURE_URI,
|
|
5558
|
+
GLOBAL_STYLES_IMPORTED_EVENT,
|
|
4916
5559
|
STYLE_SCHEMA_URI,
|
|
4917
5560
|
UnknownStyleStateError,
|
|
4918
5561
|
UnknownStyleTypeError,
|
|
@@ -4924,6 +5567,7 @@ export {
|
|
|
4924
5567
|
createTemplatedElementView,
|
|
4925
5568
|
createTransformer,
|
|
4926
5569
|
createTransformersRegistry,
|
|
5570
|
+
doAfterRender,
|
|
4927
5571
|
endDragElementFromPanel,
|
|
4928
5572
|
init,
|
|
4929
5573
|
isAtomicWidget,
|