@elementor/editor-canvas 4.0.0-564 → 4.0.0-573
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +0 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js +123 -128
- package/dist/index.mjs +123 -128
- package/package.json +18 -18
- package/src/legacy/create-nested-templated-element-type.ts +77 -24
- package/src/legacy/create-templated-element-type.ts +70 -23
- package/src/legacy/twig-rendering-utils.ts +16 -135
- package/src/legacy/types.ts +0 -2
- package/src/mcp/tools/build-composition/schema.ts +0 -14
- package/src/mcp/tools/build-composition/tool.ts +11 -10
- package/src/renderers/__tests__/create-dom-renderer.test.ts +1 -0
- package/src/renderers/__tests__/create-styles-renderer.test.ts +1 -0
- package/src/legacy/__tests__/twig-rendering-utils.test.ts +0 -115
package/dist/index.d.mts
CHANGED
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -1762,9 +1762,9 @@ function createElementViewClassDeclaration() {
|
|
|
1762
1762
|
var import_editor_elements4 = require("@elementor/editor-elements");
|
|
1763
1763
|
|
|
1764
1764
|
// src/legacy/twig-rendering-utils.ts
|
|
1765
|
-
function
|
|
1765
|
+
function setupTwigRenderer({ renderer, element }) {
|
|
1766
1766
|
const templateKey = element.twig_main_template;
|
|
1767
|
-
const
|
|
1767
|
+
const baseStylesDictionary = element.base_styles_dictionary;
|
|
1768
1768
|
Object.entries(element.twig_templates).forEach(([key, template]) => {
|
|
1769
1769
|
renderer.register(key, template);
|
|
1770
1770
|
});
|
|
@@ -1772,7 +1772,7 @@ function createTwigRenderState({ renderer, element }) {
|
|
|
1772
1772
|
transformers: settingsTransformersRegistry,
|
|
1773
1773
|
schema: element.atomic_props_schema
|
|
1774
1774
|
});
|
|
1775
|
-
return { templateKey,
|
|
1775
|
+
return { templateKey, baseStylesDictionary, resolveProps };
|
|
1776
1776
|
}
|
|
1777
1777
|
function createBeforeRender(view) {
|
|
1778
1778
|
view._ensureViewIsIntact();
|
|
@@ -1785,87 +1785,18 @@ function createAfterRender(view) {
|
|
|
1785
1785
|
view.isRendered = true;
|
|
1786
1786
|
view.triggerMethod("render", view);
|
|
1787
1787
|
}
|
|
1788
|
-
function
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
domUpdateWasSkipped: false,
|
|
1792
|
-
invalidate() {
|
|
1793
|
-
this.lastResolvedSettingsHash = null;
|
|
1794
|
-
this.domUpdateWasSkipped = false;
|
|
1795
|
-
}
|
|
1796
|
-
};
|
|
1797
|
-
}
|
|
1798
|
-
async function renderTwigTemplate({
|
|
1799
|
-
view,
|
|
1800
|
-
signal,
|
|
1801
|
-
renderState,
|
|
1802
|
-
buildContext,
|
|
1803
|
-
attachContent,
|
|
1804
|
-
afterSettingsResolve
|
|
1805
|
-
}) {
|
|
1806
|
-
view.triggerMethod("before:render:template");
|
|
1807
|
-
const { resolveProps, cacheState, renderer, templateKey } = renderState;
|
|
1808
|
-
if (signal?.aborted) {
|
|
1809
|
-
return;
|
|
1810
|
-
}
|
|
1811
|
-
const settings = view.model.get("settings").toJSON();
|
|
1812
|
-
let resolvedSettings = await resolveProps({
|
|
1813
|
-
props: settings,
|
|
1814
|
-
signal,
|
|
1815
|
-
renderContext: view.getResolverRenderContext?.()
|
|
1788
|
+
function rerenderExistingChildren(view) {
|
|
1789
|
+
view.children?.each((childView) => {
|
|
1790
|
+
childView.render();
|
|
1816
1791
|
});
|
|
1817
|
-
if (signal?.aborted) {
|
|
1818
|
-
return;
|
|
1819
|
-
}
|
|
1820
|
-
if (afterSettingsResolve) {
|
|
1821
|
-
resolvedSettings = afterSettingsResolve(resolvedSettings);
|
|
1822
|
-
}
|
|
1823
|
-
const settingsHash = JSON.stringify(resolvedSettings);
|
|
1824
|
-
const settingsChanged = settingsHash !== cacheState.lastResolvedSettingsHash;
|
|
1825
|
-
if (!settingsChanged && view.isRendered) {
|
|
1826
|
-
cacheState.domUpdateWasSkipped = true;
|
|
1827
|
-
view.bindUIElements();
|
|
1828
|
-
view.triggerMethod("render:template");
|
|
1829
|
-
return;
|
|
1830
|
-
}
|
|
1831
|
-
cacheState.domUpdateWasSkipped = false;
|
|
1832
|
-
cacheState.lastResolvedSettingsHash = settingsHash;
|
|
1833
|
-
const context = buildContext(resolvedSettings);
|
|
1834
|
-
const html = await renderer.render(templateKey, context);
|
|
1835
|
-
if (signal?.aborted) {
|
|
1836
|
-
return;
|
|
1837
|
-
}
|
|
1838
|
-
attachContent(html);
|
|
1839
|
-
view.bindUIElements();
|
|
1840
|
-
view.triggerMethod("render:template");
|
|
1841
1792
|
}
|
|
1842
|
-
function
|
|
1793
|
+
async function waitForChildrenToComplete(view) {
|
|
1843
1794
|
const promises = [];
|
|
1844
|
-
children?.each((childView) => {
|
|
1795
|
+
view.children?.each((childView) => {
|
|
1845
1796
|
if (childView._currentRenderPromise) {
|
|
1846
1797
|
promises.push(childView._currentRenderPromise);
|
|
1847
1798
|
}
|
|
1848
1799
|
});
|
|
1849
|
-
return promises;
|
|
1850
|
-
}
|
|
1851
|
-
async function renderChildrenWithOptimization({
|
|
1852
|
-
children,
|
|
1853
|
-
domUpdateWasSkipped,
|
|
1854
|
-
renderChildren
|
|
1855
|
-
}) {
|
|
1856
|
-
const shouldReuseChildren = domUpdateWasSkipped && !!children?.length;
|
|
1857
|
-
if (shouldReuseChildren) {
|
|
1858
|
-
rerenderExistingChildViews(children);
|
|
1859
|
-
} else {
|
|
1860
|
-
renderChildren();
|
|
1861
|
-
}
|
|
1862
|
-
const promises = collectChildrenRenderPromises(children);
|
|
1863
|
-
await waitForChildrenToComplete(promises);
|
|
1864
|
-
}
|
|
1865
|
-
function rerenderExistingChildViews(children) {
|
|
1866
|
-
children?.each((childView) => childView.render());
|
|
1867
|
-
}
|
|
1868
|
-
async function waitForChildrenToComplete(promises) {
|
|
1869
1800
|
if (promises.length > 0) {
|
|
1870
1801
|
await Promise.all(promises);
|
|
1871
1802
|
}
|
|
@@ -1881,9 +1812,15 @@ function createTemplatedElementView({
|
|
|
1881
1812
|
element
|
|
1882
1813
|
}) {
|
|
1883
1814
|
const BaseView = createElementViewClassDeclaration();
|
|
1884
|
-
const
|
|
1815
|
+
const { templateKey, baseStylesDictionary, resolveProps } = setupTwigRenderer({
|
|
1816
|
+
type,
|
|
1817
|
+
renderer,
|
|
1818
|
+
element
|
|
1819
|
+
});
|
|
1885
1820
|
return class extends BaseView {
|
|
1886
1821
|
_abortController = null;
|
|
1822
|
+
_lastResolvedSettingsHash = null;
|
|
1823
|
+
_domUpdateWasSkipped = false;
|
|
1887
1824
|
getTemplateType() {
|
|
1888
1825
|
return "twig";
|
|
1889
1826
|
}
|
|
@@ -1900,7 +1837,7 @@ function createTemplatedElementView({
|
|
|
1900
1837
|
return this._parent?.getResolverRenderContext?.();
|
|
1901
1838
|
}
|
|
1902
1839
|
invalidateRenderCache() {
|
|
1903
|
-
|
|
1840
|
+
this._lastResolvedSettingsHash = null;
|
|
1904
1841
|
}
|
|
1905
1842
|
render() {
|
|
1906
1843
|
this._abortController?.abort();
|
|
@@ -1910,26 +1847,52 @@ function createTemplatedElementView({
|
|
|
1910
1847
|
return this._currentRenderPromise;
|
|
1911
1848
|
}
|
|
1912
1849
|
async _renderChildren() {
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
}
|
|
1850
|
+
if (this._shouldReuseChildren()) {
|
|
1851
|
+
rerenderExistingChildren(this);
|
|
1852
|
+
} else {
|
|
1853
|
+
super._renderChildren();
|
|
1854
|
+
}
|
|
1855
|
+
await waitForChildrenToComplete(this);
|
|
1856
|
+
}
|
|
1857
|
+
_shouldReuseChildren() {
|
|
1858
|
+
return this._domUpdateWasSkipped && this.children?.length > 0;
|
|
1918
1859
|
}
|
|
1919
1860
|
async _renderTemplate() {
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1861
|
+
this.triggerMethod("before:render:template");
|
|
1862
|
+
const process = signalizedProcess(this._abortController?.signal).then((_, signal) => {
|
|
1863
|
+
const settings = this.model.get("settings").toJSON();
|
|
1864
|
+
return resolveProps({
|
|
1865
|
+
props: settings,
|
|
1866
|
+
signal,
|
|
1867
|
+
renderContext: this.getResolverRenderContext()
|
|
1868
|
+
});
|
|
1869
|
+
}).then((settings) => {
|
|
1870
|
+
return this.afterSettingsResolve(settings);
|
|
1871
|
+
}).then(async (settings) => {
|
|
1872
|
+
const settingsHash = JSON.stringify(settings);
|
|
1873
|
+
const settingsChanged = settingsHash !== this._lastResolvedSettingsHash;
|
|
1874
|
+
if (!settingsChanged && this.isRendered) {
|
|
1875
|
+
this._domUpdateWasSkipped = true;
|
|
1876
|
+
return null;
|
|
1877
|
+
}
|
|
1878
|
+
this._domUpdateWasSkipped = false;
|
|
1879
|
+
this._lastResolvedSettingsHash = settingsHash;
|
|
1880
|
+
const context = {
|
|
1925
1881
|
id: this.model.get("id"),
|
|
1926
1882
|
type,
|
|
1927
|
-
settings
|
|
1928
|
-
base_styles:
|
|
1929
|
-
}
|
|
1930
|
-
|
|
1931
|
-
|
|
1883
|
+
settings,
|
|
1884
|
+
base_styles: baseStylesDictionary
|
|
1885
|
+
};
|
|
1886
|
+
return renderer.render(templateKey, context);
|
|
1887
|
+
}).then((html) => {
|
|
1888
|
+
if (html === null) {
|
|
1889
|
+
return;
|
|
1890
|
+
}
|
|
1891
|
+
this.$el.html(html);
|
|
1932
1892
|
});
|
|
1893
|
+
await process.execute();
|
|
1894
|
+
this.bindUIElements();
|
|
1895
|
+
this.triggerMethod("render:template");
|
|
1933
1896
|
}
|
|
1934
1897
|
afterSettingsResolve(settings) {
|
|
1935
1898
|
return settings;
|
|
@@ -2000,18 +1963,24 @@ function createNestedTemplatedElementView({
|
|
|
2000
1963
|
element
|
|
2001
1964
|
}) {
|
|
2002
1965
|
const legacyWindow = window;
|
|
2003
|
-
const
|
|
1966
|
+
const { templateKey, baseStylesDictionary, resolveProps } = setupTwigRenderer({
|
|
1967
|
+
type,
|
|
1968
|
+
renderer,
|
|
1969
|
+
element
|
|
1970
|
+
});
|
|
2004
1971
|
const AtomicElementBaseView = legacyWindow.elementor.modules.elements.views.createAtomicElementBase(type);
|
|
2005
1972
|
const parentRenderChildren = AtomicElementBaseView.prototype._renderChildren;
|
|
2006
1973
|
const parentOpenEditingPanel = AtomicElementBaseView.prototype._openEditingPanel;
|
|
2007
1974
|
return AtomicElementBaseView.extend({
|
|
2008
1975
|
_abortController: null,
|
|
1976
|
+
_lastResolvedSettingsHash: null,
|
|
1977
|
+
_domUpdateWasSkipped: false,
|
|
2009
1978
|
template: false,
|
|
2010
1979
|
getTemplateType() {
|
|
2011
1980
|
return "twig";
|
|
2012
1981
|
},
|
|
2013
1982
|
invalidateRenderCache() {
|
|
2014
|
-
|
|
1983
|
+
this._lastResolvedSettingsHash = null;
|
|
2015
1984
|
},
|
|
2016
1985
|
render() {
|
|
2017
1986
|
this._abortController?.abort();
|
|
@@ -2037,20 +2006,47 @@ function createNestedTemplatedElementView({
|
|
|
2037
2006
|
},
|
|
2038
2007
|
async _renderTemplate() {
|
|
2039
2008
|
const model = this.model;
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2009
|
+
this.triggerMethod("before:render:template");
|
|
2010
|
+
const process = signalizedProcess(this._abortController?.signal).then((_, signal) => {
|
|
2011
|
+
const settings = model.get("settings").toJSON();
|
|
2012
|
+
return resolveProps({
|
|
2013
|
+
props: settings,
|
|
2014
|
+
signal,
|
|
2015
|
+
renderContext: this.getResolverRenderContext?.()
|
|
2016
|
+
});
|
|
2017
|
+
}).then(async (settings) => {
|
|
2018
|
+
const settingsHash = JSON.stringify(settings);
|
|
2019
|
+
const settingsChanged = settingsHash !== this._lastResolvedSettingsHash;
|
|
2020
|
+
if (!settingsChanged && this.isRendered) {
|
|
2021
|
+
this._domUpdateWasSkipped = true;
|
|
2022
|
+
return null;
|
|
2023
|
+
}
|
|
2024
|
+
this._domUpdateWasSkipped = false;
|
|
2025
|
+
this._lastResolvedSettingsHash = settingsHash;
|
|
2026
|
+
const context = {
|
|
2045
2027
|
id: model.get("id"),
|
|
2046
2028
|
type,
|
|
2047
|
-
settings
|
|
2048
|
-
base_styles:
|
|
2029
|
+
settings,
|
|
2030
|
+
base_styles: baseStylesDictionary,
|
|
2049
2031
|
editor_attributes: buildEditorAttributes(model),
|
|
2050
2032
|
editor_classes: buildEditorClasses(model)
|
|
2051
|
-
}
|
|
2052
|
-
|
|
2033
|
+
};
|
|
2034
|
+
return renderer.render(templateKey, context);
|
|
2035
|
+
}).then((html) => {
|
|
2036
|
+
if (html === null) {
|
|
2037
|
+
return;
|
|
2038
|
+
}
|
|
2039
|
+
this._attachTwigContent(html);
|
|
2053
2040
|
});
|
|
2041
|
+
await process.execute();
|
|
2042
|
+
this.bindUIElements();
|
|
2043
|
+
this.triggerMethod("render:template");
|
|
2044
|
+
},
|
|
2045
|
+
getRenderContext() {
|
|
2046
|
+
return this._parent?.getRenderContext?.();
|
|
2047
|
+
},
|
|
2048
|
+
getResolverRenderContext() {
|
|
2049
|
+
return this._parent?.getResolverRenderContext?.();
|
|
2054
2050
|
},
|
|
2055
2051
|
getChildType() {
|
|
2056
2052
|
const allowedTypes = element.allowed_child_types ?? [];
|
|
@@ -2075,13 +2071,17 @@ function createNestedTemplatedElementView({
|
|
|
2075
2071
|
oldEl.innerHTML = overlayHTML + newEl.innerHTML;
|
|
2076
2072
|
},
|
|
2077
2073
|
async _renderChildren() {
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
}
|
|
2074
|
+
if (this._shouldReuseChildren()) {
|
|
2075
|
+
rerenderExistingChildren(this);
|
|
2076
|
+
} else {
|
|
2077
|
+
parentRenderChildren.call(this);
|
|
2078
|
+
}
|
|
2079
|
+
await waitForChildrenToComplete(this);
|
|
2083
2080
|
this._removeChildrenPlaceholder();
|
|
2084
2081
|
},
|
|
2082
|
+
_shouldReuseChildren() {
|
|
2083
|
+
return this._domUpdateWasSkipped && this.children?.length > 0;
|
|
2084
|
+
},
|
|
2085
2085
|
_removeChildrenPlaceholder() {
|
|
2086
2086
|
const el = this.$el.get(0);
|
|
2087
2087
|
if (!el) {
|
|
@@ -3449,13 +3449,6 @@ var inputSchema = {
|
|
|
3449
3449
|
`A record mapping element IDs to their styles configuration objects. Use the actual styles schema from [${STYLE_SCHEMA_URI}].`
|
|
3450
3450
|
).default({})
|
|
3451
3451
|
};
|
|
3452
|
-
var outputSchema = {
|
|
3453
|
-
errors: import_schema.z.string().describe("Error message if the composition building failed").optional(),
|
|
3454
|
-
xmlStructure: import_schema.z.string().describe(
|
|
3455
|
-
"The built XML structure as a string. Must use this XML after completion of building the composition, it contains real IDs."
|
|
3456
|
-
).optional(),
|
|
3457
|
-
llm_instructions: import_schema.z.string().describe("Instructions what to do next, Important to follow these instructions!").optional()
|
|
3458
|
-
};
|
|
3459
3452
|
|
|
3460
3453
|
// src/mcp/tools/build-composition/tool.ts
|
|
3461
3454
|
var initBuildCompositionsTool = (reg) => {
|
|
@@ -3471,7 +3464,7 @@ var initBuildCompositionsTool = (reg) => {
|
|
|
3471
3464
|
{ description: "Global Variables", uri: "elementor://global-variables" },
|
|
3472
3465
|
{ description: "Styles best practices", uri: BEST_PRACTICES_URI }
|
|
3473
3466
|
],
|
|
3474
|
-
outputSchema,
|
|
3467
|
+
// outputSchema: '',
|
|
3475
3468
|
modelPreferences: {
|
|
3476
3469
|
hints: [{ name: "claude-sonnet-4-5" }]
|
|
3477
3470
|
},
|
|
@@ -3553,10 +3546,10 @@ ${errorMessages.join(
|
|
|
3553
3546
|
Now that you have these errors, fix them and try again. Errors regarding configuration objects, please check against the PropType schemas`;
|
|
3554
3547
|
throw new Error(errorText);
|
|
3555
3548
|
}
|
|
3556
|
-
|
|
3557
|
-
|
|
3558
|
-
|
|
3559
|
-
|
|
3549
|
+
if (errors.length) {
|
|
3550
|
+
throw new Error(errors.map((e) => typeof e === "string" ? e : e.message).join("\n"));
|
|
3551
|
+
}
|
|
3552
|
+
return `The composition was built successfully with element IDs embedded in the XML.
|
|
3560
3553
|
|
|
3561
3554
|
**CRITICAL NEXT STEPS** (Follow in order):
|
|
3562
3555
|
1. **Apply Global Classes**: Use "apply-global-class" tool to apply the global classes you created BEFORE building this composition
|
|
@@ -3566,8 +3559,10 @@ Now that you have these errors, fix them and try again. Errors regarding configu
|
|
|
3566
3559
|
2. **Fine-tune if needed**: Use "configure-element" tool only for element-specific adjustments that don't warrant global classes
|
|
3567
3560
|
|
|
3568
3561
|
Remember: Global classes ensure design consistency and reusability. Don't skip applying them!
|
|
3569
|
-
|
|
3570
|
-
|
|
3562
|
+
|
|
3563
|
+
Updated XML structure:
|
|
3564
|
+
${generatedXML}
|
|
3565
|
+
`;
|
|
3571
3566
|
}
|
|
3572
3567
|
});
|
|
3573
3568
|
};
|
|
@@ -3686,7 +3681,7 @@ var inputSchema2 = {
|
|
|
3686
3681
|
elementType: import_schema3.z.string().describe("The type of the element to retreive the schema"),
|
|
3687
3682
|
elementId: import_schema3.z.string().describe("The unique id of the element to configure")
|
|
3688
3683
|
};
|
|
3689
|
-
var
|
|
3684
|
+
var outputSchema = {
|
|
3690
3685
|
success: import_schema3.z.boolean().describe(
|
|
3691
3686
|
"Whether the configuration change was successful, only if propertyName and propertyValue are provided"
|
|
3692
3687
|
)
|
|
@@ -3699,7 +3694,7 @@ var initConfigureElementTool = (reg) => {
|
|
|
3699
3694
|
name: "configure-element",
|
|
3700
3695
|
description: configureElementToolPrompt,
|
|
3701
3696
|
schema: inputSchema2,
|
|
3702
|
-
outputSchema
|
|
3697
|
+
outputSchema,
|
|
3703
3698
|
requiredResources: [
|
|
3704
3699
|
{ description: "Widgets schema", uri: WIDGET_SCHEMA_URI },
|
|
3705
3700
|
{ description: "Styles schema", uri: STYLE_SCHEMA_URI }
|
|
@@ -3797,7 +3792,7 @@ var import_schema5 = require("@elementor/schema");
|
|
|
3797
3792
|
var schema = {
|
|
3798
3793
|
elementId: import_schema5.z.string()
|
|
3799
3794
|
};
|
|
3800
|
-
var
|
|
3795
|
+
var outputSchema2 = {
|
|
3801
3796
|
properties: import_schema5.z.record(import_schema5.z.string(), import_schema5.z.any()).describe("A record mapping PropTypes to their corresponding PropValues"),
|
|
3802
3797
|
style: import_schema5.z.record(import_schema5.z.string(), import_schema5.z.any()).describe("A record mapping StyleSchema properties to their corresponding PropValues"),
|
|
3803
3798
|
childElements: import_schema5.z.array(
|
|
@@ -3824,7 +3819,7 @@ var initGetElementConfigTool = (reg) => {
|
|
|
3824
3819
|
name: "get-element-configuration-values",
|
|
3825
3820
|
description: "Retrieve the element's configuration PropValues for a specific element by unique ID.",
|
|
3826
3821
|
schema,
|
|
3827
|
-
outputSchema:
|
|
3822
|
+
outputSchema: outputSchema2,
|
|
3828
3823
|
modelPreferences: {
|
|
3829
3824
|
intelligencePriority: 0.6,
|
|
3830
3825
|
speedPriority: 0.9
|