@elementor/editor-canvas 4.0.0-552 → 4.0.0-564

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 CHANGED
@@ -77,6 +77,7 @@ declare class ElementView {
77
77
  $el: JQueryElement;
78
78
  el: HTMLElement;
79
79
  model: BackboneModel<ElementModel>;
80
+ _abortController: AbortController | null;
80
81
  collection: BackboneCollection<ElementModel>;
81
82
  children: {
82
83
  length: number;
package/dist/index.d.ts CHANGED
@@ -77,6 +77,7 @@ declare class ElementView {
77
77
  $el: JQueryElement;
78
78
  el: HTMLElement;
79
79
  model: BackboneModel<ElementModel>;
80
+ _abortController: AbortController | null;
80
81
  collection: BackboneCollection<ElementModel>;
81
82
  children: {
82
83
  length: number;
package/dist/index.js CHANGED
@@ -1238,6 +1238,11 @@ var dateTimeTransformer = createTransformer((values) => {
1238
1238
  }).join(" ");
1239
1239
  });
1240
1240
 
1241
+ // src/transformers/settings/html-v2-transformer.ts
1242
+ var htmlV2Transformer = createTransformer((value) => {
1243
+ return value?.content ?? "";
1244
+ });
1245
+
1241
1246
  // src/transformers/settings/link-transformer.ts
1242
1247
  var linkTransformer = createTransformer(({ destination, isTargetBlank, tag }) => {
1243
1248
  return {
@@ -1292,7 +1297,7 @@ var plainTransformer = createTransformer((value) => {
1292
1297
 
1293
1298
  // src/init-settings-transformers.ts
1294
1299
  function initSettingsTransformers() {
1295
- settingsTransformersRegistry.register("classes", createClassesTransformer()).register("link", linkTransformer).register("query", queryTransformer).register("image", imageTransformer).register("image-src", imageSrcTransformer).register("attributes", attributesTransformer).register("date-time", dateTimeTransformer).registerFallback(plainTransformer);
1300
+ settingsTransformersRegistry.register("classes", createClassesTransformer()).register("link", linkTransformer).register("query", queryTransformer).register("image", imageTransformer).register("image-src", imageSrcTransformer).register("attributes", attributesTransformer).register("date-time", dateTimeTransformer).register("html-v2", htmlV2Transformer).registerFallback(plainTransformer);
1296
1301
  }
1297
1302
 
1298
1303
  // src/transformers/styles/background-color-overlay-transformer.ts
@@ -1757,9 +1762,9 @@ function createElementViewClassDeclaration() {
1757
1762
  var import_editor_elements4 = require("@elementor/editor-elements");
1758
1763
 
1759
1764
  // src/legacy/twig-rendering-utils.ts
1760
- function setupTwigRenderer({ renderer, element }) {
1765
+ function createTwigRenderState({ renderer, element }) {
1761
1766
  const templateKey = element.twig_main_template;
1762
- const baseStylesDictionary = element.base_styles_dictionary;
1767
+ const cacheState = createRenderCacheState();
1763
1768
  Object.entries(element.twig_templates).forEach(([key, template]) => {
1764
1769
  renderer.register(key, template);
1765
1770
  });
@@ -1767,7 +1772,7 @@ function setupTwigRenderer({ renderer, element }) {
1767
1772
  transformers: settingsTransformersRegistry,
1768
1773
  schema: element.atomic_props_schema
1769
1774
  });
1770
- return { templateKey, baseStylesDictionary, resolveProps };
1775
+ return { templateKey, resolveProps, renderer, cacheState };
1771
1776
  }
1772
1777
  function createBeforeRender(view) {
1773
1778
  view._ensureViewIsIntact();
@@ -1780,47 +1785,91 @@ function createAfterRender(view) {
1780
1785
  view.isRendered = true;
1781
1786
  view.triggerMethod("render", view);
1782
1787
  }
1788
+ function createRenderCacheState() {
1789
+ return {
1790
+ lastResolvedSettingsHash: null,
1791
+ domUpdateWasSkipped: false,
1792
+ invalidate() {
1793
+ this.lastResolvedSettingsHash = null;
1794
+ this.domUpdateWasSkipped = false;
1795
+ }
1796
+ };
1797
+ }
1783
1798
  async function renderTwigTemplate({
1784
1799
  view,
1785
1800
  signal,
1786
- resolveProps,
1787
- templateKey,
1788
- baseStylesDictionary,
1789
- type,
1790
- renderer,
1801
+ renderState,
1791
1802
  buildContext,
1792
- attachContent
1803
+ attachContent,
1804
+ afterSettingsResolve
1793
1805
  }) {
1794
1806
  view.triggerMethod("before:render:template");
1795
- if (signal.aborted) {
1807
+ const { resolveProps, cacheState, renderer, templateKey } = renderState;
1808
+ if (signal?.aborted) {
1796
1809
  return;
1797
1810
  }
1798
1811
  const settings = view.model.get("settings").toJSON();
1799
- const resolvedSettings = await resolveProps({
1812
+ let resolvedSettings = await resolveProps({
1800
1813
  props: settings,
1801
1814
  signal,
1802
1815
  renderContext: view.getResolverRenderContext?.()
1803
1816
  });
1804
- if (signal.aborted) {
1817
+ if (signal?.aborted) {
1805
1818
  return;
1806
1819
  }
1807
- let context = {
1808
- id: view.model.get("id"),
1809
- type,
1810
- settings: resolvedSettings,
1811
- base_styles: baseStylesDictionary
1812
- };
1813
- if (buildContext) {
1814
- context = buildContext(context);
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;
1815
1830
  }
1831
+ cacheState.domUpdateWasSkipped = false;
1832
+ cacheState.lastResolvedSettingsHash = settingsHash;
1833
+ const context = buildContext(resolvedSettings);
1816
1834
  const html = await renderer.render(templateKey, context);
1817
- if (signal.aborted) {
1835
+ if (signal?.aborted) {
1818
1836
  return;
1819
1837
  }
1820
1838
  attachContent(html);
1821
1839
  view.bindUIElements();
1822
1840
  view.triggerMethod("render:template");
1823
1841
  }
1842
+ function collectChildrenRenderPromises(children) {
1843
+ const promises = [];
1844
+ children?.each((childView) => {
1845
+ if (childView._currentRenderPromise) {
1846
+ promises.push(childView._currentRenderPromise);
1847
+ }
1848
+ });
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
+ if (promises.length > 0) {
1870
+ await Promise.all(promises);
1871
+ }
1872
+ }
1824
1873
 
1825
1874
  // src/legacy/create-templated-element-type.ts
1826
1875
  function canBeTemplated(element) {
@@ -1832,16 +1881,9 @@ function createTemplatedElementView({
1832
1881
  element
1833
1882
  }) {
1834
1883
  const BaseView = createElementViewClassDeclaration();
1835
- const { templateKey, baseStylesDictionary, resolveProps } = setupTwigRenderer({
1836
- type,
1837
- renderer,
1838
- element
1839
- });
1884
+ const renderState = createTwigRenderState({ renderer, element });
1840
1885
  return class extends BaseView {
1841
- #abortController = null;
1842
- #childrenRenderPromises = [];
1843
- #lastResolvedSettingsHash = null;
1844
- #domUpdateWasSkipped = false;
1886
+ _abortController = null;
1845
1887
  getTemplateType() {
1846
1888
  return "twig";
1847
1889
  }
@@ -1858,81 +1900,36 @@ function createTemplatedElementView({
1858
1900
  return this._parent?.getResolverRenderContext?.();
1859
1901
  }
1860
1902
  invalidateRenderCache() {
1861
- this.#lastResolvedSettingsHash = null;
1903
+ renderState.cacheState.invalidate();
1862
1904
  }
1863
1905
  render() {
1864
- this.#abortController?.abort();
1865
- this.#abortController = new AbortController();
1866
- const process = signalizedProcess(this.#abortController.signal).then(() => this._beforeRender()).then(() => this._renderTemplate()).then(() => this._renderChildren()).then(() => this._afterRender());
1906
+ this._abortController?.abort();
1907
+ this._abortController = new AbortController();
1908
+ const process = signalizedProcess(this._abortController.signal).then(() => this._beforeRender()).then(() => this._renderTemplate()).then(() => this._renderChildren()).then(() => this._afterRender());
1867
1909
  this._currentRenderPromise = process.execute();
1868
1910
  return this._currentRenderPromise;
1869
1911
  }
1870
1912
  async _renderChildren() {
1871
- this.#childrenRenderPromises = [];
1872
- if (this.#shouldReuseChildren()) {
1873
- this.#rerenderExistingChildren();
1874
- } else {
1875
- super._renderChildren();
1876
- }
1877
- this.#collectChildrenRenderPromises();
1878
- await this._waitForChildrenToComplete();
1879
- }
1880
- #shouldReuseChildren() {
1881
- return this.#domUpdateWasSkipped && this.children?.length > 0;
1882
- }
1883
- #rerenderExistingChildren() {
1884
- this.children?.each((childView) => {
1885
- childView.render();
1913
+ await renderChildrenWithOptimization({
1914
+ children: this.children,
1915
+ domUpdateWasSkipped: renderState.cacheState.domUpdateWasSkipped,
1916
+ renderChildren: () => super._renderChildren()
1886
1917
  });
1887
1918
  }
1888
- #collectChildrenRenderPromises() {
1889
- this.children?.each((childView) => {
1890
- if (childView._currentRenderPromise) {
1891
- this.#childrenRenderPromises.push(childView._currentRenderPromise);
1892
- }
1893
- });
1894
- }
1895
- async _waitForChildrenToComplete() {
1896
- if (this.#childrenRenderPromises.length > 0) {
1897
- await Promise.all(this.#childrenRenderPromises);
1898
- }
1899
- }
1900
1919
  async _renderTemplate() {
1901
- this.triggerMethod("before:render:template");
1902
- const process = signalizedProcess(this.#abortController?.signal).then((_, signal) => {
1903
- const settings = this.model.get("settings").toJSON();
1904
- return resolveProps({
1905
- props: settings,
1906
- signal,
1907
- renderContext: this.getResolverRenderContext()
1908
- });
1909
- }).then((settings) => {
1910
- return this.afterSettingsResolve(settings);
1911
- }).then(async (settings) => {
1912
- const settingsHash = JSON.stringify(settings);
1913
- const settingsChanged = settingsHash !== this.#lastResolvedSettingsHash;
1914
- if (!settingsChanged && this.isRendered) {
1915
- this.#domUpdateWasSkipped = true;
1916
- return null;
1917
- }
1918
- this.#domUpdateWasSkipped = false;
1919
- this.#lastResolvedSettingsHash = settingsHash;
1920
- const context = {
1920
+ await renderTwigTemplate({
1921
+ view: this,
1922
+ signal: this._abortController?.signal,
1923
+ renderState,
1924
+ buildContext: (resolvedSettings) => ({
1921
1925
  id: this.model.get("id"),
1922
1926
  type,
1923
- settings,
1924
- base_styles: baseStylesDictionary
1925
- };
1926
- return renderer.render(templateKey, context);
1927
- }).then((html) => {
1928
- if (html === null) {
1929
- return;
1930
- }
1931
- this.$el.html(html);
1927
+ settings: resolvedSettings,
1928
+ base_styles: element.base_styles_dictionary
1929
+ }),
1930
+ attachContent: (html) => this.$el.html(html),
1931
+ afterSettingsResolve: (settings) => this.afterSettingsResolve(settings)
1932
1932
  });
1933
- await process.execute();
1934
- this.bindUIElements();
1935
- this.triggerMethod("render:template");
1936
1933
  }
1937
1934
  afterSettingsResolve(settings) {
1938
1935
  return settings;
@@ -2003,11 +2000,7 @@ function createNestedTemplatedElementView({
2003
2000
  element
2004
2001
  }) {
2005
2002
  const legacyWindow = window;
2006
- const { templateKey, baseStylesDictionary, resolveProps } = setupTwigRenderer({
2007
- type,
2008
- renderer,
2009
- element
2010
- });
2003
+ const renderState = createTwigRenderState({ renderer, element });
2011
2004
  const AtomicElementBaseView = legacyWindow.elementor.modules.elements.views.createAtomicElementBase(type);
2012
2005
  const parentRenderChildren = AtomicElementBaseView.prototype._renderChildren;
2013
2006
  const parentOpenEditingPanel = AtomicElementBaseView.prototype._openEditingPanel;
@@ -2017,6 +2010,9 @@ function createNestedTemplatedElementView({
2017
2010
  getTemplateType() {
2018
2011
  return "twig";
2019
2012
  },
2013
+ invalidateRenderCache() {
2014
+ renderState.cacheState.invalidate();
2015
+ },
2020
2016
  render() {
2021
2017
  this._abortController?.abort();
2022
2018
  this._abortController = new AbortController();
@@ -2044,13 +2040,12 @@ function createNestedTemplatedElementView({
2044
2040
  await renderTwigTemplate({
2045
2041
  view: this,
2046
2042
  signal: this._abortController?.signal,
2047
- resolveProps,
2048
- templateKey,
2049
- baseStylesDictionary,
2050
- type,
2051
- renderer,
2052
- buildContext: (context) => ({
2053
- ...context,
2043
+ renderState,
2044
+ buildContext: (resolvedSettings) => ({
2045
+ id: model.get("id"),
2046
+ type,
2047
+ settings: resolvedSettings,
2048
+ base_styles: element.base_styles_dictionary,
2054
2049
  editor_attributes: buildEditorAttributes(model),
2055
2050
  editor_classes: buildEditorClasses(model)
2056
2051
  }),
@@ -2080,14 +2075,11 @@ function createNestedTemplatedElementView({
2080
2075
  oldEl.innerHTML = overlayHTML + newEl.innerHTML;
2081
2076
  },
2082
2077
  async _renderChildren() {
2083
- parentRenderChildren.call(this);
2084
- const renderPromises = [];
2085
- this.children.each((childView) => {
2086
- if (childView._currentRenderPromise) {
2087
- renderPromises.push(childView._currentRenderPromise);
2088
- }
2078
+ await renderChildrenWithOptimization({
2079
+ children: this.children,
2080
+ domUpdateWasSkipped: renderState.cacheState.domUpdateWasSkipped,
2081
+ renderChildren: () => parentRenderChildren.call(this)
2089
2082
  });
2090
- await Promise.all(renderPromises);
2091
2083
  this._removeChildrenPlaceholder();
2092
2084
  },
2093
2085
  _removeChildrenPlaceholder() {
@@ -2293,9 +2285,6 @@ var CanvasInlineEditor = ({
2293
2285
  };
2294
2286
  useOnClickOutsideIframe(onBlur);
2295
2287
  return /* @__PURE__ */ React5.createElement(import_ui4.ThemeProvider, null, /* @__PURE__ */ React5.createElement(InlineEditingOverlay, { expectedTag, rootElement, id }), /* @__PURE__ */ React5.createElement("style", null, `
2296
- .${EDITOR_WRAPPER_SELECTOR}, .${EDITOR_WRAPPER_SELECTOR} > * {
2297
- height: 100%;
2298
- }
2299
2288
  .ProseMirror > * {
2300
2289
  height: 100%;
2301
2290
  }
@@ -2423,8 +2412,9 @@ var import_editor_props3 = require("@elementor/editor-props");
2423
2412
  var hasKey = (propType) => {
2424
2413
  return "key" in propType;
2425
2414
  };
2415
+ var TEXT_PROP_TYPE_KEYS = /* @__PURE__ */ new Set([import_editor_props3.htmlV2PropTypeUtil.key, import_editor_props3.stringPropTypeUtil.key]);
2426
2416
  var isCoreTextPropTypeKey = (key) => {
2427
- return key === import_editor_props3.htmlPropTypeUtil.key || key === import_editor_props3.stringPropTypeUtil.key;
2417
+ return TEXT_PROP_TYPE_KEYS.has(key);
2428
2418
  };
2429
2419
  var isAllowedBySchema = (propTypeFromSchema) => {
2430
2420
  if (!propTypeFromSchema) {
@@ -2436,15 +2426,13 @@ var isAllowedBySchema = (propTypeFromSchema) => {
2436
2426
  if (propTypeFromSchema.kind !== "union") {
2437
2427
  return false;
2438
2428
  }
2439
- return Boolean(
2440
- propTypeFromSchema.prop_types[import_editor_props3.htmlPropTypeUtil.key] || propTypeFromSchema.prop_types[import_editor_props3.stringPropTypeUtil.key]
2441
- );
2429
+ return [...TEXT_PROP_TYPE_KEYS].some((key) => propTypeFromSchema.prop_types[key]);
2442
2430
  };
2443
2431
  var isInlineEditingAllowed = ({ rawValue, propTypeFromSchema }) => {
2444
2432
  if (rawValue === null || rawValue === void 0) {
2445
2433
  return isAllowedBySchema(propTypeFromSchema);
2446
2434
  }
2447
- return import_editor_props3.htmlPropTypeUtil.isValid(rawValue) || import_editor_props3.stringPropTypeUtil.isValid(rawValue);
2435
+ return import_editor_props3.htmlV2PropTypeUtil.isValid(rawValue) || import_editor_props3.stringPropTypeUtil.isValid(rawValue);
2448
2436
  };
2449
2437
 
2450
2438
  // src/legacy/replacements/inline-editing/inline-editing-elements.tsx
@@ -2529,11 +2517,16 @@ var InlineEditingReplacement = class extends ReplacementBase {
2529
2517
  }
2530
2518
  getExtractedContentValue() {
2531
2519
  const propValue = this.getInlineEditablePropValue();
2532
- return import_editor_props4.htmlPropTypeUtil.extract(propValue) ?? "";
2520
+ return import_editor_props4.htmlV2PropTypeUtil.extract(propValue)?.content ?? "";
2533
2521
  }
2534
2522
  setContentValue(value) {
2535
2523
  const settingKey = this.getInlineEditablePropertyName();
2536
- const valueToSave = import_editor_props4.htmlPropTypeUtil.create(value || "");
2524
+ const html = value || "";
2525
+ const parsed = (0, import_editor_props4.parseHtmlChildren)(html);
2526
+ const valueToSave = import_editor_props4.htmlV2PropTypeUtil.create({
2527
+ content: parsed.content || null,
2528
+ children: parsed.children
2529
+ });
2537
2530
  (0, import_editor_v1_adapters11.undoable)(
2538
2531
  {
2539
2532
  do: () => {
@@ -2562,11 +2555,11 @@ var InlineEditingReplacement = class extends ReplacementBase {
2562
2555
  return null;
2563
2556
  }
2564
2557
  if (propType.kind === "union") {
2565
- if (propType.prop_types[import_editor_props4.htmlPropTypeUtil.key]) {
2566
- return import_editor_props4.htmlPropTypeUtil.key;
2567
- }
2568
- if (propType.prop_types[import_editor_props4.stringPropTypeUtil.key]) {
2569
- return import_editor_props4.stringPropTypeUtil.key;
2558
+ const textKeys = [import_editor_props4.htmlV2PropTypeUtil.key, import_editor_props4.stringPropTypeUtil.key];
2559
+ for (const key of textKeys) {
2560
+ if (propType.prop_types[key]) {
2561
+ return key;
2562
+ }
2570
2563
  }
2571
2564
  return null;
2572
2565
  }
@@ -2803,7 +2796,7 @@ var tabModelExtensions = {
2803
2796
  ...paragraphElement,
2804
2797
  settings: {
2805
2798
  ...paragraphElement.settings,
2806
- paragraph: import_editor_props5.htmlPropTypeUtil.create(`Tab ${position}`)
2799
+ paragraph: import_editor_props5.htmlV2PropTypeUtil.create({ content: `Tab ${position}`, children: [] })
2807
2800
  }
2808
2801
  };
2809
2802
  return [updatedParagraph, ...elements.slice(1)];
@@ -3461,7 +3454,7 @@ var outputSchema = {
3461
3454
  xmlStructure: import_schema.z.string().describe(
3462
3455
  "The built XML structure as a string. Must use this XML after completion of building the composition, it contains real IDs."
3463
3456
  ).optional(),
3464
- llm_instructions: import_schema.z.string().describe("Instructions what to do next, Important to follow these instructions!")
3457
+ llm_instructions: import_schema.z.string().describe("Instructions what to do next, Important to follow these instructions!").optional()
3465
3458
  };
3466
3459
 
3467
3460
  // src/mcp/tools/build-composition/tool.ts