@elementor/editor-canvas 4.0.0-512 → 4.0.0-513
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 +223 -88
- package/dist/index.mjs +228 -93
- package/package.json +18 -18
- package/src/legacy/replacements/inline-editing/canvas-inline-editor.tsx +215 -0
- package/src/legacy/replacements/inline-editing/inline-editing-elements.tsx +15 -79
- package/src/legacy/replacements/inline-editing/inline-editing-utils.ts +65 -12
package/dist/index.js
CHANGED
|
@@ -1493,8 +1493,8 @@ function escapeURL(value) {
|
|
|
1493
1493
|
|
|
1494
1494
|
// src/legacy/create-element-type.ts
|
|
1495
1495
|
function createElementType(type) {
|
|
1496
|
-
const
|
|
1497
|
-
return class extends
|
|
1496
|
+
const legacyWindow = window;
|
|
1497
|
+
return class extends legacyWindow.elementor.modules.elements.types.Widget {
|
|
1498
1498
|
getType() {
|
|
1499
1499
|
return type;
|
|
1500
1500
|
}
|
|
@@ -1504,8 +1504,8 @@ function createElementType(type) {
|
|
|
1504
1504
|
};
|
|
1505
1505
|
}
|
|
1506
1506
|
function createElementViewClassDeclaration() {
|
|
1507
|
-
const
|
|
1508
|
-
return class extends
|
|
1507
|
+
const legacyWindow = window;
|
|
1508
|
+
return class extends legacyWindow.elementor.modules.elements.views.Widget {
|
|
1509
1509
|
// Dispatch `render` event so the overlay layer will be updated
|
|
1510
1510
|
onRender(...args) {
|
|
1511
1511
|
super.onRender(...args);
|
|
@@ -1551,7 +1551,7 @@ function createElementViewClassDeclaration() {
|
|
|
1551
1551
|
);
|
|
1552
1552
|
}
|
|
1553
1553
|
#dispatchPreviewEvent(eventType) {
|
|
1554
|
-
|
|
1554
|
+
legacyWindow.elementor?.$preview?.[0]?.contentWindow.dispatchEvent(
|
|
1555
1555
|
new CustomEvent(eventType, {
|
|
1556
1556
|
detail: {
|
|
1557
1557
|
id: this.model.get("id"),
|
|
@@ -1711,14 +1711,11 @@ function createTemplatedElementView({
|
|
|
1711
1711
|
}
|
|
1712
1712
|
|
|
1713
1713
|
// src/legacy/replacements/inline-editing/inline-editing-elements.tsx
|
|
1714
|
-
var
|
|
1715
|
-
var import_react11 = require("react");
|
|
1714
|
+
var React6 = __toESM(require("react"));
|
|
1716
1715
|
var import_client = require("react-dom/client");
|
|
1717
|
-
var import_editor_controls2 = require("@elementor/editor-controls");
|
|
1718
1716
|
var import_editor_elements3 = require("@elementor/editor-elements");
|
|
1719
1717
|
var import_editor_props4 = require("@elementor/editor-props");
|
|
1720
1718
|
var import_editor_v1_adapters9 = require("@elementor/editor-v1-adapters");
|
|
1721
|
-
var import_ui4 = require("@elementor/ui");
|
|
1722
1719
|
var import_i18n = require("@wordpress/i18n");
|
|
1723
1720
|
|
|
1724
1721
|
// src/legacy/replacements/base.ts
|
|
@@ -1759,6 +1756,207 @@ var ReplacementBase = class {
|
|
|
1759
1756
|
}
|
|
1760
1757
|
};
|
|
1761
1758
|
|
|
1759
|
+
// src/legacy/replacements/inline-editing/canvas-inline-editor.tsx
|
|
1760
|
+
var React5 = __toESM(require("react"));
|
|
1761
|
+
var import_react11 = require("react");
|
|
1762
|
+
var import_editor_controls2 = require("@elementor/editor-controls");
|
|
1763
|
+
var import_ui4 = require("@elementor/ui");
|
|
1764
|
+
var import_react12 = require("@floating-ui/react");
|
|
1765
|
+
|
|
1766
|
+
// src/legacy/replacements/inline-editing/inline-editing-utils.ts
|
|
1767
|
+
var INLINE_EDITING_PROPERTY_PER_TYPE = {
|
|
1768
|
+
"e-form-label": "text",
|
|
1769
|
+
"e-heading": "title",
|
|
1770
|
+
"e-paragraph": "paragraph"
|
|
1771
|
+
};
|
|
1772
|
+
var calcSelectionCenterOffsets = (view) => {
|
|
1773
|
+
const frameWindow = view.root?.defaultView;
|
|
1774
|
+
const selection = frameWindow?.getSelection();
|
|
1775
|
+
const editorContainer = view.dom;
|
|
1776
|
+
if (!selection || !editorContainer) {
|
|
1777
|
+
return null;
|
|
1778
|
+
}
|
|
1779
|
+
const range = selection.getRangeAt(0);
|
|
1780
|
+
const selectionRect = range.getBoundingClientRect();
|
|
1781
|
+
const editorContainerRect = editorContainer.getBoundingClientRect();
|
|
1782
|
+
if (!selectionRect || !editorContainerRect) {
|
|
1783
|
+
return null;
|
|
1784
|
+
}
|
|
1785
|
+
const verticalOffset = selectionRect.top - editorContainerRect.top;
|
|
1786
|
+
const selectionCenter = selectionRect?.left + selectionRect?.width / 2;
|
|
1787
|
+
const horizontalOffset = selectionCenter - editorContainerRect.left;
|
|
1788
|
+
return { left: horizontalOffset, top: verticalOffset };
|
|
1789
|
+
};
|
|
1790
|
+
var getComputedStyle = (styles, offsets) => {
|
|
1791
|
+
const transform = extractTransformValue(styles);
|
|
1792
|
+
return transform ? {
|
|
1793
|
+
...styles,
|
|
1794
|
+
marginLeft: `${offsets.left}px`,
|
|
1795
|
+
marginTop: `${offsets.top}px`,
|
|
1796
|
+
pointerEvents: "none"
|
|
1797
|
+
} : {
|
|
1798
|
+
display: "none"
|
|
1799
|
+
};
|
|
1800
|
+
};
|
|
1801
|
+
var extractTransformValue = (styles) => {
|
|
1802
|
+
const translateRegex = /translate\([^)]*\)\s?/g;
|
|
1803
|
+
const numericValuesRegex = /(-?\d+\.?\d*)/g;
|
|
1804
|
+
const translateValue = styles?.transform?.match(translateRegex)?.[0];
|
|
1805
|
+
const values = translateValue?.match(numericValuesRegex);
|
|
1806
|
+
if (!translateValue || !values) {
|
|
1807
|
+
return null;
|
|
1808
|
+
}
|
|
1809
|
+
const [numericX, numericY] = values.map(Number);
|
|
1810
|
+
if (!numericX || !numericY) {
|
|
1811
|
+
return null;
|
|
1812
|
+
}
|
|
1813
|
+
return styles.transform;
|
|
1814
|
+
};
|
|
1815
|
+
|
|
1816
|
+
// src/legacy/replacements/inline-editing/canvas-inline-editor.tsx
|
|
1817
|
+
var TOP_BAR_SELECTOR = "#elementor-editor-wrapper-v2";
|
|
1818
|
+
var NAVIGATOR_SELECTOR = "#elementor-navigator";
|
|
1819
|
+
var EDITING_PANEL = "#elementor-panel";
|
|
1820
|
+
var EDITOR_ELEMENTS_OUT_OF_IFRAME = [TOP_BAR_SELECTOR, NAVIGATOR_SELECTOR, EDITING_PANEL];
|
|
1821
|
+
var EDITOR_WRAPPER_SELECTOR = "inline-editor-wrapper";
|
|
1822
|
+
var CanvasInlineEditor = ({
|
|
1823
|
+
elementClasses,
|
|
1824
|
+
initialValue,
|
|
1825
|
+
expectedTag,
|
|
1826
|
+
rootElement,
|
|
1827
|
+
id,
|
|
1828
|
+
setValue,
|
|
1829
|
+
onBlur
|
|
1830
|
+
}) => {
|
|
1831
|
+
const [selectionOffsets, setSelectionOffsets] = (0, import_react11.useState)(null);
|
|
1832
|
+
const [editor, setEditor] = (0, import_react11.useState)(null);
|
|
1833
|
+
const onSelectionEnd = (view) => {
|
|
1834
|
+
const hasSelection = !view.state.selection.empty;
|
|
1835
|
+
setSelectionOffsets(hasSelection ? calcSelectionCenterOffsets(view) : null);
|
|
1836
|
+
};
|
|
1837
|
+
useOnClickOutsideIframe(onBlur);
|
|
1838
|
+
return /* @__PURE__ */ React5.createElement(import_ui4.ThemeProvider, null, /* @__PURE__ */ React5.createElement(InlineEditingOverlay, { expectedTag, rootElement, id }), /* @__PURE__ */ React5.createElement("style", null, `
|
|
1839
|
+
.${EDITOR_WRAPPER_SELECTOR}, .${EDITOR_WRAPPER_SELECTOR} > * {
|
|
1840
|
+
height: 100%;
|
|
1841
|
+
}
|
|
1842
|
+
.ProseMirror > * {
|
|
1843
|
+
height: 100%;
|
|
1844
|
+
}
|
|
1845
|
+
`), /* @__PURE__ */ React5.createElement(
|
|
1846
|
+
import_editor_controls2.InlineEditor,
|
|
1847
|
+
{
|
|
1848
|
+
onEditorCreate: setEditor,
|
|
1849
|
+
editorProps: {
|
|
1850
|
+
attributes: {
|
|
1851
|
+
style: "outline: none;overflow-wrap: normal;height:100%"
|
|
1852
|
+
}
|
|
1853
|
+
},
|
|
1854
|
+
elementClasses,
|
|
1855
|
+
value: initialValue,
|
|
1856
|
+
setValue,
|
|
1857
|
+
onBlur,
|
|
1858
|
+
autofocus: true,
|
|
1859
|
+
expectedTag,
|
|
1860
|
+
wrapperClassName: EDITOR_WRAPPER_SELECTOR,
|
|
1861
|
+
onSelectionEnd
|
|
1862
|
+
}
|
|
1863
|
+
), selectionOffsets && editor && /* @__PURE__ */ React5.createElement(
|
|
1864
|
+
InlineEditingToolbarWrapper,
|
|
1865
|
+
{
|
|
1866
|
+
expectedTag,
|
|
1867
|
+
editor,
|
|
1868
|
+
rootElement,
|
|
1869
|
+
id,
|
|
1870
|
+
selectionOffsets
|
|
1871
|
+
}
|
|
1872
|
+
));
|
|
1873
|
+
};
|
|
1874
|
+
var InlineEditingOverlay = ({
|
|
1875
|
+
expectedTag,
|
|
1876
|
+
rootElement,
|
|
1877
|
+
id
|
|
1878
|
+
}) => {
|
|
1879
|
+
const inlineEditedElement = getInlineEditorElement(rootElement, expectedTag);
|
|
1880
|
+
const [overlayRefElement, setOverlayElement] = (0, import_react11.useState)(inlineEditedElement);
|
|
1881
|
+
(0, import_react11.useEffect)(() => {
|
|
1882
|
+
setOverlayElement(getInlineEditorElement(rootElement, expectedTag));
|
|
1883
|
+
}, [expectedTag, rootElement]);
|
|
1884
|
+
return overlayRefElement ? /* @__PURE__ */ React5.createElement(OutlineOverlay, { element: overlayRefElement, id, isSelected: true }) : null;
|
|
1885
|
+
};
|
|
1886
|
+
var InlineEditingToolbarWrapper = ({
|
|
1887
|
+
expectedTag,
|
|
1888
|
+
editor,
|
|
1889
|
+
rootElement,
|
|
1890
|
+
id,
|
|
1891
|
+
selectionOffsets
|
|
1892
|
+
}) => {
|
|
1893
|
+
const [element, setElement] = (0, import_react11.useState)(null);
|
|
1894
|
+
(0, import_react11.useEffect)(() => {
|
|
1895
|
+
setElement(getInlineEditorElement(rootElement, expectedTag));
|
|
1896
|
+
}, [expectedTag, rootElement]);
|
|
1897
|
+
return element ? /* @__PURE__ */ React5.createElement(InlineEditingToolbar, { element, editor, id, selectionOffsets }) : null;
|
|
1898
|
+
};
|
|
1899
|
+
var InlineEditingToolbar = ({
|
|
1900
|
+
element,
|
|
1901
|
+
editor,
|
|
1902
|
+
id,
|
|
1903
|
+
selectionOffsets
|
|
1904
|
+
}) => {
|
|
1905
|
+
const { floating } = useFloatingOnElement({
|
|
1906
|
+
element,
|
|
1907
|
+
isSelected: true
|
|
1908
|
+
});
|
|
1909
|
+
const { getFloatingProps, getReferenceProps } = (0, import_react12.useInteractions)();
|
|
1910
|
+
const style = getComputedStyle(floating.styles, selectionOffsets);
|
|
1911
|
+
useBindReactPropsToElement(element, getReferenceProps);
|
|
1912
|
+
return /* @__PURE__ */ React5.createElement(import_react12.FloatingPortal, { id: CANVAS_WRAPPER_ID }, /* @__PURE__ */ React5.createElement(
|
|
1913
|
+
import_ui4.Box,
|
|
1914
|
+
{
|
|
1915
|
+
ref: floating.setRef,
|
|
1916
|
+
style: {
|
|
1917
|
+
...floating.styles,
|
|
1918
|
+
pointerEvents: "none"
|
|
1919
|
+
},
|
|
1920
|
+
role: "presentation",
|
|
1921
|
+
...getFloatingProps({ style })
|
|
1922
|
+
},
|
|
1923
|
+
floating.styles.transform && /* @__PURE__ */ React5.createElement(
|
|
1924
|
+
import_ui4.Box,
|
|
1925
|
+
{
|
|
1926
|
+
sx: {
|
|
1927
|
+
position: "relative",
|
|
1928
|
+
transform: "translateY(-100%)",
|
|
1929
|
+
height: "max-content"
|
|
1930
|
+
}
|
|
1931
|
+
},
|
|
1932
|
+
/* @__PURE__ */ React5.createElement(
|
|
1933
|
+
import_editor_controls2.InlineEditorToolbar,
|
|
1934
|
+
{
|
|
1935
|
+
editor,
|
|
1936
|
+
elementId: id,
|
|
1937
|
+
sx: {
|
|
1938
|
+
transform: "translateX(-50%)"
|
|
1939
|
+
}
|
|
1940
|
+
}
|
|
1941
|
+
)
|
|
1942
|
+
)
|
|
1943
|
+
));
|
|
1944
|
+
};
|
|
1945
|
+
var getInlineEditorElement = (elementWrapper, expectedTag) => {
|
|
1946
|
+
return !expectedTag ? null : elementWrapper.querySelector(expectedTag);
|
|
1947
|
+
};
|
|
1948
|
+
var useOnClickOutsideIframe = (handleUnmount) => {
|
|
1949
|
+
const asyncUnmountInlineEditor = React5.useCallback(() => queueMicrotask(handleUnmount), [handleUnmount]);
|
|
1950
|
+
(0, import_react11.useEffect)(() => {
|
|
1951
|
+
EDITOR_ELEMENTS_OUT_OF_IFRAME.forEach(
|
|
1952
|
+
(selector) => document?.querySelector(selector)?.addEventListener("mousedown", asyncUnmountInlineEditor)
|
|
1953
|
+
);
|
|
1954
|
+
return () => EDITOR_ELEMENTS_OUT_OF_IFRAME.forEach(
|
|
1955
|
+
(selector) => document?.querySelector(selector)?.removeEventListener("mousedown", asyncUnmountInlineEditor)
|
|
1956
|
+
);
|
|
1957
|
+
}, []);
|
|
1958
|
+
};
|
|
1959
|
+
|
|
1762
1960
|
// src/legacy/replacements/inline-editing/inline-editing-eligibility.ts
|
|
1763
1961
|
var import_editor_props3 = require("@elementor/editor-props");
|
|
1764
1962
|
var hasKey = (propType) => {
|
|
@@ -1788,32 +1986,8 @@ var isInlineEditingAllowed = ({ rawValue, propTypeFromSchema }) => {
|
|
|
1788
1986
|
return import_editor_props3.htmlPropTypeUtil.isValid(rawValue) || import_editor_props3.stringPropTypeUtil.isValid(rawValue);
|
|
1789
1987
|
};
|
|
1790
1988
|
|
|
1791
|
-
// src/legacy/replacements/inline-editing/inline-editing-utils.ts
|
|
1792
|
-
var INLINE_EDITING_PROPERTY_PER_TYPE = {
|
|
1793
|
-
"e-form-label": "text",
|
|
1794
|
-
"e-heading": "title",
|
|
1795
|
-
"e-paragraph": "paragraph"
|
|
1796
|
-
};
|
|
1797
|
-
var legacyWindow = window;
|
|
1798
|
-
var getInitialPopoverPosition = () => {
|
|
1799
|
-
const positionFallback = { left: 0, top: 0 };
|
|
1800
|
-
const iFrameElement = legacyWindow?.elementor?.$preview?.get(0);
|
|
1801
|
-
const iFramePosition = iFrameElement?.getBoundingClientRect() ?? positionFallback;
|
|
1802
|
-
const previewElement = legacyWindow?.elementor?.$previewWrapper?.get(0);
|
|
1803
|
-
const previewPosition = previewElement ? { left: previewElement.scrollLeft, top: previewElement.scrollTop } : positionFallback;
|
|
1804
|
-
return {
|
|
1805
|
-
left: iFramePosition.left + previewPosition.left,
|
|
1806
|
-
top: iFramePosition.top + previewPosition.top
|
|
1807
|
-
};
|
|
1808
|
-
};
|
|
1809
|
-
|
|
1810
1989
|
// src/legacy/replacements/inline-editing/inline-editing-elements.tsx
|
|
1811
1990
|
var HISTORY_DEBOUNCE_WAIT = 800;
|
|
1812
|
-
var TOP_BAR_SELECTOR = "#elementor-editor-wrapper-v2";
|
|
1813
|
-
var NAVIGATOR_SELECTOR = "#elementor-navigator";
|
|
1814
|
-
var V4_EDITING_PANEL = "main.MuiBox-root";
|
|
1815
|
-
var V3_EDITING_PANEL = "#elementor-panel-content-wrapper";
|
|
1816
|
-
var BLUR_TRIGGERING_SELECTORS = [TOP_BAR_SELECTOR, NAVIGATOR_SELECTOR, V4_EDITING_PANEL, V3_EDITING_PANEL];
|
|
1817
1991
|
var InlineEditingReplacement = class extends ReplacementBase {
|
|
1818
1992
|
inlineEditorRoot = null;
|
|
1819
1993
|
handlerAttached = false;
|
|
@@ -1827,7 +2001,7 @@ var InlineEditingReplacement = class extends ReplacementBase {
|
|
|
1827
2001
|
return !!this.inlineEditorRoot;
|
|
1828
2002
|
}
|
|
1829
2003
|
shouldRenderReplacement() {
|
|
1830
|
-
return this.isInlineEditingEligible();
|
|
2004
|
+
return this.isInlineEditingEligible() && (0, import_editor_v1_adapters9.getCurrentEditMode)() === "edit";
|
|
1831
2005
|
}
|
|
1832
2006
|
handleRenderInlineEditor = () => {
|
|
1833
2007
|
if (this.isEditingModeActive() || !this.isInlineEditingEligible()) {
|
|
@@ -1973,65 +2147,26 @@ var InlineEditingReplacement = class extends ReplacementBase {
|
|
|
1973
2147
|
if (this.isEditingModeActive()) {
|
|
1974
2148
|
this.resetInlineEditorRoot();
|
|
1975
2149
|
}
|
|
1976
|
-
const InlineEditorApp = this.InlineEditorApp;
|
|
1977
|
-
const wrapperClasses = "elementor";
|
|
1978
2150
|
const elementClasses = this.element.children?.[0]?.classList.toString() ?? "";
|
|
2151
|
+
const propValue = this.getExtractedContentValue();
|
|
2152
|
+
const expectedTag = this.getExpectedTag();
|
|
1979
2153
|
this.element.innerHTML = "";
|
|
1980
2154
|
this.inlineEditorRoot = (0, import_client.createRoot)(this.element);
|
|
1981
2155
|
this.inlineEditorRoot.render(
|
|
1982
|
-
/* @__PURE__ */
|
|
1983
|
-
|
|
1984
|
-
}
|
|
1985
|
-
InlineEditorApp = ({ wrapperClasses, elementClasses }) => {
|
|
1986
|
-
const propValue = this.getExtractedContentValue();
|
|
1987
|
-
const expectedTag = this.getExpectedTag();
|
|
1988
|
-
const wrapperRef = (0, import_react11.useRef)(null);
|
|
1989
|
-
const [isWrapperRendered, setIsWrapperRendered] = (0, import_react11.useState)(false);
|
|
1990
|
-
(0, import_react11.useEffect)(() => {
|
|
1991
|
-
setIsWrapperRendered(!!wrapperRef.current);
|
|
1992
|
-
BLUR_TRIGGERING_SELECTORS.forEach(
|
|
1993
|
-
(selector) => document?.querySelector(selector)?.addEventListener("mousedown", asyncUnmountInlineEditor)
|
|
1994
|
-
);
|
|
1995
|
-
return () => BLUR_TRIGGERING_SELECTORS.forEach(
|
|
1996
|
-
(selector) => document?.querySelector(selector)?.removeEventListener("mousedown", asyncUnmountInlineEditor)
|
|
1997
|
-
);
|
|
1998
|
-
}, []);
|
|
1999
|
-
const asyncUnmountInlineEditor = React5.useCallback(
|
|
2000
|
-
() => queueMicrotask(this.unmountInlineEditor.bind(this)),
|
|
2001
|
-
[]
|
|
2002
|
-
);
|
|
2003
|
-
return /* @__PURE__ */ React5.createElement(import_ui4.ThemeProvider, null, /* @__PURE__ */ React5.createElement(
|
|
2004
|
-
import_ui4.Box,
|
|
2005
|
-
{
|
|
2006
|
-
ref: wrapperRef,
|
|
2007
|
-
sx: {
|
|
2008
|
-
"& .elementor-inline-editor-reset": {
|
|
2009
|
-
margin: 0,
|
|
2010
|
-
padding: 0
|
|
2011
|
-
}
|
|
2012
|
-
}
|
|
2013
|
-
},
|
|
2014
|
-
isWrapperRendered && /* @__PURE__ */ React5.createElement(OutlineOverlay, { element: wrapperRef.current, id: this.id, isSelected: true }),
|
|
2015
|
-
/* @__PURE__ */ React5.createElement(
|
|
2016
|
-
import_editor_controls2.InlineEditor,
|
|
2156
|
+
/* @__PURE__ */ React6.createElement(
|
|
2157
|
+
CanvasInlineEditor,
|
|
2017
2158
|
{
|
|
2018
|
-
attributes: {
|
|
2019
|
-
class: wrapperClasses,
|
|
2020
|
-
style: "outline: none;"
|
|
2021
|
-
},
|
|
2022
2159
|
elementClasses,
|
|
2023
|
-
|
|
2024
|
-
setValue: this.setContentValue.bind(this),
|
|
2025
|
-
onBlur: this.unmountInlineEditor.bind(this),
|
|
2026
|
-
autofocus: true,
|
|
2027
|
-
showToolbar: true,
|
|
2028
|
-
getInitialPopoverPosition,
|
|
2160
|
+
initialValue: propValue,
|
|
2029
2161
|
expectedTag,
|
|
2030
|
-
|
|
2162
|
+
rootElement: this.element,
|
|
2163
|
+
id: this.id,
|
|
2164
|
+
setValue: this.setContentValue.bind(this),
|
|
2165
|
+
onBlur: this.unmountInlineEditor.bind(this)
|
|
2031
2166
|
}
|
|
2032
2167
|
)
|
|
2033
|
-
)
|
|
2034
|
-
}
|
|
2168
|
+
);
|
|
2169
|
+
}
|
|
2035
2170
|
};
|
|
2036
2171
|
|
|
2037
2172
|
// src/legacy/replacements/manager.ts
|
|
@@ -2116,13 +2251,13 @@ var createTemplatedElementTypeWithReplacements = ({
|
|
|
2116
2251
|
renderer,
|
|
2117
2252
|
element
|
|
2118
2253
|
}) => {
|
|
2119
|
-
const
|
|
2254
|
+
const legacyWindow = window;
|
|
2120
2255
|
const view = createViewWithReplacements({
|
|
2121
2256
|
type,
|
|
2122
2257
|
renderer,
|
|
2123
2258
|
element
|
|
2124
2259
|
});
|
|
2125
|
-
return class extends
|
|
2260
|
+
return class extends legacyWindow.elementor.modules.elements.types.Widget {
|
|
2126
2261
|
getType() {
|
|
2127
2262
|
return type;
|
|
2128
2263
|
}
|
|
@@ -2140,7 +2275,7 @@ function registerElementType(type, elementTypeGenerator) {
|
|
|
2140
2275
|
function initLegacyViews() {
|
|
2141
2276
|
(0, import_editor_v1_adapters10.__privateListenTo)((0, import_editor_v1_adapters10.v1ReadyEvent)(), () => {
|
|
2142
2277
|
const config = (0, import_editor_elements4.getWidgetsCache)() ?? {};
|
|
2143
|
-
const
|
|
2278
|
+
const legacyWindow = window;
|
|
2144
2279
|
const renderer = createDomRenderer();
|
|
2145
2280
|
Object.entries(config).forEach(([type, element]) => {
|
|
2146
2281
|
if (!element.atomic) {
|
|
@@ -2154,7 +2289,7 @@ function initLegacyViews() {
|
|
|
2154
2289
|
} else {
|
|
2155
2290
|
ElementType = createElementType(type);
|
|
2156
2291
|
}
|
|
2157
|
-
|
|
2292
|
+
legacyWindow.elementor.elementsManager.registerElementType(new ElementType());
|
|
2158
2293
|
});
|
|
2159
2294
|
});
|
|
2160
2295
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -1464,8 +1464,8 @@ function escapeURL(value) {
|
|
|
1464
1464
|
|
|
1465
1465
|
// src/legacy/create-element-type.ts
|
|
1466
1466
|
function createElementType(type) {
|
|
1467
|
-
const
|
|
1468
|
-
return class extends
|
|
1467
|
+
const legacyWindow = window;
|
|
1468
|
+
return class extends legacyWindow.elementor.modules.elements.types.Widget {
|
|
1469
1469
|
getType() {
|
|
1470
1470
|
return type;
|
|
1471
1471
|
}
|
|
@@ -1475,8 +1475,8 @@ function createElementType(type) {
|
|
|
1475
1475
|
};
|
|
1476
1476
|
}
|
|
1477
1477
|
function createElementViewClassDeclaration() {
|
|
1478
|
-
const
|
|
1479
|
-
return class extends
|
|
1478
|
+
const legacyWindow = window;
|
|
1479
|
+
return class extends legacyWindow.elementor.modules.elements.views.Widget {
|
|
1480
1480
|
// Dispatch `render` event so the overlay layer will be updated
|
|
1481
1481
|
onRender(...args) {
|
|
1482
1482
|
super.onRender(...args);
|
|
@@ -1522,7 +1522,7 @@ function createElementViewClassDeclaration() {
|
|
|
1522
1522
|
);
|
|
1523
1523
|
}
|
|
1524
1524
|
#dispatchPreviewEvent(eventType) {
|
|
1525
|
-
|
|
1525
|
+
legacyWindow.elementor?.$preview?.[0]?.contentWindow.dispatchEvent(
|
|
1526
1526
|
new CustomEvent(eventType, {
|
|
1527
1527
|
detail: {
|
|
1528
1528
|
id: this.model.get("id"),
|
|
@@ -1682,14 +1682,11 @@ function createTemplatedElementView({
|
|
|
1682
1682
|
}
|
|
1683
1683
|
|
|
1684
1684
|
// src/legacy/replacements/inline-editing/inline-editing-elements.tsx
|
|
1685
|
-
import * as
|
|
1686
|
-
import { useEffect as useEffect7, useRef as useRef2, useState as useState4 } from "react";
|
|
1685
|
+
import * as React6 from "react";
|
|
1687
1686
|
import { createRoot } from "react-dom/client";
|
|
1688
|
-
import { InlineEditor } from "@elementor/editor-controls";
|
|
1689
1687
|
import { getContainer, getElementLabel, getElementType } from "@elementor/editor-elements";
|
|
1690
1688
|
import { htmlPropTypeUtil as htmlPropTypeUtil2, stringPropTypeUtil as stringPropTypeUtil2 } from "@elementor/editor-props";
|
|
1691
|
-
import { __privateRunCommandSync as runCommandSync, undoable } from "@elementor/editor-v1-adapters";
|
|
1692
|
-
import { Box as Box2, ThemeProvider } from "@elementor/ui";
|
|
1689
|
+
import { __privateRunCommandSync as runCommandSync, getCurrentEditMode, undoable } from "@elementor/editor-v1-adapters";
|
|
1693
1690
|
import { __ } from "@wordpress/i18n";
|
|
1694
1691
|
|
|
1695
1692
|
// src/legacy/replacements/base.ts
|
|
@@ -1730,6 +1727,207 @@ var ReplacementBase = class {
|
|
|
1730
1727
|
}
|
|
1731
1728
|
};
|
|
1732
1729
|
|
|
1730
|
+
// src/legacy/replacements/inline-editing/canvas-inline-editor.tsx
|
|
1731
|
+
import * as React5 from "react";
|
|
1732
|
+
import { useEffect as useEffect7, useState as useState4 } from "react";
|
|
1733
|
+
import { InlineEditor, InlineEditorToolbar } from "@elementor/editor-controls";
|
|
1734
|
+
import { Box as Box2, ThemeProvider } from "@elementor/ui";
|
|
1735
|
+
import { FloatingPortal as FloatingPortal2, useInteractions as useInteractions2 } from "@floating-ui/react";
|
|
1736
|
+
|
|
1737
|
+
// src/legacy/replacements/inline-editing/inline-editing-utils.ts
|
|
1738
|
+
var INLINE_EDITING_PROPERTY_PER_TYPE = {
|
|
1739
|
+
"e-form-label": "text",
|
|
1740
|
+
"e-heading": "title",
|
|
1741
|
+
"e-paragraph": "paragraph"
|
|
1742
|
+
};
|
|
1743
|
+
var calcSelectionCenterOffsets = (view) => {
|
|
1744
|
+
const frameWindow = view.root?.defaultView;
|
|
1745
|
+
const selection = frameWindow?.getSelection();
|
|
1746
|
+
const editorContainer = view.dom;
|
|
1747
|
+
if (!selection || !editorContainer) {
|
|
1748
|
+
return null;
|
|
1749
|
+
}
|
|
1750
|
+
const range = selection.getRangeAt(0);
|
|
1751
|
+
const selectionRect = range.getBoundingClientRect();
|
|
1752
|
+
const editorContainerRect = editorContainer.getBoundingClientRect();
|
|
1753
|
+
if (!selectionRect || !editorContainerRect) {
|
|
1754
|
+
return null;
|
|
1755
|
+
}
|
|
1756
|
+
const verticalOffset = selectionRect.top - editorContainerRect.top;
|
|
1757
|
+
const selectionCenter = selectionRect?.left + selectionRect?.width / 2;
|
|
1758
|
+
const horizontalOffset = selectionCenter - editorContainerRect.left;
|
|
1759
|
+
return { left: horizontalOffset, top: verticalOffset };
|
|
1760
|
+
};
|
|
1761
|
+
var getComputedStyle = (styles, offsets) => {
|
|
1762
|
+
const transform = extractTransformValue(styles);
|
|
1763
|
+
return transform ? {
|
|
1764
|
+
...styles,
|
|
1765
|
+
marginLeft: `${offsets.left}px`,
|
|
1766
|
+
marginTop: `${offsets.top}px`,
|
|
1767
|
+
pointerEvents: "none"
|
|
1768
|
+
} : {
|
|
1769
|
+
display: "none"
|
|
1770
|
+
};
|
|
1771
|
+
};
|
|
1772
|
+
var extractTransformValue = (styles) => {
|
|
1773
|
+
const translateRegex = /translate\([^)]*\)\s?/g;
|
|
1774
|
+
const numericValuesRegex = /(-?\d+\.?\d*)/g;
|
|
1775
|
+
const translateValue = styles?.transform?.match(translateRegex)?.[0];
|
|
1776
|
+
const values = translateValue?.match(numericValuesRegex);
|
|
1777
|
+
if (!translateValue || !values) {
|
|
1778
|
+
return null;
|
|
1779
|
+
}
|
|
1780
|
+
const [numericX, numericY] = values.map(Number);
|
|
1781
|
+
if (!numericX || !numericY) {
|
|
1782
|
+
return null;
|
|
1783
|
+
}
|
|
1784
|
+
return styles.transform;
|
|
1785
|
+
};
|
|
1786
|
+
|
|
1787
|
+
// src/legacy/replacements/inline-editing/canvas-inline-editor.tsx
|
|
1788
|
+
var TOP_BAR_SELECTOR = "#elementor-editor-wrapper-v2";
|
|
1789
|
+
var NAVIGATOR_SELECTOR = "#elementor-navigator";
|
|
1790
|
+
var EDITING_PANEL = "#elementor-panel";
|
|
1791
|
+
var EDITOR_ELEMENTS_OUT_OF_IFRAME = [TOP_BAR_SELECTOR, NAVIGATOR_SELECTOR, EDITING_PANEL];
|
|
1792
|
+
var EDITOR_WRAPPER_SELECTOR = "inline-editor-wrapper";
|
|
1793
|
+
var CanvasInlineEditor = ({
|
|
1794
|
+
elementClasses,
|
|
1795
|
+
initialValue,
|
|
1796
|
+
expectedTag,
|
|
1797
|
+
rootElement,
|
|
1798
|
+
id,
|
|
1799
|
+
setValue,
|
|
1800
|
+
onBlur
|
|
1801
|
+
}) => {
|
|
1802
|
+
const [selectionOffsets, setSelectionOffsets] = useState4(null);
|
|
1803
|
+
const [editor, setEditor] = useState4(null);
|
|
1804
|
+
const onSelectionEnd = (view) => {
|
|
1805
|
+
const hasSelection = !view.state.selection.empty;
|
|
1806
|
+
setSelectionOffsets(hasSelection ? calcSelectionCenterOffsets(view) : null);
|
|
1807
|
+
};
|
|
1808
|
+
useOnClickOutsideIframe(onBlur);
|
|
1809
|
+
return /* @__PURE__ */ React5.createElement(ThemeProvider, null, /* @__PURE__ */ React5.createElement(InlineEditingOverlay, { expectedTag, rootElement, id }), /* @__PURE__ */ React5.createElement("style", null, `
|
|
1810
|
+
.${EDITOR_WRAPPER_SELECTOR}, .${EDITOR_WRAPPER_SELECTOR} > * {
|
|
1811
|
+
height: 100%;
|
|
1812
|
+
}
|
|
1813
|
+
.ProseMirror > * {
|
|
1814
|
+
height: 100%;
|
|
1815
|
+
}
|
|
1816
|
+
`), /* @__PURE__ */ React5.createElement(
|
|
1817
|
+
InlineEditor,
|
|
1818
|
+
{
|
|
1819
|
+
onEditorCreate: setEditor,
|
|
1820
|
+
editorProps: {
|
|
1821
|
+
attributes: {
|
|
1822
|
+
style: "outline: none;overflow-wrap: normal;height:100%"
|
|
1823
|
+
}
|
|
1824
|
+
},
|
|
1825
|
+
elementClasses,
|
|
1826
|
+
value: initialValue,
|
|
1827
|
+
setValue,
|
|
1828
|
+
onBlur,
|
|
1829
|
+
autofocus: true,
|
|
1830
|
+
expectedTag,
|
|
1831
|
+
wrapperClassName: EDITOR_WRAPPER_SELECTOR,
|
|
1832
|
+
onSelectionEnd
|
|
1833
|
+
}
|
|
1834
|
+
), selectionOffsets && editor && /* @__PURE__ */ React5.createElement(
|
|
1835
|
+
InlineEditingToolbarWrapper,
|
|
1836
|
+
{
|
|
1837
|
+
expectedTag,
|
|
1838
|
+
editor,
|
|
1839
|
+
rootElement,
|
|
1840
|
+
id,
|
|
1841
|
+
selectionOffsets
|
|
1842
|
+
}
|
|
1843
|
+
));
|
|
1844
|
+
};
|
|
1845
|
+
var InlineEditingOverlay = ({
|
|
1846
|
+
expectedTag,
|
|
1847
|
+
rootElement,
|
|
1848
|
+
id
|
|
1849
|
+
}) => {
|
|
1850
|
+
const inlineEditedElement = getInlineEditorElement(rootElement, expectedTag);
|
|
1851
|
+
const [overlayRefElement, setOverlayElement] = useState4(inlineEditedElement);
|
|
1852
|
+
useEffect7(() => {
|
|
1853
|
+
setOverlayElement(getInlineEditorElement(rootElement, expectedTag));
|
|
1854
|
+
}, [expectedTag, rootElement]);
|
|
1855
|
+
return overlayRefElement ? /* @__PURE__ */ React5.createElement(OutlineOverlay, { element: overlayRefElement, id, isSelected: true }) : null;
|
|
1856
|
+
};
|
|
1857
|
+
var InlineEditingToolbarWrapper = ({
|
|
1858
|
+
expectedTag,
|
|
1859
|
+
editor,
|
|
1860
|
+
rootElement,
|
|
1861
|
+
id,
|
|
1862
|
+
selectionOffsets
|
|
1863
|
+
}) => {
|
|
1864
|
+
const [element, setElement] = useState4(null);
|
|
1865
|
+
useEffect7(() => {
|
|
1866
|
+
setElement(getInlineEditorElement(rootElement, expectedTag));
|
|
1867
|
+
}, [expectedTag, rootElement]);
|
|
1868
|
+
return element ? /* @__PURE__ */ React5.createElement(InlineEditingToolbar, { element, editor, id, selectionOffsets }) : null;
|
|
1869
|
+
};
|
|
1870
|
+
var InlineEditingToolbar = ({
|
|
1871
|
+
element,
|
|
1872
|
+
editor,
|
|
1873
|
+
id,
|
|
1874
|
+
selectionOffsets
|
|
1875
|
+
}) => {
|
|
1876
|
+
const { floating } = useFloatingOnElement({
|
|
1877
|
+
element,
|
|
1878
|
+
isSelected: true
|
|
1879
|
+
});
|
|
1880
|
+
const { getFloatingProps, getReferenceProps } = useInteractions2();
|
|
1881
|
+
const style = getComputedStyle(floating.styles, selectionOffsets);
|
|
1882
|
+
useBindReactPropsToElement(element, getReferenceProps);
|
|
1883
|
+
return /* @__PURE__ */ React5.createElement(FloatingPortal2, { id: CANVAS_WRAPPER_ID }, /* @__PURE__ */ React5.createElement(
|
|
1884
|
+
Box2,
|
|
1885
|
+
{
|
|
1886
|
+
ref: floating.setRef,
|
|
1887
|
+
style: {
|
|
1888
|
+
...floating.styles,
|
|
1889
|
+
pointerEvents: "none"
|
|
1890
|
+
},
|
|
1891
|
+
role: "presentation",
|
|
1892
|
+
...getFloatingProps({ style })
|
|
1893
|
+
},
|
|
1894
|
+
floating.styles.transform && /* @__PURE__ */ React5.createElement(
|
|
1895
|
+
Box2,
|
|
1896
|
+
{
|
|
1897
|
+
sx: {
|
|
1898
|
+
position: "relative",
|
|
1899
|
+
transform: "translateY(-100%)",
|
|
1900
|
+
height: "max-content"
|
|
1901
|
+
}
|
|
1902
|
+
},
|
|
1903
|
+
/* @__PURE__ */ React5.createElement(
|
|
1904
|
+
InlineEditorToolbar,
|
|
1905
|
+
{
|
|
1906
|
+
editor,
|
|
1907
|
+
elementId: id,
|
|
1908
|
+
sx: {
|
|
1909
|
+
transform: "translateX(-50%)"
|
|
1910
|
+
}
|
|
1911
|
+
}
|
|
1912
|
+
)
|
|
1913
|
+
)
|
|
1914
|
+
));
|
|
1915
|
+
};
|
|
1916
|
+
var getInlineEditorElement = (elementWrapper, expectedTag) => {
|
|
1917
|
+
return !expectedTag ? null : elementWrapper.querySelector(expectedTag);
|
|
1918
|
+
};
|
|
1919
|
+
var useOnClickOutsideIframe = (handleUnmount) => {
|
|
1920
|
+
const asyncUnmountInlineEditor = React5.useCallback(() => queueMicrotask(handleUnmount), [handleUnmount]);
|
|
1921
|
+
useEffect7(() => {
|
|
1922
|
+
EDITOR_ELEMENTS_OUT_OF_IFRAME.forEach(
|
|
1923
|
+
(selector) => document?.querySelector(selector)?.addEventListener("mousedown", asyncUnmountInlineEditor)
|
|
1924
|
+
);
|
|
1925
|
+
return () => EDITOR_ELEMENTS_OUT_OF_IFRAME.forEach(
|
|
1926
|
+
(selector) => document?.querySelector(selector)?.removeEventListener("mousedown", asyncUnmountInlineEditor)
|
|
1927
|
+
);
|
|
1928
|
+
}, []);
|
|
1929
|
+
};
|
|
1930
|
+
|
|
1733
1931
|
// src/legacy/replacements/inline-editing/inline-editing-eligibility.ts
|
|
1734
1932
|
import { htmlPropTypeUtil, stringPropTypeUtil } from "@elementor/editor-props";
|
|
1735
1933
|
var hasKey = (propType) => {
|
|
@@ -1759,32 +1957,8 @@ var isInlineEditingAllowed = ({ rawValue, propTypeFromSchema }) => {
|
|
|
1759
1957
|
return htmlPropTypeUtil.isValid(rawValue) || stringPropTypeUtil.isValid(rawValue);
|
|
1760
1958
|
};
|
|
1761
1959
|
|
|
1762
|
-
// src/legacy/replacements/inline-editing/inline-editing-utils.ts
|
|
1763
|
-
var INLINE_EDITING_PROPERTY_PER_TYPE = {
|
|
1764
|
-
"e-form-label": "text",
|
|
1765
|
-
"e-heading": "title",
|
|
1766
|
-
"e-paragraph": "paragraph"
|
|
1767
|
-
};
|
|
1768
|
-
var legacyWindow = window;
|
|
1769
|
-
var getInitialPopoverPosition = () => {
|
|
1770
|
-
const positionFallback = { left: 0, top: 0 };
|
|
1771
|
-
const iFrameElement = legacyWindow?.elementor?.$preview?.get(0);
|
|
1772
|
-
const iFramePosition = iFrameElement?.getBoundingClientRect() ?? positionFallback;
|
|
1773
|
-
const previewElement = legacyWindow?.elementor?.$previewWrapper?.get(0);
|
|
1774
|
-
const previewPosition = previewElement ? { left: previewElement.scrollLeft, top: previewElement.scrollTop } : positionFallback;
|
|
1775
|
-
return {
|
|
1776
|
-
left: iFramePosition.left + previewPosition.left,
|
|
1777
|
-
top: iFramePosition.top + previewPosition.top
|
|
1778
|
-
};
|
|
1779
|
-
};
|
|
1780
|
-
|
|
1781
1960
|
// src/legacy/replacements/inline-editing/inline-editing-elements.tsx
|
|
1782
1961
|
var HISTORY_DEBOUNCE_WAIT = 800;
|
|
1783
|
-
var TOP_BAR_SELECTOR = "#elementor-editor-wrapper-v2";
|
|
1784
|
-
var NAVIGATOR_SELECTOR = "#elementor-navigator";
|
|
1785
|
-
var V4_EDITING_PANEL = "main.MuiBox-root";
|
|
1786
|
-
var V3_EDITING_PANEL = "#elementor-panel-content-wrapper";
|
|
1787
|
-
var BLUR_TRIGGERING_SELECTORS = [TOP_BAR_SELECTOR, NAVIGATOR_SELECTOR, V4_EDITING_PANEL, V3_EDITING_PANEL];
|
|
1788
1962
|
var InlineEditingReplacement = class extends ReplacementBase {
|
|
1789
1963
|
inlineEditorRoot = null;
|
|
1790
1964
|
handlerAttached = false;
|
|
@@ -1798,7 +1972,7 @@ var InlineEditingReplacement = class extends ReplacementBase {
|
|
|
1798
1972
|
return !!this.inlineEditorRoot;
|
|
1799
1973
|
}
|
|
1800
1974
|
shouldRenderReplacement() {
|
|
1801
|
-
return this.isInlineEditingEligible();
|
|
1975
|
+
return this.isInlineEditingEligible() && getCurrentEditMode() === "edit";
|
|
1802
1976
|
}
|
|
1803
1977
|
handleRenderInlineEditor = () => {
|
|
1804
1978
|
if (this.isEditingModeActive() || !this.isInlineEditingEligible()) {
|
|
@@ -1944,65 +2118,26 @@ var InlineEditingReplacement = class extends ReplacementBase {
|
|
|
1944
2118
|
if (this.isEditingModeActive()) {
|
|
1945
2119
|
this.resetInlineEditorRoot();
|
|
1946
2120
|
}
|
|
1947
|
-
const InlineEditorApp = this.InlineEditorApp;
|
|
1948
|
-
const wrapperClasses = "elementor";
|
|
1949
2121
|
const elementClasses = this.element.children?.[0]?.classList.toString() ?? "";
|
|
2122
|
+
const propValue = this.getExtractedContentValue();
|
|
2123
|
+
const expectedTag = this.getExpectedTag();
|
|
1950
2124
|
this.element.innerHTML = "";
|
|
1951
2125
|
this.inlineEditorRoot = createRoot(this.element);
|
|
1952
2126
|
this.inlineEditorRoot.render(
|
|
1953
|
-
/* @__PURE__ */
|
|
1954
|
-
|
|
1955
|
-
}
|
|
1956
|
-
InlineEditorApp = ({ wrapperClasses, elementClasses }) => {
|
|
1957
|
-
const propValue = this.getExtractedContentValue();
|
|
1958
|
-
const expectedTag = this.getExpectedTag();
|
|
1959
|
-
const wrapperRef = useRef2(null);
|
|
1960
|
-
const [isWrapperRendered, setIsWrapperRendered] = useState4(false);
|
|
1961
|
-
useEffect7(() => {
|
|
1962
|
-
setIsWrapperRendered(!!wrapperRef.current);
|
|
1963
|
-
BLUR_TRIGGERING_SELECTORS.forEach(
|
|
1964
|
-
(selector) => document?.querySelector(selector)?.addEventListener("mousedown", asyncUnmountInlineEditor)
|
|
1965
|
-
);
|
|
1966
|
-
return () => BLUR_TRIGGERING_SELECTORS.forEach(
|
|
1967
|
-
(selector) => document?.querySelector(selector)?.removeEventListener("mousedown", asyncUnmountInlineEditor)
|
|
1968
|
-
);
|
|
1969
|
-
}, []);
|
|
1970
|
-
const asyncUnmountInlineEditor = React5.useCallback(
|
|
1971
|
-
() => queueMicrotask(this.unmountInlineEditor.bind(this)),
|
|
1972
|
-
[]
|
|
1973
|
-
);
|
|
1974
|
-
return /* @__PURE__ */ React5.createElement(ThemeProvider, null, /* @__PURE__ */ React5.createElement(
|
|
1975
|
-
Box2,
|
|
1976
|
-
{
|
|
1977
|
-
ref: wrapperRef,
|
|
1978
|
-
sx: {
|
|
1979
|
-
"& .elementor-inline-editor-reset": {
|
|
1980
|
-
margin: 0,
|
|
1981
|
-
padding: 0
|
|
1982
|
-
}
|
|
1983
|
-
}
|
|
1984
|
-
},
|
|
1985
|
-
isWrapperRendered && /* @__PURE__ */ React5.createElement(OutlineOverlay, { element: wrapperRef.current, id: this.id, isSelected: true }),
|
|
1986
|
-
/* @__PURE__ */ React5.createElement(
|
|
1987
|
-
InlineEditor,
|
|
2127
|
+
/* @__PURE__ */ React6.createElement(
|
|
2128
|
+
CanvasInlineEditor,
|
|
1988
2129
|
{
|
|
1989
|
-
attributes: {
|
|
1990
|
-
class: wrapperClasses,
|
|
1991
|
-
style: "outline: none;"
|
|
1992
|
-
},
|
|
1993
2130
|
elementClasses,
|
|
1994
|
-
|
|
1995
|
-
setValue: this.setContentValue.bind(this),
|
|
1996
|
-
onBlur: this.unmountInlineEditor.bind(this),
|
|
1997
|
-
autofocus: true,
|
|
1998
|
-
showToolbar: true,
|
|
1999
|
-
getInitialPopoverPosition,
|
|
2131
|
+
initialValue: propValue,
|
|
2000
2132
|
expectedTag,
|
|
2001
|
-
|
|
2133
|
+
rootElement: this.element,
|
|
2134
|
+
id: this.id,
|
|
2135
|
+
setValue: this.setContentValue.bind(this),
|
|
2136
|
+
onBlur: this.unmountInlineEditor.bind(this)
|
|
2002
2137
|
}
|
|
2003
2138
|
)
|
|
2004
|
-
)
|
|
2005
|
-
}
|
|
2139
|
+
);
|
|
2140
|
+
}
|
|
2006
2141
|
};
|
|
2007
2142
|
|
|
2008
2143
|
// src/legacy/replacements/manager.ts
|
|
@@ -2087,13 +2222,13 @@ var createTemplatedElementTypeWithReplacements = ({
|
|
|
2087
2222
|
renderer,
|
|
2088
2223
|
element
|
|
2089
2224
|
}) => {
|
|
2090
|
-
const
|
|
2225
|
+
const legacyWindow = window;
|
|
2091
2226
|
const view = createViewWithReplacements({
|
|
2092
2227
|
type,
|
|
2093
2228
|
renderer,
|
|
2094
2229
|
element
|
|
2095
2230
|
});
|
|
2096
|
-
return class extends
|
|
2231
|
+
return class extends legacyWindow.elementor.modules.elements.types.Widget {
|
|
2097
2232
|
getType() {
|
|
2098
2233
|
return type;
|
|
2099
2234
|
}
|
|
@@ -2111,7 +2246,7 @@ function registerElementType(type, elementTypeGenerator) {
|
|
|
2111
2246
|
function initLegacyViews() {
|
|
2112
2247
|
__privateListenTo(v1ReadyEvent2(), () => {
|
|
2113
2248
|
const config = getWidgetsCache2() ?? {};
|
|
2114
|
-
const
|
|
2249
|
+
const legacyWindow = window;
|
|
2115
2250
|
const renderer = createDomRenderer();
|
|
2116
2251
|
Object.entries(config).forEach(([type, element]) => {
|
|
2117
2252
|
if (!element.atomic) {
|
|
@@ -2125,7 +2260,7 @@ function initLegacyViews() {
|
|
|
2125
2260
|
} else {
|
|
2126
2261
|
ElementType = createElementType(type);
|
|
2127
2262
|
}
|
|
2128
|
-
|
|
2263
|
+
legacyWindow.elementor.elementsManager.registerElementType(new ElementType());
|
|
2129
2264
|
});
|
|
2130
2265
|
});
|
|
2131
2266
|
}
|
|
@@ -2207,7 +2342,7 @@ function extractElementData(element) {
|
|
|
2207
2342
|
|
|
2208
2343
|
// src/mcp/tools/build-composition/tool.ts
|
|
2209
2344
|
import {
|
|
2210
|
-
createElement as
|
|
2345
|
+
createElement as createElement8,
|
|
2211
2346
|
deleteElement,
|
|
2212
2347
|
getContainer as getContainer3,
|
|
2213
2348
|
getWidgetsCache as getWidgetsCache6
|
|
@@ -2215,7 +2350,7 @@ import {
|
|
|
2215
2350
|
|
|
2216
2351
|
// src/composition-builder/composition-builder.ts
|
|
2217
2352
|
import {
|
|
2218
|
-
createElement as
|
|
2353
|
+
createElement as createElement7,
|
|
2219
2354
|
generateElementId,
|
|
2220
2355
|
getContainer as getContainer2,
|
|
2221
2356
|
getWidgetsCache as getWidgetsCache5
|
|
@@ -2433,7 +2568,7 @@ var CompositionBuilder = class _CompositionBuilder {
|
|
|
2433
2568
|
rootContainers = [];
|
|
2434
2569
|
containerElements = [];
|
|
2435
2570
|
api = {
|
|
2436
|
-
createElement:
|
|
2571
|
+
createElement: createElement7,
|
|
2437
2572
|
getWidgetsCache: getWidgetsCache5,
|
|
2438
2573
|
generateElementId,
|
|
2439
2574
|
getContainer: getContainer2,
|
|
@@ -2822,7 +2957,7 @@ var initBuildCompositionsTool = (reg) => {
|
|
|
2822
2957
|
const documentContainer = getContainer3("document");
|
|
2823
2958
|
try {
|
|
2824
2959
|
const compositionBuilder = CompositionBuilder.fromXMLString(xmlStructure, {
|
|
2825
|
-
createElement:
|
|
2960
|
+
createElement: createElement8,
|
|
2826
2961
|
getWidgetsCache: getWidgetsCache6
|
|
2827
2962
|
});
|
|
2828
2963
|
compositionBuilder.setElementConfig(elementConfig);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elementor/editor-canvas",
|
|
3
3
|
"description": "Elementor Editor Canvas",
|
|
4
|
-
"version": "4.0.0-
|
|
4
|
+
"version": "4.0.0-513",
|
|
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": "4.0.0-
|
|
41
|
-
"@elementor/editor-controls": "4.0.0-
|
|
42
|
-
"@elementor/editor-documents": "4.0.0-
|
|
43
|
-
"@elementor/editor-elements": "4.0.0-
|
|
44
|
-
"@elementor/editor-interactions": "4.0.0-
|
|
45
|
-
"@elementor/editor-mcp": "4.0.0-
|
|
46
|
-
"@elementor/editor-notifications": "4.0.0-
|
|
47
|
-
"@elementor/editor-props": "4.0.0-
|
|
48
|
-
"@elementor/editor-responsive": "4.0.0-
|
|
49
|
-
"@elementor/editor-styles": "4.0.0-
|
|
50
|
-
"@elementor/editor-styles-repository": "4.0.0-
|
|
51
|
-
"@elementor/editor-ui": "4.0.0-
|
|
52
|
-
"@elementor/editor-v1-adapters": "4.0.0-
|
|
53
|
-
"@elementor/schema": "4.0.0-
|
|
54
|
-
"@elementor/twing": "4.0.0-
|
|
40
|
+
"@elementor/editor": "4.0.0-513",
|
|
41
|
+
"@elementor/editor-controls": "4.0.0-513",
|
|
42
|
+
"@elementor/editor-documents": "4.0.0-513",
|
|
43
|
+
"@elementor/editor-elements": "4.0.0-513",
|
|
44
|
+
"@elementor/editor-interactions": "4.0.0-513",
|
|
45
|
+
"@elementor/editor-mcp": "4.0.0-513",
|
|
46
|
+
"@elementor/editor-notifications": "4.0.0-513",
|
|
47
|
+
"@elementor/editor-props": "4.0.0-513",
|
|
48
|
+
"@elementor/editor-responsive": "4.0.0-513",
|
|
49
|
+
"@elementor/editor-styles": "4.0.0-513",
|
|
50
|
+
"@elementor/editor-styles-repository": "4.0.0-513",
|
|
51
|
+
"@elementor/editor-ui": "4.0.0-513",
|
|
52
|
+
"@elementor/editor-v1-adapters": "4.0.0-513",
|
|
53
|
+
"@elementor/schema": "4.0.0-513",
|
|
54
|
+
"@elementor/twing": "4.0.0-513",
|
|
55
55
|
"@elementor/ui": "1.36.17",
|
|
56
|
-
"@elementor/utils": "4.0.0-
|
|
57
|
-
"@elementor/wp-media": "4.0.0-
|
|
56
|
+
"@elementor/utils": "4.0.0-513",
|
|
57
|
+
"@elementor/wp-media": "4.0.0-513",
|
|
58
58
|
"@floating-ui/react": "^0.27.5",
|
|
59
59
|
"@wordpress/i18n": "^5.13.0"
|
|
60
60
|
},
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { useEffect, useState } from 'react';
|
|
3
|
+
import { InlineEditor, InlineEditorToolbar } from '@elementor/editor-controls';
|
|
4
|
+
import { Box, ThemeProvider } from '@elementor/ui';
|
|
5
|
+
import { FloatingPortal, useInteractions } from '@floating-ui/react';
|
|
6
|
+
|
|
7
|
+
import { CANVAS_WRAPPER_ID, OutlineOverlay } from '../../../components/outline-overlay';
|
|
8
|
+
import { useBindReactPropsToElement } from '../../../hooks/use-bind-react-props-to-element';
|
|
9
|
+
import { useFloatingOnElement } from '../../../hooks/use-floating-on-element';
|
|
10
|
+
import {
|
|
11
|
+
calcSelectionCenterOffsets,
|
|
12
|
+
type Editor,
|
|
13
|
+
type EditorView,
|
|
14
|
+
getComputedStyle,
|
|
15
|
+
type Offsets,
|
|
16
|
+
} from './inline-editing-utils';
|
|
17
|
+
|
|
18
|
+
const TOP_BAR_SELECTOR = '#elementor-editor-wrapper-v2';
|
|
19
|
+
const NAVIGATOR_SELECTOR = '#elementor-navigator';
|
|
20
|
+
const EDITING_PANEL = '#elementor-panel';
|
|
21
|
+
|
|
22
|
+
const EDITOR_ELEMENTS_OUT_OF_IFRAME = [ TOP_BAR_SELECTOR, NAVIGATOR_SELECTOR, EDITING_PANEL ];
|
|
23
|
+
|
|
24
|
+
const EDITOR_WRAPPER_SELECTOR = 'inline-editor-wrapper';
|
|
25
|
+
|
|
26
|
+
export const CanvasInlineEditor = ( {
|
|
27
|
+
elementClasses,
|
|
28
|
+
initialValue,
|
|
29
|
+
expectedTag,
|
|
30
|
+
rootElement,
|
|
31
|
+
id,
|
|
32
|
+
setValue,
|
|
33
|
+
onBlur,
|
|
34
|
+
}: {
|
|
35
|
+
elementClasses: string;
|
|
36
|
+
initialValue: string | null;
|
|
37
|
+
expectedTag: string | null;
|
|
38
|
+
rootElement: HTMLElement;
|
|
39
|
+
id: string;
|
|
40
|
+
setValue: ( value: string | null ) => void;
|
|
41
|
+
onBlur: () => void;
|
|
42
|
+
} ) => {
|
|
43
|
+
const [ selectionOffsets, setSelectionOffsets ] = useState< Offsets | null >( null );
|
|
44
|
+
const [ editor, setEditor ] = useState< Editor | null >( null );
|
|
45
|
+
|
|
46
|
+
const onSelectionEnd = ( view: EditorView ) => {
|
|
47
|
+
const hasSelection = ! view.state.selection.empty;
|
|
48
|
+
|
|
49
|
+
setSelectionOffsets( hasSelection ? calcSelectionCenterOffsets( view ) : null );
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
useOnClickOutsideIframe( onBlur );
|
|
53
|
+
|
|
54
|
+
return (
|
|
55
|
+
<ThemeProvider>
|
|
56
|
+
<InlineEditingOverlay expectedTag={ expectedTag } rootElement={ rootElement } id={ id } />
|
|
57
|
+
<style>
|
|
58
|
+
{ `
|
|
59
|
+
.${ EDITOR_WRAPPER_SELECTOR }, .${ EDITOR_WRAPPER_SELECTOR } > * {
|
|
60
|
+
height: 100%;
|
|
61
|
+
}
|
|
62
|
+
.ProseMirror > * {
|
|
63
|
+
height: 100%;
|
|
64
|
+
}
|
|
65
|
+
` }
|
|
66
|
+
</style>
|
|
67
|
+
<InlineEditor
|
|
68
|
+
onEditorCreate={ setEditor }
|
|
69
|
+
editorProps={ {
|
|
70
|
+
attributes: {
|
|
71
|
+
style: 'outline: none;overflow-wrap: normal;height:100%',
|
|
72
|
+
},
|
|
73
|
+
} }
|
|
74
|
+
elementClasses={ elementClasses }
|
|
75
|
+
value={ initialValue }
|
|
76
|
+
setValue={ setValue }
|
|
77
|
+
onBlur={ onBlur }
|
|
78
|
+
autofocus
|
|
79
|
+
expectedTag={ expectedTag }
|
|
80
|
+
wrapperClassName={ EDITOR_WRAPPER_SELECTOR }
|
|
81
|
+
onSelectionEnd={ onSelectionEnd }
|
|
82
|
+
/>
|
|
83
|
+
{ selectionOffsets && editor && (
|
|
84
|
+
<InlineEditingToolbarWrapper
|
|
85
|
+
expectedTag={ expectedTag }
|
|
86
|
+
editor={ editor }
|
|
87
|
+
rootElement={ rootElement }
|
|
88
|
+
id={ id }
|
|
89
|
+
selectionOffsets={ selectionOffsets }
|
|
90
|
+
/>
|
|
91
|
+
) }
|
|
92
|
+
</ThemeProvider>
|
|
93
|
+
);
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
const InlineEditingOverlay = ( {
|
|
97
|
+
expectedTag,
|
|
98
|
+
rootElement,
|
|
99
|
+
id,
|
|
100
|
+
}: {
|
|
101
|
+
expectedTag: string | null;
|
|
102
|
+
rootElement: HTMLElement;
|
|
103
|
+
id: string;
|
|
104
|
+
} ) => {
|
|
105
|
+
const inlineEditedElement = getInlineEditorElement( rootElement, expectedTag );
|
|
106
|
+
const [ overlayRefElement, setOverlayElement ] = useState< HTMLDivElement | null >( inlineEditedElement );
|
|
107
|
+
|
|
108
|
+
useEffect( () => {
|
|
109
|
+
setOverlayElement( getInlineEditorElement( rootElement, expectedTag ) );
|
|
110
|
+
}, [ expectedTag, rootElement ] );
|
|
111
|
+
|
|
112
|
+
return overlayRefElement ? <OutlineOverlay element={ overlayRefElement } id={ id } isSelected /> : null;
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
const InlineEditingToolbarWrapper = ( {
|
|
116
|
+
expectedTag,
|
|
117
|
+
editor,
|
|
118
|
+
rootElement,
|
|
119
|
+
id,
|
|
120
|
+
selectionOffsets,
|
|
121
|
+
}: {
|
|
122
|
+
expectedTag: string | null;
|
|
123
|
+
editor: Editor;
|
|
124
|
+
rootElement: HTMLElement;
|
|
125
|
+
id: string;
|
|
126
|
+
selectionOffsets: Offsets;
|
|
127
|
+
} ) => {
|
|
128
|
+
const [ element, setElement ] = useState< HTMLElement | null >( null );
|
|
129
|
+
|
|
130
|
+
useEffect( () => {
|
|
131
|
+
setElement( getInlineEditorElement( rootElement, expectedTag ) );
|
|
132
|
+
}, [ expectedTag, rootElement ] );
|
|
133
|
+
|
|
134
|
+
return element ? (
|
|
135
|
+
<InlineEditingToolbar element={ element } editor={ editor } id={ id } selectionOffsets={ selectionOffsets } />
|
|
136
|
+
) : null;
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
const InlineEditingToolbar = ( {
|
|
140
|
+
element,
|
|
141
|
+
editor,
|
|
142
|
+
id,
|
|
143
|
+
selectionOffsets,
|
|
144
|
+
}: {
|
|
145
|
+
element: HTMLElement;
|
|
146
|
+
editor: Editor;
|
|
147
|
+
id: string;
|
|
148
|
+
selectionOffsets: Offsets;
|
|
149
|
+
} ) => {
|
|
150
|
+
const { floating } = useFloatingOnElement( {
|
|
151
|
+
element,
|
|
152
|
+
isSelected: true,
|
|
153
|
+
} );
|
|
154
|
+
const { getFloatingProps, getReferenceProps } = useInteractions();
|
|
155
|
+
const style = getComputedStyle( floating.styles, selectionOffsets );
|
|
156
|
+
|
|
157
|
+
useBindReactPropsToElement( element, getReferenceProps );
|
|
158
|
+
|
|
159
|
+
return (
|
|
160
|
+
<FloatingPortal id={ CANVAS_WRAPPER_ID }>
|
|
161
|
+
<Box
|
|
162
|
+
ref={ floating.setRef }
|
|
163
|
+
style={ {
|
|
164
|
+
...floating.styles,
|
|
165
|
+
pointerEvents: 'none',
|
|
166
|
+
} }
|
|
167
|
+
role="presentation"
|
|
168
|
+
{ ...getFloatingProps( { style } ) }
|
|
169
|
+
>
|
|
170
|
+
{ floating.styles.transform && (
|
|
171
|
+
<Box
|
|
172
|
+
sx={ {
|
|
173
|
+
position: 'relative',
|
|
174
|
+
transform: 'translateY(-100%)',
|
|
175
|
+
height: 'max-content',
|
|
176
|
+
} }
|
|
177
|
+
>
|
|
178
|
+
<InlineEditorToolbar
|
|
179
|
+
editor={ editor }
|
|
180
|
+
elementId={ id }
|
|
181
|
+
sx={ {
|
|
182
|
+
transform: 'translateX(-50%)',
|
|
183
|
+
} }
|
|
184
|
+
/>
|
|
185
|
+
</Box>
|
|
186
|
+
) }
|
|
187
|
+
</Box>
|
|
188
|
+
</FloatingPortal>
|
|
189
|
+
);
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
const getInlineEditorElement = ( elementWrapper: HTMLElement, expectedTag: string | null ) => {
|
|
193
|
+
return ! expectedTag ? null : ( elementWrapper.querySelector( expectedTag ) as HTMLDivElement );
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
// Elements out of iframe and canvas don't trigger "onClickAway" which unmounts the editor
|
|
197
|
+
// since they are not part of the iframes owner document.
|
|
198
|
+
// We need to manually add listeners to these elements to unmount the editor when they are clicked.
|
|
199
|
+
const useOnClickOutsideIframe = ( handleUnmount: () => void ) => {
|
|
200
|
+
const asyncUnmountInlineEditor = React.useCallback( () => queueMicrotask( handleUnmount ), [ handleUnmount ] );
|
|
201
|
+
|
|
202
|
+
useEffect( () => {
|
|
203
|
+
EDITOR_ELEMENTS_OUT_OF_IFRAME.forEach(
|
|
204
|
+
( selector ) =>
|
|
205
|
+
document?.querySelector( selector )?.addEventListener( 'mousedown', asyncUnmountInlineEditor )
|
|
206
|
+
);
|
|
207
|
+
|
|
208
|
+
return () =>
|
|
209
|
+
EDITOR_ELEMENTS_OUT_OF_IFRAME.forEach(
|
|
210
|
+
( selector ) =>
|
|
211
|
+
document?.querySelector( selector )?.removeEventListener( 'mousedown', asyncUnmountInlineEditor )
|
|
212
|
+
);
|
|
213
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
214
|
+
}, [] );
|
|
215
|
+
};
|
|
@@ -1,17 +1,14 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { useEffect, useRef, useState } from 'react';
|
|
3
2
|
import { createRoot, type Root } from 'react-dom/client';
|
|
4
|
-
import { InlineEditor } from '@elementor/editor-controls';
|
|
5
3
|
import { getContainer, getElementLabel, getElementType } from '@elementor/editor-elements';
|
|
6
4
|
import { htmlPropTypeUtil, type PropType, type PropValue, stringPropTypeUtil } from '@elementor/editor-props';
|
|
7
|
-
import { __privateRunCommandSync as runCommandSync, undoable } from '@elementor/editor-v1-adapters';
|
|
8
|
-
import { Box, ThemeProvider } from '@elementor/ui';
|
|
5
|
+
import { __privateRunCommandSync as runCommandSync, getCurrentEditMode, undoable } from '@elementor/editor-v1-adapters';
|
|
9
6
|
import { __ } from '@wordpress/i18n';
|
|
10
7
|
|
|
11
|
-
import { OutlineOverlay } from '../../../components/outline-overlay';
|
|
12
8
|
import { ReplacementBase, TRIGGER_TIMING } from '../base';
|
|
9
|
+
import { CanvasInlineEditor } from './canvas-inline-editor';
|
|
13
10
|
import { isInlineEditingAllowed } from './inline-editing-eligibility';
|
|
14
|
-
import {
|
|
11
|
+
import { INLINE_EDITING_PROPERTY_PER_TYPE } from './inline-editing-utils';
|
|
15
12
|
|
|
16
13
|
type TagPropType = PropType< 'tag' > & {
|
|
17
14
|
settings?: {
|
|
@@ -21,13 +18,6 @@ type TagPropType = PropType< 'tag' > & {
|
|
|
21
18
|
|
|
22
19
|
const HISTORY_DEBOUNCE_WAIT = 800;
|
|
23
20
|
|
|
24
|
-
const TOP_BAR_SELECTOR = '#elementor-editor-wrapper-v2';
|
|
25
|
-
const NAVIGATOR_SELECTOR = '#elementor-navigator';
|
|
26
|
-
const V4_EDITING_PANEL = 'main.MuiBox-root';
|
|
27
|
-
const V3_EDITING_PANEL = '#elementor-panel-content-wrapper';
|
|
28
|
-
|
|
29
|
-
const BLUR_TRIGGERING_SELECTORS = [ TOP_BAR_SELECTOR, NAVIGATOR_SELECTOR, V4_EDITING_PANEL, V3_EDITING_PANEL ];
|
|
30
|
-
|
|
31
21
|
export default class InlineEditingReplacement extends ReplacementBase {
|
|
32
22
|
private inlineEditorRoot: Root | null = null;
|
|
33
23
|
private handlerAttached = false;
|
|
@@ -45,7 +35,7 @@ export default class InlineEditingReplacement extends ReplacementBase {
|
|
|
45
35
|
}
|
|
46
36
|
|
|
47
37
|
shouldRenderReplacement() {
|
|
48
|
-
return this.isInlineEditingEligible();
|
|
38
|
+
return this.isInlineEditingEligible() && getCurrentEditMode() === 'edit';
|
|
49
39
|
}
|
|
50
40
|
|
|
51
41
|
handleRenderInlineEditor = () => {
|
|
@@ -236,77 +226,23 @@ export default class InlineEditingReplacement extends ReplacementBase {
|
|
|
236
226
|
this.resetInlineEditorRoot();
|
|
237
227
|
}
|
|
238
228
|
|
|
239
|
-
const InlineEditorApp = this.InlineEditorApp;
|
|
240
|
-
const wrapperClasses = 'elementor';
|
|
241
229
|
const elementClasses = this.element.children?.[ 0 ]?.classList.toString() ?? '';
|
|
230
|
+
const propValue = this.getExtractedContentValue();
|
|
231
|
+
const expectedTag = this.getExpectedTag();
|
|
242
232
|
|
|
243
233
|
this.element.innerHTML = '';
|
|
244
234
|
|
|
245
235
|
this.inlineEditorRoot = createRoot( this.element );
|
|
246
236
|
this.inlineEditorRoot.render(
|
|
247
|
-
<
|
|
237
|
+
<CanvasInlineEditor
|
|
238
|
+
elementClasses={ elementClasses }
|
|
239
|
+
initialValue={ propValue }
|
|
240
|
+
expectedTag={ expectedTag }
|
|
241
|
+
rootElement={ this.element }
|
|
242
|
+
id={ this.id }
|
|
243
|
+
setValue={ this.setContentValue.bind( this ) }
|
|
244
|
+
onBlur={ this.unmountInlineEditor.bind( this ) }
|
|
245
|
+
/>
|
|
248
246
|
);
|
|
249
247
|
}
|
|
250
|
-
|
|
251
|
-
InlineEditorApp = ( { wrapperClasses, elementClasses }: { wrapperClasses: string; elementClasses: string } ) => {
|
|
252
|
-
const propValue = this.getExtractedContentValue();
|
|
253
|
-
const expectedTag = this.getExpectedTag();
|
|
254
|
-
const wrapperRef = useRef< HTMLDivElement | null >( null );
|
|
255
|
-
const [ isWrapperRendered, setIsWrapperRendered ] = useState( false );
|
|
256
|
-
|
|
257
|
-
useEffect( () => {
|
|
258
|
-
setIsWrapperRendered( !! wrapperRef.current );
|
|
259
|
-
BLUR_TRIGGERING_SELECTORS.forEach(
|
|
260
|
-
( selector ) =>
|
|
261
|
-
document?.querySelector( selector )?.addEventListener( 'mousedown', asyncUnmountInlineEditor )
|
|
262
|
-
);
|
|
263
|
-
|
|
264
|
-
return () =>
|
|
265
|
-
BLUR_TRIGGERING_SELECTORS.forEach(
|
|
266
|
-
( selector ) =>
|
|
267
|
-
document
|
|
268
|
-
?.querySelector( selector )
|
|
269
|
-
?.removeEventListener( 'mousedown', asyncUnmountInlineEditor )
|
|
270
|
-
);
|
|
271
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
272
|
-
}, [] );
|
|
273
|
-
|
|
274
|
-
const asyncUnmountInlineEditor = React.useCallback(
|
|
275
|
-
() => queueMicrotask( this.unmountInlineEditor.bind( this ) ),
|
|
276
|
-
[]
|
|
277
|
-
);
|
|
278
|
-
|
|
279
|
-
return (
|
|
280
|
-
<ThemeProvider>
|
|
281
|
-
<Box
|
|
282
|
-
ref={ wrapperRef }
|
|
283
|
-
sx={ {
|
|
284
|
-
'& .elementor-inline-editor-reset': {
|
|
285
|
-
margin: 0,
|
|
286
|
-
padding: 0,
|
|
287
|
-
},
|
|
288
|
-
} }
|
|
289
|
-
>
|
|
290
|
-
{ isWrapperRendered && (
|
|
291
|
-
<OutlineOverlay element={ wrapperRef.current as HTMLDivElement } id={ this.id } isSelected />
|
|
292
|
-
) }
|
|
293
|
-
<InlineEditor
|
|
294
|
-
attributes={ {
|
|
295
|
-
class: wrapperClasses,
|
|
296
|
-
style: 'outline: none;',
|
|
297
|
-
} }
|
|
298
|
-
elementClasses={ elementClasses }
|
|
299
|
-
value={ propValue }
|
|
300
|
-
setValue={ this.setContentValue.bind( this ) }
|
|
301
|
-
onBlur={ this.unmountInlineEditor.bind( this ) }
|
|
302
|
-
autofocus
|
|
303
|
-
showToolbar
|
|
304
|
-
getInitialPopoverPosition={ getInitialPopoverPosition }
|
|
305
|
-
expectedTag={ expectedTag }
|
|
306
|
-
elementId={ this.id }
|
|
307
|
-
/>
|
|
308
|
-
</Box>
|
|
309
|
-
</ThemeProvider>
|
|
310
|
-
);
|
|
311
|
-
};
|
|
312
248
|
}
|
|
@@ -1,7 +1,17 @@
|
|
|
1
|
+
import { type CSSProperties } from 'react';
|
|
2
|
+
import { type InlineEditorToolbarProps } from '@elementor/editor-controls';
|
|
1
3
|
import { type V1Element } from '@elementor/editor-elements';
|
|
2
4
|
|
|
3
5
|
import { type LegacyWindow } from '../../types';
|
|
4
6
|
|
|
7
|
+
export type Editor = InlineEditorToolbarProps[ 'editor' ];
|
|
8
|
+
export type EditorView = Editor[ 'view' ];
|
|
9
|
+
|
|
10
|
+
export type Offsets = {
|
|
11
|
+
left: number;
|
|
12
|
+
top: number;
|
|
13
|
+
};
|
|
14
|
+
|
|
5
15
|
export const INLINE_EDITING_PROPERTY_PER_TYPE: Record< string, string > = {
|
|
6
16
|
'e-form-label': 'text',
|
|
7
17
|
'e-heading': 'title',
|
|
@@ -14,19 +24,62 @@ export const getWidgetType = ( container: V1Element | null ) => {
|
|
|
14
24
|
return container?.model?.get( 'widgetType' ) ?? container?.model?.get( 'elType' ) ?? null;
|
|
15
25
|
};
|
|
16
26
|
|
|
17
|
-
export const
|
|
18
|
-
const
|
|
27
|
+
export const calcSelectionCenterOffsets = ( view: EditorView ): Offsets | null => {
|
|
28
|
+
const frameWindow = ( view.root as Document )?.defaultView;
|
|
29
|
+
const selection = frameWindow?.getSelection();
|
|
30
|
+
const editorContainer = view.dom;
|
|
31
|
+
|
|
32
|
+
if ( ! selection || ! editorContainer ) {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const range = selection.getRangeAt( 0 );
|
|
37
|
+
const selectionRect = range.getBoundingClientRect();
|
|
38
|
+
const editorContainerRect = editorContainer.getBoundingClientRect();
|
|
39
|
+
|
|
40
|
+
if ( ! selectionRect || ! editorContainerRect ) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const verticalOffset = selectionRect.top - editorContainerRect.top;
|
|
45
|
+
|
|
46
|
+
const selectionCenter = selectionRect?.left + selectionRect?.width / 2;
|
|
47
|
+
const horizontalOffset = selectionCenter - editorContainerRect.left;
|
|
48
|
+
|
|
49
|
+
return { left: horizontalOffset, top: verticalOffset };
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export const getComputedStyle = ( styles: CSSProperties, offsets: Offsets ): CSSProperties => {
|
|
53
|
+
const transform = extractTransformValue( styles );
|
|
54
|
+
|
|
55
|
+
return transform
|
|
56
|
+
? {
|
|
57
|
+
...styles,
|
|
58
|
+
marginLeft: `${ offsets.left }px`,
|
|
59
|
+
marginTop: `${ offsets.top }px`,
|
|
60
|
+
pointerEvents: 'none',
|
|
61
|
+
}
|
|
62
|
+
: {
|
|
63
|
+
display: 'none',
|
|
64
|
+
};
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const extractTransformValue = ( styles: CSSProperties ) => {
|
|
68
|
+
const translateRegex = /translate\([^)]*\)\s?/g;
|
|
69
|
+
const numericValuesRegex = /(-?\d+\.?\d*)/g;
|
|
70
|
+
|
|
71
|
+
const translateValue = styles?.transform?.match( translateRegex )?.[ 0 ];
|
|
72
|
+
const values = translateValue?.match( numericValuesRegex );
|
|
73
|
+
|
|
74
|
+
if ( ! translateValue || ! values ) {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
19
77
|
|
|
20
|
-
const
|
|
21
|
-
const iFramePosition = iFrameElement?.getBoundingClientRect() ?? positionFallback;
|
|
78
|
+
const [ numericX, numericY ] = values.map( Number );
|
|
22
79
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
: positionFallback;
|
|
80
|
+
if ( ! numericX || ! numericY ) {
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
27
83
|
|
|
28
|
-
return
|
|
29
|
-
left: iFramePosition.left + previewPosition.left,
|
|
30
|
-
top: iFramePosition.top + previewPosition.top,
|
|
31
|
-
};
|
|
84
|
+
return styles.transform;
|
|
32
85
|
};
|