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