MediaWiki:Easy-brfa.js

//

$.when( $.ready, mw.loader.using( [ "mediawiki.api"] ) ).then( function () {

const MAIN_BRFA_PAGE = "Wikipedia:Bots/Requests_for_approval";

const TRIGGER_PAGE = "Wikipedia:Bots/Requests_for_approval/request";

const TEMPLATE_PAGE = "MediaWiki:Easy-brfa.js/tpl-form.js";

mw.loader.load( ["mediawiki.ui.input", "mediawiki.ui.button"] );

const api = new mw.Api();

var currPageName = mw.config.get( "wgPageName" );

if ( currPageName === MAIN_BRFA_PAGE ) {

$( "table.collapsible" ).first().replaceWith( "
Make a new request
" );

return;

} else if ( currPageName !== TRIGGER_PAGE ) {

return;

}

$( "#easy-brfa-form" ).empty();

$( "

" )

.attr( "id", "loading-message" )

.addClass( "warningbox" )

.text( "Loading..." )

.appendTo( "#easy-brfa-form" );

// Load and display form

api.get({

format: 'json',

action: 'query',

prop: 'revisions',

rvprop: 'content',

rvlimit: 1,

titles: TEMPLATE_PAGE

}).then( function ( data ) {

const MARKER = "";

var pageId = Object.keys(data.query.pages)[0];

var formAndTemplate = data.query.pages[pageId].revisions[0]['*'];

var formMarkup = formAndTemplate.substr(0, formAndTemplate.indexOf(MARKER));

var brfaTemplate = formAndTemplate.substring(formAndTemplate.indexOf(MARKER) + MARKER.length);

$( "#easy-brfa-form #loading-message" ).remove();

$( "#easy-brfa-form" ).append( formMarkup );

// Validation logic for the bot name and task number

$( "#bot-name, #task-number" ).on( "input", function () {

var botName = document.getElementById( "bot-name" ).value;

var taskNum = document.getElementById( "task-number" ).value;

// Validate bot name

doesPageExist( "User:" + botName ).then( function ( userPageExists ) {

$( "#bot-name-status" )

.removeClass( "pass fail" )

.addClass( userPageExists ? "pass" : "fail" )

.text( userPageExists ? "Bot user page exists." : "No user page exists for that bot!" );

} );

// Validate bot number as a number

if( !isNormalInteger( taskNum ) ) {

$( "#task-number-status" )

.removeClass( "pass fail" )

.addClass( "fail" )

.text( "Invalid task number." );

} else {

// Check if bot number is being used

var title = "Wikipedia:Bots/Requests for approval/" +

$( "#bot-name" ).val() + ( taskNum === "1" ? "" : " " + taskNum );

doesPageExist( title ).then( function ( brfaExists ) {

$( "#task-number-status" )

.removeClass( "pass fail" )

.addClass( brfaExists ? "fail" : "pass" )

.text( brfaExists ? "There's already a BRFA with that task number!" : "Task number valid." );

document.getElementById( "submit-brfa" ).disabled = !isFormReady();

} );

}

document.getElementById( "submit-brfa" ).disabled = !isFormReady();

} );

// Validation handler for text fields

$( "#easy-brfa-form input[type=text], #easy-brfa-form textarea" ).each( function () {

$( this ).on( "input", function () {

document.getElementById( "submit-brfa" ).disabled = !isFormReady();

} );

} );

$( "#easy-brfa-form input[type=radio]" ).each( function () {

$( this ).on( "click", function () {

document.getElementById( "submit-brfa" ).disabled = !isFormReady();

} );

} );

// Event handler

$( "#submit-brfa" ).click( function () {

if( !isFormReady() ) {

$( this ).disabled = true;

$( "" )

.addClass( "submit-error-message" )

.text( "Fill out the missing form fields before you submit!" )

.insertAfter( $( this ) );

return;

}

$( "

    " ).attr( "id", "status-list" ).appendTo("#easy-brfa-form" );

    $( "#submit-brfa" )

    .text( "Submitting..." )

    .prop( "disabled", true );

    // Build form data

    var formData = {};

    $( "#easy-brfa-form input[type=text], #easy-brfa-form textarea" ).each( function () {

    formData[$( this ).attr( "id" )] = $( this ).val();

    } );

    $( "#easy-brfa-form input[type=checkbox]" ).each( function () {

    formData[$( this ).attr( "id" )] = $( this ).is(':checked') ? "Yes" : "No";

    } );

    formData.operation = $('input[name=operation]:checked').val();

    // Send the requests

    $.when(

    createBrfa( brfaTemplate, formData )

    ).then( function () {

    $.when(

    transcludeBrfa( formData["bot-name"], formData["task-number"] )

    ).then( function () {

    showStatus("Woohoo! We're done.");

    $( "#submit-brfa" ).text( "Submitted!" );

    } );

    } );

    } ); // end submit handler

    } ); // end form load handler

    /*

    * Is the form ready for submission?

    */

    function isFormReady() {

    // Check validated fields - any statuses marked with the fail class?

    if( document.querySelector( ".validation-status.fail" ) ) {

    return false;

    }

    // Is an operation mode selected?

    if( !document.querySelector('input[name=operation]:checked') ) {

    return false;

    }

    // Is text entered in each of the textboxes and textareas?

    var requiredTextInputIds = ["function-overview", "edit-period", "pages-affected", "function-details"];

    for( var i = 0; i < requiredTextInputIds.length; i++ ) {

    if( !document.getElementById( requiredTextInputIds[i] ).value ) {

    return false;

    }

    }

    return true;

    }

    /*

    * Returns a promise that resolves to true if the given page exists

    * and to false if it doesn't.

    */

    function doesPageExist( pageTitle ) {

    return api.get( {

    format: 'json',

    action: 'query',

    titles: pageTitle

    } ).then ( function ( data ) {

    if( data && data.query && data.query.pages ) {

    return !data.query.pages.hasOwnProperty( "-1" );

    }

    } );

    }

    function showStatus( newStatus ) {

    return $( "

  • " )

    .appendTo( "#easy-brfa-form ul" )

    .html( newStatus );

    }

    /*

    * Templates in the form responses to create a BRFA, then saves it to the BRFA subpage.

    */

    function createBrfa( brfaTemplate, formData ) {

    const HEADER = "Category:Open Wikipedia bot requests for approval\n=={{subst:#invoke:BRFA|userpageLink}}==\n{{subst:#invoke:BRFA|newbotTemplate}}\n\nOperator: {{botop|{{subst:currentuser}}}}\n\nTime filed: {{subst:Currentdate}}\n";

    // Do the template

    var brfaText = HEADER + brfaTemplate;

    for ( var fieldName in formData ) {

    brfaText = brfaText.replace("((" + fieldName + "))", formData[fieldName]);

    }

    // Get the subpage name

    var pageTitle = "Wikipedia:Bots/Requests for approval/" +

    formData["bot-name"] +

    ( (formData["task-number"] == 1) ? "" : (" " + formData["task-number"] ) );

    // Create the BRFA

    return api.postWithEditToken( {

    action: "edit",

    title: pageTitle,

    summary: "Creating a BRFA subpage for " + formData["bot-name"] + " (easy-brfa)",

    text: brfaText

    } ).then ( function ( data ) {

    if ( data && data.edit && data.edit.result && data.edit.result == 'Success' ) {

    showStatus( "BRFA subpage created at " + pageTitle + "!" );

    } else {

    showStatus( "While creating BRFA subpage, the edit query returned an error. =(" );

    return Promise.reject();

    }

    } ).catch ( function() {

    showStatus( "While creating BRFA subpage, the AJAX request failed." );

    return Promise.reject();

    } );

    }

    /*

    * Transcludes the BRFA.

    */

    transcludeBrfa = function ( botName, taskNumber ) {

    // Make a status element just for this edit

    var statusElement = showStatus( "Transcluding at WP:BRFA..." );

    // First, get the current wikitext for WP:BRFA

    var wikitext;

    return api.get({

    format: 'json',

    action: 'query',

    prop: 'revisions',

    rvprop: 'content',

    rvlimit: 1,

    titles: "Wikipedia:Bots/Requests for approval"

    }).then( function ( data ) {

    try {

    var pageId = Object.keys(data.query.pages)[0];

    wikitext = data.query.pages[pageId].revisions[0]['*'];

    statusElement.html( "Got WP:BRFA wikitext, processing..." );

    // Actually edit the content to include the new listing

    var taskNumberString = (taskNumber == 1) ? "" : (taskNumber + "");

    var newBrfaContent = wikitext.replace('directly below this message. -->', 'directly below this message. -->\n\{\{BRFA|' + botName + "|" + taskNumberString + '|Open\}\}');

    // Then, replace WP:BRFA with the new content

    return api.postWithEditToken( {

    format: 'json',

    action: 'edit',

    title: "Wikipedia:Bots/Requests for approval",

    summary: "Transcluding the BRFA for " + botName + " (easy-brfa)",

    text: newBrfaContent

    } ).then ( function ( data ) {

    if ( data && data.edit && data.edit.result && data.edit.result == 'Success' ) {

    statusElement.html( "Transcluded page on WP:BRFA!" );

    } else {

    statusElement.html( "While transcluding on BRFA, the edit query returned an error. =(" );

    return Promise.reject();

    }

    } ).catch ( function() {

    statusElement.html( "While transcluding on BRFA, the ajax request failed." );

    return Promise.reject();

    } );

    } catch ( e ) {

    statusElement.html( "While transcluding on BRFA, there was an error." );

    console.log( "BRFA content request error: " + e.message );

    console.log( "BRFA content request response: " + JSON.stringify( data ) );

    return Promise.reject();

    }

    } ).catch( function () {

    statusElement.html( "While getting the BRFA content, there was an AJAX error." );

    return Promise.reject();

    } );

    };

    // From http://stackoverflow.com/a/10834843/1757964

    function isNormalInteger( str ) {

    var n = ~~Number( str );

    return String( n ) === str && n >= 0;

    }

    } );

    //