User:LordVoldemort728/common.js
//
( function ( $, mw ) {
mw.loader.load( "jquery.chosen" );
mw.loader.load( "mediawiki.ui.input", "text/css" );
var afdcCategories = { "m": "Media and music", "o": "Organization, corporation, or product", "b": "Biographical", "s": "Society topics", "w": "Web or Internet", "g": "Games or sports", "t": "Science and technology", "f": "Fiction and the arts", "p": "Places and transportation", "i": "Indiscernible or unclassifiable topic", "u": "Not sorted yet" };
var ADVERTISEMENT = " (assisted)";
var currentAfdcCat = "";
var currentDelsortCategories = [];
if ( mw.config.get( "wgPageName" ).indexOf("Wikipedia:Articles_for_deletion/") != -1 &&
mw.config.get( "wgPageName" ).indexOf("Wikipedia:Articles_for_deletion/Log/") == -1) {
var portletLink = mw.util.addPortletLink("p-cactions", "#", "Delsort", "pt-delsort", "Perform deletion sorting");
// Load list of delsort categories
var delsortCategoriesPromise = $.ajax( {
url: "https://en.wikipedia.org/w/index.php?action=raw&title=" + encodeURIComponent( "Wikipedia:WikiProject Deletion sorting/Computer-readable.json" ) + "&maxage=86400&smaxage=86400",
dataType: "json"
} )
$( portletLink ).click( function ( e ) {
e.preventDefault();
// Validation for new custom fields
var validateCustomCat = function ( container ) {
var categoryName = container.children( "input" ).first().val();
$.getJSON(
mw.util.wikiScript("api"),
{
format: "json",
action: "query",
prop: "pageprops",
titles: "Wikipedia:WikiProject Deletion sorting/" + categoryName
}
).done( function ( data ) {
var setStatus = function ( status ) {
var text = "Not sure";
var imageSrc = "https://upload.wikimedia.org/wikipedia/commons/a/ad/Question_mark_grey.png";
switch( status ) {
case "d":
text = "Doesn't exist";
imageSrc = "https://upload.wikimedia.org/wikipedia/commons/5/5f/Red_X.svg";
break;
case "e":
text = "Exists";
imageSrc = "https://upload.wikimedia.org/wikipedia/commons/1/16/Allowed.svg";
break;
}
container.children( ".category-status" ).empty()
.append( $( "", { "src": imageSrc,
"style": "padding: 0 5px; width: 20px; height: 20px" } ) )
.append( text );
};
if( data && data.query && data.query.pages ) {
if( data.query.pages.hasOwnProperty( "-1" ) ) {
setStatus( "d" );
} else {
setStatus( "e" );
}
} else {
setStatus( "n" );
}
} );
};
// Define a function to add a new custom field, used below
var addCustomField = function ( e ) {
$( "
.appendTo( "#delsort-td" )
.css( "width", "100%" )
.css( "margin", "0.25em auto" )
.append( $( "" )
.attr( "type", "text" )
.addClass( "mw-ui-input mw-ui-input-inline custom-delsort-field" )
.change( function ( e ) {
validateCustomCat( $( this ).parent() );
} ) )
.append( $( "" ).addClass( "category-status" ) )
.append( " (" )
.append( $( "", { "src": "https://upload.wikimedia.org/wikipedia/commons/a/a2/Crystal_128_reload.svg",
"style": "width: 15px; height: 15px; cursor: pointer" } )
.click( function ( e ) {
validateCustomCat( $( this ).parent() );
} ) )
.append( ")" )
.append( $( "
.addClass( "mw-ui-button mw-ui-destructive mw-ui-quiet" )
.text( "Remove" )
.click( function () {
$( this ).parent().remove();
} ) );
};
$( "#mw-content-text" ).prepend(
'
'
'
AFDC | DELSORT |
---|---|
' +
' ' | ' +
' +
' ' + ' ' + ' | ' +
' ' +
'
$( "#add-custom-button" ).click( addCustomField );
$( "#close-button" ).click( function () { $( "#delsort" ).remove(); } );
var afdcHtml = "";
Object.keys( afdcCategories ).forEach( function ( code, i ) {
if ( i % 2 === 0 ) afdcHtml += "
afdcHtml += "
if ( i % 2 !== 0 ) afdcHtml += "
} );
// If there are an odd number of AFDC cats, we need to close off the last row
if ( Object.keys( afdcCategories ).length % 2 !== 0 ) afdcHtml += "";
$( "#afdc" ).html( afdcHtml );
// Build the deletion sorting categories
delsortCategoriesPromise.done( function ( delsortCategories ) {
$.each( delsortCategories, function ( groupName, categories ) {
var group = $( "
.appendTo( "#delsort select" )
.attr( "label", groupName );
$.each( categories, function ( index, category ) {
group.append( $( "
.val( category )
.text( category )
.addClass( "delsort-category" ) );
} );
} );
getWikitext( mw.config.get( "wgPageName" ) ).then( function ( wikitext ) {
autofillAfdc( wikitext );
// Autofill the delsort box
var DELSORT_RE = /:(.+?)<\/small>/g;
var DELSORT_LIST_RE = /\[\[Wikipedia:WikiProject Deletion sorting\/(.+?)\|.+?\]\]/;
var delsortMatch;
var delsortListMatch;
do {
delsortMatch = DELSORT_RE.exec( wikitext );
if( delsortMatch !== null ) {
delsortListMatch = DELSORT_LIST_RE.exec( delsortMatch[1] );
if( delsortListMatch !== null ) {
currentDelsortCategories.push( delsortListMatch[1] );
var delsortOption = document.querySelector( "option.delsort-category[value='" + delsortListMatch[1] + "']" );
if( delsortOption ) {
delsortOption.selected = true;
}
}
}
} while( delsortMatch );
// Now that we've updated the underlying
// update the visible search box
$( "#delsort select" ).trigger( "chosen:updated" );
} ); // end getWikitext
} ); // end delsortCategoriesPromise
// Initialize the special chosen.js select box
// (some code stolen from http://stackoverflow.com/a/27445788)
$( "#delsort select" ).chosen();
$( "#delsort .chzn-container" ).css( "text-align", "left" );
// Add the button that triggers sorting
$( "#delsort" ).append( $( "
.css( "text-align", "center" )
.append( $( "
.addClass( "mw-ui-button" )
.addClass( "mw-ui-progressive" )
.attr( "id", "sort-button" )
.text( "Save changes" )
.click( function () {
// Make a status list
$( "#delsort" ).append( $( "
- ")
- " )
.appendTo( "#delsort ul#status" )
.html( newStatus );
}
/*
* Adds some notices to the discussion page that this discussion was sorted.
*/
function postDelsortNoticesAndUpdateAfdc( cats, afdcTarget ) {
var changingAfdcCat = currentAfdcCat.toLowerCase() !== afdcTarget,
deferred = $.Deferred(),
statusElement = showStatus( "Updating the discussion page..." );
getWikitext( mw.config.get( "wgPageName" ) ).then( function ( wikitext ) {
try {
statusElement.html( "Processing wikitext..." );
// Process wikitext
// First, add delsort notices
wikitext += createDelsortNotices( cats );
// Then, update the AFDC category
var afdcMatch = wikitext.match( /REMOVE THIS TEMPLATE WHEN CLOSING THIS AfD/ );
if ( afdcMatch && afdcMatch[ 0 ] ) {
var afdcMatchIndex = wikitext.indexOf( afdcMatch[ 0 ] ) + afdcMatch[ 0 ].length,
charAfterTemplateName = wikitext[ afdcMatchIndex ];
if ( charAfterTemplateName === "}" ) {
wikitext = wikitext.slice( 0, afdcMatchIndex ) + "|" + afdcTarget.toUpperCase() + wikitext.slice( afdcMatchIndex );
} else if ( charAfterTemplateName === "|" ) {
wikitext = wikitext.replace( "|" + currentAfdcCat + "}}", "|" + afdcTarget.toUpperCase() + "}}" );
}
}
statusElement.html( "Processed wikitext. Saving..." );
var catPlural = ( cats.length === 1 ) ? "" : "s";
$.ajax( {
url: mw.util.wikiScript( "api" ),
type: "POST",
dataType: "json",
data: {
format: "json",
action: "edit",
title: mw.config.get( "wgPageName" ),
summary: "Updating nomination page with notices" + ( changingAfdcCat ? " and new AFDC cat" : "" ) + ADVERTISEMENT,
token: mw.user.tokens.get( "csrfToken" ),
text: wikitext
}
} ).done ( function ( data ) {
if ( data && data.edit && data.edit.result && data.edit.result == "Success" ) {
statusElement.html( cats.length + " notice" + catPlural + " placed on the discussion!" );
if ( changingAfdcCat ) {
if ( currentAfdcCat ) {
var formattedCurrentAfdcCat = currentAfdcCat.length === 1 ? afdcCategories[ currentAfdcCat.toLowerCase() ] : currentAfdcCat;
showStatus( "Discussion's AFDC category was changed from " + formattedCurrentAfdcCat + " to " + afdcCategories[ afdcTarget ] + "." );
} else {
showStatus( "Discussion categorized under " + afdcCategories[ afdcTarget ] + " with AFDC." );
}
}
deferred.resolve();
} else {
statusElement.html( "While editing the current discussion page, the edit query returned an error. =(" );
deferred.reject();
}
} ).fail ( function() {
statusElement.html( "While editing the current discussion page, the AJAX request failed." );
deferred.reject();
} );
} catch ( e ) {
statusElement.html( "While getting the current page content, there was an error." );
console.log( "Current page content request error: " + e.message );
deferred.reject();
}
} ).fail( function () {
statusElement.html( "While getting the current content, there was an AJAX error." );
deferred.reject();
} );
return deferred;
}
/*
* Turns a list of delsort categories into a number of delsort template notice substitutions.
*/
function createDelsortNotices( cats ) {
if ( Array.isArray(cats) && ! cats.length ) return '';
var appendText = "\n{{subst:Deletion sorting/multi";
cats.forEach( function ( cat ) {
appendText += "|" + cat;
} );
return appendText + "|sig=~~" + "~~}}"; // string concat to prevent it from being transformed into my signature
}
/*
* Adds a listing at the DELSORT page for the category.
*/
function listAtDelsort( cat ) {
// Make a status element just for this category
var statusElement = showStatus( "Listing this discussion at DELSORT/" +
cat + "..." );
// Clarify our watchlist behavior for this edit
var allowedWatchlistBehaviors = ["watch", "unwatch", "preferences",
"nochange"];
var watchlistBehavior = "nochange"; // no watchlist change by default
if( window.delsortWatchlist && allowedWatchlistBehaviors.indexOf(
window.delsortWatchlist.toLowerCase() ) >= 0 ) {
watchlistBehavior = window.delsortWatchlist.toLowerCase();
}
var listTitle = "Wikipedia:WikiProject Deletion sorting/" + cat;
// First, get the current wikitext for the DELSORT page
return $.getJSON(
mw.util.wikiScript("api"),
{
format: "json",
action: "query",
prop: "revisions",
rvprop: "content",
rvslots: "main",
rvlimit: 1,
titles: listTitle,
redirects: "true",
formatversion: 2,
}
).then( function ( data ) {
var wikitext = data.query.pages[0].revisions[0].slots.main.content;
var properTitle = data.query.pages[0].title;
try {
statusElement.html( "Got the DELSORT/" + cat + " listing wikitext, processing..." );
// Actually edit the content to include the new listing
var newDelsortContent = wikitext.replace("directly below this line -->", "directly below this line -->\n\{\{" + mw.config.get("wgPageName") + "\}\}");
// Then, replace the DELSORT listing with the new content
$.ajax( {
url: mw.util.wikiScript( "api" ),
type: "POST",
dataType: "json",
data: {
format: "json",
action: "edit",
title: properTitle,
summary: "Listing " + mw.config.get("wgPageName") + "" + ADVERTISEMENT,
token: mw.user.tokens.get( "csrfToken" ),
text: newDelsortContent,
watchlist: watchlistBehavior
}
} ).done ( function ( data ) {
if ( data && data.edit && data.edit.result && data.edit.result == "Success" ) {
statusElement.html( "Listed page at the " + cat + " deletion sorting list!" );
} else {
statusElement.html( "While listing at DELSORT/" + cat + ", the edit query returned an error. =(" );
}
} ).fail ( function() {
statusElement.html( "While listing at DELSORT/" + cat + ", the ajax request failed." );
} );
} catch ( e ) {
statusElement.html( "While getting the DELSORT/" + cat + " content, there was an error." );
console.log( "DELSORT content request error: " + e.message );
//console.log( "DELSORT content request response: " + JSON.stringify( data ) );
}
} ).fail( function () {
statusElement.html( "While getting the DELSORT/" + cat + " content, there was an AJAX error." );
} );
}
/**
* Gets the wikitext of a page with the given title (namespace required).
*/
function getWikitext( title ) {
return $.getJSON(
mw.util.wikiScript("api"),
{
format: "json",
action: "query",
prop: "revisions",
rvprop: "content",
rvslots: "main",
rvlimit: 1,
titles: title,
formatversion: 2,
}
).then( function ( data ) {
return data.query.pages[0].revisions[0].slots.main.content;
} );
}
/**
* Removes duplicates from an array.
*/
function removeDups( arr ) {
var obj = {};
for( var i = 0; i < arr.length; i++ ) {
obj[arr[i]] = 0;
}
return Object.keys( obj );
}
}( jQuery, mediaWiki ) );
//
importScript('User:Wugapodes/Capricorn.js'); // Backlink: User:Wugapodes/Capricorn.js
importScript('User:Chlod/Scripts/Coordinator.js'); // Backlink: User:Chlod/Scripts/Coordinator.js
importScript('User:SD0001/AFC-submit-wizard.js'); // Backlink: User:SD0001/AFC-submit-wizard.js
importScript('User:SD0001/AFC-submit-wizard2.js'); // Backlink: User:SD0001/AFC-submit-wizard2.js
importScript('User:Awesome Aasim/xfdvote.js'); // Backlink: User:Awesome Aasim/xfdvote.js
importScript('User:Awesome Aasim/redirectcreator.js'); // Backlink: User:Awesome Aasim/redirectcreator.js
importScript('User:Guywan/Scripts/12HourFormat.js'); // Backlink: User:Guywan/Scripts/12HourFormat.js
importScript('User:DannyS712/RemindMe.js'); // Backlink: User:DannyS712/RemindMe.js
importScript('User:Bility/statusupdate.js'); // Backlink: User:Bility/statusupdate.js
importScript('User:LordVoldemort728/code0.js'); // Backlink: User:LordVoldemort728/code0.js
importScript('User:Evad37/OneClickArchiver.js'); // Backlink: User:Evad37/OneClickArchiver.js
importScript('User:Technical_13/Scripts/OneClickArchiver.js'); // Backlink: User:Technical_13/Scripts/OneClickArchiver.js
importScript('User:LordVoldemort728/Capricorn.js'); // Backlink: User:LordVoldemort728/Capricorn.js
importScript('User:DannyS712/copyvio-check.js'); // Backlink: User:DannyS712/copyvio-check.js
importScript('User:Lourdes/PageCuration.js'); // Backlink: User:Lourdes/PageCuration.js
importScript('User:MPGuy2824/MoveToDraft.js'); // Backlink: User:MPGuy2824/MoveToDraft.js
importScript('User:Evad37/rater.js'); // Backlink: User:Evad37/rater.js
importScript('User:Phlsph7/HighlightUnreferencedPassages.js'); // Backlink: User:Phlsph7/HighlightUnreferencedPassages.js
importScript('User:Theopolisme/Scripts/adminhighlighter.js'); // Backlink: User:Theopolisme/Scripts/adminhighlighter.js
importScript('User:Ale_jrb/Scripts/statusCheck.js'); // Backlink: User:Ale_jrb/Scripts/statusCheck.js
importScript('User:Ale jrb/Scripts/statusCheck.js'); // Backlink: User:Ale jrb/Scripts/statusCheck.js
importScript('User:Enterprisey/AFCRHS.js'); // Backlink: User:Enterprisey/AFCRHS.js
importScript('User:Novem Linguae/Scripts/ReviewStatus.js'); // Backlink: User:Novem Linguae/Scripts/ReviewStatus.js
importScript('User:Novem Linguae/Scripts/DraftCleaner.js'); // Backlink: User:Novem Linguae/Scripts/DraftCleaner.js
importScript('User:Anomie/hide-images.js'); // Backlink: User:Anomie/hide-images.js
.attr( "id", "status" ) );
// Build a list of categories
var categories = $( "#delsort select" ).val() || [];
$( ".custom-delsort-field" ).each( function ( index, element ) {
categories.push( $( element ).val() );
} );
categories = categories.filter( Boolean ); // remove empty strings
categories = removeDups( categories );
// Only allow categories that aren't already there
categories = categories.filter( function ( elem ) {
return currentDelsortCategories.indexOf( elem ) < 0;
} );
// Obtain the target AFDC category, brought to you by http://stackoverflow.com/a/24886483/1757964
var afdcTarget = document.querySelector("input[name='afdc']:checked").value;
// Actually do the delsort
saveChanges( categories, afdcTarget );
} ) ) );
} );
} // End if ( mw.config.get( "wgPageName" ).indexOf('Wikipedia:Articles_for_deletion/') ... )
/*
* Autofills the AFDC radio button group based on the current
* page's wikitext
*/
function autofillAfdc( wikitext ) {
var regexMatch = /REMOVE THIS TEMPLATE WHEN CLOSING THIS AfD(?:\|(.*))?}}/.exec( wikitext );
if ( regexMatch ) {
var templateParameter = regexMatch[1];
if ( templateParameter ) {
currentAfdcCat = templateParameter;
if ( templateParameter.length === 1 ) {
var currentClass = templateParameter.toLowerCase();
$( "#afdc-" + currentClass ).prop( "checked", true );
}
}
}
}
/*
* Saves the changes to the current discussion page by adding delsort notices (if applicable) and updating the AFDC cat
*/
function saveChanges( cats, afdcTarget ) {
var changingAfdcCat = currentAfdcCat.toLowerCase() !== afdcTarget;
// Indicate to the user that we're doing some deletion sorting
$( "#delsort-table" ).remove();
$( "#delsort #sort-button" )
.text( "Sorting " + ( changingAfdcCat ? "and categorizing " : "" ) + "discussion..." )
.prop( "disabled", true )
.fadeOut( 400, function () {
$( this ).remove();
} );
var categoryTitleComponent = ( cats.length === 1 ) ? ( "the \"" + cats[0] + "\" category" ) : ( cats.length + " categories" );
var afdcTitleComponent = changingAfdcCat ? " and categorizing it as " + afdcCategories[ afdcTarget ] : "";
$( "#delsort-title" )
.html( "Sorting discussion into " + categoryTitleComponent + afdcTitleComponent + "" );
// Start the animation, using super-advanced techniques
var animationInterval = setInterval( function () {
$( "#delsort-dots" ).text( $( "#delsort-dots" ).text() + "." );
if( $( "#delsort-dots" ).text().length > 3 ) {
$( "#delsort-dots" ).text( "" );
}
}, 600 );
// Place (a) notification(s) on the discussion and update its AFDC cat
var editDiscussionDeferred = postDelsortNoticesAndUpdateAfdc( cats, afdcTarget );
// List the discussion at the DELSORT pages
var deferreds = cats.map( listAtDelsort );
// We still have to wait for the discussion to be edited
deferreds.push( editDiscussionDeferred );
// When everything's done, say something
$.when.apply( $, deferreds ).then( function () {
// Call the done hook
if( window.delsortDoneHook ) {
window.delsortDoneHook();
}
// We're done!
$( "#delsort-title" )
.text( "Done " + ( changingAfdcCat ? "updating the discussion's AFDC category and " : "" ) + "sorting discussion into " + categoryTitleComponent + "." );
showStatus( "Done! " + ( changingAfdcCat ? "The discussion's AFDC was updated and it was" : "Discussion was" ) + " sorted into " + categoryTitleComponent + ". (" )
.append( $( "" )
.text( "reload" )
.attr( "href", "#" )
.click( function () { document.location.reload( true ); } ) )
.append( ")" );
clearInterval( animationInterval );
} );
}
/*
* Adds a new status to the status list, and returns the newly-displayed element.
*/
function showStatus( newStatus ) {
return $( "