@elementor/editor-canvas 3.35.4 → 3.35.6
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
|
@@ -1767,66 +1767,129 @@ var ReplacementBase = class {
|
|
|
1767
1767
|
|
|
1768
1768
|
// src/legacy/replacements/inline-editing/canvas-inline-editor.tsx
|
|
1769
1769
|
var React5 = __toESM(require("react"));
|
|
1770
|
-
var
|
|
1770
|
+
var import_react12 = require("react");
|
|
1771
1771
|
var import_editor_controls2 = require("@elementor/editor-controls");
|
|
1772
1772
|
var import_ui4 = require("@elementor/ui");
|
|
1773
|
-
var
|
|
1773
|
+
var import_react13 = require("@floating-ui/react");
|
|
1774
1774
|
|
|
1775
1775
|
// src/legacy/replacements/inline-editing/inline-editing-utils.ts
|
|
1776
|
+
var import_react11 = require("react");
|
|
1777
|
+
var TOP_BAR_SELECTOR = "#elementor-editor-wrapper-v2";
|
|
1778
|
+
var NAVIGATOR_SELECTOR = "#elementor-navigator";
|
|
1779
|
+
var EDITING_PANEL = "#elementor-panel";
|
|
1780
|
+
var EDITOR_ELEMENTS_OUT_OF_IFRAME = [TOP_BAR_SELECTOR, NAVIGATOR_SELECTOR, EDITING_PANEL];
|
|
1781
|
+
var TOOLBAR_ANCHOR_ID_PREFIX = "inline-editing-toolbar-anchor";
|
|
1782
|
+
var TOOLBAR_ANCHOR_STATIC_STYLES = {
|
|
1783
|
+
backgroundColor: "transparent",
|
|
1784
|
+
border: "none",
|
|
1785
|
+
outline: "none",
|
|
1786
|
+
boxShadow: "none",
|
|
1787
|
+
padding: "0",
|
|
1788
|
+
margin: "0",
|
|
1789
|
+
borderRadius: "0",
|
|
1790
|
+
overflow: "hidden",
|
|
1791
|
+
opacity: "0",
|
|
1792
|
+
pointerEvents: "none",
|
|
1793
|
+
position: "absolute",
|
|
1794
|
+
display: "block"
|
|
1795
|
+
};
|
|
1776
1796
|
var INLINE_EDITING_PROPERTY_PER_TYPE = {
|
|
1777
1797
|
"e-form-label": "text",
|
|
1778
1798
|
"e-heading": "title",
|
|
1779
1799
|
"e-paragraph": "paragraph"
|
|
1780
1800
|
};
|
|
1781
|
-
var
|
|
1782
|
-
|
|
1801
|
+
var getInlineEditorElement = (elementWrapper, expectedTag) => {
|
|
1802
|
+
return !expectedTag ? null : elementWrapper.querySelector(expectedTag);
|
|
1803
|
+
};
|
|
1804
|
+
var useOnClickOutsideIframe = (handleUnmount) => {
|
|
1805
|
+
const asyncUnmountInlineEditor = (0, import_react11.useCallback)(() => queueMicrotask(handleUnmount), [handleUnmount]);
|
|
1806
|
+
(0, import_react11.useEffect)(() => {
|
|
1807
|
+
EDITOR_ELEMENTS_OUT_OF_IFRAME.forEach(
|
|
1808
|
+
(selector) => document?.querySelector(selector)?.addEventListener("mousedown", asyncUnmountInlineEditor)
|
|
1809
|
+
);
|
|
1810
|
+
return () => EDITOR_ELEMENTS_OUT_OF_IFRAME.forEach(
|
|
1811
|
+
(selector) => document?.querySelector(selector)?.removeEventListener("mousedown", asyncUnmountInlineEditor)
|
|
1812
|
+
);
|
|
1813
|
+
}, []);
|
|
1814
|
+
};
|
|
1815
|
+
var useRenderToolbar = (ownerDocument, id) => {
|
|
1816
|
+
const [anchor, setAnchor] = (0, import_react11.useState)(null);
|
|
1817
|
+
const onSelectionEnd = (view) => {
|
|
1818
|
+
const hasSelection = !view.state.selection.empty;
|
|
1819
|
+
removeToolbarAnchor(ownerDocument, id);
|
|
1820
|
+
if (hasSelection) {
|
|
1821
|
+
setAnchor(createAnchorBasedOnSelection(ownerDocument, id));
|
|
1822
|
+
} else {
|
|
1823
|
+
setAnchor(null);
|
|
1824
|
+
}
|
|
1825
|
+
};
|
|
1826
|
+
return { onSelectionEnd, anchor };
|
|
1827
|
+
};
|
|
1828
|
+
var createAnchorBasedOnSelection = (ownerDocument, id) => {
|
|
1829
|
+
const frameWindow = ownerDocument.defaultView;
|
|
1783
1830
|
const selection = frameWindow?.getSelection();
|
|
1784
|
-
|
|
1785
|
-
if (!selection || !editorContainer) {
|
|
1831
|
+
if (!selection) {
|
|
1786
1832
|
return null;
|
|
1787
1833
|
}
|
|
1788
1834
|
const range = selection.getRangeAt(0);
|
|
1789
1835
|
const selectionRect = range.getBoundingClientRect();
|
|
1790
|
-
const
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
}
|
|
1807
|
-
|
|
1808
|
-
|
|
1836
|
+
const bodyRect = ownerDocument.body.getBoundingClientRect();
|
|
1837
|
+
const toolbarAnchor = ownerDocument.createElement("span");
|
|
1838
|
+
styleToolbarAnchor(toolbarAnchor, selectionRect, bodyRect);
|
|
1839
|
+
toolbarAnchor.setAttribute("id", getToolbarAnchorId(id));
|
|
1840
|
+
ownerDocument.body.appendChild(toolbarAnchor);
|
|
1841
|
+
return toolbarAnchor;
|
|
1842
|
+
};
|
|
1843
|
+
var removeToolbarAnchor = (ownerDocument, id) => {
|
|
1844
|
+
const toolbarAnchor = getToolbarAnchor(ownerDocument, id);
|
|
1845
|
+
if (toolbarAnchor) {
|
|
1846
|
+
ownerDocument.body.removeChild(toolbarAnchor);
|
|
1847
|
+
}
|
|
1848
|
+
};
|
|
1849
|
+
var getToolbarAnchorId = (id) => `${TOOLBAR_ANCHOR_ID_PREFIX}-${id}`;
|
|
1850
|
+
var getToolbarAnchor = (ownerDocument, id) => ownerDocument.getElementById(getToolbarAnchorId(id));
|
|
1851
|
+
var styleToolbarAnchor = (anchor, selectionRect, bodyRect) => {
|
|
1852
|
+
const { width, height } = selectionRect;
|
|
1853
|
+
Object.assign(anchor.style, {
|
|
1854
|
+
...TOOLBAR_ANCHOR_STATIC_STYLES,
|
|
1855
|
+
top: `${selectionRect.top - bodyRect.top}px`,
|
|
1856
|
+
left: `${selectionRect.left - bodyRect.left}px`,
|
|
1857
|
+
width: `${width}px`,
|
|
1858
|
+
height: `${height}px`
|
|
1859
|
+
});
|
|
1809
1860
|
};
|
|
1810
|
-
var
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1861
|
+
var horizontalShifterMiddleware = {
|
|
1862
|
+
name: "horizontalShifter",
|
|
1863
|
+
fn(state) {
|
|
1864
|
+
const {
|
|
1865
|
+
x: left,
|
|
1866
|
+
y: top,
|
|
1867
|
+
elements: { reference: anchor, floating }
|
|
1868
|
+
} = state;
|
|
1869
|
+
const newState = {
|
|
1870
|
+
...state,
|
|
1871
|
+
x: left,
|
|
1872
|
+
y: top
|
|
1873
|
+
};
|
|
1874
|
+
const isLeftOverflown = left < 0;
|
|
1875
|
+
if (isLeftOverflown) {
|
|
1876
|
+
newState.x = 0;
|
|
1877
|
+
return newState;
|
|
1878
|
+
}
|
|
1879
|
+
const anchorRect = anchor.getBoundingClientRect();
|
|
1880
|
+
const right = left + floating.offsetWidth;
|
|
1881
|
+
const documentWidth = anchor.ownerDocument.body.offsetWidth;
|
|
1882
|
+
const isRightOverflown = right > documentWidth && anchorRect.right < right;
|
|
1883
|
+
if (isRightOverflown) {
|
|
1884
|
+
const diff = right - documentWidth;
|
|
1885
|
+
newState.x = left - diff;
|
|
1886
|
+
return newState;
|
|
1887
|
+
}
|
|
1888
|
+
return newState;
|
|
1821
1889
|
}
|
|
1822
|
-
return styles.transform;
|
|
1823
1890
|
};
|
|
1824
1891
|
|
|
1825
1892
|
// src/legacy/replacements/inline-editing/canvas-inline-editor.tsx
|
|
1826
|
-
var TOP_BAR_SELECTOR = "#elementor-editor-wrapper-v2";
|
|
1827
|
-
var NAVIGATOR_SELECTOR = "#elementor-navigator";
|
|
1828
|
-
var EDITING_PANEL = "#elementor-panel";
|
|
1829
|
-
var EDITOR_ELEMENTS_OUT_OF_IFRAME = [TOP_BAR_SELECTOR, NAVIGATOR_SELECTOR, EDITING_PANEL];
|
|
1830
1893
|
var EDITOR_WRAPPER_SELECTOR = "inline-editor-wrapper";
|
|
1831
1894
|
var CanvasInlineEditor = ({
|
|
1832
1895
|
elementClasses,
|
|
@@ -1835,19 +1898,23 @@ var CanvasInlineEditor = ({
|
|
|
1835
1898
|
rootElement,
|
|
1836
1899
|
id,
|
|
1837
1900
|
setValue,
|
|
1838
|
-
|
|
1901
|
+
...props
|
|
1839
1902
|
}) => {
|
|
1840
|
-
const [
|
|
1841
|
-
const
|
|
1842
|
-
const
|
|
1843
|
-
|
|
1844
|
-
|
|
1903
|
+
const [editor, setEditor] = (0, import_react12.useState)(null);
|
|
1904
|
+
const { onSelectionEnd, anchor: toolbarAnchor } = useRenderToolbar(rootElement.ownerDocument, id);
|
|
1905
|
+
const onBlur = () => {
|
|
1906
|
+
removeToolbarAnchor(rootElement.ownerDocument, id);
|
|
1907
|
+
props.onBlur();
|
|
1845
1908
|
};
|
|
1846
1909
|
useOnClickOutsideIframe(onBlur);
|
|
1847
1910
|
return /* @__PURE__ */ React5.createElement(import_ui4.ThemeProvider, null, /* @__PURE__ */ React5.createElement(InlineEditingOverlay, { expectedTag, rootElement, id }), /* @__PURE__ */ React5.createElement("style", null, `
|
|
1848
1911
|
.ProseMirror > * {
|
|
1849
1912
|
height: 100%;
|
|
1850
1913
|
}
|
|
1914
|
+
.${EDITOR_WRAPPER_SELECTOR} .ProseMirror > button[contenteditable="true"] {
|
|
1915
|
+
height: auto;
|
|
1916
|
+
cursor: text;
|
|
1917
|
+
}
|
|
1851
1918
|
`), /* @__PURE__ */ React5.createElement(
|
|
1852
1919
|
import_editor_controls2.InlineEditor,
|
|
1853
1920
|
{
|
|
@@ -1863,19 +1930,9 @@ var CanvasInlineEditor = ({
|
|
|
1863
1930
|
onBlur,
|
|
1864
1931
|
autofocus: true,
|
|
1865
1932
|
expectedTag,
|
|
1866
|
-
wrapperClassName: EDITOR_WRAPPER_SELECTOR,
|
|
1867
1933
|
onSelectionEnd
|
|
1868
1934
|
}
|
|
1869
|
-
),
|
|
1870
|
-
InlineEditingToolbarWrapper,
|
|
1871
|
-
{
|
|
1872
|
-
expectedTag,
|
|
1873
|
-
editor,
|
|
1874
|
-
rootElement,
|
|
1875
|
-
id,
|
|
1876
|
-
selectionOffsets
|
|
1877
|
-
}
|
|
1878
|
-
));
|
|
1935
|
+
), toolbarAnchor && editor && /* @__PURE__ */ React5.createElement(InlineEditingToolbar, { anchor: toolbarAnchor, editor, id }));
|
|
1879
1936
|
};
|
|
1880
1937
|
var InlineEditingOverlay = ({
|
|
1881
1938
|
expectedTag,
|
|
@@ -1883,84 +1940,25 @@ var InlineEditingOverlay = ({
|
|
|
1883
1940
|
id
|
|
1884
1941
|
}) => {
|
|
1885
1942
|
const inlineEditedElement = getInlineEditorElement(rootElement, expectedTag);
|
|
1886
|
-
const [overlayRefElement, setOverlayElement] = (0,
|
|
1887
|
-
(0,
|
|
1943
|
+
const [overlayRefElement, setOverlayElement] = (0, import_react12.useState)(inlineEditedElement);
|
|
1944
|
+
(0, import_react12.useEffect)(() => {
|
|
1888
1945
|
setOverlayElement(getInlineEditorElement(rootElement, expectedTag));
|
|
1889
1946
|
}, [expectedTag, rootElement]);
|
|
1890
1947
|
return overlayRefElement ? /* @__PURE__ */ React5.createElement(OutlineOverlay, { element: overlayRefElement, id, isSelected: true }) : null;
|
|
1891
1948
|
};
|
|
1892
|
-
var
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
const [element, setElement] = (0, import_react11.useState)(null);
|
|
1900
|
-
(0, import_react11.useEffect)(() => {
|
|
1901
|
-
setElement(getInlineEditorElement(rootElement, expectedTag));
|
|
1902
|
-
}, [expectedTag, rootElement]);
|
|
1903
|
-
return element ? /* @__PURE__ */ React5.createElement(InlineEditingToolbar, { element, editor, id, selectionOffsets }) : null;
|
|
1904
|
-
};
|
|
1905
|
-
var InlineEditingToolbar = ({
|
|
1906
|
-
element,
|
|
1907
|
-
editor,
|
|
1908
|
-
id,
|
|
1909
|
-
selectionOffsets
|
|
1910
|
-
}) => {
|
|
1911
|
-
const { floating } = useFloatingOnElement({
|
|
1912
|
-
element,
|
|
1913
|
-
isSelected: true
|
|
1949
|
+
var InlineEditingToolbar = ({ anchor, editor, id }) => {
|
|
1950
|
+
const { refs, floatingStyles } = (0, import_react13.useFloating)({
|
|
1951
|
+
placement: "top",
|
|
1952
|
+
strategy: "fixed",
|
|
1953
|
+
transform: false,
|
|
1954
|
+
whileElementsMounted: import_react13.autoUpdate,
|
|
1955
|
+
middleware: [horizontalShifterMiddleware, (0, import_react13.flip)()]
|
|
1914
1956
|
});
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
{
|
|
1921
|
-
ref: floating.setRef,
|
|
1922
|
-
style: {
|
|
1923
|
-
...floating.styles,
|
|
1924
|
-
pointerEvents: "none"
|
|
1925
|
-
},
|
|
1926
|
-
role: "presentation",
|
|
1927
|
-
...getFloatingProps({ style })
|
|
1928
|
-
},
|
|
1929
|
-
floating.styles.transform && /* @__PURE__ */ React5.createElement(
|
|
1930
|
-
import_ui4.Box,
|
|
1931
|
-
{
|
|
1932
|
-
sx: {
|
|
1933
|
-
position: "relative",
|
|
1934
|
-
transform: "translateY(-100%)",
|
|
1935
|
-
height: "max-content"
|
|
1936
|
-
}
|
|
1937
|
-
},
|
|
1938
|
-
/* @__PURE__ */ React5.createElement(
|
|
1939
|
-
import_editor_controls2.InlineEditorToolbar,
|
|
1940
|
-
{
|
|
1941
|
-
editor,
|
|
1942
|
-
elementId: id,
|
|
1943
|
-
sx: {
|
|
1944
|
-
transform: "translateX(-50%)"
|
|
1945
|
-
}
|
|
1946
|
-
}
|
|
1947
|
-
)
|
|
1948
|
-
)
|
|
1949
|
-
));
|
|
1950
|
-
};
|
|
1951
|
-
var getInlineEditorElement = (elementWrapper, expectedTag) => {
|
|
1952
|
-
return !expectedTag ? null : elementWrapper.querySelector(expectedTag);
|
|
1953
|
-
};
|
|
1954
|
-
var useOnClickOutsideIframe = (handleUnmount) => {
|
|
1955
|
-
const asyncUnmountInlineEditor = React5.useCallback(() => queueMicrotask(handleUnmount), [handleUnmount]);
|
|
1956
|
-
(0, import_react11.useEffect)(() => {
|
|
1957
|
-
EDITOR_ELEMENTS_OUT_OF_IFRAME.forEach(
|
|
1958
|
-
(selector) => document?.querySelector(selector)?.addEventListener("mousedown", asyncUnmountInlineEditor)
|
|
1959
|
-
);
|
|
1960
|
-
return () => EDITOR_ELEMENTS_OUT_OF_IFRAME.forEach(
|
|
1961
|
-
(selector) => document?.querySelector(selector)?.removeEventListener("mousedown", asyncUnmountInlineEditor)
|
|
1962
|
-
);
|
|
1963
|
-
}, []);
|
|
1957
|
+
(0, import_react12.useLayoutEffect)(() => {
|
|
1958
|
+
refs.setReference(anchor);
|
|
1959
|
+
return () => refs.setReference(null);
|
|
1960
|
+
}, [anchor, refs]);
|
|
1961
|
+
return /* @__PURE__ */ React5.createElement(import_react13.FloatingPortal, { id: CANVAS_WRAPPER_ID }, /* @__PURE__ */ React5.createElement(import_ui4.Box, { ref: refs.setFloating, role: "presentation", style: { ...floatingStyles, pointerEvents: "none" } }, /* @__PURE__ */ React5.createElement(import_editor_controls2.InlineEditorToolbar, { editor, elementId: id })));
|
|
1964
1962
|
};
|
|
1965
1963
|
|
|
1966
1964
|
// src/legacy/replacements/inline-editing/inline-editing-eligibility.ts
|
package/dist/index.mjs
CHANGED
|
@@ -1738,66 +1738,129 @@ var ReplacementBase = class {
|
|
|
1738
1738
|
|
|
1739
1739
|
// src/legacy/replacements/inline-editing/canvas-inline-editor.tsx
|
|
1740
1740
|
import * as React5 from "react";
|
|
1741
|
-
import { useEffect as
|
|
1741
|
+
import { useEffect as useEffect8, useLayoutEffect, useState as useState5 } from "react";
|
|
1742
1742
|
import { InlineEditor, InlineEditorToolbar } from "@elementor/editor-controls";
|
|
1743
1743
|
import { Box as Box2, ThemeProvider } from "@elementor/ui";
|
|
1744
|
-
import { FloatingPortal as FloatingPortal2,
|
|
1744
|
+
import { autoUpdate as autoUpdate2, flip, FloatingPortal as FloatingPortal2, useFloating as useFloating2 } from "@floating-ui/react";
|
|
1745
1745
|
|
|
1746
1746
|
// src/legacy/replacements/inline-editing/inline-editing-utils.ts
|
|
1747
|
+
import { useCallback, useEffect as useEffect7, useState as useState4 } from "react";
|
|
1748
|
+
var TOP_BAR_SELECTOR = "#elementor-editor-wrapper-v2";
|
|
1749
|
+
var NAVIGATOR_SELECTOR = "#elementor-navigator";
|
|
1750
|
+
var EDITING_PANEL = "#elementor-panel";
|
|
1751
|
+
var EDITOR_ELEMENTS_OUT_OF_IFRAME = [TOP_BAR_SELECTOR, NAVIGATOR_SELECTOR, EDITING_PANEL];
|
|
1752
|
+
var TOOLBAR_ANCHOR_ID_PREFIX = "inline-editing-toolbar-anchor";
|
|
1753
|
+
var TOOLBAR_ANCHOR_STATIC_STYLES = {
|
|
1754
|
+
backgroundColor: "transparent",
|
|
1755
|
+
border: "none",
|
|
1756
|
+
outline: "none",
|
|
1757
|
+
boxShadow: "none",
|
|
1758
|
+
padding: "0",
|
|
1759
|
+
margin: "0",
|
|
1760
|
+
borderRadius: "0",
|
|
1761
|
+
overflow: "hidden",
|
|
1762
|
+
opacity: "0",
|
|
1763
|
+
pointerEvents: "none",
|
|
1764
|
+
position: "absolute",
|
|
1765
|
+
display: "block"
|
|
1766
|
+
};
|
|
1747
1767
|
var INLINE_EDITING_PROPERTY_PER_TYPE = {
|
|
1748
1768
|
"e-form-label": "text",
|
|
1749
1769
|
"e-heading": "title",
|
|
1750
1770
|
"e-paragraph": "paragraph"
|
|
1751
1771
|
};
|
|
1752
|
-
var
|
|
1753
|
-
|
|
1772
|
+
var getInlineEditorElement = (elementWrapper, expectedTag) => {
|
|
1773
|
+
return !expectedTag ? null : elementWrapper.querySelector(expectedTag);
|
|
1774
|
+
};
|
|
1775
|
+
var useOnClickOutsideIframe = (handleUnmount) => {
|
|
1776
|
+
const asyncUnmountInlineEditor = useCallback(() => queueMicrotask(handleUnmount), [handleUnmount]);
|
|
1777
|
+
useEffect7(() => {
|
|
1778
|
+
EDITOR_ELEMENTS_OUT_OF_IFRAME.forEach(
|
|
1779
|
+
(selector) => document?.querySelector(selector)?.addEventListener("mousedown", asyncUnmountInlineEditor)
|
|
1780
|
+
);
|
|
1781
|
+
return () => EDITOR_ELEMENTS_OUT_OF_IFRAME.forEach(
|
|
1782
|
+
(selector) => document?.querySelector(selector)?.removeEventListener("mousedown", asyncUnmountInlineEditor)
|
|
1783
|
+
);
|
|
1784
|
+
}, []);
|
|
1785
|
+
};
|
|
1786
|
+
var useRenderToolbar = (ownerDocument, id) => {
|
|
1787
|
+
const [anchor, setAnchor] = useState4(null);
|
|
1788
|
+
const onSelectionEnd = (view) => {
|
|
1789
|
+
const hasSelection = !view.state.selection.empty;
|
|
1790
|
+
removeToolbarAnchor(ownerDocument, id);
|
|
1791
|
+
if (hasSelection) {
|
|
1792
|
+
setAnchor(createAnchorBasedOnSelection(ownerDocument, id));
|
|
1793
|
+
} else {
|
|
1794
|
+
setAnchor(null);
|
|
1795
|
+
}
|
|
1796
|
+
};
|
|
1797
|
+
return { onSelectionEnd, anchor };
|
|
1798
|
+
};
|
|
1799
|
+
var createAnchorBasedOnSelection = (ownerDocument, id) => {
|
|
1800
|
+
const frameWindow = ownerDocument.defaultView;
|
|
1754
1801
|
const selection = frameWindow?.getSelection();
|
|
1755
|
-
|
|
1756
|
-
if (!selection || !editorContainer) {
|
|
1802
|
+
if (!selection) {
|
|
1757
1803
|
return null;
|
|
1758
1804
|
}
|
|
1759
1805
|
const range = selection.getRangeAt(0);
|
|
1760
1806
|
const selectionRect = range.getBoundingClientRect();
|
|
1761
|
-
const
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
}
|
|
1778
|
-
|
|
1779
|
-
|
|
1807
|
+
const bodyRect = ownerDocument.body.getBoundingClientRect();
|
|
1808
|
+
const toolbarAnchor = ownerDocument.createElement("span");
|
|
1809
|
+
styleToolbarAnchor(toolbarAnchor, selectionRect, bodyRect);
|
|
1810
|
+
toolbarAnchor.setAttribute("id", getToolbarAnchorId(id));
|
|
1811
|
+
ownerDocument.body.appendChild(toolbarAnchor);
|
|
1812
|
+
return toolbarAnchor;
|
|
1813
|
+
};
|
|
1814
|
+
var removeToolbarAnchor = (ownerDocument, id) => {
|
|
1815
|
+
const toolbarAnchor = getToolbarAnchor(ownerDocument, id);
|
|
1816
|
+
if (toolbarAnchor) {
|
|
1817
|
+
ownerDocument.body.removeChild(toolbarAnchor);
|
|
1818
|
+
}
|
|
1819
|
+
};
|
|
1820
|
+
var getToolbarAnchorId = (id) => `${TOOLBAR_ANCHOR_ID_PREFIX}-${id}`;
|
|
1821
|
+
var getToolbarAnchor = (ownerDocument, id) => ownerDocument.getElementById(getToolbarAnchorId(id));
|
|
1822
|
+
var styleToolbarAnchor = (anchor, selectionRect, bodyRect) => {
|
|
1823
|
+
const { width, height } = selectionRect;
|
|
1824
|
+
Object.assign(anchor.style, {
|
|
1825
|
+
...TOOLBAR_ANCHOR_STATIC_STYLES,
|
|
1826
|
+
top: `${selectionRect.top - bodyRect.top}px`,
|
|
1827
|
+
left: `${selectionRect.left - bodyRect.left}px`,
|
|
1828
|
+
width: `${width}px`,
|
|
1829
|
+
height: `${height}px`
|
|
1830
|
+
});
|
|
1780
1831
|
};
|
|
1781
|
-
var
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1832
|
+
var horizontalShifterMiddleware = {
|
|
1833
|
+
name: "horizontalShifter",
|
|
1834
|
+
fn(state) {
|
|
1835
|
+
const {
|
|
1836
|
+
x: left,
|
|
1837
|
+
y: top,
|
|
1838
|
+
elements: { reference: anchor, floating }
|
|
1839
|
+
} = state;
|
|
1840
|
+
const newState = {
|
|
1841
|
+
...state,
|
|
1842
|
+
x: left,
|
|
1843
|
+
y: top
|
|
1844
|
+
};
|
|
1845
|
+
const isLeftOverflown = left < 0;
|
|
1846
|
+
if (isLeftOverflown) {
|
|
1847
|
+
newState.x = 0;
|
|
1848
|
+
return newState;
|
|
1849
|
+
}
|
|
1850
|
+
const anchorRect = anchor.getBoundingClientRect();
|
|
1851
|
+
const right = left + floating.offsetWidth;
|
|
1852
|
+
const documentWidth = anchor.ownerDocument.body.offsetWidth;
|
|
1853
|
+
const isRightOverflown = right > documentWidth && anchorRect.right < right;
|
|
1854
|
+
if (isRightOverflown) {
|
|
1855
|
+
const diff = right - documentWidth;
|
|
1856
|
+
newState.x = left - diff;
|
|
1857
|
+
return newState;
|
|
1858
|
+
}
|
|
1859
|
+
return newState;
|
|
1792
1860
|
}
|
|
1793
|
-
return styles.transform;
|
|
1794
1861
|
};
|
|
1795
1862
|
|
|
1796
1863
|
// src/legacy/replacements/inline-editing/canvas-inline-editor.tsx
|
|
1797
|
-
var TOP_BAR_SELECTOR = "#elementor-editor-wrapper-v2";
|
|
1798
|
-
var NAVIGATOR_SELECTOR = "#elementor-navigator";
|
|
1799
|
-
var EDITING_PANEL = "#elementor-panel";
|
|
1800
|
-
var EDITOR_ELEMENTS_OUT_OF_IFRAME = [TOP_BAR_SELECTOR, NAVIGATOR_SELECTOR, EDITING_PANEL];
|
|
1801
1864
|
var EDITOR_WRAPPER_SELECTOR = "inline-editor-wrapper";
|
|
1802
1865
|
var CanvasInlineEditor = ({
|
|
1803
1866
|
elementClasses,
|
|
@@ -1806,19 +1869,23 @@ var CanvasInlineEditor = ({
|
|
|
1806
1869
|
rootElement,
|
|
1807
1870
|
id,
|
|
1808
1871
|
setValue,
|
|
1809
|
-
|
|
1872
|
+
...props
|
|
1810
1873
|
}) => {
|
|
1811
|
-
const [
|
|
1812
|
-
const
|
|
1813
|
-
const
|
|
1814
|
-
|
|
1815
|
-
|
|
1874
|
+
const [editor, setEditor] = useState5(null);
|
|
1875
|
+
const { onSelectionEnd, anchor: toolbarAnchor } = useRenderToolbar(rootElement.ownerDocument, id);
|
|
1876
|
+
const onBlur = () => {
|
|
1877
|
+
removeToolbarAnchor(rootElement.ownerDocument, id);
|
|
1878
|
+
props.onBlur();
|
|
1816
1879
|
};
|
|
1817
1880
|
useOnClickOutsideIframe(onBlur);
|
|
1818
1881
|
return /* @__PURE__ */ React5.createElement(ThemeProvider, null, /* @__PURE__ */ React5.createElement(InlineEditingOverlay, { expectedTag, rootElement, id }), /* @__PURE__ */ React5.createElement("style", null, `
|
|
1819
1882
|
.ProseMirror > * {
|
|
1820
1883
|
height: 100%;
|
|
1821
1884
|
}
|
|
1885
|
+
.${EDITOR_WRAPPER_SELECTOR} .ProseMirror > button[contenteditable="true"] {
|
|
1886
|
+
height: auto;
|
|
1887
|
+
cursor: text;
|
|
1888
|
+
}
|
|
1822
1889
|
`), /* @__PURE__ */ React5.createElement(
|
|
1823
1890
|
InlineEditor,
|
|
1824
1891
|
{
|
|
@@ -1834,19 +1901,9 @@ var CanvasInlineEditor = ({
|
|
|
1834
1901
|
onBlur,
|
|
1835
1902
|
autofocus: true,
|
|
1836
1903
|
expectedTag,
|
|
1837
|
-
wrapperClassName: EDITOR_WRAPPER_SELECTOR,
|
|
1838
1904
|
onSelectionEnd
|
|
1839
1905
|
}
|
|
1840
|
-
),
|
|
1841
|
-
InlineEditingToolbarWrapper,
|
|
1842
|
-
{
|
|
1843
|
-
expectedTag,
|
|
1844
|
-
editor,
|
|
1845
|
-
rootElement,
|
|
1846
|
-
id,
|
|
1847
|
-
selectionOffsets
|
|
1848
|
-
}
|
|
1849
|
-
));
|
|
1906
|
+
), toolbarAnchor && editor && /* @__PURE__ */ React5.createElement(InlineEditingToolbar, { anchor: toolbarAnchor, editor, id }));
|
|
1850
1907
|
};
|
|
1851
1908
|
var InlineEditingOverlay = ({
|
|
1852
1909
|
expectedTag,
|
|
@@ -1854,84 +1911,25 @@ var InlineEditingOverlay = ({
|
|
|
1854
1911
|
id
|
|
1855
1912
|
}) => {
|
|
1856
1913
|
const inlineEditedElement = getInlineEditorElement(rootElement, expectedTag);
|
|
1857
|
-
const [overlayRefElement, setOverlayElement] =
|
|
1858
|
-
|
|
1914
|
+
const [overlayRefElement, setOverlayElement] = useState5(inlineEditedElement);
|
|
1915
|
+
useEffect8(() => {
|
|
1859
1916
|
setOverlayElement(getInlineEditorElement(rootElement, expectedTag));
|
|
1860
1917
|
}, [expectedTag, rootElement]);
|
|
1861
1918
|
return overlayRefElement ? /* @__PURE__ */ React5.createElement(OutlineOverlay, { element: overlayRefElement, id, isSelected: true }) : null;
|
|
1862
1919
|
};
|
|
1863
|
-
var
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
const [element, setElement] = useState4(null);
|
|
1871
|
-
useEffect7(() => {
|
|
1872
|
-
setElement(getInlineEditorElement(rootElement, expectedTag));
|
|
1873
|
-
}, [expectedTag, rootElement]);
|
|
1874
|
-
return element ? /* @__PURE__ */ React5.createElement(InlineEditingToolbar, { element, editor, id, selectionOffsets }) : null;
|
|
1875
|
-
};
|
|
1876
|
-
var InlineEditingToolbar = ({
|
|
1877
|
-
element,
|
|
1878
|
-
editor,
|
|
1879
|
-
id,
|
|
1880
|
-
selectionOffsets
|
|
1881
|
-
}) => {
|
|
1882
|
-
const { floating } = useFloatingOnElement({
|
|
1883
|
-
element,
|
|
1884
|
-
isSelected: true
|
|
1920
|
+
var InlineEditingToolbar = ({ anchor, editor, id }) => {
|
|
1921
|
+
const { refs, floatingStyles } = useFloating2({
|
|
1922
|
+
placement: "top",
|
|
1923
|
+
strategy: "fixed",
|
|
1924
|
+
transform: false,
|
|
1925
|
+
whileElementsMounted: autoUpdate2,
|
|
1926
|
+
middleware: [horizontalShifterMiddleware, flip()]
|
|
1885
1927
|
});
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
{
|
|
1892
|
-
ref: floating.setRef,
|
|
1893
|
-
style: {
|
|
1894
|
-
...floating.styles,
|
|
1895
|
-
pointerEvents: "none"
|
|
1896
|
-
},
|
|
1897
|
-
role: "presentation",
|
|
1898
|
-
...getFloatingProps({ style })
|
|
1899
|
-
},
|
|
1900
|
-
floating.styles.transform && /* @__PURE__ */ React5.createElement(
|
|
1901
|
-
Box2,
|
|
1902
|
-
{
|
|
1903
|
-
sx: {
|
|
1904
|
-
position: "relative",
|
|
1905
|
-
transform: "translateY(-100%)",
|
|
1906
|
-
height: "max-content"
|
|
1907
|
-
}
|
|
1908
|
-
},
|
|
1909
|
-
/* @__PURE__ */ React5.createElement(
|
|
1910
|
-
InlineEditorToolbar,
|
|
1911
|
-
{
|
|
1912
|
-
editor,
|
|
1913
|
-
elementId: id,
|
|
1914
|
-
sx: {
|
|
1915
|
-
transform: "translateX(-50%)"
|
|
1916
|
-
}
|
|
1917
|
-
}
|
|
1918
|
-
)
|
|
1919
|
-
)
|
|
1920
|
-
));
|
|
1921
|
-
};
|
|
1922
|
-
var getInlineEditorElement = (elementWrapper, expectedTag) => {
|
|
1923
|
-
return !expectedTag ? null : elementWrapper.querySelector(expectedTag);
|
|
1924
|
-
};
|
|
1925
|
-
var useOnClickOutsideIframe = (handleUnmount) => {
|
|
1926
|
-
const asyncUnmountInlineEditor = React5.useCallback(() => queueMicrotask(handleUnmount), [handleUnmount]);
|
|
1927
|
-
useEffect7(() => {
|
|
1928
|
-
EDITOR_ELEMENTS_OUT_OF_IFRAME.forEach(
|
|
1929
|
-
(selector) => document?.querySelector(selector)?.addEventListener("mousedown", asyncUnmountInlineEditor)
|
|
1930
|
-
);
|
|
1931
|
-
return () => EDITOR_ELEMENTS_OUT_OF_IFRAME.forEach(
|
|
1932
|
-
(selector) => document?.querySelector(selector)?.removeEventListener("mousedown", asyncUnmountInlineEditor)
|
|
1933
|
-
);
|
|
1934
|
-
}, []);
|
|
1928
|
+
useLayoutEffect(() => {
|
|
1929
|
+
refs.setReference(anchor);
|
|
1930
|
+
return () => refs.setReference(null);
|
|
1931
|
+
}, [anchor, refs]);
|
|
1932
|
+
return /* @__PURE__ */ React5.createElement(FloatingPortal2, { id: CANVAS_WRAPPER_ID }, /* @__PURE__ */ React5.createElement(Box2, { ref: refs.setFloating, role: "presentation", style: { ...floatingStyles, pointerEvents: "none" } }, /* @__PURE__ */ React5.createElement(InlineEditorToolbar, { editor, elementId: id })));
|
|
1935
1933
|
};
|
|
1936
1934
|
|
|
1937
1935
|
// src/legacy/replacements/inline-editing/inline-editing-eligibility.ts
|
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.
|
|
4
|
+
"version": "3.35.6",
|
|
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.
|
|
41
|
-
"@elementor/editor-controls": "3.35.
|
|
42
|
-
"@elementor/editor-documents": "3.35.
|
|
43
|
-
"@elementor/editor-elements": "3.35.
|
|
44
|
-
"@elementor/editor-interactions": "3.35.
|
|
45
|
-
"@elementor/editor-mcp": "3.35.
|
|
46
|
-
"@elementor/editor-notifications": "3.35.
|
|
47
|
-
"@elementor/editor-props": "3.35.
|
|
48
|
-
"@elementor/editor-responsive": "3.35.
|
|
49
|
-
"@elementor/editor-styles": "3.35.
|
|
50
|
-
"@elementor/editor-styles-repository": "3.35.
|
|
51
|
-
"@elementor/editor-ui": "3.35.
|
|
52
|
-
"@elementor/editor-v1-adapters": "3.35.
|
|
53
|
-
"@elementor/schema": "3.35.
|
|
54
|
-
"@elementor/twing": "3.35.
|
|
40
|
+
"@elementor/editor": "3.35.6",
|
|
41
|
+
"@elementor/editor-controls": "3.35.6",
|
|
42
|
+
"@elementor/editor-documents": "3.35.6",
|
|
43
|
+
"@elementor/editor-elements": "3.35.6",
|
|
44
|
+
"@elementor/editor-interactions": "3.35.6",
|
|
45
|
+
"@elementor/editor-mcp": "3.35.6",
|
|
46
|
+
"@elementor/editor-notifications": "3.35.6",
|
|
47
|
+
"@elementor/editor-props": "3.35.6",
|
|
48
|
+
"@elementor/editor-responsive": "3.35.6",
|
|
49
|
+
"@elementor/editor-styles": "3.35.6",
|
|
50
|
+
"@elementor/editor-styles-repository": "3.35.6",
|
|
51
|
+
"@elementor/editor-ui": "3.35.6",
|
|
52
|
+
"@elementor/editor-v1-adapters": "3.35.6",
|
|
53
|
+
"@elementor/schema": "3.35.6",
|
|
54
|
+
"@elementor/twing": "3.35.6",
|
|
55
55
|
"@elementor/ui": "1.36.17",
|
|
56
|
-
"@elementor/utils": "3.35.
|
|
57
|
-
"@elementor/wp-media": "3.35.
|
|
56
|
+
"@elementor/utils": "3.35.6",
|
|
57
|
+
"@elementor/wp-media": "3.35.6",
|
|
58
58
|
"@floating-ui/react": "^0.27.5",
|
|
59
59
|
"@wordpress/i18n": "^5.13.0"
|
|
60
60
|
},
|
|
@@ -1,26 +1,19 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { useEffect, useState } from 'react';
|
|
2
|
+
import { useEffect, useLayoutEffect, useState } from 'react';
|
|
3
3
|
import { InlineEditor, InlineEditorToolbar } from '@elementor/editor-controls';
|
|
4
4
|
import { Box, ThemeProvider } from '@elementor/ui';
|
|
5
|
-
import { FloatingPortal,
|
|
5
|
+
import { autoUpdate, flip, FloatingPortal, useFloating } from '@floating-ui/react';
|
|
6
6
|
|
|
7
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
8
|
import {
|
|
11
|
-
calcSelectionCenterOffsets,
|
|
12
9
|
type Editor,
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
10
|
+
getInlineEditorElement,
|
|
11
|
+
horizontalShifterMiddleware as horizontalShifter,
|
|
12
|
+
removeToolbarAnchor,
|
|
13
|
+
useOnClickOutsideIframe,
|
|
14
|
+
useRenderToolbar,
|
|
16
15
|
} from './inline-editing-utils';
|
|
17
16
|
|
|
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
17
|
const EDITOR_WRAPPER_SELECTOR = 'inline-editor-wrapper';
|
|
25
18
|
|
|
26
19
|
export const CanvasInlineEditor = ( {
|
|
@@ -30,7 +23,7 @@ export const CanvasInlineEditor = ( {
|
|
|
30
23
|
rootElement,
|
|
31
24
|
id,
|
|
32
25
|
setValue,
|
|
33
|
-
|
|
26
|
+
...props
|
|
34
27
|
}: {
|
|
35
28
|
elementClasses: string;
|
|
36
29
|
initialValue: string | null;
|
|
@@ -40,13 +33,13 @@ export const CanvasInlineEditor = ( {
|
|
|
40
33
|
setValue: ( value: string | null ) => void;
|
|
41
34
|
onBlur: () => void;
|
|
42
35
|
} ) => {
|
|
43
|
-
const [ selectionOffsets, setSelectionOffsets ] = useState< Offsets | null >( null );
|
|
44
36
|
const [ editor, setEditor ] = useState< Editor | null >( null );
|
|
37
|
+
const { onSelectionEnd, anchor: toolbarAnchor } = useRenderToolbar( rootElement.ownerDocument, id );
|
|
45
38
|
|
|
46
|
-
const
|
|
47
|
-
|
|
39
|
+
const onBlur = () => {
|
|
40
|
+
removeToolbarAnchor( rootElement.ownerDocument, id );
|
|
48
41
|
|
|
49
|
-
|
|
42
|
+
props.onBlur();
|
|
50
43
|
};
|
|
51
44
|
|
|
52
45
|
useOnClickOutsideIframe( onBlur );
|
|
@@ -59,6 +52,10 @@ export const CanvasInlineEditor = ( {
|
|
|
59
52
|
.ProseMirror > * {
|
|
60
53
|
height: 100%;
|
|
61
54
|
}
|
|
55
|
+
.${ EDITOR_WRAPPER_SELECTOR } .ProseMirror > button[contenteditable="true"] {
|
|
56
|
+
height: auto;
|
|
57
|
+
cursor: text;
|
|
58
|
+
}
|
|
62
59
|
` }
|
|
63
60
|
</style>
|
|
64
61
|
<InlineEditor
|
|
@@ -74,18 +71,9 @@ export const CanvasInlineEditor = ( {
|
|
|
74
71
|
onBlur={ onBlur }
|
|
75
72
|
autofocus
|
|
76
73
|
expectedTag={ expectedTag }
|
|
77
|
-
wrapperClassName={ EDITOR_WRAPPER_SELECTOR }
|
|
78
74
|
onSelectionEnd={ onSelectionEnd }
|
|
79
75
|
/>
|
|
80
|
-
{
|
|
81
|
-
<InlineEditingToolbarWrapper
|
|
82
|
-
expectedTag={ expectedTag }
|
|
83
|
-
editor={ editor }
|
|
84
|
-
rootElement={ rootElement }
|
|
85
|
-
id={ id }
|
|
86
|
-
selectionOffsets={ selectionOffsets }
|
|
87
|
-
/>
|
|
88
|
-
) }
|
|
76
|
+
{ toolbarAnchor && editor && <InlineEditingToolbar anchor={ toolbarAnchor } editor={ editor } id={ id } /> }
|
|
89
77
|
</ThemeProvider>
|
|
90
78
|
);
|
|
91
79
|
};
|
|
@@ -109,104 +97,26 @@ const InlineEditingOverlay = ( {
|
|
|
109
97
|
return overlayRefElement ? <OutlineOverlay element={ overlayRefElement } id={ id } isSelected /> : null;
|
|
110
98
|
};
|
|
111
99
|
|
|
112
|
-
const
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
expectedTag: string | null;
|
|
120
|
-
editor: Editor;
|
|
121
|
-
rootElement: HTMLElement;
|
|
122
|
-
id: string;
|
|
123
|
-
selectionOffsets: Offsets;
|
|
124
|
-
} ) => {
|
|
125
|
-
const [ element, setElement ] = useState< HTMLElement | null >( null );
|
|
126
|
-
|
|
127
|
-
useEffect( () => {
|
|
128
|
-
setElement( getInlineEditorElement( rootElement, expectedTag ) );
|
|
129
|
-
}, [ expectedTag, rootElement ] );
|
|
130
|
-
|
|
131
|
-
return element ? (
|
|
132
|
-
<InlineEditingToolbar element={ element } editor={ editor } id={ id } selectionOffsets={ selectionOffsets } />
|
|
133
|
-
) : null;
|
|
134
|
-
};
|
|
135
|
-
|
|
136
|
-
const InlineEditingToolbar = ( {
|
|
137
|
-
element,
|
|
138
|
-
editor,
|
|
139
|
-
id,
|
|
140
|
-
selectionOffsets,
|
|
141
|
-
}: {
|
|
142
|
-
element: HTMLElement;
|
|
143
|
-
editor: Editor;
|
|
144
|
-
id: string;
|
|
145
|
-
selectionOffsets: Offsets;
|
|
146
|
-
} ) => {
|
|
147
|
-
const { floating } = useFloatingOnElement( {
|
|
148
|
-
element,
|
|
149
|
-
isSelected: true,
|
|
100
|
+
const InlineEditingToolbar = ( { anchor, editor, id }: { anchor: HTMLElement; editor: Editor; id: string } ) => {
|
|
101
|
+
const { refs, floatingStyles } = useFloating( {
|
|
102
|
+
placement: 'top',
|
|
103
|
+
strategy: 'fixed',
|
|
104
|
+
transform: false,
|
|
105
|
+
whileElementsMounted: autoUpdate,
|
|
106
|
+
middleware: [ horizontalShifter, flip() ],
|
|
150
107
|
} );
|
|
151
|
-
const { getFloatingProps, getReferenceProps } = useInteractions();
|
|
152
|
-
const style = getComputedStyle( floating.styles, selectionOffsets );
|
|
153
108
|
|
|
154
|
-
|
|
109
|
+
useLayoutEffect( () => {
|
|
110
|
+
refs.setReference( anchor );
|
|
111
|
+
|
|
112
|
+
return () => refs.setReference( null );
|
|
113
|
+
}, [ anchor, refs ] );
|
|
155
114
|
|
|
156
115
|
return (
|
|
157
116
|
<FloatingPortal id={ CANVAS_WRAPPER_ID }>
|
|
158
|
-
<Box
|
|
159
|
-
|
|
160
|
-
style={ {
|
|
161
|
-
...floating.styles,
|
|
162
|
-
pointerEvents: 'none',
|
|
163
|
-
} }
|
|
164
|
-
role="presentation"
|
|
165
|
-
{ ...getFloatingProps( { style } ) }
|
|
166
|
-
>
|
|
167
|
-
{ floating.styles.transform && (
|
|
168
|
-
<Box
|
|
169
|
-
sx={ {
|
|
170
|
-
position: 'relative',
|
|
171
|
-
transform: 'translateY(-100%)',
|
|
172
|
-
height: 'max-content',
|
|
173
|
-
} }
|
|
174
|
-
>
|
|
175
|
-
<InlineEditorToolbar
|
|
176
|
-
editor={ editor }
|
|
177
|
-
elementId={ id }
|
|
178
|
-
sx={ {
|
|
179
|
-
transform: 'translateX(-50%)',
|
|
180
|
-
} }
|
|
181
|
-
/>
|
|
182
|
-
</Box>
|
|
183
|
-
) }
|
|
117
|
+
<Box ref={ refs.setFloating } role="presentation" style={ { ...floatingStyles, pointerEvents: 'none' } }>
|
|
118
|
+
<InlineEditorToolbar editor={ editor } elementId={ id } />
|
|
184
119
|
</Box>
|
|
185
120
|
</FloatingPortal>
|
|
186
121
|
);
|
|
187
122
|
};
|
|
188
|
-
|
|
189
|
-
const getInlineEditorElement = ( elementWrapper: HTMLElement, expectedTag: string | null ) => {
|
|
190
|
-
return ! expectedTag ? null : ( elementWrapper.querySelector( expectedTag ) as HTMLDivElement );
|
|
191
|
-
};
|
|
192
|
-
|
|
193
|
-
// Elements out of iframe and canvas don't trigger "onClickAway" which unmounts the editor
|
|
194
|
-
// since they are not part of the iframes owner document.
|
|
195
|
-
// We need to manually add listeners to these elements to unmount the editor when they are clicked.
|
|
196
|
-
const useOnClickOutsideIframe = ( handleUnmount: () => void ) => {
|
|
197
|
-
const asyncUnmountInlineEditor = React.useCallback( () => queueMicrotask( handleUnmount ), [ handleUnmount ] );
|
|
198
|
-
|
|
199
|
-
useEffect( () => {
|
|
200
|
-
EDITOR_ELEMENTS_OUT_OF_IFRAME.forEach(
|
|
201
|
-
( selector ) =>
|
|
202
|
-
document?.querySelector( selector )?.addEventListener( 'mousedown', asyncUnmountInlineEditor )
|
|
203
|
-
);
|
|
204
|
-
|
|
205
|
-
return () =>
|
|
206
|
-
EDITOR_ELEMENTS_OUT_OF_IFRAME.forEach(
|
|
207
|
-
( selector ) =>
|
|
208
|
-
document?.querySelector( selector )?.removeEventListener( 'mousedown', asyncUnmountInlineEditor )
|
|
209
|
-
);
|
|
210
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
211
|
-
}, [] );
|
|
212
|
-
};
|
|
@@ -1,9 +1,35 @@
|
|
|
1
|
-
import { type CSSProperties } from 'react';
|
|
1
|
+
import { type CSSProperties, useCallback, useEffect, useState } from 'react';
|
|
2
2
|
import { type InlineEditorToolbarProps } from '@elementor/editor-controls';
|
|
3
3
|
import { type V1Element } from '@elementor/editor-elements';
|
|
4
|
+
import { type MiddlewareReturn, type MiddlewareState } from '@floating-ui/react';
|
|
4
5
|
|
|
5
6
|
import { type LegacyWindow } from '../../types';
|
|
6
7
|
|
|
8
|
+
const TOP_BAR_SELECTOR = '#elementor-editor-wrapper-v2';
|
|
9
|
+
const NAVIGATOR_SELECTOR = '#elementor-navigator';
|
|
10
|
+
const EDITING_PANEL = '#elementor-panel';
|
|
11
|
+
|
|
12
|
+
const EDITOR_ELEMENTS_OUT_OF_IFRAME = [ TOP_BAR_SELECTOR, NAVIGATOR_SELECTOR, EDITING_PANEL ];
|
|
13
|
+
|
|
14
|
+
export const EDITOR_WRAPPER_SELECTOR = 'inline-editor-wrapper';
|
|
15
|
+
|
|
16
|
+
const TOOLBAR_ANCHOR_ID_PREFIX = 'inline-editing-toolbar-anchor';
|
|
17
|
+
|
|
18
|
+
const TOOLBAR_ANCHOR_STATIC_STYLES: CSSProperties = {
|
|
19
|
+
backgroundColor: 'transparent',
|
|
20
|
+
border: 'none',
|
|
21
|
+
outline: 'none',
|
|
22
|
+
boxShadow: 'none',
|
|
23
|
+
padding: '0',
|
|
24
|
+
margin: '0',
|
|
25
|
+
borderRadius: '0',
|
|
26
|
+
overflow: 'hidden',
|
|
27
|
+
opacity: '0',
|
|
28
|
+
pointerEvents: 'none',
|
|
29
|
+
position: 'absolute',
|
|
30
|
+
display: 'block',
|
|
31
|
+
};
|
|
32
|
+
|
|
7
33
|
export type Editor = InlineEditorToolbarProps[ 'editor' ];
|
|
8
34
|
export type EditorView = Editor[ 'view' ];
|
|
9
35
|
|
|
@@ -24,62 +50,134 @@ export const getWidgetType = ( container: V1Element | null ) => {
|
|
|
24
50
|
return container?.model?.get( 'widgetType' ) ?? container?.model?.get( 'elType' ) ?? null;
|
|
25
51
|
};
|
|
26
52
|
|
|
27
|
-
export const
|
|
28
|
-
|
|
53
|
+
export const getInlineEditorElement = ( elementWrapper: HTMLElement, expectedTag: string | null ) => {
|
|
54
|
+
return ! expectedTag ? null : ( elementWrapper.querySelector( expectedTag ) as HTMLDivElement );
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
// Elements out of iframe and canvas don't trigger "onClickAway" which unmounts the editor
|
|
58
|
+
// since they are not part of the iframes owner document.
|
|
59
|
+
// We need to manually add listeners to these elements to unmount the editor when they are clicked.
|
|
60
|
+
export const useOnClickOutsideIframe = ( handleUnmount: () => void ) => {
|
|
61
|
+
const asyncUnmountInlineEditor = useCallback( () => queueMicrotask( handleUnmount ), [ handleUnmount ] );
|
|
62
|
+
|
|
63
|
+
useEffect( () => {
|
|
64
|
+
EDITOR_ELEMENTS_OUT_OF_IFRAME.forEach(
|
|
65
|
+
( selector ) =>
|
|
66
|
+
document?.querySelector( selector )?.addEventListener( 'mousedown', asyncUnmountInlineEditor )
|
|
67
|
+
);
|
|
68
|
+
|
|
69
|
+
return () =>
|
|
70
|
+
EDITOR_ELEMENTS_OUT_OF_IFRAME.forEach(
|
|
71
|
+
( selector ) =>
|
|
72
|
+
document?.querySelector( selector )?.removeEventListener( 'mousedown', asyncUnmountInlineEditor )
|
|
73
|
+
);
|
|
74
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
75
|
+
}, [] );
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
export const useRenderToolbar = ( ownerDocument: Document, id: string ) => {
|
|
79
|
+
const [ anchor, setAnchor ] = useState< HTMLElement | null >( null );
|
|
80
|
+
|
|
81
|
+
const onSelectionEnd = ( view: EditorView ) => {
|
|
82
|
+
const hasSelection = ! view.state.selection.empty;
|
|
83
|
+
|
|
84
|
+
removeToolbarAnchor( ownerDocument, id );
|
|
85
|
+
|
|
86
|
+
if ( hasSelection ) {
|
|
87
|
+
setAnchor( createAnchorBasedOnSelection( ownerDocument, id ) );
|
|
88
|
+
} else {
|
|
89
|
+
setAnchor( null );
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
return { onSelectionEnd, anchor };
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
const createAnchorBasedOnSelection = ( ownerDocument: Document, id: string ): HTMLElement | null => {
|
|
97
|
+
const frameWindow = ownerDocument.defaultView;
|
|
29
98
|
const selection = frameWindow?.getSelection();
|
|
30
|
-
const editorContainer = view.dom;
|
|
31
99
|
|
|
32
|
-
if ( ! selection
|
|
100
|
+
if ( ! selection ) {
|
|
33
101
|
return null;
|
|
34
102
|
}
|
|
35
103
|
|
|
36
104
|
const range = selection.getRangeAt( 0 );
|
|
37
105
|
const selectionRect = range.getBoundingClientRect();
|
|
38
|
-
const
|
|
106
|
+
const bodyRect = ownerDocument.body.getBoundingClientRect();
|
|
107
|
+
const toolbarAnchor = ownerDocument.createElement( 'span' );
|
|
39
108
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
109
|
+
styleToolbarAnchor( toolbarAnchor, selectionRect, bodyRect );
|
|
110
|
+
toolbarAnchor.setAttribute( 'id', getToolbarAnchorId( id ) );
|
|
43
111
|
|
|
44
|
-
|
|
112
|
+
ownerDocument.body.appendChild( toolbarAnchor );
|
|
45
113
|
|
|
46
|
-
|
|
47
|
-
|
|
114
|
+
return toolbarAnchor;
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
export const removeToolbarAnchor = ( ownerDocument: Document, id: string ) => {
|
|
118
|
+
const toolbarAnchor = getToolbarAnchor( ownerDocument, id );
|
|
48
119
|
|
|
49
|
-
|
|
120
|
+
if ( toolbarAnchor ) {
|
|
121
|
+
ownerDocument.body.removeChild( toolbarAnchor );
|
|
122
|
+
}
|
|
50
123
|
};
|
|
51
124
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
: {
|
|
63
|
-
|
|
64
|
-
|
|
125
|
+
const getToolbarAnchorId = ( id: string ) => `${ TOOLBAR_ANCHOR_ID_PREFIX }-${ id }`;
|
|
126
|
+
|
|
127
|
+
export const getToolbarAnchor = ( ownerDocument: Document, id: string ) =>
|
|
128
|
+
ownerDocument.getElementById( getToolbarAnchorId( id ) ) as HTMLElement | null;
|
|
129
|
+
|
|
130
|
+
const styleToolbarAnchor = ( anchor: HTMLElement, selectionRect: DOMRect, bodyRect: DOMRect ) => {
|
|
131
|
+
const { width, height } = selectionRect;
|
|
132
|
+
|
|
133
|
+
Object.assign( anchor.style, {
|
|
134
|
+
...TOOLBAR_ANCHOR_STATIC_STYLES,
|
|
135
|
+
top: `${ selectionRect.top - bodyRect.top }px`,
|
|
136
|
+
left: `${ selectionRect.left - bodyRect.left }px`,
|
|
137
|
+
width: `${ width }px`,
|
|
138
|
+
height: `${ height }px`,
|
|
139
|
+
} );
|
|
65
140
|
};
|
|
66
141
|
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
|
|
142
|
+
export const horizontalShifterMiddleware: {
|
|
143
|
+
name: string;
|
|
144
|
+
fn: ( state: MiddlewareState ) => MiddlewareReturn;
|
|
145
|
+
} = {
|
|
146
|
+
name: 'horizontalShifter',
|
|
147
|
+
fn( state ) {
|
|
148
|
+
const {
|
|
149
|
+
x: left,
|
|
150
|
+
y: top,
|
|
151
|
+
elements: { reference: anchor, floating },
|
|
152
|
+
} = state;
|
|
70
153
|
|
|
71
|
-
|
|
72
|
-
|
|
154
|
+
const newState: MiddlewareReturn = {
|
|
155
|
+
...state,
|
|
156
|
+
x: left,
|
|
157
|
+
y: top,
|
|
158
|
+
};
|
|
73
159
|
|
|
74
|
-
|
|
75
|
-
return null;
|
|
76
|
-
}
|
|
160
|
+
const isLeftOverflown = left < 0;
|
|
77
161
|
|
|
78
|
-
|
|
162
|
+
if ( isLeftOverflown ) {
|
|
163
|
+
newState.x = 0;
|
|
79
164
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
165
|
+
return newState;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
const anchorRect = anchor.getBoundingClientRect();
|
|
169
|
+
const right = left + floating.offsetWidth;
|
|
170
|
+
const documentWidth = ( anchor as HTMLElement ).ownerDocument.body.offsetWidth;
|
|
171
|
+
const isRightOverflown = right > documentWidth && anchorRect.right < right;
|
|
172
|
+
|
|
173
|
+
if ( isRightOverflown ) {
|
|
174
|
+
const diff = right - documentWidth;
|
|
175
|
+
|
|
176
|
+
newState.x = left - diff;
|
|
177
|
+
|
|
178
|
+
return newState;
|
|
179
|
+
}
|
|
83
180
|
|
|
84
|
-
|
|
181
|
+
return newState;
|
|
182
|
+
},
|
|
85
183
|
};
|