Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
[User script] StackExchange Election: Primary counter – Support on Stack Apps: http://stackapps.com/questions/4548
// ==UserScript==
// @id stackexchange-election-primary-counter@poke
// @name StackExchange Election: Primary counter
// @namespace poke
// @version 1.5.2
// @author Patrick Westerhoff
// @match *://*.stackoverflow.com/election*
// @match *://*.stackexchange.com/election*
// @match *://*.askubuntu.com/election*
// @match *://*.mathoverflow.net/election*
// @match *://*.serverfault.com/election*
// @match *://*.stackapps.com/election*
// @match *://*.superuser.com/election*
// @updateURL https://gist.githubusercontent.com/poke/9058895/raw/stackexchange-election-primary-counter.user.js
// @run-at document-end
// ==/UserScript==
(function () {
var primaryLink = document.querySelector('#tabs > a[href$="primary"]');
if (!primaryLink || !primaryLink.classList.contains('youarehere'))
return;
function addRow (table, cols, isHeader) {
var row = document.createElement('tr');
cols.forEach(function (cell) {
if (typeof cell !== 'object') {
cell = document.createTextNode(cell);
}
row.appendChild(document.createElement(isHeader ? 'th' : 'td')).appendChild(cell);
});
return table.appendChild(row);
}
// styles
var style = document.createElement('style');
style.textContent = '#_primary-counter { border: 1px solid silver; margin-bottom: 1em;}' +
'#_primary-counter th { border-bottom: 1px solid silver; }' +
'#_primary-counter td, #_primary-counter th { padding: 1px .5em; }' +
'#_primary-counter tr :nth-child(n+3) { text-align: right; }' +
'#_primary-counter tr:nth-child(11) { border-bottom: 1px solid silver; }' +
'#_primary-counter tr.withdrawn { color: #999; }';
document.head.appendChild(style);
// query candidate data
var users = Array.prototype.map.call(document.querySelectorAll('#mainbar .candidate-row'), function (post) {
var scores = post.querySelector('.candidate-score-breakdown');
return {
name: post.querySelector('.owner .user-info .user-details > a').textContent,
id: post.id.substr(5),
href: '#' + post.id,
votes: parseInt(post.querySelector('.votecell .js-vote-count').textContent, 10),
score: scores.querySelector('b').textContent.match(/(\d+\/\d+)/)[1],
rep: scores.querySelector('ul > li:nth-child(1)').textContent.trim().match(/reputation (.+)/)[1],
modBadges: scores.querySelector('ul > li:nth-child(2)').textContent.match(/moderation badges: (\d)\/\d/)[1],
editBadges: scores.querySelector('ul > li:nth-child(3)').textContent.match(/editing badges: (\d)\/\d/)[1],
participationBadges: scores.querySelector('ul > li:nth-child(4)').textContent.match(/participation badges: (\d)\/\d/)[1],
memberFor: post.querySelector('.user-details').lastChild.textContent.trim().match(/member for (.+)/)[1],
withdrawn: !!post.querySelector('.withdraw-date')
};
});
users.sort(function (a, b) { return b.votes - a.votes; });
// vote count querying
var mayQueryVoteCounts = document.body.innerHTML.includes('StackExchange.vote.election_init(true');
function queryVoteCounts (evt) {
evt.preventDefault();
var xhr = new XMLHttpRequest();
xhr.open('get', '/posts/' + this.id + '/vote-counts?_=' + (+new Date()), true);
xhr.onload = function () {
if (this.status == 200) {
var data = JSON.parse(this.response);
evt.target.parentNode.innerHTML = '+' + (+Math.abs(data.up)) + ' / ' + (-Math.abs(data.down));
}
};
xhr.send(null);
}
// display data
var table = document.createElement('table');
table.id = '_primary-counter';
addRow(table, ['#', 'User', 'Votes', 'Score', 'Reputation', 'Badges (M/E/P)', 'Member for'], true);
users.forEach(function (user, index) {
var link = document.createElement('a')
link.href = user.href;
link.appendChild(document.createTextNode(user.name));
var votes;
if (mayQueryVoteCounts) {
votes = document.createElement('a');
votes.addEventListener('click', queryVoteCounts.bind(user));
}
else {
votes = document.createElement('span');
}
votes.appendChild(document.createTextNode(user.votes));
var badges = [user.modBadges, user.editBadges, user.participationBadges].join(' / ');
var row = addRow(table, [index + 1, link, votes, user.score, user.rep, badges, user.memberFor]);
row.className = user.withdrawn ? 'withdrawn' : '';
});
document.querySelector('.question-status').appendChild(table);
})();
@mjpieters

This comment has been minimized.

Copy link

mjpieters commented Apr 13, 2015

New version, updated for the 2015 elections:

// ==UserScript==
// @id             stackexchange-election-primary-counter@poke
// @name           StackExchange Election: Primary counter
// @namespace      poke
// @version        1.2.0
// @author         Patrick Westerhoff
// @include        http://stackoverflow.com/election/*
// @include        http://stackoverflow.com/election
// @updateURL      https://gist.github.com/poke/9058895/raw/stackexchange-election-primary-counter.user.js
// @run-at         document-end
// ==/UserScript==
(function () {
    var primaryLink = document.querySelector('#tabs > a[href$="primary"]');
    if (!primaryLink || primaryLink.className != 'youarehere')
        return;

    function addRow (table, cols, isHeader) {
        var row = document.createElement('tr');
        cols.forEach(function (cell) {
            if (typeof cell !== 'object') {
                cell = document.createTextNode(cell);
            }
            row.appendChild(document.createElement(isHeader ? 'th' : 'td')).appendChild(cell);
        });
        return table.appendChild(row);
    }

    // styles
    var style = document.createElement('style');
    style.textContent = '#_primary-counter { border: 1px solid silver; margin-bottom: 1em;}' +
        '#_primary-counter th { border-bottom: 1px solid silver; }' +
        '#_primary-counter td, #_primary-counter th { padding: 1px .5em; }' +
        '#_primary-counter tr :nth-child(n+3) { text-align: right; }' +
        '#_primary-counter tr:nth-child(11) { border-bottom: 1px solid silver; }' +
        '#_primary-counter tr.withdrawn { color: #999; }';
    document.head.appendChild(style);

    // query candidate data
    var users = Array.prototype.map.call(document.querySelectorAll('#mainbar > table > tbody > tr'), function (post) {
        return {
            name: post.querySelector('td.owner .user-info .user-details > a').textContent,
            href: '#' + post.id,
            votes: parseInt(post.querySelector('.votecell .vote-count-post').textContent, 10),
            score: post.querySelector('.user-info .candidate-score-breakdown span').textContent.substr(16),
            withdrawn: !!post.querySelector('.withdraw-date')
        };
    });
    users.sort(function (a, b) { return b.votes - a.votes; });

    // display data
    var table = document.createElement('table');
    table.id = '_primary-counter';
    addRow(table, ['#', 'User', 'Votes', 'Candidate score'], true);
    users.forEach(function (user, index) {
        var link = document.createElement('a')
        link.href = user.href;
        link.appendChild(document.createTextNode(user.name));
        var row = addRow(table, [index + 1, link, user.votes, user.score]);
        row.className = user.withdrawn ? 'withdrawn' : '';
    });
    document.querySelector('.question-status').appendChild(table);
})();
@samliew

This comment has been minimized.

Copy link

samliew commented Mar 5, 2019

'.votecell .vote-count-post' needs to be changed to '.votecell .js-vote-count' for the new post layout on L45

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.