Utilisateur:EDUCA33E/LiveRC.js
Un article de Wikipédia, l'encyclopédie libre.
Note : Après avoir sauvegardé, vous devez forcer le rechargement de la page pour voir les changements : Mozilla / Konqueror / Firefox : Shift-Ctrl-R, IE / Opera : Ctrl-F5, Safari : Cmd-R.
/* ==LiveWP== *Documentation : [[:fr:User:EDUCA33E/LiveRC/Documentation]] *Authors : [[:fr:User:EDUCA33E]] & [[:fr:User:TiChou]] *Version: 0.3.2b (beta) Version modifiée basée sur la version du 1er avril 2007 à 00:49 : http://fr.wikipedia.org/w/index.php?title=User:EDUCA33E/LiveRC.js&oldid=15525649 Légende des modifications apportées : # = commentaire + = nouvelle fonctionnalité * = fonctionnalité améliorée ou modifiée ! = bug corrigé - = fonctionnalité retiré 1 avr 2007 ------------ # récupération de la liste des recentchanges et des articles récents modifiés ! correction du problème de performance et de lenteur du aux téléchargements massifs et répétitifs des révisions des articles déjà analysés auparavant why?because! : si nombre de rc < rclimit, alors l'API ne fournit pas le dernier timestamp dans le champ rcstart du noeud query-continue et donc on reste avec un timestamp (tsInit) périmé + récupération à partir de la liste des rc des utilisateurs (IP ou non), des commentaires et du type de modif (bot, nouvelle page, modif. mineure) permet ainsi de récupérer toutes les révocations ainsi que tous les utilisateurs révoqués (ce n'était pas le cas avec la méthode précédente) permet aussi un meilleur suivi des utilisateurs de sa liste de contact * filtrage des utilisateurs IP depuis la fonction getRC * timestamp du dernier article analysé récupéré depuis champ timestamp et non à partir du rcstart qui n'est pas suffisamment fiable + mémorisation du revid du dernier article modifié afin d'empêcher d'analyser une même modification d'un article (if revid <= lastrevid then stop) * utilisation des méthodes et propriétés Javascript XML pour parser la liste XML des RC renvoyée par l'API et pour un traitement plus fin et sûr. # namespaces (getNS, ...) * utilisation des méthodes et propriétés XML pour parser la liste XML des NS - suppression des namespaces Special et Media (id < 0) * le namespace virtuel 'Tout' est la jonction de tous les namespaces (lstNs.join('|')) 2 avr 2007 ------------ # fonctions de la classe wpajax : * amélioration de la détection de l'objet XMLHttpRequest/Microsoft.XMLHTTP * amélioration lisibilité du code + choix de la méthode (GET, POST, HEAD... ; GET par défaut) + en-têtes paramétrables + possibilité d'envoyer des données (utile pour la méthode POST) + les articles que l'on révoque, ne se font plus à partir d'une nouvelle fenêtre dans le navigateur et de l'analyse de son URL pour traitement mais directement en asynchrone avec la fonction wpajax.http on charge l'article de la version oldid (GET), on récupère les paramètres wpTextbox1, wpStart/EditTime, wpEditToken, on définit le paramètre wpSummary avec le message de révocation et on envoie l'article (POST) - suppression des fonctions queryString et getContent (inutilisées) 3 avr 2007 ------------ + les utilisateurs sont désormais avertis en asynchrone (GET + POST) * amélioration du message d'avert (lien [[article]]) * les bots sont désormais détectés par le flag bot="" présent dans la liste des RC ; pour tester si le RC est effectué par un bot : if (state & BOT) - suppression de la variable lstBot et des fonctions liveBot() et getBot() # fonction getRedirCat() : + nouvelle fonction getRedirCAt() permettant de récupérer la liste des catégories de la page et de déterminer si la page est un REDIRECT via une requete query.php?titles=page&what=redirects|categories sur chaque page si catégorisé alors (state & CATEGORIZED) renvoi true si redirection alors (state & REDIRECT) renvoi true à partir de la liste des catégories, tests déterminant si la page est un AdQ (state & ADQ), protégée (state & LOCK), etc. (tableau categoriestests) * optimisation de la détection des révocations (commenttests, (state & REVERT)) # fontion getRevision() : * utilisation des méthodes et propriétés Javascript XML pour parser la liste XML des révisions renvoyée par l'API et pour un traitement plus fin et sûr. * récupération des infos de la page (title, id, user, state, ...) depuis l'objet rc (data.rc) retourné par getRC() et getRedirCAt() * si page nouvelle (state & NEW), alors lien diff figé, corrigeant par la même occasion le bug 'user1.replace is not a function' * simplification des tests redirect, homonymie, etc. (state & VARIABLE) # fonction getRC() : + création de l'objet rc facilitant le transfert vers les autres fonctions des informations de la page dans cet objet, sont stockées toutes les informations fournies dans la liste des RC ainsi que les différents statuts de la page (rc.state) TODO : * choix entre plusieurs namespaces + afficher la liste des révoqués bloqués par sysop * informer du bon déroulement de l'envoi de l'article révoqué ou de l'avert + créer une variable pour que le patrouilleur puisse définir sa propre liste de modèles d'avertissement (par ex. pour utiliser ses propres modèles) ! bug dans liveRC() 'document.getElementById("showNS0") has no properties' si getNS pas terminé de charger + liste de suivi en direct à partir de la liste des RC et de sa liste de suivi ! bug tri horaire des révoqués après minuit ! bug des révoqueurs utilisant popups qui se retrouve dans la liste des révoqués + avertir le patrouilleur si messages en attente (query.php?what=userinfo&uihasmsg) + ajout des fonctionnalités sysop si sysop (wgUserGroups) + indiquer si utilisateur déjà averti (x avert) ===Variables globales=== <pre> */ // Taille de la liste des RC par défaut; var rclimit = 30; // Hauteur du cadre de prévisualisation; var previewHeight = '250px'; // Effacement automatique de la ligne sur clic diff; var autoCloseDiff=0; // Timestamp d'initialisation; var lastrevid,lasttimestamp=1; // Découpage de l'URL et de ses paramètres; var _GET = new Array(); var _uri = location.href; var _temp_get_arr = _uri.substring(_uri.indexOf('?')+1, _uri.length).split("&"); var _temp_get_arr_1 = new Array(); for(_get_arr_i=0; _get_arr_i<_temp_get_arr.length; _get_arr_i++){ _temp_get_arr_1 = _temp_get_arr[_get_arr_i].split("="); _GET[decodeURIComponent(_temp_get_arr_1[0])] = decodeURIComponent(_temp_get_arr_1[1]); } delete _uri; delete _temp_get_arr; delete _temp_get_arr_1; // Variables d'état (pour test sur rc.state) var IP = 1; var BOT = 2 << 0; var SYSOP = 2 << 1; var NEW = 2 << 2; var MINOR = 2 << 3; var NEWNS = 2 << 4; var RENAMED = 2 << 5; var PATROLLED = 2 << 6; var REVERT = 2 << 7; var BLANKING = 2 << 8; var REPLACED = 2 << 9; var REDIRECT = 2 << 10; var CATEGORIZED = 2 << 11; var LOCK = 2 << 12; var FULLLOCK = 2 << 13; var HOMONYMIE = 2 << 14; var ADQ = 2 << 15; var BA = 2 << 16; var APDQ = 2 << 17; var COPYRIGHT = 2 << 18; var PAS = 2 << 19; var FIRE = 2 << 20; // Tableau des tests commentaires var commenttests = new Array( { regex: new RegExp(/^(LiveRC : )?Révocation |^Annulation des modifications|^(Undid|Revert to( the)?)revision|^(Undoing|Reverted( \d+)?) edit|^r(e)?v(ert(ing|ed)?)?\b/), state: REVERT }, { regex: new RegExp(/^Résumé automatique : blanchiment|^[Bb]lanchi/), state: BLANKING }, { regex: new RegExp(/^Résumé automatique : contenu remplacé par/), state: REPLACED } ); // Tableau des tests catégories var categoriestests = new Array( { regex: new RegExp(/^Cat[ée]gor(y|ie)[ ]?:[ ]?Page (semi-protégée|en semi-protection longue)$/i), state: LOCK }, { regex: new RegExp(/^Cat[ée]gor(y|ie)[ ]?:[ ]?Page protégée$/i), state: FULLLOCK }, { regex: new RegExp(/^Cat[ée]gor(y|ie)[ ]?:[ ]?Homonymie$/i), state: HOMONYMIE }, { regex: new RegExp(/^Cat[ée]gor(y|ie)[ ]?:[ ]?Article de qualité$/i), state: ADQ }, { regex: new RegExp(/^Cat[ée]gor(y|ie)[ ]?:[ ]?Bon article$/i), state: BA }, { regex: new RegExp(/^Cat[ée]gor(y|ie)[ ]?:[ ]?Article potentiellement (bon|de qualité)$/i), state: APDQ }, { regex: new RegExp(/^Cat[ée]gor(y|ie)[ ]?:[ ]?Article soupçonné de travail sous copyright$/i), state: COPYRIGHT }, { regex: new RegExp(/^Cat[ée]gor(y|ie)[ ]?:[ ]?Page proposée à la suppression$/i), state: PAS }, { regex: new RegExp(/^Cat[ée]gor(y|ie)[ ]?:[ ]?Wikipompiers /i), state: FIRE } ); // Liste des Sysop; var lstSysop = new Array(); /* // Gestion liste de suivi; var lstSuivi = new Array(); var lstSuiviHH = new Array(); */ // Gestion liste de contact; var lstContact = new Array(); // Gestion liste des révoc var lstRevoc = new Array(); // Menu outil; var menu = '<a href="javascript:;" onClick="supprLigne(\'*\');" style="color: red; font-weight: bold;">X</a>' + '<input id="stopLive" type="checkbox" value="true" />' + '<label for="stopLive">Pause</label>' + '<input id="shidPrev" type="checkbox" onclick="showHideObj(this, \'divLivePreview\');" />' + '<label for="shidPrev">Prévisualiser</label>' + '<input id="shidList" type="checkbox" onclick="showHideObj(this, \'liveFollow\');" />' + '<label for="shidList">Listes</label>' + '<input id="showDiffR" type="checkbox" />' + '<label for="showDiffR">Diff réduit</label>' + '<input id="shidRC" type="checkbox" checked onclick="showHideObj(this, \'divTabRC\');" />' + '<label for="shidRC">RC</label>' + '<input id="showBot" type="checkbox" checked />' + '<label for="showBot">Sans Bots</label>' + '<input id="showIP" type="checkbox" />' + '<label for="showIP">IP seules • </label>' + '<span id="selectNS" />'; // Appel des paramètres utilisateur : document.write('<script type="text/javascript" src="' + wgServer + wgScriptPath + '/index.php?title=User:'+wgUserName+'/LiveRCparam.js' + '&action=raw&ctype=text/javascript&dontcountme=s"></script>'); /* </pre> ===Utilitaires=== <pre> */ var wpajax = { http: function(bundle) { // mandatory: bundle.url // optional: bundle.async // optional: bundle.method // optional: bundle.headers // optional: bundle.data // optional: bundle.onSuccess (xmlhttprequest, bundle) // optional: bundle.onFailure (xmlhttprequest, bundle) // optional: bundle.otherStuff OK too, passed to onSuccess and onFailure var xmlhttp; try { xmlhttp = new XMLHttpRequest(); } catch(e) { try { xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { try { xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); } catch (e) { xmlhttp = false } } } if (xmlhttp) { xmlhttp.onreadystatechange = function() { if (xmlhttp.readyState == 4) wpajax.httpComplete(xmlhttp,bundle); }; xmlhttp.open(bundle.method ? bundle.method : "GET",bundle.url,bundle.async == false ? false : true); if (bundle.headers) { for (var field in bundle.headers) xmlhttp.setRequestHeader(field,bundle.headers[field]); } xmlhttp.send(bundle.data ? bundle.data : null); } return xmlhttp; }, httpComplete: function(xmlhttp,bundle) { if (xmlhttp.status == 200 || xmlhttp.status == 302) { if (bundle.onSuccess) bundle.onSuccess(xmlhttp,bundle); } else if (bundle.onFailure) { bundle.onFailure(xmlhttp,bundle); } else { // A activer en debug mode ? // alert(xmlhttp.statusText); } } }; // Parser if (document.implementation.createDocument) { var gml_xmlparser = new DOMParser(); } function gml_XMLParse(string) { if (document.implementation.createDocument) { return gml_xmlparser.parseFromString(string, "text/xml"); } else if (window.ActiveXObject) { var gml_xmldoc = new ActiveXObject("Microsoft.XMLDOM"); gml_xmldoc.async = "false"; ret = gml_xmldoc.loadXML(string); if (!ret) return null; return gml_xmldoc.documentElement; } return null; } /* </pre> === LiveDiff === <pre> */ function liveDiff(page, id, oldid) { var el = document.getElementById( 'livePreviewTitle' ); el.innerHTML="<b>Recherche du diff de : <span style='color:red'>"+page+"</span> en cours...</b>"; wpajax.http({ url: wgServer + wgScriptPath + '/index.php?title='+encodeURI(page)+'&diffonly=1&diff='+id+'&oldid='+oldid, onSuccess: getDiff, mpage: page, mid: id, moldid:oldid}); } function getDiff(xmlreq, data) { var doc = gml_XMLParse(xmlreq.responseText); var page=data.mpage; var oldid=data.moldid; var id=data.mid; var bC = doc.getElementById('bodyContent'); var LP = document.getElementById( 'livePreview' ); var dLP = document.getElementById( 'divLivePreview' ); var lD = getElementsByClass('diff',bC,null); // Get username of submitter var user1 = getElementsByClass('diff-otitle',doc,'td'); if (user1 != null && user1[0] != null) user1 = user1[0].getElementsByTagName('a')[2].innerHTML; var user2 = getElementsByClass('diff-ntitle',doc,'td'); if (user2 != null && user2[0] != null) user2 = user2[0].getElementsByTagName('a')[2].innerHTML; if (user2 == "défaire") { user2 = getElementsByClass('diff-ntitle',doc,'td'); user2 = user2[0].getElementsByTagName('a')[3].innerHTML; } user1=user1.replace(new RegExp(/\'/g), "\\'"); user2=user2.replace(new RegExp(/\'/g), "\\'"); var upage=page.replace(new RegExp(/\'/g), "\\'"); if (lD[0] == null) LP.innerHTML = bC.innerHTML; else { if (document.getElementById('showDiffR').checked) { var avantEl = getElementsByClass('diff-deletedline',bC,null); var apresEl = getElementsByClass('diff-addedline',bC,null); var avant = ""; var apres = ""; var lav = avantEl.length; var lap = apresEl.length; for(var n=0; n < lav ; n++) avant = avant + avantEl[n].innerHTML + "<br />"; for(var n=0; n < lap ; n++) apres = apres + apresEl[n].innerHTML + "<br />"; LP.innerHTML = "<table width='100%'><tr><td width='50%' class='diff-deletedline'>"+avant+"</td><td class='diff-addedline'>"+apres+"</td></tr></table>"; } else { LP.innerHTML = "<table border='0' width='98%' cellpadding='0' cellspacing='4' class='diff'>"+lD[0].innerHTML+"</table>"; } } if (dLP.style.display == "none") { var elcb = document.getElementById( 'shidPrev' ); elcb.checked="true"; dLP.style.display = "inline"; } var entete = document.getElementById( 'livePreviewTitle' ); entete.innerHTML='<b>Dernier diff de : <a href="'+wgServer + '/wiki/' + encodeURI(page) + '">' + page + '</a></b> • ' + '(<a href="javascript:;" onClick="liveHist(\''+upage+'\');" style="color:darkorange">Hist</a>)'; entete.innerHTML = '<table width="100%" class="creator"><tr><td>' + entete.innerHTML + '</td><td align="right"><small>' + // Verifier avant si le patrouilleur peut modifier cette page ? (query.php?what=permissions&titles=page) '[<a id="LiveRevertLink" href="javascript:getLiveMessage(\'liverevert\',\''+user1+'\',\''+user2+'\',\''+upage+'\',\''+oldid+'\');" >Défaire</a>] • ' + '[<a id="LiveVandalismLink" href="javascript:getLiveMessage(\'livevandalism\',\''+user1+'\',\''+user2+'\',\''+upage+'\',\''+oldid+'\');" >Vandalisme</a>] • ' + 'Raison : <input id="LiveRevertMessage" /> ••• ' + '[<a id="LiveAvertoLink" href="javascript:getLiveAverto(\''+user2+'\');">Avertir</a>] : ' + '<select id="averto">' + '<option value="Test 0">Test 0</option>' + '<option value="Test 1">Test 1</option>' + '<option value="Test 2">Test 2</option>' + '<option value="Test 3">Test 3</option>' + '<option value="Vandalisme|'+upage+'">Vandal</option>' + '<option value="Spammeur|'+upage+'">Spam</option>' + '<option value="Coucou">Coucou</option>' + '<option value="Motivation_modif|'+upage+'">Résumé</option>' + '<option value="Signature">Signature</option>' + '<option value="Bienvenue_copyright|'+upage+'">Copyright</option>' + '</select>' + '</td></tr></table>'; document.getElementById('LiveRevertMessage').focus(); } function getLiveAverto(user) { var link = document.getElementById('LiveAvertoLink'); link.href = "javascript:;"; link.style.color = "silver"; link.style.cursor = "default"; link.style.textDecoration = "none"; document.getElementById('averto').disabled = true; var message = document.getElementById('averto').value; wpajax.http({ url: wgServer + wgScriptPath + '/index.php?title=User_Talk:' + encodeURIComponent(user) + '&action=edit', onSuccess: postLiveAverto, user: user, message: message }); } function postLiveAverto(xmlreq, data) { var parser = new DOMParser(); var doc = parser.parseFromString(xmlreq.responseText, 'application/xhtml+xml'); var user = data.user; var message = data.message; var wpTextbox1 = encodeURIComponent('{{subst:' + message + '}} ~~~~\n' + doc.getElementById('wpTextbox1').value); var inputs = doc.getElementById('editform').getElementsByTagName('input'); var editform = new Array(); for (i=0; i<inputs.length; i++) { editform[inputs[i].name] = inputs[i].value; } var wpStarttime = encodeURIComponent(editform['wpStarttime']); var wpEdittime = encodeURIComponent(editform['wpEdittime']); var wpEditToken = encodeURIComponent(editform['wpEditToken']); var wpSummary = encodeURIComponent('LiveRC : Avertissement ! ' + message.replace(new RegExp(/\|(.*)/), ' sur [[$1]]') + ' !'); var headers = new Array(); headers['Content-Type'] = 'application/x-www-form-urlencoded'; wpajax.http({ url: wgServer + wgScriptPath + '/index.php?title=User_Talk:' + encodeURIComponent(user) + '&action=submit', method: "POST", headers: headers, data: 'wpSave=1&wpTextbox1=' + wpTextbox1 + '&wpStarttime=' + wpStarttime + '&wpEdittime=' + wpEdittime + '&wpEditToken=' + wpEditToken + '&wpSummary=' + wpSummary}); } function getLiveMessage(where, user1, user2, page, oldid) { var links = [ document.getElementById('LiveRevertLink'), document.getElementById('LiveVandalismLink') ]; var i,len=links.length; for (i=0; i<len; i++) { links[i].href = "javascript:;"; links[i].style.color = "silver"; links[i].style.cursor = "default"; links[i].style.textDecoration = "none"; } document.getElementById('LiveRevertMessage').disabled = true; var message = document.getElementById('LiveRevertMessage').value; wpajax.http({ url: wgServer + wgScriptPath + '/index.php?title=' + encodeURIComponent(page) + '&action=edit&oldid=' + oldid, onSuccess: postLiveRevert, where: where, page: page, user1: user1, user2: user2, message: message }); } function postLiveRevert(xmlreq, data) { var parser = new DOMParser(); var doc = parser.parseFromString(xmlreq.responseText, 'application/xhtml+xml'); var where = data.where; var page = data.page; var user1 = data.user1; var user2 = data.user2; var message = data.message; var wpTextbox1 = encodeURIComponent(doc.getElementById('wpTextbox1').value); var inputs = doc.getElementById('editform').getElementsByTagName('input'); var editform = new Array(); for (i=0; i<inputs.length; i++) { editform[inputs[i].name] = inputs[i].value; } var wpStarttime = encodeURIComponent(editform['wpStarttime']); var wpEdittime = encodeURIComponent(editform['wpEdittime']); var wpEditToken = encodeURIComponent(editform['wpEditToken']); switch(where) { case 'liverevert': var wpSummary = 'LiveRC : Révocation des modifications de [[Special:Contributions/' + user2 + '|' + user2 + ']]; retour à la version de [[User:' + user1 + '|' + user1 + ']]'; break; case 'livevandalism': var wpSummary = 'LiveRC : Révocation de vandalisme par [[Special:Contributions/' + user2 + '|' + user2 + ']]; retour à la version de [[User:' + user1 + '|' + user1 + ']]'; break; } if (message) wpSummary = wpSummary + ' ; ' + message; wpSummary = encodeURIComponent(wpSummary); var headers = new Array(); headers['Content-Type'] = 'application/x-www-form-urlencoded'; wpajax.http({ url: wgServer + wgScriptPath + '/index.php?title=' + encodeURIComponent(page) + '&action=submit', method: "POST", headers: headers, data: 'wpSave=1&wpTextbox1=' + wpTextbox1 + '&wpStarttime=' + wpStarttime + '&wpEdittime=' + wpEdittime + '&wpEditToken=' + wpEditToken + '&wpSummary=' + wpSummary}); } /* </pre> === LiveHist === <pre> */ function liveHist(page) { var el = document.getElementById( 'livePreviewTitle' ); el.innerHTML="<b>Recherche de l'historique de : <span style='color:red'>"+page+"</span> en cours...</b>"; wpajax.http({url:wgServer + wgScriptPath + '/index.php?title=' + encodeURI(page) + '&action=history', onSuccess: getHist, message: page }); } function getHist(xmlreq, data) { doc = gml_XMLParse(xmlreq.responseText); bC = doc.getElementById('bodyContent') var c=data.message; var LP = document.getElementById( 'livePreview' ); var dLP = document.getElementById( 'divLivePreview' ); LP.innerHTML = bC.innerHTML; if (dLP.style.display == "none") { var elcb = document.getElementById( 'shidPrev' ); elcb.checked="true"; dLP.style.display = "inline"; } var elt = document.getElementById( 'livePreviewTitle' ); elt.innerHTML='<b>Historique de : <a href="'+wgServer+'/wiki/'+encodeURI(c)+'">'+c+'</a></b>'; } /* </pre> === LiveContrib === <pre> */ function liveContrib(user) { var el = document.getElementById( 'livePreviewTitle' ); el.innerHTML="<b>Recherche des contributions de : <span style='color:red'>"+user+"</span> en cours...</b>"; wpajax.http({url:wgServer + '/wiki/Special:Contributions/'+encodeURI(user), onSuccess: getContrib, message: user }); } function getContrib(xmlreq, data) { doc = gml_XMLParse(xmlreq.responseText); bC = doc.getElementById('bodyContent') var user=data.message; var LP = document.getElementById( 'livePreview' ); var dLP = document.getElementById( 'divLivePreview' ); LP.innerHTML = bC.innerHTML; if (dLP.style.display == "none") { var elcb = document.getElementById( 'shidPrev' ); elcb.checked="true"; dLP.style.display = "inline"; } var utilde=user.replace(new RegExp(/\'/g), "\\'"); var entete = document.getElementById( 'livePreviewTitle' ); entete.innerHTML='<b>Contributions de : <a href="'+wgServer+'/wiki/User:'+encodeURI(user)+'">'+user+'</a></b>'; entete.innerHTML = '<table width="100%" class="creator"><tr><td>'+entete.innerHTML + '</td><td align="right"><small>' + '[<a href="javascript:var message=getLiveAverto(\''+utilde+'\');">Avertir</a>] : ' + '<select id="averto">' + '<option value="Test 0">Test 0</option>' + '<option value="Test 1">Test 1</option>' + '<option value="Test 2">Test 2</option>' + '<option value="Test 3">Test 3</option>' + '<option value="Coucou">Coucou</option>' + '<option value="Signature">Signature</option>' + '</select>' + '</td></tr></table>'; } /* </pre> === LiveSuivi === <pre> */ function liveSysop() { wpajax.http({url:wgServer + wgScriptPath + '/index.php?title=Special:Listusers&limit=500&group=sysop', onSuccess: getSysop, message: "Récup sysoplist" }); } function getSysop(xmlreq, data) { var doc = gml_XMLParse(xmlreq.responseText); var bC = doc.getElementById('bodyContent'); var lstSys = bC.getElementsByTagName( 'ul' )[ 0 ].getElementsByTagName( 'li' ); var info=""; var len = lstSys.length for(var i=0; i < len ; i++) { info=lstSys[i].getElementsByTagName( 'a' )[ 0 ].innerHTML; lstSysop.push(info); } liveNS(); } /* function liveWatch() { wpajax.http({url:wgServer + wgScriptPath + '/api.php?action=query&list=watchlist&wllimit=500&format=xml', onSuccess: getWatch, message: "Récup watchlist" }); } function getWatch(xmlreq, data) { var a=xmlreq.responseText; var c=data.message; var i; // document.getElementById('debug').innerHTML = a+"<br />**************************"; if(a.indexOf("<error")!=-1) { var lvSuivi = document.getElementById( 'liveSuivi' ); lvSuivi.innerHTML = "<small>Suivi désactivé. (API.php : watchlist)</small>"; return; } a=a.split("title=\""); var info=""; for(i=a.length-1; i >= 0 ; i--) { info=a[i].substr(0,a[i].indexOf("\" pageid")); if (info == "") continue; lstSuivi.push(info); lstSuiviHH.push("--:--"); } //document.getElementById('debug').innerHTML += lstSuivi; } */ function liveNS() { wpajax.http({url: wgServer + wgScriptPath + '/api.php?action=query&meta=siteinfo&siprop=namespaces&format=xml', onSuccess: getNS, message: "Récup NS" }); } function getNS(xmlreq, data) { var api = xmlreq.responseXML; if (api.firstChild.nodeName == "error") return; var nss = api.getElementsByTagName('query')[0].getElementsByTagName('namespaces')[0].getElementsByTagName('ns'); var len = nss.length; var i; var id,ns; var options = ""; var lstNs = new Array(); for (i=0; i<len; i++) { id = nss[i].getAttribute('id'); ns = nss[i].textContent; if (id < 0) continue; if (id == 0) ns = "Article"; options += '<option value="' + id + '">' + ns + '</option>'; lstNs.push(id); } options = '<option value="' + lstNs.join('|') + '">Tout</option>' + options; document.getElementById('selectNS').innerHTML = '<label for="showNS0">Espace </label><select id="showNS0">' + options + '</select>'; liveRC(); } /* </pre> === LiveRC === <pre> */ function supprLigne(quelLigne) { var tab = document.getElementById('tabRC'); var els = new Array(); if (quelLigne == '*') els = tab.getElementsByTagName('tr'); else els.push(document.getElementById(quelLigne)); var len = els.length; for (var i=len-1; i>=0; i--) if (els[i] != null) tab.removeChild(els[i]); } function getElementsByClass(searchClass,node,tag) { var classElements = new Array(); if ( node == null ) node = document; if ( tag == null ) tag = '*'; var els = node.getElementsByTagName(tag); var elsLen = els.length; var pattern = new RegExp('(^|\\s)'+searchClass+'(\\s|$)'); for (i = 0, j = 0; i < elsLen; i++) { if (pattern.test(els[i].className) ) { classElements[j] = els[i]; j++; } } return classElements; } function updateFollowContact() { var tempAr = new Array(); for (var user in lstContact) { var timestamp = lstContact[user].ts; if (timestamp == 0) continue; var ts = timestamp.replace(new RegExp(/.*T(\d\d:\d\d):\d\dZ/g), "$1"); var utilde = user.replace(new RegExp(/\'/g), "\\'"); var udiscut = '<a href="'+wgServer+'/wiki/User talk:'+encodeURI(user)+'" style="color:seagreen">D</a>'; var ucontrib = '<a href="javascript:;" onClick="liveContrib(\''+utilde+'\');" style="color:darkseagreen">C</a>'; var ueditor = '<a href="'+wgServer+'/wiki/User:'+encodeURI(user)+'">'+user+'</a>'; var ligne = '<span id="contact-' + timestamp + '"><small>' + ts +' • ' + udiscut + ' • ' + ucontrib + ' • </small>' + ueditor + '</span><br />'; tempAr.push(ligne); } tempAr.sort(); var lvContact = document.getElementById('liveContact'); lvContact.innerHTML = ""; var len = tempAr.length; for (var n=len-1; n>=0; n--) lvContact.innerHTML += tempAr[n]; } function updateFollowRevoc() { var tempAr = new Array(); for (var user in lstRevoc) { var timestamp = lstRevoc[user].ts; var ts = timestamp.replace(new RegExp(/.*T(\d\d:\d\d):\d\dZ/g), "$1"); var utilde = user.replace(new RegExp(/\'/g), "\\'"); var udiscut = '<a href="'+wgServer+'/wiki/User talk:'+encodeURI(user)+'" style="color:seagreen">D</a>'; var ucontrib = '<a href="javascript:;" onClick="liveContrib(\''+utilde+'\');" style="color:darkseagreen">C</a>'; var ueditor = '<a href="'+wgServer+'/wiki/User:'+encodeURI(user)+'">'+user+'</a>'; var ligne = '<span id="revoc-' + timestamp + '"><small>' + ts +' • ' + udiscut + ' • ' + ucontrib + ' • </small>' + ueditor + ' (' + lstRevoc[user].nb + ' fois)</span><br />'; tempAr.push(ligne); } tempAr.sort(); var lvRevoc = document.getElementById('liveRevoc'); lvRevoc.innerHTML = ""; var len = tempAr.length; for (var n=len-1; n>=0; n--) lvRevoc.innerHTML += tempAr[n]; } function getRevision(xmlreq, data) { if (document.getElementById('stopLive').checked) return; var api = xmlreq.responseXML.getElementsByTagName('api')[0]; if (api.firstChild.nodeName == "error") return; var rc = data.rc var title = rc.title; var pageid = rc.pageid; var revid = rc.revid; var oldid = rc.old_revid; var user = rc.user; var comment = (rc.comment ? rc.comment : ""); var timestamp = rc.timestamp; var ts = rc.timestamp.replace(new RegExp(/.*T(\d\d:\d\d):\d\dZ/g), "$1"); var ns = rc.ns; var state = rc.state; var revisions = api.getElementsByTagName('query')[0].getElementsByTagName('pages')[0].getElementsByTagName('page')[0].getElementsByTagName('revisions')[0].getElementsByTagName('rev'); var oldsize = (state & NEW ? 0 : revisions[1].textContent.length); var newsize = revisions[0].textContent.length var sizediff = newsize - oldsize; // INITIALISATION LIGNE RC // var tr1 = document.createElement('tr'); var th0 = document.createElement('th'); var th1 = document.createElement('th'); var td2 = document.createElement('td'); var td3 = document.createElement('td'); var td4 = document.createElement('td'); // SUPPR. LIGNE // th0.innerHTML = '<a href="javascript:;" onClick="supprLigne(\''+pageid+'_'+revid+'\');" style="color:red">X</a>'; // ARTICLE // var arti = "", artiStyle = ""; var preArti = "", postArti = ""; var ctilde = title.replace(new RegExp(/\'/g), "\\'"); var diff = ""; var diffClose = ""; if (autoCloseDiff == 1) diffClose='supprLigne(\''+pageid+'_'+revid+'\');'; if (state & NEW) diff = '<span style="color:silver">Diff</span>'; else diff = '<a href="javascript:;" onClick="liveDiff(\''+ctilde+'\','+revid+','+oldid+');'+diffClose+'" style="color:orange">Diff</a>'; var hist = '<a href="javascript:;" onClick="liveHist(\''+ctilde+'\');" style="color:darkorange">Hist</a>'; // Homonymie ? ; //////////////// if (ns == 0 && state & HOMONYMIE) { artiStyle = 'color: darkorange; font-weight: bold; font-style: italic;'; preArti += '<img src="http://upload.wikimedia.org/wikipedia/commons/thumb/7/72/Disambig.svg/16px-Disambig.svg.png" width="16px" alt="Homonymie" /> ' } // Page protégée ? ; //////////////////// if (state & FULLLOCK) preArti += '<img src="http://upload.wikimedia.org/wikipedia/commons/thumb/4/48/Padlock-red.svg/16px-Padlock-red.svg.png" width="16px" alt="Article protégé"/> '; if (state & LOCK) preArti += '<img src="http://upload.wikimedia.org/wikipedia/commons/thumb/e/e0/Padlock-gold.svg/16px-Padlock-gold.svg.png" width="16px" alt="Article semi-protégé"/> '; // Copyright ? ; ////////// if (state & COPYRIGHT) preArti += '<img src="http://upload.wikimedia.org/wikipedia/commons/thumb/b/b0/Copyright.svg/16px-Copyright.svg.png" width="16px" alt="Copyright" /> '; // PàS ? ; ////////////////// if (state & PAS) preArti += '<img src="http://upload.wikimedia.org/wikipedia/commons/thumb/b/b6/Cestino_pieno_architetto_01.svg/11px-Cestino_pieno_architetto_01.svg.png" height="11px" alt="PàS" /> '; // Intervention wikipompiers ? ; //////////////////////////////// if (state & FIRE) preArti += '<img src="http://upload.wikimedia.org/wikipedia/commons/thumb/9/99/FireIcon.svg/12px-FireIcon.svg.png" height="12px" alt="Intervention Wikipompiers" /> '; // Redirection ? ; ////////////////// if (state & REDIRECT) { artiStyle = 'color: green; font-weight: bold; font-style: italic;'; postArti += '<img src="http://upload.wikimedia.org/wikipedia/commons/thumb/b/b5/Redirectltr.png/20px-Redirectltr.png" width="20px" alt="Redirection" />'; postArti += '<a href="'+wgServer+'/wiki/'+encodeURI(rc.redirect)+'">'+rc.redirect+'</a>'; } // Adq ? ; ////////// if (state & ADQ) postArti += '<sup><img src="http://upload.wikimedia.org/wikipedia/commons/thumb/c/c7/Fairytale_bookmark_gold.png/10px-Fairytale_bookmark_gold.png" width="10px" alt="Adq" /></sup>'; // Bon article ? ; ////////////////// if (state & BA) postArti += '<sup><img src="http://upload.wikimedia.org/wikipedia/commons/thumb/8/8a/Fairytale_bookmark_silver_light.png/10px-Fairytale_bookmark_silver_light.png" width="10px" alt="Bon article" /></sup>'; // Article potentiellement de qualité ? ; ///////////////////////////////////////// if (state & APDQ) postArti += '<sup><img src="http://upload.wikimedia.org/wikipedia/commons/thumb/9/9a/Fairytale_bookmark_light.png/10px-Fairytale_bookmark_light.png" width="10px" alt="Article potentiellement de qualité" /></sup>'; // Article catégorisé ? ; ///////////////////////// var isCategorized = ""; if (!(state & REDIRECT) && !(state & HOMONYMIE) && ns == 0 && !(state & CATEGORIZED)) postArti += '<sup style="color:crimson">(cat ?)</sup>'; arti = '<a style="'+artiStyle+'" href="'+wgServer+'/wiki/'+encodeURI(title)+'">'+title+'</a>'; th1.innerHTML = '<small>' + ts + ' • ' + diff + ' • ' + hist + ' • </small>' + preArti + arti + postArti; th1.className="creator-title"; th1.style.border="1px"; th1.style.width="40%"; // EDITEUR // var usertilde = user.replace(new RegExp(/\'/g), "\\'"); var discut = '<a href="'+wgServer+'/wiki/User talk:'+encodeURI(user)+'" style="color:seagreen">D</a>'; var contrib = '<a href="javascript:;" onClick="liveContrib(\''+usertilde+'\');" style="color:darkseagreen">C</a>'; var editor = "", preEditor = ""; // Bot ? ; ////////// if (state & BOT) preEditor += '<img src="http://upload.wikimedia.org/wikipedia/commons/thumb/2/2a/Nuvola_apps_kservices.png/16px-Nuvola_apps_kservices.png" width="16px" /> '; // Sysop ? ; //////////// if (state & SYSOP) preEditor += '<img src="http://upload.wikimedia.org/wikipedia/commons/thumb/2/2c/Broom_icon.svg/16px-Broom_icon.svg.png" width="16px" /> '; // Reverté ? ; ///////////////// if (state & REVERT) preEditor = '<img src="http://upload.wikimedia.org/wikipedia/commons/thumb/2/2c/Nuvola_actions_undo.png/16px-Nuvola_actions_undo.png" width="16px" /> '; // TOR potentiel / AOL var isTOR = new RegExp(/172\.[\d]*\.[\d]*\.[\d]*/); if (isTOR.test(user)) preEditor += '<img src="http://upload.wikimedia.org/wikipedia/commons/thumb/6/6e/Dialog-warning.svg/16px-Dialog-warning.svg.png" width="16px" /> '; editor = '<a href="'+wgServer+'/wiki/User:'+encodeURI(user)+'">'+user+'</a>'; td2.innerHTML = '<small>' + discut + ' • ' + contrib + ' • </small>' + preEditor + editor; td2.className="creator-name"; td2.style.border = "1px"; td2.style.width = "20%"; if (lstRevoc[user]) { td2.style.border = "2px solid red"; td2.innerHTML += '<sup style="color:red">(' + lstRevoc[user].nb + ' révoc)</sup>' } // COMMENTAIRE // td3.innerHTML = "<small>" + comment + "</small>"; td3.style.border = "1px"; td3.style.width = "40%"; if (state & REVERT) { th0.style.backgroundColor = "#FFE4E1"; th1.style.backgroundColor = "#FFE4E1"; td2.style.backgroundColor = "#FFE4E1"; td3.style.backgroundColor = "#FFE4E1"; td4.style.backgroundColor = "#FFE4E1"; tr1.style.border = "1px solid crimson"; } if (state & BLANKING || newsize == 0) { th0.style.backgroundColor = "white"; th1.style.backgroundColor = "white"; td2.style.backgroundColor = "white"; td3.style.backgroundColor = "white"; td4.style.backgroundColor = "white"; tr1.style.border = "2px double crimson"; } if (state & NEW) { th0.style.backgroundColor = "#e2f2d2"; th1.style.backgroundColor = "#e2f2d2"; td2.style.backgroundColor = "#e2f2d2"; td3.style.backgroundColor = "#e2f2d2"; td4.style.backgroundColor = "#e2f2d2"; tr1.style.border = "1px solid green"; } if (state & IP) { td2.style.backgroundColor = "white"; td3.style.backgroundColor = "white"; td4.style.backgroundColor = "white"; } if (isTOR.test(user)) td2.style.backgroundColor = "pink"; if (state & REPLACED) { th0.style.backgroundColor = "pink"; th1.style.backgroundColor = "pink"; td2.style.backgroundColor = "pink"; td3.style.backgroundColor = "pink"; td4.style.backgroundColor = "pink"; td4.innerHTML = '<img src="http://upload.wikimedia.org/wikipedia/commons/thumb/9/95/Categorie_III.svg/10px-Categorie_III.svg.png" width="10px" alt="Warning"/>'; tr1.style.border = "2px solid crimson"; } // CONTACT LIST // ////////////////// if (lstContact[user]) { td2.style.border = "2px solid gold"; td2.style.backgroundColor = "yellow"; } if (user == wgUserName) { td2.style.border = "2px solid #A0B0E0"; td2.style.backgroundColor = "#F0F8FF"; } // DELTA SIZE // // delta de modif ; /////////////////// var txtdiff = ""; if (sizediff < 0) txtdiff = '<sub style="color:red">'+sizediff+'</sub>'; else if (sizediff == 0) txtdiff = '<small style="color:purple">='+sizediff+'</small>'; else txtdiff = '<sup style="color:blue">+'+sizediff+'</sup>'; td4.innerHTML += txtdiff; td4.style.border = "1px"; td4.style.textAlign = "right"; // ASSEMBLAGE LIGNE // tr1.appendChild(th0); tr1.appendChild(th1); tr1.appendChild(td2); tr1.appendChild(td3); tr1.appendChild(td4); tr1.id = pageid+"_"+revid; var tab = document.getElementById( 'tabRC' ); var elold = document.getElementById(pageid+"_"+oldid); if (tab.firstChild != null) tab.insertBefore(tr1, tab.firstChild); else tab.appendChild(tr1); if (elold == null) { if (tab.childNodes.length > rclimit) { var idt = tab.lastChild.id; supprLigne(idt); } } else { supprLigne(pageid+"_"+oldid); } // MISE A JOUR LISTES // /* var spos = lstSuivi.indexOf(title); if(spos != -1) { th0.style.border = "2px solid gold"; th0.style.backgroundColor = "yellow"; th1.style.border = "2px solid gold"; th1.style.backgroundColor = "yellow"; lstSuiviHH[spos] = timestamp; var tempsAr = new Array(); var len = lstSuivi.length; for (var n = 0; n < len; n++) { if(lstSuiviHH[n] == "--:--") continue; var cstilde = lstSuivi[n].replace(new RegExp(/\'/g), "\\'"); var sdiff = '<a href="javascript:;" onClick="liveDiff(\''+cstilde+'\',\'current\','+revid+');" style="color:orange">Diff</a>'; var shist = '<a href="javascript:;" onClick="liveHist(\''+cstilde+'\');" style="color:darkorange">Hist</a>'; var sarti = '<a href="'+wgServer+'/wiki/'+encodeURI(lstSuivi[n])+'">'+lstSuivi[n]+'</a>'; var ligne='<small>' + lstSuiviHH[n] + ' • ' + sdiff + ' • ' + shist + ' • </small>' + sarti +'<br />'; tempsAr.push(ligne); } tempsAr.sort(); len = tempsAr.length; var lvSuivi = document.getElementById( 'liveSuivi' ); lvSuivi.innerHTML = ""; for (var n=len-1; n >= 0; n--) lvSuivi.innerHTML = lvSuivi.innerHTML + tempsAr[n]; } */ if (lstContact[user]) { lstContact[user].ts = timestamp; updateFollowContact(); } if (state & REVERT) { var scUser = new RegExp(/\[\[Special:Contributions\/([^\]\|]+)/); var match = scUser.exec(comment); if (match != null) { var userR = match[1]; if (userR != user && userR != wgUserName) { if (!lstRevoc[userR]) lstRevoc[userR] = { ts: 0, nb: 0 }; lstRevoc[userR].ts = timestamp; lstRevoc[userR].nb += 1; updateFollowRevoc(); } } } } function getRedirCat(xmlreq, data) { if (document.getElementById('stopLive').checked) return; var yurik = xmlreq.responseXML.getElementsByTagName('yurik')[0]; if (yurik.firstChild.nodeName == "error") return; var rc = data.rc; var pageid = rc.pageid; var revid = rc.revid; var state = rc.state; var page = yurik.getElementsByTagName('pages')[0].getElementsByTagName('page')[0]; if (page.getElementsByTagName('redirect').length) { state += REDIRECT; rc.redirect = page.getElementsByTagName('redirect')[0].getElementsByTagName('to')[0].textContent; } if (page.getElementsByTagName('categories').length) { state += CATEGORIZED; var categories = page.getElementsByTagName('categories')[0].getElementsByTagName('cl'); var i,j; var leni = categories.length; var lenj = categoriestests.length; for (i=0; i<leni; i++) for (j=0; j<lenj; j++) if (categoriestests[j].regex.test(categories[i].textContent)) state += categoriestests[j].state; } rc.state = state; wpajax.http({ url: wgServer + wgScriptPath + '/api.php?action=query&prop=revisions&pageids=' + pageid + '&rvstartid=' + revid + '&rvlimit=2&rvprop=content&format=xml', onSuccess: getRevision, rc: rc }); } function getRC(xmlreq, data) { if (document.getElementById('stopLive').checked) return; var api = xmlreq.responseXML.getElementsByTagName('api')[0]; if (api.firstChild.nodeName == "error") return; var rcs = api.getElementsByTagName('query')[0].getElementsByTagName('recentchanges')[0].getElementsByTagName('rc'); var i,j,leni,lenj,rc; leni=rcs.length; for (i=leni-1; i>=0; i--) { if (rcs[i].getAttribute('revid') <= lastrevid) continue; rc = new Object(); rc.state = 0; lenj = rcs[i].attributes.length; for (j=0; j<lenj; j++) { switch(rcs[i].attributes[j].name) { case 'anon': rc.state += IP; break; case 'bot': rc.state += BOT; break; case 'new': rc.state += NEW; break; case 'minor': rc.state += MINOR; break; case 'new_ns': rc.state += NEWNS; break; case 'new_title': rc.state += RENAMED; break; case 'patrolled': rc.state += PATROLLED; break; case 'bot': rc.state += BOT; break; case 'type': break; default: rc[rcs[i].attributes[j].name] = rcs[i].attributes[j].value; break; } } if (typeof(rc.comment) != "undefined") { lenj = commenttests.length; for (j=0; j<lenj; j++) if (commenttests[j].regex.test(rc.comment)) rc.state += commenttests[j].state; } if (lstSysop.indexOf(rc.user) != -1) rc.state += SYSOP; if (document.getElementById('showIP').checked && !(rc.state & IP) && !(rc.state & REVERT) && !(rc.state & BLANKING) && !(rc.state & REPLACED) && !(lstContact[rc.user]) && !(lstRevoc[rc.user]) && (rc.user != wgUserName)) continue; wpajax.http({url: wgServer + wgScriptPath + '/query.php?titles=' + rc.title + '&what=redirects|categories&format=xml', onSuccess: getRedirCat, rc: rc }); } lastrevid = rcs[0].getAttribute('revid'); lasttimestamp = rcs[0].getAttribute('timestamp').replace(new RegExp(/\D/g), ""); document.getElementById('tsInit').innerHTML = "Dernière situation : " + lasttimestamp; } function liveRC() { var refresh = 10; timer= setTimeout("liveRC()",refresh*1000); if (document.getElementById('stopLive').checked) return; var rcns = document.getElementById('showNS0').value; if (rcns == null) return; var rcshow; if (document.getElementById('showBot').checked) rcshow = '&rcshow=!bot'; wpajax.http({url:wgServer + wgScriptPath + '/api.php?action=query&list=recentchanges&rcnamespace=' + rcns + '&rcprop=user|comment|flags' + rcshow + '&rcend=' + lasttimestamp + '&rclimit=' + rclimit + '&format=xml', onSuccess: getRC, message: "Traitement en cours...\n\n" }); } function showHideObj(parent, fils) { var ofils = document.getElementById( fils ); if (parent.checked) ofils.style.display="inline"; else ofils.style.display="none"; } addOnloadHook(function () { if (wgTitle == "EDUCA33E/LiveRC") { var top = document.getElementById( 'top' ); top.innerHTML = ""; var siteSub = document.getElementById( 'siteSub' ); var contentSub = document.getElementById( 'contentSub' ); var rtb = document.getElementById( 'RealTitleBanner' ); var rt = document.getElementById( 'RealTitle' ); var pca = document.getElementById( 'p-cactions' ); top.style.display = "none"; siteSub.style.display = "none"; contentSub.style.display = "none"; if (rtb != null) rtb.style.display = "none"; if (rt != null) rt.style.display = "none"; if (pca != null) pca.style.display = "none"; var lvPreviewFoot = document.getElementById( 'livePreviewFoot' ); lvPreviewFoot.innerHTML = menu; if (previewHeight) document.getElementById('livePreview').style.height = previewHeight; var _lstContact = lstContact; var _len = lstContact.length; lstContact = new Array(); for (var _i=0; _i<_len; _i++) lstContact[_lstContact[_i]] = { ts: 0 }; // Main //liveWatch(); liveSysop(); } }); /* </pre> */