@elementor/editor-canvas 4.3.0-1002 → 4.3.0-1004
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.js +107 -149
- package/dist/index.mjs +88 -130
- package/package.json +20 -20
- package/src/mcp/canvas-mcp.ts +2 -2
- package/src/mcp/tools/build-composition/tool.ts +15 -18
- package/src/mcp/tools/get-page-structure/tool.ts +56 -0
- package/src/mcp/utils/get-mcp-error-message.ts +16 -0
- package/src/mcp/tools/get-element-config/tool.ts +0 -114
package/dist/index.js
CHANGED
|
@@ -116,13 +116,13 @@ var initWidgetsSchemaResource = (reg) => {
|
|
|
116
116
|
if (!widgetType) {
|
|
117
117
|
throw new Error("No widget type provided.");
|
|
118
118
|
}
|
|
119
|
-
const
|
|
119
|
+
const schema = await fetchWidgetSchema(widgetType);
|
|
120
120
|
return {
|
|
121
121
|
contents: [
|
|
122
122
|
{
|
|
123
123
|
uri: uri.toString(),
|
|
124
124
|
mimeType: "application/json",
|
|
125
|
-
text: JSON.stringify(
|
|
125
|
+
text: JSON.stringify(schema)
|
|
126
126
|
}
|
|
127
127
|
]
|
|
128
128
|
};
|
|
@@ -1310,10 +1310,10 @@ var getMultiPropsValue = (multiProps) => {
|
|
|
1310
1310
|
// src/renderers/create-props-resolver.ts
|
|
1311
1311
|
var TRANSFORM_DEPTH_LIMIT = 3;
|
|
1312
1312
|
function createPropsResolver({ transformers, schema: initialSchema, onPropResolve }) {
|
|
1313
|
-
async function resolve({ props, schema
|
|
1314
|
-
|
|
1313
|
+
async function resolve({ props, schema, signal, renderContext }) {
|
|
1314
|
+
schema = schema ?? initialSchema;
|
|
1315
1315
|
const promises = Promise.all(
|
|
1316
|
-
Object.entries(
|
|
1316
|
+
Object.entries(schema).map(async ([key, type]) => {
|
|
1317
1317
|
const value = props[key] ?? type.default;
|
|
1318
1318
|
const transformed = await transform({ value, key, type, signal, renderContext });
|
|
1319
1319
|
onPropResolve?.({ key, value: transformed, propValue: value, propType: type });
|
|
@@ -3961,7 +3961,7 @@ function initTabsModelExtensions() {
|
|
|
3961
3961
|
}
|
|
3962
3962
|
|
|
3963
3963
|
// src/mcp/canvas-mcp.ts
|
|
3964
|
-
var
|
|
3964
|
+
var import_editor_props8 = require("@elementor/editor-props");
|
|
3965
3965
|
|
|
3966
3966
|
// src/mcp/resources/available-widgets-resource.ts
|
|
3967
3967
|
var import_http_client3 = require("@elementor/http-client");
|
|
@@ -4482,8 +4482,25 @@ function getElementDisplayName(container) {
|
|
|
4482
4482
|
// src/mcp/tools/build-composition/tool.ts
|
|
4483
4483
|
var import_editor_documents2 = require("@elementor/editor-documents");
|
|
4484
4484
|
var import_editor_elements11 = require("@elementor/editor-elements");
|
|
4485
|
-
var
|
|
4485
|
+
var import_http_client7 = require("@elementor/http-client");
|
|
4486
4486
|
var import_schema = require("@elementor/schema");
|
|
4487
|
+
|
|
4488
|
+
// src/mcp/utils/get-mcp-error-message.ts
|
|
4489
|
+
var import_http_client6 = require("@elementor/http-client");
|
|
4490
|
+
function getMcpErrorMessage(error, toolName) {
|
|
4491
|
+
if (error instanceof import_http_client6.AxiosError) {
|
|
4492
|
+
const data = error.response?.data;
|
|
4493
|
+
if (data?.message) {
|
|
4494
|
+
return data.code ? `${data.code}: ${data.message}` : data.message;
|
|
4495
|
+
}
|
|
4496
|
+
}
|
|
4497
|
+
if (error instanceof Error) {
|
|
4498
|
+
return error.message;
|
|
4499
|
+
}
|
|
4500
|
+
return `${toolName} failed with an unknown error.`;
|
|
4501
|
+
}
|
|
4502
|
+
|
|
4503
|
+
// src/mcp/tools/build-composition/tool.ts
|
|
4487
4504
|
var MCP_PROXY_URL5 = "elementor/v1/mcp-proxy";
|
|
4488
4505
|
var initBuildCompositionTool = (reg) => {
|
|
4489
4506
|
const { addTool } = reg;
|
|
@@ -4505,6 +4522,9 @@ var initBuildCompositionTool = (reg) => {
|
|
|
4505
4522
|
"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
4523
|
),
|
|
4507
4524
|
parentId: import_schema.z.string().optional().describe("ID of the parent container. Omit or pass 'document' to insert at document root."),
|
|
4525
|
+
mode: import_schema.z.enum(["append", "replace_children"]).optional().describe(
|
|
4526
|
+
"'append' (default) inserts under parentId; 'replace_children' removes existing direct children of parentId first, then inserts."
|
|
4527
|
+
),
|
|
4508
4528
|
dryRun: import_schema.z.boolean().optional().describe("If true, validate and return the resolved tree without persisting.")
|
|
4509
4529
|
},
|
|
4510
4530
|
outputSchema: {
|
|
@@ -4513,15 +4533,16 @@ var initBuildCompositionTool = (reg) => {
|
|
|
4513
4533
|
version: import_schema.z.string(),
|
|
4514
4534
|
resolvedXml: import_schema.z.string(),
|
|
4515
4535
|
llmInstructions: import_schema.z.string(),
|
|
4516
|
-
warnings: import_schema.z.array(import_schema.z.string()).optional()
|
|
4536
|
+
warnings: import_schema.z.array(import_schema.z.string()).optional(),
|
|
4537
|
+
removedElementIds: import_schema.z.array(import_schema.z.string()).optional()
|
|
4517
4538
|
},
|
|
4518
|
-
handler: async ({ xmlStructure, elementConfig, style, parentId, dryRun }) => {
|
|
4539
|
+
handler: async ({ xmlStructure, elementConfig, style, parentId, mode, dryRun }) => {
|
|
4519
4540
|
const document2 = (0, import_editor_documents2.getCurrentDocument)();
|
|
4520
4541
|
if (!document2?.id) {
|
|
4521
4542
|
throw new Error("No active document found.");
|
|
4522
4543
|
}
|
|
4523
4544
|
try {
|
|
4524
|
-
const { data } = await (0,
|
|
4545
|
+
const { data } = await (0, import_http_client7.httpService)().post(MCP_PROXY_URL5, {
|
|
4525
4546
|
tool: "build-composition",
|
|
4526
4547
|
input: {
|
|
4527
4548
|
post_id: document2.id,
|
|
@@ -4529,6 +4550,7 @@ var initBuildCompositionTool = (reg) => {
|
|
|
4529
4550
|
element_config: elementConfig ?? {},
|
|
4530
4551
|
style: style ?? {},
|
|
4531
4552
|
parent_id: parentId ?? "document",
|
|
4553
|
+
mode: mode ?? "append",
|
|
4532
4554
|
dry_run: dryRun ?? false
|
|
4533
4555
|
}
|
|
4534
4556
|
});
|
|
@@ -4549,26 +4571,15 @@ var initBuildCompositionTool = (reg) => {
|
|
|
4549
4571
|
version: data.data.version,
|
|
4550
4572
|
resolvedXml: data.data.resolved_xml,
|
|
4551
4573
|
llmInstructions: data.data.llm_instructions,
|
|
4552
|
-
warnings: data.data.warnings
|
|
4574
|
+
warnings: data.data.warnings,
|
|
4575
|
+
removedElementIds: data.data.removed_element_ids
|
|
4553
4576
|
};
|
|
4554
4577
|
} catch (error) {
|
|
4555
|
-
throw new Error(
|
|
4578
|
+
throw new Error(getMcpErrorMessage(error, "build-composition"));
|
|
4556
4579
|
}
|
|
4557
4580
|
}
|
|
4558
4581
|
});
|
|
4559
4582
|
};
|
|
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
|
-
}
|
|
4572
4583
|
|
|
4573
4584
|
// src/mcp/tools/configure-element/tool.ts
|
|
4574
4585
|
var import_editor_elements14 = require("@elementor/editor-elements");
|
|
@@ -4597,9 +4608,9 @@ var readStoredCustomCssText = (raw) => {
|
|
|
4597
4608
|
|
|
4598
4609
|
// src/mcp/utils/resolve-canonical-prop-name.ts
|
|
4599
4610
|
var import_editor_elements12 = require("@elementor/editor-elements");
|
|
4600
|
-
function buildAliasToCanonicalMap(
|
|
4611
|
+
function buildAliasToCanonicalMap(schema) {
|
|
4601
4612
|
const aliasToCanonical = {};
|
|
4602
|
-
for (const [canonical, propType] of Object.entries(
|
|
4613
|
+
for (const [canonical, propType] of Object.entries(schema)) {
|
|
4603
4614
|
const aliases = propType.meta?.aliases;
|
|
4604
4615
|
if (!Array.isArray(aliases)) {
|
|
4605
4616
|
continue;
|
|
@@ -4613,26 +4624,26 @@ function buildAliasToCanonicalMap(schema2) {
|
|
|
4613
4624
|
return aliasToCanonical;
|
|
4614
4625
|
}
|
|
4615
4626
|
function resolveCanonicalPropName(elementType, propertyName) {
|
|
4616
|
-
const
|
|
4617
|
-
if (!
|
|
4627
|
+
const schema = (0, import_editor_elements12.getWidgetsCache)()?.[elementType]?.atomic_props_schema;
|
|
4628
|
+
if (!schema || schema[propertyName]) {
|
|
4618
4629
|
return propertyName;
|
|
4619
4630
|
}
|
|
4620
|
-
return buildAliasToCanonicalMap(
|
|
4631
|
+
return buildAliasToCanonicalMap(schema)[propertyName] ?? propertyName;
|
|
4621
4632
|
}
|
|
4622
4633
|
function resolveCanonicalPropKeys(elementType, props) {
|
|
4623
|
-
const
|
|
4624
|
-
if (!
|
|
4634
|
+
const schema = (0, import_editor_elements12.getWidgetsCache)()?.[elementType]?.atomic_props_schema;
|
|
4635
|
+
if (!schema) {
|
|
4625
4636
|
return { ...props };
|
|
4626
4637
|
}
|
|
4627
|
-
const aliasToCanonical = buildAliasToCanonicalMap(
|
|
4638
|
+
const aliasToCanonical = buildAliasToCanonicalMap(schema);
|
|
4628
4639
|
const resolved = {};
|
|
4629
4640
|
for (const [key, value] of Object.entries(props)) {
|
|
4630
|
-
if (
|
|
4641
|
+
if (schema[key]) {
|
|
4631
4642
|
resolved[key] = value;
|
|
4632
4643
|
}
|
|
4633
4644
|
}
|
|
4634
4645
|
for (const [key, value] of Object.entries(props)) {
|
|
4635
|
-
if (
|
|
4646
|
+
if (schema[key]) {
|
|
4636
4647
|
continue;
|
|
4637
4648
|
}
|
|
4638
4649
|
const canonical = aliasToCanonical[key];
|
|
@@ -4680,9 +4691,9 @@ var dynamicTagLLMResolver = (value) => {
|
|
|
4680
4691
|
}
|
|
4681
4692
|
};
|
|
4682
4693
|
};
|
|
4683
|
-
var buildStrictSettings = (
|
|
4694
|
+
var buildStrictSettings = (schema, provided) => {
|
|
4684
4695
|
const settings = {};
|
|
4685
|
-
for (const [key, propType] of Object.entries(
|
|
4696
|
+
for (const [key, propType] of Object.entries(schema)) {
|
|
4686
4697
|
if (OMITTED_DYNAMIC_SETTING_KEYS.includes(key)) {
|
|
4687
4698
|
continue;
|
|
4688
4699
|
}
|
|
@@ -5109,102 +5120,49 @@ Provide styling as raw CSS via the "style" parameter (a flat map of CSS property
|
|
|
5109
5120
|
}`;
|
|
5110
5121
|
}
|
|
5111
5122
|
|
|
5112
|
-
// src/mcp/tools/get-
|
|
5113
|
-
var
|
|
5114
|
-
var
|
|
5123
|
+
// src/mcp/tools/get-page-structure/tool.ts
|
|
5124
|
+
var import_editor_documents3 = require("@elementor/editor-documents");
|
|
5125
|
+
var import_http_client8 = require("@elementor/http-client");
|
|
5115
5126
|
var import_schema4 = require("@elementor/schema");
|
|
5116
|
-
var
|
|
5117
|
-
|
|
5118
|
-
};
|
|
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")
|
|
5127
|
-
})
|
|
5128
|
-
).describe("An array of child element IDs, when applicable, with recursive structure")
|
|
5129
|
-
};
|
|
5130
|
-
var structuredElements = (element) => {
|
|
5131
|
-
const children = element.children || [];
|
|
5132
|
-
return children.map((child) => {
|
|
5133
|
-
return {
|
|
5134
|
-
id: child.id,
|
|
5135
|
-
elementType: child.model.get("elType") || child.model.get("widgetType") || "unknown",
|
|
5136
|
-
childElements: structuredElements(child)
|
|
5137
|
-
};
|
|
5138
|
-
});
|
|
5139
|
-
};
|
|
5140
|
-
var initGetElementConfigTool = (reg) => {
|
|
5127
|
+
var MCP_PROXY_URL6 = "elementor/v1/mcp-proxy";
|
|
5128
|
+
var initGetPageStructureTool = (reg) => {
|
|
5141
5129
|
const { addTool } = reg;
|
|
5142
5130
|
addTool({
|
|
5143
|
-
name: "get-
|
|
5144
|
-
description: "
|
|
5145
|
-
schema
|
|
5146
|
-
|
|
5147
|
-
|
|
5148
|
-
|
|
5149
|
-
|
|
5150
|
-
|
|
5151
|
-
|
|
5152
|
-
|
|
5153
|
-
|
|
5154
|
-
|
|
5155
|
-
|
|
5156
|
-
|
|
5157
|
-
);
|
|
5158
|
-
}
|
|
5159
|
-
if (!widgetData.atomic_props_schema) {
|
|
5160
|
-
throw new Error(
|
|
5161
|
-
`This tool does not support V3 elements. Please use the elementor-v3-mcp tools instead for element type: ${elementType}`
|
|
5162
|
-
);
|
|
5163
|
-
}
|
|
5164
|
-
const elementRawSettings = element.settings;
|
|
5165
|
-
const propSchema = (0, import_editor_elements15.getWidgetsCache)()?.[elementType]?.atomic_props_schema;
|
|
5166
|
-
if (!elementRawSettings || !propSchema) {
|
|
5167
|
-
throw new Error(`No settings or prop schema found for element ID: ${elementId}`);
|
|
5131
|
+
name: "get-page-structure",
|
|
5132
|
+
description: "Returns the Elementor element tree (widgets, containers, and nested content) for a post or page. If no postId is provided, uses the currently open document. Only works for posts saved with Elementor.",
|
|
5133
|
+
schema: {
|
|
5134
|
+
postId: import_schema4.z.number().optional().describe(
|
|
5135
|
+
"WordPress post ID of the Elementor document. If omitted, uses the currently open document."
|
|
5136
|
+
)
|
|
5137
|
+
},
|
|
5138
|
+
outputSchema: {
|
|
5139
|
+
elements: import_schema4.z.array(import_schema4.z.any()).describe("Root-level Elementor elements for the document.")
|
|
5140
|
+
},
|
|
5141
|
+
handler: async ({ postId }) => {
|
|
5142
|
+
const resolvedPostId = postId ?? (0, import_editor_documents3.getCurrentDocument)()?.id;
|
|
5143
|
+
if (!resolvedPostId) {
|
|
5144
|
+
throw new Error("No post ID provided and no active document found.");
|
|
5168
5145
|
}
|
|
5169
|
-
|
|
5170
|
-
|
|
5171
|
-
|
|
5172
|
-
|
|
5173
|
-
|
|
5174
|
-
const elementStyles = (0, import_editor_elements15.getElementStyles)(elementId) || {};
|
|
5175
|
-
const localStyle = Object.values(elementStyles).find((style) => style.label === "local");
|
|
5176
|
-
if (localStyle) {
|
|
5177
|
-
const defaultVariant = localStyle.variants.find(
|
|
5178
|
-
(variant) => variant.meta.breakpoint === "desktop" && !variant.meta.state
|
|
5179
|
-
);
|
|
5180
|
-
if (defaultVariant) {
|
|
5181
|
-
const styleProps = defaultVariant.props || {};
|
|
5182
|
-
Object.keys(styleProps).forEach((stylePropName) => {
|
|
5183
|
-
if (typeof styleProps[stylePropName] !== "undefined") {
|
|
5184
|
-
stylePropValues[stylePropName] = structuredClone(styleProps[stylePropName]);
|
|
5185
|
-
}
|
|
5186
|
-
});
|
|
5187
|
-
if (defaultVariant.custom_css) {
|
|
5188
|
-
stylePropValues.custom_css = atob(defaultVariant.custom_css.raw);
|
|
5146
|
+
try {
|
|
5147
|
+
const { data } = await (0, import_http_client8.httpService)().post(MCP_PROXY_URL6, {
|
|
5148
|
+
tool: "get-page-structure",
|
|
5149
|
+
input: {
|
|
5150
|
+
post_id: resolvedPostId
|
|
5189
5151
|
}
|
|
5190
|
-
}
|
|
5152
|
+
});
|
|
5153
|
+
return {
|
|
5154
|
+
elements: data.data.elements
|
|
5155
|
+
};
|
|
5156
|
+
} catch (error) {
|
|
5157
|
+
throw new Error(getMcpErrorMessage(error, "get-page-structure"));
|
|
5191
5158
|
}
|
|
5192
|
-
return {
|
|
5193
|
-
properties: {
|
|
5194
|
-
...propValues
|
|
5195
|
-
},
|
|
5196
|
-
style: {
|
|
5197
|
-
...stylePropValues
|
|
5198
|
-
},
|
|
5199
|
-
childElements: structuredElements(element)
|
|
5200
|
-
};
|
|
5201
5159
|
}
|
|
5202
5160
|
});
|
|
5203
5161
|
};
|
|
5204
5162
|
|
|
5205
5163
|
// src/mcp/canvas-mcp.ts
|
|
5206
5164
|
var initCanvasMcp = (reg) => {
|
|
5207
|
-
|
|
5165
|
+
import_editor_props8.Schema.setDynamicTagNamesResolver(getDynamicTagNamesByCategories);
|
|
5208
5166
|
initWidgetsSchemaResource(reg);
|
|
5209
5167
|
initAvailableWidgetsResource(reg);
|
|
5210
5168
|
initDocumentStructureResource(reg);
|
|
@@ -5213,9 +5171,9 @@ var initCanvasMcp = (reg) => {
|
|
|
5213
5171
|
initEditorStateResource(reg);
|
|
5214
5172
|
initGeneralContextResource(reg);
|
|
5215
5173
|
initBestPracticesResource(reg);
|
|
5216
|
-
initGetElementConfigTool(reg);
|
|
5217
5174
|
initConfigureElementTool(reg);
|
|
5218
5175
|
initBuildCompositionTool(reg);
|
|
5176
|
+
initGetPageStructureTool(reg);
|
|
5219
5177
|
initBreakpointsResource(reg);
|
|
5220
5178
|
};
|
|
5221
5179
|
|
|
@@ -5328,7 +5286,7 @@ Note: The "size" property controls image resolution/loading, not visual size. Se
|
|
|
5328
5286
|
`;
|
|
5329
5287
|
|
|
5330
5288
|
// src/prevent-link-in-link-commands.ts
|
|
5331
|
-
var
|
|
5289
|
+
var import_editor_elements15 = require("@elementor/editor-elements");
|
|
5332
5290
|
var import_editor_notifications3 = require("@elementor/editor-notifications");
|
|
5333
5291
|
var import_editor_v1_adapters21 = require("@elementor/editor-v1-adapters");
|
|
5334
5292
|
var import_i18n4 = require("@wordpress/i18n");
|
|
@@ -5399,25 +5357,25 @@ function shouldBlock(sourceElements, targetElements) {
|
|
|
5399
5357
|
return false;
|
|
5400
5358
|
}
|
|
5401
5359
|
const isSourceContainsAnAnchor = sourceElements.some((src) => {
|
|
5402
|
-
return src?.id ? (0,
|
|
5360
|
+
return src?.id ? (0, import_editor_elements15.isElementAnchored)(src.id) || !!(0, import_editor_elements15.getAnchoredDescendantId)(src.id) : false;
|
|
5403
5361
|
});
|
|
5404
5362
|
if (!isSourceContainsAnAnchor) {
|
|
5405
5363
|
return false;
|
|
5406
5364
|
}
|
|
5407
5365
|
const isTargetContainsAnAnchor = targetElements.some((target) => {
|
|
5408
|
-
return target?.id ? (0,
|
|
5366
|
+
return target?.id ? (0, import_editor_elements15.isElementAnchored)(target.id) || !!(0, import_editor_elements15.getAnchoredAncestorId)(target.id) : false;
|
|
5409
5367
|
});
|
|
5410
5368
|
return isTargetContainsAnAnchor;
|
|
5411
5369
|
}
|
|
5412
5370
|
|
|
5413
5371
|
// src/style-commands/paste-style.ts
|
|
5414
|
-
var
|
|
5415
|
-
var
|
|
5372
|
+
var import_editor_elements18 = require("@elementor/editor-elements");
|
|
5373
|
+
var import_editor_props10 = require("@elementor/editor-props");
|
|
5416
5374
|
var import_editor_v1_adapters23 = require("@elementor/editor-v1-adapters");
|
|
5417
5375
|
|
|
5418
5376
|
// src/utils/command-utils.ts
|
|
5419
|
-
var
|
|
5420
|
-
var
|
|
5377
|
+
var import_editor_elements16 = require("@elementor/editor-elements");
|
|
5378
|
+
var import_editor_props9 = require("@elementor/editor-props");
|
|
5421
5379
|
var import_i18n5 = require("@wordpress/i18n");
|
|
5422
5380
|
function hasAtomicWidgets(args) {
|
|
5423
5381
|
const { containers = [args.container] } = args;
|
|
@@ -5435,13 +5393,13 @@ function getClassesProp(container) {
|
|
|
5435
5393
|
return null;
|
|
5436
5394
|
}
|
|
5437
5395
|
const [propKey] = Object.entries(propsSchema).find(
|
|
5438
|
-
([, propType]) => propType.kind === "plain" && propType.key ===
|
|
5396
|
+
([, propType]) => propType.kind === "plain" && propType.key === import_editor_props9.CLASSES_PROP_KEY
|
|
5439
5397
|
) ?? [];
|
|
5440
5398
|
return propKey ?? null;
|
|
5441
5399
|
}
|
|
5442
5400
|
function getContainerSchema(container) {
|
|
5443
5401
|
const type = container?.model.get("widgetType") || container?.model.get("elType");
|
|
5444
|
-
const widgetsCache = (0,
|
|
5402
|
+
const widgetsCache = (0, import_editor_elements16.getWidgetsCache)();
|
|
5445
5403
|
const elementType = widgetsCache?.[type];
|
|
5446
5404
|
return elementType?.atomic_props_schema ?? null;
|
|
5447
5405
|
}
|
|
@@ -5454,11 +5412,11 @@ function getClipboardElements(storageKey = "clipboard") {
|
|
|
5454
5412
|
}
|
|
5455
5413
|
}
|
|
5456
5414
|
function getTitleForContainers(containers) {
|
|
5457
|
-
return containers.length > 1 ? (0, import_i18n5.__)("Elements", "elementor") : (0,
|
|
5415
|
+
return containers.length > 1 ? (0, import_i18n5.__)("Elements", "elementor") : (0, import_editor_elements16.getElementLabel)(containers[0].id);
|
|
5458
5416
|
}
|
|
5459
5417
|
|
|
5460
5418
|
// src/style-commands/undoable-actions/paste-element-style.ts
|
|
5461
|
-
var
|
|
5419
|
+
var import_editor_elements17 = require("@elementor/editor-elements");
|
|
5462
5420
|
var import_editor_styles_repository4 = require("@elementor/editor-styles-repository");
|
|
5463
5421
|
var import_editor_v1_adapters22 = require("@elementor/editor-v1-adapters");
|
|
5464
5422
|
var import_i18n6 = require("@wordpress/i18n");
|
|
@@ -5471,7 +5429,7 @@ var undoablePasteElementStyle = () => (0, import_editor_v1_adapters22.undoable)(
|
|
|
5471
5429
|
if (!classesProp) {
|
|
5472
5430
|
return null;
|
|
5473
5431
|
}
|
|
5474
|
-
const originalStyles = (0,
|
|
5432
|
+
const originalStyles = (0, import_editor_elements17.getElementStyles)(container.id);
|
|
5475
5433
|
const [styleId, styleDef] = Object.entries(originalStyles ?? {})[0] ?? [];
|
|
5476
5434
|
const originalStyle = Object.keys(styleDef ?? {}).length ? styleDef : null;
|
|
5477
5435
|
const revertData = {
|
|
@@ -5480,7 +5438,7 @@ var undoablePasteElementStyle = () => (0, import_editor_v1_adapters22.undoable)(
|
|
|
5480
5438
|
};
|
|
5481
5439
|
if (styleId) {
|
|
5482
5440
|
newStyle.variants.forEach(({ meta, props, custom_css: customCss }) => {
|
|
5483
|
-
(0,
|
|
5441
|
+
(0, import_editor_elements17.updateElementStyle)({
|
|
5484
5442
|
elementId,
|
|
5485
5443
|
styleId,
|
|
5486
5444
|
meta,
|
|
@@ -5491,7 +5449,7 @@ var undoablePasteElementStyle = () => (0, import_editor_v1_adapters22.undoable)(
|
|
|
5491
5449
|
} else {
|
|
5492
5450
|
const [firstVariant] = newStyle.variants;
|
|
5493
5451
|
const additionalVariants = newStyle.variants.slice(1);
|
|
5494
|
-
revertData.styleId = (0,
|
|
5452
|
+
revertData.styleId = (0, import_editor_elements17.createElementStyle)({
|
|
5495
5453
|
elementId,
|
|
5496
5454
|
classesProp,
|
|
5497
5455
|
label: import_editor_styles_repository4.ELEMENTS_STYLES_RESERVED_LABEL,
|
|
@@ -5509,7 +5467,7 @@ var undoablePasteElementStyle = () => (0, import_editor_v1_adapters22.undoable)(
|
|
|
5509
5467
|
return;
|
|
5510
5468
|
}
|
|
5511
5469
|
if (!revertData.originalStyle) {
|
|
5512
|
-
(0,
|
|
5470
|
+
(0, import_editor_elements17.deleteElementStyle)(container.id, revertData.styleId);
|
|
5513
5471
|
return;
|
|
5514
5472
|
}
|
|
5515
5473
|
const classesProp = getClassesProp(container);
|
|
@@ -5518,7 +5476,7 @@ var undoablePasteElementStyle = () => (0, import_editor_v1_adapters22.undoable)(
|
|
|
5518
5476
|
}
|
|
5519
5477
|
const [firstVariant] = revertData.originalStyle.variants;
|
|
5520
5478
|
const additionalVariants = revertData.originalStyle.variants.slice(1);
|
|
5521
|
-
(0,
|
|
5479
|
+
(0, import_editor_elements17.createElementStyle)({
|
|
5522
5480
|
elementId: container.id,
|
|
5523
5481
|
classesProp,
|
|
5524
5482
|
label: import_editor_styles_repository4.ELEMENTS_STYLES_RESERVED_LABEL,
|
|
@@ -5555,7 +5513,7 @@ function pasteStyles(args, pasteLocalStyle) {
|
|
|
5555
5513
|
}
|
|
5556
5514
|
const clipboardElements = getClipboardElements(storageKey);
|
|
5557
5515
|
const [clipboardElement] = clipboardElements ?? [];
|
|
5558
|
-
const clipboardContainer = (0,
|
|
5516
|
+
const clipboardContainer = (0, import_editor_elements18.getContainer)(clipboardElement.id);
|
|
5559
5517
|
if (!clipboardElement || !clipboardContainer || !isAtomicWidget(clipboardContainer)) {
|
|
5560
5518
|
return;
|
|
5561
5519
|
}
|
|
@@ -5574,7 +5532,7 @@ function getClassesWithoutLocalStyle(clipboardContainer, style) {
|
|
|
5574
5532
|
if (!classesProp) {
|
|
5575
5533
|
return [];
|
|
5576
5534
|
}
|
|
5577
|
-
const classesSetting = (0,
|
|
5535
|
+
const classesSetting = (0, import_editor_elements18.getElementSetting)(clipboardContainer.id, classesProp);
|
|
5578
5536
|
return classesSetting?.value.filter((styleId) => styleId !== style?.id) ?? [];
|
|
5579
5537
|
}
|
|
5580
5538
|
function pasteClasses(containers, classes) {
|
|
@@ -5583,10 +5541,10 @@ function pasteClasses(containers, classes) {
|
|
|
5583
5541
|
if (!classesProp) {
|
|
5584
5542
|
return;
|
|
5585
5543
|
}
|
|
5586
|
-
const classesSetting = (0,
|
|
5587
|
-
const currentClasses =
|
|
5588
|
-
const newClasses =
|
|
5589
|
-
(0,
|
|
5544
|
+
const classesSetting = (0, import_editor_elements18.getElementSetting)(container.id, classesProp);
|
|
5545
|
+
const currentClasses = import_editor_props10.classesPropTypeUtil.extract(classesSetting) ?? [];
|
|
5546
|
+
const newClasses = import_editor_props10.classesPropTypeUtil.create(Array.from(/* @__PURE__ */ new Set([...classes, ...currentClasses])));
|
|
5547
|
+
(0, import_editor_elements18.updateElementSettings)({
|
|
5590
5548
|
id: container.id,
|
|
5591
5549
|
props: { [classesProp]: newClasses }
|
|
5592
5550
|
});
|
|
@@ -5597,7 +5555,7 @@ function pasteClasses(containers, classes) {
|
|
|
5597
5555
|
var import_editor_v1_adapters25 = require("@elementor/editor-v1-adapters");
|
|
5598
5556
|
|
|
5599
5557
|
// src/style-commands/undoable-actions/reset-element-style.ts
|
|
5600
|
-
var
|
|
5558
|
+
var import_editor_elements19 = require("@elementor/editor-elements");
|
|
5601
5559
|
var import_editor_styles_repository5 = require("@elementor/editor-styles-repository");
|
|
5602
5560
|
var import_editor_v1_adapters24 = require("@elementor/editor-v1-adapters");
|
|
5603
5561
|
var import_i18n7 = require("@wordpress/i18n");
|
|
@@ -5606,9 +5564,9 @@ var undoableResetElementStyle = () => (0, import_editor_v1_adapters24.undoable)(
|
|
|
5606
5564
|
do: ({ containers }) => {
|
|
5607
5565
|
return containers.map((container) => {
|
|
5608
5566
|
const elementId = container.model.get("id");
|
|
5609
|
-
const containerStyles = (0,
|
|
5567
|
+
const containerStyles = (0, import_editor_elements19.getElementStyles)(elementId);
|
|
5610
5568
|
Object.keys(containerStyles ?? {}).forEach(
|
|
5611
|
-
(styleId) => (0,
|
|
5569
|
+
(styleId) => (0, import_editor_elements19.deleteElementStyle)(elementId, styleId)
|
|
5612
5570
|
);
|
|
5613
5571
|
return containerStyles;
|
|
5614
5572
|
});
|
|
@@ -5624,7 +5582,7 @@ var undoableResetElementStyle = () => (0, import_editor_v1_adapters24.undoable)(
|
|
|
5624
5582
|
Object.entries(containerStyles ?? {}).forEach(([styleId, style]) => {
|
|
5625
5583
|
const [firstVariant] = style.variants;
|
|
5626
5584
|
const additionalVariants = style.variants.slice(1);
|
|
5627
|
-
(0,
|
|
5585
|
+
(0, import_editor_elements19.createElementStyle)({
|
|
5628
5586
|
elementId,
|
|
5629
5587
|
classesProp,
|
|
5630
5588
|
styleId,
|
|
@@ -5824,10 +5782,10 @@ function useEscapeOnCanvas(canvasDocument, onEscape) {
|
|
|
5824
5782
|
}
|
|
5825
5783
|
|
|
5826
5784
|
// src/utils/after-render.ts
|
|
5827
|
-
var
|
|
5785
|
+
var import_editor_elements20 = require("@elementor/editor-elements");
|
|
5828
5786
|
function doAfterRender(elementIds, callback) {
|
|
5829
5787
|
const pending = elementIds.map((elementId) => {
|
|
5830
|
-
const view = (0,
|
|
5788
|
+
const view = (0, import_editor_elements20.getContainer)(elementId)?.view;
|
|
5831
5789
|
if (!view || !hasDoAfterRender(view)) {
|
|
5832
5790
|
return void 0;
|
|
5833
5791
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -47,13 +47,13 @@ var initWidgetsSchemaResource = (reg) => {
|
|
|
47
47
|
if (!widgetType) {
|
|
48
48
|
throw new Error("No widget type provided.");
|
|
49
49
|
}
|
|
50
|
-
const
|
|
50
|
+
const schema = await fetchWidgetSchema(widgetType);
|
|
51
51
|
return {
|
|
52
52
|
contents: [
|
|
53
53
|
{
|
|
54
54
|
uri: uri.toString(),
|
|
55
55
|
mimeType: "application/json",
|
|
56
|
-
text: JSON.stringify(
|
|
56
|
+
text: JSON.stringify(schema)
|
|
57
57
|
}
|
|
58
58
|
]
|
|
59
59
|
};
|
|
@@ -1260,10 +1260,10 @@ var getMultiPropsValue = (multiProps) => {
|
|
|
1260
1260
|
// src/renderers/create-props-resolver.ts
|
|
1261
1261
|
var TRANSFORM_DEPTH_LIMIT = 3;
|
|
1262
1262
|
function createPropsResolver({ transformers, schema: initialSchema, onPropResolve }) {
|
|
1263
|
-
async function resolve({ props, schema
|
|
1264
|
-
|
|
1263
|
+
async function resolve({ props, schema, signal, renderContext }) {
|
|
1264
|
+
schema = schema ?? initialSchema;
|
|
1265
1265
|
const promises = Promise.all(
|
|
1266
|
-
Object.entries(
|
|
1266
|
+
Object.entries(schema).map(async ([key, type]) => {
|
|
1267
1267
|
const value = props[key] ?? type.default;
|
|
1268
1268
|
const transformed = await transform({ value, key, type, signal, renderContext });
|
|
1269
1269
|
onPropResolve?.({ key, value: transformed, propValue: value, propType: type });
|
|
@@ -3922,7 +3922,7 @@ function initTabsModelExtensions() {
|
|
|
3922
3922
|
}
|
|
3923
3923
|
|
|
3924
3924
|
// src/mcp/canvas-mcp.ts
|
|
3925
|
-
import { Schema as
|
|
3925
|
+
import { Schema as Schema3 } from "@elementor/editor-props";
|
|
3926
3926
|
|
|
3927
3927
|
// src/mcp/resources/available-widgets-resource.ts
|
|
3928
3928
|
import { httpService as httpService3 } from "@elementor/http-client";
|
|
@@ -4448,8 +4448,25 @@ function getElementDisplayName(container) {
|
|
|
4448
4448
|
// src/mcp/tools/build-composition/tool.ts
|
|
4449
4449
|
import { getCurrentDocument, reloadCurrentDocument } from "@elementor/editor-documents";
|
|
4450
4450
|
import { getContainer as getContainer4, selectElement } from "@elementor/editor-elements";
|
|
4451
|
-
import {
|
|
4451
|
+
import { httpService as httpService6 } from "@elementor/http-client";
|
|
4452
4452
|
import { z } from "@elementor/schema";
|
|
4453
|
+
|
|
4454
|
+
// src/mcp/utils/get-mcp-error-message.ts
|
|
4455
|
+
import { AxiosError } from "@elementor/http-client";
|
|
4456
|
+
function getMcpErrorMessage(error, toolName) {
|
|
4457
|
+
if (error instanceof AxiosError) {
|
|
4458
|
+
const data = error.response?.data;
|
|
4459
|
+
if (data?.message) {
|
|
4460
|
+
return data.code ? `${data.code}: ${data.message}` : data.message;
|
|
4461
|
+
}
|
|
4462
|
+
}
|
|
4463
|
+
if (error instanceof Error) {
|
|
4464
|
+
return error.message;
|
|
4465
|
+
}
|
|
4466
|
+
return `${toolName} failed with an unknown error.`;
|
|
4467
|
+
}
|
|
4468
|
+
|
|
4469
|
+
// src/mcp/tools/build-composition/tool.ts
|
|
4453
4470
|
var MCP_PROXY_URL5 = "elementor/v1/mcp-proxy";
|
|
4454
4471
|
var initBuildCompositionTool = (reg) => {
|
|
4455
4472
|
const { addTool } = reg;
|
|
@@ -4471,6 +4488,9 @@ var initBuildCompositionTool = (reg) => {
|
|
|
4471
4488
|
"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."
|
|
4472
4489
|
),
|
|
4473
4490
|
parentId: z.string().optional().describe("ID of the parent container. Omit or pass 'document' to insert at document root."),
|
|
4491
|
+
mode: z.enum(["append", "replace_children"]).optional().describe(
|
|
4492
|
+
"'append' (default) inserts under parentId; 'replace_children' removes existing direct children of parentId first, then inserts."
|
|
4493
|
+
),
|
|
4474
4494
|
dryRun: z.boolean().optional().describe("If true, validate and return the resolved tree without persisting.")
|
|
4475
4495
|
},
|
|
4476
4496
|
outputSchema: {
|
|
@@ -4479,9 +4499,10 @@ var initBuildCompositionTool = (reg) => {
|
|
|
4479
4499
|
version: z.string(),
|
|
4480
4500
|
resolvedXml: z.string(),
|
|
4481
4501
|
llmInstructions: z.string(),
|
|
4482
|
-
warnings: z.array(z.string()).optional()
|
|
4502
|
+
warnings: z.array(z.string()).optional(),
|
|
4503
|
+
removedElementIds: z.array(z.string()).optional()
|
|
4483
4504
|
},
|
|
4484
|
-
handler: async ({ xmlStructure, elementConfig, style, parentId, dryRun }) => {
|
|
4505
|
+
handler: async ({ xmlStructure, elementConfig, style, parentId, mode, dryRun }) => {
|
|
4485
4506
|
const document2 = getCurrentDocument();
|
|
4486
4507
|
if (!document2?.id) {
|
|
4487
4508
|
throw new Error("No active document found.");
|
|
@@ -4495,6 +4516,7 @@ var initBuildCompositionTool = (reg) => {
|
|
|
4495
4516
|
element_config: elementConfig ?? {},
|
|
4496
4517
|
style: style ?? {},
|
|
4497
4518
|
parent_id: parentId ?? "document",
|
|
4519
|
+
mode: mode ?? "append",
|
|
4498
4520
|
dry_run: dryRun ?? false
|
|
4499
4521
|
}
|
|
4500
4522
|
});
|
|
@@ -4515,26 +4537,15 @@ var initBuildCompositionTool = (reg) => {
|
|
|
4515
4537
|
version: data.data.version,
|
|
4516
4538
|
resolvedXml: data.data.resolved_xml,
|
|
4517
4539
|
llmInstructions: data.data.llm_instructions,
|
|
4518
|
-
warnings: data.data.warnings
|
|
4540
|
+
warnings: data.data.warnings,
|
|
4541
|
+
removedElementIds: data.data.removed_element_ids
|
|
4519
4542
|
};
|
|
4520
4543
|
} catch (error) {
|
|
4521
|
-
throw new Error(
|
|
4544
|
+
throw new Error(getMcpErrorMessage(error, "build-composition"));
|
|
4522
4545
|
}
|
|
4523
4546
|
}
|
|
4524
4547
|
});
|
|
4525
4548
|
};
|
|
4526
|
-
function getErrorMessage(error) {
|
|
4527
|
-
if (error instanceof AxiosError) {
|
|
4528
|
-
const data = error.response?.data;
|
|
4529
|
-
if (data?.message) {
|
|
4530
|
-
return data.code ? `${data.code}: ${data.message}` : data.message;
|
|
4531
|
-
}
|
|
4532
|
-
}
|
|
4533
|
-
if (error instanceof Error) {
|
|
4534
|
-
return error.message;
|
|
4535
|
-
}
|
|
4536
|
-
return "build-composition failed with an unknown error.";
|
|
4537
|
-
}
|
|
4538
4549
|
|
|
4539
4550
|
// src/mcp/tools/configure-element/tool.ts
|
|
4540
4551
|
import { getContainer as getContainer5, getWidgetsCache as getWidgetsCache6 } from "@elementor/editor-elements";
|
|
@@ -4569,9 +4580,9 @@ var readStoredCustomCssText = (raw) => {
|
|
|
4569
4580
|
|
|
4570
4581
|
// src/mcp/utils/resolve-canonical-prop-name.ts
|
|
4571
4582
|
import { getWidgetsCache as getWidgetsCache4 } from "@elementor/editor-elements";
|
|
4572
|
-
function buildAliasToCanonicalMap(
|
|
4583
|
+
function buildAliasToCanonicalMap(schema) {
|
|
4573
4584
|
const aliasToCanonical = {};
|
|
4574
|
-
for (const [canonical, propType] of Object.entries(
|
|
4585
|
+
for (const [canonical, propType] of Object.entries(schema)) {
|
|
4575
4586
|
const aliases = propType.meta?.aliases;
|
|
4576
4587
|
if (!Array.isArray(aliases)) {
|
|
4577
4588
|
continue;
|
|
@@ -4585,26 +4596,26 @@ function buildAliasToCanonicalMap(schema2) {
|
|
|
4585
4596
|
return aliasToCanonical;
|
|
4586
4597
|
}
|
|
4587
4598
|
function resolveCanonicalPropName(elementType, propertyName) {
|
|
4588
|
-
const
|
|
4589
|
-
if (!
|
|
4599
|
+
const schema = getWidgetsCache4()?.[elementType]?.atomic_props_schema;
|
|
4600
|
+
if (!schema || schema[propertyName]) {
|
|
4590
4601
|
return propertyName;
|
|
4591
4602
|
}
|
|
4592
|
-
return buildAliasToCanonicalMap(
|
|
4603
|
+
return buildAliasToCanonicalMap(schema)[propertyName] ?? propertyName;
|
|
4593
4604
|
}
|
|
4594
4605
|
function resolveCanonicalPropKeys(elementType, props) {
|
|
4595
|
-
const
|
|
4596
|
-
if (!
|
|
4606
|
+
const schema = getWidgetsCache4()?.[elementType]?.atomic_props_schema;
|
|
4607
|
+
if (!schema) {
|
|
4597
4608
|
return { ...props };
|
|
4598
4609
|
}
|
|
4599
|
-
const aliasToCanonical = buildAliasToCanonicalMap(
|
|
4610
|
+
const aliasToCanonical = buildAliasToCanonicalMap(schema);
|
|
4600
4611
|
const resolved = {};
|
|
4601
4612
|
for (const [key, value] of Object.entries(props)) {
|
|
4602
|
-
if (
|
|
4613
|
+
if (schema[key]) {
|
|
4603
4614
|
resolved[key] = value;
|
|
4604
4615
|
}
|
|
4605
4616
|
}
|
|
4606
4617
|
for (const [key, value] of Object.entries(props)) {
|
|
4607
|
-
if (
|
|
4618
|
+
if (schema[key]) {
|
|
4608
4619
|
continue;
|
|
4609
4620
|
}
|
|
4610
4621
|
const canonical = aliasToCanonical[key];
|
|
@@ -4652,9 +4663,9 @@ var dynamicTagLLMResolver = (value) => {
|
|
|
4652
4663
|
}
|
|
4653
4664
|
};
|
|
4654
4665
|
};
|
|
4655
|
-
var buildStrictSettings = (
|
|
4666
|
+
var buildStrictSettings = (schema, provided) => {
|
|
4656
4667
|
const settings = {};
|
|
4657
|
-
for (const [key, propType] of Object.entries(
|
|
4668
|
+
for (const [key, propType] of Object.entries(schema)) {
|
|
4658
4669
|
if (OMITTED_DYNAMIC_SETTING_KEYS.includes(key)) {
|
|
4659
4670
|
continue;
|
|
4660
4671
|
}
|
|
@@ -5081,102 +5092,49 @@ Provide styling as raw CSS via the "style" parameter (a flat map of CSS property
|
|
|
5081
5092
|
}`;
|
|
5082
5093
|
}
|
|
5083
5094
|
|
|
5084
|
-
// src/mcp/tools/get-
|
|
5085
|
-
import {
|
|
5086
|
-
import {
|
|
5095
|
+
// src/mcp/tools/get-page-structure/tool.ts
|
|
5096
|
+
import { getCurrentDocument as getCurrentDocument2 } from "@elementor/editor-documents";
|
|
5097
|
+
import { httpService as httpService7 } from "@elementor/http-client";
|
|
5087
5098
|
import { z as z3 } from "@elementor/schema";
|
|
5088
|
-
var
|
|
5089
|
-
|
|
5090
|
-
};
|
|
5091
|
-
var outputSchema2 = {
|
|
5092
|
-
properties: z3.record(z3.string(), z3.any()).describe("A record mapping PropTypes to their corresponding PropValues"),
|
|
5093
|
-
style: z3.record(z3.string(), z3.any()).describe("A record mapping StyleSchema properties to their corresponding PropValues"),
|
|
5094
|
-
childElements: z3.array(
|
|
5095
|
-
z3.object({
|
|
5096
|
-
id: z3.string(),
|
|
5097
|
-
elementType: z3.string(),
|
|
5098
|
-
childElements: z3.array(z3.any()).describe("An array of child element IDs, when applicable, same structure recursively")
|
|
5099
|
-
})
|
|
5100
|
-
).describe("An array of child element IDs, when applicable, with recursive structure")
|
|
5101
|
-
};
|
|
5102
|
-
var structuredElements = (element) => {
|
|
5103
|
-
const children = element.children || [];
|
|
5104
|
-
return children.map((child) => {
|
|
5105
|
-
return {
|
|
5106
|
-
id: child.id,
|
|
5107
|
-
elementType: child.model.get("elType") || child.model.get("widgetType") || "unknown",
|
|
5108
|
-
childElements: structuredElements(child)
|
|
5109
|
-
};
|
|
5110
|
-
});
|
|
5111
|
-
};
|
|
5112
|
-
var initGetElementConfigTool = (reg) => {
|
|
5099
|
+
var MCP_PROXY_URL6 = "elementor/v1/mcp-proxy";
|
|
5100
|
+
var initGetPageStructureTool = (reg) => {
|
|
5113
5101
|
const { addTool } = reg;
|
|
5114
5102
|
addTool({
|
|
5115
|
-
name: "get-
|
|
5116
|
-
description: "
|
|
5117
|
-
schema
|
|
5118
|
-
|
|
5119
|
-
|
|
5120
|
-
|
|
5121
|
-
|
|
5122
|
-
|
|
5123
|
-
|
|
5124
|
-
|
|
5125
|
-
|
|
5126
|
-
|
|
5127
|
-
|
|
5128
|
-
|
|
5129
|
-
);
|
|
5130
|
-
}
|
|
5131
|
-
if (!widgetData.atomic_props_schema) {
|
|
5132
|
-
throw new Error(
|
|
5133
|
-
`This tool does not support V3 elements. Please use the elementor-v3-mcp tools instead for element type: ${elementType}`
|
|
5134
|
-
);
|
|
5135
|
-
}
|
|
5136
|
-
const elementRawSettings = element.settings;
|
|
5137
|
-
const propSchema = getWidgetsCache7()?.[elementType]?.atomic_props_schema;
|
|
5138
|
-
if (!elementRawSettings || !propSchema) {
|
|
5139
|
-
throw new Error(`No settings or prop schema found for element ID: ${elementId}`);
|
|
5103
|
+
name: "get-page-structure",
|
|
5104
|
+
description: "Returns the Elementor element tree (widgets, containers, and nested content) for a post or page. If no postId is provided, uses the currently open document. Only works for posts saved with Elementor.",
|
|
5105
|
+
schema: {
|
|
5106
|
+
postId: z3.number().optional().describe(
|
|
5107
|
+
"WordPress post ID of the Elementor document. If omitted, uses the currently open document."
|
|
5108
|
+
)
|
|
5109
|
+
},
|
|
5110
|
+
outputSchema: {
|
|
5111
|
+
elements: z3.array(z3.any()).describe("Root-level Elementor elements for the document.")
|
|
5112
|
+
},
|
|
5113
|
+
handler: async ({ postId }) => {
|
|
5114
|
+
const resolvedPostId = postId ?? getCurrentDocument2()?.id;
|
|
5115
|
+
if (!resolvedPostId) {
|
|
5116
|
+
throw new Error("No post ID provided and no active document found.");
|
|
5140
5117
|
}
|
|
5141
|
-
|
|
5142
|
-
|
|
5143
|
-
|
|
5144
|
-
|
|
5145
|
-
|
|
5146
|
-
const elementStyles = getElementStyles2(elementId) || {};
|
|
5147
|
-
const localStyle = Object.values(elementStyles).find((style) => style.label === "local");
|
|
5148
|
-
if (localStyle) {
|
|
5149
|
-
const defaultVariant = localStyle.variants.find(
|
|
5150
|
-
(variant) => variant.meta.breakpoint === "desktop" && !variant.meta.state
|
|
5151
|
-
);
|
|
5152
|
-
if (defaultVariant) {
|
|
5153
|
-
const styleProps = defaultVariant.props || {};
|
|
5154
|
-
Object.keys(styleProps).forEach((stylePropName) => {
|
|
5155
|
-
if (typeof styleProps[stylePropName] !== "undefined") {
|
|
5156
|
-
stylePropValues[stylePropName] = structuredClone(styleProps[stylePropName]);
|
|
5157
|
-
}
|
|
5158
|
-
});
|
|
5159
|
-
if (defaultVariant.custom_css) {
|
|
5160
|
-
stylePropValues.custom_css = atob(defaultVariant.custom_css.raw);
|
|
5118
|
+
try {
|
|
5119
|
+
const { data } = await httpService7().post(MCP_PROXY_URL6, {
|
|
5120
|
+
tool: "get-page-structure",
|
|
5121
|
+
input: {
|
|
5122
|
+
post_id: resolvedPostId
|
|
5161
5123
|
}
|
|
5162
|
-
}
|
|
5124
|
+
});
|
|
5125
|
+
return {
|
|
5126
|
+
elements: data.data.elements
|
|
5127
|
+
};
|
|
5128
|
+
} catch (error) {
|
|
5129
|
+
throw new Error(getMcpErrorMessage(error, "get-page-structure"));
|
|
5163
5130
|
}
|
|
5164
|
-
return {
|
|
5165
|
-
properties: {
|
|
5166
|
-
...propValues
|
|
5167
|
-
},
|
|
5168
|
-
style: {
|
|
5169
|
-
...stylePropValues
|
|
5170
|
-
},
|
|
5171
|
-
childElements: structuredElements(element)
|
|
5172
|
-
};
|
|
5173
5131
|
}
|
|
5174
5132
|
});
|
|
5175
5133
|
};
|
|
5176
5134
|
|
|
5177
5135
|
// src/mcp/canvas-mcp.ts
|
|
5178
5136
|
var initCanvasMcp = (reg) => {
|
|
5179
|
-
|
|
5137
|
+
Schema3.setDynamicTagNamesResolver(getDynamicTagNamesByCategories);
|
|
5180
5138
|
initWidgetsSchemaResource(reg);
|
|
5181
5139
|
initAvailableWidgetsResource(reg);
|
|
5182
5140
|
initDocumentStructureResource(reg);
|
|
@@ -5185,9 +5143,9 @@ var initCanvasMcp = (reg) => {
|
|
|
5185
5143
|
initEditorStateResource(reg);
|
|
5186
5144
|
initGeneralContextResource(reg);
|
|
5187
5145
|
initBestPracticesResource(reg);
|
|
5188
|
-
initGetElementConfigTool(reg);
|
|
5189
5146
|
initConfigureElementTool(reg);
|
|
5190
5147
|
initBuildCompositionTool(reg);
|
|
5148
|
+
initGetPageStructureTool(reg);
|
|
5191
5149
|
initBreakpointsResource(reg);
|
|
5192
5150
|
};
|
|
5193
5151
|
|
|
@@ -5387,7 +5345,7 @@ function shouldBlock(sourceElements, targetElements) {
|
|
|
5387
5345
|
}
|
|
5388
5346
|
|
|
5389
5347
|
// src/style-commands/paste-style.ts
|
|
5390
|
-
import { getContainer as
|
|
5348
|
+
import { getContainer as getContainer6, getElementSetting, updateElementSettings as updateElementSettings2 } from "@elementor/editor-elements";
|
|
5391
5349
|
import { classesPropTypeUtil } from "@elementor/editor-props";
|
|
5392
5350
|
import {
|
|
5393
5351
|
__privateListenTo as listenTo5,
|
|
@@ -5396,7 +5354,7 @@ import {
|
|
|
5396
5354
|
} from "@elementor/editor-v1-adapters";
|
|
5397
5355
|
|
|
5398
5356
|
// src/utils/command-utils.ts
|
|
5399
|
-
import { getElementLabel as getElementLabel2, getWidgetsCache as
|
|
5357
|
+
import { getElementLabel as getElementLabel2, getWidgetsCache as getWidgetsCache7 } from "@elementor/editor-elements";
|
|
5400
5358
|
import { CLASSES_PROP_KEY } from "@elementor/editor-props";
|
|
5401
5359
|
import { __ as __5 } from "@wordpress/i18n";
|
|
5402
5360
|
function hasAtomicWidgets(args) {
|
|
@@ -5421,7 +5379,7 @@ function getClassesProp(container) {
|
|
|
5421
5379
|
}
|
|
5422
5380
|
function getContainerSchema(container) {
|
|
5423
5381
|
const type = container?.model.get("widgetType") || container?.model.get("elType");
|
|
5424
|
-
const widgetsCache =
|
|
5382
|
+
const widgetsCache = getWidgetsCache7();
|
|
5425
5383
|
const elementType = widgetsCache?.[type];
|
|
5426
5384
|
return elementType?.atomic_props_schema ?? null;
|
|
5427
5385
|
}
|
|
@@ -5441,7 +5399,7 @@ function getTitleForContainers(containers) {
|
|
|
5441
5399
|
import {
|
|
5442
5400
|
createElementStyle as createElementStyle2,
|
|
5443
5401
|
deleteElementStyle,
|
|
5444
|
-
getElementStyles as
|
|
5402
|
+
getElementStyles as getElementStyles2,
|
|
5445
5403
|
updateElementStyle as updateElementStyle2
|
|
5446
5404
|
} from "@elementor/editor-elements";
|
|
5447
5405
|
import { ELEMENTS_STYLES_RESERVED_LABEL } from "@elementor/editor-styles-repository";
|
|
@@ -5456,7 +5414,7 @@ var undoablePasteElementStyle = () => undoable2(
|
|
|
5456
5414
|
if (!classesProp) {
|
|
5457
5415
|
return null;
|
|
5458
5416
|
}
|
|
5459
|
-
const originalStyles =
|
|
5417
|
+
const originalStyles = getElementStyles2(container.id);
|
|
5460
5418
|
const [styleId, styleDef] = Object.entries(originalStyles ?? {})[0] ?? [];
|
|
5461
5419
|
const originalStyle = Object.keys(styleDef ?? {}).length ? styleDef : null;
|
|
5462
5420
|
const revertData = {
|
|
@@ -5540,7 +5498,7 @@ function pasteStyles(args, pasteLocalStyle) {
|
|
|
5540
5498
|
}
|
|
5541
5499
|
const clipboardElements = getClipboardElements(storageKey);
|
|
5542
5500
|
const [clipboardElement] = clipboardElements ?? [];
|
|
5543
|
-
const clipboardContainer =
|
|
5501
|
+
const clipboardContainer = getContainer6(clipboardElement.id);
|
|
5544
5502
|
if (!clipboardElement || !clipboardContainer || !isAtomicWidget(clipboardContainer)) {
|
|
5545
5503
|
return;
|
|
5546
5504
|
}
|
|
@@ -5586,7 +5544,7 @@ import {
|
|
|
5586
5544
|
} from "@elementor/editor-v1-adapters";
|
|
5587
5545
|
|
|
5588
5546
|
// src/style-commands/undoable-actions/reset-element-style.ts
|
|
5589
|
-
import { createElementStyle as createElementStyle3, deleteElementStyle as deleteElementStyle2, getElementStyles as
|
|
5547
|
+
import { createElementStyle as createElementStyle3, deleteElementStyle as deleteElementStyle2, getElementStyles as getElementStyles3 } from "@elementor/editor-elements";
|
|
5590
5548
|
import { ELEMENTS_STYLES_RESERVED_LABEL as ELEMENTS_STYLES_RESERVED_LABEL2 } from "@elementor/editor-styles-repository";
|
|
5591
5549
|
import { undoable as undoable3 } from "@elementor/editor-v1-adapters";
|
|
5592
5550
|
import { __ as __7 } from "@wordpress/i18n";
|
|
@@ -5595,7 +5553,7 @@ var undoableResetElementStyle = () => undoable3(
|
|
|
5595
5553
|
do: ({ containers }) => {
|
|
5596
5554
|
return containers.map((container) => {
|
|
5597
5555
|
const elementId = container.model.get("id");
|
|
5598
|
-
const containerStyles =
|
|
5556
|
+
const containerStyles = getElementStyles3(elementId);
|
|
5599
5557
|
Object.keys(containerStyles ?? {}).forEach(
|
|
5600
5558
|
(styleId) => deleteElementStyle2(elementId, styleId)
|
|
5601
5559
|
);
|
|
@@ -5817,10 +5775,10 @@ function useEscapeOnCanvas(canvasDocument, onEscape) {
|
|
|
5817
5775
|
}
|
|
5818
5776
|
|
|
5819
5777
|
// src/utils/after-render.ts
|
|
5820
|
-
import { getContainer as
|
|
5778
|
+
import { getContainer as getContainer7 } from "@elementor/editor-elements";
|
|
5821
5779
|
function doAfterRender(elementIds, callback) {
|
|
5822
5780
|
const pending = elementIds.map((elementId) => {
|
|
5823
|
-
const view =
|
|
5781
|
+
const view = getContainer7(elementId)?.view;
|
|
5824
5782
|
if (!view || !hasDoAfterRender(view)) {
|
|
5825
5783
|
return void 0;
|
|
5826
5784
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elementor/editor-canvas",
|
|
3
3
|
"description": "Elementor Editor Canvas",
|
|
4
|
-
"version": "4.3.0-
|
|
4
|
+
"version": "4.3.0-1004",
|
|
5
5
|
"private": false,
|
|
6
6
|
"author": "Elementor Team",
|
|
7
7
|
"homepage": "https://elementor.com/",
|
|
@@ -37,26 +37,26 @@
|
|
|
37
37
|
"react-dom": "^18.3.1"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@elementor/editor": "4.3.0-
|
|
41
|
-
"@elementor/editor-controls": "4.3.0-
|
|
42
|
-
"@elementor/editor-documents": "4.3.0-
|
|
43
|
-
"@elementor/editor-elements": "4.3.0-
|
|
44
|
-
"@elementor/editor-interactions": "4.3.0-
|
|
45
|
-
"@elementor/editor-mcp": "4.3.0-
|
|
46
|
-
"@elementor/editor-notifications": "4.3.0-
|
|
47
|
-
"@elementor/editor-props": "4.3.0-
|
|
48
|
-
"@elementor/editor-responsive": "4.3.0-
|
|
49
|
-
"@elementor/editor-styles": "4.3.0-
|
|
50
|
-
"@elementor/editor-styles-repository": "4.3.0-
|
|
51
|
-
"@elementor/editor-ui": "4.3.0-
|
|
52
|
-
"@elementor/editor-v1-adapters": "4.3.0-
|
|
53
|
-
"@elementor/events": "4.3.0-
|
|
54
|
-
"@elementor/http-client": "4.3.0-
|
|
55
|
-
"@elementor/schema": "4.3.0-
|
|
56
|
-
"@elementor/twing": "4.3.0-
|
|
40
|
+
"@elementor/editor": "4.3.0-1004",
|
|
41
|
+
"@elementor/editor-controls": "4.3.0-1004",
|
|
42
|
+
"@elementor/editor-documents": "4.3.0-1004",
|
|
43
|
+
"@elementor/editor-elements": "4.3.0-1004",
|
|
44
|
+
"@elementor/editor-interactions": "4.3.0-1004",
|
|
45
|
+
"@elementor/editor-mcp": "4.3.0-1004",
|
|
46
|
+
"@elementor/editor-notifications": "4.3.0-1004",
|
|
47
|
+
"@elementor/editor-props": "4.3.0-1004",
|
|
48
|
+
"@elementor/editor-responsive": "4.3.0-1004",
|
|
49
|
+
"@elementor/editor-styles": "4.3.0-1004",
|
|
50
|
+
"@elementor/editor-styles-repository": "4.3.0-1004",
|
|
51
|
+
"@elementor/editor-ui": "4.3.0-1004",
|
|
52
|
+
"@elementor/editor-v1-adapters": "4.3.0-1004",
|
|
53
|
+
"@elementor/events": "4.3.0-1004",
|
|
54
|
+
"@elementor/http-client": "4.3.0-1004",
|
|
55
|
+
"@elementor/schema": "4.3.0-1004",
|
|
56
|
+
"@elementor/twing": "4.3.0-1004",
|
|
57
57
|
"@elementor/ui": "1.37.5",
|
|
58
|
-
"@elementor/utils": "4.3.0-
|
|
59
|
-
"@elementor/wp-media": "4.3.0-
|
|
58
|
+
"@elementor/utils": "4.3.0-1004",
|
|
59
|
+
"@elementor/wp-media": "4.3.0-1004",
|
|
60
60
|
"@floating-ui/react": "^0.27.5",
|
|
61
61
|
"@wordpress/i18n": "^5.13.0",
|
|
62
62
|
"dompurify": "^3.2.6"
|
package/src/mcp/canvas-mcp.ts
CHANGED
|
@@ -12,7 +12,7 @@ import { initSelectedElementResource } from './resources/selected-element-resour
|
|
|
12
12
|
import { initWidgetsSchemaResource } from './resources/widgets-schema-resource';
|
|
13
13
|
import { initBuildCompositionTool } from './tools/build-composition/tool';
|
|
14
14
|
import { initConfigureElementTool } from './tools/configure-element/tool';
|
|
15
|
-
import {
|
|
15
|
+
import { initGetPageStructureTool } from './tools/get-page-structure/tool';
|
|
16
16
|
import { getDynamicTagNamesByCategories } from './utils/resolve-dynamic-tag';
|
|
17
17
|
|
|
18
18
|
export const initCanvasMcp = ( reg: MCPRegistryEntry ) => {
|
|
@@ -28,8 +28,8 @@ export const initCanvasMcp = ( reg: MCPRegistryEntry ) => {
|
|
|
28
28
|
initEditorStateResource( reg );
|
|
29
29
|
initGeneralContextResource( reg );
|
|
30
30
|
initBestPracticesResource( reg );
|
|
31
|
-
initGetElementConfigTool( reg );
|
|
32
31
|
initConfigureElementTool( reg );
|
|
33
32
|
initBuildCompositionTool( reg );
|
|
33
|
+
initGetPageStructureTool( reg );
|
|
34
34
|
initBreakpointsResource( reg );
|
|
35
35
|
};
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { getCurrentDocument, reloadCurrentDocument } from '@elementor/editor-documents';
|
|
2
2
|
import { getContainer, selectElement } from '@elementor/editor-elements';
|
|
3
3
|
import { type MCPRegistryEntry } from '@elementor/editor-mcp';
|
|
4
|
-
import {
|
|
4
|
+
import { type HttpResponse, httpService } from '@elementor/http-client';
|
|
5
5
|
import { z } from '@elementor/schema';
|
|
6
6
|
|
|
7
|
+
import { getMcpErrorMessage } from '../../utils/get-mcp-error-message';
|
|
8
|
+
|
|
7
9
|
const MCP_PROXY_URL = 'elementor/v1/mcp-proxy';
|
|
8
10
|
|
|
9
11
|
type BuildCompositionResponse = {
|
|
@@ -15,6 +17,7 @@ type BuildCompositionResponse = {
|
|
|
15
17
|
resolved_xml: string;
|
|
16
18
|
llm_instructions: string;
|
|
17
19
|
warnings?: string[];
|
|
20
|
+
removed_element_ids?: string[];
|
|
18
21
|
};
|
|
19
22
|
|
|
20
23
|
export const initBuildCompositionTool = ( reg: MCPRegistryEntry ) => {
|
|
@@ -56,6 +59,12 @@ export const initBuildCompositionTool = ( reg: MCPRegistryEntry ) => {
|
|
|
56
59
|
.string()
|
|
57
60
|
.optional()
|
|
58
61
|
.describe( "ID of the parent container. Omit or pass 'document' to insert at document root." ),
|
|
62
|
+
mode: z
|
|
63
|
+
.enum( [ 'append', 'replace_children' ] )
|
|
64
|
+
.optional()
|
|
65
|
+
.describe(
|
|
66
|
+
"'append' (default) inserts under parentId; 'replace_children' removes existing direct children of parentId first, then inserts."
|
|
67
|
+
),
|
|
59
68
|
dryRun: z
|
|
60
69
|
.boolean()
|
|
61
70
|
.optional()
|
|
@@ -68,8 +77,9 @@ export const initBuildCompositionTool = ( reg: MCPRegistryEntry ) => {
|
|
|
68
77
|
resolvedXml: z.string(),
|
|
69
78
|
llmInstructions: z.string(),
|
|
70
79
|
warnings: z.array( z.string() ).optional(),
|
|
80
|
+
removedElementIds: z.array( z.string() ).optional(),
|
|
71
81
|
},
|
|
72
|
-
handler: async ( { xmlStructure, elementConfig, style, parentId, dryRun } ) => {
|
|
82
|
+
handler: async ( { xmlStructure, elementConfig, style, parentId, mode, dryRun } ) => {
|
|
73
83
|
const document = getCurrentDocument();
|
|
74
84
|
|
|
75
85
|
if ( ! document?.id ) {
|
|
@@ -85,6 +95,7 @@ export const initBuildCompositionTool = ( reg: MCPRegistryEntry ) => {
|
|
|
85
95
|
element_config: elementConfig ?? {},
|
|
86
96
|
style: style ?? {},
|
|
87
97
|
parent_id: parentId ?? 'document',
|
|
98
|
+
mode: mode ?? 'append',
|
|
88
99
|
dry_run: dryRun ?? false,
|
|
89
100
|
},
|
|
90
101
|
} );
|
|
@@ -109,25 +120,11 @@ export const initBuildCompositionTool = ( reg: MCPRegistryEntry ) => {
|
|
|
109
120
|
resolvedXml: data.data.resolved_xml,
|
|
110
121
|
llmInstructions: data.data.llm_instructions,
|
|
111
122
|
warnings: data.data.warnings,
|
|
123
|
+
removedElementIds: data.data.removed_element_ids,
|
|
112
124
|
};
|
|
113
125
|
} catch ( error ) {
|
|
114
|
-
throw new Error(
|
|
126
|
+
throw new Error( getMcpErrorMessage( error, 'build-composition' ) );
|
|
115
127
|
}
|
|
116
128
|
},
|
|
117
129
|
} );
|
|
118
130
|
};
|
|
119
|
-
|
|
120
|
-
function getErrorMessage( error: unknown ): string {
|
|
121
|
-
if ( error instanceof AxiosError ) {
|
|
122
|
-
const data = error.response?.data as { message?: string; code?: string } | undefined;
|
|
123
|
-
if ( data?.message ) {
|
|
124
|
-
return data.code ? `${ data.code }: ${ data.message }` : data.message;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
if ( error instanceof Error ) {
|
|
129
|
-
return error.message;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
return 'build-composition failed with an unknown error.';
|
|
133
|
-
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { getCurrentDocument } from '@elementor/editor-documents';
|
|
2
|
+
import { type MCPRegistryEntry } from '@elementor/editor-mcp';
|
|
3
|
+
import { type HttpResponse, httpService } from '@elementor/http-client';
|
|
4
|
+
import { z } from '@elementor/schema';
|
|
5
|
+
|
|
6
|
+
import { getMcpErrorMessage } from '../../utils/get-mcp-error-message';
|
|
7
|
+
|
|
8
|
+
const MCP_PROXY_URL = 'elementor/v1/mcp-proxy';
|
|
9
|
+
|
|
10
|
+
type GetPageStructureResponse = {
|
|
11
|
+
elements: Array< Record< string, unknown > >;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export const initGetPageStructureTool = ( reg: MCPRegistryEntry ) => {
|
|
15
|
+
const { addTool } = reg;
|
|
16
|
+
|
|
17
|
+
addTool( {
|
|
18
|
+
name: 'get-page-structure',
|
|
19
|
+
description:
|
|
20
|
+
'Returns the Elementor element tree (widgets, containers, and nested content) for a post or page. ' +
|
|
21
|
+
'If no postId is provided, uses the currently open document. Only works for posts saved with Elementor.',
|
|
22
|
+
schema: {
|
|
23
|
+
postId: z
|
|
24
|
+
.number()
|
|
25
|
+
.optional()
|
|
26
|
+
.describe(
|
|
27
|
+
'WordPress post ID of the Elementor document. If omitted, uses the currently open document.'
|
|
28
|
+
),
|
|
29
|
+
},
|
|
30
|
+
outputSchema: {
|
|
31
|
+
elements: z.array( z.any() ).describe( 'Root-level Elementor elements for the document.' ),
|
|
32
|
+
},
|
|
33
|
+
handler: async ( { postId } ) => {
|
|
34
|
+
const resolvedPostId = postId ?? getCurrentDocument()?.id;
|
|
35
|
+
|
|
36
|
+
if ( ! resolvedPostId ) {
|
|
37
|
+
throw new Error( 'No post ID provided and no active document found.' );
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
try {
|
|
41
|
+
const { data } = await httpService().post< HttpResponse< GetPageStructureResponse > >( MCP_PROXY_URL, {
|
|
42
|
+
tool: 'get-page-structure',
|
|
43
|
+
input: {
|
|
44
|
+
post_id: resolvedPostId,
|
|
45
|
+
},
|
|
46
|
+
} );
|
|
47
|
+
|
|
48
|
+
return {
|
|
49
|
+
elements: data.data.elements,
|
|
50
|
+
};
|
|
51
|
+
} catch ( error ) {
|
|
52
|
+
throw new Error( getMcpErrorMessage( error, 'get-page-structure' ) );
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
} );
|
|
56
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { AxiosError } from '@elementor/http-client';
|
|
2
|
+
|
|
3
|
+
export function getMcpErrorMessage( error: unknown, toolName: string ): string {
|
|
4
|
+
if ( error instanceof AxiosError ) {
|
|
5
|
+
const data = error.response?.data as { message?: string; code?: string } | undefined;
|
|
6
|
+
if ( data?.message ) {
|
|
7
|
+
return data.code ? `${ data.code }: ${ data.message }` : data.message;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
if ( error instanceof Error ) {
|
|
12
|
+
return error.message;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
return `${ toolName } failed with an unknown error.`;
|
|
16
|
+
}
|
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
import { getContainer, getElementStyles, getWidgetsCache, type V1Element } from '@elementor/editor-elements';
|
|
2
|
-
import { type MCPRegistryEntry } from '@elementor/editor-mcp';
|
|
3
|
-
import { type PropValue, Schema } from '@elementor/editor-props';
|
|
4
|
-
import { z } from '@elementor/schema';
|
|
5
|
-
|
|
6
|
-
const schema = {
|
|
7
|
-
elementId: z.string(),
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
const outputSchema = {
|
|
11
|
-
properties: z
|
|
12
|
-
.record( z.string(), z.any() )
|
|
13
|
-
.describe( 'A record mapping PropTypes to their corresponding PropValues' ),
|
|
14
|
-
style: z
|
|
15
|
-
.record( z.string(), z.any() )
|
|
16
|
-
.describe( 'A record mapping StyleSchema properties to their corresponding PropValues' ),
|
|
17
|
-
childElements: z
|
|
18
|
-
.array(
|
|
19
|
-
z.object( {
|
|
20
|
-
id: z.string(),
|
|
21
|
-
elementType: z.string(),
|
|
22
|
-
childElements: z
|
|
23
|
-
.array( z.any() )
|
|
24
|
-
.describe( 'An array of child element IDs, when applicable, same structure recursively' ),
|
|
25
|
-
} )
|
|
26
|
-
)
|
|
27
|
-
.describe( 'An array of child element IDs, when applicable, with recursive structure' ),
|
|
28
|
-
};
|
|
29
|
-
type ElementStructure = {
|
|
30
|
-
id: string;
|
|
31
|
-
elementType: string;
|
|
32
|
-
childElements: ElementStructure[];
|
|
33
|
-
};
|
|
34
|
-
const structuredElements = ( element: V1Element ): ElementStructure[] => {
|
|
35
|
-
const children = element.children || [];
|
|
36
|
-
return children.map( ( child ) => {
|
|
37
|
-
return {
|
|
38
|
-
id: child.id,
|
|
39
|
-
elementType: child.model.get( 'elType' ) || child.model.get( 'widgetType' ) || 'unknown',
|
|
40
|
-
childElements: structuredElements( child ),
|
|
41
|
-
};
|
|
42
|
-
} );
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
export const initGetElementConfigTool = ( reg: MCPRegistryEntry ) => {
|
|
46
|
-
const { addTool } = reg;
|
|
47
|
-
|
|
48
|
-
addTool( {
|
|
49
|
-
name: 'get-element-configuration-values',
|
|
50
|
-
description: "Retrieve the element's configuration PropValues for a specific element by unique ID.",
|
|
51
|
-
schema,
|
|
52
|
-
outputSchema,
|
|
53
|
-
handler: async ( { elementId } ) => {
|
|
54
|
-
const element = getContainer( elementId );
|
|
55
|
-
if ( ! element ) {
|
|
56
|
-
throw new Error( `Element with ID ${ elementId } not found.` );
|
|
57
|
-
}
|
|
58
|
-
const elementType = element.model.get( 'widgetType' ) || element.model.get( 'elType' ) || '';
|
|
59
|
-
const widgetData = getWidgetsCache()?.[ elementType ];
|
|
60
|
-
if ( ! widgetData ) {
|
|
61
|
-
throw new Error(
|
|
62
|
-
`Unknown element type: ${ elementType }. Check the available-widgets resource for valid types.`
|
|
63
|
-
);
|
|
64
|
-
}
|
|
65
|
-
if ( ! widgetData.atomic_props_schema ) {
|
|
66
|
-
throw new Error(
|
|
67
|
-
`This tool does not support V3 elements. Please use the elementor-v3-mcp tools instead for element type: ${ elementType }`
|
|
68
|
-
);
|
|
69
|
-
}
|
|
70
|
-
const elementRawSettings = element.settings;
|
|
71
|
-
const propSchema = getWidgetsCache()?.[ elementType ]?.atomic_props_schema;
|
|
72
|
-
|
|
73
|
-
if ( ! elementRawSettings || ! propSchema ) {
|
|
74
|
-
throw new Error( `No settings or prop schema found for element ID: ${ elementId }` );
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
const propValues: Record< string, PropValue > = {};
|
|
78
|
-
const stylePropValues: Record< string, PropValue > = {};
|
|
79
|
-
|
|
80
|
-
Schema.configurableKeys( propSchema ).forEach( ( key ) => {
|
|
81
|
-
propValues[ key ] = structuredClone( elementRawSettings.get( key ) );
|
|
82
|
-
} );
|
|
83
|
-
const elementStyles = getElementStyles( elementId ) || {};
|
|
84
|
-
const localStyle = Object.values( elementStyles ).find( ( style ) => style.label === 'local' );
|
|
85
|
-
|
|
86
|
-
if ( localStyle ) {
|
|
87
|
-
const defaultVariant = localStyle.variants.find(
|
|
88
|
-
( variant ) => variant.meta.breakpoint === 'desktop' && ! variant.meta.state
|
|
89
|
-
);
|
|
90
|
-
if ( defaultVariant ) {
|
|
91
|
-
const styleProps = defaultVariant.props || {};
|
|
92
|
-
Object.keys( styleProps ).forEach( ( stylePropName ) => {
|
|
93
|
-
if ( typeof styleProps[ stylePropName ] !== 'undefined' ) {
|
|
94
|
-
stylePropValues[ stylePropName ] = structuredClone( styleProps[ stylePropName ] );
|
|
95
|
-
}
|
|
96
|
-
} );
|
|
97
|
-
if ( defaultVariant.custom_css ) {
|
|
98
|
-
stylePropValues.custom_css = atob( defaultVariant.custom_css.raw );
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
return {
|
|
104
|
-
properties: {
|
|
105
|
-
...propValues,
|
|
106
|
-
},
|
|
107
|
-
style: {
|
|
108
|
-
...stylePropValues,
|
|
109
|
-
},
|
|
110
|
-
childElements: structuredElements( element ),
|
|
111
|
-
};
|
|
112
|
-
},
|
|
113
|
-
} );
|
|
114
|
-
};
|