@milkdown/plugin-upload 7.3.1 → 7.3.2

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.
@@ -1,5 +1,5 @@
1
1
  import type { Uploader } from './upload';
2
- export declare const readImageAsBase64: (file: File) => Promise<{
2
+ export declare function readImageAsBase64(file: File): Promise<{
3
3
  alt: string;
4
4
  src: string;
5
5
  }>;
@@ -1 +1 @@
1
- {"version":3,"file":"default-uploader.d.ts","sourceRoot":"","sources":["../src/default-uploader.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAGxC,eAAO,MAAM,iBAAiB,SAAU,IAAI,KAAG,QAAQ;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAelF,CAAA;AAID,eAAO,MAAM,eAAe,EAAE,QAqB7B,CAAA"}
1
+ {"version":3,"file":"default-uploader.d.ts","sourceRoot":"","sources":["../src/default-uploader.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAGxC,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC,CAenF;AAID,eAAO,MAAM,eAAe,EAAE,QAqB7B,CAAA"}
package/lib/index.es.js CHANGED
@@ -3,34 +3,37 @@ import { PluginKey as D, Plugin as P } from "@milkdown/prose/state";
3
3
  import { Decoration as k, DecorationSet as C } from "@milkdown/prose/view";
4
4
  import { $ctx as b, $prose as U } from "@milkdown/utils";
5
5
  import { missingNodeInSchema as F } from "@milkdown/exception";
6
- const w = (n) => new Promise((i) => {
7
- const r = new FileReader();
8
- r.addEventListener(
9
- "load",
10
- () => {
11
- i({
12
- alt: n.name,
13
- src: r.result
14
- });
15
- },
16
- !1
17
- ), r.readAsDataURL(n);
18
- }), A = async (n, i) => {
6
+ function w(n) {
7
+ return new Promise((s) => {
8
+ const r = new FileReader();
9
+ r.addEventListener(
10
+ "load",
11
+ () => {
12
+ s({
13
+ alt: n.name,
14
+ src: r.result
15
+ });
16
+ },
17
+ !1
18
+ ), r.readAsDataURL(n);
19
+ });
20
+ }
21
+ const A = async (n, s) => {
19
22
  const r = [];
20
23
  for (let t = 0; t < n.length; t++) {
21
24
  const e = n.item(t);
22
25
  e && e.type.includes("image") && r.push(e);
23
26
  }
24
- const { image: l } = i.nodes;
27
+ const { image: l } = s.nodes;
25
28
  if (!l)
26
29
  throw F("image");
27
30
  return (await Promise.all(r.map((t) => w(t)))).map(({ alt: t, src: e }) => l.createAndFill({ src: e, alt: t }));
28
31
  }, c = b({
29
32
  uploader: A,
30
33
  enableHtmlFileUploader: !1,
31
- uploadWidgetFactory: (n, i) => {
34
+ uploadWidgetFactory: (n, s) => {
32
35
  const r = document.createElement("span");
33
- return r.textContent = "Upload in progress...", k.widget(n, r, i);
36
+ return r.textContent = "Upload in progress...", k.widget(n, r, s);
34
37
  }
35
38
  }, "uploadConfig");
36
39
  c.meta = {
@@ -38,31 +41,31 @@ c.meta = {
38
41
  displayName: "Ctx<uploadConfig>"
39
42
  };
40
43
  const f = U((n) => {
41
- const i = new D("MILKDOWN_UPLOAD"), r = (o, t) => {
42
- var s;
43
- const e = i.getState(o);
44
+ const s = new D("MILKDOWN_UPLOAD"), r = (o, t) => {
45
+ var i;
46
+ const e = s.getState(o);
44
47
  if (!e)
45
48
  return -1;
46
49
  const a = e.find(void 0, void 0, (d) => d.id === t);
47
- return a.length ? ((s = a[0]) == null ? void 0 : s.from) ?? -1 : -1;
50
+ return a.length ? ((i = a[0]) == null ? void 0 : i.from) ?? -1 : -1;
48
51
  }, l = (o, t, e) => {
49
52
  var m;
50
53
  if (!e || e.length <= 0)
51
54
  return !1;
52
- const a = Symbol("upload symbol"), s = n.get(y), { tr: d } = o.state, g = t instanceof DragEvent ? ((m = o.posAtCoords({ left: t.clientX, top: t.clientY })) == null ? void 0 : m.pos) ?? d.selection.from : d.selection.from;
53
- o.dispatch(d.setMeta(i, { add: { id: a, pos: g } }));
55
+ const a = Symbol("upload symbol"), i = n.get(y), { tr: d } = o.state, g = t instanceof DragEvent ? ((m = o.posAtCoords({ left: t.clientX, top: t.clientY })) == null ? void 0 : m.pos) ?? d.selection.from : d.selection.from;
56
+ o.dispatch(d.setMeta(s, { add: { id: a, pos: g } }));
54
57
  const { uploader: h } = n.get(c.key);
55
- return h(e, s).then((p) => {
58
+ return h(e, i).then((p) => {
56
59
  const u = r(o.state, a);
57
60
  u < 0 || o.dispatch(
58
- o.state.tr.replaceWith(u, u, p).setMeta(i, { remove: { id: a } })
61
+ o.state.tr.replaceWith(u, u, p).setMeta(s, { remove: { id: a } })
59
62
  );
60
63
  }).catch((p) => {
61
64
  console.error(p);
62
65
  }), !0;
63
66
  };
64
67
  return new P({
65
- key: i,
68
+ key: s,
66
69
  state: {
67
70
  init() {
68
71
  return C.empty;
@@ -72,12 +75,12 @@ const f = U((n) => {
72
75
  if (!a)
73
76
  return e;
74
77
  if (a.add) {
75
- const { uploadWidgetFactory: s } = n.get(c.key), d = s(a.add.pos, { id: a.add.id });
78
+ const { uploadWidgetFactory: i } = n.get(c.key), d = i(a.add.pos, { id: a.add.id });
76
79
  return e.add(o.doc, [d]);
77
80
  }
78
81
  if (a.remove) {
79
- const s = e.find(void 0, void 0, (d) => d.id === a.remove.id);
80
- return e.remove(s);
82
+ const i = e.find(void 0, void 0, (d) => d.id === a.remove.id);
83
+ return e.remove(i);
81
84
  }
82
85
  return e;
83
86
  }
@@ -87,9 +90,9 @@ const f = U((n) => {
87
90
  return this.getState(o);
88
91
  },
89
92
  handlePaste: (o, t) => {
90
- var a, s;
93
+ var a, i;
91
94
  const { enableHtmlFileUploader: e } = n.get(c.key);
92
- return !(t instanceof ClipboardEvent) || !e && ((a = t.clipboardData) != null && a.getData("text/html")) ? !1 : l(o, t, (s = t.clipboardData) == null ? void 0 : s.files);
95
+ return !(t instanceof ClipboardEvent) || !e && ((a = t.clipboardData) != null && a.getData("text/html")) ? !1 : l(o, t, (i = t.clipboardData) == null ? void 0 : i.files);
93
96
  },
94
97
  handleDrop: (o, t) => {
95
98
  var e;
@@ -1 +1 @@
1
- {"version":3,"file":"index.es.js","sources":["../src/default-uploader.ts","../src/upload.ts","../src/index.ts"],"sourcesContent":["/* Copyright 2021, Milkdown by Mirone. */\nimport { missingNodeInSchema } from '@milkdown/exception'\nimport type { Node } from '@milkdown/prose/model'\n\nimport type { Uploader } from './upload'\n\n/// Read the image file as base64.\nexport const readImageAsBase64 = (file: File): Promise<{ alt: string; src: string }> => {\n return new Promise((resolve) => {\n const reader = new FileReader()\n reader.addEventListener(\n 'load',\n () => {\n resolve({\n alt: file.name,\n src: reader.result as string,\n })\n },\n false,\n )\n reader.readAsDataURL(file)\n })\n}\n\n/// The default uploader.\n/// It will upload transform images to base64.\nexport const defaultUploader: Uploader = async (files, schema) => {\n const imgs: File[] = []\n\n for (let i = 0; i < files.length; i++) {\n const file = files.item(i)\n if (!file)\n continue\n\n if (!file.type.includes('image'))\n continue\n\n imgs.push(file)\n }\n\n const { image } = schema.nodes\n if (!image)\n throw missingNodeInSchema('image')\n\n const data = await Promise.all(imgs.map(img => readImageAsBase64(img)))\n\n return data.map(({ alt, src }) => image.createAndFill({ src, alt }) as Node)\n}\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { schemaCtx } from '@milkdown/core'\nimport type { Fragment, Node, Schema } from '@milkdown/prose/model'\nimport type { EditorState } from '@milkdown/prose/state'\nimport { Plugin, PluginKey } from '@milkdown/prose/state'\nimport type { EditorView } from '@milkdown/prose/view'\nimport { Decoration, DecorationSet } from '@milkdown/prose/view'\nimport { $ctx, $prose } from '@milkdown/utils'\n\nimport { defaultUploader } from './default-uploader'\n\n/// @internal\nexport type Uploader = UploadOptions['uploader']\ninterface Spec { id: symbol; pos: number }\n\n/// The configuration for upload.\nexport interface UploadOptions {\n /// The uploader for upload plugin.\n /// It takes the files and schema as parameters.\n /// It should return a `Promise` of Prosemirror `Fragment` or `Node` or `Node[]`.\n uploader: (files: FileList, schema: Schema) => Promise<Fragment | Node | Node[]>\n /// Whether to enable the html file uploader.\n /// When paste files from html (for example copy images by right click context menu),\n /// this option will make the plugin to upload the image copied instead of using the original link.\n enableHtmlFileUploader: boolean\n /// The factory for upload widget.\n /// The widget will be displayed when the file is uploading.\n /// It takes the position and spec as parameters.\n /// It should return a `Decoration` of Prosemirror.\n /// By default, it will return `<span>Upload in progress...</span>`.\n uploadWidgetFactory: (pos: number, spec: Parameters<typeof Decoration.widget>[2]) => Decoration\n}\n\n/// A slice that contains the configuration for upload.\n/// It should be typed of `UploadConfig`.\nexport const uploadConfig = $ctx<UploadOptions, 'uploadConfig'>({\n uploader: defaultUploader,\n enableHtmlFileUploader: false,\n uploadWidgetFactory: (pos, spec) => {\n const widgetDOM = document.createElement('span')\n widgetDOM.textContent = 'Upload in progress...'\n return Decoration.widget(pos, widgetDOM, spec)\n },\n}, 'uploadConfig')\n\nuploadConfig.meta = {\n package: '@milkdown/plugin-upload',\n displayName: 'Ctx<uploadConfig>',\n}\n\n/// The prosemirror plugin for upload.\nexport const uploadPlugin = $prose((ctx) => {\n const pluginKey = new PluginKey('MILKDOWN_UPLOAD')\n\n const findPlaceholder = (state: EditorState, id: symbol): number => {\n const decorations = pluginKey.getState(state)\n if (!decorations)\n return -1\n const found = decorations.find(undefined, undefined, (spec: Spec) => spec.id === id)\n if (!found.length)\n return -1\n return found[0]?.from ?? -1\n }\n\n const handleUpload = (view: EditorView, event: DragEvent | ClipboardEvent, files: FileList | undefined) => {\n if (!files || files.length <= 0)\n return false\n\n const id = Symbol('upload symbol')\n const schema = ctx.get(schemaCtx)\n const { tr } = view.state\n const insertPos = event instanceof DragEvent\n ? view.posAtCoords({ left: event.clientX, top: event.clientY })?.pos ?? tr.selection.from\n : tr.selection.from\n view.dispatch(tr.setMeta(pluginKey, { add: { id, pos: insertPos } }))\n\n const { uploader } = ctx.get(uploadConfig.key)\n uploader(files, schema)\n .then((fragment) => {\n const pos = findPlaceholder(view.state, id)\n if (pos < 0)\n return\n\n view.dispatch(\n view.state.tr\n .replaceWith(pos, pos, fragment)\n .setMeta(pluginKey, { remove: { id } }),\n )\n })\n .catch((e) => {\n console.error(e)\n })\n return true\n }\n\n return new Plugin({\n key: pluginKey,\n state: {\n init() {\n return DecorationSet.empty\n },\n apply(this: Plugin, tr, set) {\n const _set = set.map(tr.mapping, tr.doc)\n const action = tr.getMeta(this)\n if (!action)\n return _set\n\n if (action.add) {\n const { uploadWidgetFactory } = ctx.get(uploadConfig.key)\n\n const decoration = uploadWidgetFactory(action.add.pos, { id: action.add.id })\n return _set.add(tr.doc, [decoration])\n }\n if (action.remove) {\n const target = _set.find(undefined, undefined, (spec: Spec) => spec.id === action.remove.id)\n return _set.remove(target)\n }\n\n return _set\n },\n },\n props: {\n decorations(this: Plugin, state) {\n return this.getState(state)\n },\n handlePaste: (view, event) => {\n const { enableHtmlFileUploader } = ctx.get(uploadConfig.key)\n if (!(event instanceof ClipboardEvent))\n return false\n\n if (!enableHtmlFileUploader && event.clipboardData?.getData('text/html'))\n return false\n\n return handleUpload(view, event, event.clipboardData?.files)\n },\n handleDrop: (view, event) => {\n if (!(event instanceof DragEvent))\n return false\n\n return handleUpload(view, event, event.dataTransfer?.files)\n },\n },\n })\n})\n\nuploadPlugin.meta = {\n package: '@milkdown/plugin-upload',\n displayName: 'Prose<upload>',\n}\n","/* Copyright 2021, Milkdown by Mirone. */\nimport type { MilkdownPlugin } from '@milkdown/ctx'\nimport { uploadConfig, uploadPlugin } from './upload'\n\nexport * from './upload'\nexport * from './default-uploader'\n\n/// All plugins exported by this package.\nexport const upload: MilkdownPlugin[] = [uploadConfig, uploadPlugin]\n"],"names":["readImageAsBase64","file","resolve","reader","defaultUploader","files","schema","imgs","i","image","missingNodeInSchema","img","alt","src","uploadConfig","$ctx","pos","spec","widgetDOM","Decoration","uploadPlugin","$prose","ctx","pluginKey","PluginKey","findPlaceholder","state","id","decorations","found","_a","handleUpload","view","event","schemaCtx","tr","insertPos","uploader","fragment","e","Plugin","DecorationSet","set","_set","action","uploadWidgetFactory","decoration","target","enableHtmlFileUploader","_b","upload"],"mappings":"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"}
1
+ {"version":3,"file":"index.es.js","sources":["../src/default-uploader.ts","../src/upload.ts","../src/index.ts"],"sourcesContent":["/* Copyright 2021, Milkdown by Mirone. */\nimport { missingNodeInSchema } from '@milkdown/exception'\nimport type { Node } from '@milkdown/prose/model'\n\nimport type { Uploader } from './upload'\n\n/// Read the image file as base64.\nexport function readImageAsBase64(file: File): Promise<{ alt: string, src: string }> {\n return new Promise((resolve) => {\n const reader = new FileReader()\n reader.addEventListener(\n 'load',\n () => {\n resolve({\n alt: file.name,\n src: reader.result as string,\n })\n },\n false,\n )\n reader.readAsDataURL(file)\n })\n}\n\n/// The default uploader.\n/// It will upload transform images to base64.\nexport const defaultUploader: Uploader = async (files, schema) => {\n const imgs: File[] = []\n\n for (let i = 0; i < files.length; i++) {\n const file = files.item(i)\n if (!file)\n continue\n\n if (!file.type.includes('image'))\n continue\n\n imgs.push(file)\n }\n\n const { image } = schema.nodes\n if (!image)\n throw missingNodeInSchema('image')\n\n const data = await Promise.all(imgs.map(img => readImageAsBase64(img)))\n\n return data.map(({ alt, src }) => image.createAndFill({ src, alt }) as Node)\n}\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { schemaCtx } from '@milkdown/core'\nimport type { Fragment, Node, Schema } from '@milkdown/prose/model'\nimport type { EditorState } from '@milkdown/prose/state'\nimport { Plugin, PluginKey } from '@milkdown/prose/state'\nimport type { EditorView } from '@milkdown/prose/view'\nimport { Decoration, DecorationSet } from '@milkdown/prose/view'\nimport { $ctx, $prose } from '@milkdown/utils'\n\nimport { defaultUploader } from './default-uploader'\n\n/// @internal\nexport type Uploader = UploadOptions['uploader']\ninterface Spec { id: symbol, pos: number }\n\n/// The configuration for upload.\nexport interface UploadOptions {\n /// The uploader for upload plugin.\n /// It takes the files and schema as parameters.\n /// It should return a `Promise` of Prosemirror `Fragment` or `Node` or `Node[]`.\n uploader: (files: FileList, schema: Schema) => Promise<Fragment | Node | Node[]>\n /// Whether to enable the html file uploader.\n /// When paste files from html (for example copy images by right click context menu),\n /// this option will make the plugin to upload the image copied instead of using the original link.\n enableHtmlFileUploader: boolean\n /// The factory for upload widget.\n /// The widget will be displayed when the file is uploading.\n /// It takes the position and spec as parameters.\n /// It should return a `Decoration` of Prosemirror.\n /// By default, it will return `<span>Upload in progress...</span>`.\n uploadWidgetFactory: (pos: number, spec: Parameters<typeof Decoration.widget>[2]) => Decoration\n}\n\n/// A slice that contains the configuration for upload.\n/// It should be typed of `UploadConfig`.\nexport const uploadConfig = $ctx<UploadOptions, 'uploadConfig'>({\n uploader: defaultUploader,\n enableHtmlFileUploader: false,\n uploadWidgetFactory: (pos, spec) => {\n const widgetDOM = document.createElement('span')\n widgetDOM.textContent = 'Upload in progress...'\n return Decoration.widget(pos, widgetDOM, spec)\n },\n}, 'uploadConfig')\n\nuploadConfig.meta = {\n package: '@milkdown/plugin-upload',\n displayName: 'Ctx<uploadConfig>',\n}\n\n/// The prosemirror plugin for upload.\nexport const uploadPlugin = $prose((ctx) => {\n const pluginKey = new PluginKey('MILKDOWN_UPLOAD')\n\n const findPlaceholder = (state: EditorState, id: symbol): number => {\n const decorations = pluginKey.getState(state)\n if (!decorations)\n return -1\n const found = decorations.find(undefined, undefined, (spec: Spec) => spec.id === id)\n if (!found.length)\n return -1\n return found[0]?.from ?? -1\n }\n\n const handleUpload = (view: EditorView, event: DragEvent | ClipboardEvent, files: FileList | undefined) => {\n if (!files || files.length <= 0)\n return false\n\n const id = Symbol('upload symbol')\n const schema = ctx.get(schemaCtx)\n const { tr } = view.state\n const insertPos = event instanceof DragEvent\n ? view.posAtCoords({ left: event.clientX, top: event.clientY })?.pos ?? tr.selection.from\n : tr.selection.from\n view.dispatch(tr.setMeta(pluginKey, { add: { id, pos: insertPos } }))\n\n const { uploader } = ctx.get(uploadConfig.key)\n uploader(files, schema)\n .then((fragment) => {\n const pos = findPlaceholder(view.state, id)\n if (pos < 0)\n return\n\n view.dispatch(\n view.state.tr\n .replaceWith(pos, pos, fragment)\n .setMeta(pluginKey, { remove: { id } }),\n )\n })\n .catch((e) => {\n console.error(e)\n })\n return true\n }\n\n return new Plugin({\n key: pluginKey,\n state: {\n init() {\n return DecorationSet.empty\n },\n apply(this: Plugin, tr, set) {\n const _set = set.map(tr.mapping, tr.doc)\n const action = tr.getMeta(this)\n if (!action)\n return _set\n\n if (action.add) {\n const { uploadWidgetFactory } = ctx.get(uploadConfig.key)\n\n const decoration = uploadWidgetFactory(action.add.pos, { id: action.add.id })\n return _set.add(tr.doc, [decoration])\n }\n if (action.remove) {\n const target = _set.find(undefined, undefined, (spec: Spec) => spec.id === action.remove.id)\n return _set.remove(target)\n }\n\n return _set\n },\n },\n props: {\n decorations(this: Plugin, state) {\n return this.getState(state)\n },\n handlePaste: (view, event) => {\n const { enableHtmlFileUploader } = ctx.get(uploadConfig.key)\n if (!(event instanceof ClipboardEvent))\n return false\n\n if (!enableHtmlFileUploader && event.clipboardData?.getData('text/html'))\n return false\n\n return handleUpload(view, event, event.clipboardData?.files)\n },\n handleDrop: (view, event) => {\n if (!(event instanceof DragEvent))\n return false\n\n return handleUpload(view, event, event.dataTransfer?.files)\n },\n },\n })\n})\n\nuploadPlugin.meta = {\n package: '@milkdown/plugin-upload',\n displayName: 'Prose<upload>',\n}\n","/* Copyright 2021, Milkdown by Mirone. */\nimport type { MilkdownPlugin } from '@milkdown/ctx'\nimport { uploadConfig, uploadPlugin } from './upload'\n\nexport * from './upload'\nexport * from './default-uploader'\n\n/// All plugins exported by this package.\nexport const upload: MilkdownPlugin[] = [uploadConfig, uploadPlugin]\n"],"names":["readImageAsBase64","file","resolve","reader","defaultUploader","files","schema","imgs","i","image","missingNodeInSchema","img","alt","src","uploadConfig","$ctx","pos","spec","widgetDOM","Decoration","uploadPlugin","$prose","ctx","pluginKey","PluginKey","findPlaceholder","state","id","decorations","found","_a","handleUpload","view","event","schemaCtx","tr","insertPos","uploader","fragment","e","Plugin","DecorationSet","set","_set","action","uploadWidgetFactory","decoration","target","enableHtmlFileUploader","_b","upload"],"mappings":";;;;;AAOO,SAASA,EAAkBC,GAAmD;AAC5E,SAAA,IAAI,QAAQ,CAACC,MAAY;AACxB,UAAAC,IAAS,IAAI;AACZ,IAAAA,EAAA;AAAA,MACL;AAAA,MACA,MAAM;AACI,QAAAD,EAAA;AAAA,UACN,KAAKD,EAAK;AAAA,UACV,KAAKE,EAAO;AAAA,QAAA,CACb;AAAA,MACH;AAAA,MACA;AAAA,IAAA,GAEFA,EAAO,cAAcF,CAAI;AAAA,EAAA,CAC1B;AACH;AAIa,MAAAG,IAA4B,OAAOC,GAAOC,MAAW;AAChE,QAAMC,IAAe,CAAA;AAErB,WAASC,IAAI,GAAGA,IAAIH,EAAM,QAAQG,KAAK;AAC/B,UAAAP,IAAOI,EAAM,KAAKG,CAAC;AACzB,IAAKP,KAGAA,EAAK,KAAK,SAAS,OAAO,KAG/BM,EAAK,KAAKN,CAAI;AAAA,EAChB;AAEM,QAAA,EAAE,OAAAQ,EAAM,IAAIH,EAAO;AACzB,MAAI,CAACG;AACH,UAAMC,EAAoB,OAAO;AAInC,UAFa,MAAM,QAAQ,IAAIH,EAAK,IAAI,CAAOI,MAAAX,EAAkBW,CAAG,CAAC,CAAC,GAE1D,IAAI,CAAC,EAAE,KAAAC,GAAK,KAAAC,EAAA,MAAUJ,EAAM,cAAc,EAAE,KAAAI,GAAK,KAAAD,EAAA,CAAK,CAAS;AAC7E,GCZaE,IAAeC,EAAoC;AAAA,EAC9D,UAAUX;AAAA,EACV,wBAAwB;AAAA,EACxB,qBAAqB,CAACY,GAAKC,MAAS;AAC5B,UAAAC,IAAY,SAAS,cAAc,MAAM;AAC/C,WAAAA,EAAU,cAAc,yBACjBC,EAAW,OAAOH,GAAKE,GAAWD,CAAI;AAAA,EAC/C;AACF,GAAG,cAAc;AAEjBH,EAAa,OAAO;AAAA,EAClB,SAAS;AAAA,EACT,aAAa;AACf;AAGa,MAAAM,IAAeC,EAAO,CAACC,MAAQ;AACpC,QAAAC,IAAY,IAAIC,EAAU,iBAAiB,GAE3CC,IAAkB,CAACC,GAAoBC,MAAuB;;AAC5D,UAAAC,IAAcL,EAAU,SAASG,CAAK;AAC5C,QAAI,CAACE;AACI,aAAA;AACH,UAAAC,IAAQD,EAAY,KAAK,QAAW,QAAW,CAACX,MAAeA,EAAK,OAAOU,CAAE;AACnF,WAAKE,EAAM,WAEJC,IAAAD,EAAM,CAAC,MAAP,gBAAAC,EAAU,SAAQ,KADhB;AAAA,EACgB,GAGrBC,IAAe,CAACC,GAAkBC,GAAmC5B,MAAgC;;AACrG,QAAA,CAACA,KAASA,EAAM,UAAU;AACrB,aAAA;AAEH,UAAAsB,IAAK,OAAO,eAAe,GAC3BrB,IAASgB,EAAI,IAAIY,CAAS,GAC1B,EAAE,IAAAC,EAAG,IAAIH,EAAK,OACdI,IAAYH,aAAiB,cAC/BH,IAAAE,EAAK,YAAY,EAAE,MAAMC,EAAM,SAAS,KAAKA,EAAM,QAAA,CAAS,MAA5D,gBAAAH,EAA+D,QAAOK,EAAG,UAAU,OACnFA,EAAG,UAAU;AACjB,IAAAH,EAAK,SAASG,EAAG,QAAQZ,GAAW,EAAE,KAAK,EAAE,IAAAI,GAAI,KAAKS,EAAY,EAAA,CAAC,CAAC;AAEpE,UAAM,EAAE,UAAAC,EAAS,IAAIf,EAAI,IAAIR,EAAa,GAAG;AAC7C,WAAAuB,EAAShC,GAAOC,CAAM,EACnB,KAAK,CAACgC,MAAa;AAClB,YAAMtB,IAAMS,EAAgBO,EAAK,OAAOL,CAAE;AAC1C,MAAIX,IAAM,KAGLgB,EAAA;AAAA,QACHA,EAAK,MAAM,GACR,YAAYhB,GAAKA,GAAKsB,CAAQ,EAC9B,QAAQf,GAAW,EAAE,QAAQ,EAAE,IAAAI,KAAM;AAAA,MAAA;AAAA,IAC1C,CACD,EACA,MAAM,CAACY,MAAM;AACZ,cAAQ,MAAMA,CAAC;AAAA,IAAA,CAChB,GACI;AAAA,EAAA;AAGT,SAAO,IAAIC,EAAO;AAAA,IAChB,KAAKjB;AAAA,IACL,OAAO;AAAA,MACL,OAAO;AACL,eAAOkB,EAAc;AAAA,MACvB;AAAA,MACA,MAAoBN,GAAIO,GAAK;AAC3B,cAAMC,IAAOD,EAAI,IAAIP,EAAG,SAASA,EAAG,GAAG,GACjCS,IAAST,EAAG,QAAQ,IAAI;AAC9B,YAAI,CAACS;AACI,iBAAAD;AAET,YAAIC,EAAO,KAAK;AACd,gBAAM,EAAE,qBAAAC,EAAoB,IAAIvB,EAAI,IAAIR,EAAa,GAAG,GAElDgC,IAAaD,EAAoBD,EAAO,IAAI,KAAK,EAAE,IAAIA,EAAO,IAAI,GAAI,CAAA;AAC5E,iBAAOD,EAAK,IAAIR,EAAG,KAAK,CAACW,CAAU,CAAC;AAAA,QACtC;AACA,YAAIF,EAAO,QAAQ;AACX,gBAAAG,IAASJ,EAAK,KAAK,QAAW,QAAW,CAAC1B,MAAeA,EAAK,OAAO2B,EAAO,OAAO,EAAE;AACpF,iBAAAD,EAAK,OAAOI,CAAM;AAAA,QAC3B;AAEO,eAAAJ;AAAA,MACT;AAAA,IACF;AAAA,IACA,OAAO;AAAA,MACL,YAA0BjB,GAAO;AACxB,eAAA,KAAK,SAASA,CAAK;AAAA,MAC5B;AAAA,MACA,aAAa,CAACM,GAAMC,MAAU;;AAC5B,cAAM,EAAE,wBAAAe,EAAuB,IAAI1B,EAAI,IAAIR,EAAa,GAAG;AAI3D,eAHI,EAAEmB,aAAiB,mBAGnB,CAACe,OAA0BlB,IAAAG,EAAM,kBAAN,QAAAH,EAAqB,QAAQ,gBACnD,KAEFC,EAAaC,GAAMC,IAAOgB,IAAAhB,EAAM,kBAAN,gBAAAgB,EAAqB,KAAK;AAAA,MAC7D;AAAA,MACA,YAAY,CAACjB,GAAMC,MAAU;;AAC3B,eAAMA,aAAiB,YAGhBF,EAAaC,GAAMC,IAAOH,IAAAG,EAAM,iBAAN,gBAAAH,EAAoB,KAAK,IAFjD;AAAA,MAGX;AAAA,IACF;AAAA,EAAA,CACD;AACH,CAAC;AAEDV,EAAa,OAAO;AAAA,EAClB,SAAS;AAAA,EACT,aAAa;AACf;AC5Ia,MAAA8B,IAA2B,CAACpC,GAAcM,CAAY;"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@milkdown/plugin-upload",
3
3
  "type": "module",
4
- "version": "7.3.1",
4
+ "version": "7.3.2",
5
5
  "license": "MIT",
6
6
  "repository": {
7
7
  "type": "git",
@@ -26,13 +26,13 @@
26
26
  },
27
27
  "dependencies": {
28
28
  "tslib": "^2.5.0",
29
- "@milkdown/exception": "7.3.1",
30
- "@milkdown/utils": "7.3.1"
29
+ "@milkdown/exception": "7.3.2",
30
+ "@milkdown/utils": "7.3.2"
31
31
  },
32
32
  "devDependencies": {
33
- "@milkdown/core": "7.3.1",
34
- "@milkdown/ctx": "7.3.1",
35
- "@milkdown/prose": "7.3.1"
33
+ "@milkdown/core": "7.3.2",
34
+ "@milkdown/ctx": "7.3.2",
35
+ "@milkdown/prose": "7.3.2"
36
36
  },
37
37
  "nx": {
38
38
  "targets": {
@@ -5,7 +5,7 @@ import type { Node } from '@milkdown/prose/model'
5
5
  import type { Uploader } from './upload'
6
6
 
7
7
  /// Read the image file as base64.
8
- export const readImageAsBase64 = (file: File): Promise<{ alt: string; src: string }> => {
8
+ export function readImageAsBase64(file: File): Promise<{ alt: string, src: string }> {
9
9
  return new Promise((resolve) => {
10
10
  const reader = new FileReader()
11
11
  reader.addEventListener(
package/src/upload.ts CHANGED
@@ -11,7 +11,7 @@ import { defaultUploader } from './default-uploader'
11
11
 
12
12
  /// @internal
13
13
  export type Uploader = UploadOptions['uploader']
14
- interface Spec { id: symbol; pos: number }
14
+ interface Spec { id: symbol, pos: number }
15
15
 
16
16
  /// The configuration for upload.
17
17
  export interface UploadOptions {