forked from slab/quill
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathuploader.ts
74 lines (69 loc) · 2.33 KB
/
uploader.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
import Delta from 'quill-delta';
import Quill from '../core/quill';
import Emitter from '../core/emitter';
import Module from '../core/module';
import { Range } from '../core/selection';
interface UploaderOptions {
mimetypes: string[];
handler: (this: { quill: Quill }, range: Range, files: File[]) => void;
}
class Uploader extends Module<UploaderOptions> {
constructor(quill: Quill, options: Partial<UploaderOptions>) {
super(quill, options);
quill.root.addEventListener('drop', e => {
e.preventDefault();
let native: ReturnType<typeof document.createRange>;
if (document.caretRangeFromPoint) {
native = document.caretRangeFromPoint(e.clientX, e.clientY);
// @ts-expect-error
} else if (document.caretPositionFromPoint) {
// @ts-expect-error
const position = document.caretPositionFromPoint(e.clientX, e.clientY);
native = document.createRange();
native.setStart(position.offsetNode, position.offset);
native.setEnd(position.offsetNode, position.offset);
} else {
return;
}
const normalized = quill.selection.normalizeNative(native);
const range = quill.selection.normalizedToRange(normalized);
this.upload(range, e.dataTransfer.files);
});
}
upload(range: Range, files: FileList | File[]) {
const uploads = [];
Array.from(files).forEach(file => {
if (file && this.options.mimetypes.includes(file.type)) {
uploads.push(file);
}
});
if (uploads.length > 0) {
this.options.handler.call(this, range, uploads);
}
}
}
Uploader.DEFAULTS = {
mimetypes: ['image/png', 'image/jpeg'],
handler(range: Range, files: File[]) {
const promises = files.map(file => {
return new Promise(resolve => {
const reader = new FileReader();
reader.onload = e => {
resolve(e.target.result);
};
reader.readAsDataURL(file);
});
});
Promise.all(promises).then(images => {
const update = images.reduce((delta: Delta, image) => {
return delta.insert({ image });
}, new Delta().retain(range.index).delete(range.length));
this.quill.updateContents(update, Emitter.sources.USER);
this.quill.setSelection(
range.index + images.length,
Emitter.sources.SILENT,
);
});
},
};
export default Uploader;