@trafica/editor 1.0.46 → 1.0.48
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 +76 -126
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +76 -126
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1038,26 +1038,33 @@ function renderCodeBlock(node, path) {
|
|
|
1038
1038
|
return wrapper;
|
|
1039
1039
|
}
|
|
1040
1040
|
function renderImage(node, path) {
|
|
1041
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
1041
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
1042
1042
|
const wrapper = document.createElement("figure");
|
|
1043
1043
|
wrapper.dataset.blockPath = JSON.stringify(path);
|
|
1044
1044
|
wrapper.dataset.imagePath = JSON.stringify(path);
|
|
1045
1045
|
wrapper.contentEditable = "false";
|
|
1046
1046
|
const align = (_a = node.attrs) == null ? void 0 : _a.align;
|
|
1047
|
+
const fx = (_b = node.attrs) == null ? void 0 : _b.x;
|
|
1048
|
+
const fy = (_c = node.attrs) == null ? void 0 : _c.y;
|
|
1047
1049
|
wrapper.className = [
|
|
1048
1050
|
"editor-image-wrapper",
|
|
1049
|
-
|
|
1050
|
-
align === "
|
|
1051
|
-
align === "
|
|
1051
|
+
fx !== void 0 ? "editor-image-floating" : "",
|
|
1052
|
+
!fx && align === "center" ? "editor-image-center" : "",
|
|
1053
|
+
!fx && align === "right" ? "editor-image-right" : "",
|
|
1054
|
+
!fx && align === "left" ? "editor-image-left" : ""
|
|
1052
1055
|
].filter(Boolean).join(" ");
|
|
1056
|
+
if (fx !== void 0) {
|
|
1057
|
+
wrapper.style.left = `${fx}px`;
|
|
1058
|
+
wrapper.style.top = `${fy != null ? fy : 0}px`;
|
|
1059
|
+
}
|
|
1053
1060
|
const img = document.createElement("img");
|
|
1054
|
-
img.src = (
|
|
1055
|
-
img.alt = (
|
|
1061
|
+
img.src = (_e = (_d = node.attrs) == null ? void 0 : _d.src) != null ? _e : "";
|
|
1062
|
+
img.alt = (_g = (_f = node.attrs) == null ? void 0 : _f.alt) != null ? _g : "";
|
|
1056
1063
|
img.className = "editor-image";
|
|
1057
1064
|
img.draggable = false;
|
|
1058
|
-
if ((
|
|
1065
|
+
if ((_h = node.attrs) == null ? void 0 : _h.width) img.style.width = `${node.attrs.width}px`;
|
|
1059
1066
|
wrapper.appendChild(img);
|
|
1060
|
-
const caption = (
|
|
1067
|
+
const caption = (_i = node.attrs) == null ? void 0 : _i.caption;
|
|
1061
1068
|
if (caption !== void 0) {
|
|
1062
1069
|
const figcaption = document.createElement("figcaption");
|
|
1063
1070
|
figcaption.className = "editor-image-caption";
|
|
@@ -1644,7 +1651,7 @@ var htmlSerializer = {
|
|
|
1644
1651
|
}
|
|
1645
1652
|
};
|
|
1646
1653
|
function serializeBlock(node, idCounts = /* @__PURE__ */ new Map(), inCell = false) {
|
|
1647
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A;
|
|
1654
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C;
|
|
1648
1655
|
switch (node.type) {
|
|
1649
1656
|
case "paragraph": {
|
|
1650
1657
|
const alignVal = (_a = node.attrs) == null ? void 0 : _a.align;
|
|
@@ -1696,16 +1703,19 @@ function serializeBlock(node, idCounts = /* @__PURE__ */ new Map(), inCell = fal
|
|
|
1696
1703
|
const width = ((_m = node.attrs) == null ? void 0 : _m.width) ? ` width="${node.attrs.width}"` : "";
|
|
1697
1704
|
const align = ((_n = node.attrs) == null ? void 0 : _n.align) ? ` data-align="${node.attrs.align}"` : "";
|
|
1698
1705
|
const caption = ((_o = node.attrs) == null ? void 0 : _o.caption) ? escapeHTML(node.attrs.caption) : "";
|
|
1706
|
+
const x = (_p = node.attrs) == null ? void 0 : _p.x;
|
|
1707
|
+
const y = (_q = node.attrs) == null ? void 0 : _q.y;
|
|
1708
|
+
const posAttrs = x !== void 0 ? ` data-x="${Math.round(x)}" data-y="${Math.round(y != null ? y : 0)}" style="position:absolute;left:${Math.round(x)}px;top:${Math.round(y != null ? y : 0)}px;"` : "";
|
|
1699
1709
|
if (caption) {
|
|
1700
|
-
return `<figure${align}><img src="${src}" alt="${alt}"${width} /><figcaption>${caption}</figcaption></figure>`;
|
|
1710
|
+
return `<figure${align}${posAttrs}><img src="${src}" alt="${alt}"${width} /><figcaption>${caption}</figcaption></figure>`;
|
|
1701
1711
|
}
|
|
1702
|
-
return `<figure${align}><img src="${src}" alt="${alt}"${width} /></figure>`;
|
|
1712
|
+
return `<figure${align}${posAttrs}><img src="${src}" alt="${alt}"${width} /></figure>`;
|
|
1703
1713
|
}
|
|
1704
1714
|
case "horizontal_rule":
|
|
1705
1715
|
return "<hr />";
|
|
1706
1716
|
case "table": {
|
|
1707
1717
|
const rows = node.children.map((c) => serializeBlock(c)).join("");
|
|
1708
|
-
const colWidths = (
|
|
1718
|
+
const colWidths = (_s = (_r = node.attrs) == null ? void 0 : _r.colWidths) != null ? _s : [];
|
|
1709
1719
|
let colgroup = "";
|
|
1710
1720
|
if (colWidths.length > 0) {
|
|
1711
1721
|
const total = colWidths.reduce((s, w) => s + w, 0) || colWidths.length * 120;
|
|
@@ -1718,15 +1728,15 @@ function serializeBlock(node, idCounts = /* @__PURE__ */ new Map(), inCell = fal
|
|
|
1718
1728
|
return `<tr>${cells}</tr>`;
|
|
1719
1729
|
}
|
|
1720
1730
|
case "table_cell": {
|
|
1721
|
-
if ((
|
|
1722
|
-
const cs = ((
|
|
1723
|
-
const rs = ((
|
|
1731
|
+
if ((_t = node.attrs) == null ? void 0 : _t.covered) return "";
|
|
1732
|
+
const cs = ((_u = node.attrs) == null ? void 0 : _u.colspan) > 1 ? ` colspan="${(_v = node.attrs) == null ? void 0 : _v.colspan}"` : "";
|
|
1733
|
+
const rs = ((_w = node.attrs) == null ? void 0 : _w.rowspan) > 1 ? ` rowspan="${(_x = node.attrs) == null ? void 0 : _x.rowspan}"` : "";
|
|
1724
1734
|
return `<td${cs}${rs} style="border:1px solid #d1d5db;padding:0.5em 0.75em;vertical-align:top;min-width:40px;word-break:break-word;">${node.children.map((c) => serializeBlock(c, /* @__PURE__ */ new Map(), true)).join("")}</td>`;
|
|
1725
1735
|
}
|
|
1726
1736
|
case "table_header": {
|
|
1727
|
-
if ((
|
|
1728
|
-
const cs = ((
|
|
1729
|
-
const rs = ((
|
|
1737
|
+
if ((_y = node.attrs) == null ? void 0 : _y.covered) return "";
|
|
1738
|
+
const cs = ((_z = node.attrs) == null ? void 0 : _z.colspan) > 1 ? ` colspan="${(_A = node.attrs) == null ? void 0 : _A.colspan}"` : "";
|
|
1739
|
+
const rs = ((_B = node.attrs) == null ? void 0 : _B.rowspan) > 1 ? ` rowspan="${(_C = node.attrs) == null ? void 0 : _C.rowspan}"` : "";
|
|
1730
1740
|
return `<th${cs}${rs} style="border:1px solid #d1d5db;padding:0.5em 0.75em;vertical-align:top;min-width:40px;word-break:break-word;background:#f9fafb;font-weight:600;text-align:left;">${node.children.map((c) => serializeBlock(c, /* @__PURE__ */ new Map(), true)).join("")}</th>`;
|
|
1731
1741
|
}
|
|
1732
1742
|
default:
|
|
@@ -1880,6 +1890,10 @@ function parseHTMLNode(node) {
|
|
|
1880
1890
|
const img = el.querySelector("img");
|
|
1881
1891
|
const caption = (_h = (_g = el.querySelector("figcaption")) == null ? void 0 : _g.textContent) != null ? _h : "";
|
|
1882
1892
|
const align = (_i = el.getAttribute("data-align")) != null ? _i : "";
|
|
1893
|
+
const dxRaw = el.getAttribute("data-x");
|
|
1894
|
+
const dyRaw = el.getAttribute("data-y");
|
|
1895
|
+
const fx = dxRaw !== null ? parseFloat(dxRaw) : void 0;
|
|
1896
|
+
const fy = dyRaw !== null ? parseFloat(dyRaw) : void 0;
|
|
1883
1897
|
if (img) {
|
|
1884
1898
|
return {
|
|
1885
1899
|
type: "image",
|
|
@@ -1888,7 +1902,8 @@ function parseHTMLNode(node) {
|
|
|
1888
1902
|
alt: (_k = img.getAttribute("alt")) != null ? _k : "",
|
|
1889
1903
|
...img.getAttribute("width") ? { width: parseFloat(img.getAttribute("width")) } : {},
|
|
1890
1904
|
...align ? { align } : {},
|
|
1891
|
-
...caption ? { caption } : {}
|
|
1905
|
+
...caption ? { caption } : {},
|
|
1906
|
+
...fx !== void 0 && !isNaN(fx) ? { x: fx, y: fy != null ? fy : 0 } : {}
|
|
1892
1907
|
},
|
|
1893
1908
|
children: []
|
|
1894
1909
|
};
|
|
@@ -8036,7 +8051,7 @@ function EditorCore({
|
|
|
8036
8051
|
const isComposingRef = react.useRef(false);
|
|
8037
8052
|
const stateRef = react.useRef(engine.getState());
|
|
8038
8053
|
const [selectedImagePath, setSelectedImagePath] = react.useState(null);
|
|
8039
|
-
const [
|
|
8054
|
+
const [imageDragging, setImageDragging] = react.useState(false);
|
|
8040
8055
|
const [findReplaceOpen, setFindReplaceOpen] = react.useState(false);
|
|
8041
8056
|
const [findReplaceMode, setFindReplaceMode] = react.useState("find");
|
|
8042
8057
|
const [linkPopupOpen, setLinkPopupOpen] = react.useState(false);
|
|
@@ -8519,19 +8534,19 @@ function EditorCore({
|
|
|
8519
8534
|
e.preventDefault();
|
|
8520
8535
|
const path = JSON.parse(fig.dataset.imagePath);
|
|
8521
8536
|
setSelectedImagePath(path);
|
|
8522
|
-
|
|
8523
|
-
|
|
8524
|
-
|
|
8525
|
-
|
|
8526
|
-
|
|
8527
|
-
|
|
8528
|
-
|
|
8529
|
-
|
|
8530
|
-
|
|
8531
|
-
|
|
8532
|
-
|
|
8533
|
-
|
|
8534
|
-
}
|
|
8537
|
+
const imgEl = fig.querySelector("img");
|
|
8538
|
+
const figRect = fig.getBoundingClientRect();
|
|
8539
|
+
imageDragRef.current = {
|
|
8540
|
+
imagePath: path,
|
|
8541
|
+
startX: e.clientX,
|
|
8542
|
+
startY: e.clientY,
|
|
8543
|
+
active: false,
|
|
8544
|
+
ghostW: Math.min(figRect.width || 300, 320),
|
|
8545
|
+
ghostH: Math.min(figRect.height || 200, 200),
|
|
8546
|
+
ghostSrc: (imgEl == null ? void 0 : imgEl.src) || "",
|
|
8547
|
+
offsetX: e.clientX - figRect.left,
|
|
8548
|
+
offsetY: e.clientY - figRect.top
|
|
8549
|
+
};
|
|
8535
8550
|
return;
|
|
8536
8551
|
}
|
|
8537
8552
|
setSelectedImagePath(null);
|
|
@@ -8618,39 +8633,47 @@ function EditorCore({
|
|
|
8618
8633
|
};
|
|
8619
8634
|
}, [engine]);
|
|
8620
8635
|
react.useEffect(() => {
|
|
8621
|
-
const DRAG_THRESHOLD =
|
|
8636
|
+
const DRAG_THRESHOLD = 4;
|
|
8622
8637
|
const onMouseMove = (e) => {
|
|
8623
8638
|
const drag = imageDragRef.current;
|
|
8624
8639
|
if (!drag) return;
|
|
8625
8640
|
const dx = e.clientX - drag.startX;
|
|
8626
8641
|
const dy = e.clientY - drag.startY;
|
|
8627
8642
|
if (!drag.active && Math.sqrt(dx * dx + dy * dy) < DRAG_THRESHOLD) return;
|
|
8628
|
-
drag.active
|
|
8643
|
+
if (!drag.active) {
|
|
8644
|
+
drag.active = true;
|
|
8645
|
+
setImageDragging(true);
|
|
8646
|
+
document.body.style.userSelect = "none";
|
|
8647
|
+
}
|
|
8629
8648
|
const container = containerRef.current;
|
|
8630
|
-
|
|
8631
|
-
|
|
8632
|
-
|
|
8633
|
-
|
|
8634
|
-
|
|
8635
|
-
|
|
8636
|
-
|
|
8637
|
-
|
|
8638
|
-
|
|
8639
|
-
|
|
8640
|
-
|
|
8649
|
+
if (!container) return;
|
|
8650
|
+
const cr = container.getBoundingClientRect();
|
|
8651
|
+
const x = Math.max(0, e.clientX - cr.left - drag.offsetX + container.scrollLeft);
|
|
8652
|
+
const y = Math.max(0, e.clientY - cr.top - drag.offsetY + container.scrollTop);
|
|
8653
|
+
const fig = container.querySelector(
|
|
8654
|
+
`[data-image-path="${JSON.stringify(drag.imagePath)}"]`
|
|
8655
|
+
);
|
|
8656
|
+
if (fig) {
|
|
8657
|
+
fig.style.position = "absolute";
|
|
8658
|
+
fig.style.left = `${x}px`;
|
|
8659
|
+
fig.style.top = `${y}px`;
|
|
8660
|
+
fig.style.margin = "0";
|
|
8661
|
+
fig.style.zIndex = "10";
|
|
8662
|
+
}
|
|
8641
8663
|
};
|
|
8642
8664
|
const onMouseUp = (e) => {
|
|
8643
8665
|
const drag = imageDragRef.current;
|
|
8644
8666
|
if (!drag) return;
|
|
8645
8667
|
imageDragRef.current = null;
|
|
8646
|
-
|
|
8647
|
-
|
|
8648
|
-
|
|
8649
|
-
}
|
|
8668
|
+
document.body.style.userSelect = "";
|
|
8669
|
+
setImageDragging(false);
|
|
8670
|
+
if (!drag.active) return;
|
|
8650
8671
|
const container = containerRef.current;
|
|
8651
|
-
|
|
8652
|
-
|
|
8653
|
-
|
|
8672
|
+
if (!container) return;
|
|
8673
|
+
const cr = container.getBoundingClientRect();
|
|
8674
|
+
const x = Math.max(0, e.clientX - cr.left - drag.offsetX + container.scrollLeft);
|
|
8675
|
+
const y = Math.max(0, e.clientY - cr.top - drag.offsetY + container.scrollTop);
|
|
8676
|
+
setImageAttr(drag.imagePath, { x: Math.round(x), y: Math.round(y) })(engine);
|
|
8654
8677
|
};
|
|
8655
8678
|
document.addEventListener("mousemove", onMouseMove);
|
|
8656
8679
|
document.addEventListener("mouseup", onMouseUp);
|
|
@@ -8776,19 +8799,6 @@ function EditorCore({
|
|
|
8776
8799
|
].join(" ")
|
|
8777
8800
|
}
|
|
8778
8801
|
),
|
|
8779
|
-
imageDragState && (() => {
|
|
8780
|
-
const container = containerRef.current;
|
|
8781
|
-
if (!container) return null;
|
|
8782
|
-
const cr = container.getBoundingClientRect();
|
|
8783
|
-
const relY = imageDragState.dropIndicatorClientY - cr.top + container.scrollTop;
|
|
8784
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
8785
|
-
"div",
|
|
8786
|
-
{
|
|
8787
|
-
className: "editor-image-drop-indicator",
|
|
8788
|
-
style: { top: relY }
|
|
8789
|
-
}
|
|
8790
|
-
);
|
|
8791
|
-
})(),
|
|
8792
8802
|
linkTooltip && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
8793
8803
|
"div",
|
|
8794
8804
|
{
|
|
@@ -8849,26 +8859,6 @@ function EditorCore({
|
|
|
8849
8859
|
onClose: () => setSelectedImagePath(null)
|
|
8850
8860
|
}
|
|
8851
8861
|
),
|
|
8852
|
-
imageDragState && /* @__PURE__ */ jsxRuntime.jsx(
|
|
8853
|
-
"div",
|
|
8854
|
-
{
|
|
8855
|
-
className: "editor-image-drag-ghost",
|
|
8856
|
-
style: {
|
|
8857
|
-
left: imageDragState.ghostX,
|
|
8858
|
-
top: imageDragState.ghostY,
|
|
8859
|
-
width: imageDragState.ghostW,
|
|
8860
|
-
height: imageDragState.ghostH
|
|
8861
|
-
},
|
|
8862
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
8863
|
-
"img",
|
|
8864
|
-
{
|
|
8865
|
-
src: imageDragState.ghostSrc,
|
|
8866
|
-
alt: "",
|
|
8867
|
-
style: { width: "100%", height: "100%", objectFit: "contain", display: "block" }
|
|
8868
|
-
}
|
|
8869
|
-
)
|
|
8870
|
-
}
|
|
8871
|
-
),
|
|
8872
8862
|
!readOnly && /* @__PURE__ */ jsxRuntime.jsx(
|
|
8873
8863
|
"div",
|
|
8874
8864
|
{
|
|
@@ -8891,46 +8881,6 @@ function EditorCore({
|
|
|
8891
8881
|
}
|
|
8892
8882
|
);
|
|
8893
8883
|
}
|
|
8894
|
-
function getImageDropTarget(container, clientY, imagePath) {
|
|
8895
|
-
const fallback = { dropIndex: imagePath[0], indicatorClientY: clientY };
|
|
8896
|
-
if (!container) return fallback;
|
|
8897
|
-
const blocks = Array.from(
|
|
8898
|
-
container.querySelectorAll(":scope > [data-block-path]")
|
|
8899
|
-
);
|
|
8900
|
-
if (blocks.length === 0) return fallback;
|
|
8901
|
-
const gaps = [];
|
|
8902
|
-
gaps.push({ y: blocks[0].getBoundingClientRect().top, index: 0 });
|
|
8903
|
-
for (let i = 0; i < blocks.length - 1; i++) {
|
|
8904
|
-
const bottom = blocks[i].getBoundingClientRect().bottom;
|
|
8905
|
-
const top = blocks[i + 1].getBoundingClientRect().top;
|
|
8906
|
-
gaps.push({ y: (bottom + top) / 2, index: i + 1 });
|
|
8907
|
-
}
|
|
8908
|
-
gaps.push({ y: blocks[blocks.length - 1].getBoundingClientRect().bottom, index: blocks.length });
|
|
8909
|
-
let best = gaps[0];
|
|
8910
|
-
let bestDist = Math.abs(clientY - best.y);
|
|
8911
|
-
for (const gap of gaps) {
|
|
8912
|
-
const dist = Math.abs(clientY - gap.y);
|
|
8913
|
-
if (dist < bestDist) {
|
|
8914
|
-
bestDist = dist;
|
|
8915
|
-
best = gap;
|
|
8916
|
-
}
|
|
8917
|
-
}
|
|
8918
|
-
return { dropIndex: best.index, indicatorClientY: best.y };
|
|
8919
|
-
}
|
|
8920
|
-
function moveImageInDoc(imagePath, targetIndex, engine) {
|
|
8921
|
-
const state = engine.getState();
|
|
8922
|
-
const imageNode = getNodeAtPath(state.doc, imagePath);
|
|
8923
|
-
if (!imageNode) return;
|
|
8924
|
-
const oldIndex = imagePath[imagePath.length - 1];
|
|
8925
|
-
const parentPath = imagePath.slice(0, -1);
|
|
8926
|
-
let adj = targetIndex > oldIndex ? targetIndex - 1 : targetIndex;
|
|
8927
|
-
adj = Math.max(0, Math.min(state.doc.children.length - 1, adj));
|
|
8928
|
-
if (adj === oldIndex) return;
|
|
8929
|
-
const tr = createTransaction();
|
|
8930
|
-
tr.steps.push({ type: "delete_node", path: imagePath });
|
|
8931
|
-
tr.steps.push({ type: "insert_node", parentPath, index: adj, node: imageNode });
|
|
8932
|
-
engine.dispatch(tr);
|
|
8933
|
-
}
|
|
8934
8884
|
var BLOCK_TAGS = "p|h[1-6]|ul|ol|li|blockquote|pre|figure|table|thead|tbody|tr|th|td";
|
|
8935
8885
|
var _OPEN_ONLY_RE = new RegExp(`^<(${BLOCK_TAGS})(?:\\s[^>]*)?>$`, "i");
|
|
8936
8886
|
var _CLOSE_ONLY_RE = new RegExp(`^<\\/(${BLOCK_TAGS})>$`, "i");
|