欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-05-30 20:35:35
...

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

  1. 首先是要为 Browse for an image 上传文件按钮添加 multiple 多文件选择的属性,如图:TinyMce 修改插件 实现多文件/图片上传
    设置这个属性的默认文件路径是:\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)
    })
}()

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