User:François Melchior/CatHelp.js

Note: After saving, you have to bypass your browser's cache to see the changes. Internet Explorer: press Ctrl-F5, Mozilla: hold down Shift while clicking Reload (or press Ctrl-Shift-R), Opera/Konqueror: press F5, Safari: hold down Shift + Alt while clicking Reload, Chrome: hold down Shift while clicking Reload.
/*
 * CatHelp
 *
 * CatHelp does add functionality to Categories.
 *
 * Author(s): François Melchior ([[:fr:Utilisateur:François Melchior]])
 * Date of last revision: alpha version
 * Licence: GPL
 * Documentation: [[User:François Melchior/CatHelp]]
 */

// Notes:
// * some functions here do make use of 'innerHTML'.
// * the script here highly depends on the structure of the page.
// * the script must be on the same server as the category and the pages to modify.

//<nowiki>

/////////////////////CUSTOMIZABLE VARIABLES/////////////////////
var CatHelp_showConfirmCheckbox; //true or false, to show or not the 'Confirm' checkbox.
var CatHelp_htmlDone; //Some HTML to show that the item has been processed (example: an image).
var CatHelp_htmlWarning; //Some HTML to show that the item has not been processed because of a warning (example: an image and a placeholer for some text as %s).
var CatHelp_htmlError; //Some HTML to show that the item has not been processed because of an error (example: an image and a placeholer for some text as %s).
var CatHelp_htmlDoing; //Some HTML to show that the item is being processed (example: an image).
var CatHelp_styleHref; //URL of the (default) CatHelp stylesheet.
/////////////////END OF CUSTOMIZABLE VARIABLES//////////////////

//////////////////////STRINGS TO TRANSLATE//////////////////////
var CatHelp_msgs=new Array();
//Category page
CatHelp_msgs.prefixNS14='Category';
//CatHelp_msgs.prefixNS6='Image';
CatHelp_msgs.boxTitle='Opérations sur les éléments cochés';
CatHelp_msgs.actionLabel='Action:';
CatHelp_msgs.summaryLabel='Résumé:';
CatHelp_msgs.confirmLabel='Confirmer avant de procéder?';
CatHelp_msgs.submitLabel='OK';
CatHelp_msgs.selectNoneLabel='Désélectionner tout';
CatHelp_msgs.selectAllLabel='Sélectionner tout';
CatHelp_msgs.actionAdd='Ajouter à';
CatHelp_msgs.actionSub='Retirer d\'ici';
CatHelp_msgs.actionMov='Transférer vers';
CatHelp_msgs.defaultSummary='Category modification with CatHelp.js';
//Summary pseudo-page
CatHelp_msgs.summaryIntroAddConfirm='Vous vous apprêtez à ajouter la catégorie <b>%s</b> aux éléments suivants:';
CatHelp_msgs.summaryIntroAdd='Ajout de la catégorie <b>%s</b>...';
CatHelp_msgs.summaryIntroSubConfirm='Vous vous apprêtez à retirer la catégorie en cours des éléments suivants:';
CatHelp_msgs.summaryIntroSub='Retrait de la catégorie courante...';
CatHelp_msgs.summaryIntroMovConfirm='Vous vous apprêtez à transférer les éléments suivants de la catégorie en cours vers <b>%s</b> :';
CatHelp_msgs.summaryIntroMov='Transfert vers <b>%s</b>...';
CatHelp_msgs.confirmBoxTitle='Confirmation';
CatHelp_msgs.confirmBoxIntro='Cette action est susceptible de modifier un grand nombre d\'éléments; êtes-vous sûr de vouloir continuer?';
CatHelp_msgs.cancelLabel='Abandonner';
CatHelp_msgs.alreadyPresent='Déjà incluse.' //Must be short.
CatHelp_msgs.notPresent='Catégorie non incluse.' //Must be short.
CatHelp_msgs.notCatYet='Aucune catégorie présente???'; //Must be short.
CatHelp_msgs.onlyOneCat='Seule catégorie.' //Must be short.
//Message boxes
CatHelp_msgs.noneSelected='Aucun élément n\'est sélectionné.';
CatHelp_msgs.noOtherCategory='Aucune catégorie de destination n\'a été spécifiée.';
CatHelp_msgs.noCatPrefix='Le préfixe "Catégorie:" n\'était pas présent: il a été ajouté; veuillez vérifier et soumettre à nouveau.';
CatHelp_msgs.newCategory='La catégorie %s n\'existe pas: elle va être créée; veuillez confirmer.';
CatHelp_msgs.isCurrentCategory='La catégorie demandée est la catégorie courante.';
//////////////////END OF STRINGS TO TRANSLATE///////////////////

var CatHelp_debug=''; //May be 'local' or 'confirm'; anything other disables the debug parts.

/***************************************************************
 CatHelp_setIfNotSetYet:
  to initialize a variable if not yet set.
  (used by CatHelp_init)
 ***************************************************************/
function CatHelp_setIfNotSetYet(nameOfVar,defaultValue) //Inspired by Gadget-AdvancedResearch.js (:fr:Utilisateur:Seb35)
 {
 if(eval(nameOfVar+'==undefined')) eval(nameOfVar+'=defaultValue');
 }

/***************************************************************
 CatHelp_simpleSPrintf:
  permit the inclusion of some text in a string.
  (used by CatHelp_onSubmit and maybe others)
 ***************************************************************/
function CatHelp_simpleSPrintf(s,t)
 {
 s=s.replace(/\%s/,t);
 s=s.replace(/\%\%/g,'%');
 return s;
 }

/***************************************************************
 CatHelp_prepareForRegExp:
  modify the string to include it in a RegExp.
  (used by CatHelp_onSubmit and maybe others)
 ***************************************************************/
function CatHelp_prepareForRegExp(s)
 {
 s=s.replace(/[^\w\s]/g,'\\$&'); //escape every special character
 s=s.replace(/\s/g,'\\s'); //escape blanks
 return s;
 }

/***************************************************************
 CatHelp_newCheckbox:
  returns a DOM element object (a checkbox).
  (used by CatHelp_makeList)
 ***************************************************************/
var CatHelp_uneCheckboxCheckee=false;
function CatHelp_newCheckbox(classAttrib)
 {
 var checkbox=document.createElement('input');
 checkbox.setAttribute('type','checkbox');
 checkbox.setAttribute('value','mandatory');
 checkbox.setAttribute('class','');
 checkbox.attributes.getNamedItem('class').value=classAttrib+' noprint';/*Trick for MSIE*/
 return checkbox;
 }

/***************************************************************
 CatHelp_makeList:
  Build the list of items and add checkboxes.
  (called by CatHelp_init)
 ***************************************************************/
var CatHelp_arraySize=0;
var CatHelp_array=new Array();

function CatHelp_makeList()
 {
 var i,itemTypeDIV,anchorElement,anchorElements,listOfLIs;
 
 //Part 1: Sub-categories
 itemTypeDIV=document.getElementById('mw-subcategories');
 if(itemTypeDIV)
  {
  listOfLIs=itemTypeDIV.getElementsByTagName('li');
  for(i=0;i<listOfLIs.length;i++)
   {
   anchorElements=listOfLIs[i].getElementsByTagName('a');
   if(anchorElements.length)
    {
    anchorElement=anchorElements[anchorElements.length-1];
    CatHelp_array[CatHelp_arraySize]=new Array();
    CatHelp_array[CatHelp_arraySize][0]=CatHelp_msgs.prefixNS14+':'+anchorElement.firstChild.nodeValue;
    CatHelp_array[CatHelp_arraySize][1]=
     anchorElement.parentNode.insertBefore(CatHelp_newCheckbox('CatHelp_checkbox_subcat'),
                                             anchorElement.parentNode.firstChild);
    CatHelp_arraySize++;
    }
   }
  }

 //Part 2: Pages
 itemTypeDIV=document.getElementById('mw-pages');
 if(itemTypeDIV)
  {
  listOfLIs=itemTypeDIV.getElementsByTagName('li');
  for(i=0;i<listOfLIs.length;i++)
   {
   anchorElements=listOfLIs[i].getElementsByTagName('a');
   if(anchorElements.length)
    {
    anchorElement=anchorElements[0];
    CatHelp_array[CatHelp_arraySize]=new Array();
    CatHelp_array[CatHelp_arraySize][0]=anchorElement.firstChild.nodeValue;
    CatHelp_array[CatHelp_arraySize][1]=
     anchorElement.parentNode.insertBefore(CatHelp_newCheckbox('CatHelp_checkbox_pages'),
                                             anchorElement.parentNode.firstChild);
    CatHelp_arraySize++;
    }
   }
  }

 //Part 3: Media
 itemTypeDIV=document.getElementById('mw-category-media');
 if(itemTypeDIV)
  {
  listOfDIVs=itemTypeDIV.getElementsByTagName('div');
  for(i=0;i<listOfDIVs.length;i++)
   {
   if(listOfDIVs[i].className.indexOf('gallerytext')!=-1)
    {
    anchorElements=listOfDIVs[i].getElementsByTagName('a');
    if(anchorElements.length)
     {
     anchorElement=anchorElements[0];
     /*linebreakElements=listOfDIVs[i].getElementsByTagName('br');
     if(!linebreakElements.length) linebreakElements=new Array();*/
     CatHelp_array[CatHelp_arraySize]=new Array();
     CatHelp_array[CatHelp_arraySize][0]=anchorElement.title;
     CatHelp_array[CatHelp_arraySize][1]=
      anchorElement.parentNode.appendChild(CatHelp_newCheckbox('CatHelp_checkbox_media'));
     CatHelp_arraySize++;
     }
    }
   }
  }
 }

/***************************************************************
 CatHelp_init:
  Initialization.
  (called by external script if the page is a category)
 ***************************************************************/
var CatHelp_iframe;

function CatHelp_init()
 {
 //Initialize customizable variables if not already done (by user's script)
 CatHelp_setIfNotSetYet('CatHelp_showConfirmCheckbox',false);
 CatHelp_setIfNotSetYet('CatHelp_htmlDone','<image src="http://upload.wikimedia.org/wikipedia/commons/thumb/f/fb/Yes_check.svg/20px-Yes_check.svg.png" alt="Done" />');
 CatHelp_setIfNotSetYet('CatHelp_htmlWarning','<image src="http://upload.wikimedia.org/wikipedia/commons/thumb/3/35/Achtung-yellow.svg/20px-Achtung-yellow.svg.png" alt="Warning" />&nbsp;%s');
 CatHelp_setIfNotSetYet('CatHelp_htmlError','<image src="http://upload.wikimedia.org/wikipedia/commons/thumb/b/ba/Red_x.svg/20px-Red_x.svg.png" alt="Error" />&nbsp;%s');
 CatHelp_setIfNotSetYet('CatHelp_htmlDoing','<image src="http://upload.wikimedia.org/wikipedia/commons/thumb/d/d9/Dotdotdot.gif/20px-Dotdotdot.gif" alt="Processing..." />');
 if(CatHelp_debug=='local')
  CatHelp_setIfNotSetYet('CatHelp_styleHref','CatHelp.css');
 else
  CatHelp_setIfNotSetYet('CatHelp_styleHref',
   'http://fr.wikipedia.org/w/index.php?title=User:François_Melchior/CatHelp.css&action=raw&ctype=text/css&dontcountme=s');

 //Load CatHelp stylesheet
 var newLinkElement=document.createElement('link');
 newLinkElement.setAttribute('rel','stylesheet');
 newLinkElement.setAttribute('type','text/css');
 newLinkElement.setAttribute('href',CatHelp_styleHref);
 var headElement=document.getElementsByTagName('head')[0];
 headElement.insertBefore(newLinkElement,headElement.firstChild);

 //Build the list of items and add checkboxes
 CatHelp_makeList();
 if(!CatHelp_arraySize) return; //Empty category

 //Add CatHelp box
 var catsLinksDIV=document.getElementById('catlinks'),
     CatHelpDIV=document.createElement('div');
 CatHelpDIV.setAttribute('class','');
 CatHelpDIV.attributes.getNamedItem('class').value='CatHelp noprint';/*Trick for MSIE*/
 /* material to use if want to be W3C DOM only (no '.innerHTML')
 var newSELECT=document.createElement('select');
 checkbox.setAttribute('class','CatHelp');
 var newDIV=document.createElement('div');
 checkbox.setAttribute('class','CatHelp');
 var newDIV=document.createElement('div');
 checkbox.setAttribute('class','CatHelp');
 var newDIV=document.createElement('div');
 checkbox.setAttribute('class','CatHelp');
 var newDIV=document.createElement('div');
 checkbox.setAttribute('class','CatHelp');
 CatHelpDIV.appendChild(document.createTextNode(showedText));*/
 CatHelpDIV.innerHTML=
  '<h5>'+CatHelp_msgs.boxTitle+'</h5>'+
  '<form action="" onsubmit="return CatHelp_onSubmit_A(this)">'+
  '<label>'+CatHelp_msgs.actionLabel+'&nbsp;'+
  '<select name="Action" onchange="this.form.OtherCategory.disabled=this.value==\'Sub\';return true">'+
   '<option value="Add" selected="selected">'+CatHelp_msgs.actionAdd+'</option>'+
   '<option value="Sub">'+CatHelp_msgs.actionSub+'</option>'+
   '<option value="Mov">'+CatHelp_msgs.actionMov+'</option>'+
  '</select></label>&nbsp;'+
  '<input name="OtherCategory" value="'+CatHelp_msgs.prefixNS14+':'+
  '" size="40" /><br />'+
  '<label>'+CatHelp_msgs.summaryLabel+'&nbsp;'+
  '<input name="Summary" value="'+CatHelp_msgs.defaultSummary+'" maxlength="200" size="60" /></label><br />'+
  '<label style="'+(CatHelp_showConfirmCheckbox?'':'display:none')+'">'+
  '<input type="checkbox" name="Confirm" value="" checked="checked" />&nbsp;'+
  CatHelp_msgs.confirmLabel+'<br /></label>'+
  '<button type="submit">'+CatHelp_msgs.submitLabel+'</button>&nbsp;'+
  '<button type="button" onclick="CatHelp_selectNoneOrAll(false)">'+
  CatHelp_msgs.selectNoneLabel+'</button>&nbsp;'+
  '<button type="button" onclick="CatHelp_selectNoneOrAll(true)">'+
  CatHelp_msgs.selectAllLabel+
  '</button>'+
  '</form>';
 catsLinksDIV.parentNode.insertBefore(CatHelpDIV,catsLinksDIV);

 //Add an IFRAME to "communicate" with the server
 var bodyContentDIV=document.getElementById('bodyContent');
     CatHelp_iframe=document.createElement('iframe');
 CatHelp_iframe.setAttribute('style','border:0;margin:0;padding:0;width:0;height:0');
 //CatHelp_iframe.setAttribute('style','display:none');
 bodyContentDIV.parentNode.insertBefore(CatHelp_iframe,bodyContentDIV);
 }

/*
function CatHelp_iframeOnload()
 {
 top.oniframeload();
 }

if(top.title!=self.title)
 addOnloadHook(CatHelp_iframeOnload);
else*/
if(wgNamespaceNumber==14) //Is Category
 addOnloadHook(CatHelp_init);

/***************************************************************
 CatHelp_selectNoneOrAll:
  Check (uncheck) all the CatHelp checkboxes.
  (called by onClick for the buttons 'select all' and
   'select none')
 ***************************************************************/
function CatHelp_selectNoneOrAll(newValue)
 {
 var i;
 for(i=CatHelp_arraySize;i--;)
  CatHelp_array[i][1].checked=newValue;
 }

/***************************************************************
 CatHelp_onSubmit (CatHelp_onSubmit_A and CatHelp_onSubmit_B):
  Save the data of the form, build the confirmation/summary
  page.
  (called by onSubmit for the CatHelp form)
  Note: the function is divided into 2 sub-functions, because
        of the use of onLoad.
 ***************************************************************/
var CatHelp_onSubmit=new Array(); //object to store all "local" variables, to be useable by the second part of the function.
function CatHelp_onSubmit_A(currentForm)
 {
 var i;
 CatHelp_onSubmit.htmlList='';
 CatHelp_onSubmit.confirm=currentForm.Confirm.checked;
 CatHelp_onSubmit.summary=currentForm.Summary.value;
 CatHelp_onSubmit.action=currentForm.Action.value;

 for(i=0;i<CatHelp_arraySize;i++)
  if(CatHelp_array[i][1].checked)
   {
   CatHelp_onSubmit.htmlList+=
    '<li>'+CatHelp_array[i][0]+
    '&nbsp;<div id="CatHelp_itemStatus_'+i+'" style="display:inline"></div></li>';
   CatHelp_array[i][2]=CatHelp_array[i][1].checked;
   }

 if(!CatHelp_onSubmit.htmlList) //No item selected
  {
  alert(CatHelp_msgs.noneSelected);
  return false;
  }

 if(currentForm.OtherCategory.disabled)
  CatHelp_onSubmit.otherCategory=''; //Action that does not need a destination category
 else
  {
  var rexp=new RegExp('^\\s*'+
                      CatHelp_prepareForRegExp(CatHelp_msgs.prefixNS14)+
                      '\\s*\\:\\s*([\\S\\s]*\\S)\\s*$','i');
  
  
  if(!rexp.test(currentForm.OtherCategory.value))
   {
   if(currentForm.OtherCategory.value&&currentForm.OtherCategory.value!=CatHelp_msgs.prefixNS14+':')
    {
    currentForm.OtherCategory.value=CatHelp_msgs.prefixNS14+':'+currentForm.OtherCategory.value;
    alert(CatHelp_msgs.noCatPrefix); //No or misspelled category namespace prefix
    }
   else alert(CatHelp_msgs.noOtherCategory); //No destination category
   return false;
   }
  
  CatHelp_onSubmit.otherCategory=currentForm.OtherCategory.value.
                                 replace(rexp,'$1').
                                 replace(/\_/g,' ');
  //Uppercase the 1st chr
  CatHelp_onSubmit.otherCategory=CatHelp_onSubmit.otherCategory.charAt(0).toUpperCase()+
                                 CatHelp_onSubmit.otherCategory.substr(1);
  
  if(CatHelp_onSubmit.otherCategory==wgTitle)
   { //Destination category is identical to current category
   alert(CatHelp_msgs.isCurrentCategory);
   return false;
   }
  }

 if(CatHelp_onSubmit.otherCategory)
  {
  //Test if new category
  CatHelp_iframe.onload=CatHelp_onSubmit_B;
  CatHelp_iframe.onreadystatechange=
   function () { if(this.readyState=='complete') CatHelp_onSubmit_B(); } //Hack for MSIE
  if(CatHelp_debug=='local')
   CatHelp_iframe.src='txt.html';
  else
   CatHelp_iframe.src=wgServer+wgScriptPath+
                      '/api.php?action=query&format=txtfm&titles='+
                      CatHelp_msgs.prefixNS14+':'+
                      CatHelp_onSubmit.otherCategory;
  }
 else setTimeout(CatHelp_onSubmit_B,100);
 return false;
 }
/***************************************************************/
function CatHelp_onSubmit_B()
 {
 //CatHelp_iframe.removeAttribute('onload');
 //CatHelp_iframe.onreadystatechange=null;

 if(CatHelp_onSubmit.otherCategory)
  if(CatHelp_iframe.contentWindow.document.getElementsByTagName('pre')[0].
     innerHTML.search(/\[missing\]/)>-1)
    if(!confirm(CatHelp_simpleSPrintf(CatHelp_msgs.newCategory,CatHelp_onSubmit.otherCategory)))
     return;

 var introString;
 introString=eval('CatHelp_msgs.summaryIntro'+
                  CatHelp_onSubmit.action+
                  (CatHelp_onSubmit.confirm?'Confirm':''));
 introString=CatHelp_simpleSPrintf(introString,
                                   CatHelp_msgs.prefixNS14+':'+CatHelp_onSubmit.otherCategory);

 if(CatHelp_onSubmit.confirm)
  confirmBox=
   '<h5>'+CatHelp_msgs.confirmBoxTitle+'</h5>'+
   CatHelp_msgs.confirmBoxIntro+'<br />'+
   '<form action="" onsubmit="return CatHelp_process_A(this.Summary.value,\''+
     CatHelp_onSubmit.action+'\',\''+CatHelp_onSubmit.otherCategory+'\')">'+
   '<label>'+CatHelp_msgs.summaryLabel+'&nbsp;'+
   '<input name="Summary" value="'+CatHelp_onSubmit.summary+'" maxlength="200" size="60" /></label><br />'+
   '<button type="submit">'+CatHelp_msgs.submitLabel+'</button>&nbsp;'+
   '<button type="button" onclick="window.history.go(0)">'+ //TODO: Better way than reloading the page?
  CatHelp_msgs.cancelLabel+'</button>&nbsp;'+
   ''+
   '</form>';
 else confirmBox='';

 //scroll to the top of the window
 window.scrollTo(0,0);

 document.getElementById('bodyContent').innerHTML=
  '<div id="contentSub"></div><p>'+introString+
  '<ul>'+CatHelp_onSubmit.htmlList+'</ul>'+
  '</p><div id="CatHelpBox" class="CatHelp">'+confirmBox+'</div>';

 if(!CatHelp_onSubmit.confirm) CatHelp_process_A(CatHelp_onSubmit.summary,CatHelp_onSubmit.action,CatHelp_onSubmit.otherCategory);
 }

/***************************************************************
 CatHelp_process (CatHelp_process_A and CatHelp_process_B):
  Do the action.
  (called by onSubmit on the confirmation page, or directly
   by CatHelp_onSubmit if no confirmation)
  Note: the function is divided into 2 sub-functions, because
        of the use of onLoad.
 ***************************************************************/
var CatHelp_process=new Array();
CatHelp_process.i=-1;
function CatHelp_process_A(summaryText,wantedAction,otherCategory)
 {
 if(CatHelp_process.i==-1)
  {
  CatHelp_process.i=0;
  CatHelp_process.summary=summaryText;
  CatHelp_process.action=wantedAction;
  CatHelp_process.otherCategory=otherCategory;
  }
 else
  {
  if(CatHelp_process.warning)
   document.getElementById('CatHelp_itemStatus_'+CatHelp_process.i).innerHTML=
    CatHelp_simpleSPrintf(CatHelp_htmlWarning,CatHelp_process.warning);
  else if(CatHelp_process.error)
   document.getElementById('CatHelp_itemStatus_'+CatHelp_process.i).innerHTML=
    CatHelp_simpleSPrintf(CatHelp_htmlError,CatHelp_process.error);
  else
   document.getElementById('CatHelp_itemStatus_'+CatHelp_process.i).innerHTML=CatHelp_htmlDone;
  CatHelp_process.i++;
  }

 while(true)
  {
  if(CatHelp_process.i>=CatHelp_arraySize)
   {
   document.getElementById('CatHelpBox').innerHTML=
    '<button onclick="location=\''+
     (CatHelp_process.otherCategory?
       mw.config.get('wgServer')+mw.config.get('wgArticlePath').replace(/\$1/,CatHelp_msgs.prefixNS14+':'+
                                            CatHelp_process.otherCategory):
       location.href)+
     '\'">'+
    CatHelp_msgs.submitLabel+'</button>';
   return;
   }
  if(CatHelp_array[CatHelp_process.i][2]) break;
  CatHelp_process.i++;
  }

 document.getElementById('CatHelp_itemStatus_'+CatHelp_process.i).innerHTML=CatHelp_htmlDoing;
 CatHelp_iframe.onload=CatHelp_process_B;
 CatHelp_iframe.onreadystatechange=
  function () { if(this.readyState=='complete') CatHelp_process_B(); } //Hack for MSIE
 if(CatHelp_debug=='local')
  CatHelp_iframe.src='modif.html';
 else
  CatHelp_iframe.src=wgServer+wgScriptPath+
                     '/index.php?action=edit&title='+
                     CatHelp_array[CatHelp_process.i][0];
 return false;
 }
/***************************************************************/
function CatHelp_process_B()
 {
 //CatHelp_iframe.removeAttribute('onload');
 //CatHelp_iframe.onreadystatechange=null;

 editForm=CatHelp_iframe.contentWindow.document.forms.editform; //simpler object

 //Set summary text
 editForm.wpSummary.value=CatHelp_process.summary;

 //Set the watch checkbox to the current watch status
 if(document.getElementById('ca-watch')==undefined)
  editForm.wpWatchthis.checked=true;
 else if(document.getElementById('ca-unwatch')==undefined)
  editForm.wpWatchthis.checked=false;

 editText=editForm.wpTextbox1.value;

 //Replace comments and <nowiki> zones with something that we know it does not contain [[Category:...]].
 editText=editText.replace(/\<\!\-\-[\s\S]*?\-\-\s*\>/g,CatHelp_saveComment);
 editText=editText.replace(/\<nowiki\>[\s\S]*?\<\/nowiki\>/gi,CatHelp_saveComment);

 CatHelp_process.warning=false;
 CatHelp_process.error=false;
 var rexp=new RegExp('\\[\\[\\s*'+
                     CatHelp_msgs.prefixNS14+
                     '\\s*\\:\\s*'+
                     (CatHelp_process.otherCategory?
                      CatHelp_prepareForRegExp(CatHelp_process.otherCategory):
                      CatHelp_prepareForRegExp(wgTitle))+
                     '\\s*\\]\\]\\r?\\n?');
 var result=rexp.test(editText);

 //Finally do the work! (modify the text of the page)
 switch(CatHelp_process.action)
  {
  case 'Add':
   if(!result)
    {
    rexp=new RegExp('\\[\\[\\s*'+
                    CatHelp_prepareForRegExp(CatHelp_msgs.prefixNS14)+
                    '\\s*\\:\\s*[\\S\\s]+\\s*\\]\\]','g');
    result=rexp.exec(editText);
    if(result===null)
     CatHelp_process.error=CatHelp_msgs.notCatYet;
    else
     {
     var pos=result.index+result[0].length;
     editText=editText.substr(0,pos)+
              '\n[['+
              CatHelp_msgs.prefixNS14+':'+
              CatHelp_process.otherCategory+
              ']]'+
              editText.substr(pos);
     }
    }
   else CatHelp_process.warning=CatHelp_msgs.alreadyPresent;
   break;
  case 'Sub':
   if(!result)
    CatHelp_process.error=CatHelp_msgs.notPresent;
   else
    {
    editText=editText.replace(rexp,'');
    //Verify if it was not the only one category
    rexp=new RegExp('\\[\\[\\s*'+
                    CatHelp_prepareForRegExp(CatHelp_msgs.prefixNS14)+
                    '\\s*\\:\\s*[\\S\\s]+\\s*\\]\\]');
    if(!rexp.test(editText)) CatHelp_process.error=CatHelp_msgs.onlyOneCat;
    }
   break;
  case 'Mov':
   if(!result)
    {
    rexp=new RegExp('\\[\\[\\s*'+
                     CatHelp_prepareForRegExp(CatHelp_msgs.prefixNS14)+
                     '\\s*\\:\\s*'+
                     CatHelp_prepareForRegExp(wgTitle)+
                     '\\s*\\]\\]\\r?\\n?');
    result=rexp.exec(editText);
    if(result===null)
     CatHelp_process.error=CatHelp_msgs.notPresent;
    else
     editText=editText.replace(rexp,'[['+CatHelp_msgs.prefixNS14+':'+CatHelp_process.otherCategory+']]\n');
    }
   else CatHelp_process.warning=CatHelp_msgs.alreadyPresent;
   break;
  }

 //If an error or a warning occured, we do not want to submit the form.
 if(CatHelp_process.error||CatHelp_process.warning)
  {
  setTimeout(CatHelp_process_A,100);
  return;
  }

 //Restore comments and <nowiki> zones.
 editText=editText.replace(/\<\?CatHelp\s+Comment\((\d+)\)\s*\?\>/g,CatHelp_restoreComment);

 //Submit the form
 if(CatHelp_debug=='confirm')
  if(!confirm(editText))
   {
   setTimeout(CatHelp_process_A,100);
   return;
   }
 editForm.wpTextbox1.value=editText;
 CatHelp_iframe.onload=CatHelp_process_A;
 CatHelp_iframe.onreadystatechange=
  function () { if(this.readyState=='complete') CatHelp_process_A(); } //Hack for MSIE
  /*editForm.wpDiff.click();
 else*/ editForm.wpSave.click();
 }

/***************************************************************
 CatHelp_saveComment and CatHelp_restoreComment
  Saves and restores some text.
  (called by CatHelp_process)
 ***************************************************************/
var CatHelp_comments=new Array()
    CatHelp_nbr_comments=0;

function CatHelp_saveComment(s)
 {
 CatHelp_comments[CatHelp_nbr_comments]=s;
 CatHelp_nbr_comments++;
 return '<?CatHelp Comment('+CatHelp_nbr_comments+')?>';
 }

function CatHelp_restoreComment(s,n)
 {
 n=parseInt(n,10);
 if(n>CatHelp_nbr_comments||n<1) return '';
 return CatHelp_comments[n-1];
 }

/*/////////////////SOME COMPATIBILITY NOTES/////////////////////
 .firstChild: O9,F1,K,IE6,DOM1
 .innerText: O9,K,IE6
 .parentElement: O9,K,IE6
 .parentNode: O9,F1,K,IE6,DOM1
 (anchor).text: O9,F1,K,JavaScript 1.2
 .textContent: O9,F1
//////////////////////////////////////////////////////////////*/
//</nowiki>