User:Pyrospirit/metadata/projectbanners.js
Appearance
Code that you insert on this page could contain malicious content capable of compromising your account. If you import a script from another page with "importScript", "mw.loader.load", "iusc", or "lusc", take note that this causes you to dynamically load a remote script, which could be changed by others. Editors are responsible for all edits and actions they perform, including by scripts. User scripts are not centrally supported and may malfunction or become inoperable due to software changes. A guide to help you find broken scripts is available. If you are unsure whether code you are adding to this page is safe, you can ask at the appropriate village pump. This code will be executed when previewing this page. |
This user script seems to have a documentation page at User:Pyrospirit/metadata/projectbanners. |
/**
* Optional component for metadata script ([[User:Pyrospirit/metadata.js]]).
* This script creates a table at the top of the page, hidden by default, that
* contains each WikiProject's assessment and importance rating of the article.
* The table can be toggled on and off with the [show]/[hide] link to the right
* of the main assessment in the siteSub.
*/
if(typeof assessment !== 'undefined') {
assessment.banners = {
done: false, // flag to make sure it only runs once
runProjectBanners: function runProjectBanners () {
if (this.done) return;
this.assessments = this.getProjectBanners(assessment.text);
if (this.assessments.length == 0) return; // no projects found
var listDisplay = this.createAssessmentList(this.assessments),
button = this.makeToggle('assessment.banners.toggleBox'),
contentSub = document.getElementById('contentSub'),
siteSub = document.getElementById('siteSub');
// Add the table, initially hidden
document.getElementById('bodyContent').insertBefore(listDisplay, contentSub);
// Add the toggle button
siteSub.insertBefore(button, siteSub.firstChild);
// Move coordinates element over by 30px if present to prevent overlap
var coords = document.getElementById('coordinates');
if (coords) {
coords.style.right = '60px';
}
this.done = true;
},
/**
* Creates the HTML code for displaying an assessment list.
*/
createAssessmentList: function createAssessmentList (assessments) {
var tbody = document.createElement('tbody');
var tr, tdName, tdRating, tdImportance, link; // the table elements in each row
var rating, importance;
var assess;
var nameHeader = document.createElement('th');
nameHeader.setAttribute('width', '200');
nameHeader.innerHTML = 'WikiProject';
var ratingHeader = document.createElement('th');
ratingHeader.setAttribute('width', '80');
ratingHeader.innerHTML = 'Assessment';
var importanceHeader = document.createElement('th');
importanceHeader.setAttribute('width', '75');
importanceHeader.innerHTML = 'Importance';
var header = document.createElement('tr');
header.appendChild(nameHeader);
header.appendChild(ratingHeader);
header.appendChild(importanceHeader);
tbody.appendChild(header);
for (var i = 0; i < assessments.length; i++) {
assess = assessments[i]
rating = this.setCaps(assess.rating, false, 2);
importance = this.setCaps(assess.importance, false, 2);
tr = document.createElement('tr');
tdName = document.createElement('td');
link = document.createElement('a');
link.setAttribute('href', mw.config.get('wgArticlePath').replace('$1', '')
+ (assess.name.search(/\:/) == -1 ? 'Template:' : '') + assess.name);
link.innerHTML = assess.name;
tdName.appendChild(link);
tdRating = document.createElement('td');
tdRating.innerHTML = rating ? rating : '–';
if (rating) tdRating.setAttribute('class', 'assess-' + rating.toLowerCase());
tdImportance = document.createElement('td');
tdImportance.innerHTML = importance ? importance : '–';
if (importance) tdImportance.setAttribute('class', 'assess-importance-' + importance.toLowerCase());
tr.appendChild(tdName);
tr.appendChild(tdRating);
tr.appendChild(tdImportance);
tbody.appendChild(tr);
}
var table = document.createElement('table');
table.setAttribute('id', 'assess-box-content');
table.setAttribute('class', 'wikitable');
table.setAttribute('cellpadding', '2');
table.style.display = 'none';
table.style.textAlign = 'center';
table.appendChild(tbody);
return table;
},
/**
* Makes a toggle button for the assessment box.
* @param {String} method - the method name
* @param {String} text - the starting text of the button
* @return {String} toggle - the toggle button
*/
makeToggle: function makeToggle (method) {
var button = document.createElement('a');
var href = 'javascript:void(' + method + '());';
button.setAttribute('id', 'assess-box-toggle');
button.setAttribute('href', href);
button.setAttribute('title', 'Show assessment box');
button.innerHTML = 'show'; // starting text for the button
var toggle = document.createElement('span');
toggle.setAttribute('class', 'assess-box');
toggle.setAttribute('style', 'float: right;');
toggle.appendChild(button);
toggle.innerHTML = '[' + toggle.innerHTML + ']'; // add surrounding brackets
return toggle;
},
/**
* Toggles show/hide for the assessment box content.
*/
toggleBox: function toggleBox () {
var toggle = document.getElementById('assess-box-toggle');
var content = document.getElementById('assess-box-content');
if (content.style.display != 'none') {
content.style.display = 'none';
toggle.setAttribute('title', 'Show assessment box');
toggle.innerHTML = 'show';
} else {
content.style.display = '';
toggle.setAttribute('title', 'Hide assessment box');
toggle.innerHTML = 'hide';
}
},
/**
* Standardizes the capitalization used for the assessment table.
*/
setCaps: function setCaps (input, default_, maxcaps) {
return (input
? (input.toString().length > maxcaps
? input.toString().charAt(0).toUpperCase()
+ input.toString().substring(1).toLowerCase()
: input.toString().toUpperCase())
: default_);
},
/**
* Creates a list of WikiProject assessments from text containing the
* WikiProject banners.
* @param {String} text - the text to be read
* @return {Array} banners - an array of objects, each containing one
* project's assessment
*/
getProjectBanners: function getProjectBanners (text) {
var templates = this.findProjects(text);
var banners = [];
var parseOutput;
for (var i = 0; i < templates.length; i++) {
banners.push({});
banners[i].name = this.templateName(templates[i][0]);
parseOutput = this.parseTemplate(templates[i]);
banners[i].rating = parseOutput.rating;
banners[i].importance = parseOutput.importance;
}
return banners;
},
/**
* Finds the WikiProject templates in the provided text and returns
* them, split into arrays.
* Note that this function uses some concepts and content, particularly the
* regular expression, from [[User:Outriggr/metadatatest.js]] (which has since
* been deleted).
* @param {String} text - the text from which templates will be found
* @return {Array} templates - the templates' text, split by parameter
*/
findProjects: function findProjects (text) {
var templates = [];
// re matches most WikiProject banner templates
var re = /\{\{\s*(wikiproject[ _]\w[^\{\}]*|\w+[^\|\{\}]*?\s*\|(?:[^\{\}]*\|)?\s*(?:class|importance|priority)\s*=\s*\w?[^\{\}]*)\}\}/i;
var match; // the current match object
var tl; // the current template found
while ((match = text.match(re))) {
tl = match[1];
tl = tl.split('|');
templates.push(tl);
text = text.replace(match[0], ''); // prevent templates from being found more than once
}
return templates;
},
/**
* Takes a template array and finds its class and importance parameters.
* @param {Array} template - a single template, split by parameter
* @return {Object} rating, importance - contains the template's class= and
* and importance/priority= parameters
*/
parseTemplate: function parseTemplate (template) {
var classParam = '';
var importance = '';
var match;
for (var i = 0; i < template.length; i++) {
match = template[i].match(/^\s*class\s*=\s*(\w+)/i);
if (match)
classParam = match[1].toLowerCase();
match = template[i].match(/^\s*(?:priority|importance)\s*=\s*(\w+)/i);
if (match)
importance = match[1].toLowerCase();
if (classParam && importance)
break;
}
return {rating: classParam, importance: importance};
},
/**
* Used to determine the name of a template. This prevents two uses of the
* same template from being interpreted differently due to minor formatting
* differences.
* @param {String} rawName - the template contents before the first parameter
* @return {String} name - the name of the template
*/
templateName: function templateName (rawName) {
var name = rawName.toString();
var match = name.match(/^\s*(?:[Tt]emplate\:)?(\w[\w \-\(\)\&\/\:\.\']+\w)\s*$/);
if (!match) return ""; // invalid template name
name = match[1].replace('_', ' ');
name = name[0].toUpperCase() + name.substring(1); // capitalize first letter
return name;
}
};
// Hook the project banners function onto the request
if(assessment.addHook) {
assessment.addHook("onCompletedRequest", function () {
assessment.banners.runProjectBanners.call(assessment.banners);
});
}
} else {
mw.log.error('Problem with load order of scripts. `assessment` not found.'); // perhaps use mw.notify here if this is a problem?
}