User:Narvip/monobook.js

Source: Wikipedia, the free encyclopedia.
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
/**
 * 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.
 */
 
/**
 * Overrides the existing empty function, set to run after the request for the
 * talk page text completes.
 */
MetadataScript.prototype.onCompletedRequest = function () {
    this.assessments = this.getProjectBanners(this.text);
    if ( this.assessments.length == 0 ) return; // no projects found
    var listDisplay = this.createAssessmentList(this.assessments);
    var button = this.makeToggle('MetadataObject.toggleBox');
    var contentSub = document.getElementById('contentSub');
    // Add the table, initially hidden
    document.getElementById('bodyContent').insertBefore(listDisplay, contentSub);
    // Add the toggle button
    document.getElementById('siteSub').appendChild(button);
};
 
/**
 * Creates the HTML code for displaying an assessment list.
 */
MetadataScript.prototype.createAssessmentList = function (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', 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 : '&ndash;';
        if ( rating ) tdRating.setAttribute('class', 'assess-' + rating);
        tdImportance = document.createElement('td');
        tdImportance.innerHTML = importance ? importance : '&ndash;';
        if ( importance ) tdImportance.setAttribute('class', 'assess-importance-' + importance);
        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
 */
MetadataScript.prototype.makeToggle = function (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', 'position: absolute; right: 0%;');
    toggle.appendChild(button);
    toggle.innerHTML = '[' + toggle.innerHTML + ']'; // add surrounding brackets
    return toggle;
};
 
/**
 * Toggles show/hide for the assessment box content.
 */
MetadataScript.prototype.toggleBox = function () {
    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.
 */
MetadataScript.prototype.setCaps = function (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
 */
MetadataScript.prototype.getProjectBanners = function (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
 */
MetadataScript.prototype.findProjects = function (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
 */
MetadataScript.prototype.parseTemplate = function (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();
    }
    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
 */
MetadataScript.prototype.templateName = function (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;
};