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.
importScript('User:Timotheus Canens/afchelper4.js');
importScript('Wikipedia:AutoEd/complete.js');
importScript('User:Dipankan001/external link.js')
importScript('User:Dipankan001/Edit Count.js');
importScript('MediaWiki:Gadget-HotCat.js');
importScript('User:Ale_jrb/Scripts/igloo.js'); // [[User:Ale_jrb/Scripts/igloo]]
importScript('User:Tim Song/afchelper4.js');
importScript('User:The_Earwig/afc-helper.js'); // AfC Redirect Helper script.
importScript('User:Quarl/util.js');
importScript('User:Quarl/wikipage.js');
importScript('Wikipedia:WikiProject User scripts/Scripts/Add LI menu');
importStylesheet('Wikipedia:WikiProject User scripts/Scripts/Add LI menu/css');
importScript('Wikipedia:WikiProject Deletion sorting/delsort.js');
importScript('User:Lupin/popups.js'); // see Wikipedia:Tools/Navigation popups
importScript('User:Dr_pda/generatestats.js'); //[[User:Dr_pda/generatestats.js]]
importScript('User:TheJosh/Scripts/NewPagePatrol.js');
npp_num_pages = 5
function movetocommons()
{
var url="http://toolserver.org/~commonshelper2/?language=en&file=" + encodeURIComponent( wgTitle ) + "&use_tusc=1&transfer_user=" + encodeURIComponent( wgUserName );
window.open(url);
}
function start()
 
{
if(wgCanonicalNamespace == "Image" || wgCanonicalNamespace == "File" || wgCanonicalNamespace == "Media" )
{
mw.util.addPortletLink("p-cactions","javascript:movetocommons()","move to commons (2)","ca-mcom2");
}
}
 
addOnloadHook(start);
importScript('User:AzaToth/twinkle.js');
// [[User:Henrik/afc-helper]]
importScript('User:Henrik/js/afc-helper.js'); 
importScript('User:Cameltrader/Advisor.js');
importScript('User:Dr_pda/prosesize.js'); //[[User:Dr_pda/prosesize.js]]
importScript('User:Shubinator/DYKcheck.js');
importScript('User:GregU/dashes.js');
importScript('User:Mr.Z-man/closeAFD.js');
importScript('User:Ale_jrb/Scripts/userhist.js');  //[[User:Ale_jrb/Scripts]]
mportScript('User:Ale_jrb/Scripts/statusCheck.js');  //[[User:Ale_jrb/Scripts]]
importScript('User:Ale_jrb/Scripts/igloo.js'); // [[User:Ale_jrb/Scripts/igloo]]

function movetocommons()
{
var url="http://toolserver.org/~magnus/commonshelper.php?interface=en&image=" + encodeURIComponent( wgTitle ) + "&lang=en&username=" + encodeURIComponent( wgUserName ) + "&tusc_user=" + encodeURIComponent(  wgUserName );
window.open(url);
}
function start()
 
{
if(wgCanonicalNamespace == "Image" || wgCanonicalNamespace == "File")
{
mw.util.addPortletLink("p-cactions","javascript:movetocommons()","move to commons","ca-mcom");
}
}
 
addOnloadHook(start);

// Add [[WP:Reflinks]] launcher in the toolbox on left
addOnloadHook(function () {
 mw.util.addPortletLink(
  "p-tb",     // toolbox portlet
  "http://toolserver.org/~dispenser/cgi-bin/webreflinks.py/" + wgPageName 
   + "?client=script&citeweb=on&overwrite=&limit=30&lang=" + wgContentLanguage,
  "Reflinks"  // link label
)});
//<pre>
//This function adds a tab which, when clicked, extracts data from an infobox and
//populates the fields of the Persondata template. See the talk page for more details.
//
//To use this function add {{subst:js|User:Dr pda/persondata.js}} to your monobook.js
//
function format_name(x){
   NAME = x.substr(x.indexOf('=')+1);
   NAME = NAME.replace(/'''?/g,'');
   NAME = NAME.replace(/^\s*/g,'');
   NAME = NAME.replace(/\s*$/g,'');
   var comma = NAME.indexOf(',');
   var start = (comma == -1) ? NAME.length : comma;
   var lastSpace = NAME.lastIndexOf(' ',start);
   if(lastSpace != -1){
     NAME = NAME.substring(lastSpace,start)+', '+NAME.substring(0,lastSpace)+NAME.substring(start);
   }
   return NAME;
}

function suggestPersonData(){
  var text = document.getElementById('wpTextbox1').value;

  //do nothing if article already contains persondata
  if(text.match(/persondata/i)) return;

  var template = '';
  var NAME = '';
  var ALTERNATIVE_NAMES = '';
  var SHORT_DESCRIPTION = '';
  var PLACE_OF_BIRTH = '';
  var DATE_OF_BIRTH = '';
  var PLACE_OF_DEATH = '';
  var DATE_OF_DEATH = '';

  //handle cases where the template name doesn't contain infobox
  text = text.replace(/{{NFL player/i,'{{NFL player infobox');
  if(text.match(/Infobox/i)){
    start = text.lastIndexOf('{{',text.indexOf('nfobox'));
    stop = text.indexOf('}}',start);
    next = text.indexOf('{{',start+1)
    //Correctly handle other templates used within the infobox
    while (next < stop && text.indexOf('{{',start+1)!= -1){
      next = text.indexOf('{{',stop+1);
      stop = text.indexOf('}}',stop+1);
    }
    template = text.substring(start,stop);

    //Remove references, birth/death date and age templates
    template = template.replace(/<ref.*(\/ref>|$)/gm,'');
    template = template.replace(/{{(?:[Bb]irth|[Dd]eath) date(?: and age)?\s?(\|\s?[md]f\s?=\s?ye?s?)?\|\s?(\d{1,4})\|\s?(\d{1,2})\|\s?(\d{1,2}).*}}/g,"$2-$3-$4");
    template = template.replace(/\[\[Image:Flag.*px\]\]/ig,'');
    template = template.replace(/{{flagicon.*}}/ig,'');
    template = template.replace(/<\/?small>/ig,'');
    template = template.replace(/<br\s*\/?>/ig,'');

    var firstpar = template.indexOf('|');
    template = template.substr(firstpar+1);

    var birthplace_in_born = false;  
    var array = template.split(/(\n\s*\||\|\s*\n)/);
    for (x=0;x<array.length;x++){
      if(array[x].match(/subject_name/i)||array[x].match(/^\s*\bname\b/i)||array[x].match(/fullname/i)){
      NAME = format_name(array[x]);
    }
    if(array[x].match(/playername/i)||array[x].match(/birth_?name/i)){
      ALTERNATIVE_NAMES = (ALTERNATIVE_NAMES == '') ? format_name(array[x]):ALTERNATIVE_NAMES + ';' + format_name(array[x]);
    }
    else if(array[x].match(/date_of_birth/i)||array[x].match(/dateofbirth/i)||array[x].match(/birthdate/i)||array[x].match(/birth_date/i)||array[x].match(/date of birth/i)||array[x].match(/datebirth/i)){
      DATE_OF_BIRTH = array[x].substr(array[x].indexOf('=')+1);
    }
    else if(array[x].match(/place_of_birth/i)||(array[x].match(/origin/i)&&birthplace_in_born==false)||array[x].match(/birthplace/i)||array[x].match(/placebirth/i)||array[x].match(/location/i)||array[x].match(/placeofbirth/i)||array[x].match(/birth_place/i)||array[x].match(/place of birth/i)){
      PLACE_OF_BIRTH = array[x].substr(array[x].indexOf('=')+1);
    }
    else if(array[x].match(/born/i)){
      var temp =  array[x].indexOf('<br');
	  if(temp != -1){
	    DATE_OF_BIRTH = array[x].substring(array[x].indexOf('=')+1,temp);
            PLACE_OF_BIRTH = array[x].substr(array[x].indexOf('>',temp)+1);
	    birthplace_in_born = true;
	  }
	  else{
	    DATE_OF_BIRTH = array[x].substring(array[x].indexOf('=')+1);
	  }
    }
    else if(array[x].match(/lived/i)){
      var temp =  array[x].substr(array[x].indexOf('=')+1);
      temp = temp.replace(/born\s*/i,'');
      var dash = temp.search(/&ndash;\s*|-\s*/);
      if(dash >=0){
        DATE_OF_BIRTH = temp.substring(0,dash);
        DATE_OF_DEATH = temp.substring(temp.indexOf(' ',dash)+1);
      }
      else{
        DATE_OF_BIRTH = temp;
      }
    }
    else if(array[x].match(/cityofbirth/i)){
      var temp =  array[x].substr(array[x].indexOf('=')+1);
      temp = temp.match(/.*/);
      PLACE_OF_BIRTH = (PLACE_OF_BIRTH == '') ? temp : temp + ' ,' + PLACE_OF_BIRTH;
    }
    else if(array[x].match(/countryofbirth/i)){
      PLACE_OF_BIRTH = (PLACE_OF_BIRTH == '') ? array[x].substr(array[x].indexOf('=')+1) : PLACE_OF_BIRTH + ',' + array[x].substr(array[x].indexOf('=')+1);
    }
    else if(array[x].match(/date_of_death/i)||array[x].match(/dateofdeath/i)||array[x].match(/deathdate/i)||array[x].match(/death_date/i)||array[x].match(/date of death/i)||array[x].match(/datedeath/i)){
      DATE_OF_DEATH = array[x].substr(array[x].indexOf('=')+1);
    }
    else if(array[x].match(/place_of_death/i)||array[x].match(/deathplace/i)||array[x].match(/placeofdeath/i)||array[x].match(/death_place/i)||array[x].match(/place of death/i)||array[x].match(/placedeath/i)){
      PLACE_OF_DEATH = array[x].substr(array[x].indexOf('=')+1);
    }
    else if(array[x].match(/died/i)){
      var temp =  array[x].indexOf('<br');
	  if(temp != -1){
	    DATE_OF_DEATH = array[x].substring(array[x].indexOf('=')+1,temp);
            PLACE_OF_DEATH = array[x].substr(array[x].indexOf('>',temp)+1);
	  }
	  else{
	    DATE_OF_DEATH = array[x].substring(array[x].indexOf('=')+1);
	  }
    }
    else if(array[x].match(/cityofdeath/i)){
      var temp =  array[x].substr(array[x].indexOf('=')+1);
      temp = temp.match(/.*/);
      PLACE_OF_DEATH = (PLACE_OF_DEATH == '') ? temp : temp + ' ,' + PLACE_OF_DEATH;
    }
    else if(array[x].match(/countryofdeath/i)){
      PLACE_OF_DEATH = (PLACE_OF_DEATH == '') ? array[x].substr(array[x].indexOf('=')+1) : PLACE_OF_DEATH + ',' + array[x].substr(array[x].indexOf('=')+1);
    }
    else if(array[x].match(/occupation/i)||array[x].match(/\bfield\b\s*=/i)||array[x].match(/office/i)){
      SHORT_DESCRIPTION = array[x].substr(array[x].indexOf('=')+1);
      SHORT_DESCRIPTION = SHORT_DESCRIPTION.replace(/\s*<br\s*\/?>\s*/g,', ');
    }
  }

  //more tidy up
  DATE_OF_BIRTH = DATE_OF_BIRTH.replace(/\(age? \d*\)/i,'');
  DATE_OF_DEATH = DATE_OF_DEATH.replace(/\(age? \d*\)/i,'');
  }
  if(NAME == ''){
      var pagename = wgPageName.replace(/_/g,' ');
      pagename = pagename.replace(/\(.*\)/g,' ');
      NAME = format_name(pagename);
  }
  if(DATE_OF_BIRTH=='' && text.match(/Category:\d* births/)){
    var catbirth = text.search(/Category:\d* births/);
    DATE_OF_BIRTH = text.substring(catbirth+9,text.indexOf('births')-1);
  } 
  if(DATE_OF_DEATH=='' && text.match(/Category:\d* deaths/)){
    var catdeath = text.search(/Category:\d* deaths/);
    DATE_OF_DEATH = text.substring(catdeath+9,text.indexOf('deaths')-1);
  } 

  //restore original text, in case this special case was found
  text = text.replace(/{{NFL player infobox/i,'{{NFL player');

  var persondata = "\n\n<!-- Metadata: see [[Wikipedia:Persondata]] -->\n{{Persondata\n|NAME="+NAME+"\n|ALTERNATIVE NAMES="+ALTERNATIVE_NAMES+"\n|SHORT DESCRIPTION="+SHORT_DESCRIPTION+"\n|DATE OF BIRTH="+DATE_OF_BIRTH+"\n|PLACE OF BIRTH="+PLACE_OF_BIRTH+"\n|DATE OF DEATH="+DATE_OF_DEATH+"\n|PLACE OF DEATH="+PLACE_OF_DEATH+"\n}}\n\n";

  var insertPosition = text.indexOf('[[Category:')-1;
  if(text.match('{{DEFAULTSORT')) insertPosition = text.indexOf('{{DEFAULTSORT')-1;
  if(insertPosition != -2){
    document.getElementById('wpTextbox1').value = text.substr(0,insertPosition)+persondata+text.substr(insertPosition+1);
  }
  else{
    alert('This article does not belong to any categories! Consider adding some.');
    document.getElementById('wpTextbox1').value = text+persondata;
  }
  document.getElementById('wpSummary').value += ' adding [[WP:PDATA|persondata]] using [[User talk:Dr pda/persondata.js|User:Dr pda/persondata.js]]';
  document.getElementById('wpDiff').click();

}

function togglePersondata() {
  var element = document.getElementById('persondata');

  if (element.style.display != 'block'){
    element.style.display = 'block';
  }
  else{
    element.style.display = 'none';
  }
}

addOnloadHook(function () {
  if(!document.forms.editform){
    if (document.getElementById('persondata') != null){
      mw.util.addPortletLink('p-cactions', 'javascript:togglePersondata()', 'show/hide persondata', 'ca-pdata', 'Show/hide persondata metadata', '', '');
    }
  }
  else{
    if (wgNamespaceNumber == 0 && document.getElementById('wpTextbox1').value.match(/persondata/i) == null){
      mw.util.addPortletLink('p-cactions', 'javascript:suggestPersonData()', 'add persondata', 'ca-pdata', 'add persondata metadata', '', '');
    }
  }
});
//</pre>

// Copied from en:user:Dr pda/prosesizebytes.js

//This function adds a link to the toolbox which, when clicked, displays the size of the page
//and the size of the prose in bytes. See the talk page for more details.
//
//To use this function add ''importScript('User:Phantomsteve/prosesizebytes.js';'' to your monobook.js
//
function loadXMLDocPassingTemplate(url,handler, page)
{
    // branch for native XMLHttpRequest object
    if (window.XMLHttpRequest) {
        var req = new XMLHttpRequest();
    }
    // branch for IE/Windows ActiveX version
    else if (window.ActiveXObject) {
        var req = new ActiveXObject("Microsoft.XMLHTTP");
   }
   if (req) {
     req.onreadystatechange = function () {handler(req, page)};
     req.open("GET", url, true);
     req.send("");
   }
}

function getWikiText(req, page) {
    // only if req shows "loaded"
    if (req.readyState == 4) {
        // only if "OK"
        if (req.status == 200) {
            // ...processing statements go here...
	 response = req.responseXML.documentElement;
         var rev = response.getElementsByTagName('rev');
	 if(rev.length > 0){
	   result = rev[0].getAttribute('size');
           result = result+'&nbsp;B';
           wiki_value = document.createElement("li");
	   wiki_value.id = "wiki-size";
	   wiki_value.innerHTML = '<b>Wiki text: </b>'+result;
	   var output = document.getElementById("document-size-stats");
	   prose_value = document.getElementById("prose-size");
	   output.insertBefore(wiki_value,prose_value);
	 }
	 else{
	  //alert("There was a problem using the Wikipedia Search to find the wiki text size\nEither the search is not working or the correct article did not appear on the first page of results");
           wiki_value = document.createElement("li");
	   wiki_value.id = "wiki-size";
	   wiki_value.innerHTML = '<b>Wiki text: </b>Problem getting wiki text size';
	   var output = document.getElementById("document-size-stats");
	   prose_value = document.getElementById("prose-size");
	   output.insertBefore(wiki_value,prose_value);
	 }
        } else {
            alert("There was a problem retrieving the XML data:\n" +
                req.statusText);
        }
    }
}

function getFileSize(req, page) {
    // only if req shows "loaded"
    if (req.readyState == 4) {
        // only if "OK"
        if (req.status == 200) {
            // ...processing statements go here...
	  var fsize = req.responseText.length;
	  window.status = fsize;
	  var total_value = document.createElement("li");
	  total_value.id = "total-size";
	  total_value.innerHTML='<b>File size: </b>'+fsize+'&nbsp;B';
	  var output = document.getElementById("document-size-stats");
	  var prose_html_value = document.getElementById("prose-size-html");
	  output.insertBefore(total_value,prose_html_value);
         } else {
            alert("There was a problem retrieving the XML data:\n" +
                req.statusText + "\n(" + url + ")");
        }
    }
}

function getLength(id){
 var textLength = 0;
 for(var i=0;i<id.childNodes.length; i++){
  if(id.childNodes[i].nodeName == '#text'){
   textLength += id.childNodes[i].nodeValue.length;
  }
  else if(id.childNodes[i].id == 'coordinates'){
    //special case for {coord} template
  }
  else{
    textLength += getLength(id.childNodes[i]);
  }
 }
 return textLength;
}

function getRefMarkLength(id,html){
 var textLength = 0;
 for(var i=0;i<id.childNodes.length; i++){
  if(id.childNodes[i].className == 'reference'){
   textLength += (html)? id.childNodes[i].innerHTML.length : getLength(id.childNodes[i]);
  }
 }
 return textLength;
}

function getDocumentSize(){
 contentDivName = '';
 if(skin == 'monobook' || skin == 'chick' || skin == 'myskin' || skin == 'simple'){
   contentDivName = 'bodyContent';
 }
 else if (skin == 'modern'){
   contentDivName = 'mw_contentholder';
 }
 else if (skin == 'standard' || skin == 'cologneblue' || skin == 'nostalgia'){
   contentDivName = 'article';
 }
 else{
   //fallback case; the above covers all currently existing skins
   contentDivName = 'bodyContent';
 }
 //Same for all skins if previewing page
 if(wgAction == 'submit') contentDivName = 'wikiPreview';
 
 var bodyContent = document.getElementById(contentDivName);
 if(document.getElementById("document-size-stats")){
   //if statistics already exist, turn them off and remove highlighting
   var output = document.getElementById("document-size-stats");
   var oldStyle = output.className;
   var pList = bodyContent.getElementsByTagName("p");
   for(var i=0;i<pList.length; i++){
     if(pList[i].parentNode.id == contentDivName) pList[i].style.cssText = oldStyle;
   }
   output.parentNode.removeChild(output);
   var header = document.getElementById("document-size-header");
   header.parentNode.removeChild(header);
 }
 else{
 var output = document.createElement("ul");
 output.id = "document-size-stats";

 var prose_html_value = document.createElement("li");
 prose_html_value.id = "prose-size-html";
 output.appendChild(prose_html_value);

 var ref_html_value = document.createElement("li");
 ref_html_value.id = "ref-size-html";
 output.appendChild(ref_html_value);

 var prose_value = document.createElement("li");
 prose_value.id = "prose-size";
 output.appendChild(prose_value);
 output.className = bodyContent.getElementsByTagName("p").item(0).style.cssText;

 var ref_value = document.createElement("li");
 ref_value.id = "ref-size";
 output.appendChild(ref_value);

 var dummy = document.getElementById("siteSub");
 dummy.parentNode.insertBefore(output, dummy.nextSibling);

 var header = document.createElement("span");
 header.id = "document-size-header";
 header.innerHTML = '<br/>Document statistics: <small><i>(See <a href="http://en.wikipedia.org/wiki/User_talk:Dr_pda/prosesize.js">here</a> for details.)<i></small>';
 dummy.parentNode.insertBefore(header,output);

 //File size not well defined for preview mode or section edit
 if(wgAction != 'submit'){
   //If browser supports document.fileSize property (IE)
   if(document.fileSize){
     var total_value = document.createElement("li");
     total_value.id = "total-size";
     total_value.innerHTML='<b>File size: </b>'+document.fileSize+'&nbsp;B';
     output.insertBefore(total_value,prose_html_value);
   }
   else{
    loadXMLDocPassingTemplate(location.pathname,getFileSize,'')
   }
 }
 
 //Get size of images only if browser supports filesize property (IE)
 var iList = bodyContent.getElementsByTagName("img");
 if(iList.length >0 && iList[0].fileSize){
 //Get size of images included in document
   var image_size = 0;
   var first_magnify = true;

   for (var i=0;i<iList.length; i++){
    var im = iList[i];
    if(im.getAttribute("src").indexOf("magnify-clip.png") != -1){
      if(first_magnify){
        image_size += im.fileSize*1;
        first_magnify = false;
      }
    }
    else{
      image_size += im.fileSize*1;
    }
   }
   var image_value = document.createElement("li");
   image_value.id = "image-size";
   image_value.innerHTML='<b>Images: </b>'+image_size+'&nbsp;B';
   output.appendChild(image_value);

  }
 //Calculate prose size and size of reference markers ([1] etc)
 var pList = bodyContent.getElementsByTagName("p");

 prose_size = 0;
 prose_size_html = 0;
 refmark_size = 0;
 refmark_size_html = 0;
 word_count = 0;
 for(var i=0;i<pList.length; i++){
   var para = pList[i];
   if(para.parentNode.id == contentDivName){
    prose_size += getLength(para);
    prose_size_html += para.innerHTML.length;
    refmark_size += getRefMarkLength(para,false);
    refmark_size_html += getRefMarkLength(para,true);
    word_count += para.innerHTML.replace(/(<([^>]+)>)/ig,"").split(' ').length
    para.style.cssText = "background-color:yellow";
   }
 }

 prose_value.innerHTML='<b>Prose size (text only): </b>'+(prose_size-refmark_size)+'&nbsp;B ('+word_count+' words) "readable prose size"';

 prose_html_value.innerHTML='<b>Prose size (including all HTML code): </b>'+(prose_size_html-refmark_size_html)+'&nbsp;B';


 //Calculate size of references (i.e. output of <references/>)
 var rList = bodyContent.getElementsByTagName("ol");
 var ref_size = 0;
 var ref_size_html = 0;
 for (var i=0; i<rList.length; i++){
   if(rList[i].className == "references"){
     ref_size = getLength(rList[i]);
     ref_size_html = rList[i].innerHTML.length;
   }
 }

 ref_value.innerHTML='<b>References (text only): </b>'+(ref_size+refmark_size)+'&nbsp;B';

 ref_html_value.innerHTML='<b>References (including all HTML code): </b>'+(ref_size_html+refmark_size_html)+'&nbsp;B';

 //get correct name of article from wikipedia-defined global variables
 var pageNameUnderscores = wgPageName;
 var pageNameSpaces = pageNameUnderscores.replace(/_/g,' ')

 //if page is a permalink, diff, etc don't try to search
 if(!location.pathname.match('/w/index.php')){ 
  //Get revision size from API
  var searchURL = wgScriptPath + '/api.php?action=query&prop=revisions&rvprop=size&format=xml&revids=' + wgCurRevisionId;
  loadXMLDocPassingTemplate(searchURL,getWikiText,pageNameSpaces);
 }
 else if(wgAction == 'submit'){
   //Get size of text in edit box
   result = document.getElementById('wpTextbox1').value.length;
   result = result+'&nbsp;B';
   wiki_value = document.createElement("li");
   wiki_value.id = "wiki-size";
   wiki_value.innerHTML = '<b>Wiki text: </b>'+result;
   var output = document.getElementById("document-size-stats");
   prose_value = document.getElementById("prose-size");
   output.insertBefore(wiki_value,prose_value);
 }

}
}

addOnloadHook(function () {
  if(wgAction == 'edit' || (wgAction == 'submit' && document.getElementById('wikiDiff')) ){
    mw.util.addPortletLink('p-tb', 'javascript:alert("You need to preview the text for the prose size script to work in edit mode.")', 'Page size', 't-page-size', 'Calculate page and prose size', '', '');
    document.getElementById("t-page-size").firstChild.style.cssText = "color:black;"
  }
  else if(wgAction == 'view' || wgAction == 'submit' || wgAction == 'purge'){
    mw.util.addPortletLink('p-tb', 'javascript:getDocumentSize()', 'Page size (bytes)', 't-page-size', 'Calculate page and prose size', '', '');
  }
});

importScript('User:TheDJ/qui.js');

/* Ajax file move module, version [0.0.4c]
Originally from: http://en.wikipedia.org/wiki/User:Splarka/ajaxfilemove.js

Notes:
* Very complex script, but very simple operation:
** Go to a File: page, click [speedy move], enter new name.
* Specifically written to move requested images, summaries and template removal regex are hard coded.
** Framework can be forked though.
* Does not suppress redirects, a feature could be written though.
** This would need more complex input, than a prompt().

*/

var sfmMoveToken = '';
var sfmNewTitle = '';
if(wgNamespaceNumber == 6 && wgCurRevisionId) {
  addOnloadHook(function() {
    var move = document.getElementById('ca-move');
    if(!move) return
    var sm = mw.util.addPortletLink('p-cactions','javascript:sfmInit()','speedy move','ca-gonzales','Speed move this File','i',move);
  });
}

function sfmInit() {
  var def = wgCanonicalNamespace + ':';
  var suggest = getElementsByClassName(document,'span','media-move-suggestion');
  if(suggest.length > 0) def = getInnerText(suggest[0])
  var newtitle = prompt('Move file to page:',def);
  if(!newtitle) return
  if(newtitle.toLowerCase().indexOf(wgCanonicalNamespace.toLowerCase() + ':') != 0) {
    alert('You can\'t move files to other namespaces');
    return;
  }
  var oldext = wgPageName.split('.')[wgPageName.split('.').length-1];
  var newext = newtitle.split('.')[newtitle.split('.').length-1];
  if(oldext.toLowerCase() != newext.toLowerCase()) {
    var conf = confirm('Warning: you appear to be changing this file\'s extension from "' + oldext + '" to "' + newext + '".\nWhile this is works sometimes for very old files uploaded with the wrong\nextension, this is rare. Are you really sure you want to try that?');
    if(!conf) return
  }

  var bar = document.getElementById('contentSub') || document.getElementById('topbar');
  var out = document.createElement('pre');
  out.setAttribute('id','sfm-output');
  appendCSS('#sfm-output {border:1px solid black !important;padding:.5em;overflow:auto;font-size:120%}');
  bar.appendChild(out);

  var badchars = /([#<>\[\]{}|\/]|\:.*\:)/;
  if(newtitle == wgPageName || newtitle.indexOf(wgCanonicalNamespace + ':') != 0 || badchars.test(newtitle)) {
    out.appendChild(document.createTextNode('! That seems like a bad title to me: [[' + newtitle + ']]'));
    return;
  }

  out.appendChild(document.createTextNode('* Input accepted, fetching edit/move tokens and page text...\n'));
  document.getElementById('ca-gonzales').style.display = 'none';

  var url = wgScriptPath + '/api.php?action=query&prop=info|revisions&rvprop=content|timestamp&indexpageids=1&intoken=edit|move&format=json&titles=' + encodeURIComponent(mw.config.get('wgPageName'));
  var req = sajax_init_object();
  req.open('GET', url, true);
  req.onreadystatechange = function() {
    if(req.readyState == 4 && req.status == 200) {
      eval("sfmTokens(" + req.responseText + ",'" + req.responseText.replace(/\'/g,"`") + "')");
    }
  }
  sfmNewTitle = newtitle;
  req.send(null);
}

function sfmTokens(obj,txt) {
  //http://test.wikipedia.org/w/api.php?action=query&prop=info|revisions&rvprop=content|timestamp&indexpageids=1&intoken=edit|move&format=jsonfm&titles=File:Test.png
  var out = document.getElementById('sfm-output');
  if(obj['error']) {
    out.appendChild(document.createTextNode('! Api error: ' + obj['error']['code'] + ' - ' + obj['error']['info'] + '\n'));
    return;
  }
  if(!obj['query'] || !obj['query']['pageids'] || !obj['query']['pages'][obj['query']['pageids'][0]] || !obj['query']['pages'][obj['query']['pageids'][0]]['movetoken'] || !obj['query']['pages'][obj['query']['pageids'][0]]['edittoken'] || !obj['query']['pages'][obj['query']['pageids'][0]]['revisions'][0]['timestamp'] || !obj['query']['pages'][obj['query']['pageids'][0]]['revisions'][0]['*']) {
    out.appendChild(document.createTextNode('? Unexpected response: ' + txt + '\n'));
    return;
  }
  if(obj['query']['pages'][obj['query']['pageids'][0]]['redirect']) {
    out.appendChild(document.createTextNode('! This file is apparently a redirect, and should not be moved again.\n'));
    return;
  }
  var edittoken = obj['query']['pages'][obj['query']['pageids'][0]]['edittoken'];
  var movetoken = obj['query']['pages'][obj['query']['pageids'][0]]['movetoken'];
  var pagetext = obj['query']['pages'][obj['query']['pageids'][0]]['revisions'][0]['*'];
  var timestamp = obj['query']['pages'][obj['query']['pageids'][0]]['revisions'][0]['timestamp'];
  var startstamp = obj['query']['pages'][obj['query']['pageids'][0]]['starttimestamp'];

  out.appendChild(document.createTextNode('* Got tokens and text, searching for templates...\n'));
  var templates = /\{\{[\s\n\t]*(ifr|rename[ _]*media|rename[ _]*image|ImageRename|rename)[\s\n\t]*(\|[^\}]*|)\}\}/ig;
  var found = templates.test(pagetext);
  if(!found) {
    out.appendChild(document.createTextNode('! No automatically removable templates found, please continue manually.'));
    return;
  }
  out.appendChild(document.createTextNode('* Move template(s) found and removed, attempting edit...\n'));
  pagetext = pagetext.replace(templates,'');

  var params = 'action=edit&format=json&title=' + encodeURIComponent(mw.config.get('wgPageName')) + '&text=' + encodeURIComponent(pagetext) + '&token=' + encodeURIComponent(edittoken) + '&summary=' + encodeURIComponent('Automatic removal of requested move templates in preparation for move.') + '&minor=1&basetimestamp=' + timestamp.replace(/[^\d]/g,'');
  if(startstamp) params += '&starttimestamp=' + startstamp.replace(/[^\d]/g,'')
  var url = wgScriptPath + '/api.php';
  var req = sajax_init_object();
  req.open('POST', url, true);
  req.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
  req.setRequestHeader('Content-length', params.length);
  req.setRequestHeader('Connection', 'close');
  req.onreadystatechange = function() {
    if(req.readyState == 4 && req.status == 200) {
      eval("sfmEdit(" + req.responseText + ",'" + req.responseText.replace(/\'/g,"`") + "')");
    }
  }
  sfmMoveToken = movetoken;
  req.send(params);
}

function sfmEdit(obj,txt) {
  var out = document.getElementById('sfm-output');
  if(obj['error']) {
    out.appendChild(document.createTextNode('! Api error: ' + obj['error']['code'] + ' - ' + obj['error']['info'] + '\n* Please finish manually.'));
    return;
  } else if(obj['edit'] && obj['edit']['result']) {
    out.appendChild(document.createTextNode('* Edit returned as "' + obj['edit']['result'] + '", attempting to move page to [[' + sfmNewTitle + ']]... \n'));
  } else {
    out.appendChild(document.createTextNode('? Unexpected response: ' + txt + '\n* Please finish manually.'));
    return;
  }
  var def = "Semi-automated file move";
  var reason = getElementsByClassName(document,'span','media-move-reason');
  if(reason.length > 0) def = getInnerText(reason[0])

  var params = 'action=move&format=json&token=' + encodeURIComponent(sfmMoveToken) + '&movetalk=1&from=' + encodeURIComponent(mw.config.get('wgPageName')) + '&to=' + encodeURIComponent(sfmNewTitle) + '&reason=' + encodeURIComponent( 'using [[User:Splarka/ajaxfilemove.js]];' +def );

  var url = wgScriptPath + '/api.php';
  var req = sajax_init_object();
  req.open('POST', url, true);
  req.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
  req.setRequestHeader('Content-length', params.length);
  req.setRequestHeader('Connection', 'close');
  req.onreadystatechange = function() {
    if(req.readyState == 4 && req.status == 200) {
      eval("sfmMove(" + req.responseText + ",'" + req.responseText.replace(/\'/g,"`") + "')");
    }
  }
  req.send(params);
}

function sfmMove(obj,txt) {
  var out = document.getElementById('sfm-output');
  if(obj['error']) {
    out.appendChild(document.createTextNode('* Api error: ' + obj['error']['code'] + ' - ' + obj['error']['info'] + '\n* Please finish manually.'));
  } else if(obj['move'] && obj['move']['from'] && obj['move']['to']) {
    out.appendChild(document.createTextNode('* File [[' + obj['move']['from'] + ']] moved to [[' + obj['move']['to'] + ']]\n* Be sure to '));
    var a = document.createElement('a');
    a.setAttribute('href',wgScript + '?title=Special:WhatLinksHere&hidelinks=1&hidetrans=1&target=' + encodeURIComponent(obj['move']['to']));
    a.appendChild(document.createTextNode('Check for double redirects!'));
    out.appendChild(a);
  } else {
    out.appendChild(document.createTextNode('? Unexpected response: ' + txt + '\n* Please finish manually.'));
  }
}