@sofereditor/react 0.2.0 → 0.3.1
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.cjs +1293 -466
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +51 -4
- package/dist/index.d.ts +51 -4
- package/dist/index.js +1239 -393
- package/dist/index.js.map +1 -1
- package/package.json +10 -9
package/dist/index.js
CHANGED
|
@@ -1,16 +1,23 @@
|
|
|
1
1
|
// src/Editor.tsx
|
|
2
2
|
import {
|
|
3
|
-
useCallback as
|
|
4
|
-
useEffect as
|
|
5
|
-
useLayoutEffect as
|
|
3
|
+
useCallback as useCallback7,
|
|
4
|
+
useEffect as useEffect9,
|
|
5
|
+
useLayoutEffect as useLayoutEffect5,
|
|
6
6
|
useMemo as useMemo4,
|
|
7
|
-
useRef as
|
|
7
|
+
useRef as useRef11,
|
|
8
|
+
useState as useState10
|
|
8
9
|
} from "react";
|
|
9
10
|
import {
|
|
10
11
|
deleteBackward,
|
|
11
12
|
deleteForward,
|
|
13
|
+
deleteSelection,
|
|
14
|
+
encodeSelection,
|
|
12
15
|
insertParagraph,
|
|
13
|
-
|
|
16
|
+
insertSlice,
|
|
17
|
+
insertText,
|
|
18
|
+
serializeSelection,
|
|
19
|
+
sliceToText,
|
|
20
|
+
SOFER_MIME
|
|
14
21
|
} from "@sofereditor/core";
|
|
15
22
|
|
|
16
23
|
// src/dom-bridge.ts
|
|
@@ -211,6 +218,7 @@ function locatePoint(root, pos) {
|
|
|
211
218
|
let remaining = Math.max(0, pos.offset - containerStart);
|
|
212
219
|
let result = null;
|
|
213
220
|
let lastImg = null;
|
|
221
|
+
let lastText = null;
|
|
214
222
|
function visit(n) {
|
|
215
223
|
if (result) return;
|
|
216
224
|
if (n.nodeType === Node.TEXT_NODE) {
|
|
@@ -221,6 +229,7 @@ function locatePoint(root, pos) {
|
|
|
221
229
|
}
|
|
222
230
|
remaining -= len;
|
|
223
231
|
lastImg = null;
|
|
232
|
+
lastText = n;
|
|
224
233
|
return;
|
|
225
234
|
}
|
|
226
235
|
if (n.nodeType !== Node.ELEMENT_NODE) return;
|
|
@@ -250,6 +259,10 @@ function locatePoint(root, pos) {
|
|
|
250
259
|
const parent = lastImg.parentNode;
|
|
251
260
|
if (parent) return { node: parent, offset: indexInParent(lastImg) + 1 };
|
|
252
261
|
}
|
|
262
|
+
if (lastText) {
|
|
263
|
+
const t = lastText;
|
|
264
|
+
return { node: t, offset: (t.textContent ?? "").length };
|
|
265
|
+
}
|
|
253
266
|
return { node: container, offset: 0 };
|
|
254
267
|
}
|
|
255
268
|
function selectionsEqual(a, b) {
|
|
@@ -270,6 +283,9 @@ function applyDomSelection(root, modelSel) {
|
|
|
270
283
|
const anchorPt = locatePoint(root, modelSel.anchor);
|
|
271
284
|
const focusPt = locatePoint(root, modelSel.focus);
|
|
272
285
|
if (!anchorPt || !focusPt) return;
|
|
286
|
+
if (domSel.anchorNode === anchorPt.node && domSel.anchorOffset === anchorPt.offset && domSel.focusNode === focusPt.node && domSel.focusOffset === focusPt.offset) {
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
273
289
|
try {
|
|
274
290
|
domSel.removeAllRanges();
|
|
275
291
|
domSel.setBaseAndExtent(anchorPt.node, anchorPt.offset, focusPt.node, focusPt.offset);
|
|
@@ -277,22 +293,262 @@ function applyDomSelection(root, modelSel) {
|
|
|
277
293
|
}
|
|
278
294
|
}
|
|
279
295
|
|
|
296
|
+
// src/BehindImageSelectAffordance.tsx
|
|
297
|
+
import {
|
|
298
|
+
useCallback,
|
|
299
|
+
useEffect,
|
|
300
|
+
useLayoutEffect,
|
|
301
|
+
useState
|
|
302
|
+
} from "react";
|
|
303
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
304
|
+
var ACCENT = "#3b82f6";
|
|
305
|
+
function BehindImageSelectAffordance({
|
|
306
|
+
blockIndex,
|
|
307
|
+
offset,
|
|
308
|
+
cellIndex,
|
|
309
|
+
rootRef,
|
|
310
|
+
onSelect
|
|
311
|
+
}) {
|
|
312
|
+
const [rect, setRect] = useState(null);
|
|
313
|
+
const locateImage = useCallback(() => {
|
|
314
|
+
const root = rootRef.current;
|
|
315
|
+
if (!root) return null;
|
|
316
|
+
let container = null;
|
|
317
|
+
if (cellIndex != null) {
|
|
318
|
+
container = root.querySelector(
|
|
319
|
+
`[data-block-index="${blockIndex}"] [data-cell-index="${cellIndex}"]`
|
|
320
|
+
);
|
|
321
|
+
} else {
|
|
322
|
+
container = getFragmentForOffset(root, blockIndex, offset);
|
|
323
|
+
}
|
|
324
|
+
if (!container) return null;
|
|
325
|
+
const fragmentStart = container.dataset.fragmentStart ? Number.parseInt(container.dataset.fragmentStart, 10) || 0 : 0;
|
|
326
|
+
const localOffset = offset - fragmentStart;
|
|
327
|
+
return container.querySelector(
|
|
328
|
+
`img[data-embed="image"][data-embed-offset="${localOffset}"]`
|
|
329
|
+
);
|
|
330
|
+
}, [rootRef, blockIndex, offset, cellIndex]);
|
|
331
|
+
const measure = useCallback(() => {
|
|
332
|
+
const img = locateImage();
|
|
333
|
+
const root = rootRef.current;
|
|
334
|
+
if (!img || !root) {
|
|
335
|
+
setRect((prev) => prev === null ? prev : null);
|
|
336
|
+
return;
|
|
337
|
+
}
|
|
338
|
+
const r = img.getBoundingClientRect();
|
|
339
|
+
const rr = root.getBoundingClientRect();
|
|
340
|
+
const next = {
|
|
341
|
+
top: r.top - rr.top + root.scrollTop,
|
|
342
|
+
left: r.left - rr.left + root.scrollLeft,
|
|
343
|
+
width: r.width,
|
|
344
|
+
height: r.height
|
|
345
|
+
};
|
|
346
|
+
setRect(
|
|
347
|
+
(prev) => prev && prev.top === next.top && prev.left === next.left && prev.width === next.width && prev.height === next.height ? prev : next
|
|
348
|
+
);
|
|
349
|
+
}, [locateImage, rootRef]);
|
|
350
|
+
useLayoutEffect(() => {
|
|
351
|
+
measure();
|
|
352
|
+
let cancelled = false;
|
|
353
|
+
const remeasure = () => {
|
|
354
|
+
if (!cancelled) measure();
|
|
355
|
+
};
|
|
356
|
+
const id = typeof requestAnimationFrame === "function" ? requestAnimationFrame(remeasure) : (queueMicrotask(remeasure), 0);
|
|
357
|
+
return () => {
|
|
358
|
+
cancelled = true;
|
|
359
|
+
if (typeof cancelAnimationFrame === "function" && typeof id === "number" && id > 0) {
|
|
360
|
+
cancelAnimationFrame(id);
|
|
361
|
+
}
|
|
362
|
+
};
|
|
363
|
+
}, [measure]);
|
|
364
|
+
useEffect(() => {
|
|
365
|
+
const root = rootRef.current;
|
|
366
|
+
if (!root) return;
|
|
367
|
+
const onScroll = () => measure();
|
|
368
|
+
window.addEventListener("resize", onScroll);
|
|
369
|
+
root.addEventListener("scroll", onScroll);
|
|
370
|
+
return () => {
|
|
371
|
+
window.removeEventListener("resize", onScroll);
|
|
372
|
+
root.removeEventListener("scroll", onScroll);
|
|
373
|
+
};
|
|
374
|
+
}, [measure, rootRef]);
|
|
375
|
+
if (!rect) return null;
|
|
376
|
+
const outlineStyle = {
|
|
377
|
+
position: "absolute",
|
|
378
|
+
top: rect.top,
|
|
379
|
+
left: rect.left,
|
|
380
|
+
width: rect.width,
|
|
381
|
+
height: rect.height,
|
|
382
|
+
border: `1.5px dashed ${ACCENT}`,
|
|
383
|
+
borderRadius: 2,
|
|
384
|
+
boxSizing: "border-box",
|
|
385
|
+
pointerEvents: "none",
|
|
386
|
+
zIndex: 4
|
|
387
|
+
};
|
|
388
|
+
const badgeStyle = {
|
|
389
|
+
position: "absolute",
|
|
390
|
+
top: rect.top - 2,
|
|
391
|
+
left: rect.left - 2,
|
|
392
|
+
width: 24,
|
|
393
|
+
height: 24,
|
|
394
|
+
display: "flex",
|
|
395
|
+
alignItems: "center",
|
|
396
|
+
justifyContent: "center",
|
|
397
|
+
background: ACCENT,
|
|
398
|
+
color: "#fff",
|
|
399
|
+
borderRadius: 4,
|
|
400
|
+
cursor: "pointer",
|
|
401
|
+
pointerEvents: "auto",
|
|
402
|
+
boxShadow: "0 1px 3px rgba(0,0,0,0.3)",
|
|
403
|
+
zIndex: 5
|
|
404
|
+
};
|
|
405
|
+
const onBadgeDown = (e) => {
|
|
406
|
+
if (e.button !== 0) return;
|
|
407
|
+
e.preventDefault();
|
|
408
|
+
e.stopPropagation();
|
|
409
|
+
onSelect();
|
|
410
|
+
};
|
|
411
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
412
|
+
/* @__PURE__ */ jsx("div", { style: outlineStyle, contentEditable: false, "aria-hidden": true }),
|
|
413
|
+
/* @__PURE__ */ jsx(
|
|
414
|
+
"div",
|
|
415
|
+
{
|
|
416
|
+
style: badgeStyle,
|
|
417
|
+
contentEditable: false,
|
|
418
|
+
onPointerDown: onBadgeDown,
|
|
419
|
+
role: "button",
|
|
420
|
+
"aria-label": "Selecionar imagem",
|
|
421
|
+
title: "Selecionar imagem",
|
|
422
|
+
children: /* @__PURE__ */ jsx(
|
|
423
|
+
"svg",
|
|
424
|
+
{
|
|
425
|
+
width: "14",
|
|
426
|
+
height: "14",
|
|
427
|
+
viewBox: "0 0 24 24",
|
|
428
|
+
fill: "none",
|
|
429
|
+
stroke: "currentColor",
|
|
430
|
+
strokeWidth: "2",
|
|
431
|
+
strokeLinecap: "round",
|
|
432
|
+
strokeLinejoin: "round",
|
|
433
|
+
"aria-hidden": true,
|
|
434
|
+
children: /* @__PURE__ */ jsx("path", { d: "M5 9l-3 3 3 3M9 5l3-3 3 3M15 19l-3 3-3-3M19 9l3 3-3 3M2 12h20M12 2v20" })
|
|
435
|
+
}
|
|
436
|
+
)
|
|
437
|
+
}
|
|
438
|
+
)
|
|
439
|
+
] });
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
// src/LinkHoverTooltip.tsx
|
|
443
|
+
import { createPortal } from "react-dom";
|
|
444
|
+
|
|
445
|
+
// src/platform.ts
|
|
446
|
+
var IS_MAC = (() => {
|
|
447
|
+
if (typeof navigator === "undefined") return false;
|
|
448
|
+
const platform = navigator.userAgentData?.platform || navigator.platform || navigator.userAgent || "";
|
|
449
|
+
return /mac|iphone|ipad|ipod/i.test(platform);
|
|
450
|
+
})();
|
|
451
|
+
var MOD_SYMBOL = IS_MAC ? "\u2318" : "\u2303";
|
|
452
|
+
function hasOpenModifier(e) {
|
|
453
|
+
return IS_MAC ? e.metaKey : e.ctrlKey;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
// src/LinkHoverTooltip.tsx
|
|
457
|
+
import { Fragment as Fragment2, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
458
|
+
var MAX_WIDTH = 360;
|
|
459
|
+
var GAP = 6;
|
|
460
|
+
function LinkHoverTooltip({ href, rect }) {
|
|
461
|
+
const above = rect.top > 48;
|
|
462
|
+
const viewportW = typeof window !== "undefined" ? window.innerWidth : MAX_WIDTH + 16;
|
|
463
|
+
const left = Math.max(8, Math.min(rect.left, viewportW - MAX_WIDTH - 8));
|
|
464
|
+
const style = {
|
|
465
|
+
position: "fixed",
|
|
466
|
+
left,
|
|
467
|
+
top: above ? rect.top - GAP : rect.bottom + GAP,
|
|
468
|
+
transform: above ? "translateY(-100%)" : void 0,
|
|
469
|
+
maxWidth: MAX_WIDTH,
|
|
470
|
+
background: "#1f2937",
|
|
471
|
+
color: "#fff",
|
|
472
|
+
fontSize: 12,
|
|
473
|
+
lineHeight: 1.4,
|
|
474
|
+
padding: "6px 9px",
|
|
475
|
+
borderRadius: 6,
|
|
476
|
+
boxShadow: "0 4px 14px rgba(0,0,0,0.28)",
|
|
477
|
+
zIndex: 60,
|
|
478
|
+
pointerEvents: "none"
|
|
479
|
+
};
|
|
480
|
+
const urlStyle = {
|
|
481
|
+
display: "block",
|
|
482
|
+
maxWidth: MAX_WIDTH - 18,
|
|
483
|
+
overflow: "hidden",
|
|
484
|
+
textOverflow: "ellipsis",
|
|
485
|
+
whiteSpace: "nowrap",
|
|
486
|
+
fontWeight: 600
|
|
487
|
+
};
|
|
488
|
+
const hintStyle = {
|
|
489
|
+
display: "flex",
|
|
490
|
+
alignItems: "center",
|
|
491
|
+
gap: 4,
|
|
492
|
+
marginTop: 3,
|
|
493
|
+
fontSize: 11,
|
|
494
|
+
opacity: 0.85
|
|
495
|
+
};
|
|
496
|
+
const keycapStyle = {
|
|
497
|
+
display: "inline-flex",
|
|
498
|
+
alignItems: "center",
|
|
499
|
+
justifyContent: "center",
|
|
500
|
+
minWidth: 16,
|
|
501
|
+
height: 16,
|
|
502
|
+
padding: "0 4px",
|
|
503
|
+
fontSize: 11,
|
|
504
|
+
fontFamily: "system-ui, -apple-system, sans-serif",
|
|
505
|
+
background: "rgba(255,255,255,0.16)",
|
|
506
|
+
border: "1px solid rgba(255,255,255,0.4)",
|
|
507
|
+
borderRadius: 4,
|
|
508
|
+
boxShadow: "inset 0 -1px 0 rgba(0,0,0,0.25)"
|
|
509
|
+
};
|
|
510
|
+
if (typeof document === "undefined") return /* @__PURE__ */ jsx2(Fragment2, {});
|
|
511
|
+
return createPortal(
|
|
512
|
+
/* @__PURE__ */ jsxs2("div", { style, contentEditable: false, "aria-hidden": true, role: "tooltip", children: [
|
|
513
|
+
/* @__PURE__ */ jsx2("span", { style: urlStyle, children: href }),
|
|
514
|
+
/* @__PURE__ */ jsxs2("span", { style: hintStyle, children: [
|
|
515
|
+
/* @__PURE__ */ jsx2("kbd", { style: keycapStyle, children: MOD_SYMBOL }),
|
|
516
|
+
/* @__PURE__ */ jsx2("span", { style: { opacity: 0.8 }, children: "+ clique para abrir" })
|
|
517
|
+
] })
|
|
518
|
+
] }),
|
|
519
|
+
document.body
|
|
520
|
+
);
|
|
521
|
+
}
|
|
522
|
+
|
|
280
523
|
// src/EditorContext.tsx
|
|
281
524
|
import { createContext, useContext } from "react";
|
|
282
525
|
|
|
283
526
|
// src/LinkDialog.tsx
|
|
284
527
|
import {
|
|
285
|
-
useEffect,
|
|
528
|
+
useEffect as useEffect2,
|
|
286
529
|
useRef,
|
|
287
|
-
useState
|
|
530
|
+
useState as useState2
|
|
288
531
|
} from "react";
|
|
289
|
-
|
|
532
|
+
|
|
533
|
+
// src/dialogCenterStyle.ts
|
|
534
|
+
var DIALOG_CENTER_STYLE = {
|
|
535
|
+
position: "fixed",
|
|
536
|
+
top: "50%",
|
|
537
|
+
left: "50%",
|
|
538
|
+
transform: "translate(-50%, -50%)",
|
|
539
|
+
margin: 0,
|
|
540
|
+
maxHeight: "90vh",
|
|
541
|
+
overflow: "auto"
|
|
542
|
+
};
|
|
543
|
+
|
|
544
|
+
// src/LinkDialog.tsx
|
|
545
|
+
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
290
546
|
function LinkDialog() {
|
|
291
547
|
const { linkRequest, resolveLinkRequest } = useEditorContext();
|
|
292
548
|
const dialogRef = useRef(null);
|
|
293
549
|
const inputRef = useRef(null);
|
|
294
|
-
const [href, setHref] =
|
|
295
|
-
|
|
550
|
+
const [href, setHref] = useState2("");
|
|
551
|
+
useEffect2(() => {
|
|
296
552
|
const dialog = dialogRef.current;
|
|
297
553
|
if (!dialog) return;
|
|
298
554
|
if (linkRequest) {
|
|
@@ -320,20 +576,21 @@ function LinkDialog() {
|
|
|
320
576
|
const onCancel = () => {
|
|
321
577
|
resolveLinkRequest(null);
|
|
322
578
|
};
|
|
323
|
-
return /* @__PURE__ */
|
|
579
|
+
return /* @__PURE__ */ jsx3(
|
|
324
580
|
"dialog",
|
|
325
581
|
{
|
|
326
582
|
ref: dialogRef,
|
|
327
583
|
className: "ed-link-dialog",
|
|
584
|
+
style: DIALOG_CENTER_STYLE,
|
|
328
585
|
onClose: onCancel,
|
|
329
586
|
onCancel: (e) => {
|
|
330
587
|
e.preventDefault();
|
|
331
588
|
onCancel();
|
|
332
589
|
},
|
|
333
|
-
children: /* @__PURE__ */
|
|
334
|
-
/* @__PURE__ */
|
|
335
|
-
/* @__PURE__ */
|
|
336
|
-
/* @__PURE__ */
|
|
590
|
+
children: /* @__PURE__ */ jsxs3("form", { onSubmit, className: "ed-link-dialog-form", children: [
|
|
591
|
+
/* @__PURE__ */ jsxs3("div", { className: "ed-link-dialog-row", children: [
|
|
592
|
+
/* @__PURE__ */ jsx3("label", { htmlFor: "ed-link-href", children: "URL" }),
|
|
593
|
+
/* @__PURE__ */ jsx3(
|
|
337
594
|
"input",
|
|
338
595
|
{
|
|
339
596
|
id: "ed-link-href",
|
|
@@ -347,11 +604,11 @@ function LinkDialog() {
|
|
|
347
604
|
}
|
|
348
605
|
)
|
|
349
606
|
] }),
|
|
350
|
-
/* @__PURE__ */
|
|
351
|
-
linkRequest.initialHref ? /* @__PURE__ */
|
|
352
|
-
/* @__PURE__ */
|
|
353
|
-
/* @__PURE__ */
|
|
354
|
-
/* @__PURE__ */
|
|
607
|
+
/* @__PURE__ */ jsxs3("div", { className: "ed-link-dialog-actions", children: [
|
|
608
|
+
linkRequest.initialHref ? /* @__PURE__ */ jsx3("button", { type: "button", onClick: onRemove, className: "ed-link-dialog-remove", children: "Remover link" }) : /* @__PURE__ */ jsx3("span", {}),
|
|
609
|
+
/* @__PURE__ */ jsxs3("div", { className: "ed-link-dialog-confirm", children: [
|
|
610
|
+
/* @__PURE__ */ jsx3("button", { type: "button", onClick: onCancel, children: "Cancelar" }),
|
|
611
|
+
/* @__PURE__ */ jsx3("button", { type: "submit", className: "ed-link-dialog-apply", children: "Aplicar" })
|
|
355
612
|
] })
|
|
356
613
|
] })
|
|
357
614
|
] })
|
|
@@ -360,7 +617,7 @@ function LinkDialog() {
|
|
|
360
617
|
}
|
|
361
618
|
|
|
362
619
|
// src/PageConfigDialog.tsx
|
|
363
|
-
import { useEffect as
|
|
620
|
+
import { useEffect as useEffect3, useMemo, useRef as useRef2, useState as useState3 } from "react";
|
|
364
621
|
import {
|
|
365
622
|
MARGIN_PRESETS,
|
|
366
623
|
PAGE_PRESETS,
|
|
@@ -368,19 +625,19 @@ import {
|
|
|
368
625
|
mmToPx,
|
|
369
626
|
pxToMm
|
|
370
627
|
} from "@sofereditor/core";
|
|
371
|
-
import { jsx as
|
|
628
|
+
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
372
629
|
function PageConfigDialog() {
|
|
373
630
|
const { pageConfigRequest, resolvePageConfigRequest, setPageSettings } = useEditorContext();
|
|
374
631
|
const dialogRef = useRef2(null);
|
|
375
|
-
const [sizePreset, setSizePreset] =
|
|
376
|
-
const [widthMm, setWidthMm] =
|
|
377
|
-
const [heightMm, setHeightMm] =
|
|
378
|
-
const [marginPreset, setMarginPreset] =
|
|
379
|
-
const [marginTopMm, setMarginTopMm] =
|
|
380
|
-
const [marginBottomMm, setMarginBottomMm] =
|
|
381
|
-
const [marginLeftMm, setMarginLeftMm] =
|
|
382
|
-
const [marginRightMm, setMarginRightMm] =
|
|
383
|
-
|
|
632
|
+
const [sizePreset, setSizePreset] = useState3("a4");
|
|
633
|
+
const [widthMm, setWidthMm] = useState3(210);
|
|
634
|
+
const [heightMm, setHeightMm] = useState3(297);
|
|
635
|
+
const [marginPreset, setMarginPreset] = useState3("normal");
|
|
636
|
+
const [marginTopMm, setMarginTopMm] = useState3(25.4);
|
|
637
|
+
const [marginBottomMm, setMarginBottomMm] = useState3(25.4);
|
|
638
|
+
const [marginLeftMm, setMarginLeftMm] = useState3(25.4);
|
|
639
|
+
const [marginRightMm, setMarginRightMm] = useState3(25.4);
|
|
640
|
+
useEffect3(() => {
|
|
384
641
|
const dialog = dialogRef.current;
|
|
385
642
|
if (!dialog) return;
|
|
386
643
|
if (pageConfigRequest) {
|
|
@@ -399,13 +656,13 @@ function PageConfigDialog() {
|
|
|
399
656
|
dialog.close();
|
|
400
657
|
}
|
|
401
658
|
}, [pageConfigRequest]);
|
|
402
|
-
|
|
659
|
+
useEffect3(() => {
|
|
403
660
|
if (sizePreset === "custom") return;
|
|
404
661
|
const p = PAGE_PRESETS[sizePreset];
|
|
405
662
|
setWidthMm(roundMm(pxToMm(p.width)));
|
|
406
663
|
setHeightMm(roundMm(pxToMm(p.height)));
|
|
407
664
|
}, [sizePreset]);
|
|
408
|
-
|
|
665
|
+
useEffect3(() => {
|
|
409
666
|
if (marginPreset === "custom") return;
|
|
410
667
|
const px = MARGIN_PRESETS[marginPreset];
|
|
411
668
|
const mm = roundMm(pxToMm(px));
|
|
@@ -437,23 +694,24 @@ function PageConfigDialog() {
|
|
|
437
694
|
resolvePageConfigRequest(true);
|
|
438
695
|
};
|
|
439
696
|
const onCancel = () => resolvePageConfigRequest(false);
|
|
440
|
-
return /* @__PURE__ */
|
|
697
|
+
return /* @__PURE__ */ jsx4(
|
|
441
698
|
"dialog",
|
|
442
699
|
{
|
|
443
700
|
ref: dialogRef,
|
|
444
701
|
className: "ed-page-config-dialog",
|
|
702
|
+
style: DIALOG_CENTER_STYLE,
|
|
445
703
|
onClose: onCancel,
|
|
446
704
|
onCancel: (e) => {
|
|
447
705
|
e.preventDefault();
|
|
448
706
|
onCancel();
|
|
449
707
|
},
|
|
450
|
-
children: /* @__PURE__ */
|
|
451
|
-
/* @__PURE__ */
|
|
452
|
-
/* @__PURE__ */
|
|
453
|
-
/* @__PURE__ */
|
|
454
|
-
/* @__PURE__ */
|
|
455
|
-
/* @__PURE__ */
|
|
456
|
-
/* @__PURE__ */
|
|
708
|
+
children: /* @__PURE__ */ jsxs4("form", { onSubmit: onApply, className: "ed-page-config-form", children: [
|
|
709
|
+
/* @__PURE__ */ jsx4("h2", { children: "Configurar p\xE1gina" }),
|
|
710
|
+
/* @__PURE__ */ jsxs4("fieldset", { children: [
|
|
711
|
+
/* @__PURE__ */ jsx4("legend", { children: "Tamanho" }),
|
|
712
|
+
/* @__PURE__ */ jsxs4("div", { className: "ed-page-config-row", children: [
|
|
713
|
+
/* @__PURE__ */ jsxs4("label", { children: [
|
|
714
|
+
/* @__PURE__ */ jsx4(
|
|
457
715
|
"input",
|
|
458
716
|
{
|
|
459
717
|
type: "radio",
|
|
@@ -465,8 +723,8 @@ function PageConfigDialog() {
|
|
|
465
723
|
" ",
|
|
466
724
|
"A4 (210 \xD7 297 mm)"
|
|
467
725
|
] }),
|
|
468
|
-
/* @__PURE__ */
|
|
469
|
-
/* @__PURE__ */
|
|
726
|
+
/* @__PURE__ */ jsxs4("label", { children: [
|
|
727
|
+
/* @__PURE__ */ jsx4(
|
|
470
728
|
"input",
|
|
471
729
|
{
|
|
472
730
|
type: "radio",
|
|
@@ -478,8 +736,8 @@ function PageConfigDialog() {
|
|
|
478
736
|
" ",
|
|
479
737
|
"Carta (216 \xD7 279 mm)"
|
|
480
738
|
] }),
|
|
481
|
-
/* @__PURE__ */
|
|
482
|
-
/* @__PURE__ */
|
|
739
|
+
/* @__PURE__ */ jsxs4("label", { children: [
|
|
740
|
+
/* @__PURE__ */ jsx4(
|
|
483
741
|
"input",
|
|
484
742
|
{
|
|
485
743
|
type: "radio",
|
|
@@ -491,8 +749,8 @@ function PageConfigDialog() {
|
|
|
491
749
|
" ",
|
|
492
750
|
"Of\xEDcio (216 \xD7 330 mm)"
|
|
493
751
|
] }),
|
|
494
|
-
/* @__PURE__ */
|
|
495
|
-
/* @__PURE__ */
|
|
752
|
+
/* @__PURE__ */ jsxs4("label", { children: [
|
|
753
|
+
/* @__PURE__ */ jsx4(
|
|
496
754
|
"input",
|
|
497
755
|
{
|
|
498
756
|
type: "radio",
|
|
@@ -505,11 +763,11 @@ function PageConfigDialog() {
|
|
|
505
763
|
"Personalizado"
|
|
506
764
|
] })
|
|
507
765
|
] }),
|
|
508
|
-
/* @__PURE__ */
|
|
509
|
-
/* @__PURE__ */
|
|
766
|
+
/* @__PURE__ */ jsxs4("div", { className: "ed-page-config-row", children: [
|
|
767
|
+
/* @__PURE__ */ jsxs4("label", { children: [
|
|
510
768
|
"Largura (mm)",
|
|
511
769
|
" ",
|
|
512
|
-
/* @__PURE__ */
|
|
770
|
+
/* @__PURE__ */ jsx4(
|
|
513
771
|
"input",
|
|
514
772
|
{
|
|
515
773
|
type: "number",
|
|
@@ -522,10 +780,10 @@ function PageConfigDialog() {
|
|
|
522
780
|
}
|
|
523
781
|
)
|
|
524
782
|
] }),
|
|
525
|
-
/* @__PURE__ */
|
|
783
|
+
/* @__PURE__ */ jsxs4("label", { children: [
|
|
526
784
|
"Altura (mm)",
|
|
527
785
|
" ",
|
|
528
|
-
/* @__PURE__ */
|
|
786
|
+
/* @__PURE__ */ jsx4(
|
|
529
787
|
"input",
|
|
530
788
|
{
|
|
531
789
|
type: "number",
|
|
@@ -538,7 +796,7 @@ function PageConfigDialog() {
|
|
|
538
796
|
}
|
|
539
797
|
)
|
|
540
798
|
] }),
|
|
541
|
-
/* @__PURE__ */
|
|
799
|
+
/* @__PURE__ */ jsxs4("span", { className: "ed-page-config-preview", children: [
|
|
542
800
|
previewPx.width,
|
|
543
801
|
" \xD7 ",
|
|
544
802
|
previewPx.height,
|
|
@@ -546,11 +804,11 @@ function PageConfigDialog() {
|
|
|
546
804
|
] })
|
|
547
805
|
] })
|
|
548
806
|
] }),
|
|
549
|
-
/* @__PURE__ */
|
|
550
|
-
/* @__PURE__ */
|
|
551
|
-
/* @__PURE__ */
|
|
552
|
-
/* @__PURE__ */
|
|
553
|
-
/* @__PURE__ */
|
|
807
|
+
/* @__PURE__ */ jsxs4("fieldset", { children: [
|
|
808
|
+
/* @__PURE__ */ jsx4("legend", { children: "Margens" }),
|
|
809
|
+
/* @__PURE__ */ jsxs4("div", { className: "ed-page-config-row", children: [
|
|
810
|
+
/* @__PURE__ */ jsxs4("label", { children: [
|
|
811
|
+
/* @__PURE__ */ jsx4(
|
|
554
812
|
"input",
|
|
555
813
|
{
|
|
556
814
|
type: "radio",
|
|
@@ -562,8 +820,8 @@ function PageConfigDialog() {
|
|
|
562
820
|
" ",
|
|
563
821
|
"Normal (25,4 mm)"
|
|
564
822
|
] }),
|
|
565
|
-
/* @__PURE__ */
|
|
566
|
-
/* @__PURE__ */
|
|
823
|
+
/* @__PURE__ */ jsxs4("label", { children: [
|
|
824
|
+
/* @__PURE__ */ jsx4(
|
|
567
825
|
"input",
|
|
568
826
|
{
|
|
569
827
|
type: "radio",
|
|
@@ -575,8 +833,8 @@ function PageConfigDialog() {
|
|
|
575
833
|
" ",
|
|
576
834
|
"Estreita (12,7 mm)"
|
|
577
835
|
] }),
|
|
578
|
-
/* @__PURE__ */
|
|
579
|
-
/* @__PURE__ */
|
|
836
|
+
/* @__PURE__ */ jsxs4("label", { children: [
|
|
837
|
+
/* @__PURE__ */ jsx4(
|
|
580
838
|
"input",
|
|
581
839
|
{
|
|
582
840
|
type: "radio",
|
|
@@ -588,8 +846,8 @@ function PageConfigDialog() {
|
|
|
588
846
|
" ",
|
|
589
847
|
"Larga (50,8 mm)"
|
|
590
848
|
] }),
|
|
591
|
-
/* @__PURE__ */
|
|
592
|
-
/* @__PURE__ */
|
|
849
|
+
/* @__PURE__ */ jsxs4("label", { children: [
|
|
850
|
+
/* @__PURE__ */ jsx4(
|
|
593
851
|
"input",
|
|
594
852
|
{
|
|
595
853
|
type: "radio",
|
|
@@ -602,11 +860,11 @@ function PageConfigDialog() {
|
|
|
602
860
|
"Personalizada"
|
|
603
861
|
] })
|
|
604
862
|
] }),
|
|
605
|
-
/* @__PURE__ */
|
|
606
|
-
/* @__PURE__ */
|
|
863
|
+
/* @__PURE__ */ jsxs4("div", { className: "ed-page-config-row", children: [
|
|
864
|
+
/* @__PURE__ */ jsxs4("label", { children: [
|
|
607
865
|
"Topo",
|
|
608
866
|
" ",
|
|
609
|
-
/* @__PURE__ */
|
|
867
|
+
/* @__PURE__ */ jsx4(
|
|
610
868
|
"input",
|
|
611
869
|
{
|
|
612
870
|
type: "number",
|
|
@@ -621,10 +879,10 @@ function PageConfigDialog() {
|
|
|
621
879
|
}
|
|
622
880
|
)
|
|
623
881
|
] }),
|
|
624
|
-
/* @__PURE__ */
|
|
882
|
+
/* @__PURE__ */ jsxs4("label", { children: [
|
|
625
883
|
"Inferior",
|
|
626
884
|
" ",
|
|
627
|
-
/* @__PURE__ */
|
|
885
|
+
/* @__PURE__ */ jsx4(
|
|
628
886
|
"input",
|
|
629
887
|
{
|
|
630
888
|
type: "number",
|
|
@@ -639,10 +897,10 @@ function PageConfigDialog() {
|
|
|
639
897
|
}
|
|
640
898
|
)
|
|
641
899
|
] }),
|
|
642
|
-
/* @__PURE__ */
|
|
900
|
+
/* @__PURE__ */ jsxs4("label", { children: [
|
|
643
901
|
"Esquerda",
|
|
644
902
|
" ",
|
|
645
|
-
/* @__PURE__ */
|
|
903
|
+
/* @__PURE__ */ jsx4(
|
|
646
904
|
"input",
|
|
647
905
|
{
|
|
648
906
|
type: "number",
|
|
@@ -657,10 +915,10 @@ function PageConfigDialog() {
|
|
|
657
915
|
}
|
|
658
916
|
)
|
|
659
917
|
] }),
|
|
660
|
-
/* @__PURE__ */
|
|
918
|
+
/* @__PURE__ */ jsxs4("label", { children: [
|
|
661
919
|
"Direita",
|
|
662
920
|
" ",
|
|
663
|
-
/* @__PURE__ */
|
|
921
|
+
/* @__PURE__ */ jsx4(
|
|
664
922
|
"input",
|
|
665
923
|
{
|
|
666
924
|
type: "number",
|
|
@@ -677,9 +935,9 @@ function PageConfigDialog() {
|
|
|
677
935
|
] })
|
|
678
936
|
] })
|
|
679
937
|
] }),
|
|
680
|
-
/* @__PURE__ */
|
|
681
|
-
/* @__PURE__ */
|
|
682
|
-
/* @__PURE__ */
|
|
938
|
+
/* @__PURE__ */ jsxs4("div", { className: "ed-page-config-actions", children: [
|
|
939
|
+
/* @__PURE__ */ jsx4("button", { type: "button", onClick: onCancel, children: "Cancelar" }),
|
|
940
|
+
/* @__PURE__ */ jsx4("button", { type: "submit", className: "ed-page-config-apply", children: "Aplicar" })
|
|
683
941
|
] })
|
|
684
942
|
] })
|
|
685
943
|
}
|
|
@@ -714,15 +972,15 @@ function detectMarginPreset(s) {
|
|
|
714
972
|
}
|
|
715
973
|
|
|
716
974
|
// src/ImageCaptionDialog.tsx
|
|
717
|
-
import { useEffect as
|
|
718
|
-
import { jsx as
|
|
975
|
+
import { useEffect as useEffect4, useRef as useRef3, useState as useState4 } from "react";
|
|
976
|
+
import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
719
977
|
function ImageCaptionDialog() {
|
|
720
978
|
const { imageCaptionRequest, resolveImageCaptionRequest } = useEditorContext();
|
|
721
979
|
const dialogRef = useRef3(null);
|
|
722
980
|
const inputRef = useRef3(null);
|
|
723
|
-
const [caption, setCaption] =
|
|
724
|
-
const [align, setAlign] =
|
|
725
|
-
|
|
981
|
+
const [caption, setCaption] = useState4("");
|
|
982
|
+
const [align, setAlign] = useState4("center");
|
|
983
|
+
useEffect4(() => {
|
|
726
984
|
const dialog = dialogRef.current;
|
|
727
985
|
if (!dialog) return;
|
|
728
986
|
if (imageCaptionRequest) {
|
|
@@ -747,20 +1005,21 @@ function ImageCaptionDialog() {
|
|
|
747
1005
|
};
|
|
748
1006
|
const onRemove = () => resolveImageCaptionRequest({ caption: "", align });
|
|
749
1007
|
const onCancel = () => resolveImageCaptionRequest(null);
|
|
750
|
-
return /* @__PURE__ */
|
|
1008
|
+
return /* @__PURE__ */ jsx5(
|
|
751
1009
|
"dialog",
|
|
752
1010
|
{
|
|
753
1011
|
ref: dialogRef,
|
|
754
1012
|
className: "ed-caption-dialog ed-link-dialog",
|
|
1013
|
+
style: DIALOG_CENTER_STYLE,
|
|
755
1014
|
onClose: onCancel,
|
|
756
1015
|
onCancel: (e) => {
|
|
757
1016
|
e.preventDefault();
|
|
758
1017
|
onCancel();
|
|
759
1018
|
},
|
|
760
|
-
children: /* @__PURE__ */
|
|
761
|
-
/* @__PURE__ */
|
|
762
|
-
/* @__PURE__ */
|
|
763
|
-
/* @__PURE__ */
|
|
1019
|
+
children: /* @__PURE__ */ jsxs5("form", { onSubmit, className: "ed-link-dialog-form", children: [
|
|
1020
|
+
/* @__PURE__ */ jsxs5("div", { className: "ed-link-dialog-row", children: [
|
|
1021
|
+
/* @__PURE__ */ jsx5("label", { htmlFor: "ed-caption-input", children: "Legenda" }),
|
|
1022
|
+
/* @__PURE__ */ jsx5(
|
|
764
1023
|
"input",
|
|
765
1024
|
{
|
|
766
1025
|
id: "ed-caption-input",
|
|
@@ -773,10 +1032,10 @@ function ImageCaptionDialog() {
|
|
|
773
1032
|
}
|
|
774
1033
|
)
|
|
775
1034
|
] }),
|
|
776
|
-
/* @__PURE__ */
|
|
777
|
-
/* @__PURE__ */
|
|
778
|
-
/* @__PURE__ */
|
|
779
|
-
/* @__PURE__ */
|
|
1035
|
+
/* @__PURE__ */ jsxs5("div", { className: "ed-link-dialog-row", children: [
|
|
1036
|
+
/* @__PURE__ */ jsx5("span", { children: "Alinhamento" }),
|
|
1037
|
+
/* @__PURE__ */ jsx5("div", { className: "ed-caption-align-group", role: "radiogroup", "aria-label": "Alinhamento da legenda", children: ["left", "center", "right"].map((value) => /* @__PURE__ */ jsxs5("label", { className: "ed-caption-align-option", children: [
|
|
1038
|
+
/* @__PURE__ */ jsx5(
|
|
780
1039
|
"input",
|
|
781
1040
|
{
|
|
782
1041
|
type: "radio",
|
|
@@ -789,11 +1048,11 @@ function ImageCaptionDialog() {
|
|
|
789
1048
|
value === "left" ? "Esquerda" : value === "center" ? "Centro" : "Direita"
|
|
790
1049
|
] }, value)) })
|
|
791
1050
|
] }),
|
|
792
|
-
/* @__PURE__ */
|
|
793
|
-
imageCaptionRequest.initialCaption ? /* @__PURE__ */
|
|
794
|
-
/* @__PURE__ */
|
|
795
|
-
/* @__PURE__ */
|
|
796
|
-
/* @__PURE__ */
|
|
1051
|
+
/* @__PURE__ */ jsxs5("div", { className: "ed-link-dialog-actions", children: [
|
|
1052
|
+
imageCaptionRequest.initialCaption ? /* @__PURE__ */ jsx5("button", { type: "button", onClick: onRemove, className: "ed-link-dialog-remove", children: "Remover legenda" }) : /* @__PURE__ */ jsx5("span", {}),
|
|
1053
|
+
/* @__PURE__ */ jsxs5("div", { className: "ed-link-dialog-confirm", children: [
|
|
1054
|
+
/* @__PURE__ */ jsx5("button", { type: "button", onClick: onCancel, children: "Cancelar" }),
|
|
1055
|
+
/* @__PURE__ */ jsx5("button", { type: "submit", className: "ed-link-dialog-apply", children: "Aplicar" })
|
|
797
1056
|
] })
|
|
798
1057
|
] })
|
|
799
1058
|
] })
|
|
@@ -802,14 +1061,14 @@ function ImageCaptionDialog() {
|
|
|
802
1061
|
}
|
|
803
1062
|
|
|
804
1063
|
// src/EditorContext.tsx
|
|
805
|
-
import { jsx as
|
|
1064
|
+
import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
806
1065
|
var EditorContext = createContext(null);
|
|
807
1066
|
function EditorProvider({ editor, children }) {
|
|
808
|
-
return /* @__PURE__ */
|
|
1067
|
+
return /* @__PURE__ */ jsxs6(EditorContext.Provider, { value: editor, children: [
|
|
809
1068
|
children,
|
|
810
|
-
/* @__PURE__ */
|
|
811
|
-
/* @__PURE__ */
|
|
812
|
-
/* @__PURE__ */
|
|
1069
|
+
/* @__PURE__ */ jsx6(LinkDialog, {}),
|
|
1070
|
+
/* @__PURE__ */ jsx6(PageConfigDialog, {}),
|
|
1071
|
+
/* @__PURE__ */ jsx6(ImageCaptionDialog, {})
|
|
813
1072
|
] });
|
|
814
1073
|
}
|
|
815
1074
|
function useEditorContext() {
|
|
@@ -822,13 +1081,13 @@ function useEditorContext() {
|
|
|
822
1081
|
|
|
823
1082
|
// src/ImageResizeOverlay.tsx
|
|
824
1083
|
import {
|
|
825
|
-
useCallback,
|
|
826
|
-
useEffect as
|
|
827
|
-
useLayoutEffect,
|
|
1084
|
+
useCallback as useCallback2,
|
|
1085
|
+
useEffect as useEffect5,
|
|
1086
|
+
useLayoutEffect as useLayoutEffect2,
|
|
828
1087
|
useRef as useRef4,
|
|
829
|
-
useState as
|
|
1088
|
+
useState as useState5
|
|
830
1089
|
} from "react";
|
|
831
|
-
import { jsx as
|
|
1090
|
+
import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
832
1091
|
function ImageResizeOverlay({
|
|
833
1092
|
rootRef,
|
|
834
1093
|
blockIndex,
|
|
@@ -836,11 +1095,13 @@ function ImageResizeOverlay({
|
|
|
836
1095
|
cellIndex,
|
|
837
1096
|
embed,
|
|
838
1097
|
onCommit,
|
|
839
|
-
onCommitMove
|
|
1098
|
+
onCommitMove,
|
|
1099
|
+
onReanchor
|
|
840
1100
|
}) {
|
|
841
|
-
const [rect, setRect] =
|
|
1101
|
+
const [rect, setRect] = useState5(null);
|
|
1102
|
+
const [isMoving, setIsMoving] = useState5(false);
|
|
842
1103
|
const imgRef = useRef4(null);
|
|
843
|
-
const locateImage =
|
|
1104
|
+
const locateImage = useCallback2(() => {
|
|
844
1105
|
const root = rootRef.current;
|
|
845
1106
|
if (!root) return null;
|
|
846
1107
|
let container = null;
|
|
@@ -858,7 +1119,7 @@ function ImageResizeOverlay({
|
|
|
858
1119
|
`img[data-embed="image"][data-embed-offset="${localOffset}"]`
|
|
859
1120
|
);
|
|
860
1121
|
}, [rootRef, blockIndex, offset, cellIndex]);
|
|
861
|
-
const measure =
|
|
1122
|
+
const measure = useCallback2(() => {
|
|
862
1123
|
const img = locateImage();
|
|
863
1124
|
if (!img) {
|
|
864
1125
|
setRect((prev) => prev === null ? prev : null);
|
|
@@ -879,22 +1140,28 @@ function ImageResizeOverlay({
|
|
|
879
1140
|
(prev) => prev && prev.top === next.top && prev.left === next.left && prev.width === next.width && prev.height === next.height ? prev : next
|
|
880
1141
|
);
|
|
881
1142
|
}, [locateImage, rootRef]);
|
|
882
|
-
|
|
1143
|
+
useLayoutEffect2(() => {
|
|
883
1144
|
measure();
|
|
884
1145
|
let cancelled = false;
|
|
1146
|
+
let frame = 0;
|
|
1147
|
+
let rafId = 0;
|
|
885
1148
|
const remeasure = () => {
|
|
886
1149
|
if (cancelled) return;
|
|
887
1150
|
measure();
|
|
1151
|
+
if (!locateImage() && frame++ < 30) {
|
|
1152
|
+
rafId = typeof requestAnimationFrame === "function" ? requestAnimationFrame(remeasure) : (queueMicrotask(remeasure), 0);
|
|
1153
|
+
}
|
|
888
1154
|
};
|
|
889
|
-
|
|
1155
|
+
rafId = typeof requestAnimationFrame === "function" ? requestAnimationFrame(remeasure) : (queueMicrotask(remeasure), 0);
|
|
890
1156
|
return () => {
|
|
891
1157
|
cancelled = true;
|
|
892
|
-
if (typeof cancelAnimationFrame === "function" && typeof
|
|
893
|
-
cancelAnimationFrame(
|
|
1158
|
+
if (typeof cancelAnimationFrame === "function" && typeof rafId === "number" && rafId > 0) {
|
|
1159
|
+
cancelAnimationFrame(rafId);
|
|
894
1160
|
}
|
|
895
1161
|
};
|
|
896
1162
|
}, [
|
|
897
1163
|
measure,
|
|
1164
|
+
locateImage,
|
|
898
1165
|
embed.width,
|
|
899
1166
|
embed.height,
|
|
900
1167
|
embed.align,
|
|
@@ -903,7 +1170,7 @@ function ImageResizeOverlay({
|
|
|
903
1170
|
embed.offsetX,
|
|
904
1171
|
embed.offsetY
|
|
905
1172
|
]);
|
|
906
|
-
|
|
1173
|
+
useEffect5(() => {
|
|
907
1174
|
const root = rootRef.current;
|
|
908
1175
|
if (!root) return;
|
|
909
1176
|
const onScroll = () => measure();
|
|
@@ -914,7 +1181,7 @@ function ImageResizeOverlay({
|
|
|
914
1181
|
root.removeEventListener("scroll", onScroll);
|
|
915
1182
|
};
|
|
916
1183
|
}, [measure, rootRef]);
|
|
917
|
-
|
|
1184
|
+
useEffect5(() => {
|
|
918
1185
|
if (typeof ResizeObserver === "undefined") return;
|
|
919
1186
|
const img = locateImage();
|
|
920
1187
|
const root = rootRef.current;
|
|
@@ -927,14 +1194,36 @@ function ImageResizeOverlay({
|
|
|
927
1194
|
if (!rect) return null;
|
|
928
1195
|
const layout = embed.layout ?? "inline";
|
|
929
1196
|
const movable = layout !== "inline" && onCommitMove !== void 0;
|
|
930
|
-
return /* @__PURE__ */
|
|
1197
|
+
return /* @__PURE__ */ jsxs7(
|
|
931
1198
|
"div",
|
|
932
1199
|
{
|
|
933
1200
|
className: "ed-image-overlay",
|
|
934
1201
|
style: { top: rect.top, left: rect.left, width: rect.width, height: rect.height },
|
|
935
1202
|
contentEditable: false,
|
|
936
1203
|
children: [
|
|
937
|
-
|
|
1204
|
+
isMoving && // Non-clipped drag preview (Tier 2): the overlay lives in .ed-root and
|
|
1205
|
+
// follows the cursor, so the image stays visible while it crosses the
|
|
1206
|
+
// page boundary (the real, clipped figure is hidden during the drag).
|
|
1207
|
+
// Inline styles only — the package does not ship CSS.
|
|
1208
|
+
/* @__PURE__ */ jsx7(
|
|
1209
|
+
"img",
|
|
1210
|
+
{
|
|
1211
|
+
src: embed.src,
|
|
1212
|
+
alt: "",
|
|
1213
|
+
"aria-hidden": true,
|
|
1214
|
+
draggable: false,
|
|
1215
|
+
style: {
|
|
1216
|
+
position: "absolute",
|
|
1217
|
+
inset: 0,
|
|
1218
|
+
width: "100%",
|
|
1219
|
+
height: "100%",
|
|
1220
|
+
objectFit: "fill",
|
|
1221
|
+
opacity: 0.8,
|
|
1222
|
+
pointerEvents: "none"
|
|
1223
|
+
}
|
|
1224
|
+
}
|
|
1225
|
+
),
|
|
1226
|
+
movable && /* @__PURE__ */ jsx7(
|
|
938
1227
|
MoveHandle,
|
|
939
1228
|
{
|
|
940
1229
|
layout,
|
|
@@ -942,10 +1231,17 @@ function ImageResizeOverlay({
|
|
|
942
1231
|
startOffsetY: embed.offsetY ?? 0,
|
|
943
1232
|
imgRef,
|
|
944
1233
|
onCommit: onCommitMove,
|
|
945
|
-
onLiveChange: measure
|
|
1234
|
+
onLiveChange: measure,
|
|
1235
|
+
rootRef,
|
|
1236
|
+
blockIndex,
|
|
1237
|
+
offset,
|
|
1238
|
+
cellIndex,
|
|
1239
|
+
onReanchor,
|
|
1240
|
+
onMoveStart: () => setIsMoving(true),
|
|
1241
|
+
onMoveEnd: () => setIsMoving(false)
|
|
946
1242
|
}
|
|
947
1243
|
),
|
|
948
|
-
/* @__PURE__ */
|
|
1244
|
+
/* @__PURE__ */ jsx7(
|
|
949
1245
|
Handle,
|
|
950
1246
|
{
|
|
951
1247
|
corner: "nw",
|
|
@@ -956,7 +1252,7 @@ function ImageResizeOverlay({
|
|
|
956
1252
|
onLiveChange: measure
|
|
957
1253
|
}
|
|
958
1254
|
),
|
|
959
|
-
/* @__PURE__ */
|
|
1255
|
+
/* @__PURE__ */ jsx7(
|
|
960
1256
|
Handle,
|
|
961
1257
|
{
|
|
962
1258
|
corner: "ne",
|
|
@@ -967,7 +1263,7 @@ function ImageResizeOverlay({
|
|
|
967
1263
|
onLiveChange: measure
|
|
968
1264
|
}
|
|
969
1265
|
),
|
|
970
|
-
/* @__PURE__ */
|
|
1266
|
+
/* @__PURE__ */ jsx7(
|
|
971
1267
|
Handle,
|
|
972
1268
|
{
|
|
973
1269
|
corner: "sw",
|
|
@@ -978,7 +1274,7 @@ function ImageResizeOverlay({
|
|
|
978
1274
|
onLiveChange: measure
|
|
979
1275
|
}
|
|
980
1276
|
),
|
|
981
|
-
/* @__PURE__ */
|
|
1277
|
+
/* @__PURE__ */ jsx7(
|
|
982
1278
|
Handle,
|
|
983
1279
|
{
|
|
984
1280
|
corner: "se",
|
|
@@ -999,7 +1295,14 @@ function MoveHandle({
|
|
|
999
1295
|
startOffsetY,
|
|
1000
1296
|
imgRef,
|
|
1001
1297
|
onCommit,
|
|
1002
|
-
onLiveChange
|
|
1298
|
+
onLiveChange,
|
|
1299
|
+
rootRef,
|
|
1300
|
+
blockIndex,
|
|
1301
|
+
offset,
|
|
1302
|
+
cellIndex,
|
|
1303
|
+
onReanchor,
|
|
1304
|
+
onMoveStart,
|
|
1305
|
+
onMoveEnd
|
|
1003
1306
|
}) {
|
|
1004
1307
|
const dragRef = useRef4(null);
|
|
1005
1308
|
const onPointerDown = (e) => {
|
|
@@ -1014,35 +1317,65 @@ function MoveHandle({
|
|
|
1014
1317
|
liveOX: startOffsetX,
|
|
1015
1318
|
liveOY: startOffsetY
|
|
1016
1319
|
};
|
|
1320
|
+
const styled = imgRef.current.closest(".ed-figure") ?? imgRef.current;
|
|
1321
|
+
styled.style.opacity = "0";
|
|
1322
|
+
onMoveStart?.();
|
|
1017
1323
|
};
|
|
1018
1324
|
const onPointerMove = (e) => {
|
|
1019
1325
|
const d = dragRef.current;
|
|
1020
1326
|
if (!d || !imgRef.current) return;
|
|
1021
1327
|
const dx = e.clientX - d.startX;
|
|
1022
1328
|
const dy = e.clientY - d.startY;
|
|
1023
|
-
const
|
|
1329
|
+
const styled = imgRef.current.closest(".ed-figure") ?? imgRef.current;
|
|
1024
1330
|
let nox = startOffsetX;
|
|
1025
1331
|
let noy = startOffsetY;
|
|
1026
1332
|
if (layout === "wrap-left") {
|
|
1027
1333
|
nox = Math.max(8, startOffsetX + dx);
|
|
1028
1334
|
noy = Math.max(0, startOffsetY + dy);
|
|
1029
|
-
|
|
1030
|
-
|
|
1335
|
+
styled.style.marginRight = `${nox}px`;
|
|
1336
|
+
styled.style.marginTop = `${noy}px`;
|
|
1031
1337
|
} else if (layout === "wrap-right") {
|
|
1032
1338
|
nox = Math.max(8, startOffsetX - dx);
|
|
1033
1339
|
noy = Math.max(0, startOffsetY + dy);
|
|
1034
|
-
|
|
1035
|
-
|
|
1340
|
+
styled.style.marginLeft = `${nox}px`;
|
|
1341
|
+
styled.style.marginTop = `${noy}px`;
|
|
1036
1342
|
} else if (layout === "behind" || layout === "front") {
|
|
1037
1343
|
nox = startOffsetX + dx;
|
|
1038
1344
|
noy = startOffsetY + dy;
|
|
1039
|
-
|
|
1040
|
-
|
|
1345
|
+
styled.style.left = `${nox}px`;
|
|
1346
|
+
styled.style.top = `${noy}px`;
|
|
1041
1347
|
}
|
|
1042
1348
|
d.liveOX = nox;
|
|
1043
1349
|
d.liveOY = noy;
|
|
1044
1350
|
onLiveChange();
|
|
1045
1351
|
};
|
|
1352
|
+
const clampOffsetToFragment = (frag, oy) => {
|
|
1353
|
+
const img = imgRef.current;
|
|
1354
|
+
if (!img) return oy;
|
|
1355
|
+
const page = frag.closest(".ed-page");
|
|
1356
|
+
const content = page?.querySelector(".ed-page-content");
|
|
1357
|
+
if (!content) return oy;
|
|
1358
|
+
const fragRect = frag.getBoundingClientRect();
|
|
1359
|
+
const contentRect = content.getBoundingClientRect();
|
|
1360
|
+
const imgH = img.getBoundingClientRect().height;
|
|
1361
|
+
const minLocalTop = contentRect.top - fragRect.top;
|
|
1362
|
+
const maxLocalTop = contentRect.bottom - fragRect.top - imgH;
|
|
1363
|
+
return Math.round(Math.max(minLocalTop, Math.min(oy, maxLocalTop)));
|
|
1364
|
+
};
|
|
1365
|
+
const clampedCommit = (ox, oy) => {
|
|
1366
|
+
const img = imgRef.current;
|
|
1367
|
+
const root = rootRef.current;
|
|
1368
|
+
if (!img || !root || layout !== "behind" && layout !== "front") {
|
|
1369
|
+
onCommit(ox, oy);
|
|
1370
|
+
return;
|
|
1371
|
+
}
|
|
1372
|
+
const frag = getFragmentForOffset(root, blockIndex, offset);
|
|
1373
|
+
if (!frag) {
|
|
1374
|
+
onCommit(ox, oy);
|
|
1375
|
+
return;
|
|
1376
|
+
}
|
|
1377
|
+
onCommit(ox, clampOffsetToFragment(frag, oy));
|
|
1378
|
+
};
|
|
1046
1379
|
const finish = (e) => {
|
|
1047
1380
|
const d = dragRef.current;
|
|
1048
1381
|
if (!d) return;
|
|
@@ -1051,9 +1384,77 @@ function MoveHandle({
|
|
|
1051
1384
|
e.target.releasePointerCapture(e.pointerId);
|
|
1052
1385
|
} catch {
|
|
1053
1386
|
}
|
|
1054
|
-
|
|
1387
|
+
if (imgRef.current) {
|
|
1388
|
+
const styled = imgRef.current.closest(".ed-figure") ?? imgRef.current;
|
|
1389
|
+
styled.style.opacity = "";
|
|
1390
|
+
}
|
|
1391
|
+
onMoveEnd?.();
|
|
1392
|
+
const img = imgRef.current;
|
|
1393
|
+
const root = rootRef.current;
|
|
1394
|
+
const liveOX = Math.round(d.liveOX);
|
|
1395
|
+
const liveOY = Math.round(d.liveOY);
|
|
1396
|
+
if (!img || !root || onReanchor === void 0 || cellIndex != null) {
|
|
1397
|
+
clampedCommit(liveOX, liveOY);
|
|
1398
|
+
return;
|
|
1399
|
+
}
|
|
1400
|
+
const imgRect = img.getBoundingClientRect();
|
|
1401
|
+
const centerY = imgRect.top + imgRect.height / 2;
|
|
1402
|
+
const pages = Array.from(root.querySelectorAll(".ed-page"));
|
|
1403
|
+
let destPage = null;
|
|
1404
|
+
let bestPageDist = Infinity;
|
|
1405
|
+
for (const pg of pages) {
|
|
1406
|
+
const r = pg.getBoundingClientRect();
|
|
1407
|
+
if (centerY >= r.top && centerY <= r.bottom) {
|
|
1408
|
+
destPage = pg;
|
|
1409
|
+
break;
|
|
1410
|
+
}
|
|
1411
|
+
const dist = centerY < r.top ? r.top - centerY : centerY - r.bottom;
|
|
1412
|
+
if (dist < bestPageDist) {
|
|
1413
|
+
bestPageDist = dist;
|
|
1414
|
+
destPage = pg;
|
|
1415
|
+
}
|
|
1416
|
+
}
|
|
1417
|
+
const currentFrag = getFragmentForOffset(root, blockIndex, offset);
|
|
1418
|
+
const currentPage = currentFrag?.closest(".ed-page") ?? null;
|
|
1419
|
+
if (destPage == null || destPage === currentPage) {
|
|
1420
|
+
clampedCommit(liveOX, liveOY);
|
|
1421
|
+
return;
|
|
1422
|
+
}
|
|
1423
|
+
const blocksOnPage = Array.from(
|
|
1424
|
+
destPage.querySelectorAll("[data-block-index]")
|
|
1425
|
+
);
|
|
1426
|
+
let destFrag = null;
|
|
1427
|
+
let bestBlockDist = Infinity;
|
|
1428
|
+
for (const b of blocksOnPage) {
|
|
1429
|
+
const dist = Math.abs(b.getBoundingClientRect().top - imgRect.top);
|
|
1430
|
+
if (dist < bestBlockDist) {
|
|
1431
|
+
bestBlockDist = dist;
|
|
1432
|
+
destFrag = b;
|
|
1433
|
+
}
|
|
1434
|
+
}
|
|
1435
|
+
if (!destFrag) {
|
|
1436
|
+
clampedCommit(liveOX, liveOY);
|
|
1437
|
+
return;
|
|
1438
|
+
}
|
|
1439
|
+
const destBlockIndex = findBlockIndex(destFrag, root);
|
|
1440
|
+
if (destBlockIndex == null) {
|
|
1441
|
+
clampedCommit(liveOX, liveOY);
|
|
1442
|
+
return;
|
|
1443
|
+
}
|
|
1444
|
+
const destOffset = destFrag.dataset.fragmentStart ? Number.parseInt(destFrag.dataset.fragmentStart, 10) || 0 : 0;
|
|
1445
|
+
const fragRect = destFrag.getBoundingClientRect();
|
|
1446
|
+
const newOffsetX = Math.round(imgRect.left - fragRect.left);
|
|
1447
|
+
const newOffsetY = clampOffsetToFragment(
|
|
1448
|
+
destFrag,
|
|
1449
|
+
Math.round(imgRect.top - fragRect.top)
|
|
1450
|
+
);
|
|
1451
|
+
onReanchor(
|
|
1452
|
+
{ blockIndex: destBlockIndex, offset: destOffset, cellIndex: void 0 },
|
|
1453
|
+
newOffsetX,
|
|
1454
|
+
newOffsetY
|
|
1455
|
+
);
|
|
1055
1456
|
};
|
|
1056
|
-
return /* @__PURE__ */
|
|
1457
|
+
return /* @__PURE__ */ jsx7(
|
|
1057
1458
|
"div",
|
|
1058
1459
|
{
|
|
1059
1460
|
className: "ed-image-move",
|
|
@@ -1116,7 +1517,7 @@ function Handle({
|
|
|
1116
1517
|
}
|
|
1117
1518
|
onCommit(Math.round(d.liveW), Math.round(d.liveH));
|
|
1118
1519
|
};
|
|
1119
|
-
return /* @__PURE__ */
|
|
1520
|
+
return /* @__PURE__ */ jsx7(
|
|
1120
1521
|
"div",
|
|
1121
1522
|
{
|
|
1122
1523
|
className: `ed-image-handle ${corner}`,
|
|
@@ -1128,17 +1529,194 @@ function Handle({
|
|
|
1128
1529
|
);
|
|
1129
1530
|
}
|
|
1130
1531
|
|
|
1532
|
+
// src/RemoteCursorsOverlay.tsx
|
|
1533
|
+
import {
|
|
1534
|
+
useCallback as useCallback3,
|
|
1535
|
+
useEffect as useEffect6,
|
|
1536
|
+
useRef as useRef5,
|
|
1537
|
+
useState as useState6
|
|
1538
|
+
} from "react";
|
|
1539
|
+
import {
|
|
1540
|
+
decodeSelection
|
|
1541
|
+
} from "@sofereditor/core";
|
|
1542
|
+
import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1543
|
+
var DEFAULT_COLOR = "#3b82f6";
|
|
1544
|
+
function RemoteCursorsOverlay({
|
|
1545
|
+
rootRef,
|
|
1546
|
+
doc,
|
|
1547
|
+
awareness,
|
|
1548
|
+
revision
|
|
1549
|
+
}) {
|
|
1550
|
+
const [views, setViews] = useState6([]);
|
|
1551
|
+
const rafRef = useRef5(null);
|
|
1552
|
+
const measure = useCallback3(() => {
|
|
1553
|
+
const root = rootRef.current;
|
|
1554
|
+
if (!root) {
|
|
1555
|
+
setViews((prev) => prev.length === 0 ? prev : []);
|
|
1556
|
+
return;
|
|
1557
|
+
}
|
|
1558
|
+
const rr = root.getBoundingClientRect();
|
|
1559
|
+
const out = [];
|
|
1560
|
+
awareness.getStates().forEach((state, clientId) => {
|
|
1561
|
+
if (clientId === awareness.clientID) return;
|
|
1562
|
+
const s = state;
|
|
1563
|
+
if (!s.cursor) return;
|
|
1564
|
+
const sel = decodeSelection(doc, s.cursor);
|
|
1565
|
+
if (!sel) return;
|
|
1566
|
+
const color = s.user?.color || DEFAULT_COLOR;
|
|
1567
|
+
const name = s.user?.name || "An\xF4nimo";
|
|
1568
|
+
const focus = locatePoint(root, sel.focus);
|
|
1569
|
+
let caret = null;
|
|
1570
|
+
if (focus) {
|
|
1571
|
+
try {
|
|
1572
|
+
const range = document.createRange();
|
|
1573
|
+
range.setStart(focus.node, focus.offset);
|
|
1574
|
+
range.collapse(true);
|
|
1575
|
+
let rect = range.getBoundingClientRect();
|
|
1576
|
+
if (rect.height === 0 && focus.node.nodeType === Node.ELEMENT_NODE) {
|
|
1577
|
+
rect = focus.node.getBoundingClientRect();
|
|
1578
|
+
}
|
|
1579
|
+
caret = {
|
|
1580
|
+
top: rect.top - rr.top + root.scrollTop,
|
|
1581
|
+
left: rect.left - rr.left + root.scrollLeft,
|
|
1582
|
+
height: rect.height || 18
|
|
1583
|
+
};
|
|
1584
|
+
} catch {
|
|
1585
|
+
}
|
|
1586
|
+
}
|
|
1587
|
+
const collapsed = sel.anchor.blockIndex === sel.focus.blockIndex && (sel.anchor.cellIndex ?? -1) === (sel.focus.cellIndex ?? -1) && sel.anchor.offset === sel.focus.offset;
|
|
1588
|
+
const selection = [];
|
|
1589
|
+
if (!collapsed && focus) {
|
|
1590
|
+
const anchor = locatePoint(root, sel.anchor);
|
|
1591
|
+
if (anchor) {
|
|
1592
|
+
try {
|
|
1593
|
+
const r = document.createRange();
|
|
1594
|
+
r.setStart(anchor.node, anchor.offset);
|
|
1595
|
+
r.setEnd(focus.node, focus.offset);
|
|
1596
|
+
if (r.collapsed) {
|
|
1597
|
+
r.setStart(focus.node, focus.offset);
|
|
1598
|
+
r.setEnd(anchor.node, anchor.offset);
|
|
1599
|
+
}
|
|
1600
|
+
for (const cr of Array.from(r.getClientRects())) {
|
|
1601
|
+
if (cr.width === 0 || cr.height === 0) continue;
|
|
1602
|
+
selection.push({
|
|
1603
|
+
top: cr.top - rr.top + root.scrollTop,
|
|
1604
|
+
left: cr.left - rr.left + root.scrollLeft,
|
|
1605
|
+
width: cr.width,
|
|
1606
|
+
height: cr.height
|
|
1607
|
+
});
|
|
1608
|
+
}
|
|
1609
|
+
} catch {
|
|
1610
|
+
}
|
|
1611
|
+
}
|
|
1612
|
+
}
|
|
1613
|
+
out.push({ clientId, name, color, caret, selection });
|
|
1614
|
+
});
|
|
1615
|
+
setViews(out);
|
|
1616
|
+
}, [rootRef, doc, awareness]);
|
|
1617
|
+
const scheduleMeasure = useCallback3(() => {
|
|
1618
|
+
if (rafRef.current != null) return;
|
|
1619
|
+
const raf = typeof requestAnimationFrame === "function" ? requestAnimationFrame : (cb) => setTimeout(() => cb(0), 16);
|
|
1620
|
+
rafRef.current = raf(() => {
|
|
1621
|
+
rafRef.current = null;
|
|
1622
|
+
measure();
|
|
1623
|
+
});
|
|
1624
|
+
}, [measure]);
|
|
1625
|
+
useEffect6(() => {
|
|
1626
|
+
const onChange = () => scheduleMeasure();
|
|
1627
|
+
awareness.on("change", onChange);
|
|
1628
|
+
scheduleMeasure();
|
|
1629
|
+
return () => awareness.off("change", onChange);
|
|
1630
|
+
}, [awareness, scheduleMeasure]);
|
|
1631
|
+
useEffect6(() => {
|
|
1632
|
+
scheduleMeasure();
|
|
1633
|
+
}, [revision, scheduleMeasure]);
|
|
1634
|
+
useEffect6(() => {
|
|
1635
|
+
const root = rootRef.current;
|
|
1636
|
+
if (!root) return;
|
|
1637
|
+
const onScroll = () => scheduleMeasure();
|
|
1638
|
+
root.addEventListener("scroll", onScroll, { passive: true });
|
|
1639
|
+
let ro = null;
|
|
1640
|
+
if (typeof ResizeObserver !== "undefined") {
|
|
1641
|
+
ro = new ResizeObserver(() => scheduleMeasure());
|
|
1642
|
+
ro.observe(root);
|
|
1643
|
+
}
|
|
1644
|
+
return () => {
|
|
1645
|
+
root.removeEventListener("scroll", onScroll);
|
|
1646
|
+
ro?.disconnect();
|
|
1647
|
+
};
|
|
1648
|
+
}, [rootRef, scheduleMeasure]);
|
|
1649
|
+
if (views.length === 0) return null;
|
|
1650
|
+
const layer = {
|
|
1651
|
+
position: "absolute",
|
|
1652
|
+
inset: 0,
|
|
1653
|
+
pointerEvents: "none",
|
|
1654
|
+
zIndex: 6
|
|
1655
|
+
};
|
|
1656
|
+
return /* @__PURE__ */ jsx8("div", { className: "ed-remote-cursors", "aria-hidden": true, style: layer, children: views.map((v) => /* @__PURE__ */ jsxs8("div", { children: [
|
|
1657
|
+
v.selection.map((r, i) => /* @__PURE__ */ jsx8(
|
|
1658
|
+
"div",
|
|
1659
|
+
{
|
|
1660
|
+
style: {
|
|
1661
|
+
position: "absolute",
|
|
1662
|
+
top: r.top,
|
|
1663
|
+
left: r.left,
|
|
1664
|
+
width: r.width,
|
|
1665
|
+
height: r.height,
|
|
1666
|
+
background: v.color,
|
|
1667
|
+
opacity: 0.22,
|
|
1668
|
+
borderRadius: 2
|
|
1669
|
+
}
|
|
1670
|
+
},
|
|
1671
|
+
i
|
|
1672
|
+
)),
|
|
1673
|
+
v.caret && /* @__PURE__ */ jsx8(
|
|
1674
|
+
"div",
|
|
1675
|
+
{
|
|
1676
|
+
style: {
|
|
1677
|
+
position: "absolute",
|
|
1678
|
+
top: v.caret.top,
|
|
1679
|
+
left: v.caret.left,
|
|
1680
|
+
height: v.caret.height,
|
|
1681
|
+
width: 2,
|
|
1682
|
+
background: v.color
|
|
1683
|
+
},
|
|
1684
|
+
children: /* @__PURE__ */ jsx8(
|
|
1685
|
+
"span",
|
|
1686
|
+
{
|
|
1687
|
+
style: {
|
|
1688
|
+
position: "absolute",
|
|
1689
|
+
top: -15,
|
|
1690
|
+
left: -1,
|
|
1691
|
+
fontSize: 10,
|
|
1692
|
+
lineHeight: "14px",
|
|
1693
|
+
padding: "0 4px",
|
|
1694
|
+
borderRadius: 3,
|
|
1695
|
+
color: "#fff",
|
|
1696
|
+
background: v.color,
|
|
1697
|
+
whiteSpace: "nowrap",
|
|
1698
|
+
fontFamily: "system-ui, sans-serif",
|
|
1699
|
+
userSelect: "none"
|
|
1700
|
+
},
|
|
1701
|
+
children: v.name
|
|
1702
|
+
}
|
|
1703
|
+
)
|
|
1704
|
+
}
|
|
1705
|
+
)
|
|
1706
|
+
] }, v.clientId)) });
|
|
1707
|
+
}
|
|
1708
|
+
|
|
1131
1709
|
// src/NodeView.tsx
|
|
1132
|
-
import { useMemo as useMemo2, useRef as
|
|
1710
|
+
import { useMemo as useMemo2, useRef as useRef7 } from "react";
|
|
1133
1711
|
import { tableRectSelection } from "@sofereditor/core";
|
|
1134
1712
|
|
|
1135
1713
|
// src/renderInline.tsx
|
|
1136
|
-
import { Fragment, memo } from "react";
|
|
1714
|
+
import { Fragment as Fragment3, memo } from "react";
|
|
1137
1715
|
import { isImageEmbed } from "@sofereditor/core";
|
|
1138
|
-
import { jsx as
|
|
1716
|
+
import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1139
1717
|
function renderInline(delta, keyPrefix) {
|
|
1140
1718
|
if (delta.length === 0 || delta.length === 1 && typeof delta[0].insert === "string" && delta[0].insert === "") {
|
|
1141
|
-
return /* @__PURE__ */
|
|
1719
|
+
return /* @__PURE__ */ jsx9("br", { "data-empty": "true" });
|
|
1142
1720
|
}
|
|
1143
1721
|
let offset = 0;
|
|
1144
1722
|
const wrapAnchors = [];
|
|
@@ -1148,7 +1726,7 @@ function renderInline(delta, keyPrefix) {
|
|
|
1148
1726
|
const text = op.insert;
|
|
1149
1727
|
if (text.length === 0) continue;
|
|
1150
1728
|
const key = `${keyPrefix}-${offset}`;
|
|
1151
|
-
body.push(/* @__PURE__ */
|
|
1729
|
+
body.push(/* @__PURE__ */ jsx9(Fragment3, { children: wrap(text, op.attributes) }, key));
|
|
1152
1730
|
offset += text.length;
|
|
1153
1731
|
} else if (isImageEmbed(op.insert)) {
|
|
1154
1732
|
const key = `${keyPrefix}-${offset}`;
|
|
@@ -1156,10 +1734,10 @@ function renderInline(delta, keyPrefix) {
|
|
|
1156
1734
|
const commentMarkId = op.attributes?.comment?.markId;
|
|
1157
1735
|
if (layout === "wrap-left" || layout === "wrap-right") {
|
|
1158
1736
|
wrapAnchors.push(
|
|
1159
|
-
/* @__PURE__ */
|
|
1737
|
+
/* @__PURE__ */ jsx9(ImageEmbedView, { embed: op.insert, offset, wrapAnchor: true }, `${key}-anchor`)
|
|
1160
1738
|
);
|
|
1161
1739
|
body.push(
|
|
1162
|
-
/* @__PURE__ */
|
|
1740
|
+
/* @__PURE__ */ jsx9(
|
|
1163
1741
|
"span",
|
|
1164
1742
|
{
|
|
1165
1743
|
"data-embed-phantom": "true",
|
|
@@ -1171,10 +1749,10 @@ function renderInline(delta, keyPrefix) {
|
|
|
1171
1749
|
)
|
|
1172
1750
|
);
|
|
1173
1751
|
} else {
|
|
1174
|
-
const imgNode = /* @__PURE__ */
|
|
1752
|
+
const imgNode = /* @__PURE__ */ jsx9(ImageEmbedView, { embed: op.insert, offset }, key);
|
|
1175
1753
|
if (commentMarkId) {
|
|
1176
1754
|
body.push(
|
|
1177
|
-
/* @__PURE__ */
|
|
1755
|
+
/* @__PURE__ */ jsx9("span", { "data-comment-id": commentMarkId, className: "ed-comment", children: imgNode }, `${key}-cmt`)
|
|
1178
1756
|
);
|
|
1179
1757
|
} else {
|
|
1180
1758
|
body.push(imgNode);
|
|
@@ -1185,7 +1763,7 @@ function renderInline(delta, keyPrefix) {
|
|
|
1185
1763
|
offset += 1;
|
|
1186
1764
|
}
|
|
1187
1765
|
}
|
|
1188
|
-
if (wrapAnchors.length === 0 && body.length === 0) return /* @__PURE__ */
|
|
1766
|
+
if (wrapAnchors.length === 0 && body.length === 0) return /* @__PURE__ */ jsx9("br", { "data-empty": "true" });
|
|
1189
1767
|
return [...wrapAnchors, ...body];
|
|
1190
1768
|
}
|
|
1191
1769
|
var PHANTOM_STYLE = {
|
|
@@ -1195,6 +1773,11 @@ var PHANTOM_STYLE = {
|
|
|
1195
1773
|
overflow: "hidden",
|
|
1196
1774
|
verticalAlign: "baseline"
|
|
1197
1775
|
};
|
|
1776
|
+
var LINK_STYLE = {
|
|
1777
|
+
color: "#2563eb",
|
|
1778
|
+
textDecoration: "underline",
|
|
1779
|
+
cursor: "text"
|
|
1780
|
+
};
|
|
1198
1781
|
function imageEmbedPropsEqual(a, b) {
|
|
1199
1782
|
if (a.offset !== b.offset || a.wrapAnchor !== b.wrapAnchor) return false;
|
|
1200
1783
|
const x = a.embed;
|
|
@@ -1260,8 +1843,12 @@ function ImageEmbedViewImpl({
|
|
|
1260
1843
|
};
|
|
1261
1844
|
break;
|
|
1262
1845
|
}
|
|
1263
|
-
const imgStyle =
|
|
1264
|
-
|
|
1846
|
+
const imgStyle = {
|
|
1847
|
+
width: embed.width,
|
|
1848
|
+
height: embed.height,
|
|
1849
|
+
display: "block"
|
|
1850
|
+
};
|
|
1851
|
+
const img = /* @__PURE__ */ jsx9(
|
|
1265
1852
|
"img",
|
|
1266
1853
|
{
|
|
1267
1854
|
src: embed.src,
|
|
@@ -1280,19 +1867,18 @@ function ImageEmbedViewImpl({
|
|
|
1280
1867
|
alt: ""
|
|
1281
1868
|
}
|
|
1282
1869
|
);
|
|
1283
|
-
if (!hasCaption) return img;
|
|
1284
1870
|
const captionAlign = embed.captionAlign ?? "center";
|
|
1285
|
-
return /* @__PURE__ */
|
|
1871
|
+
return /* @__PURE__ */ jsxs9(
|
|
1286
1872
|
"figure",
|
|
1287
1873
|
{
|
|
1288
1874
|
className: "ed-figure",
|
|
1289
1875
|
contentEditable: false,
|
|
1290
|
-
"data-embed-figure": "true",
|
|
1876
|
+
"data-embed-figure": hasCaption ? "true" : void 0,
|
|
1291
1877
|
"data-embed-layout": layout,
|
|
1292
1878
|
style: outerStyle,
|
|
1293
1879
|
children: [
|
|
1294
1880
|
img,
|
|
1295
|
-
/* @__PURE__ */
|
|
1881
|
+
hasCaption && /* @__PURE__ */ jsx9(
|
|
1296
1882
|
"figcaption",
|
|
1297
1883
|
{
|
|
1298
1884
|
className: "ed-figcaption",
|
|
@@ -1308,34 +1894,38 @@ function ImageEmbedViewImpl({
|
|
|
1308
1894
|
function wrap(text, attrs) {
|
|
1309
1895
|
let node = text;
|
|
1310
1896
|
if (!attrs) return node;
|
|
1311
|
-
if (attrs.bold) node = /* @__PURE__ */
|
|
1312
|
-
if (attrs.italic) node = /* @__PURE__ */
|
|
1313
|
-
if (attrs.underline) node = /* @__PURE__ */
|
|
1314
|
-
if (attrs.strike) node = /* @__PURE__ */
|
|
1897
|
+
if (attrs.bold) node = /* @__PURE__ */ jsx9("strong", { children: node });
|
|
1898
|
+
if (attrs.italic) node = /* @__PURE__ */ jsx9("em", { children: node });
|
|
1899
|
+
if (attrs.underline) node = /* @__PURE__ */ jsx9("u", { children: node });
|
|
1900
|
+
if (attrs.strike) node = /* @__PURE__ */ jsx9("s", { children: node });
|
|
1315
1901
|
const styleParts = {};
|
|
1316
1902
|
if (attrs.color) styleParts.color = attrs.color;
|
|
1317
1903
|
if (attrs.fontFamily) styleParts.fontFamily = attrs.fontFamily;
|
|
1318
1904
|
if (attrs.fontSize) styleParts.fontSize = attrs.fontSize;
|
|
1319
1905
|
if (Object.keys(styleParts).length > 0) {
|
|
1320
|
-
node = /* @__PURE__ */
|
|
1906
|
+
node = /* @__PURE__ */ jsx9("span", { style: styleParts, children: node });
|
|
1321
1907
|
}
|
|
1322
1908
|
if (attrs.link?.href) {
|
|
1323
|
-
node = /* @__PURE__ */
|
|
1909
|
+
node = /* @__PURE__ */ jsx9(
|
|
1324
1910
|
"a",
|
|
1325
1911
|
{
|
|
1326
1912
|
href: attrs.link.href,
|
|
1327
1913
|
title: attrs.link.title,
|
|
1328
1914
|
rel: "noopener noreferrer",
|
|
1329
1915
|
target: "_blank",
|
|
1916
|
+
style: LINK_STYLE,
|
|
1330
1917
|
onClick: (e) => {
|
|
1331
|
-
|
|
1918
|
+
e.preventDefault();
|
|
1919
|
+
if (hasOpenModifier(e) && attrs.link?.href) {
|
|
1920
|
+
window.open(attrs.link.href, "_blank", "noopener,noreferrer");
|
|
1921
|
+
}
|
|
1332
1922
|
},
|
|
1333
1923
|
children: node
|
|
1334
1924
|
}
|
|
1335
1925
|
);
|
|
1336
1926
|
}
|
|
1337
1927
|
if (attrs.comment?.markId) {
|
|
1338
|
-
node = /* @__PURE__ */
|
|
1928
|
+
node = /* @__PURE__ */ jsx9("span", { "data-comment-id": attrs.comment.markId, className: "ed-comment", children: node });
|
|
1339
1929
|
}
|
|
1340
1930
|
return node;
|
|
1341
1931
|
}
|
|
@@ -1380,19 +1970,19 @@ function sliceDelta(delta, start, end) {
|
|
|
1380
1970
|
|
|
1381
1971
|
// src/TableResizeOverlay.tsx
|
|
1382
1972
|
import {
|
|
1383
|
-
useCallback as
|
|
1384
|
-
useEffect as
|
|
1385
|
-
useLayoutEffect as
|
|
1386
|
-
useRef as
|
|
1387
|
-
useState as
|
|
1973
|
+
useCallback as useCallback4,
|
|
1974
|
+
useEffect as useEffect7,
|
|
1975
|
+
useLayoutEffect as useLayoutEffect3,
|
|
1976
|
+
useRef as useRef6,
|
|
1977
|
+
useState as useState7
|
|
1388
1978
|
} from "react";
|
|
1389
|
-
import { Fragment as
|
|
1979
|
+
import { Fragment as Fragment4, jsx as jsx10 } from "react/jsx-runtime";
|
|
1390
1980
|
function TableResizeOverlay({ tableRef, blockIndex, cols }) {
|
|
1391
1981
|
const editor = useEditorContext();
|
|
1392
|
-
const [positions, setPositions] =
|
|
1393
|
-
const [layout, setLayout] =
|
|
1394
|
-
const draggingRef =
|
|
1395
|
-
const measure =
|
|
1982
|
+
const [positions, setPositions] = useState7(null);
|
|
1983
|
+
const [layout, setLayout] = useState7(null);
|
|
1984
|
+
const draggingRef = useRef6(null);
|
|
1985
|
+
const measure = useCallback4(() => {
|
|
1396
1986
|
const table = tableRef.current;
|
|
1397
1987
|
if (!table) return;
|
|
1398
1988
|
const tableRect = table.getBoundingClientRect();
|
|
@@ -1422,17 +2012,17 @@ function TableResizeOverlay({ tableRef, blockIndex, cols }) {
|
|
|
1422
2012
|
}
|
|
1423
2013
|
setLayout({ rights, height: tableRect.height });
|
|
1424
2014
|
}, [cols, tableRef]);
|
|
1425
|
-
|
|
2015
|
+
useLayoutEffect3(() => {
|
|
1426
2016
|
measure();
|
|
1427
2017
|
}, [measure]);
|
|
1428
|
-
|
|
2018
|
+
useEffect7(() => {
|
|
1429
2019
|
const table = tableRef.current;
|
|
1430
2020
|
if (!table) return;
|
|
1431
2021
|
const ro = new ResizeObserver(() => measure());
|
|
1432
2022
|
ro.observe(table);
|
|
1433
2023
|
return () => ro.disconnect();
|
|
1434
2024
|
}, [measure, tableRef]);
|
|
1435
|
-
const onPointerDown =
|
|
2025
|
+
const onPointerDown = useCallback4(
|
|
1436
2026
|
(col) => (e) => {
|
|
1437
2027
|
e.preventDefault();
|
|
1438
2028
|
e.stopPropagation();
|
|
@@ -1446,7 +2036,7 @@ function TableResizeOverlay({ tableRef, blockIndex, cols }) {
|
|
|
1446
2036
|
},
|
|
1447
2037
|
[layout, tableRef]
|
|
1448
2038
|
);
|
|
1449
|
-
const onPointerMove =
|
|
2039
|
+
const onPointerMove = useCallback4(
|
|
1450
2040
|
(e) => {
|
|
1451
2041
|
const d = draggingRef.current;
|
|
1452
2042
|
if (!d) return;
|
|
@@ -1456,7 +2046,7 @@ function TableResizeOverlay({ tableRef, blockIndex, cols }) {
|
|
|
1456
2046
|
},
|
|
1457
2047
|
[blockIndex, editor]
|
|
1458
2048
|
);
|
|
1459
|
-
const onPointerUp =
|
|
2049
|
+
const onPointerUp = useCallback4((e) => {
|
|
1460
2050
|
draggingRef.current = null;
|
|
1461
2051
|
setPositions(null);
|
|
1462
2052
|
try {
|
|
@@ -1475,7 +2065,7 @@ function TableResizeOverlay({ tableRef, blockIndex, cols }) {
|
|
|
1475
2065
|
zIndex: 5
|
|
1476
2066
|
});
|
|
1477
2067
|
void positions;
|
|
1478
|
-
return /* @__PURE__ */
|
|
2068
|
+
return /* @__PURE__ */ jsx10(Fragment4, { children: layout.rights.map((x, c) => /* @__PURE__ */ jsx10(
|
|
1479
2069
|
"div",
|
|
1480
2070
|
{
|
|
1481
2071
|
contentEditable: false,
|
|
@@ -1492,10 +2082,10 @@ function TableResizeOverlay({ tableRef, blockIndex, cols }) {
|
|
|
1492
2082
|
}
|
|
1493
2083
|
|
|
1494
2084
|
// src/NodeView.tsx
|
|
1495
|
-
import { jsx as
|
|
2085
|
+
import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1496
2086
|
function NodeView({ block, index, children, fragment, tableFragment }) {
|
|
1497
2087
|
if (block.type === "table") {
|
|
1498
|
-
return /* @__PURE__ */
|
|
2088
|
+
return /* @__PURE__ */ jsx11(TableView, { block, index, tableFragment });
|
|
1499
2089
|
}
|
|
1500
2090
|
const inline = fragment ? renderInline(sliceDelta(block.delta, fragment.start, fragment.end), index) : renderInline(block.delta, index);
|
|
1501
2091
|
const common = commonBlockProps(block.attrs, index, block.type, fragment);
|
|
@@ -1503,7 +2093,7 @@ function NodeView({ block, index, children, fragment, tableFragment }) {
|
|
|
1503
2093
|
case "heading": {
|
|
1504
2094
|
const level = clampLevel(block.attrs.level);
|
|
1505
2095
|
const Tag = `h${level}`;
|
|
1506
|
-
return /* @__PURE__ */
|
|
2096
|
+
return /* @__PURE__ */ jsx11(
|
|
1507
2097
|
Tag,
|
|
1508
2098
|
{
|
|
1509
2099
|
...common,
|
|
@@ -1513,7 +2103,7 @@ function NodeView({ block, index, children, fragment, tableFragment }) {
|
|
|
1513
2103
|
);
|
|
1514
2104
|
}
|
|
1515
2105
|
case "blockquote":
|
|
1516
|
-
return /* @__PURE__ */
|
|
2106
|
+
return /* @__PURE__ */ jsx11(
|
|
1517
2107
|
"blockquote",
|
|
1518
2108
|
{
|
|
1519
2109
|
...common,
|
|
@@ -1522,18 +2112,18 @@ function NodeView({ block, index, children, fragment, tableFragment }) {
|
|
|
1522
2112
|
}
|
|
1523
2113
|
);
|
|
1524
2114
|
case "codeBlock":
|
|
1525
|
-
return /* @__PURE__ */
|
|
2115
|
+
return /* @__PURE__ */ jsx11(
|
|
1526
2116
|
"pre",
|
|
1527
2117
|
{
|
|
1528
2118
|
...common,
|
|
1529
2119
|
"data-language": block.attrs.language ?? void 0,
|
|
1530
2120
|
className: `ed-block ed-codeblock${alignClass(block.attrs.align)}`,
|
|
1531
|
-
children: /* @__PURE__ */
|
|
2121
|
+
children: /* @__PURE__ */ jsx11("code", { children: inline })
|
|
1532
2122
|
}
|
|
1533
2123
|
);
|
|
1534
2124
|
case "listItem": {
|
|
1535
2125
|
const level = clampListLevel(block.attrs.listLevel);
|
|
1536
|
-
return /* @__PURE__ */
|
|
2126
|
+
return /* @__PURE__ */ jsxs10(
|
|
1537
2127
|
"li",
|
|
1538
2128
|
{
|
|
1539
2129
|
...common,
|
|
@@ -1549,7 +2139,7 @@ function NodeView({ block, index, children, fragment, tableFragment }) {
|
|
|
1549
2139
|
}
|
|
1550
2140
|
case "paragraph":
|
|
1551
2141
|
default:
|
|
1552
|
-
return /* @__PURE__ */
|
|
2142
|
+
return /* @__PURE__ */ jsx11(
|
|
1553
2143
|
"div",
|
|
1554
2144
|
{
|
|
1555
2145
|
...common,
|
|
@@ -1594,7 +2184,7 @@ function TableView({ block, index, tableFragment }) {
|
|
|
1594
2184
|
const cols = clampPositive(block.attrs.cols);
|
|
1595
2185
|
const cells = block.cells ?? [];
|
|
1596
2186
|
const widths = readColWidths(block.attrs.colWidths, cols);
|
|
1597
|
-
const tableRef =
|
|
2187
|
+
const tableRef = useRef7(null);
|
|
1598
2188
|
const rowStart = tableFragment?.rowStart ?? 0;
|
|
1599
2189
|
const rowEnd = tableFragment?.rowEnd ?? rows;
|
|
1600
2190
|
const isFirstFragment = !tableFragment || tableFragment.index === 0;
|
|
@@ -1604,8 +2194,8 @@ function TableView({ block, index, tableFragment }) {
|
|
|
1604
2194
|
if (editor.selection.focus.blockIndex !== index) return null;
|
|
1605
2195
|
return tableRectSelection(editor.doc, editor.selection);
|
|
1606
2196
|
}, [editor.doc, editor.selection, index]);
|
|
1607
|
-
return /* @__PURE__ */
|
|
1608
|
-
/* @__PURE__ */
|
|
2197
|
+
return /* @__PURE__ */ jsxs10("div", { className: "ed-table-wrap", children: [
|
|
2198
|
+
/* @__PURE__ */ jsxs10(
|
|
1609
2199
|
"table",
|
|
1610
2200
|
{
|
|
1611
2201
|
ref: tableRef,
|
|
@@ -1613,10 +2203,10 @@ function TableView({ block, index, tableFragment }) {
|
|
|
1613
2203
|
"data-block-type": "table",
|
|
1614
2204
|
className: "ed-block ed-table",
|
|
1615
2205
|
children: [
|
|
1616
|
-
widths && /* @__PURE__ */
|
|
1617
|
-
/* @__PURE__ */
|
|
2206
|
+
widths && /* @__PURE__ */ jsx11("colgroup", { children: widths.map((w, c) => /* @__PURE__ */ jsx11("col", { style: w != null ? { width: `${w}px` } : void 0 }, c)) }),
|
|
2207
|
+
/* @__PURE__ */ jsx11("tbody", { children: Array.from({ length: rowEnd - rowStart }, (_, i) => {
|
|
1618
2208
|
const r = rowStart + i;
|
|
1619
|
-
return /* @__PURE__ */
|
|
2209
|
+
return /* @__PURE__ */ jsx11("tr", { "data-cell-row": r, children: Array.from({ length: cols }, (_2, c) => {
|
|
1620
2210
|
const flat = r * cols + c;
|
|
1621
2211
|
const cell = cells[flat];
|
|
1622
2212
|
if (cell?.attrs.covered === true) return null;
|
|
@@ -1624,7 +2214,7 @@ function TableView({ block, index, tableFragment }) {
|
|
|
1624
2214
|
const colspan = spanAttr(cell?.attrs.colspan);
|
|
1625
2215
|
const delta = cell?.delta ?? [];
|
|
1626
2216
|
const inRect = rect !== null && r >= rect.top && r <= rect.bottom && c >= rect.left && c <= rect.right;
|
|
1627
|
-
return /* @__PURE__ */
|
|
2217
|
+
return /* @__PURE__ */ jsx11(
|
|
1628
2218
|
"td",
|
|
1629
2219
|
{
|
|
1630
2220
|
"data-cell-index": flat,
|
|
@@ -1634,6 +2224,7 @@ function TableView({ block, index, tableFragment }) {
|
|
|
1634
2224
|
"data-cell-colspan": colspan,
|
|
1635
2225
|
rowSpan: rowspan > 1 ? rowspan : void 0,
|
|
1636
2226
|
colSpan: colspan > 1 ? colspan : void 0,
|
|
2227
|
+
style: cell?.attrs.align ? { textAlign: cell.attrs.align } : void 0,
|
|
1637
2228
|
className: inRect ? "ed-cell ed-cell--selected" : "ed-cell",
|
|
1638
2229
|
children: renderInline(delta, `t${index}-c${flat}`)
|
|
1639
2230
|
},
|
|
@@ -1644,7 +2235,7 @@ function TableView({ block, index, tableFragment }) {
|
|
|
1644
2235
|
]
|
|
1645
2236
|
}
|
|
1646
2237
|
),
|
|
1647
|
-
isFirstFragment && /* @__PURE__ */
|
|
2238
|
+
isFirstFragment && /* @__PURE__ */ jsx11(TableResizeOverlay, { tableRef, blockIndex: index, cols })
|
|
1648
2239
|
] });
|
|
1649
2240
|
}
|
|
1650
2241
|
function readColWidths(raw, cols) {
|
|
@@ -1666,7 +2257,7 @@ function clampPositive(n) {
|
|
|
1666
2257
|
}
|
|
1667
2258
|
|
|
1668
2259
|
// src/usePagination.ts
|
|
1669
|
-
import { useLayoutEffect as
|
|
2260
|
+
import { useLayoutEffect as useLayoutEffect4, useRef as useRef8, useState as useState8 } from "react";
|
|
1670
2261
|
var A4_PAGE = {
|
|
1671
2262
|
width: 794,
|
|
1672
2263
|
height: 1123,
|
|
@@ -1692,10 +2283,10 @@ function defaultPageLayout(topLevelCount) {
|
|
|
1692
2283
|
};
|
|
1693
2284
|
}
|
|
1694
2285
|
function usePageLayout(rootRef, geometry, topLevelCount, deps) {
|
|
1695
|
-
const [phase, setPhase] =
|
|
1696
|
-
const [layout, setLayout] =
|
|
1697
|
-
const lastDepsRef =
|
|
1698
|
-
|
|
2286
|
+
const [phase, setPhase] = useState8("measure");
|
|
2287
|
+
const [layout, setLayout] = useState8(() => defaultPageLayout(topLevelCount));
|
|
2288
|
+
const lastDepsRef = useRef8(null);
|
|
2289
|
+
useLayoutEffect4(() => {
|
|
1699
2290
|
const currentDeps = [...deps, topLevelCount, geometry];
|
|
1700
2291
|
if (lastDepsRef.current !== null && shallowArrayEqual(lastDepsRef.current, currentDeps)) {
|
|
1701
2292
|
return;
|
|
@@ -1707,7 +2298,7 @@ function usePageLayout(rootRef, geometry, topLevelCount, deps) {
|
|
|
1707
2298
|
});
|
|
1708
2299
|
setPhase("measure");
|
|
1709
2300
|
});
|
|
1710
|
-
|
|
2301
|
+
useLayoutEffect4(() => {
|
|
1711
2302
|
if (phase !== "measure") return;
|
|
1712
2303
|
const root = rootRef.current;
|
|
1713
2304
|
if (!root) return;
|
|
@@ -2179,17 +2770,17 @@ function layoutsDeepEqual(a, b) {
|
|
|
2179
2770
|
}
|
|
2180
2771
|
|
|
2181
2772
|
// src/useEditor.ts
|
|
2182
|
-
import { useCallback as
|
|
2773
|
+
import { useCallback as useCallback6, useEffect as useEffect8, useMemo as useMemo3, useRef as useRef10, useState as useState9 } from "react";
|
|
2183
2774
|
|
|
2184
2775
|
// src/usePageSettings.ts
|
|
2185
|
-
import { useCallback as
|
|
2776
|
+
import { useCallback as useCallback5, useRef as useRef9, useSyncExternalStore } from "react";
|
|
2186
2777
|
function usePageSettings(doc) {
|
|
2187
|
-
const cacheRef =
|
|
2188
|
-
const subscribe =
|
|
2778
|
+
const cacheRef = useRef9(null);
|
|
2779
|
+
const subscribe = useCallback5(
|
|
2189
2780
|
(notify) => doc.observePageSettings(notify),
|
|
2190
2781
|
[doc]
|
|
2191
2782
|
);
|
|
2192
|
-
const getSnapshot =
|
|
2783
|
+
const getSnapshot = useCallback5(() => {
|
|
2193
2784
|
const next = doc.getPageSettings();
|
|
2194
2785
|
const prev = cacheRef.current;
|
|
2195
2786
|
if (prev && shallowEqual(prev, next)) return prev;
|
|
@@ -2215,6 +2806,7 @@ import {
|
|
|
2215
2806
|
mergeDown as cmdMergeDown,
|
|
2216
2807
|
mergeRight as cmdMergeRight,
|
|
2217
2808
|
mergeSelection as cmdMergeSelection,
|
|
2809
|
+
moveEmbedAnchor as cmdMoveEmbedAnchor,
|
|
2218
2810
|
setColumnWidth as cmdSetColumnWidth,
|
|
2219
2811
|
setImageAttrs as cmdSetImageAttrs,
|
|
2220
2812
|
splitCell as cmdSplitCell,
|
|
@@ -2231,6 +2823,7 @@ import {
|
|
|
2231
2823
|
orderedRange,
|
|
2232
2824
|
removeMark as cmdRemoveMark,
|
|
2233
2825
|
setBlockAttr as cmdSetBlockAttr,
|
|
2826
|
+
setCellAttr as cmdSetCellAttr,
|
|
2234
2827
|
setBlockType as cmdSetBlockType,
|
|
2235
2828
|
setMark as cmdSetMark,
|
|
2236
2829
|
splitListItem as cmdSplitListItem,
|
|
@@ -2242,19 +2835,19 @@ var MAX_INSERT_WIDTH = 600;
|
|
|
2242
2835
|
function useEditor(opts = {}) {
|
|
2243
2836
|
const doc = useMemo3(() => opts.document ?? new EditorDocument(), [opts.document]);
|
|
2244
2837
|
const history = useMemo3(() => new EditorHistory(doc), [doc]);
|
|
2245
|
-
const [snapshot, setSnapshot] =
|
|
2246
|
-
const [selection, setSelectionState] =
|
|
2838
|
+
const [snapshot, setSnapshot] = useState9(() => doc.toJSON());
|
|
2839
|
+
const [selection, setSelectionState] = useState9(
|
|
2247
2840
|
() => collapsedSelection({ blockIndex: 0, offset: 0 })
|
|
2248
2841
|
);
|
|
2249
|
-
const selectionRef =
|
|
2842
|
+
const selectionRef = useRef10(selection);
|
|
2250
2843
|
selectionRef.current = selection;
|
|
2251
|
-
const pendingMarksRef =
|
|
2252
|
-
const [pendingMarks, setPendingMarksState] =
|
|
2253
|
-
const setPendingMarks =
|
|
2844
|
+
const pendingMarksRef = useRef10({});
|
|
2845
|
+
const [pendingMarks, setPendingMarksState] = useState9({});
|
|
2846
|
+
const setPendingMarks = useCallback6((next) => {
|
|
2254
2847
|
pendingMarksRef.current = next;
|
|
2255
2848
|
setPendingMarksState(next);
|
|
2256
2849
|
}, []);
|
|
2257
|
-
|
|
2850
|
+
useEffect8(() => {
|
|
2258
2851
|
let scheduled = false;
|
|
2259
2852
|
let cancelled = false;
|
|
2260
2853
|
let frame = 0;
|
|
@@ -2281,8 +2874,8 @@ function useEditor(opts = {}) {
|
|
|
2281
2874
|
doc.ydoc.off("afterTransaction", schedule);
|
|
2282
2875
|
};
|
|
2283
2876
|
}, [doc]);
|
|
2284
|
-
const getSelection =
|
|
2285
|
-
const setSelection =
|
|
2877
|
+
const getSelection = useCallback6(() => selectionRef.current, []);
|
|
2878
|
+
const setSelection = useCallback6(
|
|
2286
2879
|
(sel) => {
|
|
2287
2880
|
const prev = selectionRef.current;
|
|
2288
2881
|
selectionRef.current = sel;
|
|
@@ -2297,16 +2890,16 @@ function useEditor(opts = {}) {
|
|
|
2297
2890
|
},
|
|
2298
2891
|
[]
|
|
2299
2892
|
);
|
|
2300
|
-
const ctxRef =
|
|
2893
|
+
const ctxRef = useRef10({ doc, getSelection, setSelection });
|
|
2301
2894
|
ctxRef.current = { doc, getSelection, setSelection };
|
|
2302
|
-
const consumePendingMarks =
|
|
2895
|
+
const consumePendingMarks = useCallback6(() => {
|
|
2303
2896
|
const current = pendingMarksRef.current;
|
|
2304
2897
|
if (Object.keys(current).length === 0) return void 0;
|
|
2305
2898
|
pendingMarksRef.current = {};
|
|
2306
2899
|
setPendingMarksState({});
|
|
2307
2900
|
return current;
|
|
2308
2901
|
}, []);
|
|
2309
|
-
const isMarkActive =
|
|
2902
|
+
const isMarkActive = useCallback6(
|
|
2310
2903
|
(name, value) => {
|
|
2311
2904
|
const sel = selectionRef.current;
|
|
2312
2905
|
const { start, end } = orderedRange(sel);
|
|
@@ -2337,7 +2930,7 @@ function useEditor(opts = {}) {
|
|
|
2337
2930
|
},
|
|
2338
2931
|
[doc]
|
|
2339
2932
|
);
|
|
2340
|
-
const getActiveMarks =
|
|
2933
|
+
const getActiveMarks = useCallback6(() => {
|
|
2341
2934
|
const sel = selectionRef.current;
|
|
2342
2935
|
const { start, end } = orderedRange(sel);
|
|
2343
2936
|
if (start.blockIndex !== end.blockIndex) {
|
|
@@ -2351,7 +2944,7 @@ function useEditor(opts = {}) {
|
|
|
2351
2944
|
}
|
|
2352
2945
|
return getMarksInRange(yText, start.offset, end.offset);
|
|
2353
2946
|
}, [doc]);
|
|
2354
|
-
const toggleMark =
|
|
2947
|
+
const toggleMark = useCallback6(
|
|
2355
2948
|
(name, value) => {
|
|
2356
2949
|
const sel = selectionRef.current;
|
|
2357
2950
|
const { start, end } = orderedRange(sel);
|
|
@@ -2371,7 +2964,7 @@ function useEditor(opts = {}) {
|
|
|
2371
2964
|
},
|
|
2372
2965
|
[isMarkActive, setPendingMarks]
|
|
2373
2966
|
);
|
|
2374
|
-
const setMark =
|
|
2967
|
+
const setMark = useCallback6(
|
|
2375
2968
|
(name, value) => {
|
|
2376
2969
|
const sel = selectionRef.current;
|
|
2377
2970
|
const { start, end } = orderedRange(sel);
|
|
@@ -2384,7 +2977,7 @@ function useEditor(opts = {}) {
|
|
|
2384
2977
|
},
|
|
2385
2978
|
[setPendingMarks]
|
|
2386
2979
|
);
|
|
2387
|
-
const removeMark =
|
|
2980
|
+
const removeMark = useCallback6(
|
|
2388
2981
|
(name) => {
|
|
2389
2982
|
const sel = selectionRef.current;
|
|
2390
2983
|
const { start, end } = orderedRange(sel);
|
|
@@ -2397,7 +2990,7 @@ function useEditor(opts = {}) {
|
|
|
2397
2990
|
},
|
|
2398
2991
|
[setPendingMarks]
|
|
2399
2992
|
);
|
|
2400
|
-
const getBlockType =
|
|
2993
|
+
const getBlockType = useCallback6(() => {
|
|
2401
2994
|
const sel = selectionRef.current;
|
|
2402
2995
|
const { start, end } = orderedRange(sel);
|
|
2403
2996
|
const first = doc.getBlockType(start.blockIndex);
|
|
@@ -2407,7 +3000,7 @@ function useEditor(opts = {}) {
|
|
|
2407
3000
|
}
|
|
2408
3001
|
return first;
|
|
2409
3002
|
}, [doc]);
|
|
2410
|
-
const getBlockAttr =
|
|
3003
|
+
const getBlockAttr = useCallback6(
|
|
2411
3004
|
(key) => {
|
|
2412
3005
|
const sel = selectionRef.current;
|
|
2413
3006
|
const { start, end } = orderedRange(sel);
|
|
@@ -2420,16 +3013,29 @@ function useEditor(opts = {}) {
|
|
|
2420
3013
|
},
|
|
2421
3014
|
[doc]
|
|
2422
3015
|
);
|
|
2423
|
-
const setBlockType =
|
|
3016
|
+
const setBlockType = useCallback6((type, attrs) => {
|
|
2424
3017
|
cmdSetBlockType(ctxRef.current, type, attrs);
|
|
2425
3018
|
}, []);
|
|
2426
|
-
const setBlockAttr =
|
|
3019
|
+
const setBlockAttr = useCallback6(
|
|
2427
3020
|
(key, value) => {
|
|
2428
3021
|
cmdSetBlockAttr(ctxRef.current, key, value);
|
|
2429
3022
|
},
|
|
2430
3023
|
[]
|
|
2431
3024
|
);
|
|
2432
|
-
const
|
|
3025
|
+
const setAlign = useCallback6((value) => {
|
|
3026
|
+
const sel = selectionRef.current;
|
|
3027
|
+
const inCell = sel.focus.cellIndex != null;
|
|
3028
|
+
if (inCell) cmdSetCellAttr(ctxRef.current, "align", value);
|
|
3029
|
+
else cmdSetBlockAttr(ctxRef.current, "align", value);
|
|
3030
|
+
}, []);
|
|
3031
|
+
const getAlign = useCallback6(() => {
|
|
3032
|
+
const sel = selectionRef.current;
|
|
3033
|
+
if (sel.focus.cellIndex != null && doc.isTable(sel.focus.blockIndex)) {
|
|
3034
|
+
return doc.getCellAttrs(sel.focus.blockIndex, sel.focus.cellIndex).align;
|
|
3035
|
+
}
|
|
3036
|
+
return getBlockAttr("align");
|
|
3037
|
+
}, [doc, getBlockAttr]);
|
|
3038
|
+
const isListActive = useCallback6(
|
|
2433
3039
|
(kind) => {
|
|
2434
3040
|
const sel = selectionRef.current;
|
|
2435
3041
|
const { start, end } = orderedRange(sel);
|
|
@@ -2441,110 +3047,116 @@ function useEditor(opts = {}) {
|
|
|
2441
3047
|
},
|
|
2442
3048
|
[doc]
|
|
2443
3049
|
);
|
|
2444
|
-
const toggleList =
|
|
3050
|
+
const toggleList = useCallback6((kind) => {
|
|
2445
3051
|
cmdToggleList(ctxRef.current, kind);
|
|
2446
3052
|
}, []);
|
|
2447
|
-
const indentList =
|
|
3053
|
+
const indentList = useCallback6(() => {
|
|
2448
3054
|
cmdIndentList(ctxRef.current);
|
|
2449
3055
|
}, []);
|
|
2450
|
-
const dedentList =
|
|
3056
|
+
const dedentList = useCallback6(() => {
|
|
2451
3057
|
cmdDedentList(ctxRef.current);
|
|
2452
3058
|
}, []);
|
|
2453
|
-
const splitListItem =
|
|
3059
|
+
const splitListItem = useCallback6(() => {
|
|
2454
3060
|
return cmdSplitListItem(ctxRef.current);
|
|
2455
3061
|
}, []);
|
|
2456
|
-
const isInTable =
|
|
3062
|
+
const isInTable = useCallback6(() => {
|
|
2457
3063
|
return selectionRef.current.focus.cellIndex != null;
|
|
2458
3064
|
}, []);
|
|
2459
|
-
const getTableLocation =
|
|
3065
|
+
const getTableLocation = useCallback6(() => {
|
|
2460
3066
|
return tableLocationOf(doc, selectionRef.current.focus);
|
|
2461
3067
|
}, [doc]);
|
|
2462
|
-
const insertTable =
|
|
3068
|
+
const insertTable = useCallback6((rows, cols) => {
|
|
2463
3069
|
cmdInsertTable(ctxRef.current, rows, cols);
|
|
2464
3070
|
}, []);
|
|
2465
|
-
const deleteTable =
|
|
3071
|
+
const deleteTable = useCallback6((blockIndex) => {
|
|
2466
3072
|
const idx = blockIndex ?? selectionRef.current.focus.blockIndex;
|
|
2467
3073
|
cmdDeleteTable(ctxRef.current, idx);
|
|
2468
3074
|
}, []);
|
|
2469
|
-
const insertRowAbove =
|
|
3075
|
+
const insertRowAbove = useCallback6(() => {
|
|
2470
3076
|
const loc = tableLocationOf(doc, selectionRef.current.focus);
|
|
2471
3077
|
if (!loc) return;
|
|
2472
3078
|
cmdInsertRow(ctxRef.current, loc.blockIndex, loc.row, "before");
|
|
2473
3079
|
}, [doc]);
|
|
2474
|
-
const insertRowBelow =
|
|
3080
|
+
const insertRowBelow = useCallback6(() => {
|
|
2475
3081
|
const loc = tableLocationOf(doc, selectionRef.current.focus);
|
|
2476
3082
|
if (!loc) return;
|
|
2477
3083
|
cmdInsertRow(ctxRef.current, loc.blockIndex, loc.row, "after");
|
|
2478
3084
|
}, [doc]);
|
|
2479
|
-
const deleteCurrentRow =
|
|
3085
|
+
const deleteCurrentRow = useCallback6(() => {
|
|
2480
3086
|
const loc = tableLocationOf(doc, selectionRef.current.focus);
|
|
2481
3087
|
if (!loc) return;
|
|
2482
3088
|
cmdDeleteRow(ctxRef.current, loc.blockIndex, loc.row);
|
|
2483
3089
|
}, [doc]);
|
|
2484
|
-
const insertColumnLeft =
|
|
3090
|
+
const insertColumnLeft = useCallback6(() => {
|
|
2485
3091
|
const loc = tableLocationOf(doc, selectionRef.current.focus);
|
|
2486
3092
|
if (!loc) return;
|
|
2487
3093
|
cmdInsertColumn(ctxRef.current, loc.blockIndex, loc.col, "before");
|
|
2488
3094
|
}, [doc]);
|
|
2489
|
-
const insertColumnRight =
|
|
3095
|
+
const insertColumnRight = useCallback6(() => {
|
|
2490
3096
|
const loc = tableLocationOf(doc, selectionRef.current.focus);
|
|
2491
3097
|
if (!loc) return;
|
|
2492
3098
|
cmdInsertColumn(ctxRef.current, loc.blockIndex, loc.col, "after");
|
|
2493
3099
|
}, [doc]);
|
|
2494
|
-
const deleteCurrentColumn =
|
|
3100
|
+
const deleteCurrentColumn = useCallback6(() => {
|
|
2495
3101
|
const loc = tableLocationOf(doc, selectionRef.current.focus);
|
|
2496
3102
|
if (!loc) return;
|
|
2497
3103
|
cmdDeleteColumn(ctxRef.current, loc.blockIndex, loc.col);
|
|
2498
3104
|
}, [doc]);
|
|
2499
|
-
const moveToNextCell =
|
|
3105
|
+
const moveToNextCell = useCallback6(() => {
|
|
2500
3106
|
cmdMoveNextCell(ctxRef.current);
|
|
2501
3107
|
}, []);
|
|
2502
|
-
const moveToPrevCell =
|
|
3108
|
+
const moveToPrevCell = useCallback6(() => {
|
|
2503
3109
|
cmdMovePrevCell(ctxRef.current);
|
|
2504
3110
|
}, []);
|
|
2505
|
-
const mergeRight =
|
|
3111
|
+
const mergeRight = useCallback6(() => {
|
|
2506
3112
|
const loc = tableLocationOf(doc, selectionRef.current.focus);
|
|
2507
3113
|
if (!loc) return false;
|
|
2508
3114
|
return cmdMergeRight(ctxRef.current, loc.blockIndex, loc.row, loc.col);
|
|
2509
3115
|
}, [doc]);
|
|
2510
|
-
const mergeDown =
|
|
3116
|
+
const mergeDown = useCallback6(() => {
|
|
2511
3117
|
const loc = tableLocationOf(doc, selectionRef.current.focus);
|
|
2512
3118
|
if (!loc) return false;
|
|
2513
3119
|
return cmdMergeDown(ctxRef.current, loc.blockIndex, loc.row, loc.col);
|
|
2514
3120
|
}, [doc]);
|
|
2515
|
-
const splitCell =
|
|
3121
|
+
const splitCell = useCallback6(() => {
|
|
2516
3122
|
const loc = tableLocationOf(doc, selectionRef.current.focus);
|
|
2517
3123
|
if (!loc) return false;
|
|
2518
3124
|
return cmdSplitCell(ctxRef.current, loc.blockIndex, loc.row, loc.col);
|
|
2519
3125
|
}, [doc]);
|
|
2520
|
-
const setColumnWidth =
|
|
3126
|
+
const setColumnWidth = useCallback6(
|
|
2521
3127
|
(blockIndex, col, widthPx) => {
|
|
2522
3128
|
cmdSetColumnWidth(ctxRef.current, blockIndex, col, widthPx);
|
|
2523
3129
|
},
|
|
2524
3130
|
[]
|
|
2525
3131
|
);
|
|
2526
|
-
const getTableRect =
|
|
3132
|
+
const getTableRect = useCallback6(
|
|
2527
3133
|
() => tableRectSelection2(doc, selectionRef.current),
|
|
2528
3134
|
[doc]
|
|
2529
3135
|
);
|
|
2530
|
-
const hasTableRectSelection =
|
|
3136
|
+
const hasTableRectSelection = useCallback6(() => {
|
|
2531
3137
|
return tableRectSelection2(doc, selectionRef.current) !== null;
|
|
2532
3138
|
}, [doc]);
|
|
2533
|
-
const mergeSelection =
|
|
3139
|
+
const mergeSelection = useCallback6(() => {
|
|
2534
3140
|
return cmdMergeSelection(ctxRef.current);
|
|
2535
3141
|
}, []);
|
|
2536
|
-
const insertImage =
|
|
3142
|
+
const insertImage = useCallback6((embed) => {
|
|
2537
3143
|
cmdInsertImage(ctxRef.current, embed);
|
|
2538
3144
|
}, []);
|
|
2539
|
-
const setImageAttrs =
|
|
3145
|
+
const setImageAttrs = useCallback6(
|
|
2540
3146
|
(blockIndex, offset, partial, cellIndex, newOffset) => {
|
|
2541
3147
|
cmdSetImageAttrs(ctxRef.current, blockIndex, offset, partial, cellIndex, newOffset);
|
|
2542
3148
|
},
|
|
2543
3149
|
[]
|
|
2544
3150
|
);
|
|
2545
|
-
const
|
|
3151
|
+
const moveEmbedAnchor = useCallback6(
|
|
3152
|
+
(from, to, newOffsetX, newOffsetY) => {
|
|
3153
|
+
cmdMoveEmbedAnchor(ctxRef.current, from, to, newOffsetX, newOffsetY);
|
|
3154
|
+
},
|
|
3155
|
+
[]
|
|
3156
|
+
);
|
|
3157
|
+
const uploadImageRef = useRef10(opts.uploadImage);
|
|
2546
3158
|
uploadImageRef.current = opts.uploadImage;
|
|
2547
|
-
const insertImageFromFile =
|
|
3159
|
+
const insertImageFromFile = useCallback6(async (file) => {
|
|
2548
3160
|
if (!file.type.startsWith("image/")) return;
|
|
2549
3161
|
const dataUrl = await readAsDataURL(file);
|
|
2550
3162
|
const dims = await readImageDimensions(dataUrl);
|
|
@@ -2558,7 +3170,7 @@ function useEditor(opts = {}) {
|
|
|
2558
3170
|
const src = upload ? await upload(file) : dataUrl;
|
|
2559
3171
|
cmdInsertImage(ctxRef.current, { type: "image", src, width: w, height: h });
|
|
2560
3172
|
}, []);
|
|
2561
|
-
const getSelectedEmbed =
|
|
3173
|
+
const getSelectedEmbed = useCallback6(() => {
|
|
2562
3174
|
const sel = selectionRef.current;
|
|
2563
3175
|
if (sel.anchor.blockIndex !== sel.focus.blockIndex) return null;
|
|
2564
3176
|
if ((sel.anchor.cellIndex ?? -1) !== (sel.focus.cellIndex ?? -1)) return null;
|
|
@@ -2587,39 +3199,48 @@ function useEditor(opts = {}) {
|
|
|
2587
3199
|
}
|
|
2588
3200
|
return null;
|
|
2589
3201
|
}, [doc]);
|
|
2590
|
-
const [linkRequest, setLinkRequest] =
|
|
2591
|
-
const
|
|
3202
|
+
const [linkRequest, setLinkRequest] = useState9(null);
|
|
3203
|
+
const linkRequestRef = useRef10(null);
|
|
3204
|
+
const requestLink = useCallback6((initialHref = "") => {
|
|
2592
3205
|
return new Promise((resolve) => {
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
const resolveLinkRequest = useCallback4((href) => {
|
|
2597
|
-
setLinkRequest((prev) => {
|
|
2598
|
-
if (prev) prev.resolve(href);
|
|
2599
|
-
return null;
|
|
3206
|
+
const req = { initialHref, resolve, selection: selectionRef.current };
|
|
3207
|
+
linkRequestRef.current = req;
|
|
3208
|
+
setLinkRequest(req);
|
|
2600
3209
|
});
|
|
2601
3210
|
}, []);
|
|
3211
|
+
const resolveLinkRequest = useCallback6(
|
|
3212
|
+
(href) => {
|
|
3213
|
+
const req = linkRequestRef.current;
|
|
3214
|
+
linkRequestRef.current = null;
|
|
3215
|
+
setLinkRequest(null);
|
|
3216
|
+
if (req) {
|
|
3217
|
+
setSelection(req.selection);
|
|
3218
|
+
req.resolve(href);
|
|
3219
|
+
}
|
|
3220
|
+
},
|
|
3221
|
+
[setSelection]
|
|
3222
|
+
);
|
|
2602
3223
|
const pageSettings = usePageSettings(doc);
|
|
2603
|
-
const setPageSettings =
|
|
3224
|
+
const setPageSettings = useCallback6(
|
|
2604
3225
|
(partial) => {
|
|
2605
3226
|
doc.setPageSettings(partial);
|
|
2606
3227
|
},
|
|
2607
3228
|
[doc]
|
|
2608
3229
|
);
|
|
2609
|
-
const [pageConfigRequest, setPageConfigRequest] =
|
|
2610
|
-
const requestPageConfig =
|
|
3230
|
+
const [pageConfigRequest, setPageConfigRequest] = useState9(null);
|
|
3231
|
+
const requestPageConfig = useCallback6(() => {
|
|
2611
3232
|
return new Promise((resolve) => {
|
|
2612
3233
|
setPageConfigRequest({ initial: doc.getPageSettings(), resolve });
|
|
2613
3234
|
});
|
|
2614
3235
|
}, [doc]);
|
|
2615
|
-
const resolvePageConfigRequest =
|
|
3236
|
+
const resolvePageConfigRequest = useCallback6((applied) => {
|
|
2616
3237
|
setPageConfigRequest((prev) => {
|
|
2617
3238
|
if (prev) prev.resolve(applied);
|
|
2618
3239
|
return null;
|
|
2619
3240
|
});
|
|
2620
3241
|
}, []);
|
|
2621
|
-
const [imageCaptionRequest, setImageCaptionRequest] =
|
|
2622
|
-
const requestImageCaption =
|
|
3242
|
+
const [imageCaptionRequest, setImageCaptionRequest] = useState9(null);
|
|
3243
|
+
const requestImageCaption = useCallback6(
|
|
2623
3244
|
(initialCaption = "", initialAlign = "center") => {
|
|
2624
3245
|
return new Promise((resolve) => {
|
|
2625
3246
|
setImageCaptionRequest({ initialCaption, initialAlign, resolve });
|
|
@@ -2627,7 +3248,7 @@ function useEditor(opts = {}) {
|
|
|
2627
3248
|
},
|
|
2628
3249
|
[]
|
|
2629
3250
|
);
|
|
2630
|
-
const resolveImageCaptionRequest =
|
|
3251
|
+
const resolveImageCaptionRequest = useCallback6((result) => {
|
|
2631
3252
|
setImageCaptionRequest((prev) => {
|
|
2632
3253
|
if (prev) prev.resolve(result);
|
|
2633
3254
|
return null;
|
|
@@ -2651,6 +3272,8 @@ function useEditor(opts = {}) {
|
|
|
2651
3272
|
getBlockAttr,
|
|
2652
3273
|
setBlockType,
|
|
2653
3274
|
setBlockAttr,
|
|
3275
|
+
setAlign,
|
|
3276
|
+
getAlign,
|
|
2654
3277
|
isListActive,
|
|
2655
3278
|
toggleList,
|
|
2656
3279
|
indentList,
|
|
@@ -2680,6 +3303,7 @@ function useEditor(opts = {}) {
|
|
|
2680
3303
|
mergeSelection,
|
|
2681
3304
|
insertImage,
|
|
2682
3305
|
setImageAttrs,
|
|
3306
|
+
moveEmbedAnchor,
|
|
2683
3307
|
insertImageFromFile,
|
|
2684
3308
|
getSelectedEmbed,
|
|
2685
3309
|
pageSettings,
|
|
@@ -2721,54 +3345,99 @@ function sameValue(a, b) {
|
|
|
2721
3345
|
}
|
|
2722
3346
|
|
|
2723
3347
|
// src/Editor.tsx
|
|
2724
|
-
import { jsx as
|
|
3348
|
+
import { jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
2725
3349
|
var defaultFooter = ({ pageNumber, pageCount }) => `${pageNumber} / ${pageCount}`;
|
|
2726
3350
|
function Editor({
|
|
2727
3351
|
editor: providedEditor,
|
|
2728
3352
|
className,
|
|
2729
3353
|
pageGeometry,
|
|
2730
3354
|
renderPageHeader,
|
|
2731
|
-
renderPageFooter = defaultFooter
|
|
3355
|
+
renderPageFooter = defaultFooter,
|
|
3356
|
+
awareness
|
|
2732
3357
|
}) {
|
|
2733
3358
|
const internal = useEditor();
|
|
2734
3359
|
const editor = providedEditor ?? internal;
|
|
2735
3360
|
const { doc, history, snapshot, getSelection, setSelection } = editor;
|
|
2736
|
-
const rootRef =
|
|
2737
|
-
const isComposingRef =
|
|
2738
|
-
const
|
|
2739
|
-
const
|
|
3361
|
+
const rootRef = useRef11(null);
|
|
3362
|
+
const isComposingRef = useRef11(false);
|
|
3363
|
+
const [hoveredBehind, setHoveredBehind] = useState10(null);
|
|
3364
|
+
const hoveredBehindRef = useRef11(null);
|
|
3365
|
+
const [hoveredLink, setHoveredLink] = useState10(null);
|
|
3366
|
+
const hoveredLinkElRef = useRef11(null);
|
|
3367
|
+
const suppressSelectionSyncRef = useRef11(false);
|
|
3368
|
+
useEffect9(() => {
|
|
3369
|
+
if (!awareness) return;
|
|
3370
|
+
const root = rootRef.current;
|
|
3371
|
+
if (!root) return;
|
|
3372
|
+
let raf = null;
|
|
3373
|
+
const publish = () => {
|
|
3374
|
+
raf = null;
|
|
3375
|
+
const sel = readDomSelection(root);
|
|
3376
|
+
awareness.setLocalStateField(
|
|
3377
|
+
"cursor",
|
|
3378
|
+
sel ? encodeSelection(doc, sel) ?? null : null
|
|
3379
|
+
);
|
|
3380
|
+
};
|
|
3381
|
+
const onSelChange = () => {
|
|
3382
|
+
const s = document.getSelection();
|
|
3383
|
+
if (!s || s.rangeCount === 0) return;
|
|
3384
|
+
if (s.anchorNode && !root.contains(s.anchorNode)) return;
|
|
3385
|
+
if (raf != null) return;
|
|
3386
|
+
raf = requestAnimationFrame(publish);
|
|
3387
|
+
};
|
|
3388
|
+
const onBlur = () => awareness.setLocalStateField("cursor", null);
|
|
3389
|
+
document.addEventListener("selectionchange", onSelChange);
|
|
3390
|
+
root.addEventListener("blur", onBlur, true);
|
|
3391
|
+
return () => {
|
|
3392
|
+
document.removeEventListener("selectionchange", onSelChange);
|
|
3393
|
+
root.removeEventListener("blur", onBlur, true);
|
|
3394
|
+
if (raf != null) cancelAnimationFrame(raf);
|
|
3395
|
+
awareness.setLocalStateField("cursor", null);
|
|
3396
|
+
};
|
|
3397
|
+
}, [awareness, doc]);
|
|
3398
|
+
const ctxRef = useRef11({ doc, getSelection, setSelection });
|
|
2740
3399
|
ctxRef.current = { doc, getSelection, setSelection };
|
|
2741
|
-
const historyRef =
|
|
3400
|
+
const historyRef = useRef11(history);
|
|
2742
3401
|
historyRef.current = history;
|
|
2743
|
-
const editorRef =
|
|
3402
|
+
const editorRef = useRef11(editor);
|
|
2744
3403
|
editorRef.current = editor;
|
|
2745
|
-
|
|
3404
|
+
useLayoutEffect5(() => {
|
|
2746
3405
|
const root = rootRef.current;
|
|
2747
3406
|
if (!root) return;
|
|
2748
3407
|
if (isComposingRef.current) return;
|
|
2749
3408
|
if (document.activeElement !== root) return;
|
|
2750
3409
|
const current = readDomSelection(root);
|
|
2751
3410
|
if (current && selectionsEqual(current, editor.selection)) return;
|
|
3411
|
+
if (isTableRectSelection(editor.selection)) {
|
|
3412
|
+
applyDomSelection(root, editor.selection);
|
|
3413
|
+
suppressSelectionSyncRef.current = false;
|
|
3414
|
+
return;
|
|
3415
|
+
}
|
|
2752
3416
|
suppressSelectionSyncRef.current = true;
|
|
2753
3417
|
applyDomSelection(root, editor.selection);
|
|
2754
|
-
queueMicrotask(() => {
|
|
2755
|
-
suppressSelectionSyncRef.current = false;
|
|
2756
|
-
});
|
|
2757
3418
|
});
|
|
2758
|
-
|
|
3419
|
+
useEffect9(() => {
|
|
2759
3420
|
const root = rootRef.current;
|
|
2760
3421
|
if (!root) return;
|
|
2761
3422
|
const handler = () => {
|
|
2762
|
-
if (suppressSelectionSyncRef.current) return;
|
|
2763
3423
|
if (isComposingRef.current) return;
|
|
2764
|
-
if (document.activeElement !== root)
|
|
3424
|
+
if (document.activeElement !== root) {
|
|
3425
|
+
suppressSelectionSyncRef.current = false;
|
|
3426
|
+
return;
|
|
3427
|
+
}
|
|
2765
3428
|
const modelSel = readDomSelection(root);
|
|
3429
|
+
if (suppressSelectionSyncRef.current) {
|
|
3430
|
+
if (modelSel && selectionsEqual(modelSel, editorRef.current.getSelection())) {
|
|
3431
|
+
suppressSelectionSyncRef.current = false;
|
|
3432
|
+
}
|
|
3433
|
+
return;
|
|
3434
|
+
}
|
|
2766
3435
|
if (modelSel) setSelection(modelSel);
|
|
2767
3436
|
};
|
|
2768
3437
|
document.addEventListener("selectionchange", handler);
|
|
2769
3438
|
return () => document.removeEventListener("selectionchange", handler);
|
|
2770
3439
|
}, [setSelection]);
|
|
2771
|
-
|
|
3440
|
+
useEffect9(() => {
|
|
2772
3441
|
const root = rootRef.current;
|
|
2773
3442
|
if (!root) return;
|
|
2774
3443
|
let drag = null;
|
|
@@ -2839,7 +3508,7 @@ function Editor({
|
|
|
2839
3508
|
document.removeEventListener("pointerup", onPointerUp);
|
|
2840
3509
|
};
|
|
2841
3510
|
}, []);
|
|
2842
|
-
|
|
3511
|
+
useEffect9(() => {
|
|
2843
3512
|
const root = rootRef.current;
|
|
2844
3513
|
if (!root) return;
|
|
2845
3514
|
const onDragOver = (e) => {
|
|
@@ -2877,7 +3546,7 @@ function Editor({
|
|
|
2877
3546
|
root.removeEventListener("drop", onDrop);
|
|
2878
3547
|
};
|
|
2879
3548
|
}, []);
|
|
2880
|
-
|
|
3549
|
+
useEffect9(() => {
|
|
2881
3550
|
const root = rootRef.current;
|
|
2882
3551
|
if (!root) return;
|
|
2883
3552
|
const onPointerDown = (e) => {
|
|
@@ -2905,7 +3574,95 @@ function Editor({
|
|
|
2905
3574
|
root.addEventListener("pointerdown", onPointerDown);
|
|
2906
3575
|
return () => root.removeEventListener("pointerdown", onPointerDown);
|
|
2907
3576
|
}, []);
|
|
2908
|
-
|
|
3577
|
+
useEffect9(() => {
|
|
3578
|
+
const root = rootRef.current;
|
|
3579
|
+
if (!root) return;
|
|
3580
|
+
const same = (a, b) => a === b || !!a && !!b && a.blockIndex === b.blockIndex && a.offset === b.offset && (a.cellIndex ?? -1) === (b.cellIndex ?? -1);
|
|
3581
|
+
const set = (next) => {
|
|
3582
|
+
if (same(next, hoveredBehindRef.current)) return;
|
|
3583
|
+
hoveredBehindRef.current = next;
|
|
3584
|
+
setHoveredBehind(next);
|
|
3585
|
+
};
|
|
3586
|
+
let raf = 0;
|
|
3587
|
+
const onMove = (e) => {
|
|
3588
|
+
if (raf) return;
|
|
3589
|
+
const x = e.clientX;
|
|
3590
|
+
const y = e.clientY;
|
|
3591
|
+
raf = requestAnimationFrame(() => {
|
|
3592
|
+
raf = 0;
|
|
3593
|
+
const imgs = root.querySelectorAll(
|
|
3594
|
+
'img[data-embed="image"][data-embed-layout="behind"]'
|
|
3595
|
+
);
|
|
3596
|
+
let hit = null;
|
|
3597
|
+
for (const img of imgs) {
|
|
3598
|
+
const r = img.getBoundingClientRect();
|
|
3599
|
+
if (x >= r.left && x <= r.right && y >= r.top && y <= r.bottom) {
|
|
3600
|
+
hit = img;
|
|
3601
|
+
break;
|
|
3602
|
+
}
|
|
3603
|
+
}
|
|
3604
|
+
if (!hit) {
|
|
3605
|
+
set(null);
|
|
3606
|
+
return;
|
|
3607
|
+
}
|
|
3608
|
+
const blockEl = hit.closest("[data-block-index]");
|
|
3609
|
+
const offsetAttr = hit.dataset.embedOffset;
|
|
3610
|
+
if (!blockEl || offsetAttr == null) {
|
|
3611
|
+
set(null);
|
|
3612
|
+
return;
|
|
3613
|
+
}
|
|
3614
|
+
const blockIndex = Number.parseInt(blockEl.dataset.blockIndex, 10);
|
|
3615
|
+
const fragmentStart = Number.parseInt(blockEl.dataset.fragmentStart ?? "0", 10) || 0;
|
|
3616
|
+
const cellEl = hit.closest("[data-cell-index]");
|
|
3617
|
+
const cellIndex = cellEl ? Number.parseInt(cellEl.dataset.cellIndex, 10) : void 0;
|
|
3618
|
+
set({ blockIndex, offset: fragmentStart + Number.parseInt(offsetAttr, 10), cellIndex });
|
|
3619
|
+
});
|
|
3620
|
+
};
|
|
3621
|
+
const onLeave = () => set(null);
|
|
3622
|
+
root.addEventListener("pointermove", onMove);
|
|
3623
|
+
root.addEventListener("pointerleave", onLeave);
|
|
3624
|
+
return () => {
|
|
3625
|
+
root.removeEventListener("pointermove", onMove);
|
|
3626
|
+
root.removeEventListener("pointerleave", onLeave);
|
|
3627
|
+
if (raf) cancelAnimationFrame(raf);
|
|
3628
|
+
};
|
|
3629
|
+
}, []);
|
|
3630
|
+
useEffect9(() => {
|
|
3631
|
+
const root = rootRef.current;
|
|
3632
|
+
if (!root) return;
|
|
3633
|
+
const clear = () => {
|
|
3634
|
+
if (hoveredLinkElRef.current) {
|
|
3635
|
+
hoveredLinkElRef.current = null;
|
|
3636
|
+
setHoveredLink(null);
|
|
3637
|
+
}
|
|
3638
|
+
};
|
|
3639
|
+
const onOver = (e) => {
|
|
3640
|
+
const target = e.target;
|
|
3641
|
+
const a = target?.closest?.("a[href]");
|
|
3642
|
+
if (a && root.contains(a)) {
|
|
3643
|
+
if (hoveredLinkElRef.current === a) return;
|
|
3644
|
+
hoveredLinkElRef.current = a;
|
|
3645
|
+
const r = a.getBoundingClientRect();
|
|
3646
|
+
setHoveredLink({
|
|
3647
|
+
href: a.getAttribute("href") ?? "",
|
|
3648
|
+
rect: { top: r.top, left: r.left, bottom: r.bottom, width: r.width }
|
|
3649
|
+
});
|
|
3650
|
+
} else {
|
|
3651
|
+
clear();
|
|
3652
|
+
}
|
|
3653
|
+
};
|
|
3654
|
+
root.addEventListener("mouseover", onOver);
|
|
3655
|
+
root.addEventListener("mouseleave", clear);
|
|
3656
|
+
root.addEventListener("scroll", clear, true);
|
|
3657
|
+
window.addEventListener("scroll", clear, true);
|
|
3658
|
+
return () => {
|
|
3659
|
+
root.removeEventListener("mouseover", onOver);
|
|
3660
|
+
root.removeEventListener("mouseleave", clear);
|
|
3661
|
+
root.removeEventListener("scroll", clear, true);
|
|
3662
|
+
window.removeEventListener("scroll", clear, true);
|
|
3663
|
+
};
|
|
3664
|
+
}, []);
|
|
3665
|
+
useEffect9(() => {
|
|
2909
3666
|
const root = rootRef.current;
|
|
2910
3667
|
if (!root) return;
|
|
2911
3668
|
const handler = (e) => {
|
|
@@ -2981,22 +3738,6 @@ function Editor({
|
|
|
2981
3738
|
}
|
|
2982
3739
|
case "insertFromPaste": {
|
|
2983
3740
|
e.preventDefault();
|
|
2984
|
-
const images = Array.from(e.dataTransfer?.files ?? []).filter(
|
|
2985
|
-
(f) => f.type.startsWith("image/")
|
|
2986
|
-
);
|
|
2987
|
-
if (images.length > 0) {
|
|
2988
|
-
void (async () => {
|
|
2989
|
-
for (const f of images) await editorRef.current.insertImageFromFile(f);
|
|
2990
|
-
})();
|
|
2991
|
-
return;
|
|
2992
|
-
}
|
|
2993
|
-
const text = e.dataTransfer?.getData("text/plain") ?? "";
|
|
2994
|
-
if (text.length === 0) return;
|
|
2995
|
-
const lines = text.split(/\r\n|\r|\n/);
|
|
2996
|
-
lines.forEach((line, i) => {
|
|
2997
|
-
if (i > 0) insertParagraph(ctx);
|
|
2998
|
-
if (line.length > 0) insertText(ctx, line);
|
|
2999
|
-
});
|
|
3000
3741
|
return;
|
|
3001
3742
|
}
|
|
3002
3743
|
case "deleteContentBackward":
|
|
@@ -3034,7 +3775,67 @@ function Editor({
|
|
|
3034
3775
|
root.addEventListener("beforeinput", handler);
|
|
3035
3776
|
return () => root.removeEventListener("beforeinput", handler);
|
|
3036
3777
|
}, []);
|
|
3037
|
-
|
|
3778
|
+
useEffect9(() => {
|
|
3779
|
+
const root = rootRef.current;
|
|
3780
|
+
if (!root) return;
|
|
3781
|
+
const writeSlice = (e) => {
|
|
3782
|
+
const ctx = ctxRef.current;
|
|
3783
|
+
const slice = serializeSelection(ctx.doc, ctx.getSelection());
|
|
3784
|
+
if (!slice || !e.clipboardData) return false;
|
|
3785
|
+
e.clipboardData.setData(SOFER_MIME, JSON.stringify(slice));
|
|
3786
|
+
e.clipboardData.setData("text/plain", sliceToText(slice));
|
|
3787
|
+
return true;
|
|
3788
|
+
};
|
|
3789
|
+
const onCopy = (e) => {
|
|
3790
|
+
if (writeSlice(e)) e.preventDefault();
|
|
3791
|
+
};
|
|
3792
|
+
const onCut = (e) => {
|
|
3793
|
+
e.preventDefault();
|
|
3794
|
+
if (writeSlice(e)) deleteSelection(ctxRef.current);
|
|
3795
|
+
};
|
|
3796
|
+
const onPaste = (e) => {
|
|
3797
|
+
const ctx = ctxRef.current;
|
|
3798
|
+
const cd = e.clipboardData;
|
|
3799
|
+
if (!cd) return;
|
|
3800
|
+
const raw = cd.getData(SOFER_MIME);
|
|
3801
|
+
if (raw) {
|
|
3802
|
+
try {
|
|
3803
|
+
const slice = JSON.parse(raw);
|
|
3804
|
+
if (slice && Array.isArray(slice.blocks)) {
|
|
3805
|
+
e.preventDefault();
|
|
3806
|
+
insertSlice(ctx, slice);
|
|
3807
|
+
return;
|
|
3808
|
+
}
|
|
3809
|
+
} catch {
|
|
3810
|
+
}
|
|
3811
|
+
}
|
|
3812
|
+
const images = Array.from(cd.files ?? []).filter((f) => f.type.startsWith("image/"));
|
|
3813
|
+
if (images.length > 0) {
|
|
3814
|
+
e.preventDefault();
|
|
3815
|
+
void (async () => {
|
|
3816
|
+
for (const f of images) await editorRef.current.insertImageFromFile(f);
|
|
3817
|
+
})();
|
|
3818
|
+
return;
|
|
3819
|
+
}
|
|
3820
|
+
const text = cd.getData("text/plain");
|
|
3821
|
+
if (text.length === 0) return;
|
|
3822
|
+
e.preventDefault();
|
|
3823
|
+
const lines = text.split(/\r\n|\r|\n/);
|
|
3824
|
+
lines.forEach((line, i) => {
|
|
3825
|
+
if (i > 0) insertParagraph(ctx);
|
|
3826
|
+
if (line.length > 0) insertText(ctx, line);
|
|
3827
|
+
});
|
|
3828
|
+
};
|
|
3829
|
+
root.addEventListener("copy", onCopy);
|
|
3830
|
+
root.addEventListener("cut", onCut);
|
|
3831
|
+
root.addEventListener("paste", onPaste);
|
|
3832
|
+
return () => {
|
|
3833
|
+
root.removeEventListener("copy", onCopy);
|
|
3834
|
+
root.removeEventListener("cut", onCut);
|
|
3835
|
+
root.removeEventListener("paste", onPaste);
|
|
3836
|
+
};
|
|
3837
|
+
}, []);
|
|
3838
|
+
const onKeyDown = useCallback7((e) => {
|
|
3038
3839
|
const ed = editorRef.current;
|
|
3039
3840
|
const mod = e.metaKey || e.ctrlKey;
|
|
3040
3841
|
if (e.key === "Tab") {
|
|
@@ -3108,10 +3909,10 @@ function Editor({
|
|
|
3108
3909
|
});
|
|
3109
3910
|
}
|
|
3110
3911
|
}, []);
|
|
3111
|
-
const onCompositionStart =
|
|
3912
|
+
const onCompositionStart = useCallback7(() => {
|
|
3112
3913
|
isComposingRef.current = true;
|
|
3113
3914
|
}, []);
|
|
3114
|
-
const onCompositionEnd =
|
|
3915
|
+
const onCompositionEnd = useCallback7((e) => {
|
|
3115
3916
|
isComposingRef.current = false;
|
|
3116
3917
|
if (e.data && e.data.length > 0) {
|
|
3117
3918
|
insertText(ctxRef.current, e.data);
|
|
@@ -3159,7 +3960,7 @@ function Editor({
|
|
|
3159
3960
|
geom.marginRight
|
|
3160
3961
|
]
|
|
3161
3962
|
);
|
|
3162
|
-
const body = /* @__PURE__ */
|
|
3963
|
+
const body = /* @__PURE__ */ jsxs11(
|
|
3163
3964
|
"div",
|
|
3164
3965
|
{
|
|
3165
3966
|
ref: rootRef,
|
|
@@ -3185,7 +3986,7 @@ function Editor({
|
|
|
3185
3986
|
const pageInlineStyle = pi === 0 && geom.firstPageExtraTop ? {
|
|
3186
3987
|
"--ed-page-margin-top": `${geom.marginTop + geom.firstPageExtraTop}px`
|
|
3187
3988
|
} : void 0;
|
|
3188
|
-
return /* @__PURE__ */
|
|
3989
|
+
return /* @__PURE__ */ jsxs11(
|
|
3189
3990
|
"div",
|
|
3190
3991
|
{
|
|
3191
3992
|
className: "ed-page",
|
|
@@ -3193,15 +3994,15 @@ function Editor({
|
|
|
3193
3994
|
"data-page-total": ctx.pageCount,
|
|
3194
3995
|
style: pageInlineStyle,
|
|
3195
3996
|
children: [
|
|
3196
|
-
renderPageHeader && /* @__PURE__ */
|
|
3197
|
-
/* @__PURE__ */
|
|
3198
|
-
renderPageFooter && /* @__PURE__ */
|
|
3997
|
+
renderPageHeader && /* @__PURE__ */ jsx12("div", { className: "ed-page-header", contentEditable: false, children: renderPageHeader(ctx) }),
|
|
3998
|
+
/* @__PURE__ */ jsx12("div", { className: "ed-page-content", children: page.slots.map((slot) => renderSlot(slot, topLevels)) }),
|
|
3999
|
+
renderPageFooter && /* @__PURE__ */ jsx12("div", { className: "ed-page-footer", contentEditable: false, children: renderPageFooter(ctx) })
|
|
3199
4000
|
]
|
|
3200
4001
|
},
|
|
3201
4002
|
`page-${pi}`
|
|
3202
4003
|
);
|
|
3203
4004
|
}) : topLevels.map((t) => renderTopLevel(t)),
|
|
3204
|
-
selectedEmbed && /* @__PURE__ */
|
|
4005
|
+
selectedEmbed && /* @__PURE__ */ jsx12(
|
|
3205
4006
|
ImageResizeOverlay,
|
|
3206
4007
|
{
|
|
3207
4008
|
rootRef,
|
|
@@ -3220,13 +4021,54 @@ function Editor({
|
|
|
3220
4021
|
selectedEmbed.offset,
|
|
3221
4022
|
{ offsetX: ox, offsetY: oy },
|
|
3222
4023
|
selectedEmbed.cellIndex
|
|
4024
|
+
),
|
|
4025
|
+
onReanchor: (to, ox, oy) => editor.moveEmbedAnchor(
|
|
4026
|
+
{
|
|
4027
|
+
blockIndex: selectedEmbed.blockIndex,
|
|
4028
|
+
offset: selectedEmbed.offset,
|
|
4029
|
+
cellIndex: selectedEmbed.cellIndex
|
|
4030
|
+
},
|
|
4031
|
+
to,
|
|
4032
|
+
ox,
|
|
4033
|
+
oy
|
|
3223
4034
|
)
|
|
3224
4035
|
}
|
|
4036
|
+
),
|
|
4037
|
+
hoveredBehind && !(selectedEmbed && selectedEmbed.blockIndex === hoveredBehind.blockIndex && selectedEmbed.offset === hoveredBehind.offset && (selectedEmbed.cellIndex ?? -1) === (hoveredBehind.cellIndex ?? -1)) && /* @__PURE__ */ jsx12(
|
|
4038
|
+
BehindImageSelectAffordance,
|
|
4039
|
+
{
|
|
4040
|
+
rootRef,
|
|
4041
|
+
blockIndex: hoveredBehind.blockIndex,
|
|
4042
|
+
offset: hoveredBehind.offset,
|
|
4043
|
+
cellIndex: hoveredBehind.cellIndex,
|
|
4044
|
+
onSelect: () => setSelection({
|
|
4045
|
+
anchor: {
|
|
4046
|
+
blockIndex: hoveredBehind.blockIndex,
|
|
4047
|
+
cellIndex: hoveredBehind.cellIndex,
|
|
4048
|
+
offset: hoveredBehind.offset
|
|
4049
|
+
},
|
|
4050
|
+
focus: {
|
|
4051
|
+
blockIndex: hoveredBehind.blockIndex,
|
|
4052
|
+
cellIndex: hoveredBehind.cellIndex,
|
|
4053
|
+
offset: hoveredBehind.offset + 1
|
|
4054
|
+
}
|
|
4055
|
+
})
|
|
4056
|
+
}
|
|
4057
|
+
),
|
|
4058
|
+
hoveredLink && hoveredLink.href && /* @__PURE__ */ jsx12(LinkHoverTooltip, { href: hoveredLink.href, rect: hoveredLink.rect }),
|
|
4059
|
+
awareness && /* @__PURE__ */ jsx12(
|
|
4060
|
+
RemoteCursorsOverlay,
|
|
4061
|
+
{
|
|
4062
|
+
rootRef,
|
|
4063
|
+
doc,
|
|
4064
|
+
awareness,
|
|
4065
|
+
revision: snapshot
|
|
4066
|
+
}
|
|
3225
4067
|
)
|
|
3226
4068
|
]
|
|
3227
4069
|
}
|
|
3228
4070
|
);
|
|
3229
|
-
return /* @__PURE__ */
|
|
4071
|
+
return /* @__PURE__ */ jsx12(EditorProvider, { editor, children: body });
|
|
3230
4072
|
}
|
|
3231
4073
|
function groupTopLevels(snapshot) {
|
|
3232
4074
|
const out = [];
|
|
@@ -3276,7 +4118,7 @@ function renderSlot(slot, topLevels) {
|
|
|
3276
4118
|
start: slot.fragment.start,
|
|
3277
4119
|
end: slot.fragment.end
|
|
3278
4120
|
};
|
|
3279
|
-
return /* @__PURE__ */
|
|
4121
|
+
return /* @__PURE__ */ jsx12(
|
|
3280
4122
|
NodeView,
|
|
3281
4123
|
{
|
|
3282
4124
|
block: top.block,
|
|
@@ -3287,7 +4129,7 @@ function renderSlot(slot, topLevels) {
|
|
|
3287
4129
|
);
|
|
3288
4130
|
}
|
|
3289
4131
|
if (slot.tableFragment && top.kind === "block" && top.block.type === "table") {
|
|
3290
|
-
return /* @__PURE__ */
|
|
4132
|
+
return /* @__PURE__ */ jsx12(
|
|
3291
4133
|
NodeView,
|
|
3292
4134
|
{
|
|
3293
4135
|
block: top.block,
|
|
@@ -3307,7 +4149,7 @@ function renderTopLevel(top) {
|
|
|
3307
4149
|
const tree = buildListTree(top.items);
|
|
3308
4150
|
return renderListTree(tree, top, top.ordinalStart, `list-${top.key}`);
|
|
3309
4151
|
}
|
|
3310
|
-
return /* @__PURE__ */
|
|
4152
|
+
return /* @__PURE__ */ jsx12(NodeView, { block: top.block, index: top.blockIndex }, top.key);
|
|
3311
4153
|
}
|
|
3312
4154
|
function renderListFragment(top, frag) {
|
|
3313
4155
|
const ranges = topLevelItemRanges(top.items);
|
|
@@ -3349,9 +4191,9 @@ function buildListTree(items) {
|
|
|
3349
4191
|
function renderListTree(tree, top, start, key) {
|
|
3350
4192
|
const className = `ed-list ed-list-${top.listKind}`;
|
|
3351
4193
|
const style = top.listStyle ? { listStyleType: top.listStyle } : void 0;
|
|
3352
|
-
const items = tree.map((node) => /* @__PURE__ */
|
|
4194
|
+
const items = tree.map((node) => /* @__PURE__ */ jsx12(NodeView, { block: node.entry.block, index: node.entry.index, children: node.children.length > 0 ? renderNestedListTree(node.children, top.listKind, `nested-${node.entry.index}`) : null }, node.entry.index));
|
|
3353
4195
|
if (top.listKind === "ordered") {
|
|
3354
|
-
return /* @__PURE__ */
|
|
4196
|
+
return /* @__PURE__ */ jsx12(
|
|
3355
4197
|
"ol",
|
|
3356
4198
|
{
|
|
3357
4199
|
className,
|
|
@@ -3363,11 +4205,11 @@ function renderListTree(tree, top, start, key) {
|
|
|
3363
4205
|
key
|
|
3364
4206
|
);
|
|
3365
4207
|
}
|
|
3366
|
-
return /* @__PURE__ */
|
|
4208
|
+
return /* @__PURE__ */ jsx12("ul", { className, "data-list-kind": "bullet", style, children: items }, key);
|
|
3367
4209
|
}
|
|
3368
4210
|
function renderNestedListTree(tree, kind, key) {
|
|
3369
4211
|
const Tag = kind === "ordered" ? "ol" : "ul";
|
|
3370
|
-
return /* @__PURE__ */
|
|
4212
|
+
return /* @__PURE__ */ jsx12(Tag, { className: `ed-list ed-list-${kind}`, "data-list-kind": kind, children: tree.map((node) => /* @__PURE__ */ jsx12(NodeView, { block: node.entry.block, index: node.entry.index, children: node.children.length > 0 ? renderNestedListTree(node.children, kind, `nested-${node.entry.index}`) : null }, node.entry.index)) }, key);
|
|
3371
4213
|
}
|
|
3372
4214
|
function clampListLevel2(l) {
|
|
3373
4215
|
if (typeof l !== "number" || !Number.isFinite(l)) return 0;
|
|
@@ -3396,12 +4238,12 @@ function caretRangeFromPoint(x, y) {
|
|
|
3396
4238
|
|
|
3397
4239
|
// src/Toolbar.tsx
|
|
3398
4240
|
import {
|
|
3399
|
-
useCallback as
|
|
3400
|
-
useEffect as
|
|
3401
|
-
useRef as
|
|
3402
|
-
useState as
|
|
4241
|
+
useCallback as useCallback8,
|
|
4242
|
+
useEffect as useEffect10,
|
|
4243
|
+
useRef as useRef12,
|
|
4244
|
+
useState as useState11
|
|
3403
4245
|
} from "react";
|
|
3404
|
-
import { jsx as
|
|
4246
|
+
import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
3405
4247
|
var FONT_FAMILIES = ["Arial"];
|
|
3406
4248
|
var FONT_SIZES = ["8pt", "10pt", "11pt", "12pt", "14pt", "16pt", "18pt", "24pt", "32pt", "48pt"];
|
|
3407
4249
|
var BLOCK_OPTIONS = [
|
|
@@ -3441,6 +4283,8 @@ function Toolbar({ className }) {
|
|
|
3441
4283
|
getBlockAttr,
|
|
3442
4284
|
setBlockType,
|
|
3443
4285
|
setBlockAttr,
|
|
4286
|
+
setAlign,
|
|
4287
|
+
getAlign,
|
|
3444
4288
|
isListActive,
|
|
3445
4289
|
toggleList,
|
|
3446
4290
|
indentList,
|
|
@@ -3449,7 +4293,7 @@ function Toolbar({ className }) {
|
|
|
3449
4293
|
const active = getActiveMarks();
|
|
3450
4294
|
const blockType = getBlockType();
|
|
3451
4295
|
const blockLevel = getBlockAttr("level");
|
|
3452
|
-
const blockAlign =
|
|
4296
|
+
const blockAlign = getAlign();
|
|
3453
4297
|
const blockDir = getBlockAttr("dir");
|
|
3454
4298
|
const stop = (e) => {
|
|
3455
4299
|
const t = e.target;
|
|
@@ -3492,16 +4336,16 @@ function Toolbar({ className }) {
|
|
|
3492
4336
|
);
|
|
3493
4337
|
return;
|
|
3494
4338
|
}
|
|
3495
|
-
|
|
4339
|
+
setAlign(value);
|
|
3496
4340
|
};
|
|
3497
|
-
const onInsertImageClick =
|
|
4341
|
+
const onInsertImageClick = useCallback8(
|
|
3498
4342
|
(e) => {
|
|
3499
4343
|
e.preventDefault();
|
|
3500
4344
|
imageInputRef.current?.click();
|
|
3501
4345
|
},
|
|
3502
4346
|
[]
|
|
3503
4347
|
);
|
|
3504
|
-
const onImageInputChange =
|
|
4348
|
+
const onImageInputChange = useCallback8(
|
|
3505
4349
|
(e) => {
|
|
3506
4350
|
const file = e.target.files?.[0];
|
|
3507
4351
|
if (file) void editor.insertImageFromFile(file);
|
|
@@ -3509,14 +4353,14 @@ function Toolbar({ className }) {
|
|
|
3509
4353
|
},
|
|
3510
4354
|
[editor]
|
|
3511
4355
|
);
|
|
3512
|
-
const imageInputRef =
|
|
4356
|
+
const imageInputRef = useRef12(null);
|
|
3513
4357
|
const onToggleDir = (e) => {
|
|
3514
4358
|
e.preventDefault();
|
|
3515
4359
|
const next = blockDir === "rtl" ? "ltr" : "rtl";
|
|
3516
4360
|
setBlockAttr("dir", next);
|
|
3517
4361
|
};
|
|
3518
4362
|
const linkActive = isMarkActive("link");
|
|
3519
|
-
const onLinkClick =
|
|
4363
|
+
const onLinkClick = useCallback8(
|
|
3520
4364
|
(e) => {
|
|
3521
4365
|
e.preventDefault();
|
|
3522
4366
|
const currentHref = active.link && typeof active.link === "object" && "href" in active.link ? active.link.href : "";
|
|
@@ -3546,7 +4390,7 @@ function Toolbar({ className }) {
|
|
|
3546
4390
|
sel.cellIndex
|
|
3547
4391
|
);
|
|
3548
4392
|
};
|
|
3549
|
-
return /* @__PURE__ */
|
|
4393
|
+
return /* @__PURE__ */ jsxs12(
|
|
3550
4394
|
"div",
|
|
3551
4395
|
{
|
|
3552
4396
|
className: className ?? "ed-toolbar",
|
|
@@ -3554,7 +4398,7 @@ function Toolbar({ className }) {
|
|
|
3554
4398
|
"aria-label": "Editor toolbar",
|
|
3555
4399
|
onMouseDown: stop,
|
|
3556
4400
|
children: [
|
|
3557
|
-
/* @__PURE__ */
|
|
4401
|
+
/* @__PURE__ */ jsx13(Group, { children: /* @__PURE__ */ jsxs12(
|
|
3558
4402
|
"select",
|
|
3559
4403
|
{
|
|
3560
4404
|
className: "ed-toolbar-select",
|
|
@@ -3563,23 +4407,23 @@ function Toolbar({ className }) {
|
|
|
3563
4407
|
onMouseDown: stop,
|
|
3564
4408
|
"aria-label": "Tipo de bloco",
|
|
3565
4409
|
children: [
|
|
3566
|
-
blockValue === "" && /* @__PURE__ */
|
|
3567
|
-
BLOCK_OPTIONS.map((o) => /* @__PURE__ */
|
|
4410
|
+
blockValue === "" && /* @__PURE__ */ jsx13("option", { value: "", children: "\u2014 (misto)" }),
|
|
4411
|
+
BLOCK_OPTIONS.map((o) => /* @__PURE__ */ jsx13("option", { value: o.value, children: o.label }, o.value))
|
|
3568
4412
|
]
|
|
3569
4413
|
}
|
|
3570
4414
|
) }),
|
|
3571
|
-
/* @__PURE__ */
|
|
3572
|
-
/* @__PURE__ */
|
|
3573
|
-
/* @__PURE__ */
|
|
3574
|
-
/* @__PURE__ */
|
|
3575
|
-
/* @__PURE__ */
|
|
4415
|
+
/* @__PURE__ */ jsxs12(Group, { children: [
|
|
4416
|
+
/* @__PURE__ */ jsx13(MarkButton, { title: "Negrito (\u2318B)", pressed: isMarkActive("bold"), onClick: onToggle("bold"), children: /* @__PURE__ */ jsx13("strong", { children: "B" }) }),
|
|
4417
|
+
/* @__PURE__ */ jsx13(MarkButton, { title: "It\xE1lico (\u2318I)", pressed: isMarkActive("italic"), onClick: onToggle("italic"), children: /* @__PURE__ */ jsx13("em", { children: "I" }) }),
|
|
4418
|
+
/* @__PURE__ */ jsx13(MarkButton, { title: "Sublinhado (\u2318U)", pressed: isMarkActive("underline"), onClick: onToggle("underline"), children: /* @__PURE__ */ jsx13("u", { children: "U" }) }),
|
|
4419
|
+
/* @__PURE__ */ jsx13(MarkButton, { title: "Tachado (\u2318\u21E7X)", pressed: isMarkActive("strike"), onClick: onToggle("strike"), children: /* @__PURE__ */ jsx13("s", { children: "S" }) })
|
|
3576
4420
|
] }),
|
|
3577
|
-
/* @__PURE__ */
|
|
3578
|
-
/* @__PURE__ */
|
|
3579
|
-
/* @__PURE__ */
|
|
3580
|
-
/* @__PURE__ */
|
|
4421
|
+
/* @__PURE__ */ jsxs12(Group, { children: [
|
|
4422
|
+
/* @__PURE__ */ jsxs12("label", { className: "ed-toolbar-label", children: [
|
|
4423
|
+
/* @__PURE__ */ jsx13("span", { className: "ed-toolbar-swatch", "aria-hidden": true, style: { background: colorValue } }),
|
|
4424
|
+
/* @__PURE__ */ jsx13("input", { type: "color", value: colorValue, onChange: onColorChange, onMouseDown: stop, "aria-label": "Cor do texto" })
|
|
3581
4425
|
] }),
|
|
3582
|
-
/* @__PURE__ */
|
|
4426
|
+
/* @__PURE__ */ jsx13(
|
|
3583
4427
|
"button",
|
|
3584
4428
|
{
|
|
3585
4429
|
type: "button",
|
|
@@ -3594,8 +4438,8 @@ function Toolbar({ className }) {
|
|
|
3594
4438
|
}
|
|
3595
4439
|
)
|
|
3596
4440
|
] }),
|
|
3597
|
-
/* @__PURE__ */
|
|
3598
|
-
/* @__PURE__ */
|
|
4441
|
+
/* @__PURE__ */ jsxs12(Group, { children: [
|
|
4442
|
+
/* @__PURE__ */ jsxs12(
|
|
3599
4443
|
"select",
|
|
3600
4444
|
{
|
|
3601
4445
|
className: "ed-toolbar-select",
|
|
@@ -3604,12 +4448,12 @@ function Toolbar({ className }) {
|
|
|
3604
4448
|
onMouseDown: stop,
|
|
3605
4449
|
"aria-label": "Fam\xEDlia da fonte",
|
|
3606
4450
|
children: [
|
|
3607
|
-
/* @__PURE__ */
|
|
3608
|
-
FONT_FAMILIES.map((f) => /* @__PURE__ */
|
|
4451
|
+
/* @__PURE__ */ jsx13("option", { value: "", children: "Fonte\u2026" }),
|
|
4452
|
+
FONT_FAMILIES.map((f) => /* @__PURE__ */ jsx13("option", { value: f, children: f }, f))
|
|
3609
4453
|
]
|
|
3610
4454
|
}
|
|
3611
4455
|
),
|
|
3612
|
-
/* @__PURE__ */
|
|
4456
|
+
/* @__PURE__ */ jsxs12(
|
|
3613
4457
|
"select",
|
|
3614
4458
|
{
|
|
3615
4459
|
className: "ed-toolbar-select",
|
|
@@ -3618,13 +4462,13 @@ function Toolbar({ className }) {
|
|
|
3618
4462
|
onMouseDown: stop,
|
|
3619
4463
|
"aria-label": "Tamanho da fonte",
|
|
3620
4464
|
children: [
|
|
3621
|
-
/* @__PURE__ */
|
|
3622
|
-
FONT_SIZES.map((s) => /* @__PURE__ */
|
|
4465
|
+
/* @__PURE__ */ jsx13("option", { value: "", children: "Tamanho\u2026" }),
|
|
4466
|
+
FONT_SIZES.map((s) => /* @__PURE__ */ jsx13("option", { value: s, children: s }, s))
|
|
3623
4467
|
]
|
|
3624
4468
|
}
|
|
3625
4469
|
)
|
|
3626
4470
|
] }),
|
|
3627
|
-
/* @__PURE__ */
|
|
4471
|
+
/* @__PURE__ */ jsx13(Group, { children: ALIGN_OPTIONS.map((a) => /* @__PURE__ */ jsx13(
|
|
3628
4472
|
"button",
|
|
3629
4473
|
{
|
|
3630
4474
|
type: "button",
|
|
@@ -3637,7 +4481,7 @@ function Toolbar({ className }) {
|
|
|
3637
4481
|
},
|
|
3638
4482
|
a.value
|
|
3639
4483
|
)) }),
|
|
3640
|
-
/* @__PURE__ */
|
|
4484
|
+
/* @__PURE__ */ jsx13(Group, { children: /* @__PURE__ */ jsx13(
|
|
3641
4485
|
"button",
|
|
3642
4486
|
{
|
|
3643
4487
|
type: "button",
|
|
@@ -3649,8 +4493,8 @@ function Toolbar({ className }) {
|
|
|
3649
4493
|
children: blockDir === "rtl" ? "RTL" : "LTR"
|
|
3650
4494
|
}
|
|
3651
4495
|
) }),
|
|
3652
|
-
/* @__PURE__ */
|
|
3653
|
-
/* @__PURE__ */
|
|
4496
|
+
/* @__PURE__ */ jsxs12(Group, { children: [
|
|
4497
|
+
/* @__PURE__ */ jsx13(
|
|
3654
4498
|
"button",
|
|
3655
4499
|
{
|
|
3656
4500
|
type: "button",
|
|
@@ -3665,7 +4509,7 @@ function Toolbar({ className }) {
|
|
|
3665
4509
|
children: "\u2022"
|
|
3666
4510
|
}
|
|
3667
4511
|
),
|
|
3668
|
-
/* @__PURE__ */
|
|
4512
|
+
/* @__PURE__ */ jsx13(
|
|
3669
4513
|
"button",
|
|
3670
4514
|
{
|
|
3671
4515
|
type: "button",
|
|
@@ -3680,7 +4524,7 @@ function Toolbar({ className }) {
|
|
|
3680
4524
|
children: "1."
|
|
3681
4525
|
}
|
|
3682
4526
|
),
|
|
3683
|
-
/* @__PURE__ */
|
|
4527
|
+
/* @__PURE__ */ jsx13(
|
|
3684
4528
|
"button",
|
|
3685
4529
|
{
|
|
3686
4530
|
type: "button",
|
|
@@ -3694,7 +4538,7 @@ function Toolbar({ className }) {
|
|
|
3694
4538
|
children: "\u21E4"
|
|
3695
4539
|
}
|
|
3696
4540
|
),
|
|
3697
|
-
/* @__PURE__ */
|
|
4541
|
+
/* @__PURE__ */ jsx13(
|
|
3698
4542
|
"button",
|
|
3699
4543
|
{
|
|
3700
4544
|
type: "button",
|
|
@@ -3709,7 +4553,7 @@ function Toolbar({ className }) {
|
|
|
3709
4553
|
}
|
|
3710
4554
|
)
|
|
3711
4555
|
] }),
|
|
3712
|
-
/* @__PURE__ */
|
|
4556
|
+
/* @__PURE__ */ jsx13(Group, { children: /* @__PURE__ */ jsx13(
|
|
3713
4557
|
"button",
|
|
3714
4558
|
{
|
|
3715
4559
|
type: "button",
|
|
@@ -3721,9 +4565,9 @@ function Toolbar({ className }) {
|
|
|
3721
4565
|
children: "\u{1F517}"
|
|
3722
4566
|
}
|
|
3723
4567
|
) }),
|
|
3724
|
-
/* @__PURE__ */
|
|
3725
|
-
/* @__PURE__ */
|
|
3726
|
-
/* @__PURE__ */
|
|
4568
|
+
/* @__PURE__ */ jsx13(Group, { children: /* @__PURE__ */ jsx13(TableMenu, {}) }),
|
|
4569
|
+
/* @__PURE__ */ jsxs12(Group, { children: [
|
|
4570
|
+
/* @__PURE__ */ jsx13(
|
|
3727
4571
|
"button",
|
|
3728
4572
|
{
|
|
3729
4573
|
type: "button",
|
|
@@ -3734,7 +4578,7 @@ function Toolbar({ className }) {
|
|
|
3734
4578
|
children: "\u{1F5BC}"
|
|
3735
4579
|
}
|
|
3736
4580
|
),
|
|
3737
|
-
/* @__PURE__ */
|
|
4581
|
+
/* @__PURE__ */ jsx13(
|
|
3738
4582
|
"input",
|
|
3739
4583
|
{
|
|
3740
4584
|
ref: imageInputRef,
|
|
@@ -3745,8 +4589,8 @@ function Toolbar({ className }) {
|
|
|
3745
4589
|
}
|
|
3746
4590
|
)
|
|
3747
4591
|
] }),
|
|
3748
|
-
selectedEmbed && /* @__PURE__ */
|
|
3749
|
-
IMAGE_LAYOUT_OPTIONS.map((opt) => /* @__PURE__ */
|
|
4592
|
+
selectedEmbed && /* @__PURE__ */ jsxs12(Group, { children: [
|
|
4593
|
+
IMAGE_LAYOUT_OPTIONS.map((opt) => /* @__PURE__ */ jsx13(
|
|
3750
4594
|
"button",
|
|
3751
4595
|
{
|
|
3752
4596
|
type: "button",
|
|
@@ -3759,7 +4603,7 @@ function Toolbar({ className }) {
|
|
|
3759
4603
|
},
|
|
3760
4604
|
opt.value
|
|
3761
4605
|
)),
|
|
3762
|
-
/* @__PURE__ */
|
|
4606
|
+
/* @__PURE__ */ jsx13(
|
|
3763
4607
|
"button",
|
|
3764
4608
|
{
|
|
3765
4609
|
type: "button",
|
|
@@ -3789,7 +4633,7 @@ function Toolbar({ className }) {
|
|
|
3789
4633
|
}
|
|
3790
4634
|
)
|
|
3791
4635
|
] }),
|
|
3792
|
-
/* @__PURE__ */
|
|
4636
|
+
/* @__PURE__ */ jsx13(Group, { children: /* @__PURE__ */ jsx13(
|
|
3793
4637
|
"button",
|
|
3794
4638
|
{
|
|
3795
4639
|
type: "button",
|
|
@@ -3810,9 +4654,9 @@ function Toolbar({ className }) {
|
|
|
3810
4654
|
function TableMenu() {
|
|
3811
4655
|
const editor = useEditorContext();
|
|
3812
4656
|
const inTable = editor.isInTable();
|
|
3813
|
-
const [open, setOpen] =
|
|
3814
|
-
const rootRef =
|
|
3815
|
-
|
|
4657
|
+
const [open, setOpen] = useState11(false);
|
|
4658
|
+
const rootRef = useRef12(null);
|
|
4659
|
+
useEffect10(() => {
|
|
3816
4660
|
if (!open) return;
|
|
3817
4661
|
const onDown = (e) => {
|
|
3818
4662
|
if (!rootRef.current) return;
|
|
@@ -3822,8 +4666,8 @@ function TableMenu() {
|
|
|
3822
4666
|
document.addEventListener("mousedown", onDown);
|
|
3823
4667
|
return () => document.removeEventListener("mousedown", onDown);
|
|
3824
4668
|
}, [open]);
|
|
3825
|
-
return /* @__PURE__ */
|
|
3826
|
-
/* @__PURE__ */
|
|
4669
|
+
return /* @__PURE__ */ jsxs12("div", { ref: rootRef, className: "ed-toolbar-tablemenu", children: [
|
|
4670
|
+
/* @__PURE__ */ jsx13(
|
|
3827
4671
|
"button",
|
|
3828
4672
|
{
|
|
3829
4673
|
type: "button",
|
|
@@ -3838,7 +4682,7 @@ function TableMenu() {
|
|
|
3838
4682
|
children: "\u25A6"
|
|
3839
4683
|
}
|
|
3840
4684
|
),
|
|
3841
|
-
open && /* @__PURE__ */
|
|
4685
|
+
open && /* @__PURE__ */ jsxs12(
|
|
3842
4686
|
"div",
|
|
3843
4687
|
{
|
|
3844
4688
|
className: "ed-table-popover",
|
|
@@ -3850,7 +4694,7 @@ function TableMenu() {
|
|
|
3850
4694
|
}
|
|
3851
4695
|
},
|
|
3852
4696
|
children: [
|
|
3853
|
-
/* @__PURE__ */
|
|
4697
|
+
/* @__PURE__ */ jsx13(
|
|
3854
4698
|
TableSizePicker,
|
|
3855
4699
|
{
|
|
3856
4700
|
onPick: (rows, cols) => {
|
|
@@ -3859,34 +4703,34 @@ function TableMenu() {
|
|
|
3859
4703
|
}
|
|
3860
4704
|
}
|
|
3861
4705
|
),
|
|
3862
|
-
inTable && /* @__PURE__ */
|
|
3863
|
-
/* @__PURE__ */
|
|
3864
|
-
/* @__PURE__ */
|
|
4706
|
+
inTable && /* @__PURE__ */ jsxs12("div", { className: "ed-table-actions", children: [
|
|
4707
|
+
/* @__PURE__ */ jsx13("hr", {}),
|
|
4708
|
+
/* @__PURE__ */ jsx13("button", { type: "button", onClick: () => {
|
|
3865
4709
|
setOpen(false);
|
|
3866
4710
|
editor.insertRowAbove();
|
|
3867
4711
|
}, children: "Inserir linha acima" }),
|
|
3868
|
-
/* @__PURE__ */
|
|
4712
|
+
/* @__PURE__ */ jsx13("button", { type: "button", onClick: () => {
|
|
3869
4713
|
setOpen(false);
|
|
3870
4714
|
editor.insertRowBelow();
|
|
3871
4715
|
}, children: "Inserir linha abaixo" }),
|
|
3872
|
-
/* @__PURE__ */
|
|
4716
|
+
/* @__PURE__ */ jsx13("button", { type: "button", onClick: () => {
|
|
3873
4717
|
setOpen(false);
|
|
3874
4718
|
editor.insertColumnLeft();
|
|
3875
4719
|
}, children: "Inserir coluna \xE0 esquerda" }),
|
|
3876
|
-
/* @__PURE__ */
|
|
4720
|
+
/* @__PURE__ */ jsx13("button", { type: "button", onClick: () => {
|
|
3877
4721
|
setOpen(false);
|
|
3878
4722
|
editor.insertColumnRight();
|
|
3879
4723
|
}, children: "Inserir coluna \xE0 direita" }),
|
|
3880
|
-
/* @__PURE__ */
|
|
4724
|
+
/* @__PURE__ */ jsx13("button", { type: "button", onClick: () => {
|
|
3881
4725
|
setOpen(false);
|
|
3882
4726
|
editor.deleteCurrentRow();
|
|
3883
4727
|
}, children: "Excluir linha" }),
|
|
3884
|
-
/* @__PURE__ */
|
|
4728
|
+
/* @__PURE__ */ jsx13("button", { type: "button", onClick: () => {
|
|
3885
4729
|
setOpen(false);
|
|
3886
4730
|
editor.deleteCurrentColumn();
|
|
3887
4731
|
}, children: "Excluir coluna" }),
|
|
3888
|
-
/* @__PURE__ */
|
|
3889
|
-
editor.hasTableRectSelection() && /* @__PURE__ */
|
|
4732
|
+
/* @__PURE__ */ jsx13("hr", {}),
|
|
4733
|
+
editor.hasTableRectSelection() && /* @__PURE__ */ jsx13(
|
|
3890
4734
|
"button",
|
|
3891
4735
|
{
|
|
3892
4736
|
type: "button",
|
|
@@ -3897,19 +4741,19 @@ function TableMenu() {
|
|
|
3897
4741
|
children: "Mesclar c\xE9lulas selecionadas"
|
|
3898
4742
|
}
|
|
3899
4743
|
),
|
|
3900
|
-
/* @__PURE__ */
|
|
4744
|
+
/* @__PURE__ */ jsx13("button", { type: "button", onClick: () => {
|
|
3901
4745
|
setOpen(false);
|
|
3902
4746
|
editor.mergeRight();
|
|
3903
4747
|
}, children: "Mesclar com c\xE9lula \xE0 direita" }),
|
|
3904
|
-
/* @__PURE__ */
|
|
4748
|
+
/* @__PURE__ */ jsx13("button", { type: "button", onClick: () => {
|
|
3905
4749
|
setOpen(false);
|
|
3906
4750
|
editor.mergeDown();
|
|
3907
4751
|
}, children: "Mesclar com c\xE9lula abaixo" }),
|
|
3908
|
-
/* @__PURE__ */
|
|
4752
|
+
/* @__PURE__ */ jsx13("button", { type: "button", onClick: () => {
|
|
3909
4753
|
setOpen(false);
|
|
3910
4754
|
editor.splitCell();
|
|
3911
4755
|
}, children: "Dividir c\xE9lulas mescladas" }),
|
|
3912
|
-
/* @__PURE__ */
|
|
4756
|
+
/* @__PURE__ */ jsx13(
|
|
3913
4757
|
"button",
|
|
3914
4758
|
{
|
|
3915
4759
|
type: "button",
|
|
@@ -3930,11 +4774,11 @@ function TableMenu() {
|
|
|
3930
4774
|
var PICKER_MAX_ROWS = 8;
|
|
3931
4775
|
var PICKER_MAX_COLS = 10;
|
|
3932
4776
|
function TableSizePicker({ onPick }) {
|
|
3933
|
-
const [hover, setHover] =
|
|
4777
|
+
const [hover, setHover] = useState11(null);
|
|
3934
4778
|
const label = hover ? `${hover.r + 1} \xD7 ${hover.c + 1}` : "Inserir tabela";
|
|
3935
|
-
return /* @__PURE__ */
|
|
3936
|
-
/* @__PURE__ */
|
|
3937
|
-
/* @__PURE__ */
|
|
4779
|
+
return /* @__PURE__ */ jsxs12("div", { className: "ed-table-picker", children: [
|
|
4780
|
+
/* @__PURE__ */ jsx13("div", { className: "ed-table-picker-label", children: label }),
|
|
4781
|
+
/* @__PURE__ */ jsx13(
|
|
3938
4782
|
"div",
|
|
3939
4783
|
{
|
|
3940
4784
|
className: "ed-table-picker-grid",
|
|
@@ -3947,7 +4791,7 @@ function TableSizePicker({ onPick }) {
|
|
|
3947
4791
|
{ length: PICKER_MAX_ROWS },
|
|
3948
4792
|
(_, r) => Array.from({ length: PICKER_MAX_COLS }, (_2, c) => {
|
|
3949
4793
|
const filled = hover != null && r <= hover.r && c <= hover.c;
|
|
3950
|
-
return /* @__PURE__ */
|
|
4794
|
+
return /* @__PURE__ */ jsx13(
|
|
3951
4795
|
"button",
|
|
3952
4796
|
{
|
|
3953
4797
|
type: "button",
|
|
@@ -3977,10 +4821,10 @@ function blockSelectValue(type, level) {
|
|
|
3977
4821
|
return type;
|
|
3978
4822
|
}
|
|
3979
4823
|
function Group({ children }) {
|
|
3980
|
-
return /* @__PURE__ */
|
|
4824
|
+
return /* @__PURE__ */ jsx13("div", { className: "ed-toolbar-group", children });
|
|
3981
4825
|
}
|
|
3982
4826
|
function MarkButton({ title, pressed, onClick, children }) {
|
|
3983
|
-
return /* @__PURE__ */
|
|
4827
|
+
return /* @__PURE__ */ jsx13(
|
|
3984
4828
|
"button",
|
|
3985
4829
|
{
|
|
3986
4830
|
type: "button",
|
|
@@ -4001,6 +4845,7 @@ export {
|
|
|
4001
4845
|
LinkDialog,
|
|
4002
4846
|
NodeView,
|
|
4003
4847
|
PageConfigDialog,
|
|
4848
|
+
RemoteCursorsOverlay,
|
|
4004
4849
|
Toolbar,
|
|
4005
4850
|
applyDomSelection,
|
|
4006
4851
|
contentHeight,
|
|
@@ -4012,6 +4857,7 @@ export {
|
|
|
4012
4857
|
getCellElement,
|
|
4013
4858
|
getFragmentForOffset,
|
|
4014
4859
|
isTableRectSelection,
|
|
4860
|
+
locatePoint,
|
|
4015
4861
|
readDomSelection,
|
|
4016
4862
|
renderInline,
|
|
4017
4863
|
selectionsEqual,
|