Baidu Tieba Quote and Post

百度贴吧图片引用 作者:铅笔、修正:huhu

  1. // ==UserScript==
  2. // @name Baidu Tieba Quote and Post
  3. // @version 2.2.2.0
  4. // @icon http://imgsrc.baidu.com/forum/pic/item/911e12087bf40ad13d03ebde552c11dfa8ecce89.jpeg
  5. // @description 百度贴吧图片引用 作者:铅笔、修正:huhu
  6. // @include http://tieba.baidu.com/p/*
  7. // @include http://tieba.baidu.com.cn/p/*
  8. // @include http://tieba.baidu.cn/p/*
  9. // @include http://tieba.baidu.com/f*
  10. // @include http://tieba.baidu.com.cn/f*
  11. // @include http://tieba.baidu.cn/f*/f?*
  12. // @copyright 5B4B
  13. // @namespace 5B4B
  14. // ==/UserScript==
  15.  
  16. function init() {
  17.  
  18. //////
  19. //// 设置
  20. //
  21. var font_family = '"微软雅黑"',
  22. font_size = '14px',
  23. line_height = '16px',
  24. font = font_size + ' ' + font_family,
  25. colour='';//自定义颜色,默认随机
  26. //////
  27. //// 产生引用内容
  28. //
  29.  
  30. function addQuote(textarea, content, pid) {
  31. var canvas = $('<canvas>').attr({
  32. width: 0,
  33. height: 0
  34. }).get(0);
  35. var ctx,
  36. style = [
  37. 'font-family:' + font_family,
  38. 'font-weight:normal',
  39. 'font-style:normal',
  40. 'font-size:' + font_size,
  41. 'line-height:' + line_height
  42. ].join(';'),
  43. metrix = measureText(content, style, 540);
  44. content=metrix.content;
  45. canvas.width = metrix.width + 10;
  46. canvas.height = metrix.height + 10;
  47. ctx = canvas.getContext('2d');
  48. ctx.clearRect(0, 0, canvas.width, canvas.height);
  49. ctx.globalAlpha = 1.0;
  50. ctx.setFillColor('transparent');
  51. ctx.fillRect(0, 0, canvas.width, canvas.height);
  52. ctx.fillStyle = 'black';
  53. ctx.font = font;
  54. ctx.textAlign = 'left';
  55. ctx.textBaseline = 'top';
  56. content.trim().split(/[\n\r]/).forEach(function(str, i) {
  57. ctx.fillText(str, 5, 5 + 14 * i + 2 * i);
  58. });
  59. ctx.lineWidth=3;
  60. ctx.strokeStyle = colour||('#'+(Math.random()*0xffffff<<0).toString(16));
  61. ctx.strokeRect(0, 0, canvas.width, canvas.height);
  62.  
  63. var savedURL = LetItGo.get('BTQP-PID-' + pid);
  64. if (savedURL) {
  65. addQuotePic(savedURL);
  66. } else {
  67. uploadPic({
  68. pid: pid,
  69. blob: dataURLtoBlob(canvas.toDataURL())
  70. }, addQuotePic);
  71. }
  72. }
  73.  
  74. function addQuotePic(url, pid) {
  75. LetItGo.set('BTQP-PID-' + pid, url);
  76. $(textarea).find('.BDE_Image[pic_type="9"]:first')
  77. .attr('src', url).attr('pic_type', 1).attr('onload', 'EditorUI.resizeImage(this, 560)');
  78. //.removeAttr('pic_type');
  79. textarea.focus();
  80. var html = textarea.innerHTML;    
  81. document.execCommand('selectAll', false, null);    
  82. document.execCommand('insertHTML', false, html);
  83. }
  84.  
  85. function uploadPic(data, callback) {
  86. var blob = data.blob,
  87. pid = data.pid;
  88. var xhr = new XMLHttpRequest(),
  89. size = blob.size;
  90. xhr.open('GET', 'http://tieba.baidu.com/dc/common/imgtbs?t=' + new Date().getTime(), true);
  91. xhr.onload = function() {
  92. var res = JSON.parse(this.responseText);
  93. if (res.no !== 0) {
  94. failedCallback();
  95. }
  96. var tbs = res.data.tbs,
  97. formData = new FormData();
  98. xhr.abort();
  99. xhr.open('POST', 'http://upload.tieba.baidu.com/upload/pic?is_wm=1&tbs=' + tbs, true);
  100. xhr.withCredentials = true;
  101. xhr.onload = function() {
  102. var res = JSON.parse(this.responseText);
  103. if (res.error_code !== 0) {
  104. alert('上传图片失败!');
  105. return;
  106. }
  107. var pic_url = 'http://imgsrc.baidu.com/forum/pic/item/' + res.info.pic_id_encode + '.jpg';
  108. callback(pic_url, pid);
  109. };
  110. formData.append('fid', PageData.forum.id);
  111. formData.append('Filename', 'blob.png');
  112. formData.append('file', blob);
  113. xhr.send(formData);
  114. };
  115. xhr.onerror = function() {
  116. alert('上传准备失败!');
  117. };
  118. xhr.send();
  119. }
  120.  
  121. function dataURLtoBlob(dataURL) {
  122. var data = atob(dataURL.split(",")[1]),
  123. arrayBuffer = new ArrayBuffer(data.length),
  124. byteArray = new Uint8Array(arrayBuffer);
  125. for (var i = 0, l = data.length; i < l; ++i) {
  126. byteArray[i] = data.charCodeAt(i)
  127. }
  128. return new window.Blob([byteArray], {
  129. type: 'image/png'
  130. });
  131. }
  132.  
  133. function measureText(content, style, width) {
  134. var res = '',
  135. text = content,
  136. maxwidth = 0;
  137. var canvas = $('<canvas>').attr({
  138. width: width,
  139. height: 100
  140. }).get(0),
  141. ctx;
  142. ctx = canvas.getContext('2d');
  143. ctx.font = font;
  144. for (var i = 0, l = text.length, line = '', tl, th, thx = 0; i < l; ++i) {
  145. tl = line + text[i];
  146. th = thx + ctx.measureText(tl).width;
  147. if (th <= width) {
  148. thx = th;
  149. res += tl
  150. } else {
  151. thx = ctx.measureText(text[i]).width;
  152. res += '\n' + text[i];
  153. line = '';
  154. }
  155. if (maxwidth < thx) maxwidth = thx;//console.log(maxwidth,res);
  156. }
  157. var body = window.document.body,
  158. dummy = $('<div>').html(res.replace(/[\n\r]/g, '<br/>')).attr('style', style).get(0),
  159. result = {};
  160. dummy.style.zIndex = '-1';
  161. dummy.style.display = 'block';
  162. dummy.style.width = '-webkit-fit-content';
  163. dummy.style.whiteSpace = 'pre';
  164. body.appendChild(dummy);
  165. result.width = maxwidth; //dummy.offsetWidth;
  166. result.height = dummy.offsetHeight;
  167. result.content = res;
  168. dummy.remove();
  169. return result;
  170. }
  171.  
  172.  
  173. //////
  174. //// 引用按钮
  175. //
  176.  
  177. function addBtnsEvents() {
  178. //$('.l_post').on('mouseover.btqp', '.j_lzl_wrapper', function(e) {
  179. $('.p_postlist').delegate('.l_post','mouseover.btqp', '.j_lzl_wrapper', function(e) {
  180. var $self = $(e.currentTarget || this);
  181. if ($self.find('.btqp_btn_a').length <= 0) {
  182. var $partOne = $self.find('.p_tail');
  183. $partOne.append($('<li><span><a class="btqp_btn_a" btqp_n="false">简引</a> <a class="btqp_btn_a">引用</a></span></li>').find('a').css({
  184. cursor: 'pointer'
  185. }).on('click.btqp', btnEventA).end());
  186. }
  187. if ($self.find('.btqp_btn_b').length <= 0) {
  188. var $partTwo = $self.find('.lzl_s_r');
  189. $partTwo.before($('<span><a class="btqp_btn_b" btqp_n="false">简引</a> | <a class="btqp_btn_b">引用</a> | </span>').find('a').css({
  190. color: '#666',
  191. cursor: 'pointer'
  192. }).on('click.btqp', btnEventB).end());
  193. }
  194. });
  195. }
  196.  
  197. function btnEventA(e) {    
  198. e.stopPropagation();    
  199. e.preventDefault();
  200.  
  201.     
  202. var $self = $(e.currentTarget || this),
  203.       $post = $self.closest('.l_post'),
  204. toQuote = !$self.attr('btqp_n'),
  205.       content = $post.find('.d_post_content').html(),
  206.       info = JSON.parse($post.attr('data-field')),
  207. pid = info.content.id,
  208.       floor = info.content.post_no,
  209.       user = info.author.user_name,
  210.       toAuthor = (PageData.thread.author === user),
  211. toSelf = (PageData.user.name === user),
  212.       atUser = ((toAuthor || toSelf) ? '@\u202D' : '@') + user + '&nbsp;';    
  213. modify(floor, atUser, content, pid, toQuote);
  214.  
  215. return false;
  216. }
  217.  
  218. function btnEventB(e) {    
  219. e.stopPropagation();    
  220. e.preventDefault();
  221.  
  222.     
  223. var $self = $(e.currentTarget || this),
  224.    content = $self.closest('.lzl_content_reply').prevAll('.lzl_content_main').html(),
  225.       infoA = $.json.decode($self.closest('.l_post').attr('data-field')),
  226.       infoB = $.json.decode($self.closest('.lzl_single_post').attr('data-field')),
  227. toQuote = !$self.attr('btqp_n'),
  228.       floor = infoA.content.post_no,
  229. pid = infoB.spid,
  230.       userB = infoB.user_name,
  231.       toAuthor = (PageData.thread.author === userB),
  232. toSelf = (PageData.user.name === userB),
  233.       atUser = ((toAuthor || toSelf) ? '@\u202D' : '@') + userB + '&nbsp;';    console.log($self.closest('.l_post').attr('data-field'));
  234. modify(floor, atUser, content, pid, toQuote);
  235.  
  236. return false;
  237. }
  238.  
  239.   
  240.  
  241. function modify(floor, atUser, content, pid, toQuote) {
  242. $textarea = $('#tb_rich_poster_container').find('#ueditor_replace');
  243. textarea = $textarea.get(-1);    
  244. var html = textarea.innerHTML,
  245. quote = '';    
  246. var reg = new RegExp('^回\\d+楼.+?\\u202D{2}.*?\\u202D{2}|^回\\d+楼(?: |&nbsp;)@\u202D?.+?(?: |&nbsp;)', 'i');    
  247. textarea.scrollIntoViewIfNeeded();    
  248. textarea.focus();    
  249. content = content.replace(/^回(?:<a[^>]+>)?\d+楼(?:<\/a>)?.+?<br>/g, '').replace(/<br.*?>/gi, '').replace(/<img.*?>/gi, '[图片]').replace(/<embed.*?>/gi, '[影音]').replace(/<div class="video_src_wrapper.*?<\/a><\/span><\/div>/gi, '[视频]').replace(/<div class="voice_player.*?<\/div>/gi, '[语音]').replace(/\u202D{2}.*?\u202D{2}/, '').replace(/\u202D/g, '').replace(/&amp;/g, "&").replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&quot;/g, '"').replace(/ /g, ' ');
  250. content = flat(content);    
  251. if (content.length > 250) {      
  252. content = content.substr(0, 250) + '\n...[省略N字]';    
  253. }
  254. //content = setWidth(content, 520);
  255. if (toQuote) {    
  256. quote = '<br>\u202D\u202D<img pic_type="9" class="BDE_Image" src="http://imgsrc.baidu.com/forum/pic/item/32645c086e061d958b03f63f7af40ad163d9cad2.png">\u202D\u202D';
  257. }    
  258. if (html.replace(/<br>|&nbsp;|&emsp;|\s/g, '') !== '') {      
  259. if (reg.test(html)) {        
  260. html = html.replace(reg, '回' + floor + '楼 ' + atUser + quote);      
  261. } else {        
  262. html = '回' + floor + '楼 ' + atUser + quote + '<br><br>' + html;      
  263. }    
  264. } else {      
  265. html = '回' + floor + '楼 ' + atUser + quote + '<br><br>&nbsp;';    
  266. }    
  267. document.execCommand('selectAll', false, null);    
  268. document.execCommand('insertHTML', false, html);
  269. if (toQuote) {
  270. addQuote(textarea, content, pid);
  271. }  
  272. }
  273.  
  274. function flat(content) {
  275. content = content.replace(/<.+?>(.*?)<\/.+?>/gi, '$1');
  276. if (/<.+?>.*?<\/.+?>/.test(content)) {
  277. return flat(content);
  278. }
  279. return content.trim();
  280. }
  281.  
  282. function byteLength(c) {
  283. return /[\x00-\xFF]/.test(c) ? 0.5 : 1;
  284. }
  285.  
  286.  
  287. //////
  288. //// 初始化
  289. //
  290. var LetItGo = {
  291. set: function(key, val) {
  292. sessionStorage.setItem(key, JSON.stringify(val));
  293. },
  294. get: function(key, def) {
  295. return JSON.parse(sessionStorage.getItem(key)) || def;
  296. }
  297. };  
  298. var $textarea, textarea;
  299. $(function() {   //$textarea = $('#editor').find('.tb-editor-editarea');
  300.      //textarea = $textarea.get(-1);
  301. addBtnsEvents();
  302. });
  303. //////
  304. //// 生成节点监听
  305. //
  306. }
  307.  
  308.  
  309. //////
  310. //// Initialization
  311. //
  312. var script = document.createElement('script');
  313. script.id = '__5B4B_BTQP__';
  314. script.charset = 'utf-8';
  315. script.type = 'text/javascript';
  316. script.innerHTML = 'try{(' + init.toString() + ')()}catch(e){console.log(e)}';
  317. document.body.appendChild(script);

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址