User:Pyrospirit/metadata/projectbanners.js

/** * 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? }