@elementor/editor-canvas 4.1.0-838 → 4.1.0-beta2
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 +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +151 -76
- package/dist/index.mjs +137 -61
- package/package.json +18 -18
- package/src/composition-builder/composition-builder.ts +35 -18
- package/src/init.tsx +7 -1
- package/src/mcp/canvas-mcp.ts +0 -9
- package/src/mcp/tools/build-composition/prompt.ts +2 -0
- package/src/mcp/tools/build-composition/tool.ts +40 -18
- package/src/mcp/tools/configure-element/prompt.ts +47 -14
- package/src/mcp/tools/configure-element/tool.ts +17 -3
- package/src/mcp/utils/__tests__/do-update-element-property.test.ts +135 -0
- package/src/mcp/utils/do-update-element-property.ts +10 -0
- package/src/mcp/utils/element-data-util.ts +4 -0
- package/src/sync/global-styles-imported-event.ts +1 -1
package/dist/index.mjs
CHANGED
|
@@ -64,6 +64,9 @@ function isWidgetAvailableForLLM(config) {
|
|
|
64
64
|
if (config.meta?.llm_support === false) {
|
|
65
65
|
return false;
|
|
66
66
|
}
|
|
67
|
+
if (config.title === "Component") {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
67
70
|
if (config.atomic_props_schema) {
|
|
68
71
|
return true;
|
|
69
72
|
}
|
|
@@ -3853,7 +3856,7 @@ function getElementDisplayName(container) {
|
|
|
3853
3856
|
import { getCurrentDocument } from "@elementor/editor-documents";
|
|
3854
3857
|
import {
|
|
3855
3858
|
createElement as createElement8,
|
|
3856
|
-
deleteElement,
|
|
3859
|
+
deleteElement as deleteElement2,
|
|
3857
3860
|
getContainer as getContainer5,
|
|
3858
3861
|
getWidgetsCache as getWidgetsCache9
|
|
3859
3862
|
} from "@elementor/editor-elements";
|
|
@@ -3861,6 +3864,7 @@ import {
|
|
|
3861
3864
|
// src/composition-builder/composition-builder.ts
|
|
3862
3865
|
import {
|
|
3863
3866
|
createElement as createElement7,
|
|
3867
|
+
deleteElement,
|
|
3864
3868
|
generateElementId as generateElementId2,
|
|
3865
3869
|
getContainer as getContainer4,
|
|
3866
3870
|
getWidgetsCache as getWidgetsCache8
|
|
@@ -3876,6 +3880,7 @@ import {
|
|
|
3876
3880
|
} from "@elementor/editor-elements";
|
|
3877
3881
|
import { getPropSchemaFromCache, Schema as Schema2 } from "@elementor/editor-props";
|
|
3878
3882
|
import { getStylesSchema as getStylesSchema3 } from "@elementor/editor-styles";
|
|
3883
|
+
import { __privateRunCommandSync as runCommandSync2 } from "@elementor/editor-v1-adapters";
|
|
3879
3884
|
function resolvePropValue(value, forceKey) {
|
|
3880
3885
|
const Utils = window.elementorV2.editorVariables.Utils;
|
|
3881
3886
|
return Schema2.adjustLlmPropValueSchema(value, {
|
|
@@ -3977,6 +3982,15 @@ var doUpdateElementProperty = (params) => {
|
|
|
3977
3982
|
}
|
|
3978
3983
|
const propKey = elementPropSchema[propertyName].key;
|
|
3979
3984
|
const value = resolvePropValue(propertyValue, propKey);
|
|
3985
|
+
const { valid, jsonSchema } = Schema2.validatePropValue(elementPropSchema[propertyName], propertyValue);
|
|
3986
|
+
if (!valid) {
|
|
3987
|
+
throw new Error(
|
|
3988
|
+
`Invalid PropValue for elementId: ${elementId}. PropKey: ${propKey}, PropValue: ${JSON.stringify(
|
|
3989
|
+
propertyValue
|
|
3990
|
+
)}
|
|
3991
|
+
Expected Schema: ${jsonSchema}`
|
|
3992
|
+
);
|
|
3993
|
+
}
|
|
3980
3994
|
updateElementSettings({
|
|
3981
3995
|
id: elementId,
|
|
3982
3996
|
props: {
|
|
@@ -3984,6 +3998,7 @@ var doUpdateElementProperty = (params) => {
|
|
|
3984
3998
|
},
|
|
3985
3999
|
withHistory: false
|
|
3986
4000
|
});
|
|
4001
|
+
runCommandSync2("document/save/set-is-modified", { status: true }, { internal: true });
|
|
3987
4002
|
};
|
|
3988
4003
|
|
|
3989
4004
|
// src/mcp/utils/validate-input.ts
|
|
@@ -4079,6 +4094,7 @@ var CompositionBuilder = class _CompositionBuilder {
|
|
|
4079
4094
|
rootContainers = [];
|
|
4080
4095
|
api = {
|
|
4081
4096
|
createElement: createElement7,
|
|
4097
|
+
deleteElement,
|
|
4082
4098
|
getWidgetsCache: getWidgetsCache8,
|
|
4083
4099
|
generateElementId: generateElementId2,
|
|
4084
4100
|
getContainer: getContainer4,
|
|
@@ -4129,7 +4145,8 @@ var CompositionBuilder = class _CompositionBuilder {
|
|
|
4129
4145
|
elements: children,
|
|
4130
4146
|
editor_settings: {
|
|
4131
4147
|
title: node.getAttribute("configuration-id") ?? void 0
|
|
4132
|
-
}
|
|
4148
|
+
},
|
|
4149
|
+
elType: "widget"
|
|
4133
4150
|
};
|
|
4134
4151
|
if (isWidget) {
|
|
4135
4152
|
return { ...base, elType: "widget", widgetType: elementTag };
|
|
@@ -4161,12 +4178,6 @@ var CompositionBuilder = class _CompositionBuilder {
|
|
|
4161
4178
|
}
|
|
4162
4179
|
return errors;
|
|
4163
4180
|
}
|
|
4164
|
-
findSchemaForNode(node) {
|
|
4165
|
-
const widgetsCache = this.api.getWidgetsCache() || {};
|
|
4166
|
-
const widgetType = node.tagName;
|
|
4167
|
-
const widgetData = widgetsCache[widgetType]?.atomic_props_schema;
|
|
4168
|
-
return widgetData || null;
|
|
4169
|
-
}
|
|
4170
4181
|
matchNodeByConfigId(configId) {
|
|
4171
4182
|
const node = this.xml.querySelector(`[configuration-id="${configId}"]`);
|
|
4172
4183
|
if (!node) {
|
|
@@ -4288,13 +4299,24 @@ ${childTypeErrors.join("\n")}`);
|
|
|
4288
4299
|
const children = Array.from(this.xml.children);
|
|
4289
4300
|
for (const childNode of children) {
|
|
4290
4301
|
const modelTree = this.buildModelTree(childNode, widgetsCache);
|
|
4291
|
-
|
|
4292
|
-
|
|
4293
|
-
|
|
4294
|
-
|
|
4295
|
-
|
|
4296
|
-
|
|
4297
|
-
|
|
4302
|
+
try {
|
|
4303
|
+
const newElement = this.api.createElement({
|
|
4304
|
+
container: rootContainer,
|
|
4305
|
+
model: modelTree,
|
|
4306
|
+
options: { useHistory: false }
|
|
4307
|
+
});
|
|
4308
|
+
this.rootContainers.push(newElement);
|
|
4309
|
+
await this.awaitViewRender(newElement);
|
|
4310
|
+
} catch (e) {
|
|
4311
|
+
const attemptToRestoreInvalidContainer = this.api.getContainer(modelTree.id);
|
|
4312
|
+
if (attemptToRestoreInvalidContainer) {
|
|
4313
|
+
this.api.deleteElement({
|
|
4314
|
+
container: attemptToRestoreInvalidContainer,
|
|
4315
|
+
options: { useHistory: false }
|
|
4316
|
+
});
|
|
4317
|
+
}
|
|
4318
|
+
throw e;
|
|
4319
|
+
}
|
|
4298
4320
|
}
|
|
4299
4321
|
const { configErrors, styleErrors, invalidStyles } = await this.applyProperties();
|
|
4300
4322
|
return {
|
|
@@ -4318,6 +4340,7 @@ function getCompositionTargetContainer(documentContainer, documentType) {
|
|
|
4318
4340
|
|
|
4319
4341
|
// src/mcp/tools/build-composition/prompt.ts
|
|
4320
4342
|
import { toolPrompts } from "@elementor/editor-mcp";
|
|
4343
|
+
var BUILD_COMPOSITIONS_GUIDE_URI = "elementor://canvas/tools/build-compositions-guide";
|
|
4321
4344
|
var generatePrompt = () => {
|
|
4322
4345
|
const buildCompositionsToolPrompt = toolPrompts("build-compositions");
|
|
4323
4346
|
buildCompositionsToolPrompt.description(`
|
|
@@ -4499,12 +4522,25 @@ var outputSchema = {
|
|
|
4499
4522
|
|
|
4500
4523
|
// src/mcp/tools/build-composition/tool.ts
|
|
4501
4524
|
var initBuildCompositionsTool = (reg) => {
|
|
4502
|
-
const { addTool } = reg;
|
|
4525
|
+
const { addTool, resource } = reg;
|
|
4526
|
+
resource(
|
|
4527
|
+
"build-compositions-guide",
|
|
4528
|
+
BUILD_COMPOSITIONS_GUIDE_URI,
|
|
4529
|
+
{
|
|
4530
|
+
title: "Build Compositions Guide",
|
|
4531
|
+
description: "Detailed guide for using the build-compositions tool",
|
|
4532
|
+
mimeType: "text/plain"
|
|
4533
|
+
},
|
|
4534
|
+
async (uri) => ({
|
|
4535
|
+
contents: [{ uri: uri.href, mimeType: "text/plain", text: generatePrompt() }]
|
|
4536
|
+
})
|
|
4537
|
+
);
|
|
4503
4538
|
addTool({
|
|
4504
4539
|
name: "build-compositions",
|
|
4505
|
-
description:
|
|
4540
|
+
description: "Build V4 element compositions on the Elementor canvas. Read the guide resource before use.",
|
|
4506
4541
|
schema: inputSchema,
|
|
4507
4542
|
requiredResources: [
|
|
4543
|
+
{ description: "Build compositions guide", uri: BUILD_COMPOSITIONS_GUIDE_URI },
|
|
4508
4544
|
{ description: "Widgets schema", uri: WIDGET_SCHEMA_URI },
|
|
4509
4545
|
{ description: "Styles schema", uri: STYLE_SCHEMA_URI },
|
|
4510
4546
|
{ description: "Global Classes", uri: "elementor://global-classes" },
|
|
@@ -4528,35 +4564,44 @@ var initBuildCompositionsTool = (reg) => {
|
|
|
4528
4564
|
try {
|
|
4529
4565
|
const compositionBuilder = CompositionBuilder.fromXMLString(xmlStructure, {
|
|
4530
4566
|
createElement: createElement8,
|
|
4567
|
+
deleteElement: deleteElement2,
|
|
4531
4568
|
getWidgetsCache: getWidgetsCache9
|
|
4532
4569
|
});
|
|
4533
4570
|
compositionBuilder.setElementConfig(elementConfig);
|
|
4534
4571
|
compositionBuilder.setStylesConfig(stylesConfig);
|
|
4535
4572
|
compositionBuilder.setCustomCSS(customCSS);
|
|
4536
|
-
const {
|
|
4573
|
+
const {
|
|
4574
|
+
invalidStyles,
|
|
4575
|
+
configErrors,
|
|
4576
|
+
rootContainers: generatedRootContainers
|
|
4577
|
+
} = await compositionBuilder.build(targetContainer);
|
|
4537
4578
|
rootContainers.push(...generatedRootContainers);
|
|
4538
4579
|
generatedXML = new XMLSerializer().serializeToString(compositionBuilder.getXML());
|
|
4539
|
-
|
|
4540
|
-
|
|
4541
|
-
|
|
4542
|
-
|
|
4543
|
-
|
|
4544
|
-
|
|
4545
|
-
|
|
4546
|
-
|
|
4547
|
-
|
|
4548
|
-
|
|
4549
|
-
|
|
4550
|
-
|
|
4551
|
-
|
|
4580
|
+
if (configErrors.length) {
|
|
4581
|
+
errors.push(...configErrors.map((msg) => new Error(msg)));
|
|
4582
|
+
} else {
|
|
4583
|
+
Object.entries(invalidStyles).forEach(([elementId, rawCssRules]) => {
|
|
4584
|
+
const customCss = {
|
|
4585
|
+
value: rawCssRules.join(";\n")
|
|
4586
|
+
};
|
|
4587
|
+
doUpdateElementProperty({
|
|
4588
|
+
elementId,
|
|
4589
|
+
propertyName: "_styles",
|
|
4590
|
+
propertyValue: {
|
|
4591
|
+
_styles: {
|
|
4592
|
+
custom_css: customCss
|
|
4593
|
+
}
|
|
4594
|
+
},
|
|
4595
|
+
elementType: "widget"
|
|
4596
|
+
});
|
|
4552
4597
|
});
|
|
4553
|
-
}
|
|
4598
|
+
}
|
|
4554
4599
|
} catch (error) {
|
|
4555
4600
|
errors.push(error);
|
|
4556
4601
|
}
|
|
4557
4602
|
if (errors.length) {
|
|
4558
4603
|
rootContainers.forEach((rootContainer) => {
|
|
4559
|
-
|
|
4604
|
+
deleteElement2({
|
|
4560
4605
|
container: rootContainer,
|
|
4561
4606
|
options: { useHistory: false }
|
|
4562
4607
|
});
|
|
@@ -4632,7 +4677,12 @@ function assertCompositionXmlUsesV4WidgetsOnly(xmlStructure) {
|
|
|
4632
4677
|
import { getWidgetsCache as getWidgetsCache10 } from "@elementor/editor-elements";
|
|
4633
4678
|
|
|
4634
4679
|
// src/mcp/tools/configure-element/prompt.ts
|
|
4635
|
-
|
|
4680
|
+
import { toolPrompts as toolPrompts2 } from "@elementor/editor-mcp";
|
|
4681
|
+
var CONFIGURE_ELEMENT_GUIDE_URI = "elementor://canvas/tools/configure-element-guide";
|
|
4682
|
+
var generatePrompt2 = () => {
|
|
4683
|
+
const configureElementToolPrompt = toolPrompts2("configure-element");
|
|
4684
|
+
configureElementToolPrompt.description(`
|
|
4685
|
+
Configure an existing element on the page.
|
|
4636
4686
|
|
|
4637
4687
|
# **CRITICAL - REQUIRED INFORMATION (Must read before using this tool)**
|
|
4638
4688
|
1. [${WIDGET_SCHEMA_URI}]
|
|
@@ -4647,12 +4697,6 @@ Before using this tool, check the definitions of the elements PropTypes at the r
|
|
|
4647
4697
|
All widgets share a common _style property for styling, which uses the common styles schema.
|
|
4648
4698
|
Retrieve and check the common styles schema at the resource list "styles-schema" at editor-canvas__elementor://styles/schema/{category}
|
|
4649
4699
|
|
|
4650
|
-
# Parameters
|
|
4651
|
-
- propertiesToChange: An object containing the properties to change, with their new values. MANDATORY. When updating a style only, provide an empty object.
|
|
4652
|
-
- stylePropertiesToChange: An object containing the style properties to change, with their new values. OPTIONAL
|
|
4653
|
-
- elementId: The ID of the element to configure. MANDATORY
|
|
4654
|
-
- elementType: The type of the element to configure (i.e. e-heading, e-button). MANDATORY
|
|
4655
|
-
|
|
4656
4700
|
# When to use this tool
|
|
4657
4701
|
When a user requires to change anything in an element, such as updating text, colors, sizes, or other configurable properties.
|
|
4658
4702
|
This tool handles elements of type "widget".
|
|
@@ -4681,7 +4725,7 @@ You can use multiple property changes at once by providing multiple entries in t
|
|
|
4681
4725
|
Some properties are nested, use the root property name, then objects with nested values inside, as the complete schema suggests.
|
|
4682
4726
|
|
|
4683
4727
|
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
|
|
4728
|
+
Make sure you have the "styles-schema" resources available to retrieve the common styles schema.
|
|
4685
4729
|
|
|
4686
4730
|
# How to configure elements
|
|
4687
4731
|
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.
|
|
@@ -4689,8 +4733,21 @@ For styleProperties, use the style schema provided, as it also uses the PropType
|
|
|
4689
4733
|
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.
|
|
4690
4734
|
|
|
4691
4735
|
Use the EXACT "PROP-TYPE" Schema given, and ALWAYS include the "key" property from the original configuration for every property you are changing.
|
|
4692
|
-
|
|
4693
|
-
|
|
4736
|
+
`);
|
|
4737
|
+
configureElementToolPrompt.parameter("elementId", "The ID of the element to configure. MANDATORY.");
|
|
4738
|
+
configureElementToolPrompt.parameter(
|
|
4739
|
+
"elementType",
|
|
4740
|
+
"The type of the element to configure (i.e. e-heading, e-button). MANDATORY."
|
|
4741
|
+
);
|
|
4742
|
+
configureElementToolPrompt.parameter(
|
|
4743
|
+
"propertiesToChange",
|
|
4744
|
+
"An object containing the properties to change, with their new values. MANDATORY. When updating a style only, provide an empty object."
|
|
4745
|
+
);
|
|
4746
|
+
configureElementToolPrompt.parameter(
|
|
4747
|
+
"stylePropertiesToChange",
|
|
4748
|
+
"An object containing the style properties to change, with their new values. OPTIONAL."
|
|
4749
|
+
);
|
|
4750
|
+
configureElementToolPrompt.example(`
|
|
4694
4751
|
\`\`\`json
|
|
4695
4752
|
{
|
|
4696
4753
|
propertiesToChange: {
|
|
@@ -4706,7 +4763,7 @@ Use the EXACT "PROP-TYPE" Schema given, and ALWAYS include the "key" property fr
|
|
|
4706
4763
|
},
|
|
4707
4764
|
stylePropertiesToChange: {
|
|
4708
4765
|
'line-height': {
|
|
4709
|
-
$$type: 'size',
|
|
4766
|
+
$$type: 'size',
|
|
4710
4767
|
value: {
|
|
4711
4768
|
size: {
|
|
4712
4769
|
$$type: 'number',
|
|
@@ -4723,11 +4780,20 @@ Use the EXACT "PROP-TYPE" Schema given, and ALWAYS include the "key" property fr
|
|
|
4723
4780
|
elementType: 'element-type'
|
|
4724
4781
|
};
|
|
4725
4782
|
\`\`\`
|
|
4783
|
+
`);
|
|
4784
|
+
configureElementToolPrompt.instruction(
|
|
4785
|
+
"The $$type property is MANDATORY for every value; it is required to parse the value and apply application-level effects."
|
|
4786
|
+
);
|
|
4787
|
+
configureElementToolPrompt.instruction(`
|
|
4788
|
+
V4 only: If MCP fails, give manual steps using V4 UI.
|
|
4726
4789
|
|
|
4727
|
-
|
|
4728
|
-
|
|
4729
|
-
|
|
4730
|
-
|
|
4790
|
+
V4 Editor structure:
|
|
4791
|
+
Panel tabs: General (\u2192 Settings section: ID, Tag, Link), Style, Interactions.
|
|
4792
|
+
NO Advanced tab. Never mention Advanced tab.
|
|
4793
|
+
`);
|
|
4794
|
+
return configureElementToolPrompt.prompt();
|
|
4795
|
+
};
|
|
4796
|
+
var CONFIGURE_ELEMENT_GUIDE_TEXT = generatePrompt2();
|
|
4731
4797
|
|
|
4732
4798
|
// src/mcp/tools/configure-element/schema.ts
|
|
4733
4799
|
import { z as z2 } from "@elementor/schema";
|
|
@@ -4753,15 +4819,28 @@ var outputSchema2 = {
|
|
|
4753
4819
|
|
|
4754
4820
|
// src/mcp/tools/configure-element/tool.ts
|
|
4755
4821
|
var initConfigureElementTool = (reg) => {
|
|
4756
|
-
const { addTool } = reg;
|
|
4822
|
+
const { addTool, resource } = reg;
|
|
4823
|
+
resource(
|
|
4824
|
+
"configure-element-guide",
|
|
4825
|
+
CONFIGURE_ELEMENT_GUIDE_URI,
|
|
4826
|
+
{
|
|
4827
|
+
title: "Configure Element Guide",
|
|
4828
|
+
description: "Detailed guide for using the configure-element tool",
|
|
4829
|
+
mimeType: "text/plain"
|
|
4830
|
+
},
|
|
4831
|
+
async (uri) => ({
|
|
4832
|
+
contents: [{ uri: uri.href, mimeType: "text/plain", text: generatePrompt2() }]
|
|
4833
|
+
})
|
|
4834
|
+
);
|
|
4757
4835
|
addTool({
|
|
4758
4836
|
name: "configure-element",
|
|
4759
|
-
description:
|
|
4837
|
+
description: "Configure an existing V4 element's properties and styles. Read the guide resource before use.",
|
|
4760
4838
|
schema: inputSchema2,
|
|
4761
4839
|
outputSchema: outputSchema2,
|
|
4762
4840
|
requiredResources: [
|
|
4763
4841
|
{ description: "Widgets schema", uri: WIDGET_SCHEMA_URI },
|
|
4764
|
-
{ description: "Styles schema", uri: STYLE_SCHEMA_URI }
|
|
4842
|
+
{ description: "Styles schema", uri: STYLE_SCHEMA_URI },
|
|
4843
|
+
{ description: "Configure element guide", uri: CONFIGURE_ELEMENT_GUIDE_URI }
|
|
4765
4844
|
],
|
|
4766
4845
|
modelPreferences: {
|
|
4767
4846
|
hints: [{ name: "claude-sonnet-4-5" }],
|
|
@@ -4959,15 +5038,6 @@ var initGetElementConfigTool = (reg) => {
|
|
|
4959
5038
|
|
|
4960
5039
|
// src/mcp/canvas-mcp.ts
|
|
4961
5040
|
var initCanvasMcp = (reg) => {
|
|
4962
|
-
const { setMCPDescription } = reg;
|
|
4963
|
-
setMCPDescription(
|
|
4964
|
-
`Everything related to V4 ( Atomic ) canvas.
|
|
4965
|
-
# Canvas workflow for new compositions
|
|
4966
|
-
- Configure elements settings and styles
|
|
4967
|
-
- Build compositions/sections out of V4 atomic elements using context aware designs using the website resources
|
|
4968
|
-
- Get and retrieve element configuration values
|
|
4969
|
-
`
|
|
4970
|
-
);
|
|
4971
5041
|
initWidgetsSchemaResource(reg);
|
|
4972
5042
|
initAvailableWidgetsResource(reg);
|
|
4973
5043
|
initDocumentStructureResource(reg);
|
|
@@ -5479,7 +5549,13 @@ function init() {
|
|
|
5479
5549
|
});
|
|
5480
5550
|
initCanvasMcp(
|
|
5481
5551
|
getMCPByDomain("canvas", {
|
|
5482
|
-
instructions:
|
|
5552
|
+
instructions: `Everything related to V4 ( Atomic ) canvas.
|
|
5553
|
+
# Canvas workflow for new compositions
|
|
5554
|
+
- Configure elements settings and styles
|
|
5555
|
+
- Build compositions/sections out of V4 atomic elements using context aware designs using the website resources
|
|
5556
|
+
- Get and retrieve element configuration values
|
|
5557
|
+
`,
|
|
5558
|
+
docs: mcpDescription
|
|
5483
5559
|
})
|
|
5484
5560
|
);
|
|
5485
5561
|
initTabsModelExtensions();
|
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.1.0-
|
|
4
|
+
"version": "4.1.0-beta2",
|
|
5
5
|
"private": false,
|
|
6
6
|
"author": "Elementor Team",
|
|
7
7
|
"homepage": "https://elementor.com/",
|
|
@@ -37,25 +37,25 @@
|
|
|
37
37
|
"react-dom": "^18.3.1"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@elementor/editor": "4.1.0-
|
|
40
|
+
"@elementor/editor": "4.1.0-beta2",
|
|
41
41
|
"dompurify": "^3.2.6",
|
|
42
|
-
"@elementor/editor-controls": "4.1.0-
|
|
43
|
-
"@elementor/editor-documents": "4.1.0-
|
|
44
|
-
"@elementor/editor-elements": "4.1.0-
|
|
45
|
-
"@elementor/editor-interactions": "4.1.0-
|
|
46
|
-
"@elementor/editor-mcp": "4.1.0-
|
|
47
|
-
"@elementor/editor-notifications": "4.1.0-
|
|
48
|
-
"@elementor/editor-props": "4.1.0-
|
|
49
|
-
"@elementor/editor-responsive": "4.1.0-
|
|
50
|
-
"@elementor/editor-styles": "4.1.0-
|
|
51
|
-
"@elementor/editor-styles-repository": "4.1.0-
|
|
52
|
-
"@elementor/editor-ui": "4.1.0-
|
|
53
|
-
"@elementor/editor-v1-adapters": "4.1.0-
|
|
54
|
-
"@elementor/schema": "4.1.0-
|
|
55
|
-
"@elementor/twing": "4.1.0-
|
|
42
|
+
"@elementor/editor-controls": "4.1.0-beta2",
|
|
43
|
+
"@elementor/editor-documents": "4.1.0-beta2",
|
|
44
|
+
"@elementor/editor-elements": "4.1.0-beta2",
|
|
45
|
+
"@elementor/editor-interactions": "4.1.0-beta2",
|
|
46
|
+
"@elementor/editor-mcp": "4.1.0-beta2",
|
|
47
|
+
"@elementor/editor-notifications": "4.1.0-beta2",
|
|
48
|
+
"@elementor/editor-props": "4.1.0-beta2",
|
|
49
|
+
"@elementor/editor-responsive": "4.1.0-beta2",
|
|
50
|
+
"@elementor/editor-styles": "4.1.0-beta2",
|
|
51
|
+
"@elementor/editor-styles-repository": "4.1.0-beta2",
|
|
52
|
+
"@elementor/editor-ui": "4.1.0-beta2",
|
|
53
|
+
"@elementor/editor-v1-adapters": "4.1.0-beta2",
|
|
54
|
+
"@elementor/schema": "4.1.0-beta2",
|
|
55
|
+
"@elementor/twing": "4.1.0-beta2",
|
|
56
56
|
"@elementor/ui": "1.37.5",
|
|
57
|
-
"@elementor/utils": "4.1.0-
|
|
58
|
-
"@elementor/wp-media": "4.1.0-
|
|
57
|
+
"@elementor/utils": "4.1.0-beta2",
|
|
58
|
+
"@elementor/wp-media": "4.1.0-beta2",
|
|
59
59
|
"@floating-ui/react": "^0.27.5",
|
|
60
60
|
"@wordpress/i18n": "^5.13.0"
|
|
61
61
|
},
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createElement,
|
|
3
3
|
type CreateElementParams,
|
|
4
|
+
deleteElement,
|
|
4
5
|
generateElementId,
|
|
5
6
|
getContainer,
|
|
6
7
|
getWidgetsCache,
|
|
7
8
|
type V1Element,
|
|
8
9
|
type V1ElementConfig,
|
|
10
|
+
type V1ElementModelProps,
|
|
9
11
|
} from '@elementor/editor-elements';
|
|
10
12
|
import { type z } from '@elementor/schema';
|
|
11
13
|
|
|
@@ -17,6 +19,7 @@ type AnyConfig = Record< string, Record< string, AnyValue > >;
|
|
|
17
19
|
|
|
18
20
|
type API = {
|
|
19
21
|
createElement: typeof createElement;
|
|
22
|
+
deleteElement: typeof deleteElement;
|
|
20
23
|
getWidgetsCache: typeof getWidgetsCache;
|
|
21
24
|
generateElementId: typeof generateElementId;
|
|
22
25
|
getContainer: typeof getContainer;
|
|
@@ -38,6 +41,7 @@ export class CompositionBuilder {
|
|
|
38
41
|
private rootContainers: V1Element[] = [];
|
|
39
42
|
private api: API = {
|
|
40
43
|
createElement,
|
|
44
|
+
deleteElement,
|
|
41
45
|
getWidgetsCache,
|
|
42
46
|
generateElementId,
|
|
43
47
|
getContainer,
|
|
@@ -94,15 +98,26 @@ export class CompositionBuilder {
|
|
|
94
98
|
|
|
95
99
|
node.setAttribute( 'id', id );
|
|
96
100
|
|
|
97
|
-
const base = {
|
|
101
|
+
const base: V1ElementModelProps = {
|
|
98
102
|
id,
|
|
99
103
|
skipDefaultChildren: true,
|
|
100
|
-
elements: children,
|
|
104
|
+
elements: children as V1ElementModelProps[ 'elements' ],
|
|
101
105
|
editor_settings: {
|
|
102
106
|
title: node.getAttribute( 'configuration-id' ) ?? undefined,
|
|
103
107
|
},
|
|
108
|
+
elType: 'widget',
|
|
104
109
|
};
|
|
105
110
|
|
|
111
|
+
// TODO: Restore this code once components are working in compositions
|
|
112
|
+
// if ( elementTag === 'e-component' ) {
|
|
113
|
+
// // apply component id before applying values
|
|
114
|
+
// const elementConfig = this.elementConfig[ String( node.getAttribute( 'configuration-id' ) ) ];
|
|
115
|
+
// if ( elementConfig ) {
|
|
116
|
+
// base.settings = base.settings || {};
|
|
117
|
+
// base.settings.component_instance = elementConfig.component_instance;
|
|
118
|
+
// }
|
|
119
|
+
// }
|
|
120
|
+
|
|
106
121
|
if ( isWidget ) {
|
|
107
122
|
return { ...base, elType: 'widget' as const, widgetType: elementTag };
|
|
108
123
|
}
|
|
@@ -142,13 +157,6 @@ export class CompositionBuilder {
|
|
|
142
157
|
return errors;
|
|
143
158
|
}
|
|
144
159
|
|
|
145
|
-
private findSchemaForNode( node: Element ) {
|
|
146
|
-
const widgetsCache = this.api.getWidgetsCache() || {};
|
|
147
|
-
const widgetType = node.tagName;
|
|
148
|
-
const widgetData = widgetsCache[ widgetType ]?.atomic_props_schema;
|
|
149
|
-
return widgetData || null;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
160
|
private matchNodeByConfigId( configId: string ) {
|
|
153
161
|
const node = this.xml.querySelector( `[configuration-id="${ configId }"]` );
|
|
154
162
|
if ( ! node ) {
|
|
@@ -282,15 +290,24 @@ export class CompositionBuilder {
|
|
|
282
290
|
for ( const childNode of children ) {
|
|
283
291
|
const modelTree = this.buildModelTree( childNode, widgetsCache );
|
|
284
292
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
293
|
+
try {
|
|
294
|
+
const newElement = this.api.createElement( {
|
|
295
|
+
container: rootContainer,
|
|
296
|
+
model: modelTree as CreateElementParams[ 'model' ],
|
|
297
|
+
options: { useHistory: false },
|
|
298
|
+
} );
|
|
299
|
+
this.rootContainers.push( newElement );
|
|
300
|
+
await this.awaitViewRender( newElement );
|
|
301
|
+
} catch ( e: unknown ) {
|
|
302
|
+
const attemptToRestoreInvalidContainer = this.api.getContainer( modelTree.id as string );
|
|
303
|
+
if ( attemptToRestoreInvalidContainer ) {
|
|
304
|
+
this.api.deleteElement( {
|
|
305
|
+
container: attemptToRestoreInvalidContainer,
|
|
306
|
+
options: { useHistory: false },
|
|
307
|
+
} );
|
|
308
|
+
}
|
|
309
|
+
throw e;
|
|
310
|
+
}
|
|
294
311
|
}
|
|
295
312
|
|
|
296
313
|
const { configErrors, styleErrors, invalidStyles } = await this.applyProperties();
|
package/src/init.tsx
CHANGED
|
@@ -53,7 +53,13 @@ export function init() {
|
|
|
53
53
|
|
|
54
54
|
initCanvasMcp(
|
|
55
55
|
getMCPByDomain( 'canvas', {
|
|
56
|
-
instructions:
|
|
56
|
+
instructions: `Everything related to V4 ( Atomic ) canvas.
|
|
57
|
+
# Canvas workflow for new compositions
|
|
58
|
+
- Configure elements settings and styles
|
|
59
|
+
- Build compositions/sections out of V4 atomic elements using context aware designs using the website resources
|
|
60
|
+
- Get and retrieve element configuration values
|
|
61
|
+
`,
|
|
62
|
+
docs: mcpDescription,
|
|
57
63
|
} )
|
|
58
64
|
);
|
|
59
65
|
|
package/src/mcp/canvas-mcp.ts
CHANGED
|
@@ -12,15 +12,6 @@ import { initConfigureElementTool } from './tools/configure-element/tool';
|
|
|
12
12
|
import { initGetElementConfigTool } from './tools/get-element-config/tool';
|
|
13
13
|
|
|
14
14
|
export const initCanvasMcp = ( reg: MCPRegistryEntry ) => {
|
|
15
|
-
const { setMCPDescription } = reg;
|
|
16
|
-
setMCPDescription(
|
|
17
|
-
`Everything related to V4 ( Atomic ) canvas.
|
|
18
|
-
# Canvas workflow for new compositions
|
|
19
|
-
- Configure elements settings and styles
|
|
20
|
-
- Build compositions/sections out of V4 atomic elements using context aware designs using the website resources
|
|
21
|
-
- Get and retrieve element configuration values
|
|
22
|
-
`
|
|
23
|
-
);
|
|
24
15
|
initWidgetsSchemaResource( reg );
|
|
25
16
|
initAvailableWidgetsResource( reg );
|
|
26
17
|
initDocumentStructureResource( reg );
|
|
@@ -2,6 +2,8 @@ import { toolPrompts } from '@elementor/editor-mcp';
|
|
|
2
2
|
|
|
3
3
|
import { AVAILABLE_WIDGETS_URI } from '../../resources/available-widgets-resource';
|
|
4
4
|
|
|
5
|
+
export const BUILD_COMPOSITIONS_GUIDE_URI = 'elementor://canvas/tools/build-compositions-guide';
|
|
6
|
+
|
|
5
7
|
export const generatePrompt = () => {
|
|
6
8
|
const buildCompositionsToolPrompt = toolPrompts( 'build-compositions' );
|
|
7
9
|
|
|
@@ -13,17 +13,31 @@ import { AVAILABLE_WIDGETS_URI_V4 } from '../../resources/available-widgets-reso
|
|
|
13
13
|
import { BEST_PRACTICES_URI, STYLE_SCHEMA_URI, WIDGET_SCHEMA_URI } from '../../resources/widgets-schema-resource';
|
|
14
14
|
import { doUpdateElementProperty } from '../../utils/do-update-element-property';
|
|
15
15
|
import { getCompositionTargetContainer } from '../../utils/get-composition-target-container';
|
|
16
|
-
import { generatePrompt } from './prompt';
|
|
16
|
+
import { BUILD_COMPOSITIONS_GUIDE_URI, generatePrompt } from './prompt';
|
|
17
17
|
import { inputSchema as schema, outputSchema } from './schema';
|
|
18
18
|
|
|
19
19
|
export const initBuildCompositionsTool = ( reg: MCPRegistryEntry ) => {
|
|
20
|
-
const { addTool } = reg;
|
|
20
|
+
const { addTool, resource } = reg;
|
|
21
|
+
|
|
22
|
+
resource(
|
|
23
|
+
'build-compositions-guide',
|
|
24
|
+
BUILD_COMPOSITIONS_GUIDE_URI,
|
|
25
|
+
{
|
|
26
|
+
title: 'Build Compositions Guide',
|
|
27
|
+
description: 'Detailed guide for using the build-compositions tool',
|
|
28
|
+
mimeType: 'text/plain',
|
|
29
|
+
},
|
|
30
|
+
async ( uri: URL ) => ( {
|
|
31
|
+
contents: [ { uri: uri.href, mimeType: 'text/plain', text: generatePrompt() } ],
|
|
32
|
+
} )
|
|
33
|
+
);
|
|
21
34
|
|
|
22
35
|
addTool( {
|
|
23
36
|
name: 'build-compositions',
|
|
24
|
-
description:
|
|
37
|
+
description: 'Build V4 element compositions on the Elementor canvas. Read the guide resource before use.',
|
|
25
38
|
schema,
|
|
26
39
|
requiredResources: [
|
|
40
|
+
{ description: 'Build compositions guide', uri: BUILD_COMPOSITIONS_GUIDE_URI },
|
|
27
41
|
{ description: 'Widgets schema', uri: WIDGET_SCHEMA_URI },
|
|
28
42
|
{ description: 'Styles schema', uri: STYLE_SCHEMA_URI },
|
|
29
43
|
{ description: 'Global Classes', uri: 'elementor://global-classes' },
|
|
@@ -47,33 +61,41 @@ export const initBuildCompositionsTool = ( reg: MCPRegistryEntry ) => {
|
|
|
47
61
|
try {
|
|
48
62
|
const compositionBuilder = CompositionBuilder.fromXMLString( xmlStructure, {
|
|
49
63
|
createElement,
|
|
64
|
+
deleteElement,
|
|
50
65
|
getWidgetsCache,
|
|
51
66
|
} );
|
|
52
67
|
compositionBuilder.setElementConfig( elementConfig );
|
|
53
68
|
compositionBuilder.setStylesConfig( stylesConfig );
|
|
54
69
|
compositionBuilder.setCustomCSS( customCSS );
|
|
55
70
|
|
|
56
|
-
const {
|
|
57
|
-
|
|
71
|
+
const {
|
|
72
|
+
invalidStyles,
|
|
73
|
+
configErrors,
|
|
74
|
+
rootContainers: generatedRootContainers,
|
|
75
|
+
} = await compositionBuilder.build( targetContainer );
|
|
58
76
|
|
|
59
77
|
rootContainers.push( ...generatedRootContainers );
|
|
60
78
|
generatedXML = new XMLSerializer().serializeToString( compositionBuilder.getXML() );
|
|
61
79
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
80
|
+
if ( configErrors.length ) {
|
|
81
|
+
errors.push( ...configErrors.map( ( msg ) => new Error( msg ) ) );
|
|
82
|
+
} else {
|
|
83
|
+
Object.entries( invalidStyles ).forEach( ( [ elementId, rawCssRules ] ) => {
|
|
84
|
+
const customCss = {
|
|
85
|
+
value: rawCssRules.join( ';\n' ),
|
|
86
|
+
};
|
|
87
|
+
doUpdateElementProperty( {
|
|
88
|
+
elementId,
|
|
89
|
+
propertyName: '_styles',
|
|
90
|
+
propertyValue: {
|
|
91
|
+
_styles: {
|
|
92
|
+
custom_css: customCss,
|
|
93
|
+
},
|
|
72
94
|
},
|
|
73
|
-
|
|
74
|
-
|
|
95
|
+
elementType: 'widget',
|
|
96
|
+
} );
|
|
75
97
|
} );
|
|
76
|
-
}
|
|
98
|
+
}
|
|
77
99
|
} catch ( error ) {
|
|
78
100
|
errors.push( error as Error );
|
|
79
101
|
}
|