tiptap-markdown-react 0.17.0 → 0.18.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.
Files changed (34) hide show
  1. package/README.md +75 -3
  2. package/dist/{ReportContent-CwcppHl8.js → ReportContent-MgbebxPV.js} +8 -8
  3. package/dist/{ReportContent-CwcppHl8.js.map → ReportContent-MgbebxPV.js.map} +1 -1
  4. package/dist/components/EditorToolbar.d.ts +12 -1
  5. package/dist/components/EditorToolbar.dom.test.d.ts +1 -0
  6. package/dist/components/FindReplaceBar.d.ts +0 -7
  7. package/dist/components/LinkPopover.d.ts +28 -0
  8. package/dist/components/LinkPopover.dom.test.d.ts +1 -0
  9. package/dist/components/MarkdownWysiwygEditor.d.ts +12 -0
  10. package/dist/components/TableHandles.d.ts +19 -0
  11. package/dist/components/TableHandles.dom.test.d.ts +1 -0
  12. package/dist/components/findEntry.dom.test.d.ts +1 -0
  13. package/dist/{extractToc-CheLC9kh.js → extractToc-BaR6LP1f.js} +42 -4
  14. package/dist/extractToc-BaR6LP1f.js.map +1 -0
  15. package/dist/findReplace.d.ts +18 -4
  16. package/dist/icons/index.d.ts +6 -0
  17. package/dist/index.d.ts +3 -1
  18. package/dist/index.js +1320 -608
  19. package/dist/index.js.map +1 -1
  20. package/dist/labels.d.ts +41 -1
  21. package/dist/linkEditing.d.ts +45 -0
  22. package/dist/linkEditing.test.d.ts +1 -0
  23. package/dist/placeholder.test.d.ts +1 -0
  24. package/dist/reader.js +2 -2
  25. package/dist/{scrollToTocHeading-CBvptTaQ.js → scrollToTocHeading-BTQWajGD.js} +2 -2
  26. package/dist/{scrollToTocHeading-CBvptTaQ.js.map → scrollToTocHeading-BTQWajGD.js.map} +1 -1
  27. package/dist/server.js +4 -4
  28. package/dist/style-inline.css +398 -174
  29. package/dist/style.css +398 -174
  30. package/dist/supSubMarkdown.test.d.ts +1 -0
  31. package/dist/supSubServer.test.d.ts +1 -0
  32. package/dist/tableSelection.d.ts +25 -5
  33. package/package.json +1 -1
  34. package/dist/extractToc-CheLC9kh.js.map +0 -1
package/dist/index.js CHANGED
@@ -1,28 +1,28 @@
1
1
  "use client";
2
2
  import { Markdown, MarkdownManager } from "@tiptap/markdown";
3
- import { c as renderOrUpdateChart, d as destroyChart } from "./scrollToTocHeading-CBvptTaQ.js";
4
- import { C, a, R, b, f, m, r, s } from "./scrollToTocHeading-CBvptTaQ.js";
3
+ import { c as renderOrUpdateChart, d as destroyChart } from "./scrollToTocHeading-BTQWajGD.js";
4
+ import { C, a, R, b, f, m, r, s } from "./scrollToTocHeading-BTQWajGD.js";
5
5
  import { jsx, jsxs, Fragment as Fragment$2 } from "react/jsx-runtime";
6
6
  import CodeBlockLowlight from "@tiptap/extension-code-block-lowlight";
7
7
  import FindAndReplace, { FindAndReplacePluginKey, createSearchRegex } from "@tiptap/extension-find-and-replace";
8
8
  import { default as default2 } from "@tiptap/extension-find-and-replace";
9
9
  import Image from "@tiptap/extension-image";
10
10
  import { TableOfContents } from "@tiptap/extension-table-of-contents";
11
+ import { skipTrailingNodeMeta, Placeholder } from "@tiptap/extensions";
11
12
  import { NodeViewWrapper, ReactNodeViewRenderer, useEditorState, ReactRenderer, NodeViewContent, useEditor, EditorContent } from "@tiptap/react";
12
13
  import { createPortal } from "react-dom";
13
14
  import { useState, useEffect, useCallback, useRef, useMemo, forwardRef, useImperativeHandle, Fragment as Fragment$1, useLayoutEffect, useId, useContext, createContext } from "react";
14
- import { e as enrichMarkdownCitations, c as styles$8 } from "./ReportContent-CwcppHl8.js";
15
- import { R as R2, a as a2, b as b2, s as s2 } from "./ReportContent-CwcppHl8.js";
16
- import { C as CitationRef, i as mergeCommentIntervals, h as mapCommentAnchors, p as prepareChartMarkdown, j as reportChart, b as baseExtensions, f as CommentMark, l as lowlight, m as makeTocGetId, k as parseCodeTokenAsChartOrCodeBlock, a as pureCodeBlock, c as pureImage, n as renderMathInto, o as subscribeMathClick, d as pureChart } from "./extractToc-CheLC9kh.js";
17
- import { g, e, s as s3 } from "./extractToc-CheLC9kh.js";
15
+ import { e as enrichMarkdownCitations, c as styles$a } from "./ReportContent-MgbebxPV.js";
16
+ import { R as R2, a as a2, b as b2, s as s2 } from "./ReportContent-MgbebxPV.js";
17
+ import { C as CitationRef, i as mergeCommentIntervals, h as mapCommentAnchors, p as prepareChartMarkdown, j as reportChart, b as baseExtensions, f as CommentMark, l as lowlight, m as makeTocGetId, k as parseCodeTokenAsChartOrCodeBlock, a as pureCodeBlock, c as pureImage, n as renderMathInto, o as subscribeMathClick, d as pureChart } from "./extractToc-BaR6LP1f.js";
18
+ import { g, e, s as s3 } from "./extractToc-BaR6LP1f.js";
18
19
  import { Slice, Fragment } from "@tiptap/pm/model";
19
20
  import { Extension, Node as Node$1 } from "@tiptap/core";
20
21
  import { PluginKey, Plugin, NodeSelection, TextSelection } from "@tiptap/pm/state";
21
22
  import { DecorationSet, Decoration } from "@tiptap/pm/view";
22
23
  import Suggestion from "@tiptap/suggestion";
23
24
  import { FileHandlePlugin } from "@tiptap/extension-file-handler";
24
- import { skipTrailingNodeMeta } from "@tiptap/extensions";
25
- import { CellSelection, isInTable, selectedRect, rowIsHeader } from "@tiptap/pm/tables";
25
+ import { CellSelection, TableMap, isInTable, selectedRect, rowIsHeader, cellAround } from "@tiptap/pm/tables";
26
26
  import * as DropdownMenu from "@radix-ui/react-dropdown-menu";
27
27
  import * as Popover from "@radix-ui/react-popover";
28
28
  function CitationRefView({ node, extension }) {
@@ -336,6 +336,17 @@ function nextComment(editor, dir = "next") {
336
336
  focusComment(editor, target);
337
337
  return target;
338
338
  }
339
+ const FIND_EXTENSION_NAME = "findAndReplace";
340
+ function isComposingKeyEvent(event) {
341
+ return event.isComposing || event.keyCode === 229;
342
+ }
343
+ function hasFindReplaceExtension(editor) {
344
+ var _a;
345
+ if (!editor || editor.isDestroyed) return false;
346
+ return ((_a = editor.extensionManager) == null ? void 0 : _a.extensions.some(
347
+ (extension) => extension.name === FIND_EXTENSION_NAME
348
+ )) ?? false;
349
+ }
339
350
  const FIND_DEBOUNCE_MS = 120;
340
351
  const MISMATCH_RE = /Applying a mismatched transaction/;
341
352
  function runFindCommand(run) {
@@ -395,6 +406,20 @@ const LinkIcon = (p) => /* @__PURE__ */ jsxs(Svg, { ...p, children: [
395
406
  /* @__PURE__ */ jsx("path", { d: "M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71" }),
396
407
  /* @__PURE__ */ jsx("path", { d: "M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71" })
397
408
  ] });
409
+ const EraserIcon = (p) => /* @__PURE__ */ jsxs(Svg, { ...p, children: [
410
+ /* @__PURE__ */ jsx("path", { d: "m7 21-4.3-4.3c-1-1-1-2.5 0-3.4l9.6-9.6c1-1 2.5-1 3.4 0l5.6 5.6c1 1 1 2.5 0 3.4L13 21" }),
411
+ /* @__PURE__ */ jsx("path", { d: "M22 21H7" }),
412
+ /* @__PURE__ */ jsx("path", { d: "m5 11 9 9" })
413
+ ] });
414
+ const RotateCcwIcon = (p) => /* @__PURE__ */ jsxs(Svg, { ...p, children: [
415
+ /* @__PURE__ */ jsx("path", { d: "M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8" }),
416
+ /* @__PURE__ */ jsx("path", { d: "M3 3v5h5" })
417
+ ] });
418
+ const ExternalLinkIcon = (p) => /* @__PURE__ */ jsxs(Svg, { ...p, children: [
419
+ /* @__PURE__ */ jsx("path", { d: "M15 3h6v6" }),
420
+ /* @__PURE__ */ jsx("path", { d: "M10 14 21 3" }),
421
+ /* @__PURE__ */ jsx("path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" })
422
+ ] });
398
423
  const ImageIcon = (p) => /* @__PURE__ */ jsxs(Svg, { ...p, children: [
399
424
  /* @__PURE__ */ jsx("rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", ry: "2" }),
400
425
  /* @__PURE__ */ jsx("circle", { cx: "9", cy: "9", r: "2" }),
@@ -577,6 +602,10 @@ const defaultToolbarLabels = {
577
602
  subscript: "Subscript",
578
603
  link: "Link",
579
604
  linkPrompt: "Enter URL",
605
+ linkApply: "Apply link",
606
+ linkOpen: "Open in new window",
607
+ linkRemove: "Remove link",
608
+ linkInvalid: "The editor rejected this address",
580
609
  image: "Image",
581
610
  imageUploadFailed: "Image upload failed",
582
611
  importMarkdownFailed: "Markdown import failed",
@@ -592,10 +621,17 @@ const defaultToolbarLabels = {
592
621
  orderedList: "Ordered list",
593
622
  taskList: "Task list",
594
623
  more: "More",
624
+ search: "Find & replace",
595
625
  codeBlock: "Code block",
596
626
  hr: "Divider",
597
627
  importMarkdown: "Markdown",
598
628
  tableInsert: "Insert table",
629
+ tableRowMenu: "Row actions",
630
+ tableColumnMenu: "Column actions",
631
+ tableClearContent: "Clear content",
632
+ tableResetCellStyles: "Reset cell styles",
633
+ tableAppendRow: "Add row",
634
+ tableAppendColumn: "Add column",
599
635
  tableSizeSelected: (cols, rows) => `${cols} × ${rows}`,
600
636
  tableAddColumnBefore: "Add column before",
601
637
  tableAddColumnAfter: "Add column after",
@@ -663,6 +699,13 @@ const defaultShortcutLabels = {
663
699
  hardBreak: "Hard break",
664
700
  findReplace: "Find & replace"
665
701
  };
702
+ const defaultLinkPopoverLabels = {
703
+ field: "Enter URL",
704
+ apply: "Apply link",
705
+ open: "Open in new window",
706
+ remove: "Remove link",
707
+ invalid: "The editor rejected this address"
708
+ };
666
709
  const defaultColorPaletteLabels = {
667
710
  none: "None",
668
711
  theme: "THEME"
@@ -705,32 +748,40 @@ const defaultFindLabels = {
705
748
  };
706
749
  const bar = "_bar_1h61e_3";
707
750
  const row$1 = "_row_1h61e_25";
708
- const field = "_field_1h61e_43";
751
+ const field$1 = "_field_1h61e_43";
709
752
  const fieldIcon = "_fieldIcon_1h61e_62";
710
- const input = "_input_1h61e_67";
753
+ const input$1 = "_input_1h61e_67";
711
754
  const counter = "_counter_1h61e_79";
712
755
  const counterInvalid = "_counterInvalid_1h61e_89";
713
- const btn$1 = "_btn_1h61e_93";
756
+ const btn$2 = "_btn_1h61e_93";
714
757
  const toggle = "_toggle_1h61e_29";
715
758
  const toggleOn = "_toggleOn_1h61e_135";
716
759
  const iconGroup = "_iconGroup_1h61e_29";
717
760
  const spacer = "_spacer_1h61e_150";
718
761
  const readOnly = "_readOnly_1h61e_155";
719
- const styles$7 = {
762
+ const styles$9 = {
720
763
  bar,
721
764
  row: row$1,
722
- field,
765
+ field: field$1,
723
766
  fieldIcon,
724
- input,
767
+ input: input$1,
725
768
  counter,
726
769
  counterInvalid,
727
- btn: btn$1,
770
+ btn: btn$2,
728
771
  toggle,
729
772
  toggleOn,
730
773
  iconGroup,
731
774
  spacer,
732
775
  readOnly
733
776
  };
777
+ let warnedMissingExtension = false;
778
+ function warnMissingExtensionOnce() {
779
+ if (warnedMissingExtension) return;
780
+ warnedMissingExtension = true;
781
+ console.warn(
782
+ "[tiptap-markdown-react] FindReplaceBar 需要官方 find 扩展:请让 <MarkdownWysiwygEditor findReplace> 保持开启(默认 true),否则 setSearchTerm / replaceAll 等命令不存在。"
783
+ );
784
+ }
734
785
  function FindReplaceBar({
735
786
  editor,
736
787
  onClose,
@@ -742,13 +793,9 @@ function FindReplaceBar({
742
793
  const t = { ...defaultFindLabels, ...labels };
743
794
  const [term, setTerm] = useState("");
744
795
  const [replaceTerm, setReplaceTerm] = useState("");
745
- const hasExtension = typeof editor.commands.setSearchTerm === "function";
796
+ const hasExtension = hasFindReplaceExtension(editor);
746
797
  useEffect(() => {
747
- if (!hasExtension) {
748
- console.warn(
749
- "[tiptap-markdown-react] FindReplaceBar 需要官方 find 扩展:请让 <MarkdownWysiwygEditor findReplace> 保持开启(默认 true),否则 setSearchTerm / replaceAll 等命令不存在。"
750
- );
751
- }
798
+ if (!hasExtension) warnMissingExtensionOnce();
752
799
  }, [hasExtension]);
753
800
  const state = useEditorState({
754
801
  editor,
@@ -809,12 +856,11 @@ function FindReplaceBar({
809
856
  }) === null,
810
857
  [term, state.useRegex, state.caseSensitive]
811
858
  );
812
- const counter2 = t.counter(
813
- state.total === 0 ? 0 : (state.currentIndex ?? 0) + 1,
814
- state.total
815
- );
859
+ const current = state.total === 0 || state.currentIndex === null ? 0 : state.currentIndex + 1;
860
+ const counter2 = t.counter(current, state.total);
816
861
  const keepFocus = (e2) => e2.preventDefault();
817
862
  const onFindKeyDown = (e2) => {
863
+ if (isComposingKeyEvent(e2.nativeEvent)) return;
818
864
  if (e2.key === "Enter") {
819
865
  e2.preventDefault();
820
866
  runAction(() => {
@@ -824,6 +870,7 @@ function FindReplaceBar({
824
870
  }
825
871
  };
826
872
  const onReplaceKeyDown = (e2) => {
873
+ if (isComposingKeyEvent(e2.nativeEvent)) return;
827
874
  if (e2.key === "Enter") {
828
875
  e2.preventDefault();
829
876
  runAction(() => editor.commands.replace());
@@ -836,29 +883,32 @@ function FindReplaceBar({
836
883
  });
837
884
  };
838
885
  if (!hasExtension) return null;
839
- const toggleClass = (on) => `${styles$7.btn} ${styles$7.toggle}${on ? ` ${styles$7.toggleOn}` : ""}`;
886
+ const toggleClass = (on) => `${styles$9.btn} ${styles$9.toggle}${on ? ` ${styles$9.toggleOn}` : ""}`;
840
887
  return /* @__PURE__ */ jsxs(
841
888
  "div",
842
889
  {
843
- className: className ? `${styles$7.bar} ${className}` : styles$7.bar,
890
+ className: className ? `${styles$9.bar} ${className}` : styles$9.bar,
844
891
  style,
892
+ "data-find-bar": "",
845
893
  role: "dialog",
846
894
  "aria-label": t.find,
847
895
  onKeyDown: (e2) => {
848
- if (e2.key === "Escape") {
849
- e2.preventDefault();
850
- onClose();
851
- }
896
+ if (isComposingKeyEvent(e2.nativeEvent)) return;
897
+ if (e2.key !== "Escape") return;
898
+ e2.preventDefault();
899
+ e2.stopPropagation();
900
+ onClose();
852
901
  },
853
902
  children: [
854
- /* @__PURE__ */ jsxs("div", { className: styles$7.row, children: [
855
- /* @__PURE__ */ jsxs("span", { className: styles$7.field, children: [
856
- /* @__PURE__ */ jsx(SearchIcon, { size: 14, className: styles$7.fieldIcon }),
903
+ /* @__PURE__ */ jsxs("div", { className: styles$9.row, children: [
904
+ /* @__PURE__ */ jsxs("span", { className: styles$9.field, children: [
905
+ /* @__PURE__ */ jsx(SearchIcon, { size: 14, className: styles$9.fieldIcon }),
857
906
  /* @__PURE__ */ jsx(
858
907
  "input",
859
908
  {
860
909
  ref: inputRef,
861
- className: styles$7.input,
910
+ className: styles$9.input,
911
+ "data-find-field": "search",
862
912
  value: term,
863
913
  onChange: (e2) => setTerm(e2.target.value),
864
914
  onKeyDown: onFindKeyDown,
@@ -871,7 +921,8 @@ function FindReplaceBar({
871
921
  /* @__PURE__ */ jsx(
872
922
  "span",
873
923
  {
874
- className: `${styles$7.counter}${invalidPattern ? ` ${styles$7.counterInvalid}` : ""}`,
924
+ className: `${styles$9.counter}${invalidPattern ? ` ${styles$9.counterInvalid}` : ""}`,
925
+ "data-find-counter": "",
875
926
  "aria-live": "polite",
876
927
  title: invalidPattern ? t.invalidRegex : void 0,
877
928
  children: invalidPattern ? t.invalidRegex : counter2
@@ -883,6 +934,7 @@ function FindReplaceBar({
883
934
  {
884
935
  type: "button",
885
936
  className: toggleClass(state.caseSensitive),
937
+ "data-find-option": "match-case",
886
938
  title: t.caseSensitive,
887
939
  "aria-label": t.caseSensitive,
888
940
  "aria-pressed": state.caseSensitive,
@@ -896,6 +948,7 @@ function FindReplaceBar({
896
948
  {
897
949
  type: "button",
898
950
  className: toggleClass(state.wholeWord),
951
+ "data-find-option": "whole-words",
899
952
  title: t.wholeWord,
900
953
  "aria-label": t.wholeWord,
901
954
  "aria-pressed": state.wholeWord,
@@ -904,13 +957,14 @@ function FindReplaceBar({
904
957
  children: "ab"
905
958
  }
906
959
  ),
907
- /* @__PURE__ */ jsx("span", { className: styles$7.spacer }),
908
- /* @__PURE__ */ jsxs("span", { className: styles$7.iconGroup, children: [
960
+ /* @__PURE__ */ jsx("span", { className: styles$9.spacer }),
961
+ /* @__PURE__ */ jsxs("span", { className: styles$9.iconGroup, children: [
909
962
  /* @__PURE__ */ jsx(
910
963
  "button",
911
964
  {
912
965
  type: "button",
913
- className: styles$7.btn,
966
+ className: styles$9.btn,
967
+ "data-find-action": "previous",
914
968
  title: t.previous,
915
969
  "aria-label": t.previous,
916
970
  disabled: state.total === 0,
@@ -923,7 +977,8 @@ function FindReplaceBar({
923
977
  "button",
924
978
  {
925
979
  type: "button",
926
- className: styles$7.btn,
980
+ className: styles$9.btn,
981
+ "data-find-action": "next",
927
982
  title: t.next,
928
983
  "aria-label": t.next,
929
984
  disabled: state.total === 0,
@@ -936,7 +991,8 @@ function FindReplaceBar({
936
991
  "button",
937
992
  {
938
993
  type: "button",
939
- className: styles$7.btn,
994
+ className: styles$9.btn,
995
+ "data-find-action": "close",
940
996
  title: t.close,
941
997
  "aria-label": t.close,
942
998
  onClick: onClose,
@@ -945,11 +1001,12 @@ function FindReplaceBar({
945
1001
  )
946
1002
  ] })
947
1003
  ] }),
948
- editor.isEditable ? /* @__PURE__ */ jsxs("div", { className: styles$7.row, children: [
949
- /* @__PURE__ */ jsx("span", { className: styles$7.field, children: /* @__PURE__ */ jsx(
1004
+ editor.isEditable ? /* @__PURE__ */ jsxs("div", { className: styles$9.row, children: [
1005
+ /* @__PURE__ */ jsx("span", { className: styles$9.field, children: /* @__PURE__ */ jsx(
950
1006
  "input",
951
1007
  {
952
- className: styles$7.input,
1008
+ className: styles$9.input,
1009
+ "data-find-field": "replace",
953
1010
  value: replaceTerm,
954
1011
  onChange: (e2) => setReplaceTerm(e2.target.value),
955
1012
  onKeyDown: onReplaceKeyDown,
@@ -958,12 +1015,13 @@ function FindReplaceBar({
958
1015
  spellCheck: false
959
1016
  }
960
1017
  ) }),
961
- /* @__PURE__ */ jsx("span", { className: styles$7.spacer }),
1018
+ /* @__PURE__ */ jsx("span", { className: styles$9.spacer }),
962
1019
  /* @__PURE__ */ jsx(
963
1020
  "button",
964
1021
  {
965
1022
  type: "button",
966
- className: styles$7.btn,
1023
+ className: styles$9.btn,
1024
+ "data-find-action": "replace",
967
1025
  title: t.replaceOne,
968
1026
  "aria-label": t.replaceOne,
969
1027
  disabled: state.total === 0,
@@ -976,7 +1034,8 @@ function FindReplaceBar({
976
1034
  "button",
977
1035
  {
978
1036
  type: "button",
979
- className: styles$7.btn,
1037
+ className: styles$9.btn,
1038
+ "data-find-action": "replace-all",
980
1039
  title: t.replaceAll,
981
1040
  "aria-label": t.replaceAll,
982
1041
  disabled: state.total === 0,
@@ -985,7 +1044,7 @@ function FindReplaceBar({
985
1044
  children: /* @__PURE__ */ jsx(ReplaceAllIcon, { size: 16 })
986
1045
  }
987
1046
  )
988
- ] }) : /* @__PURE__ */ jsx("div", { className: styles$7.row, children: /* @__PURE__ */ jsx("span", { className: styles$7.readOnly, children: t.readOnly }) })
1047
+ ] }) : /* @__PURE__ */ jsx("div", { className: styles$9.row, children: /* @__PURE__ */ jsx("span", { className: styles$9.readOnly, children: t.readOnly }) })
989
1048
  ]
990
1049
  }
991
1050
  );
@@ -1079,7 +1138,7 @@ const item$1 = "_item_1noza_53";
1079
1138
  const itemActive = "_itemActive_1noza_54";
1080
1139
  const itemIcon = "_itemIcon_1noza_79";
1081
1140
  const itemTitle = "_itemTitle_1noza_102";
1082
- const styles$6 = {
1141
+ const styles$8 = {
1083
1142
  popupHost,
1084
1143
  menu: menu$1,
1085
1144
  groupLabel,
@@ -1268,11 +1327,11 @@ const SlashMenuPopup = forwardRef(function SlashMenuPopup2({ items, query, menuL
1268
1327
  );
1269
1328
  if (!items.length) return null;
1270
1329
  let optionIndex = -1;
1271
- return /* @__PURE__ */ jsx("div", { className: styles$6.menu, role: "listbox", "aria-label": menuLabel, children: withGroupHeaders(items).map(([header2, item2]) => {
1330
+ return /* @__PURE__ */ jsx("div", { className: styles$8.menu, role: "listbox", "aria-label": menuLabel, children: withGroupHeaders(items).map(([header2, item2]) => {
1272
1331
  optionIndex += 1;
1273
1332
  const i = optionIndex;
1274
1333
  return /* @__PURE__ */ jsxs(Fragment$1, { children: [
1275
- header2 !== null ? /* @__PURE__ */ jsx("div", { className: styles$6.groupLabel, "aria-hidden": "true", children: header2 }) : null,
1334
+ header2 !== null ? /* @__PURE__ */ jsx("div", { className: styles$8.groupLabel, "aria-hidden": "true", children: header2 }) : null,
1276
1335
  /* @__PURE__ */ jsxs(
1277
1336
  "button",
1278
1337
  {
@@ -1280,7 +1339,7 @@ const SlashMenuPopup = forwardRef(function SlashMenuPopup2({ items, query, menuL
1280
1339
  role: "option",
1281
1340
  "aria-selected": i === index,
1282
1341
  title: item2.title,
1283
- className: i === index ? styles$6.itemActive : styles$6.item,
1342
+ className: i === index ? styles$8.itemActive : styles$8.item,
1284
1343
  tabIndex: -1,
1285
1344
  onMouseEnter: () => setIndex(i),
1286
1345
  onMouseDown: (e2) => {
@@ -1288,8 +1347,8 @@ const SlashMenuPopup = forwardRef(function SlashMenuPopup2({ items, query, menuL
1288
1347
  command(item2);
1289
1348
  },
1290
1349
  children: [
1291
- item2.icon != null ? /* @__PURE__ */ jsx("span", { className: styles$6.itemIcon, "aria-hidden": "true", children: item2.icon }) : /* @__PURE__ */ jsx("span", { className: styles$6.itemIcon, "aria-hidden": "true" }),
1292
- /* @__PURE__ */ jsx("span", { className: styles$6.itemTitle, children: item2.title })
1350
+ item2.icon != null ? /* @__PURE__ */ jsx("span", { className: styles$8.itemIcon, "aria-hidden": "true", children: item2.icon }) : /* @__PURE__ */ jsx("span", { className: styles$8.itemIcon, "aria-hidden": "true" }),
1351
+ /* @__PURE__ */ jsx("span", { className: styles$8.itemTitle, children: item2.title })
1293
1352
  ]
1294
1353
  }
1295
1354
  )
@@ -1340,7 +1399,7 @@ const SlashMenu = Extension.create({
1340
1399
  menuLabel: ((_a = this.options.labels) == null ? void 0 : _a.menuLabel) ?? defaultSlashMenuLabels.menuLabel,
1341
1400
  command: props.command
1342
1401
  },
1343
- className: styles$6.popupHost
1402
+ className: styles$8.popupHost
1344
1403
  }
1345
1404
  );
1346
1405
  const pmStyle = getComputedStyle(props.editor.view.dom);
@@ -1392,7 +1451,7 @@ const rowKeys = "_rowKeys_ljnq6_127";
1392
1451
  const rowMd = "_rowMd_ljnq6_128";
1393
1452
  const keycap = "_keycap_ljnq6_138";
1394
1453
  const none = "_none_ljnq6_163";
1395
- const styles$5 = {
1454
+ const styles$7 = {
1396
1455
  drawer,
1397
1456
  closeBtn,
1398
1457
  head,
@@ -1485,7 +1544,7 @@ function ShortcutPanel({ open, onClose, labels }) {
1485
1544
  return /* @__PURE__ */ jsxs(
1486
1545
  "aside",
1487
1546
  {
1488
- className: styles$5.drawer,
1547
+ className: styles$7.drawer,
1489
1548
  role: "dialog",
1490
1549
  "aria-modal": "false",
1491
1550
  "aria-label": t.panelTitle,
@@ -1494,27 +1553,27 @@ function ShortcutPanel({ open, onClose, labels }) {
1494
1553
  "button",
1495
1554
  {
1496
1555
  type: "button",
1497
- className: styles$5.closeBtn,
1556
+ className: styles$7.closeBtn,
1498
1557
  title: t.close,
1499
1558
  "aria-label": t.close,
1500
1559
  onClick: onClose,
1501
1560
  children: /* @__PURE__ */ jsx(XIcon, { size: 16 })
1502
1561
  }
1503
1562
  ),
1504
- /* @__PURE__ */ jsxs("div", { className: styles$5.head, children: [
1505
- /* @__PURE__ */ jsx("span", { className: styles$5.colFormat, children: t.colFormat }),
1506
- /* @__PURE__ */ jsx("span", { className: styles$5.colShortcut, children: t.colShortcut }),
1507
- /* @__PURE__ */ jsx("span", { className: styles$5.colMarkdown, children: t.colMarkdown })
1563
+ /* @__PURE__ */ jsxs("div", { className: styles$7.head, children: [
1564
+ /* @__PURE__ */ jsx("span", { className: styles$7.colFormat, children: t.colFormat }),
1565
+ /* @__PURE__ */ jsx("span", { className: styles$7.colShortcut, children: t.colShortcut }),
1566
+ /* @__PURE__ */ jsx("span", { className: styles$7.colMarkdown, children: t.colMarkdown })
1508
1567
  ] }),
1509
- /* @__PURE__ */ jsx("div", { className: styles$5.body, children: groups.map((group2) => /* @__PURE__ */ jsxs("section", { className: styles$5.group, children: [
1510
- /* @__PURE__ */ jsx("h3", { className: styles$5.groupTitle, children: group2.title }),
1511
- group2.entries.map((entry) => /* @__PURE__ */ jsxs("div", { className: styles$5.row, children: [
1512
- /* @__PURE__ */ jsx("span", { className: styles$5.rowLabel, children: entry.label }),
1513
- /* @__PURE__ */ jsx("span", { className: styles$5.rowKeys, children: entry.keys ? entry.keys.map((key, i) => /* @__PURE__ */ jsx("kbd", { className: styles$5.keycap, children: keycapText(key, mac) }, i)) : /* @__PURE__ */ jsx("span", { className: styles$5.none, children: "—" }) }),
1514
- /* @__PURE__ */ jsx("span", { className: styles$5.rowMd, children: entry.markdown ? /* @__PURE__ */ jsxs(Fragment$2, { children: [
1515
- /* @__PURE__ */ jsx("kbd", { className: styles$5.keycap, children: entry.markdown.marker }),
1516
- entry.markdown.terminator ? /* @__PURE__ */ jsx("kbd", { className: styles$5.keycap, children: entry.markdown.terminator }) : null
1517
- ] }) : /* @__PURE__ */ jsx("span", { className: styles$5.none, children: "—" }) })
1568
+ /* @__PURE__ */ jsx("div", { className: styles$7.body, children: groups.map((group2) => /* @__PURE__ */ jsxs("section", { className: styles$7.group, children: [
1569
+ /* @__PURE__ */ jsx("h3", { className: styles$7.groupTitle, children: group2.title }),
1570
+ group2.entries.map((entry) => /* @__PURE__ */ jsxs("div", { className: styles$7.row, children: [
1571
+ /* @__PURE__ */ jsx("span", { className: styles$7.rowLabel, children: entry.label }),
1572
+ /* @__PURE__ */ jsx("span", { className: styles$7.rowKeys, children: entry.keys ? entry.keys.map((key, i) => /* @__PURE__ */ jsx("kbd", { className: styles$7.keycap, children: keycapText(key, mac) }, i)) : /* @__PURE__ */ jsx("span", { className: styles$7.none, children: "—" }) }),
1573
+ /* @__PURE__ */ jsx("span", { className: styles$7.rowMd, children: entry.markdown ? /* @__PURE__ */ jsxs(Fragment$2, { children: [
1574
+ /* @__PURE__ */ jsx("kbd", { className: styles$7.keycap, children: entry.markdown.marker }),
1575
+ entry.markdown.terminator ? /* @__PURE__ */ jsx("kbd", { className: styles$7.keycap, children: entry.markdown.terminator }) : null
1576
+ ] }) : /* @__PURE__ */ jsx("span", { className: styles$7.none, children: "—" }) })
1518
1577
  ] }, entry.id))
1519
1578
  ] }, group2.id)) })
1520
1579
  ]
@@ -1818,7 +1877,7 @@ const gutterLine = "_gutterLine_k8th1_184";
1818
1877
  const readonlyActions = "_readonlyActions_k8th1_188";
1819
1878
  const actionBtn = "_actionBtn_k8th1_194";
1820
1879
  const langBraces = "_langBraces_k8th1_213";
1821
- const styles$4 = {
1880
+ const styles$6 = {
1822
1881
  wrapper,
1823
1882
  header: header$1,
1824
1883
  langTrigger,
@@ -1918,29 +1977,29 @@ function CodeBlockView({
1918
1977
  ta.remove();
1919
1978
  };
1920
1979
  const wrapperClass = [
1921
- styles$4.wrapper,
1922
- readonly2 ? styles$4.readonly : "",
1923
- folded2 ? styles$4.folded : ""
1980
+ styles$6.wrapper,
1981
+ readonly2 ? styles$6.readonly : "",
1982
+ folded2 ? styles$6.folded : ""
1924
1983
  ].filter(Boolean).join(" ");
1925
1984
  return /* @__PURE__ */ jsxs(NodeViewWrapper, { className: wrapperClass, children: [
1926
- editable ? /* @__PURE__ */ jsxs("div", { className: styles$4.header, contentEditable: false, children: [
1985
+ editable ? /* @__PURE__ */ jsxs("div", { className: styles$6.header, contentEditable: false, children: [
1927
1986
  /* @__PURE__ */ jsxs(DropdownMenu.Root, { children: [
1928
1987
  /* @__PURE__ */ jsx(DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(
1929
1988
  "button",
1930
1989
  {
1931
1990
  type: "button",
1932
- className: styles$4.langTrigger,
1991
+ className: styles$6.langTrigger,
1933
1992
  "aria-label": "Code language",
1934
1993
  children: [
1935
1994
  /* @__PURE__ */ jsx("span", { children: currentLabel }),
1936
- /* @__PURE__ */ jsx(ChevronDownIcon, { size: 14, className: styles$4.langChevron })
1995
+ /* @__PURE__ */ jsx(ChevronDownIcon, { size: 14, className: styles$6.langChevron })
1937
1996
  ]
1938
1997
  }
1939
1998
  ) }),
1940
1999
  /* @__PURE__ */ jsx(DropdownMenu.Portal, { children: /* @__PURE__ */ jsx(
1941
2000
  DropdownMenu.Content,
1942
2001
  {
1943
- className: styles$4.langMenu,
2002
+ className: styles$6.langMenu,
1944
2003
  sideOffset: 4,
1945
2004
  align: "end",
1946
2005
  children: LANGUAGES.map((l) => {
@@ -1949,10 +2008,10 @@ function CodeBlockView({
1949
2008
  return /* @__PURE__ */ jsxs(
1950
2009
  DropdownMenu.Item,
1951
2010
  {
1952
- className: `${styles$4.langItem}${selected ? ` ${styles$4.langItemSelected}` : ""}`,
2011
+ className: `${styles$6.langItem}${selected ? ` ${styles$6.langItemSelected}` : ""}`,
1953
2012
  onSelect: () => updateAttributes({ language: l.value }),
1954
2013
  children: [
1955
- /* @__PURE__ */ jsx("span", { className: styles$4.langItemCheck, children: selected ? /* @__PURE__ */ jsx(CheckIcon, { size: 14 }) : null }),
2014
+ /* @__PURE__ */ jsx("span", { className: styles$6.langItemCheck, children: selected ? /* @__PURE__ */ jsx(CheckIcon, { size: 14 }) : null }),
1956
2015
  optionLabel
1957
2016
  ]
1958
2017
  },
@@ -1966,7 +2025,7 @@ function CodeBlockView({
1966
2025
  "button",
1967
2026
  {
1968
2027
  type: "button",
1969
- className: styles$4.deleteBtn,
2028
+ className: styles$6.deleteBtn,
1970
2029
  title: labels.delete,
1971
2030
  "aria-label": labels.delete,
1972
2031
  onClick: () => deleteNode(),
@@ -1975,17 +2034,17 @@ function CodeBlockView({
1975
2034
  )
1976
2035
  ] }) : (
1977
2036
  // 只读头部:左侧语言标签,右侧复制 + 展开收起(展开后按钮保留,供收回)
1978
- /* @__PURE__ */ jsxs("div", { className: styles$4.readonlyHeader, contentEditable: false, children: [
1979
- /* @__PURE__ */ jsxs("span", { className: styles$4.langBadge, children: [
1980
- /* @__PURE__ */ jsx("span", { className: styles$4.langBraces, children: "{}" }),
2037
+ /* @__PURE__ */ jsxs("div", { className: styles$6.readonlyHeader, contentEditable: false, children: [
2038
+ /* @__PURE__ */ jsxs("span", { className: styles$6.langBadge, children: [
2039
+ /* @__PURE__ */ jsx("span", { className: styles$6.langBraces, children: "{}" }),
1981
2040
  currentLabel
1982
2041
  ] }),
1983
- /* @__PURE__ */ jsxs("span", { className: styles$4.readonlyActions, children: [
2042
+ /* @__PURE__ */ jsxs("span", { className: styles$6.readonlyActions, children: [
1984
2043
  /* @__PURE__ */ jsx(
1985
2044
  "button",
1986
2045
  {
1987
2046
  type: "button",
1988
- className: styles$4.actionBtn,
2047
+ className: styles$6.actionBtn,
1989
2048
  onClick: handleCopy,
1990
2049
  "aria-label": labels.copy,
1991
2050
  title: labels.copy,
@@ -1996,7 +2055,7 @@ function CodeBlockView({
1996
2055
  "button",
1997
2056
  {
1998
2057
  type: "button",
1999
- className: styles$4.actionBtn,
2058
+ className: styles$6.actionBtn,
2000
2059
  onClick: () => setFolded((v) => !v),
2001
2060
  "aria-label": folded2 ? labels.expand : labels.collapse,
2002
2061
  title: folded2 ? labels.expand : labels.collapse,
@@ -2007,14 +2066,14 @@ function CodeBlockView({
2007
2066
  ] })
2008
2067
  ] })
2009
2068
  ),
2010
- /* @__PURE__ */ jsxs("pre", { ref: preRef, className: styles$4.pre, children: [
2069
+ /* @__PURE__ */ jsxs("pre", { ref: preRef, className: styles$6.pre, children: [
2011
2070
  readonly2 ? /* @__PURE__ */ jsx(
2012
2071
  "span",
2013
2072
  {
2014
- className: styles$4.gutter,
2073
+ className: styles$6.gutter,
2015
2074
  contentEditable: false,
2016
2075
  "aria-hidden": "true",
2017
- children: Array.from({ length: lineCount }, (_, i) => /* @__PURE__ */ jsx("span", { className: styles$4.gutterLine, children: i + 1 }, i))
2076
+ children: Array.from({ length: lineCount }, (_, i) => /* @__PURE__ */ jsx("span", { className: styles$6.gutterLine, children: i + 1 }, i))
2018
2077
  }
2019
2078
  ) : null,
2020
2079
  /* @__PURE__ */ jsx(NodeViewContent, { as: "code" })
@@ -2089,6 +2148,13 @@ function findBarOffsetStyle(offset) {
2089
2148
  left: px(offset.left)
2090
2149
  };
2091
2150
  }
2151
+ function editorOwnsKeyboard(editor) {
2152
+ const active2 = document.activeElement;
2153
+ const inEditor = !!active2 && editor.view.dom.contains(active2);
2154
+ if (inEditor || editor.isFocused) return true;
2155
+ const nothingFocused = active2 === null || active2 === document.body;
2156
+ return nothingFocused && document.querySelectorAll(".ProseMirror").length <= 1;
2157
+ }
2092
2158
  const MarkdownWysiwygEditor = forwardRef(function MarkdownWysiwygEditor2({
2093
2159
  initialMarkdown = "",
2094
2160
  editable = true,
@@ -2117,6 +2183,7 @@ const MarkdownWysiwygEditor = forwardRef(function MarkdownWysiwygEditor2({
2117
2183
  findBarOffset = DEFAULT_FIND_BAR_OFFSET,
2118
2184
  findShortcut = true,
2119
2185
  findLabels,
2186
+ onFindOpenChange,
2120
2187
  slashMenu = true,
2121
2188
  slashMenuLabels,
2122
2189
  shortcutPanel = true,
@@ -2135,6 +2202,12 @@ const MarkdownWysiwygEditor = forwardRef(function MarkdownWysiwygEditor2({
2135
2202
  CodeBlock.configure({ lowlight, codeBlockLabels }),
2136
2203
  ImageWithConfirmDelete.configure({ inline: false }),
2137
2204
  ImportPlaceholder,
2205
+ // 空文档占位符:官方 Placeholder 把 data-placeholder 属性与
2206
+ // is-empty / is-editor-empty 类打在**空文本块节点**上——CSS
2207
+ // (styles/content.module.css)正是在节点上 attr(data-placeholder)
2208
+ // 取值。早先只把属性挂在根 div 上,选择器永远匹配不到,占位符从没显示过。
2209
+ // showOnlyWhenEditable 默认 true,只读态自动不显示。
2210
+ ...placeholder ? [Placeholder.configure({ placeholder })] : [],
2138
2211
  createChart({ editable: false }),
2139
2212
  createCitationRef({ renderCitation }),
2140
2213
  CommentMark,
@@ -2171,8 +2244,7 @@ const MarkdownWysiwygEditor = forwardRef(function MarkdownWysiwygEditor2({
2171
2244
  immediatelyRender: false,
2172
2245
  editorProps: {
2173
2246
  attributes: {
2174
- class: styles$8.editorContent,
2175
- "data-placeholder": placeholder ?? ""
2247
+ class: styles$a.editorContent
2176
2248
  }
2177
2249
  }
2178
2250
  });
@@ -2183,10 +2255,40 @@ const MarkdownWysiwygEditor = forwardRef(function MarkdownWysiwygEditor2({
2183
2255
  useEffect(() => {
2184
2256
  editor == null ? void 0 : editor.setEditable(editable);
2185
2257
  }, [editor, editable]);
2258
+ const openFind = useCallback(() => {
2259
+ setFindOpen(true);
2260
+ requestAnimationFrame(() => {
2261
+ var _a;
2262
+ return (_a = findInputRef.current) == null ? void 0 : _a.select();
2263
+ });
2264
+ }, []);
2186
2265
  const closeFind = useCallback(() => {
2187
2266
  setFindOpen(false);
2188
2267
  editor == null ? void 0 : editor.commands.focus();
2189
2268
  }, [editor]);
2269
+ const toggleFind = useCallback(() => {
2270
+ if (findOpen) closeFind();
2271
+ else openFind();
2272
+ }, [findOpen, closeFind, openFind]);
2273
+ const findBarOpen = findOpen && findBar && findReplace;
2274
+ const onFindOpenChangeRef = useRef(onFindOpenChange);
2275
+ onFindOpenChangeRef.current = onFindOpenChange;
2276
+ const notifiedFindOpenRef = useRef(false);
2277
+ useEffect(() => {
2278
+ var _a;
2279
+ if (notifiedFindOpenRef.current === findBarOpen) return;
2280
+ notifiedFindOpenRef.current = findBarOpen;
2281
+ (_a = onFindOpenChangeRef.current) == null ? void 0 : _a.call(onFindOpenChangeRef, findBarOpen);
2282
+ }, [findBarOpen]);
2283
+ const findBarOpenRef = useRef(findBarOpen);
2284
+ findBarOpenRef.current = findBarOpen;
2285
+ useEffect(
2286
+ () => () => {
2287
+ var _a;
2288
+ if (findBarOpenRef.current) (_a = onFindOpenChangeRef.current) == null ? void 0 : _a.call(onFindOpenChangeRef, false);
2289
+ },
2290
+ []
2291
+ );
2190
2292
  useEffect(() => {
2191
2293
  if (!editor || !findReplace || !findBar || !findShortcut) return;
2192
2294
  const onKeyDown = (event) => {
@@ -2194,23 +2296,26 @@ const MarkdownWysiwygEditor = forwardRef(function MarkdownWysiwygEditor2({
2194
2296
  return;
2195
2297
  }
2196
2298
  if (event.key !== "f" && event.key !== "F") return;
2197
- const active2 = document.activeElement;
2198
- const inEditor = !!active2 && editor.view.dom.contains(active2);
2199
- const nothingFocused = active2 === null || active2 === document.body;
2200
- const soleEditor = document.querySelectorAll(".ProseMirror").length <= 1;
2201
- if (!inEditor && !editor.isFocused && !(nothingFocused && soleEditor)) {
2202
- return;
2203
- }
2299
+ if (!editorOwnsKeyboard(editor)) return;
2204
2300
  event.preventDefault();
2205
- setFindOpen(true);
2206
- requestAnimationFrame(() => {
2207
- var _a;
2208
- return (_a = findInputRef.current) == null ? void 0 : _a.select();
2209
- });
2301
+ openFind();
2210
2302
  };
2211
2303
  document.addEventListener("keydown", onKeyDown, true);
2212
2304
  return () => document.removeEventListener("keydown", onKeyDown, true);
2213
- }, [editor, findReplace, findBar, findShortcut]);
2305
+ }, [editor, findReplace, findBar, findShortcut, openFind]);
2306
+ useEffect(() => {
2307
+ if (!editor || !findBarOpen) return;
2308
+ const onKeyDown = (event) => {
2309
+ if (event.key !== "Escape") return;
2310
+ if (isComposingKeyEvent(event)) return;
2311
+ if (!editorOwnsKeyboard(editor)) return;
2312
+ event.preventDefault();
2313
+ event.stopPropagation();
2314
+ closeFind();
2315
+ };
2316
+ document.addEventListener("keydown", onKeyDown);
2317
+ return () => document.removeEventListener("keydown", onKeyDown);
2318
+ }, [editor, findBarOpen, closeFind]);
2214
2319
  const commentsSignatureRef = useRef("");
2215
2320
  useEffect(() => {
2216
2321
  if (!editor || !editable) return;
@@ -2318,10 +2423,11 @@ const MarkdownWysiwygEditor = forwardRef(function MarkdownWysiwygEditor2({
2318
2423
  focusComment: (commentId) => editor ? focusComment(editor, commentId) : false,
2319
2424
  nextComment: (dir) => editor ? nextComment(editor, dir ?? "next") : null,
2320
2425
  getCommentIds: () => editor ? collectCommentIds(editor) : [],
2321
- openFind: () => setFindOpen(true),
2322
- closeFind
2426
+ openFind: () => openFind(),
2427
+ closeFind,
2428
+ toggleFind: () => toggleFind()
2323
2429
  }),
2324
- [editor, closeFind]
2430
+ [editor, closeFind, openFind, toggleFind]
2325
2431
  );
2326
2432
  const findBarTarget = typeof findBarContainer === "function" ? findBarContainer() : findBarContainer ?? null;
2327
2433
  useEffect(() => {
@@ -2337,7 +2443,7 @@ const MarkdownWysiwygEditor = forwardRef(function MarkdownWysiwygEditor2({
2337
2443
  labels: findLabels,
2338
2444
  onClose: closeFind,
2339
2445
  inputRef: findInputRef,
2340
- className: styles$8.findBar,
2446
+ className: styles$a.findBar,
2341
2447
  style: findBarOffsetStyle(findBarOffset)
2342
2448
  }
2343
2449
  ) : null;
@@ -2357,7 +2463,7 @@ const MarkdownWysiwygEditor = forwardRef(function MarkdownWysiwygEditor2({
2357
2463
  "button",
2358
2464
  {
2359
2465
  type: "button",
2360
- className: shortcutFabTarget ? `${styles$8.shortcutFab} ${styles$8.shortcutFabHosted}` : styles$8.shortcutFab,
2466
+ className: shortcutFabTarget ? `${styles$a.shortcutFab} ${styles$a.shortcutFabHosted}` : styles$a.shortcutFab,
2361
2467
  title: shortcutT.panelTitle,
2362
2468
  "aria-label": shortcutT.panelTitle,
2363
2469
  "aria-expanded": shortcutsOpen,
@@ -2365,14 +2471,14 @@ const MarkdownWysiwygEditor = forwardRef(function MarkdownWysiwygEditor2({
2365
2471
  children: /* @__PURE__ */ jsx(KeyboardIcon, { size: 18 })
2366
2472
  }
2367
2473
  ) : null;
2368
- return /* @__PURE__ */ jsxs("div", { className: styles$8.editorHost, children: [
2369
- findBarNode && !findBarTarget ? /* @__PURE__ */ jsx("div", { className: styles$8.findBarAnchor, children: findBarNode }) : null,
2474
+ return /* @__PURE__ */ jsxs("div", { className: styles$a.editorHost, children: [
2475
+ findBarNode && !findBarTarget ? /* @__PURE__ */ jsx("div", { className: styles$a.findBarAnchor, children: findBarNode }) : null,
2370
2476
  findBarNode && findBarTarget ? createPortal(findBarNode, findBarTarget) : null,
2371
2477
  /* @__PURE__ */ jsx(
2372
2478
  EditorContent,
2373
2479
  {
2374
2480
  editor,
2375
- className: className ? `${styles$8.editorScroll} ${className}` : styles$8.editorScroll
2481
+ className: className ? `${styles$a.editorScroll} ${className}` : styles$a.editorScroll
2376
2482
  }
2377
2483
  ),
2378
2484
  shortcutFabNode && shortcutFabTarget ? createPortal(shortcutFabNode, shortcutFabTarget) : shortcutFabNode,
@@ -2425,7 +2531,7 @@ function MarkdownPreview({
2425
2531
  editable: false,
2426
2532
  immediatelyRender: false,
2427
2533
  editorProps: {
2428
- attributes: { class: styles$8.editorContent }
2534
+ attributes: { class: styles$a.editorContent }
2429
2535
  }
2430
2536
  },
2431
2537
  [extensions]
@@ -2438,7 +2544,7 @@ function MarkdownPreview({
2438
2544
  EditorContent,
2439
2545
  {
2440
2546
  editor,
2441
- className: className ?? styles$8.editorScroll
2547
+ className: className ?? styles$a.editorScroll
2442
2548
  }
2443
2549
  );
2444
2550
  }
@@ -2510,147 +2616,56 @@ function splitTopLevelBlocks(markdown) {
2510
2616
  function stripToPlainText(markdown) {
2511
2617
  return markdown.replace(/!\[[^\]]*\]\([^)]+\)/g, "").replace(/\[([^\]]+)\]\([^)]+\)/g, "$1").replace(/^#{1,6}\s+/gm, "").replace(/^[ \t]*[-*+]\s+/gm, "").replace(/^[ \t]*\d+\.\s+/gm, "").replace(/[*_~`]+/g, "").replace(/<[^>]+>/g, "").replace(/\|/g, " ").replace(/\s+/g, " ").trim();
2512
2618
  }
2513
- function getTableSelectionInfo(state) {
2514
- if (!isInTable(state)) return null;
2515
- const rect = selectedRect(state);
2516
- const rowCount = Math.max(1, rect.bottom - rect.top);
2517
- const colCount = Math.max(1, rect.right - rect.left);
2518
- let includesHeaderRow = false;
2519
- for (let row2 = rect.top; row2 < rect.bottom; row2++) {
2520
- if (rowIsHeader(rect.map, rect.table, row2)) {
2521
- includesHeaderRow = true;
2522
- break;
2523
- }
2524
- }
2525
- return {
2526
- rowCount,
2527
- colCount,
2528
- isMultiCell: rowCount > 1 || colCount > 1,
2529
- includesHeaderRow,
2530
- coversAllRows: rect.top === 0 && rect.bottom === rect.map.height,
2531
- coversAllCols: rect.left === 0 && rect.right === rect.map.width
2532
- };
2533
- }
2534
- function isPosInCellSelection(selection, pos) {
2535
- let found = false;
2536
- selection.forEachCell((node, cellPos) => {
2537
- if (pos >= cellPos && pos <= cellPos + node.nodeSize) {
2538
- found = true;
2539
- }
2540
- });
2541
- return found;
2542
- }
2543
- function preserveTableSelectionOnContextMenu(editor, pos) {
2544
- const { selection } = editor.state;
2545
- if (selection instanceof CellSelection && isPosInCellSelection(selection, pos)) {
2546
- editor.view.focus();
2547
- return;
2548
- }
2549
- editor.chain().focus().setTextSelection(pos).run();
2550
- }
2551
- function addRowsBefore(editor, count) {
2552
- const n = Math.max(1, count);
2553
- for (let i = 0; i < n; i++) {
2554
- if (!editor.commands.addRowBefore()) return false;
2555
- }
2556
- return true;
2557
- }
2558
- function addRowsAfter(editor, count) {
2559
- const n = Math.max(1, count);
2560
- for (let i = 0; i < n; i++) {
2561
- if (!editor.commands.addRowAfter()) return false;
2562
- }
2563
- return true;
2564
- }
2565
- function addColumnsBefore(editor, count) {
2566
- const n = Math.max(1, count);
2567
- for (let i = 0; i < n; i++) {
2568
- if (!editor.commands.addColumnBefore()) return false;
2569
- }
2570
- return true;
2571
- }
2572
- function addColumnsAfter(editor, count) {
2573
- const n = Math.max(1, count);
2574
- for (let i = 0; i < n; i++) {
2575
- if (!editor.commands.addColumnAfter()) return false;
2576
- }
2577
- return true;
2578
- }
2579
- function deleteSelectedRows(editor) {
2580
- const info = getTableSelectionInfo(editor.state);
2581
- if (!info) return false;
2582
- if (info.coversAllRows) return editor.commands.deleteTable();
2583
- return editor.commands.deleteRow();
2584
- }
2585
- function deleteSelectedColumns(editor) {
2586
- const info = getTableSelectionInfo(editor.state);
2587
- if (!info) return false;
2588
- if (info.coversAllCols) {
2589
- if (info.coversAllRows) return editor.commands.deleteTable();
2590
- return false;
2591
- }
2592
- return editor.commands.deleteColumn();
2593
- }
2594
- const toolbar = "_toolbar_1f7fb_2";
2595
- const inner = "_inner_1f7fb_15";
2596
- const btn = "_btn_1f7fb_27";
2597
- const btnActive = "_btnActive_1f7fb_50";
2598
- const tableBubble = "_tableBubble_1f7fb_66";
2599
- const tableMenuItem = "_tableMenuItem_1f7fb_77";
2600
- const tableMenuItemIcon = "_tableMenuItemIcon_1f7fb_103";
2601
- const tableMenuItemLabel = "_tableMenuItemLabel_1f7fb_113";
2602
- const tableMenuDivider = "_tableMenuDivider_1f7fb_118";
2603
- const txtIcon = "_txtIcon_1f7fb_126";
2604
- const colorIcon = "_colorIcon_1f7fb_134";
2605
- const colorIconGlyph = "_colorIconGlyph_1f7fb_142";
2606
- const colorIconBar = "_colorIconBar_1f7fb_148";
2607
- const scriptTrigger = "_scriptTrigger_1f7fb_155";
2608
- const scriptTriggerGlyph = "_scriptTriggerGlyph_1f7fb_175";
2609
- const divider = "_divider_1f7fb_183";
2610
- const styleTrigger = "_styleTrigger_1f7fb_192";
2611
- const styleTriggerLabel = "_styleTriggerLabel_1f7fb_221";
2612
- const styleTriggerCaret = "_styleTriggerCaret_1f7fb_229";
2613
- const styleItem = "_styleItem_1f7fb_235";
2614
- const styleIcon = "_styleIcon_1f7fb_241";
2615
- const scriptGlyph = "_scriptGlyph_1f7fb_251";
2616
- const menu = "_menu_1f7fb_263";
2617
- const menuItem = "_menuItem_1f7fb_274";
2618
- const menuItemSelected = "_menuItemSelected_1f7fb_301";
2619
- const tableInsertCaret = "_tableInsertCaret_1f7fb_314";
2620
- const tableSizePicker = "_tableSizePicker_1f7fb_322";
2621
- const tableSizeGrid = "_tableSizeGrid_1f7fb_332";
2622
- const tableSizeCell = "_tableSizeCell_1f7fb_337";
2623
- const tableSizeCellActive = "_tableSizeCellActive_1f7fb_347";
2624
- const tableSizeLabel = "_tableSizeLabel_1f7fb_352";
2625
- const popoverContent$1 = "_popoverContent_1f7fb_361";
2626
- const mathLayer = "_mathLayer_1f7fb_365";
2627
- const mathStack = "_mathStack_1f7fb_370";
2628
- const mathStackBlock = "_mathStackBlock_1f7fb_377";
2629
- const mathHint = "_mathHint_1f7fb_382";
2630
- const mathHintBlock = "_mathHintBlock_1f7fb_394";
2631
- const mathHintIcon = "_mathHintIcon_1f7fb_400";
2632
- const mathField = "_mathField_1f7fb_431";
2633
- const mathFieldBlock = "_mathFieldBlock_1f7fb_443";
2634
- const mathInput = "_mathInput_1f7fb_450";
2635
- const mathDone = "_mathDone_1f7fb_468";
2636
- const mathDoneKbd = "_mathDoneKbd_1f7fb_493";
2637
- const styles$3 = {
2619
+ const toolbar = "_toolbar_6osph_2";
2620
+ const inner = "_inner_6osph_15";
2621
+ const btn$1 = "_btn_6osph_33";
2622
+ const btnActive = "_btnActive_6osph_56";
2623
+ const txtIcon = "_txtIcon_6osph_72";
2624
+ const colorIcon = "_colorIcon_6osph_80";
2625
+ const colorIconGlyph = "_colorIconGlyph_6osph_88";
2626
+ const colorIconBar = "_colorIconBar_6osph_94";
2627
+ const scriptTrigger = "_scriptTrigger_6osph_101";
2628
+ const scriptTriggerGlyph = "_scriptTriggerGlyph_6osph_121";
2629
+ const divider$1 = "_divider_6osph_129";
2630
+ const styleTrigger = "_styleTrigger_6osph_138";
2631
+ const styleTriggerLabel = "_styleTriggerLabel_6osph_167";
2632
+ const styleTriggerCaret = "_styleTriggerCaret_6osph_175";
2633
+ const styleItem = "_styleItem_6osph_181";
2634
+ const styleIcon = "_styleIcon_6osph_187";
2635
+ const scriptGlyph = "_scriptGlyph_6osph_197";
2636
+ const menu = "_menu_6osph_209";
2637
+ const menuItem = "_menuItem_6osph_220";
2638
+ const menuItemSelected = "_menuItemSelected_6osph_247";
2639
+ const tableInsertCaret = "_tableInsertCaret_6osph_260";
2640
+ const tableSizePicker = "_tableSizePicker_6osph_268";
2641
+ const tableSizeGrid = "_tableSizeGrid_6osph_278";
2642
+ const tableSizeCell = "_tableSizeCell_6osph_283";
2643
+ const tableSizeCellActive = "_tableSizeCellActive_6osph_293";
2644
+ const tableSizeLabel = "_tableSizeLabel_6osph_298";
2645
+ const popoverContent$1 = "_popoverContent_6osph_307";
2646
+ const mathLayer = "_mathLayer_6osph_311";
2647
+ const mathStack = "_mathStack_6osph_316";
2648
+ const mathStackBlock = "_mathStackBlock_6osph_323";
2649
+ const mathHint = "_mathHint_6osph_328";
2650
+ const mathHintBlock = "_mathHintBlock_6osph_340";
2651
+ const mathHintIcon = "_mathHintIcon_6osph_346";
2652
+ const mathField = "_mathField_6osph_377";
2653
+ const mathFieldBlock = "_mathFieldBlock_6osph_389";
2654
+ const mathInput = "_mathInput_6osph_396";
2655
+ const mathDone = "_mathDone_6osph_414";
2656
+ const mathDoneKbd = "_mathDoneKbd_6osph_439";
2657
+ const styles$5 = {
2638
2658
  toolbar,
2639
2659
  inner,
2640
- btn,
2660
+ btn: btn$1,
2641
2661
  btnActive,
2642
- tableBubble,
2643
- tableMenuItem,
2644
- tableMenuItemIcon,
2645
- tableMenuItemLabel,
2646
- tableMenuDivider,
2647
2662
  txtIcon,
2648
2663
  colorIcon,
2649
2664
  colorIconGlyph,
2650
2665
  colorIconBar,
2651
2666
  scriptTrigger,
2652
2667
  scriptTriggerGlyph,
2653
- divider,
2668
+ divider: divider$1,
2654
2669
  styleTrigger,
2655
2670
  styleTriggerLabel,
2656
2671
  styleTriggerCaret,
@@ -2688,7 +2703,7 @@ const swatch = "_swatch_x5lrq_54";
2688
2703
  const swatchActive = "_swatchActive_x5lrq_70";
2689
2704
  const themeLabel = "_themeLabel_x5lrq_76";
2690
2705
  const themeRow = "_themeRow_x5lrq_84";
2691
- const styles$2 = {
2706
+ const styles$4 = {
2692
2707
  palette,
2693
2708
  noneRow,
2694
2709
  noneIcon,
@@ -2711,25 +2726,25 @@ const THEME_COLORS = ["#ff6719", "#ff5500"];
2711
2726
  function ColorPalette({ value, onPick, labels }) {
2712
2727
  const t = { ...defaultColorPaletteLabels, ...labels };
2713
2728
  const current = value == null ? void 0 : value.toLowerCase();
2714
- return /* @__PURE__ */ jsxs("div", { className: styles$2.palette, children: [
2729
+ return /* @__PURE__ */ jsxs("div", { className: styles$4.palette, children: [
2715
2730
  /* @__PURE__ */ jsxs(
2716
2731
  "button",
2717
2732
  {
2718
2733
  type: "button",
2719
- className: styles$2.noneRow,
2734
+ className: styles$4.noneRow,
2720
2735
  onMouseDown: (e2) => e2.preventDefault(),
2721
2736
  onClick: () => onPick(null),
2722
2737
  children: [
2723
- /* @__PURE__ */ jsx("span", { className: styles$2.noneIcon, "aria-hidden": true }),
2724
- /* @__PURE__ */ jsx("span", { className: styles$2.noneLabel, children: t.none })
2738
+ /* @__PURE__ */ jsx("span", { className: styles$4.noneIcon, "aria-hidden": true }),
2739
+ /* @__PURE__ */ jsx("span", { className: styles$4.noneLabel, children: t.none })
2725
2740
  ]
2726
2741
  }
2727
2742
  ),
2728
- /* @__PURE__ */ jsx("div", { className: styles$2.grid, children: PALETTE.flat().map((c) => /* @__PURE__ */ jsx(
2743
+ /* @__PURE__ */ jsx("div", { className: styles$4.grid, children: PALETTE.flat().map((c) => /* @__PURE__ */ jsx(
2729
2744
  "button",
2730
2745
  {
2731
2746
  type: "button",
2732
- className: `${styles$2.swatch} ${current === c.toLowerCase() ? styles$2.swatchActive : ""}`,
2747
+ className: `${styles$4.swatch} ${current === c.toLowerCase() ? styles$4.swatchActive : ""}`,
2733
2748
  style: { background: c },
2734
2749
  title: c,
2735
2750
  "aria-label": c,
@@ -2738,12 +2753,12 @@ function ColorPalette({ value, onPick, labels }) {
2738
2753
  },
2739
2754
  c
2740
2755
  )) }),
2741
- /* @__PURE__ */ jsx("div", { className: styles$2.themeLabel, children: t.theme }),
2742
- /* @__PURE__ */ jsx("div", { className: styles$2.themeRow, children: THEME_COLORS.map((c) => /* @__PURE__ */ jsx(
2756
+ /* @__PURE__ */ jsx("div", { className: styles$4.themeLabel, children: t.theme }),
2757
+ /* @__PURE__ */ jsx("div", { className: styles$4.themeRow, children: THEME_COLORS.map((c) => /* @__PURE__ */ jsx(
2743
2758
  "button",
2744
2759
  {
2745
2760
  type: "button",
2746
- className: `${styles$2.swatch} ${current === c.toLowerCase() ? styles$2.swatchActive : ""}`,
2761
+ className: `${styles$4.swatch} ${current === c.toLowerCase() ? styles$4.swatchActive : ""}`,
2747
2762
  style: { background: c },
2748
2763
  title: c,
2749
2764
  "aria-label": c,
@@ -2754,116 +2769,948 @@ function ColorPalette({ value, onPick, labels }) {
2754
2769
  )) })
2755
2770
  ] });
2756
2771
  }
2757
- function resolveNodeEl(editor, pos) {
2758
- const dom = editor.view.nodeDOM(pos);
2759
- if (dom instanceof HTMLElement) return dom;
2760
- if (dom instanceof Node) return dom.parentElement;
2761
- return null;
2772
+ const OPENABLE_PROTOCOLS = /* @__PURE__ */ new Set([
2773
+ "http:",
2774
+ "https:",
2775
+ "ftp:",
2776
+ "ftps:",
2777
+ "mailto:",
2778
+ "tel:",
2779
+ "callto:",
2780
+ "sms:",
2781
+ "cid:",
2782
+ "xmpp:"
2783
+ ]);
2784
+ const HAS_SCHEME_RE = /^[a-z][a-z0-9+.-]*:/i;
2785
+ const SITE_RELATIVE_RE = /^[/#?]/;
2786
+ const HOST_PORT_RE = /^(localhost|127\.0\.0\.1|0\.0\.0\.0|\[[0-9a-f:]+\]):\d+($|[/#?])/i;
2787
+ const BARE_HOST_RE = /^[^/?#]*\.[^/?#]*/;
2788
+ function canSetLink(editor) {
2789
+ if (!editor || editor.isEditable === false) return false;
2790
+ try {
2791
+ return editor.can().setMark("link");
2792
+ } catch {
2793
+ return false;
2794
+ }
2762
2795
  }
2763
- function mathRenderTarget(el, isBlock) {
2764
- if (!isBlock) return el;
2765
- return el.querySelector(".block-math-inner") ?? el;
2796
+ function isLinkActive(editor) {
2797
+ if (!editor) return false;
2798
+ return editor.isActive("link");
2766
2799
  }
2767
- function getMathLayerStyle(editor, kind, pos) {
2768
- const host = editor.view.dom.parentElement;
2769
- if (!host) return {};
2770
- const hostRect = host.getBoundingClientRect();
2771
- const editorRect = editor.view.dom.getBoundingClientRect();
2772
- const gap = 6;
2773
- const blockWidth = editor.view.dom.clientWidth;
2774
- if (pos != null) {
2775
- const el = resolveNodeEl(editor, pos);
2776
- if (el) {
2777
- const r2 = el.getBoundingClientRect();
2778
- const top = r2.bottom - hostRect.top + gap;
2779
- if (kind === "block") {
2780
- return {
2781
- left: editorRect.left - hostRect.left,
2782
- top,
2783
- width: blockWidth
2784
- };
2785
- }
2786
- return {
2787
- left: r2.left - hostRect.left,
2788
- top
2789
- };
2790
- }
2791
- }
2792
- const coords = editor.view.coordsAtPos(editor.state.selection.from);
2793
- if (kind === "block") {
2794
- return {
2795
- left: editorRect.left - hostRect.left,
2796
- top: coords.bottom - hostRect.top + gap,
2797
- width: blockWidth
2798
- };
2800
+ function readLinkHref(editor) {
2801
+ if (!editor) return "";
2802
+ const { href } = editor.getAttributes("link");
2803
+ return typeof href === "string" ? href : "";
2804
+ }
2805
+ function defaultProtocol(editor) {
2806
+ var _a, _b;
2807
+ const link = (_a = editor.extensionManager) == null ? void 0 : _a.extensions.find(
2808
+ (extension) => extension.name === "link"
2809
+ );
2810
+ const configured = (_b = link == null ? void 0 : link.options) == null ? void 0 : _b.defaultProtocol;
2811
+ return configured || "http";
2812
+ }
2813
+ function normalizeLinkHref(editor, raw) {
2814
+ const value = raw.trim();
2815
+ if (!value) return "";
2816
+ if (SITE_RELATIVE_RE.test(value)) return value;
2817
+ if (HOST_PORT_RE.test(value)) return `${defaultProtocol(editor)}://${value}`;
2818
+ if (HAS_SCHEME_RE.test(value)) return value;
2819
+ if (!BARE_HOST_RE.test(value)) return value;
2820
+ return `${defaultProtocol(editor)}://${value}`;
2821
+ }
2822
+ function applyLink(editor, raw) {
2823
+ if (!editor) return false;
2824
+ const href = normalizeLinkHref(editor, raw);
2825
+ if (!href) return false;
2826
+ if (!editor.can().setLink({ href })) return false;
2827
+ const isEmpty = editor.state.selection.empty;
2828
+ const insideLink = isLinkActive(editor);
2829
+ const chain = editor.chain().focus().extendMarkRange("link").setLink({ href });
2830
+ if (isEmpty && !insideLink) chain.insertContent({ type: "text", text: href });
2831
+ return chain.run();
2832
+ }
2833
+ function removeLink(editor) {
2834
+ if (!editor) return false;
2835
+ return editor.chain().focus().extendMarkRange("link").unsetLink().setMeta("preventAutolink", true).run();
2836
+ }
2837
+ function sanitizeLinkUrl(input2, baseUrl) {
2838
+ try {
2839
+ const url = new URL(input2, baseUrl);
2840
+ if (OPENABLE_PROTOCOLS.has(url.protocol)) return url.href;
2841
+ } catch {
2799
2842
  }
2800
- return {
2801
- left: coords.left - hostRect.left,
2802
- top: coords.bottom - hostRect.top + gap
2803
- };
2843
+ return "#";
2804
2844
  }
2805
- function MathEditorPopover({
2845
+ function openLinkUrl(input2, baseUrl) {
2846
+ if (!input2.trim()) return false;
2847
+ const safe = sanitizeLinkUrl(input2, baseUrl);
2848
+ if (safe === "#") return false;
2849
+ window.open(safe, "_blank", "noopener,noreferrer");
2850
+ return true;
2851
+ }
2852
+ function isApplyKey(event) {
2853
+ if (event.key !== "Enter") return false;
2854
+ return !isComposingKeyEvent(event.nativeEvent);
2855
+ }
2856
+ const panel = "_panel_qysb1_7";
2857
+ const field = "_field_qysb1_28";
2858
+ const fieldInvalid = "_fieldInvalid_qysb1_47";
2859
+ const input = "_input_qysb1_52";
2860
+ const divider = "_divider_qysb1_63";
2861
+ const btn = "_btn_qysb1_71";
2862
+ const apply = "_apply_qysb1_99";
2863
+ const styles$3 = {
2864
+ panel,
2865
+ field,
2866
+ fieldInvalid,
2867
+ input,
2868
+ divider,
2869
+ btn,
2870
+ apply
2871
+ };
2872
+ function LinkPopover({
2806
2873
  editor,
2807
- kind,
2808
- mode,
2809
- pos,
2810
- latex,
2811
- isNew = false,
2812
- newLabel,
2813
- placeholder,
2814
- doneLabel,
2815
- onConfirm,
2816
- onCancel
2874
+ trigger,
2875
+ labels,
2876
+ className,
2877
+ style
2817
2878
  }) {
2818
- const [draft, setDraft] = useState(latex);
2819
- const [layerStyle, setLayerStyle] = useState(
2820
- () => getMathLayerStyle(editor, kind, pos)
2821
- );
2822
- const titleId = useId();
2823
- const inputRef = useRef(null);
2824
- const rootRef = useRef(null);
2825
- const isBlock = kind === "block";
2826
- const host = editor.view.dom.parentElement;
2827
- useEffect(() => {
2828
- setDraft(latex);
2829
- }, [latex]);
2830
- useEffect(() => {
2831
- const update = () => setLayerStyle(getMathLayerStyle(editor, kind, pos));
2832
- update();
2833
- window.addEventListener("resize", update);
2834
- return () => window.removeEventListener("resize", update);
2835
- }, [editor, kind, pos, draft]);
2836
- useEffect(() => {
2837
- var _a;
2838
- (_a = inputRef.current) == null ? void 0 : _a.focus();
2839
- }, []);
2840
- useEffect(() => {
2841
- if (pos == null) return;
2842
- const el = resolveNodeEl(editor, pos);
2843
- if (!el) return;
2844
- el.classList.add("tmr-math-editing");
2845
- return () => {
2846
- el.classList.remove("tmr-math-editing");
2847
- };
2848
- }, [editor, pos]);
2849
- useEffect(() => {
2850
- if (pos == null) return;
2851
- const el = resolveNodeEl(editor, pos);
2852
- if (!el) return;
2853
- const target = mathRenderTarget(el, isBlock);
2854
- const src = draft.trim();
2855
- if (src) renderMathInto(target, src, isBlock);
2856
- else target.textContent = "";
2857
- }, [draft, pos, editor, isBlock]);
2858
- useEffect(() => {
2859
- if (pos == null || isNew) return;
2860
- const el = resolveNodeEl(editor, pos);
2861
- if (!el) return;
2862
- const target = mathRenderTarget(el, isBlock);
2863
- return () => {
2864
- const restore = latex.trim();
2865
- if (restore) renderMathInto(target, restore, isBlock);
2866
- else target.textContent = "";
2879
+ const [open, setOpen] = useState(false);
2880
+ return /* @__PURE__ */ jsxs(Popover.Root, { open, onOpenChange: setOpen, children: [
2881
+ /* @__PURE__ */ jsx(Popover.Trigger, { asChild: true, children: trigger }),
2882
+ /* @__PURE__ */ jsx(Popover.Portal, { children: /* @__PURE__ */ jsx(
2883
+ Popover.Content,
2884
+ {
2885
+ sideOffset: 4,
2886
+ align: "start",
2887
+ onCloseAutoFocus: (e2) => e2.preventDefault(),
2888
+ children: /* @__PURE__ */ jsx(
2889
+ LinkPanel,
2890
+ {
2891
+ editor,
2892
+ labels,
2893
+ className,
2894
+ style,
2895
+ onClose: () => setOpen(false)
2896
+ }
2897
+ )
2898
+ }
2899
+ ) })
2900
+ ] });
2901
+ }
2902
+ function LinkPanel({
2903
+ editor,
2904
+ labels,
2905
+ className,
2906
+ style,
2907
+ onClose
2908
+ }) {
2909
+ const t = { ...defaultLinkPopoverLabels, ...labels };
2910
+ const [url, setUrl] = useState(() => readLinkHref(editor));
2911
+ const [invalid, setInvalid] = useState(false);
2912
+ const canEdit = canSetLink(editor);
2913
+ const hasUrl = url.trim().length > 0;
2914
+ const keepFocus = (e2) => e2.preventDefault();
2915
+ const apply2 = () => {
2916
+ if (!applyLink(editor, url)) {
2917
+ setInvalid(true);
2918
+ return;
2919
+ }
2920
+ setInvalid(false);
2921
+ onClose();
2922
+ };
2923
+ const openInNewWindow = () => {
2924
+ openLinkUrl(normalizeLinkHref(editor, url), window.location.href);
2925
+ };
2926
+ const remove = () => {
2927
+ removeLink(editor);
2928
+ onClose();
2929
+ };
2930
+ const onInputKeyDown = (e2) => {
2931
+ if (!isApplyKey(e2)) return;
2932
+ e2.preventDefault();
2933
+ apply2();
2934
+ };
2935
+ return /* @__PURE__ */ jsxs(
2936
+ "div",
2937
+ {
2938
+ className: className ? `${styles$3.panel} ${className}` : styles$3.panel,
2939
+ style,
2940
+ "data-link-popover": "",
2941
+ role: "dialog",
2942
+ "aria-label": t.field,
2943
+ children: [
2944
+ /* @__PURE__ */ jsx("span", { className: `${styles$3.field}${invalid ? ` ${styles$3.fieldInvalid}` : ""}`, children: /* @__PURE__ */ jsx(
2945
+ "input",
2946
+ {
2947
+ className: styles$3.input,
2948
+ "data-link-field": "",
2949
+ "data-link-invalid": invalid ? "" : void 0,
2950
+ type: "url",
2951
+ value: url,
2952
+ onChange: (e2) => {
2953
+ setUrl(e2.target.value);
2954
+ setInvalid(false);
2955
+ },
2956
+ onKeyDown: onInputKeyDown,
2957
+ placeholder: t.field,
2958
+ "aria-label": t.field,
2959
+ "aria-invalid": invalid || void 0,
2960
+ title: invalid ? t.invalid : void 0,
2961
+ autoFocus: true,
2962
+ autoComplete: "off",
2963
+ autoCorrect: "off",
2964
+ autoCapitalize: "off",
2965
+ spellCheck: false
2966
+ }
2967
+ ) }),
2968
+ /* @__PURE__ */ jsx(
2969
+ "button",
2970
+ {
2971
+ type: "button",
2972
+ className: `${styles$3.btn} ${styles$3.apply}`,
2973
+ "data-link-action": "apply",
2974
+ title: t.apply,
2975
+ "aria-label": t.apply,
2976
+ disabled: !canEdit || !hasUrl,
2977
+ onMouseDown: keepFocus,
2978
+ onClick: apply2,
2979
+ children: /* @__PURE__ */ jsx(CheckIcon, { size: 16 })
2980
+ }
2981
+ ),
2982
+ /* @__PURE__ */ jsx("span", { className: styles$3.divider, "aria-hidden": "true" }),
2983
+ /* @__PURE__ */ jsx(
2984
+ "button",
2985
+ {
2986
+ type: "button",
2987
+ className: styles$3.btn,
2988
+ "data-link-action": "open",
2989
+ title: t.open,
2990
+ "aria-label": t.open,
2991
+ disabled: !hasUrl,
2992
+ onMouseDown: keepFocus,
2993
+ onClick: openInNewWindow,
2994
+ children: /* @__PURE__ */ jsx(ExternalLinkIcon, { size: 16 })
2995
+ }
2996
+ ),
2997
+ /* @__PURE__ */ jsx(
2998
+ "button",
2999
+ {
3000
+ type: "button",
3001
+ className: styles$3.btn,
3002
+ "data-link-action": "remove",
3003
+ title: t.remove,
3004
+ "aria-label": t.remove,
3005
+ disabled: !canEdit,
3006
+ onMouseDown: keepFocus,
3007
+ onClick: remove,
3008
+ children: /* @__PURE__ */ jsx(TrashIcon, { size: 16 })
3009
+ }
3010
+ )
3011
+ ]
3012
+ }
3013
+ );
3014
+ }
3015
+ function getTableSelectionInfo(state) {
3016
+ if (!isInTable(state)) return null;
3017
+ const rect = selectedRect(state);
3018
+ const rowCount = Math.max(1, rect.bottom - rect.top);
3019
+ const colCount = Math.max(1, rect.right - rect.left);
3020
+ let includesHeaderRow = false;
3021
+ for (let row2 = rect.top; row2 < rect.bottom; row2++) {
3022
+ if (rowIsHeader(rect.map, rect.table, row2)) {
3023
+ includesHeaderRow = true;
3024
+ break;
3025
+ }
3026
+ }
3027
+ return {
3028
+ rowCount,
3029
+ colCount,
3030
+ isMultiCell: rowCount > 1 || colCount > 1,
3031
+ includesHeaderRow,
3032
+ coversAllRows: rect.top === 0 && rect.bottom === rect.map.height,
3033
+ coversAllCols: rect.left === 0 && rect.right === rect.map.width
3034
+ };
3035
+ }
3036
+ function isPosInCellSelection(selection, pos) {
3037
+ let found = false;
3038
+ selection.forEachCell((node, cellPos) => {
3039
+ if (pos >= cellPos && pos <= cellPos + node.nodeSize) {
3040
+ found = true;
3041
+ }
3042
+ });
3043
+ return found;
3044
+ }
3045
+ function addRowsBefore(editor, count) {
3046
+ const n = Math.max(1, count);
3047
+ for (let i = 0; i < n; i++) {
3048
+ if (!editor.commands.addRowBefore()) return false;
3049
+ }
3050
+ return true;
3051
+ }
3052
+ function addRowsAfter(editor, count) {
3053
+ const n = Math.max(1, count);
3054
+ for (let i = 0; i < n; i++) {
3055
+ if (!editor.commands.addRowAfter()) return false;
3056
+ }
3057
+ return true;
3058
+ }
3059
+ function addColumnsBefore(editor, count) {
3060
+ const n = Math.max(1, count);
3061
+ for (let i = 0; i < n; i++) {
3062
+ if (!editor.commands.addColumnBefore()) return false;
3063
+ }
3064
+ return true;
3065
+ }
3066
+ function addColumnsAfter(editor, count) {
3067
+ const n = Math.max(1, count);
3068
+ for (let i = 0; i < n; i++) {
3069
+ if (!editor.commands.addColumnAfter()) return false;
3070
+ }
3071
+ return true;
3072
+ }
3073
+ function deleteSelectedRows(editor) {
3074
+ const info = getTableSelectionInfo(editor.state);
3075
+ if (!info) return false;
3076
+ if (info.coversAllRows) return editor.commands.deleteTable();
3077
+ return editor.commands.deleteRow();
3078
+ }
3079
+ function deleteSelectedColumns(editor) {
3080
+ const info = getTableSelectionInfo(editor.state);
3081
+ if (!info) return false;
3082
+ if (info.coversAllCols) {
3083
+ if (info.coversAllRows) return editor.commands.deleteTable();
3084
+ return false;
3085
+ }
3086
+ return editor.commands.deleteColumn();
3087
+ }
3088
+ const STRUCTURAL_CELL_ATTRS = /* @__PURE__ */ new Set(["colspan", "rowspan"]);
3089
+ function selectedCellEntries(editor) {
3090
+ const { selection } = editor.state;
3091
+ const entries = [];
3092
+ if (selection instanceof CellSelection) {
3093
+ selection.forEachCell((node2, pos2) => {
3094
+ entries.push({ pos: pos2, node: node2 });
3095
+ });
3096
+ return entries;
3097
+ }
3098
+ const $cell = cellAround(selection.$from);
3099
+ if (!$cell) return entries;
3100
+ const pos = $cell.before($cell.depth);
3101
+ const node = editor.state.doc.nodeAt(pos);
3102
+ if (node) entries.push({ pos, node });
3103
+ return entries;
3104
+ }
3105
+ function clearSelectedCellContents(editor) {
3106
+ var _a;
3107
+ const entries = selectedCellEntries(editor);
3108
+ if (!entries.length) return false;
3109
+ const paragraph = editor.state.schema.nodes.paragraph;
3110
+ if (!paragraph) return false;
3111
+ const tr = editor.state.tr;
3112
+ for (const { pos, node } of [...entries].sort((a3, b3) => b3.pos - a3.pos)) {
3113
+ const isEmpty = node.childCount === 1 && !!((_a = node.firstChild) == null ? void 0 : _a.isTextblock) && node.firstChild.content.size === 0;
3114
+ if (isEmpty) continue;
3115
+ tr.replaceWith(pos + 1, pos + node.nodeSize - 1, paragraph.createAndFill());
3116
+ }
3117
+ if (!tr.docChanged) return false;
3118
+ editor.view.dispatch(tr.scrollIntoView());
3119
+ return true;
3120
+ }
3121
+ function resetSelectedCellStyles(editor) {
3122
+ const entries = selectedCellEntries(editor);
3123
+ if (!entries.length) return false;
3124
+ const tr = editor.state.tr;
3125
+ for (const { pos, node } of entries) {
3126
+ const attrs = node.type.spec.attrs ?? {};
3127
+ const next = { ...node.attrs };
3128
+ let changed = false;
3129
+ for (const [key, spec] of Object.entries(attrs)) {
3130
+ if (STRUCTURAL_CELL_ATTRS.has(key)) continue;
3131
+ const fallback = (spec == null ? void 0 : spec.default) ?? null;
3132
+ if (next[key] !== fallback) {
3133
+ next[key] = fallback;
3134
+ changed = true;
3135
+ }
3136
+ }
3137
+ if (changed) tr.setNodeMarkup(pos, void 0, next);
3138
+ }
3139
+ if (!tr.docChanged) return false;
3140
+ editor.view.dispatch(tr);
3141
+ return true;
3142
+ }
3143
+ function findTable(editor) {
3144
+ const $from = editor.state.selection.$from;
3145
+ for (let d = $from.depth; d > 0; d -= 1) {
3146
+ if ($from.node(d).type.name === "table") {
3147
+ return { pos: $from.before(d), node: $from.node(d) };
3148
+ }
3149
+ }
3150
+ let found = null;
3151
+ editor.state.doc.descendants((node, pos) => {
3152
+ if (found !== null) return false;
3153
+ if (node.type.name === "table") {
3154
+ found = { pos, node };
3155
+ return false;
3156
+ }
3157
+ return true;
3158
+ });
3159
+ return found;
3160
+ }
3161
+ function selectLineAt(editor, table, kind, index) {
3162
+ const map = TableMap.get(table.node);
3163
+ const start = table.pos + 1;
3164
+ const anchorCell = start + map.positionAt(kind === "row" ? index : 0, kind === "col" ? index : 0, table.node);
3165
+ const headCell = start + map.positionAt(
3166
+ kind === "row" ? index : map.height - 1,
3167
+ kind === "col" ? index : map.width - 1,
3168
+ table.node
3169
+ );
3170
+ editor.view.dispatch(
3171
+ editor.state.tr.setSelection(
3172
+ new CellSelection(
3173
+ editor.state.doc.resolve(anchorCell),
3174
+ editor.state.doc.resolve(headCell)
3175
+ )
3176
+ )
3177
+ );
3178
+ }
3179
+ function appendRowToTable(editor) {
3180
+ const table = findTable(editor);
3181
+ if (!table) return false;
3182
+ selectLineAt(editor, table, "row", TableMap.get(table.node).height - 1);
3183
+ return addRowsAfter(editor, 1);
3184
+ }
3185
+ function appendColumnToTable(editor) {
3186
+ const table = findTable(editor);
3187
+ if (!table) return false;
3188
+ selectLineAt(editor, table, "col", TableMap.get(table.node).width - 1);
3189
+ return addColumnsAfter(editor, 1);
3190
+ }
3191
+ const handle = "_handle_cco3n_9";
3192
+ const handleRow = "_handleRow_cco3n_30";
3193
+ const handleCol = "_handleCol_cco3n_40";
3194
+ const extend = "_extend_cco3n_70";
3195
+ const tableBubble = "_tableBubble_cco3n_115";
3196
+ const tableMenuItem = "_tableMenuItem_cco3n_128";
3197
+ const tableMenuItemIcon = "_tableMenuItemIcon_cco3n_154";
3198
+ const tableMenuItemLabel = "_tableMenuItemLabel_cco3n_164";
3199
+ const tableMenuDivider = "_tableMenuDivider_cco3n_169";
3200
+ const styles$2 = {
3201
+ handle,
3202
+ handleRow,
3203
+ handleCol,
3204
+ extend,
3205
+ tableBubble,
3206
+ tableMenuItem,
3207
+ tableMenuItemIcon,
3208
+ tableMenuItemLabel,
3209
+ tableMenuDivider
3210
+ };
3211
+ function edgeFlags(editor, cell) {
3212
+ try {
3213
+ const $cell = cellAround(editor.state.doc.resolve(editor.view.posAtDOM(cell, 0)));
3214
+ if (!$cell) return { onLastRow: false, onLastCol: false };
3215
+ const map = TableMap.get($cell.node(-1));
3216
+ const rect = map.findCell($cell.pos - $cell.start(-1));
3217
+ return {
3218
+ onLastRow: rect.bottom === map.height,
3219
+ onLastCol: rect.right === map.width
3220
+ };
3221
+ } catch {
3222
+ return { onLastRow: false, onLastCol: false };
3223
+ }
3224
+ }
3225
+ const COL_HANDLE_GAP = 22;
3226
+ const ROW_HANDLE_GAP = 26;
3227
+ const EXTEND_GAP = 6;
3228
+ const EXTEND_THICKNESS = 16;
3229
+ const HOVER_KEEP_MS = 160;
3230
+ function measureCell(editor, cell) {
3231
+ const table = cell.closest("table");
3232
+ const row2 = cell.closest("tr");
3233
+ if (!table || !row2) return null;
3234
+ try {
3235
+ editor.view.posAtDOM(cell, 0);
3236
+ } catch {
3237
+ return null;
3238
+ }
3239
+ const cellRect = cell.getBoundingClientRect();
3240
+ const rowRect = row2.getBoundingClientRect();
3241
+ const tableRect = table.getBoundingClientRect();
3242
+ const edges = edgeFlags(editor, cell);
3243
+ return {
3244
+ cell,
3245
+ ...edges,
3246
+ rowTop: rowRect.top,
3247
+ rowHeight: rowRect.height,
3248
+ colLeft: cellRect.left,
3249
+ colWidth: cellRect.width,
3250
+ tableLeft: tableRect.left,
3251
+ tableTop: tableRect.top,
3252
+ tableRight: tableRect.right,
3253
+ tableBottom: tableRect.bottom
3254
+ };
3255
+ }
3256
+ function selectRowOrColumn(editor, cell, kind) {
3257
+ let pos;
3258
+ try {
3259
+ pos = editor.view.posAtDOM(cell, 0);
3260
+ } catch {
3261
+ return false;
3262
+ }
3263
+ const $cell = cellAround(editor.state.doc.resolve(pos));
3264
+ if (!$cell) return false;
3265
+ const selection = kind === "row" ? CellSelection.rowSelection($cell) : CellSelection.colSelection($cell);
3266
+ editor.view.dispatch(editor.state.tr.setSelection(selection));
3267
+ return true;
3268
+ }
3269
+ function menuItemsFor(editor, labels, kind) {
3270
+ const info = getTableSelectionInfo(editor.state);
3271
+ const rowN = (info == null ? void 0 : info.rowCount) ?? 1;
3272
+ const colN = (info == null ? void 0 : info.colCount) ?? 1;
3273
+ const multi = kind === "multi";
3274
+ const items = [];
3275
+ if (kind === "col" || kind === "multi") {
3276
+ items.push(
3277
+ {
3278
+ key: "col-before",
3279
+ group: "col",
3280
+ label: multi ? labels.tableAddColumnBeforeN(colN) : labels.tableAddColumnBefore,
3281
+ icon: /* @__PURE__ */ jsx(ColumnBeforeIcon, {}),
3282
+ run: () => addColumnsBefore(editor, colN)
3283
+ },
3284
+ {
3285
+ key: "col-after",
3286
+ group: "col",
3287
+ label: multi ? labels.tableAddColumnAfterN(colN) : labels.tableAddColumnAfter,
3288
+ icon: /* @__PURE__ */ jsx(ColumnAfterIcon, {}),
3289
+ run: () => addColumnsAfter(editor, colN)
3290
+ },
3291
+ {
3292
+ key: "col-delete",
3293
+ group: "col",
3294
+ label: multi ? labels.tableDeleteColumnN(colN) : labels.tableDeleteColumn,
3295
+ icon: /* @__PURE__ */ jsx(ColumnDeleteIcon, {}),
3296
+ // 只选了全部列、却没选全部行:删列会把表格删没,禁掉
3297
+ disabled: !!(info == null ? void 0 : info.coversAllCols) && !(info == null ? void 0 : info.coversAllRows),
3298
+ run: () => deleteSelectedColumns(editor)
3299
+ }
3300
+ );
3301
+ }
3302
+ if (kind === "row" || kind === "multi") {
3303
+ items.push(
3304
+ {
3305
+ key: "row-before",
3306
+ group: "row",
3307
+ label: multi ? labels.tableAddRowBeforeN(rowN) : labels.tableAddRowBefore,
3308
+ icon: /* @__PURE__ */ jsx(RowBeforeIcon, {}),
3309
+ // 上方是表头行时插行没意义
3310
+ disabled: !!(info == null ? void 0 : info.includesHeaderRow),
3311
+ run: () => addRowsBefore(editor, rowN)
3312
+ },
3313
+ {
3314
+ key: "row-after",
3315
+ group: "row",
3316
+ label: multi ? labels.tableAddRowAfterN(rowN) : labels.tableAddRowAfter,
3317
+ icon: /* @__PURE__ */ jsx(RowAfterIcon, {}),
3318
+ run: () => addRowsAfter(editor, rowN)
3319
+ },
3320
+ {
3321
+ key: "row-delete",
3322
+ group: "row",
3323
+ label: multi ? labels.tableDeleteRowN(rowN) : labels.tableDeleteRow,
3324
+ icon: /* @__PURE__ */ jsx(RowDeleteIcon, {}),
3325
+ disabled: !!(info == null ? void 0 : info.includesHeaderRow),
3326
+ run: () => deleteSelectedRows(editor)
3327
+ }
3328
+ );
3329
+ }
3330
+ items.push(
3331
+ {
3332
+ key: "cells-clear",
3333
+ group: "cells",
3334
+ label: labels.tableClearContent,
3335
+ icon: /* @__PURE__ */ jsx(EraserIcon, {}),
3336
+ run: () => clearSelectedCellContents(editor)
3337
+ },
3338
+ {
3339
+ key: "cells-reset",
3340
+ group: "cells",
3341
+ label: labels.tableResetCellStyles,
3342
+ icon: /* @__PURE__ */ jsx(RotateCcwIcon, {}),
3343
+ run: () => resetSelectedCellStyles(editor)
3344
+ }
3345
+ );
3346
+ return items;
3347
+ }
3348
+ function TableHandles({ editor, labels }) {
3349
+ const [hover, setHover] = useState(null);
3350
+ const [menu2, setMenu] = useState(null);
3351
+ const hoverRef = useRef(null);
3352
+ const menuRef = useRef(null);
3353
+ menuRef.current = menu2;
3354
+ const clearHover = useCallback(() => {
3355
+ if (!hoverRef.current) return;
3356
+ hoverRef.current = null;
3357
+ setHover(null);
3358
+ }, []);
3359
+ const closeMenu = useCallback(() => setMenu(null), []);
3360
+ const remeasureHover = useCallback(() => {
3361
+ var _a;
3362
+ const cell = (_a = hoverRef.current) == null ? void 0 : _a.cell;
3363
+ if (!cell) return;
3364
+ const next = cell.isConnected ? measureCell(editor, cell) : null;
3365
+ hoverRef.current = next;
3366
+ setHover(next);
3367
+ }, [editor]);
3368
+ const clearTimerRef = useRef(null);
3369
+ const cancelPendingClear = useCallback(() => {
3370
+ if (clearTimerRef.current === null) return;
3371
+ clearTimeout(clearTimerRef.current);
3372
+ clearTimerRef.current = null;
3373
+ }, []);
3374
+ useEffect(() => {
3375
+ const onMove = (event) => {
3376
+ var _a, _b;
3377
+ if (!editor.isEditable || menuRef.current) return;
3378
+ const target = event.target;
3379
+ if ((_a = target == null ? void 0 : target.closest) == null ? void 0 : _a.call(target, "[data-table-handle], [data-table-extend]")) {
3380
+ cancelPendingClear();
3381
+ return;
3382
+ }
3383
+ const cell = target && editor.view.dom.contains(target) ? target.closest("td, th") : null;
3384
+ if (!cell) {
3385
+ if (hoverRef.current && clearTimerRef.current === null) {
3386
+ clearTimerRef.current = setTimeout(() => {
3387
+ clearTimerRef.current = null;
3388
+ clearHover();
3389
+ }, HOVER_KEEP_MS);
3390
+ }
3391
+ return;
3392
+ }
3393
+ cancelPendingClear();
3394
+ if (((_b = hoverRef.current) == null ? void 0 : _b.cell) === cell) return;
3395
+ const next = measureCell(editor, cell);
3396
+ hoverRef.current = next;
3397
+ setHover(next);
3398
+ };
3399
+ const onBlurWindow = () => {
3400
+ cancelPendingClear();
3401
+ clearHover();
3402
+ };
3403
+ document.addEventListener("mousemove", onMove);
3404
+ document.addEventListener("mouseleave", onBlurWindow);
3405
+ window.addEventListener("scroll", remeasureHover, true);
3406
+ window.addEventListener("resize", remeasureHover);
3407
+ return () => {
3408
+ cancelPendingClear();
3409
+ document.removeEventListener("mousemove", onMove);
3410
+ document.removeEventListener("mouseleave", onBlurWindow);
3411
+ window.removeEventListener("scroll", remeasureHover, true);
3412
+ window.removeEventListener("resize", remeasureHover);
3413
+ };
3414
+ }, [editor, clearHover, cancelPendingClear, remeasureHover]);
3415
+ useEffect(() => {
3416
+ const dom = editor.view.dom;
3417
+ const onContextMenu = (event) => {
3418
+ const info = getTableSelectionInfo(editor.state);
3419
+ const { selection } = editor.state;
3420
+ if (!(info == null ? void 0 : info.isMultiCell) || !(selection instanceof CellSelection)) return;
3421
+ const coords = editor.view.posAtCoords({
3422
+ left: event.clientX,
3423
+ top: event.clientY
3424
+ });
3425
+ if (!coords || !isPosInCellSelection(selection, coords.pos)) return;
3426
+ event.preventDefault();
3427
+ hoverRef.current = null;
3428
+ setHover(null);
3429
+ setMenu({ kind: "multi", x: event.clientX, y: event.clientY });
3430
+ };
3431
+ dom.addEventListener("contextmenu", onContextMenu);
3432
+ return () => dom.removeEventListener("contextmenu", onContextMenu);
3433
+ }, [editor]);
3434
+ useEffect(() => {
3435
+ if (!menu2) return;
3436
+ const onKey = (event) => {
3437
+ if (event.key === "Escape") closeMenu();
3438
+ };
3439
+ const onDown = (event) => {
3440
+ var _a;
3441
+ const target = event.target;
3442
+ if ((_a = target == null ? void 0 : target.closest) == null ? void 0 : _a.call(target, "[data-table-menu]")) return;
3443
+ closeMenu();
3444
+ };
3445
+ document.addEventListener("keydown", onKey, true);
3446
+ document.addEventListener("mousedown", onDown);
3447
+ return () => {
3448
+ document.removeEventListener("keydown", onKey, true);
3449
+ document.removeEventListener("mousedown", onDown);
3450
+ };
3451
+ }, [menu2, closeMenu]);
3452
+ if (typeof document === "undefined") return null;
3453
+ const openHandleMenu = (kind) => {
3454
+ if (!hover) return;
3455
+ if (!selectRowOrColumn(editor, hover.cell, kind)) return;
3456
+ setHover(null);
3457
+ hoverRef.current = null;
3458
+ setMenu(
3459
+ kind === "row" ? { kind, x: hover.tableLeft + 6, y: hover.rowTop } : { kind, x: hover.colLeft, y: hover.tableTop + 6 }
3460
+ );
3461
+ };
3462
+ const items = menu2 ? menuItemsFor(editor, labels, menu2.kind) : [];
3463
+ const showHandles = !!hover && !menu2 && editor.isEditable;
3464
+ return createPortal(
3465
+ /* @__PURE__ */ jsxs(Fragment$2, { children: [
3466
+ showHandles && hover ? /* @__PURE__ */ jsxs(Fragment$2, { children: [
3467
+ /* @__PURE__ */ jsx(
3468
+ "button",
3469
+ {
3470
+ type: "button",
3471
+ "data-table-handle": "row",
3472
+ className: `${styles$2.handle} ${styles$2.handleRow}`,
3473
+ style: {
3474
+ left: hover.tableLeft - ROW_HANDLE_GAP,
3475
+ // 长度跟着行高走(原来固定 28px 居中,行高时就显得太短)
3476
+ top: hover.rowTop,
3477
+ height: hover.rowHeight
3478
+ },
3479
+ title: labels.tableRowMenu,
3480
+ "aria-label": labels.tableRowMenu,
3481
+ onMouseDown: (e2) => e2.preventDefault(),
3482
+ onClick: () => openHandleMenu("row"),
3483
+ children: /* @__PURE__ */ jsx("span", { "aria-hidden": true, children: "⋮" })
3484
+ }
3485
+ ),
3486
+ /* @__PURE__ */ jsx(
3487
+ "button",
3488
+ {
3489
+ type: "button",
3490
+ "data-table-handle": "col",
3491
+ className: `${styles$2.handle} ${styles$2.handleCol}`,
3492
+ style: {
3493
+ // 长度跟着列宽走,两端与单元格对齐
3494
+ left: hover.colLeft,
3495
+ top: hover.tableTop - COL_HANDLE_GAP,
3496
+ width: hover.colWidth
3497
+ },
3498
+ title: labels.tableColumnMenu,
3499
+ "aria-label": labels.tableColumnMenu,
3500
+ onMouseDown: (e2) => e2.preventDefault(),
3501
+ onClick: () => openHandleMenu("col"),
3502
+ children: /* @__PURE__ */ jsx("span", { "aria-hidden": true, children: "⋯" })
3503
+ }
3504
+ ),
3505
+ hover.onLastCol ? /* @__PURE__ */ jsx(
3506
+ "button",
3507
+ {
3508
+ type: "button",
3509
+ "data-table-extend": "col",
3510
+ className: styles$2.extend,
3511
+ style: {
3512
+ left: hover.tableRight + EXTEND_GAP,
3513
+ top: hover.tableTop,
3514
+ width: EXTEND_THICKNESS,
3515
+ height: Math.max(EXTEND_THICKNESS, hover.tableBottom - hover.tableTop)
3516
+ },
3517
+ title: labels.tableAppendColumn,
3518
+ "aria-label": labels.tableAppendColumn,
3519
+ onMouseDown: (e2) => e2.preventDefault(),
3520
+ onClick: () => {
3521
+ appendColumnToTable(editor);
3522
+ remeasureHover();
3523
+ },
3524
+ children: /* @__PURE__ */ jsx("span", { "aria-hidden": true, children: "+" })
3525
+ }
3526
+ ) : null,
3527
+ hover.onLastRow ? /* @__PURE__ */ jsx(
3528
+ "button",
3529
+ {
3530
+ type: "button",
3531
+ "data-table-extend": "row",
3532
+ className: styles$2.extend,
3533
+ style: {
3534
+ left: hover.tableLeft,
3535
+ top: hover.tableBottom + EXTEND_GAP,
3536
+ width: Math.max(EXTEND_THICKNESS, hover.tableRight - hover.tableLeft),
3537
+ height: EXTEND_THICKNESS
3538
+ },
3539
+ title: labels.tableAppendRow,
3540
+ "aria-label": labels.tableAppendRow,
3541
+ onMouseDown: (e2) => e2.preventDefault(),
3542
+ onClick: () => {
3543
+ appendRowToTable(editor);
3544
+ remeasureHover();
3545
+ },
3546
+ children: /* @__PURE__ */ jsx("span", { "aria-hidden": true, children: "+" })
3547
+ }
3548
+ ) : null
3549
+ ] }) : null,
3550
+ menu2 ? /* @__PURE__ */ jsxs(
3551
+ "div",
3552
+ {
3553
+ className: styles$2.tableBubble,
3554
+ "data-table-menu": "",
3555
+ style: { left: menu2.x, top: menu2.y },
3556
+ role: "menu",
3557
+ onMouseDown: (e2) => e2.stopPropagation(),
3558
+ onContextMenu: (e2) => e2.preventDefault(),
3559
+ children: [
3560
+ items.map((item2, index) => /* @__PURE__ */ jsxs(Fragment$1, { children: [
3561
+ index > 0 && item2.group !== items[index - 1].group ? /* @__PURE__ */ jsx("span", { className: styles$2.tableMenuDivider, "aria-hidden": true }) : null,
3562
+ /* @__PURE__ */ jsxs(
3563
+ "button",
3564
+ {
3565
+ type: "button",
3566
+ role: "menuitem",
3567
+ className: styles$2.tableMenuItem,
3568
+ disabled: item2.disabled,
3569
+ onClick: () => {
3570
+ item2.run();
3571
+ closeMenu();
3572
+ },
3573
+ children: [
3574
+ /* @__PURE__ */ jsx("span", { className: styles$2.tableMenuItemIcon, "aria-hidden": true, children: item2.icon }),
3575
+ /* @__PURE__ */ jsx("span", { className: styles$2.tableMenuItemLabel, children: item2.label })
3576
+ ]
3577
+ }
3578
+ )
3579
+ ] }, item2.key)),
3580
+ /* @__PURE__ */ jsx("span", { className: styles$2.tableMenuDivider, "aria-hidden": true }),
3581
+ /* @__PURE__ */ jsxs(
3582
+ "button",
3583
+ {
3584
+ type: "button",
3585
+ role: "menuitem",
3586
+ className: styles$2.tableMenuItem,
3587
+ onClick: () => {
3588
+ editor.commands.deleteTable();
3589
+ closeMenu();
3590
+ },
3591
+ children: [
3592
+ /* @__PURE__ */ jsx("span", { className: styles$2.tableMenuItemIcon, "aria-hidden": true, children: /* @__PURE__ */ jsx(TableDeleteIcon, {}) }),
3593
+ /* @__PURE__ */ jsx("span", { className: styles$2.tableMenuItemLabel, children: labels.tableDeleteTable })
3594
+ ]
3595
+ }
3596
+ )
3597
+ ]
3598
+ }
3599
+ ) : null
3600
+ ] }),
3601
+ document.body
3602
+ );
3603
+ }
3604
+ function resolveNodeEl(editor, pos) {
3605
+ const dom = editor.view.nodeDOM(pos);
3606
+ if (dom instanceof HTMLElement) return dom;
3607
+ if (dom instanceof Node) return dom.parentElement;
3608
+ return null;
3609
+ }
3610
+ function mathRenderTarget(el, isBlock) {
3611
+ if (!isBlock) return el;
3612
+ return el.querySelector(".block-math-inner") ?? el;
3613
+ }
3614
+ function getMathLayerStyle(editor, kind, pos) {
3615
+ const host = editor.view.dom.parentElement;
3616
+ if (!host) return {};
3617
+ const hostRect = host.getBoundingClientRect();
3618
+ const editorRect = editor.view.dom.getBoundingClientRect();
3619
+ const gap = 6;
3620
+ const blockWidth = editor.view.dom.clientWidth;
3621
+ if (pos != null) {
3622
+ const el = resolveNodeEl(editor, pos);
3623
+ if (el) {
3624
+ const r2 = el.getBoundingClientRect();
3625
+ const top = r2.bottom - hostRect.top + gap;
3626
+ if (kind === "block") {
3627
+ return {
3628
+ left: editorRect.left - hostRect.left,
3629
+ top,
3630
+ width: blockWidth
3631
+ };
3632
+ }
3633
+ return {
3634
+ left: r2.left - hostRect.left,
3635
+ top
3636
+ };
3637
+ }
3638
+ }
3639
+ const coords = editor.view.coordsAtPos(editor.state.selection.from);
3640
+ if (kind === "block") {
3641
+ return {
3642
+ left: editorRect.left - hostRect.left,
3643
+ top: coords.bottom - hostRect.top + gap,
3644
+ width: blockWidth
3645
+ };
3646
+ }
3647
+ return {
3648
+ left: coords.left - hostRect.left,
3649
+ top: coords.bottom - hostRect.top + gap
3650
+ };
3651
+ }
3652
+ function MathEditorPopover({
3653
+ editor,
3654
+ kind,
3655
+ mode,
3656
+ pos,
3657
+ latex,
3658
+ isNew = false,
3659
+ newLabel,
3660
+ placeholder,
3661
+ doneLabel,
3662
+ onConfirm,
3663
+ onCancel
3664
+ }) {
3665
+ const [draft, setDraft] = useState(latex);
3666
+ const [layerStyle, setLayerStyle] = useState(
3667
+ () => getMathLayerStyle(editor, kind, pos)
3668
+ );
3669
+ const titleId = useId();
3670
+ const inputRef = useRef(null);
3671
+ const rootRef = useRef(null);
3672
+ const isBlock = kind === "block";
3673
+ const host = editor.view.dom.parentElement;
3674
+ useEffect(() => {
3675
+ setDraft(latex);
3676
+ }, [latex]);
3677
+ useEffect(() => {
3678
+ const update = () => setLayerStyle(getMathLayerStyle(editor, kind, pos));
3679
+ update();
3680
+ window.addEventListener("resize", update);
3681
+ return () => window.removeEventListener("resize", update);
3682
+ }, [editor, kind, pos, draft]);
3683
+ useEffect(() => {
3684
+ var _a;
3685
+ (_a = inputRef.current) == null ? void 0 : _a.focus();
3686
+ }, []);
3687
+ useEffect(() => {
3688
+ if (pos == null) return;
3689
+ const el = resolveNodeEl(editor, pos);
3690
+ if (!el) return;
3691
+ el.classList.add("tmr-math-editing");
3692
+ return () => {
3693
+ el.classList.remove("tmr-math-editing");
3694
+ };
3695
+ }, [editor, pos]);
3696
+ useEffect(() => {
3697
+ if (pos == null) return;
3698
+ const el = resolveNodeEl(editor, pos);
3699
+ if (!el) return;
3700
+ const target = mathRenderTarget(el, isBlock);
3701
+ const src = draft.trim();
3702
+ if (src) renderMathInto(target, src, isBlock);
3703
+ else target.textContent = "";
3704
+ }, [draft, pos, editor, isBlock]);
3705
+ useEffect(() => {
3706
+ if (pos == null || isNew) return;
3707
+ const el = resolveNodeEl(editor, pos);
3708
+ if (!el) return;
3709
+ const target = mathRenderTarget(el, isBlock);
3710
+ return () => {
3711
+ const restore = latex.trim();
3712
+ if (restore) renderMathInto(target, restore, isBlock);
3713
+ else target.textContent = "";
2867
3714
  };
2868
3715
  }, [pos, editor, isBlock, latex, isNew]);
2869
3716
  useEffect(() => {
@@ -2902,7 +3749,7 @@ function MathEditorPopover({
2902
3749
  "textarea",
2903
3750
  {
2904
3751
  ref: inputRef,
2905
- className: styles$3.mathInput,
3752
+ className: styles$5.mathInput,
2906
3753
  value: draft,
2907
3754
  placeholder,
2908
3755
  rows: Math.max(3, draft.split("\n").length),
@@ -2914,7 +3761,7 @@ function MathEditorPopover({
2914
3761
  "input",
2915
3762
  {
2916
3763
  ref: inputRef,
2917
- className: styles$3.mathInput,
3764
+ className: styles$5.mathInput,
2918
3765
  value: draft,
2919
3766
  placeholder,
2920
3767
  "aria-labelledby": titleId,
@@ -2928,7 +3775,7 @@ function MathEditorPopover({
2928
3775
  "div",
2929
3776
  {
2930
3777
  ref: rootRef,
2931
- className: styles$3.mathLayer,
3778
+ className: styles$5.mathLayer,
2932
3779
  style: layerStyle,
2933
3780
  role: "dialog",
2934
3781
  "aria-modal": "false",
@@ -2936,15 +3783,15 @@ function MathEditorPopover({
2936
3783
  children: /* @__PURE__ */ jsxs(
2937
3784
  "div",
2938
3785
  {
2939
- className: isBlock ? `${styles$3.mathStack} ${styles$3.mathStackBlock}` : styles$3.mathStack,
3786
+ className: isBlock ? `${styles$5.mathStack} ${styles$5.mathStackBlock}` : styles$5.mathStack,
2940
3787
  children: [
2941
3788
  showHint ? /* @__PURE__ */ jsxs(
2942
3789
  "div",
2943
3790
  {
2944
3791
  id: titleId,
2945
- className: isBlock ? `${styles$3.mathHint} ${styles$3.mathHintBlock}` : styles$3.mathHint,
3792
+ className: isBlock ? `${styles$5.mathHint} ${styles$5.mathHintBlock}` : styles$5.mathHint,
2946
3793
  children: [
2947
- /* @__PURE__ */ jsx("span", { className: styles$3.mathHintIcon, "aria-hidden": true, children: isBlock ? "TeX" : "√x" }),
3794
+ /* @__PURE__ */ jsx("span", { className: styles$5.mathHintIcon, "aria-hidden": true, children: isBlock ? "TeX" : "√x" }),
2948
3795
  newLabel
2949
3796
  ]
2950
3797
  }
@@ -2953,20 +3800,20 @@ function MathEditorPopover({
2953
3800
  "div",
2954
3801
  {
2955
3802
  id: showHint ? void 0 : titleId,
2956
- className: isBlock ? `${styles$3.mathField} ${styles$3.mathFieldBlock}` : styles$3.mathField,
3803
+ className: isBlock ? `${styles$5.mathField} ${styles$5.mathFieldBlock}` : styles$5.mathField,
2957
3804
  children: [
2958
3805
  field2,
2959
3806
  /* @__PURE__ */ jsxs(
2960
3807
  "button",
2961
3808
  {
2962
3809
  type: "button",
2963
- className: styles$3.mathDone,
3810
+ className: styles$5.mathDone,
2964
3811
  disabled: !canSubmit,
2965
3812
  title: isBlock ? `${doneLabel} (⌘/Ctrl+Enter)` : `${doneLabel} (Enter)`,
2966
3813
  onClick: submit,
2967
3814
  children: [
2968
3815
  doneLabel,
2969
- /* @__PURE__ */ jsx("span", { className: styles$3.mathDoneKbd, "aria-hidden": true, children: "↵" })
3816
+ /* @__PURE__ */ jsx("span", { className: styles$5.mathDoneKbd, "aria-hidden": true, children: "↵" })
2970
3817
  ]
2971
3818
  }
2972
3819
  )
@@ -2981,56 +3828,27 @@ function MathEditorPopover({
2981
3828
  host
2982
3829
  );
2983
3830
  }
2984
- function ToolbarButton({
2985
- title,
2986
- active: active2,
2987
- disabled,
2988
- busy,
2989
- onClick,
2990
- children
2991
- }) {
3831
+ const ToolbarButton = forwardRef(function ToolbarButton2({ title, active: active2, disabled, busy, onClick, children, className, ...rest }, ref) {
2992
3832
  return /* @__PURE__ */ jsx(
2993
3833
  "button",
2994
3834
  {
3835
+ ...rest,
3836
+ ref,
2995
3837
  type: "button",
2996
3838
  title,
2997
3839
  "aria-label": title,
2998
3840
  "aria-pressed": active2,
2999
3841
  "aria-busy": busy,
3000
3842
  disabled,
3001
- className: `${styles$3.btn} ${active2 ? styles$3.btnActive : ""}`,
3843
+ className: `${styles$5.btn} ${active2 ? styles$5.btnActive : ""}${className ? ` ${className}` : ""}`,
3002
3844
  onMouseDown: (e2) => e2.preventDefault(),
3003
3845
  onClick,
3004
3846
  children
3005
3847
  }
3006
3848
  );
3007
- }
3849
+ });
3008
3850
  function Divider() {
3009
- return /* @__PURE__ */ jsx("span", { className: styles$3.divider, "aria-hidden": true });
3010
- }
3011
- function TableMenuItem({
3012
- label,
3013
- disabled,
3014
- onClick,
3015
- children
3016
- }) {
3017
- return /* @__PURE__ */ jsxs(
3018
- "button",
3019
- {
3020
- type: "button",
3021
- disabled,
3022
- className: styles$3.tableMenuItem,
3023
- onMouseDown: (e2) => e2.preventDefault(),
3024
- onClick,
3025
- children: [
3026
- /* @__PURE__ */ jsx("span", { className: styles$3.tableMenuItemIcon, "aria-hidden": true, children }),
3027
- /* @__PURE__ */ jsx("span", { className: styles$3.tableMenuItemLabel, children: label })
3028
- ]
3029
- }
3030
- );
3031
- }
3032
- function TableMenuDivider() {
3033
- return /* @__PURE__ */ jsx("div", { className: styles$3.tableMenuDivider, "aria-hidden": true });
3851
+ return /* @__PURE__ */ jsx("span", { className: styles$5.divider, "aria-hidden": true });
3034
3852
  }
3035
3853
  const MenuCloseCtx = createContext(() => {
3036
3854
  });
@@ -3045,7 +3863,7 @@ function MenuPopover({
3045
3863
  /* @__PURE__ */ jsx(Popover.Portal, { children: /* @__PURE__ */ jsx(
3046
3864
  Popover.Content,
3047
3865
  {
3048
- className: styles$3.menu,
3866
+ className: styles$5.menu,
3049
3867
  sideOffset: 4,
3050
3868
  align: "start",
3051
3869
  onOpenAutoFocus: (e2) => e2.preventDefault(),
@@ -3067,7 +3885,7 @@ function MenuItem({
3067
3885
  {
3068
3886
  type: "button",
3069
3887
  disabled,
3070
- className: `${styles$3.menuItem} ${selected ? styles$3.menuItemSelected : ""}`,
3888
+ className: `${styles$5.menuItem} ${selected ? styles$5.menuItemSelected : ""}`,
3071
3889
  onMouseDown: (e2) => e2.preventDefault(),
3072
3890
  onClick: () => {
3073
3891
  onSelect();
@@ -3102,21 +3920,21 @@ function TableInsertItem({
3102
3920
  {
3103
3921
  type: "button",
3104
3922
  disabled,
3105
- className: `${styles$3.menuItem} ${open ? styles$3.menuItemSelected : ""}`,
3923
+ className: `${styles$5.menuItem} ${open ? styles$5.menuItemSelected : ""}`,
3106
3924
  onMouseDown: (e2) => e2.preventDefault(),
3107
3925
  children: [
3108
- /* @__PURE__ */ jsxs("span", { className: styles$3.styleItem, children: [
3109
- /* @__PURE__ */ jsx("span", { className: styles$3.styleIcon, children: "⊞" }),
3926
+ /* @__PURE__ */ jsxs("span", { className: styles$5.styleItem, children: [
3927
+ /* @__PURE__ */ jsx("span", { className: styles$5.styleIcon, children: "⊞" }),
3110
3928
  labels.tableInsert
3111
3929
  ] }),
3112
- /* @__PURE__ */ jsx(ChevronDownIcon, { size: 12, className: styles$3.tableInsertCaret })
3930
+ /* @__PURE__ */ jsx(ChevronDownIcon, { size: 12, className: styles$5.tableInsertCaret })
3113
3931
  ]
3114
3932
  }
3115
3933
  ) }),
3116
3934
  /* @__PURE__ */ jsx(Popover.Portal, { children: /* @__PURE__ */ jsxs(
3117
3935
  Popover.Content,
3118
3936
  {
3119
- className: styles$3.tableSizePicker,
3937
+ className: styles$5.tableSizePicker,
3120
3938
  side: "right",
3121
3939
  align: "start",
3122
3940
  sideOffset: 6,
@@ -3126,7 +3944,7 @@ function TableInsertItem({
3126
3944
  /* @__PURE__ */ jsx(
3127
3945
  "div",
3128
3946
  {
3129
- className: styles$3.tableSizeGrid,
3947
+ className: styles$5.tableSizeGrid,
3130
3948
  style: {
3131
3949
  gridTemplateColumns: `repeat(${TABLE_PICKER_COLS}, 1fr)`
3132
3950
  },
@@ -3140,7 +3958,7 @@ function TableInsertItem({
3140
3958
  {
3141
3959
  type: "button",
3142
3960
  "aria-label": labels.tableSizeSelected(col, row2),
3143
- className: `${styles$3.tableSizeCell} ${active2 ? styles$3.tableSizeCellActive : ""}`,
3961
+ className: `${styles$5.tableSizeCell} ${active2 ? styles$5.tableSizeCellActive : ""}`,
3144
3962
  onMouseDown: (e2) => e2.preventDefault(),
3145
3963
  onMouseEnter: () => setHover({ cols: col, rows: row2 }),
3146
3964
  onClick: () => {
@@ -3155,7 +3973,7 @@ function TableInsertItem({
3155
3973
  })
3156
3974
  }
3157
3975
  ),
3158
- /* @__PURE__ */ jsx("div", { className: styles$3.tableSizeLabel, children: hover.cols > 0 ? labels.tableSizeSelected(hover.cols, hover.rows) : labels.tableInsert })
3976
+ /* @__PURE__ */ jsx("div", { className: styles$5.tableSizeLabel, children: hover.cols > 0 ? labels.tableSizeSelected(hover.cols, hover.rows) : labels.tableInsert })
3159
3977
  ]
3160
3978
  }
3161
3979
  ) })
@@ -3177,20 +3995,20 @@ function ColorPopover({
3177
3995
  "button",
3178
3996
  {
3179
3997
  type: "button",
3180
- className: styles$3.btn,
3998
+ className: styles$5.btn,
3181
3999
  title,
3182
4000
  "aria-label": title,
3183
4001
  onMouseDown: (e2) => e2.preventDefault(),
3184
- children: /* @__PURE__ */ jsxs("span", { className: styles$3.colorIcon, children: [
3185
- /* @__PURE__ */ jsx("span", { className: styles$3.colorIconGlyph, children: glyph }),
3186
- /* @__PURE__ */ jsx("span", { className: styles$3.colorIconBar, style: { background: bar2 } })
4002
+ children: /* @__PURE__ */ jsxs("span", { className: styles$5.colorIcon, children: [
4003
+ /* @__PURE__ */ jsx("span", { className: styles$5.colorIconGlyph, children: glyph }),
4004
+ /* @__PURE__ */ jsx("span", { className: styles$5.colorIconBar, style: { background: bar2 } })
3187
4005
  ] })
3188
4006
  }
3189
4007
  ) }),
3190
4008
  /* @__PURE__ */ jsx(Popover.Portal, { children: /* @__PURE__ */ jsx(
3191
4009
  Popover.Content,
3192
4010
  {
3193
- className: styles$3.popoverContent,
4011
+ className: styles$5.popoverContent,
3194
4012
  sideOffset: 4,
3195
4013
  align: "start",
3196
4014
  onOpenAutoFocus: (e2) => e2.preventDefault(),
@@ -3221,6 +4039,8 @@ function EditorToolbar({
3221
4039
  importMenuItems,
3222
4040
  showImport = true,
3223
4041
  labels,
4042
+ onSearch,
4043
+ searchActive = false,
3224
4044
  extraToolbarItems,
3225
4045
  className
3226
4046
  }) {
@@ -3265,60 +4085,6 @@ function EditorToolbar({
3265
4085
  }, [editor]);
3266
4086
  const fileInputRef = useRef(null);
3267
4087
  const chain = () => editor.chain().focus();
3268
- const [tableMenu, setTableMenu] = useState(
3269
- null
3270
- );
3271
- const closeTableMenu = useCallback(() => setTableMenu(null), []);
3272
- useEffect(() => {
3273
- const dom = editor.view.dom;
3274
- const onContextMenu = (e2) => {
3275
- const coords = editor.view.posAtCoords({
3276
- left: e2.clientX,
3277
- top: e2.clientY
3278
- });
3279
- if (!coords) return;
3280
- const $pos = editor.state.doc.resolve(coords.pos);
3281
- let inTable = false;
3282
- for (let d = $pos.depth; d > 0; d--) {
3283
- if ($pos.node(d).type.name === "table") {
3284
- inTable = true;
3285
- break;
3286
- }
3287
- }
3288
- if (!inTable) return;
3289
- e2.preventDefault();
3290
- preserveTableSelectionOnContextMenu(editor, coords.pos);
3291
- setTableMenu({ x: e2.clientX, y: e2.clientY });
3292
- };
3293
- dom.addEventListener("contextmenu", onContextMenu);
3294
- return () => dom.removeEventListener("contextmenu", onContextMenu);
3295
- }, [editor]);
3296
- useEffect(() => {
3297
- if (!tableMenu) return;
3298
- const onKey = (e2) => {
3299
- if (e2.key === "Escape") closeTableMenu();
3300
- };
3301
- document.addEventListener("mousedown", closeTableMenu);
3302
- document.addEventListener("keydown", onKey, true);
3303
- return () => {
3304
- document.removeEventListener("mousedown", closeTableMenu);
3305
- document.removeEventListener("keydown", onKey, true);
3306
- };
3307
- }, [tableMenu, closeTableMenu]);
3308
- const runTable = useCallback(
3309
- (fn) => {
3310
- fn();
3311
- closeTableMenu();
3312
- },
3313
- [closeTableMenu]
3314
- );
3315
- const tableSel = tableMenu ? getTableSelectionInfo(editor.state) : null;
3316
- const tableRowN = (tableSel == null ? void 0 : tableSel.rowCount) ?? 1;
3317
- const tableColN = (tableSel == null ? void 0 : tableSel.colCount) ?? 1;
3318
- const tableMulti = (tableSel == null ? void 0 : tableSel.isMultiCell) ?? false;
3319
- const disableAddRowBefore = !!(tableSel == null ? void 0 : tableSel.includesHeaderRow);
3320
- const disableDeleteRow = !!(tableSel == null ? void 0 : tableSel.includesHeaderRow);
3321
- const disableDeleteColumn = !!(tableSel == null ? void 0 : tableSel.coversAllCols) && !(tableSel == null ? void 0 : tableSel.coversAllRows);
3322
4088
  const handlePickImage = () => {
3323
4089
  var _a;
3324
4090
  return (_a = fileInputRef.current) == null ? void 0 : _a.click();
@@ -3415,14 +4181,6 @@ function EditorToolbar({
3415
4181
  if (color) chain().setHighlight({ color }).run();
3416
4182
  else chain().unsetHighlight().run();
3417
4183
  };
3418
- const toggleLink = () => {
3419
- if (state.link) {
3420
- chain().unsetLink().run();
3421
- return;
3422
- }
3423
- const url = window.prompt(t.linkPrompt);
3424
- if (url) chain().setLink({ href: url }).run();
3425
- };
3426
4184
  const setBlockStyle = (level) => {
3427
4185
  if (level === 0) chain().setParagraph().run();
3428
4186
  else
@@ -3506,8 +4264,8 @@ function EditorToolbar({
3506
4264
  /* @__PURE__ */ jsx(
3507
4265
  "div",
3508
4266
  {
3509
- className: className ? `${styles$3.toolbar} ${className}` : styles$3.toolbar,
3510
- children: /* @__PURE__ */ jsxs("div", { className: styles$3.inner, children: [
4267
+ className: className ? `${styles$5.toolbar} ${className}` : styles$5.toolbar,
4268
+ children: /* @__PURE__ */ jsxs("div", { className: styles$5.inner, children: [
3511
4269
  /* @__PURE__ */ jsx(
3512
4270
  ToolbarButton,
3513
4271
  {
@@ -3534,12 +4292,12 @@ function EditorToolbar({
3534
4292
  "button",
3535
4293
  {
3536
4294
  type: "button",
3537
- className: styles$3.styleTrigger,
4295
+ className: styles$5.styleTrigger,
3538
4296
  title: t.style,
3539
4297
  onMouseDown: (e2) => e2.preventDefault(),
3540
4298
  children: [
3541
- /* @__PURE__ */ jsx("span", { className: styles$3.styleTriggerLabel, children: t.style }),
3542
- /* @__PURE__ */ jsx(ChevronDownIcon, { size: 12, className: styles$3.styleTriggerCaret })
4299
+ /* @__PURE__ */ jsx("span", { className: styles$5.styleTriggerLabel, children: t.style }),
4300
+ /* @__PURE__ */ jsx(ChevronDownIcon, { size: 12, className: styles$5.styleTriggerCaret })
3543
4301
  ]
3544
4302
  }
3545
4303
  ),
@@ -3549,8 +4307,8 @@ function EditorToolbar({
3549
4307
  {
3550
4308
  selected: (state.headingLevel ?? 0) === 0,
3551
4309
  onSelect: () => setBlockStyle(0),
3552
- children: /* @__PURE__ */ jsxs("span", { className: styles$3.styleItem, children: [
3553
- /* @__PURE__ */ jsx("span", { className: styles$3.styleIcon, children: "¶" }),
4310
+ children: /* @__PURE__ */ jsxs("span", { className: styles$5.styleItem, children: [
4311
+ /* @__PURE__ */ jsx("span", { className: styles$5.styleIcon, children: "¶" }),
3554
4312
  t.normalText
3555
4313
  ] })
3556
4314
  }
@@ -3560,8 +4318,8 @@ function EditorToolbar({
3560
4318
  {
3561
4319
  selected: state.headingLevel === lv,
3562
4320
  onSelect: () => setBlockStyle(lv),
3563
- children: /* @__PURE__ */ jsxs("span", { className: styles$3.styleItem, children: [
3564
- /* @__PURE__ */ jsx("span", { className: styles$3.styleIcon, children: `H${lv}` }),
4321
+ children: /* @__PURE__ */ jsxs("span", { className: styles$5.styleItem, children: [
4322
+ /* @__PURE__ */ jsx("span", { className: styles$5.styleIcon, children: `H${lv}` }),
3565
4323
  t.headingLabel(lv)
3566
4324
  ] })
3567
4325
  },
@@ -3577,14 +4335,14 @@ function EditorToolbar({
3577
4335
  "button",
3578
4336
  {
3579
4337
  type: "button",
3580
- className: styles$3.styleTrigger,
4338
+ className: styles$5.styleTrigger,
3581
4339
  title: t.fontSize,
3582
4340
  "aria-label": t.fontSize,
3583
4341
  disabled: !canEditFontSize,
3584
4342
  onMouseDown: (e2) => e2.preventDefault(),
3585
4343
  children: [
3586
- /* @__PURE__ */ jsx("span", { className: styles$3.styleTriggerLabel, children: state.fontSize || t.fontSize }),
3587
- /* @__PURE__ */ jsx(ChevronDownIcon, { size: 12, className: styles$3.styleTriggerCaret })
4344
+ /* @__PURE__ */ jsx("span", { className: styles$5.styleTriggerLabel, children: state.fontSize || t.fontSize }),
4345
+ /* @__PURE__ */ jsx(ChevronDownIcon, { size: 12, className: styles$5.styleTriggerCaret })
3588
4346
  ]
3589
4347
  }
3590
4348
  ),
@@ -3594,8 +4352,8 @@ function EditorToolbar({
3594
4352
  {
3595
4353
  selected: !state.fontSize,
3596
4354
  onSelect: () => applyFontSize(""),
3597
- children: /* @__PURE__ */ jsxs("span", { className: styles$3.styleItem, children: [
3598
- /* @__PURE__ */ jsx("span", { className: styles$3.styleIcon, children: "A" }),
4355
+ children: /* @__PURE__ */ jsxs("span", { className: styles$5.styleItem, children: [
4356
+ /* @__PURE__ */ jsx("span", { className: styles$5.styleIcon, children: "A" }),
3599
4357
  t.fontSizeDefault
3600
4358
  ] })
3601
4359
  }
@@ -3605,8 +4363,8 @@ function EditorToolbar({
3605
4363
  {
3606
4364
  selected: state.fontSize === size,
3607
4365
  onSelect: () => applyFontSize(size),
3608
- children: /* @__PURE__ */ jsxs("span", { className: styles$3.styleItem, children: [
3609
- /* @__PURE__ */ jsx("span", { className: styles$3.styleIcon, children: parseInt(size, 10) }),
4366
+ children: /* @__PURE__ */ jsxs("span", { className: styles$5.styleItem, children: [
4367
+ /* @__PURE__ */ jsx("span", { className: styles$5.styleIcon, children: parseInt(size, 10) }),
3610
4368
  size
3611
4369
  ] })
3612
4370
  },
@@ -3690,13 +4448,13 @@ function EditorToolbar({
3690
4448
  "button",
3691
4449
  {
3692
4450
  type: "button",
3693
- className: `${styles$3.scriptTrigger} ${scriptActive !== "normal" ? styles$3.btnActive : ""}`,
4451
+ className: `${styles$5.scriptTrigger} ${scriptActive !== "normal" ? styles$5.btnActive : ""}`,
3694
4452
  title: t.scriptMenu,
3695
4453
  "aria-label": t.scriptMenu,
3696
4454
  onMouseDown: (e2) => e2.preventDefault(),
3697
4455
  children: [
3698
- /* @__PURE__ */ jsx("span", { className: styles$3.scriptTriggerGlyph, children: "A" }),
3699
- /* @__PURE__ */ jsx(ChevronDownIcon, { size: 12, className: styles$3.styleTriggerCaret })
4456
+ /* @__PURE__ */ jsx("span", { className: styles$5.scriptTriggerGlyph, children: "A" }),
4457
+ /* @__PURE__ */ jsx(ChevronDownIcon, { size: 12, className: styles$5.styleTriggerCaret })
3700
4458
  ]
3701
4459
  }
3702
4460
  ),
@@ -3706,8 +4464,8 @@ function EditorToolbar({
3706
4464
  {
3707
4465
  selected: scriptActive === "normal",
3708
4466
  onSelect: () => chain().unsetSuperscript().unsetSubscript().run(),
3709
- children: /* @__PURE__ */ jsxs("span", { className: styles$3.styleItem, children: [
3710
- /* @__PURE__ */ jsx("span", { className: styles$3.styleIcon, children: "A" }),
4467
+ children: /* @__PURE__ */ jsxs("span", { className: styles$5.styleItem, children: [
4468
+ /* @__PURE__ */ jsx("span", { className: styles$5.styleIcon, children: "A" }),
3711
4469
  t.scriptNormal
3712
4470
  ] })
3713
4471
  }
@@ -3717,8 +4475,8 @@ function EditorToolbar({
3717
4475
  {
3718
4476
  selected: scriptActive === "superscript",
3719
4477
  onSelect: () => chain().unsetSubscript().toggleSuperscript().run(),
3720
- children: /* @__PURE__ */ jsxs("span", { className: styles$3.styleItem, children: [
3721
- /* @__PURE__ */ jsxs("span", { className: `${styles$3.styleIcon} ${styles$3.scriptGlyph}`, children: [
4478
+ children: /* @__PURE__ */ jsxs("span", { className: styles$5.styleItem, children: [
4479
+ /* @__PURE__ */ jsxs("span", { className: `${styles$5.styleIcon} ${styles$5.scriptGlyph}`, children: [
3722
4480
  "x",
3723
4481
  /* @__PURE__ */ jsx("sup", { children: "2" })
3724
4482
  ] }),
@@ -3731,8 +4489,8 @@ function EditorToolbar({
3731
4489
  {
3732
4490
  selected: scriptActive === "subscript",
3733
4491
  onSelect: () => chain().unsetSuperscript().toggleSubscript().run(),
3734
- children: /* @__PURE__ */ jsxs("span", { className: styles$3.styleItem, children: [
3735
- /* @__PURE__ */ jsxs("span", { className: `${styles$3.styleIcon} ${styles$3.scriptGlyph}`, children: [
4492
+ children: /* @__PURE__ */ jsxs("span", { className: styles$5.styleItem, children: [
4493
+ /* @__PURE__ */ jsxs("span", { className: `${styles$5.styleIcon} ${styles$5.scriptGlyph}`, children: [
3736
4494
  "x",
3737
4495
  /* @__PURE__ */ jsx("sub", { children: "2" })
3738
4496
  ] }),
@@ -3744,7 +4502,20 @@ function EditorToolbar({
3744
4502
  }
3745
4503
  ),
3746
4504
  /* @__PURE__ */ jsx(Divider, {}),
3747
- /* @__PURE__ */ jsx(ToolbarButton, { title: t.link, active: state.link, onClick: toggleLink, children: /* @__PURE__ */ jsx(LinkIcon, {}) }),
4505
+ /* @__PURE__ */ jsx(
4506
+ LinkPopover,
4507
+ {
4508
+ editor,
4509
+ labels: {
4510
+ field: t.linkPrompt,
4511
+ apply: t.linkApply,
4512
+ open: t.linkOpen,
4513
+ remove: t.linkRemove,
4514
+ invalid: t.linkInvalid
4515
+ },
4516
+ trigger: /* @__PURE__ */ jsx(ToolbarButton, { title: t.link, active: state.link, children: /* @__PURE__ */ jsx(LinkIcon, {}) })
4517
+ }
4518
+ ),
3748
4519
  onImageUpload ? /* @__PURE__ */ jsxs(Fragment$2, { children: [
3749
4520
  /* @__PURE__ */ jsx(ToolbarButton, { title: t.image, onClick: handlePickImage, children: /* @__PURE__ */ jsx(ImageIcon, {}) }),
3750
4521
  /* @__PURE__ */ jsx(
@@ -3765,19 +4536,19 @@ function EditorToolbar({
3765
4536
  "button",
3766
4537
  {
3767
4538
  type: "button",
3768
- className: styles$3.styleTrigger,
4539
+ className: styles$5.styleTrigger,
3769
4540
  title: importTitle,
3770
4541
  "aria-label": importTitle,
3771
4542
  "aria-busy": !!importing,
3772
4543
  disabled: !!importing,
3773
4544
  onMouseDown: (e2) => e2.preventDefault(),
3774
4545
  children: [
3775
- /* @__PURE__ */ jsx("span", { className: styles$3.styleTriggerLabel, children: t.importDocument }),
4546
+ /* @__PURE__ */ jsx("span", { className: styles$5.styleTriggerLabel, children: t.importDocument }),
3776
4547
  /* @__PURE__ */ jsx(
3777
4548
  ChevronDownIcon,
3778
4549
  {
3779
4550
  size: 12,
3780
- className: styles$3.styleTriggerCaret
4551
+ className: styles$5.styleTriggerCaret
3781
4552
  }
3782
4553
  )
3783
4554
  ]
@@ -3799,7 +4570,7 @@ function EditorToolbar({
3799
4570
  title: t.blockquote,
3800
4571
  active: state.blockquote,
3801
4572
  onClick: () => chain().toggleBlockquote().run(),
3802
- children: /* @__PURE__ */ jsx("span", { className: styles$3.txtIcon, children: "❝" })
4573
+ children: /* @__PURE__ */ jsx("span", { className: styles$5.txtIcon, children: "❝" })
3803
4574
  }
3804
4575
  ),
3805
4576
  /* @__PURE__ */ jsx(Divider, {}),
@@ -3831,6 +4602,15 @@ function EditorToolbar({
3831
4602
  }
3832
4603
  ),
3833
4604
  /* @__PURE__ */ jsx(Divider, {}),
4605
+ onSearch ? /* @__PURE__ */ jsx(
4606
+ ToolbarButton,
4607
+ {
4608
+ title: t.search,
4609
+ active: searchActive,
4610
+ onClick: onSearch,
4611
+ children: /* @__PURE__ */ jsx(SearchIcon, {})
4612
+ }
4613
+ ) : null,
3834
4614
  /* @__PURE__ */ jsxs(
3835
4615
  MenuPopover,
3836
4616
  {
@@ -3838,30 +4618,30 @@ function EditorToolbar({
3838
4618
  "button",
3839
4619
  {
3840
4620
  type: "button",
3841
- className: styles$3.styleTrigger,
4621
+ className: styles$5.styleTrigger,
3842
4622
  title: t.more,
3843
4623
  onMouseDown: (e2) => e2.preventDefault(),
3844
4624
  children: [
3845
- /* @__PURE__ */ jsx("span", { className: styles$3.styleTriggerLabel, children: t.more }),
3846
- /* @__PURE__ */ jsx(ChevronDownIcon, { size: 12, className: styles$3.styleTriggerCaret })
4625
+ /* @__PURE__ */ jsx("span", { className: styles$5.styleTriggerLabel, children: t.more }),
4626
+ /* @__PURE__ */ jsx(ChevronDownIcon, { size: 12, className: styles$5.styleTriggerCaret })
3847
4627
  ]
3848
4628
  }
3849
4629
  ),
3850
4630
  children: [
3851
- /* @__PURE__ */ jsx(MenuItem, { onSelect: () => chain().toggleCodeBlock().run(), children: /* @__PURE__ */ jsxs("span", { className: styles$3.styleItem, children: [
3852
- /* @__PURE__ */ jsx("span", { className: styles$3.styleIcon, children: "{ }" }),
4631
+ /* @__PURE__ */ jsx(MenuItem, { onSelect: () => chain().toggleCodeBlock().run(), children: /* @__PURE__ */ jsxs("span", { className: styles$5.styleItem, children: [
4632
+ /* @__PURE__ */ jsx("span", { className: styles$5.styleIcon, children: "{ }" }),
3853
4633
  t.codeBlock
3854
4634
  ] }) }),
3855
- /* @__PURE__ */ jsx(MenuItem, { onSelect: () => openInsertMath("inline"), children: /* @__PURE__ */ jsxs("span", { className: styles$3.styleItem, children: [
3856
- /* @__PURE__ */ jsx("span", { className: styles$3.styleIcon, children: "√x" }),
4635
+ /* @__PURE__ */ jsx(MenuItem, { onSelect: () => openInsertMath("inline"), children: /* @__PURE__ */ jsxs("span", { className: styles$5.styleItem, children: [
4636
+ /* @__PURE__ */ jsx("span", { className: styles$5.styleIcon, children: "√x" }),
3857
4637
  t.inlineMath
3858
4638
  ] }) }),
3859
- /* @__PURE__ */ jsx(MenuItem, { onSelect: () => openInsertMath("block"), children: /* @__PURE__ */ jsxs("span", { className: styles$3.styleItem, children: [
3860
- /* @__PURE__ */ jsx("span", { className: styles$3.styleIcon, children: "∑" }),
4639
+ /* @__PURE__ */ jsx(MenuItem, { onSelect: () => openInsertMath("block"), children: /* @__PURE__ */ jsxs("span", { className: styles$5.styleItem, children: [
4640
+ /* @__PURE__ */ jsx("span", { className: styles$5.styleIcon, children: "∑" }),
3861
4641
  t.blockMath
3862
4642
  ] }) }),
3863
- /* @__PURE__ */ jsx(MenuItem, { onSelect: () => chain().setHorizontalRule().run(), children: /* @__PURE__ */ jsxs("span", { className: styles$3.styleItem, children: [
3864
- /* @__PURE__ */ jsx("span", { className: styles$3.styleIcon, children: "—" }),
4643
+ /* @__PURE__ */ jsx(MenuItem, { onSelect: () => chain().setHorizontalRule().run(), children: /* @__PURE__ */ jsxs("span", { className: styles$5.styleItem, children: [
4644
+ /* @__PURE__ */ jsx("span", { className: styles$5.styleIcon, children: "—" }),
3865
4645
  t.hr
3866
4646
  ] }) }),
3867
4647
  /* @__PURE__ */ jsx(
@@ -3877,8 +4657,8 @@ function EditorToolbar({
3877
4657
  {
3878
4658
  disabled: item2.disabled,
3879
4659
  onSelect: () => item2.onSelect(editor),
3880
- children: /* @__PURE__ */ jsxs("span", { className: styles$3.styleItem, children: [
3881
- /* @__PURE__ */ jsx("span", { className: styles$3.styleIcon, children: item2.icon }),
4660
+ children: /* @__PURE__ */ jsxs("span", { className: styles$5.styleItem, children: [
4661
+ /* @__PURE__ */ jsx("span", { className: styles$5.styleIcon, children: item2.icon }),
3882
4662
  item2.label
3883
4663
  ] })
3884
4664
  },
@@ -3915,88 +4695,7 @@ function EditorToolbar({
3915
4695
  onCancel: cancelMath
3916
4696
  }
3917
4697
  ) : null,
3918
- tableMenu && createPortal(
3919
- /* @__PURE__ */ jsxs(
3920
- "div",
3921
- {
3922
- className: styles$3.tableBubble,
3923
- style: { position: "fixed", left: tableMenu.x, top: tableMenu.y },
3924
- role: "menu",
3925
- onMouseDown: (e2) => e2.stopPropagation(),
3926
- onContextMenu: (e2) => e2.preventDefault(),
3927
- children: [
3928
- /* @__PURE__ */ jsx(
3929
- TableMenuItem,
3930
- {
3931
- label: tableMulti ? t.tableAddColumnBeforeN(tableColN) : t.tableAddColumnBefore,
3932
- onClick: () => runTable(() => addColumnsBefore(editor, tableColN)),
3933
- children: /* @__PURE__ */ jsx(ColumnBeforeIcon, {})
3934
- }
3935
- ),
3936
- /* @__PURE__ */ jsx(
3937
- TableMenuItem,
3938
- {
3939
- label: tableMulti ? t.tableAddColumnAfterN(tableColN) : t.tableAddColumnAfter,
3940
- onClick: () => runTable(() => addColumnsAfter(editor, tableColN)),
3941
- children: /* @__PURE__ */ jsx(ColumnAfterIcon, {})
3942
- }
3943
- ),
3944
- /* @__PURE__ */ jsx(
3945
- TableMenuItem,
3946
- {
3947
- label: tableMulti ? t.tableDeleteColumnN(tableColN) : t.tableDeleteColumn,
3948
- disabled: disableDeleteColumn,
3949
- onClick: () => runTable(() => {
3950
- deleteSelectedColumns(editor);
3951
- }),
3952
- children: /* @__PURE__ */ jsx(ColumnDeleteIcon, {})
3953
- }
3954
- ),
3955
- /* @__PURE__ */ jsx(TableMenuDivider, {}),
3956
- /* @__PURE__ */ jsx(
3957
- TableMenuItem,
3958
- {
3959
- label: tableMulti ? t.tableAddRowBeforeN(tableRowN) : t.tableAddRowBefore,
3960
- disabled: disableAddRowBefore,
3961
- onClick: () => runTable(() => addRowsBefore(editor, tableRowN)),
3962
- children: /* @__PURE__ */ jsx(RowBeforeIcon, {})
3963
- }
3964
- ),
3965
- /* @__PURE__ */ jsx(
3966
- TableMenuItem,
3967
- {
3968
- label: tableMulti ? t.tableAddRowAfterN(tableRowN) : t.tableAddRowAfter,
3969
- onClick: () => runTable(() => addRowsAfter(editor, tableRowN)),
3970
- children: /* @__PURE__ */ jsx(RowAfterIcon, {})
3971
- }
3972
- ),
3973
- /* @__PURE__ */ jsx(
3974
- TableMenuItem,
3975
- {
3976
- label: tableMulti ? t.tableDeleteRowN(tableRowN) : t.tableDeleteRow,
3977
- disabled: disableDeleteRow,
3978
- onClick: () => runTable(() => {
3979
- deleteSelectedRows(editor);
3980
- }),
3981
- children: /* @__PURE__ */ jsx(RowDeleteIcon, {})
3982
- }
3983
- ),
3984
- /* @__PURE__ */ jsx(TableMenuDivider, {}),
3985
- /* @__PURE__ */ jsx(
3986
- TableMenuItem,
3987
- {
3988
- label: t.tableDeleteTable,
3989
- onClick: () => runTable(() => {
3990
- editor.commands.deleteTable();
3991
- }),
3992
- children: /* @__PURE__ */ jsx(TableDeleteIcon, {})
3993
- }
3994
- )
3995
- ]
3996
- }
3997
- ),
3998
- document.body
3999
- )
4698
+ /* @__PURE__ */ jsx(TableHandles, { editor, labels: t })
4000
4699
  ] });
4001
4700
  }
4002
4701
  function useIsMobile(breakpoint = 768) {
@@ -4345,6 +5044,8 @@ export {
4345
5044
  CommentPopover,
4346
5045
  CopyIcon,
4347
5046
  EditorToolbar,
5047
+ EraserIcon,
5048
+ ExternalLinkIcon,
4348
5049
  FIND_DEBOUNCE_MS,
4349
5050
  default2 as FindAndReplace,
4350
5051
  FindReplaceBar,
@@ -4354,6 +5055,7 @@ export {
4354
5055
  ItalicIcon,
4355
5056
  KeyboardIcon,
4356
5057
  LinkIcon,
5058
+ LinkPopover,
4357
5059
  ListChecksIcon,
4358
5060
  ListOrderedIcon,
4359
5061
  ListUnorderedIcon,
@@ -4370,6 +5072,7 @@ export {
4370
5072
  R2 as ReportContent,
4371
5073
  R as ReportContentInteractive,
4372
5074
  b as ReportContentWithCharts,
5075
+ RotateCcwIcon,
4373
5076
  RowAfterIcon,
4374
5077
  RowBeforeIcon,
4375
5078
  RowDeleteIcon,
@@ -4385,9 +5088,11 @@ export {
4385
5088
  XIcon,
4386
5089
  a2 as applyCitationSources,
4387
5090
  applyCommentAnchorsToEditor,
5091
+ applyLink,
4388
5092
  baseExtensions,
4389
5093
  g as blockTextHash,
4390
5094
  buildShortcutGroups,
5095
+ canSetLink,
4391
5096
  collectCommentIds,
4392
5097
  commentAnchorExtension,
4393
5098
  commentAnchorPlugin,
@@ -4401,6 +5106,7 @@ export {
4401
5106
  defaultColorPaletteLabels,
4402
5107
  defaultCommentLabels,
4403
5108
  defaultFindLabels,
5109
+ defaultLinkPopoverLabels,
4404
5110
  defaultShortcutLabels,
4405
5111
  defaultSlashMenuLabels,
4406
5112
  defaultTocLabels,
@@ -4415,6 +5121,7 @@ export {
4415
5121
  getMarkdownForRange,
4416
5122
  insertMarkdown,
4417
5123
  insertSlashMarkdown,
5124
+ isLinkActive,
4418
5125
  looksLikeMarkdown,
4419
5126
  lowlight,
4420
5127
  makeTocGetId,
@@ -4422,15 +5129,20 @@ export {
4422
5129
  mergeCommentIntervals,
4423
5130
  m as mountChartsInContainer,
4424
5131
  nextComment,
5132
+ normalizeLinkHref,
4425
5133
  normalizeMarkdown,
5134
+ openLinkUrl,
4426
5135
  prepareChartMarkdown,
4427
5136
  pureChart,
4428
5137
  pureCodeBlock,
4429
5138
  pureImage,
4430
5139
  r as readCitationAttrs,
5140
+ readLinkHref,
5141
+ removeLink,
4431
5142
  replaceRangeWithMarkdown,
4432
5143
  reportChart,
4433
5144
  runFindCommand,
5145
+ sanitizeLinkUrl,
4434
5146
  s as scrollToTocHeading,
4435
5147
  selectionKind,
4436
5148
  s2 as serializeChartPayload,