如何实现网页编辑器粘贴Word图片并自动上传文件的功能?
- 内容介绍
- 文章标签
- 相关推荐
本文共计3248个文字,预计阅读时间需要13分钟。
由于ueditor粘贴功能不能直接粘贴Word中的图片,这是一个非常头疼的问题。在我们业务场景中,客户迫切需要使用ueditor,并且支持Word图片的粘贴。这个需求已经困扰了我们近一个月,原因是前端由于安全考虑,限制了图片粘贴功能。
ueditor粘贴不能粘贴word中的图片是一个很头疼的问题,在我们的业务场景中客户要求必须使用ueditor并且支持word的图片粘贴,因为这个需求头疼了半个月,因为前端方面因为安全的原因是不允许访问本地文件的。
首先说一下,ueditor粘贴word图片的问题已经解决,但是不是纯web方法解决的,在纯浏览器的条件下是否能够解决也不确定中,但是ckeditor是可以支持word图片的富文本粘贴的
接下来就是调试思路和解决方法(所有的代码都是调试ueditor源码的ueditor.all.js文件)
1、首先是分析问题,
这块就不上代码了,大家可以自己去调试,很清晰的就是因为是本地文件所以不能上传
functionfilter(div){}//大概是14611行的这个函数会把本地的图片路径过滤成一个//编辑器默认的占位图varroot=UE.htmlparser(html);//罪魁祸首就是这行代码
但是尝试在罪魁祸首那行代码前将地址强制替换成网络地址就会发现,所替换的地址就会正常显示,因此找到了解决方案,就是将富文本中的img标签的src想办法替换成网络地址,
于是第一条解决思路出来了,在执行罪魁祸首代码之前,将本地的地址过滤出来,上传到服务器然后用服务器的地址进行替换,
2、解决问题
想到解决法案之后就去寻找解决方法,拿到图片的本地地址简单,
varimgReg=/<img.*?(?:>|\/>)/gi;varimgArr=html.match(imgReg);// arr 为包含所有img标签的数组
利用正则加一些技术基础的处理,就能把所有的图片地址过滤成为一个数组,
我们(我和客户端的大神)的解决思路就是模仿input 的type=file的方式进行上传;
接下来是怎么拿到本地地址的文件,怎么将本地地址搞成文件,我查阅了好久好久的资料,还请教了各路大神(骚骚的三水,和传说中的周皇),得到一个结论,单纯前端不可能通过本地地址拿到文件(这估计就是ueditor为什么不能粘贴word图片的根本原因),因为我们的页面也在内嵌到客户端内与客户端有数据交流,因此就委托我们的客户端大佬帮我抓到了文件对象
functionGetLocalFileObject(szPath){
varobjFile=null;
try{
objFile=newFile([],szPath,{type:"mb/bin"});
if(objFile!=null&&objFile.size==0)
objFile=null;
}
catch(err){
objFile=null;
}
returnobjFile;
}
接下来的处理就简单了,就是利用前端的各种基础知识,上传图片,替换路径,
在这儿本来以为要苦逼的自己写一个上ajax,但是突然发现了一个ueditor的函数sendMyAndInsertFile 这是ueditor用来上传拖拽图片的一个函数
UE.plugin.register('autoupload',function(){}//这下面的第一个函数sendAndInsertFile(){}
但是因为与粘贴在不同的作用域内因此需要将它copy一份到我们粘贴代码这块的作用域内,
当然为了严谨,我修改了一下方法名字,并且为了利于后面的html替换增加了一个回调函数
// 上传文件的函数functionsendMyAndInsertFile(file,editor,callback){
varme=editor;
//模拟数据varfieldName,urlPrefix,maxSize,allowFiles,actionUrl,
loadingHtml,errorHandler,successHandler,
下filetype=/image\/\w+/i.test(file.type)?'image':'file',
loadingId='loading_'+(+newDate()).toString(36);
fieldName=me.getOpt(filetype+'FieldName');
urlPrefix=me.getOpt(filetype+'UrlPrefix');
maxSize=me.getOpt(filetype+'MaxSize');
allowFiles=me.getOpt(filetype+'AllowFiles');
actionUrl=me.getActionUrl(me.getOpt(filetype+'ActionName'));
errorHandler=function(title){
varloader=me.document.getElementById(loadingId);
loader&&domUtils.remove(loader);
me.fireEvent('showmessage',{
'id':loadingId,
'content':title,
'type':'error',
'timeout':4000
});
};
if(filetype=='image'){
loadingHtml='<img class="loadingclass" id="'+loadingId+'" src="'+
me.options.themePath+me.options.theme+
'/images/spacer.gif" title="'+(me.getLang('autoupload.loading')||'')+'" >';
successHandler=function(data){
varlink=urlPrefix+data.url,
loader=me.document.getElementById(loadingId);
if(loader){
loader.setAttribute('src',link);
loader.setAttribute('_src',link);
loader.setAttribute('title',data.title||'');
loader.setAttribute('alt',data.original||'');
loader.removeAttribute('id');
domUtils.removeClasses(loader,'loadingclass');
}
};
}else{
loadingHtml='<p>'+
'<img class="loadingclass" id="'+loadingId+'" src="'+
me.options.themePath+me.options.theme+
'/images/spacer.gif" title="'+(me.getLang('autoupload.loading')||'')+'" >'+
'</p>';
successHandler=function(data){
varlink=urlPrefix+data.url,
loader=me.document.getElementById(loadingId);
varrng=me.selection.getRange(),
bk=rng.createBookmark();
rng.selectNode(loader).select();
me.execCommand('insertfile',{'url':link});
rng.moveToBookmark(bk).select();
};
}
/* 插入loading的占位符 */
// me.execCommand('inserthtml', loadingHtml);
/* 判断后端配置是否没有加载成功 */
if(!me.getOpt(filetype+'ActionName')){
errorHandler(me.getLang('autoupload.errorLoadConfig'));
return;
}
/* 判断文件大小是否超出限制 */
if(file.size>maxSize){
errorHandler(me.getLang('autoupload.exceedSizeError'));
return;
}
/* 判断文件格式是否超出允许 */
varfileext=file.name?file.name.substr(file.name.lastIndexOf('.')):'';
if((fileext&&filetype!='image')||(allowFiles&&(allowFiles.join('')+'.').indexOf(fileext.toLowerCase()+'.')==-1)){
errorHandler(me.getLang('autoupload.exceedTypeError'));
return;
}
/* 创建Ajax并提交 */
varxhr=newXMLHttpRequest(),
fd=newFormData(),
params=utils.serializeParam(me.queryCommandValue('serverparam'))||'',
url=utils.formatUrl(actionUrl+(actionUrl.indexOf('?')==-1?'?':'&')+params);
fd.append(fieldName,file,file.name||('blob.'+file.type.substr('image/'.length)));
fd.append('type','ajax');
xhr.open("post",url,true);
xhr.setRequestHeader("X-Requested-With","XMLHttpRequest");
xhr.addEventListener('load',function(e){
try{
varjson=(newFunction("return "+utils.trim(e.target.response)))();
if(json.state=='SUCCESS'&&json.url){
// 将上传的文件返回callback(json)
}else{
errorHandler(json.state);
}
}catch(er){
errorHandler(me.getLang('autoupload.loadError'));
}
});
xhr.send(fd);
}
ss
其中还有一些需要处理的,网络图片,粘贴时没有图片怎么办,以及多张图片我就不废话了直接将整个filter代码粘贴在下方
functionfilter(div){
varhtml;
if(div.firstChild){
//去掉cut中添加的边界值varnodes=domUtils.getElementsByTagName(div,'span');
for(vari=0,ni;ni=nodes[i++];){
if(ni.id=='_baidu_cut_start'||ni.id=='_baidu_cut_end'){
domUtils.remove(ni);
}
}
if(browser.webkit){
varbrs=div.querySelectorAll('div br');
for(vari=0,bi;bi=brs[i++];){
varpN=bi.parentNode;
if(pN.tagName=='DIV'&&pN.childNodes.length==1){
pN.innerHTML='<p><br/></p>';
domUtils.remove(pN);
}
}
vardivs=div.querySelectorAll('#baidu_pastebin');
for(vari=0,di;di=divs[i++];){
vartmpP=me.document.createElement('p');
di.parentNode.insertBefore(tmpP,di);
while(di.firstChild){
tmpP.appendChild(di.firstChild);
}
domUtils.remove(di);
}
varmetas=div.querySelectorAll('meta');
for(vari=0,ci;ci=metas[i++];){
domUtils.remove(ci);
}
varbrs=div.querySelectorAll('br');
for(i=0;ci=brs[i++];){
if(/^apple-/i.test(ci.className)){
domUtils.remove(ci);
}
}
}
if(browser.gecko){
vardirtyNodes=div.querySelectorAll('[_moz_dirty]');
for(i=0;ci=dirtyNodes[i++];){
ci.removeAttribute('_moz_dirty');
}
}
if(!browser.ie){
varspans=div.querySelectorAll('span.Apple-style-span');
for(vari=0,ci;ci=spans[i++];){
domUtils.remove(ci,true);
}
}
//ie下使用innerHTML会产生多余的\r\n字符,也会产生这里过滤掉html=div.innerHTML;//.replace(/>(?:(\s|)*?)</g,'><');//过滤word粘贴过来的冗余属性html=UE.filterWord(html);
/** * @处理word粘贴进来的图片 * @此处尝试将本地图片的路径分离并上传到服务器并拿到地址替换掉字符串中的img */
//待修改之: 仅在20191221版mblink客户端支持;wzhfunctionGetLocalFileObject(szPath){
varobjFile=null;
try{
objFile=newFile([],szPath,{type:"mb/bin"});
if(objFile!=null&&objFile.size==0)
objFile=null;
}
catch(err){
objFile=null;
}
returnobjFile;
}
varimgReg=/<img.*?(?:>|\/>)/gi;
varimgArr=html.match(imgReg);// arr 为包含所有img标签的数组varsrcReg=/src=[\'\"]?([^\'\"]*)[\'\"]?/i;
if(imgArr){
html=html.replace(/\\/g,"\/")//将富文本中的\与/替换 方便下面替换成网络路径varfreauency=0//定义一个变量记录处理了几张图片for(vari=0,len=imgArr.length;i<len;i++){
varstrsrc=imgArr[i].match(srcReg)[1].slice(8)
vara=GetLocalFileObject(strsrc)
if(!a){//有网络图片时的处理console.log(999)
delHtml()
continue}
// 上传文件的函数functionsendMyAndInsertFile(file,editor,callback){
varme=editor;
//模拟数据console.log(file.type)
varfieldName,urlPrefix,maxSize,allowFiles,actionUrl,
loadingHtml,errorHandler,successHandler,
filetype=/image\/\w+/i.test(file.type)?'image':'file',
loadingId='loading_'+(+newDate()).toString(36);
fieldName=me.getOpt(filetype+'FieldName');
urlPrefix=me.getOpt(filetype+'UrlPrefix');
maxSize=me.getOpt(filetype+'MaxSize');
allowFiles=me.getOpt(filetype+'AllowFiles');
actionUrl=me.getActionUrl(me.getOpt(filetype+'ActionName'));
errorHandler=function(title){
varloader=me.document.getElementById(loadingId);
loader&&domUtils.remove(loader);
me.fireEvent('showmessage',{
'id':loadingId,
'content':title,
'type':'error',
'timeout':4000
});
};
if(filetype=='image'){
loadingHtml='<img class="loadingclass" id="'+loadingId+'" src="'+
me.options.themePath+me.options.theme+
'/images/spacer.gif" title="'+(me.getLang('autoupload.loading')||'')+'" >';
successHandler=function(data){
varlink=urlPrefix+data.url,
loader=me.document.getElementById(loadingId);
if(loader){
loader.setAttribute('src',link);
loader.setAttribute('_src',link);
loader.setAttribute('title',data.title||'');
loader.setAttribute('alt',data.original||'');
loader.removeAttribute('id');
domUtils.removeClasses(loader,'loadingclass');
}
};
}else{
loadingHtml='<p>'+
'<img class="loadingclass" id="'+loadingId+'" src="'+
me.options.themePath+me.options.theme+
'/images/spacer.gif" title="'+(me.getLang('autoupload.loading')||'')+'" >'+
'</p>';
successHandler=function(data){
varlink=urlPrefix+data.url,
loader=me.document.getElementById(loadingId);
varrng=me.selection.getRange(),
bk=rng.createBookmark();
rng.selectNode(loader).select();
me.execCommand('insertfile',{'url':link});
rng.moveToBookmark(bk).select();
};
}
/* 插入loading的占位符 */
// me.execCommand('inserthtml', loadingHtml);
/* 判断后端配置是否没有加载成功 */
if(!me.getOpt(filetype+'ActionName')){
errorHandler(me.getLang('autoupload.errorLoadConfig'));
return;
}
/* 判断文件大小是否超出限制 */
if(file.size>maxSize){
errorHandler(me.getLang('autoupload.exceedSizeError'));
return;
}
/* 判断文件格式是否超出允许 */
varfileext=file.name?file.name.substr(file.name.lastIndexOf('.')):'';
if((fileext&&filetype!='image')||(allowFiles&&(allowFiles.join('')+'.').indexOf(fileext.toLowerCase()+'.')==-1)){
errorHandler(me.getLang('autoupload.exceedTypeError'));
return;
}
/* 创建Ajax并提交 */
varxhr=newXMLHttpRequest(),
fd=newFormData(),
params=utils.serializeParam(me.queryCommandValue('serverparam'))||'',
url=utils.formatUrl(actionUrl+(actionUrl.indexOf('?')==-1?'?':'&')+params);
fd.append(fieldName,file,file.name||('blob.'+file.type.substr('image/'.length)));
fd.append('type','ajax');
xhr.open("post",url,true);
xhr.setRequestHeader("X-Requested-With","XMLHttpRequest");
xhr.addEventListener('load',function(e){
try{
varjson=(newFunction("return "+utils.trim(e.target.response)))();
if(json.state=='SUCCESS'&&json.url){
// 将上传的文件返回callback(json)
}else{
errorHandler(json.state);
}
}catch(er){
errorHandler(me.getLang('autoupload.loadError'));
}
});
xhr.send(fd);
}
// 上传文件函数的回调进行图片路径替换和渲染htmlsendMyAndInsertFile(a,me,function(res){
freauency++
html=html.replace(res.original,res.url)
if(freauency!=imgArr.length){return}//多张图片粘贴时等到最后一张上传完在渲染htmldelHtml()
})
// })}
}else{
delHtml()
}
/** * @将之前处理富文本html的代码封装成一个函数便于在有图片和没图片的两张粘贴情况进行处理 * */
functiondelHtml(){
//取消了忽略空白的第二个参数,粘贴过来的有些是有空白的,会被套上相关的标签varroot=UE.htmlparser(html);//此处过滤会把file图片过滤掉//如果给了过滤规则就先进行过滤if(me.options.filterRules){
UE.filterNode(root,me.options.filterRules);
}
//执行默认的处理me.filterInputRule(root);
//针对chrome的处理if(browser.webkit){
varbr=root.lastChild();
if(br&&br.type=='element'&&br.tagName=='br'){
root.removeChild(br)
}
utils.each(me.body.querySelectorAll('div'),function(node){
if(domUtils.isEmptyBlock(node)){
//domUtils.remove(node,true)}
})
}
html={'html':root.toHtml()};
me.fireEvent('beforepaste',html,root);
//抢了默认的粘贴,那后边的内容就不执行了,比如表格粘贴if(!html.html){
return;
}
root=UE.htmlparser(html.html,true);
//如果开启了纯文本模式if(me.queryCommandState('pasteplain')===1){
me.execCommand('insertHtml',UE.filterNode(root,me.options.filterTxtRules).toHtml(),true);
}else{
//文本模式UE.filterNode(root,me.options.filterTxtRules);
txtContent=root.toHtml();
//完全模式htmlContent=html.html;
address=me.selection.getRange().createAddress(true);
me.execCommand('insertHtml',me.getOpt('retainOnlyLabelPasted')===true?getPureHtml(htmlContent):htmlContent,true);
}
me.fireEvent("afterpaste",html);
}
}
}
本文共计3248个文字,预计阅读时间需要13分钟。
由于ueditor粘贴功能不能直接粘贴Word中的图片,这是一个非常头疼的问题。在我们业务场景中,客户迫切需要使用ueditor,并且支持Word图片的粘贴。这个需求已经困扰了我们近一个月,原因是前端由于安全考虑,限制了图片粘贴功能。
ueditor粘贴不能粘贴word中的图片是一个很头疼的问题,在我们的业务场景中客户要求必须使用ueditor并且支持word的图片粘贴,因为这个需求头疼了半个月,因为前端方面因为安全的原因是不允许访问本地文件的。
首先说一下,ueditor粘贴word图片的问题已经解决,但是不是纯web方法解决的,在纯浏览器的条件下是否能够解决也不确定中,但是ckeditor是可以支持word图片的富文本粘贴的
接下来就是调试思路和解决方法(所有的代码都是调试ueditor源码的ueditor.all.js文件)
1、首先是分析问题,
这块就不上代码了,大家可以自己去调试,很清晰的就是因为是本地文件所以不能上传
functionfilter(div){}//大概是14611行的这个函数会把本地的图片路径过滤成一个//编辑器默认的占位图varroot=UE.htmlparser(html);//罪魁祸首就是这行代码
但是尝试在罪魁祸首那行代码前将地址强制替换成网络地址就会发现,所替换的地址就会正常显示,因此找到了解决方案,就是将富文本中的img标签的src想办法替换成网络地址,
于是第一条解决思路出来了,在执行罪魁祸首代码之前,将本地的地址过滤出来,上传到服务器然后用服务器的地址进行替换,
2、解决问题
想到解决法案之后就去寻找解决方法,拿到图片的本地地址简单,
varimgReg=/<img.*?(?:>|\/>)/gi;varimgArr=html.match(imgReg);// arr 为包含所有img标签的数组
利用正则加一些技术基础的处理,就能把所有的图片地址过滤成为一个数组,
我们(我和客户端的大神)的解决思路就是模仿input 的type=file的方式进行上传;
接下来是怎么拿到本地地址的文件,怎么将本地地址搞成文件,我查阅了好久好久的资料,还请教了各路大神(骚骚的三水,和传说中的周皇),得到一个结论,单纯前端不可能通过本地地址拿到文件(这估计就是ueditor为什么不能粘贴word图片的根本原因),因为我们的页面也在内嵌到客户端内与客户端有数据交流,因此就委托我们的客户端大佬帮我抓到了文件对象
functionGetLocalFileObject(szPath){
varobjFile=null;
try{
objFile=newFile([],szPath,{type:"mb/bin"});
if(objFile!=null&&objFile.size==0)
objFile=null;
}
catch(err){
objFile=null;
}
returnobjFile;
}
接下来的处理就简单了,就是利用前端的各种基础知识,上传图片,替换路径,
在这儿本来以为要苦逼的自己写一个上ajax,但是突然发现了一个ueditor的函数sendMyAndInsertFile 这是ueditor用来上传拖拽图片的一个函数
UE.plugin.register('autoupload',function(){}//这下面的第一个函数sendAndInsertFile(){}
但是因为与粘贴在不同的作用域内因此需要将它copy一份到我们粘贴代码这块的作用域内,
当然为了严谨,我修改了一下方法名字,并且为了利于后面的html替换增加了一个回调函数
// 上传文件的函数functionsendMyAndInsertFile(file,editor,callback){
varme=editor;
//模拟数据varfieldName,urlPrefix,maxSize,allowFiles,actionUrl,
loadingHtml,errorHandler,successHandler,
下filetype=/image\/\w+/i.test(file.type)?'image':'file',
loadingId='loading_'+(+newDate()).toString(36);
fieldName=me.getOpt(filetype+'FieldName');
urlPrefix=me.getOpt(filetype+'UrlPrefix');
maxSize=me.getOpt(filetype+'MaxSize');
allowFiles=me.getOpt(filetype+'AllowFiles');
actionUrl=me.getActionUrl(me.getOpt(filetype+'ActionName'));
errorHandler=function(title){
varloader=me.document.getElementById(loadingId);
loader&&domUtils.remove(loader);
me.fireEvent('showmessage',{
'id':loadingId,
'content':title,
'type':'error',
'timeout':4000
});
};
if(filetype=='image'){
loadingHtml='<img class="loadingclass" id="'+loadingId+'" src="'+
me.options.themePath+me.options.theme+
'/images/spacer.gif" title="'+(me.getLang('autoupload.loading')||'')+'" >';
successHandler=function(data){
varlink=urlPrefix+data.url,
loader=me.document.getElementById(loadingId);
if(loader){
loader.setAttribute('src',link);
loader.setAttribute('_src',link);
loader.setAttribute('title',data.title||'');
loader.setAttribute('alt',data.original||'');
loader.removeAttribute('id');
domUtils.removeClasses(loader,'loadingclass');
}
};
}else{
loadingHtml='<p>'+
'<img class="loadingclass" id="'+loadingId+'" src="'+
me.options.themePath+me.options.theme+
'/images/spacer.gif" title="'+(me.getLang('autoupload.loading')||'')+'" >'+
'</p>';
successHandler=function(data){
varlink=urlPrefix+data.url,
loader=me.document.getElementById(loadingId);
varrng=me.selection.getRange(),
bk=rng.createBookmark();
rng.selectNode(loader).select();
me.execCommand('insertfile',{'url':link});
rng.moveToBookmark(bk).select();
};
}
/* 插入loading的占位符 */
// me.execCommand('inserthtml', loadingHtml);
/* 判断后端配置是否没有加载成功 */
if(!me.getOpt(filetype+'ActionName')){
errorHandler(me.getLang('autoupload.errorLoadConfig'));
return;
}
/* 判断文件大小是否超出限制 */
if(file.size>maxSize){
errorHandler(me.getLang('autoupload.exceedSizeError'));
return;
}
/* 判断文件格式是否超出允许 */
varfileext=file.name?file.name.substr(file.name.lastIndexOf('.')):'';
if((fileext&&filetype!='image')||(allowFiles&&(allowFiles.join('')+'.').indexOf(fileext.toLowerCase()+'.')==-1)){
errorHandler(me.getLang('autoupload.exceedTypeError'));
return;
}
/* 创建Ajax并提交 */
varxhr=newXMLHttpRequest(),
fd=newFormData(),
params=utils.serializeParam(me.queryCommandValue('serverparam'))||'',
url=utils.formatUrl(actionUrl+(actionUrl.indexOf('?')==-1?'?':'&')+params);
fd.append(fieldName,file,file.name||('blob.'+file.type.substr('image/'.length)));
fd.append('type','ajax');
xhr.open("post",url,true);
xhr.setRequestHeader("X-Requested-With","XMLHttpRequest");
xhr.addEventListener('load',function(e){
try{
varjson=(newFunction("return "+utils.trim(e.target.response)))();
if(json.state=='SUCCESS'&&json.url){
// 将上传的文件返回callback(json)
}else{
errorHandler(json.state);
}
}catch(er){
errorHandler(me.getLang('autoupload.loadError'));
}
});
xhr.send(fd);
}
ss
其中还有一些需要处理的,网络图片,粘贴时没有图片怎么办,以及多张图片我就不废话了直接将整个filter代码粘贴在下方
functionfilter(div){
varhtml;
if(div.firstChild){
//去掉cut中添加的边界值varnodes=domUtils.getElementsByTagName(div,'span');
for(vari=0,ni;ni=nodes[i++];){
if(ni.id=='_baidu_cut_start'||ni.id=='_baidu_cut_end'){
domUtils.remove(ni);
}
}
if(browser.webkit){
varbrs=div.querySelectorAll('div br');
for(vari=0,bi;bi=brs[i++];){
varpN=bi.parentNode;
if(pN.tagName=='DIV'&&pN.childNodes.length==1){
pN.innerHTML='<p><br/></p>';
domUtils.remove(pN);
}
}
vardivs=div.querySelectorAll('#baidu_pastebin');
for(vari=0,di;di=divs[i++];){
vartmpP=me.document.createElement('p');
di.parentNode.insertBefore(tmpP,di);
while(di.firstChild){
tmpP.appendChild(di.firstChild);
}
domUtils.remove(di);
}
varmetas=div.querySelectorAll('meta');
for(vari=0,ci;ci=metas[i++];){
domUtils.remove(ci);
}
varbrs=div.querySelectorAll('br');
for(i=0;ci=brs[i++];){
if(/^apple-/i.test(ci.className)){
domUtils.remove(ci);
}
}
}
if(browser.gecko){
vardirtyNodes=div.querySelectorAll('[_moz_dirty]');
for(i=0;ci=dirtyNodes[i++];){
ci.removeAttribute('_moz_dirty');
}
}
if(!browser.ie){
varspans=div.querySelectorAll('span.Apple-style-span');
for(vari=0,ci;ci=spans[i++];){
domUtils.remove(ci,true);
}
}
//ie下使用innerHTML会产生多余的\r\n字符,也会产生这里过滤掉html=div.innerHTML;//.replace(/>(?:(\s|)*?)</g,'><');//过滤word粘贴过来的冗余属性html=UE.filterWord(html);
/** * @处理word粘贴进来的图片 * @此处尝试将本地图片的路径分离并上传到服务器并拿到地址替换掉字符串中的img */
//待修改之: 仅在20191221版mblink客户端支持;wzhfunctionGetLocalFileObject(szPath){
varobjFile=null;
try{
objFile=newFile([],szPath,{type:"mb/bin"});
if(objFile!=null&&objFile.size==0)
objFile=null;
}
catch(err){
objFile=null;
}
returnobjFile;
}
varimgReg=/<img.*?(?:>|\/>)/gi;
varimgArr=html.match(imgReg);// arr 为包含所有img标签的数组varsrcReg=/src=[\'\"]?([^\'\"]*)[\'\"]?/i;
if(imgArr){
html=html.replace(/\\/g,"\/")//将富文本中的\与/替换 方便下面替换成网络路径varfreauency=0//定义一个变量记录处理了几张图片for(vari=0,len=imgArr.length;i<len;i++){
varstrsrc=imgArr[i].match(srcReg)[1].slice(8)
vara=GetLocalFileObject(strsrc)
if(!a){//有网络图片时的处理console.log(999)
delHtml()
continue}
// 上传文件的函数functionsendMyAndInsertFile(file,editor,callback){
varme=editor;
//模拟数据console.log(file.type)
varfieldName,urlPrefix,maxSize,allowFiles,actionUrl,
loadingHtml,errorHandler,successHandler,
filetype=/image\/\w+/i.test(file.type)?'image':'file',
loadingId='loading_'+(+newDate()).toString(36);
fieldName=me.getOpt(filetype+'FieldName');
urlPrefix=me.getOpt(filetype+'UrlPrefix');
maxSize=me.getOpt(filetype+'MaxSize');
allowFiles=me.getOpt(filetype+'AllowFiles');
actionUrl=me.getActionUrl(me.getOpt(filetype+'ActionName'));
errorHandler=function(title){
varloader=me.document.getElementById(loadingId);
loader&&domUtils.remove(loader);
me.fireEvent('showmessage',{
'id':loadingId,
'content':title,
'type':'error',
'timeout':4000
});
};
if(filetype=='image'){
loadingHtml='<img class="loadingclass" id="'+loadingId+'" src="'+
me.options.themePath+me.options.theme+
'/images/spacer.gif" title="'+(me.getLang('autoupload.loading')||'')+'" >';
successHandler=function(data){
varlink=urlPrefix+data.url,
loader=me.document.getElementById(loadingId);
if(loader){
loader.setAttribute('src',link);
loader.setAttribute('_src',link);
loader.setAttribute('title',data.title||'');
loader.setAttribute('alt',data.original||'');
loader.removeAttribute('id');
domUtils.removeClasses(loader,'loadingclass');
}
};
}else{
loadingHtml='<p>'+
'<img class="loadingclass" id="'+loadingId+'" src="'+
me.options.themePath+me.options.theme+
'/images/spacer.gif" title="'+(me.getLang('autoupload.loading')||'')+'" >'+
'</p>';
successHandler=function(data){
varlink=urlPrefix+data.url,
loader=me.document.getElementById(loadingId);
varrng=me.selection.getRange(),
bk=rng.createBookmark();
rng.selectNode(loader).select();
me.execCommand('insertfile',{'url':link});
rng.moveToBookmark(bk).select();
};
}
/* 插入loading的占位符 */
// me.execCommand('inserthtml', loadingHtml);
/* 判断后端配置是否没有加载成功 */
if(!me.getOpt(filetype+'ActionName')){
errorHandler(me.getLang('autoupload.errorLoadConfig'));
return;
}
/* 判断文件大小是否超出限制 */
if(file.size>maxSize){
errorHandler(me.getLang('autoupload.exceedSizeError'));
return;
}
/* 判断文件格式是否超出允许 */
varfileext=file.name?file.name.substr(file.name.lastIndexOf('.')):'';
if((fileext&&filetype!='image')||(allowFiles&&(allowFiles.join('')+'.').indexOf(fileext.toLowerCase()+'.')==-1)){
errorHandler(me.getLang('autoupload.exceedTypeError'));
return;
}
/* 创建Ajax并提交 */
varxhr=newXMLHttpRequest(),
fd=newFormData(),
params=utils.serializeParam(me.queryCommandValue('serverparam'))||'',
url=utils.formatUrl(actionUrl+(actionUrl.indexOf('?')==-1?'?':'&')+params);
fd.append(fieldName,file,file.name||('blob.'+file.type.substr('image/'.length)));
fd.append('type','ajax');
xhr.open("post",url,true);
xhr.setRequestHeader("X-Requested-With","XMLHttpRequest");
xhr.addEventListener('load',function(e){
try{
varjson=(newFunction("return "+utils.trim(e.target.response)))();
if(json.state=='SUCCESS'&&json.url){
// 将上传的文件返回callback(json)
}else{
errorHandler(json.state);
}
}catch(er){
errorHandler(me.getLang('autoupload.loadError'));
}
});
xhr.send(fd);
}
// 上传文件函数的回调进行图片路径替换和渲染htmlsendMyAndInsertFile(a,me,function(res){
freauency++
html=html.replace(res.original,res.url)
if(freauency!=imgArr.length){return}//多张图片粘贴时等到最后一张上传完在渲染htmldelHtml()
})
// })}
}else{
delHtml()
}
/** * @将之前处理富文本html的代码封装成一个函数便于在有图片和没图片的两张粘贴情况进行处理 * */
functiondelHtml(){
//取消了忽略空白的第二个参数,粘贴过来的有些是有空白的,会被套上相关的标签varroot=UE.htmlparser(html);//此处过滤会把file图片过滤掉//如果给了过滤规则就先进行过滤if(me.options.filterRules){
UE.filterNode(root,me.options.filterRules);
}
//执行默认的处理me.filterInputRule(root);
//针对chrome的处理if(browser.webkit){
varbr=root.lastChild();
if(br&&br.type=='element'&&br.tagName=='br'){
root.removeChild(br)
}
utils.each(me.body.querySelectorAll('div'),function(node){
if(domUtils.isEmptyBlock(node)){
//domUtils.remove(node,true)}
})
}
html={'html':root.toHtml()};
me.fireEvent('beforepaste',html,root);
//抢了默认的粘贴,那后边的内容就不执行了,比如表格粘贴if(!html.html){
return;
}
root=UE.htmlparser(html.html,true);
//如果开启了纯文本模式if(me.queryCommandState('pasteplain')===1){
me.execCommand('insertHtml',UE.filterNode(root,me.options.filterTxtRules).toHtml(),true);
}else{
//文本模式UE.filterNode(root,me.options.filterTxtRules);
txtContent=root.toHtml();
//完全模式htmlContent=html.html;
address=me.selection.getRange().createAddress(true);
me.execCommand('insertHtml',me.getOpt('retainOnlyLabelPasted')===true?getPureHtml(htmlContent):htmlContent,true);
}
me.fireEvent("afterpaste",html);
}
}
}

