@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.
Files changed (52) hide show
  1. package/dist/index.d.mts +3 -1
  2. package/dist/index.d.ts +3 -1
  3. package/dist/index.js +535 -393
  4. package/dist/index.mjs +516 -370
  5. package/package.json +20 -20
  6. package/src/__tests__/flex-transformer.test.ts +11 -11
  7. package/src/__tests__/prop-types.ts +11 -0
  8. package/src/init-settings-transformers.ts +4 -0
  9. package/src/init-style-transformers.ts +2 -2
  10. package/src/init.tsx +5 -4
  11. package/src/legacy/__tests__/create-templated-element-type.test.ts +50 -0
  12. package/src/legacy/__tests__/list-type.test.ts +89 -0
  13. package/src/legacy/create-nested-templated-element-type.ts +3 -1
  14. package/src/legacy/create-templated-element-type.ts +5 -2
  15. package/src/legacy/list-type.ts +63 -0
  16. package/src/legacy/replacements/inline-editing/__tests__/inline-editing-eligibility.test.ts +7 -7
  17. package/src/legacy/replacements/inline-editing/inline-editing-elements.tsx +22 -9
  18. package/src/legacy/replacements/inline-editing/inline-editing-eligibility.ts +12 -3
  19. package/src/legacy/tabs-model-extensions.ts +2 -5
  20. package/src/legacy/twig-rendering-utils.ts +11 -2
  21. package/src/legacy/types.ts +4 -0
  22. package/src/mcp/canvas-mcp.ts +2 -4
  23. package/src/mcp/mcp-description.ts +18 -30
  24. package/src/mcp/resources/__tests__/available-widgets-resource.test.ts +22 -13
  25. package/src/mcp/resources/__tests__/dynamic-tags-resource.test.ts +22 -30
  26. package/src/mcp/resources/__tests__/widgets-schema-resource.test.ts +11 -6
  27. package/src/mcp/resources/available-widgets-resource.ts +13 -10
  28. package/src/mcp/resources/dynamic-tags-resource.ts +6 -15
  29. package/src/mcp/resources/widgets-schema-resource.ts +8 -5
  30. package/src/mcp/tools/configure-element/__tests__/tool.test.ts +130 -0
  31. package/src/mcp/tools/configure-element/prompt.ts +3 -6
  32. package/src/mcp/tools/configure-element/schema.ts +6 -0
  33. package/src/mcp/tools/configure-element/tool.ts +11 -1
  34. package/src/mcp/tools/get-page-structure/tool.ts +73 -0
  35. package/src/mcp/utils/__tests__/do-update-element-property.test.ts +27 -1
  36. package/src/mcp/utils/do-update-element-property.ts +18 -6
  37. package/src/mcp/utils/get-mcp-error-message.ts +16 -0
  38. package/src/renderers/__tests__/compute-html-tag.test.ts +55 -0
  39. package/src/renderers/__tests__/create-dom-renderer.test.ts +60 -0
  40. package/src/renderers/__tests__/fixtures/html-tag-computer-cases.json +87 -0
  41. package/src/renderers/compute-html-tag.ts +73 -0
  42. package/src/renderers/create-dom-renderer.ts +13 -22
  43. package/src/transformers/settings/escaped-html-transformer.ts +6 -0
  44. package/src/transformers/shared/__tests__/icon-transformer.test.ts +199 -0
  45. package/src/transformers/shared/icon-transformer.ts +231 -0
  46. package/src/transformers/shared/process-svg-content.ts +26 -0
  47. package/src/transformers/shared/svg-src-transformer.ts +1 -26
  48. package/src/transformers/styles/flex-transformer.ts +11 -32
  49. package/src/utils/__tests__/sanitize-escaped-html.test.ts +105 -0
  50. package/src/utils/sanitize-escaped-html.ts +32 -0
  51. package/src/mcp/tools/build-composition/tool.ts +0 -133
  52. package/src/mcp/tools/get-element-config/tool.ts +0 -114
package/dist/index.mjs CHANGED
@@ -12,10 +12,10 @@ var BEST_PRACTICES_FULL_URI = `${CANVAS_SERVER_NAME}_${BEST_PRACTICES_URI}`;
12
12
  var MCP_PROXY_URL = "elementor/v1/mcp-proxy";
13
13
  var listWidgetTypes = async () => {
14
14
  const { data } = await httpService().post(MCP_PROXY_URL, {
15
- tool: "list-widgets",
16
- input: {}
15
+ tool: "list-widget-schemas",
16
+ input: { summary: true }
17
17
  });
18
- return (data.data ?? []).map((widget) => widget.type);
18
+ return (data.data?.widgets ?? []).map((widget) => widget.type);
19
19
  };
20
20
  var fetchWidgetSchema = async (widgetType) => {
21
21
  const { data } = await httpService().post(MCP_PROXY_URL, {
@@ -47,13 +47,13 @@ var initWidgetsSchemaResource = (reg) => {
47
47
  if (!widgetType) {
48
48
  throw new Error("No widget type provided.");
49
49
  }
50
- const schema2 = await fetchWidgetSchema(widgetType);
50
+ const schema = await fetchWidgetSchema(widgetType);
51
51
  return {
52
52
  contents: [
53
53
  {
54
54
  uri: uri.toString(),
55
55
  mimeType: "application/json",
56
- text: JSON.stringify(schema2)
56
+ text: JSON.stringify(schema)
57
57
  }
58
58
  ]
59
59
  };
@@ -1260,10 +1260,10 @@ var getMultiPropsValue = (multiProps) => {
1260
1260
  // src/renderers/create-props-resolver.ts
1261
1261
  var TRANSFORM_DEPTH_LIMIT = 3;
1262
1262
  function createPropsResolver({ transformers, schema: initialSchema, onPropResolve }) {
1263
- async function resolve({ props, schema: schema2, signal, renderContext }) {
1264
- schema2 = schema2 ?? initialSchema;
1263
+ async function resolve({ props, schema, signal, renderContext }) {
1264
+ schema = schema ?? initialSchema;
1265
1265
  const promises = Promise.all(
1266
- Object.entries(schema2).map(async ([key, type]) => {
1266
+ Object.entries(schema).map(async ([key, type]) => {
1267
1267
  const value = props[key] ?? type.default;
1268
1268
  const transformed = await transform({ value, key, type, signal, renderContext });
1269
1269
  onPropResolve?.({ key, value: transformed, propValue: value, propType: type });
@@ -1989,6 +1989,40 @@ var dateTimeTransformer = createTransformer((values) => {
1989
1989
  }).join(" ");
1990
1990
  });
1991
1991
 
1992
+ // src/utils/sanitize-escaped-html.ts
1993
+ import DOMPurify from "dompurify";
1994
+ var ALLOWED_NON_OPERATIONAL_ATTRS = [
1995
+ "href",
1996
+ "target",
1997
+ "class",
1998
+ "id",
1999
+ "style",
2000
+ "title",
2001
+ "lang",
2002
+ "dir",
2003
+ "role"
2004
+ ];
2005
+ function getAllowedHtmlWrapperTags() {
2006
+ return window.elementorCommon?.config?.allowedHTMLWrapperTags ?? [];
2007
+ }
2008
+ function sanitizeEscapedHtml(value) {
2009
+ if (!value) {
2010
+ return "";
2011
+ }
2012
+ const allowedTags = [...getAllowedHtmlWrapperTags()];
2013
+ return DOMPurify.sanitize(value, {
2014
+ ALLOWED_TAGS: allowedTags,
2015
+ ALLOWED_ATTR: [...ALLOWED_NON_OPERATIONAL_ATTRS],
2016
+ ALLOW_DATA_ATTR: true,
2017
+ ALLOW_ARIA_ATTR: true
2018
+ });
2019
+ }
2020
+
2021
+ // src/transformers/settings/escaped-html-transformer.ts
2022
+ var escapedHtmlTransformer = createTransformer((value) => {
2023
+ return sanitizeEscapedHtml(value);
2024
+ });
2025
+
1992
2026
  // src/transformers/settings/html-v2-transformer.ts
1993
2027
  var htmlV2Transformer = createTransformer((value) => {
1994
2028
  return value?.content ?? "";
@@ -2025,6 +2059,172 @@ var timeRangeTransformer = createTransformer((value) => {
2025
2059
  };
2026
2060
  });
2027
2061
 
2062
+ // src/transformers/shared/process-svg-content.ts
2063
+ import DOMPurify2 from "dompurify";
2064
+ var SVG_INLINE_STYLES = "width: 100%; height: 100%; overflow: unset;";
2065
+ function processSvgContent(svgText) {
2066
+ const sanitized = DOMPurify2.sanitize(svgText, {
2067
+ USE_PROFILES: { svg: true, svgFilters: true }
2068
+ });
2069
+ const parser = new DOMParser();
2070
+ const doc = parser.parseFromString(sanitized, "image/svg+xml");
2071
+ const svgElement = doc.querySelector("svg");
2072
+ if (!svgElement) {
2073
+ return null;
2074
+ }
2075
+ svgElement.setAttribute("fill", "currentColor");
2076
+ const existingStyle = svgElement.getAttribute("style") ?? "";
2077
+ const trimmed = existingStyle.trim();
2078
+ const merged = trimmed ? `${trimmed.replace(/;$/, "")}; ${SVG_INLINE_STYLES}` : SVG_INLINE_STYLES;
2079
+ svgElement.setAttribute("style", merged);
2080
+ return svgElement.outerHTML;
2081
+ }
2082
+
2083
+ // src/transformers/shared/icon-transformer.ts
2084
+ var FONT_AWESOME_JSON = {
2085
+ width: 0,
2086
+ height: 1,
2087
+ aliases: 2,
2088
+ unicode: 3,
2089
+ path: 4
2090
+ };
2091
+ var fontAwesomeJsonCache = /* @__PURE__ */ new Map();
2092
+ var iconTransformer = createTransformer(async (value, { signal }) => {
2093
+ const iconValue = typeof value.value === "string" ? value.value : null;
2094
+ const library = typeof value.library === "string" ? value.library : null;
2095
+ if (!iconValue || !library) {
2096
+ return { html: null, url: null };
2097
+ }
2098
+ const iconName = getFontAwesomeIconName(iconValue);
2099
+ const jsonFileName = getFontAwesomeJsonFileName(library);
2100
+ if (!iconName || !jsonFileName) {
2101
+ return { html: null, url: null };
2102
+ }
2103
+ const icons = await fetchFontAwesomeIcons(jsonFileName, signal);
2104
+ const iconData = icons?.[iconName];
2105
+ if (!iconData) {
2106
+ return { html: null, url: null };
2107
+ }
2108
+ const svgText = buildFontAwesomeSvg(iconData);
2109
+ if (!svgText) {
2110
+ return { html: null, url: null };
2111
+ }
2112
+ const html = processIconSvgContent(svgText);
2113
+ return { html, url: null };
2114
+ });
2115
+ function getFontAwesomeIconName(iconValue) {
2116
+ const match = iconValue.match(/^fa\S*\s+fa-(.+)$/);
2117
+ return match?.[1] ?? null;
2118
+ }
2119
+ function getFontAwesomeJsonFileName(library) {
2120
+ const fileName = library.replace(/^fa-/, "");
2121
+ const config = getFontAwesome7EditorConfig();
2122
+ if (!config?.jsonFiles.includes(fileName)) {
2123
+ return null;
2124
+ }
2125
+ return fileName;
2126
+ }
2127
+ function getFontAwesome7EditorConfig() {
2128
+ const config = window.elementorCommon?.config?.fontAwesome?.v7;
2129
+ if (!config || !Array.isArray(config.jsonFiles) || typeof config.jsonBaseUrl !== "string" || config.jsonBaseUrl === "") {
2130
+ return null;
2131
+ }
2132
+ return {
2133
+ jsonFiles: config.jsonFiles,
2134
+ jsonBaseUrl: config.jsonBaseUrl
2135
+ };
2136
+ }
2137
+ async function fetchFontAwesomeIcons(jsonFileName, signal) {
2138
+ const cached = fontAwesomeJsonCache.get(jsonFileName);
2139
+ if (cached) {
2140
+ return cached;
2141
+ }
2142
+ const icons = await loadFontAwesomeIcons(jsonFileName, signal);
2143
+ if (icons) {
2144
+ fontAwesomeJsonCache.set(jsonFileName, icons);
2145
+ }
2146
+ return icons;
2147
+ }
2148
+ async function loadFontAwesomeIcons(jsonFileName, signal) {
2149
+ const config = getFontAwesome7EditorConfig();
2150
+ if (!config?.jsonFiles.includes(jsonFileName)) {
2151
+ return null;
2152
+ }
2153
+ try {
2154
+ const response = await fetch(`${config.jsonBaseUrl}${jsonFileName}.json`, {
2155
+ signal
2156
+ });
2157
+ if (!response.ok) {
2158
+ return null;
2159
+ }
2160
+ const data = await response.json();
2161
+ const icons = data.icons;
2162
+ if (!icons || typeof icons !== "object") {
2163
+ return null;
2164
+ }
2165
+ return indexFontAwesomeIcons(icons);
2166
+ } catch {
2167
+ return null;
2168
+ }
2169
+ }
2170
+ function indexFontAwesomeIcons(icons) {
2171
+ const index = {};
2172
+ for (const [name, iconData] of Object.entries(icons)) {
2173
+ if (!isValidIconTuple(iconData)) {
2174
+ continue;
2175
+ }
2176
+ index[name] = iconData;
2177
+ for (const alias of iconData[FONT_AWESOME_JSON.aliases]) {
2178
+ if (typeof alias === "string" && alias !== "" && !index[alias]) {
2179
+ index[alias] = iconData;
2180
+ }
2181
+ }
2182
+ }
2183
+ return index;
2184
+ }
2185
+ function isValidIconTuple(iconData) {
2186
+ return Array.isArray(iconData) && iconData.length >= 5 && typeof iconData[FONT_AWESOME_JSON.width] === "number" && typeof iconData[FONT_AWESOME_JSON.height] === "number" && Array.isArray(iconData[FONT_AWESOME_JSON.aliases]);
2187
+ }
2188
+ function buildFontAwesomeSvg(iconData) {
2189
+ const width = iconData[FONT_AWESOME_JSON.width];
2190
+ const height = iconData[FONT_AWESOME_JSON.height];
2191
+ const paths = normalizePaths(iconData[FONT_AWESOME_JSON.path]);
2192
+ if (paths.length === 0) {
2193
+ return null;
2194
+ }
2195
+ const pathMarkup = paths.map((path) => `<path d="${escapeSvgPath(path)}"></path>`).join("");
2196
+ return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${width} ${height}">${pathMarkup}</svg>`;
2197
+ }
2198
+ function normalizePaths(pathData) {
2199
+ if (typeof pathData === "string" && pathData !== "") {
2200
+ return [pathData];
2201
+ }
2202
+ if (!Array.isArray(pathData)) {
2203
+ return [];
2204
+ }
2205
+ return pathData.filter((path) => typeof path === "string" && path !== "");
2206
+ }
2207
+ function escapeSvgPath(path) {
2208
+ return path.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
2209
+ }
2210
+ function processIconSvgContent(svgText) {
2211
+ const html = processSvgContent(svgText);
2212
+ if (!html) {
2213
+ return null;
2214
+ }
2215
+ const parser = new DOMParser();
2216
+ const doc = parser.parseFromString(html, "image/svg+xml");
2217
+ const svgElement = doc.querySelector("svg");
2218
+ if (!svgElement) {
2219
+ return null;
2220
+ }
2221
+ svgElement.setAttribute("aria-hidden", "true");
2222
+ svgElement.style.setProperty("width", "100%");
2223
+ svgElement.style.setProperty("height", "100%");
2224
+ svgElement.style.setProperty("overflow", "visible");
2225
+ return svgElement.outerHTML;
2226
+ }
2227
+
2028
2228
  // src/transformers/shared/image-src-transformer.ts
2029
2229
  var imageSrcTransformer = createTransformer((value) => ({
2030
2230
  id: value.id ?? null,
@@ -2066,26 +2266,7 @@ var plainTransformer = createTransformer((value) => {
2066
2266
  });
2067
2267
 
2068
2268
  // src/transformers/shared/svg-src-transformer.ts
2069
- import DOMPurify from "dompurify";
2070
2269
  import { getMediaAttachment as getMediaAttachment2 } from "@elementor/wp-media";
2071
- var SVG_INLINE_STYLES = "width: 100%; height: 100%; overflow: unset;";
2072
- function processSvgContent(svgText) {
2073
- const sanitized = DOMPurify.sanitize(svgText, {
2074
- USE_PROFILES: { svg: true, svgFilters: true }
2075
- });
2076
- const parser = new DOMParser();
2077
- const doc = parser.parseFromString(sanitized, "image/svg+xml");
2078
- const svgElement = doc.querySelector("svg");
2079
- if (!svgElement) {
2080
- return null;
2081
- }
2082
- svgElement.setAttribute("fill", "currentColor");
2083
- const existingStyle = svgElement.getAttribute("style") ?? "";
2084
- const trimmed = existingStyle.trim();
2085
- const merged = trimmed ? `${trimmed.replace(/;$/, "")}; ${SVG_INLINE_STYLES}` : SVG_INLINE_STYLES;
2086
- svgElement.setAttribute("style", merged);
2087
- return svgElement.outerHTML;
2088
- }
2089
2270
  async function fetchSvgContent(url, signal) {
2090
2271
  try {
2091
2272
  const response = await fetch(url, { signal });
@@ -2141,7 +2322,7 @@ var videoSrcTransformer = createTransformer(async (value) => {
2141
2322
 
2142
2323
  // src/init-settings-transformers.ts
2143
2324
  function initSettingsTransformers() {
2144
- settingsTransformersRegistry.register("classes", createClassesTransformer()).register("link", linkTransformer).register("query", queryTransformer).register("image", imageTransformer).register("image-src", imageSrcTransformer).register("svg-src", svgSrcTransformer).register("video-src", videoSrcTransformer).register("attributes", attributesTransformer).register("date-time", dateTimeTransformer).register("html-v2", htmlV2Transformer).register("html-v3", htmlV3Transformer).register("date-range", dateRangeTransformer).register("time-range", timeRangeTransformer).registerFallback(plainTransformer);
2325
+ settingsTransformersRegistry.register("classes", createClassesTransformer()).register("link", linkTransformer).register("query", queryTransformer).register("image", imageTransformer).register("image-src", imageSrcTransformer).register("svg-src", svgSrcTransformer).register("icon", iconTransformer).register("video-src", videoSrcTransformer).register("attributes", attributesTransformer).register("date-time", dateTimeTransformer).register("html-v2", htmlV2Transformer).register("html-v3", htmlV3Transformer).register("escaped-html", escapedHtmlTransformer).register("date-range", dateRangeTransformer).register("time-range", timeRangeTransformer).registerFallback(plainTransformer);
2145
2326
  }
2146
2327
 
2147
2328
  // src/transformers/styles/background-color-overlay-transformer.ts
@@ -2287,6 +2468,10 @@ var mapToFilterFunctionString = (value) => {
2287
2468
  };
2288
2469
 
2289
2470
  // src/transformers/styles/flex-transformer.ts
2471
+ var DEFAULT_FLEX_GROW = 0;
2472
+ var DEFAULT_FLEX_SHRINK = 1;
2473
+ var DEFAULT_FLEX_BASIS = "auto";
2474
+ var formatBasis = (basis) => typeof basis === "object" && basis.size !== void 0 ? `${basis.size}${basis.unit || ""}` : basis;
2290
2475
  var flexTransformer = createTransformer((value) => {
2291
2476
  const grow = value.flexGrow;
2292
2477
  const shrink = value.flexShrink;
@@ -2297,28 +2482,10 @@ var flexTransformer = createTransformer((value) => {
2297
2482
  if (!hasGrow && !hasShrink && !hasBasis) {
2298
2483
  return null;
2299
2484
  }
2300
- if (hasGrow && hasShrink && hasBasis) {
2301
- return `${grow} ${shrink} ${typeof basis === "object" && basis.size !== void 0 ? `${basis.size}${basis.unit || ""}` : basis}`;
2302
- }
2303
- if (hasGrow && hasShrink && !hasBasis) {
2304
- return `${grow} ${shrink}`;
2305
- }
2306
- if (hasGrow && !hasShrink && hasBasis) {
2307
- return `${grow} 1 ${typeof basis === "object" && basis.size !== void 0 ? `${basis.size}${basis.unit || ""}` : basis}`;
2308
- }
2309
- if (!hasGrow && hasShrink && hasBasis) {
2310
- return `0 ${shrink} ${typeof basis === "object" && basis.size !== void 0 ? `${basis.size}${basis.unit || ""}` : basis}`;
2311
- }
2312
- if (hasGrow && !hasShrink && !hasBasis) {
2313
- return `${grow}`;
2314
- }
2315
- if (!hasGrow && hasShrink && !hasBasis) {
2316
- return `0 ${shrink}`;
2317
- }
2318
- if (!hasGrow && !hasShrink && hasBasis) {
2319
- return `0 1 ${typeof basis === "object" && basis.size !== void 0 ? `${basis.size}${basis.unit || ""}` : basis}`;
2320
- }
2321
- return null;
2485
+ const growOut = hasGrow ? grow : DEFAULT_FLEX_GROW;
2486
+ const shrinkOut = hasShrink ? shrink : DEFAULT_FLEX_SHRINK;
2487
+ const basisOut = hasBasis ? formatBasis(basis) : DEFAULT_FLEX_BASIS;
2488
+ return `${growOut} ${shrinkOut} ${basisOut}`;
2322
2489
  });
2323
2490
 
2324
2491
  // src/transformers/styles/font-family-transformer.ts
@@ -2418,11 +2585,11 @@ function getVal2(val) {
2418
2585
  var transformOriginTransformer = createTransformer((value) => {
2419
2586
  const x = getVal2(value.x);
2420
2587
  const y = getVal2(value.y);
2421
- const z4 = getVal2(value.z);
2422
- if (x === DEFAULT_XY && y === DEFAULT_XY && z4 === DEFAULT_Z) {
2588
+ const z3 = getVal2(value.z);
2589
+ if (x === DEFAULT_XY && y === DEFAULT_XY && z3 === DEFAULT_Z) {
2423
2590
  return null;
2424
2591
  }
2425
- return `${x} ${y} ${z4}`;
2592
+ return `${x} ${y} ${z3}`;
2426
2593
  });
2427
2594
 
2428
2595
  // src/transformers/styles/transform-rotate-transformer.ts
@@ -2500,13 +2667,13 @@ function initStyleTransformers() {
2500
2667
  "layout-direction",
2501
2668
  createMultiPropsTransformer(["row", "column"], ({ propKey, key }) => `${key}-${propKey}`)
2502
2669
  ).register("flex", flexTransformer).register(
2503
- "border-width",
2670
+ "border-width-v2",
2504
2671
  createMultiPropsTransformer(
2505
2672
  ["block-start", "block-end", "inline-start", "inline-end"],
2506
2673
  ({ key }) => `border-${key}-width`
2507
2674
  )
2508
2675
  ).register(
2509
- "border-radius",
2676
+ "border-radius-v2",
2510
2677
  createMultiPropsTransformer(
2511
2678
  ["start-start", "start-end", "end-start", "end-end"],
2512
2679
  ({ key }) => `border-${key}-radius`
@@ -2530,28 +2697,13 @@ function createDomRenderer() {
2530
2697
  render: environment.render
2531
2698
  };
2532
2699
  }
2700
+ function getAllowedHtmlWrapperTags2() {
2701
+ return window.elementorCommon?.config?.allowedHTMLWrapperTags ?? [];
2702
+ }
2533
2703
  function escapeHtmlTag(value) {
2534
- const allowedTags = [
2535
- "a",
2536
- "article",
2537
- "aside",
2538
- "button",
2539
- "div",
2540
- "footer",
2541
- "h1",
2542
- "h2",
2543
- "h3",
2544
- "h4",
2545
- "h5",
2546
- "h6",
2547
- "header",
2548
- "main",
2549
- "nav",
2550
- "p",
2551
- "section",
2552
- "span"
2553
- ];
2554
- return allowedTags.includes(value) ? value : "div";
2704
+ const allowedTags = getAllowedHtmlWrapperTags2();
2705
+ const normalizedTag = value?.toLowerCase?.() ?? "";
2706
+ return allowedTags.includes(normalizedTag) ? value : "div";
2555
2707
  }
2556
2708
  function escapeURL(value) {
2557
2709
  const allowedProtocols = ["http:", "https:", "mailto:", "tel:"];
@@ -2646,6 +2798,52 @@ function createElementViewClassDeclaration() {
2646
2798
  // src/legacy/create-nested-templated-element-type.ts
2647
2799
  import { ELEMENT_STYLE_CHANGE_EVENT as ELEMENT_STYLE_CHANGE_EVENT2 } from "@elementor/editor-elements";
2648
2800
 
2801
+ // src/renderers/compute-html-tag.ts
2802
+ var DEFAULT_LINK_TAG = "a";
2803
+ function computeHtmlTag(settings, defaultTag, options = {}) {
2804
+ const followLink = options.followLink ?? true;
2805
+ if (followLink && settingsHaveActiveLink(settings)) {
2806
+ const link = settings.link;
2807
+ return extractLinkHtmlTag(isRecord(link) ? link : {});
2808
+ }
2809
+ const settingsTag = extractHtmlTagValue(settings.tag);
2810
+ if (null !== settingsTag && "" !== settingsTag) {
2811
+ return settingsTag;
2812
+ }
2813
+ return defaultTag;
2814
+ }
2815
+ function settingsHaveActiveLink(settings) {
2816
+ const link = settings.link;
2817
+ if (!isRecord(link)) {
2818
+ return false;
2819
+ }
2820
+ const href = extractHtmlTagValue(link.href);
2821
+ if (null !== href && "" !== href) {
2822
+ return true;
2823
+ }
2824
+ const attributes = link.attributes;
2825
+ return typeof attributes === "string" && "" !== attributes;
2826
+ }
2827
+ function extractLinkHtmlTag(link) {
2828
+ const tag = extractHtmlTagValue(link.tag);
2829
+ if (null !== tag && "" !== tag) {
2830
+ return tag;
2831
+ }
2832
+ return DEFAULT_LINK_TAG;
2833
+ }
2834
+ function extractHtmlTagValue(value) {
2835
+ if (isRecord(value) && typeof value.value === "string") {
2836
+ return value.value;
2837
+ }
2838
+ if (typeof value === "string") {
2839
+ return value;
2840
+ }
2841
+ return null;
2842
+ }
2843
+ function isRecord(value) {
2844
+ return typeof value === "object" && null !== value && !Array.isArray(value);
2845
+ }
2846
+
2649
2847
  // src/legacy/create-pending-element.ts
2650
2848
  import {
2651
2849
  addModelToParent,
@@ -2711,7 +2909,13 @@ function setupTwigRenderer({ renderer, element }) {
2711
2909
  transformers: settingsTransformersRegistry,
2712
2910
  schema: element.atomic_props_schema
2713
2911
  });
2714
- return { templateKey, baseStylesDictionary, resolveProps };
2912
+ return {
2913
+ templateKey,
2914
+ baseStylesDictionary,
2915
+ resolveProps,
2916
+ defaultHtmlTag: element.default_html_tag ?? "div",
2917
+ htmlTagFollowsLink: element.html_tag_follows_link ?? true
2918
+ };
2715
2919
  }
2716
2920
  function createBeforeRender(view) {
2717
2921
  view._ensureViewIsIntact();
@@ -2751,7 +2955,7 @@ function createTemplatedElementView({
2751
2955
  element
2752
2956
  }) {
2753
2957
  const BaseView = createElementViewClassDeclaration();
2754
- const { templateKey, baseStylesDictionary, resolveProps } = setupTwigRenderer({
2958
+ const { templateKey, baseStylesDictionary, resolveProps, defaultHtmlTag, htmlTagFollowsLink } = setupTwigRenderer({
2755
2959
  type,
2756
2960
  renderer,
2757
2961
  element
@@ -2821,6 +3025,7 @@ function createTemplatedElementView({
2821
3025
  interaction_id: this.getInteractionId(),
2822
3026
  type,
2823
3027
  settings,
3028
+ tag: computeHtmlTag(settings, defaultHtmlTag, { followLink: htmlTagFollowsLink }),
2824
3029
  base_styles: baseStylesDictionary,
2825
3030
  ...this.getResolverRenderContext?.() ?? {}
2826
3031
  };
@@ -2910,7 +3115,7 @@ function createNestedTemplatedElementView({
2910
3115
  element
2911
3116
  }) {
2912
3117
  const legacyWindow = window;
2913
- const { templateKey, baseStylesDictionary, resolveProps } = setupTwigRenderer({
3118
+ const { templateKey, baseStylesDictionary, resolveProps, defaultHtmlTag, htmlTagFollowsLink } = setupTwigRenderer({
2914
3119
  type,
2915
3120
  renderer,
2916
3121
  element
@@ -2985,6 +3190,7 @@ function createNestedTemplatedElementView({
2985
3190
  interaction_id: this.getInteractionId(),
2986
3191
  type,
2987
3192
  settings: resolvedSettings,
3193
+ tag: computeHtmlTag(resolvedSettings, defaultHtmlTag, { followLink: htmlTagFollowsLink }),
2988
3194
  base_styles: baseStylesDictionary,
2989
3195
  editor_attributes: buildEditorAttributes(model),
2990
3196
  editor_classes: buildEditorClasses(model),
@@ -3208,8 +3414,8 @@ import { createRoot } from "react-dom/client";
3208
3414
  import * as React11 from "react";
3209
3415
  import { getContainer as getContainer2, getElementLabel, getElementType as getElementType2 } from "@elementor/editor-elements";
3210
3416
  import {
3417
+ escapedHtmlPropTypeUtil as escapedHtmlPropTypeUtil2,
3211
3418
  htmlV3PropTypeUtil as htmlV3PropTypeUtil2,
3212
- parseHtmlChildren,
3213
3419
  stringPropTypeUtil as stringPropTypeUtil2
3214
3420
  } from "@elementor/editor-props";
3215
3421
  import { __privateRunCommandSync as runCommandSync, getCurrentEditMode, undoable } from "@elementor/editor-v1-adapters";
@@ -3488,11 +3694,15 @@ var InlineEditingToolbar = ({ anchor, editor, id }) => {
3488
3694
  };
3489
3695
 
3490
3696
  // src/legacy/replacements/inline-editing/inline-editing-eligibility.ts
3491
- import { htmlV3PropTypeUtil, stringPropTypeUtil } from "@elementor/editor-props";
3697
+ import {
3698
+ escapedHtmlPropTypeUtil,
3699
+ htmlV3PropTypeUtil,
3700
+ stringPropTypeUtil
3701
+ } from "@elementor/editor-props";
3492
3702
  var hasKey = (propType) => {
3493
3703
  return "key" in propType;
3494
3704
  };
3495
- var TEXT_PROP_TYPE_KEYS = /* @__PURE__ */ new Set([htmlV3PropTypeUtil.key, stringPropTypeUtil.key]);
3705
+ var TEXT_PROP_TYPE_KEYS = /* @__PURE__ */ new Set([escapedHtmlPropTypeUtil.key, htmlV3PropTypeUtil.key, stringPropTypeUtil.key]);
3496
3706
  var isCoreTextPropTypeKey = (key) => {
3497
3707
  return TEXT_PROP_TYPE_KEYS.has(key);
3498
3708
  };
@@ -3512,7 +3722,7 @@ var isInlineEditingAllowed = ({ rawValue, propTypeFromSchema }) => {
3512
3722
  if (rawValue === null || rawValue === void 0) {
3513
3723
  return isAllowedBySchema(propTypeFromSchema);
3514
3724
  }
3515
- return htmlV3PropTypeUtil.isValid(rawValue) || stringPropTypeUtil.isValid(rawValue);
3725
+ return escapedHtmlPropTypeUtil.isValid(rawValue) || htmlV3PropTypeUtil.isValid(rawValue) || stringPropTypeUtil.isValid(rawValue);
3516
3726
  };
3517
3727
 
3518
3728
  // src/legacy/replacements/inline-editing/inline-editing-elements.tsx
@@ -3597,17 +3807,26 @@ var InlineEditingReplacement = class extends ReplacementBase {
3597
3807
  }
3598
3808
  getExtractedContentValue() {
3599
3809
  const propValue = this.getInlineEditablePropValue();
3810
+ if (escapedHtmlPropTypeUtil2.isValid(propValue)) {
3811
+ return escapedHtmlPropTypeUtil2.extract(propValue) ?? "";
3812
+ }
3600
3813
  const extracted = htmlV3PropTypeUtil2.extract(propValue);
3601
3814
  return stringPropTypeUtil2.extract(extracted?.content ?? null) ?? "";
3602
3815
  }
3816
+ createContentPropValue(value) {
3817
+ const content = value || "";
3818
+ const propTypeKey = this.getInlineEditablePropTypeKey();
3819
+ if (propTypeKey === htmlV3PropTypeUtil2.key) {
3820
+ return htmlV3PropTypeUtil2.create({
3821
+ content: stringPropTypeUtil2.create(content),
3822
+ children: []
3823
+ });
3824
+ }
3825
+ return escapedHtmlPropTypeUtil2.create(content);
3826
+ }
3603
3827
  setContentValue(value) {
3604
3828
  const settingKey = this.getInlineEditablePropertyName();
3605
- const html = value || "";
3606
- const parsed = parseHtmlChildren(html);
3607
- const valueToSave = htmlV3PropTypeUtil2.create({
3608
- content: parsed.content ? stringPropTypeUtil2.create(parsed.content) : null,
3609
- children: parsed.children
3610
- });
3829
+ const valueToSave = this.createContentPropValue(value);
3611
3830
  undoable(
3612
3831
  {
3613
3832
  do: () => {
@@ -3636,7 +3855,7 @@ var InlineEditingReplacement = class extends ReplacementBase {
3636
3855
  return null;
3637
3856
  }
3638
3857
  if (propType.kind === "union") {
3639
- const textKeys = [htmlV3PropTypeUtil2.key, stringPropTypeUtil2.key];
3858
+ const textKeys = [escapedHtmlPropTypeUtil2.key, htmlV3PropTypeUtil2.key, stringPropTypeUtil2.key];
3640
3859
  for (const key of textKeys) {
3641
3860
  if (propType.prop_types[key]) {
3642
3861
  return key;
@@ -3891,8 +4110,54 @@ function createNestedTemplatedType(type, renderer, element) {
3891
4110
  });
3892
4111
  }
3893
4112
 
4113
+ // src/legacy/list-type.ts
4114
+ var LIST_TYPE = "e-list";
4115
+ function initListType() {
4116
+ registerElementType(
4117
+ LIST_TYPE,
4118
+ (options) => createListType(options)
4119
+ );
4120
+ }
4121
+ function createListType(options) {
4122
+ const BaseType = createNestedTemplatedElementType(options);
4123
+ let ListView = null;
4124
+ return class extends BaseType {
4125
+ getView() {
4126
+ if (!ListView) {
4127
+ ListView = createListView(options);
4128
+ }
4129
+ return ListView;
4130
+ }
4131
+ };
4132
+ }
4133
+ function createListView(options) {
4134
+ const BaseView = createNestedTemplatedElementView(options);
4135
+ return BaseView.extend({
4136
+ getRenderContext() {
4137
+ const parentContext = this._parent?.getRenderContext?.();
4138
+ const settings = this.model.get("settings");
4139
+ const showMarkersProp = settings?.get?.("show_markers");
4140
+ const showMarkers = showMarkersProp?.value ?? showMarkersProp ?? true;
4141
+ return {
4142
+ ...parentContext,
4143
+ show_markers: showMarkers
4144
+ };
4145
+ },
4146
+ getResolverRenderContext() {
4147
+ const parentContext = this._parent?.getResolverRenderContext?.();
4148
+ const settings = this.model.get("settings");
4149
+ const showMarkersProp = settings?.get?.("show_markers");
4150
+ const showMarkers = showMarkersProp?.value ?? showMarkersProp ?? true;
4151
+ return {
4152
+ ...parentContext,
4153
+ show_markers: showMarkers
4154
+ };
4155
+ }
4156
+ });
4157
+ }
4158
+
3894
4159
  // src/legacy/tabs-model-extensions.ts
3895
- import { htmlV3PropTypeUtil as htmlV3PropTypeUtil3, stringPropTypeUtil as stringPropTypeUtil3 } from "@elementor/editor-props";
4160
+ import { escapedHtmlPropTypeUtil as escapedHtmlPropTypeUtil3 } from "@elementor/editor-props";
3896
4161
  var tabModelExtensions = {
3897
4162
  modifyDefaultChildren(elements) {
3898
4163
  if (!Array.isArray(elements) || elements.length === 0) {
@@ -3908,10 +4173,7 @@ var tabModelExtensions = {
3908
4173
  ...paragraphElement,
3909
4174
  settings: {
3910
4175
  ...paragraphElement.settings,
3911
- paragraph: htmlV3PropTypeUtil3.create({
3912
- content: stringPropTypeUtil3.create(`Tab ${position}`),
3913
- children: []
3914
- })
4176
+ paragraph: escapedHtmlPropTypeUtil3.create(`Tab ${position}`)
3915
4177
  }
3916
4178
  };
3917
4179
  return [updatedParagraph, ...elements.slice(1)];
@@ -3922,22 +4184,22 @@ function initTabsModelExtensions() {
3922
4184
  }
3923
4185
 
3924
4186
  // src/mcp/canvas-mcp.ts
3925
- import { Schema as Schema4 } from "@elementor/editor-props";
4187
+ import { Schema as Schema3 } from "@elementor/editor-props";
3926
4188
 
3927
4189
  // src/mcp/resources/available-widgets-resource.ts
3928
4190
  import { httpService as httpService3 } from "@elementor/http-client";
3929
4191
  var MCP_PROXY_URL2 = "elementor/v1/mcp-proxy";
3930
4192
  var AVAILABLE_WIDGETS_URI = "elementor://context/available-widgets";
3931
4193
  var AVAILABLE_WIDGETS_URI_V4 = "elementor://context/available-widgets/v4";
3932
- var fetchWidgets = async (version) => {
4194
+ var fetchWidgets = async () => {
3933
4195
  const { data } = await httpService3().post(MCP_PROXY_URL2, {
3934
- tool: "list-widgets",
3935
- input: version ? { version } : {}
4196
+ tool: "list-widget-schemas",
4197
+ input: { summary: true }
3936
4198
  });
3937
- return data.data ?? [];
4199
+ return data.data?.widgets ?? [];
3938
4200
  };
3939
- var buildContents = async (uri, version) => {
3940
- const widgets = await fetchWidgets(version);
4201
+ var buildContents = async (uri) => {
4202
+ const widgets = await fetchWidgets();
3941
4203
  return {
3942
4204
  contents: [
3943
4205
  {
@@ -3956,13 +4218,13 @@ var initAvailableWidgetsResource = (reg) => {
3956
4218
  {
3957
4219
  description: "All registered v4 version widgets"
3958
4220
  },
3959
- async () => buildContents(AVAILABLE_WIDGETS_URI_V4, "v4")
4221
+ async () => buildContents(AVAILABLE_WIDGETS_URI_V4)
3960
4222
  );
3961
4223
  resource(
3962
4224
  "available-widgets",
3963
4225
  AVAILABLE_WIDGETS_URI,
3964
4226
  {
3965
- description: "All registered widget types with v3/v4 version metadata and description."
4227
+ description: "All registered v4 widget types with description."
3966
4228
  },
3967
4229
  async () => buildContents(AVAILABLE_WIDGETS_URI)
3968
4230
  );
@@ -4097,11 +4359,10 @@ import { httpService as httpService5 } from "@elementor/http-client";
4097
4359
  var DYNAMIC_TAGS_URI = "elementor://dynamic-tags";
4098
4360
  var MCP_PROXY_URL4 = "elementor/v1/mcp-proxy";
4099
4361
  var fetchDynamicTags = async () => {
4100
- const { data } = await httpService5().post(MCP_PROXY_URL4, {
4101
- tool: "list-dynamic-tags",
4102
- input: {}
4362
+ const { data } = await httpService5().get(MCP_PROXY_URL4, {
4363
+ params: { uri: DYNAMIC_TAGS_URI }
4103
4364
  });
4104
- return data.data ?? [];
4365
+ return data.data ?? "[]";
4105
4366
  };
4106
4367
  var initDynamicTagsResource = (reg) => {
4107
4368
  const { resource } = reg;
@@ -4113,13 +4374,12 @@ var initDynamicTagsResource = (reg) => {
4113
4374
  mimeType: "application/json"
4114
4375
  },
4115
4376
  async (uri) => {
4116
- const tags = await fetchDynamicTags();
4117
4377
  return {
4118
4378
  contents: [
4119
4379
  {
4120
4380
  uri: uri.href,
4121
4381
  mimeType: "application/json",
4122
- text: JSON.stringify(tags)
4382
+ text: await fetchDynamicTags()
4123
4383
  }
4124
4384
  ]
4125
4385
  };
@@ -4445,99 +4705,8 @@ function getElementDisplayName(container) {
4445
4705
  }
4446
4706
  }
4447
4707
 
4448
- // src/mcp/tools/build-composition/tool.ts
4449
- import { getCurrentDocument, reloadCurrentDocument } from "@elementor/editor-documents";
4450
- import { getContainer as getContainer4, selectElement } from "@elementor/editor-elements";
4451
- import { AxiosError, httpService as httpService6 } from "@elementor/http-client";
4452
- import { z } from "@elementor/schema";
4453
- var MCP_PROXY_URL5 = "elementor/v1/mcp-proxy";
4454
- var initBuildCompositionTool = (reg) => {
4455
- const { addTool } = reg;
4456
- addTool({
4457
- name: "build-composition",
4458
- description: "Build a V4 element composition on the Elementor canvas via the server-side MCP ability. Pass the raw XML tags directly as xmlStructure \u2014 do NOT wrap the value in <![CDATA[ ... ]]>, code fences, or quotes. The document is saved as a draft. Reload the editor after calling this tool to see the result.",
4459
- schema: {
4460
- xmlStructure: z.string().describe(
4461
- 'Valid XML structure with custom Elementor widget tags. Every element MUST have a unique configuration-id attribute (e.g. <e-heading configuration-id="hero-title"></e-heading>). No attributes, classes, IDs, or text nodes in XML. Pass raw XML \u2014 do not wrap in CDATA.'
4462
- ),
4463
- elementConfig: z.record(
4464
- z.string().describe("configuration-id"),
4465
- z.record(z.string().describe("property name"), z.any().describe("PropValue"))
4466
- ).optional().describe("Map configuration-id \u2192 widget PropValues ($$type + value)."),
4467
- style: z.record(
4468
- z.string().describe("configuration-id"),
4469
- z.record(z.string().describe("CSS property name"), z.string().describe("CSS value"))
4470
- ).optional().describe(
4471
- "Map configuration-id \u2192 raw CSS declarations (property \u2192 value strings; no selectors). Server converts to native styles; unconvertible declarations become the element custom CSS."
4472
- ),
4473
- parentId: z.string().optional().describe("ID of the parent container. Omit or pass 'document' to insert at document root."),
4474
- dryRun: z.boolean().optional().describe("If true, validate and return the resolved tree without persisting.")
4475
- },
4476
- outputSchema: {
4477
- rootElementIds: z.array(z.string()),
4478
- previewUrl: z.string(),
4479
- version: z.string(),
4480
- resolvedXml: z.string(),
4481
- llmInstructions: z.string(),
4482
- warnings: z.array(z.string()).optional()
4483
- },
4484
- handler: async ({ xmlStructure, elementConfig, style, parentId, dryRun }) => {
4485
- const document2 = getCurrentDocument();
4486
- if (!document2?.id) {
4487
- throw new Error("No active document found.");
4488
- }
4489
- try {
4490
- const { data } = await httpService6().post(MCP_PROXY_URL5, {
4491
- tool: "build-composition",
4492
- input: {
4493
- post_id: document2.id,
4494
- xml_structure: xmlStructure,
4495
- element_config: elementConfig ?? {},
4496
- style: style ?? {},
4497
- parent_id: parentId ?? "document",
4498
- dry_run: dryRun ?? false
4499
- }
4500
- });
4501
- if (!dryRun) {
4502
- await reloadCurrentDocument();
4503
- const [firstRootId] = data.data.root_element_ids;
4504
- if (firstRootId) {
4505
- selectElement(firstRootId);
4506
- getContainer4(firstRootId)?.view?.el?.scrollIntoView({
4507
- behavior: "smooth",
4508
- block: "center"
4509
- });
4510
- }
4511
- }
4512
- return {
4513
- rootElementIds: data.data.root_element_ids,
4514
- previewUrl: data.data.preview_url,
4515
- version: data.data.version,
4516
- resolvedXml: data.data.resolved_xml,
4517
- llmInstructions: data.data.llm_instructions,
4518
- warnings: data.data.warnings
4519
- };
4520
- } catch (error) {
4521
- throw new Error(getErrorMessage(error));
4522
- }
4523
- }
4524
- });
4525
- };
4526
- function getErrorMessage(error) {
4527
- if (error instanceof AxiosError) {
4528
- const data = error.response?.data;
4529
- if (data?.message) {
4530
- return data.code ? `${data.code}: ${data.message}` : data.message;
4531
- }
4532
- }
4533
- if (error instanceof Error) {
4534
- return error.message;
4535
- }
4536
- return "build-composition failed with an unknown error.";
4537
- }
4538
-
4539
4708
  // src/mcp/tools/configure-element/tool.ts
4540
- import { getContainer as getContainer5, getWidgetsCache as getWidgetsCache6 } from "@elementor/editor-elements";
4709
+ import { getContainer as getContainer4, getWidgetsCache as getWidgetsCache6 } from "@elementor/editor-elements";
4541
4710
  import { dispatchMcpStylesAppliedEvent } from "@elementor/editor-mcp";
4542
4711
  import { Schema as Schema2 } from "@elementor/editor-props";
4543
4712
 
@@ -4569,9 +4738,9 @@ var readStoredCustomCssText = (raw) => {
4569
4738
 
4570
4739
  // src/mcp/utils/resolve-canonical-prop-name.ts
4571
4740
  import { getWidgetsCache as getWidgetsCache4 } from "@elementor/editor-elements";
4572
- function buildAliasToCanonicalMap(schema2) {
4741
+ function buildAliasToCanonicalMap(schema) {
4573
4742
  const aliasToCanonical = {};
4574
- for (const [canonical, propType] of Object.entries(schema2)) {
4743
+ for (const [canonical, propType] of Object.entries(schema)) {
4575
4744
  const aliases = propType.meta?.aliases;
4576
4745
  if (!Array.isArray(aliases)) {
4577
4746
  continue;
@@ -4585,26 +4754,26 @@ function buildAliasToCanonicalMap(schema2) {
4585
4754
  return aliasToCanonical;
4586
4755
  }
4587
4756
  function resolveCanonicalPropName(elementType, propertyName) {
4588
- const schema2 = getWidgetsCache4()?.[elementType]?.atomic_props_schema;
4589
- if (!schema2 || schema2[propertyName]) {
4757
+ const schema = getWidgetsCache4()?.[elementType]?.atomic_props_schema;
4758
+ if (!schema || schema[propertyName]) {
4590
4759
  return propertyName;
4591
4760
  }
4592
- return buildAliasToCanonicalMap(schema2)[propertyName] ?? propertyName;
4761
+ return buildAliasToCanonicalMap(schema)[propertyName] ?? propertyName;
4593
4762
  }
4594
4763
  function resolveCanonicalPropKeys(elementType, props) {
4595
- const schema2 = getWidgetsCache4()?.[elementType]?.atomic_props_schema;
4596
- if (!schema2) {
4764
+ const schema = getWidgetsCache4()?.[elementType]?.atomic_props_schema;
4765
+ if (!schema) {
4597
4766
  return { ...props };
4598
4767
  }
4599
- const aliasToCanonical = buildAliasToCanonicalMap(schema2);
4768
+ const aliasToCanonical = buildAliasToCanonicalMap(schema);
4600
4769
  const resolved = {};
4601
4770
  for (const [key, value] of Object.entries(props)) {
4602
- if (schema2[key]) {
4771
+ if (schema[key]) {
4603
4772
  resolved[key] = value;
4604
4773
  }
4605
4774
  }
4606
4775
  for (const [key, value] of Object.entries(props)) {
4607
- if (schema2[key]) {
4776
+ if (schema[key]) {
4608
4777
  continue;
4609
4778
  }
4610
4779
  const canonical = aliasToCanonical[key];
@@ -4652,9 +4821,9 @@ var dynamicTagLLMResolver = (value) => {
4652
4821
  }
4653
4822
  };
4654
4823
  };
4655
- var buildStrictSettings = (schema2, provided) => {
4824
+ var buildStrictSettings = (schema, provided) => {
4656
4825
  const settings = {};
4657
- for (const [key, propType] of Object.entries(schema2)) {
4826
+ for (const [key, propType] of Object.entries(schema)) {
4658
4827
  if (OMITTED_DYNAMIC_SETTING_KEYS.includes(key)) {
4659
4828
  continue;
4660
4829
  }
@@ -4686,6 +4855,20 @@ var LOCAL_STYLE_META = {
4686
4855
  breakpoint: "desktop",
4687
4856
  state: null
4688
4857
  };
4858
+ var UnsupportedPropertyError = class extends Error {
4859
+ elementType;
4860
+ propertyName;
4861
+ constructor(elementType, propertyName, availableProperties) {
4862
+ super(
4863
+ `Property "${propertyName}" does not exist on element type "${elementType}". Available properties are: ${availableProperties.join(
4864
+ ", "
4865
+ )}`
4866
+ );
4867
+ this.name = "UnsupportedPropertyError";
4868
+ this.elementType = elementType;
4869
+ this.propertyName = propertyName;
4870
+ }
4871
+ };
4689
4872
  function resolvePropValue(value, forceKey) {
4690
4873
  const Utils = window.elementorV2.editorVariables.Utils;
4691
4874
  return Schema.adjustLlmPropValueSchema(value, {
@@ -4791,12 +4974,7 @@ var doUpdateElementProperty = (params) => {
4791
4974
  throw new Error(`No prop schema found for element type: ${elementType}`);
4792
4975
  }
4793
4976
  if (!elementPropSchema[propertyName]) {
4794
- const propertyNames = Object.keys(elementPropSchema);
4795
- throw new Error(
4796
- `Property "${propertyName}" does not exist on element type "${elementType}". Available properties are: ${propertyNames.join(
4797
- ", "
4798
- )}`
4799
- );
4977
+ throw new UnsupportedPropertyError(elementType, propertyName, Object.keys(elementPropSchema));
4800
4978
  }
4801
4979
  const propKey = elementPropSchema[propertyName].key;
4802
4980
  const value = resolvePropValue(propertyValue, propKey);
@@ -4866,8 +5044,6 @@ For all non-primitive entries in \`propertiesToChange\`, provide the schema \`ke
4866
5044
 
4867
5045
  Use the EXACT PropType schema given, and ALWAYS include the \`key\` from the schema for every property you are changing in \`propertiesToChange\`.
4868
5046
 
4869
- Check \`llm_guidance.default_settings\` in the widget schema \u2014 include a key in \`propertiesToChange\` only when the user explicitly asks to change it.
4870
-
4871
5047
  # Dynamic tags
4872
5048
  A value can be made dynamic wherever its schema exposes a variant with "$$type": "dynamic". This may be the property root OR a NESTED field: for example an image is made dynamic on its "src" (the root stays "image"), NOT on the whole "image" value.
4873
5049
  Put the dynamic object EXACTLY at the node whose schema offers the "dynamic" variant, in place of the static variant. The variant's "name" enumerates the tags allowed at that node.
@@ -4894,7 +5070,7 @@ Do NOT send "group" (it is resolved automatically). Use { "settings": {} } only
4894
5070
  );
4895
5071
  configureElementToolPrompt.parameter(
4896
5072
  "style",
4897
- 'A flat map of raw CSS declarations (property \u2192 value), e.g. { "line-height": "1.25rem", "color": "var(--primary-text, #000)" }. Set a value to null to reset that property to its default. OPTIONAL.'
5073
+ 'A flat map of raw CSS declarations (property \u2192 value), e.g. { "line-height": "1.25rem", "color": "var(--primary-text, #000)" }. font-family must be a single Google Font name or a var(--label) \u2014 no fallback stacks. Set a value to null to reset that property to its default. OPTIONAL.'
4898
5074
  );
4899
5075
  configureElementToolPrompt.example(`
4900
5076
  \`\`\`json
@@ -4926,36 +5102,39 @@ Do NOT send "group" (it is resolved automatically). Use { "settings": {} } only
4926
5102
  V4 only: If MCP fails, give manual steps using V4 UI.
4927
5103
 
4928
5104
  V4 Editor structure:
4929
- Panel tabs: General (\u2192 Settings section: ID, Tag, Link), Style, Interactions.
5105
+ Panel tabs: General (\u2192 Settings section: ID, Tag, and Link where the widget supports it), Style, Interactions.
4930
5106
  NO Advanced tab. Never mention Advanced tab.
5107
+ Note: \`link\` is valid only when the element's PropType schema (which you must already have) includes a \`link\` property. Sending \`link\` to a widget whose schema lacks it is skipped and reported in the response \`warnings\` (other changes still apply) and the link is lost.
4931
5108
  `);
4932
5109
  return configureElementToolPrompt.prompt();
4933
5110
  };
4934
- var CONFIGURE_ELEMENT_GUIDE_TEXT = generatePrompt();
4935
5111
 
4936
5112
  // src/mcp/tools/configure-element/schema.ts
4937
- import { z as z2 } from "@elementor/schema";
5113
+ import { z } from "@elementor/schema";
4938
5114
  var inputSchema = {
4939
- propertiesToChange: z2.record(
4940
- z2.string().describe("The property name."),
4941
- z2.any().describe(`PropValue, refer to [${WIDGET_SCHEMA_URI}] by correct type, as appears in elementType`),
4942
- z2.any()
5115
+ propertiesToChange: z.record(
5116
+ z.string().describe("The property name."),
5117
+ z.any().describe(`PropValue, refer to [${WIDGET_SCHEMA_URI}] by correct type, as appears in elementType`),
5118
+ z.any()
4943
5119
  ).describe("An object record containing property names and their new values to be set on the element"),
4944
- style: z2.record(
4945
- z2.string().describe('A CSS property name, e.g. "color", "margin-top".'),
4946
- z2.string().nullable().describe(
5120
+ style: z.record(
5121
+ z.string().describe('A CSS property name, e.g. "color", "margin-top".'),
5122
+ z.string().nullable().describe(
4947
5123
  'A CSS value, e.g. "red", "10px", "1px solid #000". Use null to reset the property to its default.'
4948
5124
  )
4949
5125
  ).describe(
4950
5126
  "Raw CSS declarations as a flat property\u2192value map. Converted to native styles server-side; any declaration that cannot be converted is stored as the element custom CSS. A null value resets that property to its default."
4951
5127
  ).default({}),
4952
- elementType: z2.string().describe("The type of the element to retrieve the schema"),
4953
- elementId: z2.string().describe("The unique id of the element to configure")
5128
+ elementType: z.string().describe("The type of the element to retrieve the schema"),
5129
+ elementId: z.string().describe("The unique id of the element to configure")
4954
5130
  };
4955
5131
  var outputSchema = {
4956
- success: z2.boolean().describe(
5132
+ success: z.boolean().describe(
4957
5133
  "Whether the configuration change was successful, only if propertyName and propertyValue are provided"
4958
- )
5134
+ ),
5135
+ warnings: z.string().describe(
5136
+ 'Non-fatal notices. Present when some props were skipped because they are not in the element schema (e.g. a "link" on a widget with no link prop). Other changes were still applied.'
5137
+ ).optional()
4959
5138
  };
4960
5139
 
4961
5140
  // src/mcp/tools/configure-element/tool.ts
@@ -4990,7 +5169,7 @@ var initConfigureElementTool = (reg) => {
4990
5169
  `Unknown element type: ${elementType}. Check the available-widgets resource for valid types.`
4991
5170
  );
4992
5171
  }
4993
- const container = getContainer5(elementId);
5172
+ const container = getContainer4(elementId);
4994
5173
  if (!container) {
4995
5174
  throw new Error(`Element with id ${elementId} not found`);
4996
5175
  }
@@ -5005,6 +5184,7 @@ var initConfigureElementTool = (reg) => {
5005
5184
  }
5006
5185
  const propertiesToUpdate = resolveCanonicalPropKeys(elementType, propertiesToChange);
5007
5186
  const toUpdate = Object.entries(propertiesToUpdate);
5187
+ const skippedProps = [];
5008
5188
  for (const [propertyName, propertyValue] of toUpdate) {
5009
5189
  if (!Schema2.isPropKeyConfigurable(propertyName)) {
5010
5190
  throw new Error(`Not allowed to update ${propertyName}`);
@@ -5017,6 +5197,10 @@ var initConfigureElementTool = (reg) => {
5017
5197
  propertyValue
5018
5198
  });
5019
5199
  } catch (error) {
5200
+ if (error instanceof UnsupportedPropertyError) {
5201
+ skippedProps.push(error.propertyName);
5202
+ continue;
5203
+ }
5020
5204
  const errorMessage = createUpdateErrorMessage({
5021
5205
  propertyName,
5022
5206
  elementId,
@@ -5029,7 +5213,10 @@ var initConfigureElementTool = (reg) => {
5029
5213
  }
5030
5214
  await applyStyleFromCss({ elementId, elementType, style });
5031
5215
  return {
5032
- success: true
5216
+ success: true,
5217
+ warnings: skippedProps.length ? `Skipped unsupported props (not in the "${elementType}" schema; other changes were applied): ${skippedProps.join(
5218
+ ", "
5219
+ )}.` : void 0
5033
5220
  };
5034
5221
  }
5035
5222
  });
@@ -5081,102 +5268,74 @@ Provide styling as raw CSS via the "style" parameter (a flat map of CSS property
5081
5268
  }`;
5082
5269
  }
5083
5270
 
5084
- // src/mcp/tools/get-element-config/tool.ts
5085
- import { getContainer as getContainer6, getElementStyles as getElementStyles2, getWidgetsCache as getWidgetsCache7 } from "@elementor/editor-elements";
5086
- import { Schema as Schema3 } from "@elementor/editor-props";
5087
- import { z as z3 } from "@elementor/schema";
5088
- var schema = {
5089
- elementId: z3.string()
5090
- };
5091
- var outputSchema2 = {
5092
- properties: z3.record(z3.string(), z3.any()).describe("A record mapping PropTypes to their corresponding PropValues"),
5093
- style: z3.record(z3.string(), z3.any()).describe("A record mapping StyleSchema properties to their corresponding PropValues"),
5094
- childElements: z3.array(
5095
- z3.object({
5096
- id: z3.string(),
5097
- elementType: z3.string(),
5098
- childElements: z3.array(z3.any()).describe("An array of child element IDs, when applicable, same structure recursively")
5099
- })
5100
- ).describe("An array of child element IDs, when applicable, with recursive structure")
5101
- };
5102
- var structuredElements = (element) => {
5103
- const children = element.children || [];
5104
- return children.map((child) => {
5105
- return {
5106
- id: child.id,
5107
- elementType: child.model.get("elType") || child.model.get("widgetType") || "unknown",
5108
- childElements: structuredElements(child)
5109
- };
5110
- });
5111
- };
5112
- var initGetElementConfigTool = (reg) => {
5271
+ // src/mcp/tools/get-page-structure/tool.ts
5272
+ import { getCurrentDocument } from "@elementor/editor-documents";
5273
+ import { httpService as httpService6 } from "@elementor/http-client";
5274
+ import { z as z2 } from "@elementor/schema";
5275
+
5276
+ // src/mcp/utils/get-mcp-error-message.ts
5277
+ import { AxiosError } from "@elementor/http-client";
5278
+ function getMcpErrorMessage(error, toolName) {
5279
+ if (error instanceof AxiosError) {
5280
+ const data = error.response?.data;
5281
+ if (data?.message) {
5282
+ return data.code ? `${data.code}: ${data.message}` : data.message;
5283
+ }
5284
+ }
5285
+ if (error instanceof Error) {
5286
+ return error.message;
5287
+ }
5288
+ return `${toolName} failed with an unknown error.`;
5289
+ }
5290
+
5291
+ // src/mcp/tools/get-page-structure/tool.ts
5292
+ var MCP_PROXY_URL5 = "elementor/v1/mcp-proxy";
5293
+ var initGetPageStructureTool = (reg) => {
5113
5294
  const { addTool } = reg;
5114
5295
  addTool({
5115
- name: "get-element-configuration-values",
5116
- description: "Retrieve the element's configuration PropValues for a specific element by unique ID.",
5117
- schema,
5118
- outputSchema: outputSchema2,
5119
- handler: async ({ elementId }) => {
5120
- const element = getContainer6(elementId);
5121
- if (!element) {
5122
- throw new Error(`Element with ID ${elementId} not found.`);
5123
- }
5124
- const elementType = element.model.get("widgetType") || element.model.get("elType") || "";
5125
- const widgetData = getWidgetsCache7()?.[elementType];
5126
- if (!widgetData) {
5127
- throw new Error(
5128
- `Unknown element type: ${elementType}. Check the available-widgets resource for valid types.`
5129
- );
5130
- }
5131
- if (!widgetData.atomic_props_schema) {
5132
- throw new Error(
5133
- `This tool does not support V3 elements. Please use the elementor-v3-mcp tools instead for element type: ${elementType}`
5134
- );
5135
- }
5136
- const elementRawSettings = element.settings;
5137
- const propSchema = getWidgetsCache7()?.[elementType]?.atomic_props_schema;
5138
- if (!elementRawSettings || !propSchema) {
5139
- throw new Error(`No settings or prop schema found for element ID: ${elementId}`);
5296
+ name: "get-page-structure",
5297
+ description: "Returns a lean Elementor element tree skeleton (id, elType, widgetType, title, nested elements) for a post or page. If no postId is provided, uses the currently open document. Optionally scope to a subtree with elementId. Set includeContent=true (requires elementId) to also return each node's settings and styles.",
5298
+ schema: {
5299
+ postId: z2.number().optional().describe(
5300
+ "WordPress post ID of the Elementor document. If omitted, uses the currently open document."
5301
+ ),
5302
+ elementId: z2.string().optional().describe("If provided, returns only the subtree rooted at that element id."),
5303
+ includeContent: z2.boolean().optional().describe(
5304
+ "If true, includes each node's settings and styles (same shape build-composition accepts as input). Requires elementId."
5305
+ )
5306
+ },
5307
+ outputSchema: {
5308
+ elements: z2.array(z2.any()).describe(
5309
+ "Skeleton of Elementor elements (id, elType, widgetType, title, nested elements). When includeContent is true, each node also includes settings and styles."
5310
+ )
5311
+ },
5312
+ handler: async ({ postId, elementId, includeContent }) => {
5313
+ const resolvedPostId = postId ?? getCurrentDocument()?.id;
5314
+ if (!resolvedPostId) {
5315
+ throw new Error("No post ID provided and no active document found.");
5140
5316
  }
5141
- const propValues = {};
5142
- const stylePropValues = {};
5143
- Schema3.configurableKeys(propSchema).forEach((key) => {
5144
- propValues[key] = structuredClone(elementRawSettings.get(key));
5145
- });
5146
- const elementStyles = getElementStyles2(elementId) || {};
5147
- const localStyle = Object.values(elementStyles).find((style) => style.label === "local");
5148
- if (localStyle) {
5149
- const defaultVariant = localStyle.variants.find(
5150
- (variant) => variant.meta.breakpoint === "desktop" && !variant.meta.state
5151
- );
5152
- if (defaultVariant) {
5153
- const styleProps = defaultVariant.props || {};
5154
- Object.keys(styleProps).forEach((stylePropName) => {
5155
- if (typeof styleProps[stylePropName] !== "undefined") {
5156
- stylePropValues[stylePropName] = structuredClone(styleProps[stylePropName]);
5157
- }
5158
- });
5159
- if (defaultVariant.custom_css) {
5160
- stylePropValues.custom_css = atob(defaultVariant.custom_css.raw);
5317
+ try {
5318
+ const { data } = await httpService6().post(MCP_PROXY_URL5, {
5319
+ tool: "get-page-structure",
5320
+ input: {
5321
+ post_id: resolvedPostId,
5322
+ ...elementId ? { element_id: elementId } : {},
5323
+ ...includeContent ? { include_content: true } : {}
5161
5324
  }
5162
- }
5325
+ });
5326
+ return {
5327
+ elements: data.data.elements
5328
+ };
5329
+ } catch (error) {
5330
+ throw new Error(getMcpErrorMessage(error, "get-page-structure"));
5163
5331
  }
5164
- return {
5165
- properties: {
5166
- ...propValues
5167
- },
5168
- style: {
5169
- ...stylePropValues
5170
- },
5171
- childElements: structuredElements(element)
5172
- };
5173
5332
  }
5174
5333
  });
5175
5334
  };
5176
5335
 
5177
5336
  // src/mcp/canvas-mcp.ts
5178
5337
  var initCanvasMcp = (reg) => {
5179
- Schema4.setDynamicTagNamesResolver(getDynamicTagNamesByCategories);
5338
+ Schema3.setDynamicTagNamesResolver(getDynamicTagNamesByCategories);
5180
5339
  initWidgetsSchemaResource(reg);
5181
5340
  initAvailableWidgetsResource(reg);
5182
5341
  initDocumentStructureResource(reg);
@@ -5185,16 +5344,15 @@ var initCanvasMcp = (reg) => {
5185
5344
  initEditorStateResource(reg);
5186
5345
  initGeneralContextResource(reg);
5187
5346
  initBestPracticesResource(reg);
5188
- initGetElementConfigTool(reg);
5189
5347
  initConfigureElementTool(reg);
5190
- initBuildCompositionTool(reg);
5348
+ initGetPageStructureTool(reg);
5191
5349
  initBreakpointsResource(reg);
5192
5350
  };
5193
5351
 
5194
5352
  // src/mcp/mcp-description.ts
5195
5353
  var ELEMENT_SCHEMA_URI = WIDGET_SCHEMA_URI.replace("{widgetType}", "element-schema");
5196
5354
  var mcpDescription = `Elementor Canvas MCP
5197
- This MCP enables creation, configuration, and styling of elements on the Elementor canvas using the build_composition tool.
5355
+ This MCP enables configuration and styling of existing V4 elements on the Elementor canvas using the configure-element tool.
5198
5356
 
5199
5357
  # Core Concepts
5200
5358
 
@@ -5213,66 +5371,54 @@ The \`$$type\` defines how Elementor interprets the value. Providing the correct
5213
5371
  - **Global Classes**: Reusable style sets that can be applied to elements (\`elementor://global-classes\`)
5214
5372
  - **Widget Schemas**: Configuration options for each widget type (\`${WIDGET_SCHEMA_URI}\`)
5215
5373
 
5216
- # Building Compositions with build_composition
5374
+ # Configuring Elements with configure-element
5217
5375
 
5218
- The \`build_composition\` tool is the primary way to create elements. It accepts structure (XML), configuration, and styling in a single operation.
5376
+ The \`configure-element\` tool updates settings and styles on existing V4 elements. Read the configure-element guide resource before use.
5219
5377
 
5220
5378
  ## Complete Workflow
5221
5379
 
5222
5380
  ### 1. Parse User Requirements
5223
- Understand what needs to be built: structure, content, and styling.
5381
+ Understand what needs to change: content, settings, or styling on existing elements.
5224
5382
 
5225
5383
  ### 2. Check Global Resources FIRST
5226
- Always check existing resources before building:
5384
+ Always check existing resources before styling:
5227
5385
  - List \`elementor://global-variables\` for available variables (colors, sizes, fonts)
5228
5386
  - List \`elementor://global-classes\` for available style sets
5229
5387
  - **Always prefer using existing global resources over creating inline styles**
5230
5388
 
5231
5389
  ### 3. Retrieve Widget Schemas
5232
- For each widget you'll use:
5390
+ For each element you will configure:
5233
5391
  - List \`${WIDGET_SCHEMA_URI}\` to see available widgets
5234
5392
  - Retrieve configuration schema from \`${ELEMENT_SCHEMA_URI}\` for each widget
5235
- - Check the \`llm_guidance\` property for container nesting, \`default_styles\`, and \`default_settings\` (omit default_settings from elementConfig unless the user asks to change them)
5393
+ - Check the \`llm_guidance\` property for container nesting, \`default_styles\`, and \`default_settings\`
5236
5394
 
5237
- ### 4. Build XML Structure
5238
- Create valid XML with configuration-ids:
5239
- - Each element must have a unique \`configuration-id\` attribute
5240
- - No text nodes, classes, or IDs in XML - structure only
5241
- - Example:
5242
- \`\`\`xml
5243
- <e-container configuration-id="container-1">
5244
- <e-heading configuration-id="heading-1" />
5245
- <e-text configuration-id="text-1" />
5246
- </e-container>
5247
- \`\`\`
5395
+ ### 4. Get Current Element State
5396
+ Use page structure and element configuration resources to find element IDs and current values.
5248
5397
 
5249
- ### 5. Create elementConfig
5250
- Map each configuration-id to its widget properties using PropValues:
5398
+ ### 5. Create propertiesToChange
5399
+ Map property names to PropValues using the widget schema:
5251
5400
  - Use correct \`$$type\` matching the widget's schema
5252
5401
  - Use global variables in PropValues where applicable
5253
5402
  - Example:
5254
5403
  \`\`\`json
5255
5404
  {
5256
- "heading-1": {
5257
- "text": { "$$type": "string", "value": "Welcome" },
5258
- "tag": { "$$type": "string", "value": "h1" }
5259
- }
5405
+ "text": { "$$type": "string", "value": "Welcome" },
5406
+ "tag": { "$$type": "string", "value": "h1" }
5260
5407
  }
5261
5408
  \`\`\`
5262
5409
 
5263
5410
  ### 6. Create style
5264
- Map each configuration-id to raw CSS declarations (property \u2192 value strings). The server converts them to native styles and stores any unconvertible declarations as the element custom CSS.
5411
+ Provide raw CSS declarations (property \u2192 value strings). The server converts them to native styles and stores any unconvertible declarations as the element custom CSS.
5265
5412
  - Example:
5266
5413
  \`\`\`json
5267
5414
  {
5268
- "heading-1": "color: #1a1a1a; font-size: 2rem;"
5269
- }
5415
+ "color": "#1a1a1a",
5416
+ "font-size": "2rem"
5270
5417
  }
5271
5418
  \`\`\`
5272
5419
 
5273
- ### 7. Execute build_composition
5274
- Call the tool with your XML structure, elementConfig, and style. The response will contain the created element IDs.
5275
- At the response you will also find llm_instructions for you to do afterwards, read and follow them!
5420
+ ### 7. Execute configure-element
5421
+ Call the tool with elementId, elementType, propertiesToChange, and style as needed.
5276
5422
 
5277
5423
  ## Key Points
5278
5424
 
@@ -5387,7 +5533,7 @@ function shouldBlock(sourceElements, targetElements) {
5387
5533
  }
5388
5534
 
5389
5535
  // src/style-commands/paste-style.ts
5390
- import { getContainer as getContainer7, getElementSetting, updateElementSettings as updateElementSettings2 } from "@elementor/editor-elements";
5536
+ import { getContainer as getContainer5, getElementSetting, updateElementSettings as updateElementSettings2 } from "@elementor/editor-elements";
5391
5537
  import { classesPropTypeUtil } from "@elementor/editor-props";
5392
5538
  import {
5393
5539
  __privateListenTo as listenTo5,
@@ -5396,7 +5542,7 @@ import {
5396
5542
  } from "@elementor/editor-v1-adapters";
5397
5543
 
5398
5544
  // src/utils/command-utils.ts
5399
- import { getElementLabel as getElementLabel2, getWidgetsCache as getWidgetsCache8 } from "@elementor/editor-elements";
5545
+ import { getElementLabel as getElementLabel2, getWidgetsCache as getWidgetsCache7 } from "@elementor/editor-elements";
5400
5546
  import { CLASSES_PROP_KEY } from "@elementor/editor-props";
5401
5547
  import { __ as __5 } from "@wordpress/i18n";
5402
5548
  function hasAtomicWidgets(args) {
@@ -5421,7 +5567,7 @@ function getClassesProp(container) {
5421
5567
  }
5422
5568
  function getContainerSchema(container) {
5423
5569
  const type = container?.model.get("widgetType") || container?.model.get("elType");
5424
- const widgetsCache = getWidgetsCache8();
5570
+ const widgetsCache = getWidgetsCache7();
5425
5571
  const elementType = widgetsCache?.[type];
5426
5572
  return elementType?.atomic_props_schema ?? null;
5427
5573
  }
@@ -5441,7 +5587,7 @@ function getTitleForContainers(containers) {
5441
5587
  import {
5442
5588
  createElementStyle as createElementStyle2,
5443
5589
  deleteElementStyle,
5444
- getElementStyles as getElementStyles3,
5590
+ getElementStyles as getElementStyles2,
5445
5591
  updateElementStyle as updateElementStyle2
5446
5592
  } from "@elementor/editor-elements";
5447
5593
  import { ELEMENTS_STYLES_RESERVED_LABEL } from "@elementor/editor-styles-repository";
@@ -5456,7 +5602,7 @@ var undoablePasteElementStyle = () => undoable2(
5456
5602
  if (!classesProp) {
5457
5603
  return null;
5458
5604
  }
5459
- const originalStyles = getElementStyles3(container.id);
5605
+ const originalStyles = getElementStyles2(container.id);
5460
5606
  const [styleId, styleDef] = Object.entries(originalStyles ?? {})[0] ?? [];
5461
5607
  const originalStyle = Object.keys(styleDef ?? {}).length ? styleDef : null;
5462
5608
  const revertData = {
@@ -5540,7 +5686,7 @@ function pasteStyles(args, pasteLocalStyle) {
5540
5686
  }
5541
5687
  const clipboardElements = getClipboardElements(storageKey);
5542
5688
  const [clipboardElement] = clipboardElements ?? [];
5543
- const clipboardContainer = getContainer7(clipboardElement.id);
5689
+ const clipboardContainer = getContainer5(clipboardElement.id);
5544
5690
  if (!clipboardElement || !clipboardContainer || !isAtomicWidget(clipboardContainer)) {
5545
5691
  return;
5546
5692
  }
@@ -5586,7 +5732,7 @@ import {
5586
5732
  } from "@elementor/editor-v1-adapters";
5587
5733
 
5588
5734
  // src/style-commands/undoable-actions/reset-element-style.ts
5589
- import { createElementStyle as createElementStyle3, deleteElementStyle as deleteElementStyle2, getElementStyles as getElementStyles4 } from "@elementor/editor-elements";
5735
+ import { createElementStyle as createElementStyle3, deleteElementStyle as deleteElementStyle2, getElementStyles as getElementStyles3 } from "@elementor/editor-elements";
5590
5736
  import { ELEMENTS_STYLES_RESERVED_LABEL as ELEMENTS_STYLES_RESERVED_LABEL2 } from "@elementor/editor-styles-repository";
5591
5737
  import { undoable as undoable3 } from "@elementor/editor-v1-adapters";
5592
5738
  import { __ as __7 } from "@wordpress/i18n";
@@ -5595,7 +5741,7 @@ var undoableResetElementStyle = () => undoable3(
5595
5741
  do: ({ containers }) => {
5596
5742
  return containers.map((container) => {
5597
5743
  const elementId = container.model.get("id");
5598
- const containerStyles = getElementStyles4(elementId);
5744
+ const containerStyles = getElementStyles3(elementId);
5599
5745
  Object.keys(containerStyles ?? {}).forEach(
5600
5746
  (styleId) => deleteElementStyle2(elementId, styleId)
5601
5747
  );
@@ -5687,15 +5833,15 @@ function init() {
5687
5833
  initCanvasMcp(
5688
5834
  getMCPByDomain("canvas", {
5689
5835
  instructions: `Everything related to V4 ( Atomic ) canvas.
5690
- # Canvas workflow for new compositions
5691
- - Configure elements settings and styles
5692
- - Build compositions/sections out of V4 atomic elements using context aware designs using the website resources
5693
- - Get and retrieve element configuration values
5836
+ # Canvas workflow
5837
+ - Configure element settings and styles with configure-element
5838
+ - Get page structure and element configuration values
5694
5839
  `,
5695
5840
  docs: mcpDescription
5696
5841
  })
5697
5842
  );
5698
5843
  initTabsModelExtensions();
5844
+ initListType();
5699
5845
  }
5700
5846
 
5701
5847
  // src/sync/drag-element-from-panel.ts
@@ -5817,10 +5963,10 @@ function useEscapeOnCanvas(canvasDocument, onEscape) {
5817
5963
  }
5818
5964
 
5819
5965
  // src/utils/after-render.ts
5820
- import { getContainer as getContainer8 } from "@elementor/editor-elements";
5966
+ import { getContainer as getContainer6 } from "@elementor/editor-elements";
5821
5967
  function doAfterRender(elementIds, callback) {
5822
5968
  const pending = elementIds.map((elementId) => {
5823
- const view = getContainer8(elementId)?.view;
5969
+ const view = getContainer6(elementId)?.view;
5824
5970
  if (!view || !hasDoAfterRender(view)) {
5825
5971
  return void 0;
5826
5972
  }