User:ARTE/recentrevisionsbox.js
Note: After publishing, you may have to bypass your browser's cache to see the changes.
- Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
- Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
- Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
- Opera: Press Ctrl-F5.
////////////////////////////////////////////////////////////////////////////////
// This script reads the most recent revisions of a page using the MediaWiki API
// and places them in a box in the sidebar above the navigation box.
// The contents of the box become visible after pressing a button.
// For each revision, the edit time followed by the username is listed.
// The tooltip of the username link contains the edit summary.
// You can compare two revisions by successively clicking on their usernames.
// By clicking on the edit time, you can compare the selected revision with the
// previous one.
// In edit mode, any unsaved changes are not lost when the box is operated.
// Anyway, on some projects such as Meta, clicking the Show revisions button
// causes the page to be automatically saved and reloaded. I don't know how to
// work around this yet.
//
// Authors: nl:User:JePe, User:ARTE
function appendButton(divNodeId)
{
var revContent = document.getElementById("recRevContent");
var divNode = revContent.appendChild(document.createElement("div"));
divNode.id = divNodeId;
divNode.style.textAlign = "center";
var button = divNode.appendChild(document.createElement("button"));
button.onclick = loadJsonDoc;
button.style.fontSize = "90%";
button.style.marginTop = ".3em";
button.style.padding = "0 .5em";
return button;
}
function loadDiff(oldid,diffDir)
{
var url = "/w/index.php?title=" + wgPageName;
url += "&diff=" + diffDir;
url += "&oldid=" + oldid;
url += "&diffonly=1&action=render";
if (window.XMLHttpRequest)
{ // native XMLHttpRequest
diffReq = new XMLHttpRequest();
diffReq.onreadystatechange = processDiff;
diffReq.open("GET", url, true);
diffReq.send(null);
}
else if (window.ActiveXObject)
{ // activeX version
diffReq = new ActiveXObject("Microsoft.XMLHTTP");
if (diffReq)
{
diffReq.onreadystatechange = processDiff;
diffReq.open("GET", url, true);
diffReq.send("");
}
}
}
function loadJsonDoc()
{
var url = "/w/api.php?action=query&prop=revisions&format=json";
url += "&pageids=" + wgArticleId + "&rvprop=timestamp|user|comment|ids";
url += "&rvlimit=" + revCount;
if (rvStartId != 0) url += "&rvstartid=" + rvStartId;
if (window.XMLHttpRequest)
{ // native XMLHttpRequest
apiReq = new XMLHttpRequest();
apiReq.onreadystatechange = processReq;
apiReq.open("GET", url, true);
apiReq.send(null);
}
else if (window.ActiveXObject)
{ // activeX version
apiReq = new ActiveXObject("Microsoft.XMLHTTP");
if (apiReq)
{
apiReq.onreadystatechange = processReq;
apiReq.open("GET", url, true);
apiReq.send("");
}
}
}
function makeCloseButton(position)
{
var closeButton = document.createElement("img");
with (closeButton)
{
style.cssFloat = position;
style.styleFloat = position;
style.verticalAlign = "baseline";
style.cursor = "pointer";
title = closeButtonTitle;
src =
"http://upload.wikimedia.org/wikipedia/commons/thumb/8/8d/" +
"No-Symbol.svg/9px-No-Symbol.svg.png";
height = "9";
width = "9";
}
return closeButton;
}
function makeDateControl(date)
{
return (
date.getFullYear() * 10000 +
(date.getMonth() + 1) * 100 +
date.getDate()
);
}
function makeRevisionLinkId(revisionId)
{
return "rrb" + revisionId;
}
function nextRevisions()
{
var button = appendButton("nextButton");
button.innerHTML = buttonNextText;
button.title = buttonNextTitle;
}
function processDiff()
{
if (diffReq.readyState != 4) return;
if (diffReq.status != 200) return;
var bodyContent = document.getElementById("bodyContent");
var diffFrame = document.createElement("div");
diffFrame.id = "revisionsBoxDiff";
diffFrame.innerHTML = diffReq.responseText;
diffTable = diffFrame.getElementsByTagName("table")[0];
if (!diffTable) return;
if (diffTable.className != "diff") return;
diffTable.style.border = "1px solid #ccc";
diffTable.style.width = "100%";
diffTable.style.paddingBottom = ".5em";
diffTable.style.marginBottom = "1em";
diffTable.style.marginTop = ".5em";
var closeButton = makeCloseButton("left");
closeButton.onclick = removeDiff;
var tdNode = diffTable.getElementsByTagName("td");
for (i=0; i < tdNode.length; i++)
{
if (tdNode[i].className == "diff-otitle")
{
tdNode[i].insertBefore(closeButton, tdNode[i].firstChild);
tdNode[i].style.verticalAlign = "top";
}
else if (tdNode[i].className == "diff-ntitle")
tdNode[i].style.verticalAlign = "top";
}
var diffFrameOld = document.getElementById("revisionsBoxDiff");
if (diffFrameOld) diffFrameOld.parentNode.removeChild(diffFrameOld);
bodyContent.parentNode.insertBefore(diffFrame,bodyContent);
window.location.hash = "revisionsBoxDiff";
var prevLink = document.getElementById("differences-prevlink");
if (prevLink)
{
var oldid = prevLink.href.replace(/[\s\S]+&oldid=(\d+)[\s\S]*/, "$1");
prevLink.href = "javascript:loadDiff(" + oldid + ", 'prev')";
}
var nextLink = document.getElementById("differences-nextlink");
if (nextLink)
{
var oldid = nextLink.href.replace(/[\s\S]+&oldid=(\d+)[\s\S]*/, "$1");
nextLink.href = "javascript:loadDiff(" + oldid + ", 'next')";
}
}
function processReq()
{
if (apiReq.readyState != 4) return;
if (apiReq.status != 200) return;
var jsonObj = eval("(" + apiReq.responseText + ")");
var revObj = jsonObj.query.pages[wgArticleId].revisions;
if (revObj) writeResults(revObj);
if (jsonObj["query-continue"])
{
rvStartId = jsonObj["query-continue"].revisions.rvstartid;
nextRevisions();
}
}
function recentRevisions()
{
var revContent = document.getElementById("recRevContent");
if (revContent)
{ // when pressed the close button
prevRevisionId = undefined;
revContent.innerHTML = "";
rvStartId = 0;
dateControl = 99999999;
}
else
{
var navigationBox = document.getElementById('p-navigation');
var revBox = document.createElement("div");
var revBox =
navigationBox.parentNode.insertBefore(
document.createElement("div"),
navigationBox
);
revBox.id = "p-rev";
revBox.className = "portlet";
var h5Node = revBox.appendChild(document.createElement("h5"));
h5Node.innerHTML = revBoxTitle;
revContent = revBox.appendChild(document.createElement("div"));
revContent.id = "recRevContent";
revContent.className = "pBody";
revContent.style.padding = "0 .3em .3em .3em";
revContent.style.lineHeight = "1.2em";
revContent.style.fontFamily = "Verdana, sans-serif";
}
var button = appendButton("showButton");
button.innerHTML = buttonBeginText;
}
function removeDiff()
{
var diffFrame = document.getElementById("revisionsBoxDiff");
if (diffFrame) diffFrame.parentNode.removeChild(diffFrame);
}
function revisionClicked(revisionId)
{
if (prevRevisionId == undefined)
{
var aNodeUser = document.getElementById(makeRevisionLinkId(revisionId));
aNodeUser.style.color = "#f00";
aNodeUser.style.textDecoration = "underline";
prevRevisionId = revisionId;
}
else
{
var aNodeUser =
document.getElementById(makeRevisionLinkId(prevRevisionId));
aNodeUser.style.color = "";
aNodeUser.style.textDecoration = "";
if (prevRevisionId < revisionId)
loadDiff(prevRevisionId, revisionId);
else if (revisionId < prevRevisionId)
loadDiff(revisionId, prevRevisionId);
prevRevisionId = undefined;
}
}
function writeResults(revObj)
{
var showButton = document.getElementById('showButton');
var nextButton = document.getElementById('nextButton');
var revContent = document.getElementById("recRevContent");
if (showButton)
{
showButton.parentNode.removeChild(showButton);
var closeButton = makeCloseButton("right");
closeButton.onclick = recentRevisions;
closeButton.style.marginTop = ".3em";
revContent.appendChild(closeButton);
}
if (nextButton) nextButton.parentNode.removeChild(nextButton);
var date = new Date();
var dateNow = makeDateControl(date);
for (i = 0; i < revObj.length; i++)
{
var rev = revObj[i];
var time = rev.timestamp;
var year = time.replace(/^(\d\d\d\d)[\s\S]+/, "$1");
var month = time.replace(/^\d\d\d\d-(\d\d)[\s\S]+/, "$1");
var day = time.replace(/^\d\d\d\d-\d\d-(\d\d)[\s\S]+/, "$1");
var hours = time.replace(/[\s\S]+T(\d\d)[\s\S]+/, "$1");
var minutes = time.replace(/[\s\S]+T\d\d:(\d\d)[\s\S]+/, "$1");
date.setUTCFullYear(year, month - 1, day);
date.setUTCHours(hours, minutes);
var dateRevision = makeDateControl(date);
if (dateRevision < dateControl)
{
var divNodeDate =
revContent.appendChild(document.createElement("div"));
divNodeDate.style.fontSize = "95%";
divNodeDate.style.marginTop = ".3em";
divNodeDate.style.fontWeight = "bold";
divNodeDate.style.paddingLeft = ".5em";
divNodeDate.innerHTML =
date.getDate() + " " + monthName[date.getMonth()];
if (dateNow - dateRevision > 10000)
divNodeDate.innerHTML += " " + date.getFullYear();
dateControl = dateRevision;
}
var divNode = revContent.appendChild(document.createElement("div"));
divNode.style.marginLeft = "1em";
divNode.style.textIndent = "-1em";
divNode.style.fontSize = "95%";
divNode.style.marginTop = ".3em";
var aNodeTime = divNode.appendChild(document.createElement("a"));
aNodeTime.innerHTML =
(date.getHours() < 10) ? "0" + date.getHours() : date.getHours();
aNodeTime.innerHTML += ":";
aNodeTime.innerHTML +=
(date.getMinutes() < 10) ?
"0" + date.getMinutes() : date.getMinutes();
aNodeTime.style.fontSize = "90%";
aNodeTime.href = "javascript:loadDiff(" + rev.revid + ", 'prev')";
aNodeTime.title = timeTitle;
divNode.appendChild(document.createTextNode(" "));
var aNodeUser = divNode.appendChild(document.createElement("a"));
aNodeUser.id = makeRevisionLinkId(rev.revid);
aNodeUser.innerHTML = rev.user;
aNodeUser.title = rev.comment ? rev.comment.replace(/\\\//g, "/") : "";
aNodeUser.href = "javascript:revisionClicked(" + rev.revid + ")";
}
}
var prevRevisionId;
var diffReq;
var apiReq;
var rvStartId = 0;
var revCount = 20; // max 50, higher numbers not possible, they give an error
var dateControl = 99999999; // must only be higher than today (yyyymmdd)
if (wgUserLanguage == "de")
{
var timeTitle = "Unterschied zur vorherigen Version";
var closeButtonTitle = "Schließen";
var revBoxTitle = "Neuere Versionen";
var buttonBeginText = "Versionen zeigen";
var buttonNextText = "Folgende " + revCount;
var buttonNextTitle = "Folgende " + revCount + " Versionen zeigen";
var monthName = [
"Januar", "Februar", "März", "April", "Mai", "Juni",
"Juli", "August", "September", "Oktober", "November", "Dezember"
];
}
else if (wgUserLanguage == "it")
{
var timeTitle = "Differenze dalla versione precedente";
var closeButtonTitle = "Chiudi";
var revBoxTitle = "versioni recenti";
var buttonBeginText = "Mostra versioni";
var buttonNextText = "Successive " + revCount;
var buttonNextTitle = "Mostra le " + revCount + " versioni successive";
var monthName = [
"gennaio", "febbraio", "marzo", "aprile", "maggio", "giugno",
"luglio", "agosto", "settembre", "ottobre", "novembre", "dicembre"
];
}
else if (wgUserLanguage == "nl")
{
var timeTitle = "Verschillen met de vorige bewerking";
var closeButtonTitle = "Sluiten";
var revBoxTitle = "recente bewerkingen";
var buttonBeginText = "Toon bewerkingen";
var buttonNextText = "Volgende " + revCount;
var buttonNextTitle = "Toon de volgende " + revCount + " bewerkingen";
var monthName = [
"januari", "februari", "maart", "april", "mei", "juni",
"juli", "augustus", "september", "oktober", "november", "december"
];
}
else
{
var timeTitle = "Differences with the previous revision";
var closeButtonTitle = "Close";
var revBoxTitle = "recent revisions";
var buttonBeginText = "Show revisions";
var buttonNextText = "Next " + revCount;
var buttonNextTitle = "Show the next " + revCount + " revisions";
var monthName = [
"January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"
];
}
if (wgNamespaceNumber >= 0) addOnloadHook(recentRevisions);