UNPKG

@opentiny/fluent-editor

Version:

A rich text editor based on Quill 2.0, which extends rich modules and formats on the basis of Quill. It's powerful and out-of-the-box.

140 lines (139 loc) 4.91 kB
"use strict"; var __defProp = Object.defineProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" }); const Quill = require("quill"); const is = require("../utils/is.cjs.js"); const Uploader = Quill.import("modules/uploader"); const Delta = Quill.import("delta"); class FileUploader extends Uploader { constructor(quill, options) { super(quill, options); this.quill = quill; this.options = this.resolveOptions(options); } resolveOptions(options = {}) { return Object.assign({ mimetypes: ["*"], maxSize: Number.POSITIVE_INFINITY, multiple: true, handler(range, files) { return files.map((file) => URL.createObjectURL(file)); }, success() { }, fail() { } }, options); } inferKind(file) { const type = file.type || ""; if (type.startsWith("image/")) return "image"; if (type.startsWith("video/")) return "video"; return "file"; } filterFromArray(types, kind) { if (kind === "file") return types; const prefix = `${kind}/`; return types.filter((type) => { if (type === "*") return true; if (type.includes("/")) return type.startsWith(prefix); return true; }); } getAccept(kind) { var _a; const mimetypes = this.options.mimetypes; if (Array.isArray(mimetypes)) { return this.filterFromArray(mimetypes, kind); } const map = mimetypes || {}; const fromKind = map[kind]; if (fromKind == null ? void 0 : fromKind.length) return fromKind; if (((_a = map.file) == null ? void 0 : _a.length) && kind !== "file") return map.file; return []; } getMaxSize(kind) { const maxSize = this.options.maxSize; if (typeof maxSize === "number") { return maxSize; } const map = maxSize || {}; const fromKind = map[kind]; if (typeof fromKind === "number") return fromKind; if (typeof map.file === "number" && kind !== "file") return map.file; return Number.POSITIVE_INFINITY; } getMultiple(kind) { const multiple = this.options.multiple; if (typeof multiple === "boolean") { return multiple; } const map = multiple || {}; const fromKind = map[kind]; if (typeof fromKind === "boolean") return fromKind; if (typeof map.file === "boolean" && kind !== "file") return map.file; return true; } validateFile(file, kind) { const inferredKind = kind ?? this.inferKind(file); const accept = this.getAccept(inferredKind); const maxSize = this.getMaxSize(inferredKind); const mimeOk = accept.some((type) => { if (type.includes("/")) { return (file.type || "text/plain").match(type.replaceAll("*", ".*")); } else { const ext = type.startsWith(".") ? type.toLowerCase() : `.${type.toLowerCase()}`; return file.name.toLowerCase().endsWith(ext); } }); return mimeOk && file.size < maxSize; } async getFileUrls(files, range, kind) { const uploads = files.filter((file) => this.validateFile(file, kind)); return this.options.handler.call(this, range, uploads); } async upload(range, files, kind) { const uploads = []; const fails = []; for (const file of Array.from(files)) { if (this.validateFile(file, kind)) { uploads.push(file); } else { fails.push(file); } } const result = await this.options.handler.call(this, range, uploads); const updateDelta = result.reduce((delta, url, i) => { if (is.isString(url)) { const type = uploads[i].type; if (type.startsWith("image/")) { delta.insert({ image: url }); } else if (type.startsWith("video/")) { delta.insert({ video: { src: url } }); } else { delta.insert({ file: { size: uploads[i].size, title: uploads[i].name, src: url } }); } } else { delta.insert(" "); } return delta; }, new Delta().retain(range.index).delete(range.length)); this.quill.updateContents(updateDelta, Quill.sources.USER); this.quill.setSelection(range.index + result.length, Quill.sources.SILENT); for (const file of fails) { this.options.fail.call(this, file, range); } for (const [i, res] of result.entries()) { if (is.isString(res)) { this.options.success.call(this, files[i], { index: range.index + i, length: 0 }); } else { this.options.fail.call(this, files[i], { index: range.index + i, length: 0 }); } } } } __publicField(FileUploader, "DEFAULTS", {}); exports.FileUploader = FileUploader; //# sourceMappingURL=custom-uploader.cjs.js.map