@milkdown/crepe 7.19.2 → 7.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (209) hide show
  1. package/lib/cjs/builder.js +44 -1
  2. package/lib/cjs/builder.js.map +1 -1
  3. package/lib/cjs/feature/ai/index.js +1492 -0
  4. package/lib/cjs/feature/ai/index.js.map +1 -0
  5. package/lib/cjs/feature/block-edit/index.js +9 -2
  6. package/lib/cjs/feature/block-edit/index.js.map +1 -1
  7. package/lib/cjs/feature/code-mirror/index.js +2 -0
  8. package/lib/cjs/feature/code-mirror/index.js.map +1 -1
  9. package/lib/cjs/feature/cursor/index.js +2 -0
  10. package/lib/cjs/feature/cursor/index.js.map +1 -1
  11. package/lib/cjs/feature/image-block/index.js +5 -1
  12. package/lib/cjs/feature/image-block/index.js.map +1 -1
  13. package/lib/cjs/feature/latex/index.js +7 -0
  14. package/lib/cjs/feature/latex/index.js.map +1 -1
  15. package/lib/cjs/feature/link-tooltip/index.js +2 -0
  16. package/lib/cjs/feature/link-tooltip/index.js.map +1 -1
  17. package/lib/cjs/feature/list-item/index.js +2 -0
  18. package/lib/cjs/feature/list-item/index.js.map +1 -1
  19. package/lib/cjs/feature/placeholder/index.js +2 -0
  20. package/lib/cjs/feature/placeholder/index.js.map +1 -1
  21. package/lib/cjs/feature/table/index.js +2 -0
  22. package/lib/cjs/feature/table/index.js.map +1 -1
  23. package/lib/cjs/feature/toolbar/index.js +497 -5
  24. package/lib/cjs/feature/toolbar/index.js.map +1 -1
  25. package/lib/cjs/feature/top-bar/index.js +791 -0
  26. package/lib/cjs/feature/top-bar/index.js.map +1 -0
  27. package/lib/cjs/index.js +2047 -160
  28. package/lib/cjs/index.js.map +1 -1
  29. package/lib/cjs/llm-providers/anthropic/index.js +147 -0
  30. package/lib/cjs/llm-providers/anthropic/index.js.map +1 -0
  31. package/lib/cjs/llm-providers/openai/index.js +138 -0
  32. package/lib/cjs/llm-providers/openai/index.js.map +1 -0
  33. package/lib/esm/builder.js +44 -1
  34. package/lib/esm/builder.js.map +1 -1
  35. package/lib/esm/feature/ai/index.js +1487 -0
  36. package/lib/esm/feature/ai/index.js.map +1 -0
  37. package/lib/esm/feature/block-edit/index.js +9 -2
  38. package/lib/esm/feature/block-edit/index.js.map +1 -1
  39. package/lib/esm/feature/code-mirror/index.js +2 -0
  40. package/lib/esm/feature/code-mirror/index.js.map +1 -1
  41. package/lib/esm/feature/cursor/index.js +2 -0
  42. package/lib/esm/feature/cursor/index.js.map +1 -1
  43. package/lib/esm/feature/image-block/index.js +5 -1
  44. package/lib/esm/feature/image-block/index.js.map +1 -1
  45. package/lib/esm/feature/latex/index.js +7 -0
  46. package/lib/esm/feature/latex/index.js.map +1 -1
  47. package/lib/esm/feature/link-tooltip/index.js +2 -0
  48. package/lib/esm/feature/link-tooltip/index.js.map +1 -1
  49. package/lib/esm/feature/list-item/index.js +2 -0
  50. package/lib/esm/feature/list-item/index.js.map +1 -1
  51. package/lib/esm/feature/placeholder/index.js +2 -0
  52. package/lib/esm/feature/placeholder/index.js.map +1 -1
  53. package/lib/esm/feature/table/index.js +2 -0
  54. package/lib/esm/feature/table/index.js.map +1 -1
  55. package/lib/esm/feature/toolbar/index.js +499 -7
  56. package/lib/esm/feature/toolbar/index.js.map +1 -1
  57. package/lib/esm/feature/top-bar/index.js +789 -0
  58. package/lib/esm/feature/top-bar/index.js.map +1 -0
  59. package/lib/esm/index.js +2040 -153
  60. package/lib/esm/index.js.map +1 -1
  61. package/lib/esm/llm-providers/anthropic/index.js +145 -0
  62. package/lib/esm/llm-providers/anthropic/index.js.map +1 -0
  63. package/lib/esm/llm-providers/openai/index.js +136 -0
  64. package/lib/esm/llm-providers/openai/index.js.map +1 -0
  65. package/lib/theme/common/ai.css +446 -0
  66. package/lib/theme/common/code-mirror.css +14 -0
  67. package/lib/theme/common/diff.css +177 -0
  68. package/lib/theme/common/style.css +3 -0
  69. package/lib/theme/common/top-bar.css +152 -0
  70. package/lib/tsconfig.tsbuildinfo +1 -1
  71. package/lib/types/core/builder.d.ts +2 -1
  72. package/lib/types/core/builder.d.ts.map +1 -1
  73. package/lib/types/feature/ai/ai.spec.d.ts +2 -0
  74. package/lib/types/feature/ai/ai.spec.d.ts.map +1 -0
  75. package/lib/types/feature/ai/commands.d.ts +24 -0
  76. package/lib/types/feature/ai/commands.d.ts.map +1 -0
  77. package/lib/types/feature/ai/context.d.ts +4 -0
  78. package/lib/types/feature/ai/context.d.ts.map +1 -0
  79. package/lib/types/feature/ai/diff-actions/index.d.ts +12 -0
  80. package/lib/types/feature/ai/diff-actions/index.d.ts.map +1 -0
  81. package/lib/types/feature/ai/diff-actions/view.d.ts +21 -0
  82. package/lib/types/feature/ai/diff-actions/view.d.ts.map +1 -0
  83. package/lib/types/feature/ai/index.d.ts +7 -0
  84. package/lib/types/feature/ai/index.d.ts.map +1 -0
  85. package/lib/types/feature/ai/instruction-tooltip/component.d.ts +26 -0
  86. package/lib/types/feature/ai/instruction-tooltip/component.d.ts.map +1 -0
  87. package/lib/types/feature/ai/instruction-tooltip/index.d.ts +17 -0
  88. package/lib/types/feature/ai/instruction-tooltip/index.d.ts.map +1 -0
  89. package/lib/types/feature/ai/instruction-tooltip/suggestions.d.ts +50 -0
  90. package/lib/types/feature/ai/instruction-tooltip/suggestions.d.ts.map +1 -0
  91. package/lib/types/feature/ai/instruction-tooltip/view.d.ts +19 -0
  92. package/lib/types/feature/ai/instruction-tooltip/view.d.ts.map +1 -0
  93. package/lib/types/feature/ai/streaming-indicator.d.ts +9 -0
  94. package/lib/types/feature/ai/streaming-indicator.d.ts.map +1 -0
  95. package/lib/types/feature/ai/types.d.ts +58 -0
  96. package/lib/types/feature/ai/types.d.ts.map +1 -0
  97. package/lib/types/feature/block-edit/handle/component.d.ts.map +1 -1
  98. package/lib/types/feature/block-edit/menu/component.d.ts.map +1 -1
  99. package/lib/types/feature/image-block/index.d.ts +2 -0
  100. package/lib/types/feature/image-block/index.d.ts.map +1 -1
  101. package/lib/types/feature/index.d.ts +7 -1
  102. package/lib/types/feature/index.d.ts.map +1 -1
  103. package/lib/types/feature/latex/inline-tooltip/component.d.ts.map +1 -1
  104. package/lib/types/feature/latex/inline-tooltip/inline-tooltip.spec.d.ts +2 -0
  105. package/lib/types/feature/latex/inline-tooltip/inline-tooltip.spec.d.ts.map +1 -0
  106. package/lib/types/feature/latex/inline-tooltip/view.d.ts.map +1 -1
  107. package/lib/types/feature/loader.d.ts.map +1 -1
  108. package/lib/types/feature/toolbar/component.d.ts.map +1 -1
  109. package/lib/types/feature/toolbar/config.d.ts +1 -1
  110. package/lib/types/feature/toolbar/config.d.ts.map +1 -1
  111. package/lib/types/feature/toolbar/index.d.ts +1 -0
  112. package/lib/types/feature/toolbar/index.d.ts.map +1 -1
  113. package/lib/types/feature/top-bar/component.d.ts +11 -0
  114. package/lib/types/feature/top-bar/component.d.ts.map +1 -0
  115. package/lib/types/feature/top-bar/config.d.ts +34 -0
  116. package/lib/types/feature/top-bar/config.d.ts.map +1 -0
  117. package/lib/types/feature/top-bar/index.d.ts +26 -0
  118. package/lib/types/feature/top-bar/index.d.ts.map +1 -0
  119. package/lib/types/icons/ai.d.ts +2 -0
  120. package/lib/types/icons/ai.d.ts.map +1 -0
  121. package/lib/types/icons/chevron-left.d.ts +2 -0
  122. package/lib/types/icons/chevron-left.d.ts.map +1 -0
  123. package/lib/types/icons/chevron-right.d.ts +2 -0
  124. package/lib/types/icons/chevron-right.d.ts.map +1 -0
  125. package/lib/types/icons/code-block.d.ts +2 -0
  126. package/lib/types/icons/code-block.d.ts.map +1 -0
  127. package/lib/types/icons/enter-key.d.ts +2 -0
  128. package/lib/types/icons/enter-key.d.ts.map +1 -0
  129. package/lib/types/icons/grammar-check.d.ts +2 -0
  130. package/lib/types/icons/grammar-check.d.ts.map +1 -0
  131. package/lib/types/icons/index.d.ts +12 -0
  132. package/lib/types/icons/index.d.ts.map +1 -1
  133. package/lib/types/icons/longer.d.ts +2 -0
  134. package/lib/types/icons/longer.d.ts.map +1 -0
  135. package/lib/types/icons/retry.d.ts +2 -0
  136. package/lib/types/icons/retry.d.ts.map +1 -0
  137. package/lib/types/icons/send-prompt.d.ts +2 -0
  138. package/lib/types/icons/send-prompt.d.ts.map +1 -0
  139. package/lib/types/icons/send.d.ts +2 -0
  140. package/lib/types/icons/send.d.ts.map +1 -0
  141. package/lib/types/icons/shorter.d.ts +2 -0
  142. package/lib/types/icons/shorter.d.ts.map +1 -0
  143. package/lib/types/icons/translate.d.ts +2 -0
  144. package/lib/types/icons/translate.d.ts.map +1 -0
  145. package/lib/types/llm-providers/anthropic/index.d.ts +21 -0
  146. package/lib/types/llm-providers/anthropic/index.d.ts.map +1 -0
  147. package/lib/types/llm-providers/openai/index.d.ts +15 -0
  148. package/lib/types/llm-providers/openai/index.d.ts.map +1 -0
  149. package/lib/types/llm-providers/providers.spec.d.ts +2 -0
  150. package/lib/types/llm-providers/providers.spec.d.ts.map +1 -0
  151. package/lib/types/llm-providers/shared.d.ts +16 -0
  152. package/lib/types/llm-providers/shared.d.ts.map +1 -0
  153. package/lib/types/utils/group-builder.d.ts +1 -1
  154. package/lib/types/utils/group-builder.d.ts.map +1 -1
  155. package/lib/types/utils/keep-alive.d.ts +2 -0
  156. package/lib/types/utils/keep-alive.d.ts.map +1 -0
  157. package/package.json +34 -13
  158. package/src/core/builder.ts +39 -2
  159. package/src/feature/ai/ai.spec.ts +742 -0
  160. package/src/feature/ai/commands.ts +257 -0
  161. package/src/feature/ai/context.ts +45 -0
  162. package/src/feature/ai/diff-actions/index.ts +95 -0
  163. package/src/feature/ai/diff-actions/view.ts +237 -0
  164. package/src/feature/ai/index.ts +118 -0
  165. package/src/feature/ai/instruction-tooltip/component.tsx +414 -0
  166. package/src/feature/ai/instruction-tooltip/index.ts +101 -0
  167. package/src/feature/ai/instruction-tooltip/suggestions.ts +249 -0
  168. package/src/feature/ai/instruction-tooltip/view.ts +159 -0
  169. package/src/feature/ai/streaming-indicator.ts +183 -0
  170. package/src/feature/ai/types.ts +178 -0
  171. package/src/feature/block-edit/handle/component.tsx +3 -2
  172. package/src/feature/block-edit/menu/component.tsx +3 -2
  173. package/src/feature/block-edit/menu/config.ts +1 -1
  174. package/src/feature/image-block/index.ts +4 -0
  175. package/src/feature/index.ts +14 -2
  176. package/src/feature/latex/inline-tooltip/component.tsx +4 -2
  177. package/src/feature/latex/inline-tooltip/inline-tooltip.spec.ts +81 -0
  178. package/src/feature/latex/inline-tooltip/view.ts +2 -0
  179. package/src/feature/loader.ts +8 -0
  180. package/src/feature/toolbar/component.tsx +7 -5
  181. package/src/feature/toolbar/config.ts +27 -1
  182. package/src/feature/toolbar/index.ts +1 -0
  183. package/src/feature/top-bar/component.tsx +198 -0
  184. package/src/feature/top-bar/config.ts +367 -0
  185. package/src/feature/top-bar/index.ts +113 -0
  186. package/src/icons/ai.ts +14 -0
  187. package/src/icons/chevron-left.ts +15 -0
  188. package/src/icons/chevron-right.ts +15 -0
  189. package/src/icons/code-block.ts +12 -0
  190. package/src/icons/enter-key.ts +13 -0
  191. package/src/icons/grammar-check.ts +13 -0
  192. package/src/icons/index.ts +12 -0
  193. package/src/icons/longer.ts +13 -0
  194. package/src/icons/retry.ts +13 -0
  195. package/src/icons/send-prompt.ts +13 -0
  196. package/src/icons/send.ts +13 -0
  197. package/src/icons/shorter.ts +13 -0
  198. package/src/icons/translate.ts +13 -0
  199. package/src/llm-providers/anthropic/index.ts +132 -0
  200. package/src/llm-providers/openai/index.ts +109 -0
  201. package/src/llm-providers/providers.spec.ts +472 -0
  202. package/src/llm-providers/shared.ts +160 -0
  203. package/src/theme/common/ai.css +430 -0
  204. package/src/theme/common/code-mirror.css +14 -0
  205. package/src/theme/common/diff.css +196 -0
  206. package/src/theme/common/style.css +3 -0
  207. package/src/theme/common/top-bar.css +156 -0
  208. package/src/utils/group-builder.ts +1 -1
  209. package/src/utils/keep-alive.ts +3 -0
package/lib/esm/index.js CHANGED
@@ -1,16 +1,23 @@
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 '@milkdown/kit/plugin/block';
4
+ import { diffComponentConfig, diffComponent } from '@milkdown/kit/component/diff';
5
+ import { diffPluginKey, clearDiffReviewCmd, acceptAllDiffsCmd, diffConfig, diff } from '@milkdown/kit/plugin/diff';
6
+ import { streamingPluginKey, startStreamingCmd, abortStreamingCmd, pushChunkCmd, endStreamingCmd, streamingConfig, streaming } from '@milkdown/kit/plugin/streaming';
5
7
  import { createSlice } from '@milkdown/kit/ctx';
6
- import { commandsCtx, editorViewCtx, editorCtx, EditorStatus, Editor, rootCtx, defaultValueCtx, editorViewOptionsCtx } from '@milkdown/kit/core';
8
+ import { editorViewCtx, serializerCtx, commandsCtx, editorCtx, EditorStatus, Editor, rootCtx, defaultValueCtx, editorViewOptionsCtx } from '@milkdown/kit/core';
9
+ import { aiBuildContextError, aiProviderError } from '@milkdown/kit/exception';
10
+ import { $ctx, $command, $prose, $nodeSchema, $inputRule, $remark, getMarkdown } from '@milkdown/kit/utils';
11
+ import { TextSelection, PluginKey, Plugin, NodeSelection, EditorState } from '@milkdown/kit/prose/state';
12
+ import DOMPurify from 'dompurify';
13
+ import { TooltipProvider, tooltipFactory } from '@milkdown/kit/plugin/tooltip';
14
+ import { posToDOMRect, findParent, findNodeInSelection, nodeRule } from '@milkdown/kit/prose';
15
+ import { defineComponent, ref, watch, computed, h, nextTick, createApp, watchEffect, onUnmounted, Fragment, shallowRef, onMounted } from 'vue';
16
+ import { Icon } from '@milkdown/kit/component';
17
+ import { DecorationSet, Decoration, EditorView } from '@milkdown/kit/prose/view';
18
+ import { blockConfig, block, BlockProvider } from '@milkdown/kit/plugin/block';
7
19
  import { paragraphSchema, clearTextInCurrentBlockCommand, setBlockTypeCommand, headingSchema, blockquoteSchema, wrapInBlockTypeCommand, hrSchema, addBlockTypeCommand, bulletListSchema, orderedListSchema, listItemSchema, codeBlockSchema, selectTextNearPosCommand, toggleStrongCommand, isMarkSelectedCommand, strongSchema, toggleEmphasisCommand, emphasisSchema, toggleInlineCodeCommand, inlineCodeSchema, isNodeSelectedCommand, linkSchema, commonmark } from '@milkdown/kit/preset/commonmark';
8
- import { findParent, findNodeInSelection, nodeRule } from '@milkdown/kit/prose';
9
- import { TextSelection, NodeSelection, EditorState, Plugin, PluginKey } from '@milkdown/kit/prose/state';
10
- import { defineComponent, ref, computed, watch, watchEffect, onUnmounted, h, createApp, Fragment, shallowRef } from 'vue';
11
20
  import { slashFactory, SlashProvider } from '@milkdown/kit/plugin/slash';
12
- import { $ctx, $prose, $nodeSchema, $command, $inputRule, $remark, getMarkdown } from '@milkdown/kit/utils';
13
- import { Icon } from '@milkdown/kit/component';
14
21
  import { imageBlockSchema, imageBlockConfig, imageBlockComponent } from '@milkdown/kit/component/image-block';
15
22
  import { createTable, toggleStrikethroughCommand, strikethroughSchema, gfm } from '@milkdown/kit/preset/gfm';
16
23
  import { defaultKeymap, indentWithTab } from '@codemirror/commands';
@@ -21,11 +28,9 @@ import { dropIndicatorConfig, cursor as cursor$1 } from '@milkdown/kit/plugin/cu
21
28
  import { createVirtualCursor } from 'prosemirror-virtual-cursor';
22
29
  import { inlineImageConfig, imageInlineComponent } from '@milkdown/kit/component/image-inline';
23
30
  import katex from 'katex';
24
- import { tooltipFactory, TooltipProvider } from '@milkdown/kit/plugin/tooltip';
25
31
  import { redo, undo } from '@milkdown/kit/prose/history';
26
32
  import { keymap as keymap$1 } from '@milkdown/kit/prose/keymap';
27
33
  import { Schema } from '@milkdown/kit/prose/model';
28
- import { EditorView, DecorationSet, Decoration } from '@milkdown/kit/prose/view';
29
34
  import { textblockTypeInputRule } from '@milkdown/kit/prose/inputrules';
30
35
  import remarkMath from 'remark-math';
31
36
  import { visit } from 'unist-util-visit';
@@ -38,6 +43,7 @@ import { history } from '@milkdown/kit/plugin/history';
38
43
  import { indentConfig, indent } from '@milkdown/kit/plugin/indent';
39
44
  import { listenerCtx, listener } from '@milkdown/kit/plugin/listener';
40
45
  import { trailing } from '@milkdown/kit/plugin/trailing';
46
+ import { uploadConfig, upload } from '@milkdown/kit/plugin/upload';
41
47
 
42
48
  var CrepeFeature = /* @__PURE__ */ ((CrepeFeature2) => {
43
49
  CrepeFeature2["CodeMirror"] = "code-mirror";
@@ -50,6 +56,8 @@ var CrepeFeature = /* @__PURE__ */ ((CrepeFeature2) => {
50
56
  CrepeFeature2["Placeholder"] = "placeholder";
51
57
  CrepeFeature2["Table"] = "table";
52
58
  CrepeFeature2["Latex"] = "latex";
59
+ CrepeFeature2["TopBar"] = "top-bar";
60
+ CrepeFeature2["AI"] = "ai";
53
61
  return CrepeFeature2;
54
62
  })(CrepeFeature || {});
55
63
  const defaultFeatures = {
@@ -62,9 +70,26 @@ const defaultFeatures = {
62
70
  ["toolbar" /* Toolbar */]: true,
63
71
  ["code-mirror" /* CodeMirror */]: true,
64
72
  ["table" /* Table */]: true,
65
- ["latex" /* Latex */]: true
73
+ ["latex" /* Latex */]: true,
74
+ ["top-bar" /* TopBar */]: false,
75
+ ["ai" /* AI */]: false
66
76
  };
67
77
 
78
+ const aiIcon = `
79
+ <svg
80
+ xmlns="http://www.w3.org/2000/svg"
81
+ width="24"
82
+ height="24"
83
+ viewBox="0 0 24 24"
84
+ >
85
+ <path
86
+ fill="currentColor"
87
+ d="M19 9l1.25-2.75L23 5l-2.75-1.25L19 1l-1.25 2.75L15 5l2.75 1.25zm0 14l1.25-2.75L23 19l-2.75-1.25L19 15l-1.25 2.75L15 19l2.75 1.25zM9 20l3-6.5L18 10l-6-3.5L9 0L6 6.5L0 10l6 3.5z"
88
+ transform="translate(3 3) scale(0.75)"
89
+ />
90
+ </svg>
91
+ `;
92
+
68
93
  const alignCenterIcon = `
69
94
  <svg
70
95
  xmlns="http://www.w3.org/2000/svg"
@@ -226,6 +251,38 @@ const chevronDownIcon = `
226
251
  </svg>
227
252
  `;
228
253
 
254
+ const chevronLeftIcon = `
255
+ <svg
256
+ xmlns="http://www.w3.org/2000/svg"
257
+ fill="none"
258
+ viewBox="0 0 24 24"
259
+ stroke-width="1.5"
260
+ stroke="currentColor"
261
+ >
262
+ <path
263
+ stroke-linecap="round"
264
+ stroke-linejoin="round"
265
+ d="M15.75 19.5L8.25 12l7.5-7.5"
266
+ />
267
+ </svg>
268
+ `;
269
+
270
+ const chevronRightIcon = `
271
+ <svg
272
+ xmlns="http://www.w3.org/2000/svg"
273
+ fill="none"
274
+ viewBox="0 0 24 24"
275
+ stroke-width="1.5"
276
+ stroke="currentColor"
277
+ >
278
+ <path
279
+ stroke-linecap="round"
280
+ stroke-linejoin="round"
281
+ d="M8.25 4.5l7.5 7.5-7.5 7.5"
282
+ />
283
+ </svg>
284
+ `;
285
+
229
286
  const clearIcon = `
230
287
  <svg
231
288
  xmlns="http://www.w3.org/2000/svg"
@@ -266,6 +323,19 @@ const codeIcon = `
266
323
  </svg>
267
324
  `;
268
325
 
326
+ const codeBlockIcon = `
327
+ <svg
328
+ xmlns="http://www.w3.org/2000/svg"
329
+ width="24"
330
+ height="24"
331
+ viewBox="0 0 24 24"
332
+ >
333
+ <path
334
+ d="M3 3h18a1 1 0 0 1 1 1v16a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1zm1 2v14h16V5H4zm8 10h6v2h-6v-2zm-3.333-3L5.838 9.172l1.415-1.415L11.495 12l-4.242 4.243-1.415-1.415L8.667 12z"
335
+ />
336
+ </svg>
337
+ `;
338
+
269
339
  const confirmIcon = `
270
340
  <svg
271
341
  xmlns="http://www.w3.org/2000/svg"
@@ -357,6 +427,34 @@ const editIcon = `
357
427
  </svg>
358
428
  `;
359
429
 
430
+ const enterKeyIcon = `
431
+ <svg
432
+ xmlns="http://www.w3.org/2000/svg"
433
+ width="24"
434
+ height="24"
435
+ viewBox="0 0 24 24"
436
+ >
437
+ <path
438
+ fill="currentColor"
439
+ d="M9 16l-5-5l5-5l1.4 1.4L7.825 10H18V6h2v6H7.825l2.575 2.6z"
440
+ />
441
+ </svg>
442
+ `;
443
+
444
+ const grammarCheckIcon = `
445
+ <svg
446
+ xmlns="http://www.w3.org/2000/svg"
447
+ width="24"
448
+ height="24"
449
+ viewBox="0 0 24 24"
450
+ >
451
+ <path
452
+ fill="currentColor"
453
+ d="M9.55 17.575L4.225 12.25l1.4-1.425L9.55 14.75l8.825-8.825l1.4 1.425z"
454
+ />
455
+ </svg>
456
+ `;
457
+
360
458
  const h1Icon = `
361
459
  <svg
362
460
  xmlns="http://www.w3.org/2000/svg"
@@ -523,6 +621,20 @@ const linkIcon = `
523
621
  </svg>
524
622
  `;
525
623
 
624
+ const longerIcon = `
625
+ <svg
626
+ xmlns="http://www.w3.org/2000/svg"
627
+ width="24"
628
+ height="24"
629
+ viewBox="0 0 24 24"
630
+ >
631
+ <path
632
+ fill="currentColor"
633
+ d="M3 18v-2h13v2zm0-5v-2h18v2zm0-5V6h18v2zm15 13v-3h-3v-2h3v-3h2v3h3v2h-3v3z"
634
+ />
635
+ </svg>
636
+ `;
637
+
526
638
  const menuIcon = `
527
639
  <svg
528
640
  xmlns="http://www.w3.org/2000/svg"
@@ -616,6 +728,20 @@ const removeIcon = `
616
728
  </svg>
617
729
  `;
618
730
 
731
+ const retryIcon = `
732
+ <svg
733
+ xmlns="http://www.w3.org/2000/svg"
734
+ width="24"
735
+ height="24"
736
+ viewBox="0 0 24 24"
737
+ >
738
+ <path
739
+ fill="currentColor"
740
+ d="M12 20q-3.35 0-5.675-2.325T4 12q0-3.35 2.325-5.675T12 4q1.725 0 3.3.713T18 6.75V4h2v7h-7V9h4.2q-.8-1.4-2.187-2.2T12 6Q9.5 6 7.75 7.75T6 12q0 2.5 1.75 4.25T12 18q1.925 0 3.475-1.1T17.65 14h2.1q-.7 2.65-2.85 4.325T12 20"
741
+ />
742
+ </svg>
743
+ `;
744
+
619
745
  const searchIcon = `
620
746
  <svg
621
747
  xmlns="http://www.w3.org/2000/svg"
@@ -633,6 +759,48 @@ const searchIcon = `
633
759
  </svg>
634
760
  `;
635
761
 
762
+ const sendIcon = `
763
+ <svg
764
+ xmlns="http://www.w3.org/2000/svg"
765
+ width="24"
766
+ height="24"
767
+ viewBox="0 0 24 24"
768
+ >
769
+ <path
770
+ fill="currentColor"
771
+ d="M11 20V7.825l-5.6 5.6L4 12l8-8l8 8l-1.4 1.425l-5.6-5.6V20z"
772
+ />
773
+ </svg>
774
+ `;
775
+
776
+ const sendPromptIcon = `
777
+ <svg
778
+ xmlns="http://www.w3.org/2000/svg"
779
+ width="24"
780
+ height="24"
781
+ viewBox="0 0 24 24"
782
+ >
783
+ <path
784
+ fill="currentColor"
785
+ d="M3 20v-6l8-2l-8-2V4l19 8z"
786
+ />
787
+ </svg>
788
+ `;
789
+
790
+ const shorterIcon = `
791
+ <svg
792
+ xmlns="http://www.w3.org/2000/svg"
793
+ width="24"
794
+ height="24"
795
+ viewBox="0 0 24 24"
796
+ >
797
+ <path
798
+ fill="currentColor"
799
+ d="M5 13v-2h14v2z"
800
+ />
801
+ </svg>
802
+ `;
803
+
636
804
  const strikethroughIcon = `
637
805
  <svg
638
806
  xmlns="http://www.w3.org/2000/svg"
@@ -699,6 +867,20 @@ const todoListIcon = `
699
867
  </svg>
700
868
  `;
701
869
 
870
+ const translateIcon = `
871
+ <svg
872
+ xmlns="http://www.w3.org/2000/svg"
873
+ width="24"
874
+ height="24"
875
+ viewBox="0 0 24 24"
876
+ >
877
+ <path
878
+ fill="currentColor"
879
+ d="m12.9 16l-2.55-2.5l.05-.05q1.45-1.6 2.262-3.117T13.95 7H16V5h-6V3H8v2H2v2h9.1q-.5 1.2-1.225 2.387T8 11.7q-.6-.6-1.187-1.412T5.85 8.6H3.85q.5 1.4 1.3 2.7T6.95 13.7L2.85 17.75L4.25 19.15L8 15.4L10.55 17.95zM18.5 22h-2L21 10h2l4.5 12h-2l-1.05-3h-4.9zm1.6-5h3.6l-1.8-5.1z"
880
+ />
881
+ </svg>
882
+ `;
883
+
702
884
  const functionsIcon = `
703
885
  <svg
704
886
  xmlns="http://www.w3.org/2000/svg"
@@ -758,6 +940,1223 @@ function crepeFeatureConfig(feature) {
758
940
  };
759
941
  }
760
942
 
943
+ function defaultBuildContext(ctx, instruction) {
944
+ var _a;
945
+ const view = ctx.get(editorViewCtx);
946
+ const serializer = ctx.get(serializerCtx);
947
+ const { state } = view;
948
+ const document = serializer(state.doc);
949
+ let selection = "";
950
+ if (!state.selection.empty) {
951
+ const { from, to } = state.selection;
952
+ const slice = state.doc.slice(from, to);
953
+ const { schema } = state.doc.type;
954
+ let wrapper = schema.topNodeType.createAndFill(null, slice.content);
955
+ if (!wrapper) {
956
+ const paragraph = (_a = schema.nodes.paragraph) == null ? void 0 : _a.createAndFill(
957
+ null,
958
+ slice.content
959
+ );
960
+ if (paragraph) wrapper = schema.topNodeType.createAndFill(null, paragraph);
961
+ }
962
+ selection = wrapper ? serializer(wrapper) : state.doc.textBetween(from, to);
963
+ }
964
+ return { document, selection, instruction };
965
+ }
966
+
967
+ const aiProviderConfig = $ctx(
968
+ {
969
+ provider: void 0,
970
+ buildContext: void 0,
971
+ diffReviewOnEnd: true,
972
+ onError: (error) => {
973
+ console.error(`[milkdown/ai] [${error.code}]`, error);
974
+ },
975
+ aiIcon: void 0
976
+ },
977
+ "aiProviderConfig"
978
+ );
979
+ const aiSessionCtx = $ctx(
980
+ {
981
+ abortController: null,
982
+ label: "",
983
+ lastInstruction: "",
984
+ lastLabel: void 0,
985
+ lastFrom: -1,
986
+ lastTo: -1,
987
+ diffOwnedByAI: false
988
+ },
989
+ "aiSession"
990
+ );
991
+ function emitAIError(ctx, error) {
992
+ const config = ctx.get(aiProviderConfig.key);
993
+ try {
994
+ config.onError(error);
995
+ } catch (handlerError) {
996
+ console.error("[milkdown/ai] onError handler failed:", handlerError);
997
+ }
998
+ }
999
+ function clearActiveSession(ctx) {
1000
+ const current = ctx.get(aiSessionCtx.key);
1001
+ ctx.set(aiSessionCtx.key, {
1002
+ ...current,
1003
+ abortController: null,
1004
+ label: ""
1005
+ });
1006
+ }
1007
+ async function runProvider(ctx, provider, promptContext, abortController) {
1008
+ try {
1009
+ const iterable = provider(promptContext, abortController.signal);
1010
+ const commands = ctx.get(commandsCtx);
1011
+ for await (const chunk of iterable) {
1012
+ if (abortController.signal.aborted) break;
1013
+ commands.call(pushChunkCmd.key, chunk);
1014
+ }
1015
+ if (abortController.signal.aborted) return;
1016
+ const config = ctx.get(aiProviderConfig.key);
1017
+ if (config.diffReviewOnEnd) {
1018
+ const cur = ctx.get(aiSessionCtx.key);
1019
+ ctx.set(aiSessionCtx.key, { ...cur, diffOwnedByAI: true });
1020
+ }
1021
+ const dispatched = commands.call(endStreamingCmd.key, {
1022
+ diffReview: config.diffReviewOnEnd
1023
+ });
1024
+ if (config.diffReviewOnEnd && !dispatched) {
1025
+ const cur = ctx.get(aiSessionCtx.key);
1026
+ ctx.set(aiSessionCtx.key, { ...cur, diffOwnedByAI: false });
1027
+ }
1028
+ } catch (error) {
1029
+ if (abortController.signal.aborted) return;
1030
+ const milkdownError = aiProviderError(error);
1031
+ emitAIError(ctx, milkdownError);
1032
+ const commands = ctx.get(commandsCtx);
1033
+ commands.call(abortStreamingCmd.key, { keep: false });
1034
+ } finally {
1035
+ const current = ctx.get(aiSessionCtx.key);
1036
+ if (current.abortController === abortController) {
1037
+ clearActiveSession(ctx);
1038
+ }
1039
+ }
1040
+ }
1041
+ const runAICmd = $command("RunAI", (ctx) => {
1042
+ return (options) => (state, dispatch) => {
1043
+ var _a, _b, _c, _d;
1044
+ if (!(options == null ? void 0 : options.instruction)) return false;
1045
+ const config = ctx.get(aiProviderConfig.key);
1046
+ if (!config.provider) return false;
1047
+ const session = ctx.get(aiSessionCtx.key);
1048
+ if (session.abortController) return false;
1049
+ if ((_a = streamingPluginKey.getState(state)) == null ? void 0 : _a.active) return false;
1050
+ if ((_b = diffPluginKey.getState(state)) == null ? void 0 : _b.active) return false;
1051
+ if (!dispatch) return true;
1052
+ const abortController = new AbortController();
1053
+ const { from, to } = state.selection;
1054
+ ctx.set(aiSessionCtx.key, {
1055
+ abortController,
1056
+ label: (_c = options.label) != null ? _c : "",
1057
+ lastInstruction: options.instruction,
1058
+ lastLabel: options.label,
1059
+ lastFrom: from,
1060
+ lastTo: to,
1061
+ // Reset every run; only the success path that hands off to diff
1062
+ // review flips it back on.
1063
+ diffOwnedByAI: false
1064
+ });
1065
+ const commands = ctx.get(commandsCtx);
1066
+ const insertAt = state.selection.empty ? "cursor" : "selection";
1067
+ if (!commands.call(startStreamingCmd.key, { insertAt })) {
1068
+ clearActiveSession(ctx);
1069
+ return false;
1070
+ }
1071
+ let promptContext;
1072
+ try {
1073
+ const buildContext = (_d = config.buildContext) != null ? _d : defaultBuildContext;
1074
+ promptContext = buildContext(ctx, options.instruction);
1075
+ } catch (error) {
1076
+ const milkdownError = aiBuildContextError(error);
1077
+ emitAIError(ctx, milkdownError);
1078
+ commands.call(abortStreamingCmd.key, { keep: false });
1079
+ clearActiveSession(ctx);
1080
+ return false;
1081
+ }
1082
+ void runProvider(ctx, config.provider, promptContext, abortController);
1083
+ return true;
1084
+ };
1085
+ });
1086
+ const abortAICmd = $command("AbortAI", (ctx) => {
1087
+ return (options) => (state, dispatch) => {
1088
+ var _a;
1089
+ const session = ctx.get(aiSessionCtx.key);
1090
+ if (!dispatch) return !!session.abortController;
1091
+ if (!session.abortController) return false;
1092
+ session.abortController.abort();
1093
+ clearActiveSession(ctx);
1094
+ if ((_a = streamingPluginKey.getState(state)) == null ? void 0 : _a.active) {
1095
+ const commands = ctx.get(commandsCtx);
1096
+ commands.call(abortStreamingCmd.key, options);
1097
+ }
1098
+ return true;
1099
+ };
1100
+ });
1101
+
1102
+ var __typeError$a = (msg) => {
1103
+ throw TypeError(msg);
1104
+ };
1105
+ var __accessCheck$a = (obj, member, msg) => member.has(obj) || __typeError$a("Cannot " + msg);
1106
+ var __privateGet$a = (obj, member, getter) => (__accessCheck$a(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
1107
+ var __privateAdd$a = (obj, member, value) => member.has(obj) ? __typeError$a("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
1108
+ var __privateSet$a = (obj, member, value, setter) => (__accessCheck$a(obj, member, "write to private field"), member.set(obj, value), value);
1109
+ var __privateMethod = (obj, member, method) => (__accessCheck$a(obj, member, "access private method"), method);
1110
+ var _panel, _host, _retryBtn, _config, _visible, _diffActive, _diffStartDoc, _ownedByAI, _DiffActionsPanelView_instances, findHost_fn, makeButton_fn, makeShortcutChip_fn, _retry, canRetry_fn, _rejectAll, _acceptAll;
1111
+ const PANEL_CLASS = "milkdown-ai-diff-actions";
1112
+ function setSanitizedIcon(host, svg) {
1113
+ host.innerHTML = DOMPurify.sanitize(svg.trim());
1114
+ }
1115
+ function createIcon(svg) {
1116
+ const span = document.createElement("span");
1117
+ span.className = `${PANEL_CLASS}-icon`;
1118
+ setSanitizedIcon(span, svg);
1119
+ return span;
1120
+ }
1121
+ class DiffActionsPanelView {
1122
+ constructor(ctx, view, config) {
1123
+ this.ctx = ctx;
1124
+ __privateAdd$a(this, _DiffActionsPanelView_instances);
1125
+ __privateAdd$a(this, _panel);
1126
+ __privateAdd$a(this, _host);
1127
+ __privateAdd$a(this, _retryBtn);
1128
+ __privateAdd$a(this, _config);
1129
+ __privateAdd$a(this, _visible, false);
1130
+ /// Tracks the diff plugin's `active` flag across transactions so we
1131
+ /// can detect false→true / true→false edges independently of whether
1132
+ /// the panel is actually being shown.
1133
+ __privateAdd$a(this, _diffActive, false);
1134
+ /// Doc snapshot at the moment diff review activated. If the live doc
1135
+ /// drifts from this snapshot the user has accepted some per-change
1136
+ /// diffs and the stored `lastFrom`/`lastTo` no longer point at the
1137
+ /// original range — Retry is unsafe at that point.
1138
+ __privateAdd$a(this, _diffStartDoc, null);
1139
+ /// Whether the active diff review came from this AI session's
1140
+ /// streaming hand-off (vs being started manually via
1141
+ /// `startDiffReviewCmd`). Captured at the false→true transition.
1142
+ /// The panel only renders when this is true so it doesn't take over
1143
+ /// non-AI diff flows that exist independently of the AI feature.
1144
+ __privateAdd$a(this, _ownedByAI, false);
1145
+ __privateAdd$a(this, _retry, () => {
1146
+ const session = this.ctx.get(aiSessionCtx.key);
1147
+ if (!session.lastInstruction) return;
1148
+ if (!__privateGet$a(this, _ownedByAI) || !__privateMethod(this, _DiffActionsPanelView_instances, canRetry_fn).call(this)) return;
1149
+ const commands = this.ctx.get(commandsCtx);
1150
+ commands.call(clearDiffReviewCmd.key);
1151
+ const editorView = this.ctx.get(editorViewCtx);
1152
+ const { doc } = editorView.state;
1153
+ const from = Math.min(Math.max(session.lastFrom, 0), doc.content.size);
1154
+ const to = Math.min(Math.max(session.lastTo, 0), doc.content.size);
1155
+ editorView.dispatch(
1156
+ editorView.state.tr.setSelection(
1157
+ TextSelection.create(editorView.state.doc, from, to)
1158
+ )
1159
+ );
1160
+ commands.call(runAICmd.key, {
1161
+ instruction: session.lastInstruction,
1162
+ label: session.lastLabel
1163
+ });
1164
+ });
1165
+ __privateAdd$a(this, _rejectAll, () => {
1166
+ this.ctx.get(commandsCtx).call(clearDiffReviewCmd.key);
1167
+ });
1168
+ __privateAdd$a(this, _acceptAll, () => {
1169
+ this.ctx.get(commandsCtx).call(acceptAllDiffsCmd.key);
1170
+ });
1171
+ __privateSet$a(this, _config, config);
1172
+ __privateSet$a(this, _host, __privateMethod(this, _DiffActionsPanelView_instances, findHost_fn).call(this, view));
1173
+ const panel = document.createElement("div");
1174
+ panel.className = PANEL_CLASS;
1175
+ panel.dataset.show = "false";
1176
+ __privateSet$a(this, _retryBtn, __privateMethod(this, _DiffActionsPanelView_instances, makeButton_fn).call(this, "retry", config.retryIcon, config.retryLabel, __privateGet$a(this, _retry)));
1177
+ panel.appendChild(__privateGet$a(this, _retryBtn));
1178
+ panel.appendChild(
1179
+ __privateMethod(this, _DiffActionsPanelView_instances, makeButton_fn).call(this, "reject", config.rejectIcon, config.rejectAllLabel, __privateGet$a(this, _rejectAll))
1180
+ );
1181
+ const acceptBtn = __privateMethod(this, _DiffActionsPanelView_instances, makeButton_fn).call(this, "accept", config.acceptIcon, config.acceptAllLabel, __privateGet$a(this, _acceptAll));
1182
+ acceptBtn.appendChild(__privateMethod(this, _DiffActionsPanelView_instances, makeShortcutChip_fn).call(this));
1183
+ panel.appendChild(acceptBtn);
1184
+ __privateSet$a(this, _panel, panel);
1185
+ __privateGet$a(this, _host).appendChild(panel);
1186
+ this.update(view);
1187
+ }
1188
+ update(view) {
1189
+ var _a;
1190
+ const diffActive = !!((_a = diffPluginKey.getState(view.state)) == null ? void 0 : _a.active);
1191
+ if (diffActive !== __privateGet$a(this, _diffActive)) {
1192
+ __privateSet$a(this, _diffActive, diffActive);
1193
+ if (diffActive) {
1194
+ const session = this.ctx.get(aiSessionCtx.key);
1195
+ __privateSet$a(this, _ownedByAI, session.diffOwnedByAI);
1196
+ __privateSet$a(this, _diffStartDoc, view.state.doc);
1197
+ } else {
1198
+ __privateSet$a(this, _ownedByAI, false);
1199
+ __privateSet$a(this, _diffStartDoc, null);
1200
+ const session = this.ctx.get(aiSessionCtx.key);
1201
+ if (session.diffOwnedByAI) {
1202
+ this.ctx.set(aiSessionCtx.key, {
1203
+ ...session,
1204
+ diffOwnedByAI: false
1205
+ });
1206
+ }
1207
+ }
1208
+ }
1209
+ const shouldShow = diffActive && __privateGet$a(this, _ownedByAI);
1210
+ if (shouldShow !== __privateGet$a(this, _visible)) {
1211
+ __privateSet$a(this, _visible, shouldShow);
1212
+ __privateGet$a(this, _panel).dataset.show = shouldShow ? "true" : "false";
1213
+ }
1214
+ if (shouldShow) {
1215
+ const session = this.ctx.get(aiSessionCtx.key);
1216
+ const docUntouched = !!__privateGet$a(this, _diffStartDoc) && view.state.doc.eq(__privateGet$a(this, _diffStartDoc));
1217
+ __privateGet$a(this, _retryBtn).disabled = !session.lastInstruction || !docUntouched;
1218
+ }
1219
+ }
1220
+ destroy() {
1221
+ __privateGet$a(this, _panel).remove();
1222
+ }
1223
+ }
1224
+ _panel = new WeakMap();
1225
+ _host = new WeakMap();
1226
+ _retryBtn = new WeakMap();
1227
+ _config = new WeakMap();
1228
+ _visible = new WeakMap();
1229
+ _diffActive = new WeakMap();
1230
+ _diffStartDoc = new WeakMap();
1231
+ _ownedByAI = new WeakMap();
1232
+ _DiffActionsPanelView_instances = new WeakSet();
1233
+ findHost_fn = function(view) {
1234
+ var _a;
1235
+ return (_a = view.dom.closest(".milkdown")) != null ? _a : document.body;
1236
+ };
1237
+ makeButton_fn = function(variant, icon, label, onClick) {
1238
+ const btn = document.createElement("button");
1239
+ btn.type = "button";
1240
+ btn.className = `${PANEL_CLASS}-btn ${PANEL_CLASS}-btn-${variant}`;
1241
+ btn.appendChild(createIcon(icon));
1242
+ const text = document.createElement("span");
1243
+ text.textContent = label;
1244
+ btn.appendChild(text);
1245
+ btn.addEventListener("mousedown", (e) => e.preventDefault());
1246
+ btn.addEventListener("click", (e) => {
1247
+ e.preventDefault();
1248
+ e.stopPropagation();
1249
+ onClick();
1250
+ });
1251
+ return btn;
1252
+ };
1253
+ makeShortcutChip_fn = function() {
1254
+ const shortcut = document.createElement("span");
1255
+ shortcut.className = `${PANEL_CLASS}-shortcut`;
1256
+ const cmd = document.createElement("span");
1257
+ cmd.textContent = __privateGet$a(this, _config).modSymbol;
1258
+ const enter = document.createElement("span");
1259
+ enter.className = `${PANEL_CLASS}-shortcut-icon`;
1260
+ setSanitizedIcon(enter, __privateGet$a(this, _config).enterKeyIcon);
1261
+ shortcut.append(cmd, enter);
1262
+ return shortcut;
1263
+ };
1264
+ _retry = new WeakMap();
1265
+ canRetry_fn = function() {
1266
+ if (!__privateGet$a(this, _diffStartDoc)) return false;
1267
+ const editorView = this.ctx.get(editorViewCtx);
1268
+ return editorView.state.doc.eq(__privateGet$a(this, _diffStartDoc));
1269
+ };
1270
+ _rejectAll = new WeakMap();
1271
+ _acceptAll = new WeakMap();
1272
+
1273
+ const diffActionsPanelKey = new PluginKey("CREPE_AI_DIFF_ACTIONS_PANEL");
1274
+ const DEFAULT_DIFF_ACTIONS_RETRY_LABEL = "Retry";
1275
+ const DEFAULT_DIFF_ACTIONS_REJECT_ALL_LABEL = "Reject all";
1276
+ const DEFAULT_DIFF_ACTIONS_ACCEPT_ALL_LABEL = "Accept all";
1277
+ function detectModSymbol() {
1278
+ var _a, _b, _c, _d;
1279
+ if (typeof navigator === "undefined") return "\u2318";
1280
+ const ua = navigator;
1281
+ const platform = (_d = (_c = (_b = (_a = ua.userAgentData) == null ? void 0 : _a.platform) != null ? _b : ua.platform) != null ? _c : ua.userAgent) != null ? _d : "";
1282
+ return /mac|iphone|ipad|ipod/i.test(platform) ? "\u2318" : "Ctrl";
1283
+ }
1284
+ const DEFAULT_DIFF_ACTIONS_MOD_SYMBOL = detectModSymbol();
1285
+ function resolveDiffActionsConfig(options) {
1286
+ var _a, _b, _c, _d, _e, _f, _g;
1287
+ const { config, enterKeyIcon: enterKeyIcon$1 } = options;
1288
+ return {
1289
+ retryLabel: (_a = config == null ? void 0 : config.retryLabel) != null ? _a : DEFAULT_DIFF_ACTIONS_RETRY_LABEL,
1290
+ rejectAllLabel: (_b = config == null ? void 0 : config.rejectAllLabel) != null ? _b : DEFAULT_DIFF_ACTIONS_REJECT_ALL_LABEL,
1291
+ acceptAllLabel: (_c = config == null ? void 0 : config.acceptAllLabel) != null ? _c : DEFAULT_DIFF_ACTIONS_ACCEPT_ALL_LABEL,
1292
+ retryIcon: (_d = config == null ? void 0 : config.retryIcon) != null ? _d : retryIcon,
1293
+ rejectIcon: (_e = config == null ? void 0 : config.rejectIcon) != null ? _e : clearIcon,
1294
+ acceptIcon: (_f = config == null ? void 0 : config.acceptIcon) != null ? _f : confirmIcon,
1295
+ enterKeyIcon: enterKeyIcon$1 != null ? enterKeyIcon$1 : enterKeyIcon,
1296
+ modSymbol: (_g = config == null ? void 0 : config.modSymbol) != null ? _g : DEFAULT_DIFF_ACTIONS_MOD_SYMBOL
1297
+ };
1298
+ }
1299
+ function diffActionsPanelPlugin(options = {}) {
1300
+ const resolved = resolveDiffActionsConfig(options);
1301
+ return $prose((ctx) => {
1302
+ return new Plugin({
1303
+ key: diffActionsPanelKey,
1304
+ view(view) {
1305
+ return new DiffActionsPanelView(ctx, view, resolved);
1306
+ },
1307
+ props: {
1308
+ handleKeyDown(view, event) {
1309
+ var _a;
1310
+ if (event.key !== "Enter") return false;
1311
+ if (!(event.metaKey || event.ctrlKey)) return false;
1312
+ if (!((_a = diffPluginKey.getState(view.state)) == null ? void 0 : _a.active)) return false;
1313
+ if (!ctx.get(aiSessionCtx.key).diffOwnedByAI) return false;
1314
+ event.preventDefault();
1315
+ const commands = ctx.get(commandsCtx);
1316
+ commands.call(acceptAllDiffsCmd.key);
1317
+ return true;
1318
+ }
1319
+ }
1320
+ });
1321
+ });
1322
+ }
1323
+
1324
+ var __typeError$9 = (msg) => {
1325
+ throw TypeError(msg);
1326
+ };
1327
+ var __accessCheck$9 = (obj, member, msg) => member.has(obj) || __typeError$9("Cannot " + msg);
1328
+ var __privateGet$9 = (obj, member, getter) => (__accessCheck$9(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
1329
+ var __privateAdd$9 = (obj, member, value) => member.has(obj) ? __typeError$9("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
1330
+ var __privateSet$9 = (obj, member, value, setter) => (__accessCheck$9(obj, member, "write to private field"), member.set(obj, value), value);
1331
+ var _nodes, _removeById;
1332
+ function createSubmenuBuilder(node) {
1333
+ const builder = {
1334
+ addItem: (id, item) => {
1335
+ node.items.set(id, item);
1336
+ return builder;
1337
+ },
1338
+ removeItem: (id) => {
1339
+ node.items.delete(id);
1340
+ return builder;
1341
+ },
1342
+ getItem: (id) => node.items.get(id),
1343
+ clear: () => {
1344
+ node.items.clear();
1345
+ return builder;
1346
+ }
1347
+ };
1348
+ return builder;
1349
+ }
1350
+ class AISuggestionsBuilder {
1351
+ constructor() {
1352
+ __privateAdd$9(this, _nodes, []);
1353
+ this.addItem = (id, item) => {
1354
+ __privateGet$9(this, _removeById).call(this, id);
1355
+ __privateGet$9(this, _nodes).push({ kind: "item", id, item });
1356
+ return this;
1357
+ };
1358
+ /// Add a submenu. Populate items via the optional `build` callback,
1359
+ /// or call `getSubmenu(id)` afterward. Returns `this` so calls can be
1360
+ /// chained at the parent level alongside `addItem`.
1361
+ this.addSubmenu = (id, def, build) => {
1362
+ __privateGet$9(this, _removeById).call(this, id);
1363
+ const node = { def, items: /* @__PURE__ */ new Map() };
1364
+ if (build) build(createSubmenuBuilder(node));
1365
+ __privateGet$9(this, _nodes).push({ kind: "submenu", id, node });
1366
+ return this;
1367
+ };
1368
+ this.removeItem = (id) => {
1369
+ __privateGet$9(this, _removeById).call(this, id);
1370
+ return this;
1371
+ };
1372
+ this.getItem = (id) => {
1373
+ const node = __privateGet$9(this, _nodes).find((n) => n.kind === "item" && n.id === id);
1374
+ return (node == null ? void 0 : node.kind) === "item" ? node.item : void 0;
1375
+ };
1376
+ /// Return a builder that mutates the submenu's items in place.
1377
+ /// Multiple calls return distinct builder objects backed by the same
1378
+ /// underlying node, so changes are always visible.
1379
+ this.getSubmenu = (id) => {
1380
+ const node = __privateGet$9(this, _nodes).find((n) => n.kind === "submenu" && n.id === id);
1381
+ return (node == null ? void 0 : node.kind) === "submenu" ? createSubmenuBuilder(node.node) : void 0;
1382
+ };
1383
+ this.clear = () => {
1384
+ __privateSet$9(this, _nodes, []);
1385
+ return this;
1386
+ };
1387
+ this.build = () => {
1388
+ const main = [];
1389
+ const submenus = {};
1390
+ for (const node of __privateGet$9(this, _nodes)) {
1391
+ if (node.kind === "item") {
1392
+ main.push({ kind: "item", id: node.id, item: node.item });
1393
+ } else {
1394
+ main.push({ kind: "submenu", id: node.id, def: node.node.def });
1395
+ submenus[node.id] = {
1396
+ def: node.node.def,
1397
+ items: Array.from(node.node.items.entries()).map(([id, item]) => ({
1398
+ id,
1399
+ item
1400
+ }))
1401
+ };
1402
+ }
1403
+ }
1404
+ return { main, submenus };
1405
+ };
1406
+ __privateAdd$9(this, _removeById, (id) => {
1407
+ __privateSet$9(this, _nodes, __privateGet$9(this, _nodes).filter((n) => n.id !== id));
1408
+ });
1409
+ }
1410
+ }
1411
+ _nodes = new WeakMap();
1412
+ _removeById = new WeakMap();
1413
+ function applyDefaultSuggestions(builder) {
1414
+ builder.addItem("improve", {
1415
+ icon: aiIcon,
1416
+ label: "Improve writing",
1417
+ streamingLabel: "Improving writing",
1418
+ prompt: "Improve the writing while preserving the original meaning."
1419
+ }).addItem("grammar", {
1420
+ icon: grammarCheckIcon,
1421
+ label: "Fix grammar & spelling",
1422
+ streamingLabel: "Fixing grammar & spelling",
1423
+ prompt: "Fix any grammar and spelling errors without changing the meaning."
1424
+ }).addItem("shorter", {
1425
+ icon: shorterIcon,
1426
+ label: "Make shorter",
1427
+ streamingLabel: "Making shorter",
1428
+ prompt: "Make this shorter while preserving the key information."
1429
+ }).addItem("longer", {
1430
+ icon: longerIcon,
1431
+ label: "Make longer",
1432
+ streamingLabel: "Expanding",
1433
+ prompt: "Expand this with more detail and examples."
1434
+ });
1435
+ builder.addSubmenu(
1436
+ "tone",
1437
+ {
1438
+ icon: editIcon,
1439
+ label: "Change tone\u2026",
1440
+ title: "Change tone",
1441
+ searchPlaceholder: "Search tones\u2026"
1442
+ },
1443
+ (sub) => {
1444
+ const tones = [
1445
+ ["professional", "Professional"],
1446
+ ["casual", "Casual"],
1447
+ ["confident", "Confident"],
1448
+ ["friendly", "Friendly"],
1449
+ ["direct", "Direct"],
1450
+ ["formal", "Formal"]
1451
+ ];
1452
+ for (const [id, label] of tones) {
1453
+ sub.addItem(id, {
1454
+ icon: editIcon,
1455
+ label,
1456
+ streamingLabel: "Adjusting tone",
1457
+ prompt: `Rewrite this in a ${label.toLowerCase()} tone.`
1458
+ });
1459
+ }
1460
+ }
1461
+ );
1462
+ builder.addSubmenu(
1463
+ "translate",
1464
+ {
1465
+ icon: translateIcon,
1466
+ label: "Translate\u2026",
1467
+ title: "Translate",
1468
+ searchPlaceholder: "Search languages\u2026"
1469
+ },
1470
+ (sub) => {
1471
+ const languages = [
1472
+ ["english", "English", "English"],
1473
+ ["chinese", "Chinese", "Chinese (Simplified)"],
1474
+ ["japanese", "Japanese", "Japanese"],
1475
+ ["korean", "Korean", "Korean"],
1476
+ ["spanish", "Spanish", "Spanish"],
1477
+ ["french", "French", "French"],
1478
+ ["german", "German", "German"]
1479
+ ];
1480
+ for (const [id, label, promptName] of languages) {
1481
+ sub.addItem(id, {
1482
+ icon: translateIcon,
1483
+ label,
1484
+ streamingLabel: `Translating to ${label}`,
1485
+ prompt: `Translate this to ${promptName}.`
1486
+ });
1487
+ }
1488
+ }
1489
+ );
1490
+ }
1491
+
1492
+ function keepAlive(..._args) {
1493
+ }
1494
+
1495
+ keepAlive(h);
1496
+ function renderHighlighted(label, query) {
1497
+ const q = query.trim();
1498
+ if (!q) return [label];
1499
+ const lower = label.toLowerCase();
1500
+ const lq = q.toLowerCase();
1501
+ const idx = lower.indexOf(lq);
1502
+ if (idx === -1) return [label];
1503
+ return [
1504
+ label.slice(0, idx),
1505
+ h("mark", null, label.slice(idx, idx + q.length)),
1506
+ label.slice(idx + q.length)
1507
+ ];
1508
+ }
1509
+ const AIInstructionInput = defineComponent({
1510
+ props: {
1511
+ placeholder: { type: Object, required: true },
1512
+ resetSignal: { type: Object, required: true },
1513
+ suggestions: { type: Object, required: true },
1514
+ chrome: { type: Object, required: true },
1515
+ onConfirm: { type: Function, required: true },
1516
+ onCancel: { type: Function, required: true }
1517
+ },
1518
+ setup({
1519
+ placeholder,
1520
+ resetSignal,
1521
+ suggestions,
1522
+ chrome,
1523
+ onConfirm,
1524
+ onCancel
1525
+ }) {
1526
+ const inputValue = ref("");
1527
+ const view = ref({ kind: "main" });
1528
+ const selectedIndex = ref(0);
1529
+ const inputRef = ref(null);
1530
+ const listRef = ref(null);
1531
+ const listboxId = `ai-instruction-list-${Math.random().toString(36).slice(2, 9)}`;
1532
+ const optionId = (idx) => `${listboxId}-opt-${idx}`;
1533
+ watch(resetSignal, () => {
1534
+ inputValue.value = "";
1535
+ view.value = { kind: "main" };
1536
+ selectedIndex.value = 0;
1537
+ });
1538
+ const allItems = computed(() => {
1539
+ if (view.value.kind === "submenu") {
1540
+ const submenu = suggestions.submenus[view.value.id];
1541
+ if (!submenu) return [];
1542
+ return submenu.items.map(({ id, item }) => ({
1543
+ id,
1544
+ icon: item.icon,
1545
+ label: item.label,
1546
+ hasSubmenu: false,
1547
+ prompt: { text: item.prompt, streamingLabel: item.streamingLabel }
1548
+ }));
1549
+ }
1550
+ return suggestions.main.map((entry) => {
1551
+ if (entry.kind === "item") {
1552
+ return {
1553
+ id: entry.id,
1554
+ icon: entry.item.icon,
1555
+ label: entry.item.label,
1556
+ hasSubmenu: false,
1557
+ prompt: {
1558
+ text: entry.item.prompt,
1559
+ streamingLabel: entry.item.streamingLabel
1560
+ }
1561
+ };
1562
+ }
1563
+ return {
1564
+ id: entry.id,
1565
+ icon: entry.def.icon,
1566
+ label: entry.def.label,
1567
+ hasSubmenu: true
1568
+ };
1569
+ });
1570
+ });
1571
+ const currentSubmenuDef = computed(() => {
1572
+ var _a, _b;
1573
+ if (view.value.kind !== "submenu") return null;
1574
+ return (_b = (_a = suggestions.submenus[view.value.id]) == null ? void 0 : _a.def) != null ? _b : null;
1575
+ });
1576
+ const filteredItems = computed(() => {
1577
+ const q = inputValue.value.trim().toLowerCase();
1578
+ if (!q) return allItems.value;
1579
+ return allItems.value.filter(
1580
+ (item) => item.label.toLowerCase().includes(q)
1581
+ );
1582
+ });
1583
+ const showSendAsPrompt = computed(() => inputValue.value.trim().length > 0);
1584
+ const totalItems = computed(
1585
+ () => filteredItems.value.length + (showSendAsPrompt.value ? 1 : 0)
1586
+ );
1587
+ watch([filteredItems, view, showSendAsPrompt], () => {
1588
+ selectedIndex.value = showSendAsPrompt.value ? filteredItems.value.length : 0;
1589
+ });
1590
+ const focusInput = () => {
1591
+ void nextTick(() => {
1592
+ var _a;
1593
+ return (_a = inputRef.value) == null ? void 0 : _a.focus();
1594
+ });
1595
+ };
1596
+ const enterSubmenu = (id) => {
1597
+ view.value = { kind: "submenu", id };
1598
+ inputValue.value = "";
1599
+ selectedIndex.value = 0;
1600
+ focusInput();
1601
+ };
1602
+ const exitSubmenu = () => {
1603
+ view.value = { kind: "main" };
1604
+ inputValue.value = "";
1605
+ selectedIndex.value = 0;
1606
+ focusInput();
1607
+ };
1608
+ const runItem = (item) => {
1609
+ if (item.hasSubmenu) {
1610
+ enterSubmenu(item.id);
1611
+ } else if (item.prompt) {
1612
+ onConfirm(item.prompt.text, item.prompt.streamingLabel);
1613
+ inputValue.value = "";
1614
+ }
1615
+ };
1616
+ const submitRaw = () => {
1617
+ const v = inputValue.value.trim();
1618
+ if (!v) return;
1619
+ onConfirm(v);
1620
+ inputValue.value = "";
1621
+ };
1622
+ const onSelectCurrent = () => {
1623
+ const idx = selectedIndex.value;
1624
+ const items = filteredItems.value;
1625
+ if (idx < items.length) {
1626
+ runItem(items[idx]);
1627
+ } else if (showSendAsPrompt.value) {
1628
+ submitRaw();
1629
+ }
1630
+ };
1631
+ const scrollToSelected = () => {
1632
+ void nextTick(() => {
1633
+ const list = listRef.value;
1634
+ if (!list) return;
1635
+ const el = list.querySelector(
1636
+ `[data-index="${selectedIndex.value}"]`
1637
+ );
1638
+ el == null ? void 0 : el.scrollIntoView({ block: "nearest" });
1639
+ });
1640
+ };
1641
+ const onKeydown = (e) => {
1642
+ e.stopPropagation();
1643
+ if (e.key === "ArrowDown") {
1644
+ e.preventDefault();
1645
+ if (totalItems.value === 0) return;
1646
+ selectedIndex.value = (selectedIndex.value + 1) % totalItems.value;
1647
+ scrollToSelected();
1648
+ return;
1649
+ }
1650
+ if (e.key === "ArrowUp") {
1651
+ e.preventDefault();
1652
+ if (totalItems.value === 0) return;
1653
+ selectedIndex.value = (selectedIndex.value - 1 + totalItems.value) % totalItems.value;
1654
+ scrollToSelected();
1655
+ return;
1656
+ }
1657
+ if (e.key === "Enter") {
1658
+ e.preventDefault();
1659
+ onSelectCurrent();
1660
+ return;
1661
+ }
1662
+ if (e.key === "Escape") {
1663
+ e.preventDefault();
1664
+ if (view.value.kind === "submenu") exitSubmenu();
1665
+ else onCancel();
1666
+ return;
1667
+ }
1668
+ if (e.key === "Backspace" && inputValue.value === "" && view.value.kind === "submenu") {
1669
+ e.preventDefault();
1670
+ exitSubmenu();
1671
+ }
1672
+ };
1673
+ const onItemPointerDown = (e) => {
1674
+ e.preventDefault();
1675
+ };
1676
+ return () => {
1677
+ const items = filteredItems.value;
1678
+ const showPrompt = showSendAsPrompt.value;
1679
+ const submenuDef = currentSubmenuDef.value;
1680
+ return /* @__PURE__ */ h("div", { class: "ai-instruction" }, /* @__PURE__ */ h("div", { class: "ai-instruction-input" }, /* @__PURE__ */ h("span", { class: "ai-instruction-input-prefix" }, /* @__PURE__ */ h(Icon, { icon: chrome.aiIcon })), /* @__PURE__ */ h(
1681
+ "input",
1682
+ {
1683
+ ref: inputRef,
1684
+ class: "ai-instruction-input-field",
1685
+ role: "combobox",
1686
+ "aria-expanded": "true",
1687
+ "aria-autocomplete": "list",
1688
+ "aria-controls": listboxId,
1689
+ "aria-activedescendant": totalItems.value > 0 ? optionId(selectedIndex.value) : void 0,
1690
+ placeholder: submenuDef ? submenuDef.searchPlaceholder : placeholder.value,
1691
+ value: inputValue.value,
1692
+ onInput: (e) => {
1693
+ inputValue.value = e.target.value;
1694
+ },
1695
+ onKeydown
1696
+ }
1697
+ ), /* @__PURE__ */ h(
1698
+ "button",
1699
+ {
1700
+ type: "button",
1701
+ class: "ai-instruction-submit",
1702
+ "aria-label": chrome.submitButtonLabel,
1703
+ disabled: !showPrompt,
1704
+ onMousedown: onItemPointerDown,
1705
+ onClick: submitRaw
1706
+ },
1707
+ /* @__PURE__ */ h(Icon, { icon: chrome.sendIcon })
1708
+ )), /* @__PURE__ */ h(
1709
+ "div",
1710
+ {
1711
+ class: "ai-instruction-list",
1712
+ ref: listRef,
1713
+ id: listboxId,
1714
+ role: "listbox",
1715
+ "aria-label": chrome.listboxLabel
1716
+ },
1717
+ submenuDef && /* @__PURE__ */ h(
1718
+ "button",
1719
+ {
1720
+ type: "button",
1721
+ class: "ai-instruction-back",
1722
+ onMousedown: onItemPointerDown,
1723
+ onClick: exitSubmenu
1724
+ },
1725
+ /* @__PURE__ */ h("span", { class: "ai-instruction-back-icon", "aria-hidden": "true" }, /* @__PURE__ */ h(Icon, { icon: chrome.chevronLeftIcon })),
1726
+ /* @__PURE__ */ h("span", null, submenuDef.title)
1727
+ ),
1728
+ items.length > 0 && /* @__PURE__ */ h("div", { class: "ai-instruction-section" }, /* @__PURE__ */ h("div", { class: "ai-instruction-section-header" }, chrome.suggestionsHeaderLabel), items.map((item, idx) => /* @__PURE__ */ h(
1729
+ "div",
1730
+ {
1731
+ key: item.id,
1732
+ id: optionId(idx),
1733
+ "data-index": idx,
1734
+ role: "option",
1735
+ "aria-selected": idx === selectedIndex.value,
1736
+ class: [
1737
+ "ai-instruction-item",
1738
+ idx === selectedIndex.value ? "active" : ""
1739
+ ],
1740
+ onMousedown: onItemPointerDown,
1741
+ onClick: () => runItem(item),
1742
+ onPointerenter: () => {
1743
+ selectedIndex.value = idx;
1744
+ }
1745
+ },
1746
+ /* @__PURE__ */ h("span", { class: "ai-instruction-item-icon" }, /* @__PURE__ */ h(Icon, { icon: item.icon })),
1747
+ /* @__PURE__ */ h("span", { class: "ai-instruction-item-label" }, renderHighlighted(item.label, inputValue.value)),
1748
+ item.hasSubmenu && /* @__PURE__ */ h("span", { class: "ai-instruction-item-arrow" }, /* @__PURE__ */ h(Icon, { icon: chrome.chevronRightIcon }))
1749
+ ))),
1750
+ showPrompt && /* @__PURE__ */ h("div", { class: "ai-instruction-section" }, /* @__PURE__ */ h("div", { class: "ai-instruction-section-header" }, chrome.sendAsPromptHeaderLabel), /* @__PURE__ */ h(
1751
+ "div",
1752
+ {
1753
+ id: optionId(items.length),
1754
+ "data-index": items.length,
1755
+ role: "option",
1756
+ "aria-selected": selectedIndex.value === items.length,
1757
+ class: [
1758
+ "ai-instruction-item",
1759
+ "ai-instruction-item-prompt",
1760
+ selectedIndex.value === items.length ? "active" : ""
1761
+ ],
1762
+ onMousedown: onItemPointerDown,
1763
+ onClick: submitRaw,
1764
+ onPointerenter: () => {
1765
+ selectedIndex.value = items.length;
1766
+ }
1767
+ },
1768
+ /* @__PURE__ */ h("span", { class: "ai-instruction-item-icon" }, /* @__PURE__ */ h(Icon, { icon: chrome.sendPromptIcon })),
1769
+ /* @__PURE__ */ h("span", { class: "ai-instruction-item-label" }, chrome.sendAsPromptLabel, " ", /* @__PURE__ */ h("span", { class: "ai-instruction-item-quote" }, '"', inputValue.value, '"')),
1770
+ /* @__PURE__ */ h("span", { class: "ai-instruction-item-shortcut" }, /* @__PURE__ */ h(Icon, { icon: chrome.enterKeyIcon }))
1771
+ ))
1772
+ ));
1773
+ };
1774
+ }
1775
+ });
1776
+
1777
+ var __typeError$8 = (msg) => {
1778
+ throw TypeError(msg);
1779
+ };
1780
+ var __accessCheck$8 = (obj, member, msg) => member.has(obj) || __typeError$8("Cannot " + msg);
1781
+ var __privateGet$8 = (obj, member, getter) => (__accessCheck$8(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
1782
+ var __privateAdd$8 = (obj, member, value) => member.has(obj) ? __typeError$8("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
1783
+ var __privateSet$8 = (obj, member, value, setter) => (__accessCheck$8(obj, member, "write to private field"), member.set(obj, value), value);
1784
+ var _content$4, _provider$2, _app$5, _placeholder, _resetSignal, _from, _to, _wantsShow, _onConfirm, _onCancel;
1785
+ class AIInstructionTooltipView {
1786
+ constructor(ctx, view, config) {
1787
+ this.ctx = ctx;
1788
+ __privateAdd$8(this, _content$4);
1789
+ __privateAdd$8(this, _provider$2);
1790
+ __privateAdd$8(this, _app$5);
1791
+ __privateAdd$8(this, _placeholder);
1792
+ __privateAdd$8(this, _resetSignal);
1793
+ __privateAdd$8(this, _from, -1);
1794
+ __privateAdd$8(this, _to, -1);
1795
+ /// Source of truth for "should the palette currently be showing".
1796
+ /// `TooltipProvider.shouldShow` reads this so that forwarding `update()`
1797
+ /// to the provider on every editor transition (needed to keep the
1798
+ /// floating position in sync with layout changes) doesn't dismiss the
1799
+ /// palette behind our back.
1800
+ __privateAdd$8(this, _wantsShow, false);
1801
+ __privateAdd$8(this, _onConfirm, (instruction, label) => {
1802
+ if (!instruction.trim()) return;
1803
+ const commands = this.ctx.get(commandsCtx);
1804
+ const accepted = commands.call(runAICmd.key, { instruction, label });
1805
+ if (!accepted) return;
1806
+ __privateSet$8(this, _wantsShow, false);
1807
+ __privateGet$8(this, _provider$2).hide();
1808
+ });
1809
+ __privateAdd$8(this, _onCancel, () => {
1810
+ __privateSet$8(this, _wantsShow, false);
1811
+ __privateGet$8(this, _provider$2).hide();
1812
+ });
1813
+ this.show = (from, to) => {
1814
+ __privateSet$8(this, _from, from);
1815
+ __privateSet$8(this, _to, to);
1816
+ __privateGet$8(this, _resetSignal).value++;
1817
+ __privateSet$8(this, _wantsShow, true);
1818
+ const view = this.ctx.get(editorViewCtx);
1819
+ __privateGet$8(this, _provider$2).show(
1820
+ { getBoundingClientRect: () => posToDOMRect(view, from, to) },
1821
+ view
1822
+ );
1823
+ requestAnimationFrame(() => {
1824
+ var _a;
1825
+ (_a = __privateGet$8(this, _content$4).querySelector("input")) == null ? void 0 : _a.focus();
1826
+ });
1827
+ };
1828
+ this.update = (view, prevState) => {
1829
+ const { selection } = view.state;
1830
+ const isTextSelection = selection instanceof TextSelection;
1831
+ const movedRange = selection.from !== __privateGet$8(this, _from) || selection.to !== __privateGet$8(this, _to);
1832
+ if (!isTextSelection || movedRange) {
1833
+ __privateSet$8(this, _wantsShow, false);
1834
+ __privateGet$8(this, _provider$2).hide();
1835
+ return;
1836
+ }
1837
+ __privateGet$8(this, _provider$2).update(view, prevState);
1838
+ };
1839
+ this.destroy = () => {
1840
+ __privateGet$8(this, _app$5).unmount();
1841
+ __privateGet$8(this, _provider$2).destroy();
1842
+ __privateGet$8(this, _content$4).remove();
1843
+ };
1844
+ __privateSet$8(this, _placeholder, ref(config.placeholder));
1845
+ __privateSet$8(this, _resetSignal, ref(0));
1846
+ const content = document.createElement("div");
1847
+ content.className = "milkdown-ai-instruction";
1848
+ const app = createApp(AIInstructionInput, {
1849
+ placeholder: __privateGet$8(this, _placeholder),
1850
+ resetSignal: __privateGet$8(this, _resetSignal),
1851
+ suggestions: config.suggestions,
1852
+ chrome: config.chrome,
1853
+ onConfirm: __privateGet$8(this, _onConfirm),
1854
+ onCancel: __privateGet$8(this, _onCancel)
1855
+ });
1856
+ app.mount(content);
1857
+ __privateSet$8(this, _app$5, app);
1858
+ __privateSet$8(this, _content$4, content);
1859
+ __privateSet$8(this, _provider$2, new TooltipProvider({
1860
+ content,
1861
+ debounce: 0,
1862
+ offset: 10,
1863
+ shouldShow: () => __privateGet$8(this, _wantsShow),
1864
+ floatingUIOptions: {
1865
+ placement: "bottom"
1866
+ }
1867
+ }));
1868
+ __privateGet$8(this, _provider$2).onHide = () => {
1869
+ __privateSet$8(this, _wantsShow, false);
1870
+ requestAnimationFrame(() => {
1871
+ try {
1872
+ const root = __privateGet$8(this, _content$4).getRootNode();
1873
+ const active = root.activeElement;
1874
+ if (!active || !__privateGet$8(this, _content$4).contains(active)) return;
1875
+ const v = this.ctx.get(editorViewCtx);
1876
+ v.dom.focus({ preventScroll: true });
1877
+ } catch (e) {
1878
+ }
1879
+ });
1880
+ };
1881
+ __privateGet$8(this, _provider$2).update(view);
1882
+ }
1883
+ }
1884
+ _content$4 = new WeakMap();
1885
+ _provider$2 = new WeakMap();
1886
+ _app$5 = new WeakMap();
1887
+ _placeholder = new WeakMap();
1888
+ _resetSignal = new WeakMap();
1889
+ _from = new WeakMap();
1890
+ _to = new WeakMap();
1891
+ _wantsShow = new WeakMap();
1892
+ _onConfirm = new WeakMap();
1893
+ _onCancel = new WeakMap();
1894
+
1895
+ const defaultAPI = {
1896
+ show: () => {
1897
+ }
1898
+ };
1899
+ const aiInstructionTooltipAPI = $ctx(
1900
+ { ...defaultAPI },
1901
+ "aiInstructionTooltipAPI"
1902
+ );
1903
+ const aiInstructionTooltip = tooltipFactory("CREPE_AI_INSTRUCTION");
1904
+ const DEFAULT_SUGGESTIONS_HEADER_LABEL = "SUGGESTIONS";
1905
+ const DEFAULT_SEND_AS_PROMPT_HEADER_LABEL = "SEND AS PROMPT";
1906
+ const DEFAULT_SEND_AS_PROMPT_LABEL = "Ask AI:";
1907
+ const DEFAULT_SUBMIT_BUTTON_LABEL = "Send prompt";
1908
+ const DEFAULT_LISTBOX_LABEL = "AI suggestions";
1909
+ const DEFAULT_INSTRUCTION_PLACEHOLDER = "Tell AI what to do with the selection\u2026";
1910
+ function resolveChrome(config) {
1911
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
1912
+ return {
1913
+ aiIcon: (_a = config == null ? void 0 : config.aiIcon) != null ? _a : aiIcon,
1914
+ sendIcon: (_b = config == null ? void 0 : config.sendIcon) != null ? _b : sendIcon,
1915
+ sendPromptIcon: (_c = config == null ? void 0 : config.sendPromptIcon) != null ? _c : sendPromptIcon,
1916
+ enterKeyIcon: (_d = config == null ? void 0 : config.enterKeyIcon) != null ? _d : enterKeyIcon,
1917
+ chevronLeftIcon: (_e = config == null ? void 0 : config.chevronLeftIcon) != null ? _e : chevronLeftIcon,
1918
+ chevronRightIcon: (_f = config == null ? void 0 : config.chevronRightIcon) != null ? _f : chevronRightIcon,
1919
+ suggestionsHeaderLabel: (_g = config == null ? void 0 : config.suggestionsHeaderLabel) != null ? _g : DEFAULT_SUGGESTIONS_HEADER_LABEL,
1920
+ sendAsPromptHeaderLabel: (_h = config == null ? void 0 : config.sendAsPromptHeaderLabel) != null ? _h : DEFAULT_SEND_AS_PROMPT_HEADER_LABEL,
1921
+ sendAsPromptLabel: (_i = config == null ? void 0 : config.sendAsPromptLabel) != null ? _i : DEFAULT_SEND_AS_PROMPT_LABEL,
1922
+ submitButtonLabel: (_j = config == null ? void 0 : config.submitButtonLabel) != null ? _j : DEFAULT_SUBMIT_BUTTON_LABEL,
1923
+ listboxLabel: (_k = config == null ? void 0 : config.listboxLabel) != null ? _k : DEFAULT_LISTBOX_LABEL
1924
+ };
1925
+ }
1926
+ function resolveViewConfig(config) {
1927
+ var _a, _b;
1928
+ const builder = new AISuggestionsBuilder();
1929
+ applyDefaultSuggestions(builder);
1930
+ (_a = config == null ? void 0 : config.buildAISuggestions) == null ? void 0 : _a.call(config, builder);
1931
+ return {
1932
+ placeholder: (_b = config == null ? void 0 : config.instructionPlaceholder) != null ? _b : DEFAULT_INSTRUCTION_PLACEHOLDER,
1933
+ chrome: resolveChrome(config),
1934
+ suggestions: builder.build()
1935
+ };
1936
+ }
1937
+ function configureAIInstructionTooltip(config) {
1938
+ return (ctx) => {
1939
+ const viewConfig = resolveViewConfig(config);
1940
+ let tooltipView = null;
1941
+ ctx.update(aiInstructionTooltipAPI.key, (api) => ({
1942
+ ...api,
1943
+ show: (from, to) => {
1944
+ tooltipView == null ? void 0 : tooltipView.show(from, to);
1945
+ }
1946
+ }));
1947
+ ctx.set(aiInstructionTooltip.key, {
1948
+ view: (view) => {
1949
+ tooltipView = new AIInstructionTooltipView(ctx, view, viewConfig);
1950
+ return tooltipView;
1951
+ }
1952
+ });
1953
+ };
1954
+ }
1955
+
1956
+ var __typeError$7 = (msg) => {
1957
+ throw TypeError(msg);
1958
+ };
1959
+ var __accessCheck$7 = (obj, member, msg) => member.has(obj) || __typeError$7("Cannot " + msg);
1960
+ var __privateGet$7 = (obj, member, getter) => (__accessCheck$7(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
1961
+ var __privateAdd$7 = (obj, member, value) => member.has(obj) ? __typeError$7("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
1962
+ var __privateSet$7 = (obj, member, value, setter) => (__accessCheck$7(obj, member, "write to private field"), member.set(obj, value), value);
1963
+ var _spinner, _label, _fallbackLabel, _start, _lastLabelText, _rafId, _tick;
1964
+ const CLASS_PREFIX = "milkdown-ai-streaming";
1965
+ const SPINNER_PERIOD_MS = 800;
1966
+ const DEFAULT_STREAMING_FALLBACK_LABEL = "Generating";
1967
+ const DEFAULT_STREAMING_CANCEL_HINT = "Esc to cancel";
1968
+ const indicatorKey = new PluginKey(
1969
+ "CREPE_AI_STREAMING_INDICATOR"
1970
+ );
1971
+ class IndicatorWidget {
1972
+ constructor(ctx, fallbackLabel, cancelHint) {
1973
+ __privateAdd$7(this, _spinner);
1974
+ __privateAdd$7(this, _label);
1975
+ __privateAdd$7(this, _fallbackLabel);
1976
+ __privateAdd$7(this, _start, performance.now());
1977
+ __privateAdd$7(this, _lastLabelText, "");
1978
+ __privateAdd$7(this, _rafId, 0);
1979
+ __privateAdd$7(this, _tick, () => {
1980
+ const elapsed = performance.now() - __privateGet$7(this, _start);
1981
+ const angle = elapsed / SPINNER_PERIOD_MS * 360;
1982
+ __privateGet$7(this, _spinner).style.transform = `rotate(${angle}deg)`;
1983
+ __privateSet$7(this, _rafId, requestAnimationFrame(__privateGet$7(this, _tick)));
1984
+ });
1985
+ __privateSet$7(this, _fallbackLabel, fallbackLabel);
1986
+ const dom = document.createElement("span");
1987
+ dom.className = `${CLASS_PREFIX}-indicator`;
1988
+ dom.contentEditable = "false";
1989
+ dom.setAttribute("role", "status");
1990
+ dom.setAttribute("aria-live", "polite");
1991
+ const spinner = document.createElement("span");
1992
+ spinner.className = `${CLASS_PREFIX}-spinner`;
1993
+ spinner.setAttribute("aria-hidden", "true");
1994
+ dom.appendChild(spinner);
1995
+ const label = document.createElement("span");
1996
+ label.className = `${CLASS_PREFIX}-label`;
1997
+ dom.appendChild(label);
1998
+ const escHint = document.createElement("span");
1999
+ escHint.className = `${CLASS_PREFIX}-esc`;
2000
+ escHint.textContent = cancelHint;
2001
+ dom.appendChild(escHint);
2002
+ this.dom = dom;
2003
+ __privateSet$7(this, _spinner, spinner);
2004
+ __privateSet$7(this, _label, label);
2005
+ this.setLabel(ctx);
2006
+ __privateGet$7(this, _tick).call(this);
2007
+ }
2008
+ setLabel(ctx) {
2009
+ const session = ctx.get(aiSessionCtx.key);
2010
+ const text = `${session.label || __privateGet$7(this, _fallbackLabel)}\u2026`;
2011
+ if (text === __privateGet$7(this, _lastLabelText)) return;
2012
+ __privateSet$7(this, _lastLabelText, text);
2013
+ __privateGet$7(this, _label).textContent = text;
2014
+ }
2015
+ destroy() {
2016
+ if (__privateGet$7(this, _rafId)) cancelAnimationFrame(__privateGet$7(this, _rafId));
2017
+ __privateSet$7(this, _rafId, 0);
2018
+ }
2019
+ }
2020
+ _spinner = new WeakMap();
2021
+ _label = new WeakMap();
2022
+ _fallbackLabel = new WeakMap();
2023
+ _start = new WeakMap();
2024
+ _lastLabelText = new WeakMap();
2025
+ _rafId = new WeakMap();
2026
+ _tick = new WeakMap();
2027
+ function streamingIndicatorPlugin(options = {}) {
2028
+ var _a, _b;
2029
+ const { config } = options;
2030
+ const fallbackLabel = (_a = config == null ? void 0 : config.fallbackLabel) != null ? _a : DEFAULT_STREAMING_FALLBACK_LABEL;
2031
+ const cancelHint = (_b = config == null ? void 0 : config.cancelHint) != null ? _b : DEFAULT_STREAMING_CANCEL_HINT;
2032
+ return $prose((ctx) => {
2033
+ let widget = null;
2034
+ function ensureWidget() {
2035
+ if (!widget) widget = new IndicatorWidget(ctx, fallbackLabel, cancelHint);
2036
+ else widget.setLabel(ctx);
2037
+ return widget;
2038
+ }
2039
+ function dropWidget() {
2040
+ if (widget) {
2041
+ widget.destroy();
2042
+ widget = null;
2043
+ }
2044
+ }
2045
+ function buildSet(doc, insertEndPos) {
2046
+ const pos = Math.min(insertEndPos, doc.content.size);
2047
+ const decoration = Decoration.widget(pos, ensureWidget().dom, {
2048
+ side: 1,
2049
+ key: "ai-streaming-indicator"
2050
+ });
2051
+ return DecorationSet.create(doc, [decoration]);
2052
+ }
2053
+ return new Plugin({
2054
+ key: indicatorKey,
2055
+ state: {
2056
+ init: () => DecorationSet.empty,
2057
+ apply(tr, decorations, _oldState, newState) {
2058
+ const streaming = streamingPluginKey.getState(newState);
2059
+ if (!(streaming == null ? void 0 : streaming.active) || streaming.insertEndPos == null) {
2060
+ dropWidget();
2061
+ return DecorationSet.empty;
2062
+ }
2063
+ if (tr.getMeta(streamingPluginKey) || tr.docChanged) {
2064
+ return buildSet(newState.doc, streaming.insertEndPos);
2065
+ }
2066
+ return decorations.map(tr.mapping, tr.doc);
2067
+ }
2068
+ },
2069
+ view() {
2070
+ return {
2071
+ destroy() {
2072
+ dropWidget();
2073
+ }
2074
+ };
2075
+ },
2076
+ props: {
2077
+ decorations(state) {
2078
+ var _a2;
2079
+ return (_a2 = indicatorKey.getState(state)) != null ? _a2 : DecorationSet.empty;
2080
+ },
2081
+ handleKeyDown(view, event) {
2082
+ var _a2;
2083
+ if (event.key !== "Escape") return false;
2084
+ const commands = ctx.get(commandsCtx);
2085
+ if (ctx.get(aiSessionCtx.key).abortController) {
2086
+ event.preventDefault();
2087
+ commands.call(abortAICmd.key, { keep: true });
2088
+ return true;
2089
+ }
2090
+ if ((_a2 = streamingPluginKey.getState(view.state)) == null ? void 0 : _a2.active) {
2091
+ event.preventDefault();
2092
+ commands.call(abortStreamingCmd.key, { keep: true });
2093
+ return true;
2094
+ }
2095
+ return false;
2096
+ }
2097
+ }
2098
+ });
2099
+ });
2100
+ }
2101
+
2102
+ const CREPE_CUSTOM_BLOCK_TYPES = ["table", "image-block", "code_block"];
2103
+ const CREPE_IGNORE_ATTRS = { heading: ["id"] };
2104
+ const ai = (editor, config) => {
2105
+ var _a, _b;
2106
+ const diffCfg = (_a = config == null ? void 0 : config.diff) != null ? _a : {};
2107
+ const streamingCfg = (_b = config == null ? void 0 : config.streaming) != null ? _b : {};
2108
+ editor.config(crepeFeatureConfig(CrepeFeature.AI)).config((ctx) => {
2109
+ ctx.update(diffConfig.key, (prev) => {
2110
+ var _a2;
2111
+ return {
2112
+ ...prev,
2113
+ ignoreAttrs: (_a2 = diffCfg.ignoreAttrs) != null ? _a2 : CREPE_IGNORE_ATTRS
2114
+ };
2115
+ });
2116
+ const { ignoreAttrs: _, ...componentConfig } = diffCfg;
2117
+ ctx.update(diffComponentConfig.key, (prev) => {
2118
+ var _a2;
2119
+ return {
2120
+ ...prev,
2121
+ customBlockTypes: (_a2 = componentConfig.customBlockTypes) != null ? _a2 : CREPE_CUSTOM_BLOCK_TYPES,
2122
+ ...componentConfig
2123
+ };
2124
+ });
2125
+ }).use(diff).use(diffComponent).config((ctx) => {
2126
+ ctx.update(streamingConfig.key, (prev) => {
2127
+ var _a2;
2128
+ return {
2129
+ ...prev,
2130
+ ...streamingCfg,
2131
+ ignoreAttrs: (_a2 = streamingCfg.ignoreAttrs) != null ? _a2 : CREPE_IGNORE_ATTRS,
2132
+ // Wire diffReviewOnEnd into the streaming plugin so manual
2133
+ // endStreamingCmd calls (outside runAICmd) also respect it.
2134
+ // Only override if the user explicitly set it — otherwise
2135
+ // keep the streaming plugin's own default so tests and
2136
+ // manual-streaming use cases aren't surprised.
2137
+ ...(config == null ? void 0 : config.diffReviewOnEnd) !== void 0 ? { diffReviewOnEnd: config.diffReviewOnEnd } : {}
2138
+ };
2139
+ });
2140
+ }).use(streaming).config((ctx) => {
2141
+ ctx.update(aiProviderConfig.key, (prev) => {
2142
+ var _a2;
2143
+ return {
2144
+ ...prev,
2145
+ ...(config == null ? void 0 : config.provider) !== void 0 ? { provider: config.provider } : {},
2146
+ ...(config == null ? void 0 : config.buildContext) !== void 0 ? { buildContext: config.buildContext } : {},
2147
+ diffReviewOnEnd: (_a2 = config == null ? void 0 : config.diffReviewOnEnd) != null ? _a2 : prev.diffReviewOnEnd,
2148
+ ...(config == null ? void 0 : config.onError) !== void 0 ? { onError: config.onError } : {},
2149
+ ...(config == null ? void 0 : config.aiIcon) !== void 0 ? { aiIcon: config.aiIcon } : {}
2150
+ };
2151
+ });
2152
+ }).use(aiProviderConfig).use(aiSessionCtx).use(runAICmd).use(abortAICmd).config(configureAIInstructionTooltip(config)).use(aiInstructionTooltipAPI).use(aiInstructionTooltip).use(streamingIndicatorPlugin({ config: config == null ? void 0 : config.streamingIndicator })).use(
2153
+ diffActionsPanelPlugin({
2154
+ config: config == null ? void 0 : config.diffActions,
2155
+ enterKeyIcon: config == null ? void 0 : config.enterKeyIcon
2156
+ })
2157
+ );
2158
+ };
2159
+
761
2160
  function isInCodeBlock(selection) {
762
2161
  const type = selection.$from.parent.type;
763
2162
  return type.name === "code_block";
@@ -768,22 +2167,22 @@ function isInList(selection) {
768
2167
  return (type == null ? void 0 : type.name) === "list_item";
769
2168
  }
770
2169
 
771
- var __typeError$5 = (msg) => {
2170
+ var __typeError$6 = (msg) => {
772
2171
  throw TypeError(msg);
773
2172
  };
774
- var __accessCheck$5 = (obj, member, msg) => member.has(obj) || __typeError$5("Cannot " + msg);
775
- var __privateGet$5 = (obj, member, getter) => (__accessCheck$5(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
776
- var __privateAdd$5 = (obj, member, value) => member.has(obj) ? __typeError$5("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
777
- var __privateSet$5 = (obj, member, value, setter) => (__accessCheck$5(obj, member, "write to private field"), member.set(obj, value), value);
2173
+ var __accessCheck$6 = (obj, member, msg) => member.has(obj) || __typeError$6("Cannot " + msg);
2174
+ var __privateGet$6 = (obj, member, getter) => (__accessCheck$6(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
2175
+ 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);
2176
+ var __privateSet$6 = (obj, member, value, setter) => (__accessCheck$6(obj, member, "write to private field"), member.set(obj, value), value);
778
2177
  var _groups, _getGroupInstance;
779
2178
  class GroupBuilder {
780
2179
  constructor() {
781
- __privateAdd$5(this, _groups, []);
2180
+ __privateAdd$6(this, _groups, []);
782
2181
  this.clear = () => {
783
- __privateSet$5(this, _groups, []);
2182
+ __privateSet$6(this, _groups, []);
784
2183
  return this;
785
2184
  };
786
- __privateAdd$5(this, _getGroupInstance, (group) => {
2185
+ __privateAdd$6(this, _getGroupInstance, (group) => {
787
2186
  const groupInstance = {
788
2187
  group,
789
2188
  addItem: (key, item) => {
@@ -805,23 +2204,23 @@ class GroupBuilder {
805
2204
  label,
806
2205
  items
807
2206
  };
808
- __privateGet$5(this, _groups).push(group);
809
- return __privateGet$5(this, _getGroupInstance).call(this, group);
2207
+ __privateGet$6(this, _groups).push(group);
2208
+ return __privateGet$6(this, _getGroupInstance).call(this, group);
810
2209
  };
811
2210
  this.getGroup = (key) => {
812
- const group = __privateGet$5(this, _groups).find((group2) => group2.key === key);
2211
+ const group = __privateGet$6(this, _groups).find((group2) => group2.key === key);
813
2212
  if (!group) throw new Error(`Group with key ${key} not found`);
814
- return __privateGet$5(this, _getGroupInstance).call(this, group);
2213
+ return __privateGet$6(this, _getGroupInstance).call(this, group);
815
2214
  };
816
2215
  this.build = () => {
817
- return __privateGet$5(this, _groups);
2216
+ return __privateGet$6(this, _groups);
818
2217
  };
819
2218
  }
820
2219
  }
821
2220
  _groups = new WeakMap();
822
2221
  _getGroupInstance = new WeakMap();
823
2222
 
824
- function getGroups$1(filter, config, ctx) {
2223
+ function getGroups$2(filter, config, ctx) {
825
2224
  var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _A, _B, _C, _D, _E, _F, _G, _H, _I, _J, _K, _L, _M, _N, _O, _P, _Q, _R, _S, _T, _U, _V, _W, _X, _Y, _Z, __, _$, _aa, _ba, _ca, _da, _ea, _fa, _ga, _ha, _ia, _ja, _ka, _la, _ma, _na, _oa, _pa, _qa, _ra, _sa, _ta, _ua, _va, _wa, _xa, _ya, _za, _Aa, _Ba, _Ca, _Da, _Ea, _Fa, _Ga, _Ha, _Ia, _Ja, _Ka, _La, _Ma, _Na, _Oa, _Pa, _Qa, _Ra, _Sa, _Ta, _Ua, _Va, _Wa, _Xa, _Ya, _Za, __a, _$a, _ab, _bb, _cb, _db, _eb, _fb, _gb, _hb, _ib, _jb, _kb;
826
2225
  const flags = ctx && useCrepeFeatures(ctx).get();
827
2226
  const isLatexEnabled = flags == null ? void 0 : flags.includes(CrepeFeature.Latex);
@@ -1088,7 +2487,7 @@ function getGroups$1(filter, config, ctx) {
1088
2487
  commands.call(clearTextInCurrentBlockCommand.key);
1089
2488
  commands.call(addBlockTypeCommand.key, {
1090
2489
  nodeType: codeBlock,
1091
- attrs: { language: "LaTex" }
2490
+ attrs: { language: "LaTeX" }
1092
2491
  });
1093
2492
  }
1094
2493
  });
@@ -1124,6 +2523,7 @@ function getGroups$1(filter, config, ctx) {
1124
2523
  };
1125
2524
  }
1126
2525
 
2526
+ keepAlive(h);
1127
2527
  const Menu = defineComponent({
1128
2528
  props: {
1129
2529
  ctx: {
@@ -1149,7 +2549,7 @@ const Menu = defineComponent({
1149
2549
  },
1150
2550
  setup({ ctx, show, filter, hide, config }) {
1151
2551
  const host = ref();
1152
- const groupInfo = computed(() => getGroups$1(filter.value, config, ctx));
2552
+ const groupInfo = computed(() => getGroups$2(filter.value, config, ctx));
1153
2553
  const hoverIndex = ref(0);
1154
2554
  const prevMousePosition = ref({ x: -999, y: -999 });
1155
2555
  const onPointerMove = (e) => {
@@ -1178,7 +2578,7 @@ const Menu = defineComponent({
1178
2578
  };
1179
2579
  const runByIndex = (index) => {
1180
2580
  const item = groupInfo.value.groups.flatMap((group) => group.items).at(index);
1181
- if (item && ctx) item.onRun(ctx);
2581
+ if ((item == null ? void 0 : item.onRun) && ctx) item.onRun(ctx);
1182
2582
  hide();
1183
2583
  };
1184
2584
  const onKeydown = (e) => {
@@ -1282,14 +2682,14 @@ const Menu = defineComponent({
1282
2682
  }
1283
2683
  });
1284
2684
 
1285
- var __typeError$4 = (msg) => {
2685
+ var __typeError$5 = (msg) => {
1286
2686
  throw TypeError(msg);
1287
2687
  };
1288
- var __accessCheck$4 = (obj, member, msg) => member.has(obj) || __typeError$4("Cannot " + msg);
1289
- var __privateGet$4 = (obj, member, getter) => (__accessCheck$4(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
1290
- var __privateAdd$4 = (obj, member, value) => member.has(obj) ? __typeError$4("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
1291
- var __privateSet$4 = (obj, member, value, setter) => (__accessCheck$4(obj, member, "write to private field"), member.set(obj, value), value);
1292
- var _content$3, _app$3, _filter, _slashProvider, _programmaticallyPos;
2688
+ var __accessCheck$5 = (obj, member, msg) => member.has(obj) || __typeError$5("Cannot " + msg);
2689
+ var __privateGet$5 = (obj, member, getter) => (__accessCheck$5(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
2690
+ var __privateAdd$5 = (obj, member, value) => member.has(obj) ? __typeError$5("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
2691
+ var __privateSet$5 = (obj, member, value, setter) => (__accessCheck$5(obj, member, "write to private field"), member.set(obj, value), value);
2692
+ var _content$3, _app$4, _filter, _slashProvider, _programmaticallyPos;
1293
2693
  const menu = slashFactory("CREPE_MENU");
1294
2694
  const menuAPI = $ctx(
1295
2695
  {
@@ -1307,33 +2707,33 @@ function configureMenu(ctx, config) {
1307
2707
  }
1308
2708
  class MenuView {
1309
2709
  constructor(ctx, view, config) {
1310
- __privateAdd$4(this, _content$3);
1311
- __privateAdd$4(this, _app$3);
1312
- __privateAdd$4(this, _filter);
1313
- __privateAdd$4(this, _slashProvider);
1314
- __privateAdd$4(this, _programmaticallyPos, null);
2710
+ __privateAdd$5(this, _content$3);
2711
+ __privateAdd$5(this, _app$4);
2712
+ __privateAdd$5(this, _filter);
2713
+ __privateAdd$5(this, _slashProvider);
2714
+ __privateAdd$5(this, _programmaticallyPos, null);
1315
2715
  this.update = (view) => {
1316
- __privateGet$4(this, _slashProvider).update(view);
2716
+ __privateGet$5(this, _slashProvider).update(view);
1317
2717
  };
1318
2718
  this.show = (pos) => {
1319
- __privateSet$4(this, _programmaticallyPos, pos);
1320
- __privateGet$4(this, _filter).value = "";
1321
- __privateGet$4(this, _slashProvider).show();
2719
+ __privateSet$5(this, _programmaticallyPos, pos);
2720
+ __privateGet$5(this, _filter).value = "";
2721
+ __privateGet$5(this, _slashProvider).show();
1322
2722
  };
1323
2723
  this.hide = () => {
1324
- __privateSet$4(this, _programmaticallyPos, null);
1325
- __privateGet$4(this, _slashProvider).hide();
2724
+ __privateSet$5(this, _programmaticallyPos, null);
2725
+ __privateGet$5(this, _slashProvider).hide();
1326
2726
  };
1327
2727
  this.destroy = () => {
1328
- __privateGet$4(this, _slashProvider).destroy();
1329
- __privateGet$4(this, _app$3).unmount();
1330
- __privateGet$4(this, _content$3).remove();
2728
+ __privateGet$5(this, _slashProvider).destroy();
2729
+ __privateGet$5(this, _app$4).unmount();
2730
+ __privateGet$5(this, _content$3).remove();
1331
2731
  };
1332
2732
  const content = document.createElement("div");
1333
2733
  content.classList.add("milkdown-slash-menu");
1334
2734
  const show = ref(false);
1335
2735
  const filter = ref("");
1336
- __privateSet$4(this, _filter, filter);
2736
+ __privateSet$5(this, _filter, filter);
1337
2737
  const hide = this.hide;
1338
2738
  const app = createApp(Menu, {
1339
2739
  ctx,
@@ -1342,12 +2742,12 @@ class MenuView {
1342
2742
  filter,
1343
2743
  hide
1344
2744
  });
1345
- __privateSet$4(this, _app$3, app);
2745
+ __privateSet$5(this, _app$4, app);
1346
2746
  app.mount(content);
1347
- __privateSet$4(this, _content$3, content);
2747
+ __privateSet$5(this, _content$3, content);
1348
2748
  const self = this;
1349
- __privateSet$4(this, _slashProvider, new SlashProvider({
1350
- content: __privateGet$4(this, _content$3),
2749
+ __privateSet$5(this, _slashProvider, new SlashProvider({
2750
+ content: __privateGet$5(this, _content$3),
1351
2751
  debounce: 20,
1352
2752
  shouldShow(view2) {
1353
2753
  if (isInCodeBlock(view2.state.selection) || isInList(view2.state.selection))
@@ -1360,13 +2760,13 @@ class MenuView {
1360
2760
  if (!isSelectionAtEndOfNode(view2.state.selection)) {
1361
2761
  return false;
1362
2762
  }
1363
- const pos = __privateGet$4(self, _programmaticallyPos);
2763
+ const pos = __privateGet$5(self, _programmaticallyPos);
1364
2764
  filter.value = currentText.startsWith("/") ? currentText.slice(1) : currentText;
1365
2765
  if (typeof pos === "number") {
1366
2766
  const maxSize = view2.state.doc.nodeSize - 2;
1367
2767
  const validPos = Math.min(pos, maxSize);
1368
2768
  if (view2.state.doc.resolve(validPos).node() !== view2.state.doc.resolve(view2.state.selection.from).node()) {
1369
- __privateSet$4(self, _programmaticallyPos, null);
2769
+ __privateSet$5(self, _programmaticallyPos, null);
1370
2770
  return false;
1371
2771
  }
1372
2772
  return true;
@@ -1376,10 +2776,10 @@ class MenuView {
1376
2776
  },
1377
2777
  offset: 10
1378
2778
  }));
1379
- __privateGet$4(this, _slashProvider).onShow = () => {
2779
+ __privateGet$5(this, _slashProvider).onShow = () => {
1380
2780
  show.value = true;
1381
2781
  };
1382
- __privateGet$4(this, _slashProvider).onHide = () => {
2782
+ __privateGet$5(this, _slashProvider).onHide = () => {
1383
2783
  show.value = false;
1384
2784
  };
1385
2785
  this.update(view);
@@ -1390,7 +2790,7 @@ class MenuView {
1390
2790
  }
1391
2791
  }
1392
2792
  _content$3 = new WeakMap();
1393
- _app$3 = new WeakMap();
2793
+ _app$4 = new WeakMap();
1394
2794
  _filter = new WeakMap();
1395
2795
  _slashProvider = new WeakMap();
1396
2796
  _programmaticallyPos = new WeakMap();
@@ -1402,6 +2802,7 @@ function isSelectionAtEndOfNode(selection) {
1402
2802
  return offset === parent.content.size;
1403
2803
  }
1404
2804
 
2805
+ keepAlive(h, Fragment);
1405
2806
  const BlockHandle = defineComponent({
1406
2807
  props: {
1407
2808
  onAdd: {
@@ -1445,45 +2846,45 @@ const BlockHandle = defineComponent({
1445
2846
  }
1446
2847
  });
1447
2848
 
1448
- var __typeError$3 = (msg) => {
2849
+ var __typeError$4 = (msg) => {
1449
2850
  throw TypeError(msg);
1450
2851
  };
1451
- var __accessCheck$3 = (obj, member, msg) => member.has(obj) || __typeError$3("Cannot " + msg);
1452
- var __privateGet$3 = (obj, member, getter) => (__accessCheck$3(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
1453
- var __privateAdd$3 = (obj, member, value) => member.has(obj) ? __typeError$3("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
1454
- var __privateSet$3 = (obj, member, value, setter) => (__accessCheck$3(obj, member, "write to private field"), member.set(obj, value), value);
1455
- var _content$2, _provider$1, _app$2, _ctx;
2852
+ var __accessCheck$4 = (obj, member, msg) => member.has(obj) || __typeError$4("Cannot " + msg);
2853
+ var __privateGet$4 = (obj, member, getter) => (__accessCheck$4(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
2854
+ var __privateAdd$4 = (obj, member, value) => member.has(obj) ? __typeError$4("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
2855
+ var __privateSet$4 = (obj, member, value, setter) => (__accessCheck$4(obj, member, "write to private field"), member.set(obj, value), value);
2856
+ var _content$2, _provider$1, _app$3, _ctx;
1456
2857
  class BlockHandleView {
1457
2858
  constructor(ctx, config) {
1458
- __privateAdd$3(this, _content$2);
1459
- __privateAdd$3(this, _provider$1);
1460
- __privateAdd$3(this, _app$2);
1461
- __privateAdd$3(this, _ctx);
2859
+ __privateAdd$4(this, _content$2);
2860
+ __privateAdd$4(this, _provider$1);
2861
+ __privateAdd$4(this, _app$3);
2862
+ __privateAdd$4(this, _ctx);
1462
2863
  this.update = () => {
1463
- __privateGet$3(this, _provider$1).update();
2864
+ __privateGet$4(this, _provider$1).update();
1464
2865
  };
1465
2866
  this.destroy = () => {
1466
- __privateGet$3(this, _provider$1).destroy();
1467
- __privateGet$3(this, _content$2).remove();
1468
- __privateGet$3(this, _app$2).unmount();
2867
+ __privateGet$4(this, _provider$1).destroy();
2868
+ __privateGet$4(this, _content$2).remove();
2869
+ __privateGet$4(this, _app$3).unmount();
1469
2870
  };
1470
2871
  this.onAdd = () => {
1471
- const ctx = __privateGet$3(this, _ctx);
2872
+ const ctx = __privateGet$4(this, _ctx);
1472
2873
  const view = ctx.get(editorViewCtx);
1473
2874
  if (!view.hasFocus()) view.focus();
1474
2875
  const { state, dispatch } = view;
1475
- const active = __privateGet$3(this, _provider$1).active;
2876
+ const active = __privateGet$4(this, _provider$1).active;
1476
2877
  if (!active) return;
1477
2878
  const $pos = active.$pos;
1478
2879
  const pos = $pos.pos + active.node.nodeSize;
1479
2880
  let tr = state.tr.insert(pos, paragraphSchema.type(ctx).create());
1480
2881
  tr = tr.setSelection(TextSelection.near(tr.doc.resolve(pos)));
1481
2882
  dispatch(tr.scrollIntoView());
1482
- __privateGet$3(this, _provider$1).hide();
2883
+ __privateGet$4(this, _provider$1).hide();
1483
2884
  ctx.get(menuAPI.key).show(tr.selection.from);
1484
2885
  };
1485
2886
  var _a, _b, _c;
1486
- __privateSet$3(this, _ctx, ctx);
2887
+ __privateSet$4(this, _ctx, ctx);
1487
2888
  const content = document.createElement("div");
1488
2889
  content.classList.add("milkdown-block-handle");
1489
2890
  const app = createApp(BlockHandle, {
@@ -1492,10 +2893,10 @@ class BlockHandleView {
1492
2893
  handleIcon: (_b = config == null ? void 0 : config.handleDragIcon) != null ? _b : menuIcon
1493
2894
  });
1494
2895
  app.mount(content);
1495
- __privateSet$3(this, _app$2, app);
1496
- __privateSet$3(this, _content$2, content);
2896
+ __privateSet$4(this, _app$3, app);
2897
+ __privateSet$4(this, _content$2, content);
1497
2898
  const blockProviderOptions = (_c = config == null ? void 0 : config.blockHandle) != null ? _c : {};
1498
- __privateSet$3(this, _provider$1, new BlockProvider({
2899
+ __privateSet$4(this, _provider$1, new BlockProvider({
1499
2900
  ctx,
1500
2901
  content,
1501
2902
  getOffset: () => 16,
@@ -1522,7 +2923,7 @@ class BlockHandleView {
1522
2923
  }
1523
2924
  _content$2 = new WeakMap();
1524
2925
  _provider$1 = new WeakMap();
1525
- _app$2 = new WeakMap();
2926
+ _app$3 = new WeakMap();
1526
2927
  _ctx = new WeakMap();
1527
2928
  function configureBlockHandle(ctx, config) {
1528
2929
  ctx.set(blockConfig.key, {
@@ -1628,7 +3029,9 @@ const imageBlock = (editor, config) => {
1628
3029
  uploadPlaceholderText: (_f = config == null ? void 0 : config.blockUploadPlaceholderText) != null ? _f : "or paste link",
1629
3030
  onUpload: (_h = (_g = config == null ? void 0 : config.blockOnUpload) != null ? _g : config == null ? void 0 : config.onUpload) != null ? _h : value.onUpload,
1630
3031
  proxyDomURL: config == null ? void 0 : config.proxyDomURL,
1631
- onImageLoadError: (_i = config == null ? void 0 : config.onImageLoadError) != null ? _i : value.onImageLoadError
3032
+ onImageLoadError: (_i = config == null ? void 0 : config.onImageLoadError) != null ? _i : value.onImageLoadError,
3033
+ maxWidth: config == null ? void 0 : config.maxWidth,
3034
+ maxHeight: config == null ? void 0 : config.maxHeight
1632
3035
  };
1633
3036
  });
1634
3037
  }).use(imageBlockComponent).use(imageInlineComponent);
@@ -1745,6 +3148,7 @@ const toggleLatexCommand = $command("ToggleLatex", (ctx) => {
1745
3148
 
1746
3149
  const inlineLatexTooltip = tooltipFactory("INLINE_LATEX");
1747
3150
 
3151
+ keepAlive(h);
1748
3152
  const LatexTooltip = defineComponent({
1749
3153
  props: {
1750
3154
  config: {
@@ -1780,32 +3184,33 @@ const LatexTooltip = defineComponent({
1780
3184
  }
1781
3185
  });
1782
3186
 
1783
- var __typeError$2 = (msg) => {
3187
+ var __typeError$3 = (msg) => {
1784
3188
  throw TypeError(msg);
1785
3189
  };
1786
- var __accessCheck$2 = (obj, member, msg) => member.has(obj) || __typeError$2("Cannot " + msg);
1787
- var __privateGet$2 = (obj, member, getter) => (__accessCheck$2(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
1788
- var __privateAdd$2 = (obj, member, value) => member.has(obj) ? __typeError$2("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
1789
- var __privateSet$2 = (obj, member, value, setter) => (__accessCheck$2(obj, member, "write to private field"), member.set(obj, value), value);
1790
- var _content$1, _provider, _dom, _innerView, _updateValue, _app$1, _onHide, _shouldShow;
3190
+ var __accessCheck$3 = (obj, member, msg) => member.has(obj) || __typeError$3("Cannot " + msg);
3191
+ var __privateGet$3 = (obj, member, getter) => (__accessCheck$3(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
3192
+ var __privateAdd$3 = (obj, member, value) => member.has(obj) ? __typeError$3("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
3193
+ var __privateSet$3 = (obj, member, value, setter) => (__accessCheck$3(obj, member, "write to private field"), member.set(obj, value), value);
3194
+ var _content$1, _provider, _dom, _innerView, _updateValue, _app$2, _onHide, _shouldShow;
1791
3195
  class LatexInlineTooltip {
1792
3196
  constructor(ctx, view, config) {
1793
3197
  this.ctx = ctx;
1794
- __privateAdd$2(this, _content$1);
1795
- __privateAdd$2(this, _provider);
1796
- __privateAdd$2(this, _dom);
1797
- __privateAdd$2(this, _innerView, shallowRef(null));
1798
- __privateAdd$2(this, _updateValue, shallowRef(() => {
3198
+ __privateAdd$3(this, _content$1);
3199
+ __privateAdd$3(this, _provider);
3200
+ __privateAdd$3(this, _dom);
3201
+ __privateAdd$3(this, _innerView, shallowRef(null));
3202
+ __privateAdd$3(this, _updateValue, shallowRef(() => {
1799
3203
  }));
1800
- __privateAdd$2(this, _app$1);
1801
- __privateAdd$2(this, _onHide, () => {
1802
- if (__privateGet$2(this, _innerView).value) {
1803
- __privateGet$2(this, _innerView).value.destroy();
1804
- __privateGet$2(this, _innerView).value = null;
3204
+ __privateAdd$3(this, _app$2);
3205
+ __privateAdd$3(this, _onHide, () => {
3206
+ if (__privateGet$3(this, _innerView).value) {
3207
+ __privateGet$3(this, _innerView).value.destroy();
3208
+ __privateGet$3(this, _innerView).value = null;
1805
3209
  }
1806
3210
  });
1807
- __privateAdd$2(this, _shouldShow, (view) => {
3211
+ __privateAdd$3(this, _shouldShow, (view) => {
1808
3212
  const shouldShow = () => {
3213
+ if (!view.editable) return false;
1809
3214
  const { selection, schema } = view.state;
1810
3215
  if (selection.empty) return false;
1811
3216
  if (!(selection instanceof NodeSelection)) return false;
@@ -1816,7 +3221,7 @@ class LatexInlineTooltip {
1816
3221
  null,
1817
3222
  schema.text(node.attrs.value)
1818
3223
  );
1819
- const innerView = new EditorView(__privateGet$2(this, _dom), {
3224
+ const innerView = new EditorView(__privateGet$3(this, _dom), {
1820
3225
  state: EditorState.create({
1821
3226
  doc: paragraph,
1822
3227
  schema: new Schema({
@@ -1843,15 +3248,15 @@ class LatexInlineTooltip {
1843
3248
  "Mod-Z": redo,
1844
3249
  "Mod-y": redo,
1845
3250
  Enter: () => {
1846
- __privateGet$2(this, _updateValue).value();
3251
+ __privateGet$3(this, _updateValue).value();
1847
3252
  return true;
1848
3253
  }
1849
3254
  })
1850
3255
  ]
1851
3256
  })
1852
3257
  });
1853
- __privateGet$2(this, _innerView).value = innerView;
1854
- __privateGet$2(this, _updateValue).value = () => {
3258
+ __privateGet$3(this, _innerView).value = innerView;
3259
+ __privateGet$3(this, _updateValue).value = () => {
1855
3260
  const { tr } = view.state;
1856
3261
  tr.setNodeAttribute(textFrom, "value", innerView.state.doc.textContent);
1857
3262
  view.dispatch(tr);
@@ -1862,37 +3267,37 @@ class LatexInlineTooltip {
1862
3267
  return true;
1863
3268
  };
1864
3269
  const show = shouldShow();
1865
- if (!show) __privateGet$2(this, _onHide).call(this);
3270
+ if (!show) __privateGet$3(this, _onHide).call(this);
1866
3271
  return show;
1867
3272
  });
1868
3273
  this.update = (view, prevState) => {
1869
- __privateGet$2(this, _provider).update(view, prevState);
3274
+ __privateGet$3(this, _provider).update(view, prevState);
1870
3275
  };
1871
3276
  this.destroy = () => {
1872
- __privateGet$2(this, _app$1).unmount();
1873
- __privateGet$2(this, _provider).destroy();
1874
- __privateGet$2(this, _content$1).remove();
3277
+ __privateGet$3(this, _app$2).unmount();
3278
+ __privateGet$3(this, _provider).destroy();
3279
+ __privateGet$3(this, _content$1).remove();
1875
3280
  };
1876
3281
  const content = document.createElement("div");
1877
3282
  content.className = "milkdown-latex-inline-edit";
1878
- __privateSet$2(this, _content$1, content);
1879
- __privateSet$2(this, _app$1, createApp(LatexTooltip, {
3283
+ __privateSet$3(this, _content$1, content);
3284
+ __privateSet$3(this, _app$2, createApp(LatexTooltip, {
1880
3285
  config,
1881
- innerView: __privateGet$2(this, _innerView),
1882
- updateValue: __privateGet$2(this, _updateValue)
3286
+ innerView: __privateGet$3(this, _innerView),
3287
+ updateValue: __privateGet$3(this, _updateValue)
1883
3288
  }));
1884
- __privateGet$2(this, _app$1).mount(content);
1885
- __privateSet$2(this, _provider, new TooltipProvider({
3289
+ __privateGet$3(this, _app$2).mount(content);
3290
+ __privateSet$3(this, _provider, new TooltipProvider({
1886
3291
  debounce: 0,
1887
- content: __privateGet$2(this, _content$1),
1888
- shouldShow: __privateGet$2(this, _shouldShow),
3292
+ content: __privateGet$3(this, _content$1),
3293
+ shouldShow: __privateGet$3(this, _shouldShow),
1889
3294
  offset: 10,
1890
3295
  floatingUIOptions: {
1891
3296
  placement: "bottom"
1892
3297
  }
1893
3298
  }));
1894
- __privateGet$2(this, _provider).update(view);
1895
- __privateSet$2(this, _dom, document.createElement("div"));
3299
+ __privateGet$3(this, _provider).update(view);
3300
+ __privateSet$3(this, _dom, document.createElement("div"));
1896
3301
  }
1897
3302
  }
1898
3303
  _content$1 = new WeakMap();
@@ -1900,7 +3305,7 @@ _provider = new WeakMap();
1900
3305
  _dom = new WeakMap();
1901
3306
  _innerView = new WeakMap();
1902
3307
  _updateValue = new WeakMap();
1903
- _app$1 = new WeakMap();
3308
+ _app$2 = new WeakMap();
1904
3309
  _onHide = new WeakMap();
1905
3310
  _shouldShow = new WeakMap();
1906
3311
 
@@ -2105,8 +3510,8 @@ const table = (editor, config) => {
2105
3510
  }).use(tableBlock);
2106
3511
  };
2107
3512
 
2108
- function getGroups(config, ctx) {
2109
- var _a, _b, _c, _d, _e, _f, _g;
3513
+ function getGroups$1(config, ctx) {
3514
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
2110
3515
  const groupBuilder = new GroupBuilder();
2111
3516
  groupBuilder.addGroup("formatting", "Formatting").addItem("bold", {
2112
3517
  icon: (_a = config == null ? void 0 : config.boldIcon) != null ? _a : boldIcon,
@@ -2189,10 +3594,26 @@ function getGroups(config, ctx) {
2189
3594
  commands.call(toggleLinkCommand.key);
2190
3595
  }
2191
3596
  });
2192
- (_g = config == null ? void 0 : config.buildToolbar) == null ? void 0 : _g.call(config, groupBuilder);
3597
+ if (ctx && (flags == null ? void 0 : flags.includes(CrepeFeature.AI))) {
3598
+ const aiCfg = ctx.get(aiProviderConfig.key);
3599
+ if (aiCfg.provider) {
3600
+ functionGroup.addItem("ai", {
3601
+ icon: (_h = (_g = config == null ? void 0 : config.aiIcon) != null ? _g : aiCfg.aiIcon) != null ? _h : aiIcon,
3602
+ active: () => false,
3603
+ onRun: (ctx2) => {
3604
+ const api = ctx2.get(aiInstructionTooltipAPI.key);
3605
+ const view = ctx2.get(editorViewCtx);
3606
+ const { from, to } = view.state.selection;
3607
+ api.show(from, to);
3608
+ }
3609
+ });
3610
+ }
3611
+ }
3612
+ (_i = config == null ? void 0 : config.buildToolbar) == null ? void 0 : _i.call(config, groupBuilder);
2193
3613
  return groupBuilder.build();
2194
3614
  }
2195
3615
 
3616
+ keepAlive(h, Fragment);
2196
3617
  const Toolbar = defineComponent({
2197
3618
  props: {
2198
3619
  ctx: {
@@ -2220,15 +3641,17 @@ const Toolbar = defineComponent({
2220
3641
  const { ctx, config } = props;
2221
3642
  const onClick = (fn) => (e) => {
2222
3643
  e.preventDefault();
2223
- ctx && fn(ctx);
3644
+ if (ctx) {
3645
+ fn == null ? void 0 : fn(ctx);
3646
+ }
2224
3647
  };
2225
3648
  function checkActive(checker) {
2226
- props.selection.value;
3649
+ keepAlive(props.selection.value);
2227
3650
  const status = ctx.get(editorCtx).status;
2228
3651
  if (status !== EditorStatus.Created) return false;
2229
3652
  return checker(ctx);
2230
3653
  }
2231
- const groupInfo = computed(() => getGroups(config, ctx));
3654
+ const groupInfo = computed(() => getGroups$1(config, ctx));
2232
3655
  return () => {
2233
3656
  return /* @__PURE__ */ h(Fragment, null, groupInfo.value.map((group) => {
2234
3657
  return group.items.map((item) => {
@@ -2257,49 +3680,49 @@ const Toolbar = defineComponent({
2257
3680
  }
2258
3681
  });
2259
3682
 
2260
- var __typeError$1 = (msg) => {
3683
+ var __typeError$2 = (msg) => {
2261
3684
  throw TypeError(msg);
2262
3685
  };
2263
- var __accessCheck$1 = (obj, member, msg) => member.has(obj) || __typeError$1("Cannot " + msg);
2264
- var __privateGet$1 = (obj, member, getter) => (__accessCheck$1(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
2265
- 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);
2266
- var __privateSet$1 = (obj, member, value, setter) => (__accessCheck$1(obj, member, "write to private field"), member.set(obj, value), value);
2267
- var _tooltipProvider, _content, _app, _selection, _show;
3686
+ var __accessCheck$2 = (obj, member, msg) => member.has(obj) || __typeError$2("Cannot " + msg);
3687
+ var __privateGet$2 = (obj, member, getter) => (__accessCheck$2(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
3688
+ var __privateAdd$2 = (obj, member, value) => member.has(obj) ? __typeError$2("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
3689
+ var __privateSet$2 = (obj, member, value, setter) => (__accessCheck$2(obj, member, "write to private field"), member.set(obj, value), value);
3690
+ var _tooltipProvider, _content, _app$1, _selection, _show;
2268
3691
  const toolbarTooltip = tooltipFactory("CREPE_TOOLBAR");
2269
3692
  class ToolbarView {
2270
3693
  constructor(ctx, view, config) {
2271
- __privateAdd$1(this, _tooltipProvider);
2272
- __privateAdd$1(this, _content);
2273
- __privateAdd$1(this, _app);
2274
- __privateAdd$1(this, _selection);
2275
- __privateAdd$1(this, _show, ref(false));
3694
+ __privateAdd$2(this, _tooltipProvider);
3695
+ __privateAdd$2(this, _content);
3696
+ __privateAdd$2(this, _app$1);
3697
+ __privateAdd$2(this, _selection);
3698
+ __privateAdd$2(this, _show, ref(false));
2276
3699
  this.update = (view, prevState) => {
2277
- __privateGet$1(this, _tooltipProvider).update(view, prevState);
2278
- __privateGet$1(this, _selection).value = view.state.selection;
3700
+ __privateGet$2(this, _tooltipProvider).update(view, prevState);
3701
+ __privateGet$2(this, _selection).value = view.state.selection;
2279
3702
  };
2280
3703
  this.destroy = () => {
2281
- __privateGet$1(this, _tooltipProvider).destroy();
2282
- __privateGet$1(this, _app).unmount();
2283
- __privateGet$1(this, _content).remove();
3704
+ __privateGet$2(this, _tooltipProvider).destroy();
3705
+ __privateGet$2(this, _app$1).unmount();
3706
+ __privateGet$2(this, _content).remove();
2284
3707
  };
2285
3708
  this.hide = () => {
2286
- __privateGet$1(this, _tooltipProvider).hide();
3709
+ __privateGet$2(this, _tooltipProvider).hide();
2287
3710
  };
2288
3711
  const content = document.createElement("div");
2289
3712
  content.className = "milkdown-toolbar";
2290
- __privateSet$1(this, _selection, shallowRef(view.state.selection));
3713
+ __privateSet$2(this, _selection, shallowRef(view.state.selection));
2291
3714
  const app = createApp(Toolbar, {
2292
3715
  ctx,
2293
3716
  hide: this.hide,
2294
3717
  config,
2295
- selection: __privateGet$1(this, _selection),
2296
- show: __privateGet$1(this, _show)
3718
+ selection: __privateGet$2(this, _selection),
3719
+ show: __privateGet$2(this, _show)
2297
3720
  });
2298
3721
  app.mount(content);
2299
- __privateSet$1(this, _content, content);
2300
- __privateSet$1(this, _app, app);
2301
- __privateSet$1(this, _tooltipProvider, new TooltipProvider({
2302
- content: __privateGet$1(this, _content),
3722
+ __privateSet$2(this, _content, content);
3723
+ __privateSet$2(this, _app$1, app);
3724
+ __privateSet$2(this, _tooltipProvider, new TooltipProvider({
3725
+ content: __privateGet$2(this, _content),
2303
3726
  debounce: 20,
2304
3727
  offset: 10,
2305
3728
  shouldShow(view2) {
@@ -2316,18 +3739,18 @@ class ToolbarView {
2316
3739
  return true;
2317
3740
  }
2318
3741
  }));
2319
- __privateGet$1(this, _tooltipProvider).onShow = () => {
2320
- __privateGet$1(this, _show).value = true;
3742
+ __privateGet$2(this, _tooltipProvider).onShow = () => {
3743
+ __privateGet$2(this, _show).value = true;
2321
3744
  };
2322
- __privateGet$1(this, _tooltipProvider).onHide = () => {
2323
- __privateGet$1(this, _show).value = false;
3745
+ __privateGet$2(this, _tooltipProvider).onHide = () => {
3746
+ __privateGet$2(this, _show).value = false;
2324
3747
  };
2325
3748
  this.update(view);
2326
3749
  }
2327
3750
  }
2328
3751
  _tooltipProvider = new WeakMap();
2329
3752
  _content = new WeakMap();
2330
- _app = new WeakMap();
3753
+ _app$1 = new WeakMap();
2331
3754
  _selection = new WeakMap();
2332
3755
  _show = new WeakMap();
2333
3756
  const toolbar = (editor, config) => {
@@ -2338,6 +3761,442 @@ const toolbar = (editor, config) => {
2338
3761
  }).use(toolbarTooltip);
2339
3762
  };
2340
3763
 
3764
+ const defaultHeadingOptions = [
3765
+ { label: "Paragraph", level: null },
3766
+ { label: "Heading 1", level: 1 },
3767
+ { label: "Heading 2", level: 2 },
3768
+ { label: "Heading 3", level: 3 },
3769
+ { label: "Heading 4", level: 4 },
3770
+ { label: "Heading 5", level: 5 },
3771
+ { label: "Heading 6", level: 6 }
3772
+ ];
3773
+ function getCurrentHeading(ctx, options) {
3774
+ var _a, _b;
3775
+ const headingOptions = options != null ? options : defaultHeadingOptions;
3776
+ const view = ctx.get(editorViewCtx);
3777
+ const { $from } = view.state.selection;
3778
+ const node = $from.parent;
3779
+ const paragraphOption = (_a = headingOptions.find((o) => o.level === null)) != null ? _a : headingOptions[0];
3780
+ if (node.type === headingSchema.type(ctx)) {
3781
+ const level = node.attrs.level;
3782
+ return (_b = headingOptions.find((o) => o.level === level)) != null ? _b : paragraphOption;
3783
+ }
3784
+ return paragraphOption;
3785
+ }
3786
+ function setHeading(ctx, level) {
3787
+ const commands = ctx.get(commandsCtx);
3788
+ if (level === null || level === void 0) {
3789
+ const paragraph = paragraphSchema.type(ctx);
3790
+ commands.call(setBlockTypeCommand.key, { nodeType: paragraph });
3791
+ } else {
3792
+ const heading = headingSchema.type(ctx);
3793
+ commands.call(setBlockTypeCommand.key, {
3794
+ nodeType: heading,
3795
+ attrs: { level }
3796
+ });
3797
+ }
3798
+ }
3799
+ function isMarkActive(ctx, markType) {
3800
+ const commands = ctx.get(commandsCtx);
3801
+ const selected = commands.call(isMarkSelectedCommand.key, markType);
3802
+ if (selected) return true;
3803
+ const view = ctx.get(editorViewCtx);
3804
+ const { state } = view;
3805
+ if (state.storedMarks) {
3806
+ return state.storedMarks.some((m) => m.type === markType);
3807
+ }
3808
+ if (state.selection instanceof TextSelection) {
3809
+ const { $cursor } = state.selection;
3810
+ if ($cursor) {
3811
+ return $cursor.marks().some((m) => m.type === markType);
3812
+ }
3813
+ }
3814
+ return false;
3815
+ }
3816
+ function buildHeadingSelector(headingOptions, chevronIcon) {
3817
+ const options = headingOptions != null ? headingOptions : defaultHeadingOptions;
3818
+ return {
3819
+ icon: "",
3820
+ active: () => false,
3821
+ selector: {
3822
+ chevronIcon: chevronIcon != null ? chevronIcon : chevronDownIcon,
3823
+ activeLabel: (ctx) => getCurrentHeading(ctx, options).label,
3824
+ options: options.map((opt) => ({
3825
+ label: opt.label,
3826
+ onSelect: (ctx) => setHeading(ctx, opt.level)
3827
+ }))
3828
+ }
3829
+ };
3830
+ }
3831
+ function getGroups(config, ctx) {
3832
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o;
3833
+ const flags = ctx && useCrepeFeatures(ctx).get();
3834
+ const isLatexEnabled = flags == null ? void 0 : flags.includes(CrepeFeature.Latex);
3835
+ const isImageBlockEnabled = flags == null ? void 0 : flags.includes(CrepeFeature.ImageBlock);
3836
+ const isTableEnabled = flags == null ? void 0 : flags.includes(CrepeFeature.Table);
3837
+ const groupBuilder = new GroupBuilder();
3838
+ groupBuilder.addGroup("heading", "Heading").addItem("heading-selector", {
3839
+ ...buildHeadingSelector(config == null ? void 0 : config.headingOptions, config == null ? void 0 : config.chevronDownIcon)
3840
+ });
3841
+ groupBuilder.addGroup("formatting", "Formatting").addItem("bold", {
3842
+ icon: (_a = config == null ? void 0 : config.boldIcon) != null ? _a : boldIcon,
3843
+ active: (ctx2) => isMarkActive(ctx2, strongSchema.type(ctx2)),
3844
+ onRun: (ctx2) => {
3845
+ const commands = ctx2.get(commandsCtx);
3846
+ commands.call(toggleStrongCommand.key);
3847
+ }
3848
+ }).addItem("italic", {
3849
+ icon: (_b = config == null ? void 0 : config.italicIcon) != null ? _b : italicIcon,
3850
+ active: (ctx2) => isMarkActive(ctx2, emphasisSchema.type(ctx2)),
3851
+ onRun: (ctx2) => {
3852
+ const commands = ctx2.get(commandsCtx);
3853
+ commands.call(toggleEmphasisCommand.key);
3854
+ }
3855
+ }).addItem("strikethrough", {
3856
+ icon: (_c = config == null ? void 0 : config.strikethroughIcon) != null ? _c : strikethroughIcon,
3857
+ active: (ctx2) => isMarkActive(ctx2, strikethroughSchema.type(ctx2)),
3858
+ onRun: (ctx2) => {
3859
+ const commands = ctx2.get(commandsCtx);
3860
+ commands.call(toggleStrikethroughCommand.key);
3861
+ }
3862
+ }).addItem("code", {
3863
+ icon: (_d = config == null ? void 0 : config.codeIcon) != null ? _d : codeIcon,
3864
+ active: (ctx2) => isMarkActive(ctx2, inlineCodeSchema.type(ctx2)),
3865
+ onRun: (ctx2) => {
3866
+ const view = ctx2.get(editorViewCtx);
3867
+ const { state } = view;
3868
+ if (state.selection.empty) {
3869
+ const markType = inlineCodeSchema.type(ctx2);
3870
+ const has = isMarkActive(ctx2, markType);
3871
+ if (has) {
3872
+ view.dispatch(state.tr.removeStoredMark(markType));
3873
+ } else {
3874
+ view.dispatch(state.tr.addStoredMark(markType.create()));
3875
+ }
3876
+ } else {
3877
+ const commands = ctx2.get(commandsCtx);
3878
+ commands.call(toggleInlineCodeCommand.key);
3879
+ }
3880
+ }
3881
+ });
3882
+ groupBuilder.addGroup("list", "List").addItem("bullet-list", {
3883
+ icon: (_e = config == null ? void 0 : config.bulletListIcon) != null ? _e : bulletListIcon,
3884
+ active: () => false,
3885
+ onRun: (ctx2) => {
3886
+ const commands = ctx2.get(commandsCtx);
3887
+ const bulletList = bulletListSchema.type(ctx2);
3888
+ commands.call(wrapInBlockTypeCommand.key, { nodeType: bulletList });
3889
+ }
3890
+ }).addItem("ordered-list", {
3891
+ icon: (_f = config == null ? void 0 : config.orderedListIcon) != null ? _f : orderedListIcon,
3892
+ active: () => false,
3893
+ onRun: (ctx2) => {
3894
+ const commands = ctx2.get(commandsCtx);
3895
+ const orderedList = orderedListSchema.type(ctx2);
3896
+ commands.call(wrapInBlockTypeCommand.key, { nodeType: orderedList });
3897
+ }
3898
+ }).addItem("task-list", {
3899
+ icon: (_g = config == null ? void 0 : config.taskListIcon) != null ? _g : todoListIcon,
3900
+ active: () => false,
3901
+ onRun: (ctx2) => {
3902
+ const commands = ctx2.get(commandsCtx);
3903
+ const listItem = listItemSchema.type(ctx2);
3904
+ commands.call(wrapInBlockTypeCommand.key, {
3905
+ nodeType: listItem,
3906
+ attrs: { checked: false }
3907
+ });
3908
+ }
3909
+ });
3910
+ const insertGroup = groupBuilder.addGroup("insert", "Insert");
3911
+ insertGroup.addItem("link", {
3912
+ icon: (_h = config == null ? void 0 : config.linkIcon) != null ? _h : linkIcon,
3913
+ active: (ctx2) => isMarkActive(ctx2, linkSchema.type(ctx2)),
3914
+ onRun: (ctx2) => {
3915
+ const view = ctx2.get(editorViewCtx);
3916
+ const { state } = view;
3917
+ const markType = linkSchema.type(ctx2);
3918
+ if (state.selection.empty && isMarkActive(ctx2, markType)) {
3919
+ view.dispatch(state.tr.removeStoredMark(markType));
3920
+ return;
3921
+ }
3922
+ const commands = ctx2.get(commandsCtx);
3923
+ commands.call(toggleLinkCommand.key);
3924
+ }
3925
+ });
3926
+ if (isImageBlockEnabled) {
3927
+ insertGroup.addItem("image", {
3928
+ icon: (_i = config == null ? void 0 : config.imageIcon) != null ? _i : imageIcon,
3929
+ active: () => false,
3930
+ onRun: (ctx2) => {
3931
+ const commands = ctx2.get(commandsCtx);
3932
+ const imageBlock = imageBlockSchema.type(ctx2);
3933
+ commands.call(addBlockTypeCommand.key, { nodeType: imageBlock });
3934
+ }
3935
+ });
3936
+ }
3937
+ if (isTableEnabled) {
3938
+ insertGroup.addItem("table", {
3939
+ icon: (_j = config == null ? void 0 : config.tableIcon) != null ? _j : tableIcon,
3940
+ active: () => false,
3941
+ onRun: (ctx2) => {
3942
+ const commands = ctx2.get(commandsCtx);
3943
+ const view = ctx2.get(editorViewCtx);
3944
+ const { from } = view.state.selection;
3945
+ commands.call(addBlockTypeCommand.key, {
3946
+ nodeType: createTable(ctx2, 3, 3)
3947
+ });
3948
+ commands.call(selectTextNearPosCommand.key, { pos: from });
3949
+ }
3950
+ });
3951
+ }
3952
+ const blockGroup = groupBuilder.addGroup("block", "Block");
3953
+ blockGroup.addItem("code-block", {
3954
+ icon: (_k = config == null ? void 0 : config.codeBlockIcon) != null ? _k : codeBlockIcon,
3955
+ active: () => false,
3956
+ onRun: (ctx2) => {
3957
+ const commands = ctx2.get(commandsCtx);
3958
+ const codeBlock = codeBlockSchema.type(ctx2);
3959
+ commands.call(setBlockTypeCommand.key, { nodeType: codeBlock });
3960
+ }
3961
+ });
3962
+ if (isLatexEnabled) {
3963
+ blockGroup.addItem("math", {
3964
+ icon: (_l = config == null ? void 0 : config.mathIcon) != null ? _l : functionsIcon,
3965
+ active: () => false,
3966
+ onRun: (ctx2) => {
3967
+ const commands = ctx2.get(commandsCtx);
3968
+ const codeBlock = codeBlockSchema.type(ctx2);
3969
+ commands.call(addBlockTypeCommand.key, {
3970
+ nodeType: codeBlock,
3971
+ attrs: { language: "LaTeX" }
3972
+ });
3973
+ }
3974
+ });
3975
+ }
3976
+ groupBuilder.addGroup("more", "More").addItem("quote", {
3977
+ icon: (_m = config == null ? void 0 : config.quoteIcon) != null ? _m : quoteIcon,
3978
+ active: () => false,
3979
+ onRun: (ctx2) => {
3980
+ const commands = ctx2.get(commandsCtx);
3981
+ const blockquote = blockquoteSchema.type(ctx2);
3982
+ commands.call(wrapInBlockTypeCommand.key, { nodeType: blockquote });
3983
+ }
3984
+ }).addItem("hr", {
3985
+ icon: (_n = config == null ? void 0 : config.hrIcon) != null ? _n : dividerIcon,
3986
+ active: () => false,
3987
+ onRun: (ctx2) => {
3988
+ const commands = ctx2.get(commandsCtx);
3989
+ const hr = hrSchema.type(ctx2);
3990
+ commands.call(addBlockTypeCommand.key, { nodeType: hr });
3991
+ }
3992
+ });
3993
+ (_o = config == null ? void 0 : config.buildTopBar) == null ? void 0 : _o.call(config, groupBuilder);
3994
+ return groupBuilder.build();
3995
+ }
3996
+
3997
+ keepAlive(h, Fragment);
3998
+ const TopBar = defineComponent({
3999
+ props: {
4000
+ ctx: {
4001
+ type: Object,
4002
+ required: true
4003
+ },
4004
+ version: {
4005
+ type: Object,
4006
+ required: true
4007
+ },
4008
+ config: {
4009
+ type: Object,
4010
+ required: false
4011
+ }
4012
+ },
4013
+ setup(props) {
4014
+ const { ctx, config } = props;
4015
+ const openSelectorKey = ref(null);
4016
+ const onClick = (fn) => (e) => {
4017
+ e.preventDefault();
4018
+ if (ctx) {
4019
+ fn(ctx);
4020
+ }
4021
+ };
4022
+ function isReady() {
4023
+ const status = ctx.get(editorCtx).status;
4024
+ return status === EditorStatus.Created;
4025
+ }
4026
+ function subscribeState() {
4027
+ keepAlive(props.version.value);
4028
+ }
4029
+ function checkActive(checker) {
4030
+ subscribeState();
4031
+ if (!isReady()) return false;
4032
+ return checker(ctx);
4033
+ }
4034
+ function getSelectorLabel(selector) {
4035
+ var _a, _b;
4036
+ subscribeState();
4037
+ if (!isReady()) return (_b = (_a = selector.options[0]) == null ? void 0 : _a.label) != null ? _b : "";
4038
+ return selector.activeLabel(ctx);
4039
+ }
4040
+ function onToggleSelector(key, e) {
4041
+ e.preventDefault();
4042
+ e.stopPropagation();
4043
+ openSelectorKey.value = openSelectorKey.value === key ? null : key;
4044
+ }
4045
+ const clickOutsideHandler = (e) => {
4046
+ const target = e.target;
4047
+ if (target.closest(".top-bar-heading-selector")) return;
4048
+ openSelectorKey.value = null;
4049
+ };
4050
+ onMounted(() => {
4051
+ window.addEventListener("pointerdown", clickOutsideHandler);
4052
+ });
4053
+ onUnmounted(() => {
4054
+ window.removeEventListener("pointerdown", clickOutsideHandler);
4055
+ });
4056
+ const groupInfo = computed(() => getGroups(config, ctx));
4057
+ function renderSelector(itemKey, selector) {
4058
+ const isOpen = openSelectorKey.value === itemKey;
4059
+ const activeLabel = getSelectorLabel(selector);
4060
+ return /* @__PURE__ */ h("div", { key: itemKey, class: "top-bar-heading-selector" }, /* @__PURE__ */ h(
4061
+ "button",
4062
+ {
4063
+ type: "button",
4064
+ class: "top-bar-heading-button",
4065
+ onPointerdown: (e) => onToggleSelector(itemKey, e)
4066
+ },
4067
+ /* @__PURE__ */ h("span", { class: "top-bar-heading-label" }, activeLabel),
4068
+ selector.chevronIcon && /* @__PURE__ */ h("span", { class: "top-bar-chevron" }, /* @__PURE__ */ h(Icon, { icon: selector.chevronIcon }))
4069
+ ), isOpen && /* @__PURE__ */ h("div", { class: "top-bar-heading-dropdown" }, selector.options.map((option, index) => /* @__PURE__ */ h(
4070
+ "button",
4071
+ {
4072
+ key: `${itemKey}-${index}`,
4073
+ type: "button",
4074
+ class: clsx(
4075
+ "top-bar-heading-option",
4076
+ activeLabel === option.label && "active"
4077
+ ),
4078
+ onPointerdown: (e) => {
4079
+ e.preventDefault();
4080
+ e.stopPropagation();
4081
+ openSelectorKey.value = null;
4082
+ option.onSelect(ctx);
4083
+ }
4084
+ },
4085
+ option.label
4086
+ ))));
4087
+ }
4088
+ function renderButton(item) {
4089
+ return /* @__PURE__ */ h(
4090
+ "button",
4091
+ {
4092
+ key: item.key,
4093
+ type: "button",
4094
+ class: clsx("top-bar-item", checkActive(item.active) && "active"),
4095
+ onPointerdown: onClick(item.onRun)
4096
+ },
4097
+ /* @__PURE__ */ h(Icon, { icon: item.icon })
4098
+ );
4099
+ }
4100
+ return () => {
4101
+ const view = isReady() ? ctx.get(editorViewCtx) : null;
4102
+ const isReadonly = view ? !view.editable : false;
4103
+ if (isReadonly) return null;
4104
+ return /* @__PURE__ */ h("div", { class: "top-bar-inner" }, groupInfo.value.map((group) => {
4105
+ return group.items.map((item) => {
4106
+ if (item.selector) {
4107
+ return renderSelector(item.key, item.selector);
4108
+ }
4109
+ if (!item.onRun) return null;
4110
+ return renderButton(
4111
+ item
4112
+ );
4113
+ });
4114
+ }).reduce((acc, curr, index) => {
4115
+ var _a, _b;
4116
+ if (index === 0) {
4117
+ acc.push(...curr);
4118
+ } else {
4119
+ const groupKey = (_b = (_a = groupInfo.value[index]) == null ? void 0 : _a.key) != null ? _b : index;
4120
+ acc.push(
4121
+ /* @__PURE__ */ h("div", { key: `divider-${groupKey}`, class: "top-bar-divider" }),
4122
+ ...curr
4123
+ );
4124
+ }
4125
+ return acc;
4126
+ }, []));
4127
+ };
4128
+ }
4129
+ });
4130
+
4131
+ var __typeError$1 = (msg) => {
4132
+ throw TypeError(msg);
4133
+ };
4134
+ var __accessCheck$1 = (obj, member, msg) => member.has(obj) || __typeError$1("Cannot " + msg);
4135
+ var __privateGet$1 = (obj, member, getter) => (__accessCheck$1(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
4136
+ 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);
4137
+ var __privateSet$1 = (obj, member, value, setter) => (__accessCheck$1(obj, member, "write to private field"), member.set(obj, value), value);
4138
+ var _container, _app, _version;
4139
+ const topBarPluginKey = new PluginKey("CREPE_TOP_BAR");
4140
+ class TopBarView {
4141
+ constructor(ctx, view, config) {
4142
+ __privateAdd$1(this, _container);
4143
+ __privateAdd$1(this, _app);
4144
+ __privateAdd$1(this, _version);
4145
+ this.update = (view, _prevState) => {
4146
+ __privateGet$1(this, _container).style.display = view.editable ? "" : "none";
4147
+ __privateGet$1(this, _version).value++;
4148
+ };
4149
+ this.destroy = () => {
4150
+ __privateGet$1(this, _app).unmount();
4151
+ __privateGet$1(this, _container).remove();
4152
+ };
4153
+ __privateSet$1(this, _version, ref(0));
4154
+ const container = document.createElement("div");
4155
+ container.className = "milkdown-top-bar";
4156
+ const app = createApp(TopBar, {
4157
+ ctx,
4158
+ config,
4159
+ version: __privateGet$1(this, _version)
4160
+ });
4161
+ app.mount(container);
4162
+ __privateSet$1(this, _container, container);
4163
+ __privateSet$1(this, _app, app);
4164
+ const editorRoot = view.dom.parentElement;
4165
+ if (editorRoot) {
4166
+ editorRoot.insertBefore(container, editorRoot.firstChild);
4167
+ }
4168
+ this.update(view);
4169
+ }
4170
+ }
4171
+ _container = new WeakMap();
4172
+ _app = new WeakMap();
4173
+ _version = new WeakMap();
4174
+ const topBarSlice = $ctx(
4175
+ {
4176
+ view: () => ({
4177
+ update: () => {
4178
+ },
4179
+ destroy: () => {
4180
+ }
4181
+ })
4182
+ },
4183
+ "topBarConfig"
4184
+ );
4185
+ const topBarPlugin = $prose((ctx) => {
4186
+ const config = ctx.get(topBarSlice.key);
4187
+ return new Plugin({
4188
+ key: topBarPluginKey,
4189
+ view: config.view
4190
+ });
4191
+ });
4192
+ const topBar = (editor, config) => {
4193
+ editor.config(crepeFeatureConfig(CrepeFeature.TopBar)).config((ctx) => {
4194
+ ctx.set(topBarSlice.key, {
4195
+ view: (view) => new TopBarView(ctx, view, config)
4196
+ });
4197
+ }).use(topBarSlice).use(topBarPlugin);
4198
+ };
4199
+
2341
4200
  function loadFeature(feature, editor, config) {
2342
4201
  switch (feature) {
2343
4202
  case CrepeFeature.CodeMirror: {
@@ -2370,6 +4229,12 @@ function loadFeature(feature, editor, config) {
2370
4229
  case CrepeFeature.Latex: {
2371
4230
  return latex(editor, config);
2372
4231
  }
4232
+ case CrepeFeature.TopBar: {
4233
+ return topBar(editor, config);
4234
+ }
4235
+ case CrepeFeature.AI: {
4236
+ return ai(editor, config);
4237
+ }
2373
4238
  }
2374
4239
  }
2375
4240
 
@@ -2451,7 +4316,29 @@ class CrepeBuilder {
2451
4316
  ...value,
2452
4317
  size: 4
2453
4318
  }));
2454
- }).use(commonmark).use(listener).use(history).use(indent).use(trailing).use(clipboard).use(gfm));
4319
+ ctx.update(uploadConfig.key, (prev) => ({
4320
+ ...prev,
4321
+ uploader: async (files, schema, ctx2) => {
4322
+ const features = useCrepeFeatures(ctx2).get();
4323
+ const hasImageBlock = features.includes(CrepeFeature.ImageBlock);
4324
+ const nodeType = hasImageBlock ? schema.nodes["image-block"] : schema.nodes["image"];
4325
+ if (!nodeType) return [];
4326
+ const onUpload = hasImageBlock ? ctx2.get(imageBlockConfig.key).onUpload : void 0;
4327
+ const images = [];
4328
+ for (let i = 0; i < files.length; i++) {
4329
+ const file = files.item(i);
4330
+ if (file && file.type.includes("image")) images.push(file);
4331
+ }
4332
+ const nodes = await Promise.all(
4333
+ images.map(async (file) => {
4334
+ const src = onUpload ? await onUpload(file) : URL.createObjectURL(file);
4335
+ return nodeType.createAndFill({ src });
4336
+ })
4337
+ );
4338
+ return nodes;
4339
+ }
4340
+ }));
4341
+ }).use(commonmark).use(listener).use(history).use(indent).use(trailing).use(clipboard).use(upload).use(gfm));
2455
4342
  }
2456
4343
  /// Get the milkdown editor instance.
2457
4344
  get editor() {