@elementor/editor-canvas 4.2.0-937 → 4.2.0-939
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 +118 -56
- package/dist/index.mjs +88 -26
- package/package.json +19 -19
- package/src/mcp/resources/document-structure-resource.ts +4 -1
- package/src/mcp/tools/configure-element/tool.ts +17 -4
- package/src/mcp/utils/__tests__/do-update-element-property.test.ts +43 -0
- package/src/mcp/utils/__tests__/resolve-canonical-prop-name.test.ts +111 -0
- package/src/mcp/utils/do-update-element-property.ts +6 -1
- package/src/mcp/utils/resolve-canonical-prop-name.ts +71 -0
package/dist/index.js
CHANGED
|
@@ -4198,7 +4198,7 @@ function extractElementData(element) {
|
|
|
4198
4198
|
widgetType: model.widgetType || void 0,
|
|
4199
4199
|
version: resolveElementVersion(element)
|
|
4200
4200
|
};
|
|
4201
|
-
const title = model.title || element.model?.editor_settings?.title;
|
|
4201
|
+
const title = model.title || element.model?.editor_settings?.title || element.model.getTitle?.();
|
|
4202
4202
|
if (title) {
|
|
4203
4203
|
result.title = title;
|
|
4204
4204
|
}
|
|
@@ -4626,13 +4626,13 @@ function getElementDisplayName(container) {
|
|
|
4626
4626
|
|
|
4627
4627
|
// src/mcp/tools/build-composition/tool.ts
|
|
4628
4628
|
var import_editor_documents3 = require("@elementor/editor-documents");
|
|
4629
|
-
var
|
|
4629
|
+
var import_editor_elements16 = require("@elementor/editor-elements");
|
|
4630
4630
|
|
|
4631
4631
|
// src/composition-builder/composition-builder.ts
|
|
4632
|
-
var
|
|
4632
|
+
var import_editor_elements15 = require("@elementor/editor-elements");
|
|
4633
4633
|
|
|
4634
4634
|
// src/mcp/utils/do-update-element-property.ts
|
|
4635
|
-
var
|
|
4635
|
+
var import_editor_elements14 = require("@elementor/editor-elements");
|
|
4636
4636
|
var import_editor_props8 = require("@elementor/editor-props");
|
|
4637
4637
|
var import_editor_styles4 = require("@elementor/editor-styles");
|
|
4638
4638
|
var import_editor_v1_adapters21 = require("@elementor/editor-v1-adapters");
|
|
@@ -4651,6 +4651,58 @@ var readStoredCustomCssText = (raw) => {
|
|
|
4651
4651
|
}
|
|
4652
4652
|
};
|
|
4653
4653
|
|
|
4654
|
+
// src/mcp/utils/resolve-canonical-prop-name.ts
|
|
4655
|
+
var import_editor_elements13 = require("@elementor/editor-elements");
|
|
4656
|
+
function buildAliasToCanonicalMap(schema2) {
|
|
4657
|
+
const aliasToCanonical = {};
|
|
4658
|
+
for (const [canonical, propType] of Object.entries(schema2)) {
|
|
4659
|
+
const aliases = propType.meta?.aliases;
|
|
4660
|
+
if (!Array.isArray(aliases)) {
|
|
4661
|
+
continue;
|
|
4662
|
+
}
|
|
4663
|
+
for (const alias of aliases) {
|
|
4664
|
+
if (typeof alias === "string" && alias) {
|
|
4665
|
+
aliasToCanonical[alias] = canonical;
|
|
4666
|
+
}
|
|
4667
|
+
}
|
|
4668
|
+
}
|
|
4669
|
+
return aliasToCanonical;
|
|
4670
|
+
}
|
|
4671
|
+
function resolveCanonicalPropName(elementType, propertyName) {
|
|
4672
|
+
const schema2 = (0, import_editor_elements13.getWidgetsCache)()?.[elementType]?.atomic_props_schema;
|
|
4673
|
+
if (!schema2 || schema2[propertyName]) {
|
|
4674
|
+
return propertyName;
|
|
4675
|
+
}
|
|
4676
|
+
return buildAliasToCanonicalMap(schema2)[propertyName] ?? propertyName;
|
|
4677
|
+
}
|
|
4678
|
+
function resolveCanonicalPropKeys(elementType, props) {
|
|
4679
|
+
const schema2 = (0, import_editor_elements13.getWidgetsCache)()?.[elementType]?.atomic_props_schema;
|
|
4680
|
+
if (!schema2) {
|
|
4681
|
+
return { ...props };
|
|
4682
|
+
}
|
|
4683
|
+
const aliasToCanonical = buildAliasToCanonicalMap(schema2);
|
|
4684
|
+
const resolved = {};
|
|
4685
|
+
for (const [key, value] of Object.entries(props)) {
|
|
4686
|
+
if (schema2[key]) {
|
|
4687
|
+
resolved[key] = value;
|
|
4688
|
+
}
|
|
4689
|
+
}
|
|
4690
|
+
for (const [key, value] of Object.entries(props)) {
|
|
4691
|
+
if (schema2[key]) {
|
|
4692
|
+
continue;
|
|
4693
|
+
}
|
|
4694
|
+
const canonical = aliasToCanonical[key];
|
|
4695
|
+
if (!canonical) {
|
|
4696
|
+
resolved[key] = value;
|
|
4697
|
+
continue;
|
|
4698
|
+
}
|
|
4699
|
+
if (!Object.prototype.hasOwnProperty.call(resolved, canonical)) {
|
|
4700
|
+
resolved[canonical] = value;
|
|
4701
|
+
}
|
|
4702
|
+
}
|
|
4703
|
+
return resolved;
|
|
4704
|
+
}
|
|
4705
|
+
|
|
4654
4706
|
// src/mcp/utils/do-update-element-property.ts
|
|
4655
4707
|
var LOCAL_STYLE_META = {
|
|
4656
4708
|
breakpoint: "desktop",
|
|
@@ -4667,9 +4719,10 @@ function resolvePropValue(value, forceKey) {
|
|
|
4667
4719
|
});
|
|
4668
4720
|
}
|
|
4669
4721
|
var doUpdateElementProperty = (params) => {
|
|
4670
|
-
const { elementId,
|
|
4722
|
+
const { elementId, propertyValue, elementType, customCssWriteMode = "replace" } = params;
|
|
4723
|
+
const propertyName = params.propertyName === "_styles" ? params.propertyName : resolveCanonicalPropName(elementType, params.propertyName);
|
|
4671
4724
|
if (propertyName === "_styles") {
|
|
4672
|
-
const elementStyles = (0,
|
|
4725
|
+
const elementStyles = (0, import_editor_elements14.getElementStyles)(elementId) || {};
|
|
4673
4726
|
const propertyMapValue = propertyValue;
|
|
4674
4727
|
const styleSchema = (0, import_editor_styles4.getStylesSchema)();
|
|
4675
4728
|
const transformedStyleValues = Object.fromEntries(
|
|
@@ -4726,7 +4779,7 @@ var doUpdateElementProperty = (params) => {
|
|
|
4726
4779
|
});
|
|
4727
4780
|
delete transformedStyleValues.custom_css;
|
|
4728
4781
|
if (!localStyle) {
|
|
4729
|
-
(0,
|
|
4782
|
+
(0, import_editor_elements14.createElementStyle)({
|
|
4730
4783
|
elementId,
|
|
4731
4784
|
...typeof customCss !== "undefined" ? { custom_css: customCss } : {},
|
|
4732
4785
|
classesProp: "classes",
|
|
@@ -4740,7 +4793,7 @@ var doUpdateElementProperty = (params) => {
|
|
|
4740
4793
|
}
|
|
4741
4794
|
});
|
|
4742
4795
|
} else {
|
|
4743
|
-
(0,
|
|
4796
|
+
(0, import_editor_elements14.updateElementStyle)({
|
|
4744
4797
|
elementId,
|
|
4745
4798
|
styleId: localStyle.id,
|
|
4746
4799
|
meta: {
|
|
@@ -4755,7 +4808,7 @@ var doUpdateElementProperty = (params) => {
|
|
|
4755
4808
|
}
|
|
4756
4809
|
return;
|
|
4757
4810
|
}
|
|
4758
|
-
const elementPropSchema = (0,
|
|
4811
|
+
const elementPropSchema = (0, import_editor_elements14.getWidgetsCache)()?.[elementType]?.atomic_props_schema;
|
|
4759
4812
|
if (!elementPropSchema) {
|
|
4760
4813
|
throw new Error(`No prop schema found for element type: ${elementType}`);
|
|
4761
4814
|
}
|
|
@@ -4778,7 +4831,7 @@ var doUpdateElementProperty = (params) => {
|
|
|
4778
4831
|
Expected Schema: ${jsonSchema}`
|
|
4779
4832
|
);
|
|
4780
4833
|
}
|
|
4781
|
-
(0,
|
|
4834
|
+
(0, import_editor_elements14.updateElementSettings)({
|
|
4782
4835
|
id: elementId,
|
|
4783
4836
|
props: {
|
|
4784
4837
|
[propertyName]: value
|
|
@@ -4836,11 +4889,11 @@ var CompositionBuilder = class _CompositionBuilder {
|
|
|
4836
4889
|
elementCustomCSS = {};
|
|
4837
4890
|
rootContainers = [];
|
|
4838
4891
|
api = {
|
|
4839
|
-
createElement:
|
|
4840
|
-
deleteElement:
|
|
4841
|
-
getWidgetsCache:
|
|
4842
|
-
generateElementId:
|
|
4843
|
-
getContainer:
|
|
4892
|
+
createElement: import_editor_elements15.createElement,
|
|
4893
|
+
deleteElement: import_editor_elements15.deleteElement,
|
|
4894
|
+
getWidgetsCache: import_editor_elements15.getWidgetsCache,
|
|
4895
|
+
generateElementId: import_editor_elements15.generateElementId,
|
|
4896
|
+
getContainer: import_editor_elements15.getContainer,
|
|
4844
4897
|
doUpdateElementProperty
|
|
4845
4898
|
};
|
|
4846
4899
|
xml;
|
|
@@ -5360,19 +5413,19 @@ var initBuildCompositionsTool = (reg) => {
|
|
|
5360
5413
|
const { xmlStructure, elementConfig, stylesConfig } = adaptLeafRootParams({
|
|
5361
5414
|
...rawParams,
|
|
5362
5415
|
stylesConfig: convertedStyles,
|
|
5363
|
-
widgetsCache: (0,
|
|
5416
|
+
widgetsCache: (0, import_editor_elements16.getWidgetsCache)() ?? {}
|
|
5364
5417
|
});
|
|
5365
5418
|
let generatedXML = "";
|
|
5366
5419
|
const errors = [];
|
|
5367
5420
|
const rootContainers = [];
|
|
5368
|
-
const documentContainer = (0,
|
|
5421
|
+
const documentContainer = (0, import_editor_elements16.getContainer)("document");
|
|
5369
5422
|
const currentDocument = (0, import_editor_documents3.getCurrentDocument)();
|
|
5370
5423
|
const targetContainer = getCompositionTargetContainer(documentContainer, currentDocument?.type.value);
|
|
5371
5424
|
try {
|
|
5372
5425
|
const compositionBuilder = CompositionBuilder.fromXMLString(xmlStructure, {
|
|
5373
|
-
createElement:
|
|
5374
|
-
deleteElement:
|
|
5375
|
-
getWidgetsCache:
|
|
5426
|
+
createElement: import_editor_elements16.createElement,
|
|
5427
|
+
deleteElement: import_editor_elements16.deleteElement,
|
|
5428
|
+
getWidgetsCache: import_editor_elements16.getWidgetsCache
|
|
5376
5429
|
});
|
|
5377
5430
|
compositionBuilder.setElementConfig(elementConfig);
|
|
5378
5431
|
compositionBuilder.setStylesConfig(stylesConfig);
|
|
@@ -5388,7 +5441,7 @@ var initBuildCompositionsTool = (reg) => {
|
|
|
5388
5441
|
}
|
|
5389
5442
|
if (errors.length) {
|
|
5390
5443
|
rootContainers.forEach((rootContainer) => {
|
|
5391
|
-
(0,
|
|
5444
|
+
(0, import_editor_elements16.deleteElement)({
|
|
5392
5445
|
container: rootContainer,
|
|
5393
5446
|
options: { useHistory: false }
|
|
5394
5447
|
});
|
|
@@ -5457,7 +5510,7 @@ function assertCompositionXmlUsesV4WidgetsOnly(xmlStructure) {
|
|
|
5457
5510
|
if (doc.querySelector("parsererror")) {
|
|
5458
5511
|
throw new Error("Failed to parse XML string: " + doc);
|
|
5459
5512
|
}
|
|
5460
|
-
const widgetsCache = (0,
|
|
5513
|
+
const widgetsCache = (0, import_editor_elements16.getWidgetsCache)() ?? {};
|
|
5461
5514
|
for (const node of doc.querySelectorAll("*")) {
|
|
5462
5515
|
const type = node.tagName;
|
|
5463
5516
|
const widgetData = widgetsCache[type];
|
|
@@ -5474,10 +5527,10 @@ function assertCompositionXmlUsesV4WidgetsOnly(xmlStructure) {
|
|
|
5474
5527
|
}
|
|
5475
5528
|
|
|
5476
5529
|
// src/mcp/tools/configure-element/tool.ts
|
|
5477
|
-
var
|
|
5530
|
+
var import_editor_elements18 = require("@elementor/editor-elements");
|
|
5478
5531
|
|
|
5479
5532
|
// src/mcp/utils/validate-input.ts
|
|
5480
|
-
var
|
|
5533
|
+
var import_editor_elements17 = require("@elementor/editor-elements");
|
|
5481
5534
|
var import_editor_props9 = require("@elementor/editor-props");
|
|
5482
5535
|
var import_editor_styles5 = require("@elementor/editor-styles");
|
|
5483
5536
|
var _widgetsSchema = null;
|
|
@@ -5485,7 +5538,7 @@ var validateInput = {
|
|
|
5485
5538
|
get widgetsSchema() {
|
|
5486
5539
|
if (!_widgetsSchema) {
|
|
5487
5540
|
const schema2 = {};
|
|
5488
|
-
const cache = (0,
|
|
5541
|
+
const cache = (0, import_editor_elements17.getWidgetsCache)();
|
|
5489
5542
|
if (!cache) {
|
|
5490
5543
|
return {};
|
|
5491
5544
|
}
|
|
@@ -5726,19 +5779,28 @@ var initConfigureElementTool = (reg) => {
|
|
|
5726
5779
|
{ description: "Dynamic tags catalog", uri: DYNAMIC_TAGS_URI }
|
|
5727
5780
|
],
|
|
5728
5781
|
handler: async ({ elementId, propertiesToChange, elementType, style }) => {
|
|
5729
|
-
const widgetData = (0,
|
|
5782
|
+
const widgetData = (0, import_editor_elements18.getWidgetsCache)()?.[elementType];
|
|
5730
5783
|
if (!widgetData) {
|
|
5731
5784
|
throw new Error(
|
|
5732
5785
|
`Unknown element type: ${elementType}. Check the available-widgets resource for valid types.`
|
|
5733
5786
|
);
|
|
5734
5787
|
}
|
|
5788
|
+
const container = (0, import_editor_elements18.getContainer)(elementId);
|
|
5789
|
+
if (!container) {
|
|
5790
|
+
throw new Error(`Element with id ${elementId} not found`);
|
|
5791
|
+
}
|
|
5792
|
+
const isElementTypeMatchingId = container.settings.get("widgetType") === elementType || container.type === elementType;
|
|
5793
|
+
if (!isElementTypeMatchingId) {
|
|
5794
|
+
throw new Error(`Element with ID ${elementId} is not of type ${elementType}`);
|
|
5795
|
+
}
|
|
5735
5796
|
if (!widgetData.atomic_props_schema) {
|
|
5736
5797
|
throw new Error(
|
|
5737
5798
|
`This tool does not support V3 elements. Please use the elementor-v3-mcp tools instead for element type: ${elementType}`
|
|
5738
5799
|
);
|
|
5739
5800
|
}
|
|
5740
|
-
const
|
|
5741
|
-
const
|
|
5801
|
+
const propertiesToUpdate = resolveCanonicalPropKeys(elementType, propertiesToChange);
|
|
5802
|
+
const toUpdate = Object.entries(propertiesToUpdate);
|
|
5803
|
+
const { valid, errors } = validateInput.validatePropSchema(elementType, propertiesToUpdate);
|
|
5742
5804
|
if (!valid) {
|
|
5743
5805
|
const errorMessage = `Failed to configure element "${elementId}" due to invalid properties: ${errors?.join(
|
|
5744
5806
|
"\n- "
|
|
@@ -5818,7 +5880,7 @@ Provide styling as raw CSS via the "style" parameter (a flat map of CSS property
|
|
|
5818
5880
|
}
|
|
5819
5881
|
|
|
5820
5882
|
// src/mcp/tools/get-element-config/tool.ts
|
|
5821
|
-
var
|
|
5883
|
+
var import_editor_elements19 = require("@elementor/editor-elements");
|
|
5822
5884
|
var import_editor_props10 = require("@elementor/editor-props");
|
|
5823
5885
|
var import_schema5 = require("@elementor/schema");
|
|
5824
5886
|
var schema = {
|
|
@@ -5853,12 +5915,12 @@ var initGetElementConfigTool = (reg) => {
|
|
|
5853
5915
|
schema,
|
|
5854
5916
|
outputSchema: outputSchema3,
|
|
5855
5917
|
handler: async ({ elementId }) => {
|
|
5856
|
-
const element = (0,
|
|
5918
|
+
const element = (0, import_editor_elements19.getContainer)(elementId);
|
|
5857
5919
|
if (!element) {
|
|
5858
5920
|
throw new Error(`Element with ID ${elementId} not found.`);
|
|
5859
5921
|
}
|
|
5860
5922
|
const elementType = element.model.get("widgetType") || element.model.get("elType") || "";
|
|
5861
|
-
const widgetData = (0,
|
|
5923
|
+
const widgetData = (0, import_editor_elements19.getWidgetsCache)()?.[elementType];
|
|
5862
5924
|
if (!widgetData) {
|
|
5863
5925
|
throw new Error(
|
|
5864
5926
|
`Unknown element type: ${elementType}. Check the available-widgets resource for valid types.`
|
|
@@ -5870,7 +5932,7 @@ var initGetElementConfigTool = (reg) => {
|
|
|
5870
5932
|
);
|
|
5871
5933
|
}
|
|
5872
5934
|
const elementRawSettings = element.settings;
|
|
5873
|
-
const propSchema = (0,
|
|
5935
|
+
const propSchema = (0, import_editor_elements19.getWidgetsCache)()?.[elementType]?.atomic_props_schema;
|
|
5874
5936
|
if (!elementRawSettings || !propSchema) {
|
|
5875
5937
|
throw new Error(`No settings or prop schema found for element ID: ${elementId}`);
|
|
5876
5938
|
}
|
|
@@ -5879,7 +5941,7 @@ var initGetElementConfigTool = (reg) => {
|
|
|
5879
5941
|
import_editor_props10.Schema.configurableKeys(propSchema).forEach((key) => {
|
|
5880
5942
|
propValues[key] = structuredClone(elementRawSettings.get(key));
|
|
5881
5943
|
});
|
|
5882
|
-
const elementStyles = (0,
|
|
5944
|
+
const elementStyles = (0, import_editor_elements19.getElementStyles)(elementId) || {};
|
|
5883
5945
|
const localStyle = Object.values(elementStyles).find((style) => style.label === "local");
|
|
5884
5946
|
if (localStyle) {
|
|
5885
5947
|
const defaultVariant = localStyle.variants.find(
|
|
@@ -6035,7 +6097,7 @@ Note: The "size" property controls image resolution/loading, not visual size. Se
|
|
|
6035
6097
|
`;
|
|
6036
6098
|
|
|
6037
6099
|
// src/prevent-link-in-link-commands.ts
|
|
6038
|
-
var
|
|
6100
|
+
var import_editor_elements20 = require("@elementor/editor-elements");
|
|
6039
6101
|
var import_editor_notifications3 = require("@elementor/editor-notifications");
|
|
6040
6102
|
var import_editor_v1_adapters22 = require("@elementor/editor-v1-adapters");
|
|
6041
6103
|
var import_i18n4 = require("@wordpress/i18n");
|
|
@@ -6106,24 +6168,24 @@ function shouldBlock(sourceElements, targetElements) {
|
|
|
6106
6168
|
return false;
|
|
6107
6169
|
}
|
|
6108
6170
|
const isSourceContainsAnAnchor = sourceElements.some((src) => {
|
|
6109
|
-
return src?.id ? (0,
|
|
6171
|
+
return src?.id ? (0, import_editor_elements20.isElementAnchored)(src.id) || !!(0, import_editor_elements20.getAnchoredDescendantId)(src.id) : false;
|
|
6110
6172
|
});
|
|
6111
6173
|
if (!isSourceContainsAnAnchor) {
|
|
6112
6174
|
return false;
|
|
6113
6175
|
}
|
|
6114
6176
|
const isTargetContainsAnAnchor = targetElements.some((target) => {
|
|
6115
|
-
return target?.id ? (0,
|
|
6177
|
+
return target?.id ? (0, import_editor_elements20.isElementAnchored)(target.id) || !!(0, import_editor_elements20.getAnchoredAncestorId)(target.id) : false;
|
|
6116
6178
|
});
|
|
6117
6179
|
return isTargetContainsAnAnchor;
|
|
6118
6180
|
}
|
|
6119
6181
|
|
|
6120
6182
|
// src/style-commands/paste-style.ts
|
|
6121
|
-
var
|
|
6183
|
+
var import_editor_elements23 = require("@elementor/editor-elements");
|
|
6122
6184
|
var import_editor_props13 = require("@elementor/editor-props");
|
|
6123
6185
|
var import_editor_v1_adapters24 = require("@elementor/editor-v1-adapters");
|
|
6124
6186
|
|
|
6125
6187
|
// src/utils/command-utils.ts
|
|
6126
|
-
var
|
|
6188
|
+
var import_editor_elements21 = require("@elementor/editor-elements");
|
|
6127
6189
|
var import_editor_props12 = require("@elementor/editor-props");
|
|
6128
6190
|
var import_i18n5 = require("@wordpress/i18n");
|
|
6129
6191
|
function hasAtomicWidgets(args) {
|
|
@@ -6148,7 +6210,7 @@ function getClassesProp(container) {
|
|
|
6148
6210
|
}
|
|
6149
6211
|
function getContainerSchema(container) {
|
|
6150
6212
|
const type = container?.model.get("widgetType") || container?.model.get("elType");
|
|
6151
|
-
const widgetsCache = (0,
|
|
6213
|
+
const widgetsCache = (0, import_editor_elements21.getWidgetsCache)();
|
|
6152
6214
|
const elementType = widgetsCache?.[type];
|
|
6153
6215
|
return elementType?.atomic_props_schema ?? null;
|
|
6154
6216
|
}
|
|
@@ -6161,11 +6223,11 @@ function getClipboardElements(storageKey = "clipboard") {
|
|
|
6161
6223
|
}
|
|
6162
6224
|
}
|
|
6163
6225
|
function getTitleForContainers(containers) {
|
|
6164
|
-
return containers.length > 1 ? (0, import_i18n5.__)("Elements", "elementor") : (0,
|
|
6226
|
+
return containers.length > 1 ? (0, import_i18n5.__)("Elements", "elementor") : (0, import_editor_elements21.getElementLabel)(containers[0].id);
|
|
6165
6227
|
}
|
|
6166
6228
|
|
|
6167
6229
|
// src/style-commands/undoable-actions/paste-element-style.ts
|
|
6168
|
-
var
|
|
6230
|
+
var import_editor_elements22 = require("@elementor/editor-elements");
|
|
6169
6231
|
var import_editor_styles_repository4 = require("@elementor/editor-styles-repository");
|
|
6170
6232
|
var import_editor_v1_adapters23 = require("@elementor/editor-v1-adapters");
|
|
6171
6233
|
var import_i18n6 = require("@wordpress/i18n");
|
|
@@ -6178,7 +6240,7 @@ var undoablePasteElementStyle = () => (0, import_editor_v1_adapters23.undoable)(
|
|
|
6178
6240
|
if (!classesProp) {
|
|
6179
6241
|
return null;
|
|
6180
6242
|
}
|
|
6181
|
-
const originalStyles = (0,
|
|
6243
|
+
const originalStyles = (0, import_editor_elements22.getElementStyles)(container.id);
|
|
6182
6244
|
const [styleId, styleDef] = Object.entries(originalStyles ?? {})[0] ?? [];
|
|
6183
6245
|
const originalStyle = Object.keys(styleDef ?? {}).length ? styleDef : null;
|
|
6184
6246
|
const revertData = {
|
|
@@ -6187,7 +6249,7 @@ var undoablePasteElementStyle = () => (0, import_editor_v1_adapters23.undoable)(
|
|
|
6187
6249
|
};
|
|
6188
6250
|
if (styleId) {
|
|
6189
6251
|
newStyle.variants.forEach(({ meta, props, custom_css: customCss }) => {
|
|
6190
|
-
(0,
|
|
6252
|
+
(0, import_editor_elements22.updateElementStyle)({
|
|
6191
6253
|
elementId,
|
|
6192
6254
|
styleId,
|
|
6193
6255
|
meta,
|
|
@@ -6198,7 +6260,7 @@ var undoablePasteElementStyle = () => (0, import_editor_v1_adapters23.undoable)(
|
|
|
6198
6260
|
} else {
|
|
6199
6261
|
const [firstVariant] = newStyle.variants;
|
|
6200
6262
|
const additionalVariants = newStyle.variants.slice(1);
|
|
6201
|
-
revertData.styleId = (0,
|
|
6263
|
+
revertData.styleId = (0, import_editor_elements22.createElementStyle)({
|
|
6202
6264
|
elementId,
|
|
6203
6265
|
classesProp,
|
|
6204
6266
|
label: import_editor_styles_repository4.ELEMENTS_STYLES_RESERVED_LABEL,
|
|
@@ -6216,7 +6278,7 @@ var undoablePasteElementStyle = () => (0, import_editor_v1_adapters23.undoable)(
|
|
|
6216
6278
|
return;
|
|
6217
6279
|
}
|
|
6218
6280
|
if (!revertData.originalStyle) {
|
|
6219
|
-
(0,
|
|
6281
|
+
(0, import_editor_elements22.deleteElementStyle)(container.id, revertData.styleId);
|
|
6220
6282
|
return;
|
|
6221
6283
|
}
|
|
6222
6284
|
const classesProp = getClassesProp(container);
|
|
@@ -6225,7 +6287,7 @@ var undoablePasteElementStyle = () => (0, import_editor_v1_adapters23.undoable)(
|
|
|
6225
6287
|
}
|
|
6226
6288
|
const [firstVariant] = revertData.originalStyle.variants;
|
|
6227
6289
|
const additionalVariants = revertData.originalStyle.variants.slice(1);
|
|
6228
|
-
(0,
|
|
6290
|
+
(0, import_editor_elements22.createElementStyle)({
|
|
6229
6291
|
elementId: container.id,
|
|
6230
6292
|
classesProp,
|
|
6231
6293
|
label: import_editor_styles_repository4.ELEMENTS_STYLES_RESERVED_LABEL,
|
|
@@ -6262,7 +6324,7 @@ function pasteStyles(args, pasteLocalStyle) {
|
|
|
6262
6324
|
}
|
|
6263
6325
|
const clipboardElements = getClipboardElements(storageKey);
|
|
6264
6326
|
const [clipboardElement] = clipboardElements ?? [];
|
|
6265
|
-
const clipboardContainer = (0,
|
|
6327
|
+
const clipboardContainer = (0, import_editor_elements23.getContainer)(clipboardElement.id);
|
|
6266
6328
|
if (!clipboardElement || !clipboardContainer || !isAtomicWidget(clipboardContainer)) {
|
|
6267
6329
|
return;
|
|
6268
6330
|
}
|
|
@@ -6281,7 +6343,7 @@ function getClassesWithoutLocalStyle(clipboardContainer, style) {
|
|
|
6281
6343
|
if (!classesProp) {
|
|
6282
6344
|
return [];
|
|
6283
6345
|
}
|
|
6284
|
-
const classesSetting = (0,
|
|
6346
|
+
const classesSetting = (0, import_editor_elements23.getElementSetting)(clipboardContainer.id, classesProp);
|
|
6285
6347
|
return classesSetting?.value.filter((styleId) => styleId !== style?.id) ?? [];
|
|
6286
6348
|
}
|
|
6287
6349
|
function pasteClasses(containers, classes) {
|
|
@@ -6290,10 +6352,10 @@ function pasteClasses(containers, classes) {
|
|
|
6290
6352
|
if (!classesProp) {
|
|
6291
6353
|
return;
|
|
6292
6354
|
}
|
|
6293
|
-
const classesSetting = (0,
|
|
6355
|
+
const classesSetting = (0, import_editor_elements23.getElementSetting)(container.id, classesProp);
|
|
6294
6356
|
const currentClasses = import_editor_props13.classesPropTypeUtil.extract(classesSetting) ?? [];
|
|
6295
6357
|
const newClasses = import_editor_props13.classesPropTypeUtil.create(Array.from(/* @__PURE__ */ new Set([...classes, ...currentClasses])));
|
|
6296
|
-
(0,
|
|
6358
|
+
(0, import_editor_elements23.updateElementSettings)({
|
|
6297
6359
|
id: container.id,
|
|
6298
6360
|
props: { [classesProp]: newClasses }
|
|
6299
6361
|
});
|
|
@@ -6304,7 +6366,7 @@ function pasteClasses(containers, classes) {
|
|
|
6304
6366
|
var import_editor_v1_adapters26 = require("@elementor/editor-v1-adapters");
|
|
6305
6367
|
|
|
6306
6368
|
// src/style-commands/undoable-actions/reset-element-style.ts
|
|
6307
|
-
var
|
|
6369
|
+
var import_editor_elements24 = require("@elementor/editor-elements");
|
|
6308
6370
|
var import_editor_styles_repository5 = require("@elementor/editor-styles-repository");
|
|
6309
6371
|
var import_editor_v1_adapters25 = require("@elementor/editor-v1-adapters");
|
|
6310
6372
|
var import_i18n7 = require("@wordpress/i18n");
|
|
@@ -6313,9 +6375,9 @@ var undoableResetElementStyle = () => (0, import_editor_v1_adapters25.undoable)(
|
|
|
6313
6375
|
do: ({ containers }) => {
|
|
6314
6376
|
return containers.map((container) => {
|
|
6315
6377
|
const elementId = container.model.get("id");
|
|
6316
|
-
const containerStyles = (0,
|
|
6378
|
+
const containerStyles = (0, import_editor_elements24.getElementStyles)(elementId);
|
|
6317
6379
|
Object.keys(containerStyles ?? {}).forEach(
|
|
6318
|
-
(styleId) => (0,
|
|
6380
|
+
(styleId) => (0, import_editor_elements24.deleteElementStyle)(elementId, styleId)
|
|
6319
6381
|
);
|
|
6320
6382
|
return containerStyles;
|
|
6321
6383
|
});
|
|
@@ -6331,7 +6393,7 @@ var undoableResetElementStyle = () => (0, import_editor_v1_adapters25.undoable)(
|
|
|
6331
6393
|
Object.entries(containerStyles ?? {}).forEach(([styleId, style]) => {
|
|
6332
6394
|
const [firstVariant] = style.variants;
|
|
6333
6395
|
const additionalVariants = style.variants.slice(1);
|
|
6334
|
-
(0,
|
|
6396
|
+
(0, import_editor_elements24.createElementStyle)({
|
|
6335
6397
|
elementId,
|
|
6336
6398
|
classesProp,
|
|
6337
6399
|
styleId,
|
|
@@ -6531,10 +6593,10 @@ function useEscapeOnCanvas(canvasDocument, onEscape) {
|
|
|
6531
6593
|
}
|
|
6532
6594
|
|
|
6533
6595
|
// src/utils/after-render.ts
|
|
6534
|
-
var
|
|
6596
|
+
var import_editor_elements25 = require("@elementor/editor-elements");
|
|
6535
6597
|
function doAfterRender(elementIds, callback) {
|
|
6536
6598
|
const pending = elementIds.map((elementId) => {
|
|
6537
|
-
const view = (0,
|
|
6599
|
+
const view = (0, import_editor_elements25.getContainer)(elementId)?.view;
|
|
6538
6600
|
if (!view || !hasDoAfterRender(view)) {
|
|
6539
6601
|
return void 0;
|
|
6540
6602
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -4164,7 +4164,7 @@ function extractElementData(element) {
|
|
|
4164
4164
|
widgetType: model.widgetType || void 0,
|
|
4165
4165
|
version: resolveElementVersion(element)
|
|
4166
4166
|
};
|
|
4167
|
-
const title = model.title || element.model?.editor_settings?.title;
|
|
4167
|
+
const title = model.title || element.model?.editor_settings?.title || element.model.getTitle?.();
|
|
4168
4168
|
if (title) {
|
|
4169
4169
|
result.title = title;
|
|
4170
4170
|
}
|
|
@@ -4599,7 +4599,7 @@ import {
|
|
|
4599
4599
|
createElement as createElement13,
|
|
4600
4600
|
deleteElement as deleteElement2,
|
|
4601
4601
|
getContainer as getContainer5,
|
|
4602
|
-
getWidgetsCache as
|
|
4602
|
+
getWidgetsCache as getWidgetsCache9
|
|
4603
4603
|
} from "@elementor/editor-elements";
|
|
4604
4604
|
|
|
4605
4605
|
// src/composition-builder/composition-builder.ts
|
|
@@ -4608,14 +4608,14 @@ import {
|
|
|
4608
4608
|
deleteElement,
|
|
4609
4609
|
generateElementId as generateElementId2,
|
|
4610
4610
|
getContainer as getContainer4,
|
|
4611
|
-
getWidgetsCache as
|
|
4611
|
+
getWidgetsCache as getWidgetsCache8
|
|
4612
4612
|
} from "@elementor/editor-elements";
|
|
4613
4613
|
|
|
4614
4614
|
// src/mcp/utils/do-update-element-property.ts
|
|
4615
4615
|
import {
|
|
4616
4616
|
createElementStyle,
|
|
4617
4617
|
getElementStyles,
|
|
4618
|
-
getWidgetsCache as
|
|
4618
|
+
getWidgetsCache as getWidgetsCache7,
|
|
4619
4619
|
updateElementSettings,
|
|
4620
4620
|
updateElementStyle
|
|
4621
4621
|
} from "@elementor/editor-elements";
|
|
@@ -4637,6 +4637,58 @@ var readStoredCustomCssText = (raw) => {
|
|
|
4637
4637
|
}
|
|
4638
4638
|
};
|
|
4639
4639
|
|
|
4640
|
+
// src/mcp/utils/resolve-canonical-prop-name.ts
|
|
4641
|
+
import { getWidgetsCache as getWidgetsCache6 } from "@elementor/editor-elements";
|
|
4642
|
+
function buildAliasToCanonicalMap(schema2) {
|
|
4643
|
+
const aliasToCanonical = {};
|
|
4644
|
+
for (const [canonical, propType] of Object.entries(schema2)) {
|
|
4645
|
+
const aliases = propType.meta?.aliases;
|
|
4646
|
+
if (!Array.isArray(aliases)) {
|
|
4647
|
+
continue;
|
|
4648
|
+
}
|
|
4649
|
+
for (const alias of aliases) {
|
|
4650
|
+
if (typeof alias === "string" && alias) {
|
|
4651
|
+
aliasToCanonical[alias] = canonical;
|
|
4652
|
+
}
|
|
4653
|
+
}
|
|
4654
|
+
}
|
|
4655
|
+
return aliasToCanonical;
|
|
4656
|
+
}
|
|
4657
|
+
function resolveCanonicalPropName(elementType, propertyName) {
|
|
4658
|
+
const schema2 = getWidgetsCache6()?.[elementType]?.atomic_props_schema;
|
|
4659
|
+
if (!schema2 || schema2[propertyName]) {
|
|
4660
|
+
return propertyName;
|
|
4661
|
+
}
|
|
4662
|
+
return buildAliasToCanonicalMap(schema2)[propertyName] ?? propertyName;
|
|
4663
|
+
}
|
|
4664
|
+
function resolveCanonicalPropKeys(elementType, props) {
|
|
4665
|
+
const schema2 = getWidgetsCache6()?.[elementType]?.atomic_props_schema;
|
|
4666
|
+
if (!schema2) {
|
|
4667
|
+
return { ...props };
|
|
4668
|
+
}
|
|
4669
|
+
const aliasToCanonical = buildAliasToCanonicalMap(schema2);
|
|
4670
|
+
const resolved = {};
|
|
4671
|
+
for (const [key, value] of Object.entries(props)) {
|
|
4672
|
+
if (schema2[key]) {
|
|
4673
|
+
resolved[key] = value;
|
|
4674
|
+
}
|
|
4675
|
+
}
|
|
4676
|
+
for (const [key, value] of Object.entries(props)) {
|
|
4677
|
+
if (schema2[key]) {
|
|
4678
|
+
continue;
|
|
4679
|
+
}
|
|
4680
|
+
const canonical = aliasToCanonical[key];
|
|
4681
|
+
if (!canonical) {
|
|
4682
|
+
resolved[key] = value;
|
|
4683
|
+
continue;
|
|
4684
|
+
}
|
|
4685
|
+
if (!Object.prototype.hasOwnProperty.call(resolved, canonical)) {
|
|
4686
|
+
resolved[canonical] = value;
|
|
4687
|
+
}
|
|
4688
|
+
}
|
|
4689
|
+
return resolved;
|
|
4690
|
+
}
|
|
4691
|
+
|
|
4640
4692
|
// src/mcp/utils/do-update-element-property.ts
|
|
4641
4693
|
var LOCAL_STYLE_META = {
|
|
4642
4694
|
breakpoint: "desktop",
|
|
@@ -4653,7 +4705,8 @@ function resolvePropValue(value, forceKey) {
|
|
|
4653
4705
|
});
|
|
4654
4706
|
}
|
|
4655
4707
|
var doUpdateElementProperty = (params) => {
|
|
4656
|
-
const { elementId,
|
|
4708
|
+
const { elementId, propertyValue, elementType, customCssWriteMode = "replace" } = params;
|
|
4709
|
+
const propertyName = params.propertyName === "_styles" ? params.propertyName : resolveCanonicalPropName(elementType, params.propertyName);
|
|
4657
4710
|
if (propertyName === "_styles") {
|
|
4658
4711
|
const elementStyles = getElementStyles(elementId) || {};
|
|
4659
4712
|
const propertyMapValue = propertyValue;
|
|
@@ -4741,7 +4794,7 @@ var doUpdateElementProperty = (params) => {
|
|
|
4741
4794
|
}
|
|
4742
4795
|
return;
|
|
4743
4796
|
}
|
|
4744
|
-
const elementPropSchema =
|
|
4797
|
+
const elementPropSchema = getWidgetsCache7()?.[elementType]?.atomic_props_schema;
|
|
4745
4798
|
if (!elementPropSchema) {
|
|
4746
4799
|
throw new Error(`No prop schema found for element type: ${elementType}`);
|
|
4747
4800
|
}
|
|
@@ -4824,7 +4877,7 @@ var CompositionBuilder = class _CompositionBuilder {
|
|
|
4824
4877
|
api = {
|
|
4825
4878
|
createElement: createElement12,
|
|
4826
4879
|
deleteElement,
|
|
4827
|
-
getWidgetsCache:
|
|
4880
|
+
getWidgetsCache: getWidgetsCache8,
|
|
4828
4881
|
generateElementId: generateElementId2,
|
|
4829
4882
|
getContainer: getContainer4,
|
|
4830
4883
|
doUpdateElementProperty
|
|
@@ -5346,7 +5399,7 @@ var initBuildCompositionsTool = (reg) => {
|
|
|
5346
5399
|
const { xmlStructure, elementConfig, stylesConfig } = adaptLeafRootParams({
|
|
5347
5400
|
...rawParams,
|
|
5348
5401
|
stylesConfig: convertedStyles,
|
|
5349
|
-
widgetsCache:
|
|
5402
|
+
widgetsCache: getWidgetsCache9() ?? {}
|
|
5350
5403
|
});
|
|
5351
5404
|
let generatedXML = "";
|
|
5352
5405
|
const errors = [];
|
|
@@ -5358,7 +5411,7 @@ var initBuildCompositionsTool = (reg) => {
|
|
|
5358
5411
|
const compositionBuilder = CompositionBuilder.fromXMLString(xmlStructure, {
|
|
5359
5412
|
createElement: createElement13,
|
|
5360
5413
|
deleteElement: deleteElement2,
|
|
5361
|
-
getWidgetsCache:
|
|
5414
|
+
getWidgetsCache: getWidgetsCache9
|
|
5362
5415
|
});
|
|
5363
5416
|
compositionBuilder.setElementConfig(elementConfig);
|
|
5364
5417
|
compositionBuilder.setStylesConfig(stylesConfig);
|
|
@@ -5443,7 +5496,7 @@ function assertCompositionXmlUsesV4WidgetsOnly(xmlStructure) {
|
|
|
5443
5496
|
if (doc.querySelector("parsererror")) {
|
|
5444
5497
|
throw new Error("Failed to parse XML string: " + doc);
|
|
5445
5498
|
}
|
|
5446
|
-
const widgetsCache =
|
|
5499
|
+
const widgetsCache = getWidgetsCache9() ?? {};
|
|
5447
5500
|
for (const node of doc.querySelectorAll("*")) {
|
|
5448
5501
|
const type = node.tagName;
|
|
5449
5502
|
const widgetData = widgetsCache[type];
|
|
@@ -5460,10 +5513,10 @@ function assertCompositionXmlUsesV4WidgetsOnly(xmlStructure) {
|
|
|
5460
5513
|
}
|
|
5461
5514
|
|
|
5462
5515
|
// src/mcp/tools/configure-element/tool.ts
|
|
5463
|
-
import { getWidgetsCache as
|
|
5516
|
+
import { getContainer as getContainer6, getWidgetsCache as getWidgetsCache11 } from "@elementor/editor-elements";
|
|
5464
5517
|
|
|
5465
5518
|
// src/mcp/utils/validate-input.ts
|
|
5466
|
-
import { getWidgetsCache as
|
|
5519
|
+
import { getWidgetsCache as getWidgetsCache10 } from "@elementor/editor-elements";
|
|
5467
5520
|
import { Schema as Schema4 } from "@elementor/editor-props";
|
|
5468
5521
|
import { getStylesSchema as getStylesSchema3 } from "@elementor/editor-styles";
|
|
5469
5522
|
var _widgetsSchema = null;
|
|
@@ -5471,7 +5524,7 @@ var validateInput = {
|
|
|
5471
5524
|
get widgetsSchema() {
|
|
5472
5525
|
if (!_widgetsSchema) {
|
|
5473
5526
|
const schema2 = {};
|
|
5474
|
-
const cache =
|
|
5527
|
+
const cache = getWidgetsCache10();
|
|
5475
5528
|
if (!cache) {
|
|
5476
5529
|
return {};
|
|
5477
5530
|
}
|
|
@@ -5712,19 +5765,28 @@ var initConfigureElementTool = (reg) => {
|
|
|
5712
5765
|
{ description: "Dynamic tags catalog", uri: DYNAMIC_TAGS_URI }
|
|
5713
5766
|
],
|
|
5714
5767
|
handler: async ({ elementId, propertiesToChange, elementType, style }) => {
|
|
5715
|
-
const widgetData =
|
|
5768
|
+
const widgetData = getWidgetsCache11()?.[elementType];
|
|
5716
5769
|
if (!widgetData) {
|
|
5717
5770
|
throw new Error(
|
|
5718
5771
|
`Unknown element type: ${elementType}. Check the available-widgets resource for valid types.`
|
|
5719
5772
|
);
|
|
5720
5773
|
}
|
|
5774
|
+
const container = getContainer6(elementId);
|
|
5775
|
+
if (!container) {
|
|
5776
|
+
throw new Error(`Element with id ${elementId} not found`);
|
|
5777
|
+
}
|
|
5778
|
+
const isElementTypeMatchingId = container.settings.get("widgetType") === elementType || container.type === elementType;
|
|
5779
|
+
if (!isElementTypeMatchingId) {
|
|
5780
|
+
throw new Error(`Element with ID ${elementId} is not of type ${elementType}`);
|
|
5781
|
+
}
|
|
5721
5782
|
if (!widgetData.atomic_props_schema) {
|
|
5722
5783
|
throw new Error(
|
|
5723
5784
|
`This tool does not support V3 elements. Please use the elementor-v3-mcp tools instead for element type: ${elementType}`
|
|
5724
5785
|
);
|
|
5725
5786
|
}
|
|
5726
|
-
const
|
|
5727
|
-
const
|
|
5787
|
+
const propertiesToUpdate = resolveCanonicalPropKeys(elementType, propertiesToChange);
|
|
5788
|
+
const toUpdate = Object.entries(propertiesToUpdate);
|
|
5789
|
+
const { valid, errors } = validateInput.validatePropSchema(elementType, propertiesToUpdate);
|
|
5728
5790
|
if (!valid) {
|
|
5729
5791
|
const errorMessage = `Failed to configure element "${elementId}" due to invalid properties: ${errors?.join(
|
|
5730
5792
|
"\n- "
|
|
@@ -5804,7 +5866,7 @@ Provide styling as raw CSS via the "style" parameter (a flat map of CSS property
|
|
|
5804
5866
|
}
|
|
5805
5867
|
|
|
5806
5868
|
// src/mcp/tools/get-element-config/tool.ts
|
|
5807
|
-
import { getContainer as
|
|
5869
|
+
import { getContainer as getContainer7, getElementStyles as getElementStyles2, getWidgetsCache as getWidgetsCache12 } from "@elementor/editor-elements";
|
|
5808
5870
|
import { Schema as Schema5 } from "@elementor/editor-props";
|
|
5809
5871
|
import { z as z3 } from "@elementor/schema";
|
|
5810
5872
|
var schema = {
|
|
@@ -5839,12 +5901,12 @@ var initGetElementConfigTool = (reg) => {
|
|
|
5839
5901
|
schema,
|
|
5840
5902
|
outputSchema: outputSchema3,
|
|
5841
5903
|
handler: async ({ elementId }) => {
|
|
5842
|
-
const element =
|
|
5904
|
+
const element = getContainer7(elementId);
|
|
5843
5905
|
if (!element) {
|
|
5844
5906
|
throw new Error(`Element with ID ${elementId} not found.`);
|
|
5845
5907
|
}
|
|
5846
5908
|
const elementType = element.model.get("widgetType") || element.model.get("elType") || "";
|
|
5847
|
-
const widgetData =
|
|
5909
|
+
const widgetData = getWidgetsCache12()?.[elementType];
|
|
5848
5910
|
if (!widgetData) {
|
|
5849
5911
|
throw new Error(
|
|
5850
5912
|
`Unknown element type: ${elementType}. Check the available-widgets resource for valid types.`
|
|
@@ -5856,7 +5918,7 @@ var initGetElementConfigTool = (reg) => {
|
|
|
5856
5918
|
);
|
|
5857
5919
|
}
|
|
5858
5920
|
const elementRawSettings = element.settings;
|
|
5859
|
-
const propSchema =
|
|
5921
|
+
const propSchema = getWidgetsCache12()?.[elementType]?.atomic_props_schema;
|
|
5860
5922
|
if (!elementRawSettings || !propSchema) {
|
|
5861
5923
|
throw new Error(`No settings or prop schema found for element ID: ${elementId}`);
|
|
5862
5924
|
}
|
|
@@ -6108,7 +6170,7 @@ function shouldBlock(sourceElements, targetElements) {
|
|
|
6108
6170
|
}
|
|
6109
6171
|
|
|
6110
6172
|
// src/style-commands/paste-style.ts
|
|
6111
|
-
import { getContainer as
|
|
6173
|
+
import { getContainer as getContainer8, getElementSetting, updateElementSettings as updateElementSettings2 } from "@elementor/editor-elements";
|
|
6112
6174
|
import { classesPropTypeUtil } from "@elementor/editor-props";
|
|
6113
6175
|
import {
|
|
6114
6176
|
__privateListenTo as listenTo5,
|
|
@@ -6117,7 +6179,7 @@ import {
|
|
|
6117
6179
|
} from "@elementor/editor-v1-adapters";
|
|
6118
6180
|
|
|
6119
6181
|
// src/utils/command-utils.ts
|
|
6120
|
-
import { getElementLabel as getElementLabel2, getWidgetsCache as
|
|
6182
|
+
import { getElementLabel as getElementLabel2, getWidgetsCache as getWidgetsCache13 } from "@elementor/editor-elements";
|
|
6121
6183
|
import { CLASSES_PROP_KEY } from "@elementor/editor-props";
|
|
6122
6184
|
import { __ as __5 } from "@wordpress/i18n";
|
|
6123
6185
|
function hasAtomicWidgets(args) {
|
|
@@ -6142,7 +6204,7 @@ function getClassesProp(container) {
|
|
|
6142
6204
|
}
|
|
6143
6205
|
function getContainerSchema(container) {
|
|
6144
6206
|
const type = container?.model.get("widgetType") || container?.model.get("elType");
|
|
6145
|
-
const widgetsCache =
|
|
6207
|
+
const widgetsCache = getWidgetsCache13();
|
|
6146
6208
|
const elementType = widgetsCache?.[type];
|
|
6147
6209
|
return elementType?.atomic_props_schema ?? null;
|
|
6148
6210
|
}
|
|
@@ -6261,7 +6323,7 @@ function pasteStyles(args, pasteLocalStyle) {
|
|
|
6261
6323
|
}
|
|
6262
6324
|
const clipboardElements = getClipboardElements(storageKey);
|
|
6263
6325
|
const [clipboardElement] = clipboardElements ?? [];
|
|
6264
|
-
const clipboardContainer =
|
|
6326
|
+
const clipboardContainer = getContainer8(clipboardElement.id);
|
|
6265
6327
|
if (!clipboardElement || !clipboardContainer || !isAtomicWidget(clipboardContainer)) {
|
|
6266
6328
|
return;
|
|
6267
6329
|
}
|
|
@@ -6538,10 +6600,10 @@ function useEscapeOnCanvas(canvasDocument, onEscape) {
|
|
|
6538
6600
|
}
|
|
6539
6601
|
|
|
6540
6602
|
// src/utils/after-render.ts
|
|
6541
|
-
import { getContainer as
|
|
6603
|
+
import { getContainer as getContainer9 } from "@elementor/editor-elements";
|
|
6542
6604
|
function doAfterRender(elementIds, callback) {
|
|
6543
6605
|
const pending = elementIds.map((elementId) => {
|
|
6544
|
-
const view =
|
|
6606
|
+
const view = getContainer9(elementId)?.view;
|
|
6545
6607
|
if (!view || !hasDoAfterRender(view)) {
|
|
6546
6608
|
return void 0;
|
|
6547
6609
|
}
|
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.2.0-
|
|
4
|
+
"version": "4.2.0-939",
|
|
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.2.0-
|
|
40
|
+
"@elementor/editor": "4.2.0-939",
|
|
41
41
|
"dompurify": "^3.2.6",
|
|
42
|
-
"@elementor/editor-controls": "4.2.0-
|
|
43
|
-
"@elementor/editor-documents": "4.2.0-
|
|
44
|
-
"@elementor/editor-elements": "4.2.0-
|
|
45
|
-
"@elementor/editor-interactions": "4.2.0-
|
|
46
|
-
"@elementor/editor-mcp": "4.2.0-
|
|
47
|
-
"@elementor/editor-notifications": "4.2.0-
|
|
48
|
-
"@elementor/editor-props": "4.2.0-
|
|
49
|
-
"@elementor/editor-responsive": "4.2.0-
|
|
50
|
-
"@elementor/editor-styles": "4.2.0-
|
|
51
|
-
"@elementor/editor-styles-repository": "4.2.0-
|
|
52
|
-
"@elementor/editor-ui": "4.2.0-
|
|
53
|
-
"@elementor/editor-v1-adapters": "4.2.0-
|
|
54
|
-
"@elementor/http-client": "4.2.0-
|
|
55
|
-
"@elementor/schema": "4.2.0-
|
|
56
|
-
"@elementor/twing": "4.2.0-
|
|
42
|
+
"@elementor/editor-controls": "4.2.0-939",
|
|
43
|
+
"@elementor/editor-documents": "4.2.0-939",
|
|
44
|
+
"@elementor/editor-elements": "4.2.0-939",
|
|
45
|
+
"@elementor/editor-interactions": "4.2.0-939",
|
|
46
|
+
"@elementor/editor-mcp": "4.2.0-939",
|
|
47
|
+
"@elementor/editor-notifications": "4.2.0-939",
|
|
48
|
+
"@elementor/editor-props": "4.2.0-939",
|
|
49
|
+
"@elementor/editor-responsive": "4.2.0-939",
|
|
50
|
+
"@elementor/editor-styles": "4.2.0-939",
|
|
51
|
+
"@elementor/editor-styles-repository": "4.2.0-939",
|
|
52
|
+
"@elementor/editor-ui": "4.2.0-939",
|
|
53
|
+
"@elementor/editor-v1-adapters": "4.2.0-939",
|
|
54
|
+
"@elementor/http-client": "4.2.0-939",
|
|
55
|
+
"@elementor/schema": "4.2.0-939",
|
|
56
|
+
"@elementor/twing": "4.2.0-939",
|
|
57
57
|
"@elementor/ui": "1.37.5",
|
|
58
|
-
"@elementor/utils": "4.2.0-
|
|
59
|
-
"@elementor/wp-media": "4.2.0-
|
|
58
|
+
"@elementor/utils": "4.2.0-939",
|
|
59
|
+
"@elementor/wp-media": "4.2.0-939",
|
|
60
60
|
"@floating-ui/react": "^0.27.5",
|
|
61
61
|
"@wordpress/i18n": "^5.13.0"
|
|
62
62
|
},
|
|
@@ -136,7 +136,10 @@ function extractElementData( element: UnknownVersionElementInstanceData ): Recor
|
|
|
136
136
|
version: resolveElementVersion( element ),
|
|
137
137
|
};
|
|
138
138
|
|
|
139
|
-
const title =
|
|
139
|
+
const title =
|
|
140
|
+
model.title ||
|
|
141
|
+
element.model?.editor_settings?.title ||
|
|
142
|
+
( element.model as unknown as Record< string, CallableFunction > ).getTitle?.();
|
|
140
143
|
|
|
141
144
|
if ( title ) {
|
|
142
145
|
result.title = title;
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import { getWidgetsCache } from '@elementor/editor-elements';
|
|
1
|
+
import { getContainer, getWidgetsCache } from '@elementor/editor-elements';
|
|
2
2
|
import { type MCPRegistryEntry } from '@elementor/editor-mcp';
|
|
3
|
+
import { type PropValue } from '@elementor/editor-props';
|
|
3
4
|
|
|
4
5
|
import { DYNAMIC_TAGS_URI } from '../../resources/dynamic-tags-resource';
|
|
5
6
|
import { WIDGET_SCHEMA_URI } from '../../resources/widgets-schema-resource';
|
|
6
7
|
import { convertCssToAtomic } from '../../utils/convert-css-to-atomic';
|
|
7
8
|
import { doUpdateElementProperty } from '../../utils/do-update-element-property';
|
|
9
|
+
import { resolveCanonicalPropKeys } from '../../utils/resolve-canonical-prop-name';
|
|
8
10
|
import { validateInput } from '../../utils/validate-input';
|
|
9
11
|
import { CONFIGURE_ELEMENT_GUIDE_URI, generatePrompt } from './prompt';
|
|
10
12
|
import { inputSchema as schema, outputSchema } from './schema';
|
|
@@ -42,20 +44,31 @@ export const initConfigureElementTool = ( reg: MCPRegistryEntry ) => {
|
|
|
42
44
|
`Unknown element type: ${ elementType }. Check the available-widgets resource for valid types.`
|
|
43
45
|
);
|
|
44
46
|
}
|
|
47
|
+
const container = getContainer( elementId );
|
|
48
|
+
if ( ! container ) {
|
|
49
|
+
throw new Error( `Element with id ${ elementId } not found` );
|
|
50
|
+
}
|
|
51
|
+
const isElementTypeMatchingId =
|
|
52
|
+
container.settings.get( 'widgetType' ) === elementType ||
|
|
53
|
+
( container as Record< string, unknown > ).type === elementType;
|
|
54
|
+
if ( ! isElementTypeMatchingId ) {
|
|
55
|
+
throw new Error( `Element with ID ${ elementId } is not of type ${ elementType }` );
|
|
56
|
+
}
|
|
45
57
|
if ( ! widgetData.atomic_props_schema ) {
|
|
46
58
|
throw new Error(
|
|
47
59
|
`This tool does not support V3 elements. Please use the elementor-v3-mcp tools instead for element type: ${ elementType }`
|
|
48
60
|
);
|
|
49
61
|
}
|
|
50
|
-
const
|
|
51
|
-
const
|
|
62
|
+
const propertiesToUpdate = resolveCanonicalPropKeys( elementType, propertiesToChange );
|
|
63
|
+
const toUpdate = Object.entries( propertiesToUpdate );
|
|
64
|
+
const { valid, errors } = validateInput.validatePropSchema( elementType, propertiesToUpdate );
|
|
52
65
|
if ( ! valid ) {
|
|
53
66
|
const errorMessage = `Failed to configure element "${ elementId }" due to invalid properties: ${ errors?.join(
|
|
54
67
|
'\n- '
|
|
55
68
|
) }`;
|
|
56
69
|
throw new Error( errorMessage );
|
|
57
70
|
}
|
|
58
|
-
for ( const [ propertyName, propertyValue ] of toUpdate ) {
|
|
71
|
+
for ( const [ propertyName, propertyValue ] of toUpdate as [ string, PropValue ][] ) {
|
|
59
72
|
try {
|
|
60
73
|
doUpdateElementProperty( {
|
|
61
74
|
elementId,
|
|
@@ -143,6 +143,49 @@ describe( 'doUpdateElementProperty', () => {
|
|
|
143
143
|
);
|
|
144
144
|
} );
|
|
145
145
|
|
|
146
|
+
it( 'persists canonical prop key when an alias property name is used', () => {
|
|
147
|
+
// Arrange
|
|
148
|
+
const propertyValue = 'resolved-title';
|
|
149
|
+
jest.mocked( getWidgetsCache ).mockReturnValue( {
|
|
150
|
+
[ ELEMENT_TYPE ]: {
|
|
151
|
+
atomic_props_schema: {
|
|
152
|
+
// @ts-ignore: Mock type
|
|
153
|
+
[ PROPERTY_NAME ]: {
|
|
154
|
+
...PROP_SCHEMA_ENTRY,
|
|
155
|
+
meta: { aliases: [ 'text' ] },
|
|
156
|
+
},
|
|
157
|
+
},
|
|
158
|
+
},
|
|
159
|
+
} );
|
|
160
|
+
jest.mocked( Schema.validatePropValue ).mockReturnValue( {
|
|
161
|
+
jsonSchema: EXPECTED_JSON_SCHEMA_SNIPPET,
|
|
162
|
+
valid: true,
|
|
163
|
+
errorMessages: [],
|
|
164
|
+
errors: [],
|
|
165
|
+
} );
|
|
166
|
+
|
|
167
|
+
// Act
|
|
168
|
+
doUpdateElementProperty( {
|
|
169
|
+
elementId: ELEMENT_ID,
|
|
170
|
+
elementType: ELEMENT_TYPE,
|
|
171
|
+
propertyName: 'text',
|
|
172
|
+
propertyValue,
|
|
173
|
+
} );
|
|
174
|
+
|
|
175
|
+
// Assert
|
|
176
|
+
expect( Schema.validatePropValue ).toHaveBeenCalledWith(
|
|
177
|
+
expect.objectContaining( PROP_SCHEMA_ENTRY ),
|
|
178
|
+
propertyValue
|
|
179
|
+
);
|
|
180
|
+
expect( updateElementSettings ).toHaveBeenCalledWith( {
|
|
181
|
+
id: ELEMENT_ID,
|
|
182
|
+
props: {
|
|
183
|
+
[ PROPERTY_NAME ]: propertyValue,
|
|
184
|
+
},
|
|
185
|
+
withHistory: false,
|
|
186
|
+
} );
|
|
187
|
+
} );
|
|
188
|
+
|
|
146
189
|
it( 'replaces existing local style custom_css by default', () => {
|
|
147
190
|
// Arrange
|
|
148
191
|
jest.mocked( getElementStyles ).mockReturnValue( {
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { getWidgetsCache } from '@elementor/editor-elements';
|
|
2
|
+
|
|
3
|
+
import { resolveCanonicalPropKeys, resolveCanonicalPropName } from '../resolve-canonical-prop-name';
|
|
4
|
+
|
|
5
|
+
jest.mock( '@elementor/editor-elements', () => ( {
|
|
6
|
+
getWidgetsCache: jest.fn(),
|
|
7
|
+
} ) );
|
|
8
|
+
|
|
9
|
+
const ELEMENT_TYPE = 'e-paragraph';
|
|
10
|
+
|
|
11
|
+
const widgetsCacheFixture = {
|
|
12
|
+
[ ELEMENT_TYPE ]: {
|
|
13
|
+
atomic_props_schema: {
|
|
14
|
+
paragraph: {
|
|
15
|
+
key: 'html-v3',
|
|
16
|
+
meta: {
|
|
17
|
+
aliases: [ 'text', 'content' ],
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
tag: {
|
|
21
|
+
key: 'string',
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
describe( 'resolveCanonicalPropName', () => {
|
|
28
|
+
beforeEach( () => {
|
|
29
|
+
// @ts-ignore: Mock values for test
|
|
30
|
+
jest.mocked( getWidgetsCache ).mockReturnValue( widgetsCacheFixture );
|
|
31
|
+
} );
|
|
32
|
+
|
|
33
|
+
it( 'returns canonical property names unchanged', () => {
|
|
34
|
+
// Act
|
|
35
|
+
const resolved = resolveCanonicalPropName( ELEMENT_TYPE, 'paragraph' );
|
|
36
|
+
|
|
37
|
+
// Assert
|
|
38
|
+
expect( resolved ).toBe( 'paragraph' );
|
|
39
|
+
} );
|
|
40
|
+
|
|
41
|
+
it( 'resolves alias property names to canonical keys', () => {
|
|
42
|
+
// Act
|
|
43
|
+
const resolved = resolveCanonicalPropName( ELEMENT_TYPE, 'text' );
|
|
44
|
+
|
|
45
|
+
// Assert
|
|
46
|
+
expect( resolved ).toBe( 'paragraph' );
|
|
47
|
+
} );
|
|
48
|
+
|
|
49
|
+
it( 'returns unknown property names unchanged', () => {
|
|
50
|
+
// Act
|
|
51
|
+
const resolved = resolveCanonicalPropName( ELEMENT_TYPE, 'unknown' );
|
|
52
|
+
|
|
53
|
+
// Assert
|
|
54
|
+
expect( resolved ).toBe( 'unknown' );
|
|
55
|
+
} );
|
|
56
|
+
|
|
57
|
+
it( 'returns property names unchanged when element type has no schema', () => {
|
|
58
|
+
// Arrange
|
|
59
|
+
jest.mocked( getWidgetsCache ).mockReturnValue( null );
|
|
60
|
+
|
|
61
|
+
// Act
|
|
62
|
+
const resolved = resolveCanonicalPropName( 'missing-widget', 'text' );
|
|
63
|
+
|
|
64
|
+
// Assert
|
|
65
|
+
expect( resolved ).toBe( 'text' );
|
|
66
|
+
} );
|
|
67
|
+
} );
|
|
68
|
+
|
|
69
|
+
describe( 'resolveCanonicalPropKeys', () => {
|
|
70
|
+
beforeEach( () => {
|
|
71
|
+
// @ts-ignore: Mock values for test
|
|
72
|
+
jest.mocked( getWidgetsCache ).mockReturnValue( widgetsCacheFixture );
|
|
73
|
+
} );
|
|
74
|
+
|
|
75
|
+
it( 'rewrites alias keys to canonical keys', () => {
|
|
76
|
+
// Act
|
|
77
|
+
const resolved = resolveCanonicalPropKeys( ELEMENT_TYPE, {
|
|
78
|
+
text: 'hello',
|
|
79
|
+
} );
|
|
80
|
+
|
|
81
|
+
// Assert
|
|
82
|
+
expect( resolved ).toEqual( {
|
|
83
|
+
paragraph: 'hello',
|
|
84
|
+
} );
|
|
85
|
+
} );
|
|
86
|
+
|
|
87
|
+
it( 'prefers canonical keys when alias and canonical are both provided', () => {
|
|
88
|
+
// Act
|
|
89
|
+
const resolved = resolveCanonicalPropKeys( ELEMENT_TYPE, {
|
|
90
|
+
paragraph: 'canonical',
|
|
91
|
+
text: 'alias',
|
|
92
|
+
} );
|
|
93
|
+
|
|
94
|
+
// Assert
|
|
95
|
+
expect( resolved ).toEqual( {
|
|
96
|
+
paragraph: 'canonical',
|
|
97
|
+
} );
|
|
98
|
+
} );
|
|
99
|
+
|
|
100
|
+
it( 'passes unknown keys through for downstream validation', () => {
|
|
101
|
+
// Act
|
|
102
|
+
const resolved = resolveCanonicalPropKeys( ELEMENT_TYPE, {
|
|
103
|
+
unknown: 'value',
|
|
104
|
+
} );
|
|
105
|
+
|
|
106
|
+
// Assert
|
|
107
|
+
expect( resolved ).toEqual( {
|
|
108
|
+
unknown: 'value',
|
|
109
|
+
} );
|
|
110
|
+
} );
|
|
111
|
+
} );
|
|
@@ -12,6 +12,7 @@ import { type Utils as IUtils } from '@elementor/editor-variables';
|
|
|
12
12
|
import { type z } from '@elementor/schema';
|
|
13
13
|
|
|
14
14
|
import { mergeCustomCssText, readStoredCustomCssText } from './merge-custom-css';
|
|
15
|
+
import { resolveCanonicalPropName } from './resolve-canonical-prop-name';
|
|
15
16
|
import { DYNAMIC_PROP_TYPE_KEY, dynamicTagLLMResolver } from './resolve-dynamic-tag';
|
|
16
17
|
|
|
17
18
|
// TODO: see https://elementor.atlassian.net/browse/ED-22513 for better cross-module access
|
|
@@ -47,7 +48,11 @@ export function resolvePropValue( value: unknown, forceKey?: string ): PropValue
|
|
|
47
48
|
* Also, it supports updating styles "on-the-way" by checking for "_styles" property with PropValue bag that fits the common style schema.
|
|
48
49
|
*/
|
|
49
50
|
export const doUpdateElementProperty = ( params: OwnParams ) => {
|
|
50
|
-
const { elementId,
|
|
51
|
+
const { elementId, propertyValue, elementType, customCssWriteMode = 'replace' } = params;
|
|
52
|
+
const propertyName =
|
|
53
|
+
params.propertyName === '_styles'
|
|
54
|
+
? params.propertyName
|
|
55
|
+
: resolveCanonicalPropName( elementType, params.propertyName );
|
|
51
56
|
if ( propertyName === '_styles' ) {
|
|
52
57
|
const elementStyles = getElementStyles( elementId ) || {};
|
|
53
58
|
const propertyMapValue = propertyValue as Record< string, PropValue >;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { getWidgetsCache } from '@elementor/editor-elements';
|
|
2
|
+
import { type PropsSchema } from '@elementor/editor-props';
|
|
3
|
+
|
|
4
|
+
function buildAliasToCanonicalMap( schema: PropsSchema ): Record< string, string > {
|
|
5
|
+
const aliasToCanonical: Record< string, string > = {};
|
|
6
|
+
|
|
7
|
+
for ( const [ canonical, propType ] of Object.entries( schema ) ) {
|
|
8
|
+
const aliases = propType.meta?.aliases;
|
|
9
|
+
|
|
10
|
+
if ( ! Array.isArray( aliases ) ) {
|
|
11
|
+
continue;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
for ( const alias of aliases ) {
|
|
15
|
+
if ( typeof alias === 'string' && alias ) {
|
|
16
|
+
aliasToCanonical[ alias ] = canonical;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return aliasToCanonical;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function resolveCanonicalPropName( elementType: string, propertyName: string ): string {
|
|
25
|
+
const schema = getWidgetsCache()?.[ elementType ]?.atomic_props_schema;
|
|
26
|
+
|
|
27
|
+
if ( ! schema || schema[ propertyName ] ) {
|
|
28
|
+
return propertyName;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return buildAliasToCanonicalMap( schema )[ propertyName ] ?? propertyName;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function resolveCanonicalPropKeys(
|
|
35
|
+
elementType: string,
|
|
36
|
+
props: Record< string, unknown >
|
|
37
|
+
): Record< string, unknown > {
|
|
38
|
+
const schema = getWidgetsCache()?.[ elementType ]?.atomic_props_schema;
|
|
39
|
+
|
|
40
|
+
if ( ! schema ) {
|
|
41
|
+
return { ...props };
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const aliasToCanonical = buildAliasToCanonicalMap( schema );
|
|
45
|
+
const resolved: Record< string, unknown > = {};
|
|
46
|
+
|
|
47
|
+
for ( const [ key, value ] of Object.entries( props ) ) {
|
|
48
|
+
if ( schema[ key ] ) {
|
|
49
|
+
resolved[ key ] = value;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
for ( const [ key, value ] of Object.entries( props ) ) {
|
|
54
|
+
if ( schema[ key ] ) {
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const canonical = aliasToCanonical[ key ];
|
|
59
|
+
|
|
60
|
+
if ( ! canonical ) {
|
|
61
|
+
resolved[ key ] = value;
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if ( ! Object.prototype.hasOwnProperty.call( resolved, canonical ) ) {
|
|
66
|
+
resolved[ canonical ] = value;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return resolved;
|
|
71
|
+
}
|