const historyJump_regexpOldid = new RegExp('\\&(amp;)?oldid\\=(\\d+)');
const historyJump_regexpDiff = new RegExp('\\&diff=(\\d+)');
const historyJump_regexpRevisionCount = new RegExp('\\((One|\\d+) intermediate revisions? by (one|\\d+|more than \\d+) users? not shown\\)');
const historyJump_regexpUnderscore = new RegExp('[_]', 'g');
const historyJump_regexpIso8601Char = new RegExp('[-T:Z]', 'g');
// options
var historyJump_replaceHistoryTab; // if relevant, hide and replace History tab
if (historyJump_replaceHistoryTab === undefined) historyJump_replaceHistoryTab = false;
var historyJump_alwaysDefaultDiff; // assume default range from revId1 to revId2, skip options
if (historyJump_alwaysDefaultDiff === undefined) historyJump_alwaysDefaultDiff = true;
var historyJump_minRevCount; // minimum number of revisions to display
if (historyJump_minRevCount === undefined) historyJump_minRevCount = 10;
// extracted from URL or body
var historyJump_revIds;
var historyJump_revCount;
// fetched from API
var historyJump_revIdToTimestamp;
function historyJump_showForm() {
if (!wfSupportsAjax()) {
jsMsg('<span class="error">Your browser does not seem to support AJAX, which is required for the historyJump script.</span>');
return;
}
form = '<div id="historyJump_initialform">'+
"<strong><a id='historyJump_link'>Relevant history</a></strong>" +
'</div>';
jsMsg(form);
document.getElementById('historyJump_link').href = historyJump_calculateLink(historyJump_minRevCount);
}
function historyJump_getRevIdsFromUrl(url) {
var revIds = new Array();
match = historyJump_regexpOldid.exec(url);
if (match != null) {
revIds.push(match[2]);
}
match = historyJump_regexpDiff.exec(url);
if (match != null) {
revIds.push(match[1]);
}
return revIds;
}
function historyJump_getRevIdsFromDocument() {
var revIds = new Array();
eo = document.getElementById('mw-diff-otitle1');
if (eo != null) {
match = historyJump_regexpOldid.exec(eo.innerHTML);
if (match != null) {
revIds.push(match[2]);
}
}
en = document.getElementById('mw-diff-ntitle1');
if (en != null) {
match = historyJump_regexpOldid.exec(en.innerHTML);
if (match != null) {
revIds.push(match[2]);
}
}
return revIds;
}
/*
* For permanent links and diffs, false indicates cross-page diff.
* Special pages will usually return false.
*/
function comparePageNameAndFirstHeading() {
return wgPageName.replace(historyJump_regexpUnderscore, ' ') == document.getElementById('firstHeading').lastChild.innerHTML;
}
function historyJump_calculateRevCount() {
if (historyJump_revIds.length == 2) {
if (historyJump_revIds[0] == historyJump_revIds[1]) {
return 1;
}
if (!comparePageNameAndFirstHeading()) {
// cross-page diff
return -1;
}
body = document.getElementById('bodyContent');
if (body != null) {
match = historyJump_regexpRevisionCount.exec(body.innerHTML);
if (match != null) {
var count;
if (match[1] == "One") {
count = 1;
} else {
count = Number(match[1]);
}
return count + 2; // exclusive
}
}
return 2; // adjacent revisions
}
return -1; // not known, usually a permanent link
}
function historyJump_injectDiffRangeLink() {
if (historyJump_revCount <= 2) {
return false;
}
body = document.getElementById('bodyContent');
if (body != null) {
match = historyJump_regexpRevisionCount.exec(body.innerHTML);
if (match != null) {
body.innerHTML = body.innerHTML.replace(match[0], '<a id="historyJump-diffrange">' + match[0] + '</a>');
var dr = document.getElementById('historyJump-diffrange');
dr.title = 'Show history range';
dr.href = historyJump_calculateLink(0);
return true;
}
}
return false;
}
function historyJump_calculateLink(minRevCount) {
var minTs = Number.MAX_VALUE;
for (i = 0; i < historyJump_revIds.length; i++) {
ts = historyJump_revIdToTimestamp[historyJump_revIds[i]];
if (ts < minTs)
minTs = ts;
}
minTs -= 1; // exclusive
return wgScriptPath + '/index.php?title=' + encodeURIComponent(mw.config.get('wgPageName')) +
'&dir=prev&offset=' + minTs +
'&limit=' + Math.max(historyJump_revCount, minRevCount) + '&action=history';
}
function stripIso8601Formatting(dateIso) {
return Number(dateIso.replace(historyJump_regexpIso8601Char, ''));
}
function historyJump_getTimestamps(revIds) {
var revIdToTimestamp = new Object();
if (revIds.length == 0) {
return revIdToTimestamp;
}
revIdStr = '';
for (i = 0; i < revIds.length; i++) {
revIdStr += revIds[i] + '|';
}
revIdStr = revIdStr.substring(0, revIdStr.length-1);
var req = sajax_init_object();
req.open("GET", wgScriptPath + "/api.php?action=query&prop=revisions&rvprop=ids|timestamp&format=json&revids="+revIdStr, false);
req.send(null);
var response = eval('(' + req.responseText + ')');
var pages = response['query']['pages'];
var pageCount = 0;
for (var pageId in pages) {
pageCount++;
revisions = pages[pageId]['revisions'];
for (j = 0; j < revisions.length; j++) {
revIdToTimestamp[revisions[j]['revid']] = stripIso8601Formatting(revisions[j]['timestamp']);
}
}
revIdToTimestamp['pageCount'] = pageCount;
delete req;
return revIdToTimestamp;
}
function historyJump_testAndAddLink() {
historyJump_revIds = historyJump_getRevIdsFromUrl(document.URL);
if (historyJump_revIds.length < 2) {
var revIds = historyJump_getRevIdsFromDocument();
if (historyJump_revIds.length < revIds.length) {
historyJump_revIds = revIds;
}
}
historyJump_revCount = historyJump_calculateRevCount();
if (historyJump_revIds.length > 0) {
historyJump_revIdToTimestamp = historyJump_getTimestamps(historyJump_revIds);
nextnode = null;
if (historyJump_replaceHistoryTab) {
// disable, hide History tab
historyTab = document.getElementById('ca-history');
historyTab.disabled = true;
historyTab.style.display = 'none';
nextnode = historyTab.nextSibling;
}
var link;
if (historyJump_revCount > 0) {
// historyJump_alwaysDefaultDiff disabled
historyJump_injectDiffRangeLink();
}
if (link === undefined)
link = "javascript:historyJump_showForm()";
mw.util.addPortletLink("p-cactions", link, "History Jump", "ca-historyJump", "Jump to relevant history", null, nextnode);
}
}
addOnloadHook(historyJump_testAndAddLink);