@jvs-milkdown/components 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (192) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +11 -0
  3. package/lib/__internal__/components/icon.d.ts +24 -0
  4. package/lib/__internal__/components/icon.d.ts.map +1 -0
  5. package/lib/__internal__/components/image-input.d.ts +17 -0
  6. package/lib/__internal__/components/image-input.d.ts.map +1 -0
  7. package/lib/__internal__/keep-alive.d.ts +2 -0
  8. package/lib/__internal__/keep-alive.d.ts.map +1 -0
  9. package/lib/__internal__/meta.d.ts +3 -0
  10. package/lib/__internal__/meta.d.ts.map +1 -0
  11. package/lib/__tests__/setup.d.ts +2 -0
  12. package/lib/__tests__/setup.d.ts.map +1 -0
  13. package/lib/code-block/config.d.ts +23 -0
  14. package/lib/code-block/config.d.ts.map +1 -0
  15. package/lib/code-block/index.d.ts +5 -0
  16. package/lib/code-block/index.d.ts.map +1 -0
  17. package/lib/code-block/index.js +4160 -0
  18. package/lib/code-block/index.js.map +1 -0
  19. package/lib/code-block/view/components/code-block.d.ts +16 -0
  20. package/lib/code-block/view/components/code-block.d.ts.map +1 -0
  21. package/lib/code-block/view/components/copy-button.d.ts +9 -0
  22. package/lib/code-block/view/components/copy-button.d.ts.map +1 -0
  23. package/lib/code-block/view/components/language-picker.d.ts +5 -0
  24. package/lib/code-block/view/components/language-picker.d.ts.map +1 -0
  25. package/lib/code-block/view/components/preview-panel.d.ts +9 -0
  26. package/lib/code-block/view/components/preview-panel.d.ts.map +1 -0
  27. package/lib/code-block/view/index.d.ts +3 -0
  28. package/lib/code-block/view/index.d.ts.map +1 -0
  29. package/lib/code-block/view/loader.d.ts +13 -0
  30. package/lib/code-block/view/loader.d.ts.map +1 -0
  31. package/lib/code-block/view/node-view.d.ts +40 -0
  32. package/lib/code-block/view/node-view.d.ts.map +1 -0
  33. package/lib/image-block/config.d.ts +16 -0
  34. package/lib/image-block/config.d.ts.map +1 -0
  35. package/lib/image-block/index.d.ts +7 -0
  36. package/lib/image-block/index.d.ts.map +1 -0
  37. package/lib/image-block/index.js +660 -0
  38. package/lib/image-block/index.js.map +1 -0
  39. package/lib/image-block/remark-plugin.d.ts +2 -0
  40. package/lib/image-block/remark-plugin.d.ts.map +1 -0
  41. package/lib/image-block/schema.d.ts +3 -0
  42. package/lib/image-block/schema.d.ts.map +1 -0
  43. package/lib/image-block/view/components/__tests__/image-viewer.onImageLoadError.spec.d.ts +2 -0
  44. package/lib/image-block/view/components/__tests__/image-viewer.onImageLoadError.spec.d.ts.map +1 -0
  45. package/lib/image-block/view/components/image-block.d.ts +18 -0
  46. package/lib/image-block/view/components/image-block.d.ts.map +1 -0
  47. package/lib/image-block/view/components/image-viewer.d.ts +3 -0
  48. package/lib/image-block/view/components/image-viewer.d.ts.map +1 -0
  49. package/lib/image-block/view/index.d.ts +3 -0
  50. package/lib/image-block/view/index.d.ts.map +1 -0
  51. package/lib/image-inline/components/image-inline.d.ts +18 -0
  52. package/lib/image-inline/components/image-inline.d.ts.map +1 -0
  53. package/lib/image-inline/config.d.ts +11 -0
  54. package/lib/image-inline/config.d.ts.map +1 -0
  55. package/lib/image-inline/index.d.ts +5 -0
  56. package/lib/image-inline/index.d.ts.map +1 -0
  57. package/lib/image-inline/index.js +377 -0
  58. package/lib/image-inline/index.js.map +1 -0
  59. package/lib/image-inline/view.d.ts +3 -0
  60. package/lib/image-inline/view.d.ts.map +1 -0
  61. package/lib/index.d.ts +2 -0
  62. package/lib/index.d.ts.map +1 -0
  63. package/lib/index.js +35 -0
  64. package/lib/index.js.map +1 -0
  65. package/lib/link-tooltip/command.d.ts +2 -0
  66. package/lib/link-tooltip/command.d.ts.map +1 -0
  67. package/lib/link-tooltip/configure.d.ts +3 -0
  68. package/lib/link-tooltip/configure.d.ts.map +1 -0
  69. package/lib/link-tooltip/edit/component.d.ts +11 -0
  70. package/lib/link-tooltip/edit/component.d.ts.map +1 -0
  71. package/lib/link-tooltip/edit/edit-configure.d.ts +3 -0
  72. package/lib/link-tooltip/edit/edit-configure.d.ts.map +1 -0
  73. package/lib/link-tooltip/edit/edit-view.d.ts +15 -0
  74. package/lib/link-tooltip/edit/edit-view.d.ts.map +1 -0
  75. package/lib/link-tooltip/index.d.ts +7 -0
  76. package/lib/link-tooltip/index.d.ts.map +1 -0
  77. package/lib/link-tooltip/index.js +2526 -0
  78. package/lib/link-tooltip/index.js.map +1 -0
  79. package/lib/link-tooltip/preview/component.d.ts +11 -0
  80. package/lib/link-tooltip/preview/component.d.ts.map +1 -0
  81. package/lib/link-tooltip/preview/preview-configure.d.ts +3 -0
  82. package/lib/link-tooltip/preview/preview-configure.d.ts.map +1 -0
  83. package/lib/link-tooltip/preview/preview-view.d.ts +14 -0
  84. package/lib/link-tooltip/preview/preview-view.d.ts.map +1 -0
  85. package/lib/link-tooltip/slices.d.ts +34 -0
  86. package/lib/link-tooltip/slices.d.ts.map +1 -0
  87. package/lib/link-tooltip/tooltips.d.ts +3 -0
  88. package/lib/link-tooltip/tooltips.d.ts.map +1 -0
  89. package/lib/link-tooltip/utils.d.ts +14 -0
  90. package/lib/link-tooltip/utils.d.ts.map +1 -0
  91. package/lib/list-item-block/component.d.ts +19 -0
  92. package/lib/list-item-block/component.d.ts.map +1 -0
  93. package/lib/list-item-block/config.d.ts +13 -0
  94. package/lib/list-item-block/config.d.ts.map +1 -0
  95. package/lib/list-item-block/index.d.ts +6 -0
  96. package/lib/list-item-block/index.d.ts.map +1 -0
  97. package/lib/list-item-block/index.js +2149 -0
  98. package/lib/list-item-block/index.js.map +1 -0
  99. package/lib/list-item-block/view.d.ts +3 -0
  100. package/lib/list-item-block/view.d.ts.map +1 -0
  101. package/lib/table-block/config.d.ts +8 -0
  102. package/lib/table-block/config.d.ts.map +1 -0
  103. package/lib/table-block/dnd/calc-drag-over.d.ts +3 -0
  104. package/lib/table-block/dnd/calc-drag-over.d.ts.map +1 -0
  105. package/lib/table-block/dnd/create-drag-handler.d.ts +5 -0
  106. package/lib/table-block/dnd/create-drag-handler.d.ts.map +1 -0
  107. package/lib/table-block/dnd/drag-over-handler.d.ts +3 -0
  108. package/lib/table-block/dnd/drag-over-handler.d.ts.map +1 -0
  109. package/lib/table-block/dnd/prepare-dnd-context.d.ts +3 -0
  110. package/lib/table-block/dnd/prepare-dnd-context.d.ts.map +1 -0
  111. package/lib/table-block/dnd/preview.d.ts +3 -0
  112. package/lib/table-block/dnd/preview.d.ts.map +1 -0
  113. package/lib/table-block/index.d.ts +5 -0
  114. package/lib/table-block/index.d.ts.map +1 -0
  115. package/lib/table-block/index.js +3961 -0
  116. package/lib/table-block/index.js.map +1 -0
  117. package/lib/table-block/view/component.d.ts +16 -0
  118. package/lib/table-block/view/component.d.ts.map +1 -0
  119. package/lib/table-block/view/drag.d.ts +7 -0
  120. package/lib/table-block/view/drag.d.ts.map +1 -0
  121. package/lib/table-block/view/index.d.ts +2 -0
  122. package/lib/table-block/view/index.d.ts.map +1 -0
  123. package/lib/table-block/view/operation.d.ts +11 -0
  124. package/lib/table-block/view/operation.d.ts.map +1 -0
  125. package/lib/table-block/view/pointer.d.ts +7 -0
  126. package/lib/table-block/view/pointer.d.ts.map +1 -0
  127. package/lib/table-block/view/types.d.ts +32 -0
  128. package/lib/table-block/view/types.d.ts.map +1 -0
  129. package/lib/table-block/view/utils.d.ts +21 -0
  130. package/lib/table-block/view/utils.d.ts.map +1 -0
  131. package/lib/table-block/view/view.d.ts +22 -0
  132. package/lib/table-block/view/view.d.ts.map +1 -0
  133. package/lib/tsconfig.tsbuildinfo +1 -0
  134. package/package.json +110 -0
  135. package/src/__internal__/components/icon.tsx +38 -0
  136. package/src/__internal__/components/image-input.tsx +182 -0
  137. package/src/__internal__/keep-alive.ts +3 -0
  138. package/src/__internal__/meta.ts +15 -0
  139. package/src/__tests__/setup.ts +6 -0
  140. package/src/code-block/config.ts +54 -0
  141. package/src/code-block/index.ts +12 -0
  142. package/src/code-block/view/components/code-block.tsx +170 -0
  143. package/src/code-block/view/components/copy-button.tsx +96 -0
  144. package/src/code-block/view/components/language-picker.tsx +239 -0
  145. package/src/code-block/view/components/preview-panel.tsx +79 -0
  146. package/src/code-block/view/index.ts +24 -0
  147. package/src/code-block/view/loader.ts +40 -0
  148. package/src/code-block/view/node-view.ts +310 -0
  149. package/src/image-block/config.ts +37 -0
  150. package/src/image-block/index.ts +18 -0
  151. package/src/image-block/remark-plugin.ts +51 -0
  152. package/src/image-block/schema.ts +71 -0
  153. package/src/image-block/view/components/__tests__/image-viewer.onImageLoadError.spec.tsx +42 -0
  154. package/src/image-block/view/components/image-block.tsx +80 -0
  155. package/src/image-block/view/components/image-viewer.tsx +186 -0
  156. package/src/image-block/view/index.ts +111 -0
  157. package/src/image-inline/components/image-inline.tsx +85 -0
  158. package/src/image-inline/config.ts +30 -0
  159. package/src/image-inline/index.ts +12 -0
  160. package/src/image-inline/view.ts +109 -0
  161. package/src/index.ts +1 -0
  162. package/src/link-tooltip/command.ts +19 -0
  163. package/src/link-tooltip/configure.ts +9 -0
  164. package/src/link-tooltip/edit/component.tsx +82 -0
  165. package/src/link-tooltip/edit/edit-configure.ts +29 -0
  166. package/src/link-tooltip/edit/edit-view.ts +165 -0
  167. package/src/link-tooltip/index.ts +19 -0
  168. package/src/link-tooltip/preview/component.tsx +87 -0
  169. package/src/link-tooltip/preview/preview-configure.ts +65 -0
  170. package/src/link-tooltip/preview/preview-view.ts +101 -0
  171. package/src/link-tooltip/slices.ts +69 -0
  172. package/src/link-tooltip/tooltips.ts +22 -0
  173. package/src/link-tooltip/utils.ts +56 -0
  174. package/src/list-item-block/component.tsx +133 -0
  175. package/src/list-item-block/config.ts +39 -0
  176. package/src/list-item-block/index.ts +13 -0
  177. package/src/list-item-block/view.ts +130 -0
  178. package/src/table-block/config.ts +53 -0
  179. package/src/table-block/dnd/calc-drag-over.ts +46 -0
  180. package/src/table-block/dnd/create-drag-handler.ts +99 -0
  181. package/src/table-block/dnd/drag-over-handler.ts +113 -0
  182. package/src/table-block/dnd/prepare-dnd-context.ts +46 -0
  183. package/src/table-block/dnd/preview.ts +58 -0
  184. package/src/table-block/index.ts +9 -0
  185. package/src/table-block/view/component.tsx +219 -0
  186. package/src/table-block/view/drag.ts +121 -0
  187. package/src/table-block/view/index.ts +1 -0
  188. package/src/table-block/view/operation.ts +148 -0
  189. package/src/table-block/view/pointer.ts +165 -0
  190. package/src/table-block/view/types.ts +35 -0
  191. package/src/table-block/view/utils.ts +192 -0
  192. package/src/table-block/view/view.ts +165 -0
@@ -0,0 +1,660 @@
1
+ import { $ctx, $remark, $nodeSchema, $view } from '@jvs-milkdown/utils';
2
+ import { visit } from 'unist-util-visit';
3
+ import { expectDomTypeError } from '@jvs-milkdown/exception';
4
+ import DOMPurify from 'dompurify';
5
+ import { h, defineComponent, ref, Fragment as Fragment$1, createApp, watchEffect } from 'vue';
6
+ import clsx from 'clsx';
7
+ import { customAlphabet } from 'nanoid';
8
+
9
+ var __defProp$2 = Object.defineProperty;
10
+ var __getOwnPropSymbols$2 = Object.getOwnPropertySymbols;
11
+ var __hasOwnProp$2 = Object.prototype.hasOwnProperty;
12
+ var __propIsEnum$2 = Object.prototype.propertyIsEnumerable;
13
+ var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
14
+ var __spreadValues$2 = (a, b) => {
15
+ for (var prop in b || (b = {}))
16
+ if (__hasOwnProp$2.call(b, prop))
17
+ __defNormalProp$2(a, prop, b[prop]);
18
+ if (__getOwnPropSymbols$2)
19
+ for (var prop of __getOwnPropSymbols$2(b)) {
20
+ if (__propIsEnum$2.call(b, prop))
21
+ __defNormalProp$2(a, prop, b[prop]);
22
+ }
23
+ return a;
24
+ };
25
+ function withMeta(plugin, meta) {
26
+ Object.assign(plugin, {
27
+ meta: __spreadValues$2({
28
+ package: "@jvs-milkdown/components"
29
+ }, meta)
30
+ });
31
+ return plugin;
32
+ }
33
+
34
+ const defaultImageBlockConfig = {
35
+ imageIcon: "\u{1F30C}",
36
+ captionIcon: "\u{1F4AC}",
37
+ uploadButton: "Upload file",
38
+ confirmButton: "Confirm \u23CE",
39
+ uploadPlaceholderText: "or paste the image link ...",
40
+ captionPlaceholderText: "Image caption",
41
+ onUpload: (file) => Promise.resolve(URL.createObjectURL(file))
42
+ };
43
+ const imageBlockConfig = $ctx(
44
+ defaultImageBlockConfig,
45
+ "imageBlockConfigCtx"
46
+ );
47
+ withMeta(imageBlockConfig, {
48
+ displayName: "Config<image-block>",
49
+ group: "ImageBlock"
50
+ });
51
+
52
+ function visitImage(ast) {
53
+ return visit(
54
+ ast,
55
+ "paragraph",
56
+ (node, index, parent) => {
57
+ var _a, _b;
58
+ if (((_a = node.children) == null ? void 0 : _a.length) !== 1) return;
59
+ const firstChild = (_b = node.children) == null ? void 0 : _b[0];
60
+ if (!firstChild || firstChild.type !== "image") return;
61
+ const { url, alt, title } = firstChild;
62
+ const newNode = {
63
+ type: "image-block",
64
+ url,
65
+ alt,
66
+ title
67
+ };
68
+ parent.children.splice(index, 1, newNode);
69
+ }
70
+ );
71
+ }
72
+ const remarkImageBlockPlugin = $remark(
73
+ "remark-image-block",
74
+ () => () => visitImage
75
+ );
76
+ withMeta(remarkImageBlockPlugin.plugin, {
77
+ displayName: "Remark<remarkImageBlock>",
78
+ group: "ImageBlock"
79
+ });
80
+ withMeta(remarkImageBlockPlugin.options, {
81
+ displayName: "RemarkConfig<remarkImageBlock>",
82
+ group: "ImageBlock"
83
+ });
84
+
85
+ var __defProp$1 = Object.defineProperty;
86
+ var __getOwnPropSymbols$1 = Object.getOwnPropertySymbols;
87
+ var __hasOwnProp$1 = Object.prototype.hasOwnProperty;
88
+ var __propIsEnum$1 = Object.prototype.propertyIsEnumerable;
89
+ var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
90
+ var __spreadValues$1 = (a, b) => {
91
+ for (var prop in b || (b = {}))
92
+ if (__hasOwnProp$1.call(b, prop))
93
+ __defNormalProp$1(a, prop, b[prop]);
94
+ if (__getOwnPropSymbols$1)
95
+ for (var prop of __getOwnPropSymbols$1(b)) {
96
+ if (__propIsEnum$1.call(b, prop))
97
+ __defNormalProp$1(a, prop, b[prop]);
98
+ }
99
+ return a;
100
+ };
101
+ const IMAGE_DATA_TYPE = "image-block";
102
+ const imageBlockSchema = $nodeSchema("image-block", () => {
103
+ return {
104
+ inline: false,
105
+ group: "block",
106
+ selectable: true,
107
+ draggable: true,
108
+ isolating: true,
109
+ marks: "",
110
+ atom: true,
111
+ priority: 100,
112
+ attrs: {
113
+ src: { default: "", validate: "string" },
114
+ caption: { default: "", validate: "string" },
115
+ ratio: { default: 1, validate: "number" }
116
+ },
117
+ parseDOM: [
118
+ {
119
+ tag: `img[data-type="${IMAGE_DATA_TYPE}"]`,
120
+ getAttrs: (dom) => {
121
+ var _a;
122
+ if (!(dom instanceof HTMLElement)) throw expectDomTypeError(dom);
123
+ return {
124
+ src: dom.getAttribute("src") || "",
125
+ caption: dom.getAttribute("caption") || "",
126
+ ratio: Number((_a = dom.getAttribute("ratio")) != null ? _a : 1)
127
+ };
128
+ }
129
+ }
130
+ ],
131
+ toDOM: (node) => ["img", __spreadValues$1({ "data-type": IMAGE_DATA_TYPE }, node.attrs)],
132
+ parseMarkdown: {
133
+ match: ({ type }) => type === "image-block",
134
+ runner: (state, node, type) => {
135
+ const src = node.url;
136
+ const caption = node.title;
137
+ let ratio = Number(node.alt || 1);
138
+ if (Number.isNaN(ratio) || ratio === 0) ratio = 1;
139
+ state.addNode(type, {
140
+ src,
141
+ caption,
142
+ ratio
143
+ });
144
+ }
145
+ },
146
+ toMarkdown: {
147
+ match: (node) => node.type.name === "image-block",
148
+ runner: (state, node) => {
149
+ state.openNode("paragraph");
150
+ state.addNode("image", void 0, void 0, {
151
+ title: node.attrs.caption,
152
+ url: node.attrs.src,
153
+ alt: `${Number.parseFloat(node.attrs.ratio).toFixed(2)}`
154
+ });
155
+ state.closeNode();
156
+ }
157
+ }
158
+ };
159
+ });
160
+ withMeta(imageBlockSchema.node, {
161
+ displayName: "NodeSchema<image-block>",
162
+ group: "ImageBlock"
163
+ });
164
+
165
+ function keepAlive(..._args) {
166
+ }
167
+
168
+ keepAlive(h);
169
+ function Icon({ icon, class: className, onClick }) {
170
+ return /* @__PURE__ */ h(
171
+ "span",
172
+ {
173
+ class: clsx("milkdown-icon", className),
174
+ onPointerdown: onClick,
175
+ innerHTML: icon ? DOMPurify.sanitize(icon.trim()) : void 0
176
+ }
177
+ );
178
+ }
179
+ Icon.props = {
180
+ icon: {
181
+ type: String,
182
+ required: false
183
+ },
184
+ class: {
185
+ type: String,
186
+ required: false
187
+ },
188
+ onClick: {
189
+ type: Function,
190
+ required: false
191
+ }
192
+ };
193
+
194
+ keepAlive(h);
195
+ const nanoid = customAlphabet("abcdefg", 8);
196
+ const ImageInput = defineComponent({
197
+ props: {
198
+ src: {
199
+ type: Object,
200
+ required: true
201
+ },
202
+ selected: {
203
+ type: Object,
204
+ required: true
205
+ },
206
+ readonly: {
207
+ type: Object,
208
+ required: true
209
+ },
210
+ setLink: {
211
+ type: Function,
212
+ required: true
213
+ },
214
+ imageIcon: {
215
+ type: String,
216
+ required: false
217
+ },
218
+ uploadButton: {
219
+ type: String,
220
+ required: false
221
+ },
222
+ confirmButton: {
223
+ type: String,
224
+ required: false
225
+ },
226
+ uploadPlaceholderText: {
227
+ type: String,
228
+ required: false
229
+ },
230
+ onUpload: {
231
+ type: Function,
232
+ required: true
233
+ },
234
+ onImageLoadError: {
235
+ type: Function,
236
+ required: false
237
+ }
238
+ },
239
+ setup({
240
+ readonly,
241
+ src,
242
+ setLink,
243
+ onUpload,
244
+ imageIcon,
245
+ uploadButton,
246
+ confirmButton,
247
+ uploadPlaceholderText,
248
+ className,
249
+ onImageLoadError
250
+ }) {
251
+ var _a, _b;
252
+ const focusLinkInput = ref(false);
253
+ const linkInputRef = ref();
254
+ const currentLink = ref((_a = src.value) != null ? _a : "");
255
+ const uuid = ref(nanoid());
256
+ const hidePlaceholder = ref(((_b = src.value) == null ? void 0 : _b.length) !== 0);
257
+ const onEditLink = (e) => {
258
+ const target = e.target;
259
+ const value = target.value;
260
+ hidePlaceholder.value = value.length !== 0;
261
+ currentLink.value = value;
262
+ };
263
+ const onKeydown = (e) => {
264
+ var _a2, _b2;
265
+ if (e.key === "Enter") {
266
+ setLink((_b2 = (_a2 = linkInputRef.value) == null ? void 0 : _a2.value) != null ? _b2 : "");
267
+ }
268
+ };
269
+ const onConfirmLinkInput = () => {
270
+ var _a2, _b2;
271
+ setLink((_b2 = (_a2 = linkInputRef.value) == null ? void 0 : _a2.value) != null ? _b2 : "");
272
+ };
273
+ const onUploadFile = (e) => {
274
+ var _a2;
275
+ const file = (_a2 = e.target.files) == null ? void 0 : _a2[0];
276
+ if (!file) return;
277
+ onUpload(file).then((url) => {
278
+ if (!url) return;
279
+ setLink(url);
280
+ hidePlaceholder.value = true;
281
+ }).catch((err) => {
282
+ console.error("An error occurred while uploading image");
283
+ console.error(err);
284
+ });
285
+ };
286
+ return () => {
287
+ return /* @__PURE__ */ h("div", { class: clsx("image-edit", className) }, /* @__PURE__ */ h(Icon, { icon: imageIcon, class: "image-icon" }), /* @__PURE__ */ h("div", { class: clsx("link-importer", focusLinkInput.value && "focus") }, /* @__PURE__ */ h(
288
+ "input",
289
+ {
290
+ ref: linkInputRef,
291
+ draggable: "true",
292
+ onDragstart: (e) => {
293
+ e.preventDefault();
294
+ e.stopPropagation();
295
+ },
296
+ disabled: readonly.value,
297
+ class: "link-input-area",
298
+ value: currentLink.value,
299
+ onInput: onEditLink,
300
+ onKeydown,
301
+ onFocus: () => focusLinkInput.value = true,
302
+ onBlur: () => focusLinkInput.value = false
303
+ }
304
+ ), !hidePlaceholder.value && /* @__PURE__ */ h("div", { class: "placeholder" }, /* @__PURE__ */ h(
305
+ "input",
306
+ {
307
+ disabled: readonly.value,
308
+ class: "hidden",
309
+ id: uuid.value,
310
+ type: "file",
311
+ accept: "image/*",
312
+ onChange: onUploadFile
313
+ }
314
+ ), /* @__PURE__ */ h("label", { class: "uploader", for: uuid.value }, /* @__PURE__ */ h(Icon, { icon: uploadButton })), /* @__PURE__ */ h("span", { class: "text", onClick: () => {
315
+ var _a2;
316
+ return (_a2 = linkInputRef.value) == null ? void 0 : _a2.focus();
317
+ } }, uploadPlaceholderText))), currentLink.value && /* @__PURE__ */ h(Fragment, null, /* @__PURE__ */ h("div", { class: "image-preview" }, /* @__PURE__ */ h(
318
+ "img",
319
+ {
320
+ src: currentLink.value,
321
+ alt: "",
322
+ onError: (e) => Promise.resolve(onImageLoadError == null ? void 0 : onImageLoadError(e)).catch(() => {
323
+ })
324
+ }
325
+ )), /* @__PURE__ */ h("div", { class: "confirm", onClick: () => onConfirmLinkInput() }, /* @__PURE__ */ h(Icon, { icon: confirmButton }))));
326
+ };
327
+ }
328
+ });
329
+
330
+ keepAlive(h, Fragment$1);
331
+ const ImageViewer = defineComponent({
332
+ props: {
333
+ src: {
334
+ type: Object,
335
+ required: true
336
+ },
337
+ caption: {
338
+ type: Object,
339
+ required: true
340
+ },
341
+ ratio: {
342
+ type: Object,
343
+ required: true
344
+ },
345
+ selected: {
346
+ type: Object,
347
+ required: true
348
+ },
349
+ readonly: {
350
+ type: Object,
351
+ required: true
352
+ },
353
+ setAttr: {
354
+ type: Function,
355
+ required: true
356
+ },
357
+ config: {
358
+ type: Object,
359
+ required: true
360
+ }
361
+ },
362
+ setup({ src, caption, ratio, readonly, setAttr, config }) {
363
+ var _a;
364
+ const imageRef = ref();
365
+ const resizeHandle = ref();
366
+ const showCaption = ref(Boolean((_a = caption.value) == null ? void 0 : _a.length));
367
+ const timer = ref(0);
368
+ const onImageLoad = () => {
369
+ var _a2;
370
+ const image = imageRef.value;
371
+ if (!image) return;
372
+ const host = image.closest(".milkdown-image-block");
373
+ if (!host) return;
374
+ let maxWidth = host.getBoundingClientRect().width;
375
+ if (!maxWidth) return;
376
+ if (config.maxWidth && config.maxWidth < maxWidth)
377
+ maxWidth = config.maxWidth;
378
+ const height = image.naturalHeight;
379
+ const width = image.naturalWidth;
380
+ let transformedHeight = width < maxWidth ? height : maxWidth * (height / width);
381
+ if (config.maxHeight && transformedHeight > config.maxHeight)
382
+ transformedHeight = config.maxHeight;
383
+ const h2 = (transformedHeight * ((_a2 = ratio.value) != null ? _a2 : 1)).toFixed(2);
384
+ image.dataset.origin = transformedHeight.toFixed(2);
385
+ image.dataset.height = h2;
386
+ image.style.height = `${h2}px`;
387
+ if (config.maxWidth) image.style.maxWidth = `${config.maxWidth}px`;
388
+ };
389
+ const onToggleCaption = (e) => {
390
+ e.preventDefault();
391
+ e.stopPropagation();
392
+ if (readonly.value) return;
393
+ showCaption.value = !showCaption.value;
394
+ };
395
+ const onInputCaption = (e) => {
396
+ const target = e.target;
397
+ const value = target.value;
398
+ if (timer.value) window.clearTimeout(timer.value);
399
+ timer.value = window.setTimeout(() => {
400
+ setAttr("caption", value);
401
+ }, 1e3);
402
+ };
403
+ const onBlurCaption = (e) => {
404
+ const target = e.target;
405
+ const value = target.value;
406
+ if (timer.value) {
407
+ window.clearTimeout(timer.value);
408
+ timer.value = 0;
409
+ }
410
+ setAttr("caption", value);
411
+ };
412
+ const onResizeHandlePointerMove = (e) => {
413
+ e.preventDefault();
414
+ const image = imageRef.value;
415
+ if (!image) return;
416
+ const top = image.getBoundingClientRect().top;
417
+ let height = e.clientY - top;
418
+ if (height < 100) height = 100;
419
+ if (config.maxHeight && height > config.maxHeight)
420
+ height = config.maxHeight;
421
+ const h2 = Number(height).toFixed(2);
422
+ image.dataset.height = h2;
423
+ image.style.height = `${h2}px`;
424
+ };
425
+ const onResizeHandlePointerUp = () => {
426
+ window.removeEventListener("pointermove", onResizeHandlePointerMove);
427
+ window.removeEventListener("pointerup", onResizeHandlePointerUp);
428
+ const image = imageRef.value;
429
+ if (!image) return;
430
+ const originHeight = Number(image.dataset.origin);
431
+ const currentHeight = Number(image.dataset.height);
432
+ const ratio2 = Number.parseFloat(
433
+ Number(currentHeight / originHeight).toFixed(2)
434
+ );
435
+ if (Number.isNaN(ratio2)) return;
436
+ setAttr("ratio", ratio2);
437
+ };
438
+ const onResizeHandlePointerDown = (e) => {
439
+ if (readonly.value) return;
440
+ e.preventDefault();
441
+ e.stopPropagation();
442
+ window.addEventListener("pointermove", onResizeHandlePointerMove);
443
+ window.addEventListener("pointerup", onResizeHandlePointerUp);
444
+ };
445
+ return () => {
446
+ return /* @__PURE__ */ h(Fragment$1, null, /* @__PURE__ */ h("div", { class: "image-wrapper" }, /* @__PURE__ */ h("div", { class: "operation" }, /* @__PURE__ */ h("div", { class: "operation-item", onPointerdown: onToggleCaption }, /* @__PURE__ */ h(Icon, { icon: config.captionIcon }))), /* @__PURE__ */ h(
447
+ "img",
448
+ {
449
+ ref: imageRef,
450
+ "data-type": IMAGE_DATA_TYPE,
451
+ onLoad: onImageLoad,
452
+ src: src.value,
453
+ alt: caption.value,
454
+ onError: (e) => {
455
+ var _a2;
456
+ return Promise.resolve((_a2 = config.onImageLoadError) == null ? void 0 : _a2.call(config, e)).catch(() => {
457
+ });
458
+ }
459
+ }
460
+ ), /* @__PURE__ */ h(
461
+ "div",
462
+ {
463
+ ref: resizeHandle,
464
+ class: "image-resize-handle",
465
+ onPointerdown: onResizeHandlePointerDown
466
+ }
467
+ )), showCaption.value && /* @__PURE__ */ h(
468
+ "input",
469
+ {
470
+ draggable: "true",
471
+ onDragstart: (e) => {
472
+ e.preventDefault();
473
+ e.stopPropagation();
474
+ },
475
+ class: "caption-input",
476
+ placeholder: config == null ? void 0 : config.captionPlaceholderText,
477
+ onInput: onInputCaption,
478
+ onBlur: onBlurCaption,
479
+ value: caption.value
480
+ }
481
+ ));
482
+ };
483
+ }
484
+ });
485
+
486
+ var __defProp = Object.defineProperty;
487
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
488
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
489
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
490
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
491
+ var __spreadValues = (a, b) => {
492
+ for (var prop in b || (b = {}))
493
+ if (__hasOwnProp.call(b, prop))
494
+ __defNormalProp(a, prop, b[prop]);
495
+ if (__getOwnPropSymbols)
496
+ for (var prop of __getOwnPropSymbols(b)) {
497
+ if (__propIsEnum.call(b, prop))
498
+ __defNormalProp(a, prop, b[prop]);
499
+ }
500
+ return a;
501
+ };
502
+ keepAlive(h, Fragment$1);
503
+ const MilkdownImageBlock = defineComponent({
504
+ props: {
505
+ src: {
506
+ type: Object,
507
+ required: true
508
+ },
509
+ caption: {
510
+ type: Object,
511
+ required: true
512
+ },
513
+ ratio: {
514
+ type: Object,
515
+ required: true
516
+ },
517
+ selected: {
518
+ type: Object,
519
+ required: true
520
+ },
521
+ readonly: {
522
+ type: Object,
523
+ required: true
524
+ },
525
+ setAttr: {
526
+ type: Function,
527
+ required: true
528
+ },
529
+ config: {
530
+ type: Object,
531
+ required: true
532
+ }
533
+ },
534
+ setup(props) {
535
+ const { src } = props;
536
+ return () => {
537
+ var _a;
538
+ if (!((_a = src.value) == null ? void 0 : _a.length)) {
539
+ return /* @__PURE__ */ h(
540
+ ImageInput,
541
+ {
542
+ src: props.src,
543
+ selected: props.selected,
544
+ readonly: props.readonly,
545
+ setLink: (link) => props.setAttr("src", link),
546
+ imageIcon: props.config.imageIcon,
547
+ uploadButton: props.config.uploadButton,
548
+ confirmButton: props.config.confirmButton,
549
+ uploadPlaceholderText: props.config.uploadPlaceholderText,
550
+ onUpload: props.config.onUpload,
551
+ onImageLoadError: props.config.onImageLoadError
552
+ }
553
+ );
554
+ }
555
+ return /* @__PURE__ */ h(ImageViewer, __spreadValues({}, props));
556
+ };
557
+ }
558
+ });
559
+
560
+ const imageBlockView = $view(
561
+ imageBlockSchema.node,
562
+ (ctx) => {
563
+ return (initialNode, view, getPos) => {
564
+ const src = ref(initialNode.attrs.src);
565
+ const caption = ref(initialNode.attrs.caption);
566
+ const ratio = ref(initialNode.attrs.ratio);
567
+ const selected = ref(false);
568
+ const readonly = ref(!view.editable);
569
+ const setAttr = (attr, value) => {
570
+ if (!view.editable) return;
571
+ const pos = getPos();
572
+ if (pos == null) return;
573
+ view.dispatch(
574
+ view.state.tr.setNodeAttribute(
575
+ pos,
576
+ attr,
577
+ attr === "src" ? DOMPurify.sanitize(value) : value
578
+ )
579
+ );
580
+ };
581
+ const config = ctx.get(imageBlockConfig.key);
582
+ const app = createApp(MilkdownImageBlock, {
583
+ src,
584
+ caption,
585
+ ratio,
586
+ selected,
587
+ readonly,
588
+ setAttr,
589
+ config
590
+ });
591
+ const dom = document.createElement("div");
592
+ dom.className = "milkdown-image-block";
593
+ const disposeSelectedWatcher = watchEffect(() => {
594
+ const isSelected = selected.value;
595
+ if (isSelected) {
596
+ dom.classList.add("selected");
597
+ } else {
598
+ dom.classList.remove("selected");
599
+ }
600
+ });
601
+ const proxyDomURL = config.proxyDomURL;
602
+ const bindAttrs = (node) => {
603
+ if (!proxyDomURL) {
604
+ src.value = node.attrs.src;
605
+ } else {
606
+ const proxiedURL = proxyDomURL(node.attrs.src);
607
+ if (typeof proxiedURL === "string") {
608
+ src.value = proxiedURL;
609
+ } else {
610
+ proxiedURL.then((url) => {
611
+ src.value = url;
612
+ }).catch(console.error);
613
+ }
614
+ }
615
+ ratio.value = node.attrs.ratio;
616
+ caption.value = node.attrs.caption;
617
+ readonly.value = !view.editable;
618
+ };
619
+ bindAttrs(initialNode);
620
+ app.mount(dom);
621
+ return {
622
+ dom,
623
+ update: (updatedNode) => {
624
+ if (updatedNode.type !== initialNode.type) return false;
625
+ bindAttrs(updatedNode);
626
+ return true;
627
+ },
628
+ stopEvent: (e) => {
629
+ if (e.target instanceof HTMLInputElement) return true;
630
+ return false;
631
+ },
632
+ selectNode: () => {
633
+ selected.value = true;
634
+ },
635
+ deselectNode: () => {
636
+ selected.value = false;
637
+ },
638
+ destroy: () => {
639
+ disposeSelectedWatcher();
640
+ app.unmount();
641
+ dom.remove();
642
+ }
643
+ };
644
+ };
645
+ }
646
+ );
647
+ withMeta(imageBlockView, {
648
+ displayName: "NodeView<image-block>",
649
+ group: "ImageBlock"
650
+ });
651
+
652
+ const imageBlockComponent = [
653
+ remarkImageBlockPlugin,
654
+ imageBlockSchema,
655
+ imageBlockView,
656
+ imageBlockConfig
657
+ ].flat();
658
+
659
+ export { IMAGE_DATA_TYPE, defaultImageBlockConfig, imageBlockComponent, imageBlockConfig, imageBlockSchema, imageBlockView, remarkImageBlockPlugin };
660
+ //# sourceMappingURL=index.js.map