TinyMce 修改插件 实现多文件/图片上传

最近在用TinyMce做网页编辑器的时候,发现一个很纠结的问题 ,上传图片的时候只能一张一张上传 ,本着懒人不做重复事情的原则,于是想着怎么可以修改一下工具的js代码可以实现一次性上传多图片的目的,话不多说,先看效果:
TinyMce 修改插件 实现多文件/图片上传_第1张图片
选择中文件打开后会上传操作,上传成功后会讲图片插入到编辑器:
TinyMce 修改插件 实现多文件/图片上传_第2张图片
说说步骤吧:

  1. 首先是要为 Browse for an image 上传文件按钮添加 multiple 多文件选择的属性,如图:TinyMce 修改插件 实现多文件/图片上传_第3张图片
    设置这个属性的默认文件路径是:\tinymce\themes*silver*\theme.min.js 或者 \tinymce\themes*mobile*\theme.min.js ,编辑器主题不同路径差异而已,一般编辑器默认加载压缩过的min.js文件,在文件中搜索 image/* ,就定位到设置的地方,然后添加上 multiple: “multiple” 属性即可
c = yg({
    dom: {
        tag: "input",
        attributes: {
            type: "file",
            accept: "image/*",
            //这里为file控件添加multiple属性
            multiple: "multiple"
        },
        styles: {
            display: "none"
        }
    },
    behaviours: Lu([Fm("input-file-events", [hr(So())])])
})
  1. 第二步是修改组件,负责图片上传组件的文件路径是:\tinymce\plugins\image\plugin.min.js,我们要修改的也就是这里面的逻辑,先看原版代码:
oe = function(a, u, c, l) {
    var t, e = l.getData();
    l.block("Uploading image"),
    //e..fileinput 是选中的所有文件对象集合
    (t = e.fileinput,
    0 === t.length ? w.none() : w.some(t[0])).fold(function() {
        l.unblock()
    }, 
	//这个函数即是上传文件的主要方法
	function(n) {
        var r = s.URL.createObjectURL(n)
          , i = Xt({
            url: u.url,
            basePath: u.basePath,
            credentials: u.credentials,
            handler: u.handler
        })
          , o = function() {
            l.unblock(),
            s.URL.revokeObjectURL(r)
        };
        dt(n).then(function(t) {
            var e = a.createBlobCache(n, r, t);
            i.upload(e).then(function(t) {
                l.setData({
                    src: {
                        value: t,
                        meta: {}
                    }
                }),
                l.showTab("general"),
                re(a, u, c, l),
                o()
            })["catch"](function(t) {
                o(),
                a.alertErr(l, t)
            })
        })
    })
}

问题出在这句代码上:0 === t.length ? w.none() : w.some(t[0]),当多个文件时,只是上传第一个文件。所以我们需要修改一下这里面的逻辑,w.some会返回一个对象:

i = {
   fold: function(t, e) {
   		//这里会直接调用传入的第二个匿名函数e,并且将元素传入作参数	
       return e(n)
   },
   is: function(t) {
       return n === t
   },
   isSome: h,
   isNone: g,
   getOr: t,
   getOrThunk: t,
   getOrDie: t,
   getOrNull: t,
   getOrUndefined: t,
   or: e,
   orThunk: e,
   map: function(t) {
       return b(t(n))
   },
   ap: function(t) {
       return t.fold(y, function(t) {
           return b(t(n))
       })
   },
   each: function(t) {
       t(n)
   },
   bind: r,
   flatten: t,
   exists: r,
   forall: r,
   filter: function(t) {
       return t(n) ? i : v
   },
   equals: function(t) {
       return t.is(n)
   },
   equals_: function(t, e) {
       return t.fold(g, function(t) {
           return e(n, t)
       })
   },
   toArray: function() {
       return [n]
   },
   toString: function() {
       return "some(" + n + ")"
   }
};

里面的fold方法接收两个参数,即传入的两个匿名函数,e参数即可以运行第二个传入的匿名函数,这个函数就是具体的上传方法了。现在我们需要更改一下fold函数的逻辑,把w.some直接传入文件数组 t,然后在fold函数中做逻辑判断,同时对fold函数添加一个匿名方法,以便不该原来的逻辑,只是做多文件上传的变更,看代码:

fold: function(t, e, s) {
	if(1===n.length)
	{
		//如果只有一个文件,则调用原来的逻辑处理
		return e(n[0]);
	}else{
		//如果是多文件,则调用我们自己的逻辑处理
		return s(n);
	}
}
oe = function(a, u, c, l) {
   var t, e = l.getData();
    l.block("Uploading image");
    (t = e.fileinput,
    0 === t.length ? w.none() : w.some(t)).fold(function() {
        l.unblock()
    }, 
    //原来的上传文件处理逻辑
    function(n) {
        var r = s.URL.createObjectURL(n)
          , i = Xt({
            url: u.url,
            basePath: u.basePath,
            credentials: u.credentials,
            handler: u.handler
        })
          , o = function() {
            l.unblock(),
            s.URL.revokeObjectURL(r)
        };
        dt(n).then(function(t) {
            var e = a.createBlobCache(n, r, t);
            i.upload(e).then(function(t) {
                l.setData({
                    src: {
                        value: t,
                        meta: {}
                    }
                }),
                l.showTab("general"),
                re(a, u, c, l),
                o()
            })["catch"](function(t) {
                o(),
                a.alertErr(l, t)
            })
        })
    },
    //添加的多文件处理逻辑
    //k为多文件的列表信息
     function(k) {
        var index = 0;
        //上传文件时会对文件进行异步编码并且异步上传
        //上传单文件不会有什么问题
        //但是上传多文件同时上传,因为异步问题,原来的操作方式会上传同一个文件(最后一个文件)
        //所以采用服务器返回上传成功了,然后再次调用函数的方式进行队列上传
        var upload = function(n) {
            var r = s.URL.createObjectURL(n)
              , i = Xt({
                url: u.url,
                basePath: u.basePath,
                credentials: u.credentials,
                handler: u.handler
            })
              , o = function() {
                l.unblock(),
                s.URL.revokeObjectURL(r)
            };
            dt(n).then(function(t) {
                var e = a.createBlobCache(n, r, t);
                i.upload(e).then(function(t) {
                	//上传成功后创建img元素并进行插入
                    var img = editor.dom.createHTML('img', {
                        src: t
                    });
                    //插入内容
                    editor.insertContent(img);
                    //判断是否已经上传完,如果上传完所有文件,则关闭正在上传的操作层
                    if (++index === k.length) {
                        o();
                    } else { //否则继续上传
                        upload(k[index]);
                    }
                })["catch"](function(t) {
                    o(),
                    a.alertErr(l, t)
                })
            })
        }
		
		//对首次调用上传进行验证
        if (index < k.length) {
            upload(k[index]);
        }

    })
}

这样基本的工作就做完了 ,后台的上传处理逻辑这边就不贴代码了。还有需要注意的一点是:多图片上传成功一个后插入img元素到编辑器的操作 ,editor本身没有申明,因为组件采用的是严格代码模式,所以需要在插件的最前面申明变量editor,然后在插件调用时对editor进行赋值:

!function me() {
    u.add("image", function(t) {
    //	对editor进行赋值
	editor=t;
   fe(t),
   de(t),
   le(t)
    })
}()

差不多这样就完成了。第一次写博客,很多说的不是很清楚,大家不要见怪,稍后我把修改后的代码帖上,大家有需要就看一看 。如果有错误的地方也请大家海涵!

你可能感兴趣的:(javascript)