pasteAndDragImageIntoTiebaEditor

贴吧图片拖放和粘贴上传

目前为 2017-02-16 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name pasteAndDragImageIntoTiebaEditor
  3. // @author 527836355
  4. // @id pasteAndDragImageIntoTiebaEditor
  5. // @namespace http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul
  6. // @include https://tieba.baidu.com/*
  7. // @version 3.1
  8. // @description 贴吧图片拖放和粘贴上传
  9. // @grant GM_xmlhttpRequest
  10. // @grant unsafeWindow
  11. // @grant GM_addStyle
  12. // @grant GM_log
  13. // ==/UserScript==
  14. const editorId='ueditor_replace';//发帖框ID
  15. const parentId='tb_rich_poster_container';//父节点监听
  16. var editor=null;//初始化发贴框
  17. var preview=null;//进度预览
  18. if(!unsafeWindow.FlashImageLoader)//flash上传还是必须的
  19. {
  20. var sc=document.createElement('script');
  21. sc.id='flashUpload';
  22. sc.setAttribute('src','http://static.tieba.baidu.com/tb/static-frs/component/sign_shai/flash_image_loader.js');
  23. document.body.appendChild(sc);
  24. };
  25. if(document.getElementById(editorId))//检测是否存在这个元素
  26. {
  27. init();
  28. }
  29. else //不存在则监听节点变动
  30. {
  31. var target=document.getElementById(parentId);
  32. var observer = new MutationObserver(function(mutations)
  33. {
  34. if(document.getElementById(editorId))
  35. {
  36. observer.disconnect();//停止监听
  37. init();
  38. }
  39. })
  40. var config = { attributes: true, childList: true, characterData: true };
  41. observer.observe(target, config);
  42. }
  43.  
  44. function init()//初始化,添加事件
  45. {
  46. editor=document.getElementById(editorId);
  47.  
  48. editor.addEventListener('paste',function (e)//添加事件处理
  49. {
  50. var data=e.clipboardData.getData('text/unicode');
  51. if(!data)
  52. e.stopPropagation();//好吧,如果不是图片,我们也不能随便阻止其他事情吧。
  53. setTimeout(function ()
  54. {
  55. pasteImg()
  56. }, 200);//给图片解码留出时间
  57. //
  58. }, true);
  59. //添加拖入拖出时的效果处理
  60. document.body.addEventListener('dragenter',function(e){e.preventDefault();e.stopPropagation();},false);
  61. editor.addEventListener('dragover',function(e){e.preventDefault();e.stopPropagation();editor.style.border='2px dotted red'},false);
  62. editor.addEventListener('drop',function(e){e.preventDefault();e.stopPropagation();editor.style.border='1px solid gray';dragHandle(e);},false);
  63. editor.addEventListener('dragleave',function(e){e.preventDefault();e.stopPropagation();editor.style.border='1px solid gray';},false);
  64. addProgressBar();
  65. }
  66. function addProgressBar()
  67. {
  68. var container=document.querySelector('.old_style_wrapper');
  69. var div=document.createElement('div');
  70. div.id='progressBar';
  71. div.style.cssText='position:absolute;right:20px;top:45px;width:200px;height:280px;';
  72. container.appendChild(div);
  73. preview=div;
  74. }
  75. function dragHandle(evt)//处理拖放
  76. {
  77. var files=evt.dataTransfer.files;
  78. for(i=0;i<files.length;i++)
  79. {
  80. var file=files[i];
  81. var type=file.type;
  82. var name=file.name;
  83. var size=file.size/1024+'';
  84. size=size.substring(0,4);
  85. var reader=new FileReader();
  86. if(type.match('image'))//测试是否是图片文件
  87. {
  88. reader.onload=function(e)
  89. {
  90. var dataURL=e.target.result;//base64编码
  91. //处理数据
  92. new uploader(dataURL,false,null).init();
  93. }
  94. reader.readAsDataURL(file);
  95. }
  96. }
  97. }
  98. function pasteImg()
  99. {
  100. var imgs=document.querySelectorAll('#ueditor_replace img');
  101. for(i=0;i<imgs.length;i++)
  102. {
  103. if(imgs[i].hasAttribute('uploading')||imgs[i].src.indexOf('data:image')!=0)
  104. continue;
  105. imgs[i].setAttribute('uploading','true');
  106. var src=imgs[i].src;
  107. var nwidth=imgs[i].width;
  108. var height=imgs[i].height;
  109. width=nwidth>560?560:nwidth;
  110. height=width/nwidth*height;
  111. imgs[i].src='data:image/gif;base64,R0lGODlhEAAQAOUdAOvr69HR0cHBwby8vOzs7PHx8ff397W1tbOzs+Xl5ebm5vDw8PPz88PDw7e3t+3t7dvb2+7u7vX19eTk5OPj4+rq6tbW1unp6bu7u+fn5+jo6N/f3+/v7/7+/ra2ttXV1f39/fz8/Li4uMXFxfb29vLy8vr6+sLCwtPT0/j4+PT09MDAwL+/v7m5ubS0tM7OzsrKytra2tTU1MfHx+Li4tDQ0M/Pz9nZ2b6+vgAAAAAAAAAAAAAAAAAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQFMAA5ACwAAAAAEAAQAAAGg8CcMAcICAY5QsEwHBYPCMQhl6guGM5GNOqgVhMPbA6y5Xq/kZwkN3Fsu98EJcdYKCo5i7kKwCorVRd4GAg5GVgAfBpxaRtsZwkaiwpfD0NxkYl8QngARF8AdhmeDwl4pngUCQsVHDl2m2iveDkXcZ6YTgS3kAS0RKWxVQ+/TqydrE1BACH5BAkwADkALAAAAAAQABAAAAZ+wJwwJ1kQIgNBgDMcdh6KRILgQSAOn46TIJVSrdZGSMjpeqtgREAoYWi6BFF6xCAJS6ZyYhEIUwxNQgYkFxwBByh2gU0kKRVHi4sgOQuRTRJtJgwSBJElihwMQioqGmw5gEMLKk2AEkSBq4ElQmNNoYG2OVpDuE6Lrzmfp0NBACH5BAUwADkALAAAAAAQABAAAAaFwJwwJ1kQCDlCwTAcMh6KhDQnVSwYTkJ1un1gc5wtdxsh5iqaLbVKyVEWigq4ugZgTyiA9CK/JHIZWCsICCxpVWV/EzkHhAgth1UPQ4OOLXpScmebFA6ELHAZclBycXIULi8VZXCZawplFG05flWlakIVWravCgSaZ1CuksBDFQsAcsfFQQAh+QQJMAA5ACwAAAAAEAAQAAAGQcCccEgsGo/IpHLJzDGaOcKCCUgkAEuFNaFRbq1dJCxX2WKRCFdMmJiiEQjRp1BJwu8y5R3RWNsRBx9+SSsxgzlBACH5BAkwADkALAAAAAAQABAAAAaJwJwwJ1kQCDlCwTAcMh6KhDQnVSwYTkJ1un1gc5wtdxsh5iqaLbVKyTEWigq4ugZglRXpRX5J5DJYAFIAaVVlfhNrURqFVQ9DYhqCgzkzCGdnVQBwGRU0LQiXCRUAORQJCwAcOTChoYplBXIKLq6vUXRCCQ22olUEcroJB66KD8FNCjUrlxWpTUEAIfkEBTAAOQAsAAAAABAAEAAABobAnDAnWRAIOULBMBwyHoqENCdVLBhOQnW6fWBznC13G8nZchXNllql5Bg2xA1cZQOwShwCMdDkLgk5GVgAUgAie3syVDkTbFIaiIkIJ0NiGnp7HiNonRVVAHEuFjlQFVQVAI0JCzYjrKCPZQWnf1unYkMVWrFbBLVoUIaPD8C6CwCnAMhNQQA7';
  112. new uploader(src,true,imgs[i]).init();
  113. }
  114. }
  115. function uploader(dataURL,isPaste,oldImage)//第一次尝试模板
  116. {
  117. this.dataURL=dataURL;
  118. this.isPaste=isPaste;
  119. this.oldImage=oldImage;
  120. this.progressBar=null;
  121. this.tbs=null;
  122. this.blob=null;
  123. this.init=function() //进条度创建在此
  124. { var now=this;
  125. var div=document.createElement('DIV');//父节点
  126. div.style.cssText="background:rgba(33,33,33,0.8);width:200px;height;40px;border:1px solid red;border:2px solid gray;border-radius:10px;margin:5px;padding:5px;"
  127. var img=document.createElement('img');
  128. img.src=this.dataURL;
  129. img.style.cssText='height:auto;width:auto;max-width:200px;max-height:40px;';
  130. var bar=document.createElement('progress');
  131. bar.style.cssText='width:180px;height:15px;display:position:absolute;';
  132. div.appendChild(img);
  133. div.appendChild(document.createElement('hr'));
  134. div.appendChild(bar);
  135. preview.appendChild(div);
  136. this.progressBar=bar;
  137. var xhr = new XMLHttpRequest();
  138. xhr.open('GET', 'http://tieba.baidu.com/dc/common/imgtbs?t=' + new Date().getTime(), false);
  139. xhr.onload = function ()
  140. {
  141. var res=JSON.parse(xhr.responseText);
  142. var tbs = res.data.tbs;
  143. now.upload(tbs);
  144. }
  145. xhr.send();
  146. };
  147. this.upload=function(tbs)
  148. {
  149. //到这步是正常的
  150. var now=this;
  151. var blob=dataUrlToBlob(this.dataURL);
  152. var data=new FormData();
  153. data.append('Filename','333333.png');
  154. data.append('tbs',tbs);
  155. data.append('fid',unsafeWindow.PageData.forum.id);
  156. data.append('file',blob);
  157. //上传模块
  158. GM_xmlhttpRequest({
  159. synchronous:false,
  160. method:'POST',
  161. url:'http://upload.tieba.baidu.com/upload/pic?is_wm=1',
  162. data:data,
  163. onprogress:function(e)//处理进度条
  164. {
  165. if ( !e.lengthComputable )
  166. {
  167. now.progressBar.value=1;
  168. }
  169. else
  170. {
  171. now.progressBar.style.display='';
  172. now.progressBar.value=(e.loaded/e.total);
  173. }
  174.  
  175. },
  176. onload:function(d)//可以正常运行至此
  177. {
  178. now.onload(d);
  179. }
  180. });
  181. }
  182. this.onload=function(res)//下载完毕处理。
  183. {
  184. var mes=JSON.parse(res.responseText);//{"err_no":0,"err_msg":"","no":0,"error_code":0,"info":{"cur_time":1386817416,"pic_id":"9732578534","fullpic_width":264,"fullpic_height":149,"pic_type":4,"full_datalen":1953,"full_sign0":93043670,"full_sign1":3974064591,"pic_id_encode":"b2aab951f8198618d026c1f048ed2e738ad4e696","pic_desc":"blob","err_no":0,"pic_water":"http:\/\/imgsrc.baidu.com\/tieba\/pic\/item\/cefc1e178a82b901accced47718da9773912ef65.jpg"}}
  185. var fullWidth=mes.info.fullpic_width;//真实宽度
  186. var fullHeight=mes.info.fullpic_height;//真实高度
  187. var picId=mes.info.pic_id_encode;
  188. var picType=mes.info.pic_type;
  189. var picWater=mes.info.pic_water;
  190. var e ='http://imgsrc.baidu.com/forum/pic/item/' + picId + '.png';//图片地址
  191. var cache=new Image();//先下载再响应
  192. cache.setAttribute("pic_type","0");
  193. cache.setAttribute("unselectable","on");
  194. cache.src=e;
  195. var old=this.oldImage;
  196. var bar=this.progressBar;
  197. var nwidth=fullWidth
  198. var height=fullHeight;
  199. width=nwidth>560?560:nwidth;
  200. height=parseInt(width/nwidth*height);
  201. cache.setAttribute('width',width);
  202. cache.setAttribute('height',height);
  203. cache.setAttribute('class','BDE_Image');
  204. if(isPaste)//如果是粘贴的就替换,否则直接插入图片
  205. old.parentNode.replaceChild(cache,old);
  206. else
  207. editor.appendChild(cache);
  208. unsafeWindow.$(bar.parentNode).slideUp('slow');//动画效果
  209. bar.parentNode.removeChild(bar);//移除预览框
  210.  
  211. }
  212. }
  213. //以下三个函数可把dataURL转换成BLOB对象,研究fawave的收获,哈哈
  214. function binaryToBlob(data)
  215. {
  216. var arr=new Uint8Array(data.length);
  217. for(var i=0,l=data.length;i<l;i++)
  218. {
  219. arr[i]=data.charCodeAt(i);
  220. }
  221. var buffer=arr;
  222. return buildBlob([buffer]);
  223. }
  224. function dataUrlToBlob(dataurl)
  225. {
  226. var datas=dataurl.split(',',2);
  227. var blob=binaryToBlob(atob(datas[1]));
  228. blob.fileType=datas[0].split(';')[0].split(':')[1];
  229. blob.name='xxx.png';
  230. return blob;
  231. };
  232.  
  233. function buildBlob(parts)
  234. {
  235. blob=new Blob(parts);
  236. return blob;
  237. }