V2EXcellent.js

A Better V2EX

目前为 2015-12-01 提交的版本。查看 最新版本

  1. // ==UserScript==
  2. // @name V2EXcellent.js
  3. // @namespace http://vitovan.github.io/v2excellent.js/
  4. // @version 0.1.0.8
  5. // @description A Better V2EX
  6. // @author VitoVan
  7. // @include http*://*v2ex.com/*
  8. // @grant none
  9. // ==/UserScript==
  10.  
  11. var I_AM_A_CHROME_EXT = false;
  12. var currentLocation = location.href;
  13. //If this is the thread page
  14. if(currentLocation.match(/\/t\/\d+/g)){
  15. //Enable Reply Directly Feature
  16. $('div.topic_buttons').append('<a " href="#;" onclick="$(\'#reply_content\').focus();" class="tb">回复</a>');
  17. //Enable Img Uploader Feature
  18. enableUploadImg();
  19. var comments = [];
  20. //loading
  21. showSpinner();
  22. //Get comments from current page
  23. fillComments($('body'));
  24. //Get other pages comments
  25. var PAGES_COUNT = $('div.inner>a[href^="/t/"].page_normal').length;
  26. var CURRENT_PAGE = 0;
  27. var DOMS = [$(document)];
  28. if(PAGES_COUNT>0){
  29. $('div.inner>a[href^="/t/"].page_normal').each(function(i,o){
  30. $.get(o.href,function(result){
  31. var resultDom = $('<output>').append($.parseHTML(result));
  32. DOMS.push(resultDom);
  33. fillComments(resultDom);
  34. CURRENT_PAGE ++;
  35. //if all comments are sucked.
  36. if(CURRENT_PAGE === PAGES_COUNT){
  37. //stack'em
  38. stackComments();
  39. //reArrange
  40. reArrangeComments();
  41. }
  42. });
  43. });
  44. }else{
  45. stackComments();
  46. //reArrange
  47. reArrangeComments();
  48. }
  49. }
  50.  
  51. function jumpToReply(){
  52. var floorSpecArr = currentLocation.match(/#reply\d+/g);
  53. var floorSpec = floorSpecArr && floorSpecArr.length ? floorSpecArr[0] : false;
  54. if(floorSpec){
  55. floorSpec = floorSpec.match(/\d+/g)[0];
  56. var specFloor = $('span.no').filter(function() {return $(this).text() === floorSpec;});
  57. $('body').scrollTop(specFloor.offset().top - $('body').offset().top);
  58. }
  59. }
  60.  
  61. //Remove #reply42 from index
  62. $('span.item_title>a').attr("href",function(i,val){return val.replace(/#reply\d+/g,'');});
  63.  
  64. function fillComments(jqDom){
  65. jqDom.find('div[id^="r_"]').each(function(i,o){
  66. var cmno = parseInt($(o).find('span.no').text());
  67. comments[cmno] =
  68. {
  69. id: $(o).attr('id'),
  70. no: cmno,
  71. user: $(o).find('strong>a').text(),
  72. content: $(o).find('div.reply_content').text(),
  73. mentioned: (function(){
  74. var mentionedNames = [];
  75. $(o).find('div.reply_content>a[href^="/member/"]:not("dark")').each(function(i,o){
  76. mentionedNames.push(o.innerHTML);
  77. });
  78. return mentionedNames;
  79. }()),
  80. subComments: []
  81. };
  82. });
  83. }
  84.  
  85. //Enable Floor Specification Feature
  86. $('a[href="#;"]:has(img[alt="Reply"])').click(function(e){
  87. var floorNo = $(e.currentTarget).parent().find('span.no').text();
  88. replyContent = $("#reply_content");
  89. oldContent = replyContent.val().replace(/^r#\d+ /g,'');
  90. prefix = "r#" + floorNo + " ";
  91. newContent = ''
  92. if(oldContent.length > 0){
  93. if (oldContent != prefix) {
  94. newContent = prefix + oldContent;
  95. }
  96. } else {
  97. newContent = prefix
  98. }
  99. replyContent.focus();
  100. replyContent.val(newContent);
  101. moveEnd($("#reply_content"));
  102. });
  103.  
  104. //Enable Gift ClickOnce Feature
  105. $('a[href="/mission/daily"]').attr('id','gift_v2excellent').attr('href','#').click(function(){
  106. $('#gift_v2excellent').text('正在领取......');
  107. $.get('/mission/daily',function(result){
  108. var giftLink = $('<output>').append($.parseHTML(result)).
  109. find('input[value^="领取"]').
  110. attr('onclick').match(/\/mission\/daily\/redeem\?once=\d+/g)[0];
  111. $.get(giftLink,function(checkResult){
  112. var okSign = $('<output>').append($.parseHTML(checkResult)).find('li.fa.fa-ok-sign');
  113. if(okSign.length>0){
  114. $.get('/balance',function(result){
  115. var amount = $('<output>').append($.parseHTML(result)).find('table>tbody>tr:contains("每日登录"):first>td:nth(2)').text();
  116. $('#gift_v2excellent').html('已领取 <strong>' + amount + '</strong> 铜币。' );
  117. setTimeout(function(){
  118. $('#Rightbar>.sep20:nth(1)').remove();
  119. $('#Rightbar>.box:nth(1)').remove();
  120. },2000);
  121. });
  122. }
  123. });
  124. });
  125. return false;
  126. });
  127.  
  128. //Get comment's parent
  129. function findParentComment(comment){
  130. var parent = undefined;
  131. if(comment){
  132. var floorRegex = comment.content.match(/^r#\d+ /g);
  133. if(floorRegex && floorRegex.length>0){
  134. var floorNo = parseInt(floorRegex[0].match(/\d+/g)[0]);
  135. parent = comments[floorNo];
  136. }else{
  137. for(var i=comment.no-1;i>0;i--){
  138. var cc = comments[i];
  139. if(cc){
  140. if($.inArray(cc.user, comment.mentioned) !== -1 && parent === undefined){
  141. parent = cc;
  142. }
  143. //If they have conversation, then make them together.
  144. if(comment.mentioned.length>0 && cc.user === comment.mentioned[0] && cc.mentioned[0] === comment.user){
  145. parent = cc;
  146. break;
  147. }
  148. }
  149. }
  150. }
  151. }
  152. return parent;
  153. }
  154.  
  155. //Stack comments, make it a tree
  156. function stackComments(){
  157. for(var i=comments.length-1;i>0;i--){
  158. var parent = findParentComment(comments[i]);
  159. if(parent){
  160. parent.subComments.unshift(comments[i]);
  161. comments.splice(i,1);
  162. }
  163. }
  164. }
  165.  
  166. function getCommentDom(id){
  167. var commentDom = undefined;
  168. $.each(DOMS,function(i,o){
  169. var result = o.find('div[id="' + id + '"]');
  170. if(result.length>0){
  171. commentDom = result;
  172. }
  173. });
  174. return commentDom;
  175. }
  176.  
  177. function moveComment(comment,parent){
  178. if(comment){
  179. var commentDom = getCommentDom(comment.id);
  180. $.each(comment.subComments,function(i,o){
  181. moveComment(o,commentDom);
  182. });
  183. commentDom.appendTo(parent);
  184. }
  185. }
  186.  
  187. function showSpinner(){
  188. var commentBox = $('#Main>div.box:nth(1)');
  189. $('body').append('<style>.spinner{width:40px;height:40px;position:relative;margin:100px auto}.double-bounce1,.double-bounce2{width:100%;height:100%;border-radius:50%;background-color:#333;opacity:.6;position:absolute;top:0;left:0;-webkit-animation:sk-bounce 2.0s infinite ease-in-out;animation:sk-bounce 2.0s infinite ease-in-out}.double-bounce2{-webkit-animation-delay:-1.0s;animation-delay:-1.0s}@-webkit-keyframes sk-bounce{0%,100%{-webkit-transform:scale(0.0)}50%{-webkit-transform:scale(1.0)}}@keyframes sk-bounce{0%,100%{transform:scale(0.0);-webkit-transform:scale(0.0)}50%{transform:scale(1.0);-webkit-transform:scale(1.0)}}</style>');
  190. $('<div class="spinner"><div class="double-bounce1"></div><div class="double-bounce2"></div></div>').insertBefore(commentBox);
  191. commentBox.hide();
  192. }
  193.  
  194. function reArrangeComments(){
  195. $('div.inner:has(a[href^="/t/"].page_normal)').remove();
  196. var commentBox = $('#Main>div.box:nth(1)');
  197. $.each(comments,function(i,o){
  198. moveComment(o,commentBox);
  199. });
  200. $('div[id^="r_"]>table>tbody>tr>td:first-child').attr('width','20');
  201. $('body').append('<style>.cell{border-bottom:none;}div[id^="r_"] img.avatar{width:20px;height:20px;border-radius:50%;}div[id^="r_"]>div{margin-left: 5px;}div.box>div[id^="r_"]{border-bottom: 1px solid #E2E2E2;}</style>');
  202. commentBox.show();
  203. //removeSpinner
  204. $('.spinner').remove();
  205. jumpToReply();
  206. }
  207.  
  208. function enableUploadImg(){
  209. if(I_AM_A_CHROME_EXT){
  210. }else{
  211. $('div.cell:contains("添加一条新回复")').append('<div class="fr"><a href="http://upload.otar.im/" target="_blank"> 上传图片</a> - </div>');
  212. }
  213. }