@sofereditor/react 0.2.0 → 0.3.0
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 +4 -3
package/dist/index.cjs
CHANGED
|
@@ -27,6 +27,7 @@ __export(index_exports, {
|
|
|
27
27
|
LinkDialog: () => LinkDialog,
|
|
28
28
|
NodeView: () => NodeView,
|
|
29
29
|
PageConfigDialog: () => PageConfigDialog,
|
|
30
|
+
RemoteCursorsOverlay: () => RemoteCursorsOverlay,
|
|
30
31
|
Toolbar: () => Toolbar,
|
|
31
32
|
applyDomSelection: () => applyDomSelection,
|
|
32
33
|
contentHeight: () => contentHeight,
|
|
@@ -38,6 +39,7 @@ __export(index_exports, {
|
|
|
38
39
|
getCellElement: () => getCellElement,
|
|
39
40
|
getFragmentForOffset: () => getFragmentForOffset,
|
|
40
41
|
isTableRectSelection: () => isTableRectSelection,
|
|
42
|
+
locatePoint: () => locatePoint,
|
|
41
43
|
readDomSelection: () => readDomSelection,
|
|
42
44
|
renderInline: () => renderInline,
|
|
43
45
|
selectionsEqual: () => selectionsEqual,
|
|
@@ -51,8 +53,8 @@ __export(index_exports, {
|
|
|
51
53
|
module.exports = __toCommonJS(index_exports);
|
|
52
54
|
|
|
53
55
|
// src/Editor.tsx
|
|
54
|
-
var
|
|
55
|
-
var
|
|
56
|
+
var import_react14 = require("react");
|
|
57
|
+
var import_core6 = require("@sofereditor/core");
|
|
56
58
|
|
|
57
59
|
// src/dom-bridge.ts
|
|
58
60
|
function findContainingBlockElement(node, root) {
|
|
@@ -252,6 +254,7 @@ function locatePoint(root, pos) {
|
|
|
252
254
|
let remaining = Math.max(0, pos.offset - containerStart);
|
|
253
255
|
let result = null;
|
|
254
256
|
let lastImg = null;
|
|
257
|
+
let lastText = null;
|
|
255
258
|
function visit(n) {
|
|
256
259
|
if (result) return;
|
|
257
260
|
if (n.nodeType === Node.TEXT_NODE) {
|
|
@@ -262,6 +265,7 @@ function locatePoint(root, pos) {
|
|
|
262
265
|
}
|
|
263
266
|
remaining -= len;
|
|
264
267
|
lastImg = null;
|
|
268
|
+
lastText = n;
|
|
265
269
|
return;
|
|
266
270
|
}
|
|
267
271
|
if (n.nodeType !== Node.ELEMENT_NODE) return;
|
|
@@ -291,6 +295,10 @@ function locatePoint(root, pos) {
|
|
|
291
295
|
const parent = lastImg.parentNode;
|
|
292
296
|
if (parent) return { node: parent, offset: indexInParent(lastImg) + 1 };
|
|
293
297
|
}
|
|
298
|
+
if (lastText) {
|
|
299
|
+
const t = lastText;
|
|
300
|
+
return { node: t, offset: (t.textContent ?? "").length };
|
|
301
|
+
}
|
|
294
302
|
return { node: container, offset: 0 };
|
|
295
303
|
}
|
|
296
304
|
function selectionsEqual(a, b) {
|
|
@@ -311,6 +319,9 @@ function applyDomSelection(root, modelSel) {
|
|
|
311
319
|
const anchorPt = locatePoint(root, modelSel.anchor);
|
|
312
320
|
const focusPt = locatePoint(root, modelSel.focus);
|
|
313
321
|
if (!anchorPt || !focusPt) return;
|
|
322
|
+
if (domSel.anchorNode === anchorPt.node && domSel.anchorOffset === anchorPt.offset && domSel.focusNode === focusPt.node && domSel.focusOffset === focusPt.offset) {
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
314
325
|
try {
|
|
315
326
|
domSel.removeAllRanges();
|
|
316
327
|
domSel.setBaseAndExtent(anchorPt.node, anchorPt.offset, focusPt.node, focusPt.offset);
|
|
@@ -318,18 +329,253 @@ function applyDomSelection(root, modelSel) {
|
|
|
318
329
|
}
|
|
319
330
|
}
|
|
320
331
|
|
|
332
|
+
// src/BehindImageSelectAffordance.tsx
|
|
333
|
+
var import_react = require("react");
|
|
334
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
335
|
+
var ACCENT = "#3b82f6";
|
|
336
|
+
function BehindImageSelectAffordance({
|
|
337
|
+
blockIndex,
|
|
338
|
+
offset,
|
|
339
|
+
cellIndex,
|
|
340
|
+
rootRef,
|
|
341
|
+
onSelect
|
|
342
|
+
}) {
|
|
343
|
+
const [rect, setRect] = (0, import_react.useState)(null);
|
|
344
|
+
const locateImage = (0, import_react.useCallback)(() => {
|
|
345
|
+
const root = rootRef.current;
|
|
346
|
+
if (!root) return null;
|
|
347
|
+
let container = null;
|
|
348
|
+
if (cellIndex != null) {
|
|
349
|
+
container = root.querySelector(
|
|
350
|
+
`[data-block-index="${blockIndex}"] [data-cell-index="${cellIndex}"]`
|
|
351
|
+
);
|
|
352
|
+
} else {
|
|
353
|
+
container = getFragmentForOffset(root, blockIndex, offset);
|
|
354
|
+
}
|
|
355
|
+
if (!container) return null;
|
|
356
|
+
const fragmentStart = container.dataset.fragmentStart ? Number.parseInt(container.dataset.fragmentStart, 10) || 0 : 0;
|
|
357
|
+
const localOffset = offset - fragmentStart;
|
|
358
|
+
return container.querySelector(
|
|
359
|
+
`img[data-embed="image"][data-embed-offset="${localOffset}"]`
|
|
360
|
+
);
|
|
361
|
+
}, [rootRef, blockIndex, offset, cellIndex]);
|
|
362
|
+
const measure = (0, import_react.useCallback)(() => {
|
|
363
|
+
const img = locateImage();
|
|
364
|
+
const root = rootRef.current;
|
|
365
|
+
if (!img || !root) {
|
|
366
|
+
setRect((prev) => prev === null ? prev : null);
|
|
367
|
+
return;
|
|
368
|
+
}
|
|
369
|
+
const r = img.getBoundingClientRect();
|
|
370
|
+
const rr = root.getBoundingClientRect();
|
|
371
|
+
const next = {
|
|
372
|
+
top: r.top - rr.top + root.scrollTop,
|
|
373
|
+
left: r.left - rr.left + root.scrollLeft,
|
|
374
|
+
width: r.width,
|
|
375
|
+
height: r.height
|
|
376
|
+
};
|
|
377
|
+
setRect(
|
|
378
|
+
(prev) => prev && prev.top === next.top && prev.left === next.left && prev.width === next.width && prev.height === next.height ? prev : next
|
|
379
|
+
);
|
|
380
|
+
}, [locateImage, rootRef]);
|
|
381
|
+
(0, import_react.useLayoutEffect)(() => {
|
|
382
|
+
measure();
|
|
383
|
+
let cancelled = false;
|
|
384
|
+
const remeasure = () => {
|
|
385
|
+
if (!cancelled) measure();
|
|
386
|
+
};
|
|
387
|
+
const id = typeof requestAnimationFrame === "function" ? requestAnimationFrame(remeasure) : (queueMicrotask(remeasure), 0);
|
|
388
|
+
return () => {
|
|
389
|
+
cancelled = true;
|
|
390
|
+
if (typeof cancelAnimationFrame === "function" && typeof id === "number" && id > 0) {
|
|
391
|
+
cancelAnimationFrame(id);
|
|
392
|
+
}
|
|
393
|
+
};
|
|
394
|
+
}, [measure]);
|
|
395
|
+
(0, import_react.useEffect)(() => {
|
|
396
|
+
const root = rootRef.current;
|
|
397
|
+
if (!root) return;
|
|
398
|
+
const onScroll = () => measure();
|
|
399
|
+
window.addEventListener("resize", onScroll);
|
|
400
|
+
root.addEventListener("scroll", onScroll);
|
|
401
|
+
return () => {
|
|
402
|
+
window.removeEventListener("resize", onScroll);
|
|
403
|
+
root.removeEventListener("scroll", onScroll);
|
|
404
|
+
};
|
|
405
|
+
}, [measure, rootRef]);
|
|
406
|
+
if (!rect) return null;
|
|
407
|
+
const outlineStyle = {
|
|
408
|
+
position: "absolute",
|
|
409
|
+
top: rect.top,
|
|
410
|
+
left: rect.left,
|
|
411
|
+
width: rect.width,
|
|
412
|
+
height: rect.height,
|
|
413
|
+
border: `1.5px dashed ${ACCENT}`,
|
|
414
|
+
borderRadius: 2,
|
|
415
|
+
boxSizing: "border-box",
|
|
416
|
+
pointerEvents: "none",
|
|
417
|
+
zIndex: 4
|
|
418
|
+
};
|
|
419
|
+
const badgeStyle = {
|
|
420
|
+
position: "absolute",
|
|
421
|
+
top: rect.top - 2,
|
|
422
|
+
left: rect.left - 2,
|
|
423
|
+
width: 24,
|
|
424
|
+
height: 24,
|
|
425
|
+
display: "flex",
|
|
426
|
+
alignItems: "center",
|
|
427
|
+
justifyContent: "center",
|
|
428
|
+
background: ACCENT,
|
|
429
|
+
color: "#fff",
|
|
430
|
+
borderRadius: 4,
|
|
431
|
+
cursor: "pointer",
|
|
432
|
+
pointerEvents: "auto",
|
|
433
|
+
boxShadow: "0 1px 3px rgba(0,0,0,0.3)",
|
|
434
|
+
zIndex: 5
|
|
435
|
+
};
|
|
436
|
+
const onBadgeDown = (e) => {
|
|
437
|
+
if (e.button !== 0) return;
|
|
438
|
+
e.preventDefault();
|
|
439
|
+
e.stopPropagation();
|
|
440
|
+
onSelect();
|
|
441
|
+
};
|
|
442
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
443
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: outlineStyle, contentEditable: false, "aria-hidden": true }),
|
|
444
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
445
|
+
"div",
|
|
446
|
+
{
|
|
447
|
+
style: badgeStyle,
|
|
448
|
+
contentEditable: false,
|
|
449
|
+
onPointerDown: onBadgeDown,
|
|
450
|
+
role: "button",
|
|
451
|
+
"aria-label": "Selecionar imagem",
|
|
452
|
+
title: "Selecionar imagem",
|
|
453
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
454
|
+
"svg",
|
|
455
|
+
{
|
|
456
|
+
width: "14",
|
|
457
|
+
height: "14",
|
|
458
|
+
viewBox: "0 0 24 24",
|
|
459
|
+
fill: "none",
|
|
460
|
+
stroke: "currentColor",
|
|
461
|
+
strokeWidth: "2",
|
|
462
|
+
strokeLinecap: "round",
|
|
463
|
+
strokeLinejoin: "round",
|
|
464
|
+
"aria-hidden": true,
|
|
465
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M5 9l-3 3 3 3M9 5l3-3 3 3M15 19l-3 3-3-3M19 9l3 3-3 3M2 12h20M12 2v20" })
|
|
466
|
+
}
|
|
467
|
+
)
|
|
468
|
+
}
|
|
469
|
+
)
|
|
470
|
+
] });
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
// src/LinkHoverTooltip.tsx
|
|
474
|
+
var import_react_dom = require("react-dom");
|
|
475
|
+
|
|
476
|
+
// src/platform.ts
|
|
477
|
+
var IS_MAC = (() => {
|
|
478
|
+
if (typeof navigator === "undefined") return false;
|
|
479
|
+
const platform = navigator.userAgentData?.platform || navigator.platform || navigator.userAgent || "";
|
|
480
|
+
return /mac|iphone|ipad|ipod/i.test(platform);
|
|
481
|
+
})();
|
|
482
|
+
var MOD_SYMBOL = IS_MAC ? "\u2318" : "\u2303";
|
|
483
|
+
function hasOpenModifier(e) {
|
|
484
|
+
return IS_MAC ? e.metaKey : e.ctrlKey;
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
// src/LinkHoverTooltip.tsx
|
|
488
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
489
|
+
var MAX_WIDTH = 360;
|
|
490
|
+
var GAP = 6;
|
|
491
|
+
function LinkHoverTooltip({ href, rect }) {
|
|
492
|
+
const above = rect.top > 48;
|
|
493
|
+
const viewportW = typeof window !== "undefined" ? window.innerWidth : MAX_WIDTH + 16;
|
|
494
|
+
const left = Math.max(8, Math.min(rect.left, viewportW - MAX_WIDTH - 8));
|
|
495
|
+
const style = {
|
|
496
|
+
position: "fixed",
|
|
497
|
+
left,
|
|
498
|
+
top: above ? rect.top - GAP : rect.bottom + GAP,
|
|
499
|
+
transform: above ? "translateY(-100%)" : void 0,
|
|
500
|
+
maxWidth: MAX_WIDTH,
|
|
501
|
+
background: "#1f2937",
|
|
502
|
+
color: "#fff",
|
|
503
|
+
fontSize: 12,
|
|
504
|
+
lineHeight: 1.4,
|
|
505
|
+
padding: "6px 9px",
|
|
506
|
+
borderRadius: 6,
|
|
507
|
+
boxShadow: "0 4px 14px rgba(0,0,0,0.28)",
|
|
508
|
+
zIndex: 60,
|
|
509
|
+
pointerEvents: "none"
|
|
510
|
+
};
|
|
511
|
+
const urlStyle = {
|
|
512
|
+
display: "block",
|
|
513
|
+
maxWidth: MAX_WIDTH - 18,
|
|
514
|
+
overflow: "hidden",
|
|
515
|
+
textOverflow: "ellipsis",
|
|
516
|
+
whiteSpace: "nowrap",
|
|
517
|
+
fontWeight: 600
|
|
518
|
+
};
|
|
519
|
+
const hintStyle = {
|
|
520
|
+
display: "flex",
|
|
521
|
+
alignItems: "center",
|
|
522
|
+
gap: 4,
|
|
523
|
+
marginTop: 3,
|
|
524
|
+
fontSize: 11,
|
|
525
|
+
opacity: 0.85
|
|
526
|
+
};
|
|
527
|
+
const keycapStyle = {
|
|
528
|
+
display: "inline-flex",
|
|
529
|
+
alignItems: "center",
|
|
530
|
+
justifyContent: "center",
|
|
531
|
+
minWidth: 16,
|
|
532
|
+
height: 16,
|
|
533
|
+
padding: "0 4px",
|
|
534
|
+
fontSize: 11,
|
|
535
|
+
fontFamily: "system-ui, -apple-system, sans-serif",
|
|
536
|
+
background: "rgba(255,255,255,0.16)",
|
|
537
|
+
border: "1px solid rgba(255,255,255,0.4)",
|
|
538
|
+
borderRadius: 4,
|
|
539
|
+
boxShadow: "inset 0 -1px 0 rgba(0,0,0,0.25)"
|
|
540
|
+
};
|
|
541
|
+
if (typeof document === "undefined") return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, {});
|
|
542
|
+
return (0, import_react_dom.createPortal)(
|
|
543
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style, contentEditable: false, "aria-hidden": true, role: "tooltip", children: [
|
|
544
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: urlStyle, children: href }),
|
|
545
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: hintStyle, children: [
|
|
546
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("kbd", { style: keycapStyle, children: MOD_SYMBOL }),
|
|
547
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { opacity: 0.8 }, children: "+ clique para abrir" })
|
|
548
|
+
] })
|
|
549
|
+
] }),
|
|
550
|
+
document.body
|
|
551
|
+
);
|
|
552
|
+
}
|
|
553
|
+
|
|
321
554
|
// src/EditorContext.tsx
|
|
322
|
-
var
|
|
555
|
+
var import_react5 = require("react");
|
|
323
556
|
|
|
324
557
|
// src/LinkDialog.tsx
|
|
325
|
-
var
|
|
326
|
-
|
|
558
|
+
var import_react2 = require("react");
|
|
559
|
+
|
|
560
|
+
// src/dialogCenterStyle.ts
|
|
561
|
+
var DIALOG_CENTER_STYLE = {
|
|
562
|
+
position: "fixed",
|
|
563
|
+
top: "50%",
|
|
564
|
+
left: "50%",
|
|
565
|
+
transform: "translate(-50%, -50%)",
|
|
566
|
+
margin: 0,
|
|
567
|
+
maxHeight: "90vh",
|
|
568
|
+
overflow: "auto"
|
|
569
|
+
};
|
|
570
|
+
|
|
571
|
+
// src/LinkDialog.tsx
|
|
572
|
+
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
327
573
|
function LinkDialog() {
|
|
328
574
|
const { linkRequest, resolveLinkRequest } = useEditorContext();
|
|
329
|
-
const dialogRef = (0,
|
|
330
|
-
const inputRef = (0,
|
|
331
|
-
const [href, setHref] = (0,
|
|
332
|
-
(0,
|
|
575
|
+
const dialogRef = (0, import_react2.useRef)(null);
|
|
576
|
+
const inputRef = (0, import_react2.useRef)(null);
|
|
577
|
+
const [href, setHref] = (0, import_react2.useState)("");
|
|
578
|
+
(0, import_react2.useEffect)(() => {
|
|
333
579
|
const dialog = dialogRef.current;
|
|
334
580
|
if (!dialog) return;
|
|
335
581
|
if (linkRequest) {
|
|
@@ -357,20 +603,21 @@ function LinkDialog() {
|
|
|
357
603
|
const onCancel = () => {
|
|
358
604
|
resolveLinkRequest(null);
|
|
359
605
|
};
|
|
360
|
-
return /* @__PURE__ */ (0,
|
|
606
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
361
607
|
"dialog",
|
|
362
608
|
{
|
|
363
609
|
ref: dialogRef,
|
|
364
610
|
className: "ed-link-dialog",
|
|
611
|
+
style: DIALOG_CENTER_STYLE,
|
|
365
612
|
onClose: onCancel,
|
|
366
613
|
onCancel: (e) => {
|
|
367
614
|
e.preventDefault();
|
|
368
615
|
onCancel();
|
|
369
616
|
},
|
|
370
|
-
children: /* @__PURE__ */ (0,
|
|
371
|
-
/* @__PURE__ */ (0,
|
|
372
|
-
/* @__PURE__ */ (0,
|
|
373
|
-
/* @__PURE__ */ (0,
|
|
617
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("form", { onSubmit, className: "ed-link-dialog-form", children: [
|
|
618
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "ed-link-dialog-row", children: [
|
|
619
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("label", { htmlFor: "ed-link-href", children: "URL" }),
|
|
620
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
374
621
|
"input",
|
|
375
622
|
{
|
|
376
623
|
id: "ed-link-href",
|
|
@@ -384,11 +631,11 @@ function LinkDialog() {
|
|
|
384
631
|
}
|
|
385
632
|
)
|
|
386
633
|
] }),
|
|
387
|
-
/* @__PURE__ */ (0,
|
|
388
|
-
linkRequest.initialHref ? /* @__PURE__ */ (0,
|
|
389
|
-
/* @__PURE__ */ (0,
|
|
390
|
-
/* @__PURE__ */ (0,
|
|
391
|
-
/* @__PURE__ */ (0,
|
|
634
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "ed-link-dialog-actions", children: [
|
|
635
|
+
linkRequest.initialHref ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", onClick: onRemove, className: "ed-link-dialog-remove", children: "Remover link" }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", {}),
|
|
636
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "ed-link-dialog-confirm", children: [
|
|
637
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", onClick: onCancel, children: "Cancelar" }),
|
|
638
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "submit", className: "ed-link-dialog-apply", children: "Aplicar" })
|
|
392
639
|
] })
|
|
393
640
|
] })
|
|
394
641
|
] })
|
|
@@ -397,21 +644,21 @@ function LinkDialog() {
|
|
|
397
644
|
}
|
|
398
645
|
|
|
399
646
|
// src/PageConfigDialog.tsx
|
|
400
|
-
var
|
|
647
|
+
var import_react3 = require("react");
|
|
401
648
|
var import_core = require("@sofereditor/core");
|
|
402
|
-
var
|
|
649
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
403
650
|
function PageConfigDialog() {
|
|
404
651
|
const { pageConfigRequest, resolvePageConfigRequest, setPageSettings } = useEditorContext();
|
|
405
|
-
const dialogRef = (0,
|
|
406
|
-
const [sizePreset, setSizePreset] = (0,
|
|
407
|
-
const [widthMm, setWidthMm] = (0,
|
|
408
|
-
const [heightMm, setHeightMm] = (0,
|
|
409
|
-
const [marginPreset, setMarginPreset] = (0,
|
|
410
|
-
const [marginTopMm, setMarginTopMm] = (0,
|
|
411
|
-
const [marginBottomMm, setMarginBottomMm] = (0,
|
|
412
|
-
const [marginLeftMm, setMarginLeftMm] = (0,
|
|
413
|
-
const [marginRightMm, setMarginRightMm] = (0,
|
|
414
|
-
(0,
|
|
652
|
+
const dialogRef = (0, import_react3.useRef)(null);
|
|
653
|
+
const [sizePreset, setSizePreset] = (0, import_react3.useState)("a4");
|
|
654
|
+
const [widthMm, setWidthMm] = (0, import_react3.useState)(210);
|
|
655
|
+
const [heightMm, setHeightMm] = (0, import_react3.useState)(297);
|
|
656
|
+
const [marginPreset, setMarginPreset] = (0, import_react3.useState)("normal");
|
|
657
|
+
const [marginTopMm, setMarginTopMm] = (0, import_react3.useState)(25.4);
|
|
658
|
+
const [marginBottomMm, setMarginBottomMm] = (0, import_react3.useState)(25.4);
|
|
659
|
+
const [marginLeftMm, setMarginLeftMm] = (0, import_react3.useState)(25.4);
|
|
660
|
+
const [marginRightMm, setMarginRightMm] = (0, import_react3.useState)(25.4);
|
|
661
|
+
(0, import_react3.useEffect)(() => {
|
|
415
662
|
const dialog = dialogRef.current;
|
|
416
663
|
if (!dialog) return;
|
|
417
664
|
if (pageConfigRequest) {
|
|
@@ -430,13 +677,13 @@ function PageConfigDialog() {
|
|
|
430
677
|
dialog.close();
|
|
431
678
|
}
|
|
432
679
|
}, [pageConfigRequest]);
|
|
433
|
-
(0,
|
|
680
|
+
(0, import_react3.useEffect)(() => {
|
|
434
681
|
if (sizePreset === "custom") return;
|
|
435
682
|
const p = import_core.PAGE_PRESETS[sizePreset];
|
|
436
683
|
setWidthMm(roundMm((0, import_core.pxToMm)(p.width)));
|
|
437
684
|
setHeightMm(roundMm((0, import_core.pxToMm)(p.height)));
|
|
438
685
|
}, [sizePreset]);
|
|
439
|
-
(0,
|
|
686
|
+
(0, import_react3.useEffect)(() => {
|
|
440
687
|
if (marginPreset === "custom") return;
|
|
441
688
|
const px = import_core.MARGIN_PRESETS[marginPreset];
|
|
442
689
|
const mm = roundMm((0, import_core.pxToMm)(px));
|
|
@@ -446,7 +693,7 @@ function PageConfigDialog() {
|
|
|
446
693
|
setMarginRightMm(mm);
|
|
447
694
|
}, [marginPreset]);
|
|
448
695
|
const customWidth = sizePreset === "custom";
|
|
449
|
-
const previewPx = (0,
|
|
696
|
+
const previewPx = (0, import_react3.useMemo)(
|
|
450
697
|
() => ({
|
|
451
698
|
width: Math.round((0, import_core.mmToPx)(widthMm)),
|
|
452
699
|
height: Math.round((0, import_core.mmToPx)(heightMm))
|
|
@@ -468,23 +715,24 @@ function PageConfigDialog() {
|
|
|
468
715
|
resolvePageConfigRequest(true);
|
|
469
716
|
};
|
|
470
717
|
const onCancel = () => resolvePageConfigRequest(false);
|
|
471
|
-
return /* @__PURE__ */ (0,
|
|
718
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
472
719
|
"dialog",
|
|
473
720
|
{
|
|
474
721
|
ref: dialogRef,
|
|
475
722
|
className: "ed-page-config-dialog",
|
|
723
|
+
style: DIALOG_CENTER_STYLE,
|
|
476
724
|
onClose: onCancel,
|
|
477
725
|
onCancel: (e) => {
|
|
478
726
|
e.preventDefault();
|
|
479
727
|
onCancel();
|
|
480
728
|
},
|
|
481
|
-
children: /* @__PURE__ */ (0,
|
|
482
|
-
/* @__PURE__ */ (0,
|
|
483
|
-
/* @__PURE__ */ (0,
|
|
484
|
-
/* @__PURE__ */ (0,
|
|
485
|
-
/* @__PURE__ */ (0,
|
|
486
|
-
/* @__PURE__ */ (0,
|
|
487
|
-
/* @__PURE__ */ (0,
|
|
729
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("form", { onSubmit: onApply, className: "ed-page-config-form", children: [
|
|
730
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h2", { children: "Configurar p\xE1gina" }),
|
|
731
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("fieldset", { children: [
|
|
732
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("legend", { children: "Tamanho" }),
|
|
733
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "ed-page-config-row", children: [
|
|
734
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("label", { children: [
|
|
735
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
488
736
|
"input",
|
|
489
737
|
{
|
|
490
738
|
type: "radio",
|
|
@@ -496,8 +744,8 @@ function PageConfigDialog() {
|
|
|
496
744
|
" ",
|
|
497
745
|
"A4 (210 \xD7 297 mm)"
|
|
498
746
|
] }),
|
|
499
|
-
/* @__PURE__ */ (0,
|
|
500
|
-
/* @__PURE__ */ (0,
|
|
747
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("label", { children: [
|
|
748
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
501
749
|
"input",
|
|
502
750
|
{
|
|
503
751
|
type: "radio",
|
|
@@ -509,8 +757,8 @@ function PageConfigDialog() {
|
|
|
509
757
|
" ",
|
|
510
758
|
"Carta (216 \xD7 279 mm)"
|
|
511
759
|
] }),
|
|
512
|
-
/* @__PURE__ */ (0,
|
|
513
|
-
/* @__PURE__ */ (0,
|
|
760
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("label", { children: [
|
|
761
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
514
762
|
"input",
|
|
515
763
|
{
|
|
516
764
|
type: "radio",
|
|
@@ -522,8 +770,8 @@ function PageConfigDialog() {
|
|
|
522
770
|
" ",
|
|
523
771
|
"Of\xEDcio (216 \xD7 330 mm)"
|
|
524
772
|
] }),
|
|
525
|
-
/* @__PURE__ */ (0,
|
|
526
|
-
/* @__PURE__ */ (0,
|
|
773
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("label", { children: [
|
|
774
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
527
775
|
"input",
|
|
528
776
|
{
|
|
529
777
|
type: "radio",
|
|
@@ -536,11 +784,11 @@ function PageConfigDialog() {
|
|
|
536
784
|
"Personalizado"
|
|
537
785
|
] })
|
|
538
786
|
] }),
|
|
539
|
-
/* @__PURE__ */ (0,
|
|
540
|
-
/* @__PURE__ */ (0,
|
|
787
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "ed-page-config-row", children: [
|
|
788
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("label", { children: [
|
|
541
789
|
"Largura (mm)",
|
|
542
790
|
" ",
|
|
543
|
-
/* @__PURE__ */ (0,
|
|
791
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
544
792
|
"input",
|
|
545
793
|
{
|
|
546
794
|
type: "number",
|
|
@@ -553,10 +801,10 @@ function PageConfigDialog() {
|
|
|
553
801
|
}
|
|
554
802
|
)
|
|
555
803
|
] }),
|
|
556
|
-
/* @__PURE__ */ (0,
|
|
804
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("label", { children: [
|
|
557
805
|
"Altura (mm)",
|
|
558
806
|
" ",
|
|
559
|
-
/* @__PURE__ */ (0,
|
|
807
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
560
808
|
"input",
|
|
561
809
|
{
|
|
562
810
|
type: "number",
|
|
@@ -569,7 +817,7 @@ function PageConfigDialog() {
|
|
|
569
817
|
}
|
|
570
818
|
)
|
|
571
819
|
] }),
|
|
572
|
-
/* @__PURE__ */ (0,
|
|
820
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "ed-page-config-preview", children: [
|
|
573
821
|
previewPx.width,
|
|
574
822
|
" \xD7 ",
|
|
575
823
|
previewPx.height,
|
|
@@ -577,11 +825,11 @@ function PageConfigDialog() {
|
|
|
577
825
|
] })
|
|
578
826
|
] })
|
|
579
827
|
] }),
|
|
580
|
-
/* @__PURE__ */ (0,
|
|
581
|
-
/* @__PURE__ */ (0,
|
|
582
|
-
/* @__PURE__ */ (0,
|
|
583
|
-
/* @__PURE__ */ (0,
|
|
584
|
-
/* @__PURE__ */ (0,
|
|
828
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("fieldset", { children: [
|
|
829
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("legend", { children: "Margens" }),
|
|
830
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "ed-page-config-row", children: [
|
|
831
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("label", { children: [
|
|
832
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
585
833
|
"input",
|
|
586
834
|
{
|
|
587
835
|
type: "radio",
|
|
@@ -593,8 +841,8 @@ function PageConfigDialog() {
|
|
|
593
841
|
" ",
|
|
594
842
|
"Normal (25,4 mm)"
|
|
595
843
|
] }),
|
|
596
|
-
/* @__PURE__ */ (0,
|
|
597
|
-
/* @__PURE__ */ (0,
|
|
844
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("label", { children: [
|
|
845
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
598
846
|
"input",
|
|
599
847
|
{
|
|
600
848
|
type: "radio",
|
|
@@ -606,8 +854,8 @@ function PageConfigDialog() {
|
|
|
606
854
|
" ",
|
|
607
855
|
"Estreita (12,7 mm)"
|
|
608
856
|
] }),
|
|
609
|
-
/* @__PURE__ */ (0,
|
|
610
|
-
/* @__PURE__ */ (0,
|
|
857
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("label", { children: [
|
|
858
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
611
859
|
"input",
|
|
612
860
|
{
|
|
613
861
|
type: "radio",
|
|
@@ -619,8 +867,8 @@ function PageConfigDialog() {
|
|
|
619
867
|
" ",
|
|
620
868
|
"Larga (50,8 mm)"
|
|
621
869
|
] }),
|
|
622
|
-
/* @__PURE__ */ (0,
|
|
623
|
-
/* @__PURE__ */ (0,
|
|
870
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("label", { children: [
|
|
871
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
624
872
|
"input",
|
|
625
873
|
{
|
|
626
874
|
type: "radio",
|
|
@@ -633,11 +881,11 @@ function PageConfigDialog() {
|
|
|
633
881
|
"Personalizada"
|
|
634
882
|
] })
|
|
635
883
|
] }),
|
|
636
|
-
/* @__PURE__ */ (0,
|
|
637
|
-
/* @__PURE__ */ (0,
|
|
884
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "ed-page-config-row", children: [
|
|
885
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("label", { children: [
|
|
638
886
|
"Topo",
|
|
639
887
|
" ",
|
|
640
|
-
/* @__PURE__ */ (0,
|
|
888
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
641
889
|
"input",
|
|
642
890
|
{
|
|
643
891
|
type: "number",
|
|
@@ -652,10 +900,10 @@ function PageConfigDialog() {
|
|
|
652
900
|
}
|
|
653
901
|
)
|
|
654
902
|
] }),
|
|
655
|
-
/* @__PURE__ */ (0,
|
|
903
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("label", { children: [
|
|
656
904
|
"Inferior",
|
|
657
905
|
" ",
|
|
658
|
-
/* @__PURE__ */ (0,
|
|
906
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
659
907
|
"input",
|
|
660
908
|
{
|
|
661
909
|
type: "number",
|
|
@@ -670,10 +918,10 @@ function PageConfigDialog() {
|
|
|
670
918
|
}
|
|
671
919
|
)
|
|
672
920
|
] }),
|
|
673
|
-
/* @__PURE__ */ (0,
|
|
921
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("label", { children: [
|
|
674
922
|
"Esquerda",
|
|
675
923
|
" ",
|
|
676
|
-
/* @__PURE__ */ (0,
|
|
924
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
677
925
|
"input",
|
|
678
926
|
{
|
|
679
927
|
type: "number",
|
|
@@ -688,10 +936,10 @@ function PageConfigDialog() {
|
|
|
688
936
|
}
|
|
689
937
|
)
|
|
690
938
|
] }),
|
|
691
|
-
/* @__PURE__ */ (0,
|
|
939
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("label", { children: [
|
|
692
940
|
"Direita",
|
|
693
941
|
" ",
|
|
694
|
-
/* @__PURE__ */ (0,
|
|
942
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
695
943
|
"input",
|
|
696
944
|
{
|
|
697
945
|
type: "number",
|
|
@@ -708,9 +956,9 @@ function PageConfigDialog() {
|
|
|
708
956
|
] })
|
|
709
957
|
] })
|
|
710
958
|
] }),
|
|
711
|
-
/* @__PURE__ */ (0,
|
|
712
|
-
/* @__PURE__ */ (0,
|
|
713
|
-
/* @__PURE__ */ (0,
|
|
959
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "ed-page-config-actions", children: [
|
|
960
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { type: "button", onClick: onCancel, children: "Cancelar" }),
|
|
961
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { type: "submit", className: "ed-page-config-apply", children: "Aplicar" })
|
|
714
962
|
] })
|
|
715
963
|
] })
|
|
716
964
|
}
|
|
@@ -745,15 +993,15 @@ function detectMarginPreset(s) {
|
|
|
745
993
|
}
|
|
746
994
|
|
|
747
995
|
// src/ImageCaptionDialog.tsx
|
|
748
|
-
var
|
|
749
|
-
var
|
|
996
|
+
var import_react4 = require("react");
|
|
997
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
750
998
|
function ImageCaptionDialog() {
|
|
751
999
|
const { imageCaptionRequest, resolveImageCaptionRequest } = useEditorContext();
|
|
752
|
-
const dialogRef = (0,
|
|
753
|
-
const inputRef = (0,
|
|
754
|
-
const [caption, setCaption] = (0,
|
|
755
|
-
const [align, setAlign] = (0,
|
|
756
|
-
(0,
|
|
1000
|
+
const dialogRef = (0, import_react4.useRef)(null);
|
|
1001
|
+
const inputRef = (0, import_react4.useRef)(null);
|
|
1002
|
+
const [caption, setCaption] = (0, import_react4.useState)("");
|
|
1003
|
+
const [align, setAlign] = (0, import_react4.useState)("center");
|
|
1004
|
+
(0, import_react4.useEffect)(() => {
|
|
757
1005
|
const dialog = dialogRef.current;
|
|
758
1006
|
if (!dialog) return;
|
|
759
1007
|
if (imageCaptionRequest) {
|
|
@@ -778,20 +1026,21 @@ function ImageCaptionDialog() {
|
|
|
778
1026
|
};
|
|
779
1027
|
const onRemove = () => resolveImageCaptionRequest({ caption: "", align });
|
|
780
1028
|
const onCancel = () => resolveImageCaptionRequest(null);
|
|
781
|
-
return /* @__PURE__ */ (0,
|
|
1029
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
782
1030
|
"dialog",
|
|
783
1031
|
{
|
|
784
1032
|
ref: dialogRef,
|
|
785
1033
|
className: "ed-caption-dialog ed-link-dialog",
|
|
1034
|
+
style: DIALOG_CENTER_STYLE,
|
|
786
1035
|
onClose: onCancel,
|
|
787
1036
|
onCancel: (e) => {
|
|
788
1037
|
e.preventDefault();
|
|
789
1038
|
onCancel();
|
|
790
1039
|
},
|
|
791
|
-
children: /* @__PURE__ */ (0,
|
|
792
|
-
/* @__PURE__ */ (0,
|
|
793
|
-
/* @__PURE__ */ (0,
|
|
794
|
-
/* @__PURE__ */ (0,
|
|
1040
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("form", { onSubmit, className: "ed-link-dialog-form", children: [
|
|
1041
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "ed-link-dialog-row", children: [
|
|
1042
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("label", { htmlFor: "ed-caption-input", children: "Legenda" }),
|
|
1043
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
795
1044
|
"input",
|
|
796
1045
|
{
|
|
797
1046
|
id: "ed-caption-input",
|
|
@@ -804,10 +1053,10 @@ function ImageCaptionDialog() {
|
|
|
804
1053
|
}
|
|
805
1054
|
)
|
|
806
1055
|
] }),
|
|
807
|
-
/* @__PURE__ */ (0,
|
|
808
|
-
/* @__PURE__ */ (0,
|
|
809
|
-
/* @__PURE__ */ (0,
|
|
810
|
-
/* @__PURE__ */ (0,
|
|
1056
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "ed-link-dialog-row", children: [
|
|
1057
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "Alinhamento" }),
|
|
1058
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "ed-caption-align-group", role: "radiogroup", "aria-label": "Alinhamento da legenda", children: ["left", "center", "right"].map((value) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { className: "ed-caption-align-option", children: [
|
|
1059
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
811
1060
|
"input",
|
|
812
1061
|
{
|
|
813
1062
|
type: "radio",
|
|
@@ -820,11 +1069,11 @@ function ImageCaptionDialog() {
|
|
|
820
1069
|
value === "left" ? "Esquerda" : value === "center" ? "Centro" : "Direita"
|
|
821
1070
|
] }, value)) })
|
|
822
1071
|
] }),
|
|
823
|
-
/* @__PURE__ */ (0,
|
|
824
|
-
imageCaptionRequest.initialCaption ? /* @__PURE__ */ (0,
|
|
825
|
-
/* @__PURE__ */ (0,
|
|
826
|
-
/* @__PURE__ */ (0,
|
|
827
|
-
/* @__PURE__ */ (0,
|
|
1072
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "ed-link-dialog-actions", children: [
|
|
1073
|
+
imageCaptionRequest.initialCaption ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", onClick: onRemove, className: "ed-link-dialog-remove", children: "Remover legenda" }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", {}),
|
|
1074
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "ed-link-dialog-confirm", children: [
|
|
1075
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", onClick: onCancel, children: "Cancelar" }),
|
|
1076
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "submit", className: "ed-link-dialog-apply", children: "Aplicar" })
|
|
828
1077
|
] })
|
|
829
1078
|
] })
|
|
830
1079
|
] })
|
|
@@ -833,18 +1082,18 @@ function ImageCaptionDialog() {
|
|
|
833
1082
|
}
|
|
834
1083
|
|
|
835
1084
|
// src/EditorContext.tsx
|
|
836
|
-
var
|
|
837
|
-
var EditorContext = (0,
|
|
1085
|
+
var import_jsx_runtime6 = require("react/jsx-runtime");
|
|
1086
|
+
var EditorContext = (0, import_react5.createContext)(null);
|
|
838
1087
|
function EditorProvider({ editor, children }) {
|
|
839
|
-
return /* @__PURE__ */ (0,
|
|
1088
|
+
return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(EditorContext.Provider, { value: editor, children: [
|
|
840
1089
|
children,
|
|
841
|
-
/* @__PURE__ */ (0,
|
|
842
|
-
/* @__PURE__ */ (0,
|
|
843
|
-
/* @__PURE__ */ (0,
|
|
1090
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(LinkDialog, {}),
|
|
1091
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(PageConfigDialog, {}),
|
|
1092
|
+
/* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ImageCaptionDialog, {})
|
|
844
1093
|
] });
|
|
845
1094
|
}
|
|
846
1095
|
function useEditorContext() {
|
|
847
|
-
const ctx = (0,
|
|
1096
|
+
const ctx = (0, import_react5.useContext)(EditorContext);
|
|
848
1097
|
if (!ctx) {
|
|
849
1098
|
throw new Error("useEditorContext must be used inside an <EditorProvider>");
|
|
850
1099
|
}
|
|
@@ -852,8 +1101,8 @@ function useEditorContext() {
|
|
|
852
1101
|
}
|
|
853
1102
|
|
|
854
1103
|
// src/ImageResizeOverlay.tsx
|
|
855
|
-
var
|
|
856
|
-
var
|
|
1104
|
+
var import_react6 = require("react");
|
|
1105
|
+
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
857
1106
|
function ImageResizeOverlay({
|
|
858
1107
|
rootRef,
|
|
859
1108
|
blockIndex,
|
|
@@ -861,11 +1110,13 @@ function ImageResizeOverlay({
|
|
|
861
1110
|
cellIndex,
|
|
862
1111
|
embed,
|
|
863
1112
|
onCommit,
|
|
864
|
-
onCommitMove
|
|
1113
|
+
onCommitMove,
|
|
1114
|
+
onReanchor
|
|
865
1115
|
}) {
|
|
866
|
-
const [rect, setRect] = (0,
|
|
867
|
-
const
|
|
868
|
-
const
|
|
1116
|
+
const [rect, setRect] = (0, import_react6.useState)(null);
|
|
1117
|
+
const [isMoving, setIsMoving] = (0, import_react6.useState)(false);
|
|
1118
|
+
const imgRef = (0, import_react6.useRef)(null);
|
|
1119
|
+
const locateImage = (0, import_react6.useCallback)(() => {
|
|
869
1120
|
const root = rootRef.current;
|
|
870
1121
|
if (!root) return null;
|
|
871
1122
|
let container = null;
|
|
@@ -883,7 +1134,7 @@ function ImageResizeOverlay({
|
|
|
883
1134
|
`img[data-embed="image"][data-embed-offset="${localOffset}"]`
|
|
884
1135
|
);
|
|
885
1136
|
}, [rootRef, blockIndex, offset, cellIndex]);
|
|
886
|
-
const measure = (0,
|
|
1137
|
+
const measure = (0, import_react6.useCallback)(() => {
|
|
887
1138
|
const img = locateImage();
|
|
888
1139
|
if (!img) {
|
|
889
1140
|
setRect((prev) => prev === null ? prev : null);
|
|
@@ -904,22 +1155,28 @@ function ImageResizeOverlay({
|
|
|
904
1155
|
(prev) => prev && prev.top === next.top && prev.left === next.left && prev.width === next.width && prev.height === next.height ? prev : next
|
|
905
1156
|
);
|
|
906
1157
|
}, [locateImage, rootRef]);
|
|
907
|
-
(0,
|
|
1158
|
+
(0, import_react6.useLayoutEffect)(() => {
|
|
908
1159
|
measure();
|
|
909
1160
|
let cancelled = false;
|
|
1161
|
+
let frame = 0;
|
|
1162
|
+
let rafId = 0;
|
|
910
1163
|
const remeasure = () => {
|
|
911
1164
|
if (cancelled) return;
|
|
912
1165
|
measure();
|
|
1166
|
+
if (!locateImage() && frame++ < 30) {
|
|
1167
|
+
rafId = typeof requestAnimationFrame === "function" ? requestAnimationFrame(remeasure) : (queueMicrotask(remeasure), 0);
|
|
1168
|
+
}
|
|
913
1169
|
};
|
|
914
|
-
|
|
1170
|
+
rafId = typeof requestAnimationFrame === "function" ? requestAnimationFrame(remeasure) : (queueMicrotask(remeasure), 0);
|
|
915
1171
|
return () => {
|
|
916
1172
|
cancelled = true;
|
|
917
|
-
if (typeof cancelAnimationFrame === "function" && typeof
|
|
918
|
-
cancelAnimationFrame(
|
|
1173
|
+
if (typeof cancelAnimationFrame === "function" && typeof rafId === "number" && rafId > 0) {
|
|
1174
|
+
cancelAnimationFrame(rafId);
|
|
919
1175
|
}
|
|
920
1176
|
};
|
|
921
1177
|
}, [
|
|
922
1178
|
measure,
|
|
1179
|
+
locateImage,
|
|
923
1180
|
embed.width,
|
|
924
1181
|
embed.height,
|
|
925
1182
|
embed.align,
|
|
@@ -928,7 +1185,7 @@ function ImageResizeOverlay({
|
|
|
928
1185
|
embed.offsetX,
|
|
929
1186
|
embed.offsetY
|
|
930
1187
|
]);
|
|
931
|
-
(0,
|
|
1188
|
+
(0, import_react6.useEffect)(() => {
|
|
932
1189
|
const root = rootRef.current;
|
|
933
1190
|
if (!root) return;
|
|
934
1191
|
const onScroll = () => measure();
|
|
@@ -939,7 +1196,7 @@ function ImageResizeOverlay({
|
|
|
939
1196
|
root.removeEventListener("scroll", onScroll);
|
|
940
1197
|
};
|
|
941
1198
|
}, [measure, rootRef]);
|
|
942
|
-
(0,
|
|
1199
|
+
(0, import_react6.useEffect)(() => {
|
|
943
1200
|
if (typeof ResizeObserver === "undefined") return;
|
|
944
1201
|
const img = locateImage();
|
|
945
1202
|
const root = rootRef.current;
|
|
@@ -952,14 +1209,36 @@ function ImageResizeOverlay({
|
|
|
952
1209
|
if (!rect) return null;
|
|
953
1210
|
const layout = embed.layout ?? "inline";
|
|
954
1211
|
const movable = layout !== "inline" && onCommitMove !== void 0;
|
|
955
|
-
return /* @__PURE__ */ (0,
|
|
1212
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
|
|
956
1213
|
"div",
|
|
957
1214
|
{
|
|
958
1215
|
className: "ed-image-overlay",
|
|
959
1216
|
style: { top: rect.top, left: rect.left, width: rect.width, height: rect.height },
|
|
960
1217
|
contentEditable: false,
|
|
961
1218
|
children: [
|
|
962
|
-
|
|
1219
|
+
isMoving && // Non-clipped drag preview (Tier 2): the overlay lives in .ed-root and
|
|
1220
|
+
// follows the cursor, so the image stays visible while it crosses the
|
|
1221
|
+
// page boundary (the real, clipped figure is hidden during the drag).
|
|
1222
|
+
// Inline styles only — the package does not ship CSS.
|
|
1223
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1224
|
+
"img",
|
|
1225
|
+
{
|
|
1226
|
+
src: embed.src,
|
|
1227
|
+
alt: "",
|
|
1228
|
+
"aria-hidden": true,
|
|
1229
|
+
draggable: false,
|
|
1230
|
+
style: {
|
|
1231
|
+
position: "absolute",
|
|
1232
|
+
inset: 0,
|
|
1233
|
+
width: "100%",
|
|
1234
|
+
height: "100%",
|
|
1235
|
+
objectFit: "fill",
|
|
1236
|
+
opacity: 0.8,
|
|
1237
|
+
pointerEvents: "none"
|
|
1238
|
+
}
|
|
1239
|
+
}
|
|
1240
|
+
),
|
|
1241
|
+
movable && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
963
1242
|
MoveHandle,
|
|
964
1243
|
{
|
|
965
1244
|
layout,
|
|
@@ -967,10 +1246,17 @@ function ImageResizeOverlay({
|
|
|
967
1246
|
startOffsetY: embed.offsetY ?? 0,
|
|
968
1247
|
imgRef,
|
|
969
1248
|
onCommit: onCommitMove,
|
|
970
|
-
onLiveChange: measure
|
|
1249
|
+
onLiveChange: measure,
|
|
1250
|
+
rootRef,
|
|
1251
|
+
blockIndex,
|
|
1252
|
+
offset,
|
|
1253
|
+
cellIndex,
|
|
1254
|
+
onReanchor,
|
|
1255
|
+
onMoveStart: () => setIsMoving(true),
|
|
1256
|
+
onMoveEnd: () => setIsMoving(false)
|
|
971
1257
|
}
|
|
972
1258
|
),
|
|
973
|
-
/* @__PURE__ */ (0,
|
|
1259
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
974
1260
|
Handle,
|
|
975
1261
|
{
|
|
976
1262
|
corner: "nw",
|
|
@@ -981,7 +1267,7 @@ function ImageResizeOverlay({
|
|
|
981
1267
|
onLiveChange: measure
|
|
982
1268
|
}
|
|
983
1269
|
),
|
|
984
|
-
/* @__PURE__ */ (0,
|
|
1270
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
985
1271
|
Handle,
|
|
986
1272
|
{
|
|
987
1273
|
corner: "ne",
|
|
@@ -992,7 +1278,7 @@ function ImageResizeOverlay({
|
|
|
992
1278
|
onLiveChange: measure
|
|
993
1279
|
}
|
|
994
1280
|
),
|
|
995
|
-
/* @__PURE__ */ (0,
|
|
1281
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
996
1282
|
Handle,
|
|
997
1283
|
{
|
|
998
1284
|
corner: "sw",
|
|
@@ -1003,7 +1289,7 @@ function ImageResizeOverlay({
|
|
|
1003
1289
|
onLiveChange: measure
|
|
1004
1290
|
}
|
|
1005
1291
|
),
|
|
1006
|
-
/* @__PURE__ */ (0,
|
|
1292
|
+
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1007
1293
|
Handle,
|
|
1008
1294
|
{
|
|
1009
1295
|
corner: "se",
|
|
@@ -1024,9 +1310,16 @@ function MoveHandle({
|
|
|
1024
1310
|
startOffsetY,
|
|
1025
1311
|
imgRef,
|
|
1026
1312
|
onCommit,
|
|
1027
|
-
onLiveChange
|
|
1313
|
+
onLiveChange,
|
|
1314
|
+
rootRef,
|
|
1315
|
+
blockIndex,
|
|
1316
|
+
offset,
|
|
1317
|
+
cellIndex,
|
|
1318
|
+
onReanchor,
|
|
1319
|
+
onMoveStart,
|
|
1320
|
+
onMoveEnd
|
|
1028
1321
|
}) {
|
|
1029
|
-
const dragRef = (0,
|
|
1322
|
+
const dragRef = (0, import_react6.useRef)(null);
|
|
1030
1323
|
const onPointerDown = (e) => {
|
|
1031
1324
|
if (e.button !== 0) return;
|
|
1032
1325
|
if (!imgRef.current) return;
|
|
@@ -1039,35 +1332,65 @@ function MoveHandle({
|
|
|
1039
1332
|
liveOX: startOffsetX,
|
|
1040
1333
|
liveOY: startOffsetY
|
|
1041
1334
|
};
|
|
1335
|
+
const styled = imgRef.current.closest(".ed-figure") ?? imgRef.current;
|
|
1336
|
+
styled.style.opacity = "0";
|
|
1337
|
+
onMoveStart?.();
|
|
1042
1338
|
};
|
|
1043
1339
|
const onPointerMove = (e) => {
|
|
1044
1340
|
const d = dragRef.current;
|
|
1045
1341
|
if (!d || !imgRef.current) return;
|
|
1046
1342
|
const dx = e.clientX - d.startX;
|
|
1047
1343
|
const dy = e.clientY - d.startY;
|
|
1048
|
-
const
|
|
1344
|
+
const styled = imgRef.current.closest(".ed-figure") ?? imgRef.current;
|
|
1049
1345
|
let nox = startOffsetX;
|
|
1050
1346
|
let noy = startOffsetY;
|
|
1051
1347
|
if (layout === "wrap-left") {
|
|
1052
1348
|
nox = Math.max(8, startOffsetX + dx);
|
|
1053
1349
|
noy = Math.max(0, startOffsetY + dy);
|
|
1054
|
-
|
|
1055
|
-
|
|
1350
|
+
styled.style.marginRight = `${nox}px`;
|
|
1351
|
+
styled.style.marginTop = `${noy}px`;
|
|
1056
1352
|
} else if (layout === "wrap-right") {
|
|
1057
1353
|
nox = Math.max(8, startOffsetX - dx);
|
|
1058
1354
|
noy = Math.max(0, startOffsetY + dy);
|
|
1059
|
-
|
|
1060
|
-
|
|
1355
|
+
styled.style.marginLeft = `${nox}px`;
|
|
1356
|
+
styled.style.marginTop = `${noy}px`;
|
|
1061
1357
|
} else if (layout === "behind" || layout === "front") {
|
|
1062
1358
|
nox = startOffsetX + dx;
|
|
1063
1359
|
noy = startOffsetY + dy;
|
|
1064
|
-
|
|
1065
|
-
|
|
1360
|
+
styled.style.left = `${nox}px`;
|
|
1361
|
+
styled.style.top = `${noy}px`;
|
|
1066
1362
|
}
|
|
1067
1363
|
d.liveOX = nox;
|
|
1068
1364
|
d.liveOY = noy;
|
|
1069
1365
|
onLiveChange();
|
|
1070
1366
|
};
|
|
1367
|
+
const clampOffsetToFragment = (frag, oy) => {
|
|
1368
|
+
const img = imgRef.current;
|
|
1369
|
+
if (!img) return oy;
|
|
1370
|
+
const page = frag.closest(".ed-page");
|
|
1371
|
+
const content = page?.querySelector(".ed-page-content");
|
|
1372
|
+
if (!content) return oy;
|
|
1373
|
+
const fragRect = frag.getBoundingClientRect();
|
|
1374
|
+
const contentRect = content.getBoundingClientRect();
|
|
1375
|
+
const imgH = img.getBoundingClientRect().height;
|
|
1376
|
+
const minLocalTop = contentRect.top - fragRect.top;
|
|
1377
|
+
const maxLocalTop = contentRect.bottom - fragRect.top - imgH;
|
|
1378
|
+
return Math.round(Math.max(minLocalTop, Math.min(oy, maxLocalTop)));
|
|
1379
|
+
};
|
|
1380
|
+
const clampedCommit = (ox, oy) => {
|
|
1381
|
+
const img = imgRef.current;
|
|
1382
|
+
const root = rootRef.current;
|
|
1383
|
+
if (!img || !root || layout !== "behind" && layout !== "front") {
|
|
1384
|
+
onCommit(ox, oy);
|
|
1385
|
+
return;
|
|
1386
|
+
}
|
|
1387
|
+
const frag = getFragmentForOffset(root, blockIndex, offset);
|
|
1388
|
+
if (!frag) {
|
|
1389
|
+
onCommit(ox, oy);
|
|
1390
|
+
return;
|
|
1391
|
+
}
|
|
1392
|
+
onCommit(ox, clampOffsetToFragment(frag, oy));
|
|
1393
|
+
};
|
|
1071
1394
|
const finish = (e) => {
|
|
1072
1395
|
const d = dragRef.current;
|
|
1073
1396
|
if (!d) return;
|
|
@@ -1076,9 +1399,77 @@ function MoveHandle({
|
|
|
1076
1399
|
e.target.releasePointerCapture(e.pointerId);
|
|
1077
1400
|
} catch {
|
|
1078
1401
|
}
|
|
1079
|
-
|
|
1402
|
+
if (imgRef.current) {
|
|
1403
|
+
const styled = imgRef.current.closest(".ed-figure") ?? imgRef.current;
|
|
1404
|
+
styled.style.opacity = "";
|
|
1405
|
+
}
|
|
1406
|
+
onMoveEnd?.();
|
|
1407
|
+
const img = imgRef.current;
|
|
1408
|
+
const root = rootRef.current;
|
|
1409
|
+
const liveOX = Math.round(d.liveOX);
|
|
1410
|
+
const liveOY = Math.round(d.liveOY);
|
|
1411
|
+
if (!img || !root || onReanchor === void 0 || cellIndex != null) {
|
|
1412
|
+
clampedCommit(liveOX, liveOY);
|
|
1413
|
+
return;
|
|
1414
|
+
}
|
|
1415
|
+
const imgRect = img.getBoundingClientRect();
|
|
1416
|
+
const centerY = imgRect.top + imgRect.height / 2;
|
|
1417
|
+
const pages = Array.from(root.querySelectorAll(".ed-page"));
|
|
1418
|
+
let destPage = null;
|
|
1419
|
+
let bestPageDist = Infinity;
|
|
1420
|
+
for (const pg of pages) {
|
|
1421
|
+
const r = pg.getBoundingClientRect();
|
|
1422
|
+
if (centerY >= r.top && centerY <= r.bottom) {
|
|
1423
|
+
destPage = pg;
|
|
1424
|
+
break;
|
|
1425
|
+
}
|
|
1426
|
+
const dist = centerY < r.top ? r.top - centerY : centerY - r.bottom;
|
|
1427
|
+
if (dist < bestPageDist) {
|
|
1428
|
+
bestPageDist = dist;
|
|
1429
|
+
destPage = pg;
|
|
1430
|
+
}
|
|
1431
|
+
}
|
|
1432
|
+
const currentFrag = getFragmentForOffset(root, blockIndex, offset);
|
|
1433
|
+
const currentPage = currentFrag?.closest(".ed-page") ?? null;
|
|
1434
|
+
if (destPage == null || destPage === currentPage) {
|
|
1435
|
+
clampedCommit(liveOX, liveOY);
|
|
1436
|
+
return;
|
|
1437
|
+
}
|
|
1438
|
+
const blocksOnPage = Array.from(
|
|
1439
|
+
destPage.querySelectorAll("[data-block-index]")
|
|
1440
|
+
);
|
|
1441
|
+
let destFrag = null;
|
|
1442
|
+
let bestBlockDist = Infinity;
|
|
1443
|
+
for (const b of blocksOnPage) {
|
|
1444
|
+
const dist = Math.abs(b.getBoundingClientRect().top - imgRect.top);
|
|
1445
|
+
if (dist < bestBlockDist) {
|
|
1446
|
+
bestBlockDist = dist;
|
|
1447
|
+
destFrag = b;
|
|
1448
|
+
}
|
|
1449
|
+
}
|
|
1450
|
+
if (!destFrag) {
|
|
1451
|
+
clampedCommit(liveOX, liveOY);
|
|
1452
|
+
return;
|
|
1453
|
+
}
|
|
1454
|
+
const destBlockIndex = findBlockIndex(destFrag, root);
|
|
1455
|
+
if (destBlockIndex == null) {
|
|
1456
|
+
clampedCommit(liveOX, liveOY);
|
|
1457
|
+
return;
|
|
1458
|
+
}
|
|
1459
|
+
const destOffset = destFrag.dataset.fragmentStart ? Number.parseInt(destFrag.dataset.fragmentStart, 10) || 0 : 0;
|
|
1460
|
+
const fragRect = destFrag.getBoundingClientRect();
|
|
1461
|
+
const newOffsetX = Math.round(imgRect.left - fragRect.left);
|
|
1462
|
+
const newOffsetY = clampOffsetToFragment(
|
|
1463
|
+
destFrag,
|
|
1464
|
+
Math.round(imgRect.top - fragRect.top)
|
|
1465
|
+
);
|
|
1466
|
+
onReanchor(
|
|
1467
|
+
{ blockIndex: destBlockIndex, offset: destOffset, cellIndex: void 0 },
|
|
1468
|
+
newOffsetX,
|
|
1469
|
+
newOffsetY
|
|
1470
|
+
);
|
|
1080
1471
|
};
|
|
1081
|
-
return /* @__PURE__ */ (0,
|
|
1472
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1082
1473
|
"div",
|
|
1083
1474
|
{
|
|
1084
1475
|
className: "ed-image-move",
|
|
@@ -1098,7 +1489,7 @@ function Handle({
|
|
|
1098
1489
|
onCommit,
|
|
1099
1490
|
onLiveChange
|
|
1100
1491
|
}) {
|
|
1101
|
-
const dragRef = (0,
|
|
1492
|
+
const dragRef = (0, import_react6.useRef)(null);
|
|
1102
1493
|
const onPointerDown = (e) => {
|
|
1103
1494
|
if (e.button !== 0) return;
|
|
1104
1495
|
if (!imgRef.current) return;
|
|
@@ -1141,7 +1532,7 @@ function Handle({
|
|
|
1141
1532
|
}
|
|
1142
1533
|
onCommit(Math.round(d.liveW), Math.round(d.liveH));
|
|
1143
1534
|
};
|
|
1144
|
-
return /* @__PURE__ */ (0,
|
|
1535
|
+
return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
1145
1536
|
"div",
|
|
1146
1537
|
{
|
|
1147
1538
|
className: `ed-image-handle ${corner}`,
|
|
@@ -1153,17 +1544,187 @@ function Handle({
|
|
|
1153
1544
|
);
|
|
1154
1545
|
}
|
|
1155
1546
|
|
|
1547
|
+
// src/RemoteCursorsOverlay.tsx
|
|
1548
|
+
var import_react7 = require("react");
|
|
1549
|
+
var import_core2 = require("@sofereditor/core");
|
|
1550
|
+
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
1551
|
+
var DEFAULT_COLOR = "#3b82f6";
|
|
1552
|
+
function RemoteCursorsOverlay({
|
|
1553
|
+
rootRef,
|
|
1554
|
+
doc,
|
|
1555
|
+
awareness,
|
|
1556
|
+
revision
|
|
1557
|
+
}) {
|
|
1558
|
+
const [views, setViews] = (0, import_react7.useState)([]);
|
|
1559
|
+
const rafRef = (0, import_react7.useRef)(null);
|
|
1560
|
+
const measure = (0, import_react7.useCallback)(() => {
|
|
1561
|
+
const root = rootRef.current;
|
|
1562
|
+
if (!root) {
|
|
1563
|
+
setViews((prev) => prev.length === 0 ? prev : []);
|
|
1564
|
+
return;
|
|
1565
|
+
}
|
|
1566
|
+
const rr = root.getBoundingClientRect();
|
|
1567
|
+
const out = [];
|
|
1568
|
+
awareness.getStates().forEach((state, clientId) => {
|
|
1569
|
+
if (clientId === awareness.clientID) return;
|
|
1570
|
+
const s = state;
|
|
1571
|
+
if (!s.cursor) return;
|
|
1572
|
+
const sel = (0, import_core2.decodeSelection)(doc, s.cursor);
|
|
1573
|
+
if (!sel) return;
|
|
1574
|
+
const color = s.user?.color || DEFAULT_COLOR;
|
|
1575
|
+
const name = s.user?.name || "An\xF4nimo";
|
|
1576
|
+
const focus = locatePoint(root, sel.focus);
|
|
1577
|
+
let caret = null;
|
|
1578
|
+
if (focus) {
|
|
1579
|
+
try {
|
|
1580
|
+
const range = document.createRange();
|
|
1581
|
+
range.setStart(focus.node, focus.offset);
|
|
1582
|
+
range.collapse(true);
|
|
1583
|
+
let rect = range.getBoundingClientRect();
|
|
1584
|
+
if (rect.height === 0 && focus.node.nodeType === Node.ELEMENT_NODE) {
|
|
1585
|
+
rect = focus.node.getBoundingClientRect();
|
|
1586
|
+
}
|
|
1587
|
+
caret = {
|
|
1588
|
+
top: rect.top - rr.top + root.scrollTop,
|
|
1589
|
+
left: rect.left - rr.left + root.scrollLeft,
|
|
1590
|
+
height: rect.height || 18
|
|
1591
|
+
};
|
|
1592
|
+
} catch {
|
|
1593
|
+
}
|
|
1594
|
+
}
|
|
1595
|
+
const collapsed = sel.anchor.blockIndex === sel.focus.blockIndex && (sel.anchor.cellIndex ?? -1) === (sel.focus.cellIndex ?? -1) && sel.anchor.offset === sel.focus.offset;
|
|
1596
|
+
const selection = [];
|
|
1597
|
+
if (!collapsed && focus) {
|
|
1598
|
+
const anchor = locatePoint(root, sel.anchor);
|
|
1599
|
+
if (anchor) {
|
|
1600
|
+
try {
|
|
1601
|
+
const r = document.createRange();
|
|
1602
|
+
r.setStart(anchor.node, anchor.offset);
|
|
1603
|
+
r.setEnd(focus.node, focus.offset);
|
|
1604
|
+
if (r.collapsed) {
|
|
1605
|
+
r.setStart(focus.node, focus.offset);
|
|
1606
|
+
r.setEnd(anchor.node, anchor.offset);
|
|
1607
|
+
}
|
|
1608
|
+
for (const cr of Array.from(r.getClientRects())) {
|
|
1609
|
+
if (cr.width === 0 || cr.height === 0) continue;
|
|
1610
|
+
selection.push({
|
|
1611
|
+
top: cr.top - rr.top + root.scrollTop,
|
|
1612
|
+
left: cr.left - rr.left + root.scrollLeft,
|
|
1613
|
+
width: cr.width,
|
|
1614
|
+
height: cr.height
|
|
1615
|
+
});
|
|
1616
|
+
}
|
|
1617
|
+
} catch {
|
|
1618
|
+
}
|
|
1619
|
+
}
|
|
1620
|
+
}
|
|
1621
|
+
out.push({ clientId, name, color, caret, selection });
|
|
1622
|
+
});
|
|
1623
|
+
setViews(out);
|
|
1624
|
+
}, [rootRef, doc, awareness]);
|
|
1625
|
+
const scheduleMeasure = (0, import_react7.useCallback)(() => {
|
|
1626
|
+
if (rafRef.current != null) return;
|
|
1627
|
+
const raf = typeof requestAnimationFrame === "function" ? requestAnimationFrame : (cb) => setTimeout(() => cb(0), 16);
|
|
1628
|
+
rafRef.current = raf(() => {
|
|
1629
|
+
rafRef.current = null;
|
|
1630
|
+
measure();
|
|
1631
|
+
});
|
|
1632
|
+
}, [measure]);
|
|
1633
|
+
(0, import_react7.useEffect)(() => {
|
|
1634
|
+
const onChange = () => scheduleMeasure();
|
|
1635
|
+
awareness.on("change", onChange);
|
|
1636
|
+
scheduleMeasure();
|
|
1637
|
+
return () => awareness.off("change", onChange);
|
|
1638
|
+
}, [awareness, scheduleMeasure]);
|
|
1639
|
+
(0, import_react7.useEffect)(() => {
|
|
1640
|
+
scheduleMeasure();
|
|
1641
|
+
}, [revision, scheduleMeasure]);
|
|
1642
|
+
(0, import_react7.useEffect)(() => {
|
|
1643
|
+
const root = rootRef.current;
|
|
1644
|
+
if (!root) return;
|
|
1645
|
+
const onScroll = () => scheduleMeasure();
|
|
1646
|
+
root.addEventListener("scroll", onScroll, { passive: true });
|
|
1647
|
+
let ro = null;
|
|
1648
|
+
if (typeof ResizeObserver !== "undefined") {
|
|
1649
|
+
ro = new ResizeObserver(() => scheduleMeasure());
|
|
1650
|
+
ro.observe(root);
|
|
1651
|
+
}
|
|
1652
|
+
return () => {
|
|
1653
|
+
root.removeEventListener("scroll", onScroll);
|
|
1654
|
+
ro?.disconnect();
|
|
1655
|
+
};
|
|
1656
|
+
}, [rootRef, scheduleMeasure]);
|
|
1657
|
+
if (views.length === 0) return null;
|
|
1658
|
+
const layer = {
|
|
1659
|
+
position: "absolute",
|
|
1660
|
+
inset: 0,
|
|
1661
|
+
pointerEvents: "none",
|
|
1662
|
+
zIndex: 6
|
|
1663
|
+
};
|
|
1664
|
+
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: "ed-remote-cursors", "aria-hidden": true, style: layer, children: views.map((v) => /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { children: [
|
|
1665
|
+
v.selection.map((r, i) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1666
|
+
"div",
|
|
1667
|
+
{
|
|
1668
|
+
style: {
|
|
1669
|
+
position: "absolute",
|
|
1670
|
+
top: r.top,
|
|
1671
|
+
left: r.left,
|
|
1672
|
+
width: r.width,
|
|
1673
|
+
height: r.height,
|
|
1674
|
+
background: v.color,
|
|
1675
|
+
opacity: 0.22,
|
|
1676
|
+
borderRadius: 2
|
|
1677
|
+
}
|
|
1678
|
+
},
|
|
1679
|
+
i
|
|
1680
|
+
)),
|
|
1681
|
+
v.caret && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1682
|
+
"div",
|
|
1683
|
+
{
|
|
1684
|
+
style: {
|
|
1685
|
+
position: "absolute",
|
|
1686
|
+
top: v.caret.top,
|
|
1687
|
+
left: v.caret.left,
|
|
1688
|
+
height: v.caret.height,
|
|
1689
|
+
width: 2,
|
|
1690
|
+
background: v.color
|
|
1691
|
+
},
|
|
1692
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
1693
|
+
"span",
|
|
1694
|
+
{
|
|
1695
|
+
style: {
|
|
1696
|
+
position: "absolute",
|
|
1697
|
+
top: -15,
|
|
1698
|
+
left: -1,
|
|
1699
|
+
fontSize: 10,
|
|
1700
|
+
lineHeight: "14px",
|
|
1701
|
+
padding: "0 4px",
|
|
1702
|
+
borderRadius: 3,
|
|
1703
|
+
color: "#fff",
|
|
1704
|
+
background: v.color,
|
|
1705
|
+
whiteSpace: "nowrap",
|
|
1706
|
+
fontFamily: "system-ui, sans-serif",
|
|
1707
|
+
userSelect: "none"
|
|
1708
|
+
},
|
|
1709
|
+
children: v.name
|
|
1710
|
+
}
|
|
1711
|
+
)
|
|
1712
|
+
}
|
|
1713
|
+
)
|
|
1714
|
+
] }, v.clientId)) });
|
|
1715
|
+
}
|
|
1716
|
+
|
|
1156
1717
|
// src/NodeView.tsx
|
|
1157
|
-
var
|
|
1158
|
-
var
|
|
1718
|
+
var import_react10 = require("react");
|
|
1719
|
+
var import_core4 = require("@sofereditor/core");
|
|
1159
1720
|
|
|
1160
1721
|
// src/renderInline.tsx
|
|
1161
|
-
var
|
|
1162
|
-
var
|
|
1163
|
-
var
|
|
1722
|
+
var import_react8 = require("react");
|
|
1723
|
+
var import_core3 = require("@sofereditor/core");
|
|
1724
|
+
var import_jsx_runtime9 = require("react/jsx-runtime");
|
|
1164
1725
|
function renderInline(delta, keyPrefix) {
|
|
1165
1726
|
if (delta.length === 0 || delta.length === 1 && typeof delta[0].insert === "string" && delta[0].insert === "") {
|
|
1166
|
-
return /* @__PURE__ */ (0,
|
|
1727
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("br", { "data-empty": "true" });
|
|
1167
1728
|
}
|
|
1168
1729
|
let offset = 0;
|
|
1169
1730
|
const wrapAnchors = [];
|
|
@@ -1173,18 +1734,18 @@ function renderInline(delta, keyPrefix) {
|
|
|
1173
1734
|
const text = op.insert;
|
|
1174
1735
|
if (text.length === 0) continue;
|
|
1175
1736
|
const key = `${keyPrefix}-${offset}`;
|
|
1176
|
-
body.push(/* @__PURE__ */ (0,
|
|
1737
|
+
body.push(/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react8.Fragment, { children: wrap(text, op.attributes) }, key));
|
|
1177
1738
|
offset += text.length;
|
|
1178
|
-
} else if ((0,
|
|
1739
|
+
} else if ((0, import_core3.isImageEmbed)(op.insert)) {
|
|
1179
1740
|
const key = `${keyPrefix}-${offset}`;
|
|
1180
1741
|
const layout = op.insert.layout ?? "inline";
|
|
1181
1742
|
const commentMarkId = op.attributes?.comment?.markId;
|
|
1182
1743
|
if (layout === "wrap-left" || layout === "wrap-right") {
|
|
1183
1744
|
wrapAnchors.push(
|
|
1184
|
-
/* @__PURE__ */ (0,
|
|
1745
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ImageEmbedView, { embed: op.insert, offset, wrapAnchor: true }, `${key}-anchor`)
|
|
1185
1746
|
);
|
|
1186
1747
|
body.push(
|
|
1187
|
-
/* @__PURE__ */ (0,
|
|
1748
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1188
1749
|
"span",
|
|
1189
1750
|
{
|
|
1190
1751
|
"data-embed-phantom": "true",
|
|
@@ -1196,10 +1757,10 @@ function renderInline(delta, keyPrefix) {
|
|
|
1196
1757
|
)
|
|
1197
1758
|
);
|
|
1198
1759
|
} else {
|
|
1199
|
-
const imgNode = /* @__PURE__ */ (0,
|
|
1760
|
+
const imgNode = /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ImageEmbedView, { embed: op.insert, offset }, key);
|
|
1200
1761
|
if (commentMarkId) {
|
|
1201
1762
|
body.push(
|
|
1202
|
-
/* @__PURE__ */ (0,
|
|
1763
|
+
/* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { "data-comment-id": commentMarkId, className: "ed-comment", children: imgNode }, `${key}-cmt`)
|
|
1203
1764
|
);
|
|
1204
1765
|
} else {
|
|
1205
1766
|
body.push(imgNode);
|
|
@@ -1210,7 +1771,7 @@ function renderInline(delta, keyPrefix) {
|
|
|
1210
1771
|
offset += 1;
|
|
1211
1772
|
}
|
|
1212
1773
|
}
|
|
1213
|
-
if (wrapAnchors.length === 0 && body.length === 0) return /* @__PURE__ */ (0,
|
|
1774
|
+
if (wrapAnchors.length === 0 && body.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("br", { "data-empty": "true" });
|
|
1214
1775
|
return [...wrapAnchors, ...body];
|
|
1215
1776
|
}
|
|
1216
1777
|
var PHANTOM_STYLE = {
|
|
@@ -1220,6 +1781,11 @@ var PHANTOM_STYLE = {
|
|
|
1220
1781
|
overflow: "hidden",
|
|
1221
1782
|
verticalAlign: "baseline"
|
|
1222
1783
|
};
|
|
1784
|
+
var LINK_STYLE = {
|
|
1785
|
+
color: "#2563eb",
|
|
1786
|
+
textDecoration: "underline",
|
|
1787
|
+
cursor: "text"
|
|
1788
|
+
};
|
|
1223
1789
|
function imageEmbedPropsEqual(a, b) {
|
|
1224
1790
|
if (a.offset !== b.offset || a.wrapAnchor !== b.wrapAnchor) return false;
|
|
1225
1791
|
const x = a.embed;
|
|
@@ -1230,7 +1796,7 @@ function imageEmbedPropsEqual(a, b) {
|
|
|
1230
1796
|
// because Y.js stores the embed in its content map and re-exposes it.
|
|
1231
1797
|
x.src === y.src;
|
|
1232
1798
|
}
|
|
1233
|
-
var ImageEmbedView = (0,
|
|
1799
|
+
var ImageEmbedView = (0, import_react8.memo)(ImageEmbedViewImpl, imageEmbedPropsEqual);
|
|
1234
1800
|
function ImageEmbedViewImpl({
|
|
1235
1801
|
embed,
|
|
1236
1802
|
offset,
|
|
@@ -1285,8 +1851,12 @@ function ImageEmbedViewImpl({
|
|
|
1285
1851
|
};
|
|
1286
1852
|
break;
|
|
1287
1853
|
}
|
|
1288
|
-
const imgStyle =
|
|
1289
|
-
|
|
1854
|
+
const imgStyle = {
|
|
1855
|
+
width: embed.width,
|
|
1856
|
+
height: embed.height,
|
|
1857
|
+
display: "block"
|
|
1858
|
+
};
|
|
1859
|
+
const img = /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1290
1860
|
"img",
|
|
1291
1861
|
{
|
|
1292
1862
|
src: embed.src,
|
|
@@ -1305,19 +1875,18 @@ function ImageEmbedViewImpl({
|
|
|
1305
1875
|
alt: ""
|
|
1306
1876
|
}
|
|
1307
1877
|
);
|
|
1308
|
-
if (!hasCaption) return img;
|
|
1309
1878
|
const captionAlign = embed.captionAlign ?? "center";
|
|
1310
|
-
return /* @__PURE__ */ (0,
|
|
1879
|
+
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
|
|
1311
1880
|
"figure",
|
|
1312
1881
|
{
|
|
1313
1882
|
className: "ed-figure",
|
|
1314
1883
|
contentEditable: false,
|
|
1315
|
-
"data-embed-figure": "true",
|
|
1884
|
+
"data-embed-figure": hasCaption ? "true" : void 0,
|
|
1316
1885
|
"data-embed-layout": layout,
|
|
1317
1886
|
style: outerStyle,
|
|
1318
1887
|
children: [
|
|
1319
1888
|
img,
|
|
1320
|
-
/* @__PURE__ */ (0,
|
|
1889
|
+
hasCaption && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1321
1890
|
"figcaption",
|
|
1322
1891
|
{
|
|
1323
1892
|
className: "ed-figcaption",
|
|
@@ -1333,34 +1902,38 @@ function ImageEmbedViewImpl({
|
|
|
1333
1902
|
function wrap(text, attrs) {
|
|
1334
1903
|
let node = text;
|
|
1335
1904
|
if (!attrs) return node;
|
|
1336
|
-
if (attrs.bold) node = /* @__PURE__ */ (0,
|
|
1337
|
-
if (attrs.italic) node = /* @__PURE__ */ (0,
|
|
1338
|
-
if (attrs.underline) node = /* @__PURE__ */ (0,
|
|
1339
|
-
if (attrs.strike) node = /* @__PURE__ */ (0,
|
|
1905
|
+
if (attrs.bold) node = /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("strong", { children: node });
|
|
1906
|
+
if (attrs.italic) node = /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("em", { children: node });
|
|
1907
|
+
if (attrs.underline) node = /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("u", { children: node });
|
|
1908
|
+
if (attrs.strike) node = /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("s", { children: node });
|
|
1340
1909
|
const styleParts = {};
|
|
1341
1910
|
if (attrs.color) styleParts.color = attrs.color;
|
|
1342
1911
|
if (attrs.fontFamily) styleParts.fontFamily = attrs.fontFamily;
|
|
1343
1912
|
if (attrs.fontSize) styleParts.fontSize = attrs.fontSize;
|
|
1344
1913
|
if (Object.keys(styleParts).length > 0) {
|
|
1345
|
-
node = /* @__PURE__ */ (0,
|
|
1914
|
+
node = /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { style: styleParts, children: node });
|
|
1346
1915
|
}
|
|
1347
1916
|
if (attrs.link?.href) {
|
|
1348
|
-
node = /* @__PURE__ */ (0,
|
|
1917
|
+
node = /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
|
|
1349
1918
|
"a",
|
|
1350
1919
|
{
|
|
1351
1920
|
href: attrs.link.href,
|
|
1352
1921
|
title: attrs.link.title,
|
|
1353
1922
|
rel: "noopener noreferrer",
|
|
1354
1923
|
target: "_blank",
|
|
1924
|
+
style: LINK_STYLE,
|
|
1355
1925
|
onClick: (e) => {
|
|
1356
|
-
|
|
1926
|
+
e.preventDefault();
|
|
1927
|
+
if (hasOpenModifier(e) && attrs.link?.href) {
|
|
1928
|
+
window.open(attrs.link.href, "_blank", "noopener,noreferrer");
|
|
1929
|
+
}
|
|
1357
1930
|
},
|
|
1358
1931
|
children: node
|
|
1359
1932
|
}
|
|
1360
1933
|
);
|
|
1361
1934
|
}
|
|
1362
1935
|
if (attrs.comment?.markId) {
|
|
1363
|
-
node = /* @__PURE__ */ (0,
|
|
1936
|
+
node = /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { "data-comment-id": attrs.comment.markId, className: "ed-comment", children: node });
|
|
1364
1937
|
}
|
|
1365
1938
|
return node;
|
|
1366
1939
|
}
|
|
@@ -1404,14 +1977,14 @@ function sliceDelta(delta, start, end) {
|
|
|
1404
1977
|
}
|
|
1405
1978
|
|
|
1406
1979
|
// src/TableResizeOverlay.tsx
|
|
1407
|
-
var
|
|
1408
|
-
var
|
|
1980
|
+
var import_react9 = require("react");
|
|
1981
|
+
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
1409
1982
|
function TableResizeOverlay({ tableRef, blockIndex, cols }) {
|
|
1410
1983
|
const editor = useEditorContext();
|
|
1411
|
-
const [positions, setPositions] = (0,
|
|
1412
|
-
const [layout, setLayout] = (0,
|
|
1413
|
-
const draggingRef = (0,
|
|
1414
|
-
const measure = (0,
|
|
1984
|
+
const [positions, setPositions] = (0, import_react9.useState)(null);
|
|
1985
|
+
const [layout, setLayout] = (0, import_react9.useState)(null);
|
|
1986
|
+
const draggingRef = (0, import_react9.useRef)(null);
|
|
1987
|
+
const measure = (0, import_react9.useCallback)(() => {
|
|
1415
1988
|
const table = tableRef.current;
|
|
1416
1989
|
if (!table) return;
|
|
1417
1990
|
const tableRect = table.getBoundingClientRect();
|
|
@@ -1441,17 +2014,17 @@ function TableResizeOverlay({ tableRef, blockIndex, cols }) {
|
|
|
1441
2014
|
}
|
|
1442
2015
|
setLayout({ rights, height: tableRect.height });
|
|
1443
2016
|
}, [cols, tableRef]);
|
|
1444
|
-
(0,
|
|
2017
|
+
(0, import_react9.useLayoutEffect)(() => {
|
|
1445
2018
|
measure();
|
|
1446
2019
|
}, [measure]);
|
|
1447
|
-
(0,
|
|
2020
|
+
(0, import_react9.useEffect)(() => {
|
|
1448
2021
|
const table = tableRef.current;
|
|
1449
2022
|
if (!table) return;
|
|
1450
2023
|
const ro = new ResizeObserver(() => measure());
|
|
1451
2024
|
ro.observe(table);
|
|
1452
2025
|
return () => ro.disconnect();
|
|
1453
2026
|
}, [measure, tableRef]);
|
|
1454
|
-
const onPointerDown = (0,
|
|
2027
|
+
const onPointerDown = (0, import_react9.useCallback)(
|
|
1455
2028
|
(col) => (e) => {
|
|
1456
2029
|
e.preventDefault();
|
|
1457
2030
|
e.stopPropagation();
|
|
@@ -1465,7 +2038,7 @@ function TableResizeOverlay({ tableRef, blockIndex, cols }) {
|
|
|
1465
2038
|
},
|
|
1466
2039
|
[layout, tableRef]
|
|
1467
2040
|
);
|
|
1468
|
-
const onPointerMove = (0,
|
|
2041
|
+
const onPointerMove = (0, import_react9.useCallback)(
|
|
1469
2042
|
(e) => {
|
|
1470
2043
|
const d = draggingRef.current;
|
|
1471
2044
|
if (!d) return;
|
|
@@ -1475,7 +2048,7 @@ function TableResizeOverlay({ tableRef, blockIndex, cols }) {
|
|
|
1475
2048
|
},
|
|
1476
2049
|
[blockIndex, editor]
|
|
1477
2050
|
);
|
|
1478
|
-
const onPointerUp = (0,
|
|
2051
|
+
const onPointerUp = (0, import_react9.useCallback)((e) => {
|
|
1479
2052
|
draggingRef.current = null;
|
|
1480
2053
|
setPositions(null);
|
|
1481
2054
|
try {
|
|
@@ -1494,7 +2067,7 @@ function TableResizeOverlay({ tableRef, blockIndex, cols }) {
|
|
|
1494
2067
|
zIndex: 5
|
|
1495
2068
|
});
|
|
1496
2069
|
void positions;
|
|
1497
|
-
return /* @__PURE__ */ (0,
|
|
2070
|
+
return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_jsx_runtime10.Fragment, { children: layout.rights.map((x, c) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1498
2071
|
"div",
|
|
1499
2072
|
{
|
|
1500
2073
|
contentEditable: false,
|
|
@@ -1511,10 +2084,10 @@ function TableResizeOverlay({ tableRef, blockIndex, cols }) {
|
|
|
1511
2084
|
}
|
|
1512
2085
|
|
|
1513
2086
|
// src/NodeView.tsx
|
|
1514
|
-
var
|
|
2087
|
+
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
1515
2088
|
function NodeView({ block, index, children, fragment, tableFragment }) {
|
|
1516
2089
|
if (block.type === "table") {
|
|
1517
|
-
return /* @__PURE__ */ (0,
|
|
2090
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(TableView, { block, index, tableFragment });
|
|
1518
2091
|
}
|
|
1519
2092
|
const inline = fragment ? renderInline(sliceDelta(block.delta, fragment.start, fragment.end), index) : renderInline(block.delta, index);
|
|
1520
2093
|
const common = commonBlockProps(block.attrs, index, block.type, fragment);
|
|
@@ -1522,7 +2095,7 @@ function NodeView({ block, index, children, fragment, tableFragment }) {
|
|
|
1522
2095
|
case "heading": {
|
|
1523
2096
|
const level = clampLevel(block.attrs.level);
|
|
1524
2097
|
const Tag = `h${level}`;
|
|
1525
|
-
return /* @__PURE__ */ (0,
|
|
2098
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1526
2099
|
Tag,
|
|
1527
2100
|
{
|
|
1528
2101
|
...common,
|
|
@@ -1532,7 +2105,7 @@ function NodeView({ block, index, children, fragment, tableFragment }) {
|
|
|
1532
2105
|
);
|
|
1533
2106
|
}
|
|
1534
2107
|
case "blockquote":
|
|
1535
|
-
return /* @__PURE__ */ (0,
|
|
2108
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1536
2109
|
"blockquote",
|
|
1537
2110
|
{
|
|
1538
2111
|
...common,
|
|
@@ -1541,18 +2114,18 @@ function NodeView({ block, index, children, fragment, tableFragment }) {
|
|
|
1541
2114
|
}
|
|
1542
2115
|
);
|
|
1543
2116
|
case "codeBlock":
|
|
1544
|
-
return /* @__PURE__ */ (0,
|
|
2117
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1545
2118
|
"pre",
|
|
1546
2119
|
{
|
|
1547
2120
|
...common,
|
|
1548
2121
|
"data-language": block.attrs.language ?? void 0,
|
|
1549
2122
|
className: `ed-block ed-codeblock${alignClass(block.attrs.align)}`,
|
|
1550
|
-
children: /* @__PURE__ */ (0,
|
|
2123
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("code", { children: inline })
|
|
1551
2124
|
}
|
|
1552
2125
|
);
|
|
1553
2126
|
case "listItem": {
|
|
1554
2127
|
const level = clampListLevel(block.attrs.listLevel);
|
|
1555
|
-
return /* @__PURE__ */ (0,
|
|
2128
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
1556
2129
|
"li",
|
|
1557
2130
|
{
|
|
1558
2131
|
...common,
|
|
@@ -1568,7 +2141,7 @@ function NodeView({ block, index, children, fragment, tableFragment }) {
|
|
|
1568
2141
|
}
|
|
1569
2142
|
case "paragraph":
|
|
1570
2143
|
default:
|
|
1571
|
-
return /* @__PURE__ */ (0,
|
|
2144
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1572
2145
|
"div",
|
|
1573
2146
|
{
|
|
1574
2147
|
...common,
|
|
@@ -1613,18 +2186,18 @@ function TableView({ block, index, tableFragment }) {
|
|
|
1613
2186
|
const cols = clampPositive(block.attrs.cols);
|
|
1614
2187
|
const cells = block.cells ?? [];
|
|
1615
2188
|
const widths = readColWidths(block.attrs.colWidths, cols);
|
|
1616
|
-
const tableRef = (0,
|
|
2189
|
+
const tableRef = (0, import_react10.useRef)(null);
|
|
1617
2190
|
const rowStart = tableFragment?.rowStart ?? 0;
|
|
1618
2191
|
const rowEnd = tableFragment?.rowEnd ?? rows;
|
|
1619
2192
|
const isFirstFragment = !tableFragment || tableFragment.index === 0;
|
|
1620
2193
|
const editor = useEditorContext();
|
|
1621
|
-
const rect = (0,
|
|
2194
|
+
const rect = (0, import_react10.useMemo)(() => {
|
|
1622
2195
|
if (editor.selection.anchor.blockIndex !== index) return null;
|
|
1623
2196
|
if (editor.selection.focus.blockIndex !== index) return null;
|
|
1624
|
-
return (0,
|
|
2197
|
+
return (0, import_core4.tableRectSelection)(editor.doc, editor.selection);
|
|
1625
2198
|
}, [editor.doc, editor.selection, index]);
|
|
1626
|
-
return /* @__PURE__ */ (0,
|
|
1627
|
-
/* @__PURE__ */ (0,
|
|
2199
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: "ed-table-wrap", children: [
|
|
2200
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
|
|
1628
2201
|
"table",
|
|
1629
2202
|
{
|
|
1630
2203
|
ref: tableRef,
|
|
@@ -1632,10 +2205,10 @@ function TableView({ block, index, tableFragment }) {
|
|
|
1632
2205
|
"data-block-type": "table",
|
|
1633
2206
|
className: "ed-block ed-table",
|
|
1634
2207
|
children: [
|
|
1635
|
-
widths && /* @__PURE__ */ (0,
|
|
1636
|
-
/* @__PURE__ */ (0,
|
|
2208
|
+
widths && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("colgroup", { children: widths.map((w, c) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("col", { style: w != null ? { width: `${w}px` } : void 0 }, c)) }),
|
|
2209
|
+
/* @__PURE__ */ (0, import_jsx_runtime11.jsx)("tbody", { children: Array.from({ length: rowEnd - rowStart }, (_, i) => {
|
|
1637
2210
|
const r = rowStart + i;
|
|
1638
|
-
return /* @__PURE__ */ (0,
|
|
2211
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("tr", { "data-cell-row": r, children: Array.from({ length: cols }, (_2, c) => {
|
|
1639
2212
|
const flat = r * cols + c;
|
|
1640
2213
|
const cell = cells[flat];
|
|
1641
2214
|
if (cell?.attrs.covered === true) return null;
|
|
@@ -1643,7 +2216,7 @@ function TableView({ block, index, tableFragment }) {
|
|
|
1643
2216
|
const colspan = spanAttr(cell?.attrs.colspan);
|
|
1644
2217
|
const delta = cell?.delta ?? [];
|
|
1645
2218
|
const inRect = rect !== null && r >= rect.top && r <= rect.bottom && c >= rect.left && c <= rect.right;
|
|
1646
|
-
return /* @__PURE__ */ (0,
|
|
2219
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
1647
2220
|
"td",
|
|
1648
2221
|
{
|
|
1649
2222
|
"data-cell-index": flat,
|
|
@@ -1653,6 +2226,7 @@ function TableView({ block, index, tableFragment }) {
|
|
|
1653
2226
|
"data-cell-colspan": colspan,
|
|
1654
2227
|
rowSpan: rowspan > 1 ? rowspan : void 0,
|
|
1655
2228
|
colSpan: colspan > 1 ? colspan : void 0,
|
|
2229
|
+
style: cell?.attrs.align ? { textAlign: cell.attrs.align } : void 0,
|
|
1656
2230
|
className: inRect ? "ed-cell ed-cell--selected" : "ed-cell",
|
|
1657
2231
|
children: renderInline(delta, `t${index}-c${flat}`)
|
|
1658
2232
|
},
|
|
@@ -1663,7 +2237,7 @@ function TableView({ block, index, tableFragment }) {
|
|
|
1663
2237
|
]
|
|
1664
2238
|
}
|
|
1665
2239
|
),
|
|
1666
|
-
isFirstFragment && /* @__PURE__ */ (0,
|
|
2240
|
+
isFirstFragment && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(TableResizeOverlay, { tableRef, blockIndex: index, cols })
|
|
1667
2241
|
] });
|
|
1668
2242
|
}
|
|
1669
2243
|
function readColWidths(raw, cols) {
|
|
@@ -1685,7 +2259,7 @@ function clampPositive(n) {
|
|
|
1685
2259
|
}
|
|
1686
2260
|
|
|
1687
2261
|
// src/usePagination.ts
|
|
1688
|
-
var
|
|
2262
|
+
var import_react11 = require("react");
|
|
1689
2263
|
var A4_PAGE = {
|
|
1690
2264
|
width: 794,
|
|
1691
2265
|
height: 1123,
|
|
@@ -1711,10 +2285,10 @@ function defaultPageLayout(topLevelCount) {
|
|
|
1711
2285
|
};
|
|
1712
2286
|
}
|
|
1713
2287
|
function usePageLayout(rootRef, geometry, topLevelCount, deps) {
|
|
1714
|
-
const [phase, setPhase] = (0,
|
|
1715
|
-
const [layout, setLayout] = (0,
|
|
1716
|
-
const lastDepsRef = (0,
|
|
1717
|
-
(0,
|
|
2288
|
+
const [phase, setPhase] = (0, import_react11.useState)("measure");
|
|
2289
|
+
const [layout, setLayout] = (0, import_react11.useState)(() => defaultPageLayout(topLevelCount));
|
|
2290
|
+
const lastDepsRef = (0, import_react11.useRef)(null);
|
|
2291
|
+
(0, import_react11.useLayoutEffect)(() => {
|
|
1718
2292
|
const currentDeps = [...deps, topLevelCount, geometry];
|
|
1719
2293
|
if (lastDepsRef.current !== null && shallowArrayEqual(lastDepsRef.current, currentDeps)) {
|
|
1720
2294
|
return;
|
|
@@ -1726,7 +2300,7 @@ function usePageLayout(rootRef, geometry, topLevelCount, deps) {
|
|
|
1726
2300
|
});
|
|
1727
2301
|
setPhase("measure");
|
|
1728
2302
|
});
|
|
1729
|
-
(0,
|
|
2303
|
+
(0, import_react11.useLayoutEffect)(() => {
|
|
1730
2304
|
if (phase !== "measure") return;
|
|
1731
2305
|
const root = rootRef.current;
|
|
1732
2306
|
if (!root) return;
|
|
@@ -2198,48 +2772,48 @@ function layoutsDeepEqual(a, b) {
|
|
|
2198
2772
|
}
|
|
2199
2773
|
|
|
2200
2774
|
// src/useEditor.ts
|
|
2201
|
-
var
|
|
2775
|
+
var import_react13 = require("react");
|
|
2202
2776
|
|
|
2203
2777
|
// src/usePageSettings.ts
|
|
2204
|
-
var
|
|
2778
|
+
var import_react12 = require("react");
|
|
2205
2779
|
function usePageSettings(doc) {
|
|
2206
|
-
const cacheRef = (0,
|
|
2207
|
-
const subscribe = (0,
|
|
2780
|
+
const cacheRef = (0, import_react12.useRef)(null);
|
|
2781
|
+
const subscribe = (0, import_react12.useCallback)(
|
|
2208
2782
|
(notify) => doc.observePageSettings(notify),
|
|
2209
2783
|
[doc]
|
|
2210
2784
|
);
|
|
2211
|
-
const getSnapshot = (0,
|
|
2785
|
+
const getSnapshot = (0, import_react12.useCallback)(() => {
|
|
2212
2786
|
const next = doc.getPageSettings();
|
|
2213
2787
|
const prev = cacheRef.current;
|
|
2214
2788
|
if (prev && shallowEqual(prev, next)) return prev;
|
|
2215
2789
|
cacheRef.current = next;
|
|
2216
2790
|
return next;
|
|
2217
2791
|
}, [doc]);
|
|
2218
|
-
return (0,
|
|
2792
|
+
return (0, import_react12.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
|
|
2219
2793
|
}
|
|
2220
2794
|
function shallowEqual(a, b) {
|
|
2221
2795
|
return a.width === b.width && a.height === b.height && a.marginTop === b.marginTop && a.marginBottom === b.marginBottom && a.marginLeft === b.marginLeft && a.marginRight === b.marginRight && a.preset === b.preset && a.systemHeaderTitle === b.systemHeaderTitle && a.systemHeaderAuthor === b.systemHeaderAuthor;
|
|
2222
2796
|
}
|
|
2223
2797
|
|
|
2224
2798
|
// src/useEditor.ts
|
|
2225
|
-
var
|
|
2799
|
+
var import_core5 = require("@sofereditor/core");
|
|
2226
2800
|
var MAX_INSERT_WIDTH = 600;
|
|
2227
2801
|
function useEditor(opts = {}) {
|
|
2228
|
-
const doc = (0,
|
|
2229
|
-
const history = (0,
|
|
2230
|
-
const [snapshot, setSnapshot] = (0,
|
|
2231
|
-
const [selection, setSelectionState] = (0,
|
|
2232
|
-
() => (0,
|
|
2802
|
+
const doc = (0, import_react13.useMemo)(() => opts.document ?? new import_core5.EditorDocument(), [opts.document]);
|
|
2803
|
+
const history = (0, import_react13.useMemo)(() => new import_core5.EditorHistory(doc), [doc]);
|
|
2804
|
+
const [snapshot, setSnapshot] = (0, import_react13.useState)(() => doc.toJSON());
|
|
2805
|
+
const [selection, setSelectionState] = (0, import_react13.useState)(
|
|
2806
|
+
() => (0, import_core5.collapsedSelection)({ blockIndex: 0, offset: 0 })
|
|
2233
2807
|
);
|
|
2234
|
-
const selectionRef = (0,
|
|
2808
|
+
const selectionRef = (0, import_react13.useRef)(selection);
|
|
2235
2809
|
selectionRef.current = selection;
|
|
2236
|
-
const pendingMarksRef = (0,
|
|
2237
|
-
const [pendingMarks, setPendingMarksState] = (0,
|
|
2238
|
-
const setPendingMarks = (0,
|
|
2810
|
+
const pendingMarksRef = (0, import_react13.useRef)({});
|
|
2811
|
+
const [pendingMarks, setPendingMarksState] = (0, import_react13.useState)({});
|
|
2812
|
+
const setPendingMarks = (0, import_react13.useCallback)((next) => {
|
|
2239
2813
|
pendingMarksRef.current = next;
|
|
2240
2814
|
setPendingMarksState(next);
|
|
2241
2815
|
}, []);
|
|
2242
|
-
(0,
|
|
2816
|
+
(0, import_react13.useEffect)(() => {
|
|
2243
2817
|
let scheduled = false;
|
|
2244
2818
|
let cancelled = false;
|
|
2245
2819
|
let frame = 0;
|
|
@@ -2266,8 +2840,8 @@ function useEditor(opts = {}) {
|
|
|
2266
2840
|
doc.ydoc.off("afterTransaction", schedule);
|
|
2267
2841
|
};
|
|
2268
2842
|
}, [doc]);
|
|
2269
|
-
const getSelection = (0,
|
|
2270
|
-
const setSelection = (0,
|
|
2843
|
+
const getSelection = (0, import_react13.useCallback)(() => selectionRef.current, []);
|
|
2844
|
+
const setSelection = (0, import_react13.useCallback)(
|
|
2271
2845
|
(sel) => {
|
|
2272
2846
|
const prev = selectionRef.current;
|
|
2273
2847
|
selectionRef.current = sel;
|
|
@@ -2282,19 +2856,19 @@ function useEditor(opts = {}) {
|
|
|
2282
2856
|
},
|
|
2283
2857
|
[]
|
|
2284
2858
|
);
|
|
2285
|
-
const ctxRef = (0,
|
|
2859
|
+
const ctxRef = (0, import_react13.useRef)({ doc, getSelection, setSelection });
|
|
2286
2860
|
ctxRef.current = { doc, getSelection, setSelection };
|
|
2287
|
-
const consumePendingMarks = (0,
|
|
2861
|
+
const consumePendingMarks = (0, import_react13.useCallback)(() => {
|
|
2288
2862
|
const current = pendingMarksRef.current;
|
|
2289
2863
|
if (Object.keys(current).length === 0) return void 0;
|
|
2290
2864
|
pendingMarksRef.current = {};
|
|
2291
2865
|
setPendingMarksState({});
|
|
2292
2866
|
return current;
|
|
2293
2867
|
}, []);
|
|
2294
|
-
const isMarkActive = (0,
|
|
2868
|
+
const isMarkActive = (0, import_react13.useCallback)(
|
|
2295
2869
|
(name, value) => {
|
|
2296
2870
|
const sel = selectionRef.current;
|
|
2297
|
-
const { start, end } = (0,
|
|
2871
|
+
const { start, end } = (0, import_core5.orderedRange)(sel);
|
|
2298
2872
|
if (start.blockIndex === end.blockIndex && start.offset === end.offset) {
|
|
2299
2873
|
const pending = pendingMarksRef.current[name];
|
|
2300
2874
|
if (pending !== void 0) {
|
|
@@ -2303,7 +2877,7 @@ function useEditor(opts = {}) {
|
|
|
2303
2877
|
}
|
|
2304
2878
|
const yText2 = doc.getBlockText(start.blockIndex);
|
|
2305
2879
|
if (!yText2 || start.offset === 0) return false;
|
|
2306
|
-
return (0,
|
|
2880
|
+
return (0, import_core5.isMarkUniformInRange)(yText2, start.offset - 1, start.offset, name, value);
|
|
2307
2881
|
}
|
|
2308
2882
|
if (start.blockIndex !== end.blockIndex) {
|
|
2309
2883
|
for (let i = start.blockIndex; i <= end.blockIndex; i++) {
|
|
@@ -2312,19 +2886,19 @@ function useEditor(opts = {}) {
|
|
|
2312
2886
|
const s = i === start.blockIndex ? start.offset : 0;
|
|
2313
2887
|
const e = i === end.blockIndex ? end.offset : yText2.length;
|
|
2314
2888
|
if (s >= e) continue;
|
|
2315
|
-
if (!(0,
|
|
2889
|
+
if (!(0, import_core5.isMarkUniformInRange)(yText2, s, e, name, value)) return false;
|
|
2316
2890
|
}
|
|
2317
2891
|
return true;
|
|
2318
2892
|
}
|
|
2319
2893
|
const yText = doc.getBlockText(start.blockIndex);
|
|
2320
2894
|
if (!yText) return false;
|
|
2321
|
-
return (0,
|
|
2895
|
+
return (0, import_core5.isMarkUniformInRange)(yText, start.offset, end.offset, name, value);
|
|
2322
2896
|
},
|
|
2323
2897
|
[doc]
|
|
2324
2898
|
);
|
|
2325
|
-
const getActiveMarks = (0,
|
|
2899
|
+
const getActiveMarks = (0, import_react13.useCallback)(() => {
|
|
2326
2900
|
const sel = selectionRef.current;
|
|
2327
|
-
const { start, end } = (0,
|
|
2901
|
+
const { start, end } = (0, import_core5.orderedRange)(sel);
|
|
2328
2902
|
if (start.blockIndex !== end.blockIndex) {
|
|
2329
2903
|
return {};
|
|
2330
2904
|
}
|
|
@@ -2332,14 +2906,14 @@ function useEditor(opts = {}) {
|
|
|
2332
2906
|
if (!yText) return {};
|
|
2333
2907
|
if (start.offset === end.offset) {
|
|
2334
2908
|
if (start.offset === 0) return {};
|
|
2335
|
-
return (0,
|
|
2909
|
+
return (0, import_core5.getMarksInRange)(yText, start.offset - 1, start.offset);
|
|
2336
2910
|
}
|
|
2337
|
-
return (0,
|
|
2911
|
+
return (0, import_core5.getMarksInRange)(yText, start.offset, end.offset);
|
|
2338
2912
|
}, [doc]);
|
|
2339
|
-
const toggleMark = (0,
|
|
2913
|
+
const toggleMark = (0, import_react13.useCallback)(
|
|
2340
2914
|
(name, value) => {
|
|
2341
2915
|
const sel = selectionRef.current;
|
|
2342
|
-
const { start, end } = (0,
|
|
2916
|
+
const { start, end } = (0, import_core5.orderedRange)(sel);
|
|
2343
2917
|
const isCollapsed = start.blockIndex === end.blockIndex && start.offset === end.offset;
|
|
2344
2918
|
if (isCollapsed) {
|
|
2345
2919
|
const next = { ...pendingMarksRef.current };
|
|
@@ -2352,39 +2926,39 @@ function useEditor(opts = {}) {
|
|
|
2352
2926
|
setPendingMarks(next);
|
|
2353
2927
|
return;
|
|
2354
2928
|
}
|
|
2355
|
-
(0,
|
|
2929
|
+
(0, import_core5.toggleMark)(ctxRef.current, name, value);
|
|
2356
2930
|
},
|
|
2357
2931
|
[isMarkActive, setPendingMarks]
|
|
2358
2932
|
);
|
|
2359
|
-
const setMark = (0,
|
|
2933
|
+
const setMark = (0, import_react13.useCallback)(
|
|
2360
2934
|
(name, value) => {
|
|
2361
2935
|
const sel = selectionRef.current;
|
|
2362
|
-
const { start, end } = (0,
|
|
2936
|
+
const { start, end } = (0, import_core5.orderedRange)(sel);
|
|
2363
2937
|
const isCollapsed = start.blockIndex === end.blockIndex && start.offset === end.offset;
|
|
2364
2938
|
if (isCollapsed) {
|
|
2365
2939
|
setPendingMarks({ ...pendingMarksRef.current, [name]: value });
|
|
2366
2940
|
return;
|
|
2367
2941
|
}
|
|
2368
|
-
(0,
|
|
2942
|
+
(0, import_core5.setMark)(ctxRef.current, name, value);
|
|
2369
2943
|
},
|
|
2370
2944
|
[setPendingMarks]
|
|
2371
2945
|
);
|
|
2372
|
-
const removeMark = (0,
|
|
2946
|
+
const removeMark = (0, import_react13.useCallback)(
|
|
2373
2947
|
(name) => {
|
|
2374
2948
|
const sel = selectionRef.current;
|
|
2375
|
-
const { start, end } = (0,
|
|
2949
|
+
const { start, end } = (0, import_core5.orderedRange)(sel);
|
|
2376
2950
|
const isCollapsed = start.blockIndex === end.blockIndex && start.offset === end.offset;
|
|
2377
2951
|
if (isCollapsed) {
|
|
2378
2952
|
setPendingMarks({ ...pendingMarksRef.current, [name]: null });
|
|
2379
2953
|
return;
|
|
2380
2954
|
}
|
|
2381
|
-
(0,
|
|
2955
|
+
(0, import_core5.removeMark)(ctxRef.current, name);
|
|
2382
2956
|
},
|
|
2383
2957
|
[setPendingMarks]
|
|
2384
2958
|
);
|
|
2385
|
-
const getBlockType = (0,
|
|
2959
|
+
const getBlockType = (0, import_react13.useCallback)(() => {
|
|
2386
2960
|
const sel = selectionRef.current;
|
|
2387
|
-
const { start, end } = (0,
|
|
2961
|
+
const { start, end } = (0, import_core5.orderedRange)(sel);
|
|
2388
2962
|
const first = doc.getBlockType(start.blockIndex);
|
|
2389
2963
|
if (first === void 0) return "paragraph";
|
|
2390
2964
|
for (let i = start.blockIndex + 1; i <= end.blockIndex; i++) {
|
|
@@ -2392,10 +2966,10 @@ function useEditor(opts = {}) {
|
|
|
2392
2966
|
}
|
|
2393
2967
|
return first;
|
|
2394
2968
|
}, [doc]);
|
|
2395
|
-
const getBlockAttr = (0,
|
|
2969
|
+
const getBlockAttr = (0, import_react13.useCallback)(
|
|
2396
2970
|
(key) => {
|
|
2397
2971
|
const sel = selectionRef.current;
|
|
2398
|
-
const { start, end } = (0,
|
|
2972
|
+
const { start, end } = (0, import_core5.orderedRange)(sel);
|
|
2399
2973
|
const first = doc.getBlockAttrs(start.blockIndex)[key];
|
|
2400
2974
|
for (let i = start.blockIndex + 1; i <= end.blockIndex; i++) {
|
|
2401
2975
|
const next = doc.getBlockAttrs(i)[key];
|
|
@@ -2405,19 +2979,32 @@ function useEditor(opts = {}) {
|
|
|
2405
2979
|
},
|
|
2406
2980
|
[doc]
|
|
2407
2981
|
);
|
|
2408
|
-
const setBlockType = (0,
|
|
2409
|
-
(0,
|
|
2982
|
+
const setBlockType = (0, import_react13.useCallback)((type, attrs) => {
|
|
2983
|
+
(0, import_core5.setBlockType)(ctxRef.current, type, attrs);
|
|
2410
2984
|
}, []);
|
|
2411
|
-
const setBlockAttr = (0,
|
|
2985
|
+
const setBlockAttr = (0, import_react13.useCallback)(
|
|
2412
2986
|
(key, value) => {
|
|
2413
|
-
(0,
|
|
2987
|
+
(0, import_core5.setBlockAttr)(ctxRef.current, key, value);
|
|
2414
2988
|
},
|
|
2415
2989
|
[]
|
|
2416
2990
|
);
|
|
2417
|
-
const
|
|
2991
|
+
const setAlign = (0, import_react13.useCallback)((value) => {
|
|
2992
|
+
const sel = selectionRef.current;
|
|
2993
|
+
const inCell = sel.focus.cellIndex != null;
|
|
2994
|
+
if (inCell) (0, import_core5.setCellAttr)(ctxRef.current, "align", value);
|
|
2995
|
+
else (0, import_core5.setBlockAttr)(ctxRef.current, "align", value);
|
|
2996
|
+
}, []);
|
|
2997
|
+
const getAlign = (0, import_react13.useCallback)(() => {
|
|
2998
|
+
const sel = selectionRef.current;
|
|
2999
|
+
if (sel.focus.cellIndex != null && doc.isTable(sel.focus.blockIndex)) {
|
|
3000
|
+
return doc.getCellAttrs(sel.focus.blockIndex, sel.focus.cellIndex).align;
|
|
3001
|
+
}
|
|
3002
|
+
return getBlockAttr("align");
|
|
3003
|
+
}, [doc, getBlockAttr]);
|
|
3004
|
+
const isListActive = (0, import_react13.useCallback)(
|
|
2418
3005
|
(kind) => {
|
|
2419
3006
|
const sel = selectionRef.current;
|
|
2420
|
-
const { start, end } = (0,
|
|
3007
|
+
const { start, end } = (0, import_core5.orderedRange)(sel);
|
|
2421
3008
|
for (let i = start.blockIndex; i <= end.blockIndex; i++) {
|
|
2422
3009
|
if (doc.getBlockType(i) !== "listItem") return false;
|
|
2423
3010
|
if (doc.getBlockAttrs(i).listKind !== kind) return false;
|
|
@@ -2426,110 +3013,116 @@ function useEditor(opts = {}) {
|
|
|
2426
3013
|
},
|
|
2427
3014
|
[doc]
|
|
2428
3015
|
);
|
|
2429
|
-
const toggleList = (0,
|
|
2430
|
-
(0,
|
|
3016
|
+
const toggleList = (0, import_react13.useCallback)((kind) => {
|
|
3017
|
+
(0, import_core5.toggleList)(ctxRef.current, kind);
|
|
2431
3018
|
}, []);
|
|
2432
|
-
const indentList = (0,
|
|
2433
|
-
(0,
|
|
3019
|
+
const indentList = (0, import_react13.useCallback)(() => {
|
|
3020
|
+
(0, import_core5.indentList)(ctxRef.current);
|
|
2434
3021
|
}, []);
|
|
2435
|
-
const dedentList = (0,
|
|
2436
|
-
(0,
|
|
3022
|
+
const dedentList = (0, import_react13.useCallback)(() => {
|
|
3023
|
+
(0, import_core5.dedentList)(ctxRef.current);
|
|
2437
3024
|
}, []);
|
|
2438
|
-
const splitListItem = (0,
|
|
2439
|
-
return (0,
|
|
3025
|
+
const splitListItem = (0, import_react13.useCallback)(() => {
|
|
3026
|
+
return (0, import_core5.splitListItem)(ctxRef.current);
|
|
2440
3027
|
}, []);
|
|
2441
|
-
const isInTable = (0,
|
|
3028
|
+
const isInTable = (0, import_react13.useCallback)(() => {
|
|
2442
3029
|
return selectionRef.current.focus.cellIndex != null;
|
|
2443
3030
|
}, []);
|
|
2444
|
-
const getTableLocation = (0,
|
|
2445
|
-
return (0,
|
|
3031
|
+
const getTableLocation = (0, import_react13.useCallback)(() => {
|
|
3032
|
+
return (0, import_core5.tableLocationOf)(doc, selectionRef.current.focus);
|
|
2446
3033
|
}, [doc]);
|
|
2447
|
-
const insertTable = (0,
|
|
2448
|
-
(0,
|
|
3034
|
+
const insertTable = (0, import_react13.useCallback)((rows, cols) => {
|
|
3035
|
+
(0, import_core5.insertTable)(ctxRef.current, rows, cols);
|
|
2449
3036
|
}, []);
|
|
2450
|
-
const deleteTable = (0,
|
|
3037
|
+
const deleteTable = (0, import_react13.useCallback)((blockIndex) => {
|
|
2451
3038
|
const idx = blockIndex ?? selectionRef.current.focus.blockIndex;
|
|
2452
|
-
(0,
|
|
3039
|
+
(0, import_core5.deleteTable)(ctxRef.current, idx);
|
|
2453
3040
|
}, []);
|
|
2454
|
-
const insertRowAbove = (0,
|
|
2455
|
-
const loc = (0,
|
|
3041
|
+
const insertRowAbove = (0, import_react13.useCallback)(() => {
|
|
3042
|
+
const loc = (0, import_core5.tableLocationOf)(doc, selectionRef.current.focus);
|
|
2456
3043
|
if (!loc) return;
|
|
2457
|
-
(0,
|
|
3044
|
+
(0, import_core5.insertTableRow)(ctxRef.current, loc.blockIndex, loc.row, "before");
|
|
2458
3045
|
}, [doc]);
|
|
2459
|
-
const insertRowBelow = (0,
|
|
2460
|
-
const loc = (0,
|
|
3046
|
+
const insertRowBelow = (0, import_react13.useCallback)(() => {
|
|
3047
|
+
const loc = (0, import_core5.tableLocationOf)(doc, selectionRef.current.focus);
|
|
2461
3048
|
if (!loc) return;
|
|
2462
|
-
(0,
|
|
3049
|
+
(0, import_core5.insertTableRow)(ctxRef.current, loc.blockIndex, loc.row, "after");
|
|
2463
3050
|
}, [doc]);
|
|
2464
|
-
const deleteCurrentRow = (0,
|
|
2465
|
-
const loc = (0,
|
|
3051
|
+
const deleteCurrentRow = (0, import_react13.useCallback)(() => {
|
|
3052
|
+
const loc = (0, import_core5.tableLocationOf)(doc, selectionRef.current.focus);
|
|
2466
3053
|
if (!loc) return;
|
|
2467
|
-
(0,
|
|
3054
|
+
(0, import_core5.deleteTableRow)(ctxRef.current, loc.blockIndex, loc.row);
|
|
2468
3055
|
}, [doc]);
|
|
2469
|
-
const insertColumnLeft = (0,
|
|
2470
|
-
const loc = (0,
|
|
3056
|
+
const insertColumnLeft = (0, import_react13.useCallback)(() => {
|
|
3057
|
+
const loc = (0, import_core5.tableLocationOf)(doc, selectionRef.current.focus);
|
|
2471
3058
|
if (!loc) return;
|
|
2472
|
-
(0,
|
|
3059
|
+
(0, import_core5.insertTableColumn)(ctxRef.current, loc.blockIndex, loc.col, "before");
|
|
2473
3060
|
}, [doc]);
|
|
2474
|
-
const insertColumnRight = (0,
|
|
2475
|
-
const loc = (0,
|
|
3061
|
+
const insertColumnRight = (0, import_react13.useCallback)(() => {
|
|
3062
|
+
const loc = (0, import_core5.tableLocationOf)(doc, selectionRef.current.focus);
|
|
2476
3063
|
if (!loc) return;
|
|
2477
|
-
(0,
|
|
3064
|
+
(0, import_core5.insertTableColumn)(ctxRef.current, loc.blockIndex, loc.col, "after");
|
|
2478
3065
|
}, [doc]);
|
|
2479
|
-
const deleteCurrentColumn = (0,
|
|
2480
|
-
const loc = (0,
|
|
3066
|
+
const deleteCurrentColumn = (0, import_react13.useCallback)(() => {
|
|
3067
|
+
const loc = (0, import_core5.tableLocationOf)(doc, selectionRef.current.focus);
|
|
2481
3068
|
if (!loc) return;
|
|
2482
|
-
(0,
|
|
3069
|
+
(0, import_core5.deleteTableColumn)(ctxRef.current, loc.blockIndex, loc.col);
|
|
2483
3070
|
}, [doc]);
|
|
2484
|
-
const moveToNextCell = (0,
|
|
2485
|
-
(0,
|
|
3071
|
+
const moveToNextCell = (0, import_react13.useCallback)(() => {
|
|
3072
|
+
(0, import_core5.moveToNextCell)(ctxRef.current);
|
|
2486
3073
|
}, []);
|
|
2487
|
-
const moveToPrevCell = (0,
|
|
2488
|
-
(0,
|
|
3074
|
+
const moveToPrevCell = (0, import_react13.useCallback)(() => {
|
|
3075
|
+
(0, import_core5.moveToPrevCell)(ctxRef.current);
|
|
2489
3076
|
}, []);
|
|
2490
|
-
const mergeRight = (0,
|
|
2491
|
-
const loc = (0,
|
|
3077
|
+
const mergeRight = (0, import_react13.useCallback)(() => {
|
|
3078
|
+
const loc = (0, import_core5.tableLocationOf)(doc, selectionRef.current.focus);
|
|
2492
3079
|
if (!loc) return false;
|
|
2493
|
-
return (0,
|
|
3080
|
+
return (0, import_core5.mergeRight)(ctxRef.current, loc.blockIndex, loc.row, loc.col);
|
|
2494
3081
|
}, [doc]);
|
|
2495
|
-
const mergeDown = (0,
|
|
2496
|
-
const loc = (0,
|
|
3082
|
+
const mergeDown = (0, import_react13.useCallback)(() => {
|
|
3083
|
+
const loc = (0, import_core5.tableLocationOf)(doc, selectionRef.current.focus);
|
|
2497
3084
|
if (!loc) return false;
|
|
2498
|
-
return (0,
|
|
3085
|
+
return (0, import_core5.mergeDown)(ctxRef.current, loc.blockIndex, loc.row, loc.col);
|
|
2499
3086
|
}, [doc]);
|
|
2500
|
-
const splitCell = (0,
|
|
2501
|
-
const loc = (0,
|
|
3087
|
+
const splitCell = (0, import_react13.useCallback)(() => {
|
|
3088
|
+
const loc = (0, import_core5.tableLocationOf)(doc, selectionRef.current.focus);
|
|
2502
3089
|
if (!loc) return false;
|
|
2503
|
-
return (0,
|
|
3090
|
+
return (0, import_core5.splitCell)(ctxRef.current, loc.blockIndex, loc.row, loc.col);
|
|
2504
3091
|
}, [doc]);
|
|
2505
|
-
const setColumnWidth = (0,
|
|
3092
|
+
const setColumnWidth = (0, import_react13.useCallback)(
|
|
2506
3093
|
(blockIndex, col, widthPx) => {
|
|
2507
|
-
(0,
|
|
3094
|
+
(0, import_core5.setColumnWidth)(ctxRef.current, blockIndex, col, widthPx);
|
|
2508
3095
|
},
|
|
2509
3096
|
[]
|
|
2510
3097
|
);
|
|
2511
|
-
const getTableRect = (0,
|
|
2512
|
-
() => (0,
|
|
3098
|
+
const getTableRect = (0, import_react13.useCallback)(
|
|
3099
|
+
() => (0, import_core5.tableRectSelection)(doc, selectionRef.current),
|
|
2513
3100
|
[doc]
|
|
2514
3101
|
);
|
|
2515
|
-
const hasTableRectSelection = (0,
|
|
2516
|
-
return (0,
|
|
3102
|
+
const hasTableRectSelection = (0, import_react13.useCallback)(() => {
|
|
3103
|
+
return (0, import_core5.tableRectSelection)(doc, selectionRef.current) !== null;
|
|
2517
3104
|
}, [doc]);
|
|
2518
|
-
const mergeSelection = (0,
|
|
2519
|
-
return (0,
|
|
3105
|
+
const mergeSelection = (0, import_react13.useCallback)(() => {
|
|
3106
|
+
return (0, import_core5.mergeSelection)(ctxRef.current);
|
|
2520
3107
|
}, []);
|
|
2521
|
-
const insertImage = (0,
|
|
2522
|
-
(0,
|
|
3108
|
+
const insertImage = (0, import_react13.useCallback)((embed) => {
|
|
3109
|
+
(0, import_core5.insertImage)(ctxRef.current, embed);
|
|
2523
3110
|
}, []);
|
|
2524
|
-
const setImageAttrs = (0,
|
|
3111
|
+
const setImageAttrs = (0, import_react13.useCallback)(
|
|
2525
3112
|
(blockIndex, offset, partial, cellIndex, newOffset) => {
|
|
2526
|
-
(0,
|
|
3113
|
+
(0, import_core5.setImageAttrs)(ctxRef.current, blockIndex, offset, partial, cellIndex, newOffset);
|
|
2527
3114
|
},
|
|
2528
3115
|
[]
|
|
2529
3116
|
);
|
|
2530
|
-
const
|
|
3117
|
+
const moveEmbedAnchor = (0, import_react13.useCallback)(
|
|
3118
|
+
(from, to, newOffsetX, newOffsetY) => {
|
|
3119
|
+
(0, import_core5.moveEmbedAnchor)(ctxRef.current, from, to, newOffsetX, newOffsetY);
|
|
3120
|
+
},
|
|
3121
|
+
[]
|
|
3122
|
+
);
|
|
3123
|
+
const uploadImageRef = (0, import_react13.useRef)(opts.uploadImage);
|
|
2531
3124
|
uploadImageRef.current = opts.uploadImage;
|
|
2532
|
-
const insertImageFromFile = (0,
|
|
3125
|
+
const insertImageFromFile = (0, import_react13.useCallback)(async (file) => {
|
|
2533
3126
|
if (!file.type.startsWith("image/")) return;
|
|
2534
3127
|
const dataUrl = await readAsDataURL(file);
|
|
2535
3128
|
const dims = await readImageDimensions(dataUrl);
|
|
@@ -2541,9 +3134,9 @@ function useEditor(opts = {}) {
|
|
|
2541
3134
|
}
|
|
2542
3135
|
const upload = uploadImageRef.current;
|
|
2543
3136
|
const src = upload ? await upload(file) : dataUrl;
|
|
2544
|
-
(0,
|
|
3137
|
+
(0, import_core5.insertImage)(ctxRef.current, { type: "image", src, width: w, height: h });
|
|
2545
3138
|
}, []);
|
|
2546
|
-
const getSelectedEmbed = (0,
|
|
3139
|
+
const getSelectedEmbed = (0, import_react13.useCallback)(() => {
|
|
2547
3140
|
const sel = selectionRef.current;
|
|
2548
3141
|
if (sel.anchor.blockIndex !== sel.focus.blockIndex) return null;
|
|
2549
3142
|
if ((sel.anchor.cellIndex ?? -1) !== (sel.focus.cellIndex ?? -1)) return null;
|
|
@@ -2560,7 +3153,7 @@ function useEditor(opts = {}) {
|
|
|
2560
3153
|
cursor += op.insert.length;
|
|
2561
3154
|
continue;
|
|
2562
3155
|
}
|
|
2563
|
-
if (cursor === start && (0,
|
|
3156
|
+
if (cursor === start && (0, import_core5.isImageEmbed)(op.insert)) {
|
|
2564
3157
|
return {
|
|
2565
3158
|
blockIndex: sel.anchor.blockIndex,
|
|
2566
3159
|
cellIndex: sel.anchor.cellIndex,
|
|
@@ -2572,39 +3165,48 @@ function useEditor(opts = {}) {
|
|
|
2572
3165
|
}
|
|
2573
3166
|
return null;
|
|
2574
3167
|
}, [doc]);
|
|
2575
|
-
const [linkRequest, setLinkRequest] = (0,
|
|
2576
|
-
const
|
|
3168
|
+
const [linkRequest, setLinkRequest] = (0, import_react13.useState)(null);
|
|
3169
|
+
const linkRequestRef = (0, import_react13.useRef)(null);
|
|
3170
|
+
const requestLink = (0, import_react13.useCallback)((initialHref = "") => {
|
|
2577
3171
|
return new Promise((resolve) => {
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
const resolveLinkRequest = (0, import_react11.useCallback)((href) => {
|
|
2582
|
-
setLinkRequest((prev) => {
|
|
2583
|
-
if (prev) prev.resolve(href);
|
|
2584
|
-
return null;
|
|
3172
|
+
const req = { initialHref, resolve, selection: selectionRef.current };
|
|
3173
|
+
linkRequestRef.current = req;
|
|
3174
|
+
setLinkRequest(req);
|
|
2585
3175
|
});
|
|
2586
3176
|
}, []);
|
|
3177
|
+
const resolveLinkRequest = (0, import_react13.useCallback)(
|
|
3178
|
+
(href) => {
|
|
3179
|
+
const req = linkRequestRef.current;
|
|
3180
|
+
linkRequestRef.current = null;
|
|
3181
|
+
setLinkRequest(null);
|
|
3182
|
+
if (req) {
|
|
3183
|
+
setSelection(req.selection);
|
|
3184
|
+
req.resolve(href);
|
|
3185
|
+
}
|
|
3186
|
+
},
|
|
3187
|
+
[setSelection]
|
|
3188
|
+
);
|
|
2587
3189
|
const pageSettings = usePageSettings(doc);
|
|
2588
|
-
const setPageSettings = (0,
|
|
3190
|
+
const setPageSettings = (0, import_react13.useCallback)(
|
|
2589
3191
|
(partial) => {
|
|
2590
3192
|
doc.setPageSettings(partial);
|
|
2591
3193
|
},
|
|
2592
3194
|
[doc]
|
|
2593
3195
|
);
|
|
2594
|
-
const [pageConfigRequest, setPageConfigRequest] = (0,
|
|
2595
|
-
const requestPageConfig = (0,
|
|
3196
|
+
const [pageConfigRequest, setPageConfigRequest] = (0, import_react13.useState)(null);
|
|
3197
|
+
const requestPageConfig = (0, import_react13.useCallback)(() => {
|
|
2596
3198
|
return new Promise((resolve) => {
|
|
2597
3199
|
setPageConfigRequest({ initial: doc.getPageSettings(), resolve });
|
|
2598
3200
|
});
|
|
2599
3201
|
}, [doc]);
|
|
2600
|
-
const resolvePageConfigRequest = (0,
|
|
3202
|
+
const resolvePageConfigRequest = (0, import_react13.useCallback)((applied) => {
|
|
2601
3203
|
setPageConfigRequest((prev) => {
|
|
2602
3204
|
if (prev) prev.resolve(applied);
|
|
2603
3205
|
return null;
|
|
2604
3206
|
});
|
|
2605
3207
|
}, []);
|
|
2606
|
-
const [imageCaptionRequest, setImageCaptionRequest] = (0,
|
|
2607
|
-
const requestImageCaption = (0,
|
|
3208
|
+
const [imageCaptionRequest, setImageCaptionRequest] = (0, import_react13.useState)(null);
|
|
3209
|
+
const requestImageCaption = (0, import_react13.useCallback)(
|
|
2608
3210
|
(initialCaption = "", initialAlign = "center") => {
|
|
2609
3211
|
return new Promise((resolve) => {
|
|
2610
3212
|
setImageCaptionRequest({ initialCaption, initialAlign, resolve });
|
|
@@ -2612,7 +3214,7 @@ function useEditor(opts = {}) {
|
|
|
2612
3214
|
},
|
|
2613
3215
|
[]
|
|
2614
3216
|
);
|
|
2615
|
-
const resolveImageCaptionRequest = (0,
|
|
3217
|
+
const resolveImageCaptionRequest = (0, import_react13.useCallback)((result) => {
|
|
2616
3218
|
setImageCaptionRequest((prev) => {
|
|
2617
3219
|
if (prev) prev.resolve(result);
|
|
2618
3220
|
return null;
|
|
@@ -2636,6 +3238,8 @@ function useEditor(opts = {}) {
|
|
|
2636
3238
|
getBlockAttr,
|
|
2637
3239
|
setBlockType,
|
|
2638
3240
|
setBlockAttr,
|
|
3241
|
+
setAlign,
|
|
3242
|
+
getAlign,
|
|
2639
3243
|
isListActive,
|
|
2640
3244
|
toggleList,
|
|
2641
3245
|
indentList,
|
|
@@ -2665,6 +3269,7 @@ function useEditor(opts = {}) {
|
|
|
2665
3269
|
mergeSelection,
|
|
2666
3270
|
insertImage,
|
|
2667
3271
|
setImageAttrs,
|
|
3272
|
+
moveEmbedAnchor,
|
|
2668
3273
|
insertImageFromFile,
|
|
2669
3274
|
getSelectedEmbed,
|
|
2670
3275
|
pageSettings,
|
|
@@ -2706,54 +3311,99 @@ function sameValue(a, b) {
|
|
|
2706
3311
|
}
|
|
2707
3312
|
|
|
2708
3313
|
// src/Editor.tsx
|
|
2709
|
-
var
|
|
3314
|
+
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
2710
3315
|
var defaultFooter = ({ pageNumber, pageCount }) => `${pageNumber} / ${pageCount}`;
|
|
2711
3316
|
function Editor({
|
|
2712
3317
|
editor: providedEditor,
|
|
2713
3318
|
className,
|
|
2714
3319
|
pageGeometry,
|
|
2715
3320
|
renderPageHeader,
|
|
2716
|
-
renderPageFooter = defaultFooter
|
|
3321
|
+
renderPageFooter = defaultFooter,
|
|
3322
|
+
awareness
|
|
2717
3323
|
}) {
|
|
2718
3324
|
const internal = useEditor();
|
|
2719
3325
|
const editor = providedEditor ?? internal;
|
|
2720
3326
|
const { doc, history, snapshot, getSelection, setSelection } = editor;
|
|
2721
|
-
const rootRef = (0,
|
|
2722
|
-
const isComposingRef = (0,
|
|
2723
|
-
const
|
|
2724
|
-
const
|
|
3327
|
+
const rootRef = (0, import_react14.useRef)(null);
|
|
3328
|
+
const isComposingRef = (0, import_react14.useRef)(false);
|
|
3329
|
+
const [hoveredBehind, setHoveredBehind] = (0, import_react14.useState)(null);
|
|
3330
|
+
const hoveredBehindRef = (0, import_react14.useRef)(null);
|
|
3331
|
+
const [hoveredLink, setHoveredLink] = (0, import_react14.useState)(null);
|
|
3332
|
+
const hoveredLinkElRef = (0, import_react14.useRef)(null);
|
|
3333
|
+
const suppressSelectionSyncRef = (0, import_react14.useRef)(false);
|
|
3334
|
+
(0, import_react14.useEffect)(() => {
|
|
3335
|
+
if (!awareness) return;
|
|
3336
|
+
const root = rootRef.current;
|
|
3337
|
+
if (!root) return;
|
|
3338
|
+
let raf = null;
|
|
3339
|
+
const publish = () => {
|
|
3340
|
+
raf = null;
|
|
3341
|
+
const sel = readDomSelection(root);
|
|
3342
|
+
awareness.setLocalStateField(
|
|
3343
|
+
"cursor",
|
|
3344
|
+
sel ? (0, import_core6.encodeSelection)(doc, sel) ?? null : null
|
|
3345
|
+
);
|
|
3346
|
+
};
|
|
3347
|
+
const onSelChange = () => {
|
|
3348
|
+
const s = document.getSelection();
|
|
3349
|
+
if (!s || s.rangeCount === 0) return;
|
|
3350
|
+
if (s.anchorNode && !root.contains(s.anchorNode)) return;
|
|
3351
|
+
if (raf != null) return;
|
|
3352
|
+
raf = requestAnimationFrame(publish);
|
|
3353
|
+
};
|
|
3354
|
+
const onBlur = () => awareness.setLocalStateField("cursor", null);
|
|
3355
|
+
document.addEventListener("selectionchange", onSelChange);
|
|
3356
|
+
root.addEventListener("blur", onBlur, true);
|
|
3357
|
+
return () => {
|
|
3358
|
+
document.removeEventListener("selectionchange", onSelChange);
|
|
3359
|
+
root.removeEventListener("blur", onBlur, true);
|
|
3360
|
+
if (raf != null) cancelAnimationFrame(raf);
|
|
3361
|
+
awareness.setLocalStateField("cursor", null);
|
|
3362
|
+
};
|
|
3363
|
+
}, [awareness, doc]);
|
|
3364
|
+
const ctxRef = (0, import_react14.useRef)({ doc, getSelection, setSelection });
|
|
2725
3365
|
ctxRef.current = { doc, getSelection, setSelection };
|
|
2726
|
-
const historyRef = (0,
|
|
3366
|
+
const historyRef = (0, import_react14.useRef)(history);
|
|
2727
3367
|
historyRef.current = history;
|
|
2728
|
-
const editorRef = (0,
|
|
3368
|
+
const editorRef = (0, import_react14.useRef)(editor);
|
|
2729
3369
|
editorRef.current = editor;
|
|
2730
|
-
(0,
|
|
3370
|
+
(0, import_react14.useLayoutEffect)(() => {
|
|
2731
3371
|
const root = rootRef.current;
|
|
2732
3372
|
if (!root) return;
|
|
2733
3373
|
if (isComposingRef.current) return;
|
|
2734
3374
|
if (document.activeElement !== root) return;
|
|
2735
3375
|
const current = readDomSelection(root);
|
|
2736
3376
|
if (current && selectionsEqual(current, editor.selection)) return;
|
|
3377
|
+
if (isTableRectSelection(editor.selection)) {
|
|
3378
|
+
applyDomSelection(root, editor.selection);
|
|
3379
|
+
suppressSelectionSyncRef.current = false;
|
|
3380
|
+
return;
|
|
3381
|
+
}
|
|
2737
3382
|
suppressSelectionSyncRef.current = true;
|
|
2738
3383
|
applyDomSelection(root, editor.selection);
|
|
2739
|
-
queueMicrotask(() => {
|
|
2740
|
-
suppressSelectionSyncRef.current = false;
|
|
2741
|
-
});
|
|
2742
3384
|
});
|
|
2743
|
-
(0,
|
|
3385
|
+
(0, import_react14.useEffect)(() => {
|
|
2744
3386
|
const root = rootRef.current;
|
|
2745
3387
|
if (!root) return;
|
|
2746
3388
|
const handler = () => {
|
|
2747
|
-
if (suppressSelectionSyncRef.current) return;
|
|
2748
3389
|
if (isComposingRef.current) return;
|
|
2749
|
-
if (document.activeElement !== root)
|
|
3390
|
+
if (document.activeElement !== root) {
|
|
3391
|
+
suppressSelectionSyncRef.current = false;
|
|
3392
|
+
return;
|
|
3393
|
+
}
|
|
2750
3394
|
const modelSel = readDomSelection(root);
|
|
3395
|
+
if (suppressSelectionSyncRef.current) {
|
|
3396
|
+
if (modelSel && selectionsEqual(modelSel, editorRef.current.getSelection())) {
|
|
3397
|
+
suppressSelectionSyncRef.current = false;
|
|
3398
|
+
}
|
|
3399
|
+
return;
|
|
3400
|
+
}
|
|
2751
3401
|
if (modelSel) setSelection(modelSel);
|
|
2752
3402
|
};
|
|
2753
3403
|
document.addEventListener("selectionchange", handler);
|
|
2754
3404
|
return () => document.removeEventListener("selectionchange", handler);
|
|
2755
3405
|
}, [setSelection]);
|
|
2756
|
-
(0,
|
|
3406
|
+
(0, import_react14.useEffect)(() => {
|
|
2757
3407
|
const root = rootRef.current;
|
|
2758
3408
|
if (!root) return;
|
|
2759
3409
|
let drag = null;
|
|
@@ -2824,7 +3474,7 @@ function Editor({
|
|
|
2824
3474
|
document.removeEventListener("pointerup", onPointerUp);
|
|
2825
3475
|
};
|
|
2826
3476
|
}, []);
|
|
2827
|
-
(0,
|
|
3477
|
+
(0, import_react14.useEffect)(() => {
|
|
2828
3478
|
const root = rootRef.current;
|
|
2829
3479
|
if (!root) return;
|
|
2830
3480
|
const onDragOver = (e) => {
|
|
@@ -2862,7 +3512,7 @@ function Editor({
|
|
|
2862
3512
|
root.removeEventListener("drop", onDrop);
|
|
2863
3513
|
};
|
|
2864
3514
|
}, []);
|
|
2865
|
-
(0,
|
|
3515
|
+
(0, import_react14.useEffect)(() => {
|
|
2866
3516
|
const root = rootRef.current;
|
|
2867
3517
|
if (!root) return;
|
|
2868
3518
|
const onPointerDown = (e) => {
|
|
@@ -2890,7 +3540,95 @@ function Editor({
|
|
|
2890
3540
|
root.addEventListener("pointerdown", onPointerDown);
|
|
2891
3541
|
return () => root.removeEventListener("pointerdown", onPointerDown);
|
|
2892
3542
|
}, []);
|
|
2893
|
-
(0,
|
|
3543
|
+
(0, import_react14.useEffect)(() => {
|
|
3544
|
+
const root = rootRef.current;
|
|
3545
|
+
if (!root) return;
|
|
3546
|
+
const same = (a, b) => a === b || !!a && !!b && a.blockIndex === b.blockIndex && a.offset === b.offset && (a.cellIndex ?? -1) === (b.cellIndex ?? -1);
|
|
3547
|
+
const set = (next) => {
|
|
3548
|
+
if (same(next, hoveredBehindRef.current)) return;
|
|
3549
|
+
hoveredBehindRef.current = next;
|
|
3550
|
+
setHoveredBehind(next);
|
|
3551
|
+
};
|
|
3552
|
+
let raf = 0;
|
|
3553
|
+
const onMove = (e) => {
|
|
3554
|
+
if (raf) return;
|
|
3555
|
+
const x = e.clientX;
|
|
3556
|
+
const y = e.clientY;
|
|
3557
|
+
raf = requestAnimationFrame(() => {
|
|
3558
|
+
raf = 0;
|
|
3559
|
+
const imgs = root.querySelectorAll(
|
|
3560
|
+
'img[data-embed="image"][data-embed-layout="behind"]'
|
|
3561
|
+
);
|
|
3562
|
+
let hit = null;
|
|
3563
|
+
for (const img of imgs) {
|
|
3564
|
+
const r = img.getBoundingClientRect();
|
|
3565
|
+
if (x >= r.left && x <= r.right && y >= r.top && y <= r.bottom) {
|
|
3566
|
+
hit = img;
|
|
3567
|
+
break;
|
|
3568
|
+
}
|
|
3569
|
+
}
|
|
3570
|
+
if (!hit) {
|
|
3571
|
+
set(null);
|
|
3572
|
+
return;
|
|
3573
|
+
}
|
|
3574
|
+
const blockEl = hit.closest("[data-block-index]");
|
|
3575
|
+
const offsetAttr = hit.dataset.embedOffset;
|
|
3576
|
+
if (!blockEl || offsetAttr == null) {
|
|
3577
|
+
set(null);
|
|
3578
|
+
return;
|
|
3579
|
+
}
|
|
3580
|
+
const blockIndex = Number.parseInt(blockEl.dataset.blockIndex, 10);
|
|
3581
|
+
const fragmentStart = Number.parseInt(blockEl.dataset.fragmentStart ?? "0", 10) || 0;
|
|
3582
|
+
const cellEl = hit.closest("[data-cell-index]");
|
|
3583
|
+
const cellIndex = cellEl ? Number.parseInt(cellEl.dataset.cellIndex, 10) : void 0;
|
|
3584
|
+
set({ blockIndex, offset: fragmentStart + Number.parseInt(offsetAttr, 10), cellIndex });
|
|
3585
|
+
});
|
|
3586
|
+
};
|
|
3587
|
+
const onLeave = () => set(null);
|
|
3588
|
+
root.addEventListener("pointermove", onMove);
|
|
3589
|
+
root.addEventListener("pointerleave", onLeave);
|
|
3590
|
+
return () => {
|
|
3591
|
+
root.removeEventListener("pointermove", onMove);
|
|
3592
|
+
root.removeEventListener("pointerleave", onLeave);
|
|
3593
|
+
if (raf) cancelAnimationFrame(raf);
|
|
3594
|
+
};
|
|
3595
|
+
}, []);
|
|
3596
|
+
(0, import_react14.useEffect)(() => {
|
|
3597
|
+
const root = rootRef.current;
|
|
3598
|
+
if (!root) return;
|
|
3599
|
+
const clear = () => {
|
|
3600
|
+
if (hoveredLinkElRef.current) {
|
|
3601
|
+
hoveredLinkElRef.current = null;
|
|
3602
|
+
setHoveredLink(null);
|
|
3603
|
+
}
|
|
3604
|
+
};
|
|
3605
|
+
const onOver = (e) => {
|
|
3606
|
+
const target = e.target;
|
|
3607
|
+
const a = target?.closest?.("a[href]");
|
|
3608
|
+
if (a && root.contains(a)) {
|
|
3609
|
+
if (hoveredLinkElRef.current === a) return;
|
|
3610
|
+
hoveredLinkElRef.current = a;
|
|
3611
|
+
const r = a.getBoundingClientRect();
|
|
3612
|
+
setHoveredLink({
|
|
3613
|
+
href: a.getAttribute("href") ?? "",
|
|
3614
|
+
rect: { top: r.top, left: r.left, bottom: r.bottom, width: r.width }
|
|
3615
|
+
});
|
|
3616
|
+
} else {
|
|
3617
|
+
clear();
|
|
3618
|
+
}
|
|
3619
|
+
};
|
|
3620
|
+
root.addEventListener("mouseover", onOver);
|
|
3621
|
+
root.addEventListener("mouseleave", clear);
|
|
3622
|
+
root.addEventListener("scroll", clear, true);
|
|
3623
|
+
window.addEventListener("scroll", clear, true);
|
|
3624
|
+
return () => {
|
|
3625
|
+
root.removeEventListener("mouseover", onOver);
|
|
3626
|
+
root.removeEventListener("mouseleave", clear);
|
|
3627
|
+
root.removeEventListener("scroll", clear, true);
|
|
3628
|
+
window.removeEventListener("scroll", clear, true);
|
|
3629
|
+
};
|
|
3630
|
+
}, []);
|
|
3631
|
+
(0, import_react14.useEffect)(() => {
|
|
2894
3632
|
const root = rootRef.current;
|
|
2895
3633
|
if (!root) return;
|
|
2896
3634
|
const handler = (e) => {
|
|
@@ -2904,14 +3642,14 @@ function Editor({
|
|
|
2904
3642
|
const data = e.data ?? "";
|
|
2905
3643
|
if (data.length > 0) {
|
|
2906
3644
|
e.preventDefault();
|
|
2907
|
-
(0,
|
|
3645
|
+
(0, import_core6.insertText)(ctx, data, ed.consumePendingMarks());
|
|
2908
3646
|
}
|
|
2909
3647
|
return;
|
|
2910
3648
|
}
|
|
2911
3649
|
case "insertLineBreak": {
|
|
2912
3650
|
e.preventDefault();
|
|
2913
3651
|
if (ed.getBlockType() === "listItem") {
|
|
2914
|
-
(0,
|
|
3652
|
+
(0, import_core6.insertText)(ctx, "\n", ed.consumePendingMarks());
|
|
2915
3653
|
return;
|
|
2916
3654
|
}
|
|
2917
3655
|
const selEmbed = ed.getSelectedEmbed();
|
|
@@ -2931,7 +3669,7 @@ function Editor({
|
|
|
2931
3669
|
});
|
|
2932
3670
|
}
|
|
2933
3671
|
if (ed.splitListItem()) return;
|
|
2934
|
-
(0,
|
|
3672
|
+
(0, import_core6.insertParagraph)(ctx);
|
|
2935
3673
|
return;
|
|
2936
3674
|
}
|
|
2937
3675
|
case "insertParagraph": {
|
|
@@ -2953,35 +3691,19 @@ function Editor({
|
|
|
2953
3691
|
});
|
|
2954
3692
|
}
|
|
2955
3693
|
if (ed.splitListItem()) return;
|
|
2956
|
-
(0,
|
|
3694
|
+
(0, import_core6.insertParagraph)(ctx);
|
|
2957
3695
|
return;
|
|
2958
3696
|
}
|
|
2959
3697
|
case "insertReplacementText": {
|
|
2960
3698
|
const text = e.data ?? e.dataTransfer?.getData("text/plain") ?? "";
|
|
2961
3699
|
if (text.length > 0) {
|
|
2962
3700
|
e.preventDefault();
|
|
2963
|
-
(0,
|
|
3701
|
+
(0, import_core6.insertText)(ctx, text, ed.consumePendingMarks());
|
|
2964
3702
|
}
|
|
2965
3703
|
return;
|
|
2966
3704
|
}
|
|
2967
3705
|
case "insertFromPaste": {
|
|
2968
3706
|
e.preventDefault();
|
|
2969
|
-
const images = Array.from(e.dataTransfer?.files ?? []).filter(
|
|
2970
|
-
(f) => f.type.startsWith("image/")
|
|
2971
|
-
);
|
|
2972
|
-
if (images.length > 0) {
|
|
2973
|
-
void (async () => {
|
|
2974
|
-
for (const f of images) await editorRef.current.insertImageFromFile(f);
|
|
2975
|
-
})();
|
|
2976
|
-
return;
|
|
2977
|
-
}
|
|
2978
|
-
const text = e.dataTransfer?.getData("text/plain") ?? "";
|
|
2979
|
-
if (text.length === 0) return;
|
|
2980
|
-
const lines = text.split(/\r\n|\r|\n/);
|
|
2981
|
-
lines.forEach((line, i) => {
|
|
2982
|
-
if (i > 0) (0, import_core5.insertParagraph)(ctx);
|
|
2983
|
-
if (line.length > 0) (0, import_core5.insertText)(ctx, line);
|
|
2984
|
-
});
|
|
2985
3707
|
return;
|
|
2986
3708
|
}
|
|
2987
3709
|
case "deleteContentBackward":
|
|
@@ -2989,7 +3711,7 @@ function Editor({
|
|
|
2989
3711
|
case "deleteSoftLineBackward":
|
|
2990
3712
|
case "deleteHardLineBackward": {
|
|
2991
3713
|
e.preventDefault();
|
|
2992
|
-
(0,
|
|
3714
|
+
(0, import_core6.deleteBackward)(ctx);
|
|
2993
3715
|
return;
|
|
2994
3716
|
}
|
|
2995
3717
|
case "deleteContentForward":
|
|
@@ -2997,7 +3719,7 @@ function Editor({
|
|
|
2997
3719
|
case "deleteSoftLineForward":
|
|
2998
3720
|
case "deleteHardLineForward": {
|
|
2999
3721
|
e.preventDefault();
|
|
3000
|
-
(0,
|
|
3722
|
+
(0, import_core6.deleteForward)(ctx);
|
|
3001
3723
|
return;
|
|
3002
3724
|
}
|
|
3003
3725
|
case "historyUndo": {
|
|
@@ -3019,7 +3741,67 @@ function Editor({
|
|
|
3019
3741
|
root.addEventListener("beforeinput", handler);
|
|
3020
3742
|
return () => root.removeEventListener("beforeinput", handler);
|
|
3021
3743
|
}, []);
|
|
3022
|
-
|
|
3744
|
+
(0, import_react14.useEffect)(() => {
|
|
3745
|
+
const root = rootRef.current;
|
|
3746
|
+
if (!root) return;
|
|
3747
|
+
const writeSlice = (e) => {
|
|
3748
|
+
const ctx = ctxRef.current;
|
|
3749
|
+
const slice = (0, import_core6.serializeSelection)(ctx.doc, ctx.getSelection());
|
|
3750
|
+
if (!slice || !e.clipboardData) return false;
|
|
3751
|
+
e.clipboardData.setData(import_core6.SOFER_MIME, JSON.stringify(slice));
|
|
3752
|
+
e.clipboardData.setData("text/plain", (0, import_core6.sliceToText)(slice));
|
|
3753
|
+
return true;
|
|
3754
|
+
};
|
|
3755
|
+
const onCopy = (e) => {
|
|
3756
|
+
if (writeSlice(e)) e.preventDefault();
|
|
3757
|
+
};
|
|
3758
|
+
const onCut = (e) => {
|
|
3759
|
+
e.preventDefault();
|
|
3760
|
+
if (writeSlice(e)) (0, import_core6.deleteSelection)(ctxRef.current);
|
|
3761
|
+
};
|
|
3762
|
+
const onPaste = (e) => {
|
|
3763
|
+
const ctx = ctxRef.current;
|
|
3764
|
+
const cd = e.clipboardData;
|
|
3765
|
+
if (!cd) return;
|
|
3766
|
+
const raw = cd.getData(import_core6.SOFER_MIME);
|
|
3767
|
+
if (raw) {
|
|
3768
|
+
try {
|
|
3769
|
+
const slice = JSON.parse(raw);
|
|
3770
|
+
if (slice && Array.isArray(slice.blocks)) {
|
|
3771
|
+
e.preventDefault();
|
|
3772
|
+
(0, import_core6.insertSlice)(ctx, slice);
|
|
3773
|
+
return;
|
|
3774
|
+
}
|
|
3775
|
+
} catch {
|
|
3776
|
+
}
|
|
3777
|
+
}
|
|
3778
|
+
const images = Array.from(cd.files ?? []).filter((f) => f.type.startsWith("image/"));
|
|
3779
|
+
if (images.length > 0) {
|
|
3780
|
+
e.preventDefault();
|
|
3781
|
+
void (async () => {
|
|
3782
|
+
for (const f of images) await editorRef.current.insertImageFromFile(f);
|
|
3783
|
+
})();
|
|
3784
|
+
return;
|
|
3785
|
+
}
|
|
3786
|
+
const text = cd.getData("text/plain");
|
|
3787
|
+
if (text.length === 0) return;
|
|
3788
|
+
e.preventDefault();
|
|
3789
|
+
const lines = text.split(/\r\n|\r|\n/);
|
|
3790
|
+
lines.forEach((line, i) => {
|
|
3791
|
+
if (i > 0) (0, import_core6.insertParagraph)(ctx);
|
|
3792
|
+
if (line.length > 0) (0, import_core6.insertText)(ctx, line);
|
|
3793
|
+
});
|
|
3794
|
+
};
|
|
3795
|
+
root.addEventListener("copy", onCopy);
|
|
3796
|
+
root.addEventListener("cut", onCut);
|
|
3797
|
+
root.addEventListener("paste", onPaste);
|
|
3798
|
+
return () => {
|
|
3799
|
+
root.removeEventListener("copy", onCopy);
|
|
3800
|
+
root.removeEventListener("cut", onCut);
|
|
3801
|
+
root.removeEventListener("paste", onPaste);
|
|
3802
|
+
};
|
|
3803
|
+
}, []);
|
|
3804
|
+
const onKeyDown = (0, import_react14.useCallback)((e) => {
|
|
3023
3805
|
const ed = editorRef.current;
|
|
3024
3806
|
const mod = e.metaKey || e.ctrlKey;
|
|
3025
3807
|
if (e.key === "Tab") {
|
|
@@ -3093,17 +3875,17 @@ function Editor({
|
|
|
3093
3875
|
});
|
|
3094
3876
|
}
|
|
3095
3877
|
}, []);
|
|
3096
|
-
const onCompositionStart = (0,
|
|
3878
|
+
const onCompositionStart = (0, import_react14.useCallback)(() => {
|
|
3097
3879
|
isComposingRef.current = true;
|
|
3098
3880
|
}, []);
|
|
3099
|
-
const onCompositionEnd = (0,
|
|
3881
|
+
const onCompositionEnd = (0, import_react14.useCallback)((e) => {
|
|
3100
3882
|
isComposingRef.current = false;
|
|
3101
3883
|
if (e.data && e.data.length > 0) {
|
|
3102
|
-
(0,
|
|
3884
|
+
(0, import_core6.insertText)(ctxRef.current, e.data);
|
|
3103
3885
|
}
|
|
3104
3886
|
}, []);
|
|
3105
|
-
const topLevels = (0,
|
|
3106
|
-
const topLevelsStructuralKey = (0,
|
|
3887
|
+
const topLevels = (0, import_react14.useMemo)(() => groupTopLevels(snapshot.blocks), [snapshot]);
|
|
3888
|
+
const topLevelsStructuralKey = (0, import_react14.useMemo)(
|
|
3107
3889
|
() => topLevels.map(
|
|
3108
3890
|
(t) => t.kind === "list" ? `L:${t.listKind}:${t.items.length}:${t.ordinalStart}` : `B:${t.block.type}:${t.block.attrs.level ?? ""}`
|
|
3109
3891
|
).join("|"),
|
|
@@ -3125,7 +3907,7 @@ function Editor({
|
|
|
3125
3907
|
[topLevelsStructuralKey, pageGeometry]
|
|
3126
3908
|
);
|
|
3127
3909
|
const effectiveLayout = paginated ? layout : defaultPageLayout(topLevels.length);
|
|
3128
|
-
const pageStyle = (0,
|
|
3910
|
+
const pageStyle = (0, import_react14.useMemo)(
|
|
3129
3911
|
() => paginated ? {
|
|
3130
3912
|
"--ed-page-width": `${geom.width}px`,
|
|
3131
3913
|
"--ed-page-height": `${geom.height}px`,
|
|
@@ -3144,7 +3926,7 @@ function Editor({
|
|
|
3144
3926
|
geom.marginRight
|
|
3145
3927
|
]
|
|
3146
3928
|
);
|
|
3147
|
-
const body = /* @__PURE__ */ (0,
|
|
3929
|
+
const body = /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
3148
3930
|
"div",
|
|
3149
3931
|
{
|
|
3150
3932
|
ref: rootRef,
|
|
@@ -3170,7 +3952,7 @@ function Editor({
|
|
|
3170
3952
|
const pageInlineStyle = pi === 0 && geom.firstPageExtraTop ? {
|
|
3171
3953
|
"--ed-page-margin-top": `${geom.marginTop + geom.firstPageExtraTop}px`
|
|
3172
3954
|
} : void 0;
|
|
3173
|
-
return /* @__PURE__ */ (0,
|
|
3955
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
|
|
3174
3956
|
"div",
|
|
3175
3957
|
{
|
|
3176
3958
|
className: "ed-page",
|
|
@@ -3178,15 +3960,15 @@ function Editor({
|
|
|
3178
3960
|
"data-page-total": ctx.pageCount,
|
|
3179
3961
|
style: pageInlineStyle,
|
|
3180
3962
|
children: [
|
|
3181
|
-
renderPageHeader && /* @__PURE__ */ (0,
|
|
3182
|
-
/* @__PURE__ */ (0,
|
|
3183
|
-
renderPageFooter && /* @__PURE__ */ (0,
|
|
3963
|
+
renderPageHeader && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "ed-page-header", contentEditable: false, children: renderPageHeader(ctx) }),
|
|
3964
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "ed-page-content", children: page.slots.map((slot) => renderSlot(slot, topLevels)) }),
|
|
3965
|
+
renderPageFooter && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "ed-page-footer", contentEditable: false, children: renderPageFooter(ctx) })
|
|
3184
3966
|
]
|
|
3185
3967
|
},
|
|
3186
3968
|
`page-${pi}`
|
|
3187
3969
|
);
|
|
3188
3970
|
}) : topLevels.map((t) => renderTopLevel(t)),
|
|
3189
|
-
selectedEmbed && /* @__PURE__ */ (0,
|
|
3971
|
+
selectedEmbed && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
3190
3972
|
ImageResizeOverlay,
|
|
3191
3973
|
{
|
|
3192
3974
|
rootRef,
|
|
@@ -3205,13 +3987,54 @@ function Editor({
|
|
|
3205
3987
|
selectedEmbed.offset,
|
|
3206
3988
|
{ offsetX: ox, offsetY: oy },
|
|
3207
3989
|
selectedEmbed.cellIndex
|
|
3990
|
+
),
|
|
3991
|
+
onReanchor: (to, ox, oy) => editor.moveEmbedAnchor(
|
|
3992
|
+
{
|
|
3993
|
+
blockIndex: selectedEmbed.blockIndex,
|
|
3994
|
+
offset: selectedEmbed.offset,
|
|
3995
|
+
cellIndex: selectedEmbed.cellIndex
|
|
3996
|
+
},
|
|
3997
|
+
to,
|
|
3998
|
+
ox,
|
|
3999
|
+
oy
|
|
3208
4000
|
)
|
|
3209
4001
|
}
|
|
4002
|
+
),
|
|
4003
|
+
hoveredBehind && !(selectedEmbed && selectedEmbed.blockIndex === hoveredBehind.blockIndex && selectedEmbed.offset === hoveredBehind.offset && (selectedEmbed.cellIndex ?? -1) === (hoveredBehind.cellIndex ?? -1)) && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
4004
|
+
BehindImageSelectAffordance,
|
|
4005
|
+
{
|
|
4006
|
+
rootRef,
|
|
4007
|
+
blockIndex: hoveredBehind.blockIndex,
|
|
4008
|
+
offset: hoveredBehind.offset,
|
|
4009
|
+
cellIndex: hoveredBehind.cellIndex,
|
|
4010
|
+
onSelect: () => setSelection({
|
|
4011
|
+
anchor: {
|
|
4012
|
+
blockIndex: hoveredBehind.blockIndex,
|
|
4013
|
+
cellIndex: hoveredBehind.cellIndex,
|
|
4014
|
+
offset: hoveredBehind.offset
|
|
4015
|
+
},
|
|
4016
|
+
focus: {
|
|
4017
|
+
blockIndex: hoveredBehind.blockIndex,
|
|
4018
|
+
cellIndex: hoveredBehind.cellIndex,
|
|
4019
|
+
offset: hoveredBehind.offset + 1
|
|
4020
|
+
}
|
|
4021
|
+
})
|
|
4022
|
+
}
|
|
4023
|
+
),
|
|
4024
|
+
hoveredLink && hoveredLink.href && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(LinkHoverTooltip, { href: hoveredLink.href, rect: hoveredLink.rect }),
|
|
4025
|
+
awareness && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
4026
|
+
RemoteCursorsOverlay,
|
|
4027
|
+
{
|
|
4028
|
+
rootRef,
|
|
4029
|
+
doc,
|
|
4030
|
+
awareness,
|
|
4031
|
+
revision: snapshot
|
|
4032
|
+
}
|
|
3210
4033
|
)
|
|
3211
4034
|
]
|
|
3212
4035
|
}
|
|
3213
4036
|
);
|
|
3214
|
-
return /* @__PURE__ */ (0,
|
|
4037
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(EditorProvider, { editor, children: body });
|
|
3215
4038
|
}
|
|
3216
4039
|
function groupTopLevels(snapshot) {
|
|
3217
4040
|
const out = [];
|
|
@@ -3261,7 +4084,7 @@ function renderSlot(slot, topLevels) {
|
|
|
3261
4084
|
start: slot.fragment.start,
|
|
3262
4085
|
end: slot.fragment.end
|
|
3263
4086
|
};
|
|
3264
|
-
return /* @__PURE__ */ (0,
|
|
4087
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
3265
4088
|
NodeView,
|
|
3266
4089
|
{
|
|
3267
4090
|
block: top.block,
|
|
@@ -3272,7 +4095,7 @@ function renderSlot(slot, topLevels) {
|
|
|
3272
4095
|
);
|
|
3273
4096
|
}
|
|
3274
4097
|
if (slot.tableFragment && top.kind === "block" && top.block.type === "table") {
|
|
3275
|
-
return /* @__PURE__ */ (0,
|
|
4098
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
3276
4099
|
NodeView,
|
|
3277
4100
|
{
|
|
3278
4101
|
block: top.block,
|
|
@@ -3292,7 +4115,7 @@ function renderTopLevel(top) {
|
|
|
3292
4115
|
const tree = buildListTree(top.items);
|
|
3293
4116
|
return renderListTree(tree, top, top.ordinalStart, `list-${top.key}`);
|
|
3294
4117
|
}
|
|
3295
|
-
return /* @__PURE__ */ (0,
|
|
4118
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(NodeView, { block: top.block, index: top.blockIndex }, top.key);
|
|
3296
4119
|
}
|
|
3297
4120
|
function renderListFragment(top, frag) {
|
|
3298
4121
|
const ranges = topLevelItemRanges(top.items);
|
|
@@ -3334,9 +4157,9 @@ function buildListTree(items) {
|
|
|
3334
4157
|
function renderListTree(tree, top, start, key) {
|
|
3335
4158
|
const className = `ed-list ed-list-${top.listKind}`;
|
|
3336
4159
|
const style = top.listStyle ? { listStyleType: top.listStyle } : void 0;
|
|
3337
|
-
const items = tree.map((node) => /* @__PURE__ */ (0,
|
|
4160
|
+
const items = tree.map((node) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(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));
|
|
3338
4161
|
if (top.listKind === "ordered") {
|
|
3339
|
-
return /* @__PURE__ */ (0,
|
|
4162
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
|
|
3340
4163
|
"ol",
|
|
3341
4164
|
{
|
|
3342
4165
|
className,
|
|
@@ -3348,11 +4171,11 @@ function renderListTree(tree, top, start, key) {
|
|
|
3348
4171
|
key
|
|
3349
4172
|
);
|
|
3350
4173
|
}
|
|
3351
|
-
return /* @__PURE__ */ (0,
|
|
4174
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("ul", { className, "data-list-kind": "bullet", style, children: items }, key);
|
|
3352
4175
|
}
|
|
3353
4176
|
function renderNestedListTree(tree, kind, key) {
|
|
3354
4177
|
const Tag = kind === "ordered" ? "ol" : "ul";
|
|
3355
|
-
return /* @__PURE__ */ (0,
|
|
4178
|
+
return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Tag, { className: `ed-list ed-list-${kind}`, "data-list-kind": kind, children: tree.map((node) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(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);
|
|
3356
4179
|
}
|
|
3357
4180
|
function clampListLevel2(l) {
|
|
3358
4181
|
if (typeof l !== "number" || !Number.isFinite(l)) return 0;
|
|
@@ -3380,8 +4203,8 @@ function caretRangeFromPoint(x, y) {
|
|
|
3380
4203
|
}
|
|
3381
4204
|
|
|
3382
4205
|
// src/Toolbar.tsx
|
|
3383
|
-
var
|
|
3384
|
-
var
|
|
4206
|
+
var import_react15 = require("react");
|
|
4207
|
+
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
3385
4208
|
var FONT_FAMILIES = ["Arial"];
|
|
3386
4209
|
var FONT_SIZES = ["8pt", "10pt", "11pt", "12pt", "14pt", "16pt", "18pt", "24pt", "32pt", "48pt"];
|
|
3387
4210
|
var BLOCK_OPTIONS = [
|
|
@@ -3421,6 +4244,8 @@ function Toolbar({ className }) {
|
|
|
3421
4244
|
getBlockAttr,
|
|
3422
4245
|
setBlockType,
|
|
3423
4246
|
setBlockAttr,
|
|
4247
|
+
setAlign,
|
|
4248
|
+
getAlign,
|
|
3424
4249
|
isListActive,
|
|
3425
4250
|
toggleList,
|
|
3426
4251
|
indentList,
|
|
@@ -3429,7 +4254,7 @@ function Toolbar({ className }) {
|
|
|
3429
4254
|
const active = getActiveMarks();
|
|
3430
4255
|
const blockType = getBlockType();
|
|
3431
4256
|
const blockLevel = getBlockAttr("level");
|
|
3432
|
-
const blockAlign =
|
|
4257
|
+
const blockAlign = getAlign();
|
|
3433
4258
|
const blockDir = getBlockAttr("dir");
|
|
3434
4259
|
const stop = (e) => {
|
|
3435
4260
|
const t = e.target;
|
|
@@ -3472,16 +4297,16 @@ function Toolbar({ className }) {
|
|
|
3472
4297
|
);
|
|
3473
4298
|
return;
|
|
3474
4299
|
}
|
|
3475
|
-
|
|
4300
|
+
setAlign(value);
|
|
3476
4301
|
};
|
|
3477
|
-
const onInsertImageClick = (0,
|
|
4302
|
+
const onInsertImageClick = (0, import_react15.useCallback)(
|
|
3478
4303
|
(e) => {
|
|
3479
4304
|
e.preventDefault();
|
|
3480
4305
|
imageInputRef.current?.click();
|
|
3481
4306
|
},
|
|
3482
4307
|
[]
|
|
3483
4308
|
);
|
|
3484
|
-
const onImageInputChange = (0,
|
|
4309
|
+
const onImageInputChange = (0, import_react15.useCallback)(
|
|
3485
4310
|
(e) => {
|
|
3486
4311
|
const file = e.target.files?.[0];
|
|
3487
4312
|
if (file) void editor.insertImageFromFile(file);
|
|
@@ -3489,14 +4314,14 @@ function Toolbar({ className }) {
|
|
|
3489
4314
|
},
|
|
3490
4315
|
[editor]
|
|
3491
4316
|
);
|
|
3492
|
-
const imageInputRef = (0,
|
|
4317
|
+
const imageInputRef = (0, import_react15.useRef)(null);
|
|
3493
4318
|
const onToggleDir = (e) => {
|
|
3494
4319
|
e.preventDefault();
|
|
3495
4320
|
const next = blockDir === "rtl" ? "ltr" : "rtl";
|
|
3496
4321
|
setBlockAttr("dir", next);
|
|
3497
4322
|
};
|
|
3498
4323
|
const linkActive = isMarkActive("link");
|
|
3499
|
-
const onLinkClick = (0,
|
|
4324
|
+
const onLinkClick = (0, import_react15.useCallback)(
|
|
3500
4325
|
(e) => {
|
|
3501
4326
|
e.preventDefault();
|
|
3502
4327
|
const currentHref = active.link && typeof active.link === "object" && "href" in active.link ? active.link.href : "";
|
|
@@ -3526,7 +4351,7 @@ function Toolbar({ className }) {
|
|
|
3526
4351
|
sel.cellIndex
|
|
3527
4352
|
);
|
|
3528
4353
|
};
|
|
3529
|
-
return /* @__PURE__ */ (0,
|
|
4354
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
3530
4355
|
"div",
|
|
3531
4356
|
{
|
|
3532
4357
|
className: className ?? "ed-toolbar",
|
|
@@ -3534,7 +4359,7 @@ function Toolbar({ className }) {
|
|
|
3534
4359
|
"aria-label": "Editor toolbar",
|
|
3535
4360
|
onMouseDown: stop,
|
|
3536
4361
|
children: [
|
|
3537
|
-
/* @__PURE__ */ (0,
|
|
4362
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Group, { children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
3538
4363
|
"select",
|
|
3539
4364
|
{
|
|
3540
4365
|
className: "ed-toolbar-select",
|
|
@@ -3543,23 +4368,23 @@ function Toolbar({ className }) {
|
|
|
3543
4368
|
onMouseDown: stop,
|
|
3544
4369
|
"aria-label": "Tipo de bloco",
|
|
3545
4370
|
children: [
|
|
3546
|
-
blockValue === "" && /* @__PURE__ */ (0,
|
|
3547
|
-
BLOCK_OPTIONS.map((o) => /* @__PURE__ */ (0,
|
|
4371
|
+
blockValue === "" && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: "", children: "\u2014 (misto)" }),
|
|
4372
|
+
BLOCK_OPTIONS.map((o) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: o.value, children: o.label }, o.value))
|
|
3548
4373
|
]
|
|
3549
4374
|
}
|
|
3550
4375
|
) }),
|
|
3551
|
-
/* @__PURE__ */ (0,
|
|
3552
|
-
/* @__PURE__ */ (0,
|
|
3553
|
-
/* @__PURE__ */ (0,
|
|
3554
|
-
/* @__PURE__ */ (0,
|
|
3555
|
-
/* @__PURE__ */ (0,
|
|
4376
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Group, { children: [
|
|
4377
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(MarkButton, { title: "Negrito (\u2318B)", pressed: isMarkActive("bold"), onClick: onToggle("bold"), children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("strong", { children: "B" }) }),
|
|
4378
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(MarkButton, { title: "It\xE1lico (\u2318I)", pressed: isMarkActive("italic"), onClick: onToggle("italic"), children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("em", { children: "I" }) }),
|
|
4379
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(MarkButton, { title: "Sublinhado (\u2318U)", pressed: isMarkActive("underline"), onClick: onToggle("underline"), children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("u", { children: "U" }) }),
|
|
4380
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(MarkButton, { title: "Tachado (\u2318\u21E7X)", pressed: isMarkActive("strike"), onClick: onToggle("strike"), children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("s", { children: "S" }) })
|
|
3556
4381
|
] }),
|
|
3557
|
-
/* @__PURE__ */ (0,
|
|
3558
|
-
/* @__PURE__ */ (0,
|
|
3559
|
-
/* @__PURE__ */ (0,
|
|
3560
|
-
/* @__PURE__ */ (0,
|
|
4382
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Group, { children: [
|
|
4383
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("label", { className: "ed-toolbar-label", children: [
|
|
4384
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "ed-toolbar-swatch", "aria-hidden": true, style: { background: colorValue } }),
|
|
4385
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("input", { type: "color", value: colorValue, onChange: onColorChange, onMouseDown: stop, "aria-label": "Cor do texto" })
|
|
3561
4386
|
] }),
|
|
3562
|
-
/* @__PURE__ */ (0,
|
|
4387
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3563
4388
|
"button",
|
|
3564
4389
|
{
|
|
3565
4390
|
type: "button",
|
|
@@ -3574,8 +4399,8 @@ function Toolbar({ className }) {
|
|
|
3574
4399
|
}
|
|
3575
4400
|
)
|
|
3576
4401
|
] }),
|
|
3577
|
-
/* @__PURE__ */ (0,
|
|
3578
|
-
/* @__PURE__ */ (0,
|
|
4402
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Group, { children: [
|
|
4403
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
3579
4404
|
"select",
|
|
3580
4405
|
{
|
|
3581
4406
|
className: "ed-toolbar-select",
|
|
@@ -3584,12 +4409,12 @@ function Toolbar({ className }) {
|
|
|
3584
4409
|
onMouseDown: stop,
|
|
3585
4410
|
"aria-label": "Fam\xEDlia da fonte",
|
|
3586
4411
|
children: [
|
|
3587
|
-
/* @__PURE__ */ (0,
|
|
3588
|
-
FONT_FAMILIES.map((f) => /* @__PURE__ */ (0,
|
|
4412
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: "", children: "Fonte\u2026" }),
|
|
4413
|
+
FONT_FAMILIES.map((f) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: f, children: f }, f))
|
|
3589
4414
|
]
|
|
3590
4415
|
}
|
|
3591
4416
|
),
|
|
3592
|
-
/* @__PURE__ */ (0,
|
|
4417
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
3593
4418
|
"select",
|
|
3594
4419
|
{
|
|
3595
4420
|
className: "ed-toolbar-select",
|
|
@@ -3598,13 +4423,13 @@ function Toolbar({ className }) {
|
|
|
3598
4423
|
onMouseDown: stop,
|
|
3599
4424
|
"aria-label": "Tamanho da fonte",
|
|
3600
4425
|
children: [
|
|
3601
|
-
/* @__PURE__ */ (0,
|
|
3602
|
-
FONT_SIZES.map((s) => /* @__PURE__ */ (0,
|
|
4426
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: "", children: "Tamanho\u2026" }),
|
|
4427
|
+
FONT_SIZES.map((s) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("option", { value: s, children: s }, s))
|
|
3603
4428
|
]
|
|
3604
4429
|
}
|
|
3605
4430
|
)
|
|
3606
4431
|
] }),
|
|
3607
|
-
/* @__PURE__ */ (0,
|
|
4432
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Group, { children: ALIGN_OPTIONS.map((a) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3608
4433
|
"button",
|
|
3609
4434
|
{
|
|
3610
4435
|
type: "button",
|
|
@@ -3617,7 +4442,7 @@ function Toolbar({ className }) {
|
|
|
3617
4442
|
},
|
|
3618
4443
|
a.value
|
|
3619
4444
|
)) }),
|
|
3620
|
-
/* @__PURE__ */ (0,
|
|
4445
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Group, { children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3621
4446
|
"button",
|
|
3622
4447
|
{
|
|
3623
4448
|
type: "button",
|
|
@@ -3629,8 +4454,8 @@ function Toolbar({ className }) {
|
|
|
3629
4454
|
children: blockDir === "rtl" ? "RTL" : "LTR"
|
|
3630
4455
|
}
|
|
3631
4456
|
) }),
|
|
3632
|
-
/* @__PURE__ */ (0,
|
|
3633
|
-
/* @__PURE__ */ (0,
|
|
4457
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Group, { children: [
|
|
4458
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3634
4459
|
"button",
|
|
3635
4460
|
{
|
|
3636
4461
|
type: "button",
|
|
@@ -3645,7 +4470,7 @@ function Toolbar({ className }) {
|
|
|
3645
4470
|
children: "\u2022"
|
|
3646
4471
|
}
|
|
3647
4472
|
),
|
|
3648
|
-
/* @__PURE__ */ (0,
|
|
4473
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3649
4474
|
"button",
|
|
3650
4475
|
{
|
|
3651
4476
|
type: "button",
|
|
@@ -3660,7 +4485,7 @@ function Toolbar({ className }) {
|
|
|
3660
4485
|
children: "1."
|
|
3661
4486
|
}
|
|
3662
4487
|
),
|
|
3663
|
-
/* @__PURE__ */ (0,
|
|
4488
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3664
4489
|
"button",
|
|
3665
4490
|
{
|
|
3666
4491
|
type: "button",
|
|
@@ -3674,7 +4499,7 @@ function Toolbar({ className }) {
|
|
|
3674
4499
|
children: "\u21E4"
|
|
3675
4500
|
}
|
|
3676
4501
|
),
|
|
3677
|
-
/* @__PURE__ */ (0,
|
|
4502
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3678
4503
|
"button",
|
|
3679
4504
|
{
|
|
3680
4505
|
type: "button",
|
|
@@ -3689,7 +4514,7 @@ function Toolbar({ className }) {
|
|
|
3689
4514
|
}
|
|
3690
4515
|
)
|
|
3691
4516
|
] }),
|
|
3692
|
-
/* @__PURE__ */ (0,
|
|
4517
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Group, { children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3693
4518
|
"button",
|
|
3694
4519
|
{
|
|
3695
4520
|
type: "button",
|
|
@@ -3701,9 +4526,9 @@ function Toolbar({ className }) {
|
|
|
3701
4526
|
children: "\u{1F517}"
|
|
3702
4527
|
}
|
|
3703
4528
|
) }),
|
|
3704
|
-
/* @__PURE__ */ (0,
|
|
3705
|
-
/* @__PURE__ */ (0,
|
|
3706
|
-
/* @__PURE__ */ (0,
|
|
4529
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Group, { children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(TableMenu, {}) }),
|
|
4530
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Group, { children: [
|
|
4531
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3707
4532
|
"button",
|
|
3708
4533
|
{
|
|
3709
4534
|
type: "button",
|
|
@@ -3714,7 +4539,7 @@ function Toolbar({ className }) {
|
|
|
3714
4539
|
children: "\u{1F5BC}"
|
|
3715
4540
|
}
|
|
3716
4541
|
),
|
|
3717
|
-
/* @__PURE__ */ (0,
|
|
4542
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3718
4543
|
"input",
|
|
3719
4544
|
{
|
|
3720
4545
|
ref: imageInputRef,
|
|
@@ -3725,8 +4550,8 @@ function Toolbar({ className }) {
|
|
|
3725
4550
|
}
|
|
3726
4551
|
)
|
|
3727
4552
|
] }),
|
|
3728
|
-
selectedEmbed && /* @__PURE__ */ (0,
|
|
3729
|
-
IMAGE_LAYOUT_OPTIONS.map((opt) => /* @__PURE__ */ (0,
|
|
4553
|
+
selectedEmbed && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Group, { children: [
|
|
4554
|
+
IMAGE_LAYOUT_OPTIONS.map((opt) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3730
4555
|
"button",
|
|
3731
4556
|
{
|
|
3732
4557
|
type: "button",
|
|
@@ -3739,7 +4564,7 @@ function Toolbar({ className }) {
|
|
|
3739
4564
|
},
|
|
3740
4565
|
opt.value
|
|
3741
4566
|
)),
|
|
3742
|
-
/* @__PURE__ */ (0,
|
|
4567
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3743
4568
|
"button",
|
|
3744
4569
|
{
|
|
3745
4570
|
type: "button",
|
|
@@ -3769,7 +4594,7 @@ function Toolbar({ className }) {
|
|
|
3769
4594
|
}
|
|
3770
4595
|
)
|
|
3771
4596
|
] }),
|
|
3772
|
-
/* @__PURE__ */ (0,
|
|
4597
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Group, { children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3773
4598
|
"button",
|
|
3774
4599
|
{
|
|
3775
4600
|
type: "button",
|
|
@@ -3790,9 +4615,9 @@ function Toolbar({ className }) {
|
|
|
3790
4615
|
function TableMenu() {
|
|
3791
4616
|
const editor = useEditorContext();
|
|
3792
4617
|
const inTable = editor.isInTable();
|
|
3793
|
-
const [open, setOpen] = (0,
|
|
3794
|
-
const rootRef = (0,
|
|
3795
|
-
(0,
|
|
4618
|
+
const [open, setOpen] = (0, import_react15.useState)(false);
|
|
4619
|
+
const rootRef = (0, import_react15.useRef)(null);
|
|
4620
|
+
(0, import_react15.useEffect)(() => {
|
|
3796
4621
|
if (!open) return;
|
|
3797
4622
|
const onDown = (e) => {
|
|
3798
4623
|
if (!rootRef.current) return;
|
|
@@ -3802,8 +4627,8 @@ function TableMenu() {
|
|
|
3802
4627
|
document.addEventListener("mousedown", onDown);
|
|
3803
4628
|
return () => document.removeEventListener("mousedown", onDown);
|
|
3804
4629
|
}, [open]);
|
|
3805
|
-
return /* @__PURE__ */ (0,
|
|
3806
|
-
/* @__PURE__ */ (0,
|
|
4630
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { ref: rootRef, className: "ed-toolbar-tablemenu", children: [
|
|
4631
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3807
4632
|
"button",
|
|
3808
4633
|
{
|
|
3809
4634
|
type: "button",
|
|
@@ -3818,7 +4643,7 @@ function TableMenu() {
|
|
|
3818
4643
|
children: "\u25A6"
|
|
3819
4644
|
}
|
|
3820
4645
|
),
|
|
3821
|
-
open && /* @__PURE__ */ (0,
|
|
4646
|
+
open && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
3822
4647
|
"div",
|
|
3823
4648
|
{
|
|
3824
4649
|
className: "ed-table-popover",
|
|
@@ -3830,7 +4655,7 @@ function TableMenu() {
|
|
|
3830
4655
|
}
|
|
3831
4656
|
},
|
|
3832
4657
|
children: [
|
|
3833
|
-
/* @__PURE__ */ (0,
|
|
4658
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3834
4659
|
TableSizePicker,
|
|
3835
4660
|
{
|
|
3836
4661
|
onPick: (rows, cols) => {
|
|
@@ -3839,34 +4664,34 @@ function TableMenu() {
|
|
|
3839
4664
|
}
|
|
3840
4665
|
}
|
|
3841
4666
|
),
|
|
3842
|
-
inTable && /* @__PURE__ */ (0,
|
|
3843
|
-
/* @__PURE__ */ (0,
|
|
3844
|
-
/* @__PURE__ */ (0,
|
|
4667
|
+
inTable && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "ed-table-actions", children: [
|
|
4668
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("hr", {}),
|
|
4669
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", onClick: () => {
|
|
3845
4670
|
setOpen(false);
|
|
3846
4671
|
editor.insertRowAbove();
|
|
3847
4672
|
}, children: "Inserir linha acima" }),
|
|
3848
|
-
/* @__PURE__ */ (0,
|
|
4673
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", onClick: () => {
|
|
3849
4674
|
setOpen(false);
|
|
3850
4675
|
editor.insertRowBelow();
|
|
3851
4676
|
}, children: "Inserir linha abaixo" }),
|
|
3852
|
-
/* @__PURE__ */ (0,
|
|
4677
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", onClick: () => {
|
|
3853
4678
|
setOpen(false);
|
|
3854
4679
|
editor.insertColumnLeft();
|
|
3855
4680
|
}, children: "Inserir coluna \xE0 esquerda" }),
|
|
3856
|
-
/* @__PURE__ */ (0,
|
|
4681
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", onClick: () => {
|
|
3857
4682
|
setOpen(false);
|
|
3858
4683
|
editor.insertColumnRight();
|
|
3859
4684
|
}, children: "Inserir coluna \xE0 direita" }),
|
|
3860
|
-
/* @__PURE__ */ (0,
|
|
4685
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", onClick: () => {
|
|
3861
4686
|
setOpen(false);
|
|
3862
4687
|
editor.deleteCurrentRow();
|
|
3863
4688
|
}, children: "Excluir linha" }),
|
|
3864
|
-
/* @__PURE__ */ (0,
|
|
4689
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", onClick: () => {
|
|
3865
4690
|
setOpen(false);
|
|
3866
4691
|
editor.deleteCurrentColumn();
|
|
3867
4692
|
}, children: "Excluir coluna" }),
|
|
3868
|
-
/* @__PURE__ */ (0,
|
|
3869
|
-
editor.hasTableRectSelection() && /* @__PURE__ */ (0,
|
|
4693
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("hr", {}),
|
|
4694
|
+
editor.hasTableRectSelection() && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3870
4695
|
"button",
|
|
3871
4696
|
{
|
|
3872
4697
|
type: "button",
|
|
@@ -3877,19 +4702,19 @@ function TableMenu() {
|
|
|
3877
4702
|
children: "Mesclar c\xE9lulas selecionadas"
|
|
3878
4703
|
}
|
|
3879
4704
|
),
|
|
3880
|
-
/* @__PURE__ */ (0,
|
|
4705
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", onClick: () => {
|
|
3881
4706
|
setOpen(false);
|
|
3882
4707
|
editor.mergeRight();
|
|
3883
4708
|
}, children: "Mesclar com c\xE9lula \xE0 direita" }),
|
|
3884
|
-
/* @__PURE__ */ (0,
|
|
4709
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", onClick: () => {
|
|
3885
4710
|
setOpen(false);
|
|
3886
4711
|
editor.mergeDown();
|
|
3887
4712
|
}, children: "Mesclar com c\xE9lula abaixo" }),
|
|
3888
|
-
/* @__PURE__ */ (0,
|
|
4713
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("button", { type: "button", onClick: () => {
|
|
3889
4714
|
setOpen(false);
|
|
3890
4715
|
editor.splitCell();
|
|
3891
4716
|
}, children: "Dividir c\xE9lulas mescladas" }),
|
|
3892
|
-
/* @__PURE__ */ (0,
|
|
4717
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3893
4718
|
"button",
|
|
3894
4719
|
{
|
|
3895
4720
|
type: "button",
|
|
@@ -3910,11 +4735,11 @@ function TableMenu() {
|
|
|
3910
4735
|
var PICKER_MAX_ROWS = 8;
|
|
3911
4736
|
var PICKER_MAX_COLS = 10;
|
|
3912
4737
|
function TableSizePicker({ onPick }) {
|
|
3913
|
-
const [hover, setHover] = (0,
|
|
4738
|
+
const [hover, setHover] = (0, import_react15.useState)(null);
|
|
3914
4739
|
const label = hover ? `${hover.r + 1} \xD7 ${hover.c + 1}` : "Inserir tabela";
|
|
3915
|
-
return /* @__PURE__ */ (0,
|
|
3916
|
-
/* @__PURE__ */ (0,
|
|
3917
|
-
/* @__PURE__ */ (0,
|
|
4740
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "ed-table-picker", children: [
|
|
4741
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "ed-table-picker-label", children: label }),
|
|
4742
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3918
4743
|
"div",
|
|
3919
4744
|
{
|
|
3920
4745
|
className: "ed-table-picker-grid",
|
|
@@ -3927,7 +4752,7 @@ function TableSizePicker({ onPick }) {
|
|
|
3927
4752
|
{ length: PICKER_MAX_ROWS },
|
|
3928
4753
|
(_, r) => Array.from({ length: PICKER_MAX_COLS }, (_2, c) => {
|
|
3929
4754
|
const filled = hover != null && r <= hover.r && c <= hover.c;
|
|
3930
|
-
return /* @__PURE__ */ (0,
|
|
4755
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3931
4756
|
"button",
|
|
3932
4757
|
{
|
|
3933
4758
|
type: "button",
|
|
@@ -3957,10 +4782,10 @@ function blockSelectValue(type, level) {
|
|
|
3957
4782
|
return type;
|
|
3958
4783
|
}
|
|
3959
4784
|
function Group({ children }) {
|
|
3960
|
-
return /* @__PURE__ */ (0,
|
|
4785
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "ed-toolbar-group", children });
|
|
3961
4786
|
}
|
|
3962
4787
|
function MarkButton({ title, pressed, onClick, children }) {
|
|
3963
|
-
return /* @__PURE__ */ (0,
|
|
4788
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
3964
4789
|
"button",
|
|
3965
4790
|
{
|
|
3966
4791
|
type: "button",
|
|
@@ -3982,6 +4807,7 @@ function MarkButton({ title, pressed, onClick, children }) {
|
|
|
3982
4807
|
LinkDialog,
|
|
3983
4808
|
NodeView,
|
|
3984
4809
|
PageConfigDialog,
|
|
4810
|
+
RemoteCursorsOverlay,
|
|
3985
4811
|
Toolbar,
|
|
3986
4812
|
applyDomSelection,
|
|
3987
4813
|
contentHeight,
|
|
@@ -3993,6 +4819,7 @@ function MarkButton({ title, pressed, onClick, children }) {
|
|
|
3993
4819
|
getCellElement,
|
|
3994
4820
|
getFragmentForOffset,
|
|
3995
4821
|
isTableRectSelection,
|
|
4822
|
+
locatePoint,
|
|
3996
4823
|
readDomSelection,
|
|
3997
4824
|
renderInline,
|
|
3998
4825
|
selectionsEqual,
|