@milkdown/plugin-upload 5.1.1 → 5.3.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/index.cjs.js +2 -0
- package/lib/index.cjs.js.map +1 -0
- package/lib/index.d.ts +2 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.es.js +106 -0
- package/lib/index.es.js.map +1 -0
- package/package.json +20 -8
- package/src/index.ts +2 -1
- package/lib/default-uploader.js +0 -30
- package/lib/default-uploader.js.map +0 -1
- package/lib/index.js +0 -6
- package/lib/index.js.map +0 -1
- package/lib/upload.js +0 -82
- package/lib/upload.js.map +0 -1
package/lib/index.cjs.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});exports[Symbol.toStringTag]="Module";var S=require("@milkdown/utils"),w=require("@milkdown/core"),m=require("@milkdown/prose");const b=i=>new Promise(l=>{const a=new FileReader;a.addEventListener("load",()=>{l({alt:i.name,src:a.result})},!1),a.readAsDataURL(i)}),C=async(i,l)=>{const a=[];for(let n=0;n<i.length;n++){const d=i.item(n);!d||!d.type.includes("image")||a.push(d)}const{image:c}=l.nodes;return(await Promise.all(a.map(n=>b(n)))).map(({alt:n,src:d})=>c.createAndFill({src:d,alt:n}))},A=S.createPlugin((i,l)=>{var c;const a=(c=l==null?void 0:l.uploader)!=null?c:C;return{prosePlugins:(D,n)=>{const d=n.get(w.schemaCtx),u=new m.Plugin({state:{init(){return m.DecorationSet.empty},apply(e,s){const o=s.map(e.mapping,e.doc),t=e.getMeta(this);if(!t)return o;if(t.add){const r=document.createElement("span"),{icon:g}=n.get(w.themeToolCtx).slots;r.appendChild(g("loading"));const p=m.Decoration.widget(t.add.pos,r,{id:t.add.id});return o.add(e.doc,[p])}if(t.remove)return o.remove(o.find(null,null,r=>r.id===t.remove.id))}},props:{decorations(e){return this.getState(e)}}}),M=(e,s)=>{const t=u.getState(e).find(null,null,r=>r.id===s);return t.length?t[0].from:-1},_=new m.Plugin({props:{handleDrop:(e,s)=>{var p,P,y;if(!(s instanceof DragEvent))return!1;const{files:o}=(p=s.dataTransfer)!=null?p:{};if(!o||o.length<=0)return!1;const t=Symbol("upload symbol"),{tr:r}=e.state,g=(y=(P=e.posAtCoords({left:s.clientX,top:s.clientY}))==null?void 0:P.pos)!=null?y:r.selection.from;return e.dispatch(r.setMeta(u,{add:{id:t,pos:g}})),a(o,d).then(f=>{const h=M(e.state,t);h<0||e.dispatch(e.state.tr.replaceWith(h,h,f).setMeta(u,{remove:{id:t}}))}).catch(f=>{console.error(f)}),!0}}});return[u,_]}}}),k=S.AtomList.create([A()]);exports.upload=k;exports.uploadPlugin=A;
|
|
2
|
+
//# sourceMappingURL=index.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs.js","sources":["../src/default-uploader.ts","../src/upload.ts","../src/index.ts"],"sourcesContent":["/* Copyright 2021, Milkdown by Mirone. */\nimport type { Node } from '@milkdown/prose';\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\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, themeToolCtx } from '@milkdown/core';\nimport type { Fragment, Node, Schema } from '@milkdown/prose';\nimport { Decoration, DecorationSet, EditorState, Plugin } from '@milkdown/prose';\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 };\n\nexport const uploadPlugin = createPlugin<string, { uploader: Uploader }>((_, 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 state: {\n init() {\n return DecorationSet.empty;\n },\n apply(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 { icon } = ctx.get(themeToolCtx).slots;\n widget.appendChild(icon('loading'));\n const decoration = Decoration.widget(action.add.pos, widget, { id: action.add.id });\n return _set.add(tr.doc, [decoration]);\n }\n if (action.remove) {\n return _set.remove(_set.find(null, null, (spec: Spec) => spec.id === action.remove.id));\n }\n },\n },\n props: {\n decorations(state) {\n return this.getState(state);\n },\n },\n });\n const findPlaceholder = (state: EditorState, id: symbol): number => {\n const decorations = placeholderPlugin.getState(state);\n const found = decorations.find(null, null, (spec: Spec) => spec.id === id);\n return found.length ? found[0].from : -1;\n };\n const uploadPlugin = new Plugin({\n props: {\n handleDrop: (view, event) => {\n if (!(event instanceof DragEvent)) {\n return false;\n }\n const { files } = event.dataTransfer ?? {};\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 view.posAtCoords({ left: event.clientX, top: event.clientY })?.pos ?? 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 });\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 { uploadPlugin } from './upload';\n\nexport const upload = AtomList.create([uploadPlugin()]);\n"],"names":["createPlugin","schemaCtx","Plugin","DecorationSet","themeToolCtx","Decoration","AtomList"],"mappings":"mMAKA,KAAM,GAAoB,AAAC,GAChB,GAAI,SAAQ,AAAC,GAAY,MACtB,GAAS,GAAI,cACZ,iBACH,OACA,IAAM,GACM,CACJ,IAAK,EAAK,KACV,IAAK,EAAO,UAGpB,MAEG,cAAc,KAIhB,EAA4B,MAAO,EAAO,IAAW,MACxD,GAAe,UAEZ,GAAI,EAAG,EAAI,EAAM,OAAQ,IAAK,MAC7B,GAAO,EAAM,KAAK,GACpB,CAAC,GAID,CAAC,EAAK,KAAK,SAAS,YAInB,KAAK,QAGR,CAAE,SAAU,EAAO,YAIlB,AAFM,MAAM,SAAQ,IAAI,EAAK,IAAI,AAAC,GAAQ,EAAkB,MAEvD,IAAI,CAAC,CAAE,MAAK,SAAU,EAAM,cAAc,CAAE,MAAK,UC/BpD,EAAeA,eAA6C,CAAC,EAAG,IAAY,YAC/E,GAAW,oBAAS,WAAT,OAAqB,QAE/B,CACH,aAAc,CAAC,EAAG,IAAQ,MAChB,GAAS,EAAI,IAAIC,aAEjB,EAAoB,GAAIC,UAAO,CACjC,MAAO,CACH,MAAO,OACIC,iBAAc,OAEzB,MAAM,EAAI,EAAK,MACL,GAAO,EAAI,IAAI,EAAG,QAAS,EAAG,KAC9B,EAAS,EAAG,QAAQ,SACtB,CAAC,QACM,MAEP,EAAO,IAAK,MACN,GAAS,SAAS,cAAc,QAChC,CAAE,QAAS,EAAI,IAAIC,gBAAc,QAChC,YAAY,EAAK,iBAClB,GAAaC,aAAW,OAAO,EAAO,IAAI,IAAK,EAAQ,CAAE,GAAI,EAAO,IAAI,WACvE,GAAK,IAAI,EAAG,IAAK,CAAC,OAEzB,EAAO,aACA,GAAK,OAAO,EAAK,KAAK,KAAM,KAAM,AAAC,GAAe,EAAK,KAAO,EAAO,OAAO,OAI/F,MAAO,CACH,YAAY,EAAO,OACR,MAAK,SAAS,OAI3B,EAAkB,CAAC,EAAoB,IAAuB,MAE1D,GAAQ,AADM,EAAkB,SAAS,GACrB,KAAK,KAAM,KAAM,AAAC,GAAe,EAAK,KAAO,SAChE,GAAM,OAAS,EAAM,GAAG,KAAO,IAEpC,EAAe,GAAIH,UAAO,CAC5B,MAAO,CACH,WAAY,CAAC,EAAM,IAAU,cACrB,cAAmB,kBACZ,QAEL,CAAE,SAAU,KAAM,eAAN,OAAsB,MACpC,CAAC,GAAS,EAAM,QAAU,QACnB,QAEL,GAAK,OAAO,iBACZ,CAAE,MAAO,EAAK,MACd,EACF,QAAK,YAAY,CAAE,KAAM,EAAM,QAAS,IAAK,EAAM,YAAnD,cAA+D,MAA/D,OAAsE,EAAG,UAAU,cAClF,SAAS,EAAG,QAAQ,EAAmB,CAAE,IAAK,CAAE,KAAI,IAAK,QAErD,EAAO,GACX,KAAK,AAAC,GAAa,MACV,GAAM,EAAgB,EAAK,MAAO,GACpC,EAAM,KAEL,SACD,EAAK,MAAM,GACN,YAAY,EAAK,EAAK,GACtB,QAAQ,EAAmB,CAAE,OAAQ,CAAE,WAInD,MAAM,AAAC,GAAM,SACF,MAAM,KAEf,aAIZ,CAAC,EAAmB,OC/E1B,EAASI,WAAS,OAAO,CAAC"}
|
package/lib/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { AtomList } from '@milkdown/utils';
|
|
2
|
-
export { Uploader
|
|
2
|
+
export type { Uploader } from './upload';
|
|
3
|
+
export { uploadPlugin } from './upload';
|
|
3
4
|
export declare const upload: AtomList<import("@milkdown/utils/lib/types").Metadata<import("@milkdown/utils/lib/types").GetPlugin<string, {
|
|
4
5
|
uploader: import("./upload").Uploader;
|
|
5
6
|
}>> & import("@milkdown/core").MilkdownPlugin>;
|
package/lib/index.d.ts.map
CHANGED
|
@@ -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,
|
|
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,YAAY,EAAE,MAAM,UAAU,CAAC;AAExC,eAAO,MAAM,MAAM;;8CAAoC,CAAC"}
|
package/lib/index.es.js
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { createPlugin, AtomList } from "@milkdown/utils";
|
|
2
|
+
import { schemaCtx, themeToolCtx } from "@milkdown/core";
|
|
3
|
+
import { Plugin, DecorationSet, Decoration } from "@milkdown/prose";
|
|
4
|
+
const readImageAsBase64 = (file) => {
|
|
5
|
+
return new Promise((resolve) => {
|
|
6
|
+
const reader = new FileReader();
|
|
7
|
+
reader.addEventListener("load", () => {
|
|
8
|
+
resolve({
|
|
9
|
+
alt: file.name,
|
|
10
|
+
src: reader.result
|
|
11
|
+
});
|
|
12
|
+
}, false);
|
|
13
|
+
reader.readAsDataURL(file);
|
|
14
|
+
});
|
|
15
|
+
};
|
|
16
|
+
const defaultUploader = async (files, schema) => {
|
|
17
|
+
const imgs = [];
|
|
18
|
+
for (let i = 0; i < files.length; i++) {
|
|
19
|
+
const file = files.item(i);
|
|
20
|
+
if (!file) {
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
if (!file.type.includes("image")) {
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
imgs.push(file);
|
|
27
|
+
}
|
|
28
|
+
const { image } = schema.nodes;
|
|
29
|
+
const data = await Promise.all(imgs.map((img) => readImageAsBase64(img)));
|
|
30
|
+
return data.map(({ alt, src }) => image.createAndFill({ src, alt }));
|
|
31
|
+
};
|
|
32
|
+
const uploadPlugin = createPlugin((_, options) => {
|
|
33
|
+
var _a;
|
|
34
|
+
const uploader = (_a = options == null ? void 0 : options.uploader) != null ? _a : defaultUploader;
|
|
35
|
+
return {
|
|
36
|
+
prosePlugins: (_2, ctx) => {
|
|
37
|
+
const schema = ctx.get(schemaCtx);
|
|
38
|
+
const placeholderPlugin = new Plugin({
|
|
39
|
+
state: {
|
|
40
|
+
init() {
|
|
41
|
+
return DecorationSet.empty;
|
|
42
|
+
},
|
|
43
|
+
apply(tr, set) {
|
|
44
|
+
const _set = set.map(tr.mapping, tr.doc);
|
|
45
|
+
const action = tr.getMeta(this);
|
|
46
|
+
if (!action) {
|
|
47
|
+
return _set;
|
|
48
|
+
}
|
|
49
|
+
if (action.add) {
|
|
50
|
+
const widget = document.createElement("span");
|
|
51
|
+
const { icon } = ctx.get(themeToolCtx).slots;
|
|
52
|
+
widget.appendChild(icon("loading"));
|
|
53
|
+
const decoration = Decoration.widget(action.add.pos, widget, { id: action.add.id });
|
|
54
|
+
return _set.add(tr.doc, [decoration]);
|
|
55
|
+
}
|
|
56
|
+
if (action.remove) {
|
|
57
|
+
return _set.remove(_set.find(null, null, (spec) => spec.id === action.remove.id));
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
props: {
|
|
62
|
+
decorations(state) {
|
|
63
|
+
return this.getState(state);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
const findPlaceholder = (state, id) => {
|
|
68
|
+
const decorations = placeholderPlugin.getState(state);
|
|
69
|
+
const found = decorations.find(null, null, (spec) => spec.id === id);
|
|
70
|
+
return found.length ? found[0].from : -1;
|
|
71
|
+
};
|
|
72
|
+
const uploadPlugin2 = new Plugin({
|
|
73
|
+
props: {
|
|
74
|
+
handleDrop: (view, event) => {
|
|
75
|
+
var _a2, _b, _c;
|
|
76
|
+
if (!(event instanceof DragEvent)) {
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
const { files } = (_a2 = event.dataTransfer) != null ? _a2 : {};
|
|
80
|
+
if (!files || files.length <= 0) {
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
const id = Symbol("upload symbol");
|
|
84
|
+
const { tr } = view.state;
|
|
85
|
+
const insertPos = (_c = (_b = view.posAtCoords({ left: event.clientX, top: event.clientY })) == null ? void 0 : _b.pos) != null ? _c : tr.selection.from;
|
|
86
|
+
view.dispatch(tr.setMeta(placeholderPlugin, { add: { id, pos: insertPos } }));
|
|
87
|
+
uploader(files, schema).then((fragment) => {
|
|
88
|
+
const pos = findPlaceholder(view.state, id);
|
|
89
|
+
if (pos < 0)
|
|
90
|
+
return;
|
|
91
|
+
view.dispatch(view.state.tr.replaceWith(pos, pos, fragment).setMeta(placeholderPlugin, { remove: { id } }));
|
|
92
|
+
return;
|
|
93
|
+
}).catch((e) => {
|
|
94
|
+
console.error(e);
|
|
95
|
+
});
|
|
96
|
+
return true;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
return [placeholderPlugin, uploadPlugin2];
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
});
|
|
104
|
+
const upload = AtomList.create([uploadPlugin()]);
|
|
105
|
+
export { upload, uploadPlugin };
|
|
106
|
+
//# sourceMappingURL=index.es.js.map
|
|
@@ -0,0 +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 type { Node } from '@milkdown/prose';\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\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, themeToolCtx } from '@milkdown/core';\nimport type { Fragment, Node, Schema } from '@milkdown/prose';\nimport { Decoration, DecorationSet, EditorState, Plugin } from '@milkdown/prose';\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 };\n\nexport const uploadPlugin = createPlugin<string, { uploader: Uploader }>((_, 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 state: {\n init() {\n return DecorationSet.empty;\n },\n apply(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 { icon } = ctx.get(themeToolCtx).slots;\n widget.appendChild(icon('loading'));\n const decoration = Decoration.widget(action.add.pos, widget, { id: action.add.id });\n return _set.add(tr.doc, [decoration]);\n }\n if (action.remove) {\n return _set.remove(_set.find(null, null, (spec: Spec) => spec.id === action.remove.id));\n }\n },\n },\n props: {\n decorations(state) {\n return this.getState(state);\n },\n },\n });\n const findPlaceholder = (state: EditorState, id: symbol): number => {\n const decorations = placeholderPlugin.getState(state);\n const found = decorations.find(null, null, (spec: Spec) => spec.id === id);\n return found.length ? found[0].from : -1;\n };\n const uploadPlugin = new Plugin({\n props: {\n handleDrop: (view, event) => {\n if (!(event instanceof DragEvent)) {\n return false;\n }\n const { files } = event.dataTransfer ?? {};\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 view.posAtCoords({ left: event.clientX, top: event.clientY })?.pos ?? 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 });\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 { uploadPlugin } from './upload';\n\nexport const upload = AtomList.create([uploadPlugin()]);\n"],"names":[],"mappings":";;;AAKA,MAAM,oBAAoB,CAAC,SAAsD;SACtE,IAAI,QAAQ,CAAC,YAAY;UACtB,SAAS,IAAI;WACZ,iBACH,QACA,MAAM;cACM;AAAA,QACJ,KAAK,KAAK;AAAA,QACV,KAAK,OAAO;AAAA;AAAA,OAGpB;WAEG,cAAc;AAAA;AAAA;MAIhB,kBAA4B,OAAO,OAAO,WAAW;QACxD,OAAe;WAEZ,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;UAC7B,OAAO,MAAM,KAAK;QACpB,CAAC,MAAM;;;QAIP,CAAC,KAAK,KAAK,SAAS,UAAU;;;SAI7B,KAAK;AAAA;QAGR,EAAE,UAAU,OAAO;QAEnB,OAAO,MAAM,QAAQ,IAAI,KAAK,IAAI,CAAC,QAAQ,kBAAkB;SAE5D,KAAK,IAAI,CAAC,EAAE,KAAK,UAAU,MAAM,cAAc,EAAE,KAAK;AAAA;MC/BpD,eAAe,aAA6C,CAAC,GAAG,YAAY;;QAC/E,WAAW,yCAAS,aAAT,YAAqB;SAE/B;AAAA,IACH,cAAc,CAAC,IAAG,QAAQ;YAChB,SAAS,IAAI,IAAI;YAEjB,oBAAoB,IAAI,OAAO;AAAA,QACjC,OAAO;AAAA,UACH,OAAO;mBACI,cAAc;AAAA;AAAA,UAEzB,MAAM,IAAI,KAAK;kBACL,OAAO,IAAI,IAAI,GAAG,SAAS,GAAG;kBAC9B,SAAS,GAAG,QAAQ;gBACtB,CAAC,QAAQ;qBACF;AAAA;gBAEP,OAAO,KAAK;oBACN,SAAS,SAAS,cAAc;oBAChC,EAAE,SAAS,IAAI,IAAI,cAAc;qBAChC,YAAY,KAAK;oBAClB,aAAa,WAAW,OAAO,OAAO,IAAI,KAAK,QAAQ,EAAE,IAAI,OAAO,IAAI;qBACvE,KAAK,IAAI,GAAG,KAAK,CAAC;AAAA;gBAEzB,OAAO,QAAQ;qBACR,KAAK,OAAO,KAAK,KAAK,MAAM,MAAM,CAAC,SAAe,KAAK,OAAO,OAAO,OAAO;AAAA;AAAA;AAAA;AAAA,QAI/F,OAAO;AAAA,UACH,YAAY,OAAO;mBACR,KAAK,SAAS;AAAA;AAAA;AAAA;YAI3B,kBAAkB,CAAC,OAAoB,OAAuB;cAC1D,cAAc,kBAAkB,SAAS;cACzC,QAAQ,YAAY,KAAK,MAAM,MAAM,CAAC,SAAe,KAAK,OAAO;eAChE,MAAM,SAAS,MAAM,GAAG,OAAO;AAAA;YAEpC,gBAAe,IAAI,OAAO;AAAA,QAC5B,OAAO;AAAA,UACH,YAAY,CAAC,MAAM,UAAU;;gBACrB,mBAAmB,YAAY;qBACxB;AAAA;kBAEL,EAAE,UAAU,aAAM,iBAAN,aAAsB;gBACpC,CAAC,SAAS,MAAM,UAAU,GAAG;qBACtB;AAAA;kBAEL,KAAK,OAAO;kBACZ,EAAE,OAAO,KAAK;kBACd,YACF,iBAAK,YAAY,EAAE,MAAM,MAAM,SAAS,KAAK,MAAM,eAAnD,mBAA+D,QAA/D,YAAsE,GAAG,UAAU;iBAClF,SAAS,GAAG,QAAQ,mBAAmB,EAAE,KAAK,EAAE,IAAI,KAAK;qBAErD,OAAO,QACX,KAAK,CAAC,aAAa;oBACV,MAAM,gBAAgB,KAAK,OAAO;kBACpC,MAAM;;mBAEL,SACD,KAAK,MAAM,GACN,YAAY,KAAK,KAAK,UACtB,QAAQ,mBAAmB,EAAE,QAAQ,EAAE;;eAInD,MAAM,CAAC,MAAM;sBACF,MAAM;AAAA;mBAEf;AAAA;AAAA;AAAA;aAIZ,CAAC,mBAAmB;AAAA;AAAA;AAAA;MC/E1B,SAAS,SAAS,OAAO,CAAC;;"}
|
package/package.json
CHANGED
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@milkdown/plugin-upload",
|
|
3
|
-
"version": "5.
|
|
4
|
-
"main": "lib/index.js",
|
|
5
|
-
"module": "lib/index.js",
|
|
6
|
-
"types": "lib/index.d.ts",
|
|
3
|
+
"version": "5.3.0",
|
|
4
|
+
"main": "./lib/index.cjs.js",
|
|
5
|
+
"module": "./lib/index.es.js",
|
|
6
|
+
"types": "./lib/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"import": "./lib/index.es.js",
|
|
10
|
+
"require": "./lib/index.cjs.js"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
7
13
|
"sideEffects": false,
|
|
8
14
|
"license": "MIT",
|
|
9
15
|
"files": [
|
|
@@ -18,14 +24,20 @@
|
|
|
18
24
|
"@milkdown/core": "*"
|
|
19
25
|
},
|
|
20
26
|
"dependencies": {
|
|
21
|
-
"@milkdown/utils": "5.
|
|
27
|
+
"@milkdown/utils": "5.3.0",
|
|
22
28
|
"tslib": "^2.3.1"
|
|
23
29
|
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@milkdown/core": "5.3.0",
|
|
32
|
+
"@milkdown/prose": "5.3.0",
|
|
33
|
+
"@milkdown/utils": "5.3.0"
|
|
34
|
+
},
|
|
24
35
|
"scripts": {
|
|
25
36
|
"start": "vite",
|
|
26
|
-
"watch": "
|
|
37
|
+
"watch": "vite build --watch",
|
|
27
38
|
"test": "jest",
|
|
28
39
|
"tsc": "tsc --noEmit",
|
|
29
|
-
"build": "tsc"
|
|
30
|
-
}
|
|
40
|
+
"build": "vite build && tsc --emitDeclarationOnly"
|
|
41
|
+
},
|
|
42
|
+
"readme": "# @milkdown/plugin-upload\n\nUpload image when drop for [milkdown](https://saul-mirone.github.io/milkdown/).\n\n# Example Usage\n\n```typescript\nimport { Editor } from '@milkdown/core';\nimport { commonmark } from '@milkdown/preset-commonmark';\nimport { nord } from '@milkdown/theme-nord';\n\nimport { upload } from '@milkdown/plugin-upload';\n\nEditor.make().use(commonmark).use(upload).create();\n```\n\n# Setup Uploader\n\n> By default, this plugin will transfer image to base64 and ignore other file types.\n>\n> If you want to upload file and handle the generated blocks, you should setup the uploader.\n\n```typescript\n// ...\nimport { upload, uploadPlugin, Uploader } from '@milkdown/plugin-upload';\nimport type { Node } from 'prosemirror-model';\n\nconst uploader: Uploader = async (files, schema) => {\n const images: 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 // You can handle whatever the file type you want, we handle image here.\n if (!file.type.includes('image')) {\n continue;\n }\n\n images.push(file);\n }\n\n const nodes: Node[] = await Promise.all(\n images.map(async (image) => {\n const src = await YourUploadAPI(image);\n const alt = image.name;\n return schema.nodes.image.createAndFill({\n src,\n alt,\n }) as Node;\n }),\n );\n\n return nodes;\n};\n\nEditor.make()\n // .use(...)\n .use(\n upload.configure(uploadPlugin, {\n uploader,\n }),\n )\n .create();\n```\n\n# License\n\nMilkdown is open sourced software licensed under [MIT license](https://github.com/Saul-Mirone/milkdown/blob/main/LICENSE).\n"
|
|
31
43
|
}
|
package/src/index.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { AtomList } from '@milkdown/utils';
|
|
|
3
3
|
|
|
4
4
|
import { uploadPlugin } from './upload';
|
|
5
5
|
|
|
6
|
-
export { Uploader
|
|
6
|
+
export type { Uploader } from './upload';
|
|
7
|
+
export { uploadPlugin } from './upload';
|
|
7
8
|
|
|
8
9
|
export const upload = AtomList.create([uploadPlugin()]);
|
package/lib/default-uploader.js
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { __awaiter } from "tslib";
|
|
2
|
-
const readImageAsBase64 = (file) => {
|
|
3
|
-
return new Promise((resolve) => {
|
|
4
|
-
const reader = new FileReader();
|
|
5
|
-
reader.addEventListener('load', () => {
|
|
6
|
-
resolve({
|
|
7
|
-
alt: file.name,
|
|
8
|
-
src: reader.result,
|
|
9
|
-
});
|
|
10
|
-
}, false);
|
|
11
|
-
reader.readAsDataURL(file);
|
|
12
|
-
});
|
|
13
|
-
};
|
|
14
|
-
export const defaultUploader = (files, schema) => __awaiter(void 0, void 0, void 0, function* () {
|
|
15
|
-
const imgs = [];
|
|
16
|
-
for (let i = 0; i < files.length; i++) {
|
|
17
|
-
const file = files.item(i);
|
|
18
|
-
if (!file) {
|
|
19
|
-
continue;
|
|
20
|
-
}
|
|
21
|
-
if (!file.type.includes('image')) {
|
|
22
|
-
continue;
|
|
23
|
-
}
|
|
24
|
-
imgs.push(file);
|
|
25
|
-
}
|
|
26
|
-
const { image } = schema.nodes;
|
|
27
|
-
const data = yield Promise.all(imgs.map((img) => readImageAsBase64(img)));
|
|
28
|
-
return data.map(({ alt, src }) => image.createAndFill({ src, alt }));
|
|
29
|
-
});
|
|
30
|
-
//# sourceMappingURL=default-uploader.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"default-uploader.js","sourceRoot":"","sources":["../src/default-uploader.ts"],"names":[],"mappings":";AAKA,MAAM,iBAAiB,GAAG,CAAC,IAAU,EAAyC,EAAE;IAC5E,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC3B,MAAM,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAChC,MAAM,CAAC,gBAAgB,CACnB,MAAM,EACN,GAAG,EAAE;YACD,OAAO,CAAC;gBACJ,GAAG,EAAE,IAAI,CAAC,IAAI;gBACd,GAAG,EAAE,MAAM,CAAC,MAAgB;aAC/B,CAAC,CAAC;QACP,CAAC,EACD,KAAK,CACR,CAAC;QACF,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;AACP,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAa,CAAO,KAAK,EAAE,MAAM,EAAE,EAAE;IAC7D,MAAM,IAAI,GAAW,EAAE,CAAC;IAExB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;QACnC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC3B,IAAI,CAAC,IAAI,EAAE;YACP,SAAS;SACZ;QAED,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE;YAC9B,SAAS;SACZ;QAED,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;KACnB;IAED,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC;IAE/B,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAE1E,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAS,CAAC,CAAC;AACjF,CAAC,CAAA,CAAC"}
|
package/lib/index.js
DELETED
package/lib/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAE3C,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAExC,OAAO,EAAY,YAAY,EAAE,MAAM,UAAU,CAAC;AAElD,MAAM,CAAC,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC"}
|
package/lib/upload.js
DELETED
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
/* Copyright 2021, Milkdown by Mirone. */
|
|
2
|
-
import { schemaCtx, themeToolCtx } from '@milkdown/core';
|
|
3
|
-
import { Decoration, DecorationSet, Plugin } from '@milkdown/prose';
|
|
4
|
-
import { createPlugin } from '@milkdown/utils';
|
|
5
|
-
import { defaultUploader } from './default-uploader';
|
|
6
|
-
export const uploadPlugin = createPlugin((_, options) => {
|
|
7
|
-
var _a;
|
|
8
|
-
const uploader = (_a = options === null || options === void 0 ? void 0 : options.uploader) !== null && _a !== void 0 ? _a : defaultUploader;
|
|
9
|
-
return {
|
|
10
|
-
prosePlugins: (_, ctx) => {
|
|
11
|
-
const schema = ctx.get(schemaCtx);
|
|
12
|
-
const placeholderPlugin = new Plugin({
|
|
13
|
-
state: {
|
|
14
|
-
init() {
|
|
15
|
-
return DecorationSet.empty;
|
|
16
|
-
},
|
|
17
|
-
apply(tr, set) {
|
|
18
|
-
const _set = set.map(tr.mapping, tr.doc);
|
|
19
|
-
const action = tr.getMeta(this);
|
|
20
|
-
if (!action) {
|
|
21
|
-
return _set;
|
|
22
|
-
}
|
|
23
|
-
if (action.add) {
|
|
24
|
-
const widget = document.createElement('span');
|
|
25
|
-
const { icon } = ctx.get(themeToolCtx).slots;
|
|
26
|
-
widget.appendChild(icon('loading'));
|
|
27
|
-
const decoration = Decoration.widget(action.add.pos, widget, { id: action.add.id });
|
|
28
|
-
return _set.add(tr.doc, [decoration]);
|
|
29
|
-
}
|
|
30
|
-
if (action.remove) {
|
|
31
|
-
return _set.remove(_set.find(null, null, (spec) => spec.id === action.remove.id));
|
|
32
|
-
}
|
|
33
|
-
},
|
|
34
|
-
},
|
|
35
|
-
props: {
|
|
36
|
-
decorations(state) {
|
|
37
|
-
return this.getState(state);
|
|
38
|
-
},
|
|
39
|
-
},
|
|
40
|
-
});
|
|
41
|
-
const findPlaceholder = (state, id) => {
|
|
42
|
-
const decorations = placeholderPlugin.getState(state);
|
|
43
|
-
const found = decorations.find(null, null, (spec) => spec.id === id);
|
|
44
|
-
return found.length ? found[0].from : -1;
|
|
45
|
-
};
|
|
46
|
-
const uploadPlugin = new Plugin({
|
|
47
|
-
props: {
|
|
48
|
-
handleDrop: (view, event) => {
|
|
49
|
-
var _a, _b, _c;
|
|
50
|
-
if (!(event instanceof DragEvent)) {
|
|
51
|
-
return false;
|
|
52
|
-
}
|
|
53
|
-
const { files } = (_a = event.dataTransfer) !== null && _a !== void 0 ? _a : {};
|
|
54
|
-
if (!files || files.length <= 0) {
|
|
55
|
-
return false;
|
|
56
|
-
}
|
|
57
|
-
const id = Symbol('upload symbol');
|
|
58
|
-
const { tr } = view.state;
|
|
59
|
-
const insertPos = (_c = (_b = view.posAtCoords({ left: event.clientX, top: event.clientY })) === null || _b === void 0 ? void 0 : _b.pos) !== null && _c !== void 0 ? _c : tr.selection.from;
|
|
60
|
-
view.dispatch(tr.setMeta(placeholderPlugin, { add: { id, pos: insertPos } }));
|
|
61
|
-
uploader(files, schema)
|
|
62
|
-
.then((fragment) => {
|
|
63
|
-
const pos = findPlaceholder(view.state, id);
|
|
64
|
-
if (pos < 0)
|
|
65
|
-
return;
|
|
66
|
-
view.dispatch(view.state.tr
|
|
67
|
-
.replaceWith(pos, pos, fragment)
|
|
68
|
-
.setMeta(placeholderPlugin, { remove: { id } }));
|
|
69
|
-
return;
|
|
70
|
-
})
|
|
71
|
-
.catch((e) => {
|
|
72
|
-
console.error(e);
|
|
73
|
-
});
|
|
74
|
-
return true;
|
|
75
|
-
},
|
|
76
|
-
},
|
|
77
|
-
});
|
|
78
|
-
return [placeholderPlugin, uploadPlugin];
|
|
79
|
-
},
|
|
80
|
-
};
|
|
81
|
-
});
|
|
82
|
-
//# sourceMappingURL=upload.js.map
|
package/lib/upload.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"upload.js","sourceRoot":"","sources":["../src/upload.ts"],"names":[],"mappings":"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"}
|