Ajout et retrait massifs de pages datées à la liste de suivi de MediaWiki

Vu que c’est le début de l’année, c’est la bonne période pour ajouter plein de nouvelles pages à sa LdS.
Iluvalar l’a remarqué, Dereckson l’a remarqué, Darkoneko l’a remarqué, il faut un outil qui le fait à notre place si on veut s’en sortir.

Je vous avoue, c’est pas trop mon truc, la LdS pour moi c’est avant tout un truc qui se remplit quand on oublie de décocher une case avant de cliquer sur Publier. Mais le fait est que le défi de faire un truc chiadé en Javascript m’a tenté. Pour le code source complet, sans interférence de WordPress (qui m’a pas mal fait suer quand il s’est agi de poster ce grmbl de billet), c’est par ici !


Il fallait respecter plusieurs règles :

  • utilisable partout
  • utilisable par tous
  • utilisable pour tout
  • pratique pour ajouter et retirer des pages
  • simple d’utilisation (dans l’idéal, un simple bouton)
  • mais configurable tout de même
  • pas trop vilain à regarder
  • n’apparaissant pas sur toutes les pages1
  • indiquant ce qu’il fait (et le plus qui ne fait quasiment aucune différence sauf chez ceux qui font une poussée morbide d’Editcountitis : et comptant ce qu’il fait)
  • utilisable sous forme de Gadget

Voyons voir les étapes de la conception :

  1. Utilisable partout :
    1. les langages de programmation qui fonctionnent sur toutes les plateformes sont rares
    2. ceux qui sont déjà « installés » sur tous les terminaux visitant Wikipédia ou presque le sont encore plus !
  2. Utilisable par tous :
    1. l’outil doit être utilisable depuis un navigateur, vu que ceux qui lisent Wikipédia en utilisent généralement un pour ce faire
    2. de 1a. et 2a. découle que le JavaScript s’impose
  3. Utilisable pour tout :
    1. l’outil doit pouvoir servir pour les pages les plus diverses et variées parmi celles qui ont une date dans leur titre
    2. l’interface doit donc permettre d’effectuer un choix sur ce qu’on veut modifier
  4. Pratique pour ajouter et retirer des pages :
    1. ça se passe de commentaire, je crois : le but dans la vie d’un Wikimédien n’est pas de remplir sa LdS de choses inutiles 😉
  5. Simple d’utilisation :
    1. tout le monde n’a pas de diplôme d’informatique – moi non plus, d’ailleurs !
    2. tout le monde n’a pas le temps de lire 50 pages de mode d’emploi, et à plus forte raison s’il faut le refaire tous les 1er janvier
    3. tout le monde n’aime pas retrouver dans l’utilisation de l’interface la complexité de ce qu’on trouve dans l’organisation de l’encyclopédie ou de l’Administration
    4. donc une interface claire, avec un bouton pour chaque fonction et une seule fonction pour chaque bouton… ou presque ; un « WYSIWYW »2 est de toute évidence un plus
  6. Configurable tout de même :
    1. si on veut ajouter ou retirer une page plutôt qu’une autre
    2. si on veut ajouter un groupe de pages pas trop important
    3. il suffit de choisir ce qu’on veut faire, sans se compliquer la vie, et de laisser faire l’outil, tout simplement
  7. Pas trop vilain à regarder :
    1. ma hantise : une belle présentation – je suis une lamentable brelle en CSS (bon, j’exagère un peu, mais simplifions), j’apprécie beaucoup l’extrême sobriété dans la mesure de l’impossible
    2. il fallait un compromis entre quelque chose qui ne pique pas les yeux de la population générale
    3. mais sans pour autant me casser la nénette sur du CSS ultra compliqué
  8. n’apparaissant pas sur toutes les pages :
    1. une mauvaise manip’ est vite arrivée
    2. une mauvaise manip’ quand il s’agit de faire visiter entre une cinquantaine et plusieurs centaines de pages à XMLHttpRequest ou ActiveXObject3 , ça fait perdre pas mal de temps
    3. le temps, c’est de l’argent
    4. l’argent, c’est le nerf de la guerre
    5. la guerre, c’est l’enfer
    6. l’enfer, c’est les autres
    7. donc il fallait que l’outil soit accessible depuis les pages de la liste de suivi, et pas depuis les autres – logique, non ?
  9. indiquant ce qu’il fait :
    1. ça vous plaît, à vous, quand vous savez qu’il se passe des trucs mais que vous savez pas quoi ?
    2. moi non plus
    3. ça vous plaît, à vous, quand vous savez que ça va prendre du temps, mais que vous savez ni où ça en est, ni à quelle vitesse ça va ?
    4. là encore, moi non plus
  10. utilisable sous forme de Gadget :
    1. ça va de soi, vu que le fonctionnement censé être tout de même assez constant, compte tenu de la constance de ce qu’il est censé traiter

Partant de là, j’avais ce qu’il me fallait côté non-technique, voyons voir comment procéder d’un point de vue technique :

I. Créons un script qui n’agit que sur la LdS

function addWatchUnWatchButtons( ) {
    if ( wgCanonicalNamespace != "Special" ) return false;
    if ( wgCanonicalSpecialPageName != "Watchlist" ) return false;
    /*
    On ajoutera le corps de la fonction ici, en fait tout ce qui ajoutera des éléments à la page de la LdS
    */
}
addOnloadHook( addWatchUnWatchButtons );

Ça, c’est fait.

II. Ajoutons un semblant de structure disposant déjà d’un brin de CSS

    var WLdiv = document.createElement( "form" );
    document.getElementById( "bodyContent" ).appendChild( WLdiv );

Les <form/> HTML permettent en effet de regrouper simplement des éléments, et de donner un titre à chaque groupe, au moyen des <fieldset/> et <legend/>

    //un groupe "Année"
    var WLyearFieldSet = document.createElement( "fieldset" );
    WLdiv.appendChild( WLyearFieldSet );
    var WLyearLegend = document.createElement( "legend" );
    WLyearLegend.innerHTML = "Année";
    WLyearFieldSet.appendChild( WLyearLegend );
    /*
    ...
    */
    //un groupe "Mois"
    var WLmonthFieldSet = document.createElement( "fieldset" );
    WLmonthFieldSet.id = "WL-month-fieldset";
    WLdiv.appendChild( WLmonthFieldSet );
    var WLmonthLegend = document.createElement( "legend" );
    WLmonthLegend.innerHTML = 'Mois <span style="font-size: .8em;">(ne sera pris en compte que pour le Bistro et les éphémérides)</span>';
    WLmonthFieldSet.appendChild( WLmonthLegend );
    /*
    ...
    */
    //un groupe pour d'autres options
    var WLoptionsFieldSet = document.createElement( "fieldset" );
    WLdiv.appendChild( WLoptionsFieldSet );
    var WLoptionsLegend = document.createElement( "legend" );
    WLoptionsLegend.innerHTML = "Options";
    WLoptionsFieldSet.appendChild( WLoptionsLegend );
    /*
    ...
    */
    //un groupe "Pages à suivre/ne plus suivre"
    var WLwatchedPagesFieldSet = document.createElement( "fieldset" );
    WLdiv.appendChild( WLwatchedPagesFieldSet );
    var WLwatchedPagesLegend = document.createElement( "legend" );
    WLwatchedPagesLegend.innerHTML = "Pages à suivre/ne plus suivre";
    WLwatchedPagesFieldSet.appendChild( WLwatchedPagesLegend );
    /*
    ...
    */
    //et de quoi afficher les résultats :-)
    var WLresultsFieldSet = document.createElement( "fieldset" );
    WLdiv.appendChild( WLresultsFieldSet );
    var WLresultsLegend = document.createElement( "legend" );
    WLresultsLegend.innerHTML = "Résultats <span>(pages ajoutées et supprimées)</span>";
    WLresultsFieldSet.appendChild( WLresultsLegend );

III. Ajoutons des années

    //l'année d'il y a deux ans
    var WLmin2YearLabel = document.createElement( "label" );
    WLmin2YearLabel.innerHTML = new Date( ).getFullYear( ) - 2;
    WLmin2YearLabel.htmlFor = "WL-min2year";
    WLmin2YearLabel.style.marginLeft = "20px";
    WLyearFieldSet.appendChild( WLmin2YearLabel );
    var WLmin2Year = document.createElement( "input" );
    WLmin2Year.type = "radio";
    WLmin2Year.name = "WL-year";
    WLmin2Year.id = "WL-min2year";
    WLmin2Year.value = new Date( ).getFullYear( ) - 2;
    WLyearFieldSet.appendChild( WLmin2Year );
 
    //l'année dernière
    var WLpreviousYearLabel = document.createElement( "label" );
    WLpreviousYearLabel.innerHTML = new Date( ).getFullYear( ) - 1;
    WLpreviousYearLabel.htmlFor = "WL-previousyear";
    WLpreviousYearLabel.style.marginLeft = "20px";
    WLyearFieldSet.appendChild( WLpreviousYearLabel );
    var WLpreviousYear = document.createElement( "input" );
    WLpreviousYear.type = "radio";
    WLpreviousYear.name = "WL-year";
    WLpreviousYear.id = "WL-previousyear";
    WLpreviousYear.value = new Date( ).getFullYear( ) - 1;
    WLyearFieldSet.appendChild( WLpreviousYear );
 
    //l'année courante
    var WLcurrentYearLabel = document.createElement( "label" );
    WLcurrentYearLabel.innerHTML = new Date( ).getFullYear( );
    WLcurrentYearLabel.htmlFor = "WL-currentyear";
    WLcurrentYearLabel.style.marginLeft = "20px";
    WLyearFieldSet.appendChild( WLcurrentYearLabel );
    var WLcurrentYear = document.createElement( "input" );
    WLcurrentYear.type = "radio";
    WLcurrentYear.name = "WL-year";
    WLcurrentYear.id = "WL-currentyear";
    WLcurrentYear.checked = true;
    WLcurrentYear.value = new Date( ).getFullYear( );
    WLyearFieldSet.appendChild( WLcurrentYear );
 
    //l'année prochaine
    var WLnextYearLabel = document.createElement( "label" );
    WLnextYearLabel.innerHTML = new Date( ).getFullYear( ) + 1;
    WLnextYearLabel.htmlFor = "WL-nextyear";
    WLnextYearLabel.style.marginLeft = "20px";
    WLyearFieldSet.appendChild( WLnextYearLabel );
    var WLnextYear = document.createElement( "input" );
    WLnextYear.type = "radio";
    WLnextYear.name = "WL-year";
    WLnextYear.id = "WL-nextyear";
    WLnextYear.value = new Date( ).getFullYear( ) + 1;
    WLyearFieldSet.appendChild( WLnextYear );

IV. Ajoutons des mois

    //un arrayJavascript contenant les noms des mois
    var monthsListLocalized = {"1": "janvier", "2": "février", "3": "mars", "4": "avril", "5": "mai", "6": "juin", "7": "juillet", "8": "août", "9": "septembre", "10": "octobre", "11": "novembre", "12": "décembre"};
    var WLmonthLabel = new Array( );
    var WLmonth = new Array( );
    //pour chaque mois de l'année
    for ( var i=1 ; i &lt; 13 ; i++ ) {
        //on crée un label pour chaque mois
        WLmonthLabel[i] = document.createElement( "label" );
        WLmonthLabel[i].innerHTML = monthsListLocalized[i];
        WLmonthLabel[i].htmlFor = "WL-month" + i;
        WLmonthLabel[i].style.marginLeft = "20px";
        WLmonthFieldSet.appendChild( WLmonthLabel[i] );
        //et la checkbox correspondante
        WLmonth[i] = document.createElement( "input" )
        WLmonth[i].type = "checkbox";
        WLmonth[i].name = "WL-month";
        WLmonth[i].value = i;
        WLmonth[i].id = "WL-month" + i;
        WLmonthFieldSet.appendChild( WLmonth[i] );
    }

Et tant qu’on y est, profitons-en pour ajouter des boutons pour tous les cocher/décocher/inverser

    //d'abord une petite div
    var WLmonthButtonsDiv = document.createElement( "div" );
    WLmonthFieldSet.appendChild( WLmonthButtonsDiv );
    //à laquelle on ajoute un bouton qui permet de tout cocher
    var WLmonthTickAll = document.createElement( "input" );
    WLmonthTickAll.type = "button";
    WLmonthTickAll.value = "Cocher tout";
    WLmonthTickAll.onclick = function( ) { var monthCheckboxList = document.getElementById( "WL-month-fieldset" ).getElementsByTagName( "input" ); for ( var i = 0; i &lt; monthCheckboxList.length ; i++ ) { if ( monthCheckboxList[i].type == "checkbox" ) monthCheckboxList[i].checked = true; } };
    WLmonthButtonsDiv.appendChild( WLmonthTickAll );
    //ainsi qu'un bouton qui permet de tout décocher
    var WLmonthUntickAll = document.createElement( "input" );
    WLmonthUntickAll.type = "button";
    WLmonthUntickAll.value = "Décocher tout";
    WLmonthUntickAll.onclick = function( ) { var monthCheckboxList = document.getElementById( "WL-month-fieldset" ).getElementsByTagName( "input" ); for ( var i = 0; i &lt; monthCheckboxList.length ; i++ ) {if ( monthCheckboxList[i].type == "checkbox" ) monthCheckboxList[i].checked = false; } };
    WLmonthButtonsDiv.appendChild( WLmonthUntickAll );
    //et enfin un qui permet de cocher ce qui est décoché, et Lycée d'Versailles
    var WLmonthDisTickAll = document.createElement( "input" );
    WLmonthDisTickAll.type = "button";
    WLmonthDisTickAll.value = "Inverser la sélection";
    WLmonthDisTickAll.onclick = function( ) { var monthCheckboxList = document.getElementById( "WL-month-fieldset" ).getElementsByTagName( "input" ); for ( var i = 0; i &lt; monthCheckboxList.length ; i++ ) {if ( monthCheckboxList[i].type != "checkbox" ) continue; if ( monthCheckboxList[i].checked ) monthCheckboxList[i].checked = false; else monthCheckboxList[i].checked = true; } };
    WLmonthButtonsDiv.appendChild( WLmonthDisTickAll );

V. Ajoutons les autres options

To watch or not to watch, that is the question.
Une paire de « boutons radio » pour suivre (choix par défaut) ou ne plus suivre.

    //d'abord celui pour suivre, précédé de son label
    var WLoptionsWatchLabel = document.createElement( "label" );
    WLoptionsWatchLabel.htmlFor = "WL-watch";
    WLoptionsWatchLabel.innerHTML = "Suivre ";
    WLoptionsWatchLabel.style.marginLeft = "15px";
    WLoptionsFieldSet.appendChild( WLoptionsWatchLabel );
    var WLoptionsWatch = document.createElement( "input" );
    WLoptionsWatch.type = "radio";
    WLoptionsWatch.id = "WL-watch";
    WLoptionsWatch.value = "watch";
    WLoptionsWatch.name = "WL-watch";
    WLoptionsWatch.checked = true;
    WLoptionsFieldSet.appendChild( WLoptionsWatch );
 
    //puis celui pour ne plus suivre, suivi de son label
    var WLoptionsUnwatch = document.createElement( "input" );
    WLoptionsUnwatch.type = "radio";
    WLoptionsUnwatch.id = "WL-unwatch";
    WLoptionsUnwatch.value = "unwatch";
    WLoptionsUnwatch.name = "WL-watch";
    WLoptionsFieldSet.appendChild( WLoptionsUnwatch );
    var WLoptionsUnwatchLabel = document.createElement( "label" );
    WLoptionsUnwatchLabel.htmlFor = "WL-unwatch";
    WLoptionsUnwatchLabel.innerHTML = " Ne plus suivre";
    WLoptionsFieldSet.appendChild( WLoptionsUnwatchLabel );

Et un gros pavé pour les options des Éphémérides (plusieurs <fieldset/> imbriqués et non affichés par défaut, il suffit de cliquer sur le <legend/> du <fieldset/> principal pour afficher les autres).
Les années 1900 à +10 (à compter de l’année courante) sont affichées, et les années -1 à +10 sont cochées par défaut.
Les éphémérides de type général, en sport, dans la bande dessinée et l’animation, en sport, et dans les chemins de fer sont affichées. Seules les éphémérides de type général sont cochées par défaut.

    var WLoptionsEphemeridesFieldSet = document.createElement( "fieldset" );
    WLoptionsFieldSet.appendChild( WLoptionsEphemeridesFieldSet );
    var WLoptionsEphemeridesLegend = document.createElement( "legend" );
    WLoptionsEphemeridesLegend.innerHTML = '&Eacute;ph&eacute;m&eacute;rides <span style="font-size: .8em;">(cliquer pour afficher/masquer)</span>';
    WLoptionsEphemeridesLegend.cursor = 'pointer';
    WLoptionsEphemeridesLegend.onclick = function(){if ( document.getElementById( "WL-ephemerides-year-div" ).style.display == "none" ) { document.getElementById( "WL-ephemerides-year-div" ).style.display = "block"; document.getElementById( "WL-ephemerides-types-div" ).style.display = "block"; } else { document.getElementById( "WL-ephemerides-year-div" ).style.display = "none"; document.getElementById( "WL-ephemerides-types-div" ).style.display = "none"; } };
    WLoptionsEphemeridesFieldSet.appendChild( WLoptionsEphemeridesLegend );
 
    var WLoptionsEphemeridesYearFieldSet = document.createElement( "fieldset" );
    WLoptionsEphemeridesYearFieldSet.id = "WL-ephemerides-year-div";
    WLoptionsEphemeridesYearFieldSet.style.display = "none";
    WLoptionsEphemeridesFieldSet.appendChild( WLoptionsEphemeridesYearFieldSet );
    var WLoptionsEphemeridesYearLegend = document.createElement( "legend" );
    WLoptionsEphemeridesYearLegend.innerHTML = "Ann&eacute;es &agrave; prendre en consid&eacute;ration";
    WLoptionsEphemeridesYearFieldSet.appendChild( WLoptionsEphemeridesYearLegend );
    var WLoptionsEphemeridesYearsCheckbox = new Array();
    var WLoptionsEphemeridesYearsLabel = new Array();
    for ( var i = 1900 ; i <= new Date().getFullYear() + 10 ; i++ ) {
        WLoptionsEphemeridesYearsLabel[i] = document.createElement( "label" );
        WLoptionsEphemeridesYearsLabel[i].innerHTML = i;
        WLoptionsEphemeridesYearsLabel[i].htmlFor = "WL-ephemerides-year-" + i;
        WLoptionsEphemeridesYearsLabel[i].style.marginLeft = "20px";
        WLoptionsEphemeridesYearFieldSet.appendChild( WLoptionsEphemeridesYearsLabel[i] );
 
        WLoptionsEphemeridesYearsCheckbox[i] = document.createElement( "input" );
        WLoptionsEphemeridesYearsCheckbox[i].type = "checkbox";
        WLoptionsEphemeridesYearsCheckbox[i].id = "WL-ephemerides-year-" + i;
        WLoptionsEphemeridesYearsCheckbox[i].value = i + '';
        WLoptionsEphemeridesYearsCheckbox[i].name = 'WL-ephemerides-years';
        if ( i >= new Date().getFullYear() - 1 ) WLoptionsEphemeridesYearsCheckbox[i].checked = true;
        WLoptionsEphemeridesYearFieldSet.appendChild( WLoptionsEphemeridesYearsCheckbox[i] );
        if ( ( i % 10 ) == 9 ) WLoptionsEphemeridesYearFieldSet.appendChild( document.createElement( "br" ) );
    }
 
    var WLEphemeridesButtonsYearDiv = document.createElement( "div" );
    WLEphemeridesButtonsYearDiv.style.margin = '10px 50px 0 0';
    WLoptionsEphemeridesYearFieldSet.appendChild( WLEphemeridesButtonsYearDiv );
    var WLoptionsEphemeridesYearTickAll = document.createElement( "input" );
    WLoptionsEphemeridesYearTickAll.type = "button";
    WLoptionsEphemeridesYearTickAll.value = "Cocher toutes les années";
    WLoptionsEphemeridesYearTickAll.onclick = function() { var yearCheckboxList = document.getElementById( "WL-ephemerides-year-div" ).getElementsByTagName( "input" ); for ( var i = 0; i < yearCheckboxList.length ; i++ ) { if ( yearCheckboxList[i].type == "checkbox" ) yearCheckboxList[i].checked = true; } };
    WLEphemeridesButtonsYearDiv.appendChild( WLoptionsEphemeridesYearTickAll );
    var WLoptionsEphemeridesYearUntickAll = document.createElement( "input" );
    WLoptionsEphemeridesYearUntickAll.type = "button";
    WLoptionsEphemeridesYearUntickAll.value = "Décocher toutes les années";
    WLoptionsEphemeridesYearUntickAll.onclick = function() { var yearCheckboxList = document.getElementById( "WL-ephemerides-year-div" ).getElementsByTagName( "input" ); for ( var i = 0; i < yearCheckboxList.length ; i++ ) {if ( yearCheckboxList[i].type == "checkbox" ) yearCheckboxList[i].checked = false; } };
    WLEphemeridesButtonsYearDiv.appendChild( WLoptionsEphemeridesYearUntickAll );
    var WLoptionsEphemeridesYearDisTickAll = document.createElement( "input" );
    WLoptionsEphemeridesYearDisTickAll.type = "button";
    WLoptionsEphemeridesYearDisTickAll.value = "Inverser la sélection d'années";
    WLoptionsEphemeridesYearDisTickAll.onclick = function() { var yearCheckboxList = document.getElementById( "WL-ephemerides-year-div" ).getElementsByTagName( "input" ); for ( var i = 0; i < yearCheckboxList.length ; i++ ) {if ( yearCheckboxList[i].type != "checkbox" ) continue; if ( yearCheckboxList[i].checked ) yearCheckboxList[i].checked = false; else yearCheckboxList[i].checked = true; } };
    WLEphemeridesButtonsYearDiv.appendChild( WLoptionsEphemeridesYearDisTickAll );
 
    var WLEphemeridesTypesFieldSet = document.createElement( "fieldset" );
    WLEphemeridesTypesFieldSet.style.marginTop = "25px";
    WLEphemeridesTypesFieldSet.id = 'WL-ephemerides-types-div';
    WLEphemeridesTypesFieldSet.style.display = 'none';
    WLoptionsEphemeridesFieldSet.appendChild( WLEphemeridesTypesFieldSet );
    var WLEphemeridesTypesLegend = document.createElement( "legend" );
    WLEphemeridesTypesLegend.innerHTML = "Types de pages d'&Eacute;ph&eacute;m&eacute;ride &agrave; consid&eacute;rer";
    WLEphemeridesTypesFieldSet.appendChild( WLEphemeridesTypesLegend );
    var WLEphemeridesTypesArray = new Array( '', 'dans l\'animation et bande dessinée', 'dans les chemins de fer', 'en sport' );
    var WLEphemeridesTypesCheckboxes = new Array();
    var WLEphemeridesTypesLabels = new Array();
    for ( var i = 0 ; i < WLEphemeridesTypesArray.length ; i++ ) {
        WLEphemeridesTypesLabels[i] = document.createElement( "label" );
        WLEphemeridesTypesLabels[i].innerHTML = ( WLEphemeridesTypesArray[i] == '' ) ? '(pages g&eacute;n&eacute;rales)' : WLEphemeridesTypesArray[i] ;
        if ( WLEphemeridesTypesArray[i] == '' ) WLEphemeridesTypesLabels[i].style.fontStyle = "italic";
        WLEphemeridesTypesLabels[i].htmlFor = "WL-ephemerides-types-" + i;
        WLEphemeridesTypesLabels[i].style.marginLeft = "15px";
        WLEphemeridesTypesFieldSet.appendChild( WLEphemeridesTypesLabels[i] );
 
        WLEphemeridesTypesCheckboxes[i] = document.createElement( "input" );
        WLEphemeridesTypesCheckboxes[i].type = "checkbox";
        if ( WLEphemeridesTypesArray[i] == '' ) WLEphemeridesTypesCheckboxes[i].checked = true;
        WLEphemeridesTypesCheckboxes[i].id = "WL-ephemerides-types-" + i;
        WLEphemeridesTypesCheckboxes[i].value = WLEphemeridesTypesArray[i];
        WLEphemeridesTypesCheckboxes[i].name = "WL-ephemerides-types";
        WLEphemeridesTypesFieldSet.appendChild( WLEphemeridesTypesCheckboxes[i] );
    }
    var WLEphemeridesTypesButtonDiv = document.createElement( "div" );
    WLEphemeridesTypesButtonDiv.style.margin = '10px 50px 0 0';
    WLEphemeridesTypesFieldSet.appendChild( WLEphemeridesTypesButtonDiv );
    var WLEphemeridesTypesTickAll = document.createElement( "input" );
    WLEphemeridesTypesTickAll.type = "button";
    WLEphemeridesTypesTickAll.value = "Cocher tous les types";
    WLEphemeridesTypesTickAll.onclick = function() { var monthCheckboxList = document.getElementById( "WL-ephemerides-types-div" ).getElementsByTagName( "input" ); for ( var i = 0; i < monthCheckboxList.length ; i++ ) { if ( monthCheckboxList[i].type == "checkbox" ) monthCheckboxList[i].checked = true; } };
    WLEphemeridesTypesButtonDiv.appendChild( WLEphemeridesTypesTickAll );
    var WLEphemeridesTypesUntickAll = document.createElement( "input" );
    WLEphemeridesTypesUntickAll.type = "button";
    WLEphemeridesTypesUntickAll.value = "Décocher tous les types";
    WLEphemeridesTypesUntickAll.onclick = function() { var monthCheckboxList = document.getElementById( "WL-ephemerides-types-div" ).getElementsByTagName( "input" ); for ( var i = 0; i < monthCheckboxList.length ; i++ ) {if ( monthCheckboxList[i].type == "checkbox" ) monthCheckboxList[i].checked = false; } };
    WLEphemeridesTypesButtonDiv.appendChild( WLEphemeridesTypesUntickAll );
    var WLEphemeridesTypesDisTickAll = document.createElement( "input" );
    WLEphemeridesTypesDisTickAll.type = "button";
    WLEphemeridesTypesDisTickAll.value = "Inverser la sélection de types";
    WLEphemeridesTypesDisTickAll.onclick = function() { var monthCheckboxList = document.getElementById( "WL-ephemerides-types-div" ).getElementsByTagName( "input" ); for ( var i = 0; i < monthCheckboxList.length ; i++ ) {if ( monthCheckboxList[i].type != "checkbox" ) continue; if ( monthCheckboxList[i].checked ) monthCheckboxList[i].checked = false; else monthCheckboxList[i].checked = true; } };
    WLEphemeridesTypesButtonDiv.appendChild( WLEphemeridesTypesDisTickAll );

VI. Passons aux boutons qui permettront de lancer le script

    //un pour Le Bistro
    var WLbuttonBistro = document.createElement( "input" );
    WLbuttonBistro.type = "button";
    WLbuttonBistro.value = "Le Bistro";
    WLbuttonBistro.onclick = function( ) { if ( addBistroSubpages( checkRadioByName( "WL-year" ), checkBoxesByName( "WL-month" ), ( checkRadioByName( "WL-watch" ) == "unwatch" ) ) ) { if ( checkRadioByName( "WL-watch" ) == "unwatch" ) alert( "Retrait des pages du Bistro de votre LdS" ); else alert( "Ajout des pages du Bistro à votre LdS" ); } };
    WLwatchedPagesFieldSet.appendChild( WLbuttonBistro );
 
    //un pour le Bulletin des administrateurs
    var WLbuttonBA = document.createElement( "input" );
    WLbuttonBA.type = "button";
    WLbuttonBA.value = "Bulletin des administrateurs";
    WLbuttonBA.onclick = function( ) { if ( addWeeksSubpages( "Wikipédia:Bulletin des administrateurs", true, checkRadioByName( "WL-year" ), true, ( checkRadioByName( "WL-watch" ) == "unwatch" ) ) ) { if ( checkRadioByName( "WL-watch" ) == "unwatch" ) alert( "Retrait des pages du BA de votre LdS" ); else alert( "Ajout des pages du BA à votre LdS" ); } };
    WLwatchedPagesFieldSet.appendChild( WLbuttonBA );
 
    //un pour l'Oracle
    var WLbuttonOracle = document.createElement( "input" );
    WLbuttonOracle.type = "button";
    WLbuttonOracle.value = "Oracle";
    WLbuttonOracle.onclick = function( ) { if ( addWeeksSubpages( "Wikipédia:Oracle", false, checkRadioByName( "WL-year" ), false, ( checkRadioByName( "WL-watch" ) == "unwatch" ) ) ) { if ( checkRadioByName( "WL-watch" ) == "unwatch" ) alert( "Retrait des pages de l'Oracle de votre LdS" ); else alert( "Ajout des pages de l'Oracle à votre LdS" ); } };
    WLwatchedPagesFieldSet.appendChild( WLbuttonOracle );
 
    //un pour les Questions techniques, anciennement appelées Guilde des guides
    var WLbuttonQT = document.createElement( "input" );
    WLbuttonQT.type = "button";
    WLbuttonQT.value = "Questions techniques";
    WLbuttonQT.onclick = function( ) { if ( addWeeksSubpages( "Wikipédia:Questions techniques", false, checkRadioByName( "WL-year" ), false, ( checkRadioByName( "WL-watch" ) == "unwatch" ) ) ) { if ( checkRadioByName( "WL-watch" ) == "unwatch" ) alert( "Retrait des pages de Questions techniques de votre LdS" ); else alert( "Ajout des pages de Questions techniques à votre LdS" ); } };
    WLwatchedPagesFieldSet.appendChild( WLbuttonQT );
 
    //un pour les Éphémérides du type "1er janvier", "3 mars"
    var WLbuttonEphJM = document.createElement( "input" );
    WLbuttonEphJM.type = "button";
    WLbuttonEphJM.value = "Éphémérides Jour du Mois";
    WLbuttonEphJM.onclick = function() { if ( addEphemeridesJourMois( checkBoxesByName( "WL-month" ), checkBoxesByName( "WL-ephemerides-types" ), ( checkRadioByName( "WL-watch" ) == "unwatch" ) ) ) { if ( checkRadioByName( "WL-watch" ) == "unwatch" ) alert( "Retrait des pages d'Éphémérides Jour du Mois de votre LdS" ); else alert( "Ajout des pages d'Éphémérides Jour du Mois à votre LdS" ); } };
    WLwatchedPagesFieldSet.appendChild( WLbuttonEphJM );
 
    //un pour les Éphémérides du type "février 2003", "avril 2011"
    var WLbuttonEphMA = document.createElement( "input" );
    WLbuttonEphMA.type = "button";
    WLbuttonEphMA.value = "Éphémérides Mois de l'Année";
    WLbuttonEphMA.onclick = function() { if ( addEphemeridesMoisAnnees( checkBoxesByName( "WL-ephemerides-years" ), checkBoxesByName( "WL-ephemerides-types" ), ( checkRadioByName( "WL-watch" ) == "unwatch" ) ) ) { if ( checkRadioByName( "WL-watch" ) == "unwatch" ) alert( "Retrait des pages d'Éphéméride Mois de l'Année de votre LdS" ); else alert( "Ajout des pages dÉphéméride Mois de l'année à votre LdS" ); } };
    WLwatchedPagesFieldSet.appendChild( WLbuttonEphMA );

VII. C’est fini. Ou pas : il faut encore dire aux boutons ce qu’ils doivent faire

D’abord quelques fonctions « génériques », qui servent à plusieurs reprises :

//une fonction pour dire combien de jours il y a dans un mois donné d'une année donnée, utile pour le Bistro
//paramètres :
//* month : le numéro du mois, de 1 pour janvier à 12 pour décembre
//* year : le numéro de l'année, en 4 chiffres.
function daysInMonth( month, year ) {
    return 32 - new Date( year, month - 1, 32 ).getDate( );
}
 
//une fonction pour dire combien de jours il peut y avoir dans un mois donné (sans tenir compte de l'année), utile pour les éphémérides
function daysInMonth30fevrier( month ) {
    if ( month == 1 ) return 31;//janvier
    if ( month == 2 ) return 30;//oui, le 30 février a existé...
    if ( month == 3 ) return 31;
    if ( month == 4 ) return 30;
    if ( month == 5 ) return 31;
    if ( month == 6 ) return 30;
    if ( month == 7 ) return 31;
    if ( month == 8 ) return 31;
    if ( month == 9 ) return 30;
    if ( month == 10 ) return 31;
    if ( month == 11 ) return 30;
    if ( month == 12 ) return 31;//décembre
    return 0;
}
 
//une fonction pour déterminer lequel est sélectionné parmi un groupe de "boutons radio"
//paramètre :
//* checkedname : le name HTML du groupe de boutons radio
function checkRadioByName( checkedname ) {
    var namedElementsList = document.getElementsByName( checkedname );
    for ( var i = 0 ; i &lt; namedElementsList.length ; i++ ) {
        if ( namedElementsList[i].checked ) {
            return namedElementsList[i].value;
        }
    }
    return false;
}
 
//et une fonction similaire pour lister toutes les checkboxes sélectionnées d'un groupe
//paramètre :
//* checkedname : le name HTML du groupe de checkboxes
function checkBoxesByName( checkedname ) {
    var namedElementsList = document.getElementsByName( checkedname );
    var listedValues = new Array( );
    for ( var i = 0 ; i &lt; namedElementsList.length ; i++ ) {
        if ( namedElementsList[i].checked ) {
            listedValues.push( namedElementsList[i].value );
        }
    }
    if ( listedValues[0] ) return listedValues;
    return false;
}

Une fonction pour le bouton du Bistro. Cette fonction pouvant être amenée à faire suivre un grand nombre de pages (jusqu’à 366 pour toutes les pages de l’année prochaine, eh oui 2012 sera bissextile ), elle demandera une confirmation avant d’effectuer la grosse requête que représenterait son déclenchement pour un ensemble de plus de 3 mois. De plus, si aucun mois n’est sélectionné dans la liste, elle considèrera qu’ils le sont tous, et demandera donc une confirmation avant de démarrer.

//paramètres :
//* year : l'année à prendre en compte
//* months : un array JavaScript listant les numéros des mois (1 pour janvier, 12 pour décembre, ...) à prendre en compte
//* unwatch : un boolean valant false s'il faut suivre les pages à prendre en compte, true s'il faut ne plus les suivre
function addBistroSubpages( year, months, unwatch ) {
    if ( unwatch ) unwatch = "&amp;unwatch";
    else unwatch = '';
    if ( !months ) { months = new Array( 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 ); }
    var api = sajax_init_object( );
    var monthsListLocalized = {"1": "janvier", "2": "février", "3": "mars", "4": "avril", "5": "mai", "6": "juin", "7": "juillet", "8": "août", "9": "septembre", "10": "octobre", "11": "novembre", "12": "décembre"};
    if ( months.length &gt; 3 ) {
        var monthsListConfirm = new Array();
        for ( i = 0 ; i &lt; months.length ; i++ ) {
            monthsListConfirm.push( monthsListLocalized[months[i]] );
        }
        if ( !confirm( "Voulez-vous vraiment ajouter les mois de " + monthsListConfirm.join( ", " ) + " ? Cela risque de prendre du temps !" ) ) return false;
    }
    document.getElementById( "WL-results-maindiv" ).style.height = "300px";
    for ( var i = 0 ; i &lt; months.length ; i++ ) {
        for ( var j = 1 ; j &lt;= daysInMonth( months[i], year ) ; j++ ) {
            var fullpagename = 'Wikipédia:Le Bistro/' + j + ' ' + monthsListLocalized[months[i]] + ' ' + year;
            api.open( 'POST', wgServer + '/w/api.php?action=watch&amp;title=' + fullpagename + unwatch, false );
            api.send( null );
            document.getElementById( "WLaddsubpages-results" ).innerHTML += fullpagename;
            if ( unwatch == '' ) document.getElementById( "WLaddsubpages-results" ).innerHTML = document.getElementById( "WLaddsubpages-results" ).innerHTML + ' <img title="suivi" src="http://upload.wikimedia.org/wikipedia/commons/thumb/f/fb/Yes_check.svg/10px-Yes_check.svg.png" alt="" />
';
            else document.getElementById( "WLaddsubpages-results" ).innerHTML += ' <img title="n\'est plus suivi" src="http://upload.wikimedia.org/wikipedia/commons/thumb/a/a2/X_mark.svg/10px-X_mark.svg.png" alt="" />
';
            document.getElementById( "WLaddsubpages-results-count" ).innerHTML = parseInt( document.getElementById( "WLaddsubpages-results-count" ).innerHTML ) + 1;
            document.location.hash = "WLaddsubpages-results-bottom";
        }
    }
    return true;
}

Une fonction équivalente pour les sous-pages dont le titre inclut le numéro de semaine et l’année :

//Cette fonction ajoute les semaines 1 à 53 quelle que soit l'année. Vu que ça prend peu de temps en plus de faire une 53ème semaine, ça ne valait pas le coup de créer une fonction qui détermine le nombre de semaines dans une année, ce qui s'avère plus long qu'on pourrait croire...
//paramètres :
//* basepagename : le nom de la page de base
//* yearisprefix : un boolean qui vaut true si l'année est avant le numéro de semaine dans le titre des sous-pages, false sinon
//* yearaffix : le numéro de l'année, en 4 chiffres. Ce paramètre est directement fourni par la valeur de la liste de boutons radio correspondante, en utilisant la fonction checkRadioByName()
//* semaineMinMaj : vu que sinon ce serait trop simple, un boolean qui vaut true si le titre contient "Semaine", false s'il contient "semaine" (notez la différence entre majuscule et minuscule initiales)
//* unwatch : un boolean valant false s'il faut suivre les pages à prendre en compte, true s'il faut ne plus les suivre
function addWeeksSubpages( basepagename, yearisprefix, yearaffix, semaineMinMaj, unwatch ) {
    if ( semaineMinMaj ) semaineMinMaj = 'Semaine';
    else semaineMinMaj = 'semaine';
    if ( unwatch ) unwatch = "&amp;unwatch";
    else unwatch = '';
    var api = sajax_init_object( );
    if ( !yearaffix ) yearaffix = new Date( ).getFullYear( ) + 1900;
    document.getElementById( "WL-results-maindiv" ).style.height = "300px";
    for ( var i = 1 ; i &lt; 54 ; i++ ) {
        var fullpagename = basepagename.replace( /( \/ )?$/ ,'' ) + '/';
        if ( yearisprefix ) fullpagename += yearaffix + "/";
        fullpagename += semaineMinMaj + ' ' + i;
        if ( !yearisprefix ) fullpagename += " " + yearaffix;
        api.open( 'POST', wgServer + '/w/api.php?action=watch&amp;title=' + fullpagename + unwatch, false );
        api.send( null );
        document.getElementById( "WLaddsubpages-results" ).innerHTML += fullpagename;
        if ( unwatch == '' ) document.getElementById( "WLaddsubpages-results" ).innerHTML = document.getElementById( "WLaddsubpages-results" ).innerHTML + ' <img src="http://upload.wikimedia.org/wikipedia/commons/thumb/f/fb/Yes_check.svg/10px-Yes_check.svg.png" alt="" />
';
        else document.getElementById( "WLaddsubpages-results" ).innerHTML += ' <img src="http://upload.wikimedia.org/wikipedia/commons/thumb/a/a2/X_mark.svg/10px-X_mark.svg.png" alt="" />
';
        document.getElementById( "WLaddsubpages-results-count" ).innerHTML = parseInt( document.getElementById( "WLaddsubpages-results-count" ).innerHTML ) + 1;
        document.location.hash = "WLaddsubpages-results-bottom";
    }
    return true;
}

Et enfin, une pour chaque groupe de pages d’éphéméride (Jour du Mois, Mois de l’Année) :

//cette fonction ajoute les jours de chaque mois qu'on lui demande, y compris le 29 et le 30 février, sisi, je vous assure que ça existe !
//paramètres :
//* months : une liste de mois sous forme de tableau Javascript
//* basepageaffixes : une liste de type de pages d'éphéméride (les éphémérides toutes bêtes, en sport, etc...)
//* unwatch : un boolean valant false s'il faut suivre les pages à prendre en compte, true s'il faut ne plus les suivre
function addEphemeridesJourMois( months, basepageaffixes, unwatch ) {
    if ( unwatch ) unwatch = "&unwatch";
    else unwatch = '';
    if ( !basepageaffixes.length ) basepageaffixes = new Array( '', 'dans l\'animation et bande dessinée', 'dans les chemins de fer', 'en sport' );
    if ( !months.length ) { months = new Array( 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 ); }
    var api = sajax_init_object();
    var monthsListLocalized = {"1": "janvier", "2": "février", "3": "mars", "4": "avril", "5": "mai", "6": "juin", "7": "juillet", "8": "août", "9": "septembre", "10": "octobre", "11": "novembre", "12": "décembre"};
    if ( months.length > 3 ) {
        var monthsListConfirm = new Array();
        for ( i = 0 ; i < months.length ; i++ ) {
            monthsListConfirm.push( monthsListLocalized[months[i]] );
        }
        if ( !confirm( "Voulez-vous vraiment ajouter les mois de " + monthsListConfirm.join( ", " ) + " ? Cela risque de prendre du temps !" ) ) return false;
    }
 
    document.getElementById( "WL-results-maindiv" ).style.height = "300px";
 
    for ( var i = 0 ; i < months.length ; i++ ) {
        for ( var j = 1 ; j <= daysInMonth30fevrier( months[i] ) ; j++ ) {
            for ( var k = 0 ; k < basepageaffixes.length ; k++ ) {
                if ( basepageaffixes[k] != '' ) basepageaffixes[k] = ' ' + basepageaffixes[k].replace( /^\s*(\S.*\S)\s*$/, '$1' );
                if ( !( basepageaffixes[k] in { '':1, ' dans l\'animation et bande dessinée':1, ' dans les chemins de fer':1, ' en sport':1 } ) ) {
                    document.getElementById( "WLaddsubpages-results" ).innerHTML += 'Il n\'y a pas de pages de la forme "Mois Année ' + basepageaffixes[k] + '"&nbsp;<img src="http://upload.wikimedia.org/wikipedia/commons/thumb/d/dc/Nuvola_apps_important_yellow.svg/15px-Nuvola_apps_important_yellow.svg.png" title="pas de page de ce genre" /><br/>';
                    continue;
                }
                var fullpagename = ( j == 1) ? '1er' : j ;
                fullpagename += ' ' + monthsListLocalized[ months[i] ] + basepageaffixes[k];
                api.open( 'POST', wgServer + '/w/api.php?action=watch&title=' + fullpagename + unwatch, false );
                api.send( null );
                document.getElementById( "WLaddsubpages-results" ).innerHTML += fullpagename;
                if ( unwatch == '' ) document.getElementById( "WLaddsubpages-results" ).innerHTML = document.getElementById( "WLaddsubpages-results" ).innerHTML + '&nbsp;<img src="http://upload.wikimedia.org/wikipedia/commons/thumb/f/fb/Yes_check.svg/10px-Yes_check.svg.png" title="suivi" /><br/>';
                else document.getElementById( "WLaddsubpages-results" ).innerHTML += '&nbsp;<img src="http://upload.wikimedia.org/wikipedia/commons/thumb/a/a2/X_mark.svg/10px-X_mark.svg.png" title="n\'est plus suivi" /><br/>';
                document.getElementById( "WLaddsubpages-results-count" ).innerHTML = parseInt( document.getElementById( "WLaddsubpages-results-count" ).innerHTML ) + 1;
                document.location.hash = "WLaddsubpages-results-bottom";
            }
        }
    }
    return true;
}
 
//cette fonction ajoute les jours de chaque mois qu'on lui demande, y compris le 29 et le 30 février, sisi, je vous assure que ça existe !
//paramètres :
//* years : une liste d'années sous forme de tableau Javascript
//* basepageaffixes : une liste de type de pages d'éphéméride (les éphémérides toutes bêtes, en sport, etc...)
//* unwatch : un boolean valant false s'il faut suivre les pages à prendre en compte, true s'il faut ne plus les suivre
function addEphemeridesMoisAnnees( years, basepageaffixes, unwatch ) {
    if ( unwatch ) unwatch = "&unwatch";
    else unwatch = '';
    if ( !basepageaffixes.length ) basepageaffixes = new Array( '', 'en sport' );
    for ( var i = 0 ; i < basepageaffixes.length ; i++ ) if ( basepageaffixes[i] != '' ) basepageaffixes[i] = ' ' + basepageaffixes[i].replace( /^\s*(\S.*\S)\s*$/, '$1' );
    if ( !years.length ) {
        years = new Array();
        for ( var i = 0 ; i <= new Date().getYear() - 10 ; i++ ) { years.push( 1900 + i ); }
    }
    var api = sajax_init_object();
    var monthsListLocalized = {"1": "janvier", "2": "février", "3": "mars", "4": "avril", "5": "mai", "6": "juin", "7": "juillet", "8": "août", "9": "septembre", "10": "octobre", "11": "novembre", "12": "décembre"};
    if ( years.length > 7 ) {
        if ( !confirm( "Voulez-vous vraiment ajouter les années " + years.join( ", " ) + " ? Cela risque de prendre du temps !" ) ) return false;
    }
    document.getElementById( "WL-results-maindiv" ).style.height = "300px";
    for ( var i = 0 ; i < years.length ; i++ ) {
        for ( var j = 1 ; j <= 12 ; j++ ) {
            for ( var k = 0 ; k < basepageaffixes.length ; k++ ) {
                if ( !( basepageaffixes[k] in { '':1, ' en sport':1 } ) ) {
                    document.getElementById( "WLaddsubpages-results" ).innerHTML += 'Il n\'y a pas de pages de la forme "Mois Année ' + basepageaffixes[k] + '"&nbsp;<img src="http://upload.wikimedia.org/wikipedia/commons/thumb/d/dc/Nuvola_apps_important_yellow.svg/15px-Nuvola_apps_important_yellow.svg.png" title="pas de page de ce genre" /><br/>';
                    continue;
                }
                var fullpagename = monthsListLocalized[ j ] + ' ' + years[i] + basepageaffixes[k];
                api.open( 'POST', wgServer + '/w/api.php?action=watch&title=' + fullpagename + unwatch, false );
                api.send( null );
                document.getElementById( "WLaddsubpages-results" ).innerHTML += fullpagename;
                if ( unwatch == '' ) document.getElementById( "WLaddsubpages-results" ).innerHTML = document.getElementById( "WLaddsubpages-results" ).innerHTML + '&nbsp;<img src="http://upload.wikimedia.org/wikipedia/commons/thumb/f/fb/Yes_check.svg/10px-Yes_check.svg.png" title="suivi" /><br/>';
                else document.getElementById( "WLaddsubpages-results" ).innerHTML += '&nbsp;<img src="http://upload.wikimedia.org/wikipedia/commons/thumb/a/a2/X_mark.svg/10px-X_mark.svg.png" title="n\'est plus suivi" /><br/>';
                document.getElementById( "WLaddsubpages-results-count" ).innerHTML = parseInt( document.getElementById( "WLaddsubpages-results-count" ).innerHTML ) + 1;
                document.location.hash = "WLaddsubpages-results-bottom";
            }
        }
    }
    return true;
}

Et alors, ça donne quoi ?

C’est bien simple, si vous avez tout suivi, le résultat, c’est ça :

function daysInMonth( month, year ) {
    return 32 - new Date( year, month - 1, 32 ).getDate();
}
 
function daysInMonth30fevrier( month ) {
    if ( month == 1 ) return 31;//janvier
    if ( month == 2 ) return 30;
    if ( month == 3 ) return 31;
    if ( month == 4 ) return 30;
    if ( month == 5 ) return 31;
    if ( month == 6 ) return 30;
    if ( month == 7 ) return 31;
    if ( month == 8 ) return 31;
    if ( month == 9 ) return 30;
    if ( month == 10 ) return 31;
    if ( month == 11 ) return 30;
    if ( month == 12 ) return 31;//décembre
    return 0;
}
 
function addWeeksSubpages( basepagename, yearisprefix, yearaffix, semaineMinMaj, unwatch ) {
    if ( semaineMinMaj ) semaineMinMaj = 'Semaine';
    else semaineMinMaj = 'semaine';
    if ( unwatch ) unwatch = "&unwatch";
    else unwatch = '';
    var api = sajax_init_object();
    if ( !yearaffix ) yearaffix = new Date().getFullYear() + 1900;
    document.getElementById( "WL-results-maindiv" ).style.height = "300px";
    for ( var i = 1 ; i < 54 ; i++ ) {
        var fullpagename = basepagename.replace( /( \/ )?$/ ,'' ) + '/';
        if ( yearisprefix ) fullpagename += yearaffix + "/";
        fullpagename += semaineMinMaj + ' ' + i;
        if ( !yearisprefix ) fullpagename += " " + yearaffix;
        api.open( 'POST', wgServer + '/w/api.php?action=watch&title=' + fullpagename + unwatch, false );
        api.send( null );
        document.getElementById( "WLaddsubpages-results" ).innerHTML += fullpagename;
        if ( unwatch == '' ) document.getElementById( "WLaddsubpages-results" ).innerHTML = document.getElementById( "WLaddsubpages-results" ).innerHTML + '&nbsp;<img src="http://upload.wikimedia.org/wikipedia/commons/thumb/f/fb/Yes_check.svg/10px-Yes_check.svg.png" /><br/>';
        else document.getElementById( "WLaddsubpages-results" ).innerHTML += '&nbsp;<img src="http://upload.wikimedia.org/wikipedia/commons/thumb/a/a2/X_mark.svg/10px-X_mark.svg.png" /><br/>';
        document.getElementById( "WLaddsubpages-results-count" ).innerHTML = parseInt( document.getElementById( "WLaddsubpages-results-count" ).innerHTML ) + 1;
        document.location.hash = "WLaddsubpages-results-bottom";
    }
    return true;
}
 
function addBistroSubpages( year, months, unwatch ) {
    if ( unwatch ) unwatch = "&unwatch";
    else unwatch = '';
    if ( months === false ) { months = new Array( 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 ); }
    var api = sajax_init_object();
    var monthsListLocalized = {"1": "janvier", "2": "février", "3": "mars", "4": "avril", "5": "mai", "6": "juin", "7": "juillet", "8": "août", "9": "septembre", "10": "octobre", "11": "novembre", "12": "décembre"};
    if ( months.length > 3 ) {
        var monthsListConfirm = new Array();
        for ( i = 0 ; i < months.length ; i++ ) {
            monthsListConfirm.push( monthsListLocalized[ months[i] ] );
        }
        if ( !confirm( "Voulez-vous vraiment ajouter les mois de " + monthsListConfirm.join( ", " ) + " ? Cela risque de prendre du temps !" ) ) return false;
    }
    document.getElementById( "WL-results-maindiv" ).style.height = "300px";
    for ( var i = 0 ; i < months.length ; i++ ) {
        for ( var j = 1 ; j <= daysInMonth( months[i], year ) ; j++ ) {
            var fullpagename = 'Wikipédia:Le Bistro/' + j + ' ' + monthsListLocalized[ months[i] ] + ' ' + year;
            api.open( 'POST', wgServer + '/w/api.php?action=watch&title=' + fullpagename + unwatch, false );
            api.send( null );
            document.getElementById( "WLaddsubpages-results" ).innerHTML += fullpagename;
            if ( unwatch == '' ) document.getElementById( "WLaddsubpages-results" ).innerHTML = document.getElementById( "WLaddsubpages-results" ).innerHTML + '&nbsp;<img src="http://upload.wikimedia.org/wikipedia/commons/thumb/f/fb/Yes_check.svg/10px-Yes_check.svg.png" title="suivi" /><br/>';
            else document.getElementById( "WLaddsubpages-results" ).innerHTML += '&nbsp;<img src="http://upload.wikimedia.org/wikipedia/commons/thumb/a/a2/X_mark.svg/10px-X_mark.svg.png" title="n\'est plus suivi" /><br/>';
            document.getElementById( "WLaddsubpages-results-count" ).innerHTML = parseInt( document.getElementById( "WLaddsubpages-results-count" ).innerHTML ) + 1;
            document.location.hash = "WLaddsubpages-results-bottom";
        }
    }
    return true;
}
 
function addEphemeridesJourMois( months, basepageaffixes, unwatch ) {
    if ( unwatch ) unwatch = "&unwatch";
    else unwatch = '';
    if ( !basepageaffixes.length ) basepageaffixes = new Array( '', 'dans l\'animation et bande dessinée', 'dans les chemins de fer', 'en sport' );
    if ( !months.length ) { months = new Array( 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 ); }
    var api = sajax_init_object();
    var monthsListLocalized = {"1": "janvier", "2": "février", "3": "mars", "4": "avril", "5": "mai", "6": "juin", "7": "juillet", "8": "août", "9": "septembre", "10": "octobre", "11": "novembre", "12": "décembre"};
    if ( months.length > 3 ) {
        var monthsListConfirm = new Array();
        for ( i = 0 ; i < months.length ; i++ ) {
            monthsListConfirm.push( monthsListLocalized[months[i]] );
        }
        if ( !confirm( "Voulez-vous vraiment ajouter les mois de " + monthsListConfirm.join( ", " ) + " ? Cela risque de prendre du temps !" ) ) return false;
    }
 
    document.getElementById( "WL-results-maindiv" ).style.height = "300px";
    for ( var i = 0 ; i < months.length ; i++ ) {
        for ( var j = 1 ; j <= daysInMonth30fevrier( months[i] ) ; j++ ) {
            for ( var k = 0 ; k < basepageaffixes.length ; k++ ) {
                if ( basepageaffixes[k] != '' ) basepageaffixes[k] = ' ' + basepageaffixes[k].replace( /^\s*(\S.*\S)\s*$/, '$1' );
                if ( !( basepageaffixes[k] in { '':1, ' dans l\'animation et bande dessinée':1, ' dans les chemins de fer':1, ' en sport':1 } ) ) {
                    document.getElementById( "WLaddsubpages-results" ).innerHTML += 'Il n\'y a pas de pages de la forme "Mois Année ' + basepageaffixes[k] + '"&nbsp;<img src="http://upload.wikimedia.org/wikipedia/commons/thumb/d/dc/Nuvola_apps_important_yellow.svg/15px-Nuvola_apps_important_yellow.svg.png" title="pas de page de ce genre" /><br/>';
                    continue;
                }
                var fullpagename = ( j == 1) ? '1er' : j ;
                fullpagename += ' ' + monthsListLocalized[ months[i] ] + basepageaffixes[k];
                api.open( 'POST', wgServer + '/w/api.php?action=watch&title=' + fullpagename + unwatch, false );
                api.send( null );
                document.getElementById( "WLaddsubpages-results" ).innerHTML += fullpagename;
                if ( unwatch == '' ) document.getElementById( "WLaddsubpages-results" ).innerHTML = document.getElementById( "WLaddsubpages-results" ).innerHTML + '&nbsp;<img src="http://upload.wikimedia.org/wikipedia/commons/thumb/f/fb/Yes_check.svg/10px-Yes_check.svg.png" title="suivi" /><br/>';
                else document.getElementById( "WLaddsubpages-results" ).innerHTML += '&nbsp;<img src="http://upload.wikimedia.org/wikipedia/commons/thumb/a/a2/X_mark.svg/10px-X_mark.svg.png" title="n\'est plus suivi" /><br/>';
                document.getElementById( "WLaddsubpages-results-count" ).innerHTML = parseInt( document.getElementById( "WLaddsubpages-results-count" ).innerHTML ) + 1;
                document.location.hash = "WLaddsubpages-results-bottom";
            }
        }
    }
    return true;
}
 
function addEphemeridesMoisAnnees( years, basepageaffixes, unwatch ) {
    if ( unwatch ) unwatch = "&unwatch";
    else unwatch = '';
    if ( !basepageaffixes.length ) basepageaffixes = new Array( '', 'en sport' );
    for ( var i = 0 ; i < basepageaffixes.length ; i++ ) if ( basepageaffixes[i] != '' ) basepageaffixes[i] = ' ' + basepageaffixes[i].replace( /^\s*(\S.*\S)\s*$/, '$1' );
    if ( !years.length ) {
        years = new Array();
        for ( var i = 0 ; i <= new Date().getYear() - 10 ; i++ ) { years.push( 1900 + i ); }
    }
    var api = sajax_init_object();
    var monthsListLocalized = {"1": "janvier", "2": "février", "3": "mars", "4": "avril", "5": "mai", "6": "juin", "7": "juillet", "8": "août", "9": "septembre", "10": "octobre", "11": "novembre", "12": "décembre"};
    if ( years.length > 7 ) {
        if ( !confirm( "Voulez-vous vraiment ajouter les années " + years.join( ", " ) + " ? Cela risque de prendre du temps !" ) ) return false;
    }
    document.getElementById( "WL-results-maindiv" ).style.height = "300px";
    for ( var i = 0 ; i < years.length ; i++ ) {
        for ( var j = 1 ; j <= 12 ; j++ ) {
            for ( var k = 0 ; k < basepageaffixes.length ; k++ ) {
                if ( !( basepageaffixes[k] in { '':1, ' en sport':1 } ) ) {
                    document.getElementById( "WLaddsubpages-results" ).innerHTML += 'Il n\'y a pas de pages de la forme "Mois Année ' + basepageaffixes[k] + '"&nbsp;<img src="http://upload.wikimedia.org/wikipedia/commons/thumb/d/dc/Nuvola_apps_important_yellow.svg/15px-Nuvola_apps_important_yellow.svg.png" title="pas de page de ce genre" /><br/>';
                    continue;
                }
                var fullpagename = monthsListLocalized[ j ] + ' ' + years[i] + basepageaffixes[k];
                api.open( 'POST', wgServer + '/w/api.php?action=watch&title=' + fullpagename + unwatch, false );
                api.send( null );
                document.getElementById( "WLaddsubpages-results" ).innerHTML += fullpagename;
                if ( unwatch == '' ) document.getElementById( "WLaddsubpages-results" ).innerHTML = document.getElementById( "WLaddsubpages-results" ).innerHTML + '&nbsp;<img src="http://upload.wikimedia.org/wikipedia/commons/thumb/f/fb/Yes_check.svg/10px-Yes_check.svg.png" title="suivi" /><br/>';
                else document.getElementById( "WLaddsubpages-results" ).innerHTML += '&nbsp;<img src="http://upload.wikimedia.org/wikipedia/commons/thumb/a/a2/X_mark.svg/10px-X_mark.svg.png" title="n\'est plus suivi" /><br/>';
                document.getElementById( "WLaddsubpages-results-count" ).innerHTML = parseInt( document.getElementById( "WLaddsubpages-results-count" ).innerHTML ) + 1;
                document.location.hash = "WLaddsubpages-results-bottom";
            }
        }
    }
    return true;
}
 
function addWatchUnWatchButtons() {
    if ( wgCanonicalNamespace != "Special" ) return false;
    if ( wgCanonicalSpecialPageName != "Watchlist" ) return false;
    var WLdiv = document.createElement( "form" );
    document.getElementById( "bodyContent" ).appendChild( WLdiv );
 
    var monthsListLocalized = {"1": "janvier", "2": "février", "3": "mars", "4": "avril", "5": "mai", "6": "juin", "7": "juillet", "8": "août", "9": "septembre", "10": "octobre", "11": "novembre", "12": "décembre"};
 
    var WLyearFieldSet = document.createElement( "fieldset" );
    WLdiv.appendChild( WLyearFieldSet );
    var WLyearLegend = document.createElement( "legend" );
    WLyearLegend.innerHTML = "Ann&eacute;e";
    WLyearFieldSet.appendChild( WLyearLegend );
 
    var WLmin2YearLabel = document.createElement( "label" );
    WLmin2YearLabel.innerHTML = new Date().getFullYear() - 2;
    WLmin2YearLabel.htmlFor = "WL-min2year";
    WLmin2YearLabel.style.marginLeft = "20px";
    WLyearFieldSet.appendChild( WLmin2YearLabel );
    var WLmin2Year = document.createElement( "input" );
    WLmin2Year.type = "radio";
    WLmin2Year.name = "WL-year";
    WLmin2Year.id = "WL-min2year";
    WLmin2Year.value = new Date().getFullYear() - 2;
    WLyearFieldSet.appendChild( WLmin2Year );
 
    var WLpreviousYearLabel = document.createElement( "label" );
    WLpreviousYearLabel.innerHTML = new Date().getFullYear() - 1;
    WLpreviousYearLabel.htmlFor = "WL-previousyear";
    WLpreviousYearLabel.style.marginLeft = "20px";
    WLyearFieldSet.appendChild( WLpreviousYearLabel );
    var WLpreviousYear = document.createElement( "input" );
    WLpreviousYear.type = "radio";
    WLpreviousYear.name = "WL-year";
    WLpreviousYear.id = "WL-previousyear";
    WLpreviousYear.value = new Date().getFullYear() - 1;
    WLyearFieldSet.appendChild( WLpreviousYear );
 
    var WLcurrentYearLabel = document.createElement( "label" );
    WLcurrentYearLabel.innerHTML = new Date().getFullYear();
    WLcurrentYearLabel.htmlFor = "WL-currentyear";
    WLcurrentYearLabel.style.marginLeft = "20px";
    WLyearFieldSet.appendChild( WLcurrentYearLabel );
    var WLcurrentYear = document.createElement( "input" );
    WLcurrentYear.type = "radio";
    WLcurrentYear.name = "WL-year";
    WLcurrentYear.id = "WL-currentyear";
    WLcurrentYear.checked = true;
    WLcurrentYear.value = new Date().getFullYear();
    WLyearFieldSet.appendChild( WLcurrentYear );
 
    var WLnextYearLabel = document.createElement( "label" );
    WLnextYearLabel.innerHTML = new Date().getFullYear() + 1;
    WLnextYearLabel.htmlFor = "WL-nextyear";
    WLnextYearLabel.style.marginLeft = "20px";
    WLyearFieldSet.appendChild( WLnextYearLabel );
    var WLnextYear = document.createElement( "input" );
    WLnextYear.type = "radio";
    WLnextYear.name = "WL-year";
    WLnextYear.id = "WL-nextyear";
    WLnextYear.value = new Date().getFullYear() + 1;
    WLyearFieldSet.appendChild( WLnextYear );
 
    var WLmonthFieldSet = document.createElement( "fieldset" );
    WLmonthFieldSet.id = "WL-month-fieldset";
    WLdiv.appendChild( WLmonthFieldSet );
    var WLmonthLegend = document.createElement( "legend" );
    WLmonthLegend.innerHTML = 'Mois <span style="font-size: .8em;">(ne sera pris en compte que pour le Bistro et les &Eacute;ph&eacute;m&eacute;rides)</span>';
    WLmonthFieldSet.appendChild( WLmonthLegend );
    var monthsListLocalized = {"1": "janvier", "2": "février", "3": "mars", "4": "avril", "5": "mai", "6": "juin", "7": "juillet", "8": "août", "9": "septembre", "10": "octobre", "11": "novembre", "12": "décembre"};
    var WLmonthLabel = new Array();
    var WLmonth = new Array();
    for ( var i=1 ; i < 13 ; i++ ) {
        WLmonthLabel[i] = document.createElement( "label" );
        WLmonthLabel[i].innerHTML = monthsListLocalized[i];
        WLmonthLabel[i].htmlFor = "WL-month" + i;
        WLmonthLabel[i].style.marginLeft = "20px";
        WLmonthFieldSet.appendChild( WLmonthLabel[i] );
 
        WLmonth[i] = document.createElement( "input" )
        WLmonth[i].type = "checkbox";
        WLmonth[i].name = "WL-month";
        WLmonth[i].value = i;
        WLmonth[i].id = "WL-month" + i;
        WLmonthFieldSet.appendChild( WLmonth[i] );
    }
    var WLmonthButtonsDiv = document.createElement( "div" );
    WLmonthFieldSet.appendChild( WLmonthButtonsDiv );
    var WLmonthTickAll = document.createElement( "input" );
    WLmonthTickAll.type = "button";
    WLmonthTickAll.value = "Cocher tout";
    WLmonthTickAll.onclick = function() { var monthCheckboxList = document.getElementById( "WL-month-fieldset" ).getElementsByTagName( "input" ); for ( var i = 0; i < monthCheckboxList.length ; i++ ) { if ( monthCheckboxList[i].type == "checkbox" ) monthCheckboxList[i].checked = true; } };
    WLmonthButtonsDiv.appendChild( WLmonthTickAll );
    var WLmonthUntickAll = document.createElement( "input" );
    WLmonthUntickAll.type = "button";
    WLmonthUntickAll.value = "Décocher tout";
    WLmonthUntickAll.onclick = function() { var monthCheckboxList = document.getElementById( "WL-month-fieldset" ).getElementsByTagName( "input" ); for ( var i = 0; i < monthCheckboxList.length ; i++ ) {if ( monthCheckboxList[i].type == "checkbox" ) monthCheckboxList[i].checked = false; } };
    WLmonthButtonsDiv.appendChild( WLmonthUntickAll );
    var WLmonthDisTickAll = document.createElement( "input" );
    WLmonthDisTickAll.type = "button";
    WLmonthDisTickAll.value = "Inverser la sélection";
    WLmonthDisTickAll.onclick = function() { var monthCheckboxList = document.getElementById( "WL-month-fieldset" ).getElementsByTagName( "input" ); for ( var i = 0; i < monthCheckboxList.length ; i++ ) {if ( monthCheckboxList[i].type != "checkbox" ) continue; if ( monthCheckboxList[i].checked ) monthCheckboxList[i].checked = false; else monthCheckboxList[i].checked = true; } };
    WLmonthButtonsDiv.appendChild( WLmonthDisTickAll );
 
    var WLoptionsFieldSet = document.createElement( "fieldset" );
    WLdiv.appendChild( WLoptionsFieldSet );
    var WLoptionsLegend = document.createElement( "legend" );
    WLoptionsLegend.innerHTML = "Options g&eacute;n&eacute;rales";
    WLoptionsFieldSet.appendChild( WLoptionsLegend );
 
    var WLoptionsWatchFieldSet = document.createElement( "fieldset" );
    WLoptionsFieldSet.appendChild( WLoptionsWatchFieldSet );
    var WLoptionsWatchLegend = document.createElement( "legend" );
    WLoptionsWatchLegend.innerHTML = "Options de suivi";
    WLoptionsWatchFieldSet.appendChild( WLoptionsWatchLegend );
    var WLoptionsWatchLabel = document.createElement( "label" );
    WLoptionsWatchLabel.htmlFor = "WL-watch";
    WLoptionsWatchLabel.innerHTML = "Suivre";
    WLoptionsWatchLabel.style.marginLeft = "15px";
    WLoptionsWatchFieldSet.appendChild( WLoptionsWatchLabel );
    var WLoptionsWatch = document.createElement( "input" );
    WLoptionsWatch.type = "radio";
    WLoptionsWatch.id = "WL-watch";
    WLoptionsWatch.value = "watch";
    WLoptionsWatch.name = "WL-watch";
    WLoptionsWatch.checked = true;
    WLoptionsWatchFieldSet.appendChild( WLoptionsWatch );
 
    var WLoptionsUnwatch = document.createElement( "input" );
    WLoptionsUnwatch.type = "radio";
    WLoptionsUnwatch.id = "WL-unwatch";
    WLoptionsUnwatch.value = "unwatch";
    WLoptionsUnwatch.name = "WL-watch";
    WLoptionsWatchFieldSet.appendChild( WLoptionsUnwatch );
    var WLoptionsUnwatchLabel = document.createElement( "label" );
    WLoptionsUnwatchLabel.htmlFor = "WL-unwatch";
    WLoptionsUnwatchLabel.innerHTML = "Ne plus suivre";
    WLoptionsWatchFieldSet.appendChild( WLoptionsUnwatchLabel );
 
    var WLoptionsEphemeridesFieldSet = document.createElement( "fieldset" );
    WLoptionsFieldSet.appendChild( WLoptionsEphemeridesFieldSet );
    var WLoptionsEphemeridesLegend = document.createElement( "legend" );
    WLoptionsEphemeridesLegend.innerHTML = '&Eacute;ph&eacute;m&eacute;rides <span style="font-size: .8em;">(cliquer pour afficher/masquer)</span>';
    WLoptionsEphemeridesLegend.cursor = 'pointer';
    WLoptionsEphemeridesLegend.onclick = function(){if ( document.getElementById( "WL-ephemerides-year-div" ).style.display == "none" ) { document.getElementById( "WL-ephemerides-year-div" ).style.display = "block"; document.getElementById( "WL-ephemerides-types-div" ).style.display = "block"; } else { document.getElementById( "WL-ephemerides-year-div" ).style.display = "none"; document.getElementById( "WL-ephemerides-types-div" ).style.display = "none"; } };
    WLoptionsEphemeridesFieldSet.appendChild( WLoptionsEphemeridesLegend );
 
    var WLoptionsEphemeridesYearFieldSet = document.createElement( "fieldset" );
    WLoptionsEphemeridesYearFieldSet.id = "WL-ephemerides-year-div";
    WLoptionsEphemeridesYearFieldSet.style.display = "none";
    WLoptionsEphemeridesFieldSet.appendChild( WLoptionsEphemeridesYearFieldSet );
    var WLoptionsEphemeridesYearLegend = document.createElement( "legend" );
    WLoptionsEphemeridesYearLegend.innerHTML = "Ann&eacute;es &agrave; prendre en consid&eacute;ration";
    WLoptionsEphemeridesYearFieldSet.appendChild( WLoptionsEphemeridesYearLegend );
    var WLoptionsEphemeridesYearsCheckbox = new Array();
    var WLoptionsEphemeridesYearsLabel = new Array();
    for ( var i = 1900 ; i <= new Date().getFullYear() + 10 ; i++ ) {
        WLoptionsEphemeridesYearsLabel[i] = document.createElement( "label" );
        WLoptionsEphemeridesYearsLabel[i].innerHTML = i;
        WLoptionsEphemeridesYearsLabel[i].htmlFor = "WL-ephemerides-year-" + i;
        WLoptionsEphemeridesYearsLabel[i].style.marginLeft = "20px";
        WLoptionsEphemeridesYearFieldSet.appendChild( WLoptionsEphemeridesYearsLabel[i] );
 
        WLoptionsEphemeridesYearsCheckbox[i] = document.createElement( "input" );
        WLoptionsEphemeridesYearsCheckbox[i].type = "checkbox";
        WLoptionsEphemeridesYearsCheckbox[i].id = "WL-ephemerides-year-" + i;
        WLoptionsEphemeridesYearsCheckbox[i].value = i + '';
        WLoptionsEphemeridesYearsCheckbox[i].name = 'WL-ephemerides-years';
        if ( i >= new Date().getFullYear() - 1 ) WLoptionsEphemeridesYearsCheckbox[i].checked = true;
        WLoptionsEphemeridesYearFieldSet.appendChild( WLoptionsEphemeridesYearsCheckbox[i] );
        if ( ( i % 10 ) == 9 ) WLoptionsEphemeridesYearFieldSet.appendChild( document.createElement( "br" ) );
    }
 
    var WLEphemeridesButtonsYearDiv = document.createElement( "div" );
    WLEphemeridesButtonsYearDiv.style.margin = '10px 50px 0 0';
    WLoptionsEphemeridesYearFieldSet.appendChild( WLEphemeridesButtonsYearDiv );
    var WLoptionsEphemeridesYearTickAll = document.createElement( "input" );
    WLoptionsEphemeridesYearTickAll.type = "button";
    WLoptionsEphemeridesYearTickAll.value = "Cocher toutes les années";
    WLoptionsEphemeridesYearTickAll.onclick = function() { var yearCheckboxList = document.getElementById( "WL-ephemerides-year-div" ).getElementsByTagName( "input" ); for ( var i = 0; i < yearCheckboxList.length ; i++ ) { if ( yearCheckboxList[i].type == "checkbox" ) yearCheckboxList[i].checked = true; } };
    WLEphemeridesButtonsYearDiv.appendChild( WLoptionsEphemeridesYearTickAll );
    var WLoptionsEphemeridesYearUntickAll = document.createElement( "input" );
    WLoptionsEphemeridesYearUntickAll.type = "button";
    WLoptionsEphemeridesYearUntickAll.value = "Décocher toutes les années";
    WLoptionsEphemeridesYearUntickAll.onclick = function() { var yearCheckboxList = document.getElementById( "WL-ephemerides-year-div" ).getElementsByTagName( "input" ); for ( var i = 0; i < yearCheckboxList.length ; i++ ) {if ( yearCheckboxList[i].type == "checkbox" ) yearCheckboxList[i].checked = false; } };
    WLEphemeridesButtonsYearDiv.appendChild( WLoptionsEphemeridesYearUntickAll );
    var WLoptionsEphemeridesYearDisTickAll = document.createElement( "input" );
    WLoptionsEphemeridesYearDisTickAll.type = "button";
    WLoptionsEphemeridesYearDisTickAll.value = "Inverser la sélection d'années";
    WLoptionsEphemeridesYearDisTickAll.onclick = function() { var yearCheckboxList = document.getElementById( "WL-ephemerides-year-div" ).getElementsByTagName( "input" ); for ( var i = 0; i < yearCheckboxList.length ; i++ ) {if ( yearCheckboxList[i].type != "checkbox" ) continue; if ( yearCheckboxList[i].checked ) yearCheckboxList[i].checked = false; else yearCheckboxList[i].checked = true; } };
    WLEphemeridesButtonsYearDiv.appendChild( WLoptionsEphemeridesYearDisTickAll );
 
    var WLEphemeridesTypesFieldSet = document.createElement( "fieldset" );
    WLEphemeridesTypesFieldSet.style.marginTop = "25px";
    WLEphemeridesTypesFieldSet.id = 'WL-ephemerides-types-div';
    WLEphemeridesTypesFieldSet.style.display = 'none';
    WLoptionsEphemeridesFieldSet.appendChild( WLEphemeridesTypesFieldSet );
    var WLEphemeridesTypesLegend = document.createElement( "legend" );
    WLEphemeridesTypesLegend.innerHTML = "Types de pages d'&Eacute;ph&eacute;m&eacute;ride &agrave; consid&eacute;rer";
    WLEphemeridesTypesFieldSet.appendChild( WLEphemeridesTypesLegend );
    var WLEphemeridesTypesArray = new Array( '', 'dans l\'animation et bande dessinée', 'dans les chemins de fer', 'en sport' );
    var WLEphemeridesTypesCheckboxes = new Array();
    var WLEphemeridesTypesLabels = new Array();
    for ( var i = 0 ; i < WLEphemeridesTypesArray.length ; i++ ) {
        WLEphemeridesTypesLabels[i] = document.createElement( "label" );
        WLEphemeridesTypesLabels[i].innerHTML = ( WLEphemeridesTypesArray[i] == '' ) ? '(pages g&eacute;n&eacute;rales)' : WLEphemeridesTypesArray[i] ;
        if ( WLEphemeridesTypesArray[i] == '' ) WLEphemeridesTypesLabels[i].style.fontStyle = "italic";
        WLEphemeridesTypesLabels[i].htmlFor = "WL-ephemerides-types-" + i;
        WLEphemeridesTypesLabels[i].style.marginLeft = "15px";
        WLEphemeridesTypesFieldSet.appendChild( WLEphemeridesTypesLabels[i] );
 
        WLEphemeridesTypesCheckboxes[i] = document.createElement( "input" );
        WLEphemeridesTypesCheckboxes[i].type = "checkbox";
        if ( WLEphemeridesTypesArray[i] == '' ) WLEphemeridesTypesCheckboxes[i].checked = true;
        WLEphemeridesTypesCheckboxes[i].id = "WL-ephemerides-types-" + i;
        WLEphemeridesTypesCheckboxes[i].value = WLEphemeridesTypesArray[i];
        WLEphemeridesTypesCheckboxes[i].name = "WL-ephemerides-types";
        WLEphemeridesTypesFieldSet.appendChild( WLEphemeridesTypesCheckboxes[i] );
    }
    var WLEphemeridesTypesButtonDiv = document.createElement( "div" );
    WLEphemeridesTypesButtonDiv.style.margin = '10px 50px 0 0';
    WLEphemeridesTypesFieldSet.appendChild( WLEphemeridesTypesButtonDiv );
    var WLEphemeridesTypesTickAll = document.createElement( "input" );
    WLEphemeridesTypesTickAll.type = "button";
    WLEphemeridesTypesTickAll.value = "Cocher tous les types";
    WLEphemeridesTypesTickAll.onclick = function() { var monthCheckboxList = document.getElementById( "WL-ephemerides-types-div" ).getElementsByTagName( "input" ); for ( var i = 0; i < monthCheckboxList.length ; i++ ) { if ( monthCheckboxList[i].type == "checkbox" ) monthCheckboxList[i].checked = true; } };
    WLEphemeridesTypesButtonDiv.appendChild( WLEphemeridesTypesTickAll );
    var WLEphemeridesTypesUntickAll = document.createElement( "input" );
    WLEphemeridesTypesUntickAll.type = "button";
    WLEphemeridesTypesUntickAll.value = "Décocher tous les types";
    WLEphemeridesTypesUntickAll.onclick = function() { var monthCheckboxList = document.getElementById( "WL-ephemerides-types-div" ).getElementsByTagName( "input" ); for ( var i = 0; i < monthCheckboxList.length ; i++ ) {if ( monthCheckboxList[i].type == "checkbox" ) monthCheckboxList[i].checked = false; } };
    WLEphemeridesTypesButtonDiv.appendChild( WLEphemeridesTypesUntickAll );
    var WLEphemeridesTypesDisTickAll = document.createElement( "input" );
    WLEphemeridesTypesDisTickAll.type = "button";
    WLEphemeridesTypesDisTickAll.value = "Inverser la sélection de types";
    WLEphemeridesTypesDisTickAll.onclick = function() { var monthCheckboxList = document.getElementById( "WL-ephemerides-types-div" ).getElementsByTagName( "input" ); for ( var i = 0; i < monthCheckboxList.length ; i++ ) {if ( monthCheckboxList[i].type != "checkbox" ) continue; if ( monthCheckboxList[i].checked ) monthCheckboxList[i].checked = false; else monthCheckboxList[i].checked = true; } };
    WLEphemeridesTypesButtonDiv.appendChild( WLEphemeridesTypesDisTickAll );
 
    var WLwatchedPagesFieldSet = document.createElement( "fieldset" );
    WLdiv.appendChild( WLwatchedPagesFieldSet );
    var WLwatchedPagesLegend = document.createElement( "legend" );
    WLwatchedPagesLegend.innerHTML = "Pages à suivre/ne plus suivre";
    WLwatchedPagesFieldSet.appendChild( WLwatchedPagesLegend );
 
    var WLbuttonBistro = document.createElement( "input" );
    WLbuttonBistro.type = "button";
    WLbuttonBistro.value = "Le Bistro";
    WLbuttonBistro.onclick = function() { if ( addBistroSubpages( checkRadioByName( "WL-year" ), checkBoxesByName( "WL-month" ), ( checkRadioByName( "WL-watch" ) == "unwatch" ) ) ) { if ( checkRadioByName( "WL-watch" ) == "unwatch" ) alert( "Retrait des pages du Bistro de votre LdS" ); else alert( "Ajout des pages du Bistro à votre LdS" ); } };
    WLwatchedPagesFieldSet.appendChild( WLbuttonBistro );
 
    var WLbuttonBA = document.createElement( "input" );
    WLbuttonBA.type = "button";
    WLbuttonBA.value = "Bulletin des administrateurs";
    WLbuttonBA.onclick = function() { if ( addWeeksSubpages( "Wikipédia:Bulletin des administrateurs", true, checkRadioByName( "WL-year" ), true, ( checkRadioByName( "WL-watch" ) == "unwatch" ) ) ) { if ( checkRadioByName( "WL-watch" ) == "unwatch" ) alert( "Retrait des pages du BA de votre LdS" ); else alert( "Ajout des pages du BA à votre LdS" ); } };
    WLwatchedPagesFieldSet.appendChild( WLbuttonBA );
 
    var WLbuttonOracle = document.createElement( "input" );
    WLbuttonOracle.type = "button";
    WLbuttonOracle.value = "Oracle";
    WLbuttonOracle.onclick = function() { if ( addWeeksSubpages( "Wikipédia:Oracle", false, checkRadioByName( "WL-year" ), false, ( checkRadioByName( "WL-watch" ) == "unwatch" ) ) ) { if ( checkRadioByName( "WL-watch" ) == "unwatch" ) alert( "Retrait des pages de l'Oracle de votre LdS" ); else alert( "Ajout des pages de l'Oracle à votre LdS" ); } };
    WLwatchedPagesFieldSet.appendChild( WLbuttonOracle );
 
    var WLbuttonQT = document.createElement( "input" );
    WLbuttonQT.type = "button";
    WLbuttonQT.value = "Questions techniques";
    WLbuttonQT.onclick = function() { if ( addWeeksSubpages( "Wikipédia:Questions techniques", false, checkRadioByName( "WL-year" ), false, ( checkRadioByName( "WL-watch" ) == "unwatch" ) ) ) { if ( checkRadioByName( "WL-watch" ) == "unwatch" ) alert( "Retrait des pages de Questions techniques de votre LdS" ); else alert( "Ajout des pages de Questions techniques à votre LdS" ); } };
    WLwatchedPagesFieldSet.appendChild( WLbuttonQT );
 
    var WLbuttonEphJM = document.createElement( "input" );
    WLbuttonEphJM.type = "button";
    WLbuttonEphJM.value = "Éphémérides Jour du Mois";
    WLbuttonEphJM.onclick = function() { if ( addEphemeridesJourMois( checkBoxesByName( "WL-month" ), checkBoxesByName( "WL-ephemerides-types" ), ( checkRadioByName( "WL-watch" ) == "unwatch" ) ) ) { if ( checkRadioByName( "WL-watch" ) == "unwatch" ) alert( "Retrait des pages d'Éphémérides Jour du Mois de votre LdS" ); else alert( "Ajout des pages d'Éphémérides Jour du Mois à votre LdS" ); } };
    WLwatchedPagesFieldSet.appendChild( WLbuttonEphJM );
 
    var WLbuttonEphMA = document.createElement( "input" );
    WLbuttonEphMA.type = "button";
    WLbuttonEphMA.value = "Éphémérides Mois de l'Année";
    WLbuttonEphMA.onclick = function() { if ( addEphemeridesMoisAnnees( checkBoxesByName( "WL-ephemerides-years" ), checkBoxesByName( "WL-ephemerides-types" ), ( checkRadioByName( "WL-watch" ) == "unwatch" ) ) ) { if ( checkRadioByName( "WL-watch" ) == "unwatch" ) alert( "Retrait des pages d'Éphéméride Mois de l'Année de votre LdS" ); else alert( "Ajout des pages dÉphéméride Mois de l'année à votre LdS" ); } };
    WLwatchedPagesFieldSet.appendChild( WLbuttonEphMA );
 
    var WLresultsFieldSet = document.createElement( "fieldset" );
    WLdiv.appendChild( WLresultsFieldSet );
    var WLresultsLegend = document.createElement( "legend" );
    WLresultsLegend.innerHTML = 'R&eacute;sultats <span style="font-size: .8em;">(pages ajout&eacute;es et supprim&eacute;es)</span>';
    WLresultsFieldSet.appendChild( WLresultsLegend );
    var WLresultsCountDiv = document.createElement( "div" );
    WLresultsFieldSet.appendChild( WLresultsCountDiv );
    WLresultsCountDiv.innerHTML = '<span id="WLaddsubpages-results-count">0</span> pages ajout&eacute;es ou supprim&eacute;es de votre LdS';
    var WLresultsMainDiv = document.createElement( "div" );
    WLresultsMainDiv.style.height = "50px";
    WLresultsMainDiv.style.width = "650px";
    WLresultsMainDiv.style.overflow = "auto";
    WLresultsMainDiv.id = "WL-results-maindiv";
    WLresultsFieldSet.appendChild( WLresultsMainDiv );
    var WLresultsDiv = document.createElement( "div" );
    WLresultsDiv.id = "WLaddsubpages-results";
    WLresultsDiv.style.fontSize = ".8em";
    WLresultsMainDiv.appendChild( WLresultsDiv );
    var WLresultsBottom = document.createElement( "a" );
    WLresultsBottom.id = "WLaddsubpages-results-bottom";
    WLresultsBottom.name = "WLaddsubpages-results-bottom";
    WLresultsBottom.href= document.location.href.replace( /#(.*)$/,'' );
    WLresultsBottom.innerHTML = "Recharger la page";
    WLresultsMainDiv.appendChild( WLresultsBottom );
 
    return true;
}
addOnloadHook( addWatchUnWatchButtons );
 
function checkRadioByName( checkedname ) {
    var namedElementsList = document.getElementsByName( checkedname );
    for ( var i = 0 ; i < namedElementsList.length ; i++ ) {
        if ( namedElementsList[i].checked ) {
            return namedElementsList[i].value;
        }
    }
    return false;
}
 
function checkBoxesByName( checkedname ) {
    var namedElementsList = document.getElementsByName( checkedname );
    var listedValues = new Array();
    for ( var i = 0 ; i < namedElementsList.length ; i++ ) {
        if ( namedElementsList[i].checked ) {
            listedValues.push( namedElementsList[i].value );
        }
    }
    if ( listedValues[0] !== false) return listedValues;
    return false;
}

Attendu qu’il ne fait qu’ajouter des <fieldset/> dans un élément commun aux skins Monobook et Vector (à savoir l’élément dont l’id est "bodyContent"), il devrait fonctionner sur l’un comme sur l’autre.


  1. si on veut ajouter la page sur laquelle on est à sa LdS, y’a le bouton « suivre/ne plus suivre », désormais représenté par une de ces 4 icônes []
  2. même s’il ne s’agit pas là d’un éditeur de texte, c’est la notion qui est derrière qui importe []
  3. pour simplifier, les deux grands « navigateurs » qu’emploient JavaScript, respectivement partout ailleurs et sur IE, pour plus de lecture consultez l’article idoine sur Wikipédia []

Leave a Reply

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre lang="" line="" escaped="" cssfile="">