@elementor/editor-canvas 3.33.0-291 → 3.33.0-293
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 +157 -57
- package/dist/index.mjs +150 -46
- package/package.json +17 -17
- package/src/mcp/canvas-mcp.ts +2 -0
- package/src/mcp/mcp-description.ts +18 -8
- package/src/mcp/resources/widgets-schema-resource.ts +22 -3
- package/src/mcp/tools/build-composition/prompt.ts +5 -2
- package/src/mcp/tools/build-composition/tool.ts +20 -15
- package/src/mcp/tools/configure-element/prompt.ts +6 -3
- package/src/mcp/tools/get-element-config/tool.ts +75 -0
- package/src/mcp/utils/do-update-element-property.ts +17 -3
|
@@ -26,16 +26,9 @@ export const initBuildCompositionsTool = ( reg: MCPRegistryEntry ) => {
|
|
|
26
26
|
const { xmlStructure, elementConfig, stylesConfig } = params;
|
|
27
27
|
const errors: Error[] = [];
|
|
28
28
|
const softErrors: Error[] = [];
|
|
29
|
+
const rootContainers: V1Element[] = [];
|
|
29
30
|
const widgetsCache = getWidgetsCache() || {};
|
|
30
31
|
const documentContainer = getContainer( 'document' ) as unknown as V1Element;
|
|
31
|
-
const rootContainer = createElement( {
|
|
32
|
-
containerId: documentContainer.id,
|
|
33
|
-
model: {
|
|
34
|
-
elType: 'container',
|
|
35
|
-
id: generateElementId(),
|
|
36
|
-
},
|
|
37
|
-
options: { useHistory: false },
|
|
38
|
-
} );
|
|
39
32
|
try {
|
|
40
33
|
const parser = new DOMParser();
|
|
41
34
|
xml = parser.parseFromString( xmlStructure, 'application/xml' );
|
|
@@ -45,7 +38,7 @@ export const initBuildCompositionsTool = ( reg: MCPRegistryEntry ) => {
|
|
|
45
38
|
}
|
|
46
39
|
|
|
47
40
|
const children = Array.from( xml.children );
|
|
48
|
-
const iterate = ( node: Element, containerElement: V1Element ) => {
|
|
41
|
+
const iterate = ( node: Element, containerElement: V1Element = documentContainer ) => {
|
|
49
42
|
const elementTag = node.tagName;
|
|
50
43
|
if ( ! widgetsCache[ elementTag ] ) {
|
|
51
44
|
errors.push( new Error( `Unknown widget type: ${ elementTag }` ) );
|
|
@@ -69,6 +62,9 @@ export const initBuildCompositionsTool = ( reg: MCPRegistryEntry ) => {
|
|
|
69
62
|
},
|
|
70
63
|
options: { useHistory: false },
|
|
71
64
|
} );
|
|
65
|
+
if ( containerElement === documentContainer ) {
|
|
66
|
+
rootContainers.push( newElement );
|
|
67
|
+
}
|
|
72
68
|
node.setAttribute( 'id', newElement.id );
|
|
73
69
|
const configId = node.getAttribute( 'configuration-id' ) || '';
|
|
74
70
|
try {
|
|
@@ -78,7 +74,11 @@ export const initBuildCompositionsTool = ( reg: MCPRegistryEntry ) => {
|
|
|
78
74
|
for ( const [ propertyName, propertyValue ] of Object.entries( configObject ) ) {
|
|
79
75
|
// validate property existance
|
|
80
76
|
const widgetSchema = widgetsCache[ elementTag ];
|
|
81
|
-
if (
|
|
77
|
+
if (
|
|
78
|
+
! widgetSchema?.atomic_props_schema?.[ propertyName ] &&
|
|
79
|
+
propertyName !== '_styles' &&
|
|
80
|
+
propertyName !== 'custom_css'
|
|
81
|
+
) {
|
|
82
82
|
softErrors.push(
|
|
83
83
|
new Error(
|
|
84
84
|
`Property "${ propertyName }" does not exist on element type "${ elementTag }".`
|
|
@@ -90,7 +90,10 @@ export const initBuildCompositionsTool = ( reg: MCPRegistryEntry ) => {
|
|
|
90
90
|
doUpdateElementProperty( {
|
|
91
91
|
elementId: newElement.id,
|
|
92
92
|
propertyName,
|
|
93
|
-
propertyValue:
|
|
93
|
+
propertyValue:
|
|
94
|
+
propertyName === 'custom_css'
|
|
95
|
+
? { _styles: propertyValue }
|
|
96
|
+
: ( propertyValue as unknown as PropValue ),
|
|
94
97
|
elementType: elementTag,
|
|
95
98
|
} );
|
|
96
99
|
} catch ( error ) {
|
|
@@ -110,7 +113,7 @@ export const initBuildCompositionsTool = ( reg: MCPRegistryEntry ) => {
|
|
|
110
113
|
};
|
|
111
114
|
|
|
112
115
|
for ( const childNode of children ) {
|
|
113
|
-
iterate( childNode,
|
|
116
|
+
iterate( childNode, documentContainer );
|
|
114
117
|
try {
|
|
115
118
|
} catch ( error ) {
|
|
116
119
|
errors.push( error as Error );
|
|
@@ -121,9 +124,11 @@ export const initBuildCompositionsTool = ( reg: MCPRegistryEntry ) => {
|
|
|
121
124
|
}
|
|
122
125
|
|
|
123
126
|
if ( errors.length ) {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
+
rootContainers.forEach( ( rootContainer ) => {
|
|
128
|
+
deleteElement( {
|
|
129
|
+
elementId: rootContainer.id,
|
|
130
|
+
options: { useHistory: false },
|
|
131
|
+
} );
|
|
127
132
|
} );
|
|
128
133
|
}
|
|
129
134
|
|
|
@@ -2,19 +2,20 @@ import { STYLE_SCHEMA_URI, WIDGET_SCHEMA_URI } from '../../resources/widgets-sch
|
|
|
2
2
|
|
|
3
3
|
export const configureElementToolPrompt = `Configure an existing element on the page.
|
|
4
4
|
|
|
5
|
-
# **CRITICAL - REQUIRED
|
|
5
|
+
# **CRITICAL - REQUIRED INFORMATION (Must read before using this tool)**
|
|
6
6
|
1. [${ WIDGET_SCHEMA_URI }]
|
|
7
7
|
Required to understand which widgets are available, and what are their configuration schemas.
|
|
8
8
|
Every widgetType (i.e. e-heading, e-button) that is supported has it's own property schema, that you must follow in order to apply property values correctly.
|
|
9
9
|
2. [${ STYLE_SCHEMA_URI }]
|
|
10
10
|
Required to understand the styles schema for the widgets. All widgets share the same styles schema, grouped by categories.
|
|
11
11
|
Use this resource to understand which style properties are available for each element, and how to structure the "_styles" configuration property.
|
|
12
|
+
3. If not sure about the PropValues schema, you can use the "get-element-configuration-values" tool to retreive the current PropValues configuration of the element.
|
|
12
13
|
|
|
13
14
|
Before using this tool, check the definitions of the elements PropTypes at the resource "widget-schema-by-type" at editor-canvas__elementor://widgets/schema/{widgetType}
|
|
14
15
|
All widgets share a common _style property for styling, which uses the common styles schema.
|
|
15
16
|
Retreive and check the common styles schema at the resource list "styles-schema" at editor-canvas__elementor://styles/schema/{category}
|
|
16
17
|
|
|
17
|
-
|
|
18
|
+
Attempt to use the _style property "custom_css" for any styling that have complicated schemas (such as backgrounds), read the resource editor-canvas__elementor://styles/schema/custom_css for more information.
|
|
18
19
|
|
|
19
20
|
# Parameters
|
|
20
21
|
- propertiesToChange: An object containing the properties to change, with their new values. MANDATORY
|
|
@@ -59,6 +60,7 @@ Use the EXACT "PROP-TYPE" Schema given, and ALWAYS include the "key" property fr
|
|
|
59
60
|
\`\`\`json
|
|
60
61
|
{
|
|
61
62
|
propertiesToChange: {
|
|
63
|
+
// List of properties TO CHANGE, following the PropType schema for the element as defined in the resource [${ WIDGET_SCHEMA_URI }]
|
|
62
64
|
title: {
|
|
63
65
|
$$type: 'string',
|
|
64
66
|
value: 'New Title Text'
|
|
@@ -68,8 +70,9 @@ Use the EXACT "PROP-TYPE" Schema given, and ALWAYS include the "key" property fr
|
|
|
68
70
|
value: false
|
|
69
71
|
},
|
|
70
72
|
_styles: {
|
|
73
|
+
// List of available keys available at the [${ STYLE_SCHEMA_URI }] dynamic resource
|
|
71
74
|
'line-height': {
|
|
72
|
-
$$type: 'size',
|
|
75
|
+
$$type: 'size', // MANDATORY do not forget to include the correct $$type for every property
|
|
73
76
|
value: {
|
|
74
77
|
size: {
|
|
75
78
|
$$type: 'number',
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { getContainer, getElementStyles, getWidgetsCache } 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
|
+
import { decodeString } from '@elementor/utils';
|
|
6
|
+
|
|
7
|
+
const schema = {
|
|
8
|
+
elementId: z.string(),
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const outputSchema = {
|
|
12
|
+
propValues: z
|
|
13
|
+
.record( z.string(), z.any() )
|
|
14
|
+
.describe(
|
|
15
|
+
'A record mapping PropTypes to their corresponding PropValues, with _styles record for style-related PropValues'
|
|
16
|
+
),
|
|
17
|
+
customCss: z.string().optional().describe( 'The custom CSS string associated with the element, if any.' ),
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export const initGetElementConfigTool = ( reg: MCPRegistryEntry ) => {
|
|
21
|
+
const { addTool } = reg;
|
|
22
|
+
|
|
23
|
+
addTool( {
|
|
24
|
+
name: 'get-element-configuration-values',
|
|
25
|
+
description: "Retrieve the element's configuration PropValues for a specific element by unique ID.",
|
|
26
|
+
schema,
|
|
27
|
+
outputSchema,
|
|
28
|
+
handler: async ( { elementId } ) => {
|
|
29
|
+
const element = getContainer( elementId );
|
|
30
|
+
if ( ! element ) {
|
|
31
|
+
throw new Error( `Element with ID ${ elementId } not found.` );
|
|
32
|
+
}
|
|
33
|
+
const elementRawSettings = element.settings;
|
|
34
|
+
const propSchema = getWidgetsCache()?.[ element.model.get( 'widgetType' ) || '' ]?.atomic_props_schema;
|
|
35
|
+
|
|
36
|
+
if ( ! elementRawSettings || ! propSchema ) {
|
|
37
|
+
throw new Error( `No settings or prop schema found for element ID: ${ elementId }` );
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const propValues: Record< string, PropValue > = {};
|
|
41
|
+
const stylePropValues: Record< string, PropValue > = {};
|
|
42
|
+
|
|
43
|
+
Schema.configurableKeys( propSchema ).forEach( ( key ) => {
|
|
44
|
+
propValues[ key ] = structuredClone( elementRawSettings.get( key ) );
|
|
45
|
+
} );
|
|
46
|
+
const elementStyles = getElementStyles( elementId ) || {};
|
|
47
|
+
const localStyle = Object.values( elementStyles ).find( ( style ) => style.label === 'local' );
|
|
48
|
+
|
|
49
|
+
if ( localStyle ) {
|
|
50
|
+
const defaultVariant = localStyle.variants.find(
|
|
51
|
+
( variant ) => variant.meta.breakpoint === 'desktop' && ! variant.meta.state
|
|
52
|
+
);
|
|
53
|
+
if ( defaultVariant ) {
|
|
54
|
+
const styleProps = defaultVariant.props || {};
|
|
55
|
+
Object.keys( styleProps ).forEach( ( stylePropName ) => {
|
|
56
|
+
if ( typeof styleProps[ stylePropName ] !== 'undefined' ) {
|
|
57
|
+
stylePropValues[ stylePropName ] = structuredClone( styleProps[ stylePropName ] );
|
|
58
|
+
}
|
|
59
|
+
} );
|
|
60
|
+
|
|
61
|
+
if ( defaultVariant.custom_css?.raw ) {
|
|
62
|
+
stylePropValues.custom_css = decodeString( defaultVariant.custom_css.raw, undefined );
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return {
|
|
68
|
+
propValues: {
|
|
69
|
+
...propValues,
|
|
70
|
+
_styles: stylePropValues,
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
},
|
|
74
|
+
} );
|
|
75
|
+
};
|
|
@@ -5,7 +5,13 @@ import {
|
|
|
5
5
|
updateElementSettings,
|
|
6
6
|
updateElementStyle,
|
|
7
7
|
} from '@elementor/editor-elements';
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
getPropSchemaFromCache,
|
|
10
|
+
type PropValue,
|
|
11
|
+
Schema,
|
|
12
|
+
stringPropTypeUtil,
|
|
13
|
+
type TransformablePropValue,
|
|
14
|
+
} from '@elementor/editor-props';
|
|
9
15
|
import { type CustomCss, getStylesSchema } from '@elementor/editor-styles';
|
|
10
16
|
|
|
11
17
|
type OwnParams = {
|
|
@@ -42,8 +48,15 @@ export const doUpdateElementProperty = ( params: OwnParams ) => {
|
|
|
42
48
|
Object.keys( propertyMapValue as Record< string, unknown > ).forEach( ( stylePropName ) => {
|
|
43
49
|
const propertyRawSchema = styleSchema[ stylePropName ];
|
|
44
50
|
if ( stylePropName === 'custom_css' ) {
|
|
51
|
+
let customCssValue = propertyMapValue[ stylePropName ] as object | string;
|
|
52
|
+
if ( typeof customCssValue === 'object' ) {
|
|
53
|
+
customCssValue =
|
|
54
|
+
stringPropTypeUtil.extract( customCssValue ) ||
|
|
55
|
+
( customCssValue as { value: unknown } )?.value ||
|
|
56
|
+
'';
|
|
57
|
+
}
|
|
45
58
|
customCss = {
|
|
46
|
-
raw: btoa(
|
|
59
|
+
raw: btoa( customCssValue as string ),
|
|
47
60
|
};
|
|
48
61
|
return;
|
|
49
62
|
}
|
|
@@ -65,7 +78,7 @@ export const doUpdateElementProperty = ( params: OwnParams ) => {
|
|
|
65
78
|
if ( ! localStyle ) {
|
|
66
79
|
createElementStyle( {
|
|
67
80
|
elementId,
|
|
68
|
-
custom_css: customCss,
|
|
81
|
+
...( typeof customCss !== 'undefined' ? { custom_css: customCss } : {} ),
|
|
69
82
|
classesProp: 'classes',
|
|
70
83
|
label: 'local',
|
|
71
84
|
meta: {
|
|
@@ -84,6 +97,7 @@ export const doUpdateElementProperty = ( params: OwnParams ) => {
|
|
|
84
97
|
breakpoint: 'desktop',
|
|
85
98
|
state: null,
|
|
86
99
|
},
|
|
100
|
+
...( typeof customCss !== 'undefined' ? { custom_css: customCss } : {} ),
|
|
87
101
|
props: {
|
|
88
102
|
...transformedStyleValues,
|
|
89
103
|
},
|