zhihu-reply-tip

显示被引用的用户的最近一条评论

Voor het installeren van scripts heb je een extensie nodig, zoals Tampermonkey, Greasemonkey of Violentmonkey.

Voor het installeren van scripts heb je een extensie nodig, zoals {tampermonkey_link:Tampermonkey}.

Voor het installeren van scripts heb je een extensie nodig, zoals Tampermonkey of Violentmonkey.

Voor het installeren van scripts heb je een extensie nodig, zoals Tampermonkey of Userscripts.

Voor het installeren van scripts heb je een extensie nodig, zoals {tampermonkey_link:Tampermonkey}.

Voor het installeren van scripts heb je een gebruikersscriptbeheerder nodig.

(Ik heb al een user script manager, laat me het downloaden!)

Voor het installeren van gebruikersstijlen heb je een extensie nodig, zoals {stylus_link:Stylus}.

Voor het installeren van gebruikersstijlen heb je een extensie nodig, zoals {stylus_link:Stylus}.

Voor het installeren van gebruikersstijlen heb je een extensie nodig, zoals {stylus_link:Stylus}.

Voor het installeren van gebruikersstijlen heb je een gebruikersstijlbeheerder nodig.

Voor het installeren van gebruikersstijlen heb je een gebruikersstijlbeheerder nodig.

Voor het installeren van gebruikersstijlen heb je een gebruikersstijlbeheerder nodig.

(Ik heb al een beheerder - laat me doorgaan met de installatie!)

// ==UserScript==
// @name       zhihu-reply-tip
// @namespace  https://github.com/QingYun/
// @version    0.1
// @description  显示被引用的用户的最近一条评论
 // @match      http://www.zhihu.com/*
// @copyright  2012+, QingYun
// ==/UserScript==

var HIDE_STYLE = "display: none";

function hasClass(node, className) {
	return node && node.classList && node.classList.contains(className);
}

function createReplyTipNode() {
    var a = document.createElement("a");
    a.setAttribute("href", "#");
    a.setAttribute("class", "like zm-comment-op-link");
    
    var i = document.createElement("i");
    i.setAttribute("class", "zg-icon zg-icon-comment-reply");
    
    a.appendChild(i);
    a.appendChild(document.createTextNode("查看 TA 的最近一条评论"));
    
    return a;
}

function createQuoteBlockNode(content) {
	var bq = document.createElement("blockquote");
    bq.setAttribute("style", HIDE_STYLE);
    
    var p = document.createElement("p");
    p.appendChild(document.createTextNode(content));
    
    bq.appendChild(p);
    
    return bq;
}

function latestReply(commentItems, userLookingFor, endIndex) {
    for (var i = endIndex - 1; i >= 0 ; i--) {
        var curUser = commentItems[i].querySelector(".zg-link").textContent;
        if (curUser ==  userLookingFor) {
            return commentItems[i].querySelector(".zm-comment-content").textContent;
        }
    }
}

function addOneReplyTip(commentItems, targetIndex) {
    var curItem = commentItems[targetIndex];
    if (curItem.querySelector(".zm-comment-hd .like") !== null) 
        return ;
    
    var headNode = curItem.querySelector(".zm-comment-hd");
    if (headNode.childNodes.length > 3) {
        var referredUser;
        if (headNode.firstChild.nodeValue == "\n 匿名用户")
            referredUser = headNode.querySelectorAll(".zg-link")[0];
        else
            referredUser = headNode.querySelectorAll(".zg-link")[1];
        
        if (referredUser) {
            var referredReply = latestReply(commentItems, referredUser.textContent, targetIndex);
            if (!referredReply)
                return ;
            
            var q = null;
            var replyTip = createReplyTipNode();
            replyTip.addEventListener("click", function() {
                if (q === null) {
                    q = createQuoteBlockNode(referredReply);
                    var content = curItem.querySelector(".zm-comment-content");
                    content.parentNode.insertBefore(q, content);
                }
                
                if (q.getAttribute("style") == HIDE_STYLE)
                    q.removeAttribute("style");
                else
                    q.setAttribute("style", HIDE_STYLE);
            });
            
            curItem.querySelector(".zm-comment-hd").appendChild(replyTip);
        }
    }
}

function addReplyTips(commentList) {
    var commentItems = commentList.querySelectorAll(".zm-item-comment");
    for (var i = 0; i < commentItems.length; i++) {
        addOneReplyTip(commentItems, i);
    }
}

(function(){
    var addReplyTipTimer;
    var observer = new MutationObserver(function(mutations) {
        mutations.forEach(function(mutation) {
            if (mutation.type == "childList") {
                var firstAddedNode = mutation.addedNodes.length && mutation.addedNodes[0];
                var firstRemovedNode = mutation.removedNodes.length && mutation.removedNodes[0];
                
                if (hasClass(firstAddedNode, "zm-comment-box") && hasClass(firstRemovedNode, "zm-comment-box"))
                    addReplyTips(mutation.addedNodes[0].querySelector(".zm-comment-list"));
                else if (hasClass(firstAddedNode, "zm-item-comment")) {
                	if (addReplyTipTimer) clearTimeout(addReplyTipTimer);
                    addReplyTipTimer = setTimeout(function() {
                    	addReplyTips(mutation.target);
                    }, 100);
                }
            }
        });
    });
    
    observer.observe(document.body, {
        childList: true
        , subtree: true
        , attributes: false
        , characterData: false
    });
})();