User:Enterprisey/easy-brfa.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:Enterprisey/easy-brfa. |
//<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.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;
$( "<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( requiredTextInputIds[i] ).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 + "))", 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
( 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.edit && data.edit.result && data.edit.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.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
$.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.edit && data.edit.result && data.edit.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>