@jvs-milkdown/crepe 1.2.4 → 1.2.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. package/lib/cjs/builder.js +2 -0
  2. package/lib/cjs/builder.js.map +1 -1
  3. package/lib/cjs/feature/block-edit/index.js +6 -2
  4. package/lib/cjs/feature/block-edit/index.js.map +1 -1
  5. package/lib/cjs/feature/code-mirror/index.js +2 -0
  6. package/lib/cjs/feature/code-mirror/index.js.map +1 -1
  7. package/lib/cjs/feature/cursor/index.js +2 -0
  8. package/lib/cjs/feature/cursor/index.js.map +1 -1
  9. package/lib/cjs/feature/image-block/index.js +3 -4
  10. package/lib/cjs/feature/image-block/index.js.map +1 -1
  11. package/lib/cjs/feature/latex/index.js +2 -0
  12. package/lib/cjs/feature/latex/index.js.map +1 -1
  13. package/lib/cjs/feature/link-tooltip/index.js +2 -0
  14. package/lib/cjs/feature/link-tooltip/index.js.map +1 -1
  15. package/lib/cjs/feature/list-item/index.js +2 -0
  16. package/lib/cjs/feature/list-item/index.js.map +1 -1
  17. package/lib/cjs/feature/placeholder/index.js +4 -1
  18. package/lib/cjs/feature/placeholder/index.js.map +1 -1
  19. package/lib/cjs/feature/table/index.js +2 -0
  20. package/lib/cjs/feature/table/index.js.map +1 -1
  21. package/lib/cjs/feature/toolbar/index.js +242 -7
  22. package/lib/cjs/feature/toolbar/index.js.map +1 -1
  23. package/lib/cjs/index.js +1254 -960
  24. package/lib/cjs/index.js.map +1 -1
  25. package/lib/esm/builder.js +2 -0
  26. package/lib/esm/builder.js.map +1 -1
  27. package/lib/esm/feature/block-edit/index.js +6 -2
  28. package/lib/esm/feature/block-edit/index.js.map +1 -1
  29. package/lib/esm/feature/code-mirror/index.js +2 -0
  30. package/lib/esm/feature/code-mirror/index.js.map +1 -1
  31. package/lib/esm/feature/cursor/index.js +2 -0
  32. package/lib/esm/feature/cursor/index.js.map +1 -1
  33. package/lib/esm/feature/image-block/index.js +3 -4
  34. package/lib/esm/feature/image-block/index.js.map +1 -1
  35. package/lib/esm/feature/latex/index.js +2 -0
  36. package/lib/esm/feature/latex/index.js.map +1 -1
  37. package/lib/esm/feature/link-tooltip/index.js +2 -0
  38. package/lib/esm/feature/link-tooltip/index.js.map +1 -1
  39. package/lib/esm/feature/list-item/index.js +2 -0
  40. package/lib/esm/feature/list-item/index.js.map +1 -1
  41. package/lib/esm/feature/placeholder/index.js +4 -1
  42. package/lib/esm/feature/placeholder/index.js.map +1 -1
  43. package/lib/esm/feature/table/index.js +2 -0
  44. package/lib/esm/feature/table/index.js.map +1 -1
  45. package/lib/esm/feature/toolbar/index.js +242 -7
  46. package/lib/esm/feature/toolbar/index.js.map +1 -1
  47. package/lib/esm/index.js +1329 -1035
  48. package/lib/esm/index.js.map +1 -1
  49. package/lib/theme/common/table.css +11 -7
  50. package/lib/theme/common/toolbar.css +6 -6
  51. package/lib/tsconfig.tsbuildinfo +1 -1
  52. package/lib/types/core/locale.d.ts +2 -0
  53. package/lib/types/core/locale.d.ts.map +1 -1
  54. package/lib/types/feature/attachment/view/components/attachment-block.d.ts.map +1 -1
  55. package/lib/types/feature/attachment/view/index.d.ts.map +1 -1
  56. package/lib/types/feature/block-edit/handle/component.d.ts.map +1 -1
  57. package/lib/types/feature/block-edit/handle/index.d.ts.map +1 -1
  58. package/lib/types/feature/block-edit/index.d.ts.map +1 -1
  59. package/lib/types/feature/block-edit/menu/api.d.ts.map +1 -1
  60. package/lib/types/feature/block-edit/menu/component.d.ts.map +1 -1
  61. package/lib/types/feature/block-edit/menu/index.d.ts.map +1 -1
  62. package/lib/types/feature/fixed-toolbar/component.d.ts.map +1 -1
  63. package/lib/types/feature/fixed-toolbar/config.d.ts +9 -1
  64. package/lib/types/feature/fixed-toolbar/config.d.ts.map +1 -1
  65. package/lib/types/feature/fixed-toolbar/document-header.d.ts.map +1 -1
  66. package/lib/types/feature/fixed-toolbar/index.d.ts.map +1 -1
  67. package/lib/types/feature/fixed-toolbar/menu-bar.d.ts.map +1 -1
  68. package/lib/types/feature/fixed-toolbar/outline-panel.d.ts.map +1 -1
  69. package/lib/types/feature/fixed-toolbar/shortcut-help-modal.d.ts.map +1 -1
  70. package/lib/types/feature/fixed-toolbar/view-menu-state.d.ts.map +1 -1
  71. package/lib/types/feature/index.d.ts +1 -1
  72. package/lib/types/feature/index.d.ts.map +1 -1
  73. package/lib/types/feature/latex/inline-tooltip/component.d.ts.map +1 -1
  74. package/lib/types/feature/latex/inline-tooltip/view.d.ts.map +1 -1
  75. package/lib/types/feature/loader.d.ts.map +1 -1
  76. package/lib/types/feature/placeholder/index.d.ts.map +1 -1
  77. package/lib/types/feature/toolbar/color.d.ts +1 -1
  78. package/lib/types/feature/toolbar/color.d.ts.map +1 -1
  79. package/lib/types/feature/toolbar/component.d.ts.map +1 -1
  80. package/lib/types/feature/toolbar/font.d.ts +1 -1
  81. package/lib/types/feature/toolbar/highlight-mark.d.ts +1 -1
  82. package/lib/types/feature/toolbar/index.d.ts.map +1 -1
  83. package/lib/types/feature/toolbar/underline.d.ts +1 -1
  84. package/lib/types/icons/crop.d.ts +1 -1
  85. package/lib/types/icons/crop.d.ts.map +1 -1
  86. package/lib/types/icons/format-painter.d.ts +2 -0
  87. package/lib/types/icons/format-painter.d.ts.map +1 -0
  88. package/lib/types/icons/index.d.ts +1 -0
  89. package/lib/types/icons/index.d.ts.map +1 -1
  90. package/package.json +4 -4
  91. package/src/core/locale.ts +2 -0
  92. package/src/feature/attachment/view/components/attachment-block.tsx +12 -7
  93. package/src/feature/attachment/view/index.ts +1 -0
  94. package/src/feature/block-edit/handle/component.tsx +5 -4
  95. package/src/feature/block-edit/handle/index.ts +1 -0
  96. package/src/feature/block-edit/index.ts +4 -1
  97. package/src/feature/block-edit/menu/api.ts +6 -1
  98. package/src/feature/block-edit/menu/component.tsx +49 -46
  99. package/src/feature/block-edit/menu/index.ts +1 -0
  100. package/src/feature/fixed-toolbar/component.tsx +3 -2
  101. package/src/feature/fixed-toolbar/config.ts +198 -146
  102. package/src/feature/fixed-toolbar/document-header.tsx +45 -14
  103. package/src/feature/fixed-toolbar/index.ts +2 -1
  104. package/src/feature/fixed-toolbar/menu-bar.tsx +15 -10
  105. package/src/feature/fixed-toolbar/outline-panel.tsx +17 -16
  106. package/src/feature/fixed-toolbar/shortcut-help-modal.tsx +3 -2
  107. package/src/feature/fixed-toolbar/view-menu-state.ts +1 -0
  108. package/src/feature/index.ts +1 -1
  109. package/src/feature/latex/inline-tooltip/component.tsx +3 -2
  110. package/src/feature/latex/inline-tooltip/view.ts +1 -0
  111. package/src/feature/loader.ts +1 -1
  112. package/src/feature/placeholder/index.ts +2 -1
  113. package/src/feature/toolbar/color.ts +77 -73
  114. package/src/feature/toolbar/component.tsx +321 -35
  115. package/src/feature/toolbar/index.ts +1 -0
  116. package/src/icons/align-center.ts +1 -1
  117. package/src/icons/bold.ts +1 -1
  118. package/src/icons/bullet-list.ts +1 -1
  119. package/src/icons/crop.ts +1 -4
  120. package/src/icons/divider.ts +1 -1
  121. package/src/icons/format-painter.ts +5 -0
  122. package/src/icons/h2.ts +1 -1
  123. package/src/icons/index.ts +1 -0
  124. package/src/icons/ordered-list.ts +1 -1
  125. package/src/icons/quote.ts +1 -1
  126. package/src/icons/strikethrough.ts +1 -1
  127. package/src/icons/text.ts +0 -1
  128. package/src/theme/common/table.css +11 -7
  129. package/src/theme/common/toolbar.css +6 -6
  130. package/src/feature/table/test.ts +0 -9
package/lib/esm/index.js CHANGED
@@ -1,18 +1,18 @@
1
1
  import { defaultsDeep } from 'lodash-es';
2
2
  import { languages } from '@codemirror/language-data';
3
3
  import { oneDark } from '@codemirror/theme-one-dark';
4
- import { blockConfig, block, BlockProvider } from '@jvs-milkdown/kit/plugin/block';
5
4
  import { createSlice } from '@jvs-milkdown/kit/ctx';
5
+ import { $ctx, $nodeSchema, $view, $remark, $markAttr, $markSchema, $command, $prose, $useKeymap, $inputRule, getMarkdown } from '@jvs-milkdown/kit/utils';
6
+ import { defineComponent, shallowRef, ref, computed, createApp, watchEffect, watch, onUnmounted, h as h$1, Fragment, reactive, onMounted, onBeforeUnmount, nextTick } from 'vue';
7
+ import { Icon } from '@jvs-milkdown/kit/component';
8
+ import { blockConfig, block, BlockProvider } from '@jvs-milkdown/kit/plugin/block';
6
9
  import { commandsCtx, editorViewCtx, editorCtx, EditorStatus, schemaCtx, editorViewOptionsCtx, Editor, rootCtx, defaultValueCtx } from '@jvs-milkdown/kit/core';
7
10
  import { findNodeInSelection, findParent, nodeRule } from '@jvs-milkdown/kit/prose';
8
11
  import { NodeSelection, TextSelection, Plugin, PluginKey, EditorState, AllSelection } from '@jvs-milkdown/kit/prose/state';
9
- import { defineComponent, ref, computed, watch, watchEffect, onUnmounted, h, createApp, Fragment, reactive, onMounted, onBeforeUnmount, shallowRef, nextTick } from 'vue';
10
12
  import { computePosition, flip, shift, offset } from '@floating-ui/dom';
11
13
  import { slashFactory, SlashProvider } from '@jvs-milkdown/kit/plugin/slash';
12
- import { Icon } from '@jvs-milkdown/kit/component';
13
14
  import { paragraphSchema, clearTextInCurrentBlockCommand, setBlockTypeCommand, headingSchema, wrapInHeadingCommand, blockquoteSchema, wrapInBlockTypeCommand, hrSchema, addBlockTypeCommand, bulletListSchema, orderedListSchema, listItemSchema, liftListItemCommand, wrapInBulletListCommand, wrapInOrderedListCommand, codeBlockSchema, selectTextNearPosCommand, toggleStrongCommand, isMarkSelectedCommand, strongSchema, toggleEmphasisCommand, emphasisSchema, toggleInlineCodeCommand, inlineCodeSchema, linkSchema, commonmark } from '@jvs-milkdown/kit/preset/commonmark';
14
15
  import { createTable, toggleStrikethroughCommand, strikethroughSchema, mergeCellsCommand, gfm } from '@jvs-milkdown/kit/preset/gfm';
15
- import { $remark, $markAttr, $markSchema, $command, $ctx, $nodeSchema, $prose, $useKeymap, $inputRule, $view, getMarkdown } from '@jvs-milkdown/kit/utils';
16
16
  import { visit } from 'unist-util-visit';
17
17
  import { imageBlockSchema, imageBlockConfig, imageBlockComponent } from '@jvs-milkdown/kit/component/image-block';
18
18
  import { lift, toggleMark } from '@jvs-milkdown/kit/prose/commands';
@@ -627,10 +627,7 @@ const wordWrapIcon = `
627
627
  `;
628
628
 
629
629
  const cropIcon = `
630
- <svg viewBox="0 0 1024 1024" height="24px" width="24px">
631
- <path d="M192 128v128H128v64h192V128h-128z m0 0h64v128h-64V128z m512 0v128h192v64H640V128h64z m-512 640H128v-64h192v192h-128v-128z m0 128h64v-128h-64v128z m512 0v-128h192v64h-128v128h-64z m0 0h64v-128h-64v128z" fill="currentColor"/>
632
- <path d="M256 256h512v512H256z" fill="none" stroke="currentColor" stroke-width="64"/>
633
- </svg>
630
+ <svg viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7429" width="24px" height="24px"><path d="M279.296 46.592a46.592 46.592 0 1 0-93.1328 0v139.5712H46.592a46.592 46.592 0 1 0 0 93.1328h139.6224v512c0 25.7024 20.8384 46.5408 46.592 46.5408h512v139.6224a46.592 46.592 0 0 0 93.0816 0v-139.6224h139.6224a46.592 46.592 0 1 0 0-93.1328H279.296V46.592z m139.6224 139.5712a46.592 46.592 0 1 0 0 93.1328h325.7856v325.7856a46.592 46.592 0 0 0 93.1328 0V232.704a46.592 46.592 0 0 0-46.592-46.5408H418.9696z" fill="currentColor" p-id="7430"></path></svg>
634
631
  `;
635
632
 
636
633
  const borderIcon = `
@@ -639,6 +636,12 @@ const borderIcon = `
639
636
  </svg>
640
637
  `;
641
638
 
639
+ const formatPainterIcon = `
640
+ <svg viewBox="0 0 1024 1024" version="1.1" width="20" height="20">
641
+ <path d="M454.698667 302.506667H323.84q-23.04 0-41.6 13.824-18.517333 13.824-25.130667 35.968l-31.36 104.704q-10.112 33.621333 10.794667 61.738666 11.52 15.445333 27.221333 22.442667 0.853333 46.165333-0.810666 105.6-1.408 51.84-58.368 138.496-23.338667 35.413333-3.413334 72.96 20.053333 37.76 62.677334 37.76h477.994666q39.509333 0 69.077334-26.325333 29.738667-26.453333 34.090666-65.962667 10.24-93.738667 10.24-155.946667 0-57.088-8.618666-103.68 20.949333-6.058667 35.285333-25.344 20.864-28.117333 10.837333-61.738666l-31.36-104.704q-6.656-22.144-25.173333-35.968-18.517333-13.781333-41.6-13.781334h-130.858667V197.802667q0-28.885333-20.437333-49.365334Q622.933333 128 594.090667 128H524.373333q-28.842667 0-49.237333 20.48-20.437333 20.437333-20.437333 49.322667v104.746666z m68.992 41.728q0.682667-3.370667 0.682666-6.784V197.802667h69.717334V337.493333q0 3.413333 0.64 6.826667 0.682667 3.370667 2.005333 6.528 1.28 3.2 3.2 6.058667 1.92 2.816 4.352 5.248 2.389333 2.474667 5.248 4.352 2.901333 1.92 6.058667 3.242666 3.157333 1.322667 6.528 1.962667 3.328 0.682667 6.826666 0.682667h165.674667l31.36 104.746666H292.48l31.36-104.746666h165.717333q3.413333 0 6.826667-0.64 3.328-0.682667 6.528-2.005334 3.157333-1.322667 5.973333-3.242666 2.858667-1.877333 5.290667-4.352 2.432-2.432 4.309333-5.248 1.92-2.901333 3.242667-6.058667 1.322667-3.157333 1.962667-6.570667z m252.501333 202.666666q9.429333 43.648 9.429333 100.864 0 58.368-9.813333 148.352-1.450667 12.757333-11.093333 21.376-9.813333 8.704-22.826667 8.704h-100.309333q22.058667-81.493333 22.058666-174.592h-69.674666q0 94.421333-24.96 174.592h-121.514667q41.941333-81.450667 41.941333-174.592H419.754667q0 94.378667-52.992 174.592H263.808q-0.725333 0-1.109333-0.725333-0.469333-0.981333 0.042666-1.749333 67.968-103.253333 69.888-175.018667 1.536-56.533333 0.938667-101.802667H776.106667z" fill="currentColor" p-id="11997"></path>
642
+ </svg>
643
+ `;
644
+
642
645
  const defaultConfig = {
643
646
  [CrepeFeature.CodeMirror]: {
644
647
  theme: oneDark,
@@ -661,6 +664,7 @@ const zhCN = {
661
664
  "toolbar.heading": "\u6807\u9898",
662
665
  "toolbar.formatting": "\u683C\u5F0F",
663
666
  "toolbar.function": "\u529F\u80FD",
667
+ "toolbar.formatPainter": "\u683C\u5F0F\u5237",
664
668
  // menu bar
665
669
  "menuBar.file": "\u6587\u4EF6",
666
670
  "menuBar.edit": "\u7F16\u8F91",
@@ -814,6 +818,7 @@ const enUS = {
814
818
  "toolbar.heading": "Heading",
815
819
  "toolbar.formatting": "Formatting",
816
820
  "toolbar.function": "Function",
821
+ "toolbar.formatPainter": "Format Painter",
817
822
  "menuBar.file": "File",
818
823
  "menuBar.edit": "Edit",
819
824
  "menuBar.view": "View",
@@ -981,102 +986,493 @@ function crepeFeatureConfig(feature) {
981
986
  };
982
987
  }
983
988
 
984
- function isInCodeBlock(selection) {
985
- const type = selection.$from.parent.type;
986
- return type.name === "code_block";
987
- }
988
- function isInList(selection) {
989
- var _a;
990
- const type = (_a = selection.$from.node(selection.$from.depth - 1)) == null ? void 0 : _a.type;
991
- return (type == null ? void 0 : type.name) === "list_item";
992
- }
989
+ const attachmentConfig = $ctx(
990
+ {
991
+ onUpload: async (file) => {
992
+ return {
993
+ url: URL.createObjectURL(file),
994
+ name: file.name,
995
+ size: file.size
996
+ };
997
+ },
998
+ uploadButton: "Upload file",
999
+ uploadPlaceholderText: "or paste link",
1000
+ downloadText: "Download"
1001
+ },
1002
+ "attachmentConfig"
1003
+ );
993
1004
 
994
- var __typeError$6 = (msg) => {
995
- throw TypeError(msg);
996
- };
997
- var __accessCheck$6 = (obj, member, msg) => member.has(obj) || __typeError$6("Cannot " + msg);
998
- var __privateGet$6 = (obj, member, getter) => (__accessCheck$6(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
999
- var __privateAdd$6 = (obj, member, value) => member.has(obj) ? __typeError$6("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
1000
- var __privateSet$6 = (obj, member, value, setter) => (__accessCheck$6(obj, member, "write to private field"), member.set(obj, value), value);
1001
- var _groups, _getGroupInstance;
1002
- class GroupBuilder {
1003
- constructor() {
1004
- __privateAdd$6(this, _groups, []);
1005
- this.clear = () => {
1006
- __privateSet$6(this, _groups, []);
1007
- return this;
1008
- };
1009
- __privateAdd$6(this, _getGroupInstance, (group) => {
1010
- const groupInstance = {
1011
- group,
1012
- addItem: (key, item) => {
1013
- const data = { ...item, key };
1014
- group.items.push(data);
1015
- return groupInstance;
1016
- },
1017
- clear: () => {
1018
- group.items = [];
1019
- return groupInstance;
1005
+ const ATTACHMENT_DATA_TYPE = "attachment-block";
1006
+ const attachmentSchema = $nodeSchema("attachment", () => {
1007
+ return {
1008
+ inline: false,
1009
+ group: "block",
1010
+ selectable: true,
1011
+ draggable: true,
1012
+ isolating: true,
1013
+ marks: "",
1014
+ atom: true,
1015
+ priority: 100,
1016
+ attrs: {
1017
+ src: { default: "", validate: "string" },
1018
+ name: { default: "", validate: "string" },
1019
+ size: { default: 0, validate: "number" },
1020
+ videoWidth: { default: 0, validate: "number" }
1021
+ },
1022
+ parseDOM: [
1023
+ {
1024
+ tag: `a[data-type="${ATTACHMENT_DATA_TYPE}"]`,
1025
+ getAttrs: (dom) => {
1026
+ if (!(dom instanceof HTMLElement))
1027
+ throw new TypeError("Expect dom to be HTMLElement");
1028
+ return {
1029
+ src: dom.getAttribute("href") || "",
1030
+ name: dom.getAttribute("data-name") || "",
1031
+ size: Number(dom.getAttribute("data-size") || 0),
1032
+ videoWidth: Number(dom.getAttribute("data-video-width") || 0)
1033
+ };
1020
1034
  }
1021
- };
1022
- return groupInstance;
1035
+ }
1036
+ ],
1037
+ toDOM: (node) => [
1038
+ "a",
1039
+ {
1040
+ "data-type": ATTACHMENT_DATA_TYPE,
1041
+ href: node.attrs.src,
1042
+ "data-name": node.attrs.name,
1043
+ "data-size": String(node.attrs.size),
1044
+ "data-video-width": String(node.attrs.videoWidth || 0),
1045
+ class: "attachment"
1046
+ },
1047
+ node.attrs.name
1048
+ ],
1049
+ parseMarkdown: {
1050
+ match: (node) => {
1051
+ return node.type === "attachment";
1052
+ },
1053
+ runner: (state, node, type) => {
1054
+ state.addNode(type, {
1055
+ src: node.url,
1056
+ name: node.name || "",
1057
+ size: Number(node.size || 0)
1058
+ });
1059
+ }
1060
+ },
1061
+ toMarkdown: {
1062
+ match: (node) => node.type.name === "attachment",
1063
+ runner: (state, node) => {
1064
+ state.openNode("paragraph");
1065
+ state.addNode(
1066
+ "html",
1067
+ void 0,
1068
+ `<a href="${node.attrs.src}" data-size="${node.attrs.size}" data-name="${node.attrs.name}" data-video-width="${node.attrs.videoWidth || 0}" data-type="${ATTACHMENT_DATA_TYPE}" class="attachment">${node.attrs.name}</a>`
1069
+ );
1070
+ state.closeNode();
1071
+ }
1072
+ }
1073
+ };
1074
+ });
1075
+
1076
+ const downloadIcon = `<svg viewBox="0 0 1024 1024" width="20" height="20" fill="currentColor">
1077
+ <path d="M464.96 743.936L194.304 479.68c-4.928-4.8-10.24-9.408-14.592-14.656-20.736-24.768-21.376-45.76-2.368-63.424 17.664-16.384 43.328-16 65.472 4.8 49.088 46.144 96.64 93.824 144.896 140.8l69.376 67.52 11.968 11.392v-184.96c0-36.096-0.128-86.272-0.32-136.96-0.192-54.912-0.32-110.464-0.32-149.504l-0.064-9.28a208 208 0 0 1 0.704-26.56c3.52-31.168 19.328-46.592 45.248-45.76 25.344 0.832 41.088 16.96 42.688 48.576 1.28 24.384 1.024 48.896 0.768 73.408l-0.128 28.928c0 53.376 0.128 120.32 0.256 188.096 0.192 76.352 0.384 153.792 0.32 214.016 74.432-72.704 185.6-181.12 216.32-210.88 7.424-7.168 14.912-15.168 24-19.52 18.688-8.96 37.632-8.32 52.672 7.872 14.72 15.744 16.448 33.408 4.032 51.392-3.84 5.632-8.576 10.816-13.44 15.616-45.696 44.736-243.328 238.272-289.728 282.24a62.592 62.592 0 0 1-8.064 6.4 43.392 43.392 0 0 1-15.872 10.432c-20.544 7.616-37.504-0.512-51.968-14.848l-11.2-10.88z m430.784-39.744c24-0.576 42.176 14.4 43.328 41.6 1.728 40.832 2.944 82.176-1.088 122.816-5.312 54.144-51.52 89.792-114.752 91.008-50.112 0.896-100.224 0.704-150.4 0.512L608 960H434.944c-64.832 0.128-129.6 0.192-194.432-0.192-90.624-0.512-130.752-40.192-131.392-128.64l-0.192-18.56c-0.32-21.12-0.576-42.304 0.768-63.36 1.92-29.76 20.48-46.528 45.76-45.184 23.488 1.28 37.312 16.32 40.064 45.184 0.896 9.792 0.832 19.648 0.704 29.504l-0.064 11.52c0.384 76.544 7.36 83.392 88.128 83.456a163213.952 163213.952 0 0 0 351.68 0.064l43.968 0.128c36.096 0.128 72.192 0.256 108.288-0.448 52.672-1.024 64-12.864 65.152-64.32 0.192-7.68 0.128-15.488 0-23.232a414.72 414.72 0 0 1 0.704-38.208c2.24-27.712 17.92-42.944 41.664-43.52z" fill="currentColor"></path>
1078
+ </svg>`;
1079
+ function formatBytes(bytes, decimals = 2) {
1080
+ if (!+bytes) return "0 Bytes";
1081
+ const k = 1024;
1082
+ const dm = decimals < 0 ? 0 : decimals;
1083
+ const sizes = ["Bytes", "KB", "MB", "GB", "TB"];
1084
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
1085
+ return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`;
1086
+ }
1087
+ const MilkdownAttachmentBlock = defineComponent({
1088
+ props: {
1089
+ src: { type: Object, required: true },
1090
+ name: { type: Object, required: true },
1091
+ size: { type: Object, required: true },
1092
+ videoWidth: { type: Object, required: true },
1093
+ selected: { type: Object, required: true },
1094
+ readonly: { type: Object, required: true },
1095
+ setAttr: { type: Function, required: true },
1096
+ config: { type: Object, required: true }
1097
+ },
1098
+ setup(props) {
1099
+ const { src, name, size, videoWidth } = props;
1100
+ const isUploading = shallowRef(false);
1101
+ const fileInput = shallowRef(null);
1102
+ const videoWrapperRef = ref(null);
1103
+ const currentWidth = ref(0);
1104
+ const isResizing = ref(false);
1105
+ const isVideo = computed(() => {
1106
+ return name.value && /\.(mp4|webm|ogg|mov|avi|mkv|flv|wmv|m4v|3gp|ts)$/i.test(name.value);
1023
1107
  });
1024
- this.addGroup = (key, label) => {
1025
- const items = [];
1026
- const group = {
1027
- key,
1028
- label,
1029
- items
1030
- };
1031
- __privateGet$6(this, _groups).push(group);
1032
- return __privateGet$6(this, _getGroupInstance).call(this, group);
1108
+ let resizeDir = "";
1109
+ let startX = 0;
1110
+ let startWidth = 0;
1111
+ const triggerUpload = () => {
1112
+ var _a;
1113
+ (_a = fileInput.value) == null ? void 0 : _a.click();
1033
1114
  };
1034
- this.getGroup = (key) => {
1035
- const group = __privateGet$6(this, _groups).find((group2) => group2.key === key);
1036
- if (!group) throw new Error(`Group with key ${key} not found`);
1037
- return __privateGet$6(this, _getGroupInstance).call(this, group);
1115
+ const onFileChange = async (e) => {
1116
+ var _a;
1117
+ const target = e.target;
1118
+ const file = (_a = target.files) == null ? void 0 : _a[0];
1119
+ if (!file) return;
1120
+ isUploading.value = true;
1121
+ try {
1122
+ const result = await props.config.onUpload(file);
1123
+ props.setAttr("src", result.url);
1124
+ props.setAttr("name", result.name);
1125
+ props.setAttr("size", result.size);
1126
+ } catch (err) {
1127
+ console.error("Failed to upload file", err);
1128
+ } finally {
1129
+ isUploading.value = false;
1130
+ target.value = "";
1131
+ }
1038
1132
  };
1039
- this.build = () => {
1040
- return __privateGet$6(this, _groups);
1133
+ const openLink = () => {
1134
+ if (src.value) {
1135
+ window.open(src.value, "_blank");
1136
+ }
1041
1137
  };
1042
- }
1043
- }
1044
- _groups = new WeakMap();
1045
- _getGroupInstance = new WeakMap();
1046
-
1047
- function keepAlive(..._args) {
1048
- }
1049
-
1050
- const remarkTextColorPlugin = $remark(
1051
- "remarkTextColor",
1052
- () => function() {
1053
- const data = this.data();
1054
- function add(key, value) {
1055
- if (Array.isArray(data[key])) {
1056
- data[key].push(value);
1057
- } else {
1058
- data[key] = [value];
1138
+ let activeHandle = null;
1139
+ const onResizePointerMove = (e) => {
1140
+ e.preventDefault();
1141
+ const deltaX = e.clientX - startX;
1142
+ let dw = 0;
1143
+ if (resizeDir.includes("right")) {
1144
+ dw = deltaX;
1145
+ } else if (resizeDir.includes("left")) {
1146
+ dw = -deltaX;
1059
1147
  }
1060
- }
1061
- add("toMarkdownExtensions", {
1062
- handlers: {
1063
- textColor: (node, _, state) => {
1064
- return `<span style="color:${node.color}">${state.containerPhrasing(node, state)}</span>`;
1065
- },
1066
- bgColor: (node, _, state) => {
1067
- return `<span style="background-color:${node.color}">${state.containerPhrasing(node, state)}</span>`;
1148
+ let newWidth = startWidth + dw;
1149
+ if (newWidth < 200) newWidth = 200;
1150
+ const wrapper = videoWrapperRef.value;
1151
+ if (wrapper) {
1152
+ const parent = wrapper.closest(".milkdown-attachment-block-wrapper");
1153
+ if (parent) {
1154
+ const maxWidth = parent.getBoundingClientRect().width;
1155
+ if (newWidth > maxWidth) newWidth = maxWidth;
1068
1156
  }
1069
1157
  }
1070
- });
1071
- return (ast) => {
1072
- visit(ast, (node, index, parent) => {
1073
- if ((node == null ? void 0 : node.type) === "html" && node.value.startsWith("<span") && parent && index != null) {
1074
- const hasTextColor = node.value.includes("color:") && !node.value.match(/background-color:\s*([^"';>]+)/);
1075
- const hasBgColor = node.value.includes("background-color:");
1076
- if (!hasTextColor && !hasBgColor) return;
1077
- let color = null;
1078
- let markType = null;
1079
- if (hasBgColor) {
1158
+ currentWidth.value = newWidth;
1159
+ };
1160
+ const onResizePointerUp = (e) => {
1161
+ if (activeHandle) {
1162
+ activeHandle.releasePointerCapture(e.pointerId);
1163
+ activeHandle.removeEventListener(
1164
+ "pointermove",
1165
+ onResizePointerMove
1166
+ );
1167
+ activeHandle.removeEventListener(
1168
+ "pointerup",
1169
+ onResizePointerUp
1170
+ );
1171
+ activeHandle = null;
1172
+ }
1173
+ isResizing.value = false;
1174
+ if (currentWidth.value > 0) {
1175
+ props.setAttr("videoWidth", Math.round(currentWidth.value));
1176
+ }
1177
+ };
1178
+ const onResizePointerDown = (e, dir) => {
1179
+ if (props.readonly.value) return;
1180
+ e.preventDefault();
1181
+ e.stopPropagation();
1182
+ resizeDir = dir;
1183
+ startX = e.clientX;
1184
+ isResizing.value = true;
1185
+ const handle = e.currentTarget;
1186
+ activeHandle = handle;
1187
+ handle.setPointerCapture(e.pointerId);
1188
+ const wrapper = videoWrapperRef.value;
1189
+ if (wrapper) {
1190
+ startWidth = wrapper.getBoundingClientRect().width;
1191
+ currentWidth.value = startWidth;
1192
+ }
1193
+ handle.addEventListener("pointermove", onResizePointerMove);
1194
+ handle.addEventListener("pointerup", onResizePointerUp);
1195
+ };
1196
+ return () => {
1197
+ var _a;
1198
+ if (!((_a = src.value) == null ? void 0 : _a.length)) {
1199
+ return /* @__PURE__ */ h(
1200
+ "div",
1201
+ {
1202
+ class: [
1203
+ "milkdown-attachment-placeholder",
1204
+ props.selected.value ? "selected" : ""
1205
+ ]
1206
+ },
1207
+ /* @__PURE__ */ h("div", { class: "milkdown-attachment-uploader", onClick: triggerUpload }, /* @__PURE__ */ h(Icon, { icon: fileLinkIcon }), /* @__PURE__ */ h("span", { class: "milkdown-attachment-upload-text" }, isUploading.value ? "Uploading..." : props.config.uploadButton), /* @__PURE__ */ h(
1208
+ "input",
1209
+ {
1210
+ type: "file",
1211
+ ref: fileInput,
1212
+ onChange: onFileChange,
1213
+ style: "display: none;"
1214
+ }
1215
+ ))
1216
+ );
1217
+ }
1218
+ if (isVideo.value) {
1219
+ const savedWidth = videoWidth.value;
1220
+ const widthStyle = isResizing.value && currentWidth.value > 0 ? `${currentWidth.value}px` : savedWidth && savedWidth > 0 ? `${savedWidth}px` : "100%";
1221
+ return /* @__PURE__ */ h(
1222
+ "div",
1223
+ {
1224
+ ref: videoWrapperRef,
1225
+ class: [
1226
+ "milkdown-attachment-video-viewer",
1227
+ props.selected.value ? "selected" : ""
1228
+ ],
1229
+ style: {
1230
+ width: widthStyle,
1231
+ margin: "0 auto",
1232
+ position: "relative"
1233
+ }
1234
+ },
1235
+ /* @__PURE__ */ h(
1236
+ "video",
1237
+ {
1238
+ src: src.value,
1239
+ controls: true,
1240
+ style: "width: 100%; display: block; border-radius: 8px;",
1241
+ onMousedown: (e) => e.stopPropagation()
1242
+ }
1243
+ ),
1244
+ /* @__PURE__ */ h(
1245
+ "div",
1246
+ {
1247
+ class: "video-resize-handle top-left",
1248
+ onPointerdown: (e) => onResizePointerDown(e, "top-left")
1249
+ }
1250
+ ),
1251
+ /* @__PURE__ */ h(
1252
+ "div",
1253
+ {
1254
+ class: "video-resize-handle top-right",
1255
+ onPointerdown: (e) => onResizePointerDown(e, "top-right")
1256
+ }
1257
+ ),
1258
+ /* @__PURE__ */ h(
1259
+ "div",
1260
+ {
1261
+ class: "video-resize-handle bottom-left",
1262
+ onPointerdown: (e) => onResizePointerDown(e, "bottom-left")
1263
+ }
1264
+ ),
1265
+ /* @__PURE__ */ h(
1266
+ "div",
1267
+ {
1268
+ class: "video-resize-handle bottom-right",
1269
+ onPointerdown: (e) => onResizePointerDown(e, "bottom-right")
1270
+ }
1271
+ )
1272
+ );
1273
+ }
1274
+ return /* @__PURE__ */ h(
1275
+ "div",
1276
+ {
1277
+ class: [
1278
+ "milkdown-attachment-viewer",
1279
+ props.selected.value ? "selected" : ""
1280
+ ]
1281
+ },
1282
+ /* @__PURE__ */ h("div", { class: "milkdown-attachment-icon-wrapper" }, /* @__PURE__ */ h("div", { class: "milkdown-attachment-raw-icon-bg" }, /* @__PURE__ */ h(Icon, { icon: fileLinkIcon }))),
1283
+ /* @__PURE__ */ h("div", { class: "milkdown-attachment-info" }, /* @__PURE__ */ h("div", { class: "milkdown-attachment-name" }, name.value), /* @__PURE__ */ h("div", { class: "milkdown-attachment-size" }, (size.value || 0) > 0 ? formatBytes(size.value) : "")),
1284
+ /* @__PURE__ */ h(
1285
+ "div",
1286
+ {
1287
+ class: "milkdown-attachment-action",
1288
+ onClick: openLink,
1289
+ title: props.config.downloadText
1290
+ },
1291
+ /* @__PURE__ */ h(Icon, { icon: downloadIcon })
1292
+ )
1293
+ );
1294
+ };
1295
+ }
1296
+ });
1297
+
1298
+ const attachmentView = $view(
1299
+ attachmentSchema.node,
1300
+ (ctx) => {
1301
+ return (initialNode, view, getPos) => {
1302
+ const src = ref(initialNode.attrs.src);
1303
+ const name = ref(initialNode.attrs.name);
1304
+ const size = ref(initialNode.attrs.size);
1305
+ const videoWidth = ref(initialNode.attrs.videoWidth);
1306
+ const selected = ref(false);
1307
+ const readonly = ref(!view.editable);
1308
+ const setAttr = (attr, value) => {
1309
+ if (!view.editable) return;
1310
+ const pos = getPos();
1311
+ if (pos == null) return;
1312
+ view.dispatch(view.state.tr.setNodeAttribute(pos, attr, value));
1313
+ };
1314
+ const config = ctx.get(attachmentConfig.key);
1315
+ const app = createApp(MilkdownAttachmentBlock, {
1316
+ src,
1317
+ name,
1318
+ size,
1319
+ videoWidth,
1320
+ selected,
1321
+ readonly,
1322
+ setAttr,
1323
+ config
1324
+ });
1325
+ const dom = document.createElement("div");
1326
+ dom.className = "milkdown-attachment-block-wrapper";
1327
+ const disposeSelectedWatcher = watchEffect(() => {
1328
+ if (selected.value) {
1329
+ dom.classList.add("selected");
1330
+ } else {
1331
+ dom.classList.remove("selected");
1332
+ }
1333
+ });
1334
+ const bindAttrs = (node) => {
1335
+ src.value = node.attrs.src;
1336
+ name.value = node.attrs.name;
1337
+ size.value = node.attrs.size;
1338
+ videoWidth.value = node.attrs.videoWidth;
1339
+ readonly.value = !view.editable;
1340
+ };
1341
+ bindAttrs(initialNode);
1342
+ app.mount(dom);
1343
+ return {
1344
+ dom,
1345
+ update: (updatedNode) => {
1346
+ if (updatedNode.type !== initialNode.type) return false;
1347
+ bindAttrs(updatedNode);
1348
+ return true;
1349
+ },
1350
+ selectNode: () => {
1351
+ selected.value = true;
1352
+ },
1353
+ deselectNode: () => {
1354
+ selected.value = false;
1355
+ },
1356
+ destroy: () => {
1357
+ disposeSelectedWatcher();
1358
+ app.unmount();
1359
+ dom.remove();
1360
+ }
1361
+ };
1362
+ };
1363
+ }
1364
+ );
1365
+
1366
+ const attachment = (editor, config) => {
1367
+ editor.config(crepeFeatureConfig(CrepeFeature.Attachment)).config((ctx) => {
1368
+ ctx.update(attachmentConfig.key, (value) => {
1369
+ var _a, _b, _c, _d;
1370
+ return {
1371
+ uploadButton: (_a = config == null ? void 0 : config.uploadButton) != null ? _a : i18n(ctx, "attachmentBlock.uploadButton"),
1372
+ uploadPlaceholderText: (_b = config == null ? void 0 : config.uploadPlaceholderText) != null ? _b : i18n(ctx, "attachmentBlock.uploadPlaceholderText"),
1373
+ downloadText: (_c = config == null ? void 0 : config.downloadText) != null ? _c : i18n(ctx, "attachmentBlock.download"),
1374
+ onUpload: (_d = config == null ? void 0 : config.onUpload) != null ? _d : value.onUpload
1375
+ };
1376
+ });
1377
+ }).use(attachmentConfig).use(attachmentSchema).use(attachmentView);
1378
+ };
1379
+
1380
+ function isInCodeBlock(selection) {
1381
+ const type = selection.$from.parent.type;
1382
+ return type.name === "code_block";
1383
+ }
1384
+ function isInList(selection) {
1385
+ var _a;
1386
+ const type = (_a = selection.$from.node(selection.$from.depth - 1)) == null ? void 0 : _a.type;
1387
+ return (type == null ? void 0 : type.name) === "list_item";
1388
+ }
1389
+
1390
+ var __typeError$6 = (msg) => {
1391
+ throw TypeError(msg);
1392
+ };
1393
+ var __accessCheck$6 = (obj, member, msg) => member.has(obj) || __typeError$6("Cannot " + msg);
1394
+ var __privateGet$6 = (obj, member, getter) => (__accessCheck$6(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
1395
+ var __privateAdd$6 = (obj, member, value) => member.has(obj) ? __typeError$6("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
1396
+ var __privateSet$6 = (obj, member, value, setter) => (__accessCheck$6(obj, member, "write to private field"), member.set(obj, value), value);
1397
+ var _groups, _getGroupInstance;
1398
+ class GroupBuilder {
1399
+ constructor() {
1400
+ __privateAdd$6(this, _groups, []);
1401
+ this.clear = () => {
1402
+ __privateSet$6(this, _groups, []);
1403
+ return this;
1404
+ };
1405
+ __privateAdd$6(this, _getGroupInstance, (group) => {
1406
+ const groupInstance = {
1407
+ group,
1408
+ addItem: (key, item) => {
1409
+ const data = { ...item, key };
1410
+ group.items.push(data);
1411
+ return groupInstance;
1412
+ },
1413
+ clear: () => {
1414
+ group.items = [];
1415
+ return groupInstance;
1416
+ }
1417
+ };
1418
+ return groupInstance;
1419
+ });
1420
+ this.addGroup = (key, label) => {
1421
+ const items = [];
1422
+ const group = {
1423
+ key,
1424
+ label,
1425
+ items
1426
+ };
1427
+ __privateGet$6(this, _groups).push(group);
1428
+ return __privateGet$6(this, _getGroupInstance).call(this, group);
1429
+ };
1430
+ this.getGroup = (key) => {
1431
+ const group = __privateGet$6(this, _groups).find((group2) => group2.key === key);
1432
+ if (!group) throw new Error(`Group with key ${key} not found`);
1433
+ return __privateGet$6(this, _getGroupInstance).call(this, group);
1434
+ };
1435
+ this.build = () => {
1436
+ return __privateGet$6(this, _groups);
1437
+ };
1438
+ }
1439
+ }
1440
+ _groups = new WeakMap();
1441
+ _getGroupInstance = new WeakMap();
1442
+
1443
+ function keepAlive(..._args) {
1444
+ }
1445
+
1446
+ const remarkTextColorPlugin = $remark(
1447
+ "remarkTextColor",
1448
+ () => function() {
1449
+ const data = this.data();
1450
+ function add(key, value) {
1451
+ if (Array.isArray(data[key])) {
1452
+ data[key].push(value);
1453
+ } else {
1454
+ data[key] = [value];
1455
+ }
1456
+ }
1457
+ add("toMarkdownExtensions", {
1458
+ handlers: {
1459
+ textColor: (node, _, state) => {
1460
+ return `<span style="color:${node.color}">${state.containerPhrasing(node, state)}</span>`;
1461
+ },
1462
+ bgColor: (node, _, state) => {
1463
+ return `<span style="background-color:${node.color}">${state.containerPhrasing(node, state)}</span>`;
1464
+ }
1465
+ }
1466
+ });
1467
+ return (ast) => {
1468
+ visit(ast, (node, index, parent) => {
1469
+ if ((node == null ? void 0 : node.type) === "html" && node.value.startsWith("<span") && parent && index != null) {
1470
+ const hasTextColor = node.value.includes("color:") && !node.value.match(/background-color:\s*([^"';>]+)/);
1471
+ const hasBgColor = node.value.includes("background-color:");
1472
+ if (!hasTextColor && !hasBgColor) return;
1473
+ let color = null;
1474
+ let markType = null;
1475
+ if (hasBgColor) {
1080
1476
  const match = node.value.match(/background-color:\s*([^"';>]+)/);
1081
1477
  color = match ? match[1].trim() : null;
1082
1478
  markType = "bgColor";
@@ -1290,77 +1686,6 @@ const menuAPI = $ctx(
1290
1686
  "menuAPICtx"
1291
1687
  );
1292
1688
 
1293
- const ATTACHMENT_DATA_TYPE = "attachment-block";
1294
- const attachmentSchema = $nodeSchema("attachment", () => {
1295
- return {
1296
- inline: false,
1297
- group: "block",
1298
- selectable: true,
1299
- draggable: true,
1300
- isolating: true,
1301
- marks: "",
1302
- atom: true,
1303
- priority: 100,
1304
- attrs: {
1305
- src: { default: "", validate: "string" },
1306
- name: { default: "", validate: "string" },
1307
- size: { default: 0, validate: "number" },
1308
- videoWidth: { default: 0, validate: "number" }
1309
- },
1310
- parseDOM: [
1311
- {
1312
- tag: `a[data-type="${ATTACHMENT_DATA_TYPE}"]`,
1313
- getAttrs: (dom) => {
1314
- if (!(dom instanceof HTMLElement))
1315
- throw new TypeError("Expect dom to be HTMLElement");
1316
- return {
1317
- src: dom.getAttribute("href") || "",
1318
- name: dom.getAttribute("data-name") || "",
1319
- size: Number(dom.getAttribute("data-size") || 0),
1320
- videoWidth: Number(dom.getAttribute("data-video-width") || 0)
1321
- };
1322
- }
1323
- }
1324
- ],
1325
- toDOM: (node) => [
1326
- "a",
1327
- {
1328
- "data-type": ATTACHMENT_DATA_TYPE,
1329
- href: node.attrs.src,
1330
- "data-name": node.attrs.name,
1331
- "data-size": String(node.attrs.size),
1332
- "data-video-width": String(node.attrs.videoWidth || 0),
1333
- class: "attachment"
1334
- },
1335
- node.attrs.name
1336
- ],
1337
- parseMarkdown: {
1338
- match: (node) => {
1339
- return node.type === "attachment";
1340
- },
1341
- runner: (state, node, type) => {
1342
- state.addNode(type, {
1343
- src: node.url,
1344
- name: node.name || "",
1345
- size: Number(node.size || 0)
1346
- });
1347
- }
1348
- },
1349
- toMarkdown: {
1350
- match: (node) => node.type.name === "attachment",
1351
- runner: (state, node) => {
1352
- state.openNode("paragraph");
1353
- state.addNode(
1354
- "html",
1355
- void 0,
1356
- `<a href="${node.attrs.src}" data-size="${node.attrs.size}" data-name="${node.attrs.name}" data-video-width="${node.attrs.videoWidth || 0}" data-type="${ATTACHMENT_DATA_TYPE}" class="attachment">${node.attrs.name}</a>`
1357
- );
1358
- state.closeNode();
1359
- }
1360
- }
1361
- };
1362
- });
1363
-
1364
1689
  const mathInlineId = "math_inline";
1365
1690
  const mathInlineSchema = $nodeSchema(mathInlineId, () => ({
1366
1691
  group: "inline",
@@ -2156,7 +2481,7 @@ function getGroups$1(filter, config, ctx) {
2156
2481
  };
2157
2482
  }
2158
2483
 
2159
- keepAlive(h);
2484
+ keepAlive(h$1);
2160
2485
  const Menu = defineComponent({
2161
2486
  props: {
2162
2487
  ctx: {
@@ -2498,11 +2823,11 @@ const Menu = defineComponent({
2498
2823
  });
2499
2824
  return () => {
2500
2825
  var _a, _b, _c;
2501
- show.value;
2826
+ void show.value;
2502
2827
  const api = ctx.get(menuAPI.key);
2503
2828
  const showListMenu = (api == null ? void 0 : api.getMode()) === "list" || !(api == null ? void 0 : api.isProgrammatic()) || filter.value !== "";
2504
2829
  if (showListMenu) {
2505
- return /* @__PURE__ */ h("div", { ref: host, onPointerdown: (e) => e.preventDefault() }, /* @__PURE__ */ h("div", { class: "menu-groups", onPointermove: onPointerMove }, groupInfo.value.groups.map((group) => /* @__PURE__ */ h("div", { key: group.key, class: "menu-group" }, /* @__PURE__ */ h("h6", null, group.label), /* @__PURE__ */ h("ul", null, group.items.map((item) => /* @__PURE__ */ h(
2830
+ return /* @__PURE__ */ h$1("div", { ref: host, onPointerdown: (e) => e.preventDefault() }, /* @__PURE__ */ h$1("div", { class: "menu-groups", onPointermove: onPointerMove }, groupInfo.value.groups.map((group) => /* @__PURE__ */ h$1("div", { key: group.key, class: "menu-group" }, /* @__PURE__ */ h$1("h6", null, group.label), /* @__PURE__ */ h$1("ul", null, group.items.map((item) => /* @__PURE__ */ h$1(
2506
2831
  "li",
2507
2832
  {
2508
2833
  key: item.key,
@@ -2545,9 +2870,9 @@ const Menu = defineComponent({
2545
2870
  runByIndex(item.index);
2546
2871
  }
2547
2872
  },
2548
- /* @__PURE__ */ h(Icon, { icon: item.icon }),
2549
- /* @__PURE__ */ h("span", { style: item.key === "table" ? { flex: 1 } : {} }, item.label),
2550
- item.key === "table" ? /* @__PURE__ */ h(
2873
+ /* @__PURE__ */ h$1(Icon, { icon: item.icon }),
2874
+ /* @__PURE__ */ h$1("span", { style: item.key === "table" ? { flex: 1 } : {} }, item.label),
2875
+ item.key === "table" ? /* @__PURE__ */ h$1(
2551
2876
  "div",
2552
2877
  {
2553
2878
  style: {
@@ -2557,9 +2882,9 @@ const Menu = defineComponent({
2557
2882
  transform: "rotate(-90deg)"
2558
2883
  }
2559
2884
  },
2560
- /* @__PURE__ */ h(Icon, { icon: chevronDownIcon })
2885
+ /* @__PURE__ */ h$1(Icon, { icon: chevronDownIcon })
2561
2886
  ) : null
2562
- )))))), showTableMenu.value ? /* @__PURE__ */ h(
2887
+ )))))), showTableMenu.value ? /* @__PURE__ */ h$1(
2563
2888
  "div",
2564
2889
  {
2565
2890
  class: "milkdown-slash-menu custom-submenu",
@@ -2582,7 +2907,7 @@ const Menu = defineComponent({
2582
2907
  },
2583
2908
  onPointerleave: handleTableLeave
2584
2909
  },
2585
- /* @__PURE__ */ h(
2910
+ /* @__PURE__ */ h$1(
2586
2911
  "div",
2587
2912
  {
2588
2913
  style: {
@@ -2594,7 +2919,7 @@ const Menu = defineComponent({
2594
2919
  },
2595
2920
  i18n(ctx, "customMenu.insertTable")
2596
2921
  ),
2597
- /* @__PURE__ */ h(
2922
+ /* @__PURE__ */ h$1(
2598
2923
  "div",
2599
2924
  {
2600
2925
  style: {
@@ -2607,7 +2932,7 @@ const Menu = defineComponent({
2607
2932
  Array.from({ length: 9 }).map(
2608
2933
  (_, r) => Array.from({ length: 9 }).map((_2, c) => {
2609
2934
  const isHovered = r < tableHoverIndices.value.r && c < tableHoverIndices.value.c;
2610
- return /* @__PURE__ */ h(
2935
+ return /* @__PURE__ */ h$1(
2611
2936
  "div",
2612
2937
  {
2613
2938
  key: `cell-${r}-${c}`,
@@ -2636,7 +2961,7 @@ const Menu = defineComponent({
2636
2961
  })
2637
2962
  )
2638
2963
  ),
2639
- tableHoverIndices.value.r > 0 ? /* @__PURE__ */ h(
2964
+ tableHoverIndices.value.r > 0 ? /* @__PURE__ */ h$1(
2640
2965
  "div",
2641
2966
  {
2642
2967
  style: {
@@ -2649,7 +2974,7 @@ const Menu = defineComponent({
2649
2974
  tableHoverIndices.value.r,
2650
2975
  " x ",
2651
2976
  tableHoverIndices.value.c
2652
- ) : /* @__PURE__ */ h(
2977
+ ) : /* @__PURE__ */ h$1(
2653
2978
  "div",
2654
2979
  {
2655
2980
  style: {
@@ -2819,7 +3144,7 @@ const Menu = defineComponent({
2819
3144
  const renderGridBtn = (key) => {
2820
3145
  const item = findItem(key);
2821
3146
  if (!item) return null;
2822
- return /* @__PURE__ */ h(
3147
+ return /* @__PURE__ */ h$1(
2823
3148
  "div",
2824
3149
  {
2825
3150
  title: item.label,
@@ -2840,11 +3165,11 @@ const Menu = defineComponent({
2840
3165
  },
2841
3166
  "data-index": item.index
2842
3167
  },
2843
- /* @__PURE__ */ h(Icon, { icon: item.icon })
3168
+ /* @__PURE__ */ h$1(Icon, { icon: item.icon })
2844
3169
  );
2845
3170
  };
2846
3171
  const renderCustomRow = (iconHtml, label, hasArrow, onPointerEnter, onPointerLeave, onClick) => {
2847
- return /* @__PURE__ */ h(
3172
+ return /* @__PURE__ */ h$1(
2848
3173
  "div",
2849
3174
  {
2850
3175
  class: "custom-menu-row",
@@ -2860,12 +3185,12 @@ const Menu = defineComponent({
2860
3185
  onClick == null ? void 0 : onClick();
2861
3186
  }
2862
3187
  },
2863
- /* @__PURE__ */ h("div", { class: "custom-menu-row-left" }, /* @__PURE__ */ h(Icon, { icon: iconHtml }), /* @__PURE__ */ h("span", null, label)),
2864
- hasArrow ? /* @__PURE__ */ h(Icon, { icon: chevronDownIcon }) : null
3188
+ /* @__PURE__ */ h$1("div", { class: "custom-menu-row-left" }, /* @__PURE__ */ h$1(Icon, { icon: iconHtml }), /* @__PURE__ */ h$1("span", null, label)),
3189
+ hasArrow ? /* @__PURE__ */ h$1(Icon, { icon: chevronDownIcon }) : null
2865
3190
  );
2866
3191
  };
2867
3192
  const renderSubMenuItem = (iconHtml, label, isActive, onClick, disabled = false) => {
2868
- return /* @__PURE__ */ h(
3193
+ return /* @__PURE__ */ h$1(
2869
3194
  "div",
2870
3195
  {
2871
3196
  class: ["custom-menu-row", disabled ? "disabled" : ""],
@@ -2883,7 +3208,7 @@ const Menu = defineComponent({
2883
3208
  if (!disabled) onClick();
2884
3209
  }
2885
3210
  },
2886
- /* @__PURE__ */ h("div", { class: "custom-menu-row-left" }, /* @__PURE__ */ h(Icon, { icon: iconHtml }), /* @__PURE__ */ h(
3211
+ /* @__PURE__ */ h$1("div", { class: "custom-menu-row-left" }, /* @__PURE__ */ h$1(Icon, { icon: iconHtml }), /* @__PURE__ */ h$1(
2887
3212
  "span",
2888
3213
  {
2889
3214
  style: {
@@ -2892,18 +3217,18 @@ const Menu = defineComponent({
2892
3217
  },
2893
3218
  label
2894
3219
  )),
2895
- isActive ? /* @__PURE__ */ h("span", { style: { color: "var(--crepe-color-primary)" } }, /* @__PURE__ */ h(Icon, { icon: confirmIcon })) : null
3220
+ isActive ? /* @__PURE__ */ h$1("span", { style: { color: "var(--crepe-color-primary)" } }, /* @__PURE__ */ h$1(Icon, { icon: confirmIcon })) : null
2896
3221
  );
2897
3222
  };
2898
- return /* @__PURE__ */ h(
3223
+ return /* @__PURE__ */ h$1(
2899
3224
  "div",
2900
3225
  {
2901
3226
  ref: host,
2902
3227
  onPointerdown: (e) => e.preventDefault(),
2903
3228
  class: "custom-block-menu"
2904
3229
  },
2905
- !isMedia ? /* @__PURE__ */ h("div", { class: "custom-grid-container" }, gridRows.map((rowKeys, rIndex) => /* @__PURE__ */ h("div", { class: "custom-grid-row", key: "row-" + rIndex }, rowKeys.map(renderGridBtn)))) : null,
2906
- showAlign ? /* @__PURE__ */ h("div", { class: "custom-divider" }) : null,
3230
+ !isMedia ? /* @__PURE__ */ h$1("div", { class: "custom-grid-container" }, gridRows.map((rowKeys, rIndex) => /* @__PURE__ */ h$1("div", { class: "custom-grid-row", key: "row-" + rIndex }, rowKeys.map(renderGridBtn)))) : null,
3231
+ showAlign ? /* @__PURE__ */ h$1("div", { class: "custom-divider" }) : null,
2907
3232
  showAlign && renderCustomRow(
2908
3233
  alignLeftIcon,
2909
3234
  i18n(ctx, "customMenu.indentAndAlign"),
@@ -2911,7 +3236,7 @@ const Menu = defineComponent({
2911
3236
  handleIndentAlignEnter,
2912
3237
  handleIndentAlignLeave
2913
3238
  ),
2914
- showIndentAlignMenu.value ? /* @__PURE__ */ h(
3239
+ showIndentAlignMenu.value ? /* @__PURE__ */ h$1(
2915
3240
  "div",
2916
3241
  {
2917
3242
  class: "milkdown-slash-menu custom-submenu",
@@ -2948,7 +3273,7 @@ const Menu = defineComponent({
2948
3273
  currentAlign === "right",
2949
3274
  () => setAlign("right")
2950
3275
  ),
2951
- /* @__PURE__ */ h("div", { class: "custom-divider" }),
3276
+ /* @__PURE__ */ h$1("div", { class: "custom-divider" }),
2952
3277
  renderSubMenuItem(
2953
3278
  indentIncreaseIcon,
2954
3279
  i18n(ctx, "customMenu.increaseIndent"),
@@ -2970,7 +3295,7 @@ const Menu = defineComponent({
2970
3295
  handleColorEnter,
2971
3296
  handleColorLeave
2972
3297
  ),
2973
- showColorMenu.value ? /* @__PURE__ */ h(
3298
+ showColorMenu.value ? /* @__PURE__ */ h$1(
2974
3299
  "div",
2975
3300
  {
2976
3301
  class: "milkdown-slash-menu custom-submenu",
@@ -2994,7 +3319,7 @@ const Menu = defineComponent({
2994
3319
  },
2995
3320
  onPointerleave: handleColorLeave
2996
3321
  },
2997
- /* @__PURE__ */ h(
3322
+ /* @__PURE__ */ h$1(
2998
3323
  "div",
2999
3324
  {
3000
3325
  style: {
@@ -3005,7 +3330,7 @@ const Menu = defineComponent({
3005
3330
  },
3006
3331
  i18n(ctx, "customMenu.textColor")
3007
3332
  ),
3008
- /* @__PURE__ */ h("div", { style: { display: "flex", gap: "4px", flexWrap: "wrap" } }, [
3333
+ /* @__PURE__ */ h$1("div", { style: { display: "flex", gap: "4px", flexWrap: "wrap" } }, [
3009
3334
  "#000000",
3010
3335
  "#8C8C8C",
3011
3336
  "#F5222D",
@@ -3014,7 +3339,7 @@ const Menu = defineComponent({
3014
3339
  "#52C41A",
3015
3340
  "#1677FF",
3016
3341
  "#722ED1"
3017
- ].map((color) => /* @__PURE__ */ h(
3342
+ ].map((color) => /* @__PURE__ */ h$1(
3018
3343
  "div",
3019
3344
  {
3020
3345
  key: color,
@@ -3044,7 +3369,7 @@ const Menu = defineComponent({
3044
3369
  },
3045
3370
  "A"
3046
3371
  ))),
3047
- /* @__PURE__ */ h(
3372
+ /* @__PURE__ */ h$1(
3048
3373
  "div",
3049
3374
  {
3050
3375
  style: {
@@ -3056,7 +3381,7 @@ const Menu = defineComponent({
3056
3381
  },
3057
3382
  i18n(ctx, "customMenu.bgColor")
3058
3383
  ),
3059
- /* @__PURE__ */ h("div", { style: { display: "flex", gap: "4px", flexWrap: "wrap" } }, [
3384
+ /* @__PURE__ */ h$1("div", { style: { display: "flex", gap: "4px", flexWrap: "wrap" } }, [
3060
3385
  "transparent",
3061
3386
  "#F5F5F5",
3062
3387
  "#FFCCC7",
@@ -3065,7 +3390,7 @@ const Menu = defineComponent({
3065
3390
  "#D9F7BE",
3066
3391
  "#D6E4FF",
3067
3392
  "#EFDBFF"
3068
- ].map((color) => /* @__PURE__ */ h(
3393
+ ].map((color) => /* @__PURE__ */ h$1(
3069
3394
  "div",
3070
3395
  {
3071
3396
  key: color,
@@ -3089,7 +3414,7 @@ const Menu = defineComponent({
3089
3414
  overflow: "hidden"
3090
3415
  }
3091
3416
  },
3092
- color === "transparent" ? /* @__PURE__ */ h(
3417
+ color === "transparent" ? /* @__PURE__ */ h$1(
3093
3418
  "div",
3094
3419
  {
3095
3420
  style: {
@@ -3113,7 +3438,7 @@ const Menu = defineComponent({
3113
3438
  "#52C41A",
3114
3439
  "#1677FF",
3115
3440
  "#722ED1"
3116
- ].map((color) => /* @__PURE__ */ h(
3441
+ ].map((color) => /* @__PURE__ */ h$1(
3117
3442
  "div",
3118
3443
  {
3119
3444
  key: color,
@@ -3136,7 +3461,7 @@ const Menu = defineComponent({
3136
3461
  }
3137
3462
  }
3138
3463
  ))),
3139
- /* @__PURE__ */ h(
3464
+ /* @__PURE__ */ h$1(
3140
3465
  "button",
3141
3466
  {
3142
3467
  onPointerdown: (e) => {
@@ -3163,7 +3488,7 @@ const Menu = defineComponent({
3163
3488
  i18n(ctx, "customMenu.restoreDefault")
3164
3489
  )
3165
3490
  ) : null,
3166
- !isMedia ? /* @__PURE__ */ h("div", { class: "custom-divider" }) : null,
3491
+ !isMedia ? /* @__PURE__ */ h$1("div", { class: "custom-divider" }) : null,
3167
3492
  renderCustomRow(
3168
3493
  clearIcon,
3169
3494
  i18n(ctx, "customMenu.cut"),
@@ -3188,7 +3513,7 @@ const Menu = defineComponent({
3188
3513
  void 0,
3189
3514
  applyDelete
3190
3515
  ),
3191
- /* @__PURE__ */ h("div", { class: "custom-divider" }),
3516
+ /* @__PURE__ */ h$1("div", { class: "custom-divider" }),
3192
3517
  renderCustomRow(
3193
3518
  plusIcon,
3194
3519
  i18n(ctx, "customMenu.addBelow"),
@@ -3196,7 +3521,7 @@ const Menu = defineComponent({
3196
3521
  handleAddBelowEnter,
3197
3522
  handleAddBelowLeave
3198
3523
  ),
3199
- showAddBelowMenu.value ? /* @__PURE__ */ h(
3524
+ showAddBelowMenu.value ? /* @__PURE__ */ h$1(
3200
3525
  "div",
3201
3526
  {
3202
3527
  class: "milkdown-slash-menu custom-submenu",
@@ -3216,14 +3541,14 @@ const Menu = defineComponent({
3216
3541
  },
3217
3542
  onPointerleave: handleAddBelowLeave
3218
3543
  },
3219
- /* @__PURE__ */ h(
3544
+ /* @__PURE__ */ h$1(
3220
3545
  "div",
3221
3546
  {
3222
3547
  class: "menu-groups",
3223
3548
  onPointermove: onPointerMove,
3224
3549
  style: { maxHeight: "300px", overflowY: "auto" }
3225
3550
  },
3226
- groupInfo.value.groups.map((group) => /* @__PURE__ */ h("div", { key: group.key, class: "menu-group" }, /* @__PURE__ */ h("h6", null, group.label), /* @__PURE__ */ h("ul", null, group.items.map((item) => /* @__PURE__ */ h(
3551
+ groupInfo.value.groups.map((group) => /* @__PURE__ */ h$1("div", { key: group.key, class: "menu-group" }, /* @__PURE__ */ h$1("h6", null, group.label), /* @__PURE__ */ h$1("ul", null, group.items.map((item) => /* @__PURE__ */ h$1(
3227
3552
  "li",
3228
3553
  {
3229
3554
  key: item.key,
@@ -3244,12 +3569,14 @@ const Menu = defineComponent({
3244
3569
  var _a2;
3245
3570
  e.preventDefault();
3246
3571
  e.stopPropagation();
3247
- (_a2 = host.value) == null ? void 0 : _a2.querySelectorAll(`[data-index="${item.index}"]`).forEach((el) => el.classList.remove("active"));
3572
+ (_a2 = host.value) == null ? void 0 : _a2.querySelectorAll(`[data-index="${item.index}"]`).forEach(
3573
+ (el) => el.classList.remove("active")
3574
+ );
3248
3575
  runByIndexForAddBelow(item.index);
3249
3576
  }
3250
3577
  },
3251
- /* @__PURE__ */ h(Icon, { icon: item.icon }),
3252
- /* @__PURE__ */ h("span", null, item.label)
3578
+ /* @__PURE__ */ h$1(Icon, { icon: item.icon }),
3579
+ /* @__PURE__ */ h$1("span", null, item.label)
3253
3580
  )))))
3254
3581
  )
3255
3582
  ) : null
@@ -3496,7 +3823,7 @@ function getBlockKey(node) {
3496
3823
  }
3497
3824
  }
3498
3825
 
3499
- keepAlive(h, Fragment);
3826
+ keepAlive(h$1, Fragment);
3500
3827
  const BlockHandle = defineComponent({
3501
3828
  props: {
3502
3829
  onAdd: {
@@ -3544,7 +3871,7 @@ const BlockHandle = defineComponent({
3544
3871
  const addButton = ref();
3545
3872
  const menuButton = ref();
3546
3873
  return () => {
3547
- return /* @__PURE__ */ h(Fragment, null, /* @__PURE__ */ h(
3874
+ return /* @__PURE__ */ h$1(Fragment, null, /* @__PURE__ */ h$1(
3548
3875
  "div",
3549
3876
  {
3550
3877
  ref: addButton,
@@ -3570,8 +3897,8 @@ const BlockHandle = defineComponent({
3570
3897
  props.onAdd(addButton.value);
3571
3898
  }
3572
3899
  },
3573
- /* @__PURE__ */ h(Icon, { icon: props.addIcon })
3574
- ), /* @__PURE__ */ h(
3900
+ /* @__PURE__ */ h$1(Icon, { icon: props.addIcon })
3901
+ ), /* @__PURE__ */ h$1(
3575
3902
  "div",
3576
3903
  {
3577
3904
  ref: menuButton,
@@ -3589,14 +3916,14 @@ const BlockHandle = defineComponent({
3589
3916
  props.onLeaveMenu();
3590
3917
  }
3591
3918
  },
3592
- /* @__PURE__ */ h(Icon, { icon: props.state.icon })
3593
- ), /* @__PURE__ */ h("div", { class: "divider" }), /* @__PURE__ */ h(
3919
+ /* @__PURE__ */ h$1(Icon, { icon: props.state.icon })
3920
+ ), /* @__PURE__ */ h$1("div", { class: "divider" }), /* @__PURE__ */ h$1(
3594
3921
  "div",
3595
3922
  {
3596
3923
  class: "operation-item drag-item",
3597
3924
  title: i18n(props.ctx, "handle.drag")
3598
3925
  },
3599
- /* @__PURE__ */ h(Icon, { icon: dragHandleIcon })
3926
+ /* @__PURE__ */ h$1(Icon, { icon: dragHandleIcon })
3600
3927
  ));
3601
3928
  };
3602
3929
  }
@@ -4997,7 +5324,11 @@ const activeIconMap = {
4997
5324
  [dividerIcon]: dividerIconActive
4998
5325
  // [highLineCodeIcon]: highLineCodeIconActive,
4999
5326
  };
5000
- keepAlive(h, Fragment);
5327
+ keepAlive(h$1, Fragment);
5328
+ const formatPainterStates = /* @__PURE__ */ new WeakMap();
5329
+ const formatPainterHandlers = /* @__PURE__ */ new WeakMap();
5330
+ const formatPainterIgnoreNext = /* @__PURE__ */ new WeakMap();
5331
+ const cursorStyleEls = /* @__PURE__ */ new WeakMap();
5001
5332
  const Toolbar = defineComponent({
5002
5333
  props: {
5003
5334
  ctx: { type: Object, required: true },
@@ -5028,6 +5359,184 @@ const Toolbar = defineComponent({
5028
5359
  const tableMenuPos = ref({ top: 0, left: 0 });
5029
5360
  const tableHoverIndices = ref({ r: 0, c: 0 });
5030
5361
  let hideTableTimer = null;
5362
+ let formatPainterState = formatPainterStates.get(ctx);
5363
+ if (!formatPainterState) {
5364
+ formatPainterState = ref(null);
5365
+ formatPainterStates.set(ctx, formatPainterState);
5366
+ }
5367
+ let formatPainterIgnore = formatPainterIgnoreNext.get(ctx);
5368
+ if (!formatPainterIgnore) {
5369
+ formatPainterIgnore = { value: false };
5370
+ formatPainterIgnoreNext.set(ctx, formatPainterIgnore);
5371
+ }
5372
+ let formatPainterHandler = formatPainterHandlers.get(ctx);
5373
+ if (!formatPainterHandler) {
5374
+ formatPainterHandler = (ev) => {
5375
+ if (!formatPainterState.value) return;
5376
+ if (formatPainterIgnore.value) {
5377
+ formatPainterIgnore.value = false;
5378
+ return;
5379
+ }
5380
+ const currentView = ctx.get(editorViewCtx);
5381
+ const targetElement = ev.target instanceof Element ? ev.target : ev.target.parentElement;
5382
+ if (targetElement && targetElement.closest(".milkdown-toolbar, .milkdown-fixed-toolbar")) {
5383
+ return;
5384
+ }
5385
+ setTimeout(() => {
5386
+ if (!formatPainterState.value) return;
5387
+ const { state: curState, dispatch } = currentView;
5388
+ const { selection: curSelection, tr } = curState;
5389
+ const {
5390
+ marks: savedMarks,
5391
+ align: savedAlign,
5392
+ isPersistent
5393
+ } = formatPainterState.value;
5394
+ let applied = false;
5395
+ if (!curSelection.empty) {
5396
+ savedMarks.forEach((m) => {
5397
+ tr.addMark(curSelection.from, curSelection.to, m);
5398
+ });
5399
+ if (savedAlign) {
5400
+ curState.doc.nodesBetween(
5401
+ curSelection.from,
5402
+ curSelection.to,
5403
+ (node, pos) => {
5404
+ if (node.type.name === "paragraph" || node.type.name === "heading") {
5405
+ tr.setNodeMarkup(pos, null, {
5406
+ ...node.attrs,
5407
+ align: savedAlign
5408
+ });
5409
+ }
5410
+ }
5411
+ );
5412
+ }
5413
+ dispatch(tr);
5414
+ applied = true;
5415
+ } else {
5416
+ if (savedMarks.length > 0) {
5417
+ const $pos = curSelection.$from;
5418
+ if ($pos.parent.isTextblock) {
5419
+ const text = $pos.parent.textContent;
5420
+ const offset = $pos.parentOffset;
5421
+ let start = offset;
5422
+ let end = offset;
5423
+ const isWordChar = (char) => !/[\s,.\-!?;:()[\]{}"'“”‘’,。!?;:()【】《》、\n\r]/.test(
5424
+ char
5425
+ );
5426
+ while (start > 0 && isWordChar(text[start - 1])) start--;
5427
+ while (end < text.length && isWordChar(text[end])) end++;
5428
+ if (start < end) {
5429
+ savedMarks.forEach((m) => {
5430
+ tr.addMark($pos.start() + start, $pos.start() + end, m);
5431
+ });
5432
+ }
5433
+ }
5434
+ }
5435
+ if (savedAlign) {
5436
+ const pos = curSelection.$from.before(curSelection.$from.depth);
5437
+ const node = curState.doc.nodeAt(pos);
5438
+ if (node && (node.type.name === "paragraph" || node.type.name === "heading")) {
5439
+ tr.setNodeMarkup(pos, null, {
5440
+ ...node.attrs,
5441
+ align: savedAlign
5442
+ });
5443
+ }
5444
+ }
5445
+ tr.setStoredMarks(savedMarks);
5446
+ dispatch(tr);
5447
+ applied = true;
5448
+ }
5449
+ if (applied && !isPersistent) {
5450
+ formatPainterState.value = null;
5451
+ document.removeEventListener("pointerup", formatPainterHandler);
5452
+ }
5453
+ }, 50);
5454
+ };
5455
+ formatPainterHandlers.set(ctx, formatPainterHandler);
5456
+ }
5457
+ const toggleFormatPainter = (isPersistent) => {
5458
+ const view = ctx.get(editorViewCtx);
5459
+ const { state } = view;
5460
+ const { selection } = state;
5461
+ let marks = [];
5462
+ if (selection.empty) {
5463
+ marks = state.storedMarks ? [...state.storedMarks] : [...selection.$from.marks()];
5464
+ } else {
5465
+ let foundMarks = null;
5466
+ state.doc.nodesBetween(selection.from, selection.to, (node) => {
5467
+ if (foundMarks) return false;
5468
+ if (node.isInline) {
5469
+ foundMarks = [...node.marks];
5470
+ return false;
5471
+ }
5472
+ return void 0;
5473
+ });
5474
+ marks = foundMarks || [];
5475
+ }
5476
+ let align = null;
5477
+ let foundAlign = null;
5478
+ state.doc.nodesBetween(selection.from, selection.to, (node) => {
5479
+ if (foundAlign) return false;
5480
+ if (node.isBlock && (node.type.name === "paragraph" || node.type.name === "heading")) {
5481
+ foundAlign = node.attrs.align || null;
5482
+ return false;
5483
+ }
5484
+ return void 0;
5485
+ });
5486
+ if (!foundAlign) {
5487
+ const parent = selection.$from.parent;
5488
+ if (parent && (parent.type.name === "paragraph" || parent.type.name === "heading")) {
5489
+ foundAlign = parent.attrs.align || null;
5490
+ }
5491
+ }
5492
+ align = foundAlign;
5493
+ formatPainterState.value = { marks, align, isPersistent };
5494
+ document.removeEventListener("pointerup", formatPainterHandler);
5495
+ setTimeout(() => {
5496
+ document.addEventListener("pointerup", formatPainterHandler);
5497
+ }, 0);
5498
+ };
5499
+ const handleFormatPainterClick = (e) => {
5500
+ e.preventDefault();
5501
+ e.stopPropagation();
5502
+ if (formatPainterState.value) {
5503
+ formatPainterState.value = null;
5504
+ document.removeEventListener("pointerup", formatPainterHandler);
5505
+ } else {
5506
+ formatPainterIgnore.value = true;
5507
+ toggleFormatPainter(false);
5508
+ }
5509
+ };
5510
+ const handleFormatPainterDblClick = (e) => {
5511
+ e.preventDefault();
5512
+ e.stopPropagation();
5513
+ toggleFormatPainter(true);
5514
+ };
5515
+ watch(
5516
+ () => formatPainterState.value,
5517
+ (newVal) => {
5518
+ if (newVal) {
5519
+ let cursorStyleEl = cursorStyleEls.get(ctx);
5520
+ if (!cursorStyleEl) {
5521
+ cursorStyleEl = document.createElement("style");
5522
+ const encodedSvg = encodeURIComponent(
5523
+ formatPainterIcon.replace(/currentColor/g, "#363B4C")
5524
+ );
5525
+ cursorStyleEl.innerHTML = `.milkdown .ProseMirror, .milkdown .ProseMirror * { cursor: url("data:image/svg+xml;utf8,${encodedSvg}") 0 16, auto !important; }`;
5526
+ document.head.appendChild(cursorStyleEl);
5527
+ cursorStyleEls.set(ctx, cursorStyleEl);
5528
+ }
5529
+ } else {
5530
+ const cursorStyleEl = cursorStyleEls.get(ctx);
5531
+ if (cursorStyleEl) {
5532
+ cursorStyleEl.remove();
5533
+ cursorStyleEls.delete(ctx);
5534
+ }
5535
+ }
5536
+ }
5537
+ );
5538
+ onUnmounted(() => {
5539
+ });
5031
5540
  const toolbarContainerRef = ref(null);
5032
5541
  const overflowVisibleCount = ref(Infinity);
5033
5542
  const totalSectionCount = ref(Infinity);
@@ -5619,7 +6128,7 @@ const Toolbar = defineComponent({
5619
6128
  showFontSizeMenu.value = false;
5620
6129
  };
5621
6130
  const renderSubMenuItem = (iconHtml, label, isActive, onClick2, disabled = false) => {
5622
- return /* @__PURE__ */ h(
6131
+ return /* @__PURE__ */ h$1(
5623
6132
  "div",
5624
6133
  {
5625
6134
  class: ["custom-menu-row", disabled ? "disabled" : ""],
@@ -5651,13 +6160,13 @@ const Toolbar = defineComponent({
5651
6160
  e.currentTarget.style.backgroundColor = "transparent";
5652
6161
  }
5653
6162
  },
5654
- /* @__PURE__ */ h(
6163
+ /* @__PURE__ */ h$1(
5655
6164
  "div",
5656
6165
  {
5657
6166
  class: "custom-menu-row-left",
5658
6167
  style: { display: "flex", alignItems: "center", gap: "8px" }
5659
6168
  },
5660
- /* @__PURE__ */ h(
6169
+ /* @__PURE__ */ h$1(
5661
6170
  "span",
5662
6171
  {
5663
6172
  style: {
@@ -5669,7 +6178,7 @@ const Toolbar = defineComponent({
5669
6178
  innerHTML: iconHtml
5670
6179
  }
5671
6180
  ),
5672
- /* @__PURE__ */ h(
6181
+ /* @__PURE__ */ h$1(
5673
6182
  "span",
5674
6183
  {
5675
6184
  style: {
@@ -5680,7 +6189,7 @@ const Toolbar = defineComponent({
5680
6189
  label
5681
6190
  )
5682
6191
  ),
5683
- isActive ? /* @__PURE__ */ h(
6192
+ isActive ? /* @__PURE__ */ h$1(
5684
6193
  "span",
5685
6194
  {
5686
6195
  style: {
@@ -5689,7 +6198,7 @@ const Toolbar = defineComponent({
5689
6198
  color: "var(--crepe-color-primary)"
5690
6199
  }
5691
6200
  },
5692
- /* @__PURE__ */ h(Icon, { icon: confirmIcon })
6201
+ /* @__PURE__ */ h$1(Icon, { icon: confirmIcon })
5693
6202
  ) : null
5694
6203
  );
5695
6204
  };
@@ -5713,7 +6222,7 @@ const Toolbar = defineComponent({
5713
6222
  );
5714
6223
  const isSectionOverflowed = (idx) => idx >= overflowVisibleCount.value;
5715
6224
  const hasOverflow = overflowVisibleCount.value < totalSectionCount.value;
5716
- return /* @__PURE__ */ h(
6225
+ return /* @__PURE__ */ h$1(
5717
6226
  "div",
5718
6227
  {
5719
6228
  ref: toolbarContainerRef,
@@ -5724,7 +6233,7 @@ const Toolbar = defineComponent({
5724
6233
  overflow: "hidden"
5725
6234
  }
5726
6235
  },
5727
- /* @__PURE__ */ h(
6236
+ /* @__PURE__ */ h$1(
5728
6237
  "div",
5729
6238
  {
5730
6239
  class: "toolbar-item",
@@ -5734,26 +6243,69 @@ const Toolbar = defineComponent({
5734
6243
  position: "relative",
5735
6244
  display: isSectionOverflowed(0) ? "none" : "flex",
5736
6245
  alignItems: "center",
5737
- padding: "0 8px",
6246
+ padding: "0 6px",
5738
6247
  flexShrink: 0
5739
6248
  }
5740
6249
  },
5741
- /* @__PURE__ */ h(
6250
+ /* @__PURE__ */ h$1(
5742
6251
  "span",
5743
6252
  {
5744
6253
  style: { display: "inline-flex", alignItems: "center" },
5745
6254
  innerHTML: activeBlockItem.value || textIcon
5746
6255
  }
5747
6256
  ),
5748
- /* @__PURE__ */ h(
6257
+ /* @__PURE__ */ h$1(
5749
6258
  "span",
5750
6259
  {
5751
6260
  style: { width: "20px", display: "flex", alignItems: "center" }
5752
6261
  },
5753
- /* @__PURE__ */ h(Icon, { icon: chevronDownIcon })
6262
+ /* @__PURE__ */ h$1(Icon, { icon: chevronDownIcon })
5754
6263
  )
5755
6264
  ),
5756
- /* @__PURE__ */ h(
6265
+ /* @__PURE__ */ h$1(
6266
+ "div",
6267
+ {
6268
+ style: {
6269
+ position: "relative",
6270
+ display: isSectionOverflowed(0) ? "none" : "flex",
6271
+ flexShrink: 0
6272
+ }
6273
+ },
6274
+ /* @__PURE__ */ h$1(
6275
+ "button",
6276
+ {
6277
+ type: "button",
6278
+ class: clsx(
6279
+ "toolbar-item",
6280
+ formatPainterState.value && "active"
6281
+ ),
6282
+ onPointerdown: (e) => {
6283
+ e.preventDefault();
6284
+ handleFormatPainterClick(e);
6285
+ },
6286
+ onDblclick: handleFormatPainterDblClick,
6287
+ title: i18n(ctx, "toolbar.formatPainter") || "Format Painter",
6288
+ style: {
6289
+ display: "flex",
6290
+ alignItems: "center",
6291
+ justifyContent: "center",
6292
+ backgroundColor: formatPainterState.value ? "var(--crepe-color-selected, var(--crepe-color-hover))" : void 0
6293
+ }
6294
+ },
6295
+ /* @__PURE__ */ h$1(
6296
+ "span",
6297
+ {
6298
+ style: {
6299
+ display: "inline-flex",
6300
+ alignItems: "center",
6301
+ "--toolbar-icon-color": formatPainterState.value ? "var(--crepe-color-primary)" : "#363B4C"
6302
+ },
6303
+ innerHTML: formatPainterIcon
6304
+ }
6305
+ )
6306
+ )
6307
+ ),
6308
+ /* @__PURE__ */ h$1(
5757
6309
  "div",
5758
6310
  {
5759
6311
  class: "divider",
@@ -5765,7 +6317,7 @@ const Toolbar = defineComponent({
5765
6317
  }
5766
6318
  }
5767
6319
  ),
5768
- /* @__PURE__ */ h(
6320
+ /* @__PURE__ */ h$1(
5769
6321
  "div",
5770
6322
  {
5771
6323
  class: "toolbar-item custom-font-family-item",
@@ -5775,12 +6327,12 @@ const Toolbar = defineComponent({
5775
6327
  position: "relative",
5776
6328
  display: isSectionOverflowed(2) ? "none" : "flex",
5777
6329
  alignItems: "center",
5778
- padding: "0 8px",
6330
+ padding: "0 6px",
5779
6331
  minWidth: "50px",
5780
6332
  flexShrink: 0
5781
6333
  }
5782
6334
  },
5783
- /* @__PURE__ */ h(
6335
+ /* @__PURE__ */ h$1(
5784
6336
  "span",
5785
6337
  {
5786
6338
  style: {
@@ -5794,7 +6346,7 @@ const Toolbar = defineComponent({
5794
6346
  },
5795
6347
  currentFontState.value.fontFamily && currentFontState.value.fontFamily !== "mixed" ? currentFontState.value.fontFamily.split(",")[0].replace(/['"]/g, "") || (ctx ? i18n(ctx, "customMenu.fontDefault") : "\u9ED8\u8BA4") : ctx ? i18n(ctx, "customMenu.fontDefault") : "\u9ED8\u8BA4"
5796
6348
  ),
5797
- /* @__PURE__ */ h(
6349
+ /* @__PURE__ */ h$1(
5798
6350
  "span",
5799
6351
  {
5800
6352
  style: {
@@ -5804,10 +6356,10 @@ const Toolbar = defineComponent({
5804
6356
  marginLeft: "4px"
5805
6357
  }
5806
6358
  },
5807
- /* @__PURE__ */ h(Icon, { icon: chevronDownIcon })
6359
+ /* @__PURE__ */ h$1(Icon, { icon: chevronDownIcon })
5808
6360
  )
5809
6361
  ),
5810
- /* @__PURE__ */ h(
6362
+ /* @__PURE__ */ h$1(
5811
6363
  "div",
5812
6364
  {
5813
6365
  class: "toolbar-item custom-font-size-item",
@@ -5817,13 +6369,13 @@ const Toolbar = defineComponent({
5817
6369
  position: "relative",
5818
6370
  display: isSectionOverflowed(3) ? "none" : "flex",
5819
6371
  alignItems: "center",
5820
- padding: "0 8px",
6372
+ padding: "0 6px",
5821
6373
  minWidth: "40px",
5822
6374
  flexShrink: 0
5823
6375
  }
5824
6376
  },
5825
- /* @__PURE__ */ h("span", { style: { fontSize: "13px", color: "#363B4C" } }, currentFontState.value.fontSize && currentFontState.value.fontSize !== "mixed" ? currentFontState.value.fontSize : "16px"),
5826
- /* @__PURE__ */ h(
6377
+ /* @__PURE__ */ h$1("span", { style: { fontSize: "13px", color: "#363B4C" } }, currentFontState.value.fontSize && currentFontState.value.fontSize !== "mixed" ? currentFontState.value.fontSize : "16px"),
6378
+ /* @__PURE__ */ h$1(
5827
6379
  "span",
5828
6380
  {
5829
6381
  style: {
@@ -5833,10 +6385,10 @@ const Toolbar = defineComponent({
5833
6385
  marginLeft: "4px"
5834
6386
  }
5835
6387
  },
5836
- /* @__PURE__ */ h(Icon, { icon: chevronDownIcon })
6388
+ /* @__PURE__ */ h$1(Icon, { icon: chevronDownIcon })
5837
6389
  )
5838
6390
  ),
5839
- /* @__PURE__ */ h(
6391
+ /* @__PURE__ */ h$1(
5840
6392
  "div",
5841
6393
  {
5842
6394
  class: "divider",
@@ -5848,7 +6400,7 @@ const Toolbar = defineComponent({
5848
6400
  }
5849
6401
  }
5850
6402
  ),
5851
- /* @__PURE__ */ h(
6403
+ /* @__PURE__ */ h$1(
5852
6404
  "div",
5853
6405
  {
5854
6406
  class: "toolbar-item",
@@ -5858,26 +6410,26 @@ const Toolbar = defineComponent({
5858
6410
  position: "relative",
5859
6411
  display: isSectionOverflowed(5) ? "none" : "flex",
5860
6412
  alignItems: "center",
5861
- padding: "0 8px",
6413
+ padding: "0 6px",
5862
6414
  flexShrink: 0
5863
6415
  }
5864
6416
  },
5865
- /* @__PURE__ */ h(
6417
+ /* @__PURE__ */ h$1(
5866
6418
  "span",
5867
6419
  {
5868
6420
  style: { display: "inline-flex", alignItems: "center" },
5869
6421
  innerHTML: currentAlignIndent.value.align === "center" ? alignCenterIcon : currentAlignIndent.value.align === "right" ? alignRightIcon : alignLeftIcon
5870
6422
  }
5871
6423
  ),
5872
- /* @__PURE__ */ h(
6424
+ /* @__PURE__ */ h$1(
5873
6425
  "span",
5874
6426
  {
5875
6427
  style: { width: "20px", display: "flex", alignItems: "center" }
5876
6428
  },
5877
- /* @__PURE__ */ h(Icon, { icon: chevronDownIcon })
6429
+ /* @__PURE__ */ h$1(Icon, { icon: chevronDownIcon })
5878
6430
  )
5879
6431
  ),
5880
- /* @__PURE__ */ h(
6432
+ /* @__PURE__ */ h$1(
5881
6433
  "div",
5882
6434
  {
5883
6435
  class: "toolbar-item",
@@ -5891,7 +6443,7 @@ const Toolbar = defineComponent({
5891
6443
  flexShrink: 0
5892
6444
  }
5893
6445
  },
5894
- /* @__PURE__ */ h(
6446
+ /* @__PURE__ */ h$1(
5895
6447
  "span",
5896
6448
  {
5897
6449
  class: "milkdown-icon",
@@ -5904,12 +6456,12 @@ const Toolbar = defineComponent({
5904
6456
  }
5905
6457
  }
5906
6458
  ),
5907
- /* @__PURE__ */ h(
6459
+ /* @__PURE__ */ h$1(
5908
6460
  "span",
5909
6461
  {
5910
6462
  style: { width: "20px", display: "flex", alignItems: "center" }
5911
6463
  },
5912
- /* @__PURE__ */ h(Icon, { icon: chevronDownIcon })
6464
+ /* @__PURE__ */ h$1(Icon, { icon: chevronDownIcon })
5913
6465
  )
5914
6466
  ),
5915
6467
  (() => {
@@ -5919,7 +6471,7 @@ const Toolbar = defineComponent({
5919
6471
  const idx = sectionIdx;
5920
6472
  sectionIdx++;
5921
6473
  const isTable = item.icon === tableIcon;
5922
- return /* @__PURE__ */ h(
6474
+ return /* @__PURE__ */ h$1(
5923
6475
  "div",
5924
6476
  {
5925
6477
  key: item.label,
@@ -5931,7 +6483,7 @@ const Toolbar = defineComponent({
5931
6483
  onMouseenter: isTable ? handleTableEnter : void 0,
5932
6484
  onMouseleave: isTable ? handleTableLeave : void 0
5933
6485
  },
5934
- /* @__PURE__ */ h(
6486
+ /* @__PURE__ */ h$1(
5935
6487
  "button",
5936
6488
  {
5937
6489
  type: "button",
@@ -5954,14 +6506,14 @@ const Toolbar = defineComponent({
5954
6506
  justifyContent: "center"
5955
6507
  }
5956
6508
  },
5957
- /* @__PURE__ */ h(
6509
+ /* @__PURE__ */ h$1(
5958
6510
  "span",
5959
6511
  {
5960
6512
  style: { display: "inline-flex", alignItems: "center" },
5961
6513
  innerHTML: ctx && checkActive(item.active) ? activeIconMap[item.icon] || item.icon : item.icon
5962
6514
  }
5963
6515
  ),
5964
- isTable ? /* @__PURE__ */ h(
6516
+ isTable ? /* @__PURE__ */ h$1(
5965
6517
  "span",
5966
6518
  {
5967
6519
  style: {
@@ -5972,7 +6524,7 @@ const Toolbar = defineComponent({
5972
6524
  opacity: 0.5
5973
6525
  }
5974
6526
  },
5975
- /* @__PURE__ */ h(Icon, { icon: chevronDownIcon })
6527
+ /* @__PURE__ */ h$1(Icon, { icon: chevronDownIcon })
5976
6528
  ) : null
5977
6529
  )
5978
6530
  );
@@ -5981,7 +6533,7 @@ const Toolbar = defineComponent({
5981
6533
  if (groupIndex < nonHeadingGroups.length - 1 && group.items.length > 0) {
5982
6534
  sectionIdx++;
5983
6535
  }
5984
- return /* @__PURE__ */ h(Fragment, { key: group.key }, items, groupIndex < nonHeadingGroups.length - 1 && group.items.length > 0 ? /* @__PURE__ */ h(
6536
+ return /* @__PURE__ */ h$1(Fragment, { key: group.key }, items, groupIndex < nonHeadingGroups.length - 1 && group.items.length > 0 ? /* @__PURE__ */ h$1(
5985
6537
  "div",
5986
6538
  {
5987
6539
  class: "divider",
@@ -5993,7 +6545,7 @@ const Toolbar = defineComponent({
5993
6545
  ) : null);
5994
6546
  });
5995
6547
  })(),
5996
- hasOverflow ? /* @__PURE__ */ h(
6548
+ hasOverflow ? /* @__PURE__ */ h$1(
5997
6549
  "div",
5998
6550
  {
5999
6551
  "data-overflow-button": "true",
@@ -6020,7 +6572,7 @@ const Toolbar = defineComponent({
6020
6572
  showOverflowMenu.value = true;
6021
6573
  }
6022
6574
  },
6023
- /* @__PURE__ */ h(
6575
+ /* @__PURE__ */ h$1(
6024
6576
  "span",
6025
6577
  {
6026
6578
  style: { display: "inline-flex", alignItems: "center" },
@@ -6028,7 +6580,7 @@ const Toolbar = defineComponent({
6028
6580
  }
6029
6581
  )
6030
6582
  ) : null,
6031
- showBlockMenu.value ? /* @__PURE__ */ h(
6583
+ showBlockMenu.value ? /* @__PURE__ */ h$1(
6032
6584
  "div",
6033
6585
  {
6034
6586
  class: "milkdown-slash-menu custom-submenu",
@@ -6053,7 +6605,7 @@ const Toolbar = defineComponent({
6053
6605
  },
6054
6606
  onMouseleave: handleBlockLeave
6055
6607
  },
6056
- /* @__PURE__ */ h(
6608
+ /* @__PURE__ */ h$1(
6057
6609
  "div",
6058
6610
  {
6059
6611
  style: {
@@ -6110,7 +6662,7 @@ const Toolbar = defineComponent({
6110
6662
  );
6111
6663
  })
6112
6664
  ) : null,
6113
- showAlignMenu.value ? /* @__PURE__ */ h(
6665
+ showAlignMenu.value ? /* @__PURE__ */ h$1(
6114
6666
  "div",
6115
6667
  {
6116
6668
  class: "milkdown-slash-menu custom-submenu",
@@ -6133,7 +6685,7 @@ const Toolbar = defineComponent({
6133
6685
  },
6134
6686
  onMouseleave: handleAlignLeave
6135
6687
  },
6136
- /* @__PURE__ */ h(
6688
+ /* @__PURE__ */ h$1(
6137
6689
  "div",
6138
6690
  {
6139
6691
  style: {
@@ -6164,7 +6716,7 @@ const Toolbar = defineComponent({
6164
6716
  currentAlignIndent.value.align === "right",
6165
6717
  () => setAlign("right")
6166
6718
  ),
6167
- /* @__PURE__ */ h(
6719
+ /* @__PURE__ */ h$1(
6168
6720
  "div",
6169
6721
  {
6170
6722
  style: {
@@ -6186,7 +6738,7 @@ const Toolbar = defineComponent({
6186
6738
  () => setIndent(-1),
6187
6739
  currentAlignIndent.value.indent <= 0
6188
6740
  ),
6189
- canMerge.value || canSplit.value ? /* @__PURE__ */ h(Fragment, null, /* @__PURE__ */ h(
6741
+ canMerge.value || canSplit.value ? /* @__PURE__ */ h$1(Fragment, null, /* @__PURE__ */ h$1(
6190
6742
  "div",
6191
6743
  {
6192
6744
  style: {
@@ -6206,7 +6758,7 @@ const Toolbar = defineComponent({
6206
6758
  onSplitCell
6207
6759
  )) : null
6208
6760
  ) : null,
6209
- showColorMenu.value ? /* @__PURE__ */ h(
6761
+ showColorMenu.value ? /* @__PURE__ */ h$1(
6210
6762
  "div",
6211
6763
  {
6212
6764
  class: "milkdown-slash-menu custom-submenu",
@@ -6230,7 +6782,7 @@ const Toolbar = defineComponent({
6230
6782
  },
6231
6783
  onMouseleave: handleColorLeave
6232
6784
  },
6233
- /* @__PURE__ */ h(
6785
+ /* @__PURE__ */ h$1(
6234
6786
  "div",
6235
6787
  {
6236
6788
  style: {
@@ -6243,7 +6795,7 @@ const Toolbar = defineComponent({
6243
6795
  }
6244
6796
  }
6245
6797
  ),
6246
- /* @__PURE__ */ h(
6798
+ /* @__PURE__ */ h$1(
6247
6799
  "div",
6248
6800
  {
6249
6801
  style: {
@@ -6254,7 +6806,7 @@ const Toolbar = defineComponent({
6254
6806
  },
6255
6807
  ctx ? i18n(ctx, "customMenu.textColor") : "\u5B57\u4F53\u989C\u8272"
6256
6808
  ),
6257
- /* @__PURE__ */ h("div", { style: { display: "flex", gap: "4px", flexWrap: "wrap" } }, [
6809
+ /* @__PURE__ */ h$1("div", { style: { display: "flex", gap: "4px", flexWrap: "wrap" } }, [
6258
6810
  "#000000",
6259
6811
  "#8C8C8C",
6260
6812
  "#F5222D",
@@ -6263,7 +6815,7 @@ const Toolbar = defineComponent({
6263
6815
  "#52C41A",
6264
6816
  "#1677FF",
6265
6817
  "#722ED1"
6266
- ].map((color) => /* @__PURE__ */ h(
6818
+ ].map((color) => /* @__PURE__ */ h$1(
6267
6819
  "div",
6268
6820
  {
6269
6821
  key: color,
@@ -6286,7 +6838,7 @@ const Toolbar = defineComponent({
6286
6838
  },
6287
6839
  "A"
6288
6840
  ))),
6289
- /* @__PURE__ */ h(
6841
+ /* @__PURE__ */ h$1(
6290
6842
  "div",
6291
6843
  {
6292
6844
  style: {
@@ -6298,7 +6850,7 @@ const Toolbar = defineComponent({
6298
6850
  },
6299
6851
  ctx ? i18n(ctx, "customMenu.bgColor") : "\u80CC\u666F\u989C\u8272"
6300
6852
  ),
6301
- /* @__PURE__ */ h("div", { style: { display: "flex", gap: "4px", flexWrap: "wrap" } }, [
6853
+ /* @__PURE__ */ h$1("div", { style: { display: "flex", gap: "4px", flexWrap: "wrap" } }, [
6302
6854
  "transparent",
6303
6855
  "#F5F5F5",
6304
6856
  "#FFCCC7",
@@ -6307,7 +6859,7 @@ const Toolbar = defineComponent({
6307
6859
  "#D9F7BE",
6308
6860
  "#D6E4FF",
6309
6861
  "#EFDBFF"
6310
- ].map((color) => /* @__PURE__ */ h(
6862
+ ].map((color) => /* @__PURE__ */ h$1(
6311
6863
  "div",
6312
6864
  {
6313
6865
  key: color,
@@ -6324,7 +6876,7 @@ const Toolbar = defineComponent({
6324
6876
  overflow: "hidden"
6325
6877
  }
6326
6878
  },
6327
- color === "transparent" ? /* @__PURE__ */ h(
6879
+ color === "transparent" ? /* @__PURE__ */ h$1(
6328
6880
  "div",
6329
6881
  {
6330
6882
  style: {
@@ -6348,7 +6900,7 @@ const Toolbar = defineComponent({
6348
6900
  "#52C41A",
6349
6901
  "#1677FF",
6350
6902
  "#722ED1"
6351
- ].map((color) => /* @__PURE__ */ h(
6903
+ ].map((color) => /* @__PURE__ */ h$1(
6352
6904
  "div",
6353
6905
  {
6354
6906
  key: color,
@@ -6364,7 +6916,7 @@ const Toolbar = defineComponent({
6364
6916
  }
6365
6917
  }
6366
6918
  ))),
6367
- /* @__PURE__ */ h(
6919
+ /* @__PURE__ */ h$1(
6368
6920
  "button",
6369
6921
  {
6370
6922
  onClick: clearColor,
@@ -6383,7 +6935,7 @@ const Toolbar = defineComponent({
6383
6935
  ctx ? i18n(ctx, "customMenu.restoreDefault") : "\u6062\u590D\u9ED8\u8BA4"
6384
6936
  )
6385
6937
  ) : null,
6386
- showFontFamilyMenu.value ? /* @__PURE__ */ h(
6938
+ showFontFamilyMenu.value ? /* @__PURE__ */ h$1(
6387
6939
  "div",
6388
6940
  {
6389
6941
  class: "milkdown-slash-menu custom-submenu",
@@ -6408,7 +6960,7 @@ const Toolbar = defineComponent({
6408
6960
  },
6409
6961
  onMouseleave: handleFontFamilyLeave
6410
6962
  },
6411
- /* @__PURE__ */ h(
6963
+ /* @__PURE__ */ h$1(
6412
6964
  "div",
6413
6965
  {
6414
6966
  style: {
@@ -6469,7 +7021,7 @@ const Toolbar = defineComponent({
6469
7021
  }
6470
7022
  ].map((font) => {
6471
7023
  const supported = isFontSupported(font.value);
6472
- return /* @__PURE__ */ h(
7024
+ return /* @__PURE__ */ h$1(
6473
7025
  "div",
6474
7026
  {
6475
7027
  key: font.label,
@@ -6506,7 +7058,7 @@ const Toolbar = defineComponent({
6506
7058
  e.currentTarget.style.backgroundColor = "transparent";
6507
7059
  }
6508
7060
  },
6509
- /* @__PURE__ */ h(
7061
+ /* @__PURE__ */ h$1(
6510
7062
  "span",
6511
7063
  {
6512
7064
  style: {
@@ -6516,7 +7068,7 @@ const Toolbar = defineComponent({
6516
7068
  },
6517
7069
  font.label
6518
7070
  ),
6519
- currentFontState.value.fontFamily === font.value ? /* @__PURE__ */ h(
7071
+ currentFontState.value.fontFamily === font.value ? /* @__PURE__ */ h$1(
6520
7072
  "span",
6521
7073
  {
6522
7074
  style: {
@@ -6525,12 +7077,12 @@ const Toolbar = defineComponent({
6525
7077
  color: "var(--crepe-color-primary)"
6526
7078
  }
6527
7079
  },
6528
- /* @__PURE__ */ h(Icon, { icon: confirmIcon })
7080
+ /* @__PURE__ */ h$1(Icon, { icon: confirmIcon })
6529
7081
  ) : null
6530
7082
  );
6531
7083
  })
6532
7084
  ) : null,
6533
- showFontSizeMenu.value ? /* @__PURE__ */ h(
7085
+ showFontSizeMenu.value ? /* @__PURE__ */ h$1(
6534
7086
  "div",
6535
7087
  {
6536
7088
  class: "milkdown-slash-menu custom-submenu",
@@ -6555,7 +7107,7 @@ const Toolbar = defineComponent({
6555
7107
  },
6556
7108
  onMouseleave: handleFontSizeLeave
6557
7109
  },
6558
- /* @__PURE__ */ h(
7110
+ /* @__PURE__ */ h$1(
6559
7111
  "div",
6560
7112
  {
6561
7113
  style: {
@@ -6580,7 +7132,7 @@ const Toolbar = defineComponent({
6580
7132
  { label: "28px", value: "28px" },
6581
7133
  { label: "32px", value: "32px" },
6582
7134
  { label: "36px", value: "36px" }
6583
- ].map((size) => /* @__PURE__ */ h(
7135
+ ].map((size) => /* @__PURE__ */ h$1(
6584
7136
  "div",
6585
7137
  {
6586
7138
  key: size.label,
@@ -6611,7 +7163,7 @@ const Toolbar = defineComponent({
6611
7163
  e.currentTarget.style.backgroundColor = "transparent";
6612
7164
  }
6613
7165
  },
6614
- /* @__PURE__ */ h(
7166
+ /* @__PURE__ */ h$1(
6615
7167
  "span",
6616
7168
  {
6617
7169
  style: {
@@ -6621,7 +7173,7 @@ const Toolbar = defineComponent({
6621
7173
  },
6622
7174
  size.label
6623
7175
  ),
6624
- currentFontState.value.fontSize === size.value ? /* @__PURE__ */ h(
7176
+ currentFontState.value.fontSize === size.value ? /* @__PURE__ */ h$1(
6625
7177
  "span",
6626
7178
  {
6627
7179
  style: {
@@ -6630,11 +7182,11 @@ const Toolbar = defineComponent({
6630
7182
  color: "var(--crepe-color-primary)"
6631
7183
  }
6632
7184
  },
6633
- /* @__PURE__ */ h(Icon, { icon: confirmIcon })
7185
+ /* @__PURE__ */ h$1(Icon, { icon: confirmIcon })
6634
7186
  ) : null
6635
7187
  ))
6636
7188
  ) : null,
6637
- showTableMenu.value ? /* @__PURE__ */ h(
7189
+ showTableMenu.value ? /* @__PURE__ */ h$1(
6638
7190
  "div",
6639
7191
  {
6640
7192
  class: "milkdown-slash-menu custom-submenu",
@@ -6657,7 +7209,7 @@ const Toolbar = defineComponent({
6657
7209
  },
6658
7210
  onMouseleave: handleTableLeave
6659
7211
  },
6660
- /* @__PURE__ */ h(
7212
+ /* @__PURE__ */ h$1(
6661
7213
  "div",
6662
7214
  {
6663
7215
  style: {
@@ -6670,7 +7222,7 @@ const Toolbar = defineComponent({
6670
7222
  }
6671
7223
  }
6672
7224
  ),
6673
- /* @__PURE__ */ h(
7225
+ /* @__PURE__ */ h$1(
6674
7226
  "div",
6675
7227
  {
6676
7228
  style: {
@@ -6682,7 +7234,7 @@ const Toolbar = defineComponent({
6682
7234
  },
6683
7235
  i18n(ctx, "customMenu.insertTable")
6684
7236
  ),
6685
- /* @__PURE__ */ h(
7237
+ /* @__PURE__ */ h$1(
6686
7238
  "div",
6687
7239
  {
6688
7240
  style: {
@@ -6695,7 +7247,7 @@ const Toolbar = defineComponent({
6695
7247
  Array.from({ length: 9 }).map(
6696
7248
  (_, r) => Array.from({ length: 9 }).map((_2, c) => {
6697
7249
  const isHovered = r < tableHoverIndices.value.r && c < tableHoverIndices.value.c;
6698
- return /* @__PURE__ */ h(
7250
+ return /* @__PURE__ */ h$1(
6699
7251
  "div",
6700
7252
  {
6701
7253
  key: `cell-${r}-${c}`,
@@ -6724,7 +7276,7 @@ const Toolbar = defineComponent({
6724
7276
  })
6725
7277
  )
6726
7278
  ),
6727
- tableHoverIndices.value.r > 0 ? /* @__PURE__ */ h(
7279
+ tableHoverIndices.value.r > 0 ? /* @__PURE__ */ h$1(
6728
7280
  "div",
6729
7281
  {
6730
7282
  style: {
@@ -6737,7 +7289,7 @@ const Toolbar = defineComponent({
6737
7289
  tableHoverIndices.value.r,
6738
7290
  " x ",
6739
7291
  tableHoverIndices.value.c
6740
- ) : /* @__PURE__ */ h(
7292
+ ) : /* @__PURE__ */ h$1(
6741
7293
  "div",
6742
7294
  {
6743
7295
  style: {
@@ -6750,7 +7302,7 @@ const Toolbar = defineComponent({
6750
7302
  "0 x 0"
6751
7303
  )
6752
7304
  ) : null,
6753
- showOverflowMenu.value ? /* @__PURE__ */ h(
7305
+ showOverflowMenu.value ? /* @__PURE__ */ h$1(
6754
7306
  "div",
6755
7307
  {
6756
7308
  class: "overflow-menu-popup",
@@ -6775,7 +7327,7 @@ const Toolbar = defineComponent({
6775
7327
  (() => {
6776
7328
  const cutoff = overflowVisibleCount.value;
6777
7329
  const items = [];
6778
- const renderIconButton = (iconHtml, title, isActive, onClick2, hasDropdown = false, onMouseEnter, onMouseLeave) => /* @__PURE__ */ h(
7330
+ const renderIconButton = (iconHtml, title, isActive, onClick2, hasDropdown = false, onMouseEnter, onMouseLeave) => /* @__PURE__ */ h$1(
6779
7331
  "button",
6780
7332
  {
6781
7333
  type: "button",
@@ -6798,14 +7350,14 @@ const Toolbar = defineComponent({
6798
7350
  justifyContent: "center"
6799
7351
  }
6800
7352
  },
6801
- /* @__PURE__ */ h(
7353
+ /* @__PURE__ */ h$1(
6802
7354
  "span",
6803
7355
  {
6804
7356
  style: { display: "inline-flex", alignItems: "center" },
6805
7357
  innerHTML: iconHtml
6806
7358
  }
6807
7359
  ),
6808
- hasDropdown ? /* @__PURE__ */ h(
7360
+ hasDropdown ? /* @__PURE__ */ h$1(
6809
7361
  "span",
6810
7362
  {
6811
7363
  style: {
@@ -6815,7 +7367,7 @@ const Toolbar = defineComponent({
6815
7367
  opacity: 0.5
6816
7368
  }
6817
7369
  },
6818
- /* @__PURE__ */ h(Icon, { icon: chevronDownIcon })
7370
+ /* @__PURE__ */ h$1(Icon, { icon: chevronDownIcon })
6819
7371
  ) : null
6820
7372
  );
6821
7373
  if (0 >= cutoff) {
@@ -6895,7 +7447,7 @@ const Toolbar = defineComponent({
6895
7447
  ctx && checkActive(item.active) ? activeIconMap[item.icon] || item.icon : item.icon,
6896
7448
  item.label,
6897
7449
  ctx ? checkActive(item.active) : false,
6898
- isTable ? void 0 : (e) => {
7450
+ isTable ? void 0 : (_e) => {
6899
7451
  item.onRun(ctx);
6900
7452
  showOverflowMenu.value = false;
6901
7453
  },
@@ -7161,7 +7713,9 @@ const MenuBar = defineComponent({
7161
7713
  boxShadow: "0 4px 12px rgba(0,0,0,0.1)",
7162
7714
  cursor: "default"
7163
7715
  },
7164
- onClick: (e) => e.stopPropagation()
7716
+ onClick: (e) => {
7717
+ e.stopPropagation();
7718
+ }
7165
7719
  },
7166
7720
  menuKeys.map((menuKey) => {
7167
7721
  const isHovered = activeSubmenu.value === menuKey;
@@ -7170,7 +7724,9 @@ const MenuBar = defineComponent({
7170
7724
  "div",
7171
7725
  {
7172
7726
  key: menuKey,
7173
- onMouseenter: () => onMouseEnterItem(menuKey),
7727
+ onMouseenter: () => {
7728
+ onMouseEnterItem(menuKey);
7729
+ },
7174
7730
  onMouseleave: () => {
7175
7731
  if (hasSubmenu(menuKey)) {
7176
7732
  activeSubmenu.value = null;
@@ -7591,7 +8147,7 @@ const labelStyle = {
7591
8147
  color: "var(--crepe-color-on-surface, #333)"
7592
8148
  };
7593
8149
  function renderGroup(ctx, group) {
7594
- return /* @__PURE__ */ h("div", { style: { marginBottom: "16px" }, key: group.titleKey }, /* @__PURE__ */ h("div", { style: groupTitleStyle }, i18n(ctx, group.titleKey)), /* @__PURE__ */ h("div", { style: { display: "flex", flexDirection: "column" } }, group.items.map((item) => /* @__PURE__ */ h("div", { key: item.labelKey, style: rowStyle }, /* @__PURE__ */ h("span", { style: labelStyle }, i18n(ctx, item.labelKey)), /* @__PURE__ */ h("div", { style: { display: "flex", gap: "4px", alignItems: "center" } }, item.keys.map((key, i) => /* @__PURE__ */ h("span", { key: i, style: badgeStyle }, fmt(key))))))));
8150
+ return /* @__PURE__ */ h$1("div", { style: { marginBottom: "16px" }, key: group.titleKey }, /* @__PURE__ */ h$1("div", { style: groupTitleStyle }, i18n(ctx, group.titleKey)), /* @__PURE__ */ h$1("div", { style: { display: "flex", flexDirection: "column" } }, group.items.map((item) => /* @__PURE__ */ h$1("div", { key: item.labelKey, style: rowStyle }, /* @__PURE__ */ h$1("span", { style: labelStyle }, i18n(ctx, item.labelKey)), /* @__PURE__ */ h$1("div", { style: { display: "flex", gap: "4px", alignItems: "center" } }, item.keys.map((key, i) => /* @__PURE__ */ h$1("span", { key: i, style: badgeStyle }, fmt(key))))))));
7595
8151
  }
7596
8152
  const ShortcutHelpModal = defineComponent({
7597
8153
  props: {
@@ -7607,7 +8163,7 @@ const ShortcutHelpModal = defineComponent({
7607
8163
  };
7608
8164
  onMounted(() => document.addEventListener("keydown", onKeydown));
7609
8165
  onBeforeUnmount(() => document.removeEventListener("keydown", onKeydown));
7610
- return () => /* @__PURE__ */ h(
8166
+ return () => /* @__PURE__ */ h$1(
7611
8167
  "div",
7612
8168
  {
7613
8169
  style: {
@@ -7621,7 +8177,7 @@ const ShortcutHelpModal = defineComponent({
7621
8177
  },
7622
8178
  onClick: close
7623
8179
  },
7624
- /* @__PURE__ */ h(
8180
+ /* @__PURE__ */ h$1(
7625
8181
  "div",
7626
8182
  {
7627
8183
  style: {
@@ -7635,7 +8191,7 @@ const ShortcutHelpModal = defineComponent({
7635
8191
  },
7636
8192
  onClick: (e) => e.stopPropagation()
7637
8193
  },
7638
- /* @__PURE__ */ h(
8194
+ /* @__PURE__ */ h$1(
7639
8195
  "div",
7640
8196
  {
7641
8197
  style: {
@@ -7647,7 +8203,7 @@ const ShortcutHelpModal = defineComponent({
7647
8203
  borderBottom: "1px solid var(--crepe-color-outline-variant, color-mix(in srgb, var(--crepe-color-outline), transparent 80%))"
7648
8204
  }
7649
8205
  },
7650
- /* @__PURE__ */ h(
8206
+ /* @__PURE__ */ h$1(
7651
8207
  "span",
7652
8208
  {
7653
8209
  style: {
@@ -7658,7 +8214,7 @@ const ShortcutHelpModal = defineComponent({
7658
8214
  },
7659
8215
  i18n(props.ctx, "shortcuts.title")
7660
8216
  ),
7661
- /* @__PURE__ */ h(
8217
+ /* @__PURE__ */ h$1(
7662
8218
  "button",
7663
8219
  {
7664
8220
  type: "button",
@@ -7676,10 +8232,10 @@ const ShortcutHelpModal = defineComponent({
7676
8232
  color: "var(--crepe-color-on-surface-variant, #666)"
7677
8233
  }
7678
8234
  },
7679
- /* @__PURE__ */ h(Icon, { icon: closeIcon })
8235
+ /* @__PURE__ */ h$1(Icon, { icon: closeIcon })
7680
8236
  )
7681
8237
  ),
7682
- /* @__PURE__ */ h("div", { style: { display: "flex", gap: "24px" } }, /* @__PURE__ */ h("div", { style: columnStyle }, leftGroups.map((g) => renderGroup(props.ctx, g))), /* @__PURE__ */ h(
8238
+ /* @__PURE__ */ h$1("div", { style: { display: "flex", gap: "24px" } }, /* @__PURE__ */ h$1("div", { style: columnStyle }, leftGroups.map((g) => renderGroup(props.ctx, g))), /* @__PURE__ */ h$1(
7683
8239
  "div",
7684
8240
  {
7685
8241
  style: {
@@ -7688,7 +8244,7 @@ const ShortcutHelpModal = defineComponent({
7688
8244
  backgroundColor: "var(--crepe-color-outline-variant, color-mix(in srgb, var(--crepe-color-outline), transparent 80%))"
7689
8245
  }
7690
8246
  }
7691
- ), /* @__PURE__ */ h("div", { style: columnStyle }, rightGroups.map((g) => renderGroup(props.ctx, g))))
8247
+ ), /* @__PURE__ */ h$1("div", { style: columnStyle }, rightGroups.map((g) => renderGroup(props.ctx, g))))
7692
8248
  )
7693
8249
  );
7694
8250
  }
@@ -7730,194 +8286,66 @@ const FixedToolbarComponent = defineComponent({
7730
8286
  /* @__PURE__ */ h(
7731
8287
  Toolbar,
7732
8288
  {
7733
- ctx: props.ctx,
7734
- hide: props.hide,
7735
- show: props.show,
7736
- selection: props.selection,
7737
- config: props.config,
7738
- isFixed: true
7739
- }
7740
- ),
7741
- /* @__PURE__ */ h(
7742
- "div",
7743
- {
7744
- style: {
7745
- width: "1px",
7746
- minWidth: "1px",
7747
- height: "20px",
7748
- flexShrink: 0,
7749
- backgroundColor: "var(--crepe-color-outline-variant, color-mix(in srgb, var(--crepe-color-outline), transparent 80%))"
7750
- }
7751
- }
7752
- ),
7753
- /* @__PURE__ */ h(
7754
- "button",
7755
- {
7756
- type: "button",
7757
- class: "toolbar-shortcut-btn",
7758
- title: i18n(props.ctx, "shortcuts.title"),
7759
- onClick: () => {
7760
- showShortcuts.value = true;
7761
- }
7762
- },
7763
- /* @__PURE__ */ h(Icon, { icon: keyboardIcon })
7764
- ),
7765
- showShortcuts.value && /* @__PURE__ */ h(ShortcutHelpModal, { ctx: props.ctx, visible: showShortcuts })
7766
- );
7767
- }
7768
- });
7769
-
7770
- function convertHeadingToParagraphIfNeeded(ctx) {
7771
- const commands = ctx.get(commandsCtx);
7772
- const view = ctx.get(editorViewCtx);
7773
- const heading = headingSchema.type(ctx);
7774
- const { from, to } = view.state.selection;
7775
- let hasHeading = false;
7776
- view.state.doc.nodesBetween(from, to, (node) => {
7777
- if (node.type === heading) hasHeading = true;
7778
- });
7779
- if (hasHeading) {
7780
- commands.call(setBlockTypeCommand.key, {
7781
- nodeType: paragraphSchema.type(ctx)
7782
- });
7783
- }
7784
- }
7785
- function buildDefaultFixedToolbar(builder, _config, ctx) {
7786
- const flags = ctx && useCrepeFeatures(ctx).get();
7787
- const isLatexEnabled = flags == null ? void 0 : flags.includes(CrepeFeature.Latex);
7788
- const isImageBlockEnabled = flags == null ? void 0 : flags.includes(CrepeFeature.ImageBlock);
7789
- const isTableEnabled = flags == null ? void 0 : flags.includes(CrepeFeature.Table);
7790
- const hasFunctionGroup = builder.build().some((g) => g.key === "function");
7791
- const embedGroup = hasFunctionGroup ? builder.getGroup("function") : builder.addGroup("embed", "Embed");
7792
- if (isImageBlockEnabled) {
7793
- embedGroup.addItem("image", {
7794
- label: ctx ? i18n(ctx, "menu.item.image") : "Image",
7795
- icon: imageIcon,
7796
- active: () => false,
7797
- onRun: (ctx2) => {
7798
- const commands = ctx2.get(commandsCtx);
7799
- commands.call(addBlockTypeCommand.key, {
7800
- nodeType: imageBlockSchema.type(ctx2)
7801
- });
7802
- }
7803
- });
7804
- }
7805
- const isAttachmentEnabled = flags == null ? void 0 : flags.includes(CrepeFeature.Attachment);
7806
- if (isAttachmentEnabled) {
7807
- embedGroup.addItem("attachment", {
7808
- label: ctx ? i18n(ctx, "menu.item.attachment") : "Video or File",
7809
- icon: fileLinkIcon,
7810
- active: () => false,
7811
- onRun: (ctx2) => {
7812
- const commands = ctx2.get(commandsCtx);
7813
- commands.call(addBlockTypeCommand.key, {
7814
- nodeType: attachmentSchema.type(ctx2)
7815
- });
7816
- }
7817
- });
7818
- }
7819
- embedGroup.addItem("code-block", {
7820
- label: ctx ? i18n(ctx, "menu.item.code") : "Code Block",
7821
- icon: codeIcon,
7822
- active: (ctx2) => {
7823
- var _a, _b;
7824
- const view = ctx2.get(editorViewCtx);
7825
- const result = findNodeInSelection(view.state, codeBlockSchema.type(ctx2));
7826
- return result.hasNode && ((_b = (_a = result.target) == null ? void 0 : _a.attrs) == null ? void 0 : _b.language) !== "LaTex";
7827
- },
7828
- onRun: (ctx2) => {
7829
- const commands = ctx2.get(commandsCtx);
7830
- const view = ctx2.get(editorViewCtx);
7831
- const { state, dispatch } = view;
7832
- const { selection, tr } = state;
7833
- const { from, to } = selection;
7834
- let text = "";
7835
- let blockCount = 0;
7836
- state.doc.nodesBetween(from, to, (node) => {
7837
- if (node.isTextblock) {
7838
- text += (blockCount > 0 ? "\n" : "") + node.textContent;
7839
- blockCount++;
7840
- }
7841
- });
7842
- if (blockCount > 1) {
7843
- if (dispatch) {
7844
- const range = selection.$from.blockRange(selection.$to);
7845
- const codeBlock = codeBlockSchema.type(ctx2).createAndFill({}, text ? state.schema.text(text) : void 0);
7846
- if (range && codeBlock) {
7847
- tr.replaceWith(range.start, range.end, codeBlock);
7848
- dispatch(tr.scrollIntoView());
8289
+ ctx: props.ctx,
8290
+ hide: props.hide,
8291
+ show: props.show,
8292
+ selection: props.selection,
8293
+ config: props.config,
8294
+ isFixed: true
8295
+ }
8296
+ ),
8297
+ /* @__PURE__ */ h(
8298
+ "div",
8299
+ {
8300
+ style: {
8301
+ width: "1px",
8302
+ minWidth: "1px",
8303
+ height: "20px",
8304
+ flexShrink: 0,
8305
+ backgroundColor: "var(--crepe-color-outline-variant, color-mix(in srgb, var(--crepe-color-outline), transparent 80%))"
7849
8306
  }
7850
8307
  }
7851
- return;
7852
- }
7853
- commands.call(setBlockTypeCommand.key, {
7854
- nodeType: codeBlockSchema.type(ctx2)
7855
- });
7856
- }
7857
- });
7858
- if (isTableEnabled) {
7859
- embedGroup.addItem("table", {
7860
- label: ctx ? i18n(ctx, "menu.item.table") : "Table",
7861
- icon: tableIcon,
7862
- active: () => false,
7863
- onRun: (ctx2) => {
7864
- const commands = ctx2.get(commandsCtx);
7865
- const view = ctx2.get(editorViewCtx);
7866
- const { from } = view.state.selection;
7867
- commands.call(addBlockTypeCommand.key, {
7868
- nodeType: createTable(ctx2, 3, 3)
7869
- });
7870
- commands.call(selectTextNearPosCommand.key, { pos: from });
7871
- }
7872
- });
8308
+ ),
8309
+ /* @__PURE__ */ h(
8310
+ "button",
8311
+ {
8312
+ type: "button",
8313
+ class: "toolbar-shortcut-btn",
8314
+ title: i18n(props.ctx, "shortcuts.title"),
8315
+ onClick: () => {
8316
+ showShortcuts.value = true;
8317
+ }
8318
+ },
8319
+ /* @__PURE__ */ h(Icon, { icon: keyboardIcon })
8320
+ ),
8321
+ showShortcuts.value && /* @__PURE__ */ h(ShortcutHelpModal, { ctx: props.ctx, visible: showShortcuts })
8322
+ );
7873
8323
  }
7874
- if (isLatexEnabled) {
7875
- embedGroup.addItem("math-block", {
7876
- label: ctx ? i18n(ctx, "menu.item.math") : "Math Block",
7877
- icon: functionsIcon,
7878
- active: (ctx2) => {
7879
- var _a, _b;
7880
- const view = ctx2.get(editorViewCtx);
7881
- const result = findNodeInSelection(
7882
- view.state,
7883
- codeBlockSchema.type(ctx2)
7884
- );
7885
- return result.hasNode && ((_b = (_a = result.target) == null ? void 0 : _a.attrs) == null ? void 0 : _b.language) === "LaTex";
7886
- },
7887
- onRun: (ctx2) => {
7888
- const commands = ctx2.get(commandsCtx);
7889
- commands.call(toggleLatexCommand.key);
7890
- }
8324
+ });
8325
+
8326
+ function convertHeadingToParagraphIfNeeded(ctx) {
8327
+ const commands = ctx.get(commandsCtx);
8328
+ const view = ctx.get(editorViewCtx);
8329
+ const heading = headingSchema.type(ctx);
8330
+ const { from, to } = view.state.selection;
8331
+ let hasHeading = false;
8332
+ view.state.doc.nodesBetween(from, to, (node) => {
8333
+ if (node.type === heading) hasHeading = true;
8334
+ });
8335
+ if (hasHeading) {
8336
+ commands.call(setBlockTypeCommand.key, {
8337
+ nodeType: paragraphSchema.type(ctx)
7891
8338
  });
7892
8339
  }
7893
- const blockGroup = builder.addGroup("block", "Block");
7894
- blockGroup.addItem("quote", {
7895
- label: ctx ? i18n(ctx, "menu.item.quote") : "Quote",
7896
- icon: quoteIcon,
7897
- active: (ctx2) => {
7898
- const view = ctx2.get(editorViewCtx);
7899
- const result = findNodeInSelection(
7900
- view.state,
7901
- blockquoteSchema.type(ctx2)
7902
- );
7903
- return result.hasNode;
7904
- },
7905
- onRun: (ctx2) => {
7906
- const view = ctx2.get(editorViewCtx);
7907
- const commands = ctx2.get(commandsCtx);
7908
- const isActive = findNodeInSelection(
7909
- view.state,
7910
- blockquoteSchema.type(ctx2)
7911
- ).hasNode;
7912
- if (isActive) {
7913
- lift(view.state, view.dispatch);
7914
- } else {
7915
- commands.call(wrapInBlockTypeCommand.key, {
7916
- nodeType: blockquoteSchema.type(ctx2)
7917
- });
7918
- }
7919
- }
7920
- }).addItem("divider", {
8340
+ }
8341
+ function buildDefaultFixedToolbar(builder, _config, ctx) {
8342
+ const flags = ctx && useCrepeFeatures(ctx).get();
8343
+ const isLatexEnabled = flags == null ? void 0 : flags.includes(CrepeFeature.Latex);
8344
+ const isImageBlockEnabled = flags == null ? void 0 : flags.includes(CrepeFeature.ImageBlock);
8345
+ const isTableEnabled = flags == null ? void 0 : flags.includes(CrepeFeature.Table);
8346
+ const isAttachmentEnabled = flags == null ? void 0 : flags.includes(CrepeFeature.Attachment);
8347
+ const listGroup = builder.addGroup("list", "List");
8348
+ listGroup.addItem("divider", {
7921
8349
  label: ctx ? i18n(ctx, "menu.item.divider") : "Divider",
7922
8350
  icon: dividerIcon,
7923
8351
  active: () => false,
@@ -7925,9 +8353,7 @@ function buildDefaultFixedToolbar(builder, _config, ctx) {
7925
8353
  const commands = ctx2.get(commandsCtx);
7926
8354
  commands.call(addBlockTypeCommand.key, { nodeType: hrSchema.type(ctx2) });
7927
8355
  }
7928
- });
7929
- const listGroup = blockGroup;
7930
- listGroup.addItem("bullet-list", {
8356
+ }).addItem("bullet-list", {
7931
8357
  label: ctx ? i18n(ctx, "menu.item.bulletList") : "Bullet List",
7932
8358
  icon: bulletListIcon,
7933
8359
  active: (ctx2) => {
@@ -8147,11 +8573,179 @@ function buildDefaultFixedToolbar(builder, _config, ctx) {
8147
8573
  }
8148
8574
  }
8149
8575
  );
8150
- view.dispatch(tr);
8151
- });
8152
- if (result) return;
8153
- }
8154
- });
8576
+ view.dispatch(tr);
8577
+ });
8578
+ if (result) return;
8579
+ }
8580
+ });
8581
+ const blockGroup = builder.addGroup("block", "Block");
8582
+ blockGroup.addItem("quote", {
8583
+ label: ctx ? i18n(ctx, "menu.item.quote") : "Quote",
8584
+ icon: quoteIcon,
8585
+ active: (ctx2) => {
8586
+ const view = ctx2.get(editorViewCtx);
8587
+ const result = findNodeInSelection(
8588
+ view.state,
8589
+ blockquoteSchema.type(ctx2)
8590
+ );
8591
+ return result.hasNode;
8592
+ },
8593
+ onRun: (ctx2) => {
8594
+ const view = ctx2.get(editorViewCtx);
8595
+ const commands = ctx2.get(commandsCtx);
8596
+ const isActive = findNodeInSelection(
8597
+ view.state,
8598
+ blockquoteSchema.type(ctx2)
8599
+ ).hasNode;
8600
+ if (isActive) {
8601
+ lift(view.state, view.dispatch);
8602
+ } else {
8603
+ commands.call(wrapInBlockTypeCommand.key, {
8604
+ nodeType: blockquoteSchema.type(ctx2)
8605
+ });
8606
+ }
8607
+ }
8608
+ }).addItem("highlight", {
8609
+ label: ctx ? i18n(ctx, "menu.item.highlight") : "Highlight",
8610
+ icon: highLineCodeIcon,
8611
+ active: (ctx2) => {
8612
+ const commands = ctx2.get(commandsCtx);
8613
+ return commands.call(
8614
+ isMarkSelectedCommand.key,
8615
+ highlightMarkSchema.type(ctx2)
8616
+ );
8617
+ },
8618
+ onRun: (ctx2) => {
8619
+ const commands = ctx2.get(commandsCtx);
8620
+ commands.call(toggleHighlightMarkCommand.key);
8621
+ }
8622
+ }).addItem("code", {
8623
+ label: ctx ? i18n(ctx, "menu.item.lineCode") : "Inline Code",
8624
+ icon: linCodeIcon,
8625
+ active: (ctx2) => {
8626
+ const commands = ctx2.get(commandsCtx);
8627
+ return commands.call(
8628
+ isMarkSelectedCommand.key,
8629
+ inlineCodeSchema.type(ctx2)
8630
+ );
8631
+ },
8632
+ onRun: (ctx2) => {
8633
+ const commands = ctx2.get(commandsCtx);
8634
+ commands.call(toggleInlineCodeCommand.key);
8635
+ }
8636
+ }).addItem("link", {
8637
+ label: ctx ? i18n(ctx, "menu.item.link") : "Link",
8638
+ icon: linkIcon,
8639
+ active: (ctx2) => {
8640
+ const commands = ctx2.get(commandsCtx);
8641
+ return commands.call(isMarkSelectedCommand.key, linkSchema.type(ctx2));
8642
+ },
8643
+ onRun: (ctx2) => {
8644
+ const commands = ctx2.get(commandsCtx);
8645
+ commands.call(toggleLinkCommand.key);
8646
+ }
8647
+ });
8648
+ if (isImageBlockEnabled) {
8649
+ blockGroup.addItem("image", {
8650
+ label: ctx ? i18n(ctx, "menu.item.image") : "Image",
8651
+ icon: imageIcon,
8652
+ active: () => false,
8653
+ onRun: (ctx2) => {
8654
+ const commands = ctx2.get(commandsCtx);
8655
+ commands.call(addBlockTypeCommand.key, {
8656
+ nodeType: imageBlockSchema.type(ctx2)
8657
+ });
8658
+ }
8659
+ });
8660
+ }
8661
+ if (isAttachmentEnabled) {
8662
+ blockGroup.addItem("attachment", {
8663
+ label: ctx ? i18n(ctx, "menu.item.attachment") : "Video or File",
8664
+ icon: fileLinkIcon,
8665
+ active: () => false,
8666
+ onRun: (ctx2) => {
8667
+ const commands = ctx2.get(commandsCtx);
8668
+ commands.call(addBlockTypeCommand.key, {
8669
+ nodeType: attachmentSchema.type(ctx2)
8670
+ });
8671
+ }
8672
+ });
8673
+ }
8674
+ blockGroup.addItem("code-block", {
8675
+ label: ctx ? i18n(ctx, "menu.item.code") : "Code Block",
8676
+ icon: codeIcon,
8677
+ active: (ctx2) => {
8678
+ var _a, _b;
8679
+ const view = ctx2.get(editorViewCtx);
8680
+ const result = findNodeInSelection(view.state, codeBlockSchema.type(ctx2));
8681
+ return result.hasNode && ((_b = (_a = result.target) == null ? void 0 : _a.attrs) == null ? void 0 : _b.language) !== "LaTex";
8682
+ },
8683
+ onRun: (ctx2) => {
8684
+ const commands = ctx2.get(commandsCtx);
8685
+ const view = ctx2.get(editorViewCtx);
8686
+ const { state, dispatch } = view;
8687
+ const { selection, tr } = state;
8688
+ const { from, to } = selection;
8689
+ let text = "";
8690
+ let blockCount = 0;
8691
+ state.doc.nodesBetween(from, to, (node) => {
8692
+ if (node.isTextblock) {
8693
+ text += (blockCount > 0 ? "\n" : "") + node.textContent;
8694
+ blockCount++;
8695
+ }
8696
+ });
8697
+ if (blockCount > 1) {
8698
+ if (dispatch) {
8699
+ const range = selection.$from.blockRange(selection.$to);
8700
+ const codeBlock = codeBlockSchema.type(ctx2).createAndFill({}, text ? state.schema.text(text) : void 0);
8701
+ if (range && codeBlock) {
8702
+ tr.replaceWith(range.start, range.end, codeBlock);
8703
+ dispatch(tr.scrollIntoView());
8704
+ }
8705
+ }
8706
+ return;
8707
+ }
8708
+ commands.call(setBlockTypeCommand.key, {
8709
+ nodeType: codeBlockSchema.type(ctx2)
8710
+ });
8711
+ }
8712
+ });
8713
+ if (isTableEnabled) {
8714
+ blockGroup.addItem("table", {
8715
+ label: ctx ? i18n(ctx, "menu.item.table") : "Table",
8716
+ icon: tableIcon,
8717
+ active: () => false,
8718
+ onRun: (ctx2) => {
8719
+ const commands = ctx2.get(commandsCtx);
8720
+ const view = ctx2.get(editorViewCtx);
8721
+ const { from } = view.state.selection;
8722
+ commands.call(addBlockTypeCommand.key, {
8723
+ nodeType: createTable(ctx2, 3, 3)
8724
+ });
8725
+ commands.call(selectTextNearPosCommand.key, { pos: from });
8726
+ }
8727
+ });
8728
+ }
8729
+ if (isLatexEnabled) {
8730
+ blockGroup.addItem("math-block", {
8731
+ label: ctx ? i18n(ctx, "menu.item.math") : "Math Block",
8732
+ icon: functionsIcon,
8733
+ active: (ctx2) => {
8734
+ var _a, _b;
8735
+ const view = ctx2.get(editorViewCtx);
8736
+ const result = findNodeInSelection(
8737
+ view.state,
8738
+ codeBlockSchema.type(ctx2)
8739
+ );
8740
+ return result.hasNode && ((_b = (_a = result.target) == null ? void 0 : _a.attrs) == null ? void 0 : _b.language) === "LaTex";
8741
+ },
8742
+ onRun: (ctx2) => {
8743
+ const commands = ctx2.get(commandsCtx);
8744
+ commands.call(toggleLatexCommand.key);
8745
+ }
8746
+ });
8747
+ }
8748
+ return builder.build();
8155
8749
  }
8156
8750
 
8157
8751
  const DocumentHeader = defineComponent({
@@ -8172,12 +8766,26 @@ const DocumentHeader = defineComponent({
8172
8766
  titleTextareaRef.value.style.height = titleTextareaRef.value.scrollHeight + "px";
8173
8767
  }
8174
8768
  };
8769
+ let resizeObserver = null;
8770
+ onMounted(() => {
8771
+ setTimeout(adjustTitleHeight, 0);
8772
+ if (titleTextareaRef.value) {
8773
+ resizeObserver = new ResizeObserver(() => {
8774
+ adjustTitleHeight();
8775
+ });
8776
+ resizeObserver.observe(titleTextareaRef.value);
8777
+ }
8778
+ });
8779
+ onUnmounted(() => {
8780
+ if (resizeObserver) {
8781
+ resizeObserver.disconnect();
8782
+ }
8783
+ });
8175
8784
  watch(
8176
8785
  () => title.value,
8177
8786
  () => {
8178
8787
  setTimeout(adjustTitleHeight, 0);
8179
- },
8180
- { immediate: true }
8788
+ }
8181
8789
  );
8182
8790
  watch(
8183
8791
  () => viewState.value.showCover,
@@ -8388,7 +8996,11 @@ const DocumentHeader = defineComponent({
8388
8996
  ref: titleTextareaRef,
8389
8997
  class: "milkdown-document-title",
8390
8998
  placeholder: "\u8BF7\u8F93\u5165\u6807\u9898",
8391
- "v-model": title.value,
8999
+ value: title.value,
9000
+ onInput: (e) => {
9001
+ title.value = e.target.value;
9002
+ adjustTitleHeight();
9003
+ },
8392
9004
  rows: 1,
8393
9005
  style: {
8394
9006
  width: "100%",
@@ -8749,7 +9361,8 @@ const OutlinePanel = defineComponent({
8749
9361
  e.currentTarget.style.backgroundColor = "transparent";
8750
9362
  }
8751
9363
  },
8752
- "\u25BC"
9364
+ "\uFFFD?",
9365
+ " "
8753
9366
  ),
8754
9367
  /* @__PURE__ */ h(
8755
9368
  "span",
@@ -9157,7 +9770,7 @@ const blockLatexSchema = codeBlockSchema.extendSchema((prev) => {
9157
9770
 
9158
9771
  const inlineLatexTooltip = tooltipFactory("INLINE_LATEX");
9159
9772
 
9160
- keepAlive(h);
9773
+ keepAlive(h$1);
9161
9774
  const LatexTooltip = defineComponent({
9162
9775
  props: {
9163
9776
  ctx: {
@@ -9193,7 +9806,7 @@ const LatexTooltip = defineComponent({
9193
9806
  }
9194
9807
  };
9195
9808
  return () => {
9196
- return /* @__PURE__ */ h("div", { class: "container container-large" }, /* @__PURE__ */ h("div", { class: "input-container" }, props.innerView ? /* @__PURE__ */ h("div", { ref: innerViewRef }) : null), /* @__PURE__ */ h("div", { class: "footer" }, /* @__PURE__ */ h("span", { class: "left" }, i18n(props.ctx, "latex.escToExit")), /* @__PURE__ */ h(
9809
+ return /* @__PURE__ */ h$1("div", { class: "container container-large" }, /* @__PURE__ */ h$1("div", { class: "input-container" }, props.innerView ? /* @__PURE__ */ h$1("div", { ref: innerViewRef }) : null), /* @__PURE__ */ h$1("div", { class: "footer" }, /* @__PURE__ */ h$1("span", { class: "left" }, i18n(props.ctx, "latex.escToExit")), /* @__PURE__ */ h$1(
9197
9810
  "a",
9198
9811
  {
9199
9812
  class: "right",
@@ -9201,7 +9814,7 @@ const LatexTooltip = defineComponent({
9201
9814
  target: "_blank",
9202
9815
  style: "display: none;"
9203
9816
  },
9204
- /* @__PURE__ */ h(Icon, { icon: helpIcon }),
9817
+ /* @__PURE__ */ h$1(Icon, { icon: helpIcon }),
9205
9818
  " ",
9206
9819
  i18n(props.ctx, "latex.helpDoc")
9207
9820
  )));
@@ -9479,547 +10092,228 @@ const linkTooltip = (editor, config) => {
9479
10092
  ...prev,
9480
10093
  linkIcon: (_a = config == null ? void 0 : config.linkIcon) != null ? _a : copyIcon,
9481
10094
  editButton: (_b = config == null ? void 0 : config.editButton) != null ? _b : editIcon,
9482
- removeButton: (_c = config == null ? void 0 : config.removeButton) != null ? _c : removeIcon,
9483
- confirmButton: (_d = config == null ? void 0 : config.confirmButton) != null ? _d : confirmIcon,
9484
- inputPlaceholder: (_e = config == null ? void 0 : config.inputPlaceholder) != null ? _e : i18n(ctx, "linkTooltip.pasteLink"),
9485
- onCopyLink: (_f = config == null ? void 0 : config.onCopyLink) != null ? _f : (() => {
9486
- })
9487
- };
9488
- });
9489
- }).use(linkTooltipPlugin);
9490
- };
9491
-
9492
- function configureListItem(ctx, config) {
9493
- ctx.set(listItemBlockConfig.key, {
9494
- renderLabel: ({ label, listType, checked }) => {
9495
- var _a, _b, _c;
9496
- if (checked == null) {
9497
- if (listType === "bullet") return (_a = config == null ? void 0 : config.bulletIcon) != null ? _a : bulletIcon;
9498
- return label;
9499
- }
9500
- if (checked) return (_b = config == null ? void 0 : config.checkBoxCheckedIcon) != null ? _b : checkBoxCheckedIcon;
9501
- return (_c = config == null ? void 0 : config.checkBoxUncheckedIcon) != null ? _c : checkBoxUncheckedIcon;
9502
- }
9503
- });
9504
- }
9505
- const listItem = (editor, config) => {
9506
- editor.config(crepeFeatureConfig(CrepeFeature.ListItem)).config((ctx) => configureListItem(ctx, config)).use(listItemBlockComponent);
9507
- };
9508
-
9509
- function isDocEmpty(doc) {
9510
- var _a;
9511
- return doc.childCount <= 1 && !((_a = doc.firstChild) == null ? void 0 : _a.content.size);
9512
- }
9513
- function createPlaceholderDecoration(state, placeholderText) {
9514
- const { selection } = state;
9515
- if (!selection.empty) return null;
9516
- const $pos = selection.$anchor;
9517
- const node = $pos.parent;
9518
- if (node.content.size > 0) return null;
9519
- const inTable = findParent((node2) => node2.type.name === "table")($pos);
9520
- if (inTable) return null;
9521
- const before = $pos.before();
9522
- return Decoration.node(before, before + node.nodeSize, {
9523
- class: "crepe-placeholder",
9524
- "data-placeholder": placeholderText
9525
- });
9526
- }
9527
- const placeholderConfig = $ctx(
9528
- {
9529
- mode: "doc"
9530
- },
9531
- "placeholderConfigCtx"
9532
- );
9533
- const placeholderPlugin = $prose((ctx) => {
9534
- return new Plugin({
9535
- key: new PluginKey("CREPE_PLACEHOLDER"),
9536
- props: {
9537
- decorations: (state) => {
9538
- var _a;
9539
- const crepe = useCrepe(ctx);
9540
- if (crepe.readonly) return DecorationSet.empty;
9541
- const config = ctx.get(placeholderConfig.key);
9542
- if (config.mode === "doc" && !isDocEmpty(state.doc)) return DecorationSet.empty;
9543
- if (isInCodeBlock(state.selection) || isInList(state.selection))
9544
- return DecorationSet.empty;
9545
- const placeholderText = (_a = config.text) != null ? _a : i18n(ctx, "placeholder.text");
9546
- const deco = createPlaceholderDecoration(state, placeholderText);
9547
- if (!deco) return DecorationSet.empty;
9548
- return DecorationSet.create(state.doc, [deco]);
9549
- }
9550
- }
9551
- });
9552
- });
9553
- const placeholder = (editor, config) => {
9554
- editor.config(crepeFeatureConfig(CrepeFeature.Placeholder)).config((ctx) => {
9555
- if (config) {
9556
- ctx.update(placeholderConfig.key, (prev) => {
9557
- return {
9558
- ...prev,
9559
- ...config
9560
- };
9561
- });
9562
- }
9563
- }).use(placeholderPlugin).use(placeholderConfig);
9564
- };
9565
-
9566
- const table = (editor, config) => {
9567
- editor.config(crepeFeatureConfig(CrepeFeature.Table)).config((ctx) => {
9568
- ctx.update(tableBlockConfig.key, (defaultConfig) => ({
9569
- ...defaultConfig,
9570
- renderButton: (renderType) => {
9571
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
9572
- switch (renderType) {
9573
- case "add_row":
9574
- return (_a = config == null ? void 0 : config.addRowIcon) != null ? _a : plusIcon;
9575
- case "add_col":
9576
- return (_b = config == null ? void 0 : config.addColIcon) != null ? _b : plusIcon;
9577
- case "delete_row":
9578
- return (_c = config == null ? void 0 : config.deleteRowIcon) != null ? _c : removeIcon;
9579
- case "delete_col":
9580
- return (_d = config == null ? void 0 : config.deleteColIcon) != null ? _d : removeIcon;
9581
- case "align_col_left":
9582
- return (_e = config == null ? void 0 : config.alignLeftIcon) != null ? _e : alignLeftIcon;
9583
- case "align_col_center":
9584
- return (_f = config == null ? void 0 : config.alignCenterIcon) != null ? _f : alignCenterIcon;
9585
- case "align_col_right":
9586
- return (_g = config == null ? void 0 : config.alignRightIcon) != null ? _g : alignRightIcon;
9587
- case "col_drag_handle":
9588
- return (_h = config == null ? void 0 : config.colDragHandleIcon) != null ? _h : dragHandleIcon;
9589
- case "row_drag_handle":
9590
- return (_i = config == null ? void 0 : config.rowDragHandleIcon) != null ? _i : dragHandleIcon;
9591
- case "merge_cells":
9592
- return (_j = config == null ? void 0 : config.mergeCellsIcon) != null ? _j : mergeCellIcon;
9593
- case "split_cell":
9594
- return (_k = config == null ? void 0 : config.splitCellIcon) != null ? _k : splitCellIcon;
9595
- }
9596
- }
9597
- }));
9598
- }).use(tableBlock);
9599
- };
9600
-
9601
- var __typeError$1 = (msg) => {
9602
- throw TypeError(msg);
9603
- };
9604
- var __accessCheck$1 = (obj, member, msg) => member.has(obj) || __typeError$1("Cannot " + msg);
9605
- var __privateGet$1 = (obj, member, getter) => (__accessCheck$1(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
9606
- var __privateAdd$1 = (obj, member, value) => member.has(obj) ? __typeError$1("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
9607
- var __privateSet$1 = (obj, member, value, setter) => (__accessCheck$1(obj, member, "write to private field"), member.set(obj, value), value);
9608
- var _tooltipProvider, _content, _app, _selection, _show, _mousePressed;
9609
- const toolbarTooltip = tooltipFactory("CREPE_TOOLBAR");
9610
- class ToolbarView {
9611
- constructor(ctx, view, config) {
9612
- __privateAdd$1(this, _tooltipProvider);
9613
- __privateAdd$1(this, _content);
9614
- __privateAdd$1(this, _app);
9615
- __privateAdd$1(this, _selection);
9616
- __privateAdd$1(this, _show, ref(false));
9617
- __privateAdd$1(this, _mousePressed, false);
9618
- this.update = (view, prevState) => {
9619
- __privateGet$1(this, _tooltipProvider).update(view, prevState);
9620
- __privateGet$1(this, _selection).value = view.state.selection;
9621
- };
9622
- this.destroy = () => {
9623
- __privateGet$1(this, _tooltipProvider).destroy();
9624
- __privateGet$1(this, _app).unmount();
9625
- __privateGet$1(this, _content).remove();
9626
- };
9627
- this.hide = () => {
9628
- __privateGet$1(this, _tooltipProvider).hide();
9629
- };
9630
- const content = document.createElement("div");
9631
- content.className = "milkdown-toolbar";
9632
- __privateSet$1(this, _selection, shallowRef(view.state.selection));
9633
- const app = createApp(Toolbar, {
9634
- ctx,
9635
- hide: this.hide,
9636
- config,
9637
- selection: __privateGet$1(this, _selection),
9638
- show: __privateGet$1(this, _show)
9639
- });
9640
- app.mount(content);
9641
- __privateSet$1(this, _content, content);
9642
- __privateSet$1(this, _app, app);
9643
- view.dom.addEventListener("mousedown", () => {
9644
- __privateSet$1(this, _mousePressed, true);
9645
- });
9646
- view.dom.addEventListener("mouseup", () => {
9647
- __privateSet$1(this, _mousePressed, false);
9648
- setTimeout(() => {
9649
- this.update(view);
9650
- }, 0);
9651
- });
9652
- __privateSet$1(this, _tooltipProvider, new TooltipProvider({
9653
- content: __privateGet$1(this, _content),
9654
- debounce: 20,
9655
- offset: 10,
9656
- shouldShow: (view2) => {
9657
- if (__privateGet$1(this, _mousePressed)) return false;
9658
- const { doc, selection } = view2.state;
9659
- const { empty, from, to } = selection;
9660
- const isEmptyTextBlock = !doc.textBetween(from, to).length && selection instanceof TextSelection;
9661
- const isNotTextBlock = !(selection instanceof TextSelection) && !(selection instanceof AllSelection);
9662
- const activeElement = view2.dom.getRootNode().activeElement;
9663
- const isTooltipChildren = content.contains(activeElement);
9664
- const notHasFocus = !view2.hasFocus() && !isTooltipChildren;
9665
- const isReadonly = !view2.editable;
9666
- if (notHasFocus || isNotTextBlock || empty || isEmptyTextBlock || isReadonly)
9667
- return false;
9668
- return true;
9669
- }
9670
- }));
9671
- __privateGet$1(this, _tooltipProvider).onShow = () => {
9672
- __privateGet$1(this, _show).value = true;
9673
- };
9674
- __privateGet$1(this, _tooltipProvider).onHide = () => {
9675
- __privateGet$1(this, _show).value = false;
9676
- };
9677
- this.update(view);
9678
- }
9679
- }
9680
- _tooltipProvider = new WeakMap();
9681
- _content = new WeakMap();
9682
- _app = new WeakMap();
9683
- _selection = new WeakMap();
9684
- _show = new WeakMap();
9685
- _mousePressed = new WeakMap();
9686
- const toolbar = (editor, config) => {
9687
- editor.config(crepeFeatureConfig(CrepeFeature.Toolbar)).config((ctx) => {
9688
- ctx.set(toolbarTooltip.key, {
9689
- view: (view) => new ToolbarView(ctx, view, config)
9690
- });
9691
- }).config((ctx) => {
9692
- ctx.update(editorViewOptionsCtx, (prev) => {
9693
- const prevTransform = prev.transformPastedHTML;
9694
- return {
9695
- ...prev,
9696
- transformPastedHTML: (html, view) => {
9697
- if (prevTransform) html = prevTransform(html, view);
9698
- return stripFontFamilyFromExternalHTML(html);
9699
- }
10095
+ removeButton: (_c = config == null ? void 0 : config.removeButton) != null ? _c : removeIcon,
10096
+ confirmButton: (_d = config == null ? void 0 : config.confirmButton) != null ? _d : confirmIcon,
10097
+ inputPlaceholder: (_e = config == null ? void 0 : config.inputPlaceholder) != null ? _e : i18n(ctx, "linkTooltip.pasteLink"),
10098
+ onCopyLink: (_f = config == null ? void 0 : config.onCopyLink) != null ? _f : (() => {
10099
+ })
9700
10100
  };
9701
10101
  });
9702
- }).use(underline).use(highlightMark).use(colorPlugins).use(fontPlugins).use(toolbarTooltip);
10102
+ }).use(linkTooltipPlugin);
9703
10103
  };
9704
10104
 
9705
- const attachmentConfig = $ctx(
9706
- {
9707
- onUpload: async (file) => {
9708
- return {
9709
- url: URL.createObjectURL(file),
9710
- name: file.name,
9711
- size: file.size
9712
- };
9713
- },
9714
- uploadButton: "Upload file",
9715
- uploadPlaceholderText: "or paste link",
9716
- downloadText: "Download"
9717
- },
9718
- "attachmentConfig"
9719
- );
10105
+ function configureListItem(ctx, config) {
10106
+ ctx.set(listItemBlockConfig.key, {
10107
+ renderLabel: ({ label, listType, checked }) => {
10108
+ var _a, _b, _c;
10109
+ if (checked == null) {
10110
+ if (listType === "bullet") return (_a = config == null ? void 0 : config.bulletIcon) != null ? _a : bulletIcon;
10111
+ return label;
10112
+ }
10113
+ if (checked) return (_b = config == null ? void 0 : config.checkBoxCheckedIcon) != null ? _b : checkBoxCheckedIcon;
10114
+ return (_c = config == null ? void 0 : config.checkBoxUncheckedIcon) != null ? _c : checkBoxUncheckedIcon;
10115
+ }
10116
+ });
10117
+ }
10118
+ const listItem = (editor, config) => {
10119
+ editor.config(crepeFeatureConfig(CrepeFeature.ListItem)).config((ctx) => configureListItem(ctx, config)).use(listItemBlockComponent);
10120
+ };
9720
10121
 
9721
- const downloadIcon = `<svg viewBox="0 0 1024 1024" width="20" height="20" fill="currentColor">
9722
- <path d="M464.96 743.936L194.304 479.68c-4.928-4.8-10.24-9.408-14.592-14.656-20.736-24.768-21.376-45.76-2.368-63.424 17.664-16.384 43.328-16 65.472 4.8 49.088 46.144 96.64 93.824 144.896 140.8l69.376 67.52 11.968 11.392v-184.96c0-36.096-0.128-86.272-0.32-136.96-0.192-54.912-0.32-110.464-0.32-149.504l-0.064-9.28a208 208 0 0 1 0.704-26.56c3.52-31.168 19.328-46.592 45.248-45.76 25.344 0.832 41.088 16.96 42.688 48.576 1.28 24.384 1.024 48.896 0.768 73.408l-0.128 28.928c0 53.376 0.128 120.32 0.256 188.096 0.192 76.352 0.384 153.792 0.32 214.016 74.432-72.704 185.6-181.12 216.32-210.88 7.424-7.168 14.912-15.168 24-19.52 18.688-8.96 37.632-8.32 52.672 7.872 14.72 15.744 16.448 33.408 4.032 51.392-3.84 5.632-8.576 10.816-13.44 15.616-45.696 44.736-243.328 238.272-289.728 282.24a62.592 62.592 0 0 1-8.064 6.4 43.392 43.392 0 0 1-15.872 10.432c-20.544 7.616-37.504-0.512-51.968-14.848l-11.2-10.88z m430.784-39.744c24-0.576 42.176 14.4 43.328 41.6 1.728 40.832 2.944 82.176-1.088 122.816-5.312 54.144-51.52 89.792-114.752 91.008-50.112 0.896-100.224 0.704-150.4 0.512L608 960H434.944c-64.832 0.128-129.6 0.192-194.432-0.192-90.624-0.512-130.752-40.192-131.392-128.64l-0.192-18.56c-0.32-21.12-0.576-42.304 0.768-63.36 1.92-29.76 20.48-46.528 45.76-45.184 23.488 1.28 37.312 16.32 40.064 45.184 0.896 9.792 0.832 19.648 0.704 29.504l-0.064 11.52c0.384 76.544 7.36 83.392 88.128 83.456a163213.952 163213.952 0 0 0 351.68 0.064l43.968 0.128c36.096 0.128 72.192 0.256 108.288-0.448 52.672-1.024 64-12.864 65.152-64.32 0.192-7.68 0.128-15.488 0-23.232a414.72 414.72 0 0 1 0.704-38.208c2.24-27.712 17.92-42.944 41.664-43.52z" fill="currentColor"></path>
9723
- </svg>`;
9724
- function formatBytes(bytes, decimals = 2) {
9725
- if (!+bytes) return "0 Bytes";
9726
- const k = 1024;
9727
- const dm = decimals < 0 ? 0 : decimals;
9728
- const sizes = ["Bytes", "KB", "MB", "GB", "TB"];
9729
- const i = Math.floor(Math.log(bytes) / Math.log(k));
9730
- return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`;
10122
+ function isDocEmpty(doc) {
10123
+ var _a;
10124
+ return doc.childCount <= 1 && !((_a = doc.firstChild) == null ? void 0 : _a.content.size);
9731
10125
  }
9732
- const MilkdownAttachmentBlock = defineComponent({
9733
- props: {
9734
- src: { type: Object, required: true },
9735
- name: { type: Object, required: true },
9736
- size: { type: Object, required: true },
9737
- videoWidth: { type: Object, required: true },
9738
- selected: { type: Object, required: true },
9739
- readonly: { type: Object, required: true },
9740
- setAttr: { type: Function, required: true },
9741
- config: { type: Object, required: true }
10126
+ function createPlaceholderDecoration(state, placeholderText) {
10127
+ const { selection } = state;
10128
+ if (!selection.empty) return null;
10129
+ const $pos = selection.$anchor;
10130
+ const node = $pos.parent;
10131
+ if (node.content.size > 0) return null;
10132
+ const inTable = findParent((node2) => node2.type.name === "table")($pos);
10133
+ if (inTable) return null;
10134
+ const before = $pos.before();
10135
+ return Decoration.node(before, before + node.nodeSize, {
10136
+ class: "crepe-placeholder",
10137
+ "data-placeholder": placeholderText
10138
+ });
10139
+ }
10140
+ const placeholderConfig = $ctx(
10141
+ {
10142
+ mode: "doc"
9742
10143
  },
9743
- setup(props) {
9744
- const { src, name, size, videoWidth } = props;
9745
- const isUploading = shallowRef(false);
9746
- const fileInput = shallowRef(null);
9747
- const videoWrapperRef = ref(null);
9748
- const currentWidth = ref(0);
9749
- const isResizing = ref(false);
9750
- const isVideo = computed(() => {
9751
- return name.value && /\.(mp4|webm|ogg|mov|avi|mkv|flv|wmv|m4v|3gp|ts)$/i.test(name.value);
9752
- });
9753
- let resizeDir = "";
9754
- let startX = 0;
9755
- let startWidth = 0;
9756
- const triggerUpload = () => {
9757
- var _a;
9758
- (_a = fileInput.value) == null ? void 0 : _a.click();
9759
- };
9760
- const onFileChange = async (e) => {
9761
- var _a;
9762
- const target = e.target;
9763
- const file = (_a = target.files) == null ? void 0 : _a[0];
9764
- if (!file) return;
9765
- isUploading.value = true;
9766
- try {
9767
- const result = await props.config.onUpload(file);
9768
- props.setAttr("src", result.url);
9769
- props.setAttr("name", result.name);
9770
- props.setAttr("size", result.size);
9771
- } catch (err) {
9772
- console.error("Failed to upload file", err);
9773
- } finally {
9774
- isUploading.value = false;
9775
- target.value = "";
9776
- }
9777
- };
9778
- const openLink = () => {
9779
- if (src.value) {
9780
- window.open(src.value, "_blank");
9781
- }
9782
- };
9783
- let activeHandle = null;
9784
- const onResizePointerMove = (e) => {
9785
- e.preventDefault();
9786
- const deltaX = e.clientX - startX;
9787
- let dw = 0;
9788
- if (resizeDir.includes("right")) {
9789
- dw = deltaX;
9790
- } else if (resizeDir.includes("left")) {
9791
- dw = -deltaX;
9792
- }
9793
- let newWidth = startWidth + dw;
9794
- if (newWidth < 200) newWidth = 200;
9795
- const wrapper = videoWrapperRef.value;
9796
- if (wrapper) {
9797
- const parent = wrapper.closest(".milkdown-attachment-block-wrapper");
9798
- if (parent) {
9799
- const maxWidth = parent.getBoundingClientRect().width;
9800
- if (newWidth > maxWidth) newWidth = maxWidth;
9801
- }
9802
- }
9803
- currentWidth.value = newWidth;
9804
- };
9805
- const onResizePointerUp = (e) => {
9806
- if (activeHandle) {
9807
- activeHandle.releasePointerCapture(e.pointerId);
9808
- activeHandle.removeEventListener(
9809
- "pointermove",
9810
- onResizePointerMove
9811
- );
9812
- activeHandle.removeEventListener(
9813
- "pointerup",
9814
- onResizePointerUp
9815
- );
9816
- activeHandle = null;
9817
- }
9818
- isResizing.value = false;
9819
- if (currentWidth.value > 0) {
9820
- props.setAttr("videoWidth", Math.round(currentWidth.value));
9821
- }
9822
- };
9823
- const onResizePointerDown = (e, dir) => {
9824
- if (props.readonly.value) return;
9825
- e.preventDefault();
9826
- e.stopPropagation();
9827
- resizeDir = dir;
9828
- startX = e.clientX;
9829
- isResizing.value = true;
9830
- const handle = e.currentTarget;
9831
- activeHandle = handle;
9832
- handle.setPointerCapture(e.pointerId);
9833
- const wrapper = videoWrapperRef.value;
9834
- if (wrapper) {
9835
- startWidth = wrapper.getBoundingClientRect().width;
9836
- currentWidth.value = startWidth;
9837
- }
9838
- handle.addEventListener("pointermove", onResizePointerMove);
9839
- handle.addEventListener("pointerup", onResizePointerUp);
9840
- };
9841
- return () => {
9842
- var _a;
9843
- if (!((_a = src.value) == null ? void 0 : _a.length)) {
9844
- return /* @__PURE__ */ h(
9845
- "div",
9846
- {
9847
- class: [
9848
- "milkdown-attachment-placeholder",
9849
- props.selected.value ? "selected" : ""
9850
- ]
9851
- },
9852
- /* @__PURE__ */ h("div", { class: "milkdown-attachment-uploader", onClick: triggerUpload }, /* @__PURE__ */ h(Icon, { icon: fileLinkIcon }), /* @__PURE__ */ h("span", { class: "milkdown-attachment-upload-text" }, isUploading.value ? "Uploading..." : props.config.uploadButton), /* @__PURE__ */ h(
9853
- "input",
9854
- {
9855
- type: "file",
9856
- ref: fileInput,
9857
- onChange: onFileChange,
9858
- style: "display: none;"
9859
- }
9860
- ))
9861
- );
9862
- }
9863
- if (isVideo.value) {
9864
- const savedWidth = videoWidth.value;
9865
- const widthStyle = isResizing.value && currentWidth.value > 0 ? `${currentWidth.value}px` : savedWidth && savedWidth > 0 ? `${savedWidth}px` : "100%";
9866
- return /* @__PURE__ */ h(
9867
- "div",
9868
- {
9869
- ref: videoWrapperRef,
9870
- class: [
9871
- "milkdown-attachment-video-viewer",
9872
- props.selected.value ? "selected" : ""
9873
- ],
9874
- style: {
9875
- width: widthStyle,
9876
- margin: "0 auto",
9877
- position: "relative"
9878
- }
9879
- },
9880
- /* @__PURE__ */ h(
9881
- "video",
9882
- {
9883
- src: src.value,
9884
- controls: true,
9885
- style: "width: 100%; display: block; border-radius: 8px;",
9886
- onMousedown: (e) => e.stopPropagation()
9887
- }
9888
- ),
9889
- /* @__PURE__ */ h(
9890
- "div",
9891
- {
9892
- class: "video-resize-handle top-left",
9893
- onPointerdown: (e) => onResizePointerDown(e, "top-left")
9894
- }
9895
- ),
9896
- /* @__PURE__ */ h(
9897
- "div",
9898
- {
9899
- class: "video-resize-handle top-right",
9900
- onPointerdown: (e) => onResizePointerDown(e, "top-right")
9901
- }
9902
- ),
9903
- /* @__PURE__ */ h(
9904
- "div",
9905
- {
9906
- class: "video-resize-handle bottom-left",
9907
- onPointerdown: (e) => onResizePointerDown(e, "bottom-left")
9908
- }
9909
- ),
9910
- /* @__PURE__ */ h(
9911
- "div",
9912
- {
9913
- class: "video-resize-handle bottom-right",
9914
- onPointerdown: (e) => onResizePointerDown(e, "bottom-right")
9915
- }
9916
- )
9917
- );
10144
+ "placeholderConfigCtx"
10145
+ );
10146
+ const placeholderPlugin = $prose((ctx) => {
10147
+ return new Plugin({
10148
+ key: new PluginKey("CREPE_PLACEHOLDER"),
10149
+ props: {
10150
+ decorations: (state) => {
10151
+ var _a;
10152
+ const crepe = useCrepe(ctx);
10153
+ if (crepe.readonly) return DecorationSet.empty;
10154
+ const config = ctx.get(placeholderConfig.key);
10155
+ if (config.mode === "doc" && !isDocEmpty(state.doc))
10156
+ return DecorationSet.empty;
10157
+ if (isInCodeBlock(state.selection) || isInList(state.selection))
10158
+ return DecorationSet.empty;
10159
+ const placeholderText = (_a = config.text) != null ? _a : i18n(ctx, "placeholder.text");
10160
+ const deco = createPlaceholderDecoration(state, placeholderText);
10161
+ if (!deco) return DecorationSet.empty;
10162
+ return DecorationSet.create(state.doc, [deco]);
9918
10163
  }
9919
- return /* @__PURE__ */ h(
9920
- "div",
9921
- {
9922
- class: [
9923
- "milkdown-attachment-viewer",
9924
- props.selected.value ? "selected" : ""
9925
- ]
9926
- },
9927
- /* @__PURE__ */ h("div", { class: "milkdown-attachment-icon-wrapper" }, /* @__PURE__ */ h("div", { class: "milkdown-attachment-raw-icon-bg" }, /* @__PURE__ */ h(Icon, { icon: fileLinkIcon }))),
9928
- /* @__PURE__ */ h("div", { class: "milkdown-attachment-info" }, /* @__PURE__ */ h("div", { class: "milkdown-attachment-name" }, name.value), /* @__PURE__ */ h("div", { class: "milkdown-attachment-size" }, (size.value || 0) > 0 ? formatBytes(size.value) : "")),
9929
- /* @__PURE__ */ h(
9930
- "div",
9931
- {
9932
- class: "milkdown-attachment-action",
9933
- onClick: openLink,
9934
- title: props.config.downloadText
9935
- },
9936
- /* @__PURE__ */ h(Icon, { icon: downloadIcon })
9937
- )
9938
- );
9939
- };
9940
- }
10164
+ }
10165
+ });
9941
10166
  });
9942
-
9943
- const attachmentView = $view(
9944
- attachmentSchema.node,
9945
- (ctx) => {
9946
- return (initialNode, view, getPos) => {
9947
- const src = ref(initialNode.attrs.src);
9948
- const name = ref(initialNode.attrs.name);
9949
- const size = ref(initialNode.attrs.size);
9950
- const videoWidth = ref(initialNode.attrs.videoWidth);
9951
- const selected = ref(false);
9952
- const readonly = ref(!view.editable);
9953
- const setAttr = (attr, value) => {
9954
- if (!view.editable) return;
9955
- const pos = getPos();
9956
- if (pos == null) return;
9957
- view.dispatch(view.state.tr.setNodeAttribute(pos, attr, value));
9958
- };
9959
- const config = ctx.get(attachmentConfig.key);
9960
- const app = createApp(MilkdownAttachmentBlock, {
9961
- src,
9962
- name,
9963
- size,
9964
- videoWidth,
9965
- selected,
9966
- readonly,
9967
- setAttr,
9968
- config
9969
- });
9970
- const dom = document.createElement("div");
9971
- dom.className = "milkdown-attachment-block-wrapper";
9972
- const disposeSelectedWatcher = watchEffect(() => {
9973
- if (selected.value) {
9974
- dom.classList.add("selected");
9975
- } else {
9976
- dom.classList.remove("selected");
9977
- }
10167
+ const placeholder = (editor, config) => {
10168
+ editor.config(crepeFeatureConfig(CrepeFeature.Placeholder)).config((ctx) => {
10169
+ if (config) {
10170
+ ctx.update(placeholderConfig.key, (prev) => {
10171
+ return {
10172
+ ...prev,
10173
+ ...config
10174
+ };
9978
10175
  });
9979
- const bindAttrs = (node) => {
9980
- src.value = node.attrs.src;
9981
- name.value = node.attrs.name;
9982
- size.value = node.attrs.size;
9983
- videoWidth.value = node.attrs.videoWidth;
9984
- readonly.value = !view.editable;
9985
- };
9986
- bindAttrs(initialNode);
9987
- app.mount(dom);
9988
- return {
9989
- dom,
9990
- update: (updatedNode) => {
9991
- if (updatedNode.type !== initialNode.type) return false;
9992
- bindAttrs(updatedNode);
9993
- return true;
9994
- },
9995
- selectNode: () => {
9996
- selected.value = true;
9997
- },
9998
- deselectNode: () => {
9999
- selected.value = false;
10000
- },
10001
- destroy: () => {
10002
- disposeSelectedWatcher();
10003
- app.unmount();
10004
- dom.remove();
10176
+ }
10177
+ }).use(placeholderPlugin).use(placeholderConfig);
10178
+ };
10179
+
10180
+ const table = (editor, config) => {
10181
+ editor.config(crepeFeatureConfig(CrepeFeature.Table)).config((ctx) => {
10182
+ ctx.update(tableBlockConfig.key, (defaultConfig) => ({
10183
+ ...defaultConfig,
10184
+ renderButton: (renderType) => {
10185
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
10186
+ switch (renderType) {
10187
+ case "add_row":
10188
+ return (_a = config == null ? void 0 : config.addRowIcon) != null ? _a : plusIcon;
10189
+ case "add_col":
10190
+ return (_b = config == null ? void 0 : config.addColIcon) != null ? _b : plusIcon;
10191
+ case "delete_row":
10192
+ return (_c = config == null ? void 0 : config.deleteRowIcon) != null ? _c : removeIcon;
10193
+ case "delete_col":
10194
+ return (_d = config == null ? void 0 : config.deleteColIcon) != null ? _d : removeIcon;
10195
+ case "align_col_left":
10196
+ return (_e = config == null ? void 0 : config.alignLeftIcon) != null ? _e : alignLeftIcon;
10197
+ case "align_col_center":
10198
+ return (_f = config == null ? void 0 : config.alignCenterIcon) != null ? _f : alignCenterIcon;
10199
+ case "align_col_right":
10200
+ return (_g = config == null ? void 0 : config.alignRightIcon) != null ? _g : alignRightIcon;
10201
+ case "col_drag_handle":
10202
+ return (_h = config == null ? void 0 : config.colDragHandleIcon) != null ? _h : dragHandleIcon;
10203
+ case "row_drag_handle":
10204
+ return (_i = config == null ? void 0 : config.rowDragHandleIcon) != null ? _i : dragHandleIcon;
10205
+ case "merge_cells":
10206
+ return (_j = config == null ? void 0 : config.mergeCellsIcon) != null ? _j : mergeCellIcon;
10207
+ case "split_cell":
10208
+ return (_k = config == null ? void 0 : config.splitCellIcon) != null ? _k : splitCellIcon;
10005
10209
  }
10006
- };
10210
+ }
10211
+ }));
10212
+ }).use(tableBlock);
10213
+ };
10214
+
10215
+ var __typeError$1 = (msg) => {
10216
+ throw TypeError(msg);
10217
+ };
10218
+ var __accessCheck$1 = (obj, member, msg) => member.has(obj) || __typeError$1("Cannot " + msg);
10219
+ var __privateGet$1 = (obj, member, getter) => (__accessCheck$1(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
10220
+ var __privateAdd$1 = (obj, member, value) => member.has(obj) ? __typeError$1("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
10221
+ var __privateSet$1 = (obj, member, value, setter) => (__accessCheck$1(obj, member, "write to private field"), member.set(obj, value), value);
10222
+ var _tooltipProvider, _content, _app, _selection, _show, _mousePressed;
10223
+ const toolbarTooltip = tooltipFactory("CREPE_TOOLBAR");
10224
+ class ToolbarView {
10225
+ constructor(ctx, view, config) {
10226
+ __privateAdd$1(this, _tooltipProvider);
10227
+ __privateAdd$1(this, _content);
10228
+ __privateAdd$1(this, _app);
10229
+ __privateAdd$1(this, _selection);
10230
+ __privateAdd$1(this, _show, ref(false));
10231
+ __privateAdd$1(this, _mousePressed, false);
10232
+ this.update = (view, prevState) => {
10233
+ __privateGet$1(this, _tooltipProvider).update(view, prevState);
10234
+ __privateGet$1(this, _selection).value = view.state.selection;
10235
+ };
10236
+ this.destroy = () => {
10237
+ __privateGet$1(this, _tooltipProvider).destroy();
10238
+ __privateGet$1(this, _app).unmount();
10239
+ __privateGet$1(this, _content).remove();
10240
+ };
10241
+ this.hide = () => {
10242
+ __privateGet$1(this, _tooltipProvider).hide();
10243
+ };
10244
+ const content = document.createElement("div");
10245
+ content.className = "milkdown-toolbar";
10246
+ __privateSet$1(this, _selection, shallowRef(view.state.selection));
10247
+ const app = createApp(Toolbar, {
10248
+ ctx,
10249
+ hide: this.hide,
10250
+ config,
10251
+ selection: __privateGet$1(this, _selection),
10252
+ show: __privateGet$1(this, _show)
10253
+ });
10254
+ app.mount(content);
10255
+ __privateSet$1(this, _content, content);
10256
+ __privateSet$1(this, _app, app);
10257
+ view.dom.addEventListener("mousedown", () => {
10258
+ __privateSet$1(this, _mousePressed, true);
10259
+ });
10260
+ view.dom.addEventListener("mouseup", () => {
10261
+ __privateSet$1(this, _mousePressed, false);
10262
+ setTimeout(() => {
10263
+ this.update(view);
10264
+ }, 0);
10265
+ });
10266
+ __privateSet$1(this, _tooltipProvider, new TooltipProvider({
10267
+ content: __privateGet$1(this, _content),
10268
+ debounce: 20,
10269
+ offset: 10,
10270
+ shouldShow: (view2) => {
10271
+ if (__privateGet$1(this, _mousePressed)) return false;
10272
+ const { doc, selection } = view2.state;
10273
+ const { empty, from, to } = selection;
10274
+ const isEmptyTextBlock = !doc.textBetween(from, to).length && selection instanceof TextSelection;
10275
+ const isNotTextBlock = !(selection instanceof TextSelection) && !(selection instanceof AllSelection);
10276
+ const activeElement = view2.dom.getRootNode().activeElement;
10277
+ const isTooltipChildren = content.contains(activeElement);
10278
+ const notHasFocus = !view2.hasFocus() && !isTooltipChildren;
10279
+ const isReadonly = !view2.editable;
10280
+ if (notHasFocus || isNotTextBlock || empty || isEmptyTextBlock || isReadonly)
10281
+ return false;
10282
+ return true;
10283
+ }
10284
+ }));
10285
+ __privateGet$1(this, _tooltipProvider).onShow = () => {
10286
+ __privateGet$1(this, _show).value = true;
10007
10287
  };
10288
+ __privateGet$1(this, _tooltipProvider).onHide = () => {
10289
+ __privateGet$1(this, _show).value = false;
10290
+ };
10291
+ this.update(view);
10008
10292
  }
10009
- );
10010
-
10011
- const attachment = (editor, config) => {
10012
- editor.config(crepeFeatureConfig(CrepeFeature.Attachment)).config((ctx) => {
10013
- ctx.update(attachmentConfig.key, (value) => {
10014
- var _a, _b, _c, _d;
10293
+ }
10294
+ _tooltipProvider = new WeakMap();
10295
+ _content = new WeakMap();
10296
+ _app = new WeakMap();
10297
+ _selection = new WeakMap();
10298
+ _show = new WeakMap();
10299
+ _mousePressed = new WeakMap();
10300
+ const toolbar = (editor, config) => {
10301
+ editor.config(crepeFeatureConfig(CrepeFeature.Toolbar)).config((ctx) => {
10302
+ ctx.set(toolbarTooltip.key, {
10303
+ view: (view) => new ToolbarView(ctx, view, config)
10304
+ });
10305
+ }).config((ctx) => {
10306
+ ctx.update(editorViewOptionsCtx, (prev) => {
10307
+ const prevTransform = prev.transformPastedHTML;
10015
10308
  return {
10016
- uploadButton: (_a = config == null ? void 0 : config.uploadButton) != null ? _a : i18n(ctx, "attachmentBlock.uploadButton"),
10017
- uploadPlaceholderText: (_b = config == null ? void 0 : config.uploadPlaceholderText) != null ? _b : i18n(ctx, "attachmentBlock.uploadPlaceholderText"),
10018
- downloadText: (_c = config == null ? void 0 : config.downloadText) != null ? _c : i18n(ctx, "attachmentBlock.download"),
10019
- onUpload: (_d = config == null ? void 0 : config.onUpload) != null ? _d : value.onUpload
10309
+ ...prev,
10310
+ transformPastedHTML: (html, view) => {
10311
+ if (prevTransform) html = prevTransform(html, view);
10312
+ return stripFontFamilyFromExternalHTML(html);
10313
+ }
10020
10314
  };
10021
10315
  });
10022
- }).use(attachmentConfig).use(attachmentSchema).use(attachmentView);
10316
+ }).use(underline).use(highlightMark).use(colorPlugins).use(fontPlugins).use(toolbarTooltip);
10023
10317
  };
10024
10318
 
10025
10319
  function loadFeature(feature, editor, config) {