v2exBetterReply

better reply experience for v2ex

当前为 2016-08-27 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name v2exBetterReply
  3. // @author dbw9580
  4. // @namespace v2ex.com
  5. // @description better reply experience for v2ex
  6. // @include /^https?:\/\/(\w+\.)?v2ex\.com\/t\//
  7. // @version 2016-08-27
  8. // @grant GM_log
  9. // @grant GM_addStyle
  10. // @run-at document-end
  11. // @require https://code.jquery.com/jquery-2.2.4.min.js
  12. // ==/UserScript==
  13.  
  14. GM_addStyle(".v2exBR-reply-no-target{background-color: #AAAAAA; color: black !important; cursor: pointer; font-weight:bold;}");
  15. GM_addStyle(".v2exBR-cited-comment-view{background-color: white; position: absolute; display: none; max-width: 500px;}");
  16. GM_addStyle(".v2exBR-reply-citation{color: #778087; cursor: pointer;} .v2exBR-reply-citation:hover{color: #4d5256; text-decoration: underline;}");
  17. GM_addStyle(".v2exBR-cited-comment-view .fr{display: none;}");
  18.  
  19. $(document.body).append($("<div class=\"v2exBR-cited-comment-view cell\" id=\"v2exBR_citation_div\"></div>"));
  20.  
  21. $(".no").hover(function(){
  22. $(this).addClass("v2exBR-reply-no-target");
  23. }, function(){
  24. $(this).removeClass("v2exBR-reply-no-target");
  25. }).click(function(){
  26. var username = $(this).parent().next().next().children("a").text();
  27. var commentNo = $(this).text();
  28. makeCitedReply(username, commentNo);
  29. });
  30.  
  31.  
  32.  
  33. var numCurrentPage = Math.ceil(parseInt($(".no").eq(0).text()) / 100);
  34. var citedPages = {};
  35. var commentCells = $("div.cell").filter(function(){
  36. return this.id.startsWith("r");
  37. });
  38. var citedPagesNos = [];
  39. var threadUrl = window.location.href.match(/^.+\/t\/\d+/)[0];
  40.  
  41. commentCells.find("div.reply_content")
  42. .each(function(index){
  43. var content = $(this).html();
  44. var replacementSpan = "<span class=\"v2exBR-reply-citation\" v2exBR-commentCellId=\"null\" v2exBR-citedPage=\"0\">";
  45. content = content.replace(/&gt;&gt;\d+(?=\s|<br)/g, replacementSpan + "$&" + "</span>");
  46. $(this).html(content);
  47. $("span.v2exBR-reply-citation", this).each(function(){
  48. var replyNo = parseInt($(this).text().match(/>>(\d+)/)[1]);
  49. var numCitedPage = Math.ceil(replyNo / 100);
  50. if(citedPagesNos.indexOf(numCitedPage) < 0){
  51. citedPagesNos.push(numCitedPage);
  52. }
  53. });
  54. });
  55.  
  56. for(var i = 0; i < citedPagesNos.length; i++){
  57. var thisPageNo = citedPagesNos[i];
  58. if(thisPageNo == numCurrentPage) continue;
  59. (function(thisPageNo){
  60. $.get(threadUrl + "?p=" + thisPageNo, function(data, status){
  61. var resultPageRoot = $(data);
  62.  
  63. if(resultPageRoot.find("a.page_current").attr("href").match("\\?p=" + thisPageNo) === null){
  64. return;
  65. }
  66. citedPages[thisPageNo] = resultPageRoot;
  67. bindCitationElements(thisPageNo);
  68. });
  69. })(thisPageNo);
  70.  
  71. }
  72.  
  73. bindCitationElements(numCurrentPage);
  74.  
  75. $(".v2exBR-reply-citation").hover(function(){
  76. var self = this;
  77. var commentCellId = $(self).attr("v2exBR-commentCellId");
  78. var numCitedPage = parseInt($(self).attr("v2exBR-citedPage"));
  79.  
  80. if(commentCellId === "null") return;
  81.  
  82. if(citedPages[numCitedPage] === undefined){
  83. var citedPageRoot = window.document;
  84. }
  85. else{
  86. var citedPageRoot = citedPages[numCitedPage];
  87. }
  88.  
  89. var citationHTML = $("#"+commentCellId, citedPageRoot).html();
  90. var divPosTopOffset = window.getComputedStyle(self).getPropertyValue("font-size").match(/(\d+)px/)[1];
  91. $("#v2exBR_citation_div").html(citationHTML)
  92. .css({
  93. top:$(self).offset().top,
  94. left:$(self).offset().left + $(self).width()
  95. })
  96. .fadeIn(100);
  97. }, function(){
  98. $("#v2exBR_citation_div").fadeOut(100);
  99. });
  100.  
  101.  
  102. $(".v2exBR-reply-citation").click(function(){
  103. var commentCellId = $(this).attr("v2exBR-commentCellId");
  104. var numCitedPage = parseInt($(this).attr("v2exBR-citedPage"));
  105. if(commentCellId == "null") return;
  106.  
  107. if(numCitedPage == numCurrentPage){
  108. $("html, body").animate({
  109. scrollTop: $("#" + commentCellId).offset().top
  110. }, 500);
  111. }
  112. else{
  113. window.location.href = threadUrl + "?p=" + numCitedPage + "&v2exBR_commentCellId=" + commentCellId;
  114. }
  115. });
  116.  
  117. (function(){
  118. var commentCellId = window.location.href.match(/v2exBR_commentCellId=(r_\d+)/);
  119. if(commentCellId != null){
  120. commentCellId = commentCellId[1];
  121. $("html, body").animate({
  122. scrollTop: $("#" + commentCellId).offset().top
  123. }, 500);
  124. }
  125. })();
  126.  
  127. function bindCitationElements(numPageLoaded){
  128. $("span.v2exBR-reply-citation").each(function(){
  129. var self = this;
  130. var replyNo = parseInt($(this).text().match(/>>(\d+)/)[1]);
  131. var citedCommentCellId = "";
  132. var numCitedPage = Math.ceil(replyNo / 100);
  133. var isMultiPage = ($("a.page_current").length > 0);
  134. if(numCitedPage != numPageLoaded) return true;
  135.  
  136. if(numCitedPage != numCurrentPage){
  137. if(!isMultiPage){ //cited a non-existent comment ID
  138. return true;
  139. }
  140.  
  141. if(citedPages[numCitedPage] != undefined){
  142. citedCommentCellId = getCommentCellIdFromReplyNo(citedPages[numCitedPage], replyNo);
  143. registerCitation(self, citedCommentCellId, numCitedPage);
  144. }
  145. }
  146. else if((replyNo - 1) % 100 <= commentCells.length){ //cited comment is on the same page, retrieve info directly from this page
  147. citedCommentCellId = commentCells.get((replyNo - 1) % 100).id;
  148. registerCitation(self, citedCommentCellId, numCitedPage);
  149. }
  150. });
  151. }
  152.  
  153.  
  154. function getCommentCellIdFromReplyNo(documentRoot, replyNo){
  155. return documentRoot.find(".no").filter(function(){
  156. return parseInt($(this).text()) == replyNo;
  157. }).parents("div.cell").get(0).id;
  158. }
  159.  
  160. function registerCitation(elem, id, numPage){
  161. $(elem).attr("v2exBR-commentCellId", id);
  162. $(elem).attr("v2exBR-citedPage", numPage);
  163. }
  164.  
  165. function makeCitedReply(username, commentNo){
  166. replyContent = $("#reply_content");
  167. oldContent = replyContent.val();
  168.  
  169. userTag = "@" + username + " ";
  170. commentTag = ">>" + commentNo + " \n";
  171.  
  172. newContent = commentTag + userTag;
  173. if(oldContent.length > 0){
  174. if (oldContent != commentTag + userTag) {
  175. newContent = oldContent + "\n" + commentTag + userTag;
  176. }
  177. } else {
  178. newContent = commentTag + userTag;
  179. }
  180.  
  181. replyContent.focus();
  182. replyContent.val(newContent);
  183. moveEnd($("#reply_content"));
  184. }
  185.  
  186.