quoin-editor 2.0.5 → 2.1.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/CHANGELOG.md +105 -0
- package/MIGRATION.md +1 -1
- package/README.md +4 -3
- package/dist/ai.cjs +124 -94
- package/dist/ai.d.cts +7 -0
- package/dist/ai.d.ts +7 -0
- package/dist/ai.js +50 -20
- package/dist/ai.js.map +1 -1
- package/dist/catalogue.cjs +28 -26
- package/dist/catalogue.js +19 -17
- package/dist/catalogue.js.map +1 -1
- package/dist/{chunk-JGEDJYIV.cjs → chunk-2FUWXPPC.cjs} +92 -98
- package/dist/{chunk-NHNW5DK3.js → chunk-3F76QQ65.js} +6 -6
- package/dist/{chunk-NHNW5DK3.js.map → chunk-3F76QQ65.js.map} +1 -1
- package/dist/{chunk-DBOZFNWU.js → chunk-3QYFAAQR.js} +3 -3
- package/dist/{chunk-DBOZFNWU.js.map → chunk-3QYFAAQR.js.map} +1 -1
- package/dist/{chunk-I7X7B3WD.cjs → chunk-4JDRDPLC.cjs} +17 -8
- package/dist/{chunk-EBSDPHPS.cjs → chunk-4UFWFV43.cjs} +1060 -719
- package/dist/{chunk-LM3DHROX.cjs → chunk-5AUIA4B3.cjs} +2 -2
- package/dist/{chunk-3INFNIGN.cjs → chunk-5H3BB5VJ.cjs} +131 -78
- package/dist/{chunk-DJU25PFC.cjs → chunk-5L2NSIHZ.cjs} +11 -11
- package/dist/{chunk-W376L2GM.js → chunk-6Y7JAWYY.js} +8 -8
- package/dist/chunk-6Y7JAWYY.js.map +1 -0
- package/dist/{chunk-UDBLZILE.js → chunk-ATKDXQEY.js} +12 -7
- package/dist/{chunk-UDBLZILE.js.map → chunk-ATKDXQEY.js.map} +1 -1
- package/dist/{chunk-A2IQHMIH.js → chunk-BE2SYPK5.js} +49 -54
- package/dist/chunk-BE2SYPK5.js.map +1 -0
- package/dist/{chunk-PURYVDC3.cjs → chunk-CFICD2JP.cjs} +21 -16
- package/dist/{chunk-3HW3WRYC.cjs → chunk-CSIUXYRU.cjs} +2 -2
- package/dist/{chunk-N7BSFDDM.cjs → chunk-DBKL524I.cjs} +23 -23
- package/dist/{chunk-XE3IYW5B.js → chunk-DEFYFIWW.js} +90 -37
- package/dist/chunk-DEFYFIWW.js.map +1 -0
- package/dist/{chunk-7E43TURF.cjs → chunk-ECI3PSMS.cjs} +7 -7
- package/dist/{chunk-4G645EYO.js → chunk-F73QEF7E.js} +5 -5
- package/dist/{chunk-4G645EYO.js.map → chunk-F73QEF7E.js.map} +1 -1
- package/dist/{chunk-KHRVCTQQ.cjs → chunk-FUT7XLMP.cjs} +61 -74
- package/dist/{chunk-7J63427U.cjs → chunk-GQSBOBOM.cjs} +375 -320
- package/dist/{chunk-LU3T3JB4.js → chunk-HPNSQWRD.js} +15 -28
- package/dist/chunk-HPNSQWRD.js.map +1 -0
- package/dist/{chunk-7Y4B7NHO.js → chunk-I34BFOLL.js} +18 -11
- package/dist/chunk-I34BFOLL.js.map +1 -0
- package/dist/{chunk-AJT54OMZ.js → chunk-IFRXEFQH.js} +9 -15
- package/dist/chunk-IFRXEFQH.js.map +1 -0
- package/dist/{chunk-YYW33WUL.cjs → chunk-K3XWVRL4.cjs} +8 -8
- package/dist/{chunk-LSI4RMTY.js → chunk-L5L6YNLT.js} +3 -3
- package/dist/{chunk-LSI4RMTY.js.map → chunk-L5L6YNLT.js.map} +1 -1
- package/dist/{chunk-2BPXVQBP.js → chunk-MO4UMXMT.js} +238 -86
- package/dist/chunk-MO4UMXMT.js.map +1 -0
- package/dist/{chunk-2QKFRKOP.cjs → chunk-N25EH2GZ.cjs} +351 -205
- package/dist/{chunk-CSPCDVCT.js → chunk-NCV2ML25.js} +3 -3
- package/dist/{chunk-CSPCDVCT.js.map → chunk-NCV2ML25.js.map} +1 -1
- package/dist/{chunk-NUQ64S5B.cjs → chunk-OJSKSQTL.cjs} +26 -26
- package/dist/chunk-PIWMU4BV.js +9 -0
- package/dist/chunk-PIWMU4BV.js.map +1 -0
- package/dist/chunk-QFGWSFOI.cjs +10 -0
- package/dist/{chunk-GPTJYWGS.js → chunk-RNBLVGWY.js} +3 -3
- package/dist/{chunk-GPTJYWGS.js.map → chunk-RNBLVGWY.js.map} +1 -1
- package/dist/{chunk-5RBMZGKV.js → chunk-TL2MJOWM.js} +325 -57
- package/dist/chunk-TL2MJOWM.js.map +1 -0
- package/dist/{chunk-YEDPBYO5.cjs → chunk-UDQ52EEC.cjs} +4 -4
- package/dist/{chunk-EIWPJWY3.js → chunk-UE2NQPNG.js} +5 -5
- package/dist/{chunk-EIWPJWY3.js.map → chunk-UE2NQPNG.js.map} +1 -1
- package/dist/{chunk-BE2YHZXA.cjs → chunk-ULV3SCYP.cjs} +26 -15
- package/dist/{chunk-WDBFGX3U.cjs → chunk-VTTMJGWP.cjs} +72 -77
- package/dist/{chunk-556PFYES.js → chunk-WK4UGDZN.js} +290 -235
- package/dist/chunk-WK4UGDZN.js.map +1 -0
- package/dist/{chunk-JZF6UQH5.cjs → chunk-WMKA37NJ.cjs} +12 -12
- package/dist/{chunk-F2ZK6Z52.js → chunk-Y26F2X4E.js} +3 -3
- package/dist/{chunk-F2ZK6Z52.js.map → chunk-Y26F2X4E.js.map} +1 -1
- package/dist/{chunk-FK7EBZPX.cjs → chunk-Z5EEDCRI.cjs} +549 -276
- package/dist/{chunk-G6NBQYMM.js → chunk-ZGFZRVQA.js} +817 -478
- package/dist/chunk-ZGFZRVQA.js.map +1 -0
- package/dist/{chunk-QLVX7MPS.js → chunk-ZQF45LA4.js} +19 -8
- package/dist/chunk-ZQF45LA4.js.map +1 -0
- package/dist/comments.cjs +127 -65
- package/dist/comments.d.cts +35 -2
- package/dist/comments.d.ts +35 -2
- package/dist/comments.js +73 -12
- package/dist/comments.js.map +1 -1
- package/dist/{diagram-extension-22x_njXB.d.ts → diagram-extension-BMlh8GCw.d.ts} +1 -1
- package/dist/{diagram-extension-C_FSkoj9.d.cts → diagram-extension-gmndUpti.d.cts} +1 -1
- package/dist/diagram.cjs +10 -9
- package/dist/diagram.d.cts +2 -2
- package/dist/diagram.d.ts +2 -2
- package/dist/diagram.js +7 -6
- package/dist/diff.cjs +25 -25
- package/dist/diff.js +3 -3
- package/dist/docx.cjs +31 -30
- package/dist/docx.js +5 -4
- package/dist/docx.js.map +1 -1
- package/dist/embed.cjs +10 -9
- package/dist/embed.js +8 -7
- package/dist/{emoji-extension-Dk5IQLZf.d.cts → emoji-extension-DD9CQTQj.d.cts} +1 -1
- package/dist/{emoji-extension-C832oGeT.d.ts → emoji-extension-U_PWZ2fX.d.ts} +1 -1
- package/dist/emoji.cjs +10 -9
- package/dist/emoji.d.cts +2 -2
- package/dist/emoji.d.ts +2 -2
- package/dist/emoji.js +7 -6
- package/dist/engine.cjs +58 -58
- package/dist/engine.d.cts +3 -3
- package/dist/engine.d.ts +3 -3
- package/dist/engine.js +3 -3
- package/dist/{find-extension-DmK9_N81.d.ts → find-extension-BGlqooZi.d.ts} +1 -1
- package/dist/{find-extension-BfruAPLi.d.cts → find-extension-BPnAJ8bY.d.cts} +1 -1
- package/dist/find.cjs +11 -10
- package/dist/find.d.cts +1 -1
- package/dist/find.d.ts +1 -1
- package/dist/find.js +7 -6
- package/dist/headless.cjs +70 -69
- package/dist/headless.d.cts +33 -10
- package/dist/headless.d.ts +33 -10
- package/dist/headless.js +5 -4
- package/dist/highlight.cjs +7 -6
- package/dist/highlight.js +6 -5
- package/dist/highlight.js.map +1 -1
- package/dist/{index-3fYvwqUZ.d.cts → index-DN7vRKFw.d.cts} +1 -1
- package/dist/{index-CgxnzCO5.d.ts → index-DyIYI3PM.d.ts} +1 -1
- package/dist/index.cjs +82 -81
- package/dist/index.d.cts +19 -12
- package/dist/index.d.ts +19 -12
- package/dist/index.js +6 -5
- package/dist/{labels-CiCxj2jP.d.cts → labels-BJORhN93.d.ts} +10 -5
- package/dist/{labels-BhRJYo46.d.ts → labels-CVYJ2-1X.d.cts} +10 -5
- package/dist/locale-ar.cjs +10 -0
- package/dist/locale-ar.d.cts +1 -1
- package/dist/locale-ar.d.ts +1 -1
- package/dist/locale-ar.js +10 -0
- package/dist/locale-ar.js.map +1 -1
- package/dist/locale-de.cjs +4 -0
- package/dist/locale-de.d.cts +1 -1
- package/dist/locale-de.d.ts +1 -1
- package/dist/locale-de.js +4 -0
- package/dist/locale-de.js.map +1 -1
- package/dist/locale-es.cjs +4 -0
- package/dist/locale-es.d.cts +1 -1
- package/dist/locale-es.d.ts +1 -1
- package/dist/locale-es.js +4 -0
- package/dist/locale-es.js.map +1 -1
- package/dist/locale-fr.cjs +4 -0
- package/dist/locale-fr.d.cts +1 -1
- package/dist/locale-fr.d.ts +1 -1
- package/dist/locale-fr.js +4 -0
- package/dist/locale-fr.js.map +1 -1
- package/dist/locale-ja.cjs +4 -0
- package/dist/locale-ja.d.cts +1 -1
- package/dist/locale-ja.d.ts +1 -1
- package/dist/locale-ja.js +4 -0
- package/dist/locale-ja.js.map +1 -1
- package/dist/locale-pt.cjs +4 -0
- package/dist/locale-pt.d.cts +1 -1
- package/dist/locale-pt.d.ts +1 -1
- package/dist/locale-pt.js +4 -0
- package/dist/locale-pt.js.map +1 -1
- package/dist/locale-zh.cjs +4 -0
- package/dist/locale-zh.d.cts +1 -1
- package/dist/locale-zh.d.ts +1 -1
- package/dist/locale-zh.js +4 -0
- package/dist/locale-zh.js.map +1 -1
- package/dist/math.cjs +11 -10
- package/dist/math.js +9 -8
- package/dist/mention.cjs +11 -10
- package/dist/mention.js +9 -8
- package/dist/{node-reveal-DY6bimv3.d.cts → node-reveal-Be7Xa0BL.d.cts} +1 -1
- package/dist/{node-reveal-BnFcnHhz.d.ts → node-reveal-CftIEqF_.d.ts} +1 -1
- package/dist/palette-DuIFHYHc.d.cts +10 -0
- package/dist/palette-DuIFHYHc.d.ts +10 -0
- package/dist/presence.cjs +39 -38
- package/dist/presence.js +8 -7
- package/dist/presence.js.map +1 -1
- package/dist/source.cjs +10 -9
- package/dist/source.d.cts +1 -1
- package/dist/source.d.ts +1 -1
- package/dist/source.js +6 -5
- package/dist/source.js.map +1 -1
- package/dist/{stats-extension-Dmw0Ujxe.d.ts → stats-extension-Bbpr593p.d.ts} +1 -1
- package/dist/{stats-extension-D5HySF0a.d.cts → stats-extension-D7FaeydW.d.cts} +1 -1
- package/dist/stats.cjs +12 -10
- package/dist/stats.d.cts +2 -2
- package/dist/stats.d.ts +2 -2
- package/dist/stats.js +9 -7
- package/dist/styles.css +1 -1
- package/dist/{table-extension-7LkLNK6Q.d.cts → table-extension-DNijjmxV.d.cts} +1 -1
- package/dist/{table-extension-DEpV0DnP.d.ts → table-extension-Dp6FYGPh.d.ts} +1 -1
- package/dist/table.cjs +26 -25
- package/dist/table.d.cts +4 -3
- package/dist/table.d.ts +4 -3
- package/dist/table.js +7 -6
- package/dist/{toc-extension-Dvh37bWQ.d.cts → toc-extension-BGEVAmSY.d.cts} +1 -1
- package/dist/{toc-extension-SVckrFmb.d.ts → toc-extension-DZIe40eV.d.ts} +1 -1
- package/dist/toc.cjs +10 -9
- package/dist/toc.d.cts +2 -2
- package/dist/toc.d.ts +2 -2
- package/dist/toc.js +7 -6
- package/dist/{types-DMuuDBVh.d.ts → types-Byu2a9qk.d.ts} +6 -1
- package/dist/{types-Bzhq5AXj.d.cts → types-DdDlCyyZ.d.cts} +6 -1
- package/dist/view.cjs +4 -4
- package/dist/view.js +2 -2
- package/dist/yjs.cjs +121 -121
- package/dist/yjs.d.cts +2 -2
- package/dist/yjs.d.ts +2 -2
- package/dist/yjs.js +5 -5
- package/package.json +4 -3
- package/dist/chunk-2BPXVQBP.js.map +0 -1
- package/dist/chunk-556PFYES.js.map +0 -1
- package/dist/chunk-5RBMZGKV.js.map +0 -1
- package/dist/chunk-7Y4B7NHO.js.map +0 -1
- package/dist/chunk-A2IQHMIH.js.map +0 -1
- package/dist/chunk-AJT54OMZ.js.map +0 -1
- package/dist/chunk-G6NBQYMM.js.map +0 -1
- package/dist/chunk-LU3T3JB4.js.map +0 -1
- package/dist/chunk-QLVX7MPS.js.map +0 -1
- package/dist/chunk-W376L2GM.js.map +0 -1
- package/dist/chunk-XE3IYW5B.js.map +0 -1
- package/dist/palette-BrX-hEd-.d.cts +0 -4
- package/dist/palette-BrX-hEd-.d.ts +0 -4
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkN25EH2GZ_cjs = require('./chunk-N25EH2GZ.cjs');
|
|
4
4
|
var chunkZWTIRGY5_cjs = require('./chunk-ZWTIRGY5.cjs');
|
|
5
5
|
var chunkA6PGQVTR_cjs = require('./chunk-A6PGQVTR.cjs');
|
|
6
|
-
var
|
|
7
|
-
var
|
|
6
|
+
var chunkQFGWSFOI_cjs = require('./chunk-QFGWSFOI.cjs');
|
|
7
|
+
var chunkZ5EEDCRI_cjs = require('./chunk-Z5EEDCRI.cjs');
|
|
8
|
+
var chunk4JDRDPLC_cjs = require('./chunk-4JDRDPLC.cjs');
|
|
8
9
|
var reactDirection = require('@radix-ui/react-direction');
|
|
9
10
|
var React7 = require('react');
|
|
10
11
|
var jsxRuntime = require('react/jsx-runtime');
|
|
@@ -472,21 +473,9 @@ function frozen(labels) {
|
|
|
472
473
|
var englishLabels = frozen({
|
|
473
474
|
document: "Editor",
|
|
474
475
|
editorHint: "Press Escape, then Tab, to leave the editor.",
|
|
475
|
-
|
|
476
|
-
heading: (level) => `Heading ${level}`,
|
|
477
|
-
bulletItem: "Bullet list item",
|
|
478
|
-
numberedItem: (n) => `Numbered list item ${n}`,
|
|
479
|
-
task: "Task",
|
|
480
|
-
quote: "Quote",
|
|
481
|
-
callout: (tone) => `Callout, ${tone}`,
|
|
482
|
-
calloutTones: { info: "info", tip: "tip", success: "success", warning: "warning", danger: "danger" },
|
|
476
|
+
...chunkN25EH2GZ_cjs.englishRendererLabels,
|
|
483
477
|
calloutIcon: "Callout icon",
|
|
484
478
|
calloutToneMenu: (tone) => `Callout tone: ${tone}`,
|
|
485
|
-
toggle: "Toggle",
|
|
486
|
-
toggleButton: (hidden) => {
|
|
487
|
-
if (hidden === 0) return "Toggle";
|
|
488
|
-
return `Toggle, ${hidden} ${hidden === 1 ? "block" : "blocks"} hidden`;
|
|
489
|
-
},
|
|
490
479
|
placeholderEmpty: "Type '/' for commands",
|
|
491
480
|
placeholderHeading: (level) => `Heading ${level}`,
|
|
492
481
|
placeholderList: "List",
|
|
@@ -509,18 +498,21 @@ var englishLabels = frozen({
|
|
|
509
498
|
color: "Color",
|
|
510
499
|
textColor: "Text color",
|
|
511
500
|
backgroundColor: "Background color",
|
|
501
|
+
textColorSample: "A",
|
|
512
502
|
tone: "Tone",
|
|
513
503
|
icon: "Icon",
|
|
514
504
|
duplicate: "Duplicate",
|
|
515
505
|
copy: "Copy",
|
|
516
506
|
copyLink: "Copy link to block",
|
|
517
507
|
copied: "Copied",
|
|
508
|
+
copyFailed: "Could not copy",
|
|
518
509
|
moveUp: "Move up",
|
|
519
510
|
moveDown: "Move down",
|
|
520
511
|
delete: "Delete",
|
|
521
512
|
askAi: "Ask AI",
|
|
522
513
|
addBelow: "Add block below",
|
|
523
514
|
dragHandle: "Drag to move, click for options",
|
|
515
|
+
blockOptions: "Block options",
|
|
524
516
|
slashMenu: "Commands",
|
|
525
517
|
noResults: "No results",
|
|
526
518
|
resultCount: (n) => `${n} ${n === 1 ? "result" : "results"}`,
|
|
@@ -584,6 +576,7 @@ var englishLabels = frozen({
|
|
|
584
576
|
},
|
|
585
577
|
blockMoved: (position, total) => `Block moved to position ${position} of ${total}`,
|
|
586
578
|
blockInserted: (position, total) => `Block inserted at position ${position} of ${total}`,
|
|
579
|
+
blocksInserted: (n, position, total) => `${n} blocks inserted at position ${position} of ${total}`,
|
|
587
580
|
blockDeleted: (n) => n === 1 ? "Block deleted" : `${n} blocks deleted`,
|
|
588
581
|
blocksSelected: (n) => `${n} ${n === 1 ? "block" : "blocks"} selected`,
|
|
589
582
|
undoHint: (shortcut) => `Press ${shortcut} to undo`,
|
|
@@ -706,7 +699,7 @@ function useLabels() {
|
|
|
706
699
|
}
|
|
707
700
|
|
|
708
701
|
// src/blocks/caption-markdown.ts
|
|
709
|
-
var captionText = (markdown) =>
|
|
702
|
+
var captionText = (markdown) => chunk4JDRDPLC_cjs.inlineText(chunk4JDRDPLC_cjs.parseInline(markdown), () => "");
|
|
710
703
|
function Token({ text: text2, color, className }) {
|
|
711
704
|
return /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: chunkA6PGQVTR_cjs.tokenColour(color) }, className, children: text2 });
|
|
712
705
|
}
|
|
@@ -727,17 +720,17 @@ function assetHref(resolveAssetUrl, storageKey) {
|
|
|
727
720
|
if (storageKey === "") return null;
|
|
728
721
|
try {
|
|
729
722
|
const src = resolveAssetUrl(storageKey);
|
|
730
|
-
return typeof src === "string" &&
|
|
723
|
+
return typeof src === "string" && chunk4JDRDPLC_cjs.sanitizeAssetUrl(src) || null;
|
|
731
724
|
} catch {
|
|
732
725
|
return null;
|
|
733
726
|
}
|
|
734
727
|
}
|
|
735
728
|
|
|
736
729
|
// src/blocks/image/image-source.ts
|
|
737
|
-
var hasPicture = (attrs) =>
|
|
730
|
+
var hasPicture = (attrs) => chunk4JDRDPLC_cjs.str(attrs.url) !== "" || chunk4JDRDPLC_cjs.str(attrs.storageKey) !== "";
|
|
738
731
|
function imageSource(attrs, resolveAssetUrl) {
|
|
739
|
-
const url =
|
|
740
|
-
return url === "" ? assetHref(resolveAssetUrl,
|
|
732
|
+
const url = chunk4JDRDPLC_cjs.str(attrs.url);
|
|
733
|
+
return url === "" ? assetHref(resolveAssetUrl, chunk4JDRDPLC_cjs.str(attrs.storageKey)) : chunk4JDRDPLC_cjs.sanitizeHref(url);
|
|
741
734
|
}
|
|
742
735
|
var HINT = "text-sm text-muted-foreground";
|
|
743
736
|
var TONE = {
|
|
@@ -749,36 +742,35 @@ var TONE = {
|
|
|
749
742
|
};
|
|
750
743
|
function MarkdownPreview({ data }) {
|
|
751
744
|
const labels = useLabels();
|
|
752
|
-
const markdown =
|
|
745
|
+
const markdown = chunk4JDRDPLC_cjs.str(data.markdown);
|
|
753
746
|
if (markdown.trim() === "") return /* @__PURE__ */ jsxRuntime.jsx("p", { className: HINT, children: labels.emptyMarkdown });
|
|
754
747
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "whitespace-pre-wrap text-base leading-7", children: markdown });
|
|
755
748
|
}
|
|
756
749
|
function CodePreview({ data }) {
|
|
757
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { dir: "ltr", className: "quoin-code quoin-code-scroll pt-3", children: /* @__PURE__ */ jsxRuntime.jsx(HighlightOverlay, { code:
|
|
750
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { dir: "ltr", className: "quoin-code quoin-code-scroll pt-3", children: /* @__PURE__ */ jsxRuntime.jsx(HighlightOverlay, { code: chunk4JDRDPLC_cjs.str(data.code), language: chunk4JDRDPLC_cjs.str(data.language) }) });
|
|
758
751
|
}
|
|
759
752
|
function ImagePreview({ data }) {
|
|
760
753
|
const { resolveAssetUrl, labels } = useQuoin();
|
|
761
754
|
const src = imageSource(data, resolveAssetUrl);
|
|
762
755
|
if (src === null) return /* @__PURE__ */ jsxRuntime.jsx("p", { className: HINT, children: labels.emptyImage });
|
|
763
|
-
const caption = captionText(
|
|
756
|
+
const caption = captionText(chunk4JDRDPLC_cjs.str(data.caption));
|
|
764
757
|
return /* @__PURE__ */ jsxRuntime.jsxs("figure", { children: [
|
|
765
|
-
/* @__PURE__ */ jsxRuntime.jsx("img", { src, alt:
|
|
758
|
+
/* @__PURE__ */ jsxRuntime.jsx("img", { src, alt: chunk4JDRDPLC_cjs.str(data.alt) || labels.imageNoAlt, className: "max-w-full rounded-md" }),
|
|
766
759
|
caption && /* @__PURE__ */ jsxRuntime.jsx("figcaption", { className: HINT, children: caption })
|
|
767
760
|
] });
|
|
768
761
|
}
|
|
769
762
|
function FilePreview({ data }) {
|
|
770
763
|
const labels = useLabels();
|
|
771
|
-
const name =
|
|
764
|
+
const name = chunk4JDRDPLC_cjs.str(data.filename);
|
|
772
765
|
if (name === "") return /* @__PURE__ */ jsxRuntime.jsx("p", { className: HINT, children: labels.emptyFile });
|
|
773
766
|
return /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm", children: name });
|
|
774
767
|
}
|
|
775
768
|
function CalloutPreview({ data }) {
|
|
776
769
|
const labels = useLabels();
|
|
777
|
-
const body =
|
|
770
|
+
const body = chunk4JDRDPLC_cjs.str(data.body);
|
|
778
771
|
if (body.trim() === "") return /* @__PURE__ */ jsxRuntime.jsx("p", { className: HINT, children: labels.emptyCallout });
|
|
779
|
-
const tone =
|
|
780
|
-
|
|
781
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { "data-tone": tone, className: `rounded-md border-l-4 ${paint} p-3 text-sm`, children: body });
|
|
772
|
+
const tone = chunkQFGWSFOI_cjs.calloutTone(data.tone);
|
|
773
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { "data-tone": tone, className: `rounded-md border-l-4 ${TONE[tone]} p-3 text-sm`, children: body });
|
|
782
774
|
}
|
|
783
775
|
|
|
784
776
|
// src/blocks/core.ts
|
|
@@ -825,7 +817,7 @@ function selectNode(controller, blockId) {
|
|
|
825
817
|
const { editor } = controller;
|
|
826
818
|
const { selection } = editor.state;
|
|
827
819
|
if (selection?.kind === "node" && selection.block === blockId) return;
|
|
828
|
-
|
|
820
|
+
chunkN25EH2GZ_cjs.dispatchSelection(controller, chunkZ5EEDCRI_cjs.nodeSelection(blockId));
|
|
829
821
|
}
|
|
830
822
|
function focusNode(controller, blockId) {
|
|
831
823
|
selectNode(controller, blockId);
|
|
@@ -855,8 +847,8 @@ var OPEN_EDITOR = "openEditor";
|
|
|
855
847
|
var ABOVE_CORE_KEYS = 200;
|
|
856
848
|
function turnedBlock(tr, { doc, selection }) {
|
|
857
849
|
if (selection?.kind !== "node" || tr.origin === "remote" || tr.origin === "reconcile") return void 0;
|
|
858
|
-
const before =
|
|
859
|
-
return before !== void 0 && before.type !==
|
|
850
|
+
const before = chunk4JDRDPLC_cjs.blockById(tr.before.doc, selection.block);
|
|
851
|
+
return before !== void 0 && before.type !== chunk4JDRDPLC_cjs.blockById(doc, selection.block)?.type ? selection.block : void 0;
|
|
860
852
|
}
|
|
861
853
|
function createVoidEditing() {
|
|
862
854
|
const starters = /* @__PURE__ */ new Map();
|
|
@@ -876,7 +868,7 @@ function createVoidEditing() {
|
|
|
876
868
|
start?.();
|
|
877
869
|
};
|
|
878
870
|
return {
|
|
879
|
-
extension:
|
|
871
|
+
extension: chunkZ5EEDCRI_cjs.defineExtension({
|
|
880
872
|
name: "void-editing",
|
|
881
873
|
priority: ABOVE_CORE_KEYS,
|
|
882
874
|
keymap: { Enter: openEditor },
|
|
@@ -898,7 +890,8 @@ function createVoidEditing() {
|
|
|
898
890
|
// src/blocks/text/return-focus-to-text.ts
|
|
899
891
|
function focusBelongsInText(controller, focused) {
|
|
900
892
|
if (!focused || focused === focused.ownerDocument.body) return true;
|
|
901
|
-
|
|
893
|
+
const canvasMenuButton = focused.getAttribute("aria-haspopup") === "menu" && focused.tabIndex < 0;
|
|
894
|
+
return canvasMenuButton && controller.root?.contains(focused) === true;
|
|
902
895
|
}
|
|
903
896
|
function returnFocusToText(controller) {
|
|
904
897
|
return (event) => {
|
|
@@ -974,7 +967,10 @@ var FOCUS_RING = [
|
|
|
974
967
|
"focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-solid",
|
|
975
968
|
"focus-visible:outline-[var(--quoin-ring)]"
|
|
976
969
|
].join(" ");
|
|
977
|
-
var HIGHLIGHT_BAR =
|
|
970
|
+
var HIGHLIGHT_BAR = [
|
|
971
|
+
"data-[highlighted]:shadow-[inset_2px_0_0_var(--quoin-ring)]",
|
|
972
|
+
"rtl:data-[highlighted]:shadow-[inset_-2px_0_0_var(--quoin-ring)]"
|
|
973
|
+
].join(" ");
|
|
978
974
|
|
|
979
975
|
// src/ui/touch-target.ts
|
|
980
976
|
var TAP_TARGET_FLOOR = "pointer-coarse:min-h-11";
|
|
@@ -990,24 +986,24 @@ var FLOATING_TOOLBAR = "flex w-auto items-center gap-0.5 p-1 shadow-md";
|
|
|
990
986
|
var MENU_CONTENT = "quoin bg-popover text-popover-foreground z-50 max-h-(--radix-popper-available-height) min-w-[8rem] overflow-x-hidden overflow-y-auto rounded-lg border border-border p-1 shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0";
|
|
991
987
|
var MENU_SUB_CONTENT = "quoin bg-popover text-popover-foreground z-50 max-h-(--radix-popper-available-height) min-w-[8rem] overflow-x-hidden overflow-y-auto rounded-lg border border-border p-1 shadow-lg";
|
|
992
988
|
var MENU_ITEM = [
|
|
993
|
-
"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm focus:outline-hidden select-none data-[inset]:
|
|
989
|
+
"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm focus:outline-hidden select-none data-[inset]:ps-8 data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg:not([class*='size-'])]:size-4",
|
|
994
990
|
HIGHLIGHT_BAR,
|
|
995
991
|
TAP_TARGET_FLOOR
|
|
996
992
|
].join(" ");
|
|
997
993
|
var MENU_CHECKABLE_ITEM = [
|
|
998
|
-
"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5
|
|
994
|
+
"focus:bg-accent focus:text-accent-foreground relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pe-2 ps-8 text-sm focus:outline-hidden select-none",
|
|
999
995
|
HIGHLIGHT_BAR,
|
|
1000
996
|
TAP_TARGET_FLOOR
|
|
1001
997
|
].join(" ");
|
|
1002
|
-
var MENU_ITEM_INDICATOR = "pointer-events-none absolute
|
|
998
|
+
var MENU_ITEM_INDICATOR = "pointer-events-none absolute start-2 flex size-3.5 items-center justify-center";
|
|
1003
999
|
var MENU_SUB_TRIGGER = [
|
|
1004
|
-
"focus:bg-accent data-[state=open]:bg-accent flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm focus:outline-hidden select-none data-[inset]:
|
|
1000
|
+
"focus:bg-accent data-[state=open]:bg-accent flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm focus:outline-hidden select-none data-[inset]:ps-8",
|
|
1005
1001
|
HIGHLIGHT_BAR,
|
|
1006
1002
|
TAP_TARGET_FLOOR
|
|
1007
1003
|
].join(" ");
|
|
1008
|
-
var MENU_LABEL = "px-2 py-1.5 text-sm font-medium data-[inset]:
|
|
1004
|
+
var MENU_LABEL = "px-2 py-1.5 text-sm font-medium data-[inset]:ps-8";
|
|
1009
1005
|
var MENU_SEPARATOR = "bg-border -mx-1 my-1 h-px";
|
|
1010
|
-
var MENU_SHORTCUT = "text-muted-foreground
|
|
1006
|
+
var MENU_SHORTCUT = "text-muted-foreground ms-auto text-xs tracking-widest";
|
|
1011
1007
|
function ContextMenu({ modal = false, ...props }) {
|
|
1012
1008
|
return /* @__PURE__ */ jsxRuntime.jsx(ContextMenuPrimitive__namespace.Root, { modal, ...props });
|
|
1013
1009
|
}
|
|
@@ -1098,7 +1094,7 @@ var ContextMenuSubTrigger = /* @__PURE__ */ React7__namespace.forwardRef(functio
|
|
|
1098
1094
|
...props,
|
|
1099
1095
|
children: [
|
|
1100
1096
|
children,
|
|
1101
|
-
/* @__PURE__ */ jsxRuntime.jsx(ChevronRight, { className: "
|
|
1097
|
+
/* @__PURE__ */ jsxRuntime.jsx(ChevronRight, { className: "ms-auto size-4 rtl:rotate-180" })
|
|
1102
1098
|
]
|
|
1103
1099
|
}
|
|
1104
1100
|
);
|
|
@@ -1115,150 +1111,27 @@ var ContextMenuSubContent = /* @__PURE__ */ React7__namespace.forwardRef(functio
|
|
|
1115
1111
|
);
|
|
1116
1112
|
});
|
|
1117
1113
|
|
|
1118
|
-
// src/
|
|
1119
|
-
function copyThroughTextArea(text2, doc) {
|
|
1120
|
-
const previous = doc.activeElement instanceof HTMLElement ? doc.activeElement : null;
|
|
1121
|
-
const area = doc.createElement("textarea");
|
|
1122
|
-
area.value = text2;
|
|
1123
|
-
area.readOnly = true;
|
|
1124
|
-
area.setAttribute("aria-hidden", "true");
|
|
1125
|
-
area.style.cssText = "position:fixed;top:0;left:0;width:1px;height:1px;opacity:0;pointer-events:none";
|
|
1126
|
-
const beside = previous !== null && previous !== doc.body ? previous.parentElement : null;
|
|
1127
|
-
(beside ?? doc.body).append(area);
|
|
1128
|
-
area.focus({ preventScroll: true });
|
|
1129
|
-
area.select();
|
|
1130
|
-
try {
|
|
1131
|
-
return doc.execCommand("copy");
|
|
1132
|
-
} catch {
|
|
1133
|
-
return false;
|
|
1134
|
-
} finally {
|
|
1135
|
-
area.remove();
|
|
1136
|
-
previous?.focus({ preventScroll: true });
|
|
1137
|
-
}
|
|
1138
|
-
}
|
|
1139
|
-
async function copyText(text2, doc = document) {
|
|
1140
|
-
const clipboard = doc.defaultView?.navigator.clipboard;
|
|
1141
|
-
if (clipboard === void 0) return copyThroughTextArea(text2, doc);
|
|
1142
|
-
try {
|
|
1143
|
-
await clipboard.writeText(text2);
|
|
1144
|
-
return true;
|
|
1145
|
-
} catch {
|
|
1146
|
-
return copyThroughTextArea(text2, doc);
|
|
1147
|
-
}
|
|
1148
|
-
}
|
|
1149
|
-
|
|
1150
|
-
// src/gutter/run-on-blocks.ts
|
|
1151
|
-
function settle(tr, before) {
|
|
1152
|
-
const { doc } = tr;
|
|
1153
|
-
const { schema } = tr.before;
|
|
1154
|
-
const result = tr.selection;
|
|
1155
|
-
if (result?.kind !== "blocks" || before?.kind === "blocks") return result;
|
|
1156
|
-
const ids = chunkFK7EBZPX_cjs.selectedBlockIds(doc, result);
|
|
1157
|
-
const head = chunkFK7EBZPX_cjs.headBlockId(before);
|
|
1158
|
-
if (head !== null && ids.includes(head) && chunkFK7EBZPX_cjs.validateSelection(doc, schema, before) === before) return before;
|
|
1159
|
-
return chunkFK7EBZPX_cjs.endOf(doc, schema, ids[0]);
|
|
1160
|
-
}
|
|
1161
|
-
function runOnBlocks(controller, blockIds, command) {
|
|
1162
|
-
const { state } = controller.editor;
|
|
1163
|
-
const ids = blockIds.filter((id) => state.doc.index.has(id));
|
|
1164
|
-
if (ids.length === 0) return false;
|
|
1165
|
-
const before = state.selection;
|
|
1166
|
-
const exact = chunkI7X7B3WD_cjs.sameItems(chunkFK7EBZPX_cjs.selectedBlockIds(state.doc, before), ids);
|
|
1167
|
-
const ran = exact ? before : chunkFK7EBZPX_cjs.blockRangeSelection(ids[0], ids[ids.length - 1]);
|
|
1168
|
-
const { ok, tr } = chunkFK7EBZPX_cjs.runCommands(state, [chunkFK7EBZPX_cjs.setSelection(ran), command]);
|
|
1169
|
-
const result = ok && tr !== null ? tr : new chunkFK7EBZPX_cjs.Transaction(state).setSelection(ran);
|
|
1170
|
-
const settled = exact ? result.selection : settle(result, before);
|
|
1171
|
-
if (!chunkFK7EBZPX_cjs.sameSelection(settled, result.selection)) result.setSelection(settled);
|
|
1172
|
-
if (result.docChanged || !chunkFK7EBZPX_cjs.sameSelection(result.selection, before)) controller.dispatch(result);
|
|
1173
|
-
return ok;
|
|
1174
|
-
}
|
|
1175
|
-
var noChange = () => true;
|
|
1176
|
-
|
|
1177
|
-
// src/gutter/block-menu-items.ts
|
|
1178
|
-
var rangeOf = (blockIds) => chunkFK7EBZPX_cjs.blockRangeSelection(blockIds[0], blockIds[blockIds.length - 1]);
|
|
1114
|
+
// src/canvas/block-targets.ts
|
|
1179
1115
|
function selectedWith(state, blockId) {
|
|
1180
1116
|
const { doc, selection } = state;
|
|
1181
|
-
const selected =
|
|
1117
|
+
const selected = chunkZ5EEDCRI_cjs.selectedBlockIds(doc, selection);
|
|
1182
1118
|
const ofBlocks = selection?.kind === "blocks" || selection?.kind === "text" && selected.length > 1;
|
|
1183
1119
|
return ofBlocks && selected.includes(blockId) ? selected : null;
|
|
1184
1120
|
}
|
|
1185
|
-
function
|
|
1121
|
+
function handleTargets(state, blockId) {
|
|
1186
1122
|
const selected = selectedWith(state, blockId);
|
|
1187
1123
|
if (selected !== null) return selected;
|
|
1188
1124
|
const { doc } = state;
|
|
1189
|
-
const index =
|
|
1190
|
-
return doc.blocks.slice(index,
|
|
1125
|
+
const index = chunk4JDRDPLC_cjs.requireBlockIndex(doc, blockId);
|
|
1126
|
+
return doc.blocks.slice(index, chunkZ5EEDCRI_cjs.descendantsEnd(doc, index)).map((block) => block.id);
|
|
1191
1127
|
}
|
|
1192
1128
|
function styleTargets(state, blockId) {
|
|
1193
1129
|
return selectedWith(state, blockId) ?? [blockId];
|
|
1194
1130
|
}
|
|
1195
|
-
function menuActions(core, extra = []) {
|
|
1196
|
-
return [...core.filter((action) => !action.destructive), ...extra, ...core.filter((action) => action.destructive)];
|
|
1197
|
-
}
|
|
1198
|
-
function markdownOf(editor, blockIds, resolveAssetUrl) {
|
|
1199
|
-
const { doc } = editor.state;
|
|
1200
|
-
const range = chunkFK7EBZPX_cjs.selectedBlockRange(doc, rangeOf(blockIds));
|
|
1201
|
-
if (range === null) return "";
|
|
1202
|
-
const blocks = editor.codec.blocksFromDoc(chunkI7X7B3WD_cjs.createDoc(doc.blocks.slice(range.start, range.end)));
|
|
1203
|
-
return chunkFK7EBZPX_cjs.toMarkdown(blocks, { schema: editor.schema, resolveAssetUrl, comments: false });
|
|
1204
|
-
}
|
|
1205
|
-
var applies = (command) => (state, blockIds) => blockIds.every((id) => state.doc.index.has(id)) && chunkFK7EBZPX_cjs.runCommands(state, [chunkFK7EBZPX_cjs.setSelection(rangeOf(blockIds)), command]).ok;
|
|
1206
|
-
function coreBlockMenuActions(labels, options) {
|
|
1207
|
-
const copy = (controller, blockIds, text2) => {
|
|
1208
|
-
void copyText(text2).then((copied) => {
|
|
1209
|
-
if (copied) options.onCopied?.();
|
|
1210
|
-
});
|
|
1211
|
-
runOnBlocks(controller, blockIds, noChange);
|
|
1212
|
-
};
|
|
1213
|
-
return [
|
|
1214
|
-
{
|
|
1215
|
-
id: "duplicate",
|
|
1216
|
-
label: labels.duplicate,
|
|
1217
|
-
icon: CopyPlus,
|
|
1218
|
-
shortcut: "Mod-d",
|
|
1219
|
-
run: (controller, blockIds) => runOnBlocks(controller, blockIds, chunkFK7EBZPX_cjs.duplicateBlocks())
|
|
1220
|
-
},
|
|
1221
|
-
{
|
|
1222
|
-
id: "copy",
|
|
1223
|
-
label: labels.copy,
|
|
1224
|
-
icon: Copy,
|
|
1225
|
-
run: (controller, blockIds) => copy(controller, blockIds, markdownOf(controller.editor, blockIds, options.resolveAssetUrl))
|
|
1226
|
-
},
|
|
1227
|
-
{
|
|
1228
|
-
id: "copy-link",
|
|
1229
|
-
label: labels.copyLink,
|
|
1230
|
-
icon: Link,
|
|
1231
|
-
run: (controller, blockIds) => copy(controller, blockIds, options.blockLink(blockIds[0]))
|
|
1232
|
-
},
|
|
1233
|
-
{
|
|
1234
|
-
id: "move-up",
|
|
1235
|
-
label: labels.moveUp,
|
|
1236
|
-
icon: ArrowUp,
|
|
1237
|
-
shortcut: "Mod-Shift-ArrowUp",
|
|
1238
|
-
run: (controller, blockIds) => runOnBlocks(controller, blockIds, chunkFK7EBZPX_cjs.moveBlocksUp),
|
|
1239
|
-
available: applies(chunkFK7EBZPX_cjs.moveBlocksUp)
|
|
1240
|
-
},
|
|
1241
|
-
{
|
|
1242
|
-
id: "move-down",
|
|
1243
|
-
label: labels.moveDown,
|
|
1244
|
-
icon: ArrowDown,
|
|
1245
|
-
shortcut: "Mod-Shift-ArrowDown",
|
|
1246
|
-
run: (controller, blockIds) => runOnBlocks(controller, blockIds, chunkFK7EBZPX_cjs.moveBlocksDown),
|
|
1247
|
-
available: applies(chunkFK7EBZPX_cjs.moveBlocksDown)
|
|
1248
|
-
},
|
|
1249
|
-
{
|
|
1250
|
-
id: "delete",
|
|
1251
|
-
label: labels.delete,
|
|
1252
|
-
icon: Trash,
|
|
1253
|
-
destructive: true,
|
|
1254
|
-
run: (controller, blockIds) => runOnBlocks(controller, blockIds, chunkFK7EBZPX_cjs.deleteBlocks)
|
|
1255
|
-
}
|
|
1256
|
-
];
|
|
1257
|
-
}
|
|
1258
1131
|
|
|
1259
1132
|
// src/gutter/block-menu-state.ts
|
|
1260
1133
|
var targetsOf = (state, blockId) => ({
|
|
1261
|
-
blockIds:
|
|
1134
|
+
blockIds: handleTargets(state, blockId),
|
|
1262
1135
|
styleIds: styleTargets(state, blockId)
|
|
1263
1136
|
});
|
|
1264
1137
|
function openBlockMenu(store, state, blockId) {
|
|
@@ -1283,24 +1156,54 @@ var TONE_ICONS = {
|
|
|
1283
1156
|
function calloutIcon(attrs, tone) {
|
|
1284
1157
|
return typeof attrs.icon === "string" && attrs.icon !== "" ? attrs.icon : TONE_ICONS[tone];
|
|
1285
1158
|
}
|
|
1159
|
+
function iconTellsTone(attrs, tone) {
|
|
1160
|
+
return calloutIcon(attrs, tone) === TONE_ICONS[tone];
|
|
1161
|
+
}
|
|
1286
1162
|
function MenuIcon({ icon: Icon2 }) {
|
|
1287
1163
|
return /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", className: "flex shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(Icon2, { className: "size-4" }) });
|
|
1288
1164
|
}
|
|
1165
|
+
|
|
1166
|
+
// src/gutter/run-on-blocks.ts
|
|
1167
|
+
function settle(tr, before) {
|
|
1168
|
+
const { doc } = tr;
|
|
1169
|
+
const { schema } = tr.before;
|
|
1170
|
+
const result = tr.selection;
|
|
1171
|
+
if (result?.kind !== "blocks" || before?.kind === "blocks") return result;
|
|
1172
|
+
const ids = chunkZ5EEDCRI_cjs.selectedBlockIds(doc, result);
|
|
1173
|
+
const head = chunkZ5EEDCRI_cjs.headBlockId(before);
|
|
1174
|
+
if (head !== null && ids.includes(head) && chunkZ5EEDCRI_cjs.validateSelection(doc, schema, before) === before) return before;
|
|
1175
|
+
return chunkZ5EEDCRI_cjs.endOf(doc, schema, ids[0]);
|
|
1176
|
+
}
|
|
1177
|
+
function runOnBlocks(controller, blockIds, command) {
|
|
1178
|
+
const { state } = controller.editor;
|
|
1179
|
+
const ids = blockIds.filter((id) => state.doc.index.has(id));
|
|
1180
|
+
if (ids.length === 0) return false;
|
|
1181
|
+
const before = state.selection;
|
|
1182
|
+
const exact = chunk4JDRDPLC_cjs.sameItems(chunkZ5EEDCRI_cjs.selectedBlockIds(state.doc, before), ids);
|
|
1183
|
+
const ran = exact ? before : chunkZ5EEDCRI_cjs.blockRangeSelection(ids[0], ids[ids.length - 1]);
|
|
1184
|
+
const { ok, tr } = chunkZ5EEDCRI_cjs.runCommands(state, [chunkZ5EEDCRI_cjs.setSelection(ran), command]);
|
|
1185
|
+
const result = ok && tr !== null ? tr : new chunkZ5EEDCRI_cjs.Transaction(state).setSelection(ran);
|
|
1186
|
+
const settled = exact ? result.selection : settle(result, before);
|
|
1187
|
+
if (!chunkZ5EEDCRI_cjs.sameSelection(settled, result.selection)) result.setSelection(settled);
|
|
1188
|
+
if (result.docChanged || !chunkZ5EEDCRI_cjs.sameSelection(result.selection, before)) controller.dispatch(result);
|
|
1189
|
+
return ok;
|
|
1190
|
+
}
|
|
1191
|
+
var noChange = () => true;
|
|
1289
1192
|
var sharedTone = (blocks) => {
|
|
1290
|
-
const tones = new Set(blocks.map((block) =>
|
|
1193
|
+
const tones = new Set(blocks.map((block) => chunkQFGWSFOI_cjs.calloutTone(block.attrs.tone)));
|
|
1291
1194
|
return tones.size === 1 ? [...tones][0] : "";
|
|
1292
1195
|
};
|
|
1293
1196
|
function CalloutMenus({ kit, controller, blocks }) {
|
|
1294
1197
|
const labels = useLabels();
|
|
1295
1198
|
const blockIds = blocks.map((block) => block.id);
|
|
1296
|
-
const apply = (patch) => runOnBlocks(controller, blockIds,
|
|
1199
|
+
const apply = (patch) => runOnBlocks(controller, blockIds, chunkZ5EEDCRI_cjs.setAttrs(patch));
|
|
1297
1200
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1298
1201
|
/* @__PURE__ */ jsxRuntime.jsxs(kit.Sub, { children: [
|
|
1299
1202
|
/* @__PURE__ */ jsxRuntime.jsxs(kit.SubTrigger, { children: [
|
|
1300
1203
|
/* @__PURE__ */ jsxRuntime.jsx(MenuIcon, { icon: Droplet }),
|
|
1301
1204
|
labels.tone
|
|
1302
1205
|
] }),
|
|
1303
|
-
/* @__PURE__ */ jsxRuntime.jsx(kit.SubContent, { children: /* @__PURE__ */ jsxRuntime.jsx(kit.RadioGroup, { value: sharedTone(blocks), onValueChange: (tone) => apply({ tone }), children:
|
|
1206
|
+
/* @__PURE__ */ jsxRuntime.jsx(kit.SubContent, { children: /* @__PURE__ */ jsxRuntime.jsx(kit.RadioGroup, { value: sharedTone(blocks), onValueChange: (tone) => apply({ tone }), children: chunkQFGWSFOI_cjs.CALLOUT_TONES.map((tone) => /* @__PURE__ */ jsxRuntime.jsx(kit.RadioItem, { value: tone, indicator: /* @__PURE__ */ jsxRuntime.jsx(Check, { className: "size-4" }), children: labels.calloutTones[tone] }, tone)) }) })
|
|
1304
1207
|
] }),
|
|
1305
1208
|
/* @__PURE__ */ jsxRuntime.jsxs(kit.Sub, { children: [
|
|
1306
1209
|
/* @__PURE__ */ jsxRuntime.jsxs(kit.SubTrigger, { children: [
|
|
@@ -1313,11 +1216,11 @@ function CalloutMenus({ kit, controller, blocks }) {
|
|
|
1313
1216
|
}
|
|
1314
1217
|
function sharedColor(blocks, key) {
|
|
1315
1218
|
const coloured = blocks.filter((block) => block.type === "MARKDOWN");
|
|
1316
|
-
const colors = new Set(coloured.map((block) =>
|
|
1219
|
+
const colors = new Set(coloured.map((block) => chunk4JDRDPLC_cjs.paletteOrUndefined(block.attrs[key]) ?? "default"));
|
|
1317
1220
|
return colors.size === 1 ? [...colors][0] : "";
|
|
1318
1221
|
}
|
|
1319
1222
|
var swatches = {
|
|
1320
|
-
color: (name) => /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", "data-color": name, className: "w-4 text-center font-medium", children:
|
|
1223
|
+
color: (name, labels) => /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", "data-color": name, className: "w-4 text-center font-medium", children: labels.textColorSample ?? englishLabels.textColorSample }),
|
|
1321
1224
|
background: (name) => /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", "data-bg": name, className: "size-4 rounded-sm border border-border" })
|
|
1322
1225
|
};
|
|
1323
1226
|
function ColorGroups({ kit, value, onPick }) {
|
|
@@ -1326,8 +1229,8 @@ function ColorGroups({ kit, value, onPick }) {
|
|
|
1326
1229
|
const backgroundTitle = React7.useId();
|
|
1327
1230
|
const group = (key, title, titleId) => /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1328
1231
|
/* @__PURE__ */ jsxRuntime.jsx(kit.Label, { id: titleId, children: title }),
|
|
1329
|
-
/* @__PURE__ */ jsxRuntime.jsx(kit.RadioGroup, { "aria-labelledby": titleId, value: value[key], onValueChange: (name) => onPick(key, name), children:
|
|
1330
|
-
swatches[key](name),
|
|
1232
|
+
/* @__PURE__ */ jsxRuntime.jsx(kit.RadioGroup, { "aria-labelledby": titleId, value: value[key], onValueChange: (name) => onPick(key, name), children: chunk4JDRDPLC_cjs.PALETTE.map((name) => /* @__PURE__ */ jsxRuntime.jsxs(kit.RadioItem, { value: name, indicator: /* @__PURE__ */ jsxRuntime.jsx(Check, { className: "size-4" }), children: [
|
|
1233
|
+
swatches[key](name, labels),
|
|
1331
1234
|
labels.colors[name]
|
|
1332
1235
|
] }, name)) })
|
|
1333
1236
|
] });
|
|
@@ -1341,7 +1244,7 @@ function ColorMenu({ kit, controller, blocks }) {
|
|
|
1341
1244
|
const labels = useLabels();
|
|
1342
1245
|
const blockIds = blocks.map((block) => block.id);
|
|
1343
1246
|
const value = { color: sharedColor(blocks, "color"), background: sharedColor(blocks, "background") };
|
|
1344
|
-
const pick = (key, name) => runOnBlocks(controller, blockIds,
|
|
1247
|
+
const pick = (key, name) => runOnBlocks(controller, blockIds, chunkZ5EEDCRI_cjs.setBlockColor({ [key]: name === "default" ? null : name }));
|
|
1345
1248
|
return /* @__PURE__ */ jsxRuntime.jsxs(kit.Sub, { children: [
|
|
1346
1249
|
/* @__PURE__ */ jsxRuntime.jsxs(kit.SubTrigger, { children: [
|
|
1347
1250
|
/* @__PURE__ */ jsxRuntime.jsx(MenuIcon, { icon: Palette }),
|
|
@@ -1372,7 +1275,7 @@ function modifierText(modifier, isMac, { keyNames }) {
|
|
|
1372
1275
|
return Object.hasOwn(MODIFIERS, name) ? keyNames[MODIFIERS[name]] : capitalized(modifier);
|
|
1373
1276
|
}
|
|
1374
1277
|
function formatShortcut(shortcut, platform = {}) {
|
|
1375
|
-
const { isMac =
|
|
1278
|
+
const { isMac = chunkZ5EEDCRI_cjs.detectMac(), labels = englishLabels } = platform;
|
|
1376
1279
|
const parts = shortcut.split(shortcut.includes("+") ? "+" : "-");
|
|
1377
1280
|
const key = parts.pop() ?? shortcut;
|
|
1378
1281
|
const written = [...parts.map((modifier) => modifierText(modifier, isMac, labels)), keyText(key, labels)];
|
|
@@ -1452,21 +1355,21 @@ function languageOptions(query, plainText) {
|
|
|
1452
1355
|
}
|
|
1453
1356
|
|
|
1454
1357
|
// src/blocks/insert-blocks.ts
|
|
1455
|
-
var isEmptyParagraph = (schema, block) =>
|
|
1358
|
+
var isEmptyParagraph = (schema, block) => chunkZ5EEDCRI_cjs.isParagraph(block) && chunkZ5EEDCRI_cjs.regionLength(block, chunkZ5EEDCRI_cjs.primaryRegion(schema, block) ?? "") === 0;
|
|
1456
1359
|
function fresh(schema, { id, type, attrs, regions }, indent3) {
|
|
1457
|
-
const block =
|
|
1360
|
+
const block = chunkZ5EEDCRI_cjs.createBlock(schema, type, attrs, indent3, id);
|
|
1458
1361
|
return regions === void 0 ? block : { ...block, regions };
|
|
1459
1362
|
}
|
|
1460
1363
|
function landOnLine(tr, schema, index, indent3) {
|
|
1461
1364
|
const next = tr.doc.blocks[index];
|
|
1462
1365
|
const reused = next !== void 0 && next.indent === indent3 && isEmptyParagraph(schema, next);
|
|
1463
|
-
const line = reused ? next :
|
|
1464
|
-
if (!reused) tr.step(
|
|
1465
|
-
tr.setSelection(
|
|
1366
|
+
const line = reused ? next : chunkZ5EEDCRI_cjs.createBlock(schema, schema.defaultTextBlock, {}, indent3);
|
|
1367
|
+
if (!reused) tr.step(chunkZ5EEDCRI_cjs.insertBlocksStep(index, [line]));
|
|
1368
|
+
tr.setSelection(chunkZ5EEDCRI_cjs.startOf(tr.doc, schema, line.id));
|
|
1466
1369
|
}
|
|
1467
1370
|
function land(tr, schema, landing, first, after) {
|
|
1468
|
-
if (landing === "text") tr.setSelection(
|
|
1469
|
-
if (landing === "editor") tr.setSelection(
|
|
1371
|
+
if (landing === "text") tr.setSelection(chunkZ5EEDCRI_cjs.startOf(tr.doc, schema, first.id));
|
|
1372
|
+
if (landing === "editor") tr.setSelection(chunkZ5EEDCRI_cjs.nodeSelection(first.id)).setMeta(OPEN_EDITOR, first.id);
|
|
1470
1373
|
if (landing === "line") landOnLine(tr, schema, after, first.indent);
|
|
1471
1374
|
}
|
|
1472
1375
|
function anchorIndex(doc, id) {
|
|
@@ -1476,24 +1379,24 @@ function anchorIndex(doc, id) {
|
|
|
1476
1379
|
function insertBlocks(blocks, landing, anchorId) {
|
|
1477
1380
|
return (state, dispatch) => {
|
|
1478
1381
|
const { doc, schema } = state;
|
|
1479
|
-
const id = anchorId === void 0 ?
|
|
1382
|
+
const id = anchorId === void 0 ? chunkZ5EEDCRI_cjs.headBlockId(state.selection) : anchorId;
|
|
1480
1383
|
const index = anchorIndex(doc, id);
|
|
1481
1384
|
if (index === void 0 || blocks.length === 0) return false;
|
|
1482
1385
|
const anchor = id === null ? void 0 : doc.blocks[index];
|
|
1483
1386
|
const created2 = blocks.map((block) => fresh(schema, block, anchor?.indent ?? 0));
|
|
1484
|
-
const tr = new
|
|
1387
|
+
const tr = new chunkZ5EEDCRI_cjs.Transaction(state);
|
|
1485
1388
|
const empty = anchor !== void 0 && landing !== "stay" && isEmptyParagraph(schema, anchor);
|
|
1486
1389
|
if (empty && landing === "line") {
|
|
1487
|
-
tr.step(
|
|
1390
|
+
tr.step(chunkZ5EEDCRI_cjs.insertBlocksStep(index, created2)).setSelection(chunkZ5EEDCRI_cjs.startOf(tr.doc, schema, anchor.id));
|
|
1488
1391
|
} else if (empty) {
|
|
1489
1392
|
const [first, ...rest] = created2;
|
|
1490
1393
|
const filled = { ...first, id: anchor.id };
|
|
1491
|
-
tr.step(
|
|
1492
|
-
if (rest.length > 0) tr.step(
|
|
1394
|
+
tr.step(chunkZ5EEDCRI_cjs.replaceBlockStep(filled));
|
|
1395
|
+
if (rest.length > 0) tr.step(chunkZ5EEDCRI_cjs.insertBlocksStep(index + 1, rest));
|
|
1493
1396
|
land(tr, schema, landing, filled, index + created2.length);
|
|
1494
1397
|
} else {
|
|
1495
|
-
const at = anchor === void 0 ? 0 :
|
|
1496
|
-
tr.step(
|
|
1398
|
+
const at = anchor === void 0 ? 0 : chunkZ5EEDCRI_cjs.descendantsEnd(doc, index);
|
|
1399
|
+
tr.step(chunkZ5EEDCRI_cjs.insertBlocksStep(at, created2));
|
|
1497
1400
|
land(tr, schema, landing, created2[0], at + created2.length);
|
|
1498
1401
|
}
|
|
1499
1402
|
dispatch?.(tr);
|
|
@@ -1506,7 +1409,7 @@ function landingFor(flow, hasEditor) {
|
|
|
1506
1409
|
}
|
|
1507
1410
|
function insertBlockToWrite(block, hasEditor, anchorId) {
|
|
1508
1411
|
return (state, dispatch) => {
|
|
1509
|
-
const landing = landingFor(
|
|
1412
|
+
const landing = landingFor(chunk4JDRDPLC_cjs.specFor(state.schema, block.type).flow, hasEditor);
|
|
1510
1413
|
return insertBlocks([block], landing, anchorId)(state, dispatch);
|
|
1511
1414
|
};
|
|
1512
1415
|
}
|
|
@@ -1514,20 +1417,20 @@ function insertBlockToWrite(block, hasEditor, anchorId) {
|
|
|
1514
1417
|
// src/blocks/code/code-actions.ts
|
|
1515
1418
|
function writeCode(controller, blockId, code, group) {
|
|
1516
1419
|
const { editor } = controller;
|
|
1517
|
-
const block =
|
|
1420
|
+
const block = chunk4JDRDPLC_cjs.blockById(editor.state.doc, blockId);
|
|
1518
1421
|
if (block === void 0 || block.attrs.code === code) return;
|
|
1519
|
-
controller.dispatch(editor.createTransaction().step(
|
|
1422
|
+
controller.dispatch(editor.createTransaction().step(chunkZ5EEDCRI_cjs.setAttrsStep(blockId, { code })).setMeta(chunkZ5EEDCRI_cjs.HISTORY_GROUP, group));
|
|
1520
1423
|
}
|
|
1521
1424
|
function codeToParagraph(blockId) {
|
|
1522
1425
|
return (state, dispatch) => {
|
|
1523
|
-
const turn =
|
|
1524
|
-
const { ok, tr } =
|
|
1426
|
+
const turn = chunkZ5EEDCRI_cjs.setBlockType("MARKDOWN", { kind: "paragraph" });
|
|
1427
|
+
const { ok, tr } = chunkZ5EEDCRI_cjs.runCommands(state, [chunkZ5EEDCRI_cjs.setSelection(chunkZ5EEDCRI_cjs.nodeSelection(blockId)), turn]);
|
|
1525
1428
|
if (ok && tr !== null) dispatch?.(tr);
|
|
1526
1429
|
return ok;
|
|
1527
1430
|
};
|
|
1528
1431
|
}
|
|
1529
1432
|
function leaveCode(controller, blockId, direction, addsLine = false) {
|
|
1530
|
-
const moved =
|
|
1433
|
+
const moved = chunkN25EH2GZ_cjs.moveToNeighbour(controller, blockId, direction);
|
|
1531
1434
|
if (!moved && !(addsLine && controller.run(insertBlocks([{ type: "MARKDOWN" }], "text", blockId)))) return false;
|
|
1532
1435
|
controller.focus();
|
|
1533
1436
|
return true;
|
|
@@ -1605,8 +1508,8 @@ var MOD_KEYS = [
|
|
|
1605
1508
|
["Mod-a", ({ value, start, end }) => start === 0 && end === value.length ? { kind: "selectAll" } : null]
|
|
1606
1509
|
];
|
|
1607
1510
|
function codeKeyAction(event, field, isMac) {
|
|
1608
|
-
const name =
|
|
1609
|
-
const modKey = MOD_KEYS.find(([key]) =>
|
|
1511
|
+
const name = chunkZ5EEDCRI_cjs.keyName(event, isMac);
|
|
1512
|
+
const modKey = MOD_KEYS.find(([key]) => chunkZ5EEDCRI_cjs.normalizeKey(key, isMac) === name);
|
|
1610
1513
|
const handler = modKey?.[1] ?? (Object.hasOwn(KEYS, name) ? KEYS[name] : void 0);
|
|
1611
1514
|
return handler?.(field) ?? null;
|
|
1612
1515
|
}
|
|
@@ -1648,13 +1551,16 @@ function selectAndFocus({ controller }, command) {
|
|
|
1648
1551
|
controller.focus();
|
|
1649
1552
|
return true;
|
|
1650
1553
|
}
|
|
1651
|
-
function travel({ controller, blockId, area }, command) {
|
|
1554
|
+
function travel({ controller, blockId, area, reveal }, command) {
|
|
1652
1555
|
const before = area.value;
|
|
1653
1556
|
controller.run(command);
|
|
1654
1557
|
const { selection } = controller.editor.state;
|
|
1655
|
-
const edit2 =
|
|
1558
|
+
const edit2 = chunkN25EH2GZ_cjs.textDiff(before, area.value);
|
|
1656
1559
|
if (selection?.kind !== "node" || selection.block !== blockId) controller.focus();
|
|
1657
|
-
else if (edit2 !== null)
|
|
1560
|
+
else if (edit2 !== null) {
|
|
1561
|
+
area.setSelectionRange(edit2.from + edit2.insert.length, edit2.from + edit2.insert.length);
|
|
1562
|
+
reveal();
|
|
1563
|
+
}
|
|
1658
1564
|
return true;
|
|
1659
1565
|
}
|
|
1660
1566
|
function runCodeAction(action, context) {
|
|
@@ -1668,13 +1574,13 @@ function runCodeAction(action, context) {
|
|
|
1668
1574
|
case "paragraph":
|
|
1669
1575
|
return selectAndFocus(context, codeToParagraph(blockId));
|
|
1670
1576
|
case "undo":
|
|
1671
|
-
return travel(context,
|
|
1577
|
+
return travel(context, chunkZ5EEDCRI_cjs.undo);
|
|
1672
1578
|
case "redo":
|
|
1673
|
-
return travel(context,
|
|
1579
|
+
return travel(context, chunkZ5EEDCRI_cjs.redo);
|
|
1674
1580
|
case "selectAll":
|
|
1675
|
-
return selectAndFocus(context,
|
|
1581
|
+
return selectAndFocus(context, chunkZ5EEDCRI_cjs.selectAll);
|
|
1676
1582
|
case "escape":
|
|
1677
|
-
return selectAndFocus(context,
|
|
1583
|
+
return selectAndFocus(context, chunkZ5EEDCRI_cjs.setSelection(chunkZ5EEDCRI_cjs.blockRangeSelection(blockId)));
|
|
1678
1584
|
case "controls":
|
|
1679
1585
|
context.focusControls();
|
|
1680
1586
|
return true;
|
|
@@ -1737,18 +1643,18 @@ function CodeEditor({ block, controller, field, focusControls }) {
|
|
|
1737
1643
|
useTypeIntoCode(controller, blockId, field, edit2);
|
|
1738
1644
|
const onKeyDown = (event) => {
|
|
1739
1645
|
const area = event.currentTarget;
|
|
1740
|
-
if (
|
|
1646
|
+
if (chunkN25EH2GZ_cjs.isComposingKey(controller, event.nativeEvent)) return;
|
|
1741
1647
|
const action = codeKeyAction(event, fieldOf(area), controller.isMac);
|
|
1742
|
-
if (action !== null && runCodeAction(action, { controller, blockId, area, edit: edit2, focusControls })) event.preventDefault();
|
|
1648
|
+
if (action !== null && runCodeAction(action, { controller, blockId, area, edit: edit2, reveal, focusControls })) event.preventDefault();
|
|
1743
1649
|
};
|
|
1744
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { ...{ [
|
|
1650
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { ...{ [chunkN25EH2GZ_cjs.NATIVE_INTERACTION]: "" }, dir: "ltr", className: "quoin-code-scroll", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "quoin-code-lines", children: [
|
|
1745
1651
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
1746
1652
|
HighlightOverlay,
|
|
1747
1653
|
{
|
|
1748
1654
|
"aria-hidden": "true",
|
|
1749
1655
|
drawnRef: drawn,
|
|
1750
|
-
code:
|
|
1751
|
-
language:
|
|
1656
|
+
code: chunk4JDRDPLC_cjs.str(block.attrs.code),
|
|
1657
|
+
language: chunk4JDRDPLC_cjs.str(block.attrs.language)
|
|
1752
1658
|
}
|
|
1753
1659
|
),
|
|
1754
1660
|
/* @__PURE__ */ jsxRuntime.jsx("span", { ref: mark, "aria-hidden": "true", className: "quoin-code-caret" }),
|
|
@@ -1758,7 +1664,7 @@ function CodeEditor({ block, controller, field, focusControls }) {
|
|
|
1758
1664
|
ref: field,
|
|
1759
1665
|
"aria-label": labels.codeText,
|
|
1760
1666
|
"aria-keyshortcuts": "Alt+F10",
|
|
1761
|
-
value:
|
|
1667
|
+
value: chunk4JDRDPLC_cjs.str(block.attrs.code),
|
|
1762
1668
|
wrap: "off",
|
|
1763
1669
|
tabIndex: -1,
|
|
1764
1670
|
spellCheck: false,
|
|
@@ -1777,6 +1683,38 @@ function CodeEditor({ block, controller, field, focusControls }) {
|
|
|
1777
1683
|
)
|
|
1778
1684
|
] }) });
|
|
1779
1685
|
}
|
|
1686
|
+
|
|
1687
|
+
// src/gutter/copy-text.ts
|
|
1688
|
+
function copyThroughTextArea(text2, doc) {
|
|
1689
|
+
const previous = doc.activeElement instanceof HTMLElement ? doc.activeElement : null;
|
|
1690
|
+
const area = doc.createElement("textarea");
|
|
1691
|
+
area.value = text2;
|
|
1692
|
+
area.readOnly = true;
|
|
1693
|
+
area.setAttribute("aria-hidden", "true");
|
|
1694
|
+
area.style.cssText = "position:fixed;top:0;left:0;width:1px;height:1px;opacity:0;pointer-events:none";
|
|
1695
|
+
const beside = previous !== null && previous !== doc.body ? previous.parentElement : null;
|
|
1696
|
+
(beside ?? doc.body).append(area);
|
|
1697
|
+
area.focus({ preventScroll: true });
|
|
1698
|
+
area.select();
|
|
1699
|
+
try {
|
|
1700
|
+
return doc.execCommand("copy");
|
|
1701
|
+
} catch {
|
|
1702
|
+
return false;
|
|
1703
|
+
} finally {
|
|
1704
|
+
area.remove();
|
|
1705
|
+
previous?.focus({ preventScroll: true });
|
|
1706
|
+
}
|
|
1707
|
+
}
|
|
1708
|
+
async function copyText(text2, doc = document) {
|
|
1709
|
+
const clipboard = doc.defaultView?.navigator.clipboard;
|
|
1710
|
+
if (clipboard === void 0) return copyThroughTextArea(text2, doc);
|
|
1711
|
+
try {
|
|
1712
|
+
await clipboard.writeText(text2);
|
|
1713
|
+
return true;
|
|
1714
|
+
} catch {
|
|
1715
|
+
return copyThroughTextArea(text2, doc);
|
|
1716
|
+
}
|
|
1717
|
+
}
|
|
1780
1718
|
var BASE = [
|
|
1781
1719
|
"inline-flex cursor-pointer items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-[color,background-color,border-color,box-shadow,opacity] disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 shrink-0",
|
|
1782
1720
|
FOCUS_RING
|
|
@@ -1811,7 +1749,7 @@ var Button = React7__namespace.forwardRef(function Button2({ className, variant
|
|
|
1811
1749
|
var COPIED_FOR_MS = 1500;
|
|
1812
1750
|
function CopyCodeButton({ code, controller }) {
|
|
1813
1751
|
const labels = useLabels();
|
|
1814
|
-
const readOnly =
|
|
1752
|
+
const readOnly = chunkN25EH2GZ_cjs.useReadOnly(controller);
|
|
1815
1753
|
const [copied, setCopied] = React7.useState(false);
|
|
1816
1754
|
React7.useEffect(() => {
|
|
1817
1755
|
if (!copied) return;
|
|
@@ -1873,10 +1811,12 @@ var PopoverAnchor = /* @__PURE__ */ React7__namespace.forwardRef(function Popove
|
|
|
1873
1811
|
return /* @__PURE__ */ jsxRuntime.jsx(PopoverPrimitive__namespace.Anchor, { ref, "data-slot": "popover-anchor", ...props });
|
|
1874
1812
|
});
|
|
1875
1813
|
var PopoverContent = /* @__PURE__ */ React7__namespace.forwardRef(function PopoverContent2({ className, align = "center", sideOffset = 4, ...props }, ref) {
|
|
1814
|
+
const dir = reactDirection.useDirection();
|
|
1876
1815
|
return /* @__PURE__ */ jsxRuntime.jsx(PopoverPrimitive__namespace.Portal, { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
1877
1816
|
PopoverPrimitive__namespace.Content,
|
|
1878
1817
|
{
|
|
1879
1818
|
ref,
|
|
1819
|
+
dir,
|
|
1880
1820
|
"data-slot": "popover-content",
|
|
1881
1821
|
align,
|
|
1882
1822
|
sideOffset,
|
|
@@ -1894,7 +1834,7 @@ var preventDefault = (event) => event.preventDefault();
|
|
|
1894
1834
|
|
|
1895
1835
|
// src/blocks/text/set-block-attrs.ts
|
|
1896
1836
|
function setBlockAttrs(controller, blockId, patch) {
|
|
1897
|
-
if (!controller.readOnly) controller.run(
|
|
1837
|
+
if (!controller.readOnly) controller.run(chunkN25EH2GZ_cjs.onBlock(blockId, chunkZ5EEDCRI_cjs.setAttrs(patch)));
|
|
1898
1838
|
}
|
|
1899
1839
|
var FIELD = `quoin-code-language quoin-code-control ${FOCUS_RING}`;
|
|
1900
1840
|
var CONTENT = `${MENU_CONTENT} flex max-h-64 w-48 flex-col overflow-y-hidden`;
|
|
@@ -1910,7 +1850,7 @@ function LanguageCombobox({ blockId, controller, language: language2, field, onD
|
|
|
1910
1850
|
const options = draft === null ? [] : languageOptions(draft === shown ? "" : draft, labels.plainText);
|
|
1911
1851
|
const open = options.length > 0;
|
|
1912
1852
|
const optionId = (index) => `${listboxId}-${index}`;
|
|
1913
|
-
|
|
1853
|
+
chunkN25EH2GZ_cjs.useIsomorphicLayoutEffect(() => {
|
|
1914
1854
|
list2.current?.querySelector('[aria-selected="true"]')?.scrollIntoView?.({ block: "nearest" });
|
|
1915
1855
|
}, [active]);
|
|
1916
1856
|
const close = () => {
|
|
@@ -1936,7 +1876,7 @@ function LanguageCombobox({ blockId, controller, language: language2, field, onD
|
|
|
1936
1876
|
onDone();
|
|
1937
1877
|
};
|
|
1938
1878
|
const onKeyDown = (event) => {
|
|
1939
|
-
if (
|
|
1879
|
+
if (chunkN25EH2GZ_cjs.isComposingKey(controller, event.nativeEvent)) return;
|
|
1940
1880
|
if (event.key === "ArrowDown" || event.key === "ArrowUp") {
|
|
1941
1881
|
event.preventDefault();
|
|
1942
1882
|
const step = event.key === "ArrowDown" ? 1 : -1;
|
|
@@ -2010,11 +1950,11 @@ function LanguageCombobox({ blockId, controller, language: language2, field, onD
|
|
|
2010
1950
|
}
|
|
2011
1951
|
var CodeBlock = ({ block, controller }) => {
|
|
2012
1952
|
const labels = useLabels();
|
|
2013
|
-
const readOnly =
|
|
1953
|
+
const readOnly = chunkN25EH2GZ_cjs.useReadOnly(controller);
|
|
2014
1954
|
const languageField = React7.useRef(null);
|
|
2015
1955
|
const codeField = React7.useRef(null);
|
|
2016
|
-
const code =
|
|
2017
|
-
const language2 =
|
|
1956
|
+
const code = chunk4JDRDPLC_cjs.str(block.attrs.code);
|
|
1957
|
+
const language2 = chunk4JDRDPLC_cjs.str(block.attrs.language);
|
|
2018
1958
|
const name = languageName(language2) ?? language2;
|
|
2019
1959
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { role: "group", "aria-label": labels.blockNames.code, contentEditable: false, className: "quoin-code", children: [
|
|
2020
1960
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "quoin-code-header", children: [
|
|
@@ -2043,6 +1983,7 @@ var CodeBlock = ({ block, controller }) => {
|
|
|
2043
1983
|
};
|
|
2044
1984
|
function FilePickerButton({ label, accept, disabled, busy = false, onPick }) {
|
|
2045
1985
|
const inputRef = React7__namespace.useRef(null);
|
|
1986
|
+
const wrapper = React7__namespace.useRef(null);
|
|
2046
1987
|
const restoreFocus = React7__namespace.useRef(false);
|
|
2047
1988
|
React7__namespace.useEffect(() => {
|
|
2048
1989
|
if (disabled || !restoreFocus.current) return;
|
|
@@ -2050,34 +1991,49 @@ function FilePickerButton({ label, accept, disabled, busy = false, onPick }) {
|
|
|
2050
1991
|
const { activeElement } = document;
|
|
2051
1992
|
if (activeElement === null || activeElement === document.body) inputRef.current?.focus();
|
|
2052
1993
|
}, [disabled]);
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
},
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
1994
|
+
React7__namespace.useEffect(() => {
|
|
1995
|
+
const doc = wrapper.current?.ownerDocument;
|
|
1996
|
+
const pressed = (event) => {
|
|
1997
|
+
if (!wrapper.current?.contains(event.target)) restoreFocus.current = false;
|
|
1998
|
+
};
|
|
1999
|
+
doc?.addEventListener("pointerdown", pressed, true);
|
|
2000
|
+
return () => doc?.removeEventListener("pointerdown", pressed, true);
|
|
2001
|
+
}, []);
|
|
2002
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
2003
|
+
"span",
|
|
2004
|
+
{
|
|
2005
|
+
ref: wrapper,
|
|
2006
|
+
className: "relative inline-flex rounded-md has-[:focus-visible]:outline-2 has-[:focus-visible]:outline-offset-2 has-[:focus-visible]:outline-[var(--quoin-ring)]",
|
|
2007
|
+
children: [
|
|
2008
|
+
/* @__PURE__ */ jsxRuntime.jsx(Button, { asChild: true, variant: "outline", size: "sm", children: /* @__PURE__ */ jsxRuntime.jsxs("span", { "aria-hidden": "true", className: disabled || busy ? "pointer-events-none opacity-50" : void 0, children: [
|
|
2009
|
+
/* @__PURE__ */ jsxRuntime.jsx(Upload, { "aria-hidden": "true" }),
|
|
2010
|
+
label
|
|
2011
|
+
] }) }),
|
|
2012
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
2013
|
+
"input",
|
|
2014
|
+
{
|
|
2015
|
+
ref: inputRef,
|
|
2016
|
+
type: "file",
|
|
2017
|
+
accept,
|
|
2018
|
+
"aria-label": label,
|
|
2019
|
+
disabled,
|
|
2020
|
+
"aria-disabled": busy || void 0,
|
|
2021
|
+
className: "absolute inset-0 cursor-pointer opacity-0 disabled:cursor-not-allowed aria-disabled:cursor-not-allowed",
|
|
2022
|
+
onClick: (e) => {
|
|
2023
|
+
if (busy) e.preventDefault();
|
|
2024
|
+
},
|
|
2025
|
+
onChange: (e) => {
|
|
2026
|
+
const file = e.target.files?.[0];
|
|
2027
|
+
e.target.value = "";
|
|
2028
|
+
if (!file || busy) return;
|
|
2029
|
+
restoreFocus.current = true;
|
|
2030
|
+
onPick(file);
|
|
2031
|
+
}
|
|
2032
|
+
}
|
|
2033
|
+
)
|
|
2034
|
+
]
|
|
2035
|
+
}
|
|
2036
|
+
);
|
|
2081
2037
|
}
|
|
2082
2038
|
|
|
2083
2039
|
// src/blocks/void/interactive-target.ts
|
|
@@ -2112,7 +2068,7 @@ function selectHandlers(controller, blockId, root, onSelect) {
|
|
|
2112
2068
|
return {
|
|
2113
2069
|
onKeyDown(event) {
|
|
2114
2070
|
const key = event.nativeEvent;
|
|
2115
|
-
if (
|
|
2071
|
+
if (chunkN25EH2GZ_cjs.isComposingKey(controller, key)) return;
|
|
2116
2072
|
if (event.key === "Escape") select();
|
|
2117
2073
|
else if (!(event.metaKey || event.ctrlKey) || event.target.matches("input:not([type=file])") || !controller.edit(() => controller.editor.handleKey(key)))
|
|
2118
2074
|
return;
|
|
@@ -2124,6 +2080,29 @@ function selectHandlers(controller, blockId, root, onSelect) {
|
|
|
2124
2080
|
}
|
|
2125
2081
|
};
|
|
2126
2082
|
}
|
|
2083
|
+
|
|
2084
|
+
// src/blocks/upload/upload-targets.ts
|
|
2085
|
+
var targets = /* @__PURE__ */ new WeakMap();
|
|
2086
|
+
function offerUploadTarget(controller, blockId, target) {
|
|
2087
|
+
const offered = targets.get(controller) ?? /* @__PURE__ */ new Map();
|
|
2088
|
+
targets.set(controller, offered.set(blockId, target));
|
|
2089
|
+
return () => {
|
|
2090
|
+
if (offered.get(blockId) === target) offered.delete(blockId);
|
|
2091
|
+
};
|
|
2092
|
+
}
|
|
2093
|
+
function fillSelectedBlock(controller, files) {
|
|
2094
|
+
const { selection } = controller.editor.state;
|
|
2095
|
+
const target = selection?.kind === "node" ? targets.get(controller)?.get(selection.block) : void 0;
|
|
2096
|
+
const taken = target && files.find((file) => target.takes(file));
|
|
2097
|
+
if (taken === void 0) return files;
|
|
2098
|
+
target.start(taken);
|
|
2099
|
+
return files.filter((file) => file !== taken);
|
|
2100
|
+
}
|
|
2101
|
+
|
|
2102
|
+
// src/upload/upload-error.ts
|
|
2103
|
+
var uploadError = (cause, failed) => cause instanceof Error && cause.message ? cause : new Error(failed);
|
|
2104
|
+
|
|
2105
|
+
// src/blocks/upload/use-block-upload.ts
|
|
2127
2106
|
var IDLE = { busy: false, error: "" };
|
|
2128
2107
|
function useBlockUpload(controller, blockId, area, uploader) {
|
|
2129
2108
|
const { upload, resolveAssetUrl, onError, labels } = useQuoin();
|
|
@@ -2137,12 +2116,13 @@ function useBlockUpload(controller, blockId, area, uploader) {
|
|
|
2137
2116
|
if (started.current === run) setState(next);
|
|
2138
2117
|
};
|
|
2139
2118
|
setState({ busy: true, error: "" });
|
|
2119
|
+
controller.announce(labels.uploading);
|
|
2140
2120
|
const onLand = () => {
|
|
2141
2121
|
if (area.current?.contains(area.current.ownerDocument.activeElement)) focusNode(controller, blockId);
|
|
2142
2122
|
};
|
|
2143
2123
|
uploader(controller, blockId, file, { upload, resolveAssetUrl, onLand }).then(
|
|
2144
2124
|
() => settle2(IDLE),
|
|
2145
|
-
(cause) => settle2({ busy: false, error: cause
|
|
2125
|
+
(cause) => settle2({ busy: false, error: uploadError(cause, labels.uploadFailed).message })
|
|
2146
2126
|
);
|
|
2147
2127
|
},
|
|
2148
2128
|
[controller, blockId, area, uploader, upload, resolveAssetUrl, onError, labels]
|
|
@@ -2167,6 +2147,7 @@ function UploadArea(props) {
|
|
|
2167
2147
|
element?.addEventListener("drop", onDrop);
|
|
2168
2148
|
return () => element?.removeEventListener("drop", onDrop);
|
|
2169
2149
|
}, [start, takes]);
|
|
2150
|
+
React7.useEffect(() => offerUploadTarget(controller, blockId, { takes, start }), [controller, blockId, takes, start]);
|
|
2170
2151
|
const onPaste = (event) => {
|
|
2171
2152
|
const file = fileIn(event.clipboardData, takes);
|
|
2172
2153
|
if (file === void 0) return;
|
|
@@ -2187,7 +2168,7 @@ function UploadArea(props) {
|
|
|
2187
2168
|
] }),
|
|
2188
2169
|
children,
|
|
2189
2170
|
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "quoin-block-message", children: upload ? hint : labels.uploadsUnavailable }),
|
|
2190
|
-
/* @__PURE__ */ jsxRuntime.jsx("p", {
|
|
2171
|
+
busy && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "quoin-block-message", children: labels.uploading }),
|
|
2191
2172
|
error !== "" && /* @__PURE__ */ jsxRuntime.jsx("p", { role: "alert", className: "quoin-block-message text-destructive", children: error })
|
|
2192
2173
|
]
|
|
2193
2174
|
}
|
|
@@ -2195,8 +2176,8 @@ function UploadArea(props) {
|
|
|
2195
2176
|
}
|
|
2196
2177
|
var CONTROL = "input:not([disabled]), button:not([disabled])";
|
|
2197
2178
|
var typed = (event) => !event.ctrlKey && !event.metaKey && [...event.key].length === 1;
|
|
2198
|
-
function useNodeKeys(controller, blockId, editable,
|
|
2199
|
-
const { editing, stop } = useVoidEditing(controller, blockId, editable &&
|
|
2179
|
+
function useNodeKeys(controller, blockId, editable, opens2, root, { enter, type } = {}) {
|
|
2180
|
+
const { editing, stop } = useVoidEditing(controller, blockId, editable && opens2);
|
|
2200
2181
|
React7.useEffect(() => {
|
|
2201
2182
|
if (!editing) return;
|
|
2202
2183
|
stop();
|
|
@@ -2216,7 +2197,7 @@ function useNodeKeys(controller, blockId, editable, opens, root, { enter, type }
|
|
|
2216
2197
|
}, [controller, blockId, editable, type]);
|
|
2217
2198
|
}
|
|
2218
2199
|
|
|
2219
|
-
// src/
|
|
2200
|
+
// src/toolbar/bubble-part.ts
|
|
2220
2201
|
var BUBBLE_PART = "data-quoin-bubble";
|
|
2221
2202
|
var partIds = /* @__PURE__ */ new WeakMap();
|
|
2222
2203
|
var created = 0;
|
|
@@ -2252,16 +2233,16 @@ var kindOf = (value) => KINDS.find(([, pattern]) => pattern.test(value))?.[0];
|
|
|
2252
2233
|
var fileIcon = (mime, filename) => kindOf(mime.toLowerCase()) ?? kindOf(/\.([^.]+)$/.exec(filename)?.[1].toLowerCase() ?? "") ?? FileIcon;
|
|
2253
2234
|
|
|
2254
2235
|
// src/blocks/file/file-source.ts
|
|
2255
|
-
var fileName = (attrs) =>
|
|
2236
|
+
var fileName = (attrs) => chunk4JDRDPLC_cjs.str(attrs.filename) || chunk4JDRDPLC_cjs.str(attrs.storageKey);
|
|
2256
2237
|
var hasFile = (attrs) => fileName(attrs) !== "";
|
|
2257
2238
|
function FileCard({ block, controller, readOnly }) {
|
|
2258
2239
|
const { labels, resolveAssetUrl } = useQuoin();
|
|
2259
2240
|
const card = React7.useRef(null);
|
|
2260
2241
|
const { id, attrs } = block;
|
|
2261
2242
|
const name = fileName(attrs);
|
|
2262
|
-
const size =
|
|
2263
|
-
const href = assetHref(resolveAssetUrl,
|
|
2264
|
-
const Icon2 = fileIcon(
|
|
2243
|
+
const size = chunk4JDRDPLC_cjs.optionalNumber(attrs.size);
|
|
2244
|
+
const href = assetHref(resolveAssetUrl, chunk4JDRDPLC_cjs.str(attrs.storageKey));
|
|
2245
|
+
const Icon2 = fileIcon(chunk4JDRDPLC_cjs.str(attrs.mime), name);
|
|
2265
2246
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { ref: card, className: "quoin-file-card", ...selectHandlers(controller, id, card), children: [
|
|
2266
2247
|
/* @__PURE__ */ jsxRuntime.jsx(Icon2, { "aria-hidden": "true", className: "quoin-file-icon" }),
|
|
2267
2248
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "quoin-file-name", children: name }),
|
|
@@ -2270,7 +2251,7 @@ function FileCard({ block, controller, readOnly }) {
|
|
|
2270
2251
|
"a",
|
|
2271
2252
|
{
|
|
2272
2253
|
href,
|
|
2273
|
-
download:
|
|
2254
|
+
download: chunk4JDRDPLC_cjs.str(attrs.filename),
|
|
2274
2255
|
target: "_blank",
|
|
2275
2256
|
rel: "noopener",
|
|
2276
2257
|
"aria-label": labels.downloadFile(name),
|
|
@@ -2296,21 +2277,22 @@ function claimUpload(controller, blockId) {
|
|
|
2296
2277
|
}
|
|
2297
2278
|
var isNewestUpload = (controller, blockId, token) => newestUploads.get(controller)?.get(blockId) === token;
|
|
2298
2279
|
function assetOf(controller, blockId, type) {
|
|
2299
|
-
const block =
|
|
2280
|
+
const block = chunk4JDRDPLC_cjs.blockById(controller.editor.state.doc, blockId);
|
|
2300
2281
|
if (block?.type !== type || controller.readOnly) return null;
|
|
2301
|
-
return { url:
|
|
2282
|
+
return { url: chunk4JDRDPLC_cjs.str(block.attrs.url), storageKey: chunk4JDRDPLC_cjs.str(block.attrs.storageKey) };
|
|
2302
2283
|
}
|
|
2284
|
+
var isStored = (stored) => typeof stored?.storageKey === "string" && stored.storageKey !== "";
|
|
2303
2285
|
var sameAsset = (a, b) => a !== null && b !== null && a.url === b.url && a.storageKey === b.storageKey;
|
|
2304
2286
|
function writeAttrs(controller, blockId, patch, recorded) {
|
|
2305
2287
|
const { editor } = controller;
|
|
2306
|
-
const tr = editor.createTransaction().step(
|
|
2288
|
+
const tr = editor.createTransaction().step(chunkZ5EEDCRI_cjs.setAttrsStep(blockId, patch));
|
|
2307
2289
|
editor.dispatch(recorded ? tr : tr.setMeta("addToHistory", false));
|
|
2308
2290
|
}
|
|
2309
2291
|
async function uploadInto(controller, blockId, file, { type, category }, { upload, onLand }, land2) {
|
|
2310
2292
|
const token = claimUpload(controller, blockId);
|
|
2311
2293
|
const before = assetOf(controller, blockId, type);
|
|
2312
2294
|
const stored = await upload(file, category);
|
|
2313
|
-
if (
|
|
2295
|
+
if (!isStored(stored)) throw new Error();
|
|
2314
2296
|
if (!isNewestUpload(controller, blockId, token) || !sameAsset(assetOf(controller, blockId, type), before)) return;
|
|
2315
2297
|
onLand?.();
|
|
2316
2298
|
await land2(stored, token);
|
|
@@ -2334,7 +2316,7 @@ var uploadFile = (controller, blockId, file, host) => uploadInto(
|
|
|
2334
2316
|
var anyFile = () => true;
|
|
2335
2317
|
var FileBlock = ({ block, controller }) => {
|
|
2336
2318
|
const labels = useLabels();
|
|
2337
|
-
const readOnly =
|
|
2319
|
+
const readOnly = chunkN25EH2GZ_cjs.useReadOnly(controller);
|
|
2338
2320
|
const root = React7.useRef(null);
|
|
2339
2321
|
const filled = hasFile(block.attrs);
|
|
2340
2322
|
useNodeKeys(controller, block.id, !readOnly, !filled, root);
|
|
@@ -2360,7 +2342,7 @@ function useReplacePicker(controller, blockId, uploader, accept) {
|
|
|
2360
2342
|
if (file === void 0 || !upload) return;
|
|
2361
2343
|
controller.announce(labels.uploading);
|
|
2362
2344
|
uploader(controller, blockId, file, { upload, resolveAssetUrl }).catch(
|
|
2363
|
-
(cause) => onError(cause
|
|
2345
|
+
(cause) => onError(uploadError(cause, labels.uploadFailed))
|
|
2364
2346
|
);
|
|
2365
2347
|
};
|
|
2366
2348
|
return {
|
|
@@ -2400,7 +2382,7 @@ function usePartAnchor(controller, blockId, selector) {
|
|
|
2400
2382
|
// src/blocks/void/node-toolbar-items.ts
|
|
2401
2383
|
var replaceItem = (title, run) => run ? [{ id: "replace", title, icon: Upload, run }] : [];
|
|
2402
2384
|
function deleteBlock(controller, blockId) {
|
|
2403
|
-
runOnBlocks(controller, [blockId],
|
|
2385
|
+
runOnBlocks(controller, [blockId], chunkZ5EEDCRI_cjs.deleteBlocks);
|
|
2404
2386
|
controller.focus();
|
|
2405
2387
|
}
|
|
2406
2388
|
var deleteItem = (blockId, title) => ({
|
|
@@ -2410,37 +2392,10 @@ var deleteItem = (blockId, title) => ({
|
|
|
2410
2392
|
run: (controller) => deleteBlock(controller, blockId)
|
|
2411
2393
|
});
|
|
2412
2394
|
var PRESSED = "aria-pressed:bg-accent aria-pressed:text-accent-foreground";
|
|
2413
|
-
function markItem(mark, title, icon) {
|
|
2414
|
-
return {
|
|
2415
|
-
id: mark,
|
|
2416
|
-
title,
|
|
2417
|
-
icon,
|
|
2418
|
-
isActive: (state) => chunkFK7EBZPX_cjs.isActive(state, mark),
|
|
2419
|
-
run: (controller) => void controller.run(chunkFK7EBZPX_cjs.toggleMark(mark))
|
|
2420
|
-
};
|
|
2421
|
-
}
|
|
2422
|
-
var linkItem = (labels, openLink) => ({
|
|
2423
|
-
id: "link",
|
|
2424
|
-
title: labels.link,
|
|
2425
|
-
icon: Link,
|
|
2426
|
-
run: openLink
|
|
2427
|
-
});
|
|
2428
|
-
function bubbleItems(labels, openLink) {
|
|
2429
|
-
return {
|
|
2430
|
-
inline: [
|
|
2431
|
-
markItem("bold", labels.bold, Bold),
|
|
2432
|
-
markItem("italic", labels.italic, Italic),
|
|
2433
|
-
markItem("underline", labels.underline, Underline),
|
|
2434
|
-
markItem("strike", labels.strike, Strikethrough),
|
|
2435
|
-
markItem("code", labels.code, Code),
|
|
2436
|
-
linkItem(labels, openLink)
|
|
2437
|
-
],
|
|
2438
|
-
scripts: [markItem("sub", labels.subscript, Subscript), markItem("sup", labels.superscript, Superscript)]
|
|
2439
|
-
};
|
|
2440
|
-
}
|
|
2441
2395
|
function ToolbarButton({ item, state, controller, buttonRef }) {
|
|
2442
2396
|
if (item.available?.(state) === false) return null;
|
|
2443
2397
|
const Icon2 = item.icon;
|
|
2398
|
+
const disabled = item.enabled?.(state) === false;
|
|
2444
2399
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
2445
2400
|
Button,
|
|
2446
2401
|
{
|
|
@@ -2450,8 +2405,12 @@ function ToolbarButton({ item, state, controller, buttonRef }) {
|
|
|
2450
2405
|
size: "icon-sm",
|
|
2451
2406
|
"aria-label": item.title,
|
|
2452
2407
|
"aria-pressed": item.isActive?.(state),
|
|
2408
|
+
"aria-haspopup": item.opensDialog ? "dialog" : void 0,
|
|
2409
|
+
"aria-disabled": disabled || void 0,
|
|
2453
2410
|
className: PRESSED,
|
|
2454
|
-
onClick: () =>
|
|
2411
|
+
onClick: () => {
|
|
2412
|
+
if (!disabled) item.run(controller);
|
|
2413
|
+
},
|
|
2455
2414
|
children: /* @__PURE__ */ jsxRuntime.jsx(Icon2, {})
|
|
2456
2415
|
}
|
|
2457
2416
|
);
|
|
@@ -2486,7 +2445,7 @@ function useRovingFocus() {
|
|
|
2486
2445
|
},
|
|
2487
2446
|
[syncTabStop]
|
|
2488
2447
|
);
|
|
2489
|
-
|
|
2448
|
+
chunkN25EH2GZ_cjs.useIsomorphicLayoutEffect(syncTabStop);
|
|
2490
2449
|
const onFocus = (event) => {
|
|
2491
2450
|
if (!owns(event.target)) return;
|
|
2492
2451
|
current.current = event.target;
|
|
@@ -2495,7 +2454,7 @@ function useRovingFocus() {
|
|
|
2495
2454
|
const onKeyDown = (event) => {
|
|
2496
2455
|
const all = items();
|
|
2497
2456
|
const index = all.indexOf(event.target);
|
|
2498
|
-
const key = row.current === null ? event.key :
|
|
2457
|
+
const key = row.current === null ? event.key : chunkN25EH2GZ_cjs.arrowAsWritten(event.key, chunkN25EH2GZ_cjs.inlineDirection(row.current));
|
|
2499
2458
|
if (index === -1 || !Object.hasOwn(MOVES, key)) return;
|
|
2500
2459
|
event.preventDefault();
|
|
2501
2460
|
all[MOVES[key](index, all.length)].focus();
|
|
@@ -2506,7 +2465,7 @@ function useRovingFocus() {
|
|
|
2506
2465
|
// src/menus/floating/use-focus-key.ts
|
|
2507
2466
|
var isFocusKey = (event) => event.key === "F10" && event.altKey && !event.ctrlKey && !event.metaKey && !event.shiftKey;
|
|
2508
2467
|
function useFocusKey(controller, focus) {
|
|
2509
|
-
|
|
2468
|
+
chunkN25EH2GZ_cjs.useIsomorphicLayoutEffect(() => {
|
|
2510
2469
|
const intercept = (event) => {
|
|
2511
2470
|
if (!isFocusKey(event)) return false;
|
|
2512
2471
|
event.preventDefault();
|
|
@@ -2518,11 +2477,11 @@ function useFocusKey(controller, focus) {
|
|
|
2518
2477
|
}
|
|
2519
2478
|
function NodeToolbar(props) {
|
|
2520
2479
|
const { blockId, controller, label, anchor, items, next, buttonRefs, children, popover } = props;
|
|
2521
|
-
const state =
|
|
2480
|
+
const state = chunkN25EH2GZ_cjs.useEditorState(controller, chunkN25EH2GZ_cjs.wholeState);
|
|
2522
2481
|
const roving = useRovingFocus();
|
|
2523
2482
|
useFocusKey(controller, roving.focusCurrent);
|
|
2524
2483
|
const onKeyDown = (event) => {
|
|
2525
|
-
if (!roving.owns(event.target) ||
|
|
2484
|
+
if (!roving.owns(event.target) || chunkN25EH2GZ_cjs.isComposingKey(controller, event.nativeEvent)) return;
|
|
2526
2485
|
const tab = event.key === "Tab" && !event.altKey && !event.ctrlKey && !event.metaKey;
|
|
2527
2486
|
const ahead = tab && !event.shiftKey && next !== void 0 ? blockPart(controller, blockId, next) : void 0;
|
|
2528
2487
|
if (ahead !== void 0) ahead.focus();
|
|
@@ -2560,10 +2519,12 @@ function createSettled(controller) {
|
|
|
2560
2519
|
let pressed = false;
|
|
2561
2520
|
let composing = false;
|
|
2562
2521
|
const inEditor = (event) => event.target instanceof Node && controller.root?.contains(event.target) === true;
|
|
2522
|
+
const release = () => void (pressed = false);
|
|
2563
2523
|
const handlers = {
|
|
2564
2524
|
pointerdown: (event) => void (pressed ||= inEditor(event)),
|
|
2565
|
-
pointerup:
|
|
2566
|
-
pointercancel:
|
|
2525
|
+
pointerup: release,
|
|
2526
|
+
pointercancel: release,
|
|
2527
|
+
dragend: release,
|
|
2567
2528
|
compositionstart: (event) => void (composing ||= inEditor(event)),
|
|
2568
2529
|
compositionend: () => void (composing = false),
|
|
2569
2530
|
focusin: () => {
|
|
@@ -2584,9 +2545,27 @@ function createSettled(controller) {
|
|
|
2584
2545
|
doc.addEventListener(type, listener, true);
|
|
2585
2546
|
return () => doc.removeEventListener(type, listener, true);
|
|
2586
2547
|
});
|
|
2548
|
+
const timers = /* @__PURE__ */ new Set();
|
|
2549
|
+
const afterView = () => {
|
|
2550
|
+
const timer = setTimeout(() => {
|
|
2551
|
+
timers.delete(timer);
|
|
2552
|
+
notify();
|
|
2553
|
+
}, 0);
|
|
2554
|
+
timers.add(timer);
|
|
2555
|
+
};
|
|
2556
|
+
const stopDoc = chunkN25EH2GZ_cjs.listen(doc, { compositionend: afterView });
|
|
2557
|
+
const onWindowBlur = () => {
|
|
2558
|
+
release();
|
|
2559
|
+
notify();
|
|
2560
|
+
};
|
|
2561
|
+
const stopWindow = doc.defaultView ? chunkN25EH2GZ_cjs.listen(doc.defaultView, { blur: onWindowBlur }) : () => {
|
|
2562
|
+
};
|
|
2587
2563
|
const stopState = controller.editor.subscribe(() => notify());
|
|
2588
2564
|
return () => {
|
|
2589
2565
|
listeners2.forEach((remove) => remove());
|
|
2566
|
+
timers.forEach(clearTimeout);
|
|
2567
|
+
stopDoc();
|
|
2568
|
+
stopWindow();
|
|
2590
2569
|
stopState();
|
|
2591
2570
|
};
|
|
2592
2571
|
}
|
|
@@ -2600,12 +2579,12 @@ function useSelectionSettled(controller) {
|
|
|
2600
2579
|
|
|
2601
2580
|
// src/blocks/void/use-toolbar-block.ts
|
|
2602
2581
|
var selectedBlock = (type, filled) => ({ doc, selection }) => {
|
|
2603
|
-
const block = selection?.kind === "node" ?
|
|
2582
|
+
const block = selection?.kind === "node" ? chunk4JDRDPLC_cjs.blockById(doc, selection.block) : void 0;
|
|
2604
2583
|
return block?.type === type && filled(block.attrs) ? block.id : null;
|
|
2605
2584
|
};
|
|
2606
2585
|
function useToolbarBlock(controller, selected, keptFor = null) {
|
|
2607
|
-
const blockId =
|
|
2608
|
-
const readOnly =
|
|
2586
|
+
const blockId = chunkN25EH2GZ_cjs.useEditorState(controller, selected);
|
|
2587
|
+
const readOnly = chunkN25EH2GZ_cjs.useReadOnly(controller);
|
|
2609
2588
|
const settled = useSelectionSettled(controller);
|
|
2610
2589
|
return blockId !== null && !readOnly && (settled || keptFor === blockId) ? blockId : null;
|
|
2611
2590
|
}
|
|
@@ -2645,6 +2624,23 @@ function requestAlt(controller, blockId) {
|
|
|
2645
2624
|
listeners.get(controller)?.(blockId);
|
|
2646
2625
|
}
|
|
2647
2626
|
|
|
2627
|
+
// src/blocks/image/owed-size.ts
|
|
2628
|
+
var owedSizes = /* @__PURE__ */ new WeakMap();
|
|
2629
|
+
var showsKey = (controller, blockId, storageKey) => sameAsset(assetOf(controller, blockId, "IMAGE"), { url: "", storageKey });
|
|
2630
|
+
function writeSize(controller, blockId, measured) {
|
|
2631
|
+
if (!isNewestUpload(controller, blockId, measured.token)) return;
|
|
2632
|
+
if (showsKey(controller, blockId, measured.storageKey)) writeAttrs(controller, blockId, { ...measured.size }, false);
|
|
2633
|
+
else owedSizes.set(controller, (owedSizes.get(controller) ?? /* @__PURE__ */ new Map()).set(blockId, measured));
|
|
2634
|
+
}
|
|
2635
|
+
function payOwedSize(controller, blockId) {
|
|
2636
|
+
const owing = owedSizes.get(controller);
|
|
2637
|
+
const owed = owing?.get(blockId);
|
|
2638
|
+
if (owed === void 0 || !showsKey(controller, blockId, owed.storageKey)) return;
|
|
2639
|
+
owing.delete(blockId);
|
|
2640
|
+
const unsized = chunk4JDRDPLC_cjs.blockById(controller.editor.state.doc, blockId)?.attrs.width === void 0;
|
|
2641
|
+
if (unsized && isNewestUpload(controller, blockId, owed.token)) writeAttrs(controller, blockId, { ...owed.size }, false);
|
|
2642
|
+
}
|
|
2643
|
+
|
|
2648
2644
|
// src/blocks/image/resize-width.ts
|
|
2649
2645
|
var MIN_WIDTH = 10;
|
|
2650
2646
|
var MAX_WIDTH = 100;
|
|
@@ -2684,7 +2680,7 @@ function ResizeHandles({ blockId, controller, frame, percent, centred, onPreview
|
|
|
2684
2680
|
const value = percent ?? drawn;
|
|
2685
2681
|
const write = (widthPercent) => setBlockAttrs(controller, blockId, { widthPercent });
|
|
2686
2682
|
const onKeyDown = (event) => {
|
|
2687
|
-
if (
|
|
2683
|
+
if (chunkN25EH2GZ_cjs.isComposingKey(controller, event.nativeEvent)) return;
|
|
2688
2684
|
const next = keyedWidth(event.key, value);
|
|
2689
2685
|
if (event.key === "Escape") controller.focus();
|
|
2690
2686
|
else if (next === null) return;
|
|
@@ -2726,7 +2722,7 @@ function ResizeHandles({ blockId, controller, frame, percent, centred, onPreview
|
|
|
2726
2722
|
"aria-valuetext": labels.widthValue(value),
|
|
2727
2723
|
"data-side": side,
|
|
2728
2724
|
className: "quoin-image-handle",
|
|
2729
|
-
...{ [
|
|
2725
|
+
...{ [chunkN25EH2GZ_cjs.NATIVE_INTERACTION]: "" },
|
|
2730
2726
|
...bubblePart(controller),
|
|
2731
2727
|
onKeyDown,
|
|
2732
2728
|
onPointerDown: onPointerDown(side),
|
|
@@ -2747,15 +2743,16 @@ function ImageFigure({ block, controller, readOnly }) {
|
|
|
2747
2743
|
const [failed, setFailed] = React7.useState(null);
|
|
2748
2744
|
const { id, attrs, regions } = block;
|
|
2749
2745
|
const src = imageSource(attrs, resolveAssetUrl);
|
|
2750
|
-
const alt =
|
|
2746
|
+
const alt = chunk4JDRDPLC_cjs.str(attrs.alt);
|
|
2751
2747
|
const name = alt || labels.imageNoAlt;
|
|
2752
|
-
const percent =
|
|
2748
|
+
const percent = chunk4JDRDPLC_cjs.optionalNumber(attrs.widthPercent);
|
|
2753
2749
|
const width = preview ?? percent;
|
|
2754
2750
|
const flagged = !readOnly && alt === "" && attrs.decorative !== true;
|
|
2755
2751
|
const select = () => focusNode(controller, id);
|
|
2756
2752
|
const badgeText = labels.noAltBadge ?? englishLabels.noAltBadge;
|
|
2757
2753
|
const badgeName = labels.addAltText ?? englishLabels.addAltText;
|
|
2758
2754
|
const translatedAlone = badgeText !== englishLabels.noAltBadge && badgeName === englishLabels.addAltText;
|
|
2755
|
+
React7.useEffect(() => payOwedSize(controller, id), [controller, id, attrs.storageKey]);
|
|
2759
2756
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
2760
2757
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { ref: frame, className: "quoin-image-frame", style: width === void 0 ? void 0 : { width: `${width}%` }, children: [
|
|
2761
2758
|
src !== null && src !== failed ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -2763,8 +2760,8 @@ function ImageFigure({ block, controller, readOnly }) {
|
|
|
2763
2760
|
{
|
|
2764
2761
|
src,
|
|
2765
2762
|
alt: name,
|
|
2766
|
-
width:
|
|
2767
|
-
height:
|
|
2763
|
+
width: chunk4JDRDPLC_cjs.optionalNumber(attrs.width),
|
|
2764
|
+
height: chunk4JDRDPLC_cjs.optionalNumber(attrs.height),
|
|
2768
2765
|
draggable: false,
|
|
2769
2766
|
onError: () => setFailed(src),
|
|
2770
2767
|
onClick: select
|
|
@@ -2799,7 +2796,7 @@ function ImageFigure({ block, controller, readOnly }) {
|
|
|
2799
2796
|
)
|
|
2800
2797
|
] }),
|
|
2801
2798
|
(!readOnly || (regions.caption?.length ?? 0) > 0) && /* @__PURE__ */ jsxRuntime.jsx(
|
|
2802
|
-
|
|
2799
|
+
chunkN25EH2GZ_cjs.EditableRegion,
|
|
2803
2800
|
{
|
|
2804
2801
|
block: id,
|
|
2805
2802
|
region: "caption",
|
|
@@ -2812,18 +2809,20 @@ function ImageFigure({ block, controller, readOnly }) {
|
|
|
2812
2809
|
}
|
|
2813
2810
|
|
|
2814
2811
|
// src/menus/link/link-address.ts
|
|
2815
|
-
var
|
|
2816
|
-
var EMAIL = /^[
|
|
2812
|
+
var DOMAIN_START = /^[^/#?.]/;
|
|
2813
|
+
var EMAIL = /^[^@/]+@([^@/]+)$/;
|
|
2817
2814
|
var WHITESPACE = /\s/;
|
|
2815
|
+
var isEmail = (address) => EMAIL.exec(address)?.[1].slice(1, -1).includes(".") === true;
|
|
2816
|
+
var isBareDomain = (address) => DOMAIN_START.test(address) && address.includes(".", 1);
|
|
2818
2817
|
function scheme(address) {
|
|
2819
|
-
if (
|
|
2820
|
-
return
|
|
2818
|
+
if (isEmail(address)) return `mailto:${address}`;
|
|
2819
|
+
return isBareDomain(address) ? `https://${address}` : address;
|
|
2821
2820
|
}
|
|
2822
2821
|
function linkAddress(typed2) {
|
|
2823
2822
|
const address = typed2.trim();
|
|
2824
2823
|
if (WHITESPACE.test(address)) return null;
|
|
2825
|
-
const completed =
|
|
2826
|
-
const href =
|
|
2824
|
+
const completed = chunk4JDRDPLC_cjs.SCHEME.test(address) ? address : scheme(address);
|
|
2825
|
+
const href = chunk4JDRDPLC_cjs.sanitizeHref(completed);
|
|
2827
2826
|
return href || null;
|
|
2828
2827
|
}
|
|
2829
2828
|
var Input = React7__namespace.forwardRef(function Input2({ className, type, ...props }, ref) {
|
|
@@ -2897,9 +2896,7 @@ var isImageFile = (file) => file.type.startsWith("image/");
|
|
|
2897
2896
|
async function measureImage(controller, blockId, storageKey, resolveAssetUrl, token = claimUpload(controller, blockId)) {
|
|
2898
2897
|
const src = assetHref(resolveAssetUrl, storageKey);
|
|
2899
2898
|
const size = src === null ? null : await intrinsicSize(src);
|
|
2900
|
-
if (size
|
|
2901
|
-
writeAttrs(controller, blockId, { ...size }, false);
|
|
2902
|
-
}
|
|
2899
|
+
if (size) writeSize(controller, blockId, { storageKey, size, token });
|
|
2903
2900
|
}
|
|
2904
2901
|
var uploadImage = (controller, blockId, file, host) => uploadInto(controller, blockId, file, { type: "IMAGE", category: "image" }, host, async ({ storageKey }, token) => {
|
|
2905
2902
|
writeAttrs(controller, blockId, { storageKey, url: void 0, width: void 0, height: void 0 }, true);
|
|
@@ -2929,8 +2926,8 @@ function ImageUploadArea({ blockId, controller }) {
|
|
|
2929
2926
|
);
|
|
2930
2927
|
}
|
|
2931
2928
|
function captionEnd(controller, blockId) {
|
|
2932
|
-
const caption =
|
|
2933
|
-
return { block: blockId, region: "caption", offset:
|
|
2929
|
+
const caption = chunk4JDRDPLC_cjs.blockById(controller.editor.state.doc, blockId)?.regions.caption ?? [];
|
|
2930
|
+
return { block: blockId, region: "caption", offset: chunk4JDRDPLC_cjs.inlineLength(caption) };
|
|
2934
2931
|
}
|
|
2935
2932
|
var plainEnter = (event) => event.key === "Enter" && !event.shiftKey && !event.altKey && !event.ctrlKey && !event.metaKey;
|
|
2936
2933
|
var menuOpenOn = (host) => host?.getAttribute("aria-expanded") === "true";
|
|
@@ -2942,7 +2939,7 @@ function useImageKeys(controller, blockId, picture, editable, root) {
|
|
|
2942
2939
|
// then follows.
|
|
2943
2940
|
enter() {
|
|
2944
2941
|
const { editor } = controller;
|
|
2945
|
-
editor.dispatch(editor.createTransaction().setSelection(
|
|
2942
|
+
editor.dispatch(editor.createTransaction().setSelection(chunkZ5EEDCRI_cjs.textSelection(captionEnd(controller, blockId))));
|
|
2946
2943
|
controller.focus();
|
|
2947
2944
|
},
|
|
2948
2945
|
type(key) {
|
|
@@ -2967,7 +2964,7 @@ function useImageKeys(controller, blockId, picture, editable, root) {
|
|
|
2967
2964
|
}
|
|
2968
2965
|
var ImageBlock = ({ block, controller }) => {
|
|
2969
2966
|
const labels = useLabels();
|
|
2970
|
-
const readOnly =
|
|
2967
|
+
const readOnly = chunkN25EH2GZ_cjs.useReadOnly(controller);
|
|
2971
2968
|
const root = React7.useRef(null);
|
|
2972
2969
|
const picture = hasPicture(block.attrs);
|
|
2973
2970
|
useImageKeys(controller, block.id, picture, !readOnly, root);
|
|
@@ -2980,17 +2977,39 @@ var ImageBlock = ({ block, controller }) => {
|
|
|
2980
2977
|
"aria-label": labels.blockNames.image,
|
|
2981
2978
|
contentEditable: false,
|
|
2982
2979
|
className: "quoin-image",
|
|
2983
|
-
...picture ? { [
|
|
2980
|
+
...picture ? { [chunkN25EH2GZ_cjs.NODE_ENTRY]: "" } : void 0,
|
|
2984
2981
|
children: picture ? /* @__PURE__ */ jsxRuntime.jsx(ImageFigure, { block, controller, readOnly }) : empty
|
|
2985
2982
|
}
|
|
2986
2983
|
);
|
|
2987
2984
|
};
|
|
2985
|
+
function useClosing(controller, { store, onClose, onReturn }) {
|
|
2986
|
+
const closed = React7.useRef(false);
|
|
2987
|
+
const finish = (save, refocus = false) => {
|
|
2988
|
+
if (closed.current) return false;
|
|
2989
|
+
closed.current = true;
|
|
2990
|
+
if (save) store(refocus);
|
|
2991
|
+
return true;
|
|
2992
|
+
};
|
|
2993
|
+
const latestFinish = React7.useRef(finish);
|
|
2994
|
+
latestFinish.current = finish;
|
|
2995
|
+
React7.useEffect(() => {
|
|
2996
|
+
closed.current = false;
|
|
2997
|
+
return () => void latestFinish.current(true);
|
|
2998
|
+
}, []);
|
|
2999
|
+
const close = (save, refocus = true) => {
|
|
3000
|
+
if (!refocus) controller.readSelectionFromDom();
|
|
3001
|
+
if (!finish(save, refocus)) return;
|
|
3002
|
+
onClose();
|
|
3003
|
+
if (refocus) onReturn();
|
|
3004
|
+
};
|
|
3005
|
+
return { finish, close };
|
|
3006
|
+
}
|
|
2988
3007
|
function useOutsidePress(element, ownerDocument, onPress) {
|
|
2989
3008
|
const latest = React7.useRef(onPress);
|
|
2990
|
-
|
|
3009
|
+
chunkN25EH2GZ_cjs.useIsomorphicLayoutEffect(() => {
|
|
2991
3010
|
latest.current = onPress;
|
|
2992
3011
|
});
|
|
2993
|
-
|
|
3012
|
+
chunkN25EH2GZ_cjs.useIsomorphicLayoutEffect(() => {
|
|
2994
3013
|
const doc = ownerDocument();
|
|
2995
3014
|
const inside = (target) => element.current?.contains(target) === true;
|
|
2996
3015
|
let touched = null;
|
|
@@ -3005,15 +3024,15 @@ function useOutsidePress(element, ownerDocument, onPress) {
|
|
|
3005
3024
|
if (touched !== null && !inside(event.target)) latest.current(touched);
|
|
3006
3025
|
touched = null;
|
|
3007
3026
|
};
|
|
3008
|
-
return
|
|
3027
|
+
return chunkN25EH2GZ_cjs.listen(doc, { pointerdown: down, click }, true);
|
|
3009
3028
|
}, [element, ownerDocument]);
|
|
3010
3029
|
}
|
|
3011
3030
|
function storeAlt(controller, blockId, opened, patch) {
|
|
3012
3031
|
const { editor } = controller;
|
|
3013
|
-
const attrs =
|
|
3014
|
-
const changed =
|
|
3032
|
+
const attrs = chunk4JDRDPLC_cjs.blockById(editor.state.doc, blockId)?.attrs ?? {};
|
|
3033
|
+
const changed = chunk4JDRDPLC_cjs.str(attrs.alt) !== opened.alt || attrs.decorative === true !== opened.decorative;
|
|
3015
3034
|
if (controller.readOnly || controller.root === null || changed) return;
|
|
3016
|
-
|
|
3035
|
+
chunkN25EH2GZ_cjs.onBlock(blockId, chunkZ5EEDCRI_cjs.setAttrs(patch))(editor.state, (tr) => editor.dispatch(tr));
|
|
3017
3036
|
}
|
|
3018
3037
|
function AltTextPopover({ blockId, controller, anchor, opener, alt, decorative, onClose }) {
|
|
3019
3038
|
const labels = useLabels();
|
|
@@ -3022,29 +3041,18 @@ function AltTextPopover({ blockId, controller, anchor, opener, alt, decorative,
|
|
|
3022
3041
|
const [marked, setMarked] = React7.useState(decorative);
|
|
3023
3042
|
const fieldId = React7.useId();
|
|
3024
3043
|
const hintId = `${fieldId}-hint`;
|
|
3025
|
-
const
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
latestFinish.current = finish;
|
|
3035
|
-
React7.useEffect(() => {
|
|
3036
|
-
closed.current = false;
|
|
3037
|
-
return () => void latestFinish.current(true);
|
|
3038
|
-
}, []);
|
|
3044
|
+
const { finish, close } = useClosing(controller, {
|
|
3045
|
+
store() {
|
|
3046
|
+
if (draft !== alt || marked !== decorative) {
|
|
3047
|
+
storeAlt(controller, blockId, opened, { alt: draft, decorative: marked || void 0 });
|
|
3048
|
+
}
|
|
3049
|
+
},
|
|
3050
|
+
onClose,
|
|
3051
|
+
onReturn: () => controller.focus()
|
|
3052
|
+
});
|
|
3039
3053
|
React7.useEffect(() => {
|
|
3040
3054
|
if ((alt !== opened.alt || decorative !== opened.decorative) && finish(false)) onClose();
|
|
3041
3055
|
});
|
|
3042
|
-
const close = (store, refocus = true) => {
|
|
3043
|
-
if (!refocus) controller.readSelectionFromDom();
|
|
3044
|
-
if (!finish(store)) return;
|
|
3045
|
-
onClose();
|
|
3046
|
-
if (refocus) controller.focus();
|
|
3047
|
-
};
|
|
3048
3056
|
const content = React7.useRef(null);
|
|
3049
3057
|
const ownerDocument = React7.useCallback(() => controller.root?.ownerDocument ?? document, [controller]);
|
|
3050
3058
|
useOutsidePress(content, ownerDocument, (target) => {
|
|
@@ -3055,7 +3063,7 @@ function AltTextPopover({ blockId, controller, anchor, opener, alt, decorative,
|
|
|
3055
3063
|
close(true);
|
|
3056
3064
|
};
|
|
3057
3065
|
const onKeyDown = (event) => {
|
|
3058
|
-
if (event.key !== "Tab" ||
|
|
3066
|
+
if (event.key !== "Tab" || chunkN25EH2GZ_cjs.isComposingKey(controller, event.nativeEvent)) return;
|
|
3059
3067
|
const controls = [...event.currentTarget.elements];
|
|
3060
3068
|
const next = controls[controls.indexOf(event.target) + (event.shiftKey ? -1 : 1)];
|
|
3061
3069
|
event.preventDefault();
|
|
@@ -3083,7 +3091,7 @@ function AltTextPopover({ blockId, controller, anchor, opener, alt, decorative,
|
|
|
3083
3091
|
onCloseAutoFocus: preventDefault,
|
|
3084
3092
|
onEscapeKeyDown: (event) => {
|
|
3085
3093
|
event.preventDefault();
|
|
3086
|
-
if (!
|
|
3094
|
+
if (!chunkN25EH2GZ_cjs.isComposingKey(controller, event)) close(false);
|
|
3087
3095
|
},
|
|
3088
3096
|
...bubblePart(controller),
|
|
3089
3097
|
children: /* @__PURE__ */ jsxRuntime.jsxs("form", { noValidate: true, className: "quoin-image-alt", onSubmit: save, onKeyDown, children: [
|
|
@@ -3124,6 +3132,21 @@ function AltTextPopover({ blockId, controller, anchor, opener, alt, decorative,
|
|
|
3124
3132
|
}
|
|
3125
3133
|
);
|
|
3126
3134
|
}
|
|
3135
|
+
function around(a, b) {
|
|
3136
|
+
const left = Math.min(a.left, b.left);
|
|
3137
|
+
const top = Math.min(a.top, b.top);
|
|
3138
|
+
return new DOMRect(left, top, Math.max(a.right, b.right) - left, Math.max(a.bottom, b.bottom) - top);
|
|
3139
|
+
}
|
|
3140
|
+
function useAroundToolbar(part, inToolbar) {
|
|
3141
|
+
return React7.useMemo(() => {
|
|
3142
|
+
const measure2 = () => {
|
|
3143
|
+
const box = part.current.getBoundingClientRect();
|
|
3144
|
+
const toolbar = inToolbar.current?.closest('[role="toolbar"]')?.getBoundingClientRect();
|
|
3145
|
+
return toolbar === void 0 ? box : around(box, toolbar);
|
|
3146
|
+
};
|
|
3147
|
+
return { current: virtualAnchor(measure2, () => part.current.contextElement) };
|
|
3148
|
+
}, [part, inToolbar]);
|
|
3149
|
+
}
|
|
3127
3150
|
|
|
3128
3151
|
// src/blocks/image/image-toolbar-items.ts
|
|
3129
3152
|
var ALIGNS = [
|
|
@@ -3137,7 +3160,7 @@ function imageToolbarItems(blockId, labels, actions) {
|
|
|
3137
3160
|
id: align,
|
|
3138
3161
|
title: labels[label],
|
|
3139
3162
|
icon,
|
|
3140
|
-
isActive: (state) => (
|
|
3163
|
+
isActive: (state) => (chunk4JDRDPLC_cjs.alignOrUndefined(chunk4JDRDPLC_cjs.blockById(state.doc, blockId)?.attrs.align) ?? "left") === align,
|
|
3141
3164
|
run: (controller) => setBlockAttrs(controller, blockId, { align })
|
|
3142
3165
|
})
|
|
3143
3166
|
);
|
|
@@ -3179,11 +3202,12 @@ function ImageToolbarOverlay({ controller }) {
|
|
|
3179
3202
|
}
|
|
3180
3203
|
function ImageToolbar({ blockId, controller, editingAlt, onEditAlt }) {
|
|
3181
3204
|
const { labels, resolveAssetUrl } = useQuoin();
|
|
3182
|
-
const state =
|
|
3205
|
+
const state = chunkN25EH2GZ_cjs.useEditorState(controller, chunkN25EH2GZ_cjs.wholeState);
|
|
3183
3206
|
const picker = useReplacePicker(controller, blockId, uploadImage, "image/*");
|
|
3184
3207
|
const altButton = React7.useRef(null);
|
|
3185
3208
|
const anchor = usePartAnchor(controller, blockId, ".quoin-image-frame");
|
|
3186
|
-
const
|
|
3209
|
+
const altAnchor = useAroundToolbar(anchor, altButton);
|
|
3210
|
+
const attrs = chunk4JDRDPLC_cjs.blockById(state.doc, blockId)?.attrs ?? {};
|
|
3187
3211
|
const items = imageToolbarItems(blockId, labels, {
|
|
3188
3212
|
replace: picker.open,
|
|
3189
3213
|
editAlt: () => {
|
|
@@ -3207,9 +3231,9 @@ function ImageToolbar({ blockId, controller, editingAlt, onEditAlt }) {
|
|
|
3207
3231
|
{
|
|
3208
3232
|
blockId,
|
|
3209
3233
|
controller,
|
|
3210
|
-
anchor,
|
|
3234
|
+
anchor: altAnchor,
|
|
3211
3235
|
opener: altButton,
|
|
3212
|
-
alt:
|
|
3236
|
+
alt: chunk4JDRDPLC_cjs.str(attrs.alt),
|
|
3213
3237
|
decorative: attrs.decorative === true,
|
|
3214
3238
|
onClose: () => onEditAlt(null)
|
|
3215
3239
|
}
|
|
@@ -3337,7 +3361,7 @@ var DropdownMenuSubTrigger = /* @__PURE__ */ React7__namespace.forwardRef(functi
|
|
|
3337
3361
|
...props,
|
|
3338
3362
|
children: [
|
|
3339
3363
|
children,
|
|
3340
|
-
/* @__PURE__ */ jsxRuntime.jsx(ChevronRight, { className: "
|
|
3364
|
+
/* @__PURE__ */ jsxRuntime.jsx(ChevronRight, { className: "ms-auto size-4 rtl:rotate-180" })
|
|
3341
3365
|
]
|
|
3342
3366
|
}
|
|
3343
3367
|
);
|
|
@@ -3383,7 +3407,7 @@ var SHOWN_WITH_THE_BLOCK = [
|
|
|
3383
3407
|
"opacity-0 group-hover/callout:opacity-100 group-focus-within/callout:opacity-100",
|
|
3384
3408
|
"in-data-[selected=true]:opacity-100 pointer-coarse:opacity-100 focus-visible:opacity-100 data-[state=open]:opacity-100"
|
|
3385
3409
|
].join(" ");
|
|
3386
|
-
function CalloutToneMenu({ blockId, controller, tone }) {
|
|
3410
|
+
function CalloutToneMenu({ blockId, controller, tone, alwaysShown }) {
|
|
3387
3411
|
const labels = useLabels();
|
|
3388
3412
|
const name = labels.calloutTones[tone];
|
|
3389
3413
|
return /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenu, { children: [
|
|
@@ -3395,7 +3419,7 @@ function CalloutToneMenu({ blockId, controller, tone }) {
|
|
|
3395
3419
|
size: "xs",
|
|
3396
3420
|
tabIndex: -1,
|
|
3397
3421
|
"aria-label": labels.calloutToneMenu(name),
|
|
3398
|
-
className: SHOWN_WITH_THE_BLOCK,
|
|
3422
|
+
className: alwaysShown ? void 0 : SHOWN_WITH_THE_BLOCK,
|
|
3399
3423
|
children: name
|
|
3400
3424
|
}
|
|
3401
3425
|
) }),
|
|
@@ -3404,20 +3428,21 @@ function CalloutToneMenu({ blockId, controller, tone }) {
|
|
|
3404
3428
|
{
|
|
3405
3429
|
value: tone,
|
|
3406
3430
|
onValueChange: (value) => setBlockAttrs(controller, blockId, { tone: value }),
|
|
3407
|
-
children:
|
|
3431
|
+
children: chunkQFGWSFOI_cjs.CALLOUT_TONES.map((option) => /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuRadioItem, { value: option, children: labels.calloutTones[option] }, option))
|
|
3408
3432
|
}
|
|
3409
3433
|
) })
|
|
3410
3434
|
] });
|
|
3411
3435
|
}
|
|
3412
3436
|
var CalloutBlock = ({ block, controller }) => {
|
|
3413
3437
|
const labels = useLabels();
|
|
3414
|
-
const readOnly =
|
|
3415
|
-
const tone =
|
|
3438
|
+
const readOnly = chunkN25EH2GZ_cjs.useReadOnly(controller);
|
|
3439
|
+
const tone = chunkQFGWSFOI_cjs.calloutTone(block.attrs.tone);
|
|
3416
3440
|
const icon = calloutIcon(block.attrs, tone);
|
|
3441
|
+
const toneInWords = !iconTellsTone(block.attrs, tone);
|
|
3417
3442
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("quoin-callout group/callout flex items-start gap-2", TONE[tone]), "data-tone": tone, children: [
|
|
3418
3443
|
readOnly ? /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", className: "flex size-6 items-center justify-center text-base", children: icon }) : /* @__PURE__ */ jsxRuntime.jsx(CalloutIconMenu, { blockId: block.id, controller, icon }),
|
|
3419
3444
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3420
|
-
|
|
3445
|
+
chunkN25EH2GZ_cjs.EditableRegion,
|
|
3421
3446
|
{
|
|
3422
3447
|
block: block.id,
|
|
3423
3448
|
region: "body",
|
|
@@ -3425,7 +3450,7 @@ var CalloutBlock = ({ block, controller }) => {
|
|
|
3425
3450
|
className: "min-w-0 flex-1"
|
|
3426
3451
|
}
|
|
3427
3452
|
),
|
|
3428
|
-
|
|
3453
|
+
readOnly ? toneInWords && /* @__PURE__ */ jsxRuntime.jsx("span", { "aria-hidden": "true", className: "flex h-6 items-center px-2 text-xs", children: labels.calloutTones[tone] }) : /* @__PURE__ */ jsxRuntime.jsx(CalloutToneMenu, { blockId: block.id, controller, tone, alwaysShown: toneInWords })
|
|
3429
3454
|
] });
|
|
3430
3455
|
};
|
|
3431
3456
|
var DividerBlock = ({ block, controller }) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "py-2", contentEditable: false, onClick: () => focusNode(controller, block.id), children: /* @__PURE__ */ jsxRuntime.jsx("hr", { className: "border-t border-border" }) });
|
|
@@ -3473,92 +3498,23 @@ var COUNTERS = [decimal, lowerAlpha, lowerRoman];
|
|
|
3473
3498
|
function bulletGlyph(depth) {
|
|
3474
3499
|
return BULLETS[cycleOf(depth)];
|
|
3475
3500
|
}
|
|
3476
|
-
function orderedLabel(n, depth) {
|
|
3477
|
-
return `${COUNTERS[cycleOf(depth)](n)}.`;
|
|
3478
|
-
}
|
|
3479
|
-
function ListMarker(props) {
|
|
3480
|
-
const text2 = props.list === "bullet" ? bulletGlyph(props.depth) : orderedLabel(props.number, props.depth);
|
|
3481
|
-
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "quoin-marker", "aria-hidden": "true", children: text2 });
|
|
3482
|
-
}
|
|
3483
|
-
var REGION = "text";
|
|
3484
|
-
var HEADING_LEVELS = ["mt-6 text-3xl", "mt-5 text-2xl", "mt-4 text-xl", "mt-3 text-lg", "mt-3 text-base", "mt-3 text-sm"];
|
|
3485
|
-
var headingStyles = (level) => `quoin-heading mb-1 font-semibold leading-tight in-[[data-quoin-block]:first-child]:mt-0 ${HEADING_LEVELS[level - 1]}`;
|
|
3486
|
-
function Heading({ block }) {
|
|
3487
|
-
const labels = useLabels();
|
|
3488
|
-
const level = chunkI7X7B3WD_cjs.headingLevel(block.attrs.level);
|
|
3489
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { role: "heading", "aria-level": level, className: headingStyles(level), children: /* @__PURE__ */ jsxRuntime.jsx(chunk2QKFRKOP_cjs.EditableRegion, { block: block.id, region: REGION, label: labels.heading(level) }) });
|
|
3490
|
-
}
|
|
3491
|
-
function NumberedItem({ block, controller }) {
|
|
3492
|
-
const labels = useLabels();
|
|
3493
|
-
const number = chunk2QKFRKOP_cjs.useOrderedNumber(controller, block.id);
|
|
3494
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "quoin-list-item", "data-list": "ordered", children: [
|
|
3495
|
-
/* @__PURE__ */ jsxRuntime.jsx(ListMarker, { list: "ordered", number, depth: block.indent }),
|
|
3496
|
-
/* @__PURE__ */ jsxRuntime.jsx(chunk2QKFRKOP_cjs.EditableRegion, { block: block.id, region: REGION, label: labels.numberedItem(number) })
|
|
3497
|
-
] });
|
|
3498
|
-
}
|
|
3499
|
-
function TaskItem({ block, controller }) {
|
|
3500
|
-
const labels = useLabels();
|
|
3501
|
-
const hostId = chunk2QKFRKOP_cjs.useRegionDomId(block.id, REGION);
|
|
3502
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "quoin-task", "data-checked": block.attrs.checked === true, children: [
|
|
3503
|
-
/* @__PURE__ */ jsxRuntime.jsx(chunk2QKFRKOP_cjs.TaskCheckbox, { block, controller, label: labels.task, labelledBy: hostId }),
|
|
3504
|
-
/* @__PURE__ */ jsxRuntime.jsx(chunk2QKFRKOP_cjs.EditableRegion, { id: hostId, block: block.id, region: REGION, label: labels.task })
|
|
3505
|
-
] });
|
|
3506
|
-
}
|
|
3507
|
-
var MarkdownBlock = (props) => {
|
|
3508
|
-
const { block } = props;
|
|
3509
|
-
const labels = useLabels();
|
|
3510
|
-
switch (block.attrs.kind) {
|
|
3511
|
-
case "heading":
|
|
3512
|
-
return /* @__PURE__ */ jsxRuntime.jsx(Heading, { block });
|
|
3513
|
-
case "bullet":
|
|
3514
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "quoin-list-item", "data-list": "bullet", children: [
|
|
3515
|
-
/* @__PURE__ */ jsxRuntime.jsx(ListMarker, { list: "bullet", depth: block.indent }),
|
|
3516
|
-
/* @__PURE__ */ jsxRuntime.jsx(chunk2QKFRKOP_cjs.EditableRegion, { block: block.id, region: REGION, label: labels.bulletItem })
|
|
3517
|
-
] });
|
|
3518
|
-
case "ordered":
|
|
3519
|
-
return /* @__PURE__ */ jsxRuntime.jsx(NumberedItem, { ...props });
|
|
3520
|
-
case "task":
|
|
3521
|
-
return /* @__PURE__ */ jsxRuntime.jsx(TaskItem, { ...props });
|
|
3522
|
-
case "quote":
|
|
3523
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "quoin-quote", children: /* @__PURE__ */ jsxRuntime.jsx(chunk2QKFRKOP_cjs.EditableRegion, { block: block.id, region: REGION, label: labels.quote }) });
|
|
3524
|
-
default:
|
|
3525
|
-
return /* @__PURE__ */ jsxRuntime.jsx(chunk2QKFRKOP_cjs.EditableRegion, { block: block.id, region: REGION, label: labels.paragraph });
|
|
3526
|
-
}
|
|
3527
|
-
};
|
|
3528
|
-
|
|
3529
|
-
// src/blocks/text/use-nested-blocks.ts
|
|
3530
|
-
function nestedBlockIds({ doc }, blockId) {
|
|
3531
|
-
const index = doc.index.get(blockId);
|
|
3532
|
-
if (index === void 0) return [];
|
|
3533
|
-
return doc.blocks.slice(index + 1, chunkFK7EBZPX_cjs.descendantsEnd(doc, index)).map((block) => block.id);
|
|
3501
|
+
function orderedLabel(n, depth) {
|
|
3502
|
+
return `${COUNTERS[cycleOf(depth)](n)}.`;
|
|
3534
3503
|
}
|
|
3535
|
-
function
|
|
3536
|
-
|
|
3504
|
+
function ListMarker(props) {
|
|
3505
|
+
const text2 = props.list === "bullet" ? bulletGlyph(props.depth) : orderedLabel(props.number, props.depth);
|
|
3506
|
+
return /* @__PURE__ */ jsxRuntime.jsx("span", { className: "quoin-marker", "aria-hidden": "true", children: text2 });
|
|
3537
3507
|
}
|
|
3538
|
-
var
|
|
3539
|
-
|
|
3540
|
-
|
|
3541
|
-
|
|
3542
|
-
const open = chunk2QKFRKOP_cjs.useToggleOpen(controller, block);
|
|
3543
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "quoin-toggle", "data-open": open, children: [
|
|
3544
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3545
|
-
chunk2QKFRKOP_cjs.ToggleChevron,
|
|
3546
|
-
{
|
|
3547
|
-
block,
|
|
3548
|
-
controller,
|
|
3549
|
-
label: labels.toggleButton(open ? 0 : nested.length),
|
|
3550
|
-
controls: nested.length === 0 ? void 0 : nested.map(domId).join(" ")
|
|
3551
|
-
}
|
|
3552
|
-
),
|
|
3553
|
-
/* @__PURE__ */ jsxRuntime.jsx(chunk2QKFRKOP_cjs.EditableRegion, { block: block.id, region: "text", label: labels.toggle })
|
|
3554
|
-
] });
|
|
3555
|
-
};
|
|
3508
|
+
var HEADING_LEVELS = ["mt-6 text-3xl", "mt-5 text-2xl", "mt-4 text-xl", "mt-3 text-lg", "mt-3 text-base", "mt-3 text-sm"];
|
|
3509
|
+
var headingStyles = (level) => `quoin-heading mb-1 font-semibold leading-tight in-[[data-quoin-block]:first-child]:mt-0 ${HEADING_LEVELS[level - 1]}`;
|
|
3510
|
+
var CANVAS_LOOK = { Marker: ListMarker, headingClassName: headingStyles };
|
|
3511
|
+
var MarkdownBlock = (props) => /* @__PURE__ */ jsxRuntime.jsx(chunkN25EH2GZ_cjs.MarkdownText, { ...props, look: CANVAS_LOOK });
|
|
3556
3512
|
|
|
3557
3513
|
// src/blocks/text/text-renderers.ts
|
|
3558
3514
|
var textRenderers = {
|
|
3559
3515
|
MARKDOWN: MarkdownBlock,
|
|
3560
3516
|
CALLOUT: CalloutBlock,
|
|
3561
|
-
TOGGLE: ToggleBlock,
|
|
3517
|
+
TOGGLE: chunkN25EH2GZ_cjs.ToggleBlock,
|
|
3562
3518
|
DIVIDER: DividerBlock
|
|
3563
3519
|
};
|
|
3564
3520
|
|
|
@@ -3576,6 +3532,7 @@ function drawnAsText(definitions, type, readOnly) {
|
|
|
3576
3532
|
return !hostDefines(definitions, type) || !readOnly && TYPED_IN_PLACE.includes(type);
|
|
3577
3533
|
}
|
|
3578
3534
|
var definedTypedInPlace = (definitions) => TYPED_IN_PLACE.filter((type) => hostDefines(definitions, type));
|
|
3535
|
+
var hostLabel = (definitions, type) => !TYPED_IN_PLACE.includes(type) && hostDefines(definitions, type) ? chunkA6PGQVTR_cjs.blockByType(definitions, type)?.label : void 0;
|
|
3579
3536
|
function drawnInPlace(definitions, type) {
|
|
3580
3537
|
return Object.hasOwn(inPlaceRenderers, type) && chunkA6PGQVTR_cjs.blockByType(definitions, type) !== void 0 && !hostDefines(definitions, type);
|
|
3581
3538
|
}
|
|
@@ -3611,10 +3568,10 @@ function turnIntoTargets(labels) {
|
|
|
3611
3568
|
}
|
|
3612
3569
|
function TurnIntoItems({ kit, controller, blockIds }) {
|
|
3613
3570
|
const { blockTypes, labels } = useQuoin();
|
|
3614
|
-
const
|
|
3615
|
-
return
|
|
3571
|
+
const targets2 = turnIntoTargets(labels).filter((target) => drawsType(blockTypes, target.type));
|
|
3572
|
+
return targets2.map((target) => /* @__PURE__ */ jsxRuntime.jsxs(kit.Item, { onSelect: () => runOnBlocks(controller, blockIds, chunkZ5EEDCRI_cjs.setBlockType(target.type, target.attrs)), children: [
|
|
3616
3573
|
/* @__PURE__ */ jsxRuntime.jsx(MenuIcon, { icon: target.icon }),
|
|
3617
|
-
target.label
|
|
3574
|
+
hostLabel(blockTypes, target.type) ?? target.label
|
|
3618
3575
|
] }, target.id));
|
|
3619
3576
|
}
|
|
3620
3577
|
function TurnIntoMenu(props) {
|
|
@@ -3647,10 +3604,10 @@ function ActionItem({ kit, controller, action, blockIds }) {
|
|
|
3647
3604
|
);
|
|
3648
3605
|
}
|
|
3649
3606
|
function BlockMenuItems({ kit, controller, blocks, styled, title, actions }) {
|
|
3650
|
-
const state =
|
|
3607
|
+
const state = chunkN25EH2GZ_cjs.useEditorState(controller, chunkN25EH2GZ_cjs.wholeState);
|
|
3651
3608
|
const blockIds = blocks.map((block) => block.id);
|
|
3652
3609
|
const shown = actions.filter((action) => action.available?.(state, blockIds) ?? true);
|
|
3653
|
-
const anyText = styled.some((block) =>
|
|
3610
|
+
const anyText = styled.some((block) => chunkZ5EEDCRI_cjs.isTextFlow(state.schema, block));
|
|
3654
3611
|
const anyMarkdown = styled.some((block) => block.type === "MARKDOWN");
|
|
3655
3612
|
const allCallouts = styled.length > 0 && styled.every((block) => block.type === "CALLOUT");
|
|
3656
3613
|
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
@@ -3692,7 +3649,7 @@ var CONTEXT_KIT = {
|
|
|
3692
3649
|
SubTrigger: ContextMenuSubTrigger
|
|
3693
3650
|
};
|
|
3694
3651
|
var GUTTER_BLOCK = "data-quoin-gutter-block";
|
|
3695
|
-
var OWN_MENU = `[${
|
|
3652
|
+
var OWN_MENU = `[${chunkN25EH2GZ_cjs.NATIVE_INTERACTION}], input, textarea, select`;
|
|
3696
3653
|
function contextBlock(controller, target) {
|
|
3697
3654
|
const { state } = controller.editor;
|
|
3698
3655
|
const gutter = target.closest(`[${GUTTER_BLOCK}]`)?.getAttribute(GUTTER_BLOCK);
|
|
@@ -3701,8 +3658,8 @@ function contextBlock(controller, target) {
|
|
|
3701
3658
|
if (selection?.kind === "blocks") return selection.head;
|
|
3702
3659
|
if (target.closest(OWN_MENU) || controller.registry.locate(target) !== null) return null;
|
|
3703
3660
|
const id = controller.blockAt(target);
|
|
3704
|
-
const block = id === void 0 ? void 0 :
|
|
3705
|
-
return block === void 0 ||
|
|
3661
|
+
const block = id === void 0 ? void 0 : chunk4JDRDPLC_cjs.blockById(state.doc, id);
|
|
3662
|
+
return block === void 0 || chunkZ5EEDCRI_cjs.isTextFlow(state.schema, block) ? null : block.id;
|
|
3706
3663
|
}
|
|
3707
3664
|
function useContextMenuOpener(controller, store, trigger) {
|
|
3708
3665
|
React7.useEffect(() => {
|
|
@@ -3712,8 +3669,15 @@ function useContextMenuOpener(controller, store, trigger) {
|
|
|
3712
3669
|
const onMouseDown = (event) => {
|
|
3713
3670
|
if (event.button === 2 && blockOf(event) !== null) event.preventDefault();
|
|
3714
3671
|
};
|
|
3672
|
+
let pressed = null;
|
|
3673
|
+
const onPointerDown = (event) => {
|
|
3674
|
+
const block = event.button === 2 ? blockOf(event) : null;
|
|
3675
|
+
pressed = block === null ? null : { block, x: event.clientX, y: event.clientY };
|
|
3676
|
+
};
|
|
3677
|
+
const pressedAt = ({ clientX, clientY }) => pressed !== null && Math.hypot(clientX - pressed.x, clientY - pressed.y) <= 2 ? pressed.block : null;
|
|
3715
3678
|
const onContextMenu = (event) => {
|
|
3716
|
-
const block = blockOf(event);
|
|
3679
|
+
const block = blockOf(event) ?? pressedAt(event);
|
|
3680
|
+
pressed = null;
|
|
3717
3681
|
const hidden = trigger.current;
|
|
3718
3682
|
if (block === null || hidden === null) return;
|
|
3719
3683
|
event.preventDefault();
|
|
@@ -3721,7 +3685,7 @@ function useContextMenuOpener(controller, store, trigger) {
|
|
|
3721
3685
|
openBlockMenuAt(store, controller.editor.state, block, clientX, clientY);
|
|
3722
3686
|
hidden.dispatchEvent(new MouseEvent("contextmenu", { bubbles: true, cancelable: true, clientX, clientY }));
|
|
3723
3687
|
};
|
|
3724
|
-
return
|
|
3688
|
+
return chunkN25EH2GZ_cjs.listen(root, { pointerdown: onPointerDown, mousedown: onMouseDown, contextmenu: onContextMenu });
|
|
3725
3689
|
}, [controller, store, trigger]);
|
|
3726
3690
|
}
|
|
3727
3691
|
|
|
@@ -3745,6 +3709,8 @@ var nameIn = (names, key) => typeof key === "string" && Object.hasOwn(names, key
|
|
|
3745
3709
|
function blockTypeLabel(labels, block, definitions, extensionNames = {}) {
|
|
3746
3710
|
const { kind, level } = block.attrs;
|
|
3747
3711
|
if (block.type === "MARKDOWN" && kind === "heading") return labels.heading(typeof level === "number" ? level : 1);
|
|
3712
|
+
const own = hostLabel(definitions, block.type);
|
|
3713
|
+
if (own !== void 0) return own;
|
|
3748
3714
|
const name = block.type === "MARKDOWN" ? nameIn(KIND_NAMES, kind) : nameIn(TYPE_NAMES, block.type);
|
|
3749
3715
|
if (name !== void 0) return labels.blockNames[name];
|
|
3750
3716
|
return nameIn(extensionNames, block.type) ?? chunkA6PGQVTR_cjs.blockByType(definitions, block.type)?.label ?? labels.unsupportedBlock;
|
|
@@ -3754,10 +3720,10 @@ var ExtensionBlockNames = React7.createContext({});
|
|
|
3754
3720
|
// src/gutter/use-menu-blocks.ts
|
|
3755
3721
|
function useLiveBlocks(controller, blockIds) {
|
|
3756
3722
|
const select = React7.useCallback(
|
|
3757
|
-
(state) => blockIds.flatMap((id) =>
|
|
3723
|
+
(state) => blockIds.flatMap((id) => chunk4JDRDPLC_cjs.blockById(state.doc, id) ?? []),
|
|
3758
3724
|
[blockIds]
|
|
3759
3725
|
);
|
|
3760
|
-
return
|
|
3726
|
+
return chunkN25EH2GZ_cjs.useEditorState(controller, select, chunk4JDRDPLC_cjs.sameItems);
|
|
3761
3727
|
}
|
|
3762
3728
|
function useMenuBlocks(controller, store, menu) {
|
|
3763
3729
|
const labels = useLabels();
|
|
@@ -3807,15 +3773,81 @@ function BlockContextMenu({ controller, store, actions }) {
|
|
|
3807
3773
|
);
|
|
3808
3774
|
}
|
|
3809
3775
|
|
|
3776
|
+
// src/gutter/block-menu-items.ts
|
|
3777
|
+
var rangeOf = (blockIds) => chunkZ5EEDCRI_cjs.blockRangeSelection(blockIds[0], blockIds[blockIds.length - 1]);
|
|
3778
|
+
function menuActions(core, extra = []) {
|
|
3779
|
+
return [...core.filter((action) => !action.destructive), ...extra, ...core.filter((action) => action.destructive)];
|
|
3780
|
+
}
|
|
3781
|
+
function markdownOf(editor, blockIds, resolveAssetUrl) {
|
|
3782
|
+
const { doc } = editor.state;
|
|
3783
|
+
const range = chunkZ5EEDCRI_cjs.selectedBlockRange(doc, rangeOf(blockIds));
|
|
3784
|
+
if (range === null) return "";
|
|
3785
|
+
const blocks = editor.codec.blocksFromDoc(chunk4JDRDPLC_cjs.createDoc(doc.blocks.slice(range.start, range.end)));
|
|
3786
|
+
return chunkZ5EEDCRI_cjs.toMarkdown(blocks, { schema: editor.schema, resolveAssetUrl, comments: false });
|
|
3787
|
+
}
|
|
3788
|
+
var applies = (command) => (state, blockIds) => blockIds.every((id) => state.doc.index.has(id)) && chunkZ5EEDCRI_cjs.runCommands(state, [chunkZ5EEDCRI_cjs.setSelection(rangeOf(blockIds)), command]).ok;
|
|
3789
|
+
function coreBlockMenuActions(labels, options) {
|
|
3790
|
+
const copy = (controller, blockIds, text2) => {
|
|
3791
|
+
void copyText(text2, controller.root?.ownerDocument).then((copied) => {
|
|
3792
|
+
(copied ? options.onCopied : options.onCopyFailed)?.();
|
|
3793
|
+
});
|
|
3794
|
+
runOnBlocks(controller, blockIds, noChange);
|
|
3795
|
+
};
|
|
3796
|
+
return [
|
|
3797
|
+
{
|
|
3798
|
+
id: "duplicate",
|
|
3799
|
+
label: labels.duplicate,
|
|
3800
|
+
icon: CopyPlus,
|
|
3801
|
+
shortcut: "Mod-d",
|
|
3802
|
+
run: (controller, blockIds) => runOnBlocks(controller, blockIds, chunkZ5EEDCRI_cjs.duplicateBlocks())
|
|
3803
|
+
},
|
|
3804
|
+
{
|
|
3805
|
+
id: "copy",
|
|
3806
|
+
label: labels.copy,
|
|
3807
|
+
icon: Copy,
|
|
3808
|
+
run: (controller, blockIds) => copy(controller, blockIds, markdownOf(controller.editor, blockIds, options.resolveAssetUrl))
|
|
3809
|
+
},
|
|
3810
|
+
{
|
|
3811
|
+
id: "copy-link",
|
|
3812
|
+
label: labels.copyLink,
|
|
3813
|
+
icon: Link,
|
|
3814
|
+
run: (controller, blockIds) => copy(controller, blockIds, options.blockLink(blockIds[0]))
|
|
3815
|
+
},
|
|
3816
|
+
{
|
|
3817
|
+
id: "move-up",
|
|
3818
|
+
label: labels.moveUp,
|
|
3819
|
+
icon: ArrowUp,
|
|
3820
|
+
shortcut: "Mod-Shift-ArrowUp",
|
|
3821
|
+
run: (controller, blockIds) => runOnBlocks(controller, blockIds, chunkZ5EEDCRI_cjs.moveBlocksUp),
|
|
3822
|
+
available: applies(chunkZ5EEDCRI_cjs.moveBlocksUp)
|
|
3823
|
+
},
|
|
3824
|
+
{
|
|
3825
|
+
id: "move-down",
|
|
3826
|
+
label: labels.moveDown,
|
|
3827
|
+
icon: ArrowDown,
|
|
3828
|
+
shortcut: "Mod-Shift-ArrowDown",
|
|
3829
|
+
run: (controller, blockIds) => runOnBlocks(controller, blockIds, chunkZ5EEDCRI_cjs.moveBlocksDown),
|
|
3830
|
+
available: applies(chunkZ5EEDCRI_cjs.moveBlocksDown)
|
|
3831
|
+
},
|
|
3832
|
+
{
|
|
3833
|
+
id: "delete",
|
|
3834
|
+
label: labels.delete,
|
|
3835
|
+
icon: Trash,
|
|
3836
|
+
destructive: true,
|
|
3837
|
+
run: (controller, blockIds) => runOnBlocks(controller, blockIds, chunkZ5EEDCRI_cjs.deleteBlocks)
|
|
3838
|
+
}
|
|
3839
|
+
];
|
|
3840
|
+
}
|
|
3841
|
+
|
|
3810
3842
|
// src/gutter/block-menu-keymap.ts
|
|
3811
3843
|
function blockMenuKeymap(store) {
|
|
3812
3844
|
const openForHead = (state, dispatch) => {
|
|
3813
|
-
const head =
|
|
3845
|
+
const head = chunkZ5EEDCRI_cjs.headBlockId(state.selection);
|
|
3814
3846
|
if (head === null || !state.doc.index.has(head)) return false;
|
|
3815
3847
|
if (dispatch) openBlockMenu(store, state, head);
|
|
3816
3848
|
return true;
|
|
3817
3849
|
};
|
|
3818
|
-
return
|
|
3850
|
+
return chunkZ5EEDCRI_cjs.defineExtension({ name: "block-menu", keymap: { "Mod-/": openForHead } });
|
|
3819
3851
|
}
|
|
3820
3852
|
var UNIQUE_OR_FOCUSABLE = ["id", "data-block-id", "contenteditable", "tabindex"];
|
|
3821
3853
|
function copyOf(shell) {
|
|
@@ -3880,14 +3912,28 @@ var DragOverlay = React7.forwardRef(function DragOverlay2(_props, ref) {
|
|
|
3880
3912
|
] });
|
|
3881
3913
|
});
|
|
3882
3914
|
|
|
3915
|
+
// src/canvas/removed-blocks.ts
|
|
3916
|
+
function blockRemovals(tr) {
|
|
3917
|
+
return tr.steps.flatMap((step, at) => {
|
|
3918
|
+
if (step.stepType !== "removeBlocks") return [];
|
|
3919
|
+
const { index, count } = step.toJSON();
|
|
3920
|
+
return typeof index === "number" && typeof count === "number" ? [{ step: at, index, count }] : [];
|
|
3921
|
+
});
|
|
3922
|
+
}
|
|
3923
|
+
|
|
3883
3924
|
// src/canvas/structure-announcement.ts
|
|
3884
3925
|
var DELETION_STEPS = /* @__PURE__ */ new Set(["removeBlocks", "setIndent"]);
|
|
3885
3926
|
function drawnPosition(doc, blockId) {
|
|
3886
|
-
const index = doc.index.get(blockId)
|
|
3887
|
-
return [
|
|
3927
|
+
const index = doc.index.get(blockId);
|
|
3928
|
+
return index === void 0 ? null : [chunkN25EH2GZ_cjs.drawnBlockCount(doc, 0, index) + 1, chunkN25EH2GZ_cjs.drawnBlockCount(doc)];
|
|
3888
3929
|
}
|
|
3889
3930
|
function blockMovedMessage(doc, blockId, labels) {
|
|
3890
|
-
|
|
3931
|
+
const position = drawnPosition(doc, blockId);
|
|
3932
|
+
return position && labels.blockMoved(...position);
|
|
3933
|
+
}
|
|
3934
|
+
function announceBlockMoved(controller, blockId, labels) {
|
|
3935
|
+
const message = blockMovedMessage(controller.editor.state.doc, blockId, labels);
|
|
3936
|
+
if (message !== null && controller.announcer.current()?.message !== message) controller.announce(message);
|
|
3891
3937
|
}
|
|
3892
3938
|
function movedBlock(tr) {
|
|
3893
3939
|
const at = tr.steps.findIndex((step) => step.stepType === "moveBlocks");
|
|
@@ -3897,71 +3943,111 @@ function movedBlock(tr) {
|
|
|
3897
3943
|
}
|
|
3898
3944
|
function deletedCount(tr) {
|
|
3899
3945
|
if (!tr.steps.every((step) => DELETION_STEPS.has(step.stepType))) return 0;
|
|
3900
|
-
return tr.
|
|
3901
|
-
|
|
3902
|
-
|
|
3903
|
-
|
|
3904
|
-
}, 0);
|
|
3946
|
+
return blockRemovals(tr).reduce(
|
|
3947
|
+
(deleted, { step, index, count }) => deleted + chunkN25EH2GZ_cjs.drawnBlockCount(tr.docs[step], index, index + count),
|
|
3948
|
+
0
|
|
3949
|
+
);
|
|
3905
3950
|
}
|
|
3906
|
-
function
|
|
3907
|
-
if (tr.getMeta(chunkFK7EBZPX_cjs.LINE_SPLIT) === true || tr.steps.some((step) => step.stepType === "removeBlocks")) return null;
|
|
3951
|
+
function insertedIds(tr) {
|
|
3908
3952
|
const inserted = tr.steps.flatMap((step) => {
|
|
3909
3953
|
const { blocks } = step.toJSON();
|
|
3910
3954
|
return step.stepType === "insertBlocks" && Array.isArray(blocks) ? blocks : [];
|
|
3911
3955
|
});
|
|
3912
|
-
return inserted.
|
|
3956
|
+
return new Set(inserted.map(({ id }) => id));
|
|
3957
|
+
}
|
|
3958
|
+
function isCaretLine(tr, block) {
|
|
3959
|
+
const { selection } = tr;
|
|
3960
|
+
const empty = chunkZ5EEDCRI_cjs.isParagraph(block) && chunkZ5EEDCRI_cjs.regionLength(block, chunkZ5EEDCRI_cjs.primaryRegion(tr.before.schema, block) ?? "") === 0;
|
|
3961
|
+
return empty && selection?.kind === "text" && selection.head.block === block.id;
|
|
3962
|
+
}
|
|
3963
|
+
function insertedBlocks(tr) {
|
|
3964
|
+
if (tr.getMeta(chunkZ5EEDCRI_cjs.LINE_SPLIT) === true || tr.steps.some((step) => step.stepType === "removeBlocks")) return [];
|
|
3965
|
+
const inserted = insertedIds(tr);
|
|
3966
|
+
const { doc } = tr;
|
|
3967
|
+
const drawn = doc.blocks.filter((block, index) => inserted.has(block.id) && chunkN25EH2GZ_cjs.drawnBlockCount(doc, index, index + 1));
|
|
3968
|
+
const last2 = drawn.at(-1);
|
|
3969
|
+
if (drawn.length > 1 && last2 !== void 0 && isCaretLine(tr, last2)) drawn.pop();
|
|
3970
|
+
return drawn.map((block) => block.id);
|
|
3971
|
+
}
|
|
3972
|
+
function insertedMessage(tr, labels) {
|
|
3973
|
+
const [first, ...more] = insertedBlocks(tr);
|
|
3974
|
+
const position = first === void 0 ? null : drawnPosition(tr.doc, first);
|
|
3975
|
+
if (position === null) return null;
|
|
3976
|
+
if (more.length === 0) return labels.blockInserted(...position);
|
|
3977
|
+
const blocksInserted = labels.blocksInserted ?? englishLabels.blocksInserted;
|
|
3978
|
+
return blocksInserted(more.length + 1, ...position);
|
|
3913
3979
|
}
|
|
3914
3980
|
function structureAnnouncement(tr, labels, undoKeys) {
|
|
3915
|
-
if (tr.origin !== "command" || tr.getMeta(
|
|
3981
|
+
if (tr.origin !== "command" || tr.getMeta(chunkZ5EEDCRI_cjs.LINE_JOIN) === true) return null;
|
|
3916
3982
|
const moved = movedBlock(tr);
|
|
3917
3983
|
if (moved !== null) return blockMovedMessage(tr.doc, moved, labels);
|
|
3918
3984
|
const deleted = deletedCount(tr);
|
|
3919
3985
|
if (deleted > 0) return `${labels.blockDeleted(deleted)}. ${labels.undoHint(undoKeys)}`;
|
|
3920
|
-
|
|
3921
|
-
return inserted === null ? null : labels.blockInserted(...drawnPosition(tr.doc, inserted));
|
|
3986
|
+
return insertedMessage(tr, labels);
|
|
3922
3987
|
}
|
|
3923
3988
|
|
|
3924
3989
|
// src/drag/drag-layout.ts
|
|
3925
|
-
var INDENT_STEP_REM = 1.5;
|
|
3926
3990
|
function rootOrigin(root) {
|
|
3927
3991
|
const box = root.getBoundingClientRect();
|
|
3928
3992
|
return { x: box.left + root.clientLeft - root.scrollLeft, y: box.top + root.clientTop - root.scrollTop };
|
|
3929
3993
|
}
|
|
3930
3994
|
var spanBetween = (a, b) => ({ left: Math.min(a, b), width: Math.abs(b - a) });
|
|
3931
|
-
|
|
3932
|
-
|
|
3995
|
+
var leadingMargin = (element, rtl) => parseFloat(getComputedStyle(element)[rtl ? "marginRight" : "marginLeft"]) || 0;
|
|
3996
|
+
function indentStep(shell, rtl) {
|
|
3997
|
+
const copies = [0, 1].map((depth) => {
|
|
3998
|
+
const copy = shell.cloneNode(false);
|
|
3999
|
+
copy.removeAttribute("id");
|
|
4000
|
+
copy.removeAttribute("data-block-id");
|
|
4001
|
+
copy.style.setProperty("--quoin-indent", String(depth));
|
|
4002
|
+
copy.style.display = "none";
|
|
4003
|
+
return copy;
|
|
4004
|
+
});
|
|
4005
|
+
shell.after(...copies);
|
|
4006
|
+
const [flat, nested] = copies.map((copy) => leadingMargin(copy, rtl));
|
|
4007
|
+
for (const copy of copies) copy.remove();
|
|
4008
|
+
return nested > flat ? nested - flat : parseFloat(getComputedStyle(shell).fontSize) || 16;
|
|
3933
4009
|
}
|
|
3934
4010
|
function inlineEdges(shell, box, rtl) {
|
|
3935
|
-
const
|
|
3936
|
-
|
|
3937
|
-
return { start: box.left - (parseFloat(style.marginLeft) || 0), end: box.right };
|
|
4011
|
+
const margin = leadingMargin(shell, rtl);
|
|
4012
|
+
return rtl ? { start: box.right + margin, end: box.left } : { start: box.left - margin, end: box.right };
|
|
3938
4013
|
}
|
|
3939
4014
|
function measure(controller, root, moved, rtl) {
|
|
3940
4015
|
const { doc } = controller.editor.state;
|
|
3941
4016
|
const origin = rootOrigin(root);
|
|
3942
|
-
return
|
|
3943
|
-
const
|
|
3944
|
-
const shell = controller.blockElement(id);
|
|
4017
|
+
return chunkN25EH2GZ_cjs.visibleBlockIndexes(doc).flatMap((index) => {
|
|
4018
|
+
const block = doc.blocks[index];
|
|
4019
|
+
const shell = controller.blockElement(block.id);
|
|
3945
4020
|
if (shell === void 0) return [];
|
|
3946
4021
|
const box = shell.getBoundingClientRect();
|
|
3947
4022
|
const { start, end } = inlineEdges(shell, box, rtl);
|
|
3948
|
-
|
|
3949
|
-
|
|
4023
|
+
return [
|
|
4024
|
+
{
|
|
4025
|
+
id: block.id,
|
|
4026
|
+
top: box.top - origin.y,
|
|
4027
|
+
bottom: box.bottom - origin.y,
|
|
4028
|
+
start: start - origin.x,
|
|
4029
|
+
end: end - origin.x,
|
|
4030
|
+
indent: block.indent,
|
|
4031
|
+
dragged: moved.has(block.id),
|
|
4032
|
+
hidesNested: chunkZ5EEDCRI_cjs.isClosedToggle(block),
|
|
4033
|
+
shell
|
|
4034
|
+
}
|
|
4035
|
+
];
|
|
3950
4036
|
});
|
|
3951
4037
|
}
|
|
3952
4038
|
var furthestEnd = (blocks, rtl) => blocks.reduce((end, block) => rtl ? Math.min(end, block.end) : Math.max(end, block.end), blocks[0].end);
|
|
3953
4039
|
function measureDrag(controller, root, ids) {
|
|
3954
4040
|
const { doc } = controller.editor.state;
|
|
3955
|
-
const direction =
|
|
4041
|
+
const direction = chunkN25EH2GZ_cjs.inlineDirection(root);
|
|
3956
4042
|
const rtl = direction === "rtl";
|
|
3957
|
-
const moved = new Set(
|
|
4043
|
+
const moved = new Set(chunkZ5EEDCRI_cjs.movedBlockIds(doc, ids));
|
|
3958
4044
|
const blocks = measure(controller, root, moved, rtl);
|
|
3959
4045
|
const dragged = blocks.filter((block) => block.dragged);
|
|
3960
4046
|
if (dragged.length === 0) return null;
|
|
3961
4047
|
const [first] = dragged;
|
|
3962
4048
|
const origin = rootOrigin(root);
|
|
3963
4049
|
const viewport = root.ownerDocument.defaultView?.innerHeight ?? Infinity;
|
|
3964
|
-
const step = indentStep(
|
|
4050
|
+
const step = indentStep(first.shell, rtl);
|
|
3965
4051
|
const rest = doc.blocks.filter((block) => !moved.has(block.id));
|
|
3966
4052
|
const restIndex = new Map(rest.map((block, index) => [block.id, index]));
|
|
3967
4053
|
const staying = blocks.filter((block) => !block.dragged);
|
|
@@ -3992,6 +4078,7 @@ function nearestGap(blocks, pointerY) {
|
|
|
3992
4078
|
return nearest2;
|
|
3993
4079
|
}
|
|
3994
4080
|
function computeDropTarget({ pointerX, pointerY, blocks, indentStep: indentStep2, direction }) {
|
|
4081
|
+
if (blocks.length === 0) return null;
|
|
3995
4082
|
const staying = blocks.filter((block) => !block.dragged);
|
|
3996
4083
|
if (staying.length === 0) return { index: 0, indent: 0, lineTop: blocks[0].top, lineStart: blocks[0].start };
|
|
3997
4084
|
const index = nearestGap(staying, pointerY);
|
|
@@ -3999,7 +4086,8 @@ function computeDropTarget({ pointerX, pointerY, blocks, indentStep: indentStep2
|
|
|
3999
4086
|
if (index === 0) return { index, indent: 0, lineTop, lineStart: staying[0].start };
|
|
4000
4087
|
const above = staying[index - 1];
|
|
4001
4088
|
const step = direction === "rtl" ? -indentStep2 : indentStep2;
|
|
4002
|
-
const
|
|
4089
|
+
const deepest = above.hidesNested ? above.indent : above.indent + 1;
|
|
4090
|
+
const indent3 = Math.min(Math.max(Math.round((pointerX - above.start) / step), 0), deepest);
|
|
4003
4091
|
return { index, indent: indent3, lineTop, lineStart: above.start + indent3 * step };
|
|
4004
4092
|
}
|
|
4005
4093
|
|
|
@@ -4009,12 +4097,12 @@ var SCROLL_EDGE = 48;
|
|
|
4009
4097
|
var sameTarget = (a, b) => a?.index === b.index && a.indent === b.indent;
|
|
4010
4098
|
function draggedBlocks(controller, blockId) {
|
|
4011
4099
|
const { state } = controller.editor;
|
|
4012
|
-
return state.doc.index.has(blockId) ?
|
|
4100
|
+
return state.doc.index.has(blockId) ? handleTargets(state, blockId) : [];
|
|
4013
4101
|
}
|
|
4014
4102
|
function followPress(press, root, view) {
|
|
4015
4103
|
const { controller, store, overlay, handle: handle2, pointerId } = press;
|
|
4016
4104
|
const doc = view.document;
|
|
4017
|
-
const scroll =
|
|
4105
|
+
const scroll = chunkN25EH2GZ_cjs.createAutoScroll(root, follow, SCROLL_EDGE);
|
|
4018
4106
|
let pointer = { x: press.x, y: press.y };
|
|
4019
4107
|
let active = null;
|
|
4020
4108
|
let unsubscribe = () => {
|
|
@@ -4042,6 +4130,7 @@ function followPress(press, root, view) {
|
|
|
4042
4130
|
const { indentStep: indentStep2, blocks, direction } = layout;
|
|
4043
4131
|
const target = computeDropTarget({ pointerX: layout.draggedStart + dx, pointerY, blocks, indentStep: indentStep2, direction });
|
|
4044
4132
|
overlay.follow(dx, pointer.y - press.y);
|
|
4133
|
+
if (target === null) return;
|
|
4045
4134
|
overlay.mark({ top: target.lineTop, ...spanBetween(target.lineStart, layout.end) });
|
|
4046
4135
|
if (!sameTarget(active.target, target)) {
|
|
4047
4136
|
store.set({ drag: { blockIds: ids, targetIndent: target.indent } });
|
|
@@ -4052,6 +4141,7 @@ function followPress(press, root, view) {
|
|
|
4052
4141
|
if (done) return;
|
|
4053
4142
|
done = true;
|
|
4054
4143
|
unlistenDocument();
|
|
4144
|
+
unlistenScroll();
|
|
4055
4145
|
unlistenBlur();
|
|
4056
4146
|
unlistenKeys();
|
|
4057
4147
|
scroll.stop();
|
|
@@ -4067,7 +4157,7 @@ function followPress(press, root, view) {
|
|
|
4067
4157
|
finish();
|
|
4068
4158
|
if (dropped === null || dropped.target === null || controller.readOnly) return;
|
|
4069
4159
|
const { ids, layout, target } = dropped;
|
|
4070
|
-
if (!controller.run(
|
|
4160
|
+
if (!controller.run(chunkZ5EEDCRI_cjs.moveBlocksTo(ids, layout.toIndex(target.index), target.indent))) return;
|
|
4071
4161
|
controller.focus();
|
|
4072
4162
|
press.onMoved(ids[0]);
|
|
4073
4163
|
}
|
|
@@ -4089,9 +4179,10 @@ function followPress(press, root, view) {
|
|
|
4089
4179
|
event.stopPropagation();
|
|
4090
4180
|
finish();
|
|
4091
4181
|
}
|
|
4092
|
-
const unlistenDocument =
|
|
4093
|
-
const
|
|
4094
|
-
const
|
|
4182
|
+
const unlistenDocument = chunkN25EH2GZ_cjs.listen(doc, { pointermove: onPointerMove, pointerup: onPointerUp, pointercancel: finish });
|
|
4183
|
+
const unlistenScroll = chunkN25EH2GZ_cjs.listen(doc, { scroll: follow }, true);
|
|
4184
|
+
const unlistenBlur = chunkN25EH2GZ_cjs.listen(view, { blur: finish });
|
|
4185
|
+
const unlistenKeys = chunkN25EH2GZ_cjs.listen(view, { keydown: onKeyDown }, true);
|
|
4095
4186
|
return finish;
|
|
4096
4187
|
}
|
|
4097
4188
|
function pressDragHandle(press) {
|
|
@@ -4126,9 +4217,9 @@ function useBlockDrag(controller, store, blockId, overlay) {
|
|
|
4126
4217
|
onDragStart: () => {
|
|
4127
4218
|
dragged.current = true;
|
|
4128
4219
|
},
|
|
4129
|
-
// The canvas has already said where a drop moved the block,
|
|
4130
|
-
//
|
|
4131
|
-
onMoved: (movedId) =>
|
|
4220
|
+
// The canvas has already said where a drop moved the block, so this is heard only for a drop that nested the
|
|
4221
|
+
// block in place.
|
|
4222
|
+
onMoved: (movedId) => announceBlockMoved(controller, movedId, labels)
|
|
4132
4223
|
});
|
|
4133
4224
|
},
|
|
4134
4225
|
takeClick(event) {
|
|
@@ -4138,17 +4229,44 @@ function useBlockDrag(controller, store, blockId, overlay) {
|
|
|
4138
4229
|
}
|
|
4139
4230
|
};
|
|
4140
4231
|
}
|
|
4232
|
+
var listOf = (query) => typeof window.matchMedia === "function" ? window.matchMedia(query) : null;
|
|
4233
|
+
var readOnServer = () => false;
|
|
4234
|
+
function useMediaQuery(query, unsupported) {
|
|
4235
|
+
const subscribe3 = React7.useCallback(
|
|
4236
|
+
(notify) => {
|
|
4237
|
+
const list2 = listOf(query);
|
|
4238
|
+
list2?.addEventListener("change", notify);
|
|
4239
|
+
return () => list2?.removeEventListener("change", notify);
|
|
4240
|
+
},
|
|
4241
|
+
[query]
|
|
4242
|
+
);
|
|
4243
|
+
const read2 = () => listOf(query)?.matches ?? unsupported;
|
|
4244
|
+
return React7.useSyncExternalStore(subscribe3, read2, readOnServer);
|
|
4245
|
+
}
|
|
4246
|
+
|
|
4247
|
+
// src/mobile/use-coarse-pointer.ts
|
|
4248
|
+
var useCoarsePointer = () => useMediaQuery("(pointer: coarse)", false);
|
|
4141
4249
|
|
|
4142
4250
|
// src/gutter/add-block-below.ts
|
|
4251
|
+
var paragraphAfter = (blockId) => (state, dispatch) => {
|
|
4252
|
+
const { doc, schema } = state;
|
|
4253
|
+
const index = chunk4JDRDPLC_cjs.requireBlockIndex(doc, blockId);
|
|
4254
|
+
const paragraph = chunkZ5EEDCRI_cjs.createBlock(schema, "MARKDOWN", { kind: "paragraph" }, doc.blocks[index].indent);
|
|
4255
|
+
const tr = new chunkZ5EEDCRI_cjs.Transaction(state).step(chunkZ5EEDCRI_cjs.insertBlocksStep(chunkZ5EEDCRI_cjs.descendantsEnd(doc, index), [paragraph]));
|
|
4256
|
+
dispatch?.(tr.setSelection(chunkZ5EEDCRI_cjs.startOf(tr.doc, schema, paragraph.id)));
|
|
4257
|
+
return true;
|
|
4258
|
+
};
|
|
4143
4259
|
function addBlockBelow(controller, blockId) {
|
|
4144
4260
|
const { state } = controller.editor;
|
|
4145
4261
|
const { doc, schema } = state;
|
|
4146
|
-
const
|
|
4147
|
-
if (
|
|
4148
|
-
const
|
|
4149
|
-
const
|
|
4150
|
-
const
|
|
4151
|
-
const
|
|
4262
|
+
const index = doc.index.get(blockId);
|
|
4263
|
+
if (index === void 0) return false;
|
|
4264
|
+
const block = doc.blocks[index];
|
|
4265
|
+
const alone = chunkZ5EEDCRI_cjs.descendantsEnd(doc, index) === index + 1;
|
|
4266
|
+
const empty = alone && chunkZ5EEDCRI_cjs.isParagraph(block) && chunkZ5EEDCRI_cjs.regionLength(block, chunkZ5EEDCRI_cjs.primaryRegion(schema, block) ?? "") === 0;
|
|
4267
|
+
const fill = empty ? chunkZ5EEDCRI_cjs.setSelection(chunkZ5EEDCRI_cjs.startOf(doc, schema, blockId)) : paragraphAfter(blockId);
|
|
4268
|
+
const slash = chunkZ5EEDCRI_cjs.insertText("/", { origin: "command" });
|
|
4269
|
+
const { ok, tr } = chunkZ5EEDCRI_cjs.runCommands(state, [chunkZ5EEDCRI_cjs.setSelection(chunkZ5EEDCRI_cjs.blockRangeSelection(blockId)), fill, slash]);
|
|
4152
4270
|
if (ok && tr !== null) controller.dispatch(tr);
|
|
4153
4271
|
controller.focus();
|
|
4154
4272
|
return ok;
|
|
@@ -4197,6 +4315,20 @@ function BlockMenu({ controller, store, actions, onOpen, children }) {
|
|
|
4197
4315
|
);
|
|
4198
4316
|
}
|
|
4199
4317
|
|
|
4318
|
+
// src/ui/watch-direction.ts
|
|
4319
|
+
var TURNS_ROUND = { attributeFilter: ["dir", "class", "style"] };
|
|
4320
|
+
function watchDirection(element, onChange) {
|
|
4321
|
+
let current = chunkN25EH2GZ_cjs.inlineDirection(element);
|
|
4322
|
+
const observer = new MutationObserver(() => {
|
|
4323
|
+
const next = chunkN25EH2GZ_cjs.inlineDirection(element);
|
|
4324
|
+
if (next === current) return;
|
|
4325
|
+
current = next;
|
|
4326
|
+
onChange(next);
|
|
4327
|
+
});
|
|
4328
|
+
for (let node = element; node !== null; node = node.parentElement) observer.observe(node, TURNS_ROUND);
|
|
4329
|
+
return () => observer.disconnect();
|
|
4330
|
+
}
|
|
4331
|
+
|
|
4200
4332
|
// src/gutter/use-gutter-position.ts
|
|
4201
4333
|
var GAP = 4;
|
|
4202
4334
|
var VOID_LINE = 24;
|
|
@@ -4220,13 +4352,13 @@ function place2(controller, root, gutter, block) {
|
|
|
4220
4352
|
const line = firstLine(shell);
|
|
4221
4353
|
const top = line.top + (line.height - gutter.offsetHeight) / 2 - rootBox.top - root.clientTop + root.scrollTop;
|
|
4222
4354
|
const shellBox = shell.getBoundingClientRect();
|
|
4223
|
-
const beside =
|
|
4355
|
+
const beside = chunkN25EH2GZ_cjs.inlineDirection(root) === "rtl" ? shellBox.right + GAP : shellBox.left - gutter.offsetWidth - GAP;
|
|
4224
4356
|
const left = beside - rootBox.left - root.clientLeft + root.scrollLeft;
|
|
4225
4357
|
gutter.style.transform = `translate(${left}px, ${top}px)`;
|
|
4226
4358
|
gutter.style.visibility = "";
|
|
4227
4359
|
}
|
|
4228
4360
|
function useGutterPosition(controller, gutter, block) {
|
|
4229
|
-
|
|
4361
|
+
chunkN25EH2GZ_cjs.useIsomorphicLayoutEffect(() => {
|
|
4230
4362
|
const element = gutter.current;
|
|
4231
4363
|
const root = controller.root;
|
|
4232
4364
|
const view = root?.ownerDocument.defaultView;
|
|
@@ -4239,18 +4371,20 @@ function useGutterPosition(controller, gutter, block) {
|
|
|
4239
4371
|
frame = view.requestAnimationFrame(update);
|
|
4240
4372
|
};
|
|
4241
4373
|
const unsubscribe = controller.editor.subscribe(later);
|
|
4374
|
+
const unwatch = watchDirection(root, later);
|
|
4242
4375
|
const observer = new ResizeObserver(later);
|
|
4243
4376
|
observer.observe(root);
|
|
4244
4377
|
view.addEventListener("resize", later);
|
|
4245
4378
|
return () => {
|
|
4246
4379
|
view.cancelAnimationFrame(frame);
|
|
4247
4380
|
unsubscribe();
|
|
4381
|
+
unwatch();
|
|
4248
4382
|
observer.disconnect();
|
|
4249
4383
|
view.removeEventListener("resize", later);
|
|
4250
4384
|
};
|
|
4251
4385
|
}, [controller, gutter, block]);
|
|
4252
4386
|
}
|
|
4253
|
-
var headOf = (state) =>
|
|
4387
|
+
var headOf = (state) => chunkZ5EEDCRI_cjs.headBlockId(state.selection);
|
|
4254
4388
|
function blockAcross(controller, root, y) {
|
|
4255
4389
|
const box = root.getBoundingClientRect();
|
|
4256
4390
|
const probe = root.ownerDocument.elementFromPoint?.(box.left + box.width / 2, y);
|
|
@@ -4258,7 +4392,7 @@ function blockAcross(controller, root, y) {
|
|
|
4258
4392
|
}
|
|
4259
4393
|
function useGutterTarget(controller, store, gutter) {
|
|
4260
4394
|
const hovered = useCanvasUi(store, (state) => state.hoveredBlock);
|
|
4261
|
-
const head =
|
|
4395
|
+
const head = chunkN25EH2GZ_cjs.useEditorState(controller, headOf);
|
|
4262
4396
|
const [focusWithin, setFocusWithin] = React7.useState(false);
|
|
4263
4397
|
React7.useEffect(() => {
|
|
4264
4398
|
const root = controller.root;
|
|
@@ -4276,7 +4410,7 @@ function useGutterTarget(controller, store, gutter) {
|
|
|
4276
4410
|
const onFocusIn = () => setFocusWithin(true);
|
|
4277
4411
|
const onFocusOut = (event) => setFocusWithin(root.contains(event.relatedTarget));
|
|
4278
4412
|
setFocusWithin(root.contains(root.ownerDocument.activeElement));
|
|
4279
|
-
return
|
|
4413
|
+
return chunkN25EH2GZ_cjs.listen(root, { pointermove: onPointerMove, pointerleave: onPointerLeave, focusin: onFocusIn, focusout: onFocusOut });
|
|
4280
4414
|
}, [controller, store, gutter]);
|
|
4281
4415
|
const fallback = focusWithin ? head : null;
|
|
4282
4416
|
const target = hovered ?? fallback;
|
|
@@ -4286,6 +4420,7 @@ var GUTTER = "absolute top-0 left-0 z-10 flex items-center gap-0.5 pointer-coars
|
|
|
4286
4420
|
var ADD_BELOW = "text-muted-foreground pointer-coarse:hidden";
|
|
4287
4421
|
function Gutter({ controller, store, actions }) {
|
|
4288
4422
|
const labels = useLabels();
|
|
4423
|
+
const coarse = useCoarsePointer();
|
|
4289
4424
|
const element = React7.useRef(null);
|
|
4290
4425
|
const overlay = React7.useRef(null);
|
|
4291
4426
|
const menuOpenAtPress = React7.useRef(false);
|
|
@@ -4331,7 +4466,7 @@ function Gutter({ controller, store, actions }) {
|
|
|
4331
4466
|
variant: "ghost",
|
|
4332
4467
|
size: null,
|
|
4333
4468
|
tabIndex: -1,
|
|
4334
|
-
"aria-label": labels.dragHandle,
|
|
4469
|
+
"aria-label": coarse ? labels.blockOptions ?? englishLabels.blockOptions : labels.dragHandle,
|
|
4335
4470
|
className: cn("text-muted-foreground h-6 w-4 cursor-grab rounded-md", SQUARE_TAP_TARGET_FLOOR),
|
|
4336
4471
|
onPointerDown: (event) => {
|
|
4337
4472
|
menuOpenAtPress.current = event.button === 0 && store.get().blockMenu?.anchor === "handle";
|
|
@@ -4353,17 +4488,6 @@ function Gutter({ controller, store, actions }) {
|
|
|
4353
4488
|
] });
|
|
4354
4489
|
}
|
|
4355
4490
|
|
|
4356
|
-
// src/i18n/resolve-labels.ts
|
|
4357
|
-
var isRecord = (value) => typeof value === "object" && value !== null;
|
|
4358
|
-
function ontoRecords(overrides) {
|
|
4359
|
-
const taken = Object.entries(overrides).map(([key, value]) => {
|
|
4360
|
-
const fallback = englishLabels[key];
|
|
4361
|
-
return [key, isRecord(value) && isRecord(fallback) ? { ...fallback, ...value } : value];
|
|
4362
|
-
});
|
|
4363
|
-
return Object.fromEntries(taken);
|
|
4364
|
-
}
|
|
4365
|
-
var resolveLabels = (overrides) => chunkZWTIRGY5_cjs.mergeLabels(englishLabels, overrides && ontoRecords(overrides));
|
|
4366
|
-
|
|
4367
4491
|
// src/menus/floating/range-rect.ts
|
|
4368
4492
|
var TEXT_NODE = 3;
|
|
4369
4493
|
function lineBox(rect, host) {
|
|
@@ -4377,7 +4501,7 @@ function pointInHost(host, { node, offset }) {
|
|
|
4377
4501
|
return host.contains(node) ? { node, offset: Math.min(offset, nodeLength(node)) } : null;
|
|
4378
4502
|
}
|
|
4379
4503
|
function textRect(host, { from, to }) {
|
|
4380
|
-
const map =
|
|
4504
|
+
const map = chunkN25EH2GZ_cjs.domMapOf(host);
|
|
4381
4505
|
const range = host.ownerDocument.createRange();
|
|
4382
4506
|
if (map === void 0 || typeof range.getBoundingClientRect !== "function") return null;
|
|
4383
4507
|
const start = pointInHost(host, map.toDom(from, 1));
|
|
@@ -4390,7 +4514,7 @@ function textRect(host, { from, to }) {
|
|
|
4390
4514
|
}
|
|
4391
4515
|
function rangeRect(controller, range) {
|
|
4392
4516
|
const host = controller.registry.get(range.block, range.region);
|
|
4393
|
-
if (host === void 0 || !host.isConnected || controller.composingKey ===
|
|
4517
|
+
if (host === void 0 || !host.isConnected || controller.composingKey === chunkN25EH2GZ_cjs.hostKey(range.block, range.region)) {
|
|
4394
4518
|
return null;
|
|
4395
4519
|
}
|
|
4396
4520
|
const rect = textRect(host, range);
|
|
@@ -4406,7 +4530,7 @@ function union(a, b) {
|
|
|
4406
4530
|
function selectionRect(controller) {
|
|
4407
4531
|
const { state } = controller.editor;
|
|
4408
4532
|
if (state.selection?.kind !== "text") return null;
|
|
4409
|
-
const ranges =
|
|
4533
|
+
const ranges = chunkZ5EEDCRI_cjs.markRanges(state);
|
|
4410
4534
|
if (ranges.length === 0) return null;
|
|
4411
4535
|
const first = rangeRect(controller, ranges[0]);
|
|
4412
4536
|
if (ranges.length === 1) return first;
|
|
@@ -4417,7 +4541,7 @@ function selectionRect(controller) {
|
|
|
4417
4541
|
// src/menus/floating/use-selection-anchor.ts
|
|
4418
4542
|
var ROOM_ABOVE = 56;
|
|
4419
4543
|
function selectionHost(controller) {
|
|
4420
|
-
const [first] =
|
|
4544
|
+
const [first] = chunkZ5EEDCRI_cjs.markRanges(controller.editor.state);
|
|
4421
4545
|
return (first && controller.registry.get(first.block, first.region)) ?? controller.root ?? void 0;
|
|
4422
4546
|
}
|
|
4423
4547
|
function useSelectionAnchor(controller, state) {
|
|
@@ -4431,7 +4555,7 @@ function useSelectionAnchor(controller, state) {
|
|
|
4431
4555
|
[controller, state]
|
|
4432
4556
|
);
|
|
4433
4557
|
const [side, setSide] = React7.useState("top");
|
|
4434
|
-
|
|
4558
|
+
chunkN25EH2GZ_cjs.useIsomorphicLayoutEffect(() => {
|
|
4435
4559
|
const rect = selectionRect(controller);
|
|
4436
4560
|
if (rect) setSide(rect.top < ROOM_ABOVE ? "bottom" : "top");
|
|
4437
4561
|
}, [controller, state]);
|
|
@@ -4466,9 +4590,9 @@ var ICONS = { left: AlignLeft, center: AlignCenter, right: AlignRight, justify:
|
|
|
4466
4590
|
var ALIGNS2 = Object.keys(ICONS);
|
|
4467
4591
|
var LABEL_KEYS = { left: "alignLeft", center: "alignCenter", right: "alignRight", justify: "alignJustify" };
|
|
4468
4592
|
function sharedAlign(state) {
|
|
4469
|
-
const blocks =
|
|
4593
|
+
const blocks = chunkZ5EEDCRI_cjs.selectedBlockIds(state.doc, state.selection).map((id) => chunk4JDRDPLC_cjs.blockById(state.doc, id)).filter((block) => block?.type === "MARKDOWN");
|
|
4470
4594
|
if (blocks.length === 0) return null;
|
|
4471
|
-
const aligns = new Set(blocks.map((block) =>
|
|
4595
|
+
const aligns = new Set(blocks.map((block) => chunk4JDRDPLC_cjs.alignOrUndefined(block?.attrs.align) ?? "left"));
|
|
4472
4596
|
return aligns.size === 1 ? [...aligns][0] : "";
|
|
4473
4597
|
}
|
|
4474
4598
|
function AlignDropdown({ controller, state }) {
|
|
@@ -4477,16 +4601,49 @@ function AlignDropdown({ controller, state }) {
|
|
|
4477
4601
|
if (value === null) return null;
|
|
4478
4602
|
const Icon2 = value === "" ? AlignLeft : ICONS[value];
|
|
4479
4603
|
const trigger = /* @__PURE__ */ jsxRuntime.jsx(Button, { type: "button", variant: "ghost", size: "icon-sm", "aria-label": labels.align, children: /* @__PURE__ */ jsxRuntime.jsx(Icon2, {}) });
|
|
4480
|
-
return /* @__PURE__ */ jsxRuntime.jsx(ToolbarMenu, { controller, trigger, children: /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuRadioGroup, { value, onValueChange: (align) => controller.run(
|
|
4604
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ToolbarMenu, { controller, trigger, children: /* @__PURE__ */ jsxRuntime.jsx(DropdownMenuRadioGroup, { value, onValueChange: (align) => controller.run(chunkZ5EEDCRI_cjs.setTextAlign(align)), children: ALIGNS2.map((align) => /* @__PURE__ */ jsxRuntime.jsxs(DropdownMenuRadioItem, { value: align, indicator: /* @__PURE__ */ jsxRuntime.jsx(Check, { className: "size-4" }), children: [
|
|
4481
4605
|
/* @__PURE__ */ jsxRuntime.jsx(MenuIcon, { icon: ICONS[align] }),
|
|
4482
4606
|
labels[LABEL_KEYS[align]]
|
|
4483
4607
|
] }, align)) }) });
|
|
4484
4608
|
}
|
|
4609
|
+
|
|
4610
|
+
// src/toolbar/toolbar-items.ts
|
|
4611
|
+
function markItem(mark, title, icon) {
|
|
4612
|
+
return {
|
|
4613
|
+
id: mark,
|
|
4614
|
+
title,
|
|
4615
|
+
icon,
|
|
4616
|
+
isActive: (state) => chunkZ5EEDCRI_cjs.isActive(state, mark),
|
|
4617
|
+
run: (controller) => void controller.run(chunkZ5EEDCRI_cjs.toggleMark(mark))
|
|
4618
|
+
};
|
|
4619
|
+
}
|
|
4620
|
+
var linkItem = (labels, openLink) => ({
|
|
4621
|
+
id: "link",
|
|
4622
|
+
title: labels.link,
|
|
4623
|
+
icon: Link,
|
|
4624
|
+
opensDialog: true,
|
|
4625
|
+
run: openLink
|
|
4626
|
+
});
|
|
4627
|
+
|
|
4628
|
+
// src/menus/bubble/bubble-items.ts
|
|
4629
|
+
function bubbleItems(labels, openLink) {
|
|
4630
|
+
return {
|
|
4631
|
+
inline: [
|
|
4632
|
+
markItem("bold", labels.bold, Bold),
|
|
4633
|
+
markItem("italic", labels.italic, Italic),
|
|
4634
|
+
markItem("underline", labels.underline, Underline),
|
|
4635
|
+
markItem("strike", labels.strike, Strikethrough),
|
|
4636
|
+
markItem("code", labels.code, Code),
|
|
4637
|
+
linkItem(labels, openLink)
|
|
4638
|
+
],
|
|
4639
|
+
scripts: [markItem("sub", labels.subscript, Subscript), markItem("sup", labels.superscript, Superscript)]
|
|
4640
|
+
};
|
|
4641
|
+
}
|
|
4485
4642
|
var MARKS = { color: "color", background: "highlight" };
|
|
4486
4643
|
function selectionColor(state, mark) {
|
|
4487
4644
|
const names = /* @__PURE__ */ new Set();
|
|
4488
|
-
for (const range of
|
|
4489
|
-
for (const node of
|
|
4645
|
+
for (const range of chunkZ5EEDCRI_cjs.markRanges(state)) {
|
|
4646
|
+
for (const node of chunkZ5EEDCRI_cjs.rangeContent(state, range)) {
|
|
4490
4647
|
const found = node.marks.find((candidate) => candidate.type === mark);
|
|
4491
4648
|
names.add(found === void 0 ? "default" : found.attrs?.color);
|
|
4492
4649
|
}
|
|
@@ -4495,7 +4652,7 @@ function selectionColor(state, mark) {
|
|
|
4495
4652
|
return names.size === 1 && typeof only === "string" ? only : "";
|
|
4496
4653
|
}
|
|
4497
4654
|
function colorCommand(key, name) {
|
|
4498
|
-
return name === "default" ?
|
|
4655
|
+
return name === "default" ? chunkZ5EEDCRI_cjs.unsetMark(MARKS[key]) : chunkZ5EEDCRI_cjs.setMark(MARKS[key], { color: name });
|
|
4499
4656
|
}
|
|
4500
4657
|
function ColorPopover({ controller, state }) {
|
|
4501
4658
|
const labels = useLabels();
|
|
@@ -4509,15 +4666,32 @@ function TurnIntoDropdown({ controller, state }) {
|
|
|
4509
4666
|
labels.turnInto,
|
|
4510
4667
|
/* @__PURE__ */ jsxRuntime.jsx(ChevronDown, {})
|
|
4511
4668
|
] });
|
|
4512
|
-
return /* @__PURE__ */ jsxRuntime.jsx(ToolbarMenu, { controller, trigger, children: /* @__PURE__ */ jsxRuntime.jsx(TurnIntoItems, { kit: DROPDOWN_KIT, controller, blockIds:
|
|
4669
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ToolbarMenu, { controller, trigger, children: /* @__PURE__ */ jsxRuntime.jsx(TurnIntoItems, { kit: DROPDOWN_KIT, controller, blockIds: chunkZ5EEDCRI_cjs.selectedBlockIds(state.doc, state.selection) }) });
|
|
4670
|
+
}
|
|
4671
|
+
function useFocusBackToText(controller, holds = isBubblePart) {
|
|
4672
|
+
const latest = React7.useRef(holds);
|
|
4673
|
+
chunkN25EH2GZ_cjs.useIsomorphicLayoutEffect(() => {
|
|
4674
|
+
latest.current = holds;
|
|
4675
|
+
});
|
|
4676
|
+
chunkN25EH2GZ_cjs.useIsomorphicLayoutEffect(
|
|
4677
|
+
() => () => {
|
|
4678
|
+
const doc = controller.root?.ownerDocument;
|
|
4679
|
+
if (!doc || !latest.current(doc.activeElement, controller)) return;
|
|
4680
|
+
queueMicrotask(() => {
|
|
4681
|
+
if (doc.activeElement === null || doc.activeElement === doc.body) controller.focus();
|
|
4682
|
+
});
|
|
4683
|
+
},
|
|
4684
|
+
[controller]
|
|
4685
|
+
);
|
|
4513
4686
|
}
|
|
4514
4687
|
var DIVIDER = "mx-0.5 h-5 w-px shrink-0 bg-border";
|
|
4515
4688
|
function BubbleToolbar({ controller, labels, store, extraItems }) {
|
|
4516
|
-
const state =
|
|
4689
|
+
const state = chunkN25EH2GZ_cjs.useEditorState(controller, chunkN25EH2GZ_cjs.wholeState);
|
|
4517
4690
|
const { anchor, side } = useSelectionAnchor(controller, state);
|
|
4518
4691
|
const roving = useRovingFocus();
|
|
4519
4692
|
const items = React7.useMemo(() => bubbleItems(labels, () => store.set({ linkPopover: { open: true } })), [labels, store]);
|
|
4520
4693
|
useFocusKey(controller, roving.focusCurrent);
|
|
4694
|
+
useFocusBackToText(controller);
|
|
4521
4695
|
const onKeyDown = (event) => {
|
|
4522
4696
|
if (!roving.owns(event.target)) return;
|
|
4523
4697
|
if (event.key === "Escape" || event.key === "Tab" && !event.altKey && !event.ctrlKey && !event.metaKey) {
|
|
@@ -4556,29 +4730,15 @@ function BubbleToolbar({ controller, labels, store, extraItems }) {
|
|
|
4556
4730
|
)
|
|
4557
4731
|
] });
|
|
4558
4732
|
}
|
|
4559
|
-
var listOf = (query) => typeof window.matchMedia === "function" ? window.matchMedia(query) : null;
|
|
4560
|
-
var readOnServer = () => false;
|
|
4561
|
-
function useMediaQuery(query, unsupported) {
|
|
4562
|
-
const subscribe3 = React7.useCallback(
|
|
4563
|
-
(notify) => {
|
|
4564
|
-
const list2 = listOf(query);
|
|
4565
|
-
list2?.addEventListener("change", notify);
|
|
4566
|
-
return () => list2?.removeEventListener("change", notify);
|
|
4567
|
-
},
|
|
4568
|
-
[query]
|
|
4569
|
-
);
|
|
4570
|
-
const read2 = () => listOf(query)?.matches ?? unsupported;
|
|
4571
|
-
return React7.useSyncExternalStore(subscribe3, read2, readOnServer);
|
|
4572
|
-
}
|
|
4573
4733
|
|
|
4574
4734
|
// src/menus/bubble/use-fine-pointer.ts
|
|
4575
4735
|
var useFinePointer = () => useMediaQuery("(pointer: fine)", true);
|
|
4576
4736
|
|
|
4577
4737
|
// src/menus/bubble/use-bubble-visibility.ts
|
|
4578
|
-
var hasTextRange = (state) => state.selection?.kind === "text" && !
|
|
4738
|
+
var hasTextRange = (state) => state.selection?.kind === "text" && !chunkZ5EEDCRI_cjs.isCollapsed(state.selection) && chunkZ5EEDCRI_cjs.markRanges(state).length > 0;
|
|
4579
4739
|
function useBubbleVisibility(controller) {
|
|
4580
|
-
const range =
|
|
4581
|
-
const readOnly =
|
|
4740
|
+
const range = chunkN25EH2GZ_cjs.useEditorState(controller, hasTextRange);
|
|
4741
|
+
const readOnly = chunkN25EH2GZ_cjs.useReadOnly(controller);
|
|
4582
4742
|
const fine = useFinePointer();
|
|
4583
4743
|
const settled = useSelectionSettled(controller);
|
|
4584
4744
|
return range && !readOnly && fine && settled;
|
|
@@ -4595,16 +4755,16 @@ function BubbleOverlay({ controller }) {
|
|
|
4595
4755
|
return /* @__PURE__ */ jsxRuntime.jsx(BubbleToolbar, { controller, labels, store, extraItems });
|
|
4596
4756
|
}
|
|
4597
4757
|
function bubbleExtension() {
|
|
4598
|
-
return
|
|
4758
|
+
return chunkZ5EEDCRI_cjs.defineExtension({ name: "bubble", ui: { overlays: [BubbleOverlay] } });
|
|
4599
4759
|
}
|
|
4600
4760
|
|
|
4601
4761
|
// src/menus/link/link-at-selection.ts
|
|
4602
4762
|
function linkAround(state, from, to = from) {
|
|
4603
4763
|
if (from.block !== to.block || from.region !== to.region) return null;
|
|
4604
|
-
const inline =
|
|
4605
|
-
const extent =
|
|
4764
|
+
const inline = chunkN25EH2GZ_cjs.regionInline(state, from.block, from.region) ?? [];
|
|
4765
|
+
const extent = chunkZ5EEDCRI_cjs.markExtent(inline, from.offset, "link");
|
|
4606
4766
|
if (extent === null || to.offset > extent.to) return null;
|
|
4607
|
-
const attrs =
|
|
4767
|
+
const attrs = chunk4JDRDPLC_cjs.sliceInline(inline, extent.from, extent.to)[0]?.marks.find((mark) => mark.type === "link")?.attrs;
|
|
4608
4768
|
if (attrs?.href === void 0) return null;
|
|
4609
4769
|
const range = { block: from.block, region: from.region, ...extent };
|
|
4610
4770
|
return { href: attrs.href, title: attrs.title || void 0, range };
|
|
@@ -4612,9 +4772,15 @@ function linkAround(state, from, to = from) {
|
|
|
4612
4772
|
function linkAtSelection(state) {
|
|
4613
4773
|
const { selection } = state;
|
|
4614
4774
|
if (selection?.kind !== "text") return null;
|
|
4615
|
-
const { from, to } =
|
|
4775
|
+
const { from, to } = chunkZ5EEDCRI_cjs.orderedRange(state.doc, selection.anchor, selection.head);
|
|
4616
4776
|
return linkAround(state, from, to);
|
|
4617
4777
|
}
|
|
4778
|
+
function sameLink(a, b) {
|
|
4779
|
+
if (a === null || b === null) return a === b;
|
|
4780
|
+
const [x, y] = [a.range, b.range];
|
|
4781
|
+
const sameRange2 = x.block === y.block && x.region === y.region && x.from === y.from && x.to === y.to;
|
|
4782
|
+
return sameRange2 && a.href === b.href && a.title === b.title;
|
|
4783
|
+
}
|
|
4618
4784
|
|
|
4619
4785
|
// src/menus/link/link-element.ts
|
|
4620
4786
|
var LINK = "a[data-quoin-link]";
|
|
@@ -4624,18 +4790,23 @@ function linkElementAt(controller, target) {
|
|
|
4624
4790
|
}
|
|
4625
4791
|
function linkAtElement(controller, state, element) {
|
|
4626
4792
|
const host = controller.registry.locate(element);
|
|
4627
|
-
const offset = host === null ? null :
|
|
4793
|
+
const offset = host === null ? null : chunkN25EH2GZ_cjs.domMapOf(host.element)?.fromDom(element, 0) ?? null;
|
|
4628
4794
|
if (host === null || offset === null) return null;
|
|
4629
4795
|
return linkAround(state, { block: host.block, region: host.region, offset });
|
|
4630
4796
|
}
|
|
4631
4797
|
var sameStart = (a, b) => a.block === b.block && a.region === b.region && a.from === b.from;
|
|
4632
|
-
function
|
|
4798
|
+
function sameLink2(controller, a, b) {
|
|
4633
4799
|
if (a === b || a === null || b === null) return a === b;
|
|
4634
4800
|
const { state } = controller.editor;
|
|
4635
4801
|
const first = linkAtElement(controller, state, a)?.range;
|
|
4636
4802
|
const second = linkAtElement(controller, state, b)?.range;
|
|
4637
4803
|
return first !== void 0 && second !== void 0 && sameStart(first, second);
|
|
4638
4804
|
}
|
|
4805
|
+
function OpenLinkButton({ href, label }) {
|
|
4806
|
+
const safe = chunk4JDRDPLC_cjs.sanitizeHref(href);
|
|
4807
|
+
if (!safe) return null;
|
|
4808
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Button, { asChild: true, variant: "ghost", size: "icon-sm", children: /* @__PURE__ */ jsxRuntime.jsx("a", { href: safe, target: "_blank", rel: "noopener noreferrer", "aria-label": label, children: /* @__PURE__ */ jsxRuntime.jsx(ExternalLink, {}) }) });
|
|
4809
|
+
}
|
|
4639
4810
|
|
|
4640
4811
|
// src/menus/link/truncate-middle.ts
|
|
4641
4812
|
var ELLIPSIS = "\u2026";
|
|
@@ -4650,7 +4821,7 @@ function truncateMiddle(text2, max) {
|
|
|
4650
4821
|
// src/menus/link/unlink-range.ts
|
|
4651
4822
|
function unlinkRange({ block, region, from, to }) {
|
|
4652
4823
|
return (state, dispatch) => {
|
|
4653
|
-
const tr = new
|
|
4824
|
+
const tr = new chunkZ5EEDCRI_cjs.Transaction(state).step(chunkZ5EEDCRI_cjs.removeMarkStep(block, region, from, to, "link"));
|
|
4654
4825
|
if (!tr.docChanged) return false;
|
|
4655
4826
|
dispatch?.(tr);
|
|
4656
4827
|
return true;
|
|
@@ -4672,12 +4843,12 @@ function useRestedValue(value, delay) {
|
|
|
4672
4843
|
// src/menus/link/use-caret-in-link.ts
|
|
4673
4844
|
function caretLinkKey(state) {
|
|
4674
4845
|
const { selection } = state;
|
|
4675
|
-
if (selection?.kind !== "text" || !
|
|
4846
|
+
if (selection?.kind !== "text" || !chunkZ5EEDCRI_cjs.isCollapsed(selection)) return null;
|
|
4676
4847
|
const link = linkAtSelection(state);
|
|
4677
4848
|
return link && [link.range.block, link.range.region, link.range.from, link.href].join("\0");
|
|
4678
4849
|
}
|
|
4679
4850
|
function useCaretInLink(controller, delay) {
|
|
4680
|
-
const key =
|
|
4851
|
+
const key = chunkN25EH2GZ_cjs.useEditorState(controller, caretLinkKey);
|
|
4681
4852
|
const settled = useSelectionSettled(controller);
|
|
4682
4853
|
return useRestedValue(settled ? key : null, delay) !== null;
|
|
4683
4854
|
}
|
|
@@ -4696,7 +4867,7 @@ function usePointerLink(controller, card, delay) {
|
|
|
4696
4867
|
const onCard = !!card.current?.contains(event.target);
|
|
4697
4868
|
const next = onCard ? shown.current : linkElementAt(controller, event.target);
|
|
4698
4869
|
clearTimeout(timer.current);
|
|
4699
|
-
if (!
|
|
4870
|
+
if (!sameLink2(controller, next, shown.current)) timer.current = setTimeout(() => show(next), delay);
|
|
4700
4871
|
};
|
|
4701
4872
|
document.addEventListener("pointerover", onOver);
|
|
4702
4873
|
return () => {
|
|
@@ -4707,15 +4878,16 @@ function usePointerLink(controller, card, delay) {
|
|
|
4707
4878
|
return { element, dismiss: React7.useCallback(() => show(null), [show]) };
|
|
4708
4879
|
}
|
|
4709
4880
|
var REST_MS = 300;
|
|
4881
|
+
var OPEN_POPOVER = "Mod-k";
|
|
4710
4882
|
var URL_LENGTH = 48;
|
|
4711
4883
|
var CARD = "flex w-auto items-center gap-0.5 py-1 ps-3 pe-1 shadow-md";
|
|
4712
4884
|
var ADDRESS = "me-1 whitespace-nowrap text-sm text-muted-foreground";
|
|
4713
4885
|
function LinkCard({ controller, labels, store, cardRef, element, onUnlinked }) {
|
|
4714
|
-
const
|
|
4715
|
-
|
|
4716
|
-
|
|
4717
|
-
[controller, state, element]
|
|
4886
|
+
const select = React7.useCallback(
|
|
4887
|
+
(state) => element === null ? linkAtSelection(state) : linkAtElement(controller, state, element),
|
|
4888
|
+
[controller, element]
|
|
4718
4889
|
);
|
|
4890
|
+
const link = chunkN25EH2GZ_cjs.useEditorState(controller, select, sameLink);
|
|
4719
4891
|
const anchor = React7.useMemo(() => {
|
|
4720
4892
|
if (link === null) return { current: null };
|
|
4721
4893
|
const { range } = link;
|
|
@@ -4724,12 +4896,11 @@ function LinkCard({ controller, labels, store, cardRef, element, onUnlinked }) {
|
|
|
4724
4896
|
}, [controller, link]);
|
|
4725
4897
|
if (link === null) return null;
|
|
4726
4898
|
const { block, region, from, to } = link.range;
|
|
4727
|
-
const href = chunkI7X7B3WD_cjs.sanitizeHref(link.href);
|
|
4728
4899
|
const address = truncateMiddle(link.href, URL_LENGTH);
|
|
4729
4900
|
const edit2 = () => {
|
|
4730
4901
|
if (element !== null) {
|
|
4731
|
-
const selection =
|
|
4732
|
-
|
|
4902
|
+
const selection = chunkZ5EEDCRI_cjs.textSelection({ block, region, offset: from }, { block, region, offset: to });
|
|
4903
|
+
chunkN25EH2GZ_cjs.dispatchSelection(controller, selection);
|
|
4733
4904
|
}
|
|
4734
4905
|
store.set({ linkPopover: { open: true } });
|
|
4735
4906
|
};
|
|
@@ -4743,6 +4914,7 @@ function LinkCard({ controller, labels, store, cardRef, element, onUnlinked }) {
|
|
|
4743
4914
|
PopoverContent,
|
|
4744
4915
|
{
|
|
4745
4916
|
ref: cardRef,
|
|
4917
|
+
role: "group",
|
|
4746
4918
|
"aria-label": labels.link,
|
|
4747
4919
|
side: "bottom",
|
|
4748
4920
|
align: "start",
|
|
@@ -4753,8 +4925,19 @@ function LinkCard({ controller, labels, store, cardRef, element, onUnlinked }) {
|
|
|
4753
4925
|
onMouseDown: keepFocus,
|
|
4754
4926
|
children: [
|
|
4755
4927
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: ADDRESS, title: address === link.href ? void 0 : link.href, children: address }),
|
|
4756
|
-
|
|
4757
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4928
|
+
/* @__PURE__ */ jsxRuntime.jsx(OpenLinkButton, { href: link.href, label: labels.linkOpen }),
|
|
4929
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4930
|
+
Button,
|
|
4931
|
+
{
|
|
4932
|
+
type: "button",
|
|
4933
|
+
variant: "ghost",
|
|
4934
|
+
size: "icon-sm",
|
|
4935
|
+
"aria-label": labels.linkEdit,
|
|
4936
|
+
"aria-keyshortcuts": shortcutHint(OPEN_POPOVER, controller.isMac, labels).aria,
|
|
4937
|
+
onClick: edit2,
|
|
4938
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(Pencil, {})
|
|
4939
|
+
}
|
|
4940
|
+
),
|
|
4758
4941
|
/* @__PURE__ */ jsxRuntime.jsx(Button, { type: "button", variant: "ghost", size: "icon-sm", "aria-label": labels.linkRemove, onClick: unlink, children: /* @__PURE__ */ jsxRuntime.jsx(Unlink, {}) })
|
|
4759
4942
|
]
|
|
4760
4943
|
}
|
|
@@ -4771,12 +4954,12 @@ function LinkHoverCard(props) {
|
|
|
4771
4954
|
|
|
4772
4955
|
// src/menus/link/apply-link.ts
|
|
4773
4956
|
function insertLinkedText(value, href, caret) {
|
|
4774
|
-
const safe =
|
|
4957
|
+
const safe = chunk4JDRDPLC_cjs.sanitizeHref(href);
|
|
4775
4958
|
return (state, dispatch) => {
|
|
4776
4959
|
if (!safe) return false;
|
|
4777
4960
|
const link = { type: "link", attrs: { href: safe } };
|
|
4778
|
-
const marks =
|
|
4779
|
-
const tr = new
|
|
4961
|
+
const marks = chunk4JDRDPLC_cjs.addMark(chunkZ5EEDCRI_cjs.caretMarks(state.doc, state.schema, state.storedMarks, caret), link);
|
|
4962
|
+
const tr = new chunkZ5EEDCRI_cjs.Transaction(state).step(chunkZ5EEDCRI_cjs.replaceInlineStep(caret.block, caret.region, caret.offset, caret.offset, [chunk4JDRDPLC_cjs.text(value, marks)])).setSelection(chunkZ5EEDCRI_cjs.textSelection({ ...caret, offset: caret.offset + value.length }));
|
|
4780
4963
|
dispatch?.(tr);
|
|
4781
4964
|
return true;
|
|
4782
4965
|
};
|
|
@@ -4785,21 +4968,22 @@ function applyLink(href, value) {
|
|
|
4785
4968
|
return (state, dispatch) => {
|
|
4786
4969
|
const { selection } = state;
|
|
4787
4970
|
const link = linkAtSelection(state);
|
|
4788
|
-
if (selection?.kind === "text" &&
|
|
4971
|
+
if (selection?.kind === "text" && chunkZ5EEDCRI_cjs.isCollapsed(selection) && link === null) {
|
|
4789
4972
|
return insertLinkedText(value, href, selection.head)(state, dispatch);
|
|
4790
4973
|
}
|
|
4791
|
-
return
|
|
4974
|
+
return chunkZ5EEDCRI_cjs.setLink(href, link?.title)(state, dispatch);
|
|
4792
4975
|
};
|
|
4793
4976
|
}
|
|
4794
4977
|
var CONTENT2 = "w-80 p-2 shadow-md";
|
|
4795
4978
|
var FIELD2 = "h-8";
|
|
4796
4979
|
var MESSAGE = "mt-1.5 px-1 text-sm text-destructive";
|
|
4980
|
+
var CONTROLS = "input, button, a[href]";
|
|
4797
4981
|
function popoverAnchor(controller, link) {
|
|
4798
4982
|
const { selection } = controller.editor.state;
|
|
4799
4983
|
if (selection?.kind !== "text") return null;
|
|
4800
4984
|
const { block, region, offset } = selection.head;
|
|
4801
4985
|
const caret = link?.range ?? { block, region, from: offset, to: offset };
|
|
4802
|
-
const collapsed =
|
|
4986
|
+
const collapsed = chunkZ5EEDCRI_cjs.isCollapsed(selection);
|
|
4803
4987
|
return virtualAnchor(
|
|
4804
4988
|
() => collapsed ? rangeRect(controller, caret) : selectionRect(controller),
|
|
4805
4989
|
() => controller.registry.get(block, region)
|
|
@@ -4811,7 +4995,8 @@ function LinkPopover({ controller, labels, onClose }) {
|
|
|
4811
4995
|
const [invalid, setInvalid] = React7.useState(false);
|
|
4812
4996
|
const messageId = React7.useId();
|
|
4813
4997
|
const anchor = React7.useMemo(() => ({ current: popoverAnchor(controller, link) }), [controller, link]);
|
|
4814
|
-
const
|
|
4998
|
+
const content = React7.useRef(null);
|
|
4999
|
+
useFocusBackToText(controller, (focused) => focused !== null && content.current?.contains(focused) === true);
|
|
4815
5000
|
const backToText = () => {
|
|
4816
5001
|
onClose();
|
|
4817
5002
|
controller.focus();
|
|
@@ -4823,12 +5008,23 @@ function LinkPopover({ controller, labels, onClose }) {
|
|
|
4823
5008
|
const apply = (event) => {
|
|
4824
5009
|
event.preventDefault();
|
|
4825
5010
|
const href = linkAddress(address);
|
|
4826
|
-
if (href === null)
|
|
5011
|
+
if (href === null) {
|
|
5012
|
+
setInvalid(true);
|
|
5013
|
+
controller.announce(labels.invalidLink);
|
|
5014
|
+
return;
|
|
5015
|
+
}
|
|
4827
5016
|
controller.run(applyLink(href, address.trim()));
|
|
4828
5017
|
backToText();
|
|
4829
5018
|
};
|
|
4830
5019
|
const remove = () => {
|
|
4831
|
-
controller.run(
|
|
5020
|
+
controller.run(chunkZ5EEDCRI_cjs.unsetLink);
|
|
5021
|
+
backToText();
|
|
5022
|
+
};
|
|
5023
|
+
const tabOut = (event) => {
|
|
5024
|
+
if (event.key !== "Tab" || event.ctrlKey || event.metaKey) return;
|
|
5025
|
+
const controls = [...event.currentTarget.querySelectorAll(CONTROLS)];
|
|
5026
|
+
if (event.target !== (event.shiftKey ? controls[0] : controls.at(-1))) return;
|
|
5027
|
+
event.preventDefault();
|
|
4832
5028
|
backToText();
|
|
4833
5029
|
};
|
|
4834
5030
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
@@ -4844,6 +5040,7 @@ function LinkPopover({ controller, labels, onClose }) {
|
|
|
4844
5040
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
4845
5041
|
PopoverContent,
|
|
4846
5042
|
{
|
|
5043
|
+
ref: content,
|
|
4847
5044
|
"aria-label": labels.link,
|
|
4848
5045
|
side: "bottom",
|
|
4849
5046
|
align: "start",
|
|
@@ -4853,6 +5050,7 @@ function LinkPopover({ controller, labels, onClose }) {
|
|
|
4853
5050
|
event.preventDefault();
|
|
4854
5051
|
backToText();
|
|
4855
5052
|
},
|
|
5053
|
+
onKeyDown: tabOut,
|
|
4856
5054
|
children: [
|
|
4857
5055
|
/* @__PURE__ */ jsxRuntime.jsxs("form", { noValidate: true, className: "flex items-center gap-0.5", onSubmit: apply, children: [
|
|
4858
5056
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
@@ -4868,10 +5066,10 @@ function LinkPopover({ controller, labels, onClose }) {
|
|
|
4868
5066
|
}
|
|
4869
5067
|
),
|
|
4870
5068
|
/* @__PURE__ */ jsxRuntime.jsx(Button, { type: "submit", variant: "ghost", size: "icon-sm", "aria-label": labels.linkApply, children: /* @__PURE__ */ jsxRuntime.jsx(Check, {}) }),
|
|
4871
|
-
|
|
5069
|
+
link !== null && /* @__PURE__ */ jsxRuntime.jsx(OpenLinkButton, { href: link.href, label: labels.linkOpen }),
|
|
4872
5070
|
link !== null && /* @__PURE__ */ jsxRuntime.jsx(Button, { type: "button", variant: "ghost", size: "icon-sm", "aria-label": labels.linkRemove, onClick: remove, children: /* @__PURE__ */ jsxRuntime.jsx(Unlink, {}) })
|
|
4873
5071
|
] }),
|
|
4874
|
-
invalid && /* @__PURE__ */ jsxRuntime.jsx("p", { id: messageId,
|
|
5072
|
+
invalid && /* @__PURE__ */ jsxRuntime.jsx("p", { id: messageId, className: MESSAGE, children: labels.invalidLink })
|
|
4875
5073
|
]
|
|
4876
5074
|
}
|
|
4877
5075
|
)
|
|
@@ -4896,7 +5094,7 @@ function LinkOverlay({ controller }) {
|
|
|
4896
5094
|
const labels = useLabels();
|
|
4897
5095
|
const store = useCanvasUiStore();
|
|
4898
5096
|
const popoverOpen = useCanvasUi(store, isPopoverOpen);
|
|
4899
|
-
const readOnly =
|
|
5097
|
+
const readOnly = chunkN25EH2GZ_cjs.useReadOnly(controller);
|
|
4900
5098
|
useLinkClicks(controller);
|
|
4901
5099
|
React7.useEffect(() => {
|
|
4902
5100
|
if (readOnly && store.get().linkPopover.open) store.set({ linkPopover: { open: false } });
|
|
@@ -4911,7 +5109,7 @@ function linkExtension(store) {
|
|
|
4911
5109
|
if (dispatch) store.set({ linkPopover: { open: true } });
|
|
4912
5110
|
return true;
|
|
4913
5111
|
};
|
|
4914
|
-
return
|
|
5112
|
+
return chunkZ5EEDCRI_cjs.defineExtension({ name: "link", keymap: { "Mod-k": openPopover }, ui: { overlays: [LinkOverlay] } });
|
|
4915
5113
|
}
|
|
4916
5114
|
|
|
4917
5115
|
// src/menus/suggestion/find-trigger.ts
|
|
@@ -4919,7 +5117,7 @@ var DEFAULT_MAX_LENGTH = 40;
|
|
|
4919
5117
|
var NO_TRIGGER_TYPES = /* @__PURE__ */ new Set(["CODE", "TABLE"]);
|
|
4920
5118
|
var WHITESPACE2 = /\s/;
|
|
4921
5119
|
var ATOM = "\uFFFC";
|
|
4922
|
-
var hasCode = (inline) => inline.some((node) =>
|
|
5120
|
+
var hasCode = (inline) => inline.some((node) => chunk4JDRDPLC_cjs.hasMark(node.marks, "code"));
|
|
4923
5121
|
function triggerOffset(text2, start, config) {
|
|
4924
5122
|
const { char, allowSpaces = false, startOfLine = false } = config;
|
|
4925
5123
|
const earliest = Math.max(0, text2.length - (config.maxLength ?? DEFAULT_MAX_LENGTH) - 1);
|
|
@@ -4928,7 +5126,8 @@ function triggerOffset(text2, start, config) {
|
|
|
4928
5126
|
if (character === "\n" || character === ATOM) return null;
|
|
4929
5127
|
if (character === char) {
|
|
4930
5128
|
const atRegionStart = start + i === 0;
|
|
4931
|
-
|
|
5129
|
+
const opens2 = atRegionStart || !startOfLine && i > 0 && WHITESPACE2.test(text2[i - 1]);
|
|
5130
|
+
if (opens2) return WHITESPACE2.test(text2[i + 1] ?? "") ? null : start + i;
|
|
4932
5131
|
}
|
|
4933
5132
|
if (!allowSpaces && WHITESPACE2.test(character)) return null;
|
|
4934
5133
|
}
|
|
@@ -4936,15 +5135,15 @@ function triggerOffset(text2, start, config) {
|
|
|
4936
5135
|
}
|
|
4937
5136
|
function findTrigger(state, config) {
|
|
4938
5137
|
const { doc, selection } = state;
|
|
4939
|
-
if (selection?.kind !== "text" || !
|
|
5138
|
+
if (selection?.kind !== "text" || !chunkZ5EEDCRI_cjs.isCollapsed(selection)) return null;
|
|
4940
5139
|
const { block: blockId, region, offset: caret } = selection.head;
|
|
4941
|
-
const block =
|
|
5140
|
+
const block = chunk4JDRDPLC_cjs.blockById(doc, blockId);
|
|
4942
5141
|
if (block === void 0 || NO_TRIGGER_TYPES.has(block.type) || !Object.hasOwn(block.regions, region)) return null;
|
|
4943
5142
|
const inline = block.regions[region];
|
|
4944
5143
|
const start = Math.max(0, caret - (config.maxLength ?? DEFAULT_MAX_LENGTH) - 2);
|
|
4945
|
-
const from = triggerOffset(
|
|
4946
|
-
if (from === null || hasCode(
|
|
4947
|
-
const query =
|
|
5144
|
+
const from = triggerOffset(chunk4JDRDPLC_cjs.inlineText(chunk4JDRDPLC_cjs.sliceInline(inline, start, caret)), start, config);
|
|
5145
|
+
if (from === null || hasCode(chunk4JDRDPLC_cjs.sliceInline(inline, from, caret))) return null;
|
|
5146
|
+
const query = chunk4JDRDPLC_cjs.inlineText(chunk4JDRDPLC_cjs.sliceInline(inline, from + 1, caret));
|
|
4948
5147
|
return { block: blockId, region, from, to: caret, query };
|
|
4949
5148
|
}
|
|
4950
5149
|
|
|
@@ -4959,11 +5158,13 @@ function stillDismissed(tr, dismissed, found) {
|
|
|
4959
5158
|
const same = found.block === at.block && found.region === at.region && found.from === at.offset;
|
|
4960
5159
|
return same ? rangeOf2(found) : null;
|
|
4961
5160
|
}
|
|
4962
|
-
|
|
4963
|
-
|
|
5161
|
+
var opens = (found, { minLength = 0 }) => found !== null && found.query.length >= minLength;
|
|
5162
|
+
function nearest(state, found, config) {
|
|
5163
|
+
if (!opens(found, config)) return null;
|
|
4964
5164
|
for (const { trigger } of state.plugins) {
|
|
4965
|
-
|
|
4966
|
-
|
|
5165
|
+
if (trigger === void 0) continue;
|
|
5166
|
+
const other = findTrigger(state, trigger);
|
|
5167
|
+
if (opens(other, trigger) && other.from > found.from) return null;
|
|
4967
5168
|
}
|
|
4968
5169
|
return found;
|
|
4969
5170
|
}
|
|
@@ -4971,15 +5172,15 @@ function suggestionPlugin(key, config) {
|
|
|
4971
5172
|
return {
|
|
4972
5173
|
key,
|
|
4973
5174
|
trigger: config,
|
|
4974
|
-
init: (state) => ({ active: nearest(state, findTrigger(state, config)), dismissedAt: null }),
|
|
5175
|
+
init: (state) => ({ active: nearest(state, findTrigger(state, config), config), dismissedAt: null }),
|
|
4975
5176
|
apply(tr, value, oldState, newState) {
|
|
4976
|
-
const dismissing = tr.getMeta(DISMISS)
|
|
4977
|
-
if (!dismissing && !tr.docChanged &&
|
|
5177
|
+
const dismissing = tr.getMeta(DISMISS) !== void 0;
|
|
5178
|
+
if (!dismissing && !tr.docChanged && chunkZ5EEDCRI_cjs.sameSelection(oldState.selection, newState.selection)) return value;
|
|
4978
5179
|
const found = findTrigger(newState, config);
|
|
4979
5180
|
let dismissedAt = null;
|
|
4980
5181
|
if (dismissing) dismissedAt = found && rangeOf2(found);
|
|
4981
5182
|
else if (value.dismissedAt !== null) dismissedAt = stillDismissed(tr, value.dismissedAt, found);
|
|
4982
|
-
const active = dismissedAt === null ? nearest(newState, found) : null;
|
|
5183
|
+
const active = dismissedAt === null ? nearest(newState, found, config) : null;
|
|
4983
5184
|
const unchanged = sameTrigger(active, value.active) && sameRange(dismissedAt, value.dismissedAt);
|
|
4984
5185
|
if (unchanged) return value;
|
|
4985
5186
|
return {
|
|
@@ -4991,14 +5192,14 @@ function suggestionPlugin(key, config) {
|
|
|
4991
5192
|
}
|
|
4992
5193
|
function dismissSuggestion(key) {
|
|
4993
5194
|
return (state, dispatch) => {
|
|
4994
|
-
if (
|
|
4995
|
-
dispatch?.(new
|
|
5195
|
+
if (chunkZ5EEDCRI_cjs.getPluginState(state, key).active === null) return false;
|
|
5196
|
+
dispatch?.(new chunkZ5EEDCRI_cjs.Transaction(state).setMeta(DISMISS, key.name));
|
|
4996
5197
|
return true;
|
|
4997
5198
|
};
|
|
4998
5199
|
}
|
|
4999
5200
|
|
|
5000
5201
|
// src/menus/slash/slash-key.ts
|
|
5001
|
-
var slashKey =
|
|
5202
|
+
var slashKey = chunkZ5EEDCRI_cjs.createPluginKey("slash");
|
|
5002
5203
|
|
|
5003
5204
|
// src/menus/slash/slash-items.ts
|
|
5004
5205
|
var DETAILS = {
|
|
@@ -5022,7 +5223,7 @@ function insertionItem(id, insertion, labels, definitions) {
|
|
|
5022
5223
|
const { label, icon, type, attrs } = insertion;
|
|
5023
5224
|
return {
|
|
5024
5225
|
id,
|
|
5025
|
-
title: label,
|
|
5226
|
+
title: hostLabel(definitions, type) ?? label,
|
|
5026
5227
|
description: labels.slashDescriptions[id],
|
|
5027
5228
|
icon,
|
|
5028
5229
|
...DETAILS[id],
|
|
@@ -5048,7 +5249,7 @@ function initialBlock({ schema }, definition, onError) {
|
|
|
5048
5249
|
const data = chunkA6PGQVTR_cjs.seedData(definition, onError());
|
|
5049
5250
|
if (data === null) return null;
|
|
5050
5251
|
if (data === void 0) return { type };
|
|
5051
|
-
return { type, ...
|
|
5252
|
+
return { type, ...chunk4JDRDPLC_cjs.specFor(schema, type).fromData(data, chunk4JDRDPLC_cjs.createBlockCodec(schema).context) };
|
|
5052
5253
|
}
|
|
5053
5254
|
var refuse = () => false;
|
|
5054
5255
|
function blockTypeSlashItems(definitions, onError = () => void 0) {
|
|
@@ -5076,43 +5277,69 @@ function useRangeAnchor(controller, range) {
|
|
|
5076
5277
|
const [side, setSide] = React7.useState("bottom");
|
|
5077
5278
|
const latest = React7.useRef(range);
|
|
5078
5279
|
const start = range === null ? null : `${range.block} ${range.region} ${range.from}`;
|
|
5079
|
-
|
|
5280
|
+
chunkN25EH2GZ_cjs.useIsomorphicLayoutEffect(() => {
|
|
5080
5281
|
latest.current = range;
|
|
5081
5282
|
});
|
|
5082
|
-
|
|
5283
|
+
chunkN25EH2GZ_cjs.useIsomorphicLayoutEffect(() => {
|
|
5083
5284
|
const rect = latest.current && rangeRect(controller, latest.current);
|
|
5084
5285
|
const height = controller.root?.ownerDocument.defaultView?.innerHeight;
|
|
5085
5286
|
if (rect && height !== void 0) setSide(sideFor(rect, height));
|
|
5086
5287
|
}, [controller, start]);
|
|
5087
5288
|
return { anchor, side };
|
|
5088
5289
|
}
|
|
5290
|
+
|
|
5291
|
+
// src/to-error.ts
|
|
5292
|
+
var toError = (cause) => cause instanceof Error ? cause : new Error(String(cause));
|
|
5089
5293
|
var ADDED = ["aria-expanded", "aria-controls", "aria-autocomplete", "aria-activedescendant"];
|
|
5090
5294
|
var SWAPPED = ["role", "aria-multiline"];
|
|
5091
5295
|
function restore(host, name, value) {
|
|
5092
5296
|
if (value === null) host.removeAttribute(name);
|
|
5093
5297
|
else host.setAttribute(name, value);
|
|
5094
5298
|
}
|
|
5095
|
-
|
|
5096
|
-
|
|
5299
|
+
var held = /* @__PURE__ */ new WeakMap();
|
|
5300
|
+
function makeCombobox(host, listboxId) {
|
|
5097
5301
|
host.setAttribute("role", "combobox");
|
|
5098
5302
|
host.removeAttribute("aria-multiline");
|
|
5099
5303
|
host.setAttribute("aria-expanded", "true");
|
|
5100
5304
|
host.setAttribute("aria-controls", listboxId);
|
|
5101
5305
|
host.setAttribute("aria-autocomplete", "list");
|
|
5306
|
+
}
|
|
5307
|
+
function openCombobox(host, listboxId) {
|
|
5308
|
+
const saved = () => SWAPPED.map((name) => [name, host.getAttribute(name)]);
|
|
5309
|
+
const entry = held.get(host) ?? { saved: saved(), listboxes: [] };
|
|
5310
|
+
held.set(host, entry);
|
|
5311
|
+
entry.listboxes.push(listboxId);
|
|
5312
|
+
makeCombobox(host, listboxId);
|
|
5102
5313
|
return () => {
|
|
5314
|
+
entry.listboxes.splice(entry.listboxes.lastIndexOf(listboxId), 1);
|
|
5315
|
+
const remaining = entry.listboxes.at(-1);
|
|
5316
|
+
if (remaining !== void 0) return makeCombobox(host, remaining);
|
|
5317
|
+
held.delete(host);
|
|
5103
5318
|
for (const name of ADDED) host.removeAttribute(name);
|
|
5104
|
-
for (const [name, value] of saved) restore(host, name, value);
|
|
5319
|
+
for (const [name, value] of entry.saved) restore(host, name, value);
|
|
5105
5320
|
};
|
|
5106
5321
|
}
|
|
5107
5322
|
function useComboboxHost(controller, block, region, listboxId, activeOptionId) {
|
|
5108
|
-
const
|
|
5109
|
-
|
|
5110
|
-
|
|
5111
|
-
|
|
5112
|
-
|
|
5113
|
-
|
|
5114
|
-
|
|
5115
|
-
|
|
5323
|
+
const open = block !== null && region !== null;
|
|
5324
|
+
const docWhileOpen = React7.useCallback((state) => open ? state.doc : null, [open]);
|
|
5325
|
+
chunkN25EH2GZ_cjs.useEditorState(controller, docWhileOpen);
|
|
5326
|
+
const opened = React7.useRef(null);
|
|
5327
|
+
chunkN25EH2GZ_cjs.useIsomorphicLayoutEffect(() => {
|
|
5328
|
+
const host = open ? controller.registry.get(block, region) ?? null : null;
|
|
5329
|
+
const last2 = opened.current;
|
|
5330
|
+
if (last2?.host !== host || last2.listboxId !== listboxId) {
|
|
5331
|
+
last2?.close();
|
|
5332
|
+
opened.current = host && { host, listboxId, close: openCombobox(host, listboxId) };
|
|
5333
|
+
}
|
|
5334
|
+
if (opened.current !== null) restore(opened.current.host, "aria-activedescendant", activeOptionId);
|
|
5335
|
+
});
|
|
5336
|
+
chunkN25EH2GZ_cjs.useIsomorphicLayoutEffect(
|
|
5337
|
+
() => () => {
|
|
5338
|
+
opened.current?.close();
|
|
5339
|
+
opened.current = null;
|
|
5340
|
+
},
|
|
5341
|
+
[]
|
|
5342
|
+
);
|
|
5116
5343
|
}
|
|
5117
5344
|
|
|
5118
5345
|
// src/menus/suggestion/group-items.ts
|
|
@@ -5156,10 +5383,10 @@ function handle(event, menu) {
|
|
|
5156
5383
|
}
|
|
5157
5384
|
function useSuggestionKeys(controller, open, menu) {
|
|
5158
5385
|
const latest = React7.useRef(menu);
|
|
5159
|
-
|
|
5386
|
+
chunkN25EH2GZ_cjs.useIsomorphicLayoutEffect(() => {
|
|
5160
5387
|
latest.current = menu;
|
|
5161
5388
|
});
|
|
5162
|
-
|
|
5389
|
+
chunkN25EH2GZ_cjs.useIsomorphicLayoutEffect(() => {
|
|
5163
5390
|
if (!open) return;
|
|
5164
5391
|
const intercept = (event) => {
|
|
5165
5392
|
const handled = handle(event, latest.current);
|
|
@@ -5169,21 +5396,16 @@ function useSuggestionKeys(controller, open, menu) {
|
|
|
5169
5396
|
return interceptKeys(controller, intercept);
|
|
5170
5397
|
}, [controller, open]);
|
|
5171
5398
|
}
|
|
5172
|
-
|
|
5173
|
-
// src/to-error.ts
|
|
5174
|
-
var toError = (cause) => cause instanceof Error ? cause : new Error(String(cause));
|
|
5175
|
-
|
|
5176
|
-
// src/menus/suggestion/use-suggestion-results.ts
|
|
5177
5399
|
var FORGOTTEN = { source: null, query: null, items: [] };
|
|
5178
5400
|
var CLOSED = { items: [], pending: false };
|
|
5179
5401
|
var isPromise = (value) => typeof value?.then === "function";
|
|
5180
5402
|
function useSuggestionResults(source, query, onError) {
|
|
5181
5403
|
const [answer, setAnswer] = React7.useState(FORGOTTEN);
|
|
5182
5404
|
const report = React7.useRef(onError);
|
|
5183
|
-
|
|
5405
|
+
chunkN25EH2GZ_cjs.useIsomorphicLayoutEffect(() => {
|
|
5184
5406
|
report.current = onError;
|
|
5185
5407
|
});
|
|
5186
|
-
|
|
5408
|
+
chunkN25EH2GZ_cjs.useIsomorphicLayoutEffect(() => {
|
|
5187
5409
|
if (query === null) {
|
|
5188
5410
|
setAnswer(FORGOTTEN);
|
|
5189
5411
|
return;
|
|
@@ -5224,12 +5446,13 @@ function useSuggestion({
|
|
|
5224
5446
|
itemKey: itemKey2,
|
|
5225
5447
|
groupOf: groupOf2,
|
|
5226
5448
|
onSelect,
|
|
5227
|
-
emptyLabel
|
|
5449
|
+
emptyLabel,
|
|
5450
|
+
countLabel
|
|
5228
5451
|
}) {
|
|
5229
5452
|
const { labels, onError } = useQuoin();
|
|
5230
|
-
const readOnly =
|
|
5231
|
-
const selectTrigger = React7.useCallback((state) =>
|
|
5232
|
-
const active =
|
|
5453
|
+
const readOnly = chunkN25EH2GZ_cjs.useReadOnly(controller);
|
|
5454
|
+
const selectTrigger = React7.useCallback((state) => chunkZ5EEDCRI_cjs.getPluginState(state, pluginKey).active, [pluginKey]);
|
|
5455
|
+
const active = chunkN25EH2GZ_cjs.useEditorState(controller, selectTrigger);
|
|
5233
5456
|
const trigger = readOnly ? null : active;
|
|
5234
5457
|
const results = useSuggestionResults(source, trigger?.query ?? null, onError);
|
|
5235
5458
|
const sections = React7.useMemo(() => groupItems(results.items, groupOf2), [results.items, groupOf2]);
|
|
@@ -5251,20 +5474,32 @@ function useSuggestion({
|
|
|
5251
5474
|
);
|
|
5252
5475
|
const select = React7.useCallback(
|
|
5253
5476
|
(index) => {
|
|
5254
|
-
const current =
|
|
5255
|
-
if (current
|
|
5477
|
+
const current = chunkZ5EEDCRI_cjs.getPluginState(controller.editor.state, pluginKey).active;
|
|
5478
|
+
if (current === null || index >= ordered.length) return;
|
|
5479
|
+
try {
|
|
5480
|
+
onSelect(ordered[index], rangeOf2(current));
|
|
5481
|
+
} catch (error) {
|
|
5482
|
+
onError(toError(error));
|
|
5483
|
+
}
|
|
5256
5484
|
},
|
|
5257
|
-
[controller, pluginKey, ordered, onSelect]
|
|
5485
|
+
[controller, pluginKey, ordered, onSelect, onError]
|
|
5258
5486
|
);
|
|
5259
5487
|
const dismiss = React7.useCallback(() => void controller.run(dismissSuggestion(pluginKey)), [controller, pluginKey]);
|
|
5260
5488
|
useSuggestionKeys(controller, trigger !== null, { count: ordered.length, activeIndex, highlight, select, dismiss });
|
|
5261
5489
|
useComboboxHost(controller, trigger?.block ?? null, trigger?.region ?? null, listboxId, activeId);
|
|
5262
5490
|
const query = trigger?.query ?? null;
|
|
5263
5491
|
const count = ordered.length;
|
|
5264
|
-
const resultMessage = count === 0 ? emptyLabel : labels.resultCount(count);
|
|
5492
|
+
const resultMessage = count === 0 ? emptyLabel : (countLabel ?? labels.resultCount)(count);
|
|
5493
|
+
const said = React7.useRef(null);
|
|
5265
5494
|
React7.useEffect(() => {
|
|
5266
5495
|
if (query === null || results.pending) return;
|
|
5267
|
-
const timer = setTimeout(() =>
|
|
5496
|
+
const timer = setTimeout(() => {
|
|
5497
|
+
const current = controller.announcer.current()?.message;
|
|
5498
|
+
const own = current === void 0 || current === said.current;
|
|
5499
|
+
const message = own ? resultMessage : `${current}. ${resultMessage}`;
|
|
5500
|
+
said.current = message;
|
|
5501
|
+
controller.announce(message);
|
|
5502
|
+
}, SETTLE_MS);
|
|
5268
5503
|
return () => clearTimeout(timer);
|
|
5269
5504
|
}, [controller, query, resultMessage, results.pending]);
|
|
5270
5505
|
return { trigger, sections, pending: results.pending, activeIndex, listboxId, optionId, highlight, select, dismiss };
|
|
@@ -5299,7 +5534,7 @@ function SuggestionMenu(props) {
|
|
|
5299
5534
|
const { trigger, sections, activeIndex, listboxId } = suggestion;
|
|
5300
5535
|
const { anchor, side } = useRangeAnchor(controller, trigger);
|
|
5301
5536
|
const listbox = React7.useRef(null);
|
|
5302
|
-
|
|
5537
|
+
chunkN25EH2GZ_cjs.useIsomorphicLayoutEffect(() => {
|
|
5303
5538
|
listbox.current?.querySelector('[aria-selected="true"]')?.scrollIntoView?.({ block: "nearest" });
|
|
5304
5539
|
}, [activeIndex, sections]);
|
|
5305
5540
|
if (trigger === null) return null;
|
|
@@ -5358,14 +5593,14 @@ function SuggestionMenu(props) {
|
|
|
5358
5593
|
// src/menus/suggestion/replace-trigger.ts
|
|
5359
5594
|
function deleteTrigger({ block, region, from, to }) {
|
|
5360
5595
|
return (state, dispatch) => {
|
|
5361
|
-
const tr = new
|
|
5362
|
-
if (from >= to || !tr.maybeStep(
|
|
5363
|
-
dispatch?.(tr.setSelection(
|
|
5596
|
+
const tr = new chunkZ5EEDCRI_cjs.Transaction(state);
|
|
5597
|
+
if (from >= to || !tr.maybeStep(chunkZ5EEDCRI_cjs.replaceInlineStep(block, region, from, to, []))) return false;
|
|
5598
|
+
dispatch?.(tr.setSelection(chunkZ5EEDCRI_cjs.textSelection({ block, region, offset: from })));
|
|
5364
5599
|
return true;
|
|
5365
5600
|
};
|
|
5366
5601
|
}
|
|
5367
5602
|
function triggerReplacement(state, range, command) {
|
|
5368
|
-
return
|
|
5603
|
+
return chunkZ5EEDCRI_cjs.runCommands(state, command === void 0 ? [deleteTrigger(range)] : [deleteTrigger(range), command]);
|
|
5369
5604
|
}
|
|
5370
5605
|
function replaceTrigger(controller, range, command) {
|
|
5371
5606
|
const { ok, tr } = triggerReplacement(controller.editor.state, range, command);
|
|
@@ -5378,9 +5613,9 @@ var TEXT_STEPS = /* @__PURE__ */ new Set(["replaceInline", "addMark", "removeMar
|
|
|
5378
5613
|
var WHITESPACE3 = /\s/;
|
|
5379
5614
|
var changesBlocks = (tr) => tr !== null && tr.steps.some((step) => !TEXT_STEPS.has(step.stepType));
|
|
5380
5615
|
function withSpaceBefore(state, range) {
|
|
5381
|
-
const inline =
|
|
5616
|
+
const inline = chunkN25EH2GZ_cjs.regionInline(state, range.block, range.region);
|
|
5382
5617
|
if (inline === void 0 || range.from === 0) return null;
|
|
5383
|
-
const text2 =
|
|
5618
|
+
const text2 = chunk4JDRDPLC_cjs.inlineText(inline);
|
|
5384
5619
|
const after = text2.charAt(range.to);
|
|
5385
5620
|
const spaced = text2.charAt(range.from - 1) === " " && (after === "" || WHITESPACE3.test(after));
|
|
5386
5621
|
return spaced ? { ...range, from: range.from - 1 } : null;
|
|
@@ -5485,7 +5720,7 @@ function SlashOverlay({ controller }) {
|
|
|
5485
5720
|
return /* @__PURE__ */ jsxRuntime.jsx(SlashMenu, { controller, labels, items });
|
|
5486
5721
|
}
|
|
5487
5722
|
function slashExtension() {
|
|
5488
|
-
return
|
|
5723
|
+
return chunkZ5EEDCRI_cjs.defineExtension({
|
|
5489
5724
|
name: "slash",
|
|
5490
5725
|
plugins: [suggestionPlugin(slashKey, { char: "/" })],
|
|
5491
5726
|
ui: { overlays: [SlashOverlay] }
|
|
@@ -5494,10 +5729,10 @@ function slashExtension() {
|
|
|
5494
5729
|
|
|
5495
5730
|
// src/mobile/mobile-items.tsx
|
|
5496
5731
|
function commandItem(id, title, icon, command) {
|
|
5497
|
-
return { id, title, icon, run: (controller) => void controller.run(command) };
|
|
5732
|
+
return { id, title, icon, enabled: (state) => command(state), run: (controller) => void controller.run(command) };
|
|
5498
5733
|
}
|
|
5499
5734
|
function addBlockAtCaret(controller) {
|
|
5500
|
-
const block =
|
|
5735
|
+
const block = chunkZ5EEDCRI_cjs.headBlockId(controller.editor.state.selection);
|
|
5501
5736
|
if (block !== null) addBlockBelow(controller, block);
|
|
5502
5737
|
}
|
|
5503
5738
|
function mobileItems(labels, openLink) {
|
|
@@ -5509,16 +5744,13 @@ function mobileItems(labels, openLink) {
|
|
|
5509
5744
|
markItem("strike", labels.strike, Strikethrough),
|
|
5510
5745
|
markItem("code", labels.code, Code),
|
|
5511
5746
|
linkItem(labels, openLink),
|
|
5512
|
-
commandItem("indent", labels.indent, ListIndentIncrease,
|
|
5513
|
-
commandItem("outdent", labels.outdent, ListIndentDecrease,
|
|
5514
|
-
commandItem("undo", labels.undo, Undo2,
|
|
5515
|
-
commandItem("redo", labels.redo, Redo2,
|
|
5747
|
+
commandItem("indent", labels.indent, ListIndentIncrease, chunkZ5EEDCRI_cjs.indent),
|
|
5748
|
+
commandItem("outdent", labels.outdent, ListIndentDecrease, chunkZ5EEDCRI_cjs.outdent),
|
|
5749
|
+
commandItem("undo", labels.undo, Undo2, chunkZ5EEDCRI_cjs.undo),
|
|
5750
|
+
commandItem("redo", labels.redo, Redo2, chunkZ5EEDCRI_cjs.redo)
|
|
5516
5751
|
]
|
|
5517
5752
|
};
|
|
5518
5753
|
}
|
|
5519
|
-
|
|
5520
|
-
// src/mobile/use-coarse-pointer.ts
|
|
5521
|
-
var useCoarsePointer = () => useMediaQuery("(pointer: coarse)", false);
|
|
5522
5754
|
var FOCUS_EVENTS = ["focusin", "focusout"];
|
|
5523
5755
|
function subscribe(notify) {
|
|
5524
5756
|
for (const type of FOCUS_EVENTS) document.addEventListener(type, notify);
|
|
@@ -5531,6 +5763,7 @@ function useEditorFocus(controller) {
|
|
|
5531
5763
|
const read2 = React7.useCallback(() => focusInEditor(controller), [controller]);
|
|
5532
5764
|
return React7.useSyncExternalStore(subscribe, read2, NOT_FOCUSED);
|
|
5533
5765
|
}
|
|
5766
|
+
var KEYS3 = ["offsetTop", "offsetLeft", "height", "width", "scale"];
|
|
5534
5767
|
var EVENTS = ["resize", "scroll"];
|
|
5535
5768
|
function subscribe2(notify) {
|
|
5536
5769
|
const viewport = window.visualViewport;
|
|
@@ -5545,10 +5778,8 @@ var last = null;
|
|
|
5545
5778
|
function read() {
|
|
5546
5779
|
const viewport = window.visualViewport;
|
|
5547
5780
|
if (!viewport) return null;
|
|
5548
|
-
const
|
|
5549
|
-
if (last
|
|
5550
|
-
last = { offsetTop, height, width };
|
|
5551
|
-
}
|
|
5781
|
+
const box = Object.fromEntries(KEYS3.map((key) => [key, viewport[key]]));
|
|
5782
|
+
if (last === null || KEYS3.some((key) => last?.[key] !== box[key])) last = box;
|
|
5552
5783
|
return last;
|
|
5553
5784
|
}
|
|
5554
5785
|
var readOnServer2 = () => null;
|
|
@@ -5561,14 +5792,26 @@ var TOOLBAR = [
|
|
|
5561
5792
|
].join(" ");
|
|
5562
5793
|
function placement(viewport) {
|
|
5563
5794
|
if (viewport === null) return { bottom: 0 };
|
|
5564
|
-
|
|
5795
|
+
const { offsetLeft, offsetTop, height, width, scale } = viewport;
|
|
5796
|
+
const shift = "translateY(-100%)";
|
|
5797
|
+
return {
|
|
5798
|
+
top: offsetTop + height,
|
|
5799
|
+
left: offsetLeft,
|
|
5800
|
+
right: "auto",
|
|
5801
|
+
width: width * scale,
|
|
5802
|
+
transform: scale === 1 ? shift : `scale(${1 / scale}) ${shift}`,
|
|
5803
|
+
transformOrigin: "0 0"
|
|
5804
|
+
};
|
|
5565
5805
|
}
|
|
5566
5806
|
function EditingTools({ controller }) {
|
|
5567
5807
|
const labels = useLabels();
|
|
5568
5808
|
const store = useCanvasUiStore();
|
|
5569
|
-
const state =
|
|
5809
|
+
const state = chunkN25EH2GZ_cjs.useEditorState(controller, chunkN25EH2GZ_cjs.wholeState);
|
|
5570
5810
|
const viewport = useVisualViewport();
|
|
5571
5811
|
const roving = useRovingFocus();
|
|
5812
|
+
const dir = reactDirection.useDirection();
|
|
5813
|
+
useFocusBackToText(controller);
|
|
5814
|
+
useFocusKey(controller, roving.focusCurrent);
|
|
5572
5815
|
const items = React7.useMemo(() => mobileItems(labels, () => store.set({ linkPopover: { open: true } })), [labels, store]);
|
|
5573
5816
|
const onKeyDown = (event) => {
|
|
5574
5817
|
if (event.key === "Escape" && roving.owns(event.target)) {
|
|
@@ -5582,6 +5825,7 @@ function EditingTools({ controller }) {
|
|
|
5582
5825
|
"div",
|
|
5583
5826
|
{
|
|
5584
5827
|
ref: roving.ref,
|
|
5828
|
+
dir,
|
|
5585
5829
|
role: "toolbar",
|
|
5586
5830
|
"aria-label": labels.mobileToolbar,
|
|
5587
5831
|
className: TOOLBAR,
|
|
@@ -5628,12 +5872,14 @@ var DialogOverlay = /* @__PURE__ */ React7__namespace.forwardRef(function Dialog
|
|
|
5628
5872
|
);
|
|
5629
5873
|
});
|
|
5630
5874
|
var DialogContent = /* @__PURE__ */ React7__namespace.forwardRef(function DialogContent2({ className, children, closeLabel = "Close", ...props }, ref) {
|
|
5875
|
+
const dir = reactDirection.useDirection();
|
|
5631
5876
|
return /* @__PURE__ */ jsxRuntime.jsxs(DialogPortal, { children: [
|
|
5632
5877
|
/* @__PURE__ */ jsxRuntime.jsx(DialogOverlay, {}),
|
|
5633
5878
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
5634
5879
|
DialogPrimitive__namespace.Content,
|
|
5635
5880
|
{
|
|
5636
5881
|
ref,
|
|
5882
|
+
dir,
|
|
5637
5883
|
"data-slot": "dialog-content",
|
|
5638
5884
|
className: cn(
|
|
5639
5885
|
"quoin bg-popover fixed top-[50%] left-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 rounded-xl border p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
|
@@ -5646,7 +5892,7 @@ var DialogContent = /* @__PURE__ */ React7__namespace.forwardRef(function Dialog
|
|
|
5646
5892
|
DialogPrimitive__namespace.Close,
|
|
5647
5893
|
{
|
|
5648
5894
|
className: cn(
|
|
5649
|
-
"absolute top-4
|
|
5895
|
+
"absolute top-4 end-4 rounded-xs opacity-70 transition-opacity hover:opacity-100",
|
|
5650
5896
|
FOCUS_RING,
|
|
5651
5897
|
ICON_TAP_TARGET_FLOOR
|
|
5652
5898
|
),
|
|
@@ -5763,14 +6009,14 @@ function shortcutGroups(labels, isMac) {
|
|
|
5763
6009
|
}
|
|
5764
6010
|
];
|
|
5765
6011
|
}
|
|
5766
|
-
var
|
|
6012
|
+
var KEYS4 = "rounded border bg-muted px-1.5 py-0.5 font-sans text-xs whitespace-nowrap";
|
|
5767
6013
|
function ShortcutSection({ group }) {
|
|
5768
6014
|
const titleId = React7.useId();
|
|
5769
6015
|
return /* @__PURE__ */ jsxRuntime.jsxs("section", { "aria-labelledby": titleId, children: [
|
|
5770
6016
|
/* @__PURE__ */ jsxRuntime.jsx("h3", { id: titleId, className: "mb-2 text-sm font-semibold", children: group.title }),
|
|
5771
6017
|
/* @__PURE__ */ jsxRuntime.jsx("dl", { className: "grid gap-1.5 text-sm", children: group.items.map(({ label, keys }) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-4", children: [
|
|
5772
6018
|
/* @__PURE__ */ jsxRuntime.jsx("dt", { children: label }),
|
|
5773
|
-
/* @__PURE__ */ jsxRuntime.jsx("dd", { children: /* @__PURE__ */ jsxRuntime.jsx("kbd", { className:
|
|
6019
|
+
/* @__PURE__ */ jsxRuntime.jsx("dd", { children: /* @__PURE__ */ jsxRuntime.jsx("kbd", { className: KEYS4, children: keys }) })
|
|
5774
6020
|
] }, `${label} ${keys}`)) })
|
|
5775
6021
|
] });
|
|
5776
6022
|
}
|
|
@@ -5823,7 +6069,7 @@ function shortcutsExtension(store) {
|
|
|
5823
6069
|
if (dispatch) store.set({ shortcutsOpen: true });
|
|
5824
6070
|
return true;
|
|
5825
6071
|
};
|
|
5826
|
-
return
|
|
6072
|
+
return chunkZ5EEDCRI_cjs.defineExtension({
|
|
5827
6073
|
name: "shortcuts",
|
|
5828
6074
|
keymap: { [SHORTCUT]: open, "Mod-Shift-?": open },
|
|
5829
6075
|
ui: { overlays: [ShortcutsOverlay] }
|
|
@@ -5831,9 +6077,11 @@ function shortcutsExtension(store) {
|
|
|
5831
6077
|
}
|
|
5832
6078
|
function useRootDirection(controller) {
|
|
5833
6079
|
const [direction, setDirection] = React7.useState("ltr");
|
|
5834
|
-
|
|
6080
|
+
chunkN25EH2GZ_cjs.useIsomorphicLayoutEffect(() => {
|
|
5835
6081
|
const root = controller.root;
|
|
5836
|
-
if (root
|
|
6082
|
+
if (root === null) return;
|
|
6083
|
+
setDirection(chunkN25EH2GZ_cjs.inlineDirection(root));
|
|
6084
|
+
return watchDirection(root, setDirection);
|
|
5837
6085
|
}, [controller]);
|
|
5838
6086
|
return direction;
|
|
5839
6087
|
}
|
|
@@ -5865,16 +6113,16 @@ function writeBlockData(controller, blockId, data) {
|
|
|
5865
6113
|
const index = doc.index.get(blockId);
|
|
5866
6114
|
if (index === void 0) return;
|
|
5867
6115
|
const block = doc.blocks[index];
|
|
5868
|
-
const { attrs, regions } =
|
|
5869
|
-
if (
|
|
5870
|
-
const tr = editor.createTransaction().step(
|
|
5871
|
-
editor.dispatch(tr.setMeta(
|
|
6116
|
+
const { attrs, regions } = chunk4JDRDPLC_cjs.specFor(schema, block.type).fromData(data, editor.codec.context);
|
|
6117
|
+
if (chunk4JDRDPLC_cjs.sameValue(attrs, block.attrs) && chunk4JDRDPLC_cjs.sameValue(regions, block.regions)) return;
|
|
6118
|
+
const tr = editor.createTransaction().step(chunkZ5EEDCRI_cjs.replaceBlockStep({ ...block, attrs, regions }));
|
|
6119
|
+
editor.dispatch(tr.setMeta(chunkZ5EEDCRI_cjs.HISTORY_GROUP, `block-data:${blockId}`));
|
|
5872
6120
|
}
|
|
5873
6121
|
function insertAfterBlock(controller, blockId, type, definitions, onError) {
|
|
5874
6122
|
const editor = internal(controller);
|
|
5875
6123
|
const data = chunkA6PGQVTR_cjs.seedData(chunkA6PGQVTR_cjs.blockByType(definitions, type), onError);
|
|
5876
6124
|
if (data === null) return false;
|
|
5877
|
-
const content = data &&
|
|
6125
|
+
const content = data && chunk4JDRDPLC_cjs.specFor(editor.state.schema, type).fromData(data, editor.codec.context);
|
|
5878
6126
|
controller.run(insertBlockToWrite({ type, ...content }, opensEditor(definitions, type), blockId));
|
|
5879
6127
|
return true;
|
|
5880
6128
|
}
|
|
@@ -5898,7 +6146,7 @@ function runHistoryKey(controller, event) {
|
|
|
5898
6146
|
}
|
|
5899
6147
|
function useBlockIndex(controller, blockId) {
|
|
5900
6148
|
const select = React7.useCallback((state) => state.doc.index.get(blockId) ?? -1, [blockId]);
|
|
5901
|
-
return
|
|
6149
|
+
return chunkN25EH2GZ_cjs.useEditorState(controller, select);
|
|
5902
6150
|
}
|
|
5903
6151
|
var FOCUSABLE = [
|
|
5904
6152
|
"input:not([disabled])",
|
|
@@ -5918,16 +6166,20 @@ function useEditingFocus(root, editing, stop) {
|
|
|
5918
6166
|
(element.querySelector(FOCUSABLE) ?? element).focus();
|
|
5919
6167
|
const doc = element.ownerDocument;
|
|
5920
6168
|
const canvas = element.closest(CANVAS);
|
|
5921
|
-
const leaveForCanvas = (event) => {
|
|
5922
|
-
const target = event.target;
|
|
5923
|
-
if (!element.contains(target) && canvas?.contains(target)) stop();
|
|
5924
|
-
};
|
|
5925
6169
|
const leaveUnlessInside = (event) => {
|
|
5926
6170
|
if (!inside.current.has(event)) stop();
|
|
5927
6171
|
};
|
|
5928
|
-
|
|
5929
|
-
const
|
|
6172
|
+
let afterDispatch;
|
|
6173
|
+
const onPress = (event) => {
|
|
6174
|
+
const target = event.target;
|
|
6175
|
+
if (!element.contains(target) && canvas?.contains(target)) return stop();
|
|
6176
|
+
clearTimeout(afterDispatch);
|
|
6177
|
+
afterDispatch = setTimeout(() => leaveUnlessInside(event));
|
|
6178
|
+
};
|
|
6179
|
+
const unlistenCapture = chunkN25EH2GZ_cjs.listen(doc, { pointerdown: onPress }, true);
|
|
6180
|
+
const unlisten = chunkN25EH2GZ_cjs.listen(doc, { pointerdown: leaveUnlessInside, focusin: leaveUnlessInside });
|
|
5930
6181
|
return () => {
|
|
6182
|
+
clearTimeout(afterDispatch);
|
|
5931
6183
|
unlistenCapture();
|
|
5932
6184
|
unlisten();
|
|
5933
6185
|
};
|
|
@@ -5937,6 +6189,18 @@ function useEditingFocus(root, editing, stop) {
|
|
|
5937
6189
|
return { onPointerDownCapture: mark, onFocusCapture: mark };
|
|
5938
6190
|
}, []);
|
|
5939
6191
|
}
|
|
6192
|
+
function useWhileMounted(callback) {
|
|
6193
|
+
const mounted = React7.useRef(false);
|
|
6194
|
+
React7.useEffect(() => {
|
|
6195
|
+
mounted.current = true;
|
|
6196
|
+
return () => {
|
|
6197
|
+
mounted.current = false;
|
|
6198
|
+
};
|
|
6199
|
+
}, []);
|
|
6200
|
+
return React7.useCallback(() => {
|
|
6201
|
+
if (mounted.current) callback();
|
|
6202
|
+
}, [callback]);
|
|
6203
|
+
}
|
|
5940
6204
|
function useMissingPreviewWarning(readOnly, { type, preview }) {
|
|
5941
6205
|
React7.useEffect(() => {
|
|
5942
6206
|
if (!readOnly || preview !== void 0) return;
|
|
@@ -5949,14 +6213,15 @@ function VoidPreview({ definition: { preview: Preview }, name, ...props }) {
|
|
|
5949
6213
|
if (Preview === void 0) return /* @__PURE__ */ jsxRuntime.jsx("p", { className: "py-1 text-sm text-muted-foreground", children: name });
|
|
5950
6214
|
return /* @__PURE__ */ jsxRuntime.jsx(Preview, { ...props });
|
|
5951
6215
|
}
|
|
5952
|
-
function VoidEditor({ Editor, controller, ...props }) {
|
|
6216
|
+
function VoidEditor({ Editor, controller, onDone, ...props }) {
|
|
5953
6217
|
const index = useBlockIndex(controller, props.blockId);
|
|
5954
|
-
|
|
6218
|
+
const done = useWhileMounted(onDone);
|
|
6219
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Editor, { ...props, index, onDone: done });
|
|
5955
6220
|
}
|
|
5956
6221
|
function VoidBlock({ block, controller, definition }) {
|
|
5957
6222
|
const { blockTypes, labels } = useQuoin();
|
|
5958
|
-
const { report } = React7.useContext(
|
|
5959
|
-
const readOnly =
|
|
6223
|
+
const { report } = React7.useContext(chunkN25EH2GZ_cjs.BlockErrorContext);
|
|
6224
|
+
const readOnly = chunkN25EH2GZ_cjs.useReadOnly(controller);
|
|
5960
6225
|
const { editor: Editor, alwaysEditing = false } = definition;
|
|
5961
6226
|
const name = blockTypeLabel(labels, block, blockTypes);
|
|
5962
6227
|
const blockId = block.id;
|
|
@@ -6020,7 +6285,7 @@ function VoidBlock({ block, controller, definition }) {
|
|
|
6020
6285
|
role: "group",
|
|
6021
6286
|
"aria-label": name,
|
|
6022
6287
|
tabIndex: editorShown ? -1 : void 0,
|
|
6023
|
-
...{ [
|
|
6288
|
+
...{ [chunkN25EH2GZ_cjs.NATIVE_INTERACTION]: editorShown ? "" : void 0 },
|
|
6024
6289
|
onKeyDown,
|
|
6025
6290
|
...focusHandlers,
|
|
6026
6291
|
onClick,
|
|
@@ -6091,6 +6356,11 @@ function extensionUi(extension) {
|
|
|
6091
6356
|
}
|
|
6092
6357
|
var list = (value) => Array.isArray(value) ? value : [];
|
|
6093
6358
|
var record = (value) => typeof value === "object" && value !== null && !Array.isArray(value) ? value : {};
|
|
6359
|
+
function doesSomething(item) {
|
|
6360
|
+
if (item.command !== void 0 || item.run !== void 0) return true;
|
|
6361
|
+
chunkA6PGQVTR_cjs.devWarn(`the slash command "${item.id}" has neither a command nor a run, so the slash menu leaves it out.`);
|
|
6362
|
+
return false;
|
|
6363
|
+
}
|
|
6094
6364
|
function mergeRender(uis) {
|
|
6095
6365
|
const given = uis.flatMap(({ render }) => render === void 0 ? [] : [render]);
|
|
6096
6366
|
if (given.length === 0) return void 0;
|
|
@@ -6103,7 +6373,10 @@ function mergeRender(uis) {
|
|
|
6103
6373
|
function collectUi(extensions, definitions, readOnly = false, onError) {
|
|
6104
6374
|
const uis = extensions.map(extensionUi);
|
|
6105
6375
|
return {
|
|
6106
|
-
slashItems: [
|
|
6376
|
+
slashItems: [
|
|
6377
|
+
...uis.flatMap((ui) => list(ui.slashItems)).filter(doesSomething),
|
|
6378
|
+
...blockTypeSlashItems(definitions, onError)
|
|
6379
|
+
],
|
|
6107
6380
|
bubbleItems: uis.flatMap((ui) => list(ui.bubbleItems)),
|
|
6108
6381
|
blockMenuItems: uis.flatMap((ui) => list(ui.blockMenuItems)),
|
|
6109
6382
|
renderers: Object.assign({}, canvasRenderers(definitions, readOnly), ...uis.map((ui) => record(ui.renderers))),
|
|
@@ -6118,12 +6391,12 @@ function collectUi(extensions, definitions, readOnly = false, onError) {
|
|
|
6118
6391
|
|
|
6119
6392
|
// src/canvas/insert-uploads.ts
|
|
6120
6393
|
function fileBlock(file, stored) {
|
|
6121
|
-
if (isImageFile(file)) return { id:
|
|
6394
|
+
if (isImageFile(file)) return { id: chunk4JDRDPLC_cjs.newId(), type: "IMAGE", attrs: { storageKey: stored.storageKey, alt: "" } };
|
|
6122
6395
|
return { type: "FILE", attrs: fileAttrs(file, stored) };
|
|
6123
6396
|
}
|
|
6124
6397
|
function anchorBlock(controller, at) {
|
|
6125
6398
|
const { doc, selection } = controller.editor.state;
|
|
6126
|
-
const candidates = [at?.block,
|
|
6399
|
+
const candidates = [at?.block, chunkZ5EEDCRI_cjs.headBlockId(selection), doc.blocks[doc.blocks.length - 1]?.id];
|
|
6127
6400
|
return candidates.find((id) => typeof id === "string" && doc.index.has(id)) ?? null;
|
|
6128
6401
|
}
|
|
6129
6402
|
var writerOf = (controller) => ({
|
|
@@ -6132,16 +6405,19 @@ var writerOf = (controller) => ({
|
|
|
6132
6405
|
});
|
|
6133
6406
|
function movedOn(controller, before) {
|
|
6134
6407
|
const now = writerOf(controller);
|
|
6135
|
-
return now.focus !== before.focus || !
|
|
6408
|
+
return now.focus !== before.focus || !chunkZ5EEDCRI_cjs.sameSelection(now.selection, before.selection);
|
|
6136
6409
|
}
|
|
6137
6410
|
async function insertUploads(controller, files, at, { upload, resolveAssetUrl, onError, unavailable, failed }) {
|
|
6138
6411
|
if (!upload) return onError(new Error(unavailable));
|
|
6412
|
+
controller.readSelectionFromDom();
|
|
6413
|
+
const rest = at === null ? fillSelectedBlock(controller, files) : files;
|
|
6414
|
+
if (rest.length === 0) return;
|
|
6139
6415
|
const writer = writerOf(controller);
|
|
6140
|
-
const outcomes = await Promise.allSettled(
|
|
6416
|
+
const outcomes = await Promise.allSettled(rest.map(async (file) => upload(file, isImageFile(file) ? "image" : "file")));
|
|
6141
6417
|
const blocks = [];
|
|
6142
6418
|
outcomes.forEach((outcome, index) => {
|
|
6143
|
-
if (outcome.status === "rejected") onError(
|
|
6144
|
-
else if (
|
|
6419
|
+
if (outcome.status === "rejected") onError(uploadError(outcome.reason, failed));
|
|
6420
|
+
else if (isStored(outcome.value)) blocks.push(fileBlock(rest[index], outcome.value));
|
|
6145
6421
|
else onError(new Error(failed));
|
|
6146
6422
|
});
|
|
6147
6423
|
if (blocks.length === 0 || controller.root === null || controller.readOnly) return;
|
|
@@ -6160,15 +6436,15 @@ function holdsHead({ selection }, block) {
|
|
|
6160
6436
|
}
|
|
6161
6437
|
function markdownPlaceholder(state, block, labels) {
|
|
6162
6438
|
const { kind, level } = block.attrs;
|
|
6163
|
-
if (kind === "heading") return labels.placeholderHeading(
|
|
6439
|
+
if (kind === "heading") return labels.placeholderHeading(chunk4JDRDPLC_cjs.headingLevel(level));
|
|
6164
6440
|
if (LIST_KINDS.has(kind)) return labels.placeholderList;
|
|
6165
6441
|
if (kind === "quote") return labels.placeholderQuote;
|
|
6166
6442
|
if (kind !== "paragraph") return void 0;
|
|
6167
6443
|
return holdsHead(state, block) || state.doc.blocks.length === 1 ? labels.placeholderEmpty : void 0;
|
|
6168
6444
|
}
|
|
6169
6445
|
function placeholderFor(state, block, labels) {
|
|
6170
|
-
const region =
|
|
6171
|
-
if (region === null ||
|
|
6446
|
+
const region = chunkZ5EEDCRI_cjs.primaryRegion(state.schema, block);
|
|
6447
|
+
if (region === null || chunkZ5EEDCRI_cjs.regionLength(block, region) > 0) return void 0;
|
|
6172
6448
|
switch (block.type) {
|
|
6173
6449
|
case "MARKDOWN":
|
|
6174
6450
|
return markdownPlaceholder(state, block, labels);
|
|
@@ -6184,18 +6460,18 @@ function placeholderFor(state, block, labels) {
|
|
|
6184
6460
|
// src/canvas/selected-block-label.ts
|
|
6185
6461
|
var LONGEST = 80;
|
|
6186
6462
|
function firstLine2(text2) {
|
|
6187
|
-
const
|
|
6188
|
-
return
|
|
6463
|
+
const line = text2.split("\n", 1)[0].trim();
|
|
6464
|
+
return chunkZ5EEDCRI_cjs.graphemePrefix(line, LONGEST) === line ? line : `${chunkZ5EEDCRI_cjs.graphemePrefix(line, LONGEST - 1)}\u2026`;
|
|
6189
6465
|
}
|
|
6190
6466
|
var selectedBlockLabel = (labels, definitions, extensionNames) => (block, schema) => {
|
|
6191
6467
|
const { attrs } = block;
|
|
6192
|
-
if (block.type === "IMAGE") return hasPicture(attrs) ?
|
|
6468
|
+
if (block.type === "IMAGE") return hasPicture(attrs) ? chunk4JDRDPLC_cjs.str(attrs.alt) || labels.imageNoAlt : labels.emptyImage;
|
|
6193
6469
|
if (block.type === "CODE") {
|
|
6194
|
-
const language2 =
|
|
6470
|
+
const language2 = chunk4JDRDPLC_cjs.str(attrs.language);
|
|
6195
6471
|
return labels.codeBlockName(languageName(language2) ?? (language2 || labels.plainText));
|
|
6196
6472
|
}
|
|
6197
6473
|
if (block.type === "FILE" && hasFile(attrs)) return labels.fileBlockName(firstLine2(fileName(attrs)));
|
|
6198
|
-
return firstLine2(
|
|
6474
|
+
return firstLine2(chunk4JDRDPLC_cjs.blockPlainText(block, schema)) || blockTypeLabel(labels, block, definitions, extensionNames);
|
|
6199
6475
|
};
|
|
6200
6476
|
function revealLinkedBlock(controller, hash) {
|
|
6201
6477
|
const id = linkedBlockId(hash);
|
|
@@ -6203,7 +6479,7 @@ function revealLinkedBlock(controller, hash) {
|
|
|
6203
6479
|
if (id === null || shell === void 0) return false;
|
|
6204
6480
|
const { editor } = controller;
|
|
6205
6481
|
const { doc, schema } = editor.state;
|
|
6206
|
-
editor.dispatch(editor.createTransaction().setSelection(
|
|
6482
|
+
editor.dispatch(editor.createTransaction().setSelection(chunkZ5EEDCRI_cjs.startOf(doc, schema, id)));
|
|
6207
6483
|
shell.scrollIntoView?.({ block: "center" });
|
|
6208
6484
|
return true;
|
|
6209
6485
|
}
|
|
@@ -6220,8 +6496,8 @@ function useBlockLinkTarget(controller, focusOnMount) {
|
|
|
6220
6496
|
}, [controller, focusOnMount]);
|
|
6221
6497
|
}
|
|
6222
6498
|
var WRITER_ORIGINS = /* @__PURE__ */ new Set(["command", "input", "paste"]);
|
|
6223
|
-
var isBlockDeletion = (tr) => WRITER_ORIGINS.has(tr.origin) && tr.getMeta(
|
|
6224
|
-
var isEmptyText = (schema, block) =>
|
|
6499
|
+
var isBlockDeletion = (tr) => WRITER_ORIGINS.has(tr.origin) && tr.getMeta(chunkZ5EEDCRI_cjs.LINE_JOIN) !== true;
|
|
6500
|
+
var isEmptyText = (schema, block) => chunkZ5EEDCRI_cjs.isTextFlow(schema, block) && chunkZ5EEDCRI_cjs.regionLength(block, chunkZ5EEDCRI_cjs.primaryRegion(schema, block) ?? "") === 0;
|
|
6225
6501
|
function filledLine({ origin, before }, schema) {
|
|
6226
6502
|
const { selection } = before;
|
|
6227
6503
|
if (origin !== "paste" || selection?.kind !== "text") return () => false;
|
|
@@ -6230,18 +6506,15 @@ function filledLine({ origin, before }, schema) {
|
|
|
6230
6506
|
}
|
|
6231
6507
|
function deletions(codec, tr) {
|
|
6232
6508
|
const filled = filledLine(tr, tr.before.schema);
|
|
6233
|
-
return tr.
|
|
6234
|
-
|
|
6235
|
-
const
|
|
6236
|
-
if (typeof index !== "number" || typeof count !== "number") return [];
|
|
6237
|
-
const { blocks } = tr.docs[i];
|
|
6238
|
-
const first = codec.blocksFromDoc(chunkI7X7B3WD_cjs.createDoc(blocks.slice(0, index))).length;
|
|
6509
|
+
return blockRemovals(tr).flatMap(({ step, index, count }) => {
|
|
6510
|
+
const { blocks } = tr.docs[step];
|
|
6511
|
+
const first = codec.blocksFromDoc(chunk4JDRDPLC_cjs.createDoc(blocks.slice(0, index))).length;
|
|
6239
6512
|
return blocks.slice(index, index + count).flatMap((block, offset) => filled(block) ? [] : [{ block: codec.toQuoin(block), index: first + offset }]);
|
|
6240
6513
|
});
|
|
6241
6514
|
}
|
|
6242
6515
|
function useDeleteReporter(controller, onDelete) {
|
|
6243
6516
|
const latest = React7.useRef(onDelete);
|
|
6244
|
-
|
|
6517
|
+
chunkN25EH2GZ_cjs.useIsomorphicLayoutEffect(() => {
|
|
6245
6518
|
latest.current = onDelete;
|
|
6246
6519
|
});
|
|
6247
6520
|
React7.useEffect(() => {
|
|
@@ -6253,6 +6526,61 @@ function useDeleteReporter(controller, onDelete) {
|
|
|
6253
6526
|
});
|
|
6254
6527
|
}, [controller]);
|
|
6255
6528
|
}
|
|
6529
|
+
|
|
6530
|
+
// src/canvas/upload-pasted-images.ts
|
|
6531
|
+
var FETCHABLE = /^https?:\/\//i;
|
|
6532
|
+
function pastedPictures(tr, state) {
|
|
6533
|
+
if (tr.getMeta(chunkZ5EEDCRI_cjs.PASTED_HTML) !== true) return [];
|
|
6534
|
+
return state.doc.blocks.flatMap(({ id, type, attrs }) => {
|
|
6535
|
+
const url = chunk4JDRDPLC_cjs.str(attrs.url);
|
|
6536
|
+
const pasted = type === "IMAGE" && FETCHABLE.test(url) && !chunk4JDRDPLC_cjs.str(attrs.storageKey) && !tr.before.doc.index.has(id);
|
|
6537
|
+
return pasted ? [{ id, url }] : [];
|
|
6538
|
+
});
|
|
6539
|
+
}
|
|
6540
|
+
async function pictureAt(url) {
|
|
6541
|
+
const response = await fetch(url).catch(() => null);
|
|
6542
|
+
const picture = response?.ok ? await response.blob().catch(() => null) : null;
|
|
6543
|
+
if (!picture?.type.startsWith("image/")) return null;
|
|
6544
|
+
return new File([picture], url.split(/[?#]/)[0].split("/").pop() || "image", { type: picture.type });
|
|
6545
|
+
}
|
|
6546
|
+
function uploadPastedImages(controller, tr, state, host) {
|
|
6547
|
+
for (const { id, url } of pastedPictures(tr, state)) {
|
|
6548
|
+
void pictureAt(url).then(async (file) => {
|
|
6549
|
+
if (file === null) return;
|
|
6550
|
+
await uploadImage(controller, id, file, host).catch(
|
|
6551
|
+
(cause) => host.onError(new Error(cause instanceof Error && cause.message || host.failed))
|
|
6552
|
+
);
|
|
6553
|
+
});
|
|
6554
|
+
}
|
|
6555
|
+
}
|
|
6556
|
+
|
|
6557
|
+
// src/i18n/resolve-labels.ts
|
|
6558
|
+
var isRecord = (value) => typeof value === "object" && value !== null;
|
|
6559
|
+
function ontoRecords(overrides) {
|
|
6560
|
+
const taken = Object.entries(overrides).map(([key, value]) => {
|
|
6561
|
+
const fallback = englishLabels[key];
|
|
6562
|
+
return [key, isRecord(value) && isRecord(fallback) ? { ...fallback, ...value } : value];
|
|
6563
|
+
});
|
|
6564
|
+
return Object.fromEntries(taken);
|
|
6565
|
+
}
|
|
6566
|
+
var resolveLabels = (overrides) => chunkZWTIRGY5_cjs.mergeLabels(englishLabels, overrides && ontoRecords(overrides));
|
|
6567
|
+
|
|
6568
|
+
// src/canvas/use-stable-labels.ts
|
|
6569
|
+
var isRecord2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6570
|
+
function sameEntries(a, b, deeper) {
|
|
6571
|
+
const keys = Object.keys(a);
|
|
6572
|
+
if (keys.length !== Object.keys(b).length) return false;
|
|
6573
|
+
return keys.every((key) => {
|
|
6574
|
+
const [x, y] = [a[key], b[key]];
|
|
6575
|
+
return Object.is(x, y) || deeper && isRecord2(x) && isRecord2(y) && sameEntries(x, y, false);
|
|
6576
|
+
});
|
|
6577
|
+
}
|
|
6578
|
+
var sameOverrides = (a, b) => a === b || a !== void 0 && b !== void 0 && sameEntries(a, b, true);
|
|
6579
|
+
function useStableLabels(overrides) {
|
|
6580
|
+
const [kept, setKept] = React7.useState(overrides);
|
|
6581
|
+
if (!sameOverrides(kept, overrides)) setKept(overrides);
|
|
6582
|
+
return React7.useMemo(() => resolveLabels(kept), [kept]);
|
|
6583
|
+
}
|
|
6256
6584
|
function useStructureAnnouncements(controller, labels) {
|
|
6257
6585
|
React7.useEffect(() => {
|
|
6258
6586
|
const undoKeys = formatShortcut("Mod-z", { isMac: controller.isMac, labels });
|
|
@@ -6300,7 +6628,7 @@ var BlockCanvas = React7.forwardRef(function BlockCanvas2({
|
|
|
6300
6628
|
const [voidEditing] = React7.useState(createVoidEditing);
|
|
6301
6629
|
const [uiStore] = React7.useState(createCanvasUiStore);
|
|
6302
6630
|
const [allExtensions] = React7.useState(() => [
|
|
6303
|
-
...
|
|
6631
|
+
...chunkZ5EEDCRI_cjs.coreExtensions(),
|
|
6304
6632
|
voidEditing.extension,
|
|
6305
6633
|
blockMenuKeymap(uiStore),
|
|
6306
6634
|
slashExtension(),
|
|
@@ -6309,7 +6637,7 @@ var BlockCanvas = React7.forwardRef(function BlockCanvas2({
|
|
|
6309
6637
|
shortcutsExtension(uiStore),
|
|
6310
6638
|
...extensions ?? []
|
|
6311
6639
|
]);
|
|
6312
|
-
const labels =
|
|
6640
|
+
const labels = useStableLabels(labelOverrides);
|
|
6313
6641
|
const latestOnError = React7.useRef(onError);
|
|
6314
6642
|
latestOnError.current = onError;
|
|
6315
6643
|
const ui = React7.useMemo(
|
|
@@ -6318,12 +6646,17 @@ var BlockCanvas = React7.forwardRef(function BlockCanvas2({
|
|
|
6318
6646
|
);
|
|
6319
6647
|
useDefinitionWarnings(blockTypes, readOnly);
|
|
6320
6648
|
const [focusOnMount] = React7.useState(autoFocus);
|
|
6321
|
-
const controller =
|
|
6649
|
+
const controller = chunkN25EH2GZ_cjs.useQuoinEditor({
|
|
6322
6650
|
blocks,
|
|
6323
6651
|
onChange,
|
|
6324
6652
|
readOnly,
|
|
6325
6653
|
extensions: allExtensions,
|
|
6326
6654
|
render: ui.render,
|
|
6655
|
+
onTransaction(tr, state) {
|
|
6656
|
+
if (!upload) return;
|
|
6657
|
+
const host = { upload, resolveAssetUrl: resolveAssetUrl ?? String, onError: onError ?? console.error };
|
|
6658
|
+
uploadPastedImages(controller, tr, state, { ...host, failed: labels.uploadFailed });
|
|
6659
|
+
},
|
|
6327
6660
|
onFiles(files, at) {
|
|
6328
6661
|
const report = onError ?? console.error;
|
|
6329
6662
|
void insertUploads(controller, files, at, {
|
|
@@ -6340,7 +6673,9 @@ var BlockCanvas = React7.forwardRef(function BlockCanvas2({
|
|
|
6340
6673
|
useStructureAnnouncements(controller, labels);
|
|
6341
6674
|
const actions = React7.useMemo(() => {
|
|
6342
6675
|
const onCopied = () => controller.announce(labels.copied);
|
|
6343
|
-
|
|
6676
|
+
const onCopyFailed = () => controller.announce(labels.copyFailed ?? englishLabels.copyFailed);
|
|
6677
|
+
const core = coreBlockMenuActions(labels, { blockLink, onCopied, onCopyFailed, resolveAssetUrl });
|
|
6678
|
+
return menuActions(core, ui.blockMenuItems);
|
|
6344
6679
|
}, [controller, labels, blockLink, resolveAssetUrl, ui.blockMenuItems]);
|
|
6345
6680
|
const slashItems = React7.useMemo(
|
|
6346
6681
|
() => [shortcutsSlashItem(labels, uiStore), ...ui.slashItems],
|
|
@@ -6366,7 +6701,7 @@ var BlockCanvas = React7.forwardRef(function BlockCanvas2({
|
|
|
6366
6701
|
[controller, resolveAssetUrl]
|
|
6367
6702
|
);
|
|
6368
6703
|
return /* @__PURE__ */ jsxRuntime.jsx(reactDirection.DirectionProvider, { dir: direction, children: /* @__PURE__ */ jsxRuntime.jsx(QuoinProvider, { value: { blockTypes, upload, resolveAssetUrl, onError, highlight, controller, labels }, children: /* @__PURE__ */ jsxRuntime.jsx(VoidEditingContext.Provider, { value: voidEditing, children: /* @__PURE__ */ jsxRuntime.jsx(SlashItemsProvider, { value: slashItems, children: /* @__PURE__ */ jsxRuntime.jsx(BubbleItemsProvider, { value: ui.bubbleItems, children: /* @__PURE__ */ jsxRuntime.jsx(CanvasUiProvider, { value: uiStore, children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
6369
|
-
|
|
6704
|
+
chunkN25EH2GZ_cjs.EditorView,
|
|
6370
6705
|
{
|
|
6371
6706
|
controller,
|
|
6372
6707
|
renderers: ui.renderers,
|
|
@@ -6374,6 +6709,7 @@ var BlockCanvas = React7.forwardRef(function BlockCanvas2({
|
|
|
6374
6709
|
id,
|
|
6375
6710
|
"aria-label": ariaLabel ?? labels.document,
|
|
6376
6711
|
hint: labels.editorHint,
|
|
6712
|
+
rendererLabels: labels,
|
|
6377
6713
|
paragraphLabel: labels.paragraph,
|
|
6378
6714
|
selectedContentLabel: labels.selectedContent,
|
|
6379
6715
|
blockLabel,
|
|
@@ -6400,22 +6736,25 @@ function progressText(state, labels) {
|
|
|
6400
6736
|
return "";
|
|
6401
6737
|
}
|
|
6402
6738
|
function UploadField({ category, label, accept, onUploaded }) {
|
|
6403
|
-
const { upload, onError } = useQuoin();
|
|
6739
|
+
const { upload, onError, controller } = useQuoin();
|
|
6404
6740
|
const labels = useLabels();
|
|
6405
6741
|
const [state, setState] = React7__namespace.useState({ phase: "idle" });
|
|
6406
6742
|
async function run(file) {
|
|
6407
6743
|
if (!upload) return;
|
|
6408
6744
|
setState({ phase: "busy" });
|
|
6745
|
+
controller?.announce(labels.uploading);
|
|
6409
6746
|
let result;
|
|
6410
6747
|
try {
|
|
6411
6748
|
result = await upload(file, category);
|
|
6412
6749
|
} catch (cause) {
|
|
6413
|
-
setState({ phase: "failed", message: cause
|
|
6750
|
+
setState({ phase: "failed", message: uploadError(cause, labels.uploadFailed).message });
|
|
6414
6751
|
return;
|
|
6415
6752
|
}
|
|
6416
6753
|
try {
|
|
6417
6754
|
await onUploaded(result);
|
|
6418
|
-
|
|
6755
|
+
const name = result.filename || file.name;
|
|
6756
|
+
setState({ phase: "uploaded", name });
|
|
6757
|
+
controller?.announce(labels.uploaded(name));
|
|
6419
6758
|
} catch (cause) {
|
|
6420
6759
|
onError(toError(cause));
|
|
6421
6760
|
setState({ phase: "idle" });
|
|
@@ -6434,7 +6773,7 @@ function UploadField({ category, label, accept, onUploaded }) {
|
|
|
6434
6773
|
}
|
|
6435
6774
|
),
|
|
6436
6775
|
!upload && /* @__PURE__ */ jsxRuntime.jsx("span", { role: "note", className: "text-xs text-muted-foreground", children: labels.uploadsUnavailable }),
|
|
6437
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { role: "status", className: progress === "" ? "sr-only" : "text-xs text-muted-foreground", children: progress }),
|
|
6776
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { role: controller ? void 0 : "status", className: progress === "" ? "sr-only" : "text-xs text-muted-foreground", children: progress }),
|
|
6438
6777
|
state.phase === "failed" && /* @__PURE__ */ jsxRuntime.jsx("span", { role: "alert", className: "text-xs text-destructive", children: state.message })
|
|
6439
6778
|
] });
|
|
6440
6779
|
}
|
|
@@ -6567,7 +6906,7 @@ function useAutosave({
|
|
|
6567
6906
|
const seen = seenRef.current;
|
|
6568
6907
|
seenRef.current = deps;
|
|
6569
6908
|
if (seen === null) return;
|
|
6570
|
-
const unchanged =
|
|
6909
|
+
const unchanged = chunk4JDRDPLC_cjs.sameItems(seen, deps);
|
|
6571
6910
|
if (!unchanged) runner.markDirty();
|
|
6572
6911
|
}, deps);
|
|
6573
6912
|
React7__namespace.useEffect(() => {
|
|
@@ -6676,6 +7015,7 @@ exports.styleTargets = styleTargets;
|
|
|
6676
7015
|
exports.suggestionPlugin = suggestionPlugin;
|
|
6677
7016
|
exports.toError = toError;
|
|
6678
7017
|
exports.useAutosave = useAutosave;
|
|
7018
|
+
exports.useClosing = useClosing;
|
|
6679
7019
|
exports.useFocusKey = useFocusKey;
|
|
6680
7020
|
exports.useLabels = useLabels;
|
|
6681
7021
|
exports.useNodeKeys = useNodeKeys;
|
|
@@ -6685,3 +7025,4 @@ exports.useQuoin = useQuoin;
|
|
|
6685
7025
|
exports.useRangeAnchor = useRangeAnchor;
|
|
6686
7026
|
exports.useRovingFocus = useRovingFocus;
|
|
6687
7027
|
exports.virtualAnchor = virtualAnchor;
|
|
7028
|
+
exports.watchDirection = watchDirection;
|