Quill-image-drop插件源码浅析

227 阅读2分钟

源码地址:github.com/kensnyder/q…

var exports = {};
"use strict";
Object.defineProperty(exports, "__esModule", {value: true});
  • 定义一个exports空对象,存储模块的导出内容。
  • 使用严格模式的声明,消除Javascript语法中的一些不合理的行为。
  • 指定当前模块为ES6模块。

__esModule可以传的值:

  • true,ES6模块,使用异步加载模块,以import、export定义和导出模块。
  • false,CommonJS模块,使用同步加载模块,以require()、module.exports加载和导出模块。
var _createClass = function () {
    function e(e, t) {
        for (var a = 0; a < t.length; a++) {
            var i = t[a];
            i.enumerable = i.enumerable || false;
            i.configurable = true;
            if ("value" in i) i.writable = true;
            Object.defineProperty(e, i.key, i)
        }
    }

    return function (t, a, i) {
        if (a) e(t.prototype, a);
        if (i) e(t, i);
        return t
    }
}();
  • 函数e,参数e是构造函数,参数t是方法数组,作用是将t数组中的方法都添加到构造函数e中。
  • 返回值中的函数,参数t是构造函数,a是包含了类方法的数组,i是包含类的静态方法的数组,不另外加静态方法,i将会是undefined。函数依次将类的方法添加到类的原型中,将静态方法添加到类的构造函数中。
function _classCallCheck(e, t) {
    if (!(e instanceof t)) {
        throw new TypeError("Cannot call a class as a function")
    }
}
  • 保证构造函数只能被用作为类的构造函数,而不能被当作普通函数调用。
var ImageDrop = exports.ImageDrop = function () {
    // ......
}();
window.Quill.register('modules/imageDrop', exports.ImageDrop);
  • 定义并注册ImageDrop类。
function e(t) {
    var a = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
    _classCallCheck(this, e);
    this.quill = t;
    this.handleDrop = this.handleDrop.bind(this);
    this.handlePaste = this.handlePaste.bind(this);
    this.quill.root.addEventListener("drop", this.handleDrop, false);
    this.quill.root.addEventListener("paste", this.handlePaste, false)
}

_createClass(e, [{
    key: "handleDrop", value: function e(t) {// ......}
    }, {
    key: "handlePaste", value: function e(t) {// ......}
    }, {
    key: "insert", value: function e(t) {// ......}
    }, {
    key: "readFiles", value: function e(t, a) {// ......}
    }])
  • 构造函数,参数t为Quill编辑器的示例,参数a为配置项的对象。
  • 其中,添加了handleDrop、handlePaste、insert、readFiles方法。
// handleDrop,往往是处理将桌面的图片拖拽进Quill编辑器中
function e(t) {
    t.preventDefault();
    if (t.dataTransfer && t.dataTransfer.files && t.dataTransfer.files.length) {
        if (document.caretRangeFromPoint) {
            var a = document.getSelection();
            var i = document.caretRangeFromPoint(t.clientX, t.clientY);
            if (a && i) {
                a.setBaseAndExtent(i.startContainer, i.startOffset, i.startContainer, i.startOffset)
            }
        }
        this.readFiles(t.dataTransfer.files, this.insert.bind(this))
    }
}
  • 查看Quill实例的DataTransfer对象,以及其中是否有拖动需要的数据。
  • 获取鼠标选择区域的文本范围、光标的位置以及Quill实例的Range对象。
  • 设置如果拖拽结束,光标的位置。
  • 调用读取被拖拽的图片方法。
  • preventDefault方法的调用,可能会导致拖拽的部分事件不被正常触发,可以将其提入if判断中。
// handlePaste
function e(t) {
    var a = this;
    if (t.clipboardData && t.clipboardData.items && t.clipboardData.items.length) {
        this.readFiles(t.clipboardData.items, function (e) {
            var t = a.quill.getSelection();
            if (t) {
            } else {
                setTimeout(function () {
                    return a.insert(e)
                }, 0)
            }
        })
    }
}
  • 读取拖拽图片信息,获取Quill编辑器的Range对象,调用插入图片方法。
// insert
function e(t) {
    var a = (this.quill.getSelection() || {}).index || this.quill.getLength();
    this.quill.insertEmbed(a, "image", t, "user")
}
  • 将图片插入Quill编辑器指定的位置。
// readFiles
function e(t, a) {
    [].forEach.call(t, function (e) {
        if (!e.type.match(/^image/(gif|jpe?g|a?png|svg|webp|bmp|vnd.microsoft.icon)/i)) {
            return
        }
        var t = new FileReader;
        t.onload = function (e) {
            a(e.target.result)
        };
        var i = e.getAsFile ? e.getAsFile() : e;
        if (i instanceof Blob) {
            t.readAsDataURL(i)
        }
    })
}
  • 剔除不符合的文件格式。
  • 读取图片信息。
  • 从桌面读取图片需要注意,读取的是base64的格式内容,这会导致插入图片后,保存Quill的文稿信息时,传递的数据信息过大。