From 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.

//<nowiki>

( function ( $, mw ) {

    const MAIN_BRFA_PAGE = "Wikipedia:Bots/Requests_for_approval";

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

    const TEMPLATE_PAGE = "User:Enterprisey/easy-brfa.js/tpl-form.js";



    mw.loader.load( "jquery.chosen" );

    mw.loader.load( "mediawiki.api" );

    mw.loader.load( "mediawiki.ui.input", "text/css" );

    mw.loader.load( "mediawiki.ui.button", "text/css" );



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

    if ( currPageName === MAIN_BRFA_PAGE ) {

        $( "table.collapsible" ).first().replaceWith( "<br /><a href='//en.wikipedia.org/wiki/" + TRIGGER_PAGE + "'><span class='mw-ui-button mw-ui-progressive mw-ui-big' role='button'>Make a new request</span></a><br />" );

        return;

    } else if ( currPageName !== TRIGGER_PAGE ) {

        return;

    }



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

    $( "<div>" )

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

	.addClass( "warningbox" )

	.text( "Loading..." )

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



    // Load and display form

    $.getJSON(

        mw.util.wikiScript( 'api' ),

        {

            format: 'json',

            action: 'query',

            prop: 'revisions',

            rvprop: 'content',

            rvlimit: 1,

            titles: TEMPLATE_PAGE

        }

    ).done( function ( data ) {

        const MARKER = "<!-- -------------------------------------------------------- -->";

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

        var formAndTemplate = data.query.pagespageId].revisions0]['*'];

        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;

                $( "<span>" )

                    .addClass( "submit-error-message" )

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

                    .insertAfter( $( this ) );

                return;

            }



            $( "<ul>" ).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( requiredTextInputIdsi ).value ) {

                return false;

            }

        }



        return true;

    }



    /*

     * Returns a Deferred that resolves with a true if the given page exists

     * and a false if it doesn't.

     */

    function doesPageExist( pageTitle ) {

        var result = $.Deferred();

        $.ajax( {

            url: mw.util.wikiScript( 'api' ),

            dataType: 'json',

            data: {

                format: 'json',

                action: 'query',

                titles: pageTitle

            }

        } ).done ( function ( data ) {

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

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

            }

        } );

        return result;

    }



    function showStatus( newStatus ) {

        return $( "<li>" )

            .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 ) {

        var deferred = $.Deferred();



        const HEADER = "<noinclude>[[Category:Open Wikipedia bot requests for approval|{{subst:#invoke:BRFA|botNameNumber}}]]</noinclude>\n=={{subst:#invoke:BRFA|userpageLink}}==\n{{subst:#invoke:BRFA|newbotTemplate}}\n\n'''Operator:''' {{botop|{{subst:currentuser}}}}\n\n'''Time filed:''' {{subst:Currentdate}}\n";



        // Do the template

        var brfaText = HEADER + brfaTemplate;

        for ( var fieldName in formData ) {

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

        }



        // Get the subpage name

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

            formData"bot-name" +

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



        // Create the BRFA

        ( new mw.Api() ).postWithEditToken( {

            action: "edit",

            title: pageTitle,

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

            text: brfaText

        } ).done ( function ( data ) {

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

                showStatus( "BRFA subpage created at <a href='" + mw.util.getUrl( pageTitle ) + "'>" + pageTitle + "</a>!" );

                deferred.resolve();

            } else {

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

                deferred.reject();

            }

        } ).fail ( function() {

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

            deferred.reject();

        } );

        return deferred;

    }



    /*

     * Transcludes the BRFA.

     */

    transcludeBrfa = function ( botName, taskNumber ) {

        var deferred = $.Deferred();



        // 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;

        $.getJSON(

            mw.util.wikiScript('api'),

            {

                format: 'json',

                action: 'query',

                prop: 'revisions',

                rvprop: 'content',

                rvlimit: 1,

                titles: "Wikipedia:Bots/Requests for approval"

            }

        ).done( function ( data ) {

            try {

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

                wikitext = data.query.pagespageId].revisions0]['*'];



                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

                $.ajax( {

                    url: mw.util.wikiScript( 'api' ),

                    type: 'POST',

                    dataType: 'json',

                    data: {

                        format: 'json',

                        action: 'edit',

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

                        summary: "Transcluding the BRFA for " + botName + " ([[User:APerson/easy-brfa|easy-brfa]])",

                        token: mw.user.tokens.get( 'csrfToken' ),

                        text: newBrfaContent

                    }

                } ).done ( function ( data ) {

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

                        statusElement.html( "Transcluded page on <a href=" + mw.util.getUrl( "WP:BRFA" ) + ">WP:BRFA</a>!" );

                        deferred.resolve();

                    } else {

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

                        deferred.reject();

                    }

                } ).fail ( function() {

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

                    deferred.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 ) );

                deferred.reject();

            }

        } ).fail( function () {

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

            deferred.reject();

        } );

        return deferred;

    };



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

    function isNormalInteger( str ) {

        var n = ~~Number( str );

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

    }

}( jQuery, mediaWiki ) );

//</nowiki>