// Generated by CoffeeScript 1.7.1
/*
NOMINATIONS VIEWER
Description: Compact nominations for [[WP:FAC]], [[WP:FAR]], [[WP:FLC]], [[WP:FLRC]], [[WP:FPC]], and [[WP:PR]].
Documentation: [[Wikipedia:Nominations Viewer]]
*/
/*
Begin settings
DEFAULTS:
NominationsViewer =
{
'enabledPages': ['Wikipedia:Featured article candidates', ...],
'nominationData': ['images', 'age', 'nominators', 'participants', 'votes'],
}
*/
var NominationsViewer, NominationsViewerClass, collapseTable;
if (typeof NominationsViewer === "undefined" || NominationsViewer === null) {
NominationsViewer = {};
}
if (NominationsViewer.enabledPages == null) {
NominationsViewer.enabledPages = {
'User:Gary/Sandbox': 'nominations',
'Wikipedia:Featured article candidates': 'nominations',
'Wikipedia:Featured article review': 'reviews',
'Wikipedia:Featured list candidates': 'nominations',
'Wikipedia:Featured list removal candidates': 'reviews',
'Wikipedia:Featured picture candidates': 'pictures',
'Wikipedia:Peer review': 'peer reviews'
};
}
if (NominationsViewer.nominationData == null) {
NominationsViewer.nominationData = ['images', 'age', 'nominators', 'participants', 'votes'];
}
/*
End settings
*/
collapseTable = function(event) {
var $button, $rows, $table, collapseCaption, expandCaption, tableIndex;
console.log('collapseTable was activated');
event.preventDefault();
tableIndex = event.data.index;
collapseCaption = 'hide';
expandCaption = 'show';
console.log('tableIndex: ' + tableIndex);
$button = $('#collapseButton' + tableIndex);
$table = $('#collapsibleTable' + tableIndex);
if (!($table.length && $button.length)) {
return false;
}
$rows = $table.find('> tbody > tr');
console.log('Button: ' + $button.length + ' and Table: ' + $table.length);
console.log($button);
console.log('Button text: ' + $button.text());
console.log($button.parent().html());
if ($button.text() === collapseCaption) {
$rows.each(function(index) {
if (index === 0) {
return true;
}
return $(this).hide();
});
$button.text(expandCaption);
} else {
$rows.each(function(index) {
if (index === 0) {
return true;
}
return $(this).show();
});
$button.text(collapseCaption);
}
return console.log('The end');
};
NominationsViewerClass = (function() {
function NominationsViewerClass() {}
/*
BODY
*/
NominationsViewerClass.addNominationData = function(pageName, $parentNode, ids) {
var $span, id, _i, _len, _results;
_results = [];
for (_i = 0, _len = ids.length; _i < _len; _i++) {
id = ids[_i];
$span = $('<span id="' + id + '-' + pageName + '"></span>');
_results.push($parentNode.children().last().before($span));
}
return _results;
};
NominationsViewerClass.addOverallNominationInformation = function($h3s) {
var $expandCollapseLink, $info;
$expandCollapseLink = $('<a href="javascript:void(0)" id="expand-collapse-all">expand all</a>').on('click', {
allH3Length: $h3s.length
}, this.toggleAllNoms);
$info = $('<span class="overall-controls"></span>').append(' (').append($expandCollapseLink).append(')');
return $h3s.first().next().prevUntil('h2').last().prev().append($info);
};
NominationsViewerClass.appendAllNominationData = function(pageName) {
var appendNominationData;
appendNominationData = function(callback, parameters) {
return importScriptURI(mw.config.get('wgServer') + mw.config.get('wgScriptPath') + '/api.php?callback=' + callback + '&format=json&' + parameters);
};
pageName = encodeURIComponent(pageName);
appendNominationData('NominationsViewerClass.allRevisionsCallback', 'action=query&prop=revisions&rvdir=newer&rvlimit=500&titles=' + pageName);
appendNominationData('NominationsViewerClass.currentRevisionCallback', 'action=query&prop=revisions&rvdir=older&rvlimit=1&rvprop=content&titles=' + pageName);
return appendNominationData('NominationsViewerClass.firstRevisionCallback', 'action=query&prop=revisions&rvdir=newer&rvlimit=1&titles=' + pageName);
};
NominationsViewerClass.appendGeneratedNominationData = function(pageName, data, id, abbrTitle, isFirstData) {
var $abbr, $id, $newChild, character, escapedCharacters, invalidCssCharacters, _i, _len;
if (!data) {
return false;
}
invalidCssCharacters = '~!@$%^&*()_+-=,./\';:"?><[]\{}|`#';
escapedCharacters = '';
for (_i = 0, _len = invalidCssCharacters.length; _i < _len; _i++) {
character = invalidCssCharacters[_i];
escapedCharacters += '\\' + character;
}
$id = $('#' + id + '-' + pageName.replace(RegExp('([' + escapedCharacters + '])', 'g'), '\\$1'));
$newChild = $('<span></span>');
if (!isFirstData) {
$newChild.append(' · ');
}
$abbr = $('<abbr title="' + abbrTitle + '">' + data + '</abbr>');
$newChild.append($abbr);
return $id.append($newChild);
};
NominationsViewerClass.createData = function(pageName) {
var $newSpan, $viewLink, matchArchiveNumber, matchArchiveNumberPrint, number, ordinalSuffix;
$newSpan = $('<span class="nomination-data"></span>').append('<tt>(</tt>');
matchArchiveNumber = pageName.match(/([0-9]+)$/);
matchArchiveNumberPrint = matchArchiveNumber && matchArchiveNumber[1] > 1 ? (number = parseInt(matchArchiveNumber[1]), ordinalSuffix = (function() {
switch (number) {
case 2:
return 'nd';
case 3:
return 'rd';
default:
return 'th';
}
})(), ': ' + number + ordinalSuffix) : '';
$viewLink = $('<span><a href="/https/en.m.wikipedia.org/wiki/' + pageName + '">nomination</a>' + matchArchiveNumberPrint + '</span>');
return $newSpan.append($viewLink).append('<tt>)</tt>');
};
NominationsViewerClass.createNewNode = function(oldNode, showHideLink, newSpan, index) {
var $heading, $newNode;
$newNode = $('<div id="nom-title-' + index + '"></div>').append(oldNode.clone(true));
$heading = $newNode.children().first();
$heading.prepend('<span class="nomination-order">' + (index + 1) + '.</span> ').append(' ').append(showHideLink).append(newSpan);
return $newNode;
};
NominationsViewerClass.createNomArticleName = function(pageName) {
var nomArticleName;
nomArticleName = pageName.replace(/_/g, ' ').split('/');
return nomArticleName = nomArticleName[nomArticleName.length - 2];
};
NominationsViewerClass.createNomination = function(_arg) {
var $h3, NominationsViewer, editLink, index, newNode, newSpan, nomArticleName, nomDiv, pageName, showHideLink;
$h3 = _arg.$h3, index = _arg.index, NominationsViewer = _arg.NominationsViewer;
editLink = $h3.find('.mw-editsection-bracket').next('a');
if (!editLink.length) {
return true;
}
pageName = editLink.attr('title').replace(/\ /g, '_');
nomArticleName = this.createNomArticleName(pageName);
showHideLink = this.createShowHideLink(index);
newSpan = this.createData(pageName);
this.hideNomination($h3, index);
this.addNominationData(pageName, newSpan, NominationsViewer.nominationData);
newNode = this.createNewNode($h3, showHideLink, newSpan, index);
nomDiv = this.generateNomination(index, newNode, $h3);
$h3.replaceWith(nomDiv);
return this.appendAllNominationData(pageName);
};
NominationsViewerClass.createShowHideLink = function(index) {
return $('<span class="plus-minus-button">[<a href="javascript:void(0)" id="nom-button-' + index + '">show</a>]</span>').on('click', {
index: index
}, this.toggleNomClick);
};
NominationsViewerClass.generateNomination = function(index, newNode, oldNode) {
return $('<div class="nomination" id="nom-' + index + '"></div>').append(newNode.clone(true)).append($(oldNode[0].nextSibling).clone(true));
};
NominationsViewerClass.hideNomination = function($h3, index) {
var hiddenNode, nomNextSibling, nomNextSiblingTemp;
hiddenNode = document.createElement('div');
hiddenNode.className = 'nomination-body';
hiddenNode.id = 'nom-data-' + index;
hiddenNode.style.display = 'none';
nomNextSibling = $h3[0].nextSibling;
while (nomNextSibling !== null && ['H2', 'H3'].indexOf(nomNextSibling.nodeName) === -1 && !(nomNextSibling.classList && nomNextSibling.classList.contains('printfooter'))) {
nomNextSiblingTemp = nomNextSibling.nextSibling;
if (nomNextSibling.nodeType !== 3) {
hiddenNode.appendChild(nomNextSibling);
}
nomNextSibling = nomNextSiblingTemp;
}
return $h3.after(hiddenNode);
};
NominationsViewerClass.init = function() {
var $h3s, $parentNode, currentPageIsASubpage, currentPageIsEnabled, page, type, _ref;
_ref = NominationsViewer.enabledPages;
for (page in _ref) {
type = _ref[page];
if (mw.config.get('wgPageName') === page.replace(/\ /g, '_')) {
currentPageIsEnabled = true;
break;
} else if (mw.config.get('wgPageName').indexOf(page.replace(/\ /g, '_')) === 0) {
currentPageIsASubpage = true;
break;
}
}
if (!((currentPageIsEnabled != null) && mw.config.get('wgAction') === 'view' && window.location.href.indexOf('&oldid=') === -1 && (currentPageIsASubpage == null))) {
return false;
}
this.nominationsViewerCss();
$parentNode = $('.mw-content-ltr');
$h3s = $parentNode.find('h3');
this.addOverallNominationInformation($h3s);
$h3s.each((function(_this) {
return function(index, element) {
return _this.createNomination({
$h3: $(element),
index: index,
NominationsViewer: NominationsViewer
});
};
})(this));
return $('.collapseButton').each(function(index) {
var $link;
$link = $(this).children().first();
index = $link.attr('id').substring($link.attr('id').indexOf('collapseButton') + 'collapseButton'.length, $link.attr('id').length);
return $link.attr('href', 'javascript:void(0)').on('click', {
index: index
}, collapseTable);
});
};
/*
HELPERS
*/
NominationsViewerClass.nominationsViewerCss = function() {
return mw.util.addCSS('html { overflow-y: scroll; } #content .nomination h3 { margin-bottom: 0; padding-top: 0; } .nomination-data, .nomination-order, .overall-controls { font-size: 75%; font-weight: normal; } .nomination-order { display: inline-block; width: 25px; } .plus-minus-button { font-size: 13px; font-weight: normal; display: inline-block; width: 40px; }');
};
NominationsViewerClass.toggleAllNoms = function(event) {
var $firstChild, action, allH3Length, index, _i, _results;
event.preventDefault();
allH3Length = event.data.allH3Length;
$firstChild = $('#expand-collapse-all');
if ($firstChild.text() === 'expand all') {
$firstChild.text('collapse all');
action = 'expand';
} else if ($firstChild.text() === 'collapse all') {
$firstChild.text('expand all');
action = 'collapse';
}
_results = [];
for (index = _i = 0; 0 <= allH3Length ? _i < allH3Length : _i > allH3Length; index = 0 <= allH3Length ? ++_i : --_i) {
_results.push(NominationsViewerClass.toggleNom(index, action));
}
return _results;
};
NominationsViewerClass.toggleNom = function(id, action) {
var $node, $nomButton, toggleHideNom, toggleShowNom;
if (action == null) {
action = '';
}
toggleHideNom = function($node, $nomButton) {
$node.hide();
return $nomButton.text('show');
};
toggleShowNom = function($node, $nomButton) {
$node.show();
return $nomButton.text('hide');
};
$node = $('#nom-data-' + id);
$nomButton = $('#nom-button-' + id);
if (action === 'collapse') {
return toggleHideNom($node, $nomButton);
} else if (action === 'expand') {
return toggleShowNom($node, $nomButton);
} else if ($node.is(':visible')) {
return toggleHideNom($node, $nomButton);
} else if ($node.is(':hidden')) {
return toggleShowNom($node, $nomButton);
}
};
NominationsViewerClass.toggleNomClick = function(event) {
var index;
event.preventDefault();
index = event.data.index;
return NominationsViewerClass.toggleNom(index);
};
/*
CALLBACKS
*/
NominationsViewerClass.allRevisionsCallback = function(obj) {
var count, moreThan, revision, user, userCount, users, usersArray, usersArray2, vars, _i, _j, _len, _len1, _ref;
vars = this.formatJSON(obj);
if (!vars) {
return;
}
if (this.dataIsEnabled('participants') && vars['revisions']) {
users = {};
userCount = 0;
_ref = vars['revisions'];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
revision = _ref[_i];
if (!revision['user']) {
continue;
}
if (users[revision['user']]) {
users[revision['user']]++;
} else {
users[revision['user']] = 1;
userCount++;
}
}
if (obj['query-continue']) {
moreThan = 'more than ';
} else {
moreThan = '';
}
usersArray = [];
for (user in users) {
count = users[user];
usersArray.push([user, parseInt(count)]);
}
usersArray.sort(function(a, b) {
if (a[1] < b[1]) {
return 1;
} else if (a[1] > b[1]) {
return -1;
} else {
return 0;
}
});
usersArray2 = [];
for (_j = 0, _len1 = usersArray.length; _j < _len1; _j++) {
user = usersArray[_j];
usersArray2.push(user[0] + ': ' + user[1]);
}
return this.appendGeneratedNominationData(vars['pageName'], moreThan + userCount + ' ' + this.pluralize('participant', userCount), 'participants', 'Sorted from most to least edits Total edits: ' + vars['revisions'].length + ' Format: "editor: number of edits": ' + usersArray2.join(' '));
}
};
NominationsViewerClass.currentRevisionCallback = function(obj) {
var allNominators, basicPatternClose, basicPatternOpen, content, dataText, filename, images, listOfNominators, match, matches, matches1, matches2, n, nomTypeText, opposeMatches, opposePattern, opposeText, opposes, pattern1, pattern2, showOpposesForNominations, showOpposesForReviews, showSupportsAndOpposes, split, supportMatches, supportPattern, supportText, supports, toolTip, vars, voteBuffer, _i, _len, _ref, _ref1;
vars = this.formatJSON(obj);
if (!vars) {
return;
}
if (vars['firstRevision']) {
content = vars['firstRevision']['*'];
} else {
return false;
}
if (this.nomType('pictures') && this.dataIsEnabled('images')) {
pattern1 = /\[\[(File|Image):.*?\]\]/gi;
pattern2 = /\n(File|Image):.*\|/gi;
matches1 = content.match(pattern1);
matches2 = content.match(pattern2);
if (matches1) {
matches = matches1;
} else if (matches2) {
matches = matches2;
} else {
matches = [];
}
images = [];
for (_i = 0, _len = matches.length; _i < _len; _i++) {
match = matches[_i];
split = match.split('|');
filename = $.trim(split[0].replace(/^\[\[/, ''));
images.push(filename);
}
this.appendGeneratedNominationData(vars['pageName'], matches.length + ' ' + this.pluralize('image', matches.length), 'images', 'Images (in order of appearance): ' + images.join(' '));
}
if (this.dataIsEnabled('nominators') && !this.nomType('peer reviews')) {
nomTypeText = '';
listOfNominators = {};
switch (this.nomType()) {
case 'nominations':
nomTypeText = 'nominator';
listOfNominators = this.findNominators(content, /Nominator(\(s\))?:.*/);
if ($.isEmptyObject(listOfNominators)) {
listOfNominators = this.findNominators(content, /:<small>''.*/);
}
break;
case 'reviews':
nomTypeText = 'notification';
listOfNominators = this.findNominators(content, /(Notified|Notifying):.*/);
break;
case 'pictures':
nomTypeText = 'nominator';
listOfNominators = this.findNominators(content, /\* '''Support as nominator''' – .*/);
}
allNominators = [];
for (n in listOfNominators) {
allNominators.push(n);
}
allNominators.sort();
this.appendGeneratedNominationData(vars['pageName'], (allNominators.length > 0 ? allNominators.length + ' ' + this.pluralize(nomTypeText, allNominators.length) : '? ' + this.pluralize(nomTypeText, 0)), 'nominators', this.pluralize(this.capitalize(nomTypeText), allNominators.length) + ' (sorted alphabetically): ' + allNominators.join(' '));
}
if (this.dataIsEnabled('votes') && !this.nomType('peer reviews')) {
showOpposesForNominations = false;
showOpposesForReviews = true;
showSupportsAndOpposes = false;
voteBuffer = 25;
basicPatternOpen = "'''(.{0," + voteBuffer + "})?";
basicPatternClose = "(.{0," + voteBuffer + "})?'''";
if (this.nomType('nominations')) {
supportText = 'support';
opposeText = 'oppose';
supportPattern = new RegExp(basicPatternOpen + 'support' + basicPatternClose, 'gi');
opposePattern = new RegExp(basicPatternOpen + 'oppose' + basicPatternClose, 'gi');
} else if (this.nomType('reviews')) {
supportText = 'keep';
opposeText = 'delist';
supportPattern = new RegExp(basicPatternOpen + 'keep' + basicPatternClose, 'gi');
opposePattern = new RegExp(basicPatternOpen + 'delist' + basicPatternClose, 'gi');
} else if (this.nomType('pictures')) {
supportText = 'support';
opposeText = 'oppose';
basicPatternOpen = "\\*(\\s)?'''.*?";
basicPatternClose = ".*?'''";
supportPattern = new RegExp(basicPatternOpen + 'Support' + basicPatternClose, 'gi');
opposePattern = new RegExp(basicPatternOpen + 'Oppose' + basicPatternClose, 'gi');
}
dataText = '';
supportMatches = (_ref = content.match(supportPattern)) != null ? _ref : [];
opposeMatches = (_ref1 = content.match(opposePattern)) != null ? _ref1 : [];
supports = supportMatches.length + ' ' + this.pluralize(supportText, supportMatches.length);
opposes = ', ' + opposeMatches.length + ' ' + this.pluralize(opposeText, opposeMatches.length);
if (((this.nomType('nominations') || this.nomType('pictures')) && showOpposesForNominations) || (this.nomType('reviews') && showOpposesForReviews)) {
showSupportsAndOpposes = true;
}
if ((showSupportsAndOpposes === false && supportMatches.length === 0) || ((supportMatches.length + opposeMatches.length) === 0)) {
return;
}
if (showSupportsAndOpposes) {
toolTip = dataText = supports + opposes;
} else {
dataText = supports;
}
toolTip = supports + opposes;
return this.appendGeneratedNominationData(vars['pageName'], dataText, 'votes', toolTip);
}
};
NominationsViewerClass.firstRevisionCallback = function(obj) {
var difference, differenceDays, differenceMonths, differenceYears, matches, origThen, origToday, thenDate, timeAgo, timestamp, today, vars;
vars = this.formatJSON(obj);
if (!vars) {
return;
}
if (this.dataIsEnabled('age') && vars['firstRevision']) {
timestamp = vars['firstRevision']['timestamp'];
matches = timestamp.match(/(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})Z/);
origToday = new Date();
today = new Date(origToday.getFullYear(), origToday.getMonth(), origToday.getDate());
origThen = new Date(Date.UTC(matches[1], matches[2] - 1, matches[3], matches[4], matches[5], matches[6]));
thenDate = new Date(origThen.getFullYear(), origThen.getMonth(), origThen.getDate());
difference = new Date(today.valueOf() - thenDate.valueOf());
timeAgo = '';
if (difference.valueOf() !== 0) {
differenceYears = difference.getYear() - 70;
differenceMonths = difference.getMonth();
differenceDays = difference.getDate();
if (differenceYears > 0) {
timeAgo = differenceYears + ' ' + this.pluralize('year', differenceYears) + ' old';
} else if (differenceMonths > 0) {
timeAgo = differenceMonths + ' ' + this.pluralize('month', differenceMonths) + ' old';
} else {
timeAgo = differenceDays + ' ' + this.pluralize('day', differenceDays) + ' old';
}
} else if (difference.valueOf() === 0) {
timeAgo = 'today';
}
return this.appendGeneratedNominationData(vars['pageName'], timeAgo, 'age', 'Creation date (local time): ' + origThen);
}
};
/*
CALLBACK HELPERS
*/
NominationsViewerClass.capitalize = function(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
};
NominationsViewerClass.dataIsEnabled = function(dataName) {
var data, _i, _len, _ref;
_ref = NominationsViewer.nominationData;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
data = _ref[_i];
if (dataName === data) {
return true;
}
}
return false;
};
NominationsViewerClass.findNominators = function(content, pattern) {
var listOfNominators, nominator, nominatorMatches, nominators, userTemplatePattern, username, _i, _j, _len, _len1;
nominatorMatches = content.match(pattern);
listOfNominators = {};
if (!nominatorMatches) {
return listOfNominators;
}
nominators = nominatorMatches[0].match(/\[\[(User|Wikipedia)([ _]talk)?:.*?\]\]/gi);
if (nominators) {
for (_i = 0, _len = nominators.length; _i < _len; _i++) {
nominator = nominators[_i];
username = nominator.replace(/\[\[(User|Wikipedia)([ _]talk)?:/i, '').replace(/\|.*/, '').replace(']]', '');
if (username.indexOf('/') !== -1) {
username = username.substring(0, username.indexOf('/'));
}
listOfNominators[username]++;
}
}
userTemplatePattern = /\{\{user.*?\|(.*?)\}\}/gi;
nominators = nominatorMatches[0].match(userTemplatePattern);
if (nominators) {
for (_j = 0, _len1 = nominators.length; _j < _len1; _j++) {
nominator = nominators[_j];
listOfNominators[nominator.replace(userTemplatePattern, "$1")]++;
}
}
return listOfNominators;
};
NominationsViewerClass.formatJSON = function(obj) {
var page, vars;
if (!obj['query'] || !obj['query']['pages']) {
return false;
}
vars = [];
vars['pages'] = obj['query']['pages'];
vars['page'] = [];
for (page in vars['pages']) {
vars['page'].push(page);
}
if (vars['page'].length !== 1) {
return false;
}
vars['page'] = obj['query']['pages'][vars['page'][0]];
vars['pageName'] = vars['page']['title'].replace(/\ /g, '_');
if (!vars['page']['revisions']) {
return false;
}
vars['firstRevision'] = vars['page']['revisions'][0];
vars['revisions'] = vars['page']['revisions'];
return vars;
};
NominationsViewerClass.nomType = function(type) {
var pageName, pageType;
pageName = mw.config.get('wgPageName').replace(/_/g, ' ');
pageType = NominationsViewer.enabledPages[pageName];
if (type != null) {
if (type === pageType) {
return true;
} else {
return false;
}
} else {
return pageType;
}
};
NominationsViewerClass.pluralize = function(string, count, plural) {
if (plural == null) {
plural = string + 's';
}
if (count === 1) {
return string;
} else {
return plural;
}
};
return NominationsViewerClass;
})();
if (typeof unsafeWindow !== "undefined" && unsafeWindow !== null) {
unsafeWindow.NominationsViewerClass = NominationsViewerClass;
}
$(function() {
if (window.location.href.indexOf('&disable=nomviewer') > -1) {
return false;
}
return NominationsViewerClass.init();
});