@elementor/editor-canvas 3.35.0-379 → 3.35.0-381

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -281,8 +281,8 @@ var subscribeToStylesRepository = () => {
281
281
  });
282
282
  };
283
283
  var renameClass = (oldClassName, newClassName) => {
284
- Object.values((0, import_editor_documents.getV1DocumentsManager)().documents).forEach((document) => {
285
- const container = document.container;
284
+ Object.values((0, import_editor_documents.getV1DocumentsManager)().documents).forEach((document2) => {
285
+ const container = document2.container;
286
286
  container.view?.el?.querySelectorAll(`.elementor .${oldClassName}`).forEach((element) => {
287
287
  element.classList.replace(oldClassName, newClassName);
288
288
  });
@@ -613,14 +613,14 @@ function useDocumentsCssLinks() {
613
613
  }));
614
614
  });
615
615
  }
616
- function getDocumentsIdsInCanvas(document) {
617
- return [...document.body.querySelectorAll(`[${DOCUMENT_WRAPPER_ATTR}]`) ?? []].map(
616
+ function getDocumentsIdsInCanvas(document2) {
617
+ return [...document2.body.querySelectorAll(`[${DOCUMENT_WRAPPER_ATTR}]`) ?? []].map(
618
618
  (el) => el.getAttribute(DOCUMENT_WRAPPER_ATTR) || ""
619
619
  );
620
620
  }
621
- function getDocumentsCssLinks(document) {
621
+ function getDocumentsCssLinks(document2) {
622
622
  return [
623
- ...document.head.querySelectorAll(
623
+ ...document2.head.querySelectorAll(
624
624
  `link[rel="stylesheet"][id^=${CSS_LINK_ID_PREFIX}][id$=${CSS_LINK_ID_SUFFIX}]`
625
625
  ) ?? []
626
626
  ];
@@ -1687,14 +1687,6 @@ var ReplacementBase = class {
1687
1687
  static getTypes() {
1688
1688
  return null;
1689
1689
  }
1690
- render() {
1691
- }
1692
- onDestroy() {
1693
- }
1694
- _beforeRender() {
1695
- }
1696
- _afterRender() {
1697
- }
1698
1690
  shouldRenderReplacement() {
1699
1691
  return true;
1700
1692
  }
@@ -1733,7 +1725,7 @@ var InlineEditingReplacement = class extends ReplacementBase {
1733
1725
  return !!this.inlineEditorRoot;
1734
1726
  }
1735
1727
  shouldRenderReplacement() {
1736
- return (0, import_editor_v1_adapters8.isExperimentActive)(EXPERIMENT_KEY) && this.isEditingModeActive() && !this.isValueDynamic();
1728
+ return (0, import_editor_v1_adapters8.isExperimentActive)(EXPERIMENT_KEY) && !this.isValueDynamic();
1737
1729
  }
1738
1730
  handleRenderInlineEditor = (event) => {
1739
1731
  event.stopPropagation();
@@ -1741,10 +1733,12 @@ var InlineEditingReplacement = class extends ReplacementBase {
1741
1733
  this.renderInlineEditor();
1742
1734
  }
1743
1735
  };
1744
- handleUnmountInlineEditor = (event) => {
1745
- event.stopPropagation();
1746
- this.unmountInlineEditor();
1747
- };
1736
+ renderOnChange() {
1737
+ if (this.isEditingModeActive()) {
1738
+ return;
1739
+ }
1740
+ this.refreshView();
1741
+ }
1748
1742
  onDestroy() {
1749
1743
  this.resetInlineEditorRoot();
1750
1744
  }
@@ -1784,54 +1778,77 @@ var InlineEditingReplacement = class extends ReplacementBase {
1784
1778
  const prop = this.getHtmlPropType();
1785
1779
  const defaultValue = prop?.default?.value ?? "";
1786
1780
  const settingKey = this.getInlineEditablePropertyName();
1787
- return import_editor_props3.htmlPropTypeUtil.extract(this.getSetting(settingKey) ?? null) ?? import_editor_props3.htmlPropTypeUtil.extract(prop?.default ?? null) ?? defaultValue ?? "";
1781
+ return import_editor_props3.htmlPropTypeUtil.extract(this.getSetting(settingKey) ?? null) ?? import_editor_props3.stringPropTypeUtil.extract(this.getSetting(settingKey) ?? null) ?? import_editor_props3.htmlPropTypeUtil.extract(prop?.default ?? null) ?? defaultValue ?? "";
1788
1782
  }
1789
1783
  setContentValue(value) {
1790
1784
  const settingKey = this.getInlineEditablePropertyName();
1791
1785
  const valueToSave = value ? import_editor_props3.htmlPropTypeUtil.create(value) : null;
1792
- (0, import_editor_v1_adapters8.__privateRunCommandSync)("document/elements/settings", {
1793
- container: (0, import_editor_elements3.getContainer)(this.id),
1794
- settings: {
1795
- [settingKey]: valueToSave
1796
- }
1797
- });
1786
+ (0, import_editor_v1_adapters8.__privateRunCommandSync)(
1787
+ "document/elements/set-settings",
1788
+ {
1789
+ container: (0, import_editor_elements3.getContainer)(this.id),
1790
+ settings: {
1791
+ [settingKey]: valueToSave
1792
+ }
1793
+ },
1794
+ { internal: true }
1795
+ );
1798
1796
  }
1799
1797
  getExpectedTag() {
1798
+ const tagPropType = this.getTagPropType();
1799
+ const tagSettingKey = "tag";
1800
+ return import_editor_props3.stringPropTypeUtil.extract(this.getSetting(tagSettingKey) ?? null) ?? import_editor_props3.stringPropTypeUtil.extract(tagPropType?.default ?? null) ?? null;
1801
+ }
1802
+ getTagPropType() {
1800
1803
  const propsSchema = (0, import_editor_elements3.getElementType)(this.type)?.propsSchema;
1801
1804
  if (!propsSchema?.tag) {
1802
1805
  return null;
1803
1806
  }
1804
- const tagSettingKey = "tag";
1805
- return import_editor_props3.stringPropTypeUtil.extract(this.getSetting(tagSettingKey) ?? null) ?? import_editor_props3.stringPropTypeUtil.extract(propsSchema.tag.default ?? null) ?? null;
1807
+ const tagPropType = propsSchema.tag ?? null;
1808
+ if (tagPropType.kind === "union") {
1809
+ return tagPropType.prop_types.string ?? null;
1810
+ }
1811
+ return tagPropType;
1806
1812
  }
1807
1813
  renderInlineEditor() {
1808
1814
  const InlineEditorApp = this.InlineEditorApp;
1809
- const classes = (this.element.children?.[0]?.classList.toString() ?? "") + " strip-styles";
1815
+ const wrapperClasses = "elementor";
1816
+ const elementClasses = this.element.children?.[0]?.classList.toString() ?? "";
1810
1817
  this.element.innerHTML = "";
1811
1818
  if (this.inlineEditorRoot) {
1812
1819
  this.resetInlineEditorRoot();
1813
1820
  }
1814
1821
  this.inlineEditorRoot = (0, import_client.createRoot)(this.element);
1815
- this.inlineEditorRoot.render(/* @__PURE__ */ React5.createElement(InlineEditorApp, { classes }));
1822
+ this.inlineEditorRoot.render(
1823
+ /* @__PURE__ */ React5.createElement(InlineEditorApp, { wrapperClasses, elementClasses })
1824
+ );
1816
1825
  }
1817
- InlineEditorApp = ({ classes }) => {
1826
+ InlineEditorApp = ({ wrapperClasses, elementClasses }) => {
1818
1827
  const propValue = this.getContentValue();
1819
1828
  const expectedTag = this.getExpectedTag();
1820
1829
  const wrapperRef = (0, import_react11.useRef)(null);
1821
1830
  const [isWrapperRendered, setIsWrapperRendered] = (0, import_react11.useState)(false);
1822
1831
  (0, import_react11.useEffect)(() => {
1832
+ const panel = document?.querySelector("main.MuiBox-root");
1823
1833
  setIsWrapperRendered(!!wrapperRef.current);
1834
+ panel?.addEventListener("click", asyncUnmountInlineEditor);
1835
+ return () => panel?.removeEventListener("click", asyncUnmountInlineEditor);
1824
1836
  }, []);
1837
+ const asyncUnmountInlineEditor = (0, import_react11.useCallback)(
1838
+ () => queueMicrotask(this.unmountInlineEditor.bind(this)),
1839
+ []
1840
+ );
1825
1841
  return /* @__PURE__ */ React5.createElement(import_ui4.ThemeProvider, null, /* @__PURE__ */ React5.createElement(import_ui4.Box, { ref: wrapperRef }, isWrapperRendered && /* @__PURE__ */ React5.createElement(OutlineOverlay, { element: wrapperRef.current, id: this.id, isSelected: true }), /* @__PURE__ */ React5.createElement(
1826
1842
  import_editor_controls2.InlineEditor,
1827
1843
  {
1828
1844
  attributes: {
1829
- class: classes,
1845
+ class: wrapperClasses,
1830
1846
  style: "outline: none;"
1831
1847
  },
1848
+ elementClasses,
1832
1849
  value: propValue,
1833
1850
  setValue: this.setContentValue.bind(this),
1834
- onBlur: this.handleUnmountInlineEditor.bind(this),
1851
+ onBlur: this.unmountInlineEditor.bind(this),
1835
1852
  autofocus: true,
1836
1853
  showToolbar: true,
1837
1854
  getInitialPopoverPosition,
@@ -1878,6 +1895,11 @@ var createViewWithReplacements = (options) => {
1878
1895
  refreshView() {
1879
1896
  this.render();
1880
1897
  }
1898
+ renderOnChange() {
1899
+ if (!this.#triggerMethod("renderOnChange")) {
1900
+ TemplatedView.prototype.renderOnChange.apply(this);
1901
+ }
1902
+ }
1881
1903
  render() {
1882
1904
  const config = this.#config;
1883
1905
  const widgetType = config.type;
@@ -1885,29 +1907,33 @@ var createViewWithReplacements = (options) => {
1885
1907
  if (ReplacementClass && !this.#replacement) {
1886
1908
  this.#replacement = new ReplacementClass(config);
1887
1909
  }
1888
- if (!this.#replacement?.shouldRenderReplacement()) {
1889
- return TemplatedView.prototype.render.apply(this);
1910
+ if (!this.#triggerMethod("render")) {
1911
+ TemplatedView.prototype.render.apply(this);
1890
1912
  }
1891
- this.#replacement.render();
1892
1913
  }
1893
1914
  onDestroy() {
1894
- if (this.#replacement) {
1895
- this.#replacement.onDestroy();
1915
+ if (this.#triggerMethod("onDestroy")) {
1896
1916
  this.#replacement = null;
1897
1917
  }
1898
1918
  TemplatedView.prototype.onDestroy.apply(this);
1899
1919
  }
1900
1920
  _afterRender() {
1901
- if (this.#replacement) {
1902
- this.#replacement._afterRender();
1921
+ if (!this.#triggerMethod("_afterRender")) {
1922
+ TemplatedView.prototype._afterRender.apply(this);
1903
1923
  }
1904
- TemplatedView.prototype._afterRender.apply(this);
1905
1924
  }
1906
1925
  _beforeRender() {
1907
- if (this.#replacement) {
1908
- this.#replacement._beforeRender();
1926
+ if (!this.#triggerMethod("_beforeRender")) {
1927
+ TemplatedView.prototype._beforeRender.apply(this);
1928
+ }
1929
+ }
1930
+ #triggerMethod(methodKey) {
1931
+ const method = this.#replacement?.shouldRenderReplacement() && this.#replacement[methodKey]?.bind(this.#replacement);
1932
+ if (!method || typeof method !== "function") {
1933
+ return false;
1909
1934
  }
1910
- TemplatedView.prototype._beforeRender.apply(this);
1935
+ method();
1936
+ return true;
1911
1937
  }
1912
1938
  };
1913
1939
  };
@@ -1998,18 +2024,18 @@ var initDocumentStructureResource = (reg) => {
1998
2024
  };
1999
2025
  function getDocumentStructure() {
2000
2026
  const extendedWindow = window;
2001
- const document = extendedWindow.elementor?.documents?.getCurrent?.();
2002
- if (!document) {
2027
+ const document2 = extendedWindow.elementor?.documents?.getCurrent?.();
2028
+ if (!document2) {
2003
2029
  return { error: "No active document found" };
2004
2030
  }
2005
- const containers = document.container?.children || [];
2031
+ const containers = document2.container?.children || [];
2006
2032
  const elements = containers.map(
2007
2033
  (container) => extractElementData(container)
2008
2034
  );
2009
2035
  return {
2010
- documentId: document.id,
2011
- documentType: document.config.type,
2012
- title: document.config.settings?.post_title || "Untitled",
2036
+ documentId: document2.id,
2037
+ documentType: document2.config.type,
2038
+ title: document2.config.settings?.post_title || "Untitled",
2013
2039
  elements: elements.filter((el) => el !== null)
2014
2040
  };
2015
2041
  }
package/dist/index.mjs CHANGED
@@ -230,8 +230,8 @@ var subscribeToStylesRepository = () => {
230
230
  });
231
231
  };
232
232
  var renameClass = (oldClassName, newClassName) => {
233
- Object.values(getV1DocumentsManager().documents).forEach((document) => {
234
- const container = document.container;
233
+ Object.values(getV1DocumentsManager().documents).forEach((document2) => {
234
+ const container = document2.container;
235
235
  container.view?.el?.querySelectorAll(`.elementor .${oldClassName}`).forEach((element) => {
236
236
  element.classList.replace(oldClassName, newClassName);
237
237
  });
@@ -567,14 +567,14 @@ function useDocumentsCssLinks() {
567
567
  }));
568
568
  });
569
569
  }
570
- function getDocumentsIdsInCanvas(document) {
571
- return [...document.body.querySelectorAll(`[${DOCUMENT_WRAPPER_ATTR}]`) ?? []].map(
570
+ function getDocumentsIdsInCanvas(document2) {
571
+ return [...document2.body.querySelectorAll(`[${DOCUMENT_WRAPPER_ATTR}]`) ?? []].map(
572
572
  (el) => el.getAttribute(DOCUMENT_WRAPPER_ATTR) || ""
573
573
  );
574
574
  }
575
- function getDocumentsCssLinks(document) {
575
+ function getDocumentsCssLinks(document2) {
576
576
  return [
577
- ...document.head.querySelectorAll(
577
+ ...document2.head.querySelectorAll(
578
578
  `link[rel="stylesheet"][id^=${CSS_LINK_ID_PREFIX}][id$=${CSS_LINK_ID_SUFFIX}]`
579
579
  ) ?? []
580
580
  ];
@@ -1619,7 +1619,7 @@ function createTemplatedElementView({
1619
1619
 
1620
1620
  // src/legacy/replacements/inline-editing/inline-editing-elements.tsx
1621
1621
  import * as React5 from "react";
1622
- import { useEffect as useEffect7, useRef as useRef2, useState as useState4 } from "react";
1622
+ import { useCallback, useEffect as useEffect7, useRef as useRef2, useState as useState4 } from "react";
1623
1623
  import { createRoot } from "react-dom/client";
1624
1624
  import { InlineEditor } from "@elementor/editor-controls";
1625
1625
  import { getContainer, getElementType } from "@elementor/editor-elements";
@@ -1649,14 +1649,6 @@ var ReplacementBase = class {
1649
1649
  static getTypes() {
1650
1650
  return null;
1651
1651
  }
1652
- render() {
1653
- }
1654
- onDestroy() {
1655
- }
1656
- _beforeRender() {
1657
- }
1658
- _afterRender() {
1659
- }
1660
1652
  shouldRenderReplacement() {
1661
1653
  return true;
1662
1654
  }
@@ -1695,7 +1687,7 @@ var InlineEditingReplacement = class extends ReplacementBase {
1695
1687
  return !!this.inlineEditorRoot;
1696
1688
  }
1697
1689
  shouldRenderReplacement() {
1698
- return isExperimentActive(EXPERIMENT_KEY) && this.isEditingModeActive() && !this.isValueDynamic();
1690
+ return isExperimentActive(EXPERIMENT_KEY) && !this.isValueDynamic();
1699
1691
  }
1700
1692
  handleRenderInlineEditor = (event) => {
1701
1693
  event.stopPropagation();
@@ -1703,10 +1695,12 @@ var InlineEditingReplacement = class extends ReplacementBase {
1703
1695
  this.renderInlineEditor();
1704
1696
  }
1705
1697
  };
1706
- handleUnmountInlineEditor = (event) => {
1707
- event.stopPropagation();
1708
- this.unmountInlineEditor();
1709
- };
1698
+ renderOnChange() {
1699
+ if (this.isEditingModeActive()) {
1700
+ return;
1701
+ }
1702
+ this.refreshView();
1703
+ }
1710
1704
  onDestroy() {
1711
1705
  this.resetInlineEditorRoot();
1712
1706
  }
@@ -1746,54 +1740,77 @@ var InlineEditingReplacement = class extends ReplacementBase {
1746
1740
  const prop = this.getHtmlPropType();
1747
1741
  const defaultValue = prop?.default?.value ?? "";
1748
1742
  const settingKey = this.getInlineEditablePropertyName();
1749
- return htmlPropTypeUtil.extract(this.getSetting(settingKey) ?? null) ?? htmlPropTypeUtil.extract(prop?.default ?? null) ?? defaultValue ?? "";
1743
+ return htmlPropTypeUtil.extract(this.getSetting(settingKey) ?? null) ?? stringPropTypeUtil.extract(this.getSetting(settingKey) ?? null) ?? htmlPropTypeUtil.extract(prop?.default ?? null) ?? defaultValue ?? "";
1750
1744
  }
1751
1745
  setContentValue(value) {
1752
1746
  const settingKey = this.getInlineEditablePropertyName();
1753
1747
  const valueToSave = value ? htmlPropTypeUtil.create(value) : null;
1754
- runCommandSync("document/elements/settings", {
1755
- container: getContainer(this.id),
1756
- settings: {
1757
- [settingKey]: valueToSave
1758
- }
1759
- });
1748
+ runCommandSync(
1749
+ "document/elements/set-settings",
1750
+ {
1751
+ container: getContainer(this.id),
1752
+ settings: {
1753
+ [settingKey]: valueToSave
1754
+ }
1755
+ },
1756
+ { internal: true }
1757
+ );
1760
1758
  }
1761
1759
  getExpectedTag() {
1760
+ const tagPropType = this.getTagPropType();
1761
+ const tagSettingKey = "tag";
1762
+ return stringPropTypeUtil.extract(this.getSetting(tagSettingKey) ?? null) ?? stringPropTypeUtil.extract(tagPropType?.default ?? null) ?? null;
1763
+ }
1764
+ getTagPropType() {
1762
1765
  const propsSchema = getElementType(this.type)?.propsSchema;
1763
1766
  if (!propsSchema?.tag) {
1764
1767
  return null;
1765
1768
  }
1766
- const tagSettingKey = "tag";
1767
- return stringPropTypeUtil.extract(this.getSetting(tagSettingKey) ?? null) ?? stringPropTypeUtil.extract(propsSchema.tag.default ?? null) ?? null;
1769
+ const tagPropType = propsSchema.tag ?? null;
1770
+ if (tagPropType.kind === "union") {
1771
+ return tagPropType.prop_types.string ?? null;
1772
+ }
1773
+ return tagPropType;
1768
1774
  }
1769
1775
  renderInlineEditor() {
1770
1776
  const InlineEditorApp = this.InlineEditorApp;
1771
- const classes = (this.element.children?.[0]?.classList.toString() ?? "") + " strip-styles";
1777
+ const wrapperClasses = "elementor";
1778
+ const elementClasses = this.element.children?.[0]?.classList.toString() ?? "";
1772
1779
  this.element.innerHTML = "";
1773
1780
  if (this.inlineEditorRoot) {
1774
1781
  this.resetInlineEditorRoot();
1775
1782
  }
1776
1783
  this.inlineEditorRoot = createRoot(this.element);
1777
- this.inlineEditorRoot.render(/* @__PURE__ */ React5.createElement(InlineEditorApp, { classes }));
1784
+ this.inlineEditorRoot.render(
1785
+ /* @__PURE__ */ React5.createElement(InlineEditorApp, { wrapperClasses, elementClasses })
1786
+ );
1778
1787
  }
1779
- InlineEditorApp = ({ classes }) => {
1788
+ InlineEditorApp = ({ wrapperClasses, elementClasses }) => {
1780
1789
  const propValue = this.getContentValue();
1781
1790
  const expectedTag = this.getExpectedTag();
1782
1791
  const wrapperRef = useRef2(null);
1783
1792
  const [isWrapperRendered, setIsWrapperRendered] = useState4(false);
1784
1793
  useEffect7(() => {
1794
+ const panel = document?.querySelector("main.MuiBox-root");
1785
1795
  setIsWrapperRendered(!!wrapperRef.current);
1796
+ panel?.addEventListener("click", asyncUnmountInlineEditor);
1797
+ return () => panel?.removeEventListener("click", asyncUnmountInlineEditor);
1786
1798
  }, []);
1799
+ const asyncUnmountInlineEditor = useCallback(
1800
+ () => queueMicrotask(this.unmountInlineEditor.bind(this)),
1801
+ []
1802
+ );
1787
1803
  return /* @__PURE__ */ React5.createElement(ThemeProvider, null, /* @__PURE__ */ React5.createElement(Box2, { ref: wrapperRef }, isWrapperRendered && /* @__PURE__ */ React5.createElement(OutlineOverlay, { element: wrapperRef.current, id: this.id, isSelected: true }), /* @__PURE__ */ React5.createElement(
1788
1804
  InlineEditor,
1789
1805
  {
1790
1806
  attributes: {
1791
- class: classes,
1807
+ class: wrapperClasses,
1792
1808
  style: "outline: none;"
1793
1809
  },
1810
+ elementClasses,
1794
1811
  value: propValue,
1795
1812
  setValue: this.setContentValue.bind(this),
1796
- onBlur: this.handleUnmountInlineEditor.bind(this),
1813
+ onBlur: this.unmountInlineEditor.bind(this),
1797
1814
  autofocus: true,
1798
1815
  showToolbar: true,
1799
1816
  getInitialPopoverPosition,
@@ -1840,6 +1857,11 @@ var createViewWithReplacements = (options) => {
1840
1857
  refreshView() {
1841
1858
  this.render();
1842
1859
  }
1860
+ renderOnChange() {
1861
+ if (!this.#triggerMethod("renderOnChange")) {
1862
+ TemplatedView.prototype.renderOnChange.apply(this);
1863
+ }
1864
+ }
1843
1865
  render() {
1844
1866
  const config = this.#config;
1845
1867
  const widgetType = config.type;
@@ -1847,29 +1869,33 @@ var createViewWithReplacements = (options) => {
1847
1869
  if (ReplacementClass && !this.#replacement) {
1848
1870
  this.#replacement = new ReplacementClass(config);
1849
1871
  }
1850
- if (!this.#replacement?.shouldRenderReplacement()) {
1851
- return TemplatedView.prototype.render.apply(this);
1872
+ if (!this.#triggerMethod("render")) {
1873
+ TemplatedView.prototype.render.apply(this);
1852
1874
  }
1853
- this.#replacement.render();
1854
1875
  }
1855
1876
  onDestroy() {
1856
- if (this.#replacement) {
1857
- this.#replacement.onDestroy();
1877
+ if (this.#triggerMethod("onDestroy")) {
1858
1878
  this.#replacement = null;
1859
1879
  }
1860
1880
  TemplatedView.prototype.onDestroy.apply(this);
1861
1881
  }
1862
1882
  _afterRender() {
1863
- if (this.#replacement) {
1864
- this.#replacement._afterRender();
1883
+ if (!this.#triggerMethod("_afterRender")) {
1884
+ TemplatedView.prototype._afterRender.apply(this);
1865
1885
  }
1866
- TemplatedView.prototype._afterRender.apply(this);
1867
1886
  }
1868
1887
  _beforeRender() {
1869
- if (this.#replacement) {
1870
- this.#replacement._beforeRender();
1888
+ if (!this.#triggerMethod("_beforeRender")) {
1889
+ TemplatedView.prototype._beforeRender.apply(this);
1890
+ }
1891
+ }
1892
+ #triggerMethod(methodKey) {
1893
+ const method = this.#replacement?.shouldRenderReplacement() && this.#replacement[methodKey]?.bind(this.#replacement);
1894
+ if (!method || typeof method !== "function") {
1895
+ return false;
1871
1896
  }
1872
- TemplatedView.prototype._beforeRender.apply(this);
1897
+ method();
1898
+ return true;
1873
1899
  }
1874
1900
  };
1875
1901
  };
@@ -1960,18 +1986,18 @@ var initDocumentStructureResource = (reg) => {
1960
1986
  };
1961
1987
  function getDocumentStructure() {
1962
1988
  const extendedWindow = window;
1963
- const document = extendedWindow.elementor?.documents?.getCurrent?.();
1964
- if (!document) {
1989
+ const document2 = extendedWindow.elementor?.documents?.getCurrent?.();
1990
+ if (!document2) {
1965
1991
  return { error: "No active document found" };
1966
1992
  }
1967
- const containers = document.container?.children || [];
1993
+ const containers = document2.container?.children || [];
1968
1994
  const elements = containers.map(
1969
1995
  (container) => extractElementData(container)
1970
1996
  );
1971
1997
  return {
1972
- documentId: document.id,
1973
- documentType: document.config.type,
1974
- title: document.config.settings?.post_title || "Untitled",
1998
+ documentId: document2.id,
1999
+ documentType: document2.config.type,
2000
+ title: document2.config.settings?.post_title || "Untitled",
1975
2001
  elements: elements.filter((el) => el !== null)
1976
2002
  };
1977
2003
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@elementor/editor-canvas",
3
3
  "description": "Elementor Editor Canvas",
4
- "version": "3.35.0-379",
4
+ "version": "3.35.0-381",
5
5
  "private": false,
6
6
  "author": "Elementor Team",
7
7
  "homepage": "https://elementor.com/",
@@ -37,24 +37,24 @@
37
37
  "react-dom": "^18.3.1"
38
38
  },
39
39
  "dependencies": {
40
- "@elementor/editor": "3.35.0-379",
41
- "@elementor/editor-controls": "3.35.0-379",
42
- "@elementor/editor-documents": "3.35.0-379",
43
- "@elementor/editor-elements": "3.35.0-379",
44
- "@elementor/editor-interactions": "3.35.0-379",
45
- "@elementor/editor-mcp": "3.35.0-379",
46
- "@elementor/editor-notifications": "3.35.0-379",
47
- "@elementor/editor-props": "3.35.0-379",
48
- "@elementor/editor-responsive": "3.35.0-379",
49
- "@elementor/editor-styles": "3.35.0-379",
50
- "@elementor/editor-styles-repository": "3.35.0-379",
51
- "@elementor/editor-ui": "3.35.0-379",
52
- "@elementor/editor-v1-adapters": "3.35.0-379",
53
- "@elementor/schema": "3.35.0-379",
54
- "@elementor/twing": "3.35.0-379",
40
+ "@elementor/editor": "3.35.0-381",
41
+ "@elementor/editor-controls": "3.35.0-381",
42
+ "@elementor/editor-documents": "3.35.0-381",
43
+ "@elementor/editor-elements": "3.35.0-381",
44
+ "@elementor/editor-interactions": "3.35.0-381",
45
+ "@elementor/editor-mcp": "3.35.0-381",
46
+ "@elementor/editor-notifications": "3.35.0-381",
47
+ "@elementor/editor-props": "3.35.0-381",
48
+ "@elementor/editor-responsive": "3.35.0-381",
49
+ "@elementor/editor-styles": "3.35.0-381",
50
+ "@elementor/editor-styles-repository": "3.35.0-381",
51
+ "@elementor/editor-ui": "3.35.0-381",
52
+ "@elementor/editor-v1-adapters": "3.35.0-381",
53
+ "@elementor/schema": "3.35.0-381",
54
+ "@elementor/twing": "3.35.0-381",
55
55
  "@elementor/ui": "1.36.17",
56
- "@elementor/utils": "3.35.0-379",
57
- "@elementor/wp-media": "3.35.0-379",
56
+ "@elementor/utils": "3.35.0-381",
57
+ "@elementor/wp-media": "3.35.0-381",
58
58
  "@floating-ui/react": "^0.27.5",
59
59
  "@wordpress/i18n": "^5.13.0"
60
60
  },
@@ -1,6 +1,15 @@
1
1
  import { type ReplacementSettings } from '../types';
2
2
 
3
- export default class ReplacementBase {
3
+ export interface ReplacementBaseInterface {
4
+ renderOnChange?: () => void;
5
+ onDestroy?: () => void;
6
+ _beforeRender?: () => void;
7
+ _afterRender?: () => void;
8
+ shouldRenderReplacement: () => boolean;
9
+ render?: () => void;
10
+ }
11
+
12
+ export default class ReplacementBase implements ReplacementBaseInterface {
4
13
  protected getSetting: ReplacementSettings[ 'getSetting' ];
5
14
  protected setSetting: ReplacementSettings[ 'setSetting' ];
6
15
  protected element: ReplacementSettings[ 'element' ];
@@ -21,14 +30,6 @@ export default class ReplacementBase {
21
30
  return null;
22
31
  }
23
32
 
24
- render(): void {}
25
-
26
- onDestroy(): void {}
27
-
28
- _beforeRender(): void {}
29
-
30
- _afterRender(): void {}
31
-
32
33
  shouldRenderReplacement(): boolean {
33
34
  return true;
34
35
  }
@@ -1,10 +1,11 @@
1
1
  import * as React from 'react';
2
- import { useEffect, useRef, useState } from 'react';
2
+ import { useCallback, useEffect, useRef, useState } from 'react';
3
3
  import { createRoot, type Root } from 'react-dom/client';
4
4
  import { InlineEditor } from '@elementor/editor-controls';
5
5
  import { getContainer, getElementType } from '@elementor/editor-elements';
6
6
  import {
7
7
  htmlPropTypeUtil,
8
+ type PropType,
8
9
  stringPropTypeUtil,
9
10
  type StringPropValue,
10
11
  type TransformablePropValue,
@@ -18,6 +19,12 @@ import { getInitialPopoverPosition, INLINE_EDITING_PROPERTY_PER_TYPE } from './i
18
19
 
19
20
  const EXPERIMENT_KEY = 'v4-inline-text-editing';
20
21
 
22
+ type TagPropType = PropType< 'tag' > & {
23
+ settings?: {
24
+ enum?: string[];
25
+ };
26
+ };
27
+
21
28
  export default class InlineEditingReplacement extends ReplacementBase {
22
29
  private inlineEditorRoot: Root | null = null;
23
30
  private handlerAttached = false;
@@ -35,7 +42,7 @@ export default class InlineEditingReplacement extends ReplacementBase {
35
42
  }
36
43
 
37
44
  shouldRenderReplacement() {
38
- return isExperimentActive( EXPERIMENT_KEY ) && this.isEditingModeActive() && ! this.isValueDynamic();
45
+ return isExperimentActive( EXPERIMENT_KEY ) && ! this.isValueDynamic();
39
46
  }
40
47
 
41
48
  handleRenderInlineEditor = ( event: Event ) => {
@@ -46,10 +53,13 @@ export default class InlineEditingReplacement extends ReplacementBase {
46
53
  }
47
54
  };
48
55
 
49
- handleUnmountInlineEditor = ( event: Event ) => {
50
- event.stopPropagation();
51
- this.unmountInlineEditor();
52
- };
56
+ renderOnChange() {
57
+ if ( this.isEditingModeActive() ) {
58
+ return;
59
+ }
60
+
61
+ this.refreshView();
62
+ }
53
63
 
54
64
  onDestroy() {
55
65
  this.resetInlineEditorRoot();
@@ -103,6 +113,7 @@ export default class InlineEditingReplacement extends ReplacementBase {
103
113
 
104
114
  return (
105
115
  htmlPropTypeUtil.extract( this.getSetting( settingKey ) ?? null ) ??
116
+ stringPropTypeUtil.extract( this.getSetting( settingKey ) ?? null ) ??
106
117
  htmlPropTypeUtil.extract( prop?.default ?? null ) ??
107
118
  defaultValue ??
108
119
  ''
@@ -113,33 +124,49 @@ export default class InlineEditingReplacement extends ReplacementBase {
113
124
  const settingKey = this.getInlineEditablePropertyName();
114
125
  const valueToSave = value ? htmlPropTypeUtil.create( value ) : null;
115
126
 
116
- runCommandSync( 'document/elements/settings', {
117
- container: getContainer( this.id ),
118
- settings: {
119
- [ settingKey ]: valueToSave,
127
+ runCommandSync(
128
+ 'document/elements/set-settings',
129
+ {
130
+ container: getContainer( this.id ),
131
+ settings: {
132
+ [ settingKey ]: valueToSave,
133
+ },
120
134
  },
121
- } );
135
+ { internal: true }
136
+ );
122
137
  }
123
138
 
124
139
  getExpectedTag() {
140
+ const tagPropType = this.getTagPropType();
141
+ const tagSettingKey = 'tag';
142
+
143
+ return (
144
+ stringPropTypeUtil.extract( this.getSetting( tagSettingKey ) ?? null ) ??
145
+ stringPropTypeUtil.extract( tagPropType?.default ?? null ) ??
146
+ null
147
+ );
148
+ }
149
+
150
+ getTagPropType() {
125
151
  const propsSchema = getElementType( this.type )?.propsSchema;
126
152
 
127
153
  if ( ! propsSchema?.tag ) {
128
154
  return null;
129
155
  }
130
156
 
131
- const tagSettingKey = 'tag';
157
+ const tagPropType = ( propsSchema.tag as TagPropType ) ?? null;
132
158
 
133
- return (
134
- stringPropTypeUtil.extract( this.getSetting( tagSettingKey ) ?? null ) ??
135
- stringPropTypeUtil.extract( propsSchema.tag.default ?? null ) ??
136
- null
137
- );
159
+ if ( tagPropType.kind === 'union' ) {
160
+ return ( tagPropType.prop_types.string as TagPropType ) ?? null;
161
+ }
162
+
163
+ return tagPropType;
138
164
  }
139
165
 
140
166
  renderInlineEditor() {
141
167
  const InlineEditorApp = this.InlineEditorApp;
142
- const classes = ( this.element.children?.[ 0 ]?.classList.toString() ?? '' ) + ' strip-styles';
168
+ const wrapperClasses = 'elementor';
169
+ const elementClasses = this.element.children?.[ 0 ]?.classList.toString() ?? '';
143
170
 
144
171
  this.element.innerHTML = '';
145
172
 
@@ -148,19 +175,32 @@ export default class InlineEditingReplacement extends ReplacementBase {
148
175
  }
149
176
 
150
177
  this.inlineEditorRoot = createRoot( this.element );
151
- this.inlineEditorRoot.render( <InlineEditorApp classes={ classes } /> );
178
+ this.inlineEditorRoot.render(
179
+ <InlineEditorApp wrapperClasses={ wrapperClasses } elementClasses={ elementClasses } />
180
+ );
152
181
  }
153
182
 
154
- InlineEditorApp = ( { classes }: { classes: string } ) => {
183
+ InlineEditorApp = ( { wrapperClasses, elementClasses }: { wrapperClasses: string; elementClasses: string } ) => {
155
184
  const propValue = this.getContentValue();
156
185
  const expectedTag = this.getExpectedTag();
157
186
  const wrapperRef = useRef< HTMLDivElement | null >( null );
158
187
  const [ isWrapperRendered, setIsWrapperRendered ] = useState( false );
159
188
 
160
189
  useEffect( () => {
190
+ const panel = document?.querySelector( 'main.MuiBox-root' );
191
+
161
192
  setIsWrapperRendered( !! wrapperRef.current );
193
+ panel?.addEventListener( 'click', asyncUnmountInlineEditor );
194
+
195
+ return () => panel?.removeEventListener( 'click', asyncUnmountInlineEditor );
196
+ // eslint-disable-next-line react-hooks/exhaustive-deps
162
197
  }, [] );
163
198
 
199
+ const asyncUnmountInlineEditor = useCallback(
200
+ () => queueMicrotask( this.unmountInlineEditor.bind( this ) ),
201
+ []
202
+ );
203
+
164
204
  return (
165
205
  <ThemeProvider>
166
206
  <Box ref={ wrapperRef }>
@@ -169,12 +209,13 @@ export default class InlineEditingReplacement extends ReplacementBase {
169
209
  ) }
170
210
  <InlineEditor
171
211
  attributes={ {
172
- class: classes,
212
+ class: wrapperClasses,
173
213
  style: 'outline: none;',
174
214
  } }
215
+ elementClasses={ elementClasses }
175
216
  value={ propValue }
176
217
  setValue={ this.setContentValue.bind( this ) }
177
- onBlur={ this.handleUnmountInlineEditor.bind( this ) }
218
+ onBlur={ this.unmountInlineEditor.bind( this ) }
178
219
  autofocus
179
220
  showToolbar
180
221
  getInitialPopoverPosition={ getInitialPopoverPosition }
@@ -2,6 +2,7 @@ import type { CreateTemplatedElementTypeOptions } from '../create-templated-elem
2
2
  import { createTemplatedElementView } from '../create-templated-element-type';
3
3
  import type { ElementType, ElementView, LegacyWindow, ReplacementSettings } from '../types';
4
4
  import type ReplacementBase from './base';
5
+ import { type ReplacementBaseInterface } from './base';
5
6
  import InlineEditingReplacement from './inline-editing/inline-editing-elements';
6
7
 
7
8
  type ReplacementConstructor = new ( settings: ReplacementSettings ) => ReplacementBase;
@@ -32,7 +33,7 @@ export const createViewWithReplacements = ( options: CreateTemplatedElementTypeO
32
33
  const TemplatedView = createTemplatedElementView( options );
33
34
 
34
35
  return class extends TemplatedView {
35
- #replacement: ReplacementBase | null = null;
36
+ #replacement: ReplacementBaseInterface | null = null;
36
37
  #config: ReplacementSettings;
37
38
 
38
39
  constructor( ...args: unknown[] ) {
@@ -53,6 +54,12 @@ export const createViewWithReplacements = ( options: CreateTemplatedElementTypeO
53
54
  this.render();
54
55
  }
55
56
 
57
+ renderOnChange(): void {
58
+ if ( ! this.#triggerMethod( 'renderOnChange' ) ) {
59
+ TemplatedView.prototype.renderOnChange.apply( this );
60
+ }
61
+ }
62
+
56
63
  render() {
57
64
  const config = this.#config;
58
65
  const widgetType = config.type;
@@ -62,16 +69,13 @@ export const createViewWithReplacements = ( options: CreateTemplatedElementTypeO
62
69
  this.#replacement = new ReplacementClass( config );
63
70
  }
64
71
 
65
- if ( ! this.#replacement?.shouldRenderReplacement() ) {
66
- return TemplatedView.prototype.render.apply( this );
72
+ if ( ! this.#triggerMethod( 'render' ) ) {
73
+ TemplatedView.prototype.render.apply( this );
67
74
  }
68
-
69
- this.#replacement.render();
70
75
  }
71
76
 
72
77
  onDestroy() {
73
- if ( this.#replacement ) {
74
- this.#replacement.onDestroy();
78
+ if ( this.#triggerMethod( 'onDestroy' ) ) {
75
79
  this.#replacement = null;
76
80
  }
77
81
 
@@ -79,19 +83,29 @@ export const createViewWithReplacements = ( options: CreateTemplatedElementTypeO
79
83
  }
80
84
 
81
85
  _afterRender() {
82
- if ( this.#replacement ) {
83
- this.#replacement._afterRender();
86
+ if ( ! this.#triggerMethod( '_afterRender' ) ) {
87
+ TemplatedView.prototype._afterRender.apply( this );
84
88
  }
85
-
86
- TemplatedView.prototype._afterRender.apply( this );
87
89
  }
88
90
 
89
91
  _beforeRender(): void {
90
- if ( this.#replacement ) {
91
- this.#replacement._beforeRender();
92
+ if ( ! this.#triggerMethod( '_beforeRender' ) ) {
93
+ TemplatedView.prototype._beforeRender.apply( this );
92
94
  }
95
+ }
96
+
97
+ #triggerMethod( methodKey: keyof ReplacementBaseInterface ) {
98
+ const method =
99
+ this.#replacement?.shouldRenderReplacement() &&
100
+ this.#replacement[ methodKey ]?.bind( this.#replacement );
101
+
102
+ if ( ! method || typeof method !== 'function' ) {
103
+ return false;
104
+ }
105
+
106
+ method();
93
107
 
94
- TemplatedView.prototype._beforeRender.apply( this );
108
+ return true;
95
109
  }
96
110
  };
97
111
  };