tiptap-markdown-react 0.19.1 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -37
- package/THIRD_PARTY_LICENSES.md +155 -1
- package/dist/{ReportContent-B8jIzhy3.js → ReportContent-w08GFm8v.js} +16 -8
- package/dist/{ReportContent-B8jIzhy3.js.map → ReportContent-w08GFm8v.js.map} +1 -1
- package/dist/blockDrag/actions.d.ts +30 -0
- package/dist/blockDrag/actions.test.d.ts +1 -0
- package/dist/blockDrag/listDrop.d.ts +21 -0
- package/dist/blockDrag/listDrop.test.d.ts +1 -0
- package/dist/blurSelection.dom.test.d.ts +1 -0
- package/dist/characterCount.d.ts +1 -0
- package/dist/characterCount.dom.test.d.ts +1 -0
- package/dist/characterCount.test.d.ts +1 -0
- package/dist/chart/createChart.d.ts +0 -3
- package/dist/components/BlockDragHandle.d.ts +14 -0
- package/dist/components/BlockDragHandle.dom.test.d.ts +1 -0
- package/dist/components/CodeBlockView.d.ts +2 -2
- package/dist/components/ColorPalette.d.ts +4 -3
- package/dist/components/EditorToolbar.d.ts +4 -3
- package/dist/components/FindReplaceBar.d.ts +4 -3
- package/dist/components/LinkPopover.d.ts +4 -3
- package/dist/components/MarkdownPreview.d.ts +4 -1
- package/dist/components/MarkdownWysiwygEditor.d.ts +30 -9
- package/dist/components/TocPanel.d.ts +4 -3
- package/dist/detailsMarkdown.d.ts +4 -0
- package/dist/detailsMarkdown.test.d.ts +1 -0
- package/dist/emoji/EmojiSuggestion.d.ts +23 -0
- package/dist/emoji/emojiCategories.d.ts +52 -0
- package/dist/emoji/emojiMarkdown.test.d.ts +1 -0
- package/dist/emoji/emojiSuggestion.dom.test.d.ts +1 -0
- package/dist/emoji/filterEmoji.d.ts +7 -0
- package/dist/emoji/markdownEmoji.d.ts +8 -0
- package/dist/{extractToc-CGrBMGvM.js → extractToc-Cr470fBy.js} +659 -5
- package/dist/extractToc-Cr470fBy.js.map +1 -0
- package/dist/fonts/OFL.txt +95 -0
- package/dist/i18n/index.d.ts +4 -0
- package/dist/i18n/store.d.ts +16 -0
- package/dist/i18n/types.d.ts +19 -0
- package/dist/i18n/zh.d.ts +3 -0
- package/dist/icons/index.d.ts +5 -0
- package/dist/imageUpload.d.ts +0 -3
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1983 -407
- package/dist/index.js.map +1 -1
- package/dist/labels.d.ts +56 -2
- package/dist/numberingFormat.d.ts +67 -0
- package/dist/numberingFormat.test.d.ts +1 -0
- package/dist/reader.js +2 -2
- package/dist/{scrollToTocHeading-B2QmL4wi.js → scrollToTocHeading-kPgsn3cu.js} +2 -2
- package/dist/{scrollToTocHeading-B2QmL4wi.js.map → scrollToTocHeading-kPgsn3cu.js.map} +1 -1
- package/dist/server.js +4 -4
- package/dist/shortcuts/ShortcutPanel.d.ts +4 -4
- package/dist/shortcuts/types.d.ts +2 -2
- package/dist/slashMenu/SlashMenuExtension.d.ts +0 -3
- package/dist/slashMenu/items.d.ts +2 -2
- package/dist/style-inline.css +2110 -294
- package/dist/style.css +2110 -294
- package/dist/typography.test.d.ts +1 -0
- package/package.json +19 -3
- package/dist/extractToc-CGrBMGvM.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,29 +1,33 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { Markdown, MarkdownManager } from "@tiptap/markdown";
|
|
3
|
-
import { c as renderOrUpdateChart, d as destroyChart } from "./scrollToTocHeading-
|
|
4
|
-
import { C, a, R, b, f, m, r, s } from "./scrollToTocHeading-
|
|
3
|
+
import { c as renderOrUpdateChart, d as destroyChart } from "./scrollToTocHeading-kPgsn3cu.js";
|
|
4
|
+
import { C, a, R, b, f, m, r, s } from "./scrollToTocHeading-kPgsn3cu.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
|
+
import Typography from "@tiptap/extension-typography";
|
|
9
10
|
import Image from "@tiptap/extension-image";
|
|
10
11
|
import { TableOfContents } from "@tiptap/extension-table-of-contents";
|
|
11
|
-
import { skipTrailingNodeMeta, Placeholder } from "@tiptap/extensions";
|
|
12
|
+
import { skipTrailingNodeMeta, Placeholder, Selection as Selection$1, CharacterCount } from "@tiptap/extensions";
|
|
12
13
|
import { NodeViewWrapper, ReactNodeViewRenderer, useEditorState, ReactRenderer, NodeViewContent, useEditor, EditorContent } from "@tiptap/react";
|
|
13
14
|
import { Extension, Node as Node$1, mergeAttributes } from "@tiptap/core";
|
|
14
15
|
import { createPortal } from "react-dom";
|
|
15
|
-
import { useState, useEffect, useCallback, useRef, useMemo, forwardRef, useImperativeHandle, Fragment as Fragment$1,
|
|
16
|
-
import { e as enrichMarkdownCitations, c as styles$
|
|
17
|
-
import { R as R2, a as a2, b as b2, s as s2 } from "./ReportContent-
|
|
18
|
-
import { C as CitationRef, i as mergeCommentIntervals, h as mapCommentAnchors, n as normalizeImageAlign, p as prepareChartMarkdown, j as reportChart,
|
|
19
|
-
import { P, g, e, s as s3 } from "./extractToc-
|
|
16
|
+
import { useState, useEffect, useCallback, useRef, useMemo, useSyncExternalStore, useLayoutEffect, forwardRef, useId, useImperativeHandle, Fragment as Fragment$1, useContext, createContext } from "react";
|
|
17
|
+
import { e as enrichMarkdownCitations, c as styles$e } from "./ReportContent-w08GFm8v.js";
|
|
18
|
+
import { R as R2, a as a2, b as b2, s as s2 } from "./ReportContent-w08GFm8v.js";
|
|
19
|
+
import { C as CitationRef, i as mergeCommentIntervals, h as mapCommentAnchors, n as normalizeImageAlign, p as prepareChartMarkdown, j as reportChart, f as CommentMark, b as baseExtensions, l as lowlight, m as makeTocGetId, k as parseCodeTokenAsChartOrCodeBlock, o as imageMarkdownTokenizer, q as imageParseMarkdown, t as imageRenderMarkdown, u as imageNodeHtml, v as imageFigureParseRule, w as imageCaptionAttribute, x as imageAlignAttribute, y as normalizeImageCaption, a as pureCodeBlock, c as pureImage, z as renderMathInto, A as readCurrentNumberingFormat, B as subscribeMathClick, D as applyNumberingFormat, N as NUMBERING_FORMAT_IDS, E as NUMBERING_FORMAT_LABELS, F as NUMBERING_FORMAT_PREVIEWS, d as pureChart } from "./extractToc-Cr470fBy.js";
|
|
20
|
+
import { P, g, e, s as s3 } from "./extractToc-Cr470fBy.js";
|
|
20
21
|
import { Slice, Fragment } from "@tiptap/pm/model";
|
|
21
22
|
import { PluginKey, Plugin, Selection, TextSelection, NodeSelection } from "@tiptap/pm/state";
|
|
22
23
|
import { DecorationSet, Decoration } from "@tiptap/pm/view";
|
|
24
|
+
import { EmojiSuggestionPluginKey } from "@tiptap/extension-emoji";
|
|
23
25
|
import Suggestion from "@tiptap/suggestion";
|
|
24
26
|
import { FileHandlePlugin } from "@tiptap/extension-file-handler";
|
|
25
27
|
import { CellSelection, TableMap, isInTable, selectedRect, rowIsHeader, cellAround } from "@tiptap/pm/tables";
|
|
26
28
|
import * as DropdownMenu from "@radix-ui/react-dropdown-menu";
|
|
29
|
+
import { DragHandle } from "@tiptap/extension-drag-handle-react";
|
|
30
|
+
import { dropPoint } from "@tiptap/pm/transform";
|
|
27
31
|
import * as Popover from "@radix-ui/react-popover";
|
|
28
32
|
function CitationRefView({ node, extension }) {
|
|
29
33
|
const index = String(node.attrs.index ?? "");
|
|
@@ -118,8 +122,8 @@ function sliceHasCommentMarks(slice, markType) {
|
|
|
118
122
|
}
|
|
119
123
|
function blockBounds(doc) {
|
|
120
124
|
const bounds = [];
|
|
121
|
-
doc.forEach((child,
|
|
122
|
-
bounds.push({ start:
|
|
125
|
+
doc.forEach((child, offset2) => {
|
|
126
|
+
bounds.push({ start: offset2, end: offset2 + child.nodeSize });
|
|
123
127
|
});
|
|
124
128
|
return bounds;
|
|
125
129
|
}
|
|
@@ -511,6 +515,12 @@ const ListOrderedIcon = (p) => /* @__PURE__ */ jsxs(Svg, { ...p, children: [
|
|
|
511
515
|
/* @__PURE__ */ jsx("path", { d: "M4 10h2" }),
|
|
512
516
|
/* @__PURE__ */ jsx("path", { d: "M6 18H4c0-1 2-2 2-3s-1-1.5-2-1" })
|
|
513
517
|
] });
|
|
518
|
+
const DetailsIcon = (p) => /* @__PURE__ */ jsxs(Svg, { ...p, children: [
|
|
519
|
+
/* @__PURE__ */ jsx("path", { d: "m9 7 4 5-4 5" }),
|
|
520
|
+
/* @__PURE__ */ jsx("path", { d: "M15 7h5" }),
|
|
521
|
+
/* @__PURE__ */ jsx("path", { d: "M15 12h5" }),
|
|
522
|
+
/* @__PURE__ */ jsx("path", { d: "M15 17h5" })
|
|
523
|
+
] });
|
|
514
524
|
const ListChecksIcon = (p) => /* @__PURE__ */ jsxs(Svg, { ...p, children: [
|
|
515
525
|
/* @__PURE__ */ jsx("path", { d: "m3 17 2 2 4-4" }),
|
|
516
526
|
/* @__PURE__ */ jsx("path", { d: "m3 7 2 2 4-4" }),
|
|
@@ -624,6 +634,19 @@ const ChevronsUpDownIcon = (p) => /* @__PURE__ */ jsxs(Svg, { ...p, children: [
|
|
|
624
634
|
/* @__PURE__ */ jsx("path", { d: "m7 15 5 5 5-5" }),
|
|
625
635
|
/* @__PURE__ */ jsx("path", { d: "m7 9 5-5 5 5" })
|
|
626
636
|
] });
|
|
637
|
+
const GripIcon = (p) => /* @__PURE__ */ jsxs(Svg, { ...p, fill: "currentColor", strokeWidth: 0, children: [
|
|
638
|
+
/* @__PURE__ */ jsx("circle", { cx: "9", cy: "6", r: "1.25" }),
|
|
639
|
+
/* @__PURE__ */ jsx("circle", { cx: "15", cy: "6", r: "1.25" }),
|
|
640
|
+
/* @__PURE__ */ jsx("circle", { cx: "9", cy: "12", r: "1.25" }),
|
|
641
|
+
/* @__PURE__ */ jsx("circle", { cx: "15", cy: "12", r: "1.25" }),
|
|
642
|
+
/* @__PURE__ */ jsx("circle", { cx: "9", cy: "18", r: "1.25" }),
|
|
643
|
+
/* @__PURE__ */ jsx("circle", { cx: "15", cy: "18", r: "1.25" })
|
|
644
|
+
] });
|
|
645
|
+
const DownloadIcon = (p) => /* @__PURE__ */ jsxs(Svg, { ...p, children: [
|
|
646
|
+
/* @__PURE__ */ jsx("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
|
|
647
|
+
/* @__PURE__ */ jsx("polyline", { points: "7 10 12 15 17 10" }),
|
|
648
|
+
/* @__PURE__ */ jsx("line", { x1: "12", x2: "12", y1: "15", y2: "3" })
|
|
649
|
+
] });
|
|
627
650
|
const KeyboardIcon = (p) => /* @__PURE__ */ jsxs(Svg, { ...p, children: [
|
|
628
651
|
/* @__PURE__ */ jsx("rect", { width: "20", height: "16", x: "2", y: "4", rx: "2" }),
|
|
629
652
|
/* @__PURE__ */ jsx("path", { d: "M6 8h.01" }),
|
|
@@ -698,8 +721,10 @@ const defaultToolbarLabels = {
|
|
|
698
721
|
importDocumentConverting: "Converting…",
|
|
699
722
|
importDocumentFailed: "Import failed",
|
|
700
723
|
blockquote: "Blockquote",
|
|
724
|
+
details: "Toggle",
|
|
701
725
|
bulletList: "Bullet list",
|
|
702
726
|
orderedList: "Ordered list",
|
|
727
|
+
numberingFormat: "Numbering format",
|
|
703
728
|
taskList: "Task list",
|
|
704
729
|
more: "More",
|
|
705
730
|
search: "Find & replace",
|
|
@@ -735,6 +760,23 @@ const defaultToolbarLabels = {
|
|
|
735
760
|
mathNewInline: "New equation",
|
|
736
761
|
mathNewBlock: "Add a TeX equation"
|
|
737
762
|
};
|
|
763
|
+
const defaultBlockDragLabels = {
|
|
764
|
+
dragHandle: "Drag to move",
|
|
765
|
+
menuLabel: "Block actions",
|
|
766
|
+
turnInto: "Turn into",
|
|
767
|
+
paragraph: "Normal text",
|
|
768
|
+
headingLabel: (level) => `Heading ${level}`,
|
|
769
|
+
bulletList: "Bullet list",
|
|
770
|
+
orderedList: "Ordered list",
|
|
771
|
+
taskList: "Task list",
|
|
772
|
+
blockquote: "Blockquote",
|
|
773
|
+
codeBlock: "Code block",
|
|
774
|
+
copy: "Copy",
|
|
775
|
+
duplicate: "Duplicate",
|
|
776
|
+
resetFormatting: "Reset formatting",
|
|
777
|
+
downloadImage: "Download image",
|
|
778
|
+
delete: "Delete"
|
|
779
|
+
};
|
|
738
780
|
const defaultSlashMenuLabels = {
|
|
739
781
|
menuLabel: "Insert block",
|
|
740
782
|
groupText: "Text",
|
|
@@ -746,6 +788,7 @@ const defaultSlashMenuLabels = {
|
|
|
746
788
|
orderedList: "Ordered list",
|
|
747
789
|
taskList: "Task list",
|
|
748
790
|
blockquote: "Blockquote",
|
|
791
|
+
details: "Toggle",
|
|
749
792
|
codeBlock: "Code block",
|
|
750
793
|
divider: "Divider",
|
|
751
794
|
table: "Table",
|
|
@@ -783,7 +826,19 @@ const defaultShortcutLabels = {
|
|
|
783
826
|
alignCenter: "Align center",
|
|
784
827
|
alignRight: "Align right",
|
|
785
828
|
alignJustify: "Justify",
|
|
786
|
-
imageUpload: "Upload image"
|
|
829
|
+
imageUpload: "Upload image",
|
|
830
|
+
smartQuote: "Smart quotes",
|
|
831
|
+
ellipsis: "Ellipsis",
|
|
832
|
+
emDash: "Em dash",
|
|
833
|
+
emoji: "Emoji"
|
|
834
|
+
};
|
|
835
|
+
const defaultCharacterCountLabels = {
|
|
836
|
+
label: "Document statistics",
|
|
837
|
+
characters: (count) => `${count} ${count === 1 ? "character" : "characters"}`,
|
|
838
|
+
words: (count) => `${count} ${count === 1 ? "word" : "words"}`
|
|
839
|
+
};
|
|
840
|
+
const defaultEmojiSuggestionLabels = {
|
|
841
|
+
menuLabel: "Emoji"
|
|
787
842
|
};
|
|
788
843
|
const defaultLinkPopoverLabels = {
|
|
789
844
|
field: "Enter URL",
|
|
@@ -806,16 +861,8 @@ const defaultCodeBlockLabels = {
|
|
|
806
861
|
delete: "Delete code block",
|
|
807
862
|
copy: "Copy code",
|
|
808
863
|
expand: "Expand code",
|
|
809
|
-
collapse: "Collapse code"
|
|
810
|
-
|
|
811
|
-
const defaultCommentLabels = {
|
|
812
|
-
open: "Open",
|
|
813
|
-
resolved: "Resolved",
|
|
814
|
-
dismissed: "Dismissed",
|
|
815
|
-
outdated: "Outdated",
|
|
816
|
-
ambiguous: "Ambiguous",
|
|
817
|
-
partial: "Partially matched",
|
|
818
|
-
gutterTitle: "Comment"
|
|
864
|
+
collapse: "Collapse code",
|
|
865
|
+
language: "Code language"
|
|
819
866
|
};
|
|
820
867
|
const defaultFindLabels = {
|
|
821
868
|
find: "Find",
|
|
@@ -845,6 +892,260 @@ const defaultImageUploadLabels = {
|
|
|
845
892
|
failed: "Upload failed",
|
|
846
893
|
fallbackAlt: "image"
|
|
847
894
|
};
|
|
895
|
+
const zh = {
|
|
896
|
+
toolbar: {
|
|
897
|
+
undo: "撤销",
|
|
898
|
+
redo: "重做",
|
|
899
|
+
style: "样式",
|
|
900
|
+
normalText: "正文",
|
|
901
|
+
headingLabel: (level) => `标题 ${level}`,
|
|
902
|
+
fontSize: "字号",
|
|
903
|
+
fontSizeDefault: "默认",
|
|
904
|
+
bold: "加粗",
|
|
905
|
+
italic: "斜体",
|
|
906
|
+
underline: "下划线",
|
|
907
|
+
strike: "删除线",
|
|
908
|
+
code: "行内代码",
|
|
909
|
+
textColor: "文字颜色",
|
|
910
|
+
highlight: "高亮",
|
|
911
|
+
colorNone: "无",
|
|
912
|
+
colorTheme: "主题色",
|
|
913
|
+
scriptMenu: "上标 / 下标",
|
|
914
|
+
scriptNormal: "常规",
|
|
915
|
+
superscript: "上标",
|
|
916
|
+
subscript: "下标",
|
|
917
|
+
link: "链接",
|
|
918
|
+
align: "对齐",
|
|
919
|
+
alignLeft: "左对齐",
|
|
920
|
+
alignCenter: "居中",
|
|
921
|
+
alignRight: "右对齐",
|
|
922
|
+
alignJustify: "两端对齐",
|
|
923
|
+
indent: "缩进",
|
|
924
|
+
indentIncrease: "增加缩进",
|
|
925
|
+
indentDecrease: "减少缩进",
|
|
926
|
+
lineHeight: "行高",
|
|
927
|
+
lineHeightDefault: "默认",
|
|
928
|
+
linkPrompt: "输入链接地址",
|
|
929
|
+
linkApply: "应用链接",
|
|
930
|
+
linkOpen: "在新窗口打开",
|
|
931
|
+
linkRemove: "移除链接",
|
|
932
|
+
linkInvalid: "编辑器不接受这个地址",
|
|
933
|
+
image: "图片",
|
|
934
|
+
imageUploadFailed: "图片上传失败",
|
|
935
|
+
imageAlign: "图片对齐",
|
|
936
|
+
imageAlignLeft: "左对齐",
|
|
937
|
+
imageAlignCenter: "居中",
|
|
938
|
+
imageAlignRight: "右对齐",
|
|
939
|
+
imageCaption: "图片描述",
|
|
940
|
+
imageCaptionPlaceholder: "添加描述…",
|
|
941
|
+
importMarkdownFailed: "Markdown 导入失败",
|
|
942
|
+
importDocument: "导入",
|
|
943
|
+
importDocumentHint: "导入文件",
|
|
944
|
+
importDocumentOther: "文档",
|
|
945
|
+
importDocumentBusy: "正在导入…",
|
|
946
|
+
importDocumentUploading: (percent) => `上传中 ${percent}%`,
|
|
947
|
+
importDocumentConverting: "正在转换…",
|
|
948
|
+
importDocumentFailed: "导入失败",
|
|
949
|
+
blockquote: "引用",
|
|
950
|
+
details: "折叠块",
|
|
951
|
+
bulletList: "无序列表",
|
|
952
|
+
orderedList: "有序列表",
|
|
953
|
+
numberingFormat: "编号格式",
|
|
954
|
+
taskList: "任务列表",
|
|
955
|
+
more: "更多",
|
|
956
|
+
search: "查找替换",
|
|
957
|
+
codeBlock: "代码块",
|
|
958
|
+
hr: "分隔线",
|
|
959
|
+
importMarkdown: "Markdown",
|
|
960
|
+
tableInsert: "插入表格",
|
|
961
|
+
tableRowMenu: "行操作",
|
|
962
|
+
tableColumnMenu: "列操作",
|
|
963
|
+
tableClearContent: "清空内容",
|
|
964
|
+
tableResetCellStyles: "重置单元格样式",
|
|
965
|
+
tableAppendRow: "添加行",
|
|
966
|
+
tableAppendColumn: "添加列",
|
|
967
|
+
tableSizeSelected: (cols, rows) => `${cols} × ${rows}`,
|
|
968
|
+
tableAddColumnBefore: "在左侧插入列",
|
|
969
|
+
tableAddColumnAfter: "在右侧插入列",
|
|
970
|
+
tableDeleteColumn: "删除列",
|
|
971
|
+
tableAddRowBefore: "在上方插入行",
|
|
972
|
+
tableAddRowAfter: "在下方插入行",
|
|
973
|
+
tableDeleteRow: "删除行",
|
|
974
|
+
tableAddColumnBeforeN: (n) => `在左侧插入 ${n} 列`,
|
|
975
|
+
tableAddColumnAfterN: (n) => `在右侧插入 ${n} 列`,
|
|
976
|
+
tableDeleteColumnN: (n) => `删除 ${n} 列`,
|
|
977
|
+
tableAddRowBeforeN: (n) => `在上方插入 ${n} 行`,
|
|
978
|
+
tableAddRowAfterN: (n) => `在下方插入 ${n} 行`,
|
|
979
|
+
tableDeleteRowN: (n) => `删除 ${n} 行`,
|
|
980
|
+
tableDeleteTable: "删除表格",
|
|
981
|
+
inlineMath: "行内公式",
|
|
982
|
+
blockMath: "块级公式",
|
|
983
|
+
mathPlaceholder: "E = mc^2",
|
|
984
|
+
mathDone: "完成",
|
|
985
|
+
mathCancel: "取消",
|
|
986
|
+
mathNewInline: "新建公式",
|
|
987
|
+
mathNewBlock: "插入 TeX 公式"
|
|
988
|
+
},
|
|
989
|
+
slashMenu: {
|
|
990
|
+
menuLabel: "插入块",
|
|
991
|
+
groupText: "文本",
|
|
992
|
+
groupList: "列表",
|
|
993
|
+
groupAdvanced: "高级",
|
|
994
|
+
normalText: "正文",
|
|
995
|
+
headingLabel: (level) => `标题 ${level}`,
|
|
996
|
+
bulletList: "无序列表",
|
|
997
|
+
orderedList: "有序列表",
|
|
998
|
+
taskList: "任务列表",
|
|
999
|
+
blockquote: "引用",
|
|
1000
|
+
details: "折叠块",
|
|
1001
|
+
codeBlock: "代码块",
|
|
1002
|
+
divider: "分隔线",
|
|
1003
|
+
table: "表格",
|
|
1004
|
+
inlineMath: "行内公式",
|
|
1005
|
+
blockMath: "块级公式"
|
|
1006
|
+
},
|
|
1007
|
+
chart: {
|
|
1008
|
+
tabLabel: (chartType, index) => `${chartType} ${index + 1}`,
|
|
1009
|
+
done: "完成",
|
|
1010
|
+
cancel: "取消",
|
|
1011
|
+
configLabel: "图表配置(JSON)",
|
|
1012
|
+
tableLabel: "数据表(Markdown)",
|
|
1013
|
+
editTitle: "编辑图表"
|
|
1014
|
+
},
|
|
1015
|
+
blockDrag: {
|
|
1016
|
+
dragHandle: "拖动以移动",
|
|
1017
|
+
menuLabel: "块操作",
|
|
1018
|
+
turnInto: "转换成",
|
|
1019
|
+
paragraph: "正文",
|
|
1020
|
+
headingLabel: (level) => `标题 ${level}`,
|
|
1021
|
+
bulletList: "无序列表",
|
|
1022
|
+
orderedList: "有序列表",
|
|
1023
|
+
taskList: "任务列表",
|
|
1024
|
+
blockquote: "引用",
|
|
1025
|
+
codeBlock: "代码块",
|
|
1026
|
+
copy: "复制",
|
|
1027
|
+
duplicate: "再制一份",
|
|
1028
|
+
resetFormatting: "清除格式",
|
|
1029
|
+
downloadImage: "下载图片",
|
|
1030
|
+
delete: "删除"
|
|
1031
|
+
},
|
|
1032
|
+
shortcut: {
|
|
1033
|
+
panelTitle: "快捷键",
|
|
1034
|
+
close: "关闭",
|
|
1035
|
+
colFormat: "格式",
|
|
1036
|
+
colShortcut: "快捷键",
|
|
1037
|
+
colMarkdown: "Markdown",
|
|
1038
|
+
formatGroup: "格式",
|
|
1039
|
+
insertGroup: "插入",
|
|
1040
|
+
editGroup: "编辑",
|
|
1041
|
+
bold: "加粗",
|
|
1042
|
+
italic: "斜体",
|
|
1043
|
+
strike: "删除线",
|
|
1044
|
+
underline: "下划线",
|
|
1045
|
+
inlineCode: "行内代码",
|
|
1046
|
+
highlight: "高亮",
|
|
1047
|
+
headingLabel: (level) => `标题 ${level}`,
|
|
1048
|
+
paragraph: "正文",
|
|
1049
|
+
blockquote: "引用",
|
|
1050
|
+
bulletList: "无序列表",
|
|
1051
|
+
orderedList: "有序列表",
|
|
1052
|
+
taskList: "任务列表",
|
|
1053
|
+
codeBlock: "代码块",
|
|
1054
|
+
divider: "分隔线",
|
|
1055
|
+
undo: "撤销",
|
|
1056
|
+
redo: "重做",
|
|
1057
|
+
hardBreak: "硬换行",
|
|
1058
|
+
findReplace: "查找替换",
|
|
1059
|
+
alignLeft: "左对齐",
|
|
1060
|
+
alignCenter: "居中",
|
|
1061
|
+
alignRight: "右对齐",
|
|
1062
|
+
alignJustify: "两端对齐",
|
|
1063
|
+
imageUpload: "上传图片",
|
|
1064
|
+
smartQuote: "智能引号",
|
|
1065
|
+
ellipsis: "省略号",
|
|
1066
|
+
emDash: "破折号",
|
|
1067
|
+
emoji: "表情"
|
|
1068
|
+
},
|
|
1069
|
+
characterCount: {
|
|
1070
|
+
label: "字数统计",
|
|
1071
|
+
characters: (count) => `${count} 字符`,
|
|
1072
|
+
words: (count) => `${count} 词`
|
|
1073
|
+
},
|
|
1074
|
+
emoji: {
|
|
1075
|
+
menuLabel: "表情"
|
|
1076
|
+
},
|
|
1077
|
+
link: {
|
|
1078
|
+
field: "输入链接地址",
|
|
1079
|
+
apply: "应用链接",
|
|
1080
|
+
open: "在新窗口打开",
|
|
1081
|
+
remove: "移除链接",
|
|
1082
|
+
invalid: "编辑器不接受这个地址"
|
|
1083
|
+
},
|
|
1084
|
+
palette: {
|
|
1085
|
+
none: "无",
|
|
1086
|
+
theme: "主题色"
|
|
1087
|
+
},
|
|
1088
|
+
toc: {
|
|
1089
|
+
title: "目录",
|
|
1090
|
+
expand: "展开",
|
|
1091
|
+
collapse: "收起"
|
|
1092
|
+
},
|
|
1093
|
+
codeBlock: {
|
|
1094
|
+
autoDetect: "自动识别",
|
|
1095
|
+
delete: "删除代码块",
|
|
1096
|
+
copy: "复制代码",
|
|
1097
|
+
expand: "展开代码",
|
|
1098
|
+
collapse: "收起代码",
|
|
1099
|
+
language: "代码语言"
|
|
1100
|
+
},
|
|
1101
|
+
find: {
|
|
1102
|
+
find: "查找",
|
|
1103
|
+
replace: "替换为",
|
|
1104
|
+
next: "下一处",
|
|
1105
|
+
previous: "上一处",
|
|
1106
|
+
replaceOne: "替换",
|
|
1107
|
+
replaceAll: "全部替换",
|
|
1108
|
+
close: "关闭",
|
|
1109
|
+
caseSensitive: "区分大小写",
|
|
1110
|
+
wholeWord: "全词匹配",
|
|
1111
|
+
useRegex: "正则表达式",
|
|
1112
|
+
counter: (current, total) => `${current} / ${total}`,
|
|
1113
|
+
invalidRegex: "正则无效",
|
|
1114
|
+
readOnly: "只读"
|
|
1115
|
+
},
|
|
1116
|
+
imageUpload: {
|
|
1117
|
+
dropzoneClick: "点击上传",
|
|
1118
|
+
dropzoneRest: ",或拖拽到此处",
|
|
1119
|
+
dropzoneLimits: (limit, maxSizeMb) => {
|
|
1120
|
+
const count = `最多 ${limit} 个文件`;
|
|
1121
|
+
return maxSizeMb == null ? `${count}。` : `${count},每个 ${maxSizeMb}MB。`;
|
|
1122
|
+
},
|
|
1123
|
+
uploadingCount: (count) => `正在上传 ${count} 个文件`,
|
|
1124
|
+
clearAll: "全部清除",
|
|
1125
|
+
remove: "移除",
|
|
1126
|
+
failed: "上传失败",
|
|
1127
|
+
fallbackAlt: "图片"
|
|
1128
|
+
}
|
|
1129
|
+
};
|
|
1130
|
+
const en = {
|
|
1131
|
+
toolbar: defaultToolbarLabels,
|
|
1132
|
+
slashMenu: defaultSlashMenuLabels,
|
|
1133
|
+
chart: defaultChartLabels,
|
|
1134
|
+
blockDrag: defaultBlockDragLabels,
|
|
1135
|
+
shortcut: defaultShortcutLabels,
|
|
1136
|
+
characterCount: defaultCharacterCountLabels,
|
|
1137
|
+
emoji: defaultEmojiSuggestionLabels,
|
|
1138
|
+
link: defaultLinkPopoverLabels,
|
|
1139
|
+
palette: defaultColorPaletteLabels,
|
|
1140
|
+
toc: defaultTocLabels,
|
|
1141
|
+
codeBlock: defaultCodeBlockLabels,
|
|
1142
|
+
find: defaultFindLabels,
|
|
1143
|
+
imageUpload: defaultImageUploadLabels
|
|
1144
|
+
};
|
|
1145
|
+
const bundles = { en, zh };
|
|
1146
|
+
function getLocaleBundle(locale = "en") {
|
|
1147
|
+
return bundles[locale] ?? en;
|
|
1148
|
+
}
|
|
848
1149
|
const bar$1 = "_bar_1h61e_3";
|
|
849
1150
|
const row$1 = "_row_1h61e_25";
|
|
850
1151
|
const field$1 = "_field_1h61e_43";
|
|
@@ -858,7 +1159,7 @@ const toggleOn = "_toggleOn_1h61e_135";
|
|
|
858
1159
|
const iconGroup = "_iconGroup_1h61e_29";
|
|
859
1160
|
const spacer = "_spacer_1h61e_150";
|
|
860
1161
|
const readOnly = "_readOnly_1h61e_155";
|
|
861
|
-
const styles$
|
|
1162
|
+
const styles$d = {
|
|
862
1163
|
bar: bar$1,
|
|
863
1164
|
row: row$1,
|
|
864
1165
|
field: field$1,
|
|
@@ -884,12 +1185,12 @@ function warnMissingExtensionOnce() {
|
|
|
884
1185
|
function FindReplaceBar({
|
|
885
1186
|
editor,
|
|
886
1187
|
onClose,
|
|
887
|
-
|
|
1188
|
+
locale = "en",
|
|
888
1189
|
inputRef,
|
|
889
1190
|
className,
|
|
890
1191
|
style
|
|
891
1192
|
}) {
|
|
892
|
-
const t =
|
|
1193
|
+
const t = getLocaleBundle(locale).find;
|
|
893
1194
|
const [term, setTerm] = useState("");
|
|
894
1195
|
const [replaceTerm, setReplaceTerm] = useState("");
|
|
895
1196
|
const hasExtension = hasFindReplaceExtension(editor);
|
|
@@ -982,11 +1283,11 @@ function FindReplaceBar({
|
|
|
982
1283
|
});
|
|
983
1284
|
};
|
|
984
1285
|
if (!hasExtension) return null;
|
|
985
|
-
const toggleClass = (on) => `${styles$
|
|
1286
|
+
const toggleClass = (on) => `${styles$d.btn} ${styles$d.toggle}${on ? ` ${styles$d.toggleOn}` : ""}`;
|
|
986
1287
|
return /* @__PURE__ */ jsxs(
|
|
987
1288
|
"div",
|
|
988
1289
|
{
|
|
989
|
-
className: className ? `${styles$
|
|
1290
|
+
className: className ? `${styles$d.bar} ${className}` : styles$d.bar,
|
|
990
1291
|
style,
|
|
991
1292
|
"data-find-bar": "",
|
|
992
1293
|
role: "dialog",
|
|
@@ -999,14 +1300,14 @@ function FindReplaceBar({
|
|
|
999
1300
|
onClose();
|
|
1000
1301
|
},
|
|
1001
1302
|
children: [
|
|
1002
|
-
/* @__PURE__ */ jsxs("div", { className: styles$
|
|
1003
|
-
/* @__PURE__ */ jsxs("span", { className: styles$
|
|
1004
|
-
/* @__PURE__ */ jsx(SearchIcon, { size: 14, className: styles$
|
|
1303
|
+
/* @__PURE__ */ jsxs("div", { className: styles$d.row, children: [
|
|
1304
|
+
/* @__PURE__ */ jsxs("span", { className: styles$d.field, children: [
|
|
1305
|
+
/* @__PURE__ */ jsx(SearchIcon, { size: 14, className: styles$d.fieldIcon }),
|
|
1005
1306
|
/* @__PURE__ */ jsx(
|
|
1006
1307
|
"input",
|
|
1007
1308
|
{
|
|
1008
1309
|
ref: inputRef,
|
|
1009
|
-
className: styles$
|
|
1310
|
+
className: styles$d.input,
|
|
1010
1311
|
"data-find-field": "search",
|
|
1011
1312
|
value: term,
|
|
1012
1313
|
onChange: (e2) => setTerm(e2.target.value),
|
|
@@ -1020,7 +1321,7 @@ function FindReplaceBar({
|
|
|
1020
1321
|
/* @__PURE__ */ jsx(
|
|
1021
1322
|
"span",
|
|
1022
1323
|
{
|
|
1023
|
-
className: `${styles$
|
|
1324
|
+
className: `${styles$d.counter}${invalidPattern ? ` ${styles$d.counterInvalid}` : ""}`,
|
|
1024
1325
|
"data-find-counter": "",
|
|
1025
1326
|
"aria-live": "polite",
|
|
1026
1327
|
title: invalidPattern ? t.invalidRegex : void 0,
|
|
@@ -1056,13 +1357,13 @@ function FindReplaceBar({
|
|
|
1056
1357
|
children: "ab"
|
|
1057
1358
|
}
|
|
1058
1359
|
),
|
|
1059
|
-
/* @__PURE__ */ jsx("span", { className: styles$
|
|
1060
|
-
/* @__PURE__ */ jsxs("span", { className: styles$
|
|
1360
|
+
/* @__PURE__ */ jsx("span", { className: styles$d.spacer }),
|
|
1361
|
+
/* @__PURE__ */ jsxs("span", { className: styles$d.iconGroup, children: [
|
|
1061
1362
|
/* @__PURE__ */ jsx(
|
|
1062
1363
|
"button",
|
|
1063
1364
|
{
|
|
1064
1365
|
type: "button",
|
|
1065
|
-
className: styles$
|
|
1366
|
+
className: styles$d.btn,
|
|
1066
1367
|
"data-find-action": "previous",
|
|
1067
1368
|
title: t.previous,
|
|
1068
1369
|
"aria-label": t.previous,
|
|
@@ -1076,7 +1377,7 @@ function FindReplaceBar({
|
|
|
1076
1377
|
"button",
|
|
1077
1378
|
{
|
|
1078
1379
|
type: "button",
|
|
1079
|
-
className: styles$
|
|
1380
|
+
className: styles$d.btn,
|
|
1080
1381
|
"data-find-action": "next",
|
|
1081
1382
|
title: t.next,
|
|
1082
1383
|
"aria-label": t.next,
|
|
@@ -1090,7 +1391,7 @@ function FindReplaceBar({
|
|
|
1090
1391
|
"button",
|
|
1091
1392
|
{
|
|
1092
1393
|
type: "button",
|
|
1093
|
-
className: styles$
|
|
1394
|
+
className: styles$d.btn,
|
|
1094
1395
|
"data-find-action": "close",
|
|
1095
1396
|
title: t.close,
|
|
1096
1397
|
"aria-label": t.close,
|
|
@@ -1100,11 +1401,11 @@ function FindReplaceBar({
|
|
|
1100
1401
|
)
|
|
1101
1402
|
] })
|
|
1102
1403
|
] }),
|
|
1103
|
-
editor.isEditable ? /* @__PURE__ */ jsxs("div", { className: styles$
|
|
1104
|
-
/* @__PURE__ */ jsx("span", { className: styles$
|
|
1404
|
+
editor.isEditable ? /* @__PURE__ */ jsxs("div", { className: styles$d.row, children: [
|
|
1405
|
+
/* @__PURE__ */ jsx("span", { className: styles$d.field, children: /* @__PURE__ */ jsx(
|
|
1105
1406
|
"input",
|
|
1106
1407
|
{
|
|
1107
|
-
className: styles$
|
|
1408
|
+
className: styles$d.input,
|
|
1108
1409
|
"data-find-field": "replace",
|
|
1109
1410
|
value: replaceTerm,
|
|
1110
1411
|
onChange: (e2) => setReplaceTerm(e2.target.value),
|
|
@@ -1114,12 +1415,12 @@ function FindReplaceBar({
|
|
|
1114
1415
|
spellCheck: false
|
|
1115
1416
|
}
|
|
1116
1417
|
) }),
|
|
1117
|
-
/* @__PURE__ */ jsx("span", { className: styles$
|
|
1418
|
+
/* @__PURE__ */ jsx("span", { className: styles$d.spacer }),
|
|
1118
1419
|
/* @__PURE__ */ jsx(
|
|
1119
1420
|
"button",
|
|
1120
1421
|
{
|
|
1121
1422
|
type: "button",
|
|
1122
|
-
className: styles$
|
|
1423
|
+
className: styles$d.btn,
|
|
1123
1424
|
"data-find-action": "replace",
|
|
1124
1425
|
title: t.replaceOne,
|
|
1125
1426
|
"aria-label": t.replaceOne,
|
|
@@ -1133,7 +1434,7 @@ function FindReplaceBar({
|
|
|
1133
1434
|
"button",
|
|
1134
1435
|
{
|
|
1135
1436
|
type: "button",
|
|
1136
|
-
className: styles$
|
|
1437
|
+
className: styles$d.btn,
|
|
1137
1438
|
"data-find-action": "replace-all",
|
|
1138
1439
|
title: t.replaceAll,
|
|
1139
1440
|
"aria-label": t.replaceAll,
|
|
@@ -1143,7 +1444,7 @@ function FindReplaceBar({
|
|
|
1143
1444
|
children: /* @__PURE__ */ jsx(ReplaceAllIcon, { size: 16 })
|
|
1144
1445
|
}
|
|
1145
1446
|
)
|
|
1146
|
-
] }) : /* @__PURE__ */ jsx("div", { className: styles$
|
|
1447
|
+
] }) : /* @__PURE__ */ jsx("div", { className: styles$d.row, children: /* @__PURE__ */ jsx("span", { className: styles$d.readOnly, children: t.readOnly }) })
|
|
1147
1448
|
]
|
|
1148
1449
|
}
|
|
1149
1450
|
);
|
|
@@ -1230,6 +1531,65 @@ const ImportPlaceholder = Node$1.create({
|
|
|
1230
1531
|
};
|
|
1231
1532
|
}
|
|
1232
1533
|
});
|
|
1534
|
+
const serverBundle = getLocaleBundle("en");
|
|
1535
|
+
const stores = /* @__PURE__ */ new WeakMap();
|
|
1536
|
+
function ensure(editor) {
|
|
1537
|
+
let entry = stores.get(editor);
|
|
1538
|
+
if (!entry) {
|
|
1539
|
+
entry = {
|
|
1540
|
+
locale: "en",
|
|
1541
|
+
bundle: serverBundle,
|
|
1542
|
+
listeners: /* @__PURE__ */ new Set(),
|
|
1543
|
+
pendingNotify: false
|
|
1544
|
+
};
|
|
1545
|
+
stores.set(editor, entry);
|
|
1546
|
+
}
|
|
1547
|
+
return entry;
|
|
1548
|
+
}
|
|
1549
|
+
function setEditorLocale(editor, locale) {
|
|
1550
|
+
const entry = ensure(editor);
|
|
1551
|
+
if (entry.locale === locale) return;
|
|
1552
|
+
entry.locale = locale;
|
|
1553
|
+
entry.bundle = getLocaleBundle(locale);
|
|
1554
|
+
entry.pendingNotify = true;
|
|
1555
|
+
}
|
|
1556
|
+
function flushEditorLocale(editor) {
|
|
1557
|
+
const entry = stores.get(editor);
|
|
1558
|
+
if (!(entry == null ? void 0 : entry.pendingNotify)) return;
|
|
1559
|
+
entry.pendingNotify = false;
|
|
1560
|
+
entry.listeners.forEach((listener) => listener());
|
|
1561
|
+
}
|
|
1562
|
+
function getEditorLocale(editor) {
|
|
1563
|
+
var _a;
|
|
1564
|
+
return ((_a = stores.get(editor)) == null ? void 0 : _a.locale) ?? "en";
|
|
1565
|
+
}
|
|
1566
|
+
function getEditorBundle(editor) {
|
|
1567
|
+
var _a;
|
|
1568
|
+
return ((_a = stores.get(editor)) == null ? void 0 : _a.bundle) ?? serverBundle;
|
|
1569
|
+
}
|
|
1570
|
+
function subscribeEditorLocale(editor, listener) {
|
|
1571
|
+
const entry = ensure(editor);
|
|
1572
|
+
entry.listeners.add(listener);
|
|
1573
|
+
return () => {
|
|
1574
|
+
entry.listeners.delete(listener);
|
|
1575
|
+
};
|
|
1576
|
+
}
|
|
1577
|
+
const useIsoLayoutEffect = typeof window === "undefined" ? useEffect : useLayoutEffect;
|
|
1578
|
+
function usePublishEditorLocale(editor, locale) {
|
|
1579
|
+
if (editor) setEditorLocale(editor, locale);
|
|
1580
|
+
useIsoLayoutEffect(() => {
|
|
1581
|
+
if (!editor || editor.isDestroyed) return;
|
|
1582
|
+
flushEditorLocale(editor);
|
|
1583
|
+
}, [editor, locale]);
|
|
1584
|
+
}
|
|
1585
|
+
function useEditorBundle(editor) {
|
|
1586
|
+
const subscribe = useCallback(
|
|
1587
|
+
(onStoreChange) => subscribeEditorLocale(editor, onStoreChange),
|
|
1588
|
+
[editor]
|
|
1589
|
+
);
|
|
1590
|
+
const getSnapshot = useCallback(() => getEditorBundle(editor), [editor]);
|
|
1591
|
+
return useSyncExternalStore(subscribe, getSnapshot, () => serverBundle);
|
|
1592
|
+
}
|
|
1233
1593
|
const wrap = "_wrap_1k6n1_8";
|
|
1234
1594
|
const dropzone = "_dropzone_1k6n1_24";
|
|
1235
1595
|
const dragActive = "_dragActive_1k6n1_43";
|
|
@@ -1255,7 +1615,7 @@ const fileName = "_fileName_1k6n1_205";
|
|
|
1255
1615
|
const actions = "_actions_1k6n1_215";
|
|
1256
1616
|
const progressText = "_progressText_1k6n1_222";
|
|
1257
1617
|
const remove = "_remove_1k6n1_228";
|
|
1258
|
-
const styles$
|
|
1618
|
+
const styles$c = {
|
|
1259
1619
|
wrap,
|
|
1260
1620
|
dropzone,
|
|
1261
1621
|
dragActive,
|
|
@@ -1312,10 +1672,7 @@ function focusNextNode(editor) {
|
|
|
1312
1672
|
function ImageUploadView(props) {
|
|
1313
1673
|
const { node, extension, editor, getPos } = props;
|
|
1314
1674
|
const options = extension.options;
|
|
1315
|
-
const labels =
|
|
1316
|
-
...defaultImageUploadLabels,
|
|
1317
|
-
...options.labels
|
|
1318
|
-
};
|
|
1675
|
+
const labels = useEditorBundle(editor).imageUpload;
|
|
1319
1676
|
const accept = String(node.attrs.accept ?? "image/*");
|
|
1320
1677
|
const limit = Number(node.attrs.limit ?? 1) || 1;
|
|
1321
1678
|
const maxSize = Number(node.attrs.maxSize ?? 0) || 0;
|
|
@@ -1433,14 +1790,14 @@ function ImageUploadView(props) {
|
|
|
1433
1790
|
const hasFiles = items.length > 0;
|
|
1434
1791
|
const maxSizeMb = maxSize > 0 ? toMb(maxSize) : null;
|
|
1435
1792
|
const dropzoneClass = [
|
|
1436
|
-
styles$
|
|
1437
|
-
dragActive2 ? styles$
|
|
1438
|
-
dragOver2 ? styles$
|
|
1793
|
+
styles$c.dropzone,
|
|
1794
|
+
dragActive2 ? styles$c.dragActive : "",
|
|
1795
|
+
dragOver2 ? styles$c.dragOver : ""
|
|
1439
1796
|
].filter(Boolean).join(" ");
|
|
1440
1797
|
return /* @__PURE__ */ jsxs(
|
|
1441
1798
|
NodeViewWrapper,
|
|
1442
1799
|
{
|
|
1443
|
-
className: styles$
|
|
1800
|
+
className: styles$c.wrap,
|
|
1444
1801
|
"data-image-upload": "",
|
|
1445
1802
|
tabIndex: editable ? 0 : void 0,
|
|
1446
1803
|
onClick: openPicker,
|
|
@@ -1472,28 +1829,28 @@ function ImageUploadView(props) {
|
|
|
1472
1829
|
},
|
|
1473
1830
|
onDrop,
|
|
1474
1831
|
children: [
|
|
1475
|
-
/* @__PURE__ */ jsxs("span", { className: styles$
|
|
1832
|
+
/* @__PURE__ */ jsxs("span", { className: styles$c.fileShape, "aria-hidden": true, children: [
|
|
1476
1833
|
/* @__PURE__ */ jsx(FileDocIcon, {}),
|
|
1477
1834
|
/* @__PURE__ */ jsx(FileCornerIcon, {}),
|
|
1478
|
-
/* @__PURE__ */ jsx("span", { className: styles$
|
|
1835
|
+
/* @__PURE__ */ jsx("span", { className: styles$c.fileBadge, children: /* @__PURE__ */ jsx(CloudUploadIcon, {}) })
|
|
1479
1836
|
] }),
|
|
1480
|
-
/* @__PURE__ */ jsxs("span", { className: styles$
|
|
1481
|
-
/* @__PURE__ */ jsxs("span", { className: styles$
|
|
1482
|
-
/* @__PURE__ */ jsx("em", { className: styles$
|
|
1837
|
+
/* @__PURE__ */ jsxs("span", { className: styles$c.text, children: [
|
|
1838
|
+
/* @__PURE__ */ jsxs("span", { className: styles$c.textMain, children: [
|
|
1839
|
+
/* @__PURE__ */ jsx("em", { className: styles$c.textEm, children: labels.dropzoneClick }),
|
|
1483
1840
|
labels.dropzoneRest
|
|
1484
1841
|
] }),
|
|
1485
|
-
/* @__PURE__ */ jsx("span", { className: styles$
|
|
1842
|
+
/* @__PURE__ */ jsx("span", { className: styles$c.subtext, children: labels.dropzoneLimits(limit, maxSizeMb) })
|
|
1486
1843
|
] })
|
|
1487
1844
|
]
|
|
1488
1845
|
}
|
|
1489
|
-
) : /* @__PURE__ */ jsxs("div", { className: styles$
|
|
1490
|
-
items.length > 1 && /* @__PURE__ */ jsxs("div", { className: styles$
|
|
1846
|
+
) : /* @__PURE__ */ jsxs("div", { className: styles$c.previews, "data-image-upload-list": "", children: [
|
|
1847
|
+
items.length > 1 && /* @__PURE__ */ jsxs("div", { className: styles$c.header, children: [
|
|
1491
1848
|
/* @__PURE__ */ jsx("span", { children: labels.uploadingCount(items.length) }),
|
|
1492
1849
|
/* @__PURE__ */ jsx(
|
|
1493
1850
|
"button",
|
|
1494
1851
|
{
|
|
1495
1852
|
type: "button",
|
|
1496
|
-
className: styles$
|
|
1853
|
+
className: styles$c.clearAll,
|
|
1497
1854
|
onClick: (e2) => {
|
|
1498
1855
|
e2.stopPropagation();
|
|
1499
1856
|
clearAll2();
|
|
@@ -1505,27 +1862,27 @@ function ImageUploadView(props) {
|
|
|
1505
1862
|
items.map((it) => /* @__PURE__ */ jsxs(
|
|
1506
1863
|
"div",
|
|
1507
1864
|
{
|
|
1508
|
-
className: styles$
|
|
1865
|
+
className: styles$c.preview,
|
|
1509
1866
|
"data-image-upload-item": "",
|
|
1510
1867
|
children: [
|
|
1511
1868
|
it.status === "uploading" && /* @__PURE__ */ jsx(
|
|
1512
1869
|
"div",
|
|
1513
1870
|
{
|
|
1514
|
-
className: styles$
|
|
1871
|
+
className: styles$c.progress,
|
|
1515
1872
|
style: { width: `${it.progress}%` },
|
|
1516
1873
|
"aria-hidden": true
|
|
1517
1874
|
}
|
|
1518
1875
|
),
|
|
1519
|
-
/* @__PURE__ */ jsxs("div", { className: styles$
|
|
1520
|
-
/* @__PURE__ */ jsxs("span", { className: styles$
|
|
1521
|
-
/* @__PURE__ */ jsx("span", { className: styles$
|
|
1522
|
-
/* @__PURE__ */ jsxs("span", { className: styles$
|
|
1523
|
-
/* @__PURE__ */ jsx("span", { className: styles$
|
|
1524
|
-
/* @__PURE__ */ jsx("span", { className: styles$
|
|
1876
|
+
/* @__PURE__ */ jsxs("div", { className: styles$c.previewContent, children: [
|
|
1877
|
+
/* @__PURE__ */ jsxs("span", { className: styles$c.fileInfo, children: [
|
|
1878
|
+
/* @__PURE__ */ jsx("span", { className: styles$c.fileIcon, "aria-hidden": true, children: /* @__PURE__ */ jsx(CloudUploadIcon, {}) }),
|
|
1879
|
+
/* @__PURE__ */ jsxs("span", { className: styles$c.details, children: [
|
|
1880
|
+
/* @__PURE__ */ jsx("span", { className: styles$c.fileName, children: it.file.name }),
|
|
1881
|
+
/* @__PURE__ */ jsx("span", { className: styles$c.subtext, children: it.status === "error" ? labels.failed : formatFileSize(it.file.size) })
|
|
1525
1882
|
] })
|
|
1526
1883
|
] }),
|
|
1527
|
-
/* @__PURE__ */ jsxs("span", { className: styles$
|
|
1528
|
-
it.status === "uploading" && /* @__PURE__ */ jsxs("span", { className: styles$
|
|
1884
|
+
/* @__PURE__ */ jsxs("span", { className: styles$c.actions, children: [
|
|
1885
|
+
it.status === "uploading" && /* @__PURE__ */ jsxs("span", { className: styles$c.progressText, children: [
|
|
1529
1886
|
Math.round(it.progress),
|
|
1530
1887
|
"%"
|
|
1531
1888
|
] }),
|
|
@@ -1533,7 +1890,7 @@ function ImageUploadView(props) {
|
|
|
1533
1890
|
"button",
|
|
1534
1891
|
{
|
|
1535
1892
|
type: "button",
|
|
1536
|
-
className: styles$
|
|
1893
|
+
className: styles$c.remove,
|
|
1537
1894
|
"data-image-upload-remove": "",
|
|
1538
1895
|
title: labels.remove,
|
|
1539
1896
|
"aria-label": labels.remove,
|
|
@@ -1592,7 +1949,7 @@ function FileDocIcon() {
|
|
|
1592
1949
|
viewBox: "0 0 43 57",
|
|
1593
1950
|
fill: "none",
|
|
1594
1951
|
"aria-hidden": true,
|
|
1595
|
-
className: styles$
|
|
1952
|
+
className: styles$c.fileShapeDoc,
|
|
1596
1953
|
children: /* @__PURE__ */ jsx(
|
|
1597
1954
|
"path",
|
|
1598
1955
|
{
|
|
@@ -1615,7 +1972,7 @@ function FileCornerIcon() {
|
|
|
1615
1972
|
viewBox: "0 0 10 10",
|
|
1616
1973
|
fill: "currentColor",
|
|
1617
1974
|
"aria-hidden": true,
|
|
1618
|
-
className: styles$
|
|
1975
|
+
className: styles$c.fileShapeCorner,
|
|
1619
1976
|
children: /* @__PURE__ */ jsx("path", { d: "M0 0.75H0.343146C1.40401 0.75 2.42143 1.17143 3.17157 1.92157L8.82843 7.57843C9.57857 8.32857 10 9.34599 10 10.4069V10.75H4C1.79086 10.75 0 8.95914 0 6.75V0.75Z" })
|
|
1620
1977
|
}
|
|
1621
1978
|
);
|
|
@@ -1639,8 +1996,7 @@ const ImageUploadNode = Node$1.create({
|
|
|
1639
1996
|
maxSize: 0,
|
|
1640
1997
|
type: "image",
|
|
1641
1998
|
onError: void 0,
|
|
1642
|
-
onSuccess: void 0
|
|
1643
|
-
labels: void 0
|
|
1999
|
+
onSuccess: void 0
|
|
1644
2000
|
};
|
|
1645
2001
|
},
|
|
1646
2002
|
addAttributes() {
|
|
@@ -1739,23 +2095,305 @@ function setImageAlignAt(editor, imageElement, align) {
|
|
|
1739
2095
|
return false;
|
|
1740
2096
|
}
|
|
1741
2097
|
}
|
|
2098
|
+
const popupHost$1 = "_popupHost_xhti8_5";
|
|
2099
|
+
const panel$1 = "_panel_xhti8_11";
|
|
2100
|
+
const menu$3 = "_menu_xhti8_22";
|
|
2101
|
+
const tabs = "_tabs_xhti8_32";
|
|
2102
|
+
const tab = "_tab_xhti8_32";
|
|
2103
|
+
const tabActive = "_tabActive_xhti8_40";
|
|
2104
|
+
const cell = "_cell_xhti8_71";
|
|
2105
|
+
const cellActive = "_cellActive_xhti8_72";
|
|
2106
|
+
const styles$b = {
|
|
2107
|
+
popupHost: popupHost$1,
|
|
2108
|
+
panel: panel$1,
|
|
2109
|
+
menu: menu$3,
|
|
2110
|
+
tabs,
|
|
2111
|
+
tab,
|
|
2112
|
+
tabActive,
|
|
2113
|
+
cell,
|
|
2114
|
+
cellActive
|
|
2115
|
+
};
|
|
2116
|
+
const EMOJI_CATEGORIES = [
|
|
2117
|
+
{ id: "smileys", group: "", label: "Smileys", icon: "😀" },
|
|
2118
|
+
{ id: "people", group: "people & body", label: "People", icon: "👋" },
|
|
2119
|
+
{ id: "nature", group: "animals & nature", label: "Animals & nature", icon: "🐻" },
|
|
2120
|
+
{ id: "food", group: "food & drink", label: "Food & drink", icon: "🍔" },
|
|
2121
|
+
{ id: "travel", group: "travel & places", label: "Travel & places", icon: "✈️" },
|
|
2122
|
+
{ id: "activities", group: "activities", label: "Activities", icon: "⚽" },
|
|
2123
|
+
{ id: "objects", group: "objects", label: "Objects", icon: "💡" },
|
|
2124
|
+
{ id: "symbols", group: "symbols", label: "Symbols", icon: "💯" },
|
|
2125
|
+
{ id: "flags", group: "flags", label: "Flags", icon: "🏁" }
|
|
2126
|
+
];
|
|
2127
|
+
function isEmojiComponent(item2) {
|
|
2128
|
+
return item2.group === "components";
|
|
2129
|
+
}
|
|
2130
|
+
function itemsInCategory(items, id) {
|
|
2131
|
+
const category = EMOJI_CATEGORIES.find((entry) => entry.id === id);
|
|
2132
|
+
if (!category) return [];
|
|
2133
|
+
return items.filter((item2) => (item2.group ?? "") === category.group);
|
|
2134
|
+
}
|
|
2135
|
+
function isRegionalIndicator(item2) {
|
|
2136
|
+
return item2.name.startsWith("regional_indicator_");
|
|
2137
|
+
}
|
|
2138
|
+
function filterEmojiItems(items, query) {
|
|
2139
|
+
const q = query.trim().toLowerCase();
|
|
2140
|
+
const usable = items.filter(
|
|
2141
|
+
(item2) => !!item2.emoji && !isRegionalIndicator(item2) && !isEmojiComponent(item2)
|
|
2142
|
+
);
|
|
2143
|
+
if (!q) return usable;
|
|
2144
|
+
const primary = [];
|
|
2145
|
+
const secondary = [];
|
|
2146
|
+
for (const item2 of usable) {
|
|
2147
|
+
const nameHit = item2.name.toLowerCase().startsWith(q) || item2.shortcodes.some((code) => code.toLowerCase().startsWith(q));
|
|
2148
|
+
if (nameHit) primary.push(item2);
|
|
2149
|
+
else if (item2.tags.some((tag) => tag.toLowerCase().startsWith(q))) {
|
|
2150
|
+
secondary.push(item2);
|
|
2151
|
+
}
|
|
2152
|
+
}
|
|
2153
|
+
return [...primary, ...secondary];
|
|
2154
|
+
}
|
|
2155
|
+
const COLUMNS = 8;
|
|
2156
|
+
function isComposing$1(event, view) {
|
|
2157
|
+
return view.composing || event.isComposing || event.keyCode === 229;
|
|
2158
|
+
}
|
|
2159
|
+
const themeVars = [
|
|
2160
|
+
"--tmr-text",
|
|
2161
|
+
"--tmr-accent",
|
|
2162
|
+
"--tmr-toolbar-border",
|
|
2163
|
+
"--tmr-toolbar-muted"
|
|
2164
|
+
];
|
|
2165
|
+
function copyThemeVars(from, to) {
|
|
2166
|
+
const computed = getComputedStyle(from);
|
|
2167
|
+
for (const name of themeVars) {
|
|
2168
|
+
const value = computed.getPropertyValue(name);
|
|
2169
|
+
if (value) to.style.setProperty(name, value);
|
|
2170
|
+
}
|
|
2171
|
+
}
|
|
2172
|
+
function moveIndex(index, key, length, shiftKey) {
|
|
2173
|
+
if (key === "ArrowRight" || key === "Tab" && !shiftKey) {
|
|
2174
|
+
return (index + 1) % length;
|
|
2175
|
+
}
|
|
2176
|
+
if (key === "ArrowLeft" || key === "Tab" && shiftKey) {
|
|
2177
|
+
return (index - 1 + length) % length;
|
|
2178
|
+
}
|
|
2179
|
+
if (key === "ArrowDown") {
|
|
2180
|
+
const next = index + COLUMNS;
|
|
2181
|
+
return next < length ? next : null;
|
|
2182
|
+
}
|
|
2183
|
+
if (key === "ArrowUp") {
|
|
2184
|
+
const next = index - COLUMNS;
|
|
2185
|
+
return next >= 0 ? next : null;
|
|
2186
|
+
}
|
|
2187
|
+
return null;
|
|
2188
|
+
}
|
|
2189
|
+
function keepCellInView(menu2, cell2) {
|
|
2190
|
+
const menuRect = menu2.getBoundingClientRect();
|
|
2191
|
+
const cellRect = cell2.getBoundingClientRect();
|
|
2192
|
+
if (cellRect.top < menuRect.top) menu2.scrollTop -= menuRect.top - cellRect.top;
|
|
2193
|
+
else if (cellRect.bottom > menuRect.bottom) {
|
|
2194
|
+
menu2.scrollTop += cellRect.bottom - menuRect.bottom;
|
|
2195
|
+
}
|
|
2196
|
+
}
|
|
2197
|
+
const EmojiSuggestionPopup = forwardRef(function EmojiSuggestionPopup2({ items, query, menuLabel, command }, ref) {
|
|
2198
|
+
var _a;
|
|
2199
|
+
const gridId = useId();
|
|
2200
|
+
const browsing = !query.trim();
|
|
2201
|
+
const [categoryId, setCategoryId] = useState(EMOJI_CATEGORIES[0].id);
|
|
2202
|
+
const [index, setIndex] = useState(0);
|
|
2203
|
+
const menuRef = useRef(null);
|
|
2204
|
+
const cellRefs = useRef([]);
|
|
2205
|
+
const categories = useMemo(
|
|
2206
|
+
() => EMOJI_CATEGORIES.filter((category) => itemsInCategory(items, category.id).length > 0),
|
|
2207
|
+
[items]
|
|
2208
|
+
);
|
|
2209
|
+
const activeId = categories.some((category) => category.id === categoryId) ? categoryId : ((_a = categories[0]) == null ? void 0 : _a.id) ?? EMOJI_CATEGORIES[0].id;
|
|
2210
|
+
const visible = browsing ? itemsInCategory(items, activeId) : items;
|
|
2211
|
+
useEffect(() => {
|
|
2212
|
+
var _a2;
|
|
2213
|
+
setIndex(0);
|
|
2214
|
+
(_a2 = menuRef.current) == null ? void 0 : _a2.scrollTo(0, 0);
|
|
2215
|
+
}, [query, activeId]);
|
|
2216
|
+
useEffect(() => {
|
|
2217
|
+
const menu2 = menuRef.current;
|
|
2218
|
+
const cell2 = cellRefs.current[index];
|
|
2219
|
+
if (menu2 && cell2) keepCellInView(menu2, cell2);
|
|
2220
|
+
}, [index, activeId, query]);
|
|
2221
|
+
useImperativeHandle(
|
|
2222
|
+
ref,
|
|
2223
|
+
() => ({
|
|
2224
|
+
onKeyDown(event) {
|
|
2225
|
+
if (!visible.length) return false;
|
|
2226
|
+
const next = moveIndex(index, event.key, visible.length, event.shiftKey);
|
|
2227
|
+
if (next !== null) {
|
|
2228
|
+
setIndex(next);
|
|
2229
|
+
return true;
|
|
2230
|
+
}
|
|
2231
|
+
if (event.key === "ArrowUp" || event.key === "ArrowDown" || event.key === "ArrowLeft" || event.key === "ArrowRight" || event.key === "Tab") {
|
|
2232
|
+
return true;
|
|
2233
|
+
}
|
|
2234
|
+
if (event.key === "Enter") {
|
|
2235
|
+
const item2 = visible[index];
|
|
2236
|
+
if (!item2) return false;
|
|
2237
|
+
command(item2);
|
|
2238
|
+
return true;
|
|
2239
|
+
}
|
|
2240
|
+
return false;
|
|
2241
|
+
}
|
|
2242
|
+
}),
|
|
2243
|
+
[visible, index, command]
|
|
2244
|
+
);
|
|
2245
|
+
if (!visible.length) return null;
|
|
2246
|
+
return /* @__PURE__ */ jsxs("div", { className: styles$b.panel, children: [
|
|
2247
|
+
/* @__PURE__ */ jsx(
|
|
2248
|
+
"div",
|
|
2249
|
+
{
|
|
2250
|
+
id: gridId,
|
|
2251
|
+
ref: menuRef,
|
|
2252
|
+
className: styles$b.menu,
|
|
2253
|
+
role: "listbox",
|
|
2254
|
+
"aria-label": menuLabel,
|
|
2255
|
+
children: visible.map((item2, i) => {
|
|
2256
|
+
const shortcode = `:${item2.name}:`;
|
|
2257
|
+
return /* @__PURE__ */ jsx(
|
|
2258
|
+
"button",
|
|
2259
|
+
{
|
|
2260
|
+
ref: (node) => {
|
|
2261
|
+
cellRefs.current[i] = node;
|
|
2262
|
+
},
|
|
2263
|
+
type: "button",
|
|
2264
|
+
role: "option",
|
|
2265
|
+
"aria-label": shortcode,
|
|
2266
|
+
"aria-selected": i === index,
|
|
2267
|
+
title: shortcode,
|
|
2268
|
+
className: i === index ? styles$b.cellActive : styles$b.cell,
|
|
2269
|
+
tabIndex: -1,
|
|
2270
|
+
onMouseEnter: () => setIndex(i),
|
|
2271
|
+
onMouseDown: (event) => {
|
|
2272
|
+
event.preventDefault();
|
|
2273
|
+
command(item2);
|
|
2274
|
+
},
|
|
2275
|
+
children: item2.emoji
|
|
2276
|
+
},
|
|
2277
|
+
item2.name
|
|
2278
|
+
);
|
|
2279
|
+
})
|
|
2280
|
+
}
|
|
2281
|
+
),
|
|
2282
|
+
browsing ? /* @__PURE__ */ jsx("div", { className: styles$b.tabs, role: "tablist", "aria-label": menuLabel, children: categories.map((category) => {
|
|
2283
|
+
const selected = category.id === activeId;
|
|
2284
|
+
return /* @__PURE__ */ jsx(
|
|
2285
|
+
"button",
|
|
2286
|
+
{
|
|
2287
|
+
type: "button",
|
|
2288
|
+
role: "tab",
|
|
2289
|
+
"aria-selected": selected,
|
|
2290
|
+
"aria-controls": gridId,
|
|
2291
|
+
"aria-label": category.label,
|
|
2292
|
+
title: category.label,
|
|
2293
|
+
className: selected ? styles$b.tabActive : styles$b.tab,
|
|
2294
|
+
tabIndex: -1,
|
|
2295
|
+
onMouseDown: (event) => {
|
|
2296
|
+
event.preventDefault();
|
|
2297
|
+
setCategoryId(category.id);
|
|
2298
|
+
},
|
|
2299
|
+
children: category.icon
|
|
2300
|
+
},
|
|
2301
|
+
category.id
|
|
2302
|
+
);
|
|
2303
|
+
}) }) : null
|
|
2304
|
+
] });
|
|
2305
|
+
});
|
|
2306
|
+
function configureEmojiSuggestion(extension, enabled) {
|
|
2307
|
+
if (!enabled) {
|
|
2308
|
+
return extension.configure({
|
|
2309
|
+
suggestion: { allow: () => false }
|
|
2310
|
+
});
|
|
2311
|
+
}
|
|
2312
|
+
return extension.configure({
|
|
2313
|
+
suggestion: {
|
|
2314
|
+
pluginKey: EmojiSuggestionPluginKey,
|
|
2315
|
+
items: ({ editor, query }) => filterEmojiItems(editor.storage.emoji.emojis, query),
|
|
2316
|
+
allow: ({
|
|
2317
|
+
editor,
|
|
2318
|
+
state,
|
|
2319
|
+
range
|
|
2320
|
+
}) => {
|
|
2321
|
+
if (!editor.isEditable) return false;
|
|
2322
|
+
if (editor.isActive("code") || editor.isActive("codeBlock")) return false;
|
|
2323
|
+
const type = state.schema.nodes.emoji;
|
|
2324
|
+
if (!type) return false;
|
|
2325
|
+
return !!state.doc.resolve(range.from).parent.type.contentMatch.matchType(type);
|
|
2326
|
+
},
|
|
2327
|
+
render: () => {
|
|
2328
|
+
let renderer = null;
|
|
2329
|
+
let unmountPopup = null;
|
|
2330
|
+
return {
|
|
2331
|
+
onStart: (props) => {
|
|
2332
|
+
renderer = new ReactRenderer(EmojiSuggestionPopup, {
|
|
2333
|
+
editor: props.editor,
|
|
2334
|
+
props: {
|
|
2335
|
+
items: props.items,
|
|
2336
|
+
query: props.query,
|
|
2337
|
+
menuLabel: getEditorBundle(props.editor).emoji.menuLabel,
|
|
2338
|
+
command: props.command
|
|
2339
|
+
},
|
|
2340
|
+
className: styles$b.popupHost
|
|
2341
|
+
});
|
|
2342
|
+
copyThemeVars(props.editor.view.dom, renderer.element);
|
|
2343
|
+
unmountPopup = props.mount(renderer.element);
|
|
2344
|
+
},
|
|
2345
|
+
onUpdate: (props) => {
|
|
2346
|
+
renderer == null ? void 0 : renderer.updateProps({
|
|
2347
|
+
items: props.items,
|
|
2348
|
+
query: props.query,
|
|
2349
|
+
menuLabel: getEditorBundle(props.editor).emoji.menuLabel,
|
|
2350
|
+
command: props.command
|
|
2351
|
+
});
|
|
2352
|
+
},
|
|
2353
|
+
onKeyDown: (props) => {
|
|
2354
|
+
var _a;
|
|
2355
|
+
if (!renderer || isComposing$1(props.event, props.view)) return false;
|
|
2356
|
+
return ((_a = renderer.ref) == null ? void 0 : _a.onKeyDown(props.event)) ?? false;
|
|
2357
|
+
},
|
|
2358
|
+
onExit: () => {
|
|
2359
|
+
unmountPopup == null ? void 0 : unmountPopup();
|
|
2360
|
+
unmountPopup = null;
|
|
2361
|
+
renderer == null ? void 0 : renderer.destroy();
|
|
2362
|
+
renderer = null;
|
|
2363
|
+
}
|
|
2364
|
+
};
|
|
2365
|
+
}
|
|
2366
|
+
}
|
|
2367
|
+
});
|
|
2368
|
+
}
|
|
2369
|
+
const CJK_IDEOGRAPH = /[\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff]/g;
|
|
2370
|
+
function countWords(text2) {
|
|
2371
|
+
let cjk = 0;
|
|
2372
|
+
const rest = text2.replace(CJK_IDEOGRAPH, () => {
|
|
2373
|
+
cjk += 1;
|
|
2374
|
+
return " ";
|
|
2375
|
+
});
|
|
2376
|
+
const words = rest.split(/\s+/).filter((word) => /[\p{L}\p{N}]/u.test(word));
|
|
2377
|
+
return cjk + words.length;
|
|
2378
|
+
}
|
|
1742
2379
|
const popupHost = "_popupHost_1noza_11";
|
|
1743
|
-
const menu$
|
|
1744
|
-
const groupLabel = "_groupLabel_1noza_43";
|
|
1745
|
-
const item$
|
|
1746
|
-
const itemActive = "_itemActive_1noza_54";
|
|
1747
|
-
const itemIcon = "_itemIcon_1noza_79";
|
|
2380
|
+
const menu$2 = "_menu_1noza_1";
|
|
2381
|
+
const groupLabel$1 = "_groupLabel_1noza_43";
|
|
2382
|
+
const item$2 = "_item_1noza_53";
|
|
2383
|
+
const itemActive$1 = "_itemActive_1noza_54";
|
|
2384
|
+
const itemIcon$1 = "_itemIcon_1noza_79";
|
|
1748
2385
|
const itemTitle = "_itemTitle_1noza_102";
|
|
1749
|
-
const styles$
|
|
2386
|
+
const styles$a = {
|
|
1750
2387
|
popupHost,
|
|
1751
|
-
menu: menu$
|
|
1752
|
-
groupLabel,
|
|
1753
|
-
item: item$
|
|
1754
|
-
itemActive,
|
|
1755
|
-
itemIcon,
|
|
2388
|
+
menu: menu$2,
|
|
2389
|
+
groupLabel: groupLabel$1,
|
|
2390
|
+
item: item$2,
|
|
2391
|
+
itemActive: itemActive$1,
|
|
2392
|
+
itemIcon: itemIcon$1,
|
|
1756
2393
|
itemTitle
|
|
1757
2394
|
};
|
|
1758
|
-
function createDefaultSlashMenuItems(
|
|
2395
|
+
function createDefaultSlashMenuItems(locale = "en") {
|
|
2396
|
+
const labels = getLocaleBundle(locale).slashMenu;
|
|
1759
2397
|
return [
|
|
1760
2398
|
{
|
|
1761
2399
|
id: "normal-text",
|
|
@@ -1823,6 +2461,17 @@ function createDefaultSlashMenuItems(labels = defaultSlashMenuLabels) {
|
|
|
1823
2461
|
editor.chain().focus().deleteRange(range).toggleBlockquote().run();
|
|
1824
2462
|
}
|
|
1825
2463
|
},
|
|
2464
|
+
{
|
|
2465
|
+
id: "details",
|
|
2466
|
+
title: labels.details,
|
|
2467
|
+
group: labels.groupAdvanced,
|
|
2468
|
+
icon: "▸",
|
|
2469
|
+
aliases: ["zhedie", "折叠", "toggle", "details", "collapse"],
|
|
2470
|
+
order: 8,
|
|
2471
|
+
apply: (editor, range) => {
|
|
2472
|
+
editor.chain().focus().deleteRange(range).setDetails().run();
|
|
2473
|
+
}
|
|
2474
|
+
},
|
|
1826
2475
|
{
|
|
1827
2476
|
id: "code-block",
|
|
1828
2477
|
title: labels.codeBlock,
|
|
@@ -1935,11 +2584,11 @@ const SlashMenuPopup = forwardRef(function SlashMenuPopup2({ items, query, menuL
|
|
|
1935
2584
|
);
|
|
1936
2585
|
if (!items.length) return null;
|
|
1937
2586
|
let optionIndex = -1;
|
|
1938
|
-
return /* @__PURE__ */ jsx("div", { className: styles$
|
|
2587
|
+
return /* @__PURE__ */ jsx("div", { className: styles$a.menu, role: "listbox", "aria-label": menuLabel, children: withGroupHeaders(items).map(([header2, item2]) => {
|
|
1939
2588
|
optionIndex += 1;
|
|
1940
2589
|
const i = optionIndex;
|
|
1941
2590
|
return /* @__PURE__ */ jsxs(Fragment$1, { children: [
|
|
1942
|
-
header2 !== null ? /* @__PURE__ */ jsx("div", { className: styles$
|
|
2591
|
+
header2 !== null ? /* @__PURE__ */ jsx("div", { className: styles$a.groupLabel, "aria-hidden": "true", children: header2 }) : null,
|
|
1943
2592
|
/* @__PURE__ */ jsxs(
|
|
1944
2593
|
"button",
|
|
1945
2594
|
{
|
|
@@ -1947,7 +2596,7 @@ const SlashMenuPopup = forwardRef(function SlashMenuPopup2({ items, query, menuL
|
|
|
1947
2596
|
role: "option",
|
|
1948
2597
|
"aria-selected": i === index,
|
|
1949
2598
|
title: item2.title,
|
|
1950
|
-
className: i === index ? styles$
|
|
2599
|
+
className: i === index ? styles$a.itemActive : styles$a.item,
|
|
1951
2600
|
tabIndex: -1,
|
|
1952
2601
|
onMouseEnter: () => setIndex(i),
|
|
1953
2602
|
onMouseDown: (e2) => {
|
|
@@ -1955,8 +2604,8 @@ const SlashMenuPopup = forwardRef(function SlashMenuPopup2({ items, query, menuL
|
|
|
1955
2604
|
command(item2);
|
|
1956
2605
|
},
|
|
1957
2606
|
children: [
|
|
1958
|
-
item2.icon != null ? /* @__PURE__ */ jsx("span", { className: styles$
|
|
1959
|
-
/* @__PURE__ */ jsx("span", { className: styles$
|
|
2607
|
+
item2.icon != null ? /* @__PURE__ */ jsx("span", { className: styles$a.itemIcon, "aria-hidden": "true", children: item2.icon }) : /* @__PURE__ */ jsx("span", { className: styles$a.itemIcon, "aria-hidden": "true" }),
|
|
2608
|
+
/* @__PURE__ */ jsx("span", { className: styles$a.itemTitle, children: item2.title })
|
|
1960
2609
|
]
|
|
1961
2610
|
}
|
|
1962
2611
|
)
|
|
@@ -1969,14 +2618,10 @@ function isComposing(event, view) {
|
|
|
1969
2618
|
const SlashMenu = Extension.create({
|
|
1970
2619
|
name: "slashMenu",
|
|
1971
2620
|
addOptions() {
|
|
1972
|
-
return { items: void 0
|
|
2621
|
+
return { items: void 0 };
|
|
1973
2622
|
},
|
|
1974
2623
|
addProseMirrorPlugins() {
|
|
1975
|
-
const { items: extraItems
|
|
1976
|
-
const allItems = [
|
|
1977
|
-
...createDefaultSlashMenuItems({ ...defaultSlashMenuLabels, ...labels }),
|
|
1978
|
-
...extraItems ?? []
|
|
1979
|
-
];
|
|
2624
|
+
const { items: extraItems } = this.options;
|
|
1980
2625
|
let renderer = null;
|
|
1981
2626
|
let unmountPopup = null;
|
|
1982
2627
|
return [
|
|
@@ -1989,14 +2634,19 @@ const SlashMenu = Extension.create({
|
|
|
1989
2634
|
allowSpaces: false,
|
|
1990
2635
|
decorationClass: "tmr-slash-suggestion",
|
|
1991
2636
|
decorationEmptyClass: "tmr-slash-suggestion-empty",
|
|
1992
|
-
items: ({ query }) => filterSlashItems(
|
|
2637
|
+
items: ({ editor, query }) => filterSlashItems(
|
|
2638
|
+
[
|
|
2639
|
+
...createDefaultSlashMenuItems(getEditorLocale(editor)),
|
|
2640
|
+
...extraItems ?? []
|
|
2641
|
+
],
|
|
2642
|
+
query
|
|
2643
|
+
),
|
|
1993
2644
|
command: ({ editor, range, props: item2 }) => {
|
|
1994
2645
|
item2.apply(editor, range);
|
|
1995
2646
|
},
|
|
1996
2647
|
allow: ({ editor }) => editor.isEditable && !editor.isActive("codeBlock"),
|
|
1997
2648
|
render: () => ({
|
|
1998
2649
|
onStart: (props) => {
|
|
1999
|
-
var _a;
|
|
2000
2650
|
renderer = new ReactRenderer(
|
|
2001
2651
|
SlashMenuPopup,
|
|
2002
2652
|
{
|
|
@@ -2004,10 +2654,10 @@ const SlashMenu = Extension.create({
|
|
|
2004
2654
|
props: {
|
|
2005
2655
|
items: props.items,
|
|
2006
2656
|
query: props.query,
|
|
2007
|
-
menuLabel: (
|
|
2657
|
+
menuLabel: getEditorBundle(props.editor).slashMenu.menuLabel,
|
|
2008
2658
|
command: props.command
|
|
2009
2659
|
},
|
|
2010
|
-
className: styles$
|
|
2660
|
+
className: styles$a.popupHost
|
|
2011
2661
|
}
|
|
2012
2662
|
);
|
|
2013
2663
|
const pmStyle = getComputedStyle(props.editor.view.dom);
|
|
@@ -2026,6 +2676,7 @@ const SlashMenu = Extension.create({
|
|
|
2026
2676
|
renderer == null ? void 0 : renderer.updateProps({
|
|
2027
2677
|
items: props.items,
|
|
2028
2678
|
query: props.query,
|
|
2679
|
+
menuLabel: getEditorBundle(props.editor).slashMenu.menuLabel,
|
|
2029
2680
|
command: props.command
|
|
2030
2681
|
});
|
|
2031
2682
|
},
|
|
@@ -2059,7 +2710,7 @@ const rowKeys = "_rowKeys_ljnq6_127";
|
|
|
2059
2710
|
const rowMd = "_rowMd_ljnq6_128";
|
|
2060
2711
|
const keycap = "_keycap_ljnq6_138";
|
|
2061
2712
|
const none = "_none_ljnq6_163";
|
|
2062
|
-
const styles$
|
|
2713
|
+
const styles$9 = {
|
|
2063
2714
|
drawer,
|
|
2064
2715
|
closeBtn,
|
|
2065
2716
|
head,
|
|
@@ -2075,7 +2726,8 @@ const styles$8 = {
|
|
|
2075
2726
|
keycap,
|
|
2076
2727
|
none
|
|
2077
2728
|
};
|
|
2078
|
-
function buildShortcutGroups(
|
|
2729
|
+
function buildShortcutGroups(locale = "en") {
|
|
2730
|
+
const labels = getLocaleBundle(locale).shortcut;
|
|
2079
2731
|
return [
|
|
2080
2732
|
{
|
|
2081
2733
|
id: "format",
|
|
@@ -2087,6 +2739,9 @@ function buildShortcutGroups(labels) {
|
|
|
2087
2739
|
{ id: "underline", label: labels.underline, keys: ["Mod", "u"] },
|
|
2088
2740
|
{ id: "inline-code", label: labels.inlineCode, keys: ["Mod", "e"], markdown: { marker: "`x`" } },
|
|
2089
2741
|
{ id: "highlight", label: labels.highlight, keys: ["Mod", "Shift", "h"], markdown: { marker: "==x==" } },
|
|
2742
|
+
{ id: "smart-quote", label: labels.smartQuote, markdown: { marker: '"' } },
|
|
2743
|
+
{ id: "ellipsis", label: labels.ellipsis, markdown: { marker: "..." } },
|
|
2744
|
+
{ id: "em-dash", label: labels.emDash, markdown: { marker: "--" } },
|
|
2090
2745
|
{ id: "align-left", label: labels.alignLeft, keys: ["Mod", "Shift", "l"] },
|
|
2091
2746
|
{ id: "align-center", label: labels.alignCenter, keys: ["Mod", "Shift", "e"] },
|
|
2092
2747
|
{ id: "align-right", label: labels.alignRight, keys: ["Mod", "Shift", "r"] },
|
|
@@ -2110,7 +2765,8 @@ function buildShortcutGroups(labels) {
|
|
|
2110
2765
|
{ id: "ordered-list", label: labels.orderedList, keys: ["Mod", "Shift", "7"], markdown: { marker: "1.", terminator: "Space" } },
|
|
2111
2766
|
{ id: "task-list", label: labels.taskList, markdown: { marker: "[]", terminator: "Space" } },
|
|
2112
2767
|
{ id: "code-block", label: labels.codeBlock, markdown: { marker: "```", terminator: "Space" } },
|
|
2113
|
-
{ id: "divider", label: labels.divider, markdown: { marker: "---", terminator: "Space" } }
|
|
2768
|
+
{ id: "divider", label: labels.divider, markdown: { marker: "---", terminator: "Space" } },
|
|
2769
|
+
{ id: "emoji", label: labels.emoji, markdown: { marker: ":smile:" } }
|
|
2114
2770
|
]
|
|
2115
2771
|
},
|
|
2116
2772
|
{
|
|
@@ -2135,11 +2791,12 @@ function keycapText(key, mac) {
|
|
|
2135
2791
|
if (/^[a-z]$/.test(key)) return key.toUpperCase();
|
|
2136
2792
|
return key;
|
|
2137
2793
|
}
|
|
2138
|
-
function ShortcutPanel({
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2794
|
+
function ShortcutPanel({
|
|
2795
|
+
open,
|
|
2796
|
+
onClose,
|
|
2797
|
+
locale = "en"
|
|
2798
|
+
}) {
|
|
2799
|
+
const t = getLocaleBundle(locale).shortcut;
|
|
2143
2800
|
useEffect(() => {
|
|
2144
2801
|
if (!open) return;
|
|
2145
2802
|
const onKey = (e2) => {
|
|
@@ -2149,15 +2806,15 @@ function ShortcutPanel({ open, onClose, labels }) {
|
|
|
2149
2806
|
return () => document.removeEventListener("keydown", onKey);
|
|
2150
2807
|
}, [open, onClose]);
|
|
2151
2808
|
const groups = useMemo(
|
|
2152
|
-
() => open ? buildShortcutGroups(
|
|
2153
|
-
[open,
|
|
2809
|
+
() => open ? buildShortcutGroups(locale) : [],
|
|
2810
|
+
[open, locale]
|
|
2154
2811
|
);
|
|
2155
2812
|
const mac = useMemo(isMacPlatform, []);
|
|
2156
2813
|
if (!open) return null;
|
|
2157
2814
|
return /* @__PURE__ */ jsxs(
|
|
2158
2815
|
"aside",
|
|
2159
2816
|
{
|
|
2160
|
-
className: styles$
|
|
2817
|
+
className: styles$9.drawer,
|
|
2161
2818
|
role: "dialog",
|
|
2162
2819
|
"aria-modal": "false",
|
|
2163
2820
|
"aria-label": t.panelTitle,
|
|
@@ -2166,27 +2823,27 @@ function ShortcutPanel({ open, onClose, labels }) {
|
|
|
2166
2823
|
"button",
|
|
2167
2824
|
{
|
|
2168
2825
|
type: "button",
|
|
2169
|
-
className: styles$
|
|
2826
|
+
className: styles$9.closeBtn,
|
|
2170
2827
|
title: t.close,
|
|
2171
2828
|
"aria-label": t.close,
|
|
2172
2829
|
onClick: onClose,
|
|
2173
2830
|
children: /* @__PURE__ */ jsx(XIcon, { size: 16 })
|
|
2174
2831
|
}
|
|
2175
2832
|
),
|
|
2176
|
-
/* @__PURE__ */ jsxs("div", { className: styles$
|
|
2177
|
-
/* @__PURE__ */ jsx("span", { className: styles$
|
|
2178
|
-
/* @__PURE__ */ jsx("span", { className: styles$
|
|
2179
|
-
/* @__PURE__ */ jsx("span", { className: styles$
|
|
2833
|
+
/* @__PURE__ */ jsxs("div", { className: styles$9.head, children: [
|
|
2834
|
+
/* @__PURE__ */ jsx("span", { className: styles$9.colFormat, children: t.colFormat }),
|
|
2835
|
+
/* @__PURE__ */ jsx("span", { className: styles$9.colShortcut, children: t.colShortcut }),
|
|
2836
|
+
/* @__PURE__ */ jsx("span", { className: styles$9.colMarkdown, children: t.colMarkdown })
|
|
2180
2837
|
] }),
|
|
2181
|
-
/* @__PURE__ */ jsx("div", { className: styles$
|
|
2182
|
-
/* @__PURE__ */ jsx("h3", { className: styles$
|
|
2183
|
-
group2.entries.map((entry) => /* @__PURE__ */ jsxs("div", { className: styles$
|
|
2184
|
-
/* @__PURE__ */ jsx("span", { className: styles$
|
|
2185
|
-
/* @__PURE__ */ jsx("span", { className: styles$
|
|
2186
|
-
/* @__PURE__ */ jsx("span", { className: styles$
|
|
2187
|
-
/* @__PURE__ */ jsx("kbd", { className: styles$
|
|
2188
|
-
entry.markdown.terminator ? /* @__PURE__ */ jsx("kbd", { className: styles$
|
|
2189
|
-
] }) : /* @__PURE__ */ jsx("span", { className: styles$
|
|
2838
|
+
/* @__PURE__ */ jsx("div", { className: styles$9.body, children: groups.map((group2) => /* @__PURE__ */ jsxs("section", { className: styles$9.group, children: [
|
|
2839
|
+
/* @__PURE__ */ jsx("h3", { className: styles$9.groupTitle, children: group2.title }),
|
|
2840
|
+
group2.entries.map((entry) => /* @__PURE__ */ jsxs("div", { className: styles$9.row, children: [
|
|
2841
|
+
/* @__PURE__ */ jsx("span", { className: styles$9.rowLabel, children: entry.label }),
|
|
2842
|
+
/* @__PURE__ */ jsx("span", { className: styles$9.rowKeys, children: entry.keys ? entry.keys.map((key, i) => /* @__PURE__ */ jsx("kbd", { className: styles$9.keycap, children: keycapText(key, mac) }, i)) : /* @__PURE__ */ jsx("span", { className: styles$9.none, children: "—" }) }),
|
|
2843
|
+
/* @__PURE__ */ jsx("span", { className: styles$9.rowMd, children: entry.markdown ? /* @__PURE__ */ jsxs(Fragment$2, { children: [
|
|
2844
|
+
/* @__PURE__ */ jsx("kbd", { className: styles$9.keycap, children: entry.markdown.marker }),
|
|
2845
|
+
entry.markdown.terminator ? /* @__PURE__ */ jsx("kbd", { className: styles$9.keycap, children: entry.markdown.terminator }) : null
|
|
2846
|
+
] }) : /* @__PURE__ */ jsx("span", { className: styles$9.none, children: "—" }) })
|
|
2190
2847
|
] }, entry.id))
|
|
2191
2848
|
] }, group2.id)) })
|
|
2192
2849
|
]
|
|
@@ -2270,8 +2927,8 @@ function setPendingAnchors(editor, anchors) {
|
|
|
2270
2927
|
}
|
|
2271
2928
|
function buildDecorations(doc, anchors) {
|
|
2272
2929
|
const bounds = [];
|
|
2273
|
-
doc.forEach((child,
|
|
2274
|
-
bounds.push({ from:
|
|
2930
|
+
doc.forEach((child, offset2) => {
|
|
2931
|
+
bounds.push({ from: offset2, to: offset2 + child.nodeSize });
|
|
2275
2932
|
});
|
|
2276
2933
|
const decorations = [];
|
|
2277
2934
|
for (const anchor of anchors) {
|
|
@@ -2363,6 +3020,7 @@ function ChartView({
|
|
|
2363
3020
|
const canvasRef = useRef(null);
|
|
2364
3021
|
const chartRef = useRef(null);
|
|
2365
3022
|
const [active2, setActive2] = useState(0);
|
|
3023
|
+
const labels = useEditorBundle(editor).chart;
|
|
2366
3024
|
const payload = useMemo(
|
|
2367
3025
|
() => ({
|
|
2368
3026
|
config: node.attrs.config ?? [],
|
|
@@ -2407,10 +3065,6 @@ function ChartView({
|
|
|
2407
3065
|
chart: null
|
|
2408
3066
|
});
|
|
2409
3067
|
}, [safeIndex]);
|
|
2410
|
-
const labels = {
|
|
2411
|
-
...defaultChartLabels,
|
|
2412
|
-
...extension.options.chartLabels
|
|
2413
|
-
};
|
|
2414
3068
|
const selectChart = () => {
|
|
2415
3069
|
if (!editor || !canSelect) return;
|
|
2416
3070
|
const pos = getPos();
|
|
@@ -2456,14 +3110,13 @@ function ChartView({
|
|
|
2456
3110
|
);
|
|
2457
3111
|
}
|
|
2458
3112
|
function createChart(options = {}) {
|
|
2459
|
-
const { editable = false, chartTheme = null
|
|
3113
|
+
const { editable = false, chartTheme = null } = options;
|
|
2460
3114
|
return reportChart.extend({
|
|
2461
3115
|
addOptions() {
|
|
2462
3116
|
return {
|
|
2463
3117
|
HTMLAttributes: {},
|
|
2464
3118
|
chartEditable: editable,
|
|
2465
|
-
chartTheme
|
|
2466
|
-
chartLabels
|
|
3119
|
+
chartTheme
|
|
2467
3120
|
};
|
|
2468
3121
|
},
|
|
2469
3122
|
addNodeView() {
|
|
@@ -2490,7 +3143,7 @@ const gutterLine = "_gutterLine_k8th1_184";
|
|
|
2490
3143
|
const readonlyActions = "_readonlyActions_k8th1_188";
|
|
2491
3144
|
const actionBtn = "_actionBtn_k8th1_194";
|
|
2492
3145
|
const langBraces = "_langBraces_k8th1_213";
|
|
2493
|
-
const styles$
|
|
3146
|
+
const styles$8 = {
|
|
2494
3147
|
wrapper,
|
|
2495
3148
|
header: header$1,
|
|
2496
3149
|
langTrigger,
|
|
@@ -2535,14 +3188,9 @@ function CodeBlockView({
|
|
|
2535
3188
|
node,
|
|
2536
3189
|
updateAttributes,
|
|
2537
3190
|
deleteNode,
|
|
2538
|
-
extension,
|
|
2539
3191
|
editor
|
|
2540
3192
|
}) {
|
|
2541
|
-
|
|
2542
|
-
const labels = {
|
|
2543
|
-
...defaultCodeBlockLabels,
|
|
2544
|
-
...((_a = extension == null ? void 0 : extension.options) == null ? void 0 : _a.codeBlockLabels) ?? {}
|
|
2545
|
-
};
|
|
3193
|
+
const labels = useEditorBundle(editor).codeBlock;
|
|
2546
3194
|
const language = node.attrs.language || "";
|
|
2547
3195
|
const current = LANGUAGES.find((l) => l.value === language);
|
|
2548
3196
|
const currentLabel = current ? current.value === "" ? labels.autoDetect : current.label : labels.autoDetect;
|
|
@@ -2567,13 +3215,13 @@ function CodeBlockView({
|
|
|
2567
3215
|
return () => mo.disconnect();
|
|
2568
3216
|
}, [readonly2]);
|
|
2569
3217
|
const handleCopy = () => {
|
|
2570
|
-
var
|
|
3218
|
+
var _a;
|
|
2571
3219
|
const text2 = node.textContent ?? "";
|
|
2572
3220
|
const done = () => {
|
|
2573
3221
|
setCopied(true);
|
|
2574
3222
|
window.setTimeout(() => setCopied(false), 1500);
|
|
2575
3223
|
};
|
|
2576
|
-
if ((
|
|
3224
|
+
if ((_a = navigator.clipboard) == null ? void 0 : _a.writeText) {
|
|
2577
3225
|
navigator.clipboard.writeText(text2).then(done, () => {
|
|
2578
3226
|
});
|
|
2579
3227
|
return;
|
|
@@ -2590,117 +3238,890 @@ function CodeBlockView({
|
|
|
2590
3238
|
ta.remove();
|
|
2591
3239
|
};
|
|
2592
3240
|
const wrapperClass = [
|
|
2593
|
-
styles$
|
|
2594
|
-
readonly2 ? styles$
|
|
2595
|
-
folded2 ? styles$
|
|
3241
|
+
styles$8.wrapper,
|
|
3242
|
+
readonly2 ? styles$8.readonly : "",
|
|
3243
|
+
folded2 ? styles$8.folded : ""
|
|
2596
3244
|
].filter(Boolean).join(" ");
|
|
2597
3245
|
return /* @__PURE__ */ jsxs(NodeViewWrapper, { className: wrapperClass, children: [
|
|
2598
|
-
editable ? /* @__PURE__ */ jsxs("div", { className: styles$
|
|
3246
|
+
editable ? /* @__PURE__ */ jsxs("div", { className: styles$8.header, contentEditable: false, children: [
|
|
2599
3247
|
/* @__PURE__ */ jsxs(DropdownMenu.Root, { children: [
|
|
2600
3248
|
/* @__PURE__ */ jsx(DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs(
|
|
2601
3249
|
"button",
|
|
2602
3250
|
{
|
|
2603
3251
|
type: "button",
|
|
2604
|
-
className: styles$
|
|
2605
|
-
"aria-label":
|
|
3252
|
+
className: styles$8.langTrigger,
|
|
3253
|
+
"aria-label": labels.language,
|
|
2606
3254
|
children: [
|
|
2607
3255
|
/* @__PURE__ */ jsx("span", { children: currentLabel }),
|
|
2608
|
-
/* @__PURE__ */ jsx(ChevronDownIcon, { size: 14, className: styles$
|
|
3256
|
+
/* @__PURE__ */ jsx(ChevronDownIcon, { size: 14, className: styles$8.langChevron })
|
|
2609
3257
|
]
|
|
2610
3258
|
}
|
|
2611
3259
|
) }),
|
|
2612
3260
|
/* @__PURE__ */ jsx(DropdownMenu.Portal, { children: /* @__PURE__ */ jsx(
|
|
2613
3261
|
DropdownMenu.Content,
|
|
2614
3262
|
{
|
|
2615
|
-
className: styles$
|
|
2616
|
-
sideOffset: 4,
|
|
2617
|
-
align: "end",
|
|
2618
|
-
children: LANGUAGES.map((l) => {
|
|
2619
|
-
const optionLabel = l.value === "" ? labels.autoDetect : l.label;
|
|
2620
|
-
const selected = l.value === language;
|
|
2621
|
-
return /* @__PURE__ */ jsxs(
|
|
2622
|
-
DropdownMenu.Item,
|
|
2623
|
-
{
|
|
2624
|
-
className: `${styles$
|
|
2625
|
-
onSelect: () => updateAttributes({ language: l.value }),
|
|
2626
|
-
children: [
|
|
2627
|
-
/* @__PURE__ */ jsx("span", { className: styles$
|
|
2628
|
-
optionLabel
|
|
2629
|
-
]
|
|
3263
|
+
className: styles$8.langMenu,
|
|
3264
|
+
sideOffset: 4,
|
|
3265
|
+
align: "end",
|
|
3266
|
+
children: LANGUAGES.map((l) => {
|
|
3267
|
+
const optionLabel = l.value === "" ? labels.autoDetect : l.label;
|
|
3268
|
+
const selected = l.value === language;
|
|
3269
|
+
return /* @__PURE__ */ jsxs(
|
|
3270
|
+
DropdownMenu.Item,
|
|
3271
|
+
{
|
|
3272
|
+
className: `${styles$8.langItem}${selected ? ` ${styles$8.langItemSelected}` : ""}`,
|
|
3273
|
+
onSelect: () => updateAttributes({ language: l.value }),
|
|
3274
|
+
children: [
|
|
3275
|
+
/* @__PURE__ */ jsx("span", { className: styles$8.langItemCheck, children: selected ? /* @__PURE__ */ jsx(CheckIcon, { size: 14 }) : null }),
|
|
3276
|
+
optionLabel
|
|
3277
|
+
]
|
|
3278
|
+
},
|
|
3279
|
+
l.value
|
|
3280
|
+
);
|
|
3281
|
+
})
|
|
3282
|
+
}
|
|
3283
|
+
) })
|
|
3284
|
+
] }),
|
|
3285
|
+
/* @__PURE__ */ jsx(
|
|
3286
|
+
"button",
|
|
3287
|
+
{
|
|
3288
|
+
type: "button",
|
|
3289
|
+
className: styles$8.deleteBtn,
|
|
3290
|
+
title: labels.delete,
|
|
3291
|
+
"aria-label": labels.delete,
|
|
3292
|
+
onClick: () => deleteNode(),
|
|
3293
|
+
children: /* @__PURE__ */ jsx(TrashIcon, {})
|
|
3294
|
+
}
|
|
3295
|
+
)
|
|
3296
|
+
] }) : (
|
|
3297
|
+
// 只读头部:左侧语言标签,右侧复制 + 展开收起(展开后按钮保留,供收回)
|
|
3298
|
+
/* @__PURE__ */ jsxs("div", { className: styles$8.readonlyHeader, contentEditable: false, children: [
|
|
3299
|
+
/* @__PURE__ */ jsxs("span", { className: styles$8.langBadge, children: [
|
|
3300
|
+
/* @__PURE__ */ jsx("span", { className: styles$8.langBraces, children: "{}" }),
|
|
3301
|
+
currentLabel
|
|
3302
|
+
] }),
|
|
3303
|
+
/* @__PURE__ */ jsxs("span", { className: styles$8.readonlyActions, children: [
|
|
3304
|
+
/* @__PURE__ */ jsx(
|
|
3305
|
+
"button",
|
|
3306
|
+
{
|
|
3307
|
+
type: "button",
|
|
3308
|
+
className: styles$8.actionBtn,
|
|
3309
|
+
onClick: handleCopy,
|
|
3310
|
+
"aria-label": labels.copy,
|
|
3311
|
+
title: labels.copy,
|
|
3312
|
+
children: copied ? /* @__PURE__ */ jsx(CheckIcon, { size: 14 }) : /* @__PURE__ */ jsx(CopyIcon, { size: 14 })
|
|
3313
|
+
}
|
|
3314
|
+
),
|
|
3315
|
+
/* @__PURE__ */ jsx(
|
|
3316
|
+
"button",
|
|
3317
|
+
{
|
|
3318
|
+
type: "button",
|
|
3319
|
+
className: styles$8.actionBtn,
|
|
3320
|
+
onClick: () => setFolded((v) => !v),
|
|
3321
|
+
"aria-label": folded2 ? labels.expand : labels.collapse,
|
|
3322
|
+
title: folded2 ? labels.expand : labels.collapse,
|
|
3323
|
+
"aria-expanded": !folded2,
|
|
3324
|
+
children: /* @__PURE__ */ jsx(ChevronsUpDownIcon, { size: 14 })
|
|
3325
|
+
}
|
|
3326
|
+
)
|
|
3327
|
+
] })
|
|
3328
|
+
] })
|
|
3329
|
+
),
|
|
3330
|
+
/* @__PURE__ */ jsxs("pre", { ref: preRef, className: styles$8.pre, children: [
|
|
3331
|
+
readonly2 ? /* @__PURE__ */ jsx(
|
|
3332
|
+
"span",
|
|
3333
|
+
{
|
|
3334
|
+
className: styles$8.gutter,
|
|
3335
|
+
contentEditable: false,
|
|
3336
|
+
"aria-hidden": "true",
|
|
3337
|
+
children: Array.from({ length: lineCount }, (_, i) => /* @__PURE__ */ jsx("span", { className: styles$8.gutterLine, children: i + 1 }, i))
|
|
3338
|
+
}
|
|
3339
|
+
) : null,
|
|
3340
|
+
/* @__PURE__ */ jsx(NodeViewContent, { as: "code" })
|
|
3341
|
+
] })
|
|
3342
|
+
] });
|
|
3343
|
+
}
|
|
3344
|
+
function evaluate(value, param) {
|
|
3345
|
+
return typeof value === "function" ? value(param) : value;
|
|
3346
|
+
}
|
|
3347
|
+
function getSide(placement) {
|
|
3348
|
+
return placement.split("-")[0];
|
|
3349
|
+
}
|
|
3350
|
+
function getAlignment(placement) {
|
|
3351
|
+
return placement.split("-")[1];
|
|
3352
|
+
}
|
|
3353
|
+
function getSideAxis(placement) {
|
|
3354
|
+
const firstChar = placement[0];
|
|
3355
|
+
return firstChar === "t" || firstChar === "b" ? "y" : "x";
|
|
3356
|
+
}
|
|
3357
|
+
const originSides = /* @__PURE__ */ new Set(["left", "top"]);
|
|
3358
|
+
async function convertValueToCoords(state, options) {
|
|
3359
|
+
const {
|
|
3360
|
+
placement,
|
|
3361
|
+
platform,
|
|
3362
|
+
elements
|
|
3363
|
+
} = state;
|
|
3364
|
+
const rtl = await (platform.isRTL == null ? void 0 : platform.isRTL(elements.floating));
|
|
3365
|
+
const side = getSide(placement);
|
|
3366
|
+
const alignment = getAlignment(placement);
|
|
3367
|
+
const isVertical = getSideAxis(placement) === "y";
|
|
3368
|
+
const mainAxisMulti = originSides.has(side) ? -1 : 1;
|
|
3369
|
+
const crossAxisMulti = rtl && isVertical ? -1 : 1;
|
|
3370
|
+
const rawValue = evaluate(options, state);
|
|
3371
|
+
let {
|
|
3372
|
+
mainAxis,
|
|
3373
|
+
crossAxis,
|
|
3374
|
+
alignmentAxis
|
|
3375
|
+
} = typeof rawValue === "number" ? {
|
|
3376
|
+
mainAxis: rawValue,
|
|
3377
|
+
crossAxis: 0,
|
|
3378
|
+
alignmentAxis: null
|
|
3379
|
+
} : {
|
|
3380
|
+
mainAxis: rawValue.mainAxis || 0,
|
|
3381
|
+
crossAxis: rawValue.crossAxis || 0,
|
|
3382
|
+
alignmentAxis: rawValue.alignmentAxis
|
|
3383
|
+
};
|
|
3384
|
+
if (alignment && typeof alignmentAxis === "number") {
|
|
3385
|
+
crossAxis = alignment === "end" ? alignmentAxis * -1 : alignmentAxis;
|
|
3386
|
+
}
|
|
3387
|
+
return isVertical ? {
|
|
3388
|
+
x: crossAxis * crossAxisMulti,
|
|
3389
|
+
y: mainAxis * mainAxisMulti
|
|
3390
|
+
} : {
|
|
3391
|
+
x: mainAxis * mainAxisMulti,
|
|
3392
|
+
y: crossAxis * crossAxisMulti
|
|
3393
|
+
};
|
|
3394
|
+
}
|
|
3395
|
+
const offset$1 = function(options) {
|
|
3396
|
+
if (options === void 0) {
|
|
3397
|
+
options = 0;
|
|
3398
|
+
}
|
|
3399
|
+
return {
|
|
3400
|
+
name: "offset",
|
|
3401
|
+
options,
|
|
3402
|
+
async fn(state) {
|
|
3403
|
+
var _middlewareData$offse, _middlewareData$arrow;
|
|
3404
|
+
const {
|
|
3405
|
+
x,
|
|
3406
|
+
y,
|
|
3407
|
+
placement,
|
|
3408
|
+
middlewareData
|
|
3409
|
+
} = state;
|
|
3410
|
+
const diffCoords = await convertValueToCoords(state, options);
|
|
3411
|
+
if (placement === ((_middlewareData$offse = middlewareData.offset) == null ? void 0 : _middlewareData$offse.placement) && (_middlewareData$arrow = middlewareData.arrow) != null && _middlewareData$arrow.alignmentOffset) {
|
|
3412
|
+
return {};
|
|
3413
|
+
}
|
|
3414
|
+
return {
|
|
3415
|
+
x: x + diffCoords.x,
|
|
3416
|
+
y: y + diffCoords.y,
|
|
3417
|
+
data: {
|
|
3418
|
+
...diffCoords,
|
|
3419
|
+
placement
|
|
3420
|
+
}
|
|
3421
|
+
};
|
|
3422
|
+
}
|
|
3423
|
+
};
|
|
3424
|
+
};
|
|
3425
|
+
const offset = offset$1;
|
|
3426
|
+
const TURN_INTO_KINDS = [
|
|
3427
|
+
"paragraph",
|
|
3428
|
+
"heading-1",
|
|
3429
|
+
"heading-2",
|
|
3430
|
+
"heading-3",
|
|
3431
|
+
"bulletList",
|
|
3432
|
+
"orderedList",
|
|
3433
|
+
"taskList",
|
|
3434
|
+
"blockquote",
|
|
3435
|
+
"codeBlock"
|
|
3436
|
+
];
|
|
3437
|
+
const TURNABLE = /* @__PURE__ */ new Set([
|
|
3438
|
+
"paragraph",
|
|
3439
|
+
"heading",
|
|
3440
|
+
"bulletList",
|
|
3441
|
+
"orderedList",
|
|
3442
|
+
"taskList",
|
|
3443
|
+
"listItem",
|
|
3444
|
+
"taskItem",
|
|
3445
|
+
"blockquote",
|
|
3446
|
+
"codeBlock"
|
|
3447
|
+
]);
|
|
3448
|
+
const LIFT_BEFORE_TURN = /* @__PURE__ */ new Set([
|
|
3449
|
+
"listItem",
|
|
3450
|
+
"taskItem",
|
|
3451
|
+
"bulletList",
|
|
3452
|
+
"orderedList",
|
|
3453
|
+
"taskList",
|
|
3454
|
+
"blockquote",
|
|
3455
|
+
"codeBlock"
|
|
3456
|
+
]);
|
|
3457
|
+
function canTurnBlockInto(node) {
|
|
3458
|
+
return !!node && TURNABLE.has(node.type.name);
|
|
3459
|
+
}
|
|
3460
|
+
function currentTurnIntoKind(editor, pos, node) {
|
|
3461
|
+
const name = node.type.name;
|
|
3462
|
+
if (name === "paragraph") return "paragraph";
|
|
3463
|
+
if (name === "heading") {
|
|
3464
|
+
const level = Number(node.attrs.level);
|
|
3465
|
+
if (level === 1 || level === 2 || level === 3) {
|
|
3466
|
+
return `heading-${level}`;
|
|
3467
|
+
}
|
|
3468
|
+
return null;
|
|
3469
|
+
}
|
|
3470
|
+
if (name === "bulletList") return "bulletList";
|
|
3471
|
+
if (name === "orderedList") return "orderedList";
|
|
3472
|
+
if (name === "taskList") return "taskList";
|
|
3473
|
+
if (name === "blockquote") return "blockquote";
|
|
3474
|
+
if (name === "codeBlock") return "codeBlock";
|
|
3475
|
+
if (name === "listItem" || name === "taskItem") {
|
|
3476
|
+
const parent = editor.state.doc.resolve(pos).parent.type.name;
|
|
3477
|
+
if (parent === "bulletList") return "bulletList";
|
|
3478
|
+
if (parent === "orderedList") return "orderedList";
|
|
3479
|
+
if (parent === "taskList") return "taskList";
|
|
3480
|
+
}
|
|
3481
|
+
return null;
|
|
3482
|
+
}
|
|
3483
|
+
function firstTextPos(node, pos) {
|
|
3484
|
+
if (node.isTextblock) return pos + 1;
|
|
3485
|
+
let found = null;
|
|
3486
|
+
node.descendants((child, offset2) => {
|
|
3487
|
+
if (found != null) return false;
|
|
3488
|
+
if (child.isTextblock) {
|
|
3489
|
+
found = pos + 1 + offset2 + 1;
|
|
3490
|
+
return false;
|
|
3491
|
+
}
|
|
3492
|
+
return true;
|
|
3493
|
+
});
|
|
3494
|
+
return found;
|
|
3495
|
+
}
|
|
3496
|
+
function turnBlockInto(editor, pos, kind) {
|
|
3497
|
+
const node = editor.state.doc.nodeAt(pos);
|
|
3498
|
+
if (!node || !canTurnBlockInto(node)) return false;
|
|
3499
|
+
const textPos = firstTextPos(node, pos);
|
|
3500
|
+
if (textPos == null) return false;
|
|
3501
|
+
const chain = editor.chain().setTextSelection(textPos);
|
|
3502
|
+
if (LIFT_BEFORE_TURN.has(node.type.name)) chain.clearNodes();
|
|
3503
|
+
if (kind === "heading-1" || kind === "heading-2" || kind === "heading-3") {
|
|
3504
|
+
const level = Number(kind.slice(-1));
|
|
3505
|
+
chain.setHeading({ level });
|
|
3506
|
+
} else if (kind === "paragraph") {
|
|
3507
|
+
if (!LIFT_BEFORE_TURN.has(node.type.name)) chain.setParagraph();
|
|
3508
|
+
} else if (kind === "bulletList") {
|
|
3509
|
+
chain.toggleBulletList();
|
|
3510
|
+
} else if (kind === "orderedList") {
|
|
3511
|
+
chain.toggleOrderedList();
|
|
3512
|
+
} else if (kind === "taskList") {
|
|
3513
|
+
chain.toggleTaskList();
|
|
3514
|
+
} else if (kind === "blockquote") {
|
|
3515
|
+
chain.toggleBlockquote();
|
|
3516
|
+
} else if (kind === "codeBlock") {
|
|
3517
|
+
chain.setCodeBlock();
|
|
3518
|
+
}
|
|
3519
|
+
return chain.run();
|
|
3520
|
+
}
|
|
3521
|
+
function duplicateBlock(editor, pos) {
|
|
3522
|
+
const node = editor.state.doc.nodeAt(pos);
|
|
3523
|
+
if (!node) return false;
|
|
3524
|
+
return editor.chain().insertContentAt(pos + node.nodeSize, node.toJSON()).run();
|
|
3525
|
+
}
|
|
3526
|
+
function deleteBlock(editor, pos) {
|
|
3527
|
+
const node = editor.state.doc.nodeAt(pos);
|
|
3528
|
+
if (!node) return false;
|
|
3529
|
+
let from = pos;
|
|
3530
|
+
let to = pos + node.nodeSize;
|
|
3531
|
+
const $pos = editor.state.doc.resolve(pos);
|
|
3532
|
+
const parent = $pos.parent;
|
|
3533
|
+
if ((node.type.name === "listItem" || node.type.name === "taskItem") && parent.childCount === 1) {
|
|
3534
|
+
from = pos - $pos.parentOffset - 1;
|
|
3535
|
+
const list2 = editor.state.doc.nodeAt(from);
|
|
3536
|
+
if (list2) to = from + list2.nodeSize;
|
|
3537
|
+
}
|
|
3538
|
+
if (from <= 0 && to >= editor.state.doc.content.size) {
|
|
3539
|
+
return editor.chain().insertContentAt(
|
|
3540
|
+
{ from: 0, to: editor.state.doc.content.size },
|
|
3541
|
+
{ type: "paragraph" }
|
|
3542
|
+
).run();
|
|
3543
|
+
}
|
|
3544
|
+
return editor.chain().deleteRange({ from, to }).run();
|
|
3545
|
+
}
|
|
3546
|
+
function blockMarkdown(editor, pos) {
|
|
3547
|
+
var _a;
|
|
3548
|
+
const node = editor.state.doc.nodeAt(pos);
|
|
3549
|
+
if (!node) return null;
|
|
3550
|
+
const serialized = (_a = editor.markdown) == null ? void 0 : _a.serialize(node.toJSON());
|
|
3551
|
+
if (typeof serialized === "string") return serialized;
|
|
3552
|
+
return node.textContent;
|
|
3553
|
+
}
|
|
3554
|
+
function canResetBlockFormatting(node) {
|
|
3555
|
+
if (!node || node.isAtom) return false;
|
|
3556
|
+
if (node.type.name === "image" || node.type.name === "horizontalRule") {
|
|
3557
|
+
return false;
|
|
3558
|
+
}
|
|
3559
|
+
if (node.isTextblock) return true;
|
|
3560
|
+
let found = false;
|
|
3561
|
+
node.descendants((child) => {
|
|
3562
|
+
if (child.isTextblock) {
|
|
3563
|
+
found = true;
|
|
3564
|
+
return false;
|
|
3565
|
+
}
|
|
3566
|
+
return true;
|
|
3567
|
+
});
|
|
3568
|
+
return found;
|
|
3569
|
+
}
|
|
3570
|
+
function withoutBlockStyles(node) {
|
|
3571
|
+
const next = { ...node.attrs };
|
|
3572
|
+
if ("textAlign" in next) next.textAlign = null;
|
|
3573
|
+
if ("indent" in next) next.indent = null;
|
|
3574
|
+
if ("lineHeight" in next) next.lineHeight = null;
|
|
3575
|
+
return next;
|
|
3576
|
+
}
|
|
3577
|
+
function resetBlockFormatting(editor, pos) {
|
|
3578
|
+
const node = editor.state.doc.nodeAt(pos);
|
|
3579
|
+
if (!node || !canResetBlockFormatting(node)) return false;
|
|
3580
|
+
const from = pos + 1;
|
|
3581
|
+
const to = pos + node.nodeSize - 1;
|
|
3582
|
+
let tr = editor.state.tr;
|
|
3583
|
+
if (to > from) {
|
|
3584
|
+
for (const mark of Object.values(editor.schema.marks)) {
|
|
3585
|
+
tr = tr.removeMark(from, to, mark);
|
|
3586
|
+
}
|
|
3587
|
+
}
|
|
3588
|
+
const markup = [];
|
|
3589
|
+
if (node.isTextblock) {
|
|
3590
|
+
markup.push({ pos, attrs: withoutBlockStyles(node) });
|
|
3591
|
+
}
|
|
3592
|
+
node.descendants((child, offset2) => {
|
|
3593
|
+
if (!child.isTextblock) return;
|
|
3594
|
+
markup.push({
|
|
3595
|
+
pos: pos + 1 + offset2,
|
|
3596
|
+
attrs: withoutBlockStyles(child)
|
|
3597
|
+
});
|
|
3598
|
+
});
|
|
3599
|
+
for (const item2 of markup) {
|
|
3600
|
+
tr = tr.setNodeMarkup(item2.pos, void 0, item2.attrs);
|
|
3601
|
+
}
|
|
3602
|
+
if (!tr.docChanged) return false;
|
|
3603
|
+
editor.view.dispatch(tr);
|
|
3604
|
+
return true;
|
|
3605
|
+
}
|
|
3606
|
+
function isImageBlock(node) {
|
|
3607
|
+
return (node == null ? void 0 : node.type.name) === "image" && typeof node.attrs.src === "string" && node.attrs.src.length > 0;
|
|
3608
|
+
}
|
|
3609
|
+
function downloadImageBlock(node) {
|
|
3610
|
+
var _a;
|
|
3611
|
+
if (!isImageBlock(node)) return;
|
|
3612
|
+
const src = node.attrs.src;
|
|
3613
|
+
const alt = typeof node.attrs.alt === "string" ? node.attrs.alt.trim() : "";
|
|
3614
|
+
const fromUrl = ((_a = src.split("/").pop()) == null ? void 0 : _a.split("?")[0]) ?? "";
|
|
3615
|
+
const a3 = document.createElement("a");
|
|
3616
|
+
a3.href = src;
|
|
3617
|
+
a3.download = alt || fromUrl || "image";
|
|
3618
|
+
a3.rel = "noopener";
|
|
3619
|
+
a3.target = "_blank";
|
|
3620
|
+
document.body.appendChild(a3);
|
|
3621
|
+
a3.click();
|
|
3622
|
+
a3.remove();
|
|
3623
|
+
}
|
|
3624
|
+
const LIST_NAMES = /* @__PURE__ */ new Set(["bulletList", "orderedList", "taskList"]);
|
|
3625
|
+
const draggingViews = /* @__PURE__ */ new WeakSet();
|
|
3626
|
+
const blockDragListGuardKey = new PluginKey("blockDragListGuard");
|
|
3627
|
+
function setBlockHandleDragging(view, dragging) {
|
|
3628
|
+
if (dragging) draggingViews.add(view);
|
|
3629
|
+
else draggingViews.delete(view);
|
|
3630
|
+
}
|
|
3631
|
+
function isBlockHandleDragging(view) {
|
|
3632
|
+
return draggingViews.has(view);
|
|
3633
|
+
}
|
|
3634
|
+
function outermostListDepth(doc, pos) {
|
|
3635
|
+
const safe = Math.max(0, Math.min(pos, doc.content.size));
|
|
3636
|
+
const $pos = doc.resolve(safe);
|
|
3637
|
+
let listDepth = -1;
|
|
3638
|
+
for (let depth = $pos.depth; depth > 0; depth -= 1) {
|
|
3639
|
+
if (LIST_NAMES.has($pos.node(depth).type.name)) listDepth = depth;
|
|
3640
|
+
}
|
|
3641
|
+
return listDepth;
|
|
3642
|
+
}
|
|
3643
|
+
function isPosInsideList(doc, pos) {
|
|
3644
|
+
return outermostListDepth(doc, pos) > 0;
|
|
3645
|
+
}
|
|
3646
|
+
function listEscapeEdge(view, pos, clientY) {
|
|
3647
|
+
const listDepth = outermostListDepth(view.state.doc, pos);
|
|
3648
|
+
if (listDepth < 0) return null;
|
|
3649
|
+
const $pos = view.state.doc.resolve(
|
|
3650
|
+
Math.max(0, Math.min(pos, view.state.doc.content.size))
|
|
3651
|
+
);
|
|
3652
|
+
const start = $pos.before(listDepth);
|
|
3653
|
+
const node = $pos.node(listDepth);
|
|
3654
|
+
const dom = view.nodeDOM(start);
|
|
3655
|
+
let after = pos >= start + node.nodeSize / 2;
|
|
3656
|
+
if (dom instanceof HTMLElement) {
|
|
3657
|
+
const rect = dom.getBoundingClientRect();
|
|
3658
|
+
if (rect.height > 0) after = clientY >= rect.top + rect.height / 2;
|
|
3659
|
+
}
|
|
3660
|
+
return after ? start + node.nodeSize : start;
|
|
3661
|
+
}
|
|
3662
|
+
function moveDraggedSlice(view, slice, insertPos) {
|
|
3663
|
+
const { state } = view;
|
|
3664
|
+
const { from, to } = state.selection;
|
|
3665
|
+
if (insertPos > from && insertPos < to) return true;
|
|
3666
|
+
const tr = state.tr;
|
|
3667
|
+
tr.deleteSelection();
|
|
3668
|
+
const pos = tr.mapping.map(insertPos, 1);
|
|
3669
|
+
const block = slice.openStart === 0 && slice.openEnd === 0 && slice.content.childCount === 1 ? slice.content.firstChild : null;
|
|
3670
|
+
if (block) tr.replaceRangeWith(pos, pos, block);
|
|
3671
|
+
else tr.replaceRange(pos, pos, slice);
|
|
3672
|
+
if (tr.doc.eq(state.doc)) return true;
|
|
3673
|
+
const $pos = tr.doc.resolve(Math.max(0, Math.min(pos, tr.doc.content.size)));
|
|
3674
|
+
const near = TextSelection.findFrom($pos, 1, true) ?? TextSelection.findFrom($pos, -1, true);
|
|
3675
|
+
if (near) tr.setSelection(near);
|
|
3676
|
+
try {
|
|
3677
|
+
view.focus();
|
|
3678
|
+
} catch {
|
|
3679
|
+
}
|
|
3680
|
+
view.dispatch(tr.setMeta("uiEvent", "drop").scrollIntoView());
|
|
3681
|
+
return true;
|
|
3682
|
+
}
|
|
3683
|
+
function snappedListEdge(view, clientX, clientY, slice) {
|
|
3684
|
+
const coords = view.posAtCoords({ left: clientX, top: clientY });
|
|
3685
|
+
if (!coords) return null;
|
|
3686
|
+
const natural = dropPoint(view.state.doc, coords.pos, slice);
|
|
3687
|
+
const probe = natural ?? coords.pos;
|
|
3688
|
+
if (!isPosInsideList(view.state.doc, probe)) return null;
|
|
3689
|
+
return listEscapeEdge(view, probe, clientY);
|
|
3690
|
+
}
|
|
3691
|
+
function placeBlockDropCursor(view, pos) {
|
|
3692
|
+
const parent = view.dom.offsetParent;
|
|
3693
|
+
if (!(parent instanceof HTMLElement)) return;
|
|
3694
|
+
const cursor = parent.querySelector(
|
|
3695
|
+
".prosemirror-dropcursor-block, .prosemirror-dropcursor-inline"
|
|
3696
|
+
);
|
|
3697
|
+
if (!(cursor instanceof HTMLElement)) return;
|
|
3698
|
+
const $pos = view.state.doc.resolve(pos);
|
|
3699
|
+
const before = $pos.nodeBefore;
|
|
3700
|
+
const anchorPos = before ? pos - before.nodeSize : pos;
|
|
3701
|
+
const anchor = view.nodeDOM(anchorPos);
|
|
3702
|
+
if (!(anchor instanceof HTMLElement)) return;
|
|
3703
|
+
const anchorRect = anchor.getBoundingClientRect();
|
|
3704
|
+
let lineTop = before ? anchorRect.bottom : anchorRect.top;
|
|
3705
|
+
if (before && $pos.nodeAfter) {
|
|
3706
|
+
const next = view.nodeDOM(pos);
|
|
3707
|
+
if (next instanceof HTMLElement) {
|
|
3708
|
+
lineTop = (anchorRect.bottom + next.getBoundingClientRect().top) / 2;
|
|
3709
|
+
}
|
|
3710
|
+
}
|
|
3711
|
+
const editorRect = view.dom.getBoundingClientRect();
|
|
3712
|
+
const scaleX = editorRect.width / view.dom.offsetWidth || 1;
|
|
3713
|
+
const scaleY = editorRect.height / view.dom.offsetHeight || 1;
|
|
3714
|
+
const parentRect = parent.getBoundingClientRect();
|
|
3715
|
+
const parentScaleX = parentRect.width / parent.offsetWidth || 1;
|
|
3716
|
+
const parentScaleY = parentRect.height / parent.offsetHeight || 1;
|
|
3717
|
+
const parentLeft = parentRect.left - parent.scrollLeft * parentScaleX;
|
|
3718
|
+
const parentTop = parentRect.top - parent.scrollTop * parentScaleY;
|
|
3719
|
+
const half = scaleY;
|
|
3720
|
+
cursor.classList.add("prosemirror-dropcursor-block");
|
|
3721
|
+
cursor.classList.remove("prosemirror-dropcursor-inline");
|
|
3722
|
+
cursor.style.left = `${(anchorRect.left - parentLeft) / scaleX}px`;
|
|
3723
|
+
cursor.style.top = `${(lineTop - half - parentTop) / scaleY}px`;
|
|
3724
|
+
cursor.style.width = `${(anchorRect.right - anchorRect.left) / scaleX}px`;
|
|
3725
|
+
cursor.style.height = `${2 * half / scaleY}px`;
|
|
3726
|
+
}
|
|
3727
|
+
function blockDragListGuardPlugin() {
|
|
3728
|
+
return new Plugin({
|
|
3729
|
+
key: blockDragListGuardKey,
|
|
3730
|
+
props: {
|
|
3731
|
+
handleDrop(view, event, slice, moved) {
|
|
3732
|
+
if (!moved || !isBlockHandleDragging(view)) return false;
|
|
3733
|
+
const edge = snappedListEdge(view, event.clientX, event.clientY, slice);
|
|
3734
|
+
if (edge == null) return false;
|
|
3735
|
+
moveDraggedSlice(view, slice, edge);
|
|
3736
|
+
return true;
|
|
3737
|
+
}
|
|
3738
|
+
},
|
|
3739
|
+
view(editorView) {
|
|
3740
|
+
const onDragOver = (event) => {
|
|
3741
|
+
var _a;
|
|
3742
|
+
const slice = (_a = editorView.dragging) == null ? void 0 : _a.slice;
|
|
3743
|
+
if (!slice || !isBlockHandleDragging(editorView)) return;
|
|
3744
|
+
const edge = snappedListEdge(
|
|
3745
|
+
editorView,
|
|
3746
|
+
event.clientX,
|
|
3747
|
+
event.clientY,
|
|
3748
|
+
slice
|
|
3749
|
+
);
|
|
3750
|
+
if (edge == null) return;
|
|
3751
|
+
placeBlockDropCursor(editorView, edge);
|
|
3752
|
+
};
|
|
3753
|
+
editorView.dom.addEventListener("dragover", onDragOver);
|
|
3754
|
+
return {
|
|
3755
|
+
destroy() {
|
|
3756
|
+
editorView.dom.removeEventListener("dragover", onDragOver);
|
|
3757
|
+
setBlockHandleDragging(editorView, false);
|
|
3758
|
+
}
|
|
3759
|
+
};
|
|
3760
|
+
}
|
|
3761
|
+
});
|
|
3762
|
+
}
|
|
3763
|
+
const cluster = "_cluster_5edcs_4";
|
|
3764
|
+
const clusterOnTable = "_clusterOnTable_5edcs_24";
|
|
3765
|
+
const button = "_button_5edcs_28";
|
|
3766
|
+
const grip = "_grip_5edcs_50";
|
|
3767
|
+
const menu$1 = "_menu_5edcs_61";
|
|
3768
|
+
const groupLabel = "_groupLabel_5edcs_84";
|
|
3769
|
+
const divider$3 = "_divider_5edcs_94";
|
|
3770
|
+
const item$1 = "_item_5edcs_100";
|
|
3771
|
+
const itemActive = "_itemActive_5edcs_118";
|
|
3772
|
+
const itemDanger = "_itemDanger_5edcs_123";
|
|
3773
|
+
const itemIcon = "_itemIcon_5edcs_132";
|
|
3774
|
+
const styles$7 = {
|
|
3775
|
+
cluster,
|
|
3776
|
+
clusterOnTable,
|
|
3777
|
+
button,
|
|
3778
|
+
grip,
|
|
3779
|
+
menu: menu$1,
|
|
3780
|
+
groupLabel,
|
|
3781
|
+
divider: divider$3,
|
|
3782
|
+
item: item$1,
|
|
3783
|
+
itemActive,
|
|
3784
|
+
itemDanger,
|
|
3785
|
+
itemIcon
|
|
3786
|
+
};
|
|
3787
|
+
const HANDLE_POSITION = {
|
|
3788
|
+
placement: "left-start",
|
|
3789
|
+
strategy: "absolute",
|
|
3790
|
+
middleware: [offset({ mainAxis: -6, crossAxis: 4 })]
|
|
3791
|
+
};
|
|
3792
|
+
const TABLE_ANCHOR_LIFT = 24;
|
|
3793
|
+
const THEME_VARS = [
|
|
3794
|
+
"--tmr-text",
|
|
3795
|
+
"--tmr-accent",
|
|
3796
|
+
"--tmr-toolbar-border",
|
|
3797
|
+
"--tmr-toolbar-muted",
|
|
3798
|
+
"--tmr-popover-bg",
|
|
3799
|
+
"--tmr-danger",
|
|
3800
|
+
"--tmr-code-bg"
|
|
3801
|
+
];
|
|
3802
|
+
function lockDragHandle(editor, locked2) {
|
|
3803
|
+
if (editor.isDestroyed) return;
|
|
3804
|
+
editor.view.dispatch(
|
|
3805
|
+
editor.state.tr.setMeta("lockDragHandle", locked2).setMeta("addToHistory", false)
|
|
3806
|
+
);
|
|
3807
|
+
}
|
|
3808
|
+
async function copyMarkdown(markdown) {
|
|
3809
|
+
try {
|
|
3810
|
+
await navigator.clipboard.writeText(markdown);
|
|
3811
|
+
return;
|
|
3812
|
+
} catch {
|
|
3813
|
+
}
|
|
3814
|
+
const area = document.createElement("textarea");
|
|
3815
|
+
area.value = markdown;
|
|
3816
|
+
area.setAttribute("readonly", "");
|
|
3817
|
+
area.style.position = "fixed";
|
|
3818
|
+
area.style.left = "-9999px";
|
|
3819
|
+
document.body.appendChild(area);
|
|
3820
|
+
area.select();
|
|
3821
|
+
document.execCommand("copy");
|
|
3822
|
+
area.remove();
|
|
3823
|
+
}
|
|
3824
|
+
const TURN_ICON = {
|
|
3825
|
+
paragraph: "¶",
|
|
3826
|
+
"heading-1": "H1",
|
|
3827
|
+
"heading-2": "H2",
|
|
3828
|
+
"heading-3": "H3",
|
|
3829
|
+
bulletList: "•",
|
|
3830
|
+
orderedList: "1.",
|
|
3831
|
+
taskList: "✓",
|
|
3832
|
+
blockquote: "❝",
|
|
3833
|
+
codeBlock: "{ }"
|
|
3834
|
+
};
|
|
3835
|
+
function BlockDragHandle({ editor }) {
|
|
3836
|
+
const t = useEditorBundle(editor).blockDrag;
|
|
3837
|
+
const [target, setTarget] = useState(null);
|
|
3838
|
+
const [menu2, setMenu] = useState(null);
|
|
3839
|
+
const draggedRef = useRef(false);
|
|
3840
|
+
const targetRef = useRef(null);
|
|
3841
|
+
const menuRef = useRef(null);
|
|
3842
|
+
const closeMenu = useCallback(() => {
|
|
3843
|
+
setMenu(null);
|
|
3844
|
+
lockDragHandle(editor, false);
|
|
3845
|
+
}, [editor]);
|
|
3846
|
+
useEffect(() => {
|
|
3847
|
+
const plugin = blockDragListGuardPlugin();
|
|
3848
|
+
editor.registerPlugin(plugin);
|
|
3849
|
+
return () => {
|
|
3850
|
+
setBlockHandleDragging(editor.view, false);
|
|
3851
|
+
if (!editor.isDestroyed) editor.unregisterPlugin(blockDragListGuardKey);
|
|
3852
|
+
};
|
|
3853
|
+
}, [editor]);
|
|
3854
|
+
useEffect(() => {
|
|
3855
|
+
if (!menu2) return;
|
|
3856
|
+
const onKey = (event) => {
|
|
3857
|
+
if (event.key !== "Escape") return;
|
|
3858
|
+
event.preventDefault();
|
|
3859
|
+
closeMenu();
|
|
3860
|
+
};
|
|
3861
|
+
const onDown = (event) => {
|
|
3862
|
+
const el = event.target;
|
|
3863
|
+
if (!(el instanceof Element)) return;
|
|
3864
|
+
if (el.closest("[data-block-drag-menu], [data-block-drag-grip]")) return;
|
|
3865
|
+
closeMenu();
|
|
3866
|
+
};
|
|
3867
|
+
const onScroll = () => closeMenu();
|
|
3868
|
+
document.addEventListener("keydown", onKey);
|
|
3869
|
+
document.addEventListener("mousedown", onDown);
|
|
3870
|
+
document.addEventListener("scroll", onScroll, true);
|
|
3871
|
+
return () => {
|
|
3872
|
+
document.removeEventListener("keydown", onKey);
|
|
3873
|
+
document.removeEventListener("mousedown", onDown);
|
|
3874
|
+
document.removeEventListener("scroll", onScroll, true);
|
|
3875
|
+
};
|
|
3876
|
+
}, [menu2, closeMenu]);
|
|
3877
|
+
useEffect(() => {
|
|
3878
|
+
if (!menu2 || !menuRef.current) return;
|
|
3879
|
+
const style = getComputedStyle(editor.view.dom);
|
|
3880
|
+
for (const name of THEME_VARS) {
|
|
3881
|
+
const value = style.getPropertyValue(name);
|
|
3882
|
+
if (value) menuRef.current.style.setProperty(name, value);
|
|
3883
|
+
}
|
|
3884
|
+
}, [menu2, editor]);
|
|
3885
|
+
useEffect(() => () => lockDragHandle(editor, false), [editor, closeMenu]);
|
|
3886
|
+
const openMenu = (anchor) => {
|
|
3887
|
+
if (!target) return;
|
|
3888
|
+
const rect = anchor.getBoundingClientRect();
|
|
3889
|
+
const estimated = 380;
|
|
3890
|
+
const y = rect.top + estimated > window.innerHeight ? Math.max(8, window.innerHeight - estimated - 8) : rect.top;
|
|
3891
|
+
const x = Math.min(rect.right + 6, window.innerWidth - 220);
|
|
3892
|
+
lockDragHandle(editor, true);
|
|
3893
|
+
setMenu({ x, y, pos: target.pos, node: target.node });
|
|
3894
|
+
};
|
|
3895
|
+
const run = (action) => {
|
|
3896
|
+
action();
|
|
3897
|
+
editor.commands.focus();
|
|
3898
|
+
closeMenu();
|
|
3899
|
+
};
|
|
3900
|
+
const activeKind = menu2 ? currentTurnIntoKind(editor, menu2.pos, menu2.node) : null;
|
|
3901
|
+
const showTurn = menu2 ? canTurnBlockInto(menu2.node) : false;
|
|
3902
|
+
const showReset = menu2 ? canResetBlockFormatting(menu2.node) : false;
|
|
3903
|
+
const showDownload = menu2 ? isImageBlock(menu2.node) : false;
|
|
3904
|
+
const turnLabel = (kind) => {
|
|
3905
|
+
if (kind === "paragraph") return t.paragraph;
|
|
3906
|
+
if (kind === "heading-1") return t.headingLabel(1);
|
|
3907
|
+
if (kind === "heading-2") return t.headingLabel(2);
|
|
3908
|
+
if (kind === "heading-3") return t.headingLabel(3);
|
|
3909
|
+
if (kind === "bulletList") return t.bulletList;
|
|
3910
|
+
if (kind === "orderedList") return t.orderedList;
|
|
3911
|
+
if (kind === "taskList") return t.taskList;
|
|
3912
|
+
if (kind === "blockquote") return t.blockquote;
|
|
3913
|
+
return t.codeBlock;
|
|
3914
|
+
};
|
|
3915
|
+
return /* @__PURE__ */ jsxs(Fragment$2, { children: [
|
|
3916
|
+
/* @__PURE__ */ jsx(
|
|
3917
|
+
DragHandle,
|
|
3918
|
+
{
|
|
3919
|
+
editor,
|
|
3920
|
+
computePositionConfig: HANDLE_POSITION,
|
|
3921
|
+
onNodeChange: ({ node, pos }) => {
|
|
3922
|
+
if (!node || pos < 0) {
|
|
3923
|
+
targetRef.current = null;
|
|
3924
|
+
setTarget(null);
|
|
3925
|
+
return;
|
|
3926
|
+
}
|
|
3927
|
+
const next = { node, pos };
|
|
3928
|
+
targetRef.current = next;
|
|
3929
|
+
setTarget(next);
|
|
3930
|
+
},
|
|
3931
|
+
getReferencedVirtualElement: () => {
|
|
3932
|
+
const current = targetRef.current;
|
|
3933
|
+
if (!current || current.node.type.name !== "table") return null;
|
|
3934
|
+
const pos = current.pos;
|
|
3935
|
+
return {
|
|
3936
|
+
getBoundingClientRect: () => {
|
|
3937
|
+
let dom = null;
|
|
3938
|
+
try {
|
|
3939
|
+
dom = editor.view.nodeDOM(pos);
|
|
3940
|
+
} catch {
|
|
3941
|
+
dom = null;
|
|
3942
|
+
}
|
|
3943
|
+
if (!(dom instanceof HTMLElement)) return new DOMRect();
|
|
3944
|
+
const rect = dom.getBoundingClientRect();
|
|
3945
|
+
return new DOMRect(
|
|
3946
|
+
rect.x,
|
|
3947
|
+
rect.y - TABLE_ANCHOR_LIFT,
|
|
3948
|
+
rect.width,
|
|
3949
|
+
rect.height
|
|
3950
|
+
);
|
|
3951
|
+
}
|
|
3952
|
+
};
|
|
3953
|
+
},
|
|
3954
|
+
onElementDragStart: () => {
|
|
3955
|
+
draggedRef.current = true;
|
|
3956
|
+
setBlockHandleDragging(editor.view, true);
|
|
3957
|
+
},
|
|
3958
|
+
onElementDragEnd: () => {
|
|
3959
|
+
setBlockHandleDragging(editor.view, false);
|
|
3960
|
+
setTimeout(() => {
|
|
3961
|
+
draggedRef.current = false;
|
|
3962
|
+
}, 0);
|
|
3963
|
+
},
|
|
3964
|
+
children: /* @__PURE__ */ jsx(
|
|
3965
|
+
"div",
|
|
3966
|
+
{
|
|
3967
|
+
className: `${styles$7.cluster} ${(target == null ? void 0 : target.node.type.name) === "table" ? styles$7.clusterOnTable : ""}`,
|
|
3968
|
+
"data-block-drag": "",
|
|
3969
|
+
children: /* @__PURE__ */ jsx(
|
|
3970
|
+
"div",
|
|
3971
|
+
{
|
|
3972
|
+
role: "button",
|
|
3973
|
+
tabIndex: 0,
|
|
3974
|
+
className: `${styles$7.button} ${styles$7.grip}`,
|
|
3975
|
+
"data-block-drag-grip": "",
|
|
3976
|
+
title: t.dragHandle,
|
|
3977
|
+
"aria-label": t.dragHandle,
|
|
3978
|
+
"aria-haspopup": "menu",
|
|
3979
|
+
"aria-expanded": menu2 != null,
|
|
3980
|
+
onKeyDown: (event) => {
|
|
3981
|
+
if (event.key !== "Enter" && event.key !== " ") return;
|
|
3982
|
+
event.preventDefault();
|
|
3983
|
+
if (menu2) closeMenu();
|
|
3984
|
+
else openMenu(event.currentTarget);
|
|
2630
3985
|
},
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
3986
|
+
onClick: (event) => {
|
|
3987
|
+
if (draggedRef.current) return;
|
|
3988
|
+
if (menu2) {
|
|
3989
|
+
closeMenu();
|
|
3990
|
+
return;
|
|
3991
|
+
}
|
|
3992
|
+
openMenu(event.currentTarget);
|
|
3993
|
+
},
|
|
3994
|
+
children: /* @__PURE__ */ jsx(GripIcon, { size: 14 })
|
|
3995
|
+
}
|
|
3996
|
+
)
|
|
2634
3997
|
}
|
|
2635
|
-
)
|
|
2636
|
-
|
|
2637
|
-
/* @__PURE__ */ jsx(
|
|
2638
|
-
"button",
|
|
2639
|
-
{
|
|
2640
|
-
type: "button",
|
|
2641
|
-
className: styles$7.deleteBtn,
|
|
2642
|
-
title: labels.delete,
|
|
2643
|
-
"aria-label": labels.delete,
|
|
2644
|
-
onClick: () => deleteNode(),
|
|
2645
|
-
children: /* @__PURE__ */ jsx(TrashIcon, {})
|
|
2646
|
-
}
|
|
2647
|
-
)
|
|
2648
|
-
] }) : (
|
|
2649
|
-
// 只读头部:左侧语言标签,右侧复制 + 展开收起(展开后按钮保留,供收回)
|
|
2650
|
-
/* @__PURE__ */ jsxs("div", { className: styles$7.readonlyHeader, contentEditable: false, children: [
|
|
2651
|
-
/* @__PURE__ */ jsxs("span", { className: styles$7.langBadge, children: [
|
|
2652
|
-
/* @__PURE__ */ jsx("span", { className: styles$7.langBraces, children: "{}" }),
|
|
2653
|
-
currentLabel
|
|
2654
|
-
] }),
|
|
2655
|
-
/* @__PURE__ */ jsxs("span", { className: styles$7.readonlyActions, children: [
|
|
2656
|
-
/* @__PURE__ */ jsx(
|
|
2657
|
-
"button",
|
|
2658
|
-
{
|
|
2659
|
-
type: "button",
|
|
2660
|
-
className: styles$7.actionBtn,
|
|
2661
|
-
onClick: handleCopy,
|
|
2662
|
-
"aria-label": labels.copy,
|
|
2663
|
-
title: labels.copy,
|
|
2664
|
-
children: copied ? /* @__PURE__ */ jsx(CheckIcon, { size: 14 }) : /* @__PURE__ */ jsx(CopyIcon, { size: 14 })
|
|
2665
|
-
}
|
|
2666
|
-
),
|
|
2667
|
-
/* @__PURE__ */ jsx(
|
|
2668
|
-
"button",
|
|
2669
|
-
{
|
|
2670
|
-
type: "button",
|
|
2671
|
-
className: styles$7.actionBtn,
|
|
2672
|
-
onClick: () => setFolded((v) => !v),
|
|
2673
|
-
"aria-label": folded2 ? labels.expand : labels.collapse,
|
|
2674
|
-
title: folded2 ? labels.expand : labels.collapse,
|
|
2675
|
-
"aria-expanded": !folded2,
|
|
2676
|
-
children: /* @__PURE__ */ jsx(ChevronsUpDownIcon, { size: 14 })
|
|
2677
|
-
}
|
|
2678
|
-
)
|
|
2679
|
-
] })
|
|
2680
|
-
] })
|
|
3998
|
+
)
|
|
3999
|
+
}
|
|
2681
4000
|
),
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
"
|
|
4001
|
+
menu2 ? createPortal(
|
|
4002
|
+
/* @__PURE__ */ jsxs(
|
|
4003
|
+
"div",
|
|
2685
4004
|
{
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
"
|
|
2689
|
-
|
|
4005
|
+
ref: menuRef,
|
|
4006
|
+
className: styles$7.menu,
|
|
4007
|
+
"data-block-drag-menu": "",
|
|
4008
|
+
role: "menu",
|
|
4009
|
+
"aria-label": t.menuLabel,
|
|
4010
|
+
style: { left: menu2.x, top: menu2.y },
|
|
4011
|
+
onMouseDown: (event) => event.stopPropagation(),
|
|
4012
|
+
children: [
|
|
4013
|
+
showTurn ? /* @__PURE__ */ jsxs(Fragment$2, { children: [
|
|
4014
|
+
/* @__PURE__ */ jsx("div", { className: styles$7.groupLabel, children: t.turnInto }),
|
|
4015
|
+
TURN_INTO_KINDS.map((kind) => /* @__PURE__ */ jsxs(
|
|
4016
|
+
"button",
|
|
4017
|
+
{
|
|
4018
|
+
type: "button",
|
|
4019
|
+
role: "menuitem",
|
|
4020
|
+
className: kind === activeKind ? `${styles$7.item} ${styles$7.itemActive}` : styles$7.item,
|
|
4021
|
+
"data-block-drag-action": kind,
|
|
4022
|
+
onClick: () => run(() => turnBlockInto(editor, menu2.pos, kind)),
|
|
4023
|
+
children: [
|
|
4024
|
+
/* @__PURE__ */ jsx("span", { className: styles$7.itemIcon, "aria-hidden": true, children: TURN_ICON[kind] }),
|
|
4025
|
+
/* @__PURE__ */ jsx("span", { children: turnLabel(kind) })
|
|
4026
|
+
]
|
|
4027
|
+
},
|
|
4028
|
+
kind
|
|
4029
|
+
)),
|
|
4030
|
+
/* @__PURE__ */ jsx("div", { className: styles$7.divider })
|
|
4031
|
+
] }) : null,
|
|
4032
|
+
/* @__PURE__ */ jsxs(
|
|
4033
|
+
"button",
|
|
4034
|
+
{
|
|
4035
|
+
type: "button",
|
|
4036
|
+
role: "menuitem",
|
|
4037
|
+
className: styles$7.item,
|
|
4038
|
+
"data-block-drag-action": "copy",
|
|
4039
|
+
onClick: () => run(() => {
|
|
4040
|
+
const markdown = blockMarkdown(editor, menu2.pos);
|
|
4041
|
+
if (markdown != null) void copyMarkdown(markdown);
|
|
4042
|
+
}),
|
|
4043
|
+
children: [
|
|
4044
|
+
/* @__PURE__ */ jsx("span", { className: styles$7.itemIcon, "aria-hidden": true, children: /* @__PURE__ */ jsx(CopyIcon, {}) }),
|
|
4045
|
+
/* @__PURE__ */ jsx("span", { children: t.copy })
|
|
4046
|
+
]
|
|
4047
|
+
}
|
|
4048
|
+
),
|
|
4049
|
+
/* @__PURE__ */ jsxs(
|
|
4050
|
+
"button",
|
|
4051
|
+
{
|
|
4052
|
+
type: "button",
|
|
4053
|
+
role: "menuitem",
|
|
4054
|
+
className: styles$7.item,
|
|
4055
|
+
"data-block-drag-action": "duplicate",
|
|
4056
|
+
onClick: () => run(() => duplicateBlock(editor, menu2.pos)),
|
|
4057
|
+
children: [
|
|
4058
|
+
/* @__PURE__ */ jsx("span", { className: styles$7.itemIcon, "aria-hidden": true, children: /* @__PURE__ */ jsx(CopyIcon, {}) }),
|
|
4059
|
+
/* @__PURE__ */ jsx("span", { children: t.duplicate })
|
|
4060
|
+
]
|
|
4061
|
+
}
|
|
4062
|
+
),
|
|
4063
|
+
showReset ? /* @__PURE__ */ jsxs(
|
|
4064
|
+
"button",
|
|
4065
|
+
{
|
|
4066
|
+
type: "button",
|
|
4067
|
+
role: "menuitem",
|
|
4068
|
+
className: styles$7.item,
|
|
4069
|
+
"data-block-drag-action": "reset",
|
|
4070
|
+
onClick: () => run(() => resetBlockFormatting(editor, menu2.pos)),
|
|
4071
|
+
children: [
|
|
4072
|
+
/* @__PURE__ */ jsx("span", { className: styles$7.itemIcon, "aria-hidden": true, children: /* @__PURE__ */ jsx(EraserIcon, {}) }),
|
|
4073
|
+
/* @__PURE__ */ jsx("span", { children: t.resetFormatting })
|
|
4074
|
+
]
|
|
4075
|
+
}
|
|
4076
|
+
) : null,
|
|
4077
|
+
showDownload ? /* @__PURE__ */ jsxs(
|
|
4078
|
+
"button",
|
|
4079
|
+
{
|
|
4080
|
+
type: "button",
|
|
4081
|
+
role: "menuitem",
|
|
4082
|
+
className: styles$7.item,
|
|
4083
|
+
"data-block-drag-action": "download",
|
|
4084
|
+
onClick: () => run(() => downloadImageBlock(menu2.node)),
|
|
4085
|
+
children: [
|
|
4086
|
+
/* @__PURE__ */ jsx("span", { className: styles$7.itemIcon, "aria-hidden": true, children: /* @__PURE__ */ jsx(DownloadIcon, {}) }),
|
|
4087
|
+
/* @__PURE__ */ jsx("span", { children: t.downloadImage })
|
|
4088
|
+
]
|
|
4089
|
+
}
|
|
4090
|
+
) : null,
|
|
4091
|
+
/* @__PURE__ */ jsx("div", { className: styles$7.divider }),
|
|
4092
|
+
/* @__PURE__ */ jsxs(
|
|
4093
|
+
"button",
|
|
4094
|
+
{
|
|
4095
|
+
type: "button",
|
|
4096
|
+
role: "menuitem",
|
|
4097
|
+
className: `${styles$7.item} ${styles$7.itemDanger}`,
|
|
4098
|
+
"data-block-drag-action": "delete",
|
|
4099
|
+
onClick: () => run(() => deleteBlock(editor, menu2.pos)),
|
|
4100
|
+
children: [
|
|
4101
|
+
/* @__PURE__ */ jsx("span", { className: styles$7.itemIcon, "aria-hidden": true, children: /* @__PURE__ */ jsx(TrashIcon, {}) }),
|
|
4102
|
+
/* @__PURE__ */ jsx("span", { children: t.delete })
|
|
4103
|
+
]
|
|
4104
|
+
}
|
|
4105
|
+
)
|
|
4106
|
+
]
|
|
2690
4107
|
}
|
|
2691
|
-
)
|
|
2692
|
-
|
|
2693
|
-
|
|
4108
|
+
),
|
|
4109
|
+
document.body
|
|
4110
|
+
) : null
|
|
2694
4111
|
] });
|
|
2695
4112
|
}
|
|
4113
|
+
function useIsMobile(breakpoint = 768) {
|
|
4114
|
+
const [isMobile, setIsMobile] = useState(false);
|
|
4115
|
+
useEffect(() => {
|
|
4116
|
+
const mq = window.matchMedia(`(max-width: ${breakpoint - 1}px)`);
|
|
4117
|
+
const update = () => setIsMobile(mq.matches);
|
|
4118
|
+
update();
|
|
4119
|
+
mq.addEventListener("change", update);
|
|
4120
|
+
return () => mq.removeEventListener("change", update);
|
|
4121
|
+
}, [breakpoint]);
|
|
4122
|
+
return isMobile;
|
|
4123
|
+
}
|
|
2696
4124
|
const CodeBlock = CodeBlockLowlight.extend({
|
|
2697
|
-
addOptions() {
|
|
2698
|
-
var _a;
|
|
2699
|
-
return {
|
|
2700
|
-
...(_a = this.parent) == null ? void 0 : _a.call(this),
|
|
2701
|
-
codeBlockLabels: void 0
|
|
2702
|
-
};
|
|
2703
|
-
},
|
|
2704
4125
|
// Built-in `code` tokens often win over chart's custom fence tokenizer;
|
|
2705
4126
|
// upgrade ```tmr-chart here so the mid-column card editor renders ChartView.
|
|
2706
4127
|
parseMarkdown: (token, helpers) => parseCodeTokenAsChartOrCodeBlock(token, helpers, "codeBlock"),
|
|
@@ -2846,16 +4267,48 @@ const ImageWithConfirmDelete = Image.extend({
|
|
|
2846
4267
|
}
|
|
2847
4268
|
});
|
|
2848
4269
|
const DEFAULT_FIND_BAR_OFFSET = { top: 4, right: 4 };
|
|
2849
|
-
function findBarOffsetStyle(
|
|
4270
|
+
function findBarOffsetStyle(offset2) {
|
|
2850
4271
|
const px = (v) => typeof v === "number" ? `${v}px` : v;
|
|
2851
4272
|
return {
|
|
2852
4273
|
position: "absolute",
|
|
2853
|
-
top: px(
|
|
2854
|
-
right: px(
|
|
2855
|
-
bottom: px(
|
|
2856
|
-
left: px(
|
|
4274
|
+
top: px(offset2.top),
|
|
4275
|
+
right: px(offset2.right),
|
|
4276
|
+
bottom: px(offset2.bottom),
|
|
4277
|
+
left: px(offset2.left)
|
|
2857
4278
|
};
|
|
2858
4279
|
}
|
|
4280
|
+
function CharacterCountStatus({
|
|
4281
|
+
editor,
|
|
4282
|
+
locale
|
|
4283
|
+
}) {
|
|
4284
|
+
const t = getLocaleBundle(locale).characterCount;
|
|
4285
|
+
const counts = useEditorState({
|
|
4286
|
+
editor,
|
|
4287
|
+
selector: ({ editor: current }) => {
|
|
4288
|
+
const storage = current == null ? void 0 : current.storage.characterCount;
|
|
4289
|
+
if (!storage) return { characters: 0, words: 0 };
|
|
4290
|
+
return {
|
|
4291
|
+
characters: storage.characters(),
|
|
4292
|
+
words: storage.words()
|
|
4293
|
+
};
|
|
4294
|
+
}
|
|
4295
|
+
});
|
|
4296
|
+
return /* @__PURE__ */ jsxs(
|
|
4297
|
+
"div",
|
|
4298
|
+
{
|
|
4299
|
+
className: styles$e.charCount,
|
|
4300
|
+
role: "group",
|
|
4301
|
+
"aria-label": t.label,
|
|
4302
|
+
"data-characters": counts.characters,
|
|
4303
|
+
"data-words": counts.words,
|
|
4304
|
+
children: [
|
|
4305
|
+
/* @__PURE__ */ jsx("span", { children: t.characters(counts.characters) }),
|
|
4306
|
+
/* @__PURE__ */ jsx("span", { className: styles$e.charCountSep, "aria-hidden": "true", children: "·" }),
|
|
4307
|
+
/* @__PURE__ */ jsx("span", { children: t.words(counts.words) })
|
|
4308
|
+
]
|
|
4309
|
+
}
|
|
4310
|
+
);
|
|
4311
|
+
}
|
|
2859
4312
|
function editorOwnsKeyboard(editor) {
|
|
2860
4313
|
const active2 = document.activeElement;
|
|
2861
4314
|
const inEditor = !!active2 && editor.view.dom.contains(active2);
|
|
@@ -2866,6 +4319,7 @@ function editorOwnsKeyboard(editor) {
|
|
|
2866
4319
|
const MarkdownWysiwygEditor = forwardRef(function MarkdownWysiwygEditor2({
|
|
2867
4320
|
initialMarkdown = "",
|
|
2868
4321
|
editable = true,
|
|
4322
|
+
locale = "en",
|
|
2869
4323
|
sources,
|
|
2870
4324
|
renderCitation,
|
|
2871
4325
|
placeholder,
|
|
@@ -2874,7 +4328,6 @@ const MarkdownWysiwygEditor = forwardRef(function MarkdownWysiwygEditor2({
|
|
|
2874
4328
|
markdownPaste = true,
|
|
2875
4329
|
markdownFileDrop = true,
|
|
2876
4330
|
extraExtensions,
|
|
2877
|
-
codeBlockLabels,
|
|
2878
4331
|
className,
|
|
2879
4332
|
comments,
|
|
2880
4333
|
activeCommentId,
|
|
@@ -2890,26 +4343,31 @@ const MarkdownWysiwygEditor = forwardRef(function MarkdownWysiwygEditor2({
|
|
|
2890
4343
|
findBarContainer,
|
|
2891
4344
|
findBarOffset = DEFAULT_FIND_BAR_OFFSET,
|
|
2892
4345
|
findShortcut = true,
|
|
2893
|
-
findLabels,
|
|
2894
4346
|
onFindOpenChange,
|
|
2895
4347
|
slashMenu = true,
|
|
2896
|
-
|
|
4348
|
+
typography = true,
|
|
4349
|
+
emojiSuggestion = true,
|
|
4350
|
+
blockDrag = true,
|
|
2897
4351
|
shortcutPanel = true,
|
|
2898
|
-
shortcutLabels,
|
|
2899
4352
|
shortcutFabContainer,
|
|
2900
4353
|
imageUpload,
|
|
2901
|
-
imageResize = true
|
|
4354
|
+
imageResize = true,
|
|
4355
|
+
characterCount = false
|
|
2902
4356
|
}, ref) {
|
|
2903
4357
|
const preparedInitial = prepareChartMarkdown(
|
|
2904
4358
|
enrichMarkdownCitations(initialMarkdown, sources ?? [])
|
|
2905
4359
|
);
|
|
4360
|
+
const blockDragMobile = useIsMobile(768);
|
|
4361
|
+
const showBlockDrag = blockDrag && editable && !blockDragMobile;
|
|
2906
4362
|
const [findOpen, setFindOpen] = useState(false);
|
|
2907
4363
|
const [shortcutsOpen, setShortcutsOpen] = useState(false);
|
|
2908
4364
|
const findInputRef = useRef(null);
|
|
2909
4365
|
const editor = useEditor({
|
|
2910
4366
|
extensions: [
|
|
2911
|
-
...baseExtensions
|
|
2912
|
-
|
|
4367
|
+
...baseExtensions.map(
|
|
4368
|
+
(ext) => ext.name === "emoji" ? configureEmojiSuggestion(ext, emojiSuggestion) : ext
|
|
4369
|
+
),
|
|
4370
|
+
CodeBlock.configure({ lowlight }),
|
|
2913
4371
|
ImageWithConfirmDelete.configure({
|
|
2914
4372
|
inline: false,
|
|
2915
4373
|
// 图片缩放(默认开、默认等比、默认左右两条手柄):false 关掉;对象透传官方配置
|
|
@@ -2950,6 +4408,13 @@ const MarkdownWysiwygEditor = forwardRef(function MarkdownWysiwygEditor2({
|
|
|
2950
4408
|
// - searchDebounceMs 关掉:官方防抖走 setTimeout,抛错会落在异步回调里兜不住;
|
|
2951
4409
|
// 防抖改由浮动条自己做(见 findReplace.ts)。
|
|
2952
4410
|
...findReplace ? [FindAndReplace.configure({ injectCSS: false, searchDebounceMs: 0 })] : [],
|
|
4411
|
+
// 失焦选区:MIT 的 Selection。非空文本选区失焦后打上 .tmr-blur-selection,
|
|
4412
|
+
// 样式在 content.module.css。节点选区(图片、代码块整块)官方不保留。
|
|
4413
|
+
Selection$1.configure({ className: "tmr-blur-selection" }),
|
|
4414
|
+
// 字数统计:MIT 的 @tiptap/extensions CharacterCount(不是 @tiptap-pro)。
|
|
4415
|
+
// 只调用它的 storage,统计条是本库自绘。无 limit,不裁剪正文。
|
|
4416
|
+
// 词数换成自写的 countWords,否则整段中文会被默认的按空格切分算成 1 个词。
|
|
4417
|
+
...characterCount ? [CharacterCount.configure({ wordCounter: countWords })] : [],
|
|
2953
4418
|
TableOfContents.configure({
|
|
2954
4419
|
getId: makeTocGetId(),
|
|
2955
4420
|
onUpdate: (anchors) => {
|
|
@@ -2961,7 +4426,9 @@ const MarkdownWysiwygEditor = forwardRef(function MarkdownWysiwygEditor2({
|
|
|
2961
4426
|
...markdownPaste ? [MarkdownPaste] : [],
|
|
2962
4427
|
...markdownFileDrop ? [MarkdownFileDrop] : [],
|
|
2963
4428
|
// 斜杠菜单(键入 / 唤起):默认开,只读态由 suggestion 状态机自身短路
|
|
2964
|
-
...slashMenu ? [SlashMenu
|
|
4429
|
+
...slashMenu ? [SlashMenu] : [],
|
|
4430
|
+
// 智能标点:输入规则,不增加节点,所以不进 baseExtensions。
|
|
4431
|
+
...typography ? [Typography] : [],
|
|
2965
4432
|
...extraExtensions ?? []
|
|
2966
4433
|
],
|
|
2967
4434
|
content: preparedInitial,
|
|
@@ -2971,10 +4438,11 @@ const MarkdownWysiwygEditor = forwardRef(function MarkdownWysiwygEditor2({
|
|
|
2971
4438
|
immediatelyRender: false,
|
|
2972
4439
|
editorProps: {
|
|
2973
4440
|
attributes: {
|
|
2974
|
-
class: styles$
|
|
4441
|
+
class: styles$e.editorContent
|
|
2975
4442
|
}
|
|
2976
4443
|
}
|
|
2977
4444
|
});
|
|
4445
|
+
usePublishEditorLocale(editor, locale);
|
|
2978
4446
|
useEffect(() => {
|
|
2979
4447
|
onEditorReady == null ? void 0 : onEditorReady(editor);
|
|
2980
4448
|
return () => onEditorReady == null ? void 0 : onEditorReady(null);
|
|
@@ -3167,22 +4635,19 @@ const MarkdownWysiwygEditor = forwardRef(function MarkdownWysiwygEditor2({
|
|
|
3167
4635
|
FindReplaceBar,
|
|
3168
4636
|
{
|
|
3169
4637
|
editor,
|
|
3170
|
-
|
|
4638
|
+
locale,
|
|
3171
4639
|
onClose: closeFind,
|
|
3172
4640
|
inputRef: findInputRef,
|
|
3173
|
-
className: styles$
|
|
4641
|
+
className: styles$e.findBar,
|
|
3174
4642
|
style: findBarOffsetStyle(findBarOffset)
|
|
3175
4643
|
}
|
|
3176
4644
|
) : null;
|
|
3177
|
-
const shortcutT =
|
|
3178
|
-
() => ({ ...defaultShortcutLabels, ...shortcutLabels }),
|
|
3179
|
-
[shortcutLabels]
|
|
3180
|
-
);
|
|
4645
|
+
const shortcutT = getLocaleBundle(locale).shortcut;
|
|
3181
4646
|
const [shortcutFabTarget, setShortcutFabTarget] = useState(
|
|
3182
4647
|
null
|
|
3183
4648
|
);
|
|
3184
|
-
const
|
|
3185
|
-
|
|
4649
|
+
const useIsoLayoutEffect2 = typeof window === "undefined" ? useEffect : useLayoutEffect;
|
|
4650
|
+
useIsoLayoutEffect2(() => {
|
|
3186
4651
|
const target = typeof shortcutFabContainer === "function" ? shortcutFabContainer() : shortcutFabContainer ?? null;
|
|
3187
4652
|
setShortcutFabTarget((prev) => prev === target ? prev : target);
|
|
3188
4653
|
});
|
|
@@ -3190,7 +4655,7 @@ const MarkdownWysiwygEditor = forwardRef(function MarkdownWysiwygEditor2({
|
|
|
3190
4655
|
"button",
|
|
3191
4656
|
{
|
|
3192
4657
|
type: "button",
|
|
3193
|
-
className: shortcutFabTarget ? `${styles$
|
|
4658
|
+
className: shortcutFabTarget ? `${styles$e.shortcutFab} ${styles$e.shortcutFabHosted}` : styles$e.shortcutFab,
|
|
3194
4659
|
title: shortcutT.panelTitle,
|
|
3195
4660
|
"aria-label": shortcutT.panelTitle,
|
|
3196
4661
|
"aria-expanded": shortcutsOpen,
|
|
@@ -3198,32 +4663,49 @@ const MarkdownWysiwygEditor = forwardRef(function MarkdownWysiwygEditor2({
|
|
|
3198
4663
|
children: /* @__PURE__ */ jsx(KeyboardIcon, { size: 18 })
|
|
3199
4664
|
}
|
|
3200
4665
|
) : null;
|
|
3201
|
-
return /* @__PURE__ */ jsxs(
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
|
|
3206
|
-
|
|
3207
|
-
|
|
3208
|
-
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
|
|
3212
|
-
|
|
3213
|
-
|
|
3214
|
-
|
|
3215
|
-
|
|
3216
|
-
|
|
3217
|
-
|
|
3218
|
-
|
|
3219
|
-
|
|
3220
|
-
|
|
4666
|
+
return /* @__PURE__ */ jsxs(
|
|
4667
|
+
"div",
|
|
4668
|
+
{
|
|
4669
|
+
className: styles$e.editorHost,
|
|
4670
|
+
"data-block-drag-gutter": showBlockDrag ? "" : void 0,
|
|
4671
|
+
children: [
|
|
4672
|
+
findBarNode && !findBarTarget ? /* @__PURE__ */ jsx("div", { className: styles$e.findBarAnchor, children: findBarNode }) : null,
|
|
4673
|
+
findBarNode && findBarTarget ? createPortal(findBarNode, findBarTarget) : null,
|
|
4674
|
+
/* @__PURE__ */ jsx(
|
|
4675
|
+
EditorContent,
|
|
4676
|
+
{
|
|
4677
|
+
editor,
|
|
4678
|
+
className: [
|
|
4679
|
+
styles$e.editorScroll,
|
|
4680
|
+
showBlockDrag ? styles$e.withBlockDrag : "",
|
|
4681
|
+
className ?? ""
|
|
4682
|
+
].filter(Boolean).join(" ")
|
|
4683
|
+
}
|
|
4684
|
+
),
|
|
4685
|
+
editor && showBlockDrag ? /* @__PURE__ */ jsx(BlockDragHandle, { editor }) : null,
|
|
4686
|
+
editor && characterCount ? /* @__PURE__ */ jsxs("div", { className: styles$e.editorStatus, children: [
|
|
4687
|
+
/* @__PURE__ */ jsx(CharacterCountStatus, { editor, locale }),
|
|
4688
|
+
shortcutFabNode && !shortcutFabTarget ? shortcutFabNode : null
|
|
4689
|
+
] }) : shortcutFabNode && !shortcutFabTarget ? shortcutFabNode : null,
|
|
4690
|
+
shortcutFabNode && shortcutFabTarget ? createPortal(shortcutFabNode, shortcutFabTarget) : null,
|
|
4691
|
+
shortcutPanel && editable ? /* @__PURE__ */ jsx(
|
|
4692
|
+
ShortcutPanel,
|
|
4693
|
+
{
|
|
4694
|
+
open: shortcutsOpen,
|
|
4695
|
+
onClose: () => setShortcutsOpen(false),
|
|
4696
|
+
locale
|
|
4697
|
+
}
|
|
4698
|
+
) : null
|
|
4699
|
+
]
|
|
4700
|
+
}
|
|
4701
|
+
);
|
|
3221
4702
|
});
|
|
3222
4703
|
function MarkdownPreview({
|
|
3223
4704
|
markdown,
|
|
3224
4705
|
sources,
|
|
3225
4706
|
renderCitation,
|
|
3226
|
-
className
|
|
4707
|
+
className,
|
|
4708
|
+
locale = "en"
|
|
3227
4709
|
}) {
|
|
3228
4710
|
const prepared = useMemo(
|
|
3229
4711
|
() => prepareChartMarkdown(
|
|
@@ -3258,11 +4740,12 @@ function MarkdownPreview({
|
|
|
3258
4740
|
editable: false,
|
|
3259
4741
|
immediatelyRender: false,
|
|
3260
4742
|
editorProps: {
|
|
3261
|
-
attributes: { class: styles$
|
|
4743
|
+
attributes: { class: styles$e.editorContent }
|
|
3262
4744
|
}
|
|
3263
4745
|
},
|
|
3264
4746
|
[extensions]
|
|
3265
4747
|
);
|
|
4748
|
+
usePublishEditorLocale(editor, locale);
|
|
3266
4749
|
useEffect(() => {
|
|
3267
4750
|
if (!editor) return;
|
|
3268
4751
|
editor.commands.setContent(prepared, { contentType: "markdown" });
|
|
@@ -3271,7 +4754,7 @@ function MarkdownPreview({
|
|
|
3271
4754
|
EditorContent,
|
|
3272
4755
|
{
|
|
3273
4756
|
editor,
|
|
3274
|
-
className: className ?? styles$
|
|
4757
|
+
className: className ?? styles$e.editorScroll
|
|
3275
4758
|
}
|
|
3276
4759
|
);
|
|
3277
4760
|
}
|
|
@@ -3343,45 +4826,57 @@ function splitTopLevelBlocks(markdown) {
|
|
|
3343
4826
|
function stripToPlainText(markdown) {
|
|
3344
4827
|
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();
|
|
3345
4828
|
}
|
|
3346
|
-
const toolbar = "
|
|
3347
|
-
const inner = "
|
|
3348
|
-
const btn$2 = "
|
|
3349
|
-
const btnActive$1 = "
|
|
3350
|
-
const txtIcon = "
|
|
3351
|
-
const colorIcon = "
|
|
3352
|
-
const colorIconGlyph = "
|
|
3353
|
-
const colorIconBar = "
|
|
3354
|
-
const scriptTrigger = "
|
|
3355
|
-
const scriptTriggerGlyph = "
|
|
3356
|
-
const divider$2 = "
|
|
3357
|
-
const styleTrigger = "
|
|
3358
|
-
const styleTriggerLabel = "
|
|
3359
|
-
const styleTriggerCaret = "
|
|
3360
|
-
const iconTrigger = "
|
|
3361
|
-
const styleItem = "
|
|
3362
|
-
const styleIcon = "
|
|
3363
|
-
const scriptGlyph = "
|
|
3364
|
-
const menu = "
|
|
3365
|
-
const menuItem = "
|
|
3366
|
-
const menuItemSelected = "
|
|
3367
|
-
const
|
|
3368
|
-
const
|
|
3369
|
-
const
|
|
3370
|
-
const
|
|
3371
|
-
const
|
|
3372
|
-
const
|
|
3373
|
-
const
|
|
3374
|
-
const
|
|
3375
|
-
const
|
|
3376
|
-
const
|
|
3377
|
-
const
|
|
3378
|
-
const
|
|
3379
|
-
const
|
|
3380
|
-
const
|
|
3381
|
-
const
|
|
3382
|
-
const
|
|
3383
|
-
const
|
|
3384
|
-
const
|
|
4829
|
+
const toolbar = "_toolbar_1l6t0_2";
|
|
4830
|
+
const inner = "_inner_1l6t0_15";
|
|
4831
|
+
const btn$2 = "_btn_1l6t0_35";
|
|
4832
|
+
const btnActive$1 = "_btnActive_1l6t0_58";
|
|
4833
|
+
const txtIcon = "_txtIcon_1l6t0_74";
|
|
4834
|
+
const colorIcon = "_colorIcon_1l6t0_82";
|
|
4835
|
+
const colorIconGlyph = "_colorIconGlyph_1l6t0_90";
|
|
4836
|
+
const colorIconBar = "_colorIconBar_1l6t0_96";
|
|
4837
|
+
const scriptTrigger = "_scriptTrigger_1l6t0_103";
|
|
4838
|
+
const scriptTriggerGlyph = "_scriptTriggerGlyph_1l6t0_123";
|
|
4839
|
+
const divider$2 = "_divider_1l6t0_131";
|
|
4840
|
+
const styleTrigger = "_styleTrigger_1l6t0_140";
|
|
4841
|
+
const styleTriggerLabel = "_styleTriggerLabel_1l6t0_174";
|
|
4842
|
+
const styleTriggerCaret = "_styleTriggerCaret_1l6t0_183";
|
|
4843
|
+
const iconTrigger = "_iconTrigger_1l6t0_190";
|
|
4844
|
+
const styleItem = "_styleItem_1l6t0_198";
|
|
4845
|
+
const styleIcon = "_styleIcon_1l6t0_204";
|
|
4846
|
+
const scriptGlyph = "_scriptGlyph_1l6t0_214";
|
|
4847
|
+
const menu = "_menu_1l6t0_226";
|
|
4848
|
+
const menuItem = "_menuItem_1l6t0_237";
|
|
4849
|
+
const menuItemSelected = "_menuItemSelected_1l6t0_264";
|
|
4850
|
+
const listSplit = "_listSplit_1l6t0_279";
|
|
4851
|
+
const listSplitActive = "_listSplitActive_1l6t0_285";
|
|
4852
|
+
const numberingCaret = "_numberingCaret_1l6t0_297";
|
|
4853
|
+
const numberingCaretActive = "_numberingCaretActive_1l6t0_327";
|
|
4854
|
+
const numberingMenu = "_numberingMenu_1l6t0_331";
|
|
4855
|
+
const numberingGrid = "_numberingGrid_1l6t0_341";
|
|
4856
|
+
const numberingOption = "_numberingOption_1l6t0_347";
|
|
4857
|
+
const numberingOptionActive = "_numberingOptionActive_1l6t0_362";
|
|
4858
|
+
const numberingPreview = "_numberingPreview_1l6t0_367";
|
|
4859
|
+
const numberingPreviewRow = "_numberingPreviewRow_1l6t0_373";
|
|
4860
|
+
const numberingPreviewMarker = "_numberingPreviewMarker_1l6t0_388";
|
|
4861
|
+
const numberingPreviewLine = "_numberingPreviewLine_1l6t0_396";
|
|
4862
|
+
const tableInsertCaret = "_tableInsertCaret_1l6t0_402";
|
|
4863
|
+
const tableSizePicker = "_tableSizePicker_1l6t0_410";
|
|
4864
|
+
const tableSizeGrid = "_tableSizeGrid_1l6t0_420";
|
|
4865
|
+
const tableSizeCell = "_tableSizeCell_1l6t0_425";
|
|
4866
|
+
const tableSizeCellActive = "_tableSizeCellActive_1l6t0_435";
|
|
4867
|
+
const tableSizeLabel = "_tableSizeLabel_1l6t0_440";
|
|
4868
|
+
const popoverContent$1 = "_popoverContent_1l6t0_449";
|
|
4869
|
+
const mathLayer = "_mathLayer_1l6t0_453";
|
|
4870
|
+
const mathStack = "_mathStack_1l6t0_458";
|
|
4871
|
+
const mathStackBlock = "_mathStackBlock_1l6t0_465";
|
|
4872
|
+
const mathHint = "_mathHint_1l6t0_470";
|
|
4873
|
+
const mathHintBlock = "_mathHintBlock_1l6t0_482";
|
|
4874
|
+
const mathHintIcon = "_mathHintIcon_1l6t0_488";
|
|
4875
|
+
const mathField = "_mathField_1l6t0_519";
|
|
4876
|
+
const mathFieldBlock = "_mathFieldBlock_1l6t0_531";
|
|
4877
|
+
const mathInput = "_mathInput_1l6t0_538";
|
|
4878
|
+
const mathDone = "_mathDone_1l6t0_556";
|
|
4879
|
+
const mathDoneKbd = "_mathDoneKbd_1l6t0_581";
|
|
3385
4880
|
const styles$6 = {
|
|
3386
4881
|
toolbar,
|
|
3387
4882
|
inner,
|
|
@@ -3404,6 +4899,18 @@ const styles$6 = {
|
|
|
3404
4899
|
menu,
|
|
3405
4900
|
menuItem,
|
|
3406
4901
|
menuItemSelected,
|
|
4902
|
+
listSplit,
|
|
4903
|
+
listSplitActive,
|
|
4904
|
+
numberingCaret,
|
|
4905
|
+
numberingCaretActive,
|
|
4906
|
+
numberingMenu,
|
|
4907
|
+
numberingGrid,
|
|
4908
|
+
numberingOption,
|
|
4909
|
+
numberingOptionActive,
|
|
4910
|
+
numberingPreview,
|
|
4911
|
+
numberingPreviewRow,
|
|
4912
|
+
numberingPreviewMarker,
|
|
4913
|
+
numberingPreviewLine,
|
|
3407
4914
|
tableInsertCaret,
|
|
3408
4915
|
tableSizePicker,
|
|
3409
4916
|
tableSizeGrid,
|
|
@@ -3452,8 +4959,8 @@ const PALETTE = [
|
|
|
3452
4959
|
["#5c1010", "#700818", "#7c4808", "#7c6808", "#205818", "#10403c", "#183c78", "#0c3060", "#3c1460", "#601838"]
|
|
3453
4960
|
];
|
|
3454
4961
|
const THEME_COLORS = ["#ff6719", "#ff5500"];
|
|
3455
|
-
function ColorPalette({ value, onPick,
|
|
3456
|
-
const t =
|
|
4962
|
+
function ColorPalette({ value, onPick, locale = "en" }) {
|
|
4963
|
+
const t = getLocaleBundle(locale).palette;
|
|
3457
4964
|
const current = value == null ? void 0 : value.toLowerCase();
|
|
3458
4965
|
return /* @__PURE__ */ jsxs("div", { className: styles$5.palette, children: [
|
|
3459
4966
|
/* @__PURE__ */ jsxs(
|
|
@@ -3830,7 +5337,7 @@ const styles$3 = {
|
|
|
3830
5337
|
function LinkPopover({
|
|
3831
5338
|
editor,
|
|
3832
5339
|
trigger,
|
|
3833
|
-
|
|
5340
|
+
locale = "en",
|
|
3834
5341
|
className,
|
|
3835
5342
|
style
|
|
3836
5343
|
}) {
|
|
@@ -3847,7 +5354,7 @@ function LinkPopover({
|
|
|
3847
5354
|
LinkPanel,
|
|
3848
5355
|
{
|
|
3849
5356
|
editor,
|
|
3850
|
-
|
|
5357
|
+
locale,
|
|
3851
5358
|
className,
|
|
3852
5359
|
style,
|
|
3853
5360
|
onClose: () => setOpen(false)
|
|
@@ -3859,12 +5366,12 @@ function LinkPopover({
|
|
|
3859
5366
|
}
|
|
3860
5367
|
function LinkPanel({
|
|
3861
5368
|
editor,
|
|
3862
|
-
|
|
5369
|
+
locale,
|
|
3863
5370
|
className,
|
|
3864
5371
|
style,
|
|
3865
5372
|
onClose
|
|
3866
5373
|
}) {
|
|
3867
|
-
const t =
|
|
5374
|
+
const t = getLocaleBundle(locale).link;
|
|
3868
5375
|
const [url, setUrl] = useState(() => readLinkHref(editor));
|
|
3869
5376
|
const [invalid, setInvalid] = useState(false);
|
|
3870
5377
|
const canEdit = canSetLink(editor);
|
|
@@ -4146,15 +5653,15 @@ function appendColumnToTable(editor) {
|
|
|
4146
5653
|
selectLineAt(editor, table, "col", TableMap.get(table.node).width - 1);
|
|
4147
5654
|
return addColumnsAfter(editor, 1);
|
|
4148
5655
|
}
|
|
4149
|
-
const handle = "
|
|
4150
|
-
const handleRow = "
|
|
4151
|
-
const handleCol = "
|
|
4152
|
-
const extend = "
|
|
4153
|
-
const tableBubble = "
|
|
4154
|
-
const tableMenuItem = "
|
|
4155
|
-
const tableMenuItemIcon = "
|
|
4156
|
-
const tableMenuItemLabel = "
|
|
4157
|
-
const tableMenuDivider = "
|
|
5656
|
+
const handle = "_handle_1m19y_9";
|
|
5657
|
+
const handleRow = "_handleRow_1m19y_30";
|
|
5658
|
+
const handleCol = "_handleCol_1m19y_40";
|
|
5659
|
+
const extend = "_extend_1m19y_71";
|
|
5660
|
+
const tableBubble = "_tableBubble_1m19y_117";
|
|
5661
|
+
const tableMenuItem = "_tableMenuItem_1m19y_130";
|
|
5662
|
+
const tableMenuItemIcon = "_tableMenuItemIcon_1m19y_156";
|
|
5663
|
+
const tableMenuItemLabel = "_tableMenuItemLabel_1m19y_166";
|
|
5664
|
+
const tableMenuDivider = "_tableMenuDivider_1m19y_171";
|
|
4158
5665
|
const styles$2 = {
|
|
4159
5666
|
handle,
|
|
4160
5667
|
handleRow,
|
|
@@ -4166,9 +5673,9 @@ const styles$2 = {
|
|
|
4166
5673
|
tableMenuItemLabel,
|
|
4167
5674
|
tableMenuDivider
|
|
4168
5675
|
};
|
|
4169
|
-
function edgeFlags(editor,
|
|
5676
|
+
function edgeFlags(editor, cell2) {
|
|
4170
5677
|
try {
|
|
4171
|
-
const $cell = cellAround(editor.state.doc.resolve(editor.view.posAtDOM(
|
|
5678
|
+
const $cell = cellAround(editor.state.doc.resolve(editor.view.posAtDOM(cell2, 0)));
|
|
4172
5679
|
if (!$cell) return { onLastRow: false, onLastCol: false };
|
|
4173
5680
|
const map = TableMap.get($cell.node(-1));
|
|
4174
5681
|
const rect = map.findCell($cell.pos - $cell.start(-1));
|
|
@@ -4180,26 +5687,28 @@ function edgeFlags(editor, cell) {
|
|
|
4180
5687
|
return { onLastRow: false, onLastCol: false };
|
|
4181
5688
|
}
|
|
4182
5689
|
}
|
|
4183
|
-
const COL_HANDLE_GAP =
|
|
4184
|
-
const
|
|
5690
|
+
const COL_HANDLE_GAP = 18;
|
|
5691
|
+
const COL_HANDLE_HEIGHT = 12;
|
|
5692
|
+
const ROW_HANDLE_GAP = 20;
|
|
5693
|
+
const ROW_HANDLE_WIDTH = 12;
|
|
4185
5694
|
const EXTEND_GAP = 6;
|
|
4186
|
-
const EXTEND_THICKNESS =
|
|
5695
|
+
const EXTEND_THICKNESS = 12;
|
|
4187
5696
|
const HOVER_KEEP_MS = 160;
|
|
4188
|
-
function measureCell(editor,
|
|
4189
|
-
const table =
|
|
4190
|
-
const row2 =
|
|
5697
|
+
function measureCell(editor, cell2) {
|
|
5698
|
+
const table = cell2.closest("table");
|
|
5699
|
+
const row2 = cell2.closest("tr");
|
|
4191
5700
|
if (!table || !row2) return null;
|
|
4192
5701
|
try {
|
|
4193
|
-
editor.view.posAtDOM(
|
|
5702
|
+
editor.view.posAtDOM(cell2, 0);
|
|
4194
5703
|
} catch {
|
|
4195
5704
|
return null;
|
|
4196
5705
|
}
|
|
4197
|
-
const cellRect =
|
|
5706
|
+
const cellRect = cell2.getBoundingClientRect();
|
|
4198
5707
|
const rowRect = row2.getBoundingClientRect();
|
|
4199
5708
|
const tableRect = table.getBoundingClientRect();
|
|
4200
|
-
const edges = edgeFlags(editor,
|
|
5709
|
+
const edges = edgeFlags(editor, cell2);
|
|
4201
5710
|
return {
|
|
4202
|
-
cell,
|
|
5711
|
+
cell: cell2,
|
|
4203
5712
|
...edges,
|
|
4204
5713
|
rowTop: rowRect.top,
|
|
4205
5714
|
rowHeight: rowRect.height,
|
|
@@ -4211,10 +5720,10 @@ function measureCell(editor, cell) {
|
|
|
4211
5720
|
tableBottom: tableRect.bottom
|
|
4212
5721
|
};
|
|
4213
5722
|
}
|
|
4214
|
-
function selectRowOrColumn(editor,
|
|
5723
|
+
function selectRowOrColumn(editor, cell2, kind) {
|
|
4215
5724
|
let pos;
|
|
4216
5725
|
try {
|
|
4217
|
-
pos = editor.view.posAtDOM(
|
|
5726
|
+
pos = editor.view.posAtDOM(cell2, 0);
|
|
4218
5727
|
} catch {
|
|
4219
5728
|
return false;
|
|
4220
5729
|
}
|
|
@@ -4317,9 +5826,9 @@ function TableHandles({ editor, labels }) {
|
|
|
4317
5826
|
const closeMenu = useCallback(() => setMenu(null), []);
|
|
4318
5827
|
const remeasureHover = useCallback(() => {
|
|
4319
5828
|
var _a;
|
|
4320
|
-
const
|
|
4321
|
-
if (!
|
|
4322
|
-
const next =
|
|
5829
|
+
const cell2 = (_a = hoverRef.current) == null ? void 0 : _a.cell;
|
|
5830
|
+
if (!cell2) return;
|
|
5831
|
+
const next = cell2.isConnected ? measureCell(editor, cell2) : null;
|
|
4323
5832
|
hoverRef.current = next;
|
|
4324
5833
|
setHover(next);
|
|
4325
5834
|
}, [editor]);
|
|
@@ -4338,8 +5847,8 @@ function TableHandles({ editor, labels }) {
|
|
|
4338
5847
|
cancelPendingClear();
|
|
4339
5848
|
return;
|
|
4340
5849
|
}
|
|
4341
|
-
const
|
|
4342
|
-
if (!
|
|
5850
|
+
const cell2 = target && editor.view.dom.contains(target) ? target.closest("td, th") : null;
|
|
5851
|
+
if (!cell2) {
|
|
4343
5852
|
if (hoverRef.current && clearTimerRef.current === null) {
|
|
4344
5853
|
clearTimerRef.current = setTimeout(() => {
|
|
4345
5854
|
clearTimerRef.current = null;
|
|
@@ -4349,8 +5858,8 @@ function TableHandles({ editor, labels }) {
|
|
|
4349
5858
|
return;
|
|
4350
5859
|
}
|
|
4351
5860
|
cancelPendingClear();
|
|
4352
|
-
if (((_b = hoverRef.current) == null ? void 0 : _b.cell) ===
|
|
4353
|
-
const next = measureCell(editor,
|
|
5861
|
+
if (((_b = hoverRef.current) == null ? void 0 : _b.cell) === cell2) return;
|
|
5862
|
+
const next = measureCell(editor, cell2);
|
|
4354
5863
|
hoverRef.current = next;
|
|
4355
5864
|
setHover(next);
|
|
4356
5865
|
};
|
|
@@ -4430,8 +5939,8 @@ function TableHandles({ editor, labels }) {
|
|
|
4430
5939
|
className: `${styles$2.handle} ${styles$2.handleRow}`,
|
|
4431
5940
|
style: {
|
|
4432
5941
|
left: hover.tableLeft - ROW_HANDLE_GAP,
|
|
4433
|
-
// 长度跟着行高走(原来固定 28px 居中,行高时就显得太短)
|
|
4434
5942
|
top: hover.rowTop,
|
|
5943
|
+
width: ROW_HANDLE_WIDTH,
|
|
4435
5944
|
height: hover.rowHeight
|
|
4436
5945
|
},
|
|
4437
5946
|
title: labels.tableRowMenu,
|
|
@@ -4448,10 +5957,10 @@ function TableHandles({ editor, labels }) {
|
|
|
4448
5957
|
"data-table-handle": "col",
|
|
4449
5958
|
className: `${styles$2.handle} ${styles$2.handleCol}`,
|
|
4450
5959
|
style: {
|
|
4451
|
-
// 长度跟着列宽走,两端与单元格对齐
|
|
4452
5960
|
left: hover.colLeft,
|
|
4453
5961
|
top: hover.tableTop - COL_HANDLE_GAP,
|
|
4454
|
-
width: hover.colWidth
|
|
5962
|
+
width: hover.colWidth,
|
|
5963
|
+
height: COL_HANDLE_HEIGHT
|
|
4455
5964
|
},
|
|
4456
5965
|
title: labels.tableColumnMenu,
|
|
4457
5966
|
"aria-label": labels.tableColumnMenu,
|
|
@@ -4816,7 +6325,9 @@ const MenuCloseCtx = createContext(() => {
|
|
|
4816
6325
|
});
|
|
4817
6326
|
function MenuPopover({
|
|
4818
6327
|
trigger,
|
|
4819
|
-
children
|
|
6328
|
+
children,
|
|
6329
|
+
contentClassName,
|
|
6330
|
+
align = "start"
|
|
4820
6331
|
}) {
|
|
4821
6332
|
const [open, setOpen] = useState(false);
|
|
4822
6333
|
const close = useCallback(() => setOpen(false), []);
|
|
@@ -4825,9 +6336,9 @@ function MenuPopover({
|
|
|
4825
6336
|
/* @__PURE__ */ jsx(Popover.Portal, { children: /* @__PURE__ */ jsx(
|
|
4826
6337
|
Popover.Content,
|
|
4827
6338
|
{
|
|
4828
|
-
className: styles$6.menu,
|
|
6339
|
+
className: contentClassName ? `${styles$6.menu} ${contentClassName}` : styles$6.menu,
|
|
4829
6340
|
sideOffset: 4,
|
|
4830
|
-
align
|
|
6341
|
+
align,
|
|
4831
6342
|
onOpenAutoFocus: (e2) => e2.preventDefault(),
|
|
4832
6343
|
onCloseAutoFocus: (e2) => e2.preventDefault(),
|
|
4833
6344
|
children: /* @__PURE__ */ jsx(MenuCloseCtx.Provider, { value: close, children })
|
|
@@ -4857,6 +6368,43 @@ function MenuItem({
|
|
|
4857
6368
|
}
|
|
4858
6369
|
);
|
|
4859
6370
|
}
|
|
6371
|
+
function NumberingFormatGrid({
|
|
6372
|
+
current,
|
|
6373
|
+
onSelect
|
|
6374
|
+
}) {
|
|
6375
|
+
const close = useContext(MenuCloseCtx);
|
|
6376
|
+
return /* @__PURE__ */ jsx("div", { className: styles$6.numberingGrid, role: "group", "aria-label": "Numbering formats", children: NUMBERING_FORMAT_IDS.map((format) => {
|
|
6377
|
+
const active2 = current === format;
|
|
6378
|
+
return /* @__PURE__ */ jsx(
|
|
6379
|
+
"button",
|
|
6380
|
+
{
|
|
6381
|
+
type: "button",
|
|
6382
|
+
role: "menuitem",
|
|
6383
|
+
"aria-label": NUMBERING_FORMAT_LABELS[format],
|
|
6384
|
+
"aria-pressed": active2,
|
|
6385
|
+
className: `${styles$6.numberingOption}${active2 ? ` ${styles$6.numberingOptionActive}` : ""}`,
|
|
6386
|
+
onMouseDown: (e2) => e2.preventDefault(),
|
|
6387
|
+
onClick: () => {
|
|
6388
|
+
onSelect(format);
|
|
6389
|
+
close();
|
|
6390
|
+
},
|
|
6391
|
+
children: /* @__PURE__ */ jsx("span", { className: styles$6.numberingPreview, children: NUMBERING_FORMAT_PREVIEWS[format].map((row2, index) => /* @__PURE__ */ jsxs(
|
|
6392
|
+
"span",
|
|
6393
|
+
{
|
|
6394
|
+
className: styles$6.numberingPreviewRow,
|
|
6395
|
+
"data-depth": row2.depth,
|
|
6396
|
+
children: [
|
|
6397
|
+
/* @__PURE__ */ jsx("span", { className: styles$6.numberingPreviewMarker, children: row2.marker }),
|
|
6398
|
+
/* @__PURE__ */ jsx("span", { className: styles$6.numberingPreviewLine })
|
|
6399
|
+
]
|
|
6400
|
+
},
|
|
6401
|
+
`${format}-${index}`
|
|
6402
|
+
)) })
|
|
6403
|
+
},
|
|
6404
|
+
format
|
|
6405
|
+
);
|
|
6406
|
+
}) });
|
|
6407
|
+
}
|
|
4860
6408
|
const TABLE_PICKER_COLS = 10;
|
|
4861
6409
|
const TABLE_PICKER_ROWS = 8;
|
|
4862
6410
|
function TableInsertItem({
|
|
@@ -4949,7 +6497,7 @@ function ColorPopover({
|
|
|
4949
6497
|
bar: bar2,
|
|
4950
6498
|
value,
|
|
4951
6499
|
onPick,
|
|
4952
|
-
|
|
6500
|
+
locale
|
|
4953
6501
|
}) {
|
|
4954
6502
|
const [open, setOpen] = useState(false);
|
|
4955
6503
|
return /* @__PURE__ */ jsxs(Popover.Root, { open, onOpenChange: setOpen, children: [
|
|
@@ -4983,7 +6531,7 @@ function ColorPopover({
|
|
|
4983
6531
|
onPick(c);
|
|
4984
6532
|
setOpen(false);
|
|
4985
6533
|
},
|
|
4986
|
-
|
|
6534
|
+
locale
|
|
4987
6535
|
}
|
|
4988
6536
|
)
|
|
4989
6537
|
}
|
|
@@ -5000,13 +6548,13 @@ function EditorToolbar({
|
|
|
5000
6548
|
importAccept,
|
|
5001
6549
|
importMenuItems,
|
|
5002
6550
|
showImport = true,
|
|
5003
|
-
|
|
6551
|
+
locale = "en",
|
|
5004
6552
|
onSearch,
|
|
5005
6553
|
searchActive = false,
|
|
5006
6554
|
extraToolbarItems,
|
|
5007
6555
|
className
|
|
5008
6556
|
}) {
|
|
5009
|
-
const t =
|
|
6557
|
+
const t = getLocaleBundle(locale).toolbar;
|
|
5010
6558
|
const state = useEditorState({
|
|
5011
6559
|
editor,
|
|
5012
6560
|
selector: ({ editor: e2 }) => ({
|
|
@@ -5024,7 +6572,9 @@ function EditorToolbar({
|
|
|
5024
6572
|
isParagraph: e2.isActive("paragraph"),
|
|
5025
6573
|
bulletList: e2.isActive("bulletList"),
|
|
5026
6574
|
orderedList: e2.isActive("orderedList"),
|
|
6575
|
+
numberingFormat: readCurrentNumberingFormat(e2),
|
|
5027
6576
|
blockquote: e2.isActive("blockquote"),
|
|
6577
|
+
details: e2.isActive("details"),
|
|
5028
6578
|
textColor: e2.getAttributes("textStyle").color || void 0,
|
|
5029
6579
|
highlightColor: e2.getAttributes("highlight").color || void 0,
|
|
5030
6580
|
superscript: e2.isActive("superscript"),
|
|
@@ -5397,7 +6947,7 @@ function EditorToolbar({
|
|
|
5397
6947
|
bar: state.textColor || "#ff3b30",
|
|
5398
6948
|
value: state.textColor,
|
|
5399
6949
|
onPick: applyTextColor,
|
|
5400
|
-
|
|
6950
|
+
locale
|
|
5401
6951
|
}
|
|
5402
6952
|
),
|
|
5403
6953
|
/* @__PURE__ */ jsx(
|
|
@@ -5408,7 +6958,7 @@ function EditorToolbar({
|
|
|
5408
6958
|
bar: state.highlightColor || "#ffd83d",
|
|
5409
6959
|
value: state.highlightColor,
|
|
5410
6960
|
onPick: applyHighlight,
|
|
5411
|
-
|
|
6961
|
+
locale
|
|
5412
6962
|
}
|
|
5413
6963
|
),
|
|
5414
6964
|
/* @__PURE__ */ jsxs(
|
|
@@ -5476,13 +7026,7 @@ function EditorToolbar({
|
|
|
5476
7026
|
LinkPopover,
|
|
5477
7027
|
{
|
|
5478
7028
|
editor,
|
|
5479
|
-
|
|
5480
|
-
field: t.linkPrompt,
|
|
5481
|
-
apply: t.linkApply,
|
|
5482
|
-
open: t.linkOpen,
|
|
5483
|
-
remove: t.linkRemove,
|
|
5484
|
-
invalid: t.linkInvalid
|
|
5485
|
-
},
|
|
7029
|
+
locale,
|
|
5486
7030
|
trigger: /* @__PURE__ */ jsx(ToolbarButton, { title: t.link, active: state.link, children: /* @__PURE__ */ jsx(LinkIcon, {}) })
|
|
5487
7031
|
}
|
|
5488
7032
|
),
|
|
@@ -5543,6 +7087,19 @@ function EditorToolbar({
|
|
|
5543
7087
|
children: /* @__PURE__ */ jsx("span", { className: styles$6.txtIcon, children: "❝" })
|
|
5544
7088
|
}
|
|
5545
7089
|
),
|
|
7090
|
+
/* @__PURE__ */ jsx(
|
|
7091
|
+
ToolbarButton,
|
|
7092
|
+
{
|
|
7093
|
+
title: t.details,
|
|
7094
|
+
active: state.details,
|
|
7095
|
+
onClick: () => {
|
|
7096
|
+
const next = editor.chain().focus();
|
|
7097
|
+
if (editor.isActive("details")) next.unsetDetails().run();
|
|
7098
|
+
else next.setDetails().run();
|
|
7099
|
+
},
|
|
7100
|
+
children: /* @__PURE__ */ jsx(DetailsIcon, {})
|
|
7101
|
+
}
|
|
7102
|
+
),
|
|
5546
7103
|
/* @__PURE__ */ jsx(Divider, {}),
|
|
5547
7104
|
/* @__PURE__ */ jsx(
|
|
5548
7105
|
MenuPopover,
|
|
@@ -5663,13 +7220,46 @@ function EditorToolbar({
|
|
|
5663
7220
|
children: /* @__PURE__ */ jsx(ListUnorderedIcon, {})
|
|
5664
7221
|
}
|
|
5665
7222
|
),
|
|
5666
|
-
/* @__PURE__ */
|
|
5667
|
-
|
|
7223
|
+
/* @__PURE__ */ jsxs(
|
|
7224
|
+
"span",
|
|
5668
7225
|
{
|
|
5669
|
-
|
|
5670
|
-
|
|
5671
|
-
|
|
5672
|
-
|
|
7226
|
+
className: `${styles$6.listSplit}${state.orderedList ? ` ${styles$6.listSplitActive}` : ""}`,
|
|
7227
|
+
children: [
|
|
7228
|
+
/* @__PURE__ */ jsx(
|
|
7229
|
+
ToolbarButton,
|
|
7230
|
+
{
|
|
7231
|
+
title: t.orderedList,
|
|
7232
|
+
active: state.orderedList,
|
|
7233
|
+
onClick: () => chain().toggleOrderedList().run(),
|
|
7234
|
+
children: /* @__PURE__ */ jsx(ListOrderedIcon, {})
|
|
7235
|
+
}
|
|
7236
|
+
),
|
|
7237
|
+
/* @__PURE__ */ jsx(
|
|
7238
|
+
MenuPopover,
|
|
7239
|
+
{
|
|
7240
|
+
align: "end",
|
|
7241
|
+
contentClassName: styles$6.numberingMenu,
|
|
7242
|
+
trigger: /* @__PURE__ */ jsx(
|
|
7243
|
+
"button",
|
|
7244
|
+
{
|
|
7245
|
+
type: "button",
|
|
7246
|
+
className: `${styles$6.numberingCaret}${state.numberingFormat ? ` ${styles$6.numberingCaretActive}` : ""}`,
|
|
7247
|
+
title: t.numberingFormat,
|
|
7248
|
+
"aria-label": t.numberingFormat,
|
|
7249
|
+
onMouseDown: (e2) => e2.preventDefault(),
|
|
7250
|
+
children: /* @__PURE__ */ jsx(ChevronDownIcon, { size: 12 })
|
|
7251
|
+
}
|
|
7252
|
+
),
|
|
7253
|
+
children: /* @__PURE__ */ jsx(
|
|
7254
|
+
NumberingFormatGrid,
|
|
7255
|
+
{
|
|
7256
|
+
current: state.numberingFormat,
|
|
7257
|
+
onSelect: (format) => applyNumberingFormat(editor, format)
|
|
7258
|
+
}
|
|
7259
|
+
)
|
|
7260
|
+
}
|
|
7261
|
+
)
|
|
7262
|
+
]
|
|
5673
7263
|
}
|
|
5674
7264
|
),
|
|
5675
7265
|
/* @__PURE__ */ jsx(
|
|
@@ -5779,17 +7369,6 @@ function EditorToolbar({
|
|
|
5779
7369
|
/* @__PURE__ */ jsx(ImageAlignTools, { editor, labels: t })
|
|
5780
7370
|
] });
|
|
5781
7371
|
}
|
|
5782
|
-
function useIsMobile(breakpoint = 768) {
|
|
5783
|
-
const [isMobile, setIsMobile] = useState(false);
|
|
5784
|
-
useEffect(() => {
|
|
5785
|
-
const mq = window.matchMedia(`(max-width: ${breakpoint - 1}px)`);
|
|
5786
|
-
const update = () => setIsMobile(mq.matches);
|
|
5787
|
-
update();
|
|
5788
|
-
mq.addEventListener("change", update);
|
|
5789
|
-
return () => mq.removeEventListener("change", update);
|
|
5790
|
-
}, [breakpoint]);
|
|
5791
|
-
return isMobile;
|
|
5792
|
-
}
|
|
5793
7372
|
const desktop = "_desktop_euqdt_3";
|
|
5794
7373
|
const header = "_header_euqdt_19";
|
|
5795
7374
|
const headerTitle = "_headerTitle_euqdt_27";
|
|
@@ -5828,8 +7407,13 @@ const styles$1 = {
|
|
|
5828
7407
|
mobilePanel,
|
|
5829
7408
|
mobilePanelOpen
|
|
5830
7409
|
};
|
|
5831
|
-
function TocPanel({
|
|
5832
|
-
|
|
7410
|
+
function TocPanel({
|
|
7411
|
+
items,
|
|
7412
|
+
activeId,
|
|
7413
|
+
onItemClick,
|
|
7414
|
+
locale = "en"
|
|
7415
|
+
}) {
|
|
7416
|
+
const t = getLocaleBundle(locale).toc;
|
|
5833
7417
|
const isMobile = useIsMobile();
|
|
5834
7418
|
const [collapsed, setCollapsed] = useState(false);
|
|
5835
7419
|
const [mobileOpen, setMobileOpen] = useState(false);
|
|
@@ -6000,11 +7584,11 @@ function findRangeByAnchor(editor, anchor) {
|
|
|
6000
7584
|
const BLOCK_SEPARATOR = "\n\n";
|
|
6001
7585
|
function topLevelBlocks(editor) {
|
|
6002
7586
|
const blocks = [];
|
|
6003
|
-
editor.state.doc.forEach((node,
|
|
7587
|
+
editor.state.doc.forEach((node, offset2) => {
|
|
6004
7588
|
blocks.push({
|
|
6005
7589
|
json: node.toJSON(),
|
|
6006
|
-
from:
|
|
6007
|
-
to:
|
|
7590
|
+
from: offset2,
|
|
7591
|
+
to: offset2 + node.nodeSize
|
|
6008
7592
|
});
|
|
6009
7593
|
});
|
|
6010
7594
|
return blocks;
|
|
@@ -6134,12 +7718,15 @@ export {
|
|
|
6134
7718
|
CommentMark,
|
|
6135
7719
|
CommentPopover,
|
|
6136
7720
|
CopyIcon,
|
|
7721
|
+
DetailsIcon,
|
|
7722
|
+
DownloadIcon,
|
|
6137
7723
|
EditorToolbar,
|
|
6138
7724
|
EraserIcon,
|
|
6139
7725
|
ExternalLinkIcon,
|
|
6140
7726
|
FIND_DEBOUNCE_MS,
|
|
6141
7727
|
default2 as FindAndReplace,
|
|
6142
7728
|
FindReplaceBar,
|
|
7729
|
+
GripIcon,
|
|
6143
7730
|
ImageAlignTools,
|
|
6144
7731
|
ImageIcon,
|
|
6145
7732
|
ImageUploadNode,
|
|
@@ -6198,17 +7785,6 @@ export {
|
|
|
6198
7785
|
createChart,
|
|
6199
7786
|
createCitationRef,
|
|
6200
7787
|
createDefaultSlashMenuItems,
|
|
6201
|
-
defaultChartLabels,
|
|
6202
|
-
defaultCodeBlockLabels,
|
|
6203
|
-
defaultColorPaletteLabels,
|
|
6204
|
-
defaultCommentLabels,
|
|
6205
|
-
defaultFindLabels,
|
|
6206
|
-
defaultImageUploadLabels,
|
|
6207
|
-
defaultLinkPopoverLabels,
|
|
6208
|
-
defaultShortcutLabels,
|
|
6209
|
-
defaultSlashMenuLabels,
|
|
6210
|
-
defaultTocLabels,
|
|
6211
|
-
defaultToolbarLabels,
|
|
6212
7788
|
enrichMarkdownCitations,
|
|
6213
7789
|
b2 as extractFootnoteSources,
|
|
6214
7790
|
e as extractToc,
|