Take the 2-minute tour ×
Stack Apps is a question and answer site for apps, scripts, and development with the Stack Exchange API. It's 100% free, no registration required.

vote breakdown picture

Allows you to click the vote score and get the break-down just like with the established user privilege. This script does not use the data API but extracts votes from the timeline pages (which makes it a bit slow), thus it will likely break at the slightest change to that page.

The tooltip on the breakdown shows the total if summing up two numbers again is too hard.

(I have asked on meta if i can post this and did not get any official reply but demand by some people, also there appears to be a script with similar functionality).

Sorry to not provide a file for download but i am sure you will manage somehow, adjust includes as needed:

// ==UserScript==
// @name           StackOverflow Post Score Breakdown
// @namespace      stackoverflow
// @include        http://*stackoverflow.com/questions*
// @include        http://*.stackexchange.com/questions*
// @include        http://*stackapps.com/questions*
// @include        http://*superuser.com/questions*
// ==/UserScript==

(function ()
{
    var cancelWaiting = false;
    var dictionary = null;
    jq_wait();

    function jq_wait()
    {
        if (typeof unsafeWindow.jQuery == 'undefined')
        {
            window.setTimeout(jq_wait, 100);
        } else
        {
            $ = unsafeWindow.jQuery;
            window.setTimeout(function () { cancelWaiting = true; }, 5000);
            $(document).ready(setup);
        }
    }

    function loadVotes(/*function()*/onCompletedCallback)
    {
        var qId = document.location.href.match(/[0-9]+(?=\/)/)[0];
        if (qId != 'undefined')
        {
            var timelineUrl = "http://" + document.location.host + "/posts/" + qId + "/timeline";
            $.get(timelineUrl, function (data)
            {
                var tl = document.createElement("tl");
                tl.innerHTML = data;
                var summaries = $(tl).find(".vote-summary");
                dictionary = {};

                //For each day summary
                summaries.each(function (si, se)
                {
                    //Get the first blocks for questions and answers.
                    var cells = $(se).find(".qacell");
                    cells.each(function (ci, ce)
                    {
                        var call = $(ce).find("a")[0].getAttributeNode('onclick').value;
                        var postId = idFromCall(call);
                        if (dictionary[postId] == null)
                        {
                            var array = new Array();
                            array[0] = 0;
                            array[1] = 0;
                            dictionary[postId] = array;
                        }
                        array = dictionary[postId];

                        //Get next sibling which contains the votes
                        var eVoteCounter = $(ce).find(" ~ td")[0];

                        var upMatch = $(eVoteCounter).find(".upvote").html().match(/\+[0-9]+/);
                        if (upMatch != null)
                        {
                            array[0] += parseInt(upMatch[0]);
                        }
                        var downMatch = $(eVoteCounter).find(".downvote").html().match(/-[0-9]+/);
                        if (downMatch != null)
                        {
                            array[1] += parseInt(downMatch[0]);
                        }
                    });
                });
                onCompletedCallback();
            });
        }
    }

    function setup()
    {
        var writeBreakDownToSpan = function (qVoteSpan, id)
        {
            if (dictionary == null)
            {
                qVoteSpan.html("loading...");
                loadVotes(function () { writeBreakDownToSpan(qVoteSpan, id); });
            }
            else
            {
                var array = dictionary[id];
                if (array == null)
                {
                    var qParentAnswer = qVoteSpan.closest(".answer");
                    if (qParentAnswer.length > 0 && qParentAnswer.hasClass("deleted-answer")) return;
                    array = [0, 0];
                }
                var totalScore = array[0] + array[1];
                var up = array[0].toString();
                var down = array[1];
                if (up > 0) up = "+" + up;
                qVoteSpan.html("<div style=\"color: green;\">" + up + "</div><div class=\"vote-count-separator\"></div><div style=\"color: maroon;\">" + down + "</div>");
                qVoteSpan.attr("title", "Total score: " + totalScore);
            }
        }

        $(".vote").each(function (vi, ve)
        {
            var id = $(ve).find("input").attr("value");
            var qVoteSpan = $(ve).find(".vote-count-post");

            qVoteSpan.css("cursor", "pointer");
            qVoteSpan.click(function ()
            {
                writeBreakDownToSpan(qVoteSpan, id);
                qVoteSpan.css("cursor", "");
            });
        });
    }

    function idFromCall(/*string*/input)
    {
        return idFromRev(revFromCall(input));
    }

    function revFromCall(/*string*/input)
    {
        var match = input.match(/'[^']*'/)[0];
        match = match.substring(1, match.length - 1);
        return match;
    }

    function idFromRev(/*string*/input)
    {
        var match = input.match(/rev-[0-9]+(?=-)/)[0].replace(/rev-/, "");
        match = match.substring(0, match.length - 4);
        return match;
    }
})();
share|improve this question

You must log in to answer this question.

Browse other questions tagged .