// <nowiki>
$( function () {
var ADVERT = " ([[User:Enterprisey/cv-revdel|cv-revdel]])";
var SUMMARY = "Requesting copyvio revdel" + ADVERT;
var SUMMARY_TALK = "Add note about recent copyvio" + ADVERT;
var CCLEAN_TPL = "Cclean";
var pageName; // Current page name
var urlCounter = 1;
var api;
/**
* Make a link to a given oldid of the current page.
*/
function makeOldidLink( oldid ) {
var href = "/w/index.php?title=" + encodeURIComponent( pageName ) +
"&oldid=" + oldid;
var link = document.createElement( "a" );
link.href = href;
link.textContent = oldid;
return link;
}
/**
* Add the appropriate copyvio-revdel template to the current page.
*/
function addCvRevdel( urls ) {
var deferred = $.Deferred();
var template = "{" + "{copyvio-revdel";
template += urls.map( function ( u, idx ) {
var num = idx == 0 ? "" : ( idx + 1 );
return "|url" + num + "=" + u;
} ).join( "" );
var rows = document.querySelectorAll( "#cv-revdel tr" );
var num;
for( var i = 1, n = rows.length; i < n; i++ ) {
template += "|start" + i + "=" + rows[i].childNodes[0].textContent
+ ( rows[i].childNodes[2].childNodes[0].checked ? ( "|end" + i + "=" + rows[i].childNodes[1].textContent ) : "" );
}
template += "}}";
api.postWithToken( "csrf", {
action: "edit",
title: pageName,
summary: SUMMARY,
prependtext: template + "\n"
} ).done( function ( d ) {
if( d && d.edit && d.edit.result && d.edit.result == "Success" ) {
$( "#cv-rd-status" ).text( "Success!" );
deferred.resolve();
} else if( d && d.error ) {
$( "#cv-rd-status" ).html( "Error! Edit failed: " + d.error.info );
console.log( d );
deferred.reject();
} else {
$( "#cv-rd-status" ).html( "Error! Edit failed." );
console.log( d );
deferred.reject();
}
} ).fail( function ( code, result ) {
console.log( code, result );
if( result && result.error && result.error.spamblacklist ) {
$( "#cv-rd-status" ).html( "Error! The following URLs were on the <a href='" + mw.util.getUrl( "MediaWiki:Spam-blacklist" ) + "'>spam blacklist</a>: " + result.error.spamblacklist.matches.join( ", " ) + ". Consider removing the 'https://' or 'http://' from the beginning to make them not links." );
} else {
$( "#cv-rd-status" ).html( api.getErrorMessage( result ) );
}
deferred.reject();
} );
return deferred;
}
function addCclean( urls ) {
var deferred = $.Deferred(),
template = "{" + "{subst:cclean|url=" + urls.join( " " ) + "}}",
talkNs = mw.config.get( "wgNamespaceNumber" ) | 1,
talkNsName = mw.config.get( "wgFormattedNamespaces" )[ talkNs ],
talkPage = talkNsName + ":" + mw.config.get( "wgTitle" );
api.postWithToken( "csrf", {
action: "edit",
title: talkPage,
summary: SUMMARY_TALK,
appendtext: "\n\n" + template
} ).done( function ( d ) {
if( d && d.edit && d.edit.result && d.edit.result == "Success" ) {
deferred.resolve();
} else {
deferred.reject();
console.log( d );
}
} ).fail( function ( code, result ) {
deferred.reject();
$( "#cv-rd-status" ).append( "Also, while editing " + talkPage +
", this error happened: " + api.getErrorMessage( result ) );
console.log( code, result );
} );
return deferred;
}
/**
* Load the main cv-revdel panel and add buttons/other stuff to
* the history UI
*/
function load( evt ) {
if( evt ) evt.preventDefault();
// Don't load the panel for a second time if it's already there
if( document.getElementById( "cv-revdel" ) ) return;
api = new mw.Api();
// Style for the panel
mw.util.addCSS(
"#cv-revdel { border: thin solid rgb(197, 197, 197); " +
"box-shadow: 0px 3px 8px rgba(0, 0, 0, 0.25); border-radius: 3px;" +
"padding: 2em; display: inline-block }" +
"#cv-revdel table { margin: 1em 0 }" +
"#cv-revdel td { padding: 0 0.5em }" +
"#cv-revdel a.disabled {color: gray;text-decoration: line-through;font-style: italic;}" +
"#cv-rd-submit { margin-right: 1em }"+
"#cv-rd-urls input { width: 50%; min-width: 30em; }"+
"#cv-rd-urls div { margin-bottom: 0.35em; }"+
"#cv-revdel div.bottom-row { margin-top: 1em; }"+
"#cv-rd-add-range { margin-right: 0.5em; }"
);
// Add the panel itself
var panel = document.createElement( "div" );
panel.id = "cv-revdel";
var urlHTML = "<div id='cv-rd-urls'>" +
"<div><label for='cv-rd-url0'>URL: </label><input type='text' "+
"id='cv-rd-url0' class='mw-ui-input mw-ui-input-inline'/>"+
"<button class='mw-ui-button mw-ui-quiet'>Remove</button></div>" +
"</div>"+
"<button id='cv-rd-url-add' class='mw-ui-button'>Add another</button>";
panel.innerHTML = "<p>Instructions: Select a range of revisions using " +
"the radio buttons you would normally use for comparing two " +
"revisions, then click 'Add range to revdel template' to add the " +
"range to the template. Uncheck 'Range?' to tag " +
"only the single revision in the 'Start' column. Fill in URLs, and " +
"then click 'Submit' to place the template.</p><br />" +
urlHTML + "<table id='cv-rd-ranges'><tr><th>Start</th><th>End</th>" +
"<th>Range?</th><th>Remove</th></table>" +
"<input type='checkbox' id='cv-rd-cclean' />" +
"<label for='cv-rd-cclean'>Add {{subst:<a href='" +
mw.util.getUrl( "Template:" + CCLEAN_TPL ) + "'>Cclean</a>}} to " +
( ( mw.config.get( "wgNamespaceNumber" ) % 2 ) ? "this" : "talk" ) +
" page</label><br />"+
"<div class='bottom-row'><button id='cv-rd-submit' class='mw-ui-button"+
" mw-ui-progressive'>Submit</button>" +
"<button id='cv-rd-close' class='mw-ui-button mw-ui-quiet'>Close</button>"+
"<span id='cv-rd-status'></span></div>";
document.getElementById( "bodyContent" ).insertBefore( panel,
document.getElementById( "mw-content-text" ) );
// Add range-add buttons before each of the buttons
// that say "Compare selected revisions"
var cmpSelRevsBtns = document.getElementsByClassName( "historysubmit" );
for( var i = 0, n = cmpSelRevsBtns.length; i < n; i++ ) {
var rangeBtn = document.createElement( "button" );
rangeBtn.textContent = "Add range to revdel template";
rangeBtn.className = "mw-ui-button + mw-ui-progressive";
rangeBtn.id = "cv-rd-add-range"
cmpSelRevsBtns[i].parentNode.insertBefore( rangeBtn, cmpSelRevsBtns[i] );
rangeBtn.addEventListener( "click", function ( evt ) {
evt.preventDefault();
var oldidStart = document.querySelector( "li.selected.after" ).dataset.mwRevid;
var oldidEnd = document.querySelector( "li.selected.before" ).dataset.mwRevid;
// Add new row to ranges table
var rangesTable = document.getElementById( "cv-rd-ranges" ).getElementsByTagName( "tbody" )[0];
var newRow = rangesTable.insertRow( rangesTable.rows.length );
newRow.insertCell( 0 ).appendChild( makeOldidLink( oldidStart ) );
newRow.insertCell( 1 ).appendChild( makeOldidLink( oldidEnd ) );
newRow.insertCell( 2 ).innerHTML = "<input type='checkbox' />";
newRow.cells[2].childNodes[0].checked = true;
newRow.cells[2].childNodes[0].addEventListener( "click", function () {
this.parentNode.previousElementSibling.childNodes[0].className = this.checked ? "" : "disabled";
} );
var deleteBtn = document.createElement( "button" );
deleteBtn.textContent = "Delete";
deleteBtn.className = "delete";
deleteBtn.addEventListener( "click", function () {
this.parentNode.parentNode.parentNode.removeChild(
this.parentNode.parentNode );
} );
newRow.insertCell( 3 ).appendChild( deleteBtn );
} );
}
// Panel submission handler
document.getElementById( "cv-rd-submit" ).addEventListener( "click", function () {
$( this ).prop( "disabled", true );
$( "#cv-rd-status" ).empty();
var urls = Array.prototype.map.call( document.getElementById( "cv-rd-urls" ).children,
function ( e ) { return e.children[1].value; } );
var deferreds = [ addCvRevdel( urls ) ];
if( document.getElementById( "cv-rd-cclean" ).checked ) {
deferreds.push( addCclean( urls ) );
}
$.when.apply( $, deferreds ).then( function () {
// Return to content page
document.querySelector( "#ca-view a" ).click();
}, function () {
$( this ).prop( "disabled", false );
}.bind( this ) );
} );
// "Add URL" handler
document.getElementById( "cv-rd-url-add" ).addEventListener( "click", function () {
var numUrls = document.querySelectorAll( "#cv-rd-urls div" ).length;
if( numUrls < 3 ) {
var newDiv = document.createElement( "div" );
newDiv.innerHTML = "<label for='cv-rd-url" + urlCounter + "'>URL: </label>"+
"<input type='text' id='cv-rd-url" + urlCounter +
"' class='mw-ui-input mw-ui-input-inline'/>"+
"<button class='mw-ui-button mw-ui-quiet'>Remove</button>";
document.getElementById( "cv-rd-urls" ).appendChild( newDiv );
urlCounter++;
this.disabled = numUrls >= 2;
}
} );
// Remove URL handler
document.getElementById( "cv-rd-urls" ).addEventListener( "click", function ( e ) {
var numUrls = document.querySelectorAll( "#cv-rd-urls div" ).length;
if( e.target && e.target.nodeType === 1 && numUrls > 1 &&
e.target.tagName.toLowerCase() === "button" ) {
this.removeChild( document.getElementById( e.target.previousElementSibling.getAttribute( "id" ) ).parentNode );
document.getElementById( "cv-rd-url-add" ).disabled = false;
}
} );
// Close handler
document.getElementById( "cv-rd-close" ).addEventListener( "click", function () {
$( "#cv-revdel" ).remove();
$( ".cv-rd-add-range" ).remove();
} );
document.querySelector( "#cv-rd-urls input" ).focus();
}
mw.loader.using( [ "mediawiki.api", "mediawiki.util" ], function () {
pageName = mw.config.get( "wgPageName" );
if( mw.config.get( "wgAction" ) == "history" ) {
var link = mw.util.addPortletLink( "p-cactions", "#", "Request CV revdel", "pt-cv-revdel" );
if ( link ) {
link.addEventListener( "click", load );
}
if( mw.util.getParamValue( "open_cv_revdel" ) === "true" ) {
load();
}
} else if( mw.config.get( "wgNamespaceNumber" ) >= 0 ) {
var historyPage = mw.util.getUrl( pageName, { "action": "history", "open_cv_revdel": "true" } );
var link = mw.util.addPortletLink( "p-cactions", historyPage, "Request CV revdel", "pt-cv-revdel" );
}
} );
} );
// </nowiki>