Utilisateur:Bibifricotin/Monobook.js
Apparence
Note : après avoir enregistré la page, vous devrez forcer le rechargement complet du cache de votre navigateur pour voir les changements.
Mozilla / Firefox / Konqueror / Safari : maintenez la touche Majuscule (Shift) en cliquant sur le bouton Actualiser (Reload) ou pressez Maj-Ctrl-R (Cmd-R sur Apple Mac) ;
Firefox (sur GNU/Linux) / Chrome / Internet Explorer / Opera : maintenez la touche Ctrl en cliquant sur le bouton Actualiser ou pressez Ctrl-F5.obtenir("OptimizedSuivi");
obtenir("ResumeDeluxe");
obtenir("DeluxeBar");
obtenir("OngletPurge");
importScript('MediaWiki:Gadget-Popups.js');
popupRevertSummaryPrompt=true;
popupAdminLinks=true;
function OptimizedNavig()
{
var a = document.getElementById("p-navigation");
if (a)
{
b = a.getElementsByTagName("ul");
if(b.length > 0)
{
var startUrl = '/w/index.php?title='
var endUrl = '&action=purge'
// liste des URLs
var urls = new Array()
urls[0] = 'Wikipédia:Le Bistro'
urls[1] = 'Wikipédia:Pages à supprimer'
urls[2] = 'Wikipédia:Proposition articles de qualité'
urls[3] = 'WP:BOT'
urls[4] = 'Special:Newimages'
urls[5] = 'Special:Newpages'
urls[6] = 'Special:Blockip'
urls[7] = 'Special:Log/delete'
urls[8] = 'Special:Unusedcategories'
urls[9] = 'Special:Export'
var labels = new Array()
labels[0] = 'Bistro'
labels[1] = 'PàS'
labels[2] = 'pAdQ'
labels[3] = 'Bots'
labels[4] = 'nImgs'
labels[5] = 'nPage'
labels[6] = 'Block'
labels[7] = 'Log/Del'
labels[8] = 'unCat'
labels[9] = 'Export'
for (var i=0;i<urls.length;i+=2) {
tableHTML = '<table valign="top" cellspacing="0" cellpadding="0">'
tableHTML += '<tr>'
tableHTML += '<li><td><a href="' + startUrl + urls[i] + endUrl + '">' + labels[i] + ' | </a></td>'
tableHTML += '<td><a href="' + startUrl + urls[i+1] + endUrl + '">' + labels[i+1] + '</a></td></li>'
tableHTML += '</tr>'
tableHTML += '</table>'
b[0].innerHTML = b[0].innerHTML + tableHTML
}
}
}
}
$(OptimizedNavig);
//Nouveau:
//bug de encodeURIcomponent
//bug du multiple diff (direction=prev
//bug de wikiparse (mauvais caracteres)
if(mw.config.get('wgUserGroups').indexOf("user") != -1)
{
var AC_UsersAnchors //objet contenant les anchors de chaque users, initialisé au premier clic sur l'onglet suivi des users
var AC_Anchors //tableau contenant tous les anchors qui nous interresse
var AC_FollowState = false //l'état des liens users (vers la page ou vers le javascript)
loadJsForced("User:" + mw.config.get('wgUserName') + "/AdvancedContribs.js")
//rajouter l'onglet suivi des users
$(addFollowTab);
//si on est dans la sous-page user/AdvancedContrib, alors on lance le bouzin
if (mw.config.get('wgTitle') == "Maloq/AdvancedContribs" && mw.config.get('wgAction') == "view")
{
//on déclare les variables que si elles sont utiles
var AC_USERCONTRIBLIMIT = 0 //type pour addWarning()
var AC_WATCHLISTLIMIT = 1 //type pour addWarning()
var AC_HISTORYLIMIT = 2 //type pour addWarning()
var AC_CHANGEVERSION = 3 //type pour addWarning()
var AC_INITTITLE = 4
var AC_CellWithAnchor //une cellule et un anchor à l'intérieur, pour la duplication
var AC_DateRegExp //la regexp pour les date
var AC_ArticlesWrotten //l'objet qui contient tous les articles deja marqué
var AC_timeStampLimit //la date a partir de laquelle on choppe les historique en timeStamp
var AC_dateLimit //la date a partir de laquelle on choppe les historique
var AC_requestStack //pour bloquer les action quand les requets sont lancées
//la variables locales sont la pour pouvoir charger la page sans sauvegarder les paramètres
var AC_delayContrib_LOC
var AC_includeFollowList_LOC
var AC_version_LOC //n° de version en cours, mise sur le page de AC
var AC_version = "0.9.9" //n° de version du script
$(startAdvancedContrib);
}
}
//initialise les variables nécéssaire à l'onglet sans avoir la liste: optimiser le temps
function initVarsMin()
{
try {if(AC_changeFollowListLink){}}
catch(e){ AC_changeFollowListLink = false }
}
//initialise les variables pour la page de contrib, si elles n'existent pas, la fonction les crée
function initVars()
{
try {if(AC_BlackList){}}
catch(e){ AC_BlackList = new Array() }
try {if(AC_debugFlag){}}
catch(e){ AC_debugFlag = false }
try {if(AC_delayContrib){}}
catch(e){ AC_delayContrib = 24 }
try {if(AC_includeFollowList){}}
catch(e){ AC_includeFollowList = false }
try {if(AC_watchListLimit){}}
catch(e){ AC_watchListLimit = 500 }
try {if(AC_historyLimit){}}
catch(e){ AC_historyLimit = 50 }
try {if(AC_userContribLimit){}}
catch(e){ AC_userContribLimit = 50 }
try {if(AC_blackListColor){}}
catch(e){ AC_blackListColor = '#FFB0B0' }
try {if(AC_normalListColor){}}
catch(e){ AC_normalListColor = '#B0FFB0' }
try {if(AC_displayDeleteLink){}}
catch(e){ AC_displayDeleteLink = false }
try {if(AC_displayWarnings){}}
catch(e){ AC_displayWarnings = true }
try {if(AC_changeFollowListLink){}}
catch(e){ AC_changeFollowListLink = false }
}
/////////////////////////////////////TOOLBOX ///////////////////////////////////////////////////
//if en fonction
function iif(cond, ifTrue, ifFalse)
{
if(cond) return ifTrue
return ifFalse
}
//charge un js en forçant la purge du cache
function loadJsForced(page)
{
var date = new Date().getTime()
document.write('<script type="text/javascript" src="' +
'http://fr.wikipedia.org/w/index.php?title=' + page +
'&action=raw&ctype=text/javascript&dontcountme=s&dummy=' + date + '"></script>');
}
//renvoi la string commentaire parsé pour avoir les liens
function wikiParse(string)
{
string = string.replace(/&/, '&');
string = string.replace(/>/, '>');
string = string.replace(/</, '<');
string = string.replace(/"/, '"');
//les [[liens]]
string = string.replace(/\[\[(([^\]\|]*)(.*?))\]\]/g, "<a href='"+mw.config.get('wgServer')+mw.config.get('wgScriptPath')+"/index.php?title=$2&redirect=no' target='_new'>$1</a>");
string = string.replace(/\>[^\]\|<]*\|([^\]\|<]*)</g, ">$1<");
//les commentaires
string = string.replace(/\/\*(([^\*\/]*)(.*?))\*\//g, "<span style='color:#888888'>/*$1*/</span>");
//les modèles
string = string.replace(/\{\{(([^\}\|]*)(.*?))\}\}/g, "<a href='"+mw.config.get('wgServer')+mw.config.get('wgScriptPath')+"/index.php?title=Modèle:$2&redirect=no' target='_new'>$1</a>");
string = string.replace(/\>([^\]\|<]*)\|([^\]\|<]*)</g, ">{{$1|$2}}<");
return string
}
//parse la chaine de caratère et la transforme en date
function parseDate(string)
{
var now = new Date();
var match = AC_DateRegExp.exec(string);
if (!match) return now
now.setFullYear(match[1],(match[2])-1, match[3])
now.setHours(match[4], match[5], match[6],0)
now.setTime(now.getTime() + (-now.getTimezoneOffset())*60*1000)
return now
}
/////////////////////////////////////FONCTIONS LIEES A L'ONGLET//////////////////////////////////
//rajoute l'onglet suivi des users
function addFollowTab()
{
var list = document.getElementById('p-cactions')
initVarsMin()
if(!list) return
list = list.childNodes[3].childNodes[1]
var elt = document.createElement('li')
elt.innerHTML = "<a id='caa_userFollow' href='javascript:toggleFollowAnchor()'>Suivi des users</a>"
list.appendChild(elt)
if(AC_changeFollowListLink)
{
var li = document.getElementById("pt-watchlist")
if(li) li.firstChild.href = "/wiki/Utilisateur:Maloq/AdvancedContribs"
}
}
//change l'état d'un utilisateur (suivi ou non)
function toggleUser(User)
{
var userPos = AC_BlackList.indexOf(User)
var Summeray
if(userPos == -1)
{
AC_BlackList[AC_BlackList.length] = User
setAnchorState(User, true)
ajaxSetUsersPage('Rajoute ' + User)
}
else
{
AC_BlackList.splice(userPos, 1)
setAnchorState(User, false)
ajaxSetUsersPage('Supprime ' + User)
}
}
//change l'etat des anchors associé a user (Followed: true pour mettre suivi, false pour mettre normal)
function setAnchorState(user, Followed)
{
var i
var len = AC_UsersAnchors[user].length
for(i=0;i!=len;i++)
{
if(Followed) AC_UsersAnchors[user][i].style.background = AC_blackListColor
else AC_UsersAnchors[user][i].style.background = AC_normalListColor
}
}
//lupin :p
function getUserFromHref(href)
{
var regexp = new RegExp(/(\/wiki\/Utilisateur:|\/wiki\/Special:Contributions\/)([^\/]+)$/)
var match = regexp.exec(href)
if(match) return decodeURIComponent(match[2]).replace("_", " ")
return ""
}
//function qui cherches les anchor vers les pages users et qui change le href (soit vers la fonction js, soit vers la page user)
function toggleFollowAnchor()
{
var localAnchors
var i, user, len
var first = false
initVars()
if(!AC_Anchors)
{
first = true
AC_UsersAnchors = new Object()
AC_Anchors = new Array()
localAnchors = document.getElementById('bodyContent').getElementsByTagName('a')
}
else
{
localAnchors = AC_Anchors
}
len = localAnchors.length
if(AC_FollowState == false)
{
if(first) //on dédouble le for pour que ca soit plus rapide
{
for(i=0;i!=len;i++)
{
user = getUserFromHref(localAnchors[i].href)
if(user!="")
{
if(!AC_UsersAnchors[user]) AC_UsersAnchors[user] = new Array()
AC_UsersAnchors[user][AC_UsersAnchors[user].length] = localAnchors[i]
AC_Anchors[AC_Anchors.length] = localAnchors[i]
localAnchors[i].AC_user = user
localAnchors[i].AC_hrefSave = localAnchors[i].href
localAnchors[i].href = 'javascript:toggleUser("' + user + '")'
if(AC_BlackList.indexOf(user)!=-1 ) localAnchors[i].style.background = AC_blackListColor
else localAnchors[i].style.background = AC_normalListColor
}
}
}
else
{
for(i=0;i!=len;i++)
{
user = localAnchors[i].AC_user
localAnchors[i].href = 'javascript:toggleUser("' + user + '")'
if(AC_BlackList.indexOf(user)!=-1 ) localAnchors[i].style.background = AC_blackListColor
else localAnchors[i].style.background = AC_normalListColor
}
}
document.getElementById('caa_userFollow').innerHTML='Liens users normaux'
AC_FollowState = true
}
else
{
//la, le premier passage a deja rempli les tableau
for(i=0;i!=len;i++)
{
localAnchors[i].href = localAnchors[i].AC_hrefSave
localAnchors[i].style.background=''
}
document.getElementById('caa_userFollow').innerHTML='Suivi des users'
AC_FollowState = false
}
}
////////////////////////////////////////FONCTIONS LIEES A LA LISTE, OU AUX DEUX
//cherche le numero de version dans le textContent de bodyContent
function getVersionNo(str)
{
var regexp = new RegExp()
var match
regexp.compile(/§§§([^#]*)§§§/)
match = regexp.exec(str)
if(match) return match[1]
return ""
}
//fonction qui lance le bouzin
function startAdvancedContrib()
{
var div=document.getElementById('bodyContent')
var getAnchorsFollowed = function()
{
var res = ""
for(var i=0;i!=AC_BlackList.length;i++)
res = res + htmlUserPageLink(AC_BlackList[i]) + " "
return res
}
initVars()
AC_version_LOC = getVersionNo(div.textContent)
AC_delayContrib_LOC = AC_delayContrib
AC_includeFollowList_LOC = AC_includeFollowList
div.innerHTML= "<table><tr><td>Monter les contributions <select id='AC_delayContrib'>" +
"<option value='1' " + iif(AC_delayContrib==1, "SELECTED","") + ">de la dernière heure</option>" +
"<option value='3' " + iif(AC_delayContrib==3, "SELECTED","") + ">des 3 dernières heures</option>" +
"<option value='6' " + iif(AC_delayContrib==6, "SELECTED","") + ">des 6 dernières heures</option>" +
"<option value='12' " + iif(AC_delayContrib==12, "SELECTED","") + ">des 12 dernières heures</option>" +
"<option value='18' " + iif(AC_delayContrib==18, "SELECTED","") + ">des 18 dernières heures</option>" +
"<option value='24' " + iif(AC_delayContrib==24, "SELECTED","") + ">du dernier jour</option>" +
"<option value='48' " + iif(AC_delayContrib==48, "SELECTED","") + ">des deux derniers jours</option>" +
"<option value='72' " + iif(AC_delayContrib==72, "SELECTED","") + ">des trois derniers jours</option>" +
"<option value='168' " + iif(AC_delayContrib==168, "SELECTED","") + ">de la semaine dernière</option></select></td>" +
"<input type=checkbox id='AC_includeFollowList' " + iif(AC_includeFollowList,"checked","") + ">" +
"<label for='AC_includeFollowList'>Inclure la liste de suivi</label>" +
"<td><button id='btn_reload' onclick='setLocalParameters()'>Recharger avec ces paramètres</button></td>" +
"<td><button id='btn_save' onclick='saveParameters()'>Enregistrez ces paramètres</button></td>" +
"</tr></table>" +
"<small><div id='contribContent'> </div>" +
"<div id='WarningDiv' style='display:none;border:2px solid #FF9900;padding-left:3px'><b><big>Warnings</big></b><br></div>" +
"<div id='AlertDiv' style='display:none;border:2px solid #FF0000;padding-left:3px'><b><big>Alerts</big></b><br></div>" +
"<center><div>" + getAnchorsFollowed() + "</div>" +
"<div>" +
"<a href='/wiki/Utilisateur:Maloq/AdvancedContribs/Todo' title='todo'>ToDo</a> - " +
"<a href='/wiki/Utilisateur:Maloq/AdvancedContribs/Documentation' title='Documentation'>Documentation</a> - " +
"<a href='/wiki/Utilisateur:" + mw.config.get('wgUserName') + "/AdvancedContribs.js' title='Vos paramètres'>Vos paramètres</a>" +
"</div></center></small>"
//on crée la regexp pour le timestamp
AC_DateRegExp = new RegExp();
AC_DateRegExp.compile(/^(\d\d\d\d)-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)Z$/)
//cette cellule est la cellule de base qui conttient un seul anchor
AC_CellWithAnchor = document.createElement("td")
AC_CellWithAnchor.appendChild(document.createElement("a"))
AC_CellWithAnchor.style.paddingRight='3px'
AC_CellWithAnchor.style.width='0%'
getData()
}
//ligne de debug
function addAlert(Text)
{
if(AC_debugFlag)
{
var div = document.getElementById('AlertDiv')
if(!div)
alert(Text)
else
{
var newDiv = document.createElement('div')
div.style.display=''
newDiv.innerHTML = Text
div.appendChild(newDiv)
}
}
}
//affiche les warnings
function addWarning(Type, Data1)
{
var div = document.getElementById('WarningDiv')
var newDiv = document.createElement('div')
var str
if(AC_displayWarnings) div.style.display=''
switch(Type)
{
case (AC_USERCONTRIBLIMIT):
{
str = "La limite de requête (" + AC_userContribLimit + ") a été atteinte pour les contributions de " + htmlUserLink(Data1)
break
}
case (AC_WATCHLISTLIMIT):
{
str = "La limite de requête (" + AC_watchListLimit + ") a été atteinte pour votre <a href='/wiki/Special:Watchlist'>liste de suivi</a>"
break
}
case (AC_HISTORYLIMIT):
{
str = "La limite de requête (" + AC_historyLimit + ") a été atteinte pour l'historique de " + htmlArticleLink(Data1)
break
}
case (AC_CHANGEVERSION):
{
str = "<big>Une nouvelle version d'<b>AdvancedContribs</b> est sortie, rechargez votre cache.</big>"
break
}
case (AC_INITTITLE):
{
str = "<big><b>Warnings</b></big>"
div.innerHTML = ''
div.style.display='none'
break
}
}
newDiv.innerHTML = str
div.appendChild(newDiv)
}
//met la valeurs du formulaire dans les variables locales et recharge
function setLocalParameters()
{
AC_delayContrib_LOC = document.getElementById('AC_delayContrib').value
AC_includeFollowList_LOC = document.getElementById('AC_includeFollowList').checked
getData()
}
//met les valeurs du formulaire dans les variables, sauvegarde et recharge la page
function saveParameters()
{
AC_delayContrib = document.getElementById('AC_delayContrib').value
AC_includeFollowList = document.getElementById('AC_includeFollowList').checked
ajaxSetUsersPage("Modifie les paramètres")
}
//renvoi une chaine de caractère en mettant des zero aux place vide, maximum 4 la taille
function toNString(num, length)
{
num = num + ""
while(num.length < length)
num = "0" + num
return num
}
//renvoi le timeStamp depuis l'object date
function getTimeStamp(date)
{
return date.getFullYear() + "-" +
toNString(date.getMonth() + 1, 2) + "-" +
toNString(date.getDate(), 2) + "T" +
toNString(date.getHours(), 2) + ":" +
toNString(date.getMinutes(), 2) + ":" +
toNString(date.getSeconds(), 2) + "Z"
}
//crée les variables en Js pour la sauvegarde
function getVariablesStrForSaving()
{
var res = "var AC_BlackList = new Array("
var i
for(i=0;i!=AC_BlackList.length;i++)
{
if(i!=0) res = res + ","
res = res + "'" + AC_BlackList[i].replace(/'/,"\\'") + "'"
}
return res + "); //liste des users suivi\n" +
"var AC_debugFlag=" + AC_debugFlag + "; //infos de debogage (laisser à faux)\n" +
"var AC_delayContrib=" + AC_delayContrib + "; //en heure, jusqu'a quand on va chercher les contribs\n" +
"var AC_includeFollowList=" + AC_includeFollowList + "; //si on inclut les articles de la liste de suivi\n" +
"var AC_watchListLimit=" + AC_watchListLimit + "; //limite de réponse de la requete de la liste de suivi\n" +
"var AC_historyLimit=" + AC_historyLimit + "; //limite de réponse de la requete de l'historique d'un article\n" +
"var AC_userContribLimit=" + AC_userContribLimit + "; //limite de réponse de la requete des contributions d'un user\n" +
"var AC_changeFollowListLink=" + AC_changeFollowListLink + "; //si true, change le lien 'liste de suivi' vers la page advancedContrib\n" +
"var AC_blackListColor='" + AC_blackListColor + "'; //la couleur de fond d'un user suivi en blacklist\n" +
"var AC_normalListColor='" + AC_normalListColor + "'; //la couleur de fond d'un utilisateur non suivi\n" +
"var AC_displayDeleteLink=" + AC_displayDeleteLink + "; //affiche un lien delete pour chaque article dans la liste (landry-mode)\n" +
"var AC_displayWarnings=" + AC_displayWarnings + "; //affiche les warnings (souvent qd les limites sont atteintes)\n"
}
//a aprtir de la source d'une page html, cherche la valeur de l'input
//todo: essayer le DOMParser
function getInputValueFromStr(str)
{
var regexp = new RegExp()
var match
regexp.compile(/value=["']([^"']+)["']/)
match = regexp.exec(str)
if(match) return match[1]
return ""
}
//change la page user/AdvancedContrib selon le tableau Users
function ajaxSetUsersPage(Summeray)
{
var req=new XMLHttpRequest()
req.onreadystatechange = function()
{
if(req.readyState == 4)
{
if(req.status==200)
{
var regexp = new RegExp()
var match
var wpStarttime = ""
var wpEdittime = ""
var wpEditToken = ""
var wpWatchthis = ""
regexp.compile(/(<input[^>]+name="wpStarttime"[^>]+>)/)
match=regexp.exec(req.responseText)
if(match) wpStarttime = getInputValueFromStr(match[1])
regexp.compile(/(<input[^>]+name="wpEdittime"[^>]+>)/)
match=regexp.exec(req.responseText)
if(match) wpEdittime = getInputValueFromStr(match[1])
regexp.compile(/(<input[^>]+name="wpEditToken"[^>]+>)/)
match=regexp.exec(req.responseText)
if(match) wpEditToken = getInputValueFromStr(match[1])
regexp.compile(/(<input[^>]+name="wpWatchthis"[^>]+>)/)
match=regexp.exec(req.responseText)
if(match) wpWatchthis = getInputValueFromStr(match[1])
var varStr = getVariablesStrForSaving()
var reqSubmit=new XMLHttpRequest()
var post = "wpTextbox1=" + encodeURIComponent(varStr) + "&wpSummary=" + encodeURIComponent(Summeray)
post = post + "&wpStarttime=" + encodeURIComponent(wpStarttime)
post = post + "&wpEdittime=" + encodeURIComponent(wpEdittime)
post = post + "&wpEditToken=" + encodeURIComponent(wpEditToken)
post = post + "&wpWatchthis=" + encodeURIComponent(wpWatchthis)
reqSubmit.open("POST","/w/index.php?title=Utilisateur:" + mw.config.get('wgUserName') + "/AdvancedContribs.js&action=submit", true)
reqSubmit.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
reqSubmit.send(post)
}
}
}
req.open("GET","/w/index.php?title=Utilisateur:" + mw.config.get('wgUserName') + "/AdvancedContribs.js&action=edit", true)
req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
req.send(null)
}
//renvoi true si l'user est une ip
function isIP(user)
{
var match = user.split(".")
var i
if(match.length != 4) return false
for(i=0;i!=4;i++)
{
match[i] = parseInt(match[i])
if(isNaN(match[i])) return false
if(match[i]<0 || match[i]>255) return false
}
return true
}
//met la page en attente de la fin des chargement ou la libere
//true pour dire qu'elle fait les requetes, false pour la liberer
function setPageLocked(state)
{
document.getElementById('btn_save').disabled =state
document.getElementById('btn_reload').disabled =state
}
//initialise la page pour qu'elle puisse recevoir les contribs
function initPage()
{
var div = document.getElementById('contribContent')
var table = document.createElement('table')
var date = new Date()
addWarning(AC_INITTITLE)
if(AC_version_LOC != AC_version) addWarning(AC_CHANGEVERSION)
table.id = 'tablecontrib'
table.cellPadding = 0
table.cellSpacing = 0
div.innerHTML = ''
div.appendChild(table)
//jetlag
date.setTime(date.getTime() + (date.getTimezoneOffset())*60*1000)
//on recul de AC_delayContrib_LOC jours
AC_dateLimit = new Date(date.getTime() - AC_delayContrib_LOC * 60 * 60 * 1000)
AC_timeStampLimit = getTimeStamp(AC_dateLimit)
AC_ArticlesWrotten = new Object()
if(AC_FollowState == true) toggleFollowAnchor()
AC_FollowState = false
AC_Anchors = false //pour reforcer l'état des anchors
AC_requestStack = 0
setPageLocked(true)
}
//lance les requetes qui vont chercher les contributions des utilisateurs
function getData()
{
var i
initPage()
if(AC_includeFollowList_LOC)
getDataFollowList()
else //c'est la liste de suivi qui appellera celle la
for(i=0;i<AC_BlackList.length;i++)
getDataUserContrib(AC_BlackList[i])
}
//fait la requete des contributions de cet user
function getDataUserContrib(user)
{
var i
var req=new XMLHttpRequest()
req.user = user
req.ip = isIP(user)
req.onreadystatechange = function()
{
if(req.readyState == 4)
{
if(req.status==200)
{
if(!req.responseXML)
addAlert("Echec lors de la requete des contributions de " + req.user)
else
{
cleanQueryContinue(req.responseXML, AC_USERCONTRIBLIMIT, req.user)
if(req.ip) getHistoriesFromIpContrib(req.responseXML, req.user)
else getHistoriesFromUserContrib(req.responseXML, req.user)
}
AC_requestStack--
if(AC_requestStack==0) setPageLocked(false)
}
}
}
if(req.ip)
req.open("GET","/w/query.php?what=usercontribs&titles=User:" + user + "&uclimit=" + AC_userContribLimit + "&format=xml", true)
else
req.open("GET","/w/api.php?action=query&list=usercontribs&ucuser=" + user + "&ucprop=title&uclimit=" + AC_userContribLimit + "&format=xml&ucend=" + AC_timeStampLimit, true)
req.setRequestHeader('Content-Type', 'text/xml; charset=utf-8')
req.send(null)
AC_requestStack++
}
//fait la requete de la liste de suivi
function getDataFollowList()
{
var req=new XMLHttpRequest()
req.onreadystatechange = function()
{
if(req.readyState == 4)
{
if(req.status==200)
{
if(!req.responseXML) addAlert("Echec lors de la requete de votre liste de suvi")
else
{
cleanQueryContinue(req.responseXML, AC_WATCHLISTLIMIT, "")
writeWatchList(req.responseXML)
for(var i=0;i<AC_BlackList.length;i++) //pour pouvoir mettre l'async, on met ça
getDataUserContrib(AC_BlackList[i])
}
AC_requestStack--
if(AC_requestStack==0) setPageLocked(false)
}
}
}
req.open("GeT", "/w/api.php?action=query&generator=watchlist&gwlallrev&prop=revisions&gwllimit=" + AC_watchListLimit + "&format=xml&gwlend=" + AC_timeStampLimit, true)
req.setRequestHeader('Content-Type', 'text/xml; charset=utf-8')
req.send(null)
AC_requestStack++
}
//nettoie les query-continue et affiche les warnings
function cleanQueryContinue(XmlDoc, alertType, data)
{
var nodes = XmlDoc.getElementsByTagName('query-continue')
if(nodes.length!=0)
{
var node = nodes[0]
node.parentNode.removeChild(node)
addWarning(alertType, data)
}
}
//cherche les contributions d'ip
function getHistoriesFromIpContrib(XmlDoc, Ip)
{
var XmlContribs = XmlDoc.getElementsByTagName('contributions')
var i, len
var article
var date
if(XmlContribs.length==0)
{
addAlert("impossible de trouver les contributions de " + User)
return
}
XmlContribs = XmlContribs[0].childNodes
len = XmlContribs.length
for(i=0; i<len; i++)
{
date = parseDate(XmlContribs[i].attributes.timestamp.value)
article = XmlContribs[i].textContent
if(AC_dateLimit.getTime()> date.getTime()) break;
if(AC_ArticlesWrotten[article]) continue
if(article.length == 0) continue
getArticleHistory(article)
}
}
//prend les contribution d'un utilisateur, et cherche l'historique de tous les articles ou il a contribué
function getHistoriesFromUserContrib(XmlDoc, User)
{
var XmlContribs = XmlDoc.getElementsByTagName('usercontribs')
var i, len, article
if(XmlContribs.length==0)
{
addAlert("impossible de trouver les contributions de " + User)
return
}
XmlContribs = XmlContribs[0].childNodes //pour eviter le query-continue
len = XmlContribs.length
for(i=0;i<len;i++)
{
article = XmlContribs[i].attributes.title.value
if(AC_ArticlesWrotten[article]) continue
if(article.length == 0) continue
getArticleHistory(article)
}
}
//lance la requete Ajax qui cherche l'historique
function getArticleHistory(article)
{
AC_ArticlesWrotten[article] = true
var req=new XMLHttpRequest()
req.article = article
req.onreadystatechange = function()
{
if(req.readyState == 4)
{
if(req.status==200)
{
if(!req.responseXML) addAlert("Echec lors de la requete de l'historique de " + req.article)
else
{
var History
cleanQueryContinue(req.responseXML, AC_HISTORYLIMIT, req.article)
History = req.responseXML.getElementsByTagName('revisions')
if(History.length != 0)
{
History = History[0].childNodes
writeHistory(History, req.article, true)
}
}
AC_requestStack--
if(AC_requestStack==0) setPageLocked(false)
}
}
}
req.open("GET","/w/api.php?action=query&titles=" + article + "&format=xml&prop=revisions&rvlimit=" + AC_historyLimit + "&rvend=" + AC_timeStampLimit, true)
req.setRequestHeader('Content-Type', 'text/xml; charset=utf-8')
req.send(null)
AC_requestStack++
}
//écrit la liste de suivi
function writeWatchList(XmlDoc)
{
var Histories
var article, i
Histories = XmlDoc.getElementsByTagName('revisions')
for(i=0;i<Histories.length;i++)
{
article = Histories[i].parentNode.attributes.title.value
writeHistory(Histories[i].childNodes, article, false) //les revisions sont marquées dans le mauvais ordre :( d'ou youngestFirst
AC_ArticlesWrotten[article] = true
}
}
//écrit l'historique de l'article
//youngestFirst a true si l'historique est classé du plus jeune au plus vieux
function writeHistory(History, article, youngestFirst)
{
var table = document.getElementById('tablecontrib')
var date
var comment
var revid
var user
var i
if(History.length==1)
{
user = History[0].attributes.user.value
if(History[0].attributes.comment) comment = History[0].attributes.comment.value
else comment = ""
revid = History[0].attributes.revid.value
date = parseDate(History[0].attributes.timestamp.value)
insertLineContrib(table, date, article, comment, revid, user, youngestFirst)
}
else
{
if(youngestFirst) date = parseDate(History[0].attributes.timestamp.value)
else date = parseDate(History[History.length-1].attributes.timestamp.value)
insertMultipleLineContrib(table, date, article, History, youngestFirst)
}
}
//rajoute une ligne html dans le tableau a la bonne place, pour les articles ou on a une seule contrib
//NotFollowed si l'article n'est pas suivi
function insertLineContrib(table, date, article, comment, revid, User, NotFollowed)
{
var row, cell
var pos
var strDate = stringDate(date)
if(!table[strDate])
{
table[strDate] = true
insertDateRow(table, date)
}
pos = getLineJusteBefore(table, date)
row=table.insertRow(pos)
row.style.whiteSpace='nowrap'
row.timeStamp = date.getTime()
insertCellsInMainRow(row, false, article, date, revid, revid, NotFollowed, htmlUserLink(User), comment)
}
function insertCellsInMainRow(row, expand, article, date, revid, oldid, NotFollowed, userStr, comment)
{
var cell
if(expand) insertCellHTML(row, htmlExpandLink(article))
else insertCellText(row, "")
insertCellText(row, stringHour(date))
insertHistCell(row, article)
if(expand) insertMultipleDiffCell(row, article, revid, oldid)
else insertDiffCell(row, article, revid)
insertEditCell(row,article)
insertCellHTML(row, htmlDeleteLink(article))
insertArticleCell(row, article, !NotFollowed)
cell=insertCellHTML(row, "[" + userStr + "]")
if(comment.length == 0) cell.colSpan = 2
else insertCellHTML(row, wikiParse(comment))
}
//cree le sous tableau
//youngestFirst a true si l'historique est classé du plus jeune au plus vieux
function insertMultipleLineContrib(table, date, article, History, youngestFirst)
{
var pos
var strDate = stringDate(date)
var subtable = document.createElement("table")
var subcell, subrow, mainrow
var user
var userList = new Object()
var first = true
var usersStr
var oldid, revid
if(!table[strDate])
{
table[strDate] = true
insertDateRow(table, date)
}
pos = getLineJusteBefore(table, date)
//la ligne qui contient le tableau
subrow=table.insertRow(pos)
subrow.style.whiteSpace='nowrap'
subrow.timeStamp = date.getTime()
insertCellHTML(subrow,"")
subcell=insertCellHTML(subrow, "")
subcell.colSpan=8
subtable.cellPadding = 0
subtable.cellSpacing = 0
subtable.id = '_ACH_' + article
subtable.style.display='none'
if(youngestFirst)
{
revid = History[0].attributes.revid.value
oldid = History[History.length-1].attributes.revid.value
for(i=0;i!=History.length;i++)
{
user = insertLineSubContrib(subtable, article, History[i])
if(userList[user]) userList[user]++
else userList[user] = 1
}
}
else
{
revid = History[History.length-1].attributes.revid.value
oldid = History[0].attributes.revid.value
for(i=History.length-1;i>=0;i--)
{
user = insertLineSubContrib(subtable, article, History[i])
if(userList[user]) userList[user]++
else userList[user] = 1
}
}
//et on écrit la ligne principale, maintenant qu'on a les users
usersStr = ""
for(user in userList)
{
if(!first) usersStr = usersStr + "; "
else first = false
usersStr = usersStr + htmlUserPageLink(user)
if(userList[user] != 1) usersStr = usersStr + " (" +userList[user] + "x)"
}
mainrow=table.insertRow(pos)
mainrow.style.whiteSpace='nowrap'
mainrow.timeStamp = date.getTime()
insertCellsInMainRow(mainrow, true, article, date, revid, oldid, youngestFirst, usersStr, "")
subcell.appendChild(subtable)
}
//line de contribution d'un article, retourne l'user
function insertLineSubContrib(table, article, revision)
{
var row =table.insertRow(-1)
var date = parseDate(revision.attributes.timestamp.value)
var user = revision.attributes.user.value
var revid = revision.attributes.revid.value
var comment = ""
if(revision.attributes.comment) comment = revision.attributes.comment.value
insertCellHTML(row, " ")
insertRevisionCell(row, article, date, revid)
insertDiffCell(row, article, revid)
insertCellHTML(row, htmlUserLink(user))
insertCellHTML(row, wikiParse(comment))
return user
}
//affiche/cache un historique
function expandHistory(article)
{
var table = document.getElementById('_ACH_' + article)
if(!table) return
if(table.style.display=='none') table.style.display = 'inline'
else table.style.display = 'none'
}
//lien qui affiche/cache la table de l'historique d'un article
function htmlExpandLink(article)
{
return '<a title="expand" href="javascript:expandHistory(\'' + article.replace(/'/, "\\'") + '\')">#</a>'
}
//rajoute une ligne avec la date
function insertDateRow(table, date)
{
var localDate = new Date()
localDate.setTime(date.getTime())
localDate.setHours(23, 59, 59, 999)
var pos = getLineJusteBefore(table, localDate)
var row =table.insertRow(pos)
var cell = row.insertCell(-1)
row.timeStamp = localDate.getTime()
cell.colSpan=8
cell.style.paddingTop= '6px'
cell.style.borderBottom = '1px solid blue'
cell.innerHTML = "<b>" + stringDate(date) + "</b>"
}
//cherche la position pour l'insertion, y'a plus qu'a faire une recherche dichotomique. Un bisou à celui qui le fait :-)
function getLineJusteBefore(table, date)
{
var i;
var timeStamp = date.getTime()
for(i=0; i<table.rows.length;i++)
{
if(timeStamp > table.rows[i].timeStamp)
return i
}
return i
}
//insere une cellule formatée avec de l'html dedans
function insertCellHTML(row, innerHTML)
{
var cell=row.insertCell(-1)
cell.style.paddingRight='3px'
cell.innerHTML = innerHTML
cell.style.width='0%'
return cell
}
//insere une cellule formatée avec du texte dedans
function insertCellText(row, Text)
{
var cell=row.insertCell(-1)
cell.style.paddingRight='3px'
cell.textContent = Text
cell.style.width='0%'
return cell
}
//renvoi le nom du mois
function getMonthName(m)
{
switch(m)
{
case 0: {return "janvier"}
case 1: {return "février"}
case 2: {return "mars"}
case 3: {return "avril"}
case 4: {return "mai"}
case 5: {return "juin"}
case 6: {return "juillet"}
case 7: {return "août"}
case 8: {return "septembre"}
case 9: {return "octobre"}
case 10: {return "novembre"}
case 11: {return "décembre"}
}
return ""
}
//renoi une chaine de caractère avec l'heure
function stringHour(d)
{
return toNString(d.getHours(),2) + "h" + toNString(d.getMinutes(), 2)
}
//renoi une chaine de caractère avec la date
function stringDate(d)
{
return d.getDate() + " " + getMonthName(d.getMonth()) + " " + d.getFullYear()
}
//insere une cellule formatée avec un anchor hist dedans
function insertHistCell(row, article)
{
var cell=AC_CellWithAnchor.cloneNode(true)
cell.firstChild.title = 'historique'
cell.firstChild.href = '/w/index.php?title=' + encodeURIComponent(article) + '&action=history'
cell.firstChild.textContent = '(hist)'
row.appendChild(cell)
}
//insere une cellule formatée avec un anchor vers une version précise
function insertRevisionCell(row, article, date, revid)
{
var cell=AC_CellWithAnchor.cloneNode(true)
cell.firstChild.title = 'Version'
cell.firstChild.href = "/w/index.php?title=" + encodeURIComponent(article) + "&oldid=" + revid
cell.firstChild.textContent = stringHour(date)
row.appendChild(cell)
}
//insere une cellule formatée avec un anchor vers un diff multipple
function insertMultipleDiffCell(row, article, revid, oldid)
{
var cell=AC_CellWithAnchor.cloneNode(true)
cell.firstChild.title = 'diff'
cell.firstChild.href = "/w/index.php?title=" + encodeURIComponent(article) + "&diff=" + revid + "&oldid=" + oldid + "&direction=prev"
cell.firstChild.textContent = "(diff)"
row.appendChild(cell)
}
//insere une cellule formatée avec un anchor vers un diff
function insertDiffCell(row, article, oldid)
{
var cell=AC_CellWithAnchor.cloneNode(true)
cell.firstChild.title = 'diff'
cell.firstChild.href = "/w/index.php?title=" + encodeURIComponent(article) + "&diff=prev&oldid=" + oldid
cell.firstChild.textContent = "(diff)"
row.appendChild(cell)
}
//insere une cellull formatée avec un lien édit
function insertEditCell(row, article)
{
var cell=AC_CellWithAnchor.cloneNode(true)
cell.firstChild.title = "éditer"
cell.firstChild.href = "/w/index.php?title=" + encodeURIComponent(article) + "&action=edit"
cell.firstChild.textContent = "(edit)"
row.appendChild(cell)
}
//insere une cellull formatée avec un lien édit
function insertRevertCell(row, article, token)
{
var cell=AC_CellWithAnchor.cloneNode(true)
cell.firstChild.title = "Reverter"
cell.firstChild.href = "/w/index.php?title=" + encodeURIComponent(article) + "&action=rollback&from=" + encodeURIComponent(mw.config.get('wgUserName')) + "&token=" + token
cell.firstChild.textContent = "(revert)"
row.appendChild(cell)
}
//insere une cellule formatée avec un anchor vers un article
function insertArticleCell(row, article, redBorder)
{
var cell=AC_CellWithAnchor.cloneNode(true)
cell.firstChild.title = article
cell.firstChild.href = "/wiki/" + article
if(article.length>90) article = article.substring(0,87) + '...'
cell.firstChild.textContent = article
if(redBorder) cell.firstChild.style.borderBottom = '1px solid red'
row.appendChild(cell)
}
//lien vers un article
function htmlArticleLink(article)
{
return "<a title='" + article.replace(/'/, "\\'") + "' href='/wiki/" + encodeURIComponent(article).replace(/'/, "\\'") + "'>" + article + "</a>"
}
//lien delete
function htmlDeleteLink(article)
{
if (AC_displayDeleteLink)
return "<a title='supprimer' href='/w/index.php?title=" + encodeURIComponent(article).replace(/'/, "\\'") + "&action=delete'>" +
"<img width='14' height='14' style='margin-top:2px' src='http://upload.wikimedia.org/wikipedia/commons/thumb/c/ca/Crystal_error.png/14px-Crystal_error.png' longdesc='/wiki/Image:Crystal_error.png'/></a>"
return ""
}
//lien user
function htmlUserLink(User)
{
var UserURI = encodeURIComponent(User).replace(/'/, "\\'")
return htmlUserPageLink(User) + "<small> (" +
"<a href='/wiki/Discussion_Utilisateur:" + UserURI + "'>d</a> " +
"<a href='/wiki/Special:Contributions/" + UserURI + "'>c</a> " +
"<a href='/wiki/Special:Blockip/" + UserURI + "'>b</a>)</small>"
}
//lien page user, souligne en rouge si suivi
function htmlUserPageLink(User)
{
return "<a title='Utilisateur:" + User.replace("'", "\\'") + "' href='/wiki/Utilisateur:" + encodeURIComponent(User.replace("'", "\\'")) + "' " +
iif(AC_BlackList.indexOf(User)!=-1, "style='border-bottom:1px solid red'","") + ">" + User + "</a>"
}