@milkdown/plugin-upload 6.1.0 → 6.1.3
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/README.md +3 -69
- package/lib/index.es.js +1 -1
- package/lib/index.es.js.map +1 -1
- package/lib/upload.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/upload.ts +1 -1
package/README.md
CHANGED
|
@@ -1,76 +1,10 @@
|
|
|
1
1
|
# @milkdown/plugin-upload
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The upload plugin of [milkdown](https://milkdown.dev/).
|
|
4
4
|
|
|
5
|
-
#
|
|
5
|
+
# Official Documentation
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
import { Editor } from '@milkdown/core';
|
|
9
|
-
import { commonmark } from '@milkdown/preset-commonmark';
|
|
10
|
-
import { nord } from '@milkdown/theme-nord';
|
|
11
|
-
|
|
12
|
-
import { upload } from '@milkdown/plugin-upload';
|
|
13
|
-
|
|
14
|
-
Editor.make().use(commonmark).use(upload).create();
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
# Config
|
|
18
|
-
|
|
19
|
-
## Setup Uploader
|
|
20
|
-
|
|
21
|
-
> By default, this plugin will transfer image to base64 and ignore other file types.
|
|
22
|
-
>
|
|
23
|
-
> If you want to upload file and handle the generated blocks, you should setup the uploader.
|
|
24
|
-
|
|
25
|
-
```typescript
|
|
26
|
-
// ...
|
|
27
|
-
import { upload, uploadPlugin, Uploader } from '@milkdown/plugin-upload';
|
|
28
|
-
import type { Node } from 'prosemirror-model';
|
|
29
|
-
|
|
30
|
-
const uploader: Uploader = async (files, schema) => {
|
|
31
|
-
const images: File[] = [];
|
|
32
|
-
|
|
33
|
-
for (let i = 0; i < files.length; i++) {
|
|
34
|
-
const file = files.item(i);
|
|
35
|
-
if (!file) {
|
|
36
|
-
continue;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// You can handle whatever the file type you want, we handle image here.
|
|
40
|
-
if (!file.type.includes('image')) {
|
|
41
|
-
continue;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
images.push(file);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
const nodes: Node[] = await Promise.all(
|
|
48
|
-
images.map(async (image) => {
|
|
49
|
-
const src = await YourUploadAPI(image);
|
|
50
|
-
const alt = image.name;
|
|
51
|
-
return schema.nodes.image.createAndFill({
|
|
52
|
-
src,
|
|
53
|
-
alt,
|
|
54
|
-
}) as Node;
|
|
55
|
-
}),
|
|
56
|
-
);
|
|
57
|
-
|
|
58
|
-
return nodes;
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
Editor.make()
|
|
62
|
-
// .use(...)
|
|
63
|
-
.use(
|
|
64
|
-
upload.configure(uploadPlugin, {
|
|
65
|
-
uploader,
|
|
66
|
-
}),
|
|
67
|
-
)
|
|
68
|
-
.create();
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
## enableHtmlFileUploader
|
|
72
|
-
|
|
73
|
-
When paste files from html (for example copy images by right click context menu), this option will make the plugin to upload the image copied instead of using the original link.
|
|
7
|
+
Documentation can be found on the [Milkdown website](https://milkdown.dev/plugin-upload).
|
|
74
8
|
|
|
75
9
|
# License
|
|
76
10
|
|
package/lib/index.es.js
CHANGED
|
@@ -33,7 +33,7 @@ const defaultUploader = async (files, schema) => {
|
|
|
33
33
|
const data = await Promise.all(imgs.map((img) => readImageAsBase64(img)));
|
|
34
34
|
return data.map(({ alt, src }) => image.createAndFill({ src, alt }));
|
|
35
35
|
};
|
|
36
|
-
const key = new PluginKey("
|
|
36
|
+
const key = new PluginKey("MILKDOWN_UPLOAD");
|
|
37
37
|
const uploadPlugin = createPlugin((_, options) => {
|
|
38
38
|
var _a;
|
|
39
39
|
const uploader = (_a = options == null ? void 0 : options.uploader) != null ? _a : defaultUploader;
|
package/lib/index.es.js.map
CHANGED
|
@@ -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 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 new Error();\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 { 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('
|
|
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/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 new Error();\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 { 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(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 new Error('Loading icon is not found');\n }\n widget.appendChild(loadingIcon.dom);\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\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\n const handleUpload = (\n view: EditorView<Schema>,\n event: DragEvent | ClipboardEvent,\n files: FileList | undefined,\n ) => {\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":[],"mappings":"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"}
|
package/lib/upload.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../src/upload.ts"],"names":[],"mappings":"AAEA,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,
|
|
1
|
+
{"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../src/upload.ts"],"names":[],"mappings":"AAEA,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,qBAAmC,CAAC;AAEpD,eAAO,MAAM,YAAY;;;;;;;;;;;;;;EA0GvB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@milkdown/plugin-upload",
|
|
3
|
-
"version": "6.1.
|
|
3
|
+
"version": "6.1.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./lib/index.es.js",
|
|
6
6
|
"types": "./lib/index.d.ts",
|
|
@@ -15,15 +15,15 @@
|
|
|
15
15
|
"milkdown plugin"
|
|
16
16
|
],
|
|
17
17
|
"devDependencies": {
|
|
18
|
-
"@milkdown/core": "6.1.
|
|
19
|
-
"@milkdown/prose": "6.1.
|
|
18
|
+
"@milkdown/core": "6.1.3",
|
|
19
|
+
"@milkdown/prose": "6.1.3"
|
|
20
20
|
},
|
|
21
21
|
"peerDependencies": {
|
|
22
22
|
"@milkdown/core": "^6.0.1",
|
|
23
23
|
"@milkdown/prose": "^6.0.1"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@milkdown/utils": "6.1.
|
|
26
|
+
"@milkdown/utils": "6.1.3",
|
|
27
27
|
"tslib": "^2.3.1"
|
|
28
28
|
},
|
|
29
29
|
"nx": {
|
package/src/upload.ts
CHANGED
|
@@ -13,7 +13,7 @@ export type Options = {
|
|
|
13
13
|
uploader: Uploader;
|
|
14
14
|
enableHtmlFileUploader: boolean;
|
|
15
15
|
};
|
|
16
|
-
export const key = new PluginKey('
|
|
16
|
+
export const key = new PluginKey('MILKDOWN_UPLOAD');
|
|
17
17
|
|
|
18
18
|
export const uploadPlugin = createPlugin<string, Options>((_, options) => {
|
|
19
19
|
const uploader = options?.uploader ?? defaultUploader;
|