@milkdown/plugin-upload 6.5.2 → 6.5.4

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 +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,CAAC;AAmBzC,eAAO,MAAM,eAAe,EAAE,QAwB7B,CAAC"}
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;AAmBxC,eAAO,MAAM,eAAe,EAAE,QAqB7B,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAI3C,YAAY,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,GAAG,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAE7C,eAAO,MAAM,MAAM,iKAAoC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAI1C,YAAY,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AACxC,OAAO,EAAE,GAAG,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAE5C,eAAO,MAAM,MAAM,iKAAoC,CAAA"}
package/lib/index.es.js CHANGED
@@ -37,19 +37,19 @@ const F = (l) => new Promise((o) => {
37
37
  return _.empty;
38
38
  },
39
39
  apply(e, r) {
40
- const t = r.map(e.mapping, e.doc), n = e.getMeta(this);
41
- if (!n)
40
+ const t = r.map(e.mapping, e.doc), a = e.getMeta(this);
41
+ if (!a)
42
42
  return t;
43
- if (n.add) {
44
- const a = document.createElement("span"), c = s.get(E).get(L, "loading");
43
+ if (a.add) {
44
+ const n = document.createElement("span"), c = s.get(E).get(L, "loading");
45
45
  if (!c)
46
46
  throw S("loading");
47
- a.appendChild(c.dom);
48
- const m = x.widget(n.add.pos, a, { id: n.add.id });
47
+ n.appendChild(c.dom);
48
+ const m = x.widget(a.add.pos, n, { id: a.add.id });
49
49
  return t.add(e.doc, [m]);
50
50
  }
51
- return n.remove ? t.remove(
52
- t.find(void 0, void 0, (a) => a.id === n.remove.id)
51
+ return a.remove ? t.remove(
52
+ t.find(void 0, void 0, (n) => n.id === a.remove.id)
53
53
  ) : t;
54
54
  }
55
55
  },
@@ -59,21 +59,21 @@ const F = (l) => new Promise((o) => {
59
59
  }
60
60
  }
61
61
  }), b = (e, r) => {
62
- var a, c;
62
+ var n, c;
63
63
  const t = p.getState(e);
64
64
  if (!t)
65
65
  return -1;
66
- const n = t.find(void 0, void 0, (m) => m.id === r);
67
- return n.length && (c = (a = n[0]) == null ? void 0 : a.from) != null ? c : -1;
66
+ const a = t.find(void 0, void 0, (m) => m.id === r);
67
+ return a.length && (c = (n = a[0]) == null ? void 0 : n.from) != null ? c : -1;
68
68
  }, h = (e, r, t) => {
69
69
  var m, P;
70
70
  if (!t || t.length <= 0)
71
71
  return !1;
72
- const n = Symbol("upload symbol"), { tr: a } = e.state, c = r instanceof DragEvent && (P = (m = e.posAtCoords({ left: r.clientX, top: r.clientY })) == null ? void 0 : m.pos) != null ? P : a.selection.from;
73
- return e.dispatch(a.setMeta(p, { add: { id: n, pos: c } })), i(t, d).then((f) => {
74
- const g = b(e.state, n);
72
+ const a = Symbol("upload symbol"), { tr: n } = e.state, c = r instanceof DragEvent && (P = (m = e.posAtCoords({ left: r.clientX, top: r.clientY })) == null ? void 0 : m.pos) != null ? P : n.selection.from;
73
+ return e.dispatch(n.setMeta(p, { add: { id: a, pos: c } })), i(t, d).then((f) => {
74
+ const g = b(e.state, a);
75
75
  g < 0 || e.dispatch(
76
- e.state.tr.replaceWith(g, g, f).setMeta(p, { remove: { id: n } })
76
+ e.state.tr.replaceWith(g, g, f).setMeta(p, { remove: { id: a } })
77
77
  );
78
78
  }).catch((f) => {
79
79
  console.error(f);
@@ -81,8 +81,8 @@ const F = (l) => new Promise((o) => {
81
81
  }, A = new D({
82
82
  props: {
83
83
  handlePaste: (e, r) => {
84
- var t, n;
85
- return !(r instanceof ClipboardEvent) || !(o != null && o.enableHtmlFileUploader) && ((t = r.clipboardData) == null ? void 0 : t.getData("text/html")) ? !1 : h(e, r, (n = r.clipboardData) == null ? void 0 : n.files);
84
+ var t, a;
85
+ return !(r instanceof ClipboardEvent) || !(o != null && o.enableHtmlFileUploader) && ((t = r.clipboardData) == null ? void 0 : t.getData("text/html")) ? !1 : h(e, r, (a = r.clipboardData) == null ? void 0 : a.files);
86
86
  },
87
87
  handleDrop: (e, r) => {
88
88
  var t;
@@ -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\nconst 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\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\n if (!file.type.includes('image')) {\n continue;\n }\n\n imgs.push(file);\n }\n\n const { image } = schema.nodes;\n if (!image) {\n throw missingNodeInSchema('image');\n }\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, ThemeIcon, themeManagerCtx } from '@milkdown/core';\nimport { missingIcon } from '@milkdown/exception';\nimport { Fragment, Node, Schema } from '@milkdown/prose/model';\nimport { EditorState, Plugin, PluginKey } from '@milkdown/prose/state';\nimport { Decoration, DecorationSet, EditorView } from '@milkdown/prose/view';\nimport { createPlugin } from '@milkdown/utils';\n\nimport { defaultUploader } from './default-uploader';\n\nexport type Uploader = (files: FileList, schema: Schema) => Promise<Fragment | Node | Node[]>;\ntype Spec = { id: symbol; pos: number };\nexport type Options = {\n uploader: Uploader;\n enableHtmlFileUploader: boolean;\n};\nexport const key = new PluginKey('MILKDOWN_UPLOAD');\n\nexport const uploadPlugin = createPlugin<string, Options>((_, options) => {\n const uploader = options?.uploader ?? defaultUploader;\n\n return {\n prosePlugins: (_, ctx) => {\n const schema = ctx.get(schemaCtx);\n\n const placeholderPlugin = new Plugin({\n key,\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 widget = document.createElement('span');\n const loadingIcon = ctx.get(themeManagerCtx).get(ThemeIcon, 'loading');\n if (!loadingIcon) {\n throw missingIcon('loading');\n }\n widget.appendChild(loadingIcon.dom);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const decoration = Decoration.widget(action.add.pos, widget, { id: action.add.id } as any);\n return _set.add(tr.doc, [decoration]);\n }\n if (action.remove) {\n return _set.remove(\n _set.find(undefined, undefined, (spec: Spec) => spec.id === action.remove.id),\n );\n }\n\n return _set;\n },\n },\n props: {\n decorations(this: Plugin, state) {\n return this.getState(state);\n },\n },\n });\n\n const findPlaceholder = (state: EditorState, id: symbol): number => {\n const decorations = placeholderPlugin.getState(state);\n if (!decorations) return -1;\n const found = decorations.find(undefined, undefined, (spec: Spec) => spec.id === id);\n if (!found.length) 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 { tr } = view.state;\n const insertPos =\n 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(placeholderPlugin, { add: { id, pos: insertPos } }));\n\n uploader(files, schema)\n .then((fragment) => {\n const pos = findPlaceholder(view.state, id);\n if (pos < 0) return;\n\n view.dispatch(\n view.state.tr\n .replaceWith(pos, pos, fragment)\n .setMeta(placeholderPlugin, { remove: { id } }),\n );\n return;\n })\n .catch((e) => {\n console.error(e);\n });\n return true;\n };\n\n const uploadPlugin = new Plugin({\n props: {\n handlePaste: (view, event) => {\n if (!(event instanceof ClipboardEvent)) {\n return false;\n }\n\n if (!options?.enableHtmlFileUploader && event.clipboardData?.getData('text/html')) {\n return false;\n }\n\n return handleUpload(view, event, event.clipboardData?.files);\n },\n handleDrop: (view, event) => {\n if (!(event instanceof DragEvent)) {\n return false;\n }\n\n return handleUpload(view, event, event.dataTransfer?.files);\n },\n },\n });\n return [placeholderPlugin, uploadPlugin];\n },\n };\n});\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { AtomList } from '@milkdown/utils';\n\nimport { uploadPlugin } from './upload';\n\nexport type { Uploader } from './upload';\nexport { key, uploadPlugin } from './upload';\n\nexport const upload = AtomList.create([uploadPlugin()]);\n"],"names":["readImageAsBase64","file","resolve","reader","defaultUploader","files","schema","imgs","i","image","missingNodeInSchema","img","alt","src","key","PluginKey","uploadPlugin","createPlugin","_","options","uploader","_a","ctx","schemaCtx","placeholderPlugin","Plugin","DecorationSet","tr","set","_set","action","widget","loadingIcon","themeManagerCtx","ThemeIcon","missingIcon","decoration","Decoration","spec","state","findPlaceholder","id","decorations","found","_b","handleUpload","view","event","insertPos","fragment","pos","e","upload","AtomList"],"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\nconst 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\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 { ThemeIcon, schemaCtx, themeManagerCtx } from '@milkdown/core'\nimport { missingIcon } from '@milkdown/exception'\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 { createPlugin } from '@milkdown/utils'\n\nimport { defaultUploader } from './default-uploader'\n\nexport type Uploader = (files: FileList, schema: Schema) => Promise<Fragment | Node | Node[]>\ninterface Spec { id: symbol; pos: number }\nexport interface Options {\n uploader: Uploader\n enableHtmlFileUploader: boolean\n}\nexport const key = new PluginKey('MILKDOWN_UPLOAD')\n\nexport const uploadPlugin = createPlugin<string, Options>((_, options) => {\n const uploader = options?.uploader ?? defaultUploader\n\n return {\n prosePlugins: (_, ctx) => {\n const schema = ctx.get(schemaCtx)\n\n const placeholderPlugin = new Plugin({\n key,\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 widget = document.createElement('span')\n const loadingIcon = ctx.get(themeManagerCtx).get(ThemeIcon, 'loading')\n if (!loadingIcon)\n throw missingIcon('loading')\n\n widget.appendChild(loadingIcon.dom)\n\n const decoration = Decoration.widget(action.add.pos, widget, { id: action.add.id } as any)\n return _set.add(tr.doc, [decoration])\n }\n if (action.remove) {\n return _set.remove(\n _set.find(undefined, undefined, (spec: Spec) => spec.id === action.remove.id),\n )\n }\n\n return _set\n },\n },\n props: {\n decorations(this: Plugin, state) {\n return this.getState(state)\n },\n },\n })\n\n const findPlaceholder = (state: EditorState, id: symbol): number => {\n const decorations = placeholderPlugin.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 { tr } = view.state\n const insertPos\n = 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(placeholderPlugin, { add: { id, pos: insertPos } }))\n\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(placeholderPlugin, { remove: { id } }),\n )\n })\n .catch((e) => {\n console.error(e)\n })\n return true\n }\n\n const uploadPlugin = new Plugin({\n props: {\n handlePaste: (view, event) => {\n if (!(event instanceof ClipboardEvent))\n return false\n\n if (!options?.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 return [placeholderPlugin, uploadPlugin]\n },\n }\n})\n","/* Copyright 2021, Milkdown by Mirone. */\nimport { AtomList } from '@milkdown/utils'\n\nimport { uploadPlugin } from './upload'\n\nexport type { Uploader } from './upload'\nexport { key, uploadPlugin } from './upload'\n\nexport const upload = AtomList.create([uploadPlugin()])\n"],"names":["readImageAsBase64","file","resolve","reader","defaultUploader","files","schema","imgs","i","image","missingNodeInSchema","img","alt","src","key","PluginKey","uploadPlugin","createPlugin","_","options","uploader","_a","ctx","schemaCtx","placeholderPlugin","Plugin","DecorationSet","tr","set","_set","action","widget","loadingIcon","themeManagerCtx","ThemeIcon","missingIcon","decoration","Decoration","spec","state","findPlaceholder","id","decorations","found","_b","handleUpload","view","event","insertPos","fragment","pos","e","upload","AtomList"],"mappings":"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"}
package/lib/upload.d.ts CHANGED
@@ -1,10 +1,10 @@
1
- import { Fragment, Node, Schema } from '@milkdown/prose/model';
1
+ import type { Fragment, Node, Schema } from '@milkdown/prose/model';
2
2
  import { PluginKey } from '@milkdown/prose/state';
3
- export declare type Uploader = (files: FileList, schema: Schema) => Promise<Fragment | Node | Node[]>;
4
- export declare type Options = {
3
+ export type Uploader = (files: FileList, schema: Schema) => Promise<Fragment | Node | Node[]>;
4
+ export interface Options {
5
5
  uploader: Uploader;
6
6
  enableHtmlFileUploader: boolean;
7
- };
7
+ }
8
8
  export declare const key: PluginKey<any>;
9
9
  export declare const uploadPlugin: import("@milkdown/utils").WithExtend<string, Options, import("@milkdown/utils").TypeMapping<string, string>, import("@milkdown/utils").PluginRest<string, string>>;
10
10
  //# sourceMappingURL=upload.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../src/upload.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAuB,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAMvE,oBAAY,QAAQ,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,QAAQ,GAAG,IAAI,GAAG,IAAI,EAAE,CAAC,CAAC;AAE9F,oBAAY,OAAO,GAAG;IAClB,QAAQ,EAAE,QAAQ,CAAC;IACnB,sBAAsB,EAAE,OAAO,CAAC;CACnC,CAAC;AACF,eAAO,MAAM,GAAG,gBAAmC,CAAC;AAEpD,eAAO,MAAM,YAAY,oKA6GvB,CAAC"}
1
+ {"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../src/upload.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AAEnE,OAAO,EAAU,SAAS,EAAE,MAAM,uBAAuB,CAAA;AAOzD,MAAM,MAAM,QAAQ,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,QAAQ,GAAG,IAAI,GAAG,IAAI,EAAE,CAAC,CAAA;AAE7F,MAAM,WAAW,OAAO;IACtB,QAAQ,EAAE,QAAQ,CAAA;IAClB,sBAAsB,EAAE,OAAO,CAAA;CAChC;AACD,eAAO,MAAM,GAAG,gBAAmC,CAAA;AAEnD,eAAO,MAAM,YAAY,oKA4GvB,CAAA"}
package/package.json CHANGED
@@ -1,31 +1,36 @@
1
1
  {
2
2
  "name": "@milkdown/plugin-upload",
3
- "version": "6.5.2",
4
3
  "type": "module",
4
+ "version": "6.5.4",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/Saul-Mirone/milkdown.git",
9
+ "directory": "packages/plugin-upload"
10
+ },
11
+ "keywords": [
12
+ "milkdown",
13
+ "milkdown plugin"
14
+ ],
15
+ "sideEffects": false,
5
16
  "main": "./lib/index.es.js",
6
17
  "types": "./lib/index.d.ts",
7
- "sideEffects": false,
8
- "license": "MIT",
9
18
  "files": [
10
19
  "lib",
11
20
  "src"
12
21
  ],
13
- "keywords": [
14
- "milkdown",
15
- "milkdown plugin"
16
- ],
17
- "devDependencies": {
18
- "@milkdown/core": "6.5.2",
19
- "@milkdown/prose": "6.5.2"
20
- },
21
22
  "peerDependencies": {
22
23
  "@milkdown/core": "^6.0.1",
23
24
  "@milkdown/prose": "^6.0.1"
24
25
  },
25
26
  "dependencies": {
26
- "@milkdown/utils": "6.5.2",
27
- "@milkdown/exception": "6.5.2",
28
- "tslib": "^2.4.0"
27
+ "tslib": "^2.4.0",
28
+ "@milkdown/exception": "6.5.4",
29
+ "@milkdown/utils": "6.5.4"
30
+ },
31
+ "devDependencies": {
32
+ "@milkdown/core": "6.5.4",
33
+ "@milkdown/prose": "6.5.4"
29
34
  },
30
35
  "nx": {
31
36
  "targets": {
@@ -1,48 +1,45 @@
1
1
  /* Copyright 2021, Milkdown by Mirone. */
2
- import { missingNodeInSchema } from '@milkdown/exception';
3
- import type { Node } from '@milkdown/prose/model';
2
+ import { missingNodeInSchema } from '@milkdown/exception'
3
+ import type { Node } from '@milkdown/prose/model'
4
4
 
5
- import type { Uploader } from './upload';
5
+ import type { Uploader } from './upload'
6
6
 
7
7
  const readImageAsBase64 = (file: File): Promise<{ alt: string; src: string }> => {
8
- return new Promise((resolve) => {
9
- const reader = new FileReader();
10
- reader.addEventListener(
11
- 'load',
12
- () => {
13
- resolve({
14
- alt: file.name,
15
- src: reader.result as string,
16
- });
17
- },
18
- false,
19
- );
20
- reader.readAsDataURL(file);
21
- });
22
- };
8
+ return new Promise((resolve) => {
9
+ const reader = new FileReader()
10
+ reader.addEventListener(
11
+ 'load',
12
+ () => {
13
+ resolve({
14
+ alt: file.name,
15
+ src: reader.result as string,
16
+ })
17
+ },
18
+ false,
19
+ )
20
+ reader.readAsDataURL(file)
21
+ })
22
+ }
23
23
 
24
24
  export const defaultUploader: Uploader = async (files, schema) => {
25
- const imgs: File[] = [];
25
+ const imgs: File[] = []
26
26
 
27
- for (let i = 0; i < files.length; i++) {
28
- const file = files.item(i);
29
- if (!file) {
30
- continue;
31
- }
27
+ for (let i = 0; i < files.length; i++) {
28
+ const file = files.item(i)
29
+ if (!file)
30
+ continue
32
31
 
33
- if (!file.type.includes('image')) {
34
- continue;
35
- }
32
+ if (!file.type.includes('image'))
33
+ continue
36
34
 
37
- imgs.push(file);
38
- }
35
+ imgs.push(file)
36
+ }
39
37
 
40
- const { image } = schema.nodes;
41
- if (!image) {
42
- throw missingNodeInSchema('image');
43
- }
38
+ const { image } = schema.nodes
39
+ if (!image)
40
+ throw missingNodeInSchema('image')
44
41
 
45
- const data = await Promise.all(imgs.map((img) => readImageAsBase64(img)));
42
+ const data = await Promise.all(imgs.map(img => readImageAsBase64(img)))
46
43
 
47
- return data.map(({ alt, src }) => image.createAndFill({ src, alt }) as Node);
48
- };
44
+ return data.map(({ alt, src }) => image.createAndFill({ src, alt }) as Node)
45
+ }
package/src/index.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  /* Copyright 2021, Milkdown by Mirone. */
2
- import { AtomList } from '@milkdown/utils';
2
+ import { AtomList } from '@milkdown/utils'
3
3
 
4
- import { uploadPlugin } from './upload';
4
+ import { uploadPlugin } from './upload'
5
5
 
6
- export type { Uploader } from './upload';
7
- export { key, uploadPlugin } from './upload';
6
+ export type { Uploader } from './upload'
7
+ export { key, uploadPlugin } from './upload'
8
8
 
9
- export const upload = AtomList.create([uploadPlugin()]);
9
+ export const upload = AtomList.create([uploadPlugin()])
package/src/upload.ts CHANGED
@@ -1,128 +1,129 @@
1
1
  /* Copyright 2021, Milkdown by Mirone. */
2
- import { schemaCtx, ThemeIcon, themeManagerCtx } from '@milkdown/core';
3
- import { missingIcon } from '@milkdown/exception';
4
- import { Fragment, Node, Schema } from '@milkdown/prose/model';
5
- import { EditorState, Plugin, PluginKey } from '@milkdown/prose/state';
6
- import { Decoration, DecorationSet, EditorView } from '@milkdown/prose/view';
7
- import { createPlugin } from '@milkdown/utils';
8
-
9
- import { defaultUploader } from './default-uploader';
10
-
11
- export type Uploader = (files: FileList, schema: Schema) => Promise<Fragment | Node | Node[]>;
12
- type Spec = { id: symbol; pos: number };
13
- export type Options = {
14
- uploader: Uploader;
15
- enableHtmlFileUploader: boolean;
16
- };
17
- export const key = new PluginKey('MILKDOWN_UPLOAD');
2
+ import { ThemeIcon, schemaCtx, themeManagerCtx } from '@milkdown/core'
3
+ import { missingIcon } from '@milkdown/exception'
4
+ import type { Fragment, Node, Schema } from '@milkdown/prose/model'
5
+ import type { EditorState } from '@milkdown/prose/state'
6
+ import { Plugin, PluginKey } from '@milkdown/prose/state'
7
+ import type { EditorView } from '@milkdown/prose/view'
8
+ import { Decoration, DecorationSet } from '@milkdown/prose/view'
9
+ import { createPlugin } from '@milkdown/utils'
10
+
11
+ import { defaultUploader } from './default-uploader'
12
+
13
+ export type Uploader = (files: FileList, schema: Schema) => Promise<Fragment | Node | Node[]>
14
+ interface Spec { id: symbol; pos: number }
15
+ export interface Options {
16
+ uploader: Uploader
17
+ enableHtmlFileUploader: boolean
18
+ }
19
+ export const key = new PluginKey('MILKDOWN_UPLOAD')
18
20
 
19
21
  export const uploadPlugin = createPlugin<string, Options>((_, options) => {
20
- const uploader = options?.uploader ?? defaultUploader;
21
-
22
- return {
23
- prosePlugins: (_, ctx) => {
24
- const schema = ctx.get(schemaCtx);
25
-
26
- const placeholderPlugin = new Plugin({
27
- key,
28
- state: {
29
- init() {
30
- return DecorationSet.empty;
31
- },
32
- apply(this: Plugin, tr, set) {
33
- const _set = set.map(tr.mapping, tr.doc);
34
- const action = tr.getMeta(this);
35
- if (!action) {
36
- return _set;
37
- }
38
- if (action.add) {
39
- const widget = document.createElement('span');
40
- const loadingIcon = ctx.get(themeManagerCtx).get(ThemeIcon, 'loading');
41
- if (!loadingIcon) {
42
- throw missingIcon('loading');
43
- }
44
- widget.appendChild(loadingIcon.dom);
45
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
46
- const decoration = Decoration.widget(action.add.pos, widget, { id: action.add.id } as any);
47
- return _set.add(tr.doc, [decoration]);
48
- }
49
- if (action.remove) {
50
- return _set.remove(
51
- _set.find(undefined, undefined, (spec: Spec) => spec.id === action.remove.id),
52
- );
53
- }
54
-
55
- return _set;
56
- },
57
- },
58
- props: {
59
- decorations(this: Plugin, state) {
60
- return this.getState(state);
61
- },
62
- },
63
- });
64
-
65
- const findPlaceholder = (state: EditorState, id: symbol): number => {
66
- const decorations = placeholderPlugin.getState(state);
67
- if (!decorations) return -1;
68
- const found = decorations.find(undefined, undefined, (spec: Spec) => spec.id === id);
69
- if (!found.length) return -1;
70
- return found[0]?.from ?? -1;
71
- };
72
-
73
- const handleUpload = (view: EditorView, event: DragEvent | ClipboardEvent, files: FileList | undefined) => {
74
- if (!files || files.length <= 0) {
75
- return false;
76
- }
77
- const id = Symbol('upload symbol');
78
- const { tr } = view.state;
79
- const insertPos =
80
- event instanceof DragEvent
81
- ? view.posAtCoords({ left: event.clientX, top: event.clientY })?.pos ?? tr.selection.from
82
- : tr.selection.from;
83
- view.dispatch(tr.setMeta(placeholderPlugin, { add: { id, pos: insertPos } }));
84
-
85
- uploader(files, schema)
86
- .then((fragment) => {
87
- const pos = findPlaceholder(view.state, id);
88
- if (pos < 0) return;
89
-
90
- view.dispatch(
91
- view.state.tr
92
- .replaceWith(pos, pos, fragment)
93
- .setMeta(placeholderPlugin, { remove: { id } }),
94
- );
95
- return;
96
- })
97
- .catch((e) => {
98
- console.error(e);
99
- });
100
- return true;
101
- };
102
-
103
- const uploadPlugin = new Plugin({
104
- props: {
105
- handlePaste: (view, event) => {
106
- if (!(event instanceof ClipboardEvent)) {
107
- return false;
108
- }
109
-
110
- if (!options?.enableHtmlFileUploader && event.clipboardData?.getData('text/html')) {
111
- return false;
112
- }
113
-
114
- return handleUpload(view, event, event.clipboardData?.files);
115
- },
116
- handleDrop: (view, event) => {
117
- if (!(event instanceof DragEvent)) {
118
- return false;
119
- }
120
-
121
- return handleUpload(view, event, event.dataTransfer?.files);
122
- },
123
- },
124
- });
125
- return [placeholderPlugin, uploadPlugin];
22
+ const uploader = options?.uploader ?? defaultUploader
23
+
24
+ return {
25
+ prosePlugins: (_, ctx) => {
26
+ const schema = ctx.get(schemaCtx)
27
+
28
+ const placeholderPlugin = new Plugin({
29
+ key,
30
+ state: {
31
+ init() {
32
+ return DecorationSet.empty
33
+ },
34
+ apply(this: Plugin, tr, set) {
35
+ const _set = set.map(tr.mapping, tr.doc)
36
+ const action = tr.getMeta(this)
37
+ if (!action)
38
+ return _set
39
+
40
+ if (action.add) {
41
+ const widget = document.createElement('span')
42
+ const loadingIcon = ctx.get(themeManagerCtx).get(ThemeIcon, 'loading')
43
+ if (!loadingIcon)
44
+ throw missingIcon('loading')
45
+
46
+ widget.appendChild(loadingIcon.dom)
47
+
48
+ const decoration = Decoration.widget(action.add.pos, widget, { id: action.add.id } as any)
49
+ return _set.add(tr.doc, [decoration])
50
+ }
51
+ if (action.remove) {
52
+ return _set.remove(
53
+ _set.find(undefined, undefined, (spec: Spec) => spec.id === action.remove.id),
54
+ )
55
+ }
56
+
57
+ return _set
58
+ },
59
+ },
60
+ props: {
61
+ decorations(this: Plugin, state) {
62
+ return this.getState(state)
63
+ },
64
+ },
65
+ })
66
+
67
+ const findPlaceholder = (state: EditorState, id: symbol): number => {
68
+ const decorations = placeholderPlugin.getState(state)
69
+ if (!decorations)
70
+ return -1
71
+ const found = decorations.find(undefined, undefined, (spec: Spec) => spec.id === id)
72
+ if (!found.length)
73
+ return -1
74
+ return found[0]?.from ?? -1
75
+ }
76
+
77
+ const handleUpload = (view: EditorView, event: DragEvent | ClipboardEvent, files: FileList | undefined) => {
78
+ if (!files || files.length <= 0)
79
+ return false
80
+
81
+ const id = Symbol('upload symbol')
82
+ const { tr } = view.state
83
+ const insertPos
84
+ = event instanceof DragEvent
85
+ ? view.posAtCoords({ left: event.clientX, top: event.clientY })?.pos ?? tr.selection.from
86
+ : tr.selection.from
87
+ view.dispatch(tr.setMeta(placeholderPlugin, { add: { id, pos: insertPos } }))
88
+
89
+ uploader(files, schema)
90
+ .then((fragment) => {
91
+ const pos = findPlaceholder(view.state, id)
92
+ if (pos < 0)
93
+ return
94
+
95
+ view.dispatch(
96
+ view.state.tr
97
+ .replaceWith(pos, pos, fragment)
98
+ .setMeta(placeholderPlugin, { remove: { id } }),
99
+ )
100
+ })
101
+ .catch((e) => {
102
+ console.error(e)
103
+ })
104
+ return true
105
+ }
106
+
107
+ const uploadPlugin = new Plugin({
108
+ props: {
109
+ handlePaste: (view, event) => {
110
+ if (!(event instanceof ClipboardEvent))
111
+ return false
112
+
113
+ if (!options?.enableHtmlFileUploader && event.clipboardData?.getData('text/html'))
114
+ return false
115
+
116
+ return handleUpload(view, event, event.clipboardData?.files)
117
+ },
118
+ handleDrop: (view, event) => {
119
+ if (!(event instanceof DragEvent))
120
+ return false
121
+
122
+ return handleUpload(view, event, event.dataTransfer?.files)
123
+ },
126
124
  },
127
- };
128
- });
125
+ })
126
+ return [placeholderPlugin, uploadPlugin]
127
+ },
128
+ }
129
+ })