// ==UserScript== // @name v2exBetterReply // @author dbw9580 // @namespace v2ex.com // @description better reply experience for v2ex // @include /^https?:\/\/(\w+\.)?v2ex\.com\/t\// // @version 2017-10-20 // @grant GM_log // @grant GM_addStyle // @run-at document-end // @require https://code.jquery.com/jquery-2.2.4.min.js // @supportURL https://github.com/dbw9580/v2exBetterReply/ // @downloadURL none // ==/UserScript== "use strict"; //=========================== // Configuration Section // // Set this to true to enable display of comments by blocked users. // This now only takes effect on comments referenced on the same page, // due to API restrictions, in multi-page threads, a comment referenced // on a different page that should be blocked, will still be displayed. // This may be fixed in future releases. var SHOW_BLOCKED_REF = false; // Set this to your preferred max width of the reference preview floating block. var REF_PREVIEW_WIDTH = "600px"; // End of Configuration Section //=========================== GM_addStyle(".v2exBR-reply-no-target{background-color: #AAAAAA; color: black !important; cursor: pointer; font-weight:bold;}"); GM_addStyle(".v2exBR-cited-comment-view{background-color: white; position: absolute; display: none; max-width: "+REF_PREVIEW_WIDTH+";}"); GM_addStyle(".v2exBR-reply-citation{color: #778087; cursor: pointer;} .v2exBR-reply-citation:hover{color: #4d5256; text-decoration: underline;}"); GM_addStyle(".v2exBR-cited-comment-view .fr{display: none;}"); /* insert preview block */ $(document.body).append($("
")); var API = {}; API.URL = {}; API.URL.topicReply = "https://www.v2ex.com/api/replies/show.json?topic_id="; API.getTopicReplies = function (topicId) { var url = API.URL.topicReply + topicId.toString(); var result; $.ajax({ type: "GET", url: url, dataType: "json", success: function (data) { result = data }, error: function () { return }, async: false, // important! to prevent browser caching results returned by api which is vollatile cache: false }); return result; }; API.getTopicReplyIdsInPostedOrder = function (repliesList) { var thisReply, i; var replyOrderIdMap = []; //assume that replies returned by API are already in the order of them being posted //simply walk through the array. for (i = 0; i < repliesList.length; i++){ replyOrderIdMap.push(repliesList[i].id); } return replyOrderIdMap; }; function markReplyTrueOrder(replyOrderIdMap, repliesDivList) { var lastReplyIndex = parseInt($(repliesDivList).find(".no").eq(0).text()) - 1; var thisReplyId; $(repliesDivList).each(function (index) { thisReplyId = this.id.match(/^r_(\d+)/)[1]; while (thisReplyId != replyOrderIdMap[lastReplyIndex].toString()) { if(lastReplyIndex < replyOrderIdMap.length){ lastReplyIndex++; } else{ return true; } } $(this).attr("v2exBR-true-order", 1 + lastReplyIndex++); }); } function adjustFloorNo(repliesDivList) { $(repliesDivList).each(function(){ var thisReplyTrueOrder = $(this).attr("v2exBR-true-order"); $(this).find(".no").text(thisReplyTrueOrder); }); } function inflatePreviewBlock(reply, previewDiv) { var cc = $(commentCells).eq(0).clone(); $(cc).find("img.avatar").attr("src", reply.member.avatar_normal); $(cc).find("strong>a.dark").attr("href", "/member/" + reply.member.username).text(reply.member.username); $(cc).find("strong+span.fade.small").remove(); $(cc).find("strong").after(" " + getRelativeTime(reply.last_modified) + " " + (reply.thanks != 0 ? `♥ ${reply.thanks}` : "") + ""); $(cc).find(".reply_content").html(reply.content_rendered); $(previewDiv).html($(cc).html()); return $(previewDiv); } function getRelativeTime(absTime) { var now = parseInt(Date.now() / 1000); var then = parseInt(absTime); var days = Math.floor((now - then) / (3600 * 24)); var hours = Math.floor((now - then) / 3600) - days * 24; var mins = Math.floor((now - then) / 60) - days * 24 * 60 - hours * 60; if (days > 0) { return days + " 天前"; } else if (hours > 0) { return hours + " 小时 " + mins + " 分钟前"; } else if (mins > 0) { return mins + " 分钟前"; } else { return "几秒前"; } } var numCurrentPage = Math.ceil(parseInt($(".no").eq(0).text()) / 100); var threadUrl = window.location.href.match(/^.+\/t\/\d+/)[0]; var commentCells = $("div.cell, div.inner").filter(function(){ return this.id.startsWith("r"); }); var topicId = window.location.href.match(/^.+\/t\/(\d+)/)[1]; var repliesList = API.getTopicReplies(topicId); var replyOrderIdMap = API.getTopicReplyIdsInPostedOrder(repliesList); var startId = parseInt(commentCells.eq(0).get(0).id.substring(2)); var endId = parseInt(commentCells.eq(-1).get(0).id.substring(2)); var startNo = replyOrderIdMap.indexOf(startId); var endNo = replyOrderIdMap.indexOf(endId); var hiddenReplyIds = []; for (var i = startNo + 1; i < endNo; i++){ var thisReplyId = replyOrderIdMap[i]; if ($("#r_" + thisReplyId).length == 0) { hiddenReplyIds.push(thisReplyId); } } /* parse reference */ commentCells.find("div.reply_content") .each(function(index){ var content = $(this).html(); var replacementSpan = "