@elementor/editor-canvas 4.3.0-999 → 4.3.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 +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +535 -393
- package/dist/index.mjs +516 -370
- package/package.json +20 -20
- package/src/__tests__/flex-transformer.test.ts +11 -11
- package/src/__tests__/prop-types.ts +11 -0
- package/src/init-settings-transformers.ts +4 -0
- package/src/init-style-transformers.ts +2 -2
- package/src/init.tsx +5 -4
- package/src/legacy/__tests__/create-templated-element-type.test.ts +50 -0
- package/src/legacy/__tests__/list-type.test.ts +89 -0
- package/src/legacy/create-nested-templated-element-type.ts +3 -1
- package/src/legacy/create-templated-element-type.ts +5 -2
- package/src/legacy/list-type.ts +63 -0
- package/src/legacy/replacements/inline-editing/__tests__/inline-editing-eligibility.test.ts +7 -7
- package/src/legacy/replacements/inline-editing/inline-editing-elements.tsx +22 -9
- package/src/legacy/replacements/inline-editing/inline-editing-eligibility.ts +12 -3
- package/src/legacy/tabs-model-extensions.ts +2 -5
- package/src/legacy/twig-rendering-utils.ts +11 -2
- package/src/legacy/types.ts +4 -0
- package/src/mcp/canvas-mcp.ts +2 -4
- package/src/mcp/mcp-description.ts +18 -30
- package/src/mcp/resources/__tests__/available-widgets-resource.test.ts +22 -13
- package/src/mcp/resources/__tests__/dynamic-tags-resource.test.ts +22 -30
- package/src/mcp/resources/__tests__/widgets-schema-resource.test.ts +11 -6
- package/src/mcp/resources/available-widgets-resource.ts +13 -10
- package/src/mcp/resources/dynamic-tags-resource.ts +6 -15
- package/src/mcp/resources/widgets-schema-resource.ts +8 -5
- package/src/mcp/tools/configure-element/__tests__/tool.test.ts +130 -0
- package/src/mcp/tools/configure-element/prompt.ts +3 -6
- package/src/mcp/tools/configure-element/schema.ts +6 -0
- package/src/mcp/tools/configure-element/tool.ts +11 -1
- package/src/mcp/tools/get-page-structure/tool.ts +73 -0
- package/src/mcp/utils/__tests__/do-update-element-property.test.ts +27 -1
- package/src/mcp/utils/do-update-element-property.ts +18 -6
- package/src/mcp/utils/get-mcp-error-message.ts +16 -0
- package/src/renderers/__tests__/compute-html-tag.test.ts +55 -0
- package/src/renderers/__tests__/create-dom-renderer.test.ts +60 -0
- package/src/renderers/__tests__/fixtures/html-tag-computer-cases.json +87 -0
- package/src/renderers/compute-html-tag.ts +73 -0
- package/src/renderers/create-dom-renderer.ts +13 -22
- package/src/transformers/settings/escaped-html-transformer.ts +6 -0
- package/src/transformers/shared/__tests__/icon-transformer.test.ts +199 -0
- package/src/transformers/shared/icon-transformer.ts +231 -0
- package/src/transformers/shared/process-svg-content.ts +26 -0
- package/src/transformers/shared/svg-src-transformer.ts +1 -26
- package/src/transformers/styles/flex-transformer.ts +11 -32
- package/src/utils/__tests__/sanitize-escaped-html.test.ts +105 -0
- package/src/utils/sanitize-escaped-html.ts +32 -0
- package/src/mcp/tools/build-composition/tool.ts +0 -133
- package/src/mcp/tools/get-element-config/tool.ts +0 -114
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
import { getCurrentDocument, reloadCurrentDocument } from '@elementor/editor-documents';
|
|
2
|
-
import { getContainer, selectElement } from '@elementor/editor-elements';
|
|
3
|
-
import { type MCPRegistryEntry } from '@elementor/editor-mcp';
|
|
4
|
-
import { AxiosError, type HttpResponse, httpService } from '@elementor/http-client';
|
|
5
|
-
import { z } from '@elementor/schema';
|
|
6
|
-
|
|
7
|
-
const MCP_PROXY_URL = 'elementor/v1/mcp-proxy';
|
|
8
|
-
|
|
9
|
-
type BuildCompositionResponse = {
|
|
10
|
-
success: boolean;
|
|
11
|
-
post_id: number;
|
|
12
|
-
root_element_ids: string[];
|
|
13
|
-
preview_url: string;
|
|
14
|
-
version: string;
|
|
15
|
-
resolved_xml: string;
|
|
16
|
-
llm_instructions: string;
|
|
17
|
-
warnings?: string[];
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
export const initBuildCompositionTool = ( reg: MCPRegistryEntry ) => {
|
|
21
|
-
const { addTool } = reg;
|
|
22
|
-
|
|
23
|
-
addTool( {
|
|
24
|
-
name: 'build-composition',
|
|
25
|
-
description:
|
|
26
|
-
'Build a V4 element composition on the Elementor canvas via the server-side MCP ability. ' +
|
|
27
|
-
'Pass the raw XML tags directly as xmlStructure — do NOT wrap the value in <![CDATA[ ... ]]>, ' +
|
|
28
|
-
'code fences, or quotes. The document is saved as a draft. Reload the editor after calling ' +
|
|
29
|
-
'this tool to see the result.',
|
|
30
|
-
schema: {
|
|
31
|
-
xmlStructure: z
|
|
32
|
-
.string()
|
|
33
|
-
.describe(
|
|
34
|
-
'Valid XML structure with custom Elementor widget tags. Every element MUST have a unique ' +
|
|
35
|
-
'configuration-id attribute (e.g. <e-heading configuration-id="hero-title"></e-heading>). ' +
|
|
36
|
-
'No attributes, classes, IDs, or text nodes in XML. Pass raw XML — do not wrap in CDATA.'
|
|
37
|
-
),
|
|
38
|
-
elementConfig: z
|
|
39
|
-
.record(
|
|
40
|
-
z.string().describe( 'configuration-id' ),
|
|
41
|
-
z.record( z.string().describe( 'property name' ), z.any().describe( 'PropValue' ) )
|
|
42
|
-
)
|
|
43
|
-
.optional()
|
|
44
|
-
.describe( 'Map configuration-id → widget PropValues ($$type + value).' ),
|
|
45
|
-
style: z
|
|
46
|
-
.record(
|
|
47
|
-
z.string().describe( 'configuration-id' ),
|
|
48
|
-
z.record( z.string().describe( 'CSS property name' ), z.string().describe( 'CSS value' ) )
|
|
49
|
-
)
|
|
50
|
-
.optional()
|
|
51
|
-
.describe(
|
|
52
|
-
'Map configuration-id → raw CSS declarations (property → value strings; no selectors). ' +
|
|
53
|
-
'Server converts to native styles; unconvertible declarations become the element custom CSS.'
|
|
54
|
-
),
|
|
55
|
-
parentId: z
|
|
56
|
-
.string()
|
|
57
|
-
.optional()
|
|
58
|
-
.describe( "ID of the parent container. Omit or pass 'document' to insert at document root." ),
|
|
59
|
-
dryRun: z
|
|
60
|
-
.boolean()
|
|
61
|
-
.optional()
|
|
62
|
-
.describe( 'If true, validate and return the resolved tree without persisting.' ),
|
|
63
|
-
},
|
|
64
|
-
outputSchema: {
|
|
65
|
-
rootElementIds: z.array( z.string() ),
|
|
66
|
-
previewUrl: z.string(),
|
|
67
|
-
version: z.string(),
|
|
68
|
-
resolvedXml: z.string(),
|
|
69
|
-
llmInstructions: z.string(),
|
|
70
|
-
warnings: z.array( z.string() ).optional(),
|
|
71
|
-
},
|
|
72
|
-
handler: async ( { xmlStructure, elementConfig, style, parentId, dryRun } ) => {
|
|
73
|
-
const document = getCurrentDocument();
|
|
74
|
-
|
|
75
|
-
if ( ! document?.id ) {
|
|
76
|
-
throw new Error( 'No active document found.' );
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
try {
|
|
80
|
-
const { data } = await httpService().post< HttpResponse< BuildCompositionResponse > >( MCP_PROXY_URL, {
|
|
81
|
-
tool: 'build-composition',
|
|
82
|
-
input: {
|
|
83
|
-
post_id: document.id,
|
|
84
|
-
xml_structure: xmlStructure,
|
|
85
|
-
element_config: elementConfig ?? {},
|
|
86
|
-
style: style ?? {},
|
|
87
|
-
parent_id: parentId ?? 'document',
|
|
88
|
-
dry_run: dryRun ?? false,
|
|
89
|
-
},
|
|
90
|
-
} );
|
|
91
|
-
|
|
92
|
-
if ( ! dryRun ) {
|
|
93
|
-
await reloadCurrentDocument();
|
|
94
|
-
|
|
95
|
-
const [ firstRootId ] = data.data.root_element_ids;
|
|
96
|
-
if ( firstRootId ) {
|
|
97
|
-
selectElement( firstRootId );
|
|
98
|
-
getContainer( firstRootId )?.view?.el?.scrollIntoView( {
|
|
99
|
-
behavior: 'smooth',
|
|
100
|
-
block: 'center',
|
|
101
|
-
} );
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
return {
|
|
106
|
-
rootElementIds: data.data.root_element_ids,
|
|
107
|
-
previewUrl: data.data.preview_url,
|
|
108
|
-
version: data.data.version,
|
|
109
|
-
resolvedXml: data.data.resolved_xml,
|
|
110
|
-
llmInstructions: data.data.llm_instructions,
|
|
111
|
-
warnings: data.data.warnings,
|
|
112
|
-
};
|
|
113
|
-
} catch ( error ) {
|
|
114
|
-
throw new Error( getErrorMessage( error ) );
|
|
115
|
-
}
|
|
116
|
-
},
|
|
117
|
-
} );
|
|
118
|
-
};
|
|
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
|
-
}
|
|
@@ -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
|
-
};
|