Utilisateur:Creasy/AdvancedContrib.dev.js
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.//{{Projet:JavaScript/Script|AdvancedContribs}}
//<source lang=javascript><pre><nowiki>
var ACobj = {}
ACobj.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
if(mw.config.get('wgNamespaceNumber')!=0 || mw.config.get('wgAction') == "history")
addOnloadHook(function ()
{
var list = document.getElementById('p-cactions')
AC_initVarsMin()
if(!list) return
list = list.childNodes[3].childNodes[1]
var elt = document.createElement('li')
var a = document.createElement('a')
a.onclick = toggleFollowAnchor
a.href = "#"
a.id = "caa_userFollow"
a.appendChild(document.createTextNode("Suivi des users"));
elt.appendChild(a)
list.appendChild(elt)
if(AC_changeFollowListLink)
{
var li = document.getElementById("pt-watchlist")
if(li) li.firstChild.href = "/wiki/Utilisateur:Maloq/AdvancedContribs"
}
})
//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
ACobj.USERCONTRIBLIMIT = 0 //type pour addWarning()
ACobj.WATCHLISTLIMIT = 1 //type pour addWarning()
ACobj.HISTORYLIMIT = 2 //type pour addWarning()
ACobj.CHANGEVERSION = 3 //type pour addWarning()
ACobj.INITTITLE = 4
/*
ACobj.CellWithAnchor //une cellule et un anchor à l'intérieur, pour la duplication
ACobj.DateRegExp //la regexp pour les date
ACobj.ArticlesWrotten //l'objet qui contient tous les articles deja marqué
ACobj.timeStampLimit //la date a partir de laquelle on choppe les historique en timeStamp
ACobj.dateLimit //la date a partir de laquelle on choppe les historique
ACobj.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
/*
ACobj.delayContrib_LOC
ACobj.includeFollowList_LOC
ACobj.version_LOC //n° de version en cours, mise sur le page de AC
*/
ACobj.version = "0.9.24" //n° de version du script
addOnloadHook(function ()
{
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
}
AC_initVars()
ACobj.version_LOC = getVersionNo(div.textContent)
ACobj.delayContrib_LOC = AC_delayContrib
ACobj.includeFollowList_LOC = AC_includeFollowList
div.innerHTML= "<style>.trover{} " +
".trover:hover{background:#e5e5e5} </style>" +
"<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()'>Enregistrer 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
ACobj.DateRegExp = new RegExp();
ACobj.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
ACobj.CellWithAnchor = document.createElement("td")
ACobj.CellWithAnchor.appendChild(document.createElement("a"))
ACobj.CellWithAnchor.style.paddingRight='3px'
ACobj.CellWithAnchor.style.width='0%'
getData()
});
}
//initialise les variables nécéssaire à l'onglet sans avoir la liste: optimiser le temps
function AC_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 AC_initVars()
{
try {if(AC_BlackList){}}
catch(e){ AC_BlackList = new Array() }
try {if(AC_WhiteList){}}
catch(e){ AC_WhiteList = 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 = 5000 }
try {if(AC_historyLimit){}}
catch(e){ AC_historyLimit = 500 }
try {if(AC_userContribLimit){}}
catch(e){ AC_userContribLimit = 500 }
try {if(AC_blackListColor){}}
catch(e){ AC_blackListColor = '#FFB0B0' }
try {if(AC_whiteListColor){}}
catch(e){ AC_whiteListColor = '#B0B0FF' }
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 }
try {if(AC_linkToContrib){}}
catch(e){ AC_linkToContrib = 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="' +
'//fr.wikipedia.org/w/index.php?title=' + encodeURIComponent(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" >$1</a>');
string = string.replace(/\>[^\]\|<]*\|([^\]\|<]*)</g, ">$1<");
//les commentaires
string = string.replace(/\/\*([^\*\/]*)\*\//g, "<span style='color:#888888'>/*$1*/</span>");
//les {{a|article}}
string = string.replace(/\{\{a\|([^\}]*)\}\}/g, '<a href="'+mw.config.get('wgServer')+mw.config.get('wgScriptPath')+'/index.php?title=$1&redirect=no">$1</a>');
//les {{u|utilisateur}}
string = string.replace(/\{\{u\|([^\}]*)\}\}/g, '<a href="'+mw.config.get('wgServer')+mw.config.get('wgScriptPath')+'/index.php?title=Utilisateur:$1">$1</a>');
return string
}
//parse la chaine de caratère et la transforme en date
function parseDate(string)
{
var now = new Date();
var match = ACobj.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//////////////////////////////////
//change l etat de l'user (0: rien, 1 suivi, 2 confiance)
function toggleUserAction(user, action)
{
var BLPos = AC_BlackList.indexOf(user)
var WLPos = AC_WhiteList.indexOf(user)
var Summeray
if(action == 1 && BLPos==-1)
{
AC_BlackList[AC_BlackList.length] = user
if(WLPos!=-1) AC_WhiteList.splice(WLPos, 1)
ajaxSetUsersPage('Rajoute ' + user + ' dans la liste de surveillance',user, AC_blackListColor)
}
else if(action == 2 && WLPos==-1)
{
AC_WhiteList[AC_WhiteList.length] = user
if(BLPos!=-1) AC_BlackList.splice(BLPos, 1)
ajaxSetUsersPage('Rajoute ' + user + ' dans la liste de confiance',user, AC_whiteListColor)
}
else if(action == 0 && (WLPos!=-1 || BLPos!=-1))
{
if(BLPos!=-1) AC_BlackList.splice(BLPos, 1)
if(WLPos!=-1) AC_WhiteList.splice(WLPos, 1)
ajaxSetUsersPage('supprime ' + user + ' des deux listes',user, AC_normalListColor)
}
document.AC_infoBox.style.display="none"
}
//affiche la petite boite de dialogue
function toggleUser(e)
{
var user = this.AC_user
var AC_infoBox = document.AC_infoBox
if(!AC_infoBox)
{
AC_infoBox = document.createElement("div")
AC_infoBox.style.border="1px solid grey"
AC_infoBox.style.background="#FFFFFF"
AC_infoBox.style.zIndex = "2"
AC_infoBox.style.position = "absolute"
var labels = ['Aucune liste','Liste de surveillance','Liste de confiance']
for(var i=0; i!=labels.length;i++)
{
var input = document.createElement("input")
var label = document.createElement("label")
label.htmlFor='AC_infoboxCheck' + i
label.textContent = labels[i]
label.style.cursor="pointer"
label.marginBottom='2px'
input.name = "AC_infobox"
input.id='AC_infoboxCheck' + i
input.type='radio'
input.style.width = '12px'
input.action=i
AC_infoBox.appendChild(input)
AC_infoBox.appendChild(label)
AC_infoBox.appendChild(document.createElement('br'))
input.onclick = function()
{
if(!this.checked) return
toggleUserAction(document.AC_infoBox.user, this.action)
}
AC_infoBox["input"+i] = input
}
document.body.appendChild(AC_infoBox)
document.AC_infoBox = AC_infoBox
}
else if(AC_infoBox.style.display=="")
{
AC_infoBox.style.display="none"
if(user==AC_infoBox.user) return
}
AC_infoBox["input"+0].checked = true
var inBlackList = AC_BlackList.indexOf(user) != -1
var inWhiteList = AC_WhiteList.indexOf(user) != -1
if(inBlackList) AC_infoBox["input"+1].checked = true
else if(inWhiteList) AC_infoBox["input"+2].checked = true
var posx = 300;
var posy = 300;
if (e.pageX)
{
posx = e.pageX;
posy = e.pageY;
}
else if (e.clientX )
{
posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
}
AC_infoBox.style.top = (posy + 15) + "px"
AC_infoBox.style.left = posx + "px"
AC_infoBox.user = user
AC_infoBox.style.display=""
}
//change l'etat des anchors associé a user (FollowedColor: couleur à mettre)
function setAnchorState(user, FollowedColor)
{
var i
var len = ACobj.UsersAnchors[user].length
for(i=0;i!=len;i++)
ACobj.UsersAnchors[user][i].style.background = FollowedColor
}
//lupin :p
function getUserFromHref(href)
{
var regexp = new RegExp(/(\/wiki\/Utilisateur:|\/wiki\/Sp(e|é|%C3%A9)cial:Contributions\/|\/w\/index.php\?title=Utilisateur:|\/wiki\/Discussion_Utilisateur:)([^\/&]+)([&]?.*)$/)
var match = regexp.exec(href)
if(match) return decodeURIComponent(match[3]).replace(/_/g, " ")
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
AC_initVars()
if(!ACobj.Anchors)
{
first = true
ACobj.UsersAnchors = new Object()
ACobj.Anchors = new Array()
localAnchors = document.getElementById('bodyContent').getElementsByTagName('a')
}
else
{
localAnchors = ACobj.Anchors
}
len = localAnchors.length
if(ACobj.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(!ACobj.UsersAnchors[user]) ACobj.UsersAnchors[user] = new Array()
ACobj.UsersAnchors[user][ACobj.UsersAnchors[user].length] = localAnchors[i]
ACobj.Anchors[ACobj.Anchors.length] = localAnchors[i]
localAnchors[i].AC_user = user
localAnchors[i].AC_hrefSave = localAnchors[i].href
localAnchors[i].href = '#'
localAnchors[i].onclick =toggleUser
if(AC_BlackList.indexOf(user)!=-1 ) localAnchors[i].style.background = AC_blackListColor
else if(AC_WhiteList.indexOf(user)!=-1 ) localAnchors[i].style.background = AC_whiteListColor
else localAnchors[i].style.background = AC_normalListColor
}
}
}
else
{
for(i=0;i!=len;i++)
{
user = localAnchors[i].AC_user
localAnchors[i].href = '#'
localAnchors[i].onclick =toggleUser
if(AC_BlackList.indexOf(user)!=-1 ) localAnchors[i].style.background = AC_blackListColor
else if(AC_WhiteList.indexOf(user)!=-1 ) localAnchors[i].style.background = AC_whiteListColor
else localAnchors[i].style.background = AC_normalListColor
}
}
document.getElementById('caa_userFollow').textContent='Liens users normaux'
ACobj.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').textContent='Suivi des users'
ACobj.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 ""
}
//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 (ACobj.USERCONTRIBLIMIT):
{
str = "La limite de requête (" + AC_userContribLimit + ") a été atteinte pour les contributions de " + htmlUserLink(Data1)
break
}
case (ACobj.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 (ACobj.HISTORYLIMIT):
{
str = "La limite de requête (" + AC_historyLimit + ") a été atteinte pour l'historique de " + htmlArticleLink(Data1)
break
}
case (ACobj.CHANGEVERSION):
{
str = "<big>Une nouvelle version d'<b>AdvancedContribs</b> est sortie, rechargez votre cache.</big>"
break
}
case (ACobj.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()
{
ACobj.delayContrib_LOC = document.getElementById('AC_delayContrib').value
ACobj.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(/'/,"\\'") + "'"
}
res = res + "); //liste des users suivi\n" +
"var AC_WhiteList = new Array("
for(i=0;i!=AC_WhiteList.length;i++)
{
if(i!=0) res = res + ","
res = res + "'" + AC_WhiteList[i].replace(/'/,"\\'") + "'"
}
return res + "); //liste des users de confiance\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_whiteListColor='" + AC_whiteListColor + "'; //la couleur de fond d'un utilisateur de la whitelist\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, user, color)
{
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:" + encodeURIComponent(mw.config.get('wgUserName')) + "/AdvancedContribs.js&action=submit", false)
reqSubmit.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
reqSubmit.send(post)
if(user && color) setAnchorState(user, color)
}
}
}
req.open("GET","/w/index.php?title=Utilisateur:" + encodeURIComponent(mw.config.get('wgUserName')) + "/AdvancedContribs.js&action=edit")
req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
req.send(null)
}
//met la page en attente de la fin des chargements ou la libère
//true pour dire qu'elle fait les requêtes, false pour la libérer
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(ACobj.INITTITLE)
if(ACobj.version_LOC != ACobj.version) addWarning(ACobj.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 ACobj.delayContrib_LOC jours
ACobj.dateLimit = new Date(date.getTime() - ACobj.delayContrib_LOC * 60 * 60 * 1000)
ACobj.timeStampLimit = getTimeStamp(ACobj.dateLimit)
ACobj.ArticlesWrotten = new Object()
if(ACobj.FollowState == true) toggleFollowAnchor()
ACobj.FollowState = false
ACobj.Anchors = false //pour reforcer l'état des anchors
ACobj.requestStack = 0
setPageLocked(true)
}
//lance les requetes qui vont chercher les contributions des utilisateurs
function getData()
{
var i
initPage()
if(ACobj.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.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, ACobj.USERCONTRIBLIMIT, req.user)
getHistoriesFromUserContrib(req.responseXML, req.user)
}
ACobj.requestStack--
if(ACobj.requestStack==0) setPageLocked(false)
}
}
}
req.open("GET","/w/api.php?action=query&list=usercontribs&ucuser=" + user + "&ucprop=title&uclimit=" + AC_userContribLimit + "&format=xml&ucend=" + ACobj.timeStampLimit, true)
req.setRequestHeader('Content-Type', 'text/xml; charset=utf-8')
ACobj.requestStack++
req.send(null)
}
//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, ACobj.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])
}
ACobj.requestStack--
if(ACobj.requestStack==0) setPageLocked(false)
}
}
}
req.open("GeT", "/w/api.php?action=query&generator=watchlist&gwlallrev&prop=revisions&gwllimit=" + AC_watchListLimit + "&format=xml&gwlend=" + ACobj.timeStampLimit, true)
req.setRequestHeader('Content-Type', 'text/xml; charset=utf-8')
ACobj.requestStack++
req.send(null)
}
//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)
}
}
//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(ACobj.ArticlesWrotten[article]) continue
if(article.length == 0) continue
getArticleHistory(article)
}
}
//lance la requete Ajax qui cherche l'historique
function getArticleHistory(article)
{
ACobj.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, ACobj.HISTORYLIMIT, req.article)
History = req.responseXML.getElementsByTagName('revisions')
if(History.length != 0)
{
History = History[0].childNodes
writeHistory(History, req.article, true)
}
}
ACobj.requestStack--
if(ACobj.requestStack==0) setPageLocked(false)
}
}
}
req.open("GET","/w/api.php?action=query&titles=" + article + "&format=xml&prop=revisions&rvlimit=" + AC_historyLimit + "&rvend=" + ACobj.timeStampLimit, true)
req.setRequestHeader('Content-Type', 'text/xml; charset=utf-8')
ACobj.requestStack++
req.send(null)
}
//é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
ACobj.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)
if(AC_WhiteList.indexOf(user) == -1 || article.indexOf(":") != -1)
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.className='trover'
if(article == 'Discussion Utilisateur:' + mw.config.get('wgUserName')) row.style.backgroundColor = '#fef3d8'
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))
insertCellText(row, " ").style.width='100%'
}
//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
var hide = true
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=9
subtable.cellPadding = 0
subtable.cellSpacing = 0
subtable.id = '_ACH_' + article
subtable.className= 'tablecontrib'
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])
hide = hide && (AC_WhiteList.indexOf(user) != -1)
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])
hide = hide && (AC_WhiteList.indexOf(user) != -1)
if(userList[user]) userList[user]++
else userList[user] = 1
}
}
if(!hide || article.indexOf(":") != -1) //si tous les users viennent de la whitelist, on le l'affiche pas
{
//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.className='trover'
if(article == 'Discussion Utilisateur:' + mw.config.get('wgUserName')) mainrow.style.backgroundColor = '#fef3d8'
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 = ""
row.className='trover'
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 = ''
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(/'/g, "\\'") + '\')">#</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=ACobj.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=ACobj.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=ACobj.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=ACobj.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=ACobj.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=ACobj.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=ACobj.CellWithAnchor.cloneNode(true)
cell.firstChild.title = article
cell.firstChild.href = "/wiki/" + article.replace(/ /g,"_");
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 + '" href="/wiki/' + encodeURIComponent(article) + '">' + article + '</a>'
}
//lien delete
function htmlDeleteLink(article)
{
if (AC_displayDeleteLink)
return '<a title="supprimer" href="/w/index.php?title=' + encodeURIComponent(article) + '&action=delete">' +
'<img width="14" height="14" style="margin-top:2px" src="//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)
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)
{
// redirection des liens utilisateurs vers leurs contributions ou non
var userLinkNamespace = "Utilisateur:";
if (AC_linkToContrib) { userLinkNamespace = "Special:Contributions/"; }
return '<a title="Utilisateur:' + User + '" href="/wiki/' + userLinkNamespace + encodeURIComponent(User) + '" ' +
iif(AC_BlackList.indexOf(User)!=-1, 'style="border-bottom:1px solid red"','') + '>' + User + '</a>'
}
//</nowiki></pre></source>