Utilisateur:Orlodrim/ancresbrisees.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) ;
Chrome / Internet Explorer / Opera : maintenez la touche Ctrl en cliquant sur le bouton Actualiser ou pressez Ctrl-F5.// Script pour faciliter la restauration des ancres brisées
// Partiellement basé sur http://fr.wikipedia.org/wiki/Utilisateur:Phe/Clickodrome.js
var banDefSummary = "Restauration des [[Projet:Restauration des ancres brisées|ancres brisées]]";
var banURLParam = "&rab=";
var banLastPos = new Array();
var wgAction_ = mw.config.get('wgAction');
var wgServer_ = mw.config.get('wgServer');
var wgScript_ = mw.config.get('wgScript');
var wgScriptPath_ = mw.config.get('wgScriptPath');
var wgTitle_ = mw.config.get('wgTitle');
var wgArticlePath_ = mw.config.get('wgArticlePath');
var wgPageName_ = mw.config.get('wgPageName');
var wgCanonicalNamespace_ = mw.config.get('wgCanonicalNamespace');
String.prototype.htmlize = function() {
var chars = new Array('&','<','>','"');
var entities = new Array('amp','lt','gt','quot');
var string = this;
for (var i=0; i<chars.length; i++) {
var regex = new RegExp(chars[i], "g");
string = string.replace(regex, '&' + entities[i] + ';');
}
return string;
}
function banIquo(x, y) {
var xModY = ((x >= 0) ? x : y - (-x) % y) % y;
return (x - xModY) / y;
}
function banGetPageURL(page) {
return wgServer_ + wgArticlePath_.split('$1').join(encodeURI(page));
}
function banEscapeStr(str) {
return "'" + str.replace(/\\/g, '\\\\').replace(/'/g, '\\\'').htmlize() + "'";
}
function banNormalizeLink(s) {
var i = s.indexOf("#");
if (i == -1) i = s.length;
var article = s.substr(0, i).replace(/^ +/, "").replace(/ +$/, "").replace(/ /g, "_");
if (article == "")
article = wgPageName_;
else if (article[0] == ":")
article = article.substr(1);
article = article.substr(0, 1).toUpperCase() + article.substr(1); // Ne marche que dans l'espace principal
var anchor = s.substr(i + 1).replace(/ +$/, "").replace(/ /g, "_");
anchor = encodeURI(anchor).replace(/%/g, ".");
while (true) {
var match = /[;,/?@&=+$!~*\'()]/.exec(anchor);
if (!match) break;
var i = match.index;
var cEnc = anchor.charCodeAt(i).toString(16).toUpperCase();
anchor = anchor.substr(0, i) + "." + cEnc + anchor.substr(i + 1);
}
return article + "#" + anchor;
}
function banExternalLink(link) {
var s = (link[0] == ":") ? link.substr(1) : link;
var i = s.indexOf(":");
if (i == 0) return false;
s = s.substr(0, i).toLowerCase();
return s.length == 1 || (s.length == 2 && s != "wp") || s == "wikt";
}
var banAjax = {
http: function(bundle) {
var xmlhttp = new XMLHttpRequest();
if (!xmlhttp) return false;
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4)
banAjax.httpComplete(xmlhttp, bundle);
};
xmlhttp.open(bundle.method ? bundle.method : "GET", bundle.url, true);
if (bundle.headers) {
for (var field in bundle.headers)
xmlhttp.setRequestHeader(field, bundle.headers[field]);
}
xmlhttp.send(null);
},
httpComplete: function(xmlhttp, bundle) {
if (xmlhttp.status == 200 || xmlhttp.status == 302)
bundle.onSuccess(xmlhttp, bundle);
else if (bundle.onFailure)
bundle.onFailure(xmlhttp, bundle);
}
};
// Cases à cocher et liens sur les pages du projet
// ***********************************************
function banPageInProject() {
var prefix = "Restauration des ancres brisées/";
if (wgCanonicalNamespace_ != "Projet") return false;
if (wgTitle_.substr(0, prefix.length) != prefix) return false;
var subpage = wgTitle_.substr(prefix.length);
return (subpage.length == 1 || subpage == "0-9" || subpage == "Autres"
|| subpage == "Multiple");
}
function banGetLineArticle(line) {
return line.getElementsByTagName('a')[0].innerHTML;
}
/* return true if a part of the element is striked */
function banIsItemStriked(e) {
return e.getElementsByTagName('s').length != 0;
}
function banFormatProjectPage() {
var content = document.getElementById("bodyContent");
var submit = document.createElement("button");
submit.type = "submit";
submit.innerHTML = "Valider";
//submit.onclick = dist_edit_submit_change_step1;
submit.onclick = banSubmit;
content.appendChild(submit);
var li = content.getElementsByTagName("li");
var anchors = "";
for (var j = 0; j < li.length; j++) {
var article = banGetLineArticle(li[j]);
if (j == 0 || banGetLineArticle(li[j - 1]) != article) {
anchors = "";
for (var k = j; k < li.length && banGetLineArticle(li[k]) == article; k++) {
if (k > j) anchors += "|";
anchors += li[k].getElementsByTagName('a')[1].innerHTML;
}
}
if (wgTitle_ != "Restauration des ancres brisées/Multiple") {
var lineLinks = li[j].getElementsByTagName('a');
var l1 = lineLinks[0];
var l2 = lineLinks[1];
var l3 = lineLinks[2];
l1.href = wgServer_ + wgScript_ + '?title=' + encodeURIComponent(article)
+ '&action=edit&rab=' + encodeURIComponent(anchors)
+ '#editform';
l1.target = 'banwindow1';
l2.target = 'banwindow2';
}
var input1 = document.createElement('input');
input1.type = 'checkbox';
input1.checked = banIsItemStriked(li[j]);
var input2 = document.createElement('input');
input2.type = 'checkbox';
input2.checked = false;
li[j].insertBefore(input2, li[j].firstChild);
li[j].insertBefore(input1, li[j].firstChild);
}
}
function dist_edit_change_text(text) {
var content = document.getElementById('bodyContent');
var input = content.getElementsByTagName("input");
var li = content.getElementsByTagName("li");
if (li.length * 2 != input.length) {
alert('bad li/input count ' + li.length + ' ' + input.length)
return text;
}
liensRestants = 0;
new_text = '';
lines = text.split('\n');
var k = 0;
for (var j = 0; j < lines.length; ++j) {
if (lines[j].indexOf('*') == 0) {
if (k >= li.length) {
alert('something feel bad, k >= input.length');
return text;
}
if (input[k*2].disabled || input[k*2+1].checked) {
} else if (input[k*2].checked && lines[j].indexOf('<s>') == -1) {
new_text += '*<s>' + lines[j].slice(1) + '</s>\n';
} else {
new_text += lines[j] + '\n';
liensRestants++;
}
k++;
} else {
new_text += lines[j] + '\n';
}
}
if (k * 2 != input.length) {
alert('k != input.length' + k + ' ' + input.length);
return text;
}
return new_text;
}
function dist_edit_submit_change_step2(doc, newform, form) {
var l = form.getElementsByTagName('textarea')[0];
var t = document.createElement('textarea');
t.style.display = "none";
t.name = l.name;
t.value = dist_edit_change_text(l.value);
newform.appendChild(t);
l = form.getElementsByTagName('input');
for (i = l.length; i--; ) {
if (l[i].name == 'wpSummary') {
l[i].value = "Mise à jour : " + liensRestants + " liens restants";
l[i].style.display = "none";
} else if (l[i].name == 'wpSave') {
} else if (l[i].name == 'wpPreview') {
} else if (l[i].name == 'wpDiff') {
} else {
l[i].style.display = "none";
}
newform.appendChild(l[i]);
}
}
function banSubmit() {
var xml_http_client = new XMLHttpRequest();
this.disabled = true;
url_name = wgServer_ + wgScript_ + "?title=" + wgPageName_ + "&action=edit";
banAjax.http({url: url_name, onSuccess: banSubmit2});
}
function banSubmit2(xmlreq, data) {
var parser = new DOMParser();
var doc = parser.parseFromString(xmlreq.responseText, 'application/xhtml+xml');
newform = document.createElement('form');
form = doc.getElementById('editform');
dist_edit_submit_change_step2(doc, newform, form);
newform.name = form.name;
newform.method = form.method;
newform.id = form.id;
newform.action = form.action;
newform.style.display = "none";
document.getElementById('bodyContent').appendChild(newform);
newform.submit();
//window.location = banGetPageURL("Projet:Restauration des ancres brisées");
}
// Recherche des ancres sur les pages d'édition
// ********************************************
var banBSIndex = -1;
var banBSMsg, banBSRevisions, banBSFirst, banBSLast, banBSCurrent;
var banBSText, banBSLinkN, banBSContinue, banBSTimestamp;
/* Rend inactif un lien javascript, de façon visible. */
function banDisableLink(link) {
link.href = "javascript:;";
link.style.color = "silver";
link.style.cursor = "default";
link.style.textDecoration = "none";
}
/* Recherche la première occurence d'une ancre à partir d'une position donnée. */
function banFindNext(s, link, start) {
var i = start, j, k, pageLink;
var linkN = banNormalizeLink(link);
while (true) {
i = s.indexOf("[[", i);
if (i == -1) return false;
i += 2;
j = s.indexOf("]]", i);
if (j == -1) return false;
pageLink = s.substr(i, j - i);
k = pageLink.indexOf("|");
if (k != -1)
pageLink = pageLink.substr(0, k);
else
k = pageLink.length;
if (pageLink.indexOf("#") != -1 && linkN == banNormalizeLink(pageLink))
return [i, i + k];
i = j + 2;
}
}
// Recherche dichotomique de la date d'ajout d'un lien
function banGetDate(index, link) {
banBSMsg = document.getElementById("banMsgBS" + index);
var s = document.getElementById("editform").getElementsByTagName("textarea")[0].value;
var pos = banFindNext(s, link, 0);
if (!pos) {
banBSMsg.innerHTML = "[non trouvé dans la version actuelle]"
return;
}
if (banBSIndex != -1) return;
banBSIndex = index;
banDisableLink(document.getElementById("banDate" + index));
banBSText = s.substr(pos[0] - 2, pos[1] - pos[0] + 3);
banBSLinkN = banNormalizeLink(link);
banBSMsg.innerHTML = "[initialisation recherche]";
var request = wgServer_ + wgScriptPath_ + '/api.php?format=xml'
+ '&action=query&rawcontinue=&prop=revisions&rvlimit=500'
+ '&rvprop=ids|timestamp&titles=' + encodeURIComponent(wgPageName_);
banAjax.http({url: request, onSuccess: banGetDate2});
}
function banGetDate2(request, data) {
var lst = request.responseXML.getElementsByTagName("revisions");
if (!lst) {
banBSMsg.innerHTML = "[erreur]";
banBSIndex = -1;
return;
}
banBSRevisions = lst[0].childNodes;
banBSFirst = -1;
banBSLast = banBSRevisions.length;
banBSContinue = request.responseXML.getElementsByTagName("query-continue").length > 0;
banGetDateBS();
}
function banGetDateBS() {
banBSCurrent = banIquo(banBSFirst + banBSLast, 2);
if (banBSCurrent == banBSFirst) {
if (banBSFirst == -1) {
banBSMsg.innerHTML = "[erreur : lien non trouvé]";
banBSIndex = -1;
}
else if (banBSLast == banBSRevisions.length) {
if (banBSContinue) {
banBSMsg.innerHTML = "[erreur : ajouté avant les " + banBSLast + " dernières révisions]";
banBSIndex = -1;
}
else {
banBSTimestamp = banBSRevisions[banBSCurrent].getAttribute("timestamp");
var lnk = wgServer_ + wgScript_ + "?oldid=" + banBSRevisions[banBSCurrent].getAttribute("revid");
banBSMsg.innerHTML = "[ajouté à la création le <a href=\"" + lnk
+ "\" target=\"_blank\">" + banBSTimestamp + "</a>]";
}
}
else {
banBSTimestamp = banBSRevisions[banBSCurrent].getAttribute("timestamp");
var lnk = wgServer_ + wgScript_ + "?oldid="
+ banBSRevisions[banBSCurrent + 1].getAttribute("revid") + "&diff="
+ banBSRevisions[banBSCurrent].getAttribute("revid");
banBSMsg.innerHTML = "[ajouté le <a href=\"" + lnk + "\" target=\"_blank\">"
+ banBSTimestamp + "</a>]";
}
if (banBSIndex != -1) {
// Recherche la version de la cible au moment de l'ajout du lien
var targetTitle = banBSLinkN.substr(0, banBSLinkN.indexOf("#"));
var request = wgServer_ + wgScriptPath_ + '/api.php?format=xml'
+ '&action=query&rawcontinue=&prop=revisions&rvlimit=500'
+ '&rvprop=ids|timestamp&titles=' + encodeURIComponent(targetTitle);
banAjax.http({url: request, onSuccess: banGetDateTarget});
}
}
else {
banBSMsg.innerHTML = "[dichotomie sur " + (banBSLast - banBSFirst - 1) + " révisions]";
var request = wgServer_ + wgScript_ + "?action=raw&oldid="
+ banBSRevisions[banBSCurrent].getAttribute("revid");
banAjax.http({url: request, onSuccess: banGetDateBS2});
}
}
function banGetDateBS2(xmlreq, data) {
var linkFound = xmlreq.responseText.indexOf(banBSText) != -1;
if (linkFound)
banBSFirst = banBSCurrent;
else
banBSLast = banBSCurrent;
banGetDateBS();
}
function banGetDateTarget(xmlreq, data) {
msg = banBSMsg.innerHTML;
msg = msg.substr(0, msg.length - 1);
var lst = xmlreq.responseXML.getElementsByTagName("revisions");
if (lst.length == 0)
msg += ", pas de page cible";
else {
var targetRev = lst[0].childNodes;
var i = 0;
for (; i < targetRev.length; i++) {
if (targetRev[i].getAttribute("timestamp") < banBSTimestamp) {
var lnk = wgServer_ + wgScript_ + "?oldid=" + targetRev[i].getAttribute("revid") + banBSLinkN.substr(banBSLinkN.indexOf("#"));
msg += ", <a href=\"" + lnk + "\" target=\"_blank\">cible à cette date</a>";
break;
}
}
if (i == targetRev.length) {
msg += ", page cible créée après";
}
}
banBSMsg.innerHTML = msg + "]";
banBSIndex = -1;
}
// Sélection des ancres dans le code wiki
function banSetSelection(start, end) {
var txt = document.getElementById('editform').getElementsByTagName('textarea')[0];
txt.focus();
txt.setSelectionRange(start, start);
var evt = document.createEvent('KeyEvents');
evt.initKeyEvent('keypress', true, true, window, false, false, false, false, 0, 32);
txt.dispatchEvent(evt);
evt = document.createEvent('KeyEvents');
evt.initKeyEvent('keypress', true, true, window, false, false, false, false, 8, 0);
txt.dispatchEvent(evt);
txt.setSelectionRange(start, end);
}
/* Sélectionne l'occurence suivante d'une ancre brisée donnée. */
function banSelectAnchor(index, link) {
var s = document.getElementById("editform").getElementsByTagName("textarea")[0].value;
var pos = banFindNext(s, link, banLastPos[index]);
var msg = document.getElementById("banMsg" + index);
if (!pos) var pos = banFindNext(s, link, 0);
if (!pos) {
msg.innerHTML = "(non trouvé)";
return;
}
banLastPos[index] = pos[1];
msg.innerHTML = banFindNext(s, link, pos[1]) ? "" : "[dernière occurence]";
banSetSelection(pos[0], pos[1]);
}
function banJSLink(index, link) {
return link.htmlize() + " (<a href=\"javascript:banSelectAnchor(" + index + ","
+ encodeURI(banEscapeStr(link)) + ");\">chercher</a> | "
+ "<a href=\"" + banGetPageURL(banNormalizeLink(link)) + "\" target=\"banwindow2\">voir cible</a> | "
+ "<a id=\"banDate" + index + "\" href=\"javascript:banGetDate(" + index + ","
+ encodeURI(banEscapeStr(link)) + ")\">date d'ajout</a>) "
+ "<span id=\"banMsg" + index + "\"></span> "
+ "<span id=\"banMsgBS" + index + "\"></span>";
}
/* Crée des liens sous la fenêtre d'édition pour chercher les différentes
occurences des ancres brisées de l'article. */
function banFormatEditPage(anchors, initSummary, selectFirst) {
var banList = document.getElementById("banList");
if (banList == null) {
var banList = document.createElement("span");
banList.id = "banList";
var p = document.getElementById("MediaWiki-summary");
p.insertBefore(banList, p.firstChild);
}
if (initSummary) {
var wpSummary = document.getElementById("wpSummary");
if (wpSummary) wpSummary.value = banDefSummary;
var wpMinoredit = document.getElementById("wpMinoredit");
if (wpMinoredit) wpMinoredit.checked = true;
}
var copyWarn = document.getElementById("editpage-copywarn");
if (copyWarn) copyWarn.style.display = "none";
banList.innerHTML = "<b>Ancres brisées :</b><br />"
for (var i = 0; i < anchors.length; i++) {
banLastPos[i] = 0;
banList.innerHTML += banJSLink(i, anchors[i]) + "<br />";
}
if (selectFirst && anchors.length > 0) {
banSelectAnchor(0, anchors[0]);
}
}
// Vérification d'une page indépendamment du projet
// ************************************************
var banCheckRunning = false;
var banCheckLinks, banCheckBLinks, banCheckArticle, banCheckStatus, banCheckDocSpans;
var banCheckOtherProjects;
function banCheckPage() {
if (banCheckRunning) {
alert("La vérification est déjà en cours");
return;
}
var i = 0, j, k, pageLink;
banCheckLinks = new Array();
banCheckBLinks = new Array();
banCheckArticle = "";
banCheckOtherProjects = 0;
var s = document.getElementById("editform").getElementsByTagName("textarea")[0].value;
while (true) {
i = s.indexOf("[[", i);
if (i == -1) break;
i += 2;
j = s.indexOf("]]", i);
if (j == -1) break;
pageLink = s.substr(i, j - i);
k = pageLink.indexOf("|");
if (k != -1) pageLink = pageLink.substr(0, k);
if (pageLink.indexOf("#") != -1)
banCheckLinks.push(banNormalizeLink(pageLink));
}
if (banCheckLinks.length == 0) {
alert("Cette page ne contient aucun lien ancré");
return;
}
banCheckRunning = true;
banCheckLinks.sort();
banCheckStatus = document.createElement('span');
var p = document.getElementById("MediaWiki-summary");
p.insertBefore(banCheckStatus, p.firstChild);
banCheckNext(0);
}
function banCheckNext(index) {
for (; index < banCheckLinks.length; index++) {
var link = banCheckLinks[index];
if (banExternalLink(link)) {
banCheckOtherProjects++;
continue;
}
if (index > 0 && link == banCheckLinks[index - 1]) continue;
banCheckStatus.innerHTML = "Vérification des liens ancrés en cours... (" + (index + 1) + " / " + banCheckLinks.length + ")<br />";
var sharpPos = link.indexOf("#")
var article = link.substr(0, sharpPos);
if (banCheckArticle != article) {
banCheckArticle = article;
var request = wgServer_ + wgScript_ + '?title=' + encodeURIComponent(article);
//banCheckStatus.innerHTML += request.htmlize() + "<br />";
banAjax.http({url: request, onSuccess: banCheckNextSuccess,
onFailure: banCheckNextFailure, index: index});
return;
}
var linkFound = false;
if (banCheckDocSpans != null) {
var anchor = link.substr(sharpPos + 1);
for (var i = 0; i < banCheckDocSpans.length; i++) {
if (banCheckDocSpans[i].getAttribute("id") == anchor) {
linkFound = true;
break;
}
}
}
if (!linkFound) {
banCheckBLinks.push(link);
}
}
banCheckRunning = false;
banCheckStatus.parentNode.removeChild(banCheckStatus);
alert("Liens ancrés : " + banCheckLinks.length +
"\nLiens brisés distincts : " + banCheckBLinks.length +
"\nLiens interwiki (non vérifiés) : " + banCheckOtherProjects);
if (banCheckBLinks.length == 0) return;
banFormatEditPage(banCheckBLinks, false, false);
}
function banCheckNextSuccess(xmlreq, data) {
if (xmlreq.responseText.length == 0) {
banCheckNextFailure(xmlreq, data);
return;
}
var parser = new DOMParser();
var doc = parser.parseFromString(xmlreq.responseText, 'application/xhtml+xml');
banCheckDocSpans = doc.getElementsByTagName("*");
banCheckNext(data.index);
}
function banCheckNextFailure(xmlreq, data) {
banCheckDocSpans = null;
banCheckNext(data.index);
}
// Chargement selon le type de page
// ********************************
$(function() {
if (wgAction_ == "edit" || wgAction_ == "submit") {
if (document.URL.indexOf(banURLParam) != -1) {
var url = document.URL;
var rabPos = url.indexOf(banURLParam) + banURLParam.length;
var rabEnd = url.indexOf('#', rabPos);
var anchors = decodeURIComponent(url.substr(rabPos, rabEnd - rabPos)).split("|");
banFormatEditPage(anchors, true, true);
}
else {
mw.loader.using( 'mediawiki.util', function() {
mw.util.addPortletLink("p-tb", "javascript:banCheckPage();", "Ancres brisées", "r-ban", "Rechercher les ancres brisées");
} );
}
}
else if (wgAction_ == "view" && banPageInProject()) {
banFormatProjectPage();
}
});