User:Gary/nominations viewer.js: Difference between revisions

Content deleted Content added
Fix for "mw" not being immediately available.
massive update
Line 1:
// Generated by CoffeeScript 1.8.0
 
/*
Nominations Viewer
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
---
 
Default:
 
DEFAULTS:
NominationsViewer =
{
Line 18:
'nominationData': ['images', 'age', 'nominators', 'participants', 'votes'],
}
*/
varconst NominationsViewer, NominationsViewerClass;=
window.NominationsViewer == null ? {} : window.NominationsViewer;
 
if (window.NominationsViewer == null) {
NominationsViewer = {};
} else {
NominationsViewer = window.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'
'Wikipedia:Peer review': 'peer reviews',
};
}
 
if (NominationsViewer.nominationData == null) {
NominationsViewer.nominationData = [
'images',
'age',
'nominators',
'participants',
'votes'];,
];
}
 
 
/*
End settings
*/
 
class NominationsViewerClass = (function() {
/**
function NominationsViewerClass() {}
* Add empty nomination data holders for a nomination.
* @param {string} pageName Name of the nomination page.
* @param {jQuery} $parentNode Parent node containing the entire nomination.
* @param {Array} ids The ID names to create.
*/
static addNominationData(pageName, $parentNode, ids) {
return ids.map((id) => {
const $span = $(
`<span id="${id}-${this.simplifyPageName(pageName)}"></span>`,
);
 
return $parentNode
.children()
.last()
.before($span);
});
}
 
static addOverallNominationInformation($headings) {
/*
const data = { allH3Length: $headings.length };
BODY
*/
 
const $expandAllLink = $(
NominationsViewerClass.addNominationData = function(pageName, $parentNode, ids) {
'<a href="#" id="expand-all-link">expand all</a>',
var $span, id, _i, _len, _results;
).on('click', data, this.expandAllNoms);
_results = [];
const $collapseAllLink = $(
for (_i = 0, _len = ids.length; _i < _len; _i++) {
'<a href="#" id="collapse-all-link">collapse all</a>',
id = ids[_i];
).on('click', data, this.collapseAllNoms);
$span = $('<span id="' + id + '-' + pageName + '"></span>');
const $info = $('<span class="overall-controls"></span>')
_results.push($parentNode.children().last().before($span));
} .append(' (')
.append($expandAllLink)
return _results;
.append(' / ')
};
.append($collapseAllLink)
.append(')');
 
return $headings
NominationsViewerClass.addOverallNominationInformation = function($headings) {
.first()
var $collapseAllLink, $expandAllLink, $info, data;
data = {.next()
.prevUntil('h2')
allH3Length: $headings.length
}; .last()
.prev()
$expandAllLink = $('<a href="javascript:void(0)" id="expand-all-link">expand all</a>').on('click', data, this.expandAllNoms);
.append($info);
$collapseAllLink = $('<a href="javascript:void(0) id="collapse-all-link">collapse all</a>').on('click', data, this.collapseAllNoms);
}
$info = $('<span class="overall-controls"></span>').append(' (').append($expandAllLink).append(' / ').append($collapseAllLink).append(')');
return $headings.first().next().prevUntil('h2').last().prev().append($info);
};
 
NominationsViewerClass.static appendAllNominationData = function(pageNamepageNameParam) {
varconst appendNominationData; = (callback, parameters) => {
const apiUrl = `https:${window.mw.config.get(
appendNominationData = function(callback, parameters) {
'wgServer',
return importScriptURI(mw.config.get('wgServer') + mw.config.get('wgScriptPath') + '/api.php?callback=' + callback + '&format=json&' + parameters);
)}${window.mw.config.get(
'wgScriptPath',
)}/api.php?callback=${callback}&format=json&${parameters}`;
 
mw.loader.load(apiUrl);
};
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);
};
 
const pageName = pageNameParam;
NominationsViewerClass.appendGeneratedNominationData = function(pageName, data, id, abbrTitle, isFirstData) {
 
var $abbr, $id, $newChild, character, escapedCharacters, invalidCssCharacters, _i, _len;
// Participants
appendNominationData(
'NominationsViewerClass.allRevisionsCallback',
`action=query&prop=revisions&rvdir=newer&rvlimit=500&titles=${pageName}`,
);
 
// Images, nominators, votes
appendNominationData(
'NominationsViewerClass.currentRevisionCallback',
`action=query&prop=revisions&rvdir=older&rvlimit=1&rvprop=content&titles=\
${pageName}`,
);
 
// Age
return appendNominationData(
'NominationsViewerClass.firstRevisionCallback',
`action=query&prop=revisions&rvdir=newer&rvlimit=1&titles=${pageName}`,
);
}
 
static appendGeneratedNominationData(
pageName,
data,
id,
abbrTitle,
isFirstData,
) {
if (!data) {
return false;
}
 
invalidCssCharacters = '~!@$%^&*()_+-=,./\';:"?><[]\{}|`#';
// Select the element we want to add values to.
escapedCharacters = '';
const $id = $(`#${id}-${this.simplifyPageName(pageName)}`);
for (_i = 0, _len = invalidCssCharacters.length; _i < _len; _i++) {
 
character = invalidCssCharacters[_i];
const $newChild = $('<span></span>');
escapedCharacters += '\\' + character;
}
$id = $('#' + id + '-' + pageName.replace(RegExp('([' + escapedCharacters + '])', 'g'), '\\$1'));
$newChild = $('<span></span>');
if (!isFirstData) {
$newChild.append(' · ');
}
const $abbr = $('`<abbr title="' + ${abbrTitle + '}">' + ${data + '}</abbr>'`);
 
$newChild.append($abbr);
return $id.append($newChild);
};
 
/**
NominationsViewerClass.createData = function(pageName) {
* Create the data that appears next to the nomination's listing.
var $newSpan, $viewLink, conditions, matchArchiveNumber, matchArchiveNumberPrint, number, ordinalSuffix;
* @param {string} pageName Page name of the nomination page.
$newSpan = $('<span class="nomination-data"></span>').append('<tt>(</tt>');
*/
matchArchiveNumber = pageName.match(/([0-9]+)$/);
static createData(pageName) {
conditions = matchArchiveNumber && matchArchiveNumber[1] > 1;
const $newSpan = $('<span class="nomination-data"></span>').append(
matchArchiveNumberPrint = conditions ? (number = parseInt(matchArchiveNumber[1]), ordinalSuffix = (function() {
switch '<tt>(number) {</tt>',
case 2:);
const matchArchiveNumber = pageName.match(/([0-9]+)$/);
return 'nd';
 
case 3:
const conditions = matchArchiveNumber && matchArchiveNumber[1] > 1;
return 'rd';
const matchArchiveNumberPrint = (() => {
default:
if (conditions) return 'th';{
const number = parseInt(matchArchiveNumber[1], 10);
 
const ordinalSuffix = (() => {
switch (number) {
case 2:
return 'nd';
case 3:
return 'rd';
default:
return 'th';
}
})();
 
return `: ${number}${ordinalSuffix}`;
}
 
})(), ': ' + number + ordinalSuffix) : '';
return '';
$viewLink = $('<span><a href="/https/en.m.wikipedia.org/wiki/' + pageName + '">nomination</a>' + matchArchiveNumberPrint + '</span>');
})();
 
const $viewLink = $(
`<span><a href="/https/en.m.wikipedia.org/wiki/${pageName}">nomination</a>\
${matchArchiveNumberPrint}</span>`,
);
 
return $newSpan.append($viewLink).append('<tt>)</tt>');
};
 
NominationsViewerClass.static createNewNode = function(oldNode, showHideLink, newSpan, index) {
const $newNode = $(`<div id="nom-title-${index}"></div>`).append(
var $heading, $newNode;
$newNode = $('<div id="nom-title-' + index + '"></div>').append(oldNode.clone(true));,
);
const $heading = $newNode.children().first();
$heading
$heading.prepend('<span class="nomination-order">' + (index + 1) + '.</span> ').append(' ').append(showHideLink).append(newSpan);
.prepend(`<span class="nomination-order">${index + 1}.</span> `)
.append(' ')
.append(showHideLink)
.append(newSpan);
return $newNode;
};
 
/**
NominationsViewerClass.createNomArticleName = function(pageName) {
* Replace a nomination with a new and improved one.
var nomArticleName;
* @param {jQuery} $h3 The h3 heading of the nomination.
nomArticleName = pageName.replace(/_/g, ' ').split('/');
* @param {number} index The index of the nomination among the others.
return nomArticleName = nomArticleName[nomArticleName.length - 2];
}; */
static createNomination({ $h3, index }) {
const $editLink = $h3.find('.mw-editsection-bracket').next('a');
 
// This nomination is missing an edit link, so something is wrong with it.
NominationsViewerClass.createNomination = function(_arg) {
// Skip it.
var $h3, NominationsViewer, editLink, index, newNode, newSpan, nomArticleName, nomDiv, pageName, showHideLink;
if (!$editLink.length) {
$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, '_');
// Get the name of the nomination page.
nomArticleName = this.createNomArticleName(pageName);
const pageName = decodeURIComponent(
showHideLink = this.createShowHideLink(index);
$editLink
newSpan = this.createData(pageName);
.attr('href')
.match(/title=(.*?)&/)[1]
.replace(/\s/g, '_'),
);
 
// Create the [show] / [hide] link
const showHideLink = this.createShowHideLink(index);
 
// Create the spot to put the data that we will retrieve via the Wikipedia
// API
const newSpan = this.createData(pageName);
 
// Move the nomination into a hidden node
this.hideNomination($h3, index);
 
// Add placeholders for the data that we will retrieve for the API
this.addNominationData(pageName, newSpan, NominationsViewer.nominationData);
 
newNode = this.createNewNode($h3, showHideLink, newSpan, index);
// Create the nomination's title line
nomDiv = this.generateNomination(index, newNode, $h3);
const newNode = this.createNewNode($h3, showHideLink, newSpan, index);
 
// Create the actual nomination
const nomDiv = this.generateNomination(index, newNode, $h3);
 
// Replace this nomination with the new one we created
$h3.replaceWith(nomDiv);
 
// Ask the API to add data to our placeholders
return this.appendAllNominationData(pageName);
};
 
NominationsViewerClass.static createShowHideLink = function(index) {
const link = $(`<a href="#" id="nom-button-${index}">show</a>`).on(
var link, span;
'click',
link = $('<a href="javascript:void(0)" id="nom-button-' + index + '">show</a>').on('click', {
index:{ index },
}, this.toggleNomClick);,
);
const span = $('<span class="plus-minus-button"></span>');
return span
.append('[')
.append(link)
.append(']');
};
 
NominationsViewerClass.static generateNomination = function(index, newNode, oldNode) {
return $('`<div class="nomination" id="nom-' + ${index + '}"></div>'`)
.append(newNode.clone(true))
.append($(oldNode[0].nextSibling).clone(true));
};
 
// This function MUST stay in JavaScript, rather than switch to jQuery, for
NominationsViewerClass.hideNomination = function($h3, index) {
// optmization reasons.
var hiddenNode, nomNextSibling, nomNextSiblingTemp;
//
hiddenNode = document.createElement('div');
// The jQuery version slowed the page down by about 28%. This version slows
// the page down by about 11%, so it is about 17% faster.
static hideNomination($h3, index) {
// Re-create all nodes between this H3 node, and the next one,
// then place it into a new node.
const hiddenNode = document.createElement('div');
hiddenNode.className = 'nomination-body';
hiddenNode.id = '`nom-data-' + ${index}`;
hiddenNode.style.display = 'none';
let nomNextSibling = $h3[0].nextSibling;
 
while (nomNextSibling !== null && ['H2', 'H3'].indexOf(nomNextSibling.nodeName) === -1 && !(nomNextSibling.classList && nomNextSibling.classList.contains('printfooter'))) {
// Continue to the next node, as long as the next node still exists,
nomNextSiblingTemp = nomNextSibling.nextSibling;
// it isn't an H2 or H3, and it doesn't have the class "printfooter"
while (
nomNextSibling !== null &&
['H2', 'H3'].indexOf(nomNextSibling.nodeName) === -1 &&
!(
nomNextSibling.classList &&
nomNextSibling.classList.contains('printfooter')
)
) {
const nomNextSiblingTemp = nomNextSibling.nextSibling;
 
// Move the node, if it isn't a text node
if (nomNextSibling.nodeType !== 3) {
hiddenNode.appendChild(nomNextSibling);
}
 
nomNextSibling = nomNextSiblingTemp;
}
 
// Insert hidden content
return $h3.after(hiddenNode);
};
 
static init() {
let currentPageIsASubpage;
let currentPageIsEnabled;
const pageName = window.mw.config.get('wgPageName');
 
// Check if enabled on this page
Object.keys(NominationsViewer.enabledPages).forEach((page) => {
// const type = NominationsViewer.enabledPages[page];
 
if (pageName === page.replace(/\s/g, '_')) {
NominationsViewerClass.init = function() {
var $h3s, $parentNode, currentPageIsASubpage, currentPageIsEnabled, page, pageName, type, _ref;
pageName = mw.config.get('wgPageName');
_ref = NominationsViewer.enabledPages;
for (page in _ref) {
type = _ref[page];
if (pageName === page.replace(/\ /g, '_')) {
currentPageIsEnabled = true;
} else if (pageName.indexOf(page.replace(/\s/g, '_')) === 0) {
break;
} else if (pageName.indexOf(page.replace(/\ /g, '_')) === 0) {
currentPageIsASubpage = true;
break;
}
});
 
if (!((currentPageIsEnabled != null) && mw.config.get('wgAction') === 'view' && window.location.href.indexOf('&oldid=') === -1 && (currentPageIsASubpage == null))) {
if (
currentPageIsEnabled == null ||
window.mw.config.get('wgAction') !== 'view' ||
window.location.href.indexOf('&oldid=') !== -1 ||
!(currentPageIsASubpage == null)
) {
return false;
}
 
// Only append the CSS if we are definitely running the script on this page.
this.nominationsViewerCss();
 
$parentNode = $('.mw-content-ltr');
const $h3sparentNode = $parentNode.find('h3.mw-content-ltr');
const $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, element) {
var $link;
$link = $(element).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
}, this.collapseTable);
});
};
 
// loop through each nomination
$h3s.each((index, element) =>
this.createNomination({
$h3: $(element),
index,
}),
);
 
// Fix any conflicts with collapsed comments (using the special template).
/*
return $('.collapseButton').each((index, element) => {
HELPERS
const $link = $(element)
*/
.children()
.first();
 
const newIndex = $link
NominationsViewerClass.collapseTable = function(event) {
.attr('id')
var $button, $rows, $table, collapseCaption, expandCaption, tableIndex;
.substring(
$link.attr('id').indexOf('collapseButton') + 'collapseButton'.length,
$link.attr('id').length,
);
 
return $link
.attr('href', '#')
.on('click', { newIndex }, this.collapseTable);
});
}
 
/*
Helpers
*/
static collapseTable(event) {
event.preventDefault();
const tableIndex = event.data.index;
const collapseCaption = 'hide';
const expandCaption = 'show';
 
$button = $('#collapseButton' + tableIndex);
const $tablebutton = $('`#collapsibleTable' + collapseButton${tableIndex}`);
ifconst (!($table.length &&= $button.length(`#collapsibleTable${tableIndex}`)) {;
if (!$table.length || !$button.length) {
return false;
}
const $rows = $table.find('> tbody > tr');
 
if ($button.text() === collapseCaption) {
$rows.each(function(index, element) => {
if (index === 0) {
return true;
Line 256 ⟶ 394:
});
return $button.text(expandCaption);
} else {
$rows.each(function(index, element) {
if (index === 0) {
return true;
}
return $(element).show();
});
return $button.text(collapseCaption);
}
$rows.each((index, element) => {
};
if (index === 0) {
return true;
}
return $(element).show();
});
return $button.text(collapseCaption);
}
 
NominationsViewerClass.static nominationsViewerCss = function() {
// CSS
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; }');
return window.mw.util.addCSS(
};
// eslint-disable-next-line no-multi-str
'\
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.static expandAllNoms = function(event) {
return NominationsViewerClass.toggleAllNoms(event, 'expand');
};
 
NominationsViewerClass.static collapseAllNoms = function(event) {
return NominationsViewerClass.toggleAllNoms(event, 'collapse');
};
 
static toggleAllNoms(event, actionParam) {
let action = actionParam;
 
NominationsViewerClass.toggleAllNoms = function(event, action) {
var allH3Length, index, _i, _results;
if (action == null) {
action = 'expand';
}
event.preventDefault();
const { allH3Length } = event.data.allH3Length;
 
_results = [];
Array(allH3Length)
for (index = _i = 0; 0 <= allH3Length ? _i < allH3Length : _i > allH3Length; index = 0 <= allH3Length ? ++_i : --_i) {
.fill()
_results.push(NominationsViewerClass.toggleNom(index, action));
.forEach((value, index) => {
}
NominationsViewerClass.toggleNom(index, action);
return _results;
});
}
 
static toggleNom(id, actionParam) {
let action = actionParam;
 
NominationsViewerClass.toggleNom = function(id, action) {
var $node, $nomButton, toggleHideNom, toggleShowNom;
if (action == null) {
action = '';
}
const toggleHideNom = function($node, $nomButton) => {
$node.hide();
return $nomButton.text('show');
};
 
toggleShowNom = function($node, $nomButton) {
const toggleShowNom = ($node, $nomButton) => {
$node.show();
return $nomButton.text('hide');
};
 
$node = $('#nom-data-' + id);
const $nomButtonnode = $('`#nom-buttondata-' + ${id}`);
const $nomButton = $(`#nom-button-${id}`);
 
// These are actions that override the status for all nominations.
if (action === 'collapse') {
return toggleHideNom($node, $nomButton);
} else if (action === 'expand') {
return toggleShowNom($node, $nomButton);
// These have to be separate from the above because they have a lower
// priority.
} else if ($node.is(':visible')) {
return toggleHideNom($node, $nomButton);
Line 317 ⟶ 477:
return toggleShowNom($node, $nomButton);
}
};
 
return null;
NominationsViewerClass.toggleNomClick = function(event) {
}
var index;
 
static toggleNomClick(event) {
event.preventDefault();
const { index } = event.data.index;
return NominationsViewerClass.toggleNom(index);
};
 
 
/*
CALLBACKSCallbacks
*/
static allRevisionsCallback(obj) {
 
const vars = this.formatJSON(obj);
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 null;
}
 
if (this.dataIsEnabled('participants') && vars['revisions']) {
// users = {};Participants
if (this.dataIsEnabled('participants') && vars.revisions) {
userCount = 0;
_refconst users = vars['revisions']{};
let userCount = 0;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
 
revision = _ref[_i];
if vars.revisions.forEach((!revision['user']) => {
// revision = { 'revid', 'paretnid', 'user', 'timestamp', 'comment' }
continue;
if (!revision.user) {
return;
}
 
if (users[revision['user']]) {
if (users[revision['.user']]++;) {
users[revision.user] += 1;
} else {
users[revision['.user']] = 1;
userCount ++= 1;
}
});
 
moreThan = obj['query-continue'] ? 'more than ' : '';
const moreThan = obj['query-continue'] ? 'more than ' : '';
usersArray = [];
 
for (user in users) {
const countusersArray = Object.keys(users[).map((user];) => [
usersArray.push([user, parseInt(count)]);
parseInt(users[user], 10),
}
]);
usersArray.sort(function(a, b) {
 
usersArray.sort((a, b) => {
if (a[1] < b[1]) {
return 1;
} else if (a[1] > b[1]) {
return -1;
} else {
return 0;
}
return 0;
});
 
usersArray2 = [];
forconst (_j = 0, _len1usersArray2 = usersArray.length;map((user) _j=> <`${user[0]}: _len1${user[1]}`); _j++) {
 
user = usersArray[_j];
return this.appendGeneratedNominationData(
usersArray2.push(user[0] + ': ' + user[1]);
} vars.pageName,
return this.appendGeneratedNominationData(vars['pageName'], `${moreThan + userCount} + ' ' + ${this.pluralize('participant', userCount)}`,
'participants',
' `Sorted from most to least edits&#10;Total edits: '${
+ vars['.revisions'].length
+ ' }&#10;Format: &quot;editor: number of \
edits&quot;:&#10;&#10;' + ${usersArray2.join('&#10;'));}`,
);
}
};
 
return null;
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);
static currentRevisionCallback(obj) {
let content;
 
const vars = this.formatJSON(obj);
if (!vars) {
return null;
}
 
if (vars['firstRevision']) {
if content = (vars['.firstRevision']['*'];) {
content = vars.firstRevision['*'];
} else {
return false;
}
 
// 'images'
if (this.nomType('pictures') && this.dataIsEnabled('images')) {
// Determine number of images in the nomination
pattern1 = /\[\[(File|Image):.*?\]\]/gi;
pattern2const pattern1 = /\n[\[(File|Image):.*?\|]\]/gi;
matches1const pattern2 = content.match/\n(pattern1File|Image):.*\|/gi;
matches2const matches1 = content.match(pattern2pattern1);
matches = matches1 ? matches1 :const matches2 ? matches2 := []content.match(pattern2);
 
images = [];
const matches = matches1 || (matches2 || []);
for (_i = 0, _len = matches.length; _i < _len; _i++) {
 
match = matches[_i];
const splitimages = matchmatches.splitmap('|'(match); => {
filenameconst split = $match.trim(split[0].replace(/^\[\[/, '|'));
const filename = $.trim(split[0].replace(/^\[\[/, ''));
images.push(filename);
} return filename;
});
this.appendGeneratedNominationData(vars['pageName'], matches.length + ' ' + this.pluralize('image', matches.length), 'images', 'Images (in order of appearance):&#10;&#10;' + images.join('&#10;'));
 
this.appendGeneratedNominationData(
vars.pageName,
`${matches.length} ${this.pluralize('image', matches.length)}`,
'images',
`Images (in order of appearance):&#10;&#10;${images.join('&#10;')}`,
);
}
 
// 'nominators'
if (this.dataIsEnabled('nominators') && !this.nomType('peer reviews')) {
let nomTypeText = '';
let listOfNominators = {};
 
switch (this.nomType()) {
case 'nominations':
nomTypeText = 'nominator';
listOfNominators = this.findNominators(
content,
/Nominator(\(s\))?:.*/);,
);
 
if ($.isEmptyObject(listOfNominators)) {
listOfNominators = this.findNominators(content, /:<small>''.*/);
Line 416 ⟶ 604:
case 'reviews':
nomTypeText = 'notification';
listOfNominators = this.findNominators(
content,
/(Notified|Notifying):.*/);,
);
break;
case 'pictures':
nomTypeText = 'nominator';
listOfNominators = this.findNominators(
content,
/\* '''Support as nominator''' – .*/);,
} );
allNominators = [] break;
for (n in listOfNominators) {default:
allNominators.push(n);
}
 
const allNominators = Object.keys(listOfNominators).map((n) => 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):&#10;&#10;' + allNominators.join('&#10;'));
/* eslint-disable indent */
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):&#10;&#10;${allNominators.join('&#10;')}`,
);
/* eslint-enable indent */
}
 
// 'votes'
if (this.dataIsEnabled('votes') && !this.nomType('peer reviews')) {
let opposePattern;
showOpposesForNominations = false;
showOpposesForReviewslet = trueopposeText;
let supportPattern;
showSupportsAndOpposes = false;
voteBufferlet = 25supportText;
 
basicPatternOpen = "'''(.{0," + voteBuffer + "})?";
const showOpposesForNominations = false;
basicPatternClose = "(.{0," + voteBuffer + "})?'''";
const showOpposesForReviews = true;
 
let showSupportsAndOpposes = false;
const voteBuffer = 25;
let basicPatternOpen = `'''(.{0,${voteBuffer}})?`;
let basicPatternClose = `(.{0,${voteBuffer}})?'''`;
 
if (this.nomType('nominations')) {
supportText = 'support';
opposeText = 'oppose';
 
supportPattern = new RegExp(basicPatternOpen + 'support' + basicPatternClose, 'gi');
opposePatternsupportPattern = new RegExp(basicPatternOpen + 'oppose' + basicPatternClose, 'gi');
`${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');
opposePatternsupportPattern = new RegExp(basicPatternOpen + 'delist' + basicPatternClose, 'gi');
`${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');
opposePatternsupportPattern = new RegExp(basicPatternOpen + 'Oppose' + basicPatternClose, 'gi');
`${basicPatternOpen}Support${basicPatternClose}`,
'gi',
);
opposePattern = new RegExp(
`${basicPatternOpen}Oppose${basicPatternClose}`,
'gi',
);
}
 
dataText = '';
let dataText = '';
supportMatches = (_ref = content.match(supportPattern)) != null ? _ref : [];
 
opposeMatches = (_ref1 = content.match(opposePattern)) != null ? _ref1 : [];
supports =const supportMatches.length += ' ' + thiscontent.pluralizematch(supportText, supportMatches.lengthsupportPattern);
? content.match(supportPattern)
opposes = ', ' + opposeMatches.length + ' ' + this.pluralize(opposeText, opposeMatches.length);
: [];
if (((this.nomType('nominations') || this.nomType('pictures')) && showOpposesForNominations) || (this.nomType('reviews') && showOpposesForReviews)) {
 
const opposeMatches = content.match(opposePattern)
? content.match(opposePattern)
: [];
 
const supports = `${supportMatches.length} ${this.pluralize(
supportText,
supportMatches.length,
)}`;
const 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)) {
// Only show dataText if sum(votes) > 0
return;
if (
(showSupportsAndOpposes === false && supportMatches.length === 0) ||
supportMatches.length + opposeMatches.length === 0
) {
return null;
}
 
dataText = showSupportsAndOpposes ? supports + opposes : supports;
 
toolTip = supports + opposes;
const toolTip = supports + opposes;
return this.appendGeneratedNominationData(vars['pageName'], dataText, 'votes', toolTip);
return this.appendGeneratedNominationData(
vars.pageName,
dataText,
'votes',
toolTip,
);
}
};
 
return null;
NominationsViewerClass.firstRevisionCallback = function(obj) {
}
var difference, differenceDays, differenceMonths, differenceYears, matches, origThen, origToday, thenDate, timeAgo, timestamp, today, vars;
 
vars = this.formatJSON(obj);
/**
* The callback after getting the first revision of a page.
* @param {Object} obj The response object from the Wikipedia API.
*/
static firstRevisionCallback(obj) {
const vars = this.formatJSON(obj);
 
if (!vars) {
return null;
}
 
if (this.dataIsEnabled('age') && vars['firstRevision']) {
// Nomination age
timestamp = vars['firstRevision']['timestamp'];
if (this.dataIsEnabled('age') && vars.firstRevision) {
matches = timestamp.match(/(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})Z/);
const { timestamp } = vars.firstRevision;
origToday = new Date();
const matches = timestamp.match(
today = new Date(origToday.getFullYear(), origToday.getMonth(), origToday.getDate());
/(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})Z/,
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());
timeAgoconst origToday = ''new Date();
const today = new Date(
origToday.getFullYear(),
origToday.getMonth(),
origToday.getDate(),
);
const origThen = new Date(
Date.UTC(
matches[1],
matches[2] - 1,
matches[3],
matches[4],
matches[5],
matches[6],
),
);
const thenDate = new Date(
origThen.getFullYear(),
origThen.getMonth(),
origThen.getDate(),
);
 
const difference = new Date(today.valueOf() - thenDate.valueOf());
let timeAgo = '';
 
if (difference.valueOf() !== 0) {
const differenceYears = difference.getYear() - 70;
const differenceMonths = difference.getMonth();
const differenceDays = difference.getDate();
 
timeAgo = differenceYears > 0 ? differenceYears + ' ' + this.pluralize('year', differenceYears) + ' old' : differenceMonths > 0 ? differenceMonths + ' ' + this.pluralize('month', differenceMonths) + ' old' : differenceDays + ' ' + this.pluralize('day', differenceDays) + ' old';
/* eslint-disable indent, no-nested-ternary */
timeAgo =
differenceYears > 0
? `${differenceYears} ${this.pluralize(
'year',
differenceYears,
)} old`
: differenceMonths > 0
? `${differenceMonths} ${this.pluralize(
'month',
differenceMonths,
)} old`
: `${differenceDays} ${this.pluralize(
'day',
differenceDays,
)} old`;
/* eslint-enable indent, no-nested-ternary */
} else if (difference.valueOf() === 0) {
timeAgo = 'today';
}
 
return this.appendGeneratedNominationData(vars['pageName'], timeAgo, 'age', 'Creation date (local time):&#10;&#10;' + origThen);
return this.appendGeneratedNominationData(
vars.pageName,
timeAgo,
'age',
`Creation date (local time):&#10;&#10;${origThen}`,
);
}
};
 
return null;
}
 
/*
CALLBACKCallback HELPERShelpers
*/
static capitalize(string) {
 
NominationsViewerClass.capitalize = function(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
};
 
NominationsViewerClass.static dataIsEnabled = function(dataName) {
return NominationsViewer.nominationData.some((data) => dataName === data);
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.static findNominators = function(content, pattern) {
const nominatorMatches = content.match(pattern);
var listOfNominators, nominator, nominatorMatches, nominators, userTemplatePattern, username, _i, _j, _len, _len1;
const listOfNominators = {};
nominatorMatches = content.match(pattern);
listOfNominators = {};
if (!nominatorMatches) {
return listOfNominators;
}
 
nominators = nominatorMatches[0].match(/\[\[(User|Wikipedia)([ _]talk)?:.*?\]\]/gi);
// [[User:Example|Example]], [[Wikipedia talk:WikiProject Example]]
let nominators = nominatorMatches[0].match(
/\[\[(User|Wikipedia)([ _]talk)?:.*?\]\]/gi,
);
 
if (nominators) {
nominators.forEach((nominator) => {
for (_i = 0, _len = nominators.length; _i < _len; _i++) {
nominatorlet username = nominators[_i];nominator
username = nominator.replace(/\[\[(User|Wikipedia)([ _]talk)?:/i, '')
.replace(/\|.*/, '')
.replace(']]', '');
 
// Does 'username' have a '/' that we have to strip?
if (username.indexOf('/') !== -1) {
username = username.substring(0, username.indexOf('/'));
}
 
listOfNominators[username]++;
listOfNominators[username] += 1;
}
});
}
 
userTemplatePattern = /\{\{user.*?\|(.*?)\}\}/gi;
// {{user|Example}} and similar variants
const userTemplatePattern = /\{\{user.*?\|(.*?)\}\}/gi;
nominators = nominatorMatches[0].match(userTemplatePattern);
 
if (nominators) {
nominators.forEach((singleNominator) => {
for (_j = 0, _len1 = nominators.length; _j < _len1; _j++) {
nominator = nominatorslistOfNominators[_j];
listOfNominators[nominator singleNominator.replace(userTemplatePattern, "'$1"')]++;
} ] += 1;
});
}
 
return listOfNominators;
};
 
NominationsViewerClass.static formatJSON = function(obj) {
if (!obj.query || !obj.query.pages) {
var page, vars;
if (!obj['query'] || !obj['query']['pages']) {
return false;
}
 
vars = [];
const vars['pages'] = obj['query']['pages'];
vars['page'].pages = []obj.query.pages;
 
for (page in vars['pages']) {
vars.page = Object.keys(vars['page'].pushpages).map((page) => page);
 
}
if (vars['.page'].length !== 1) {
return false;
}
 
vars['page'] = obj['query']['pages'][vars['page'][0]];
vars['pageName'].page = varsobj.query.pages['vars.page']['title'0]].replace(/\ /g, '_');
ifvars.pageName = (!vars['.page.title.replace(/\s/g, '][_'revisions']) {;
if (!vars.page.revisions) {
return false;
}
 
vars['firstRevision'] = vars['page']['revisions'][0];
[vars['revisions'.firstRevision] = vars['.page']['.revisions'];
vars.revisions = vars.page.revisions;
return vars;
};
 
static nomType(type) {
const pageName = window.mw.config.get('wgPageName').replace(/_/g, ' ');
const pageType = NominationsViewer.enabledPages[pageName];
 
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 false;
return pageType;
}
return pageType;
};
}
 
static pluralize(string, count) {
const plural = `${string}s`;
 
NominationsViewerClass.pluralize = function(string, count, plural) {
if (plural == null) {
plural = string + 's';
}
if (count === 1) {
return string;
} else {
return plural;
}
return plural;
};
}
 
static simplifyPageName(pageName) {
return NominationsViewerClass;
return pageName.replace(/\W/g, '');
 
}
})();
 
if (typeof unsafeWindow !== "undefined" && unsafeWindow !== null) {
unsafeWindow.NominationsViewerClass = NominationsViewerClass;
}
 
$(function() => {
// Check the URL to determine if this script should be disabled.
var runScript;
if (window.location.href.indexOf('&disable=nomviewer') > -1) {
return false;
}
runScript = function() {
return NominationsViewerClass.init();
};
if (typeof waitForScripts === 'function') {
return waitForScripts(runScript);
} else {
return runScript();
}
 
NominationsViewerClass.init();
});