User:Kephir/gadgets/hollis.js
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
"use strict"; // <nowiki>
/*jshint shadow:true, scripturl:true, loopfunc:true, latedef:true, undef:true */
/*global mw, jQuery */
(function(){
function el(tag, child, attr, events) {
var node = document.createElement(tag);
if (child) {
if (typeof child !== 'object')
child = [child];
for (var i = 0; i < child.length; ++i) {
var ch = child[i];
if ((ch === void(null)) || (ch === null) || (ch === false))
continue;
else if (typeof ch !== 'object')
ch = document.createTextNode(String(ch));
node.appendChild(ch);
}
}
if (attr) for (var key in attr) {
node.setAttribute(key, String(attr[key]));
}
if (events) for (var key in events) {
node.addEventListener(key, events[key], false);
}
return node;
}
if ((window.wgCanonicalSpecialPageName === "Watchlist") && !mw.user.options.get('extendwatchlist') && !window.kephirHollisLeaveWatchlistAlone)
mw.loader.using(['mediawiki.api', 'mediawiki.user', 'mediawiki.Title', 'mediawiki.Uri'], function () {
var api = new mw.Api();
var chlist = document.getElementsByClassName('mw-changeslist')[0];
var titles = chlist.getElementsByClassName('mw-title');
var titlemap = {};
var hideopts = {
bot: Number(mw.util.getParamValue('hideBots') || mw.user.options.get('watchlisthidebots')),
ano: Number(mw.util.getParamValue('hideAnons') || mw.user.options.get('watchlisthideanons')),
liu: Number(mw.util.getParamValue('hideLiu') || mw.user.options.get('watchlisthideliu')),
own: Number(mw.util.getParamValue('hideOwn') || mw.user.options.get('watchlisthideown')),
pat: Number(mw.util.getParamValue('hidePatrolled') || mw.user.options.get('watchlisthidepatrolled')),
min: Number(mw.util.getParamValue('hideMinor') || mw.user.options.get('watchlisthideminor')),
};
for (var i = 0; i < titles.length; ++i) {
var links = titles[i].parentNode.getElementsByTagName('a');
for (var j = 0; j < links.length; ++j) {
var href = new mw.Uri(links[j].href);
if (href.query.oldid && href.query.diff) {
titlemap[String(parseInt(href.query.diff, 10))] = links[j];
break;
}
}
}
function makeLink(title, pageid, revid, oldid) {
return mw.util.getUrl(title, { "curid": pageid, "diff": revid, "oldid": oldid });
}
function prepareLink(link, ready) {
if (!/^javascript/.test(link.href))
return;
if (link.busy)
return;
link.busy = true;
api.get({
action: 'query',
pageids: link.pageinfo.pageid,
prop: 'revisions',
rvprop: 'ids',
rvstart: link.pageinfo.notificationtimestamp,
// rvstartid: link.pageinfo.old_revid,
rvdir: 'older',
rvlimit: 2
}, {
success: function (result) {
if (result.error) {
link.href = 'javascript:void("API_ERROR_WHILE_ACQUIRING_LINK:CODE=' + result.error.code + '");';
link.busy = false;
console.error(result.error);
return;
}
var revs = result.query.pages[link.pageinfo.pageid].revisions;
link.href = makeLink(link.pageinfo.title, link.pageinfo.pageid, link.pageinfo.revid, (revs[1] || revs[0]).revid);
},
error: function () {
link.href = 'javascript:void("ERROR_WHILE_ACQUIRING_LINK");';
link.style.opacity = '0.5';
link.busy = false;
console.error(arguments);
}
});
}
var havePatrol = false;
function grabWatchlist(cont) {
var query = {
action: 'query',
list: 'watchlist',
wlprop: 'ids|title|timestamp|notificationtimestamp' + (havePatrol ? '|patrol' : ''), // why does it have to error? could the API not just ignore wlprop=patrol?
wltype: 'edit',
wlshow: ''
};
if (hideopts.own) query.wlexcludeuser = mw.config.get('wgUserName');
if (hideopts.bot) query.wlshow += '|!bot';
if (hideopts.ano) query.wlshow += '|!anon';
if (hideopts.liu) query.wlshow += '|anon';
if (hideopts.min) query.wlshow += '|!minor';
if (cont) {
for (var key in cont) {
query[key] = cont[key];
}
}
api.get(query, {
success: function (result) {
for (var i = 0; i < result.query.watchlist.length; ++i) {
var item = result.query.watchlist[i];
if (!titlemap[String(item.revid)])
if (hideopts.pat && ('patrolled' in item))
continue;
else
return; // we seem to have reached the end.
if (!item.notificationtimestamp) // seen it. skip.
continue;
var seenlink;
if (item.notificationtimestamp !== item.timestamp) {
seenlink = el('a', ['since last seen'], {
"href": 'javascript:void("PLEASE_WAIT_AND_TRY_AGAIN");'
}, {
"mouseover": function () {
prepareLink(this);
},
"mousedown": function () {
prepareLink(this);
},
"click": function () {
prepareLink(this, function (href) {
location.href = href;
});
}
});
seenlink.pageinfo = item;
} else {
if (!window.kephirHollisShowRedundant)
continue;
seenlink = el('a', ['since last seen'], {
"href": makeLink(item.title, item.pageid, item.revid, item.oldid)
});
}
var difflink = titlemap[String(item.revid)];
difflink.parentNode.insertBefore(seenlink, difflink);
difflink.parentNode.insertBefore(document.createTextNode('\xa0| '), difflink);
}
if (!('batchcomplete' in result))
grabWatchlist(result["continue"]);
}
});
}
if (hideopts.pat)
mw.user.getRights(function (rights) {
havePatrol = (rights.indexOf("patrol") !== -1);
grabWatchlist();
});
else
grabWatchlist();
});
else if (mw.util.getParamValue('diff') && mw.util.getParamValue('diff') && document.getElementsByClassName('diff-multi').length && !window.kephirHollisLeaveDiffsAlone)
mw.loader.using(['mediawiki.api', 'mediawiki.user', 'mediawiki.Title', 'mediawiki.Uri', 'mediawiki.language.months'], function () {
var haveRevdel = false;
var haveBlock = false;
function fmtDate(date) {
// XXX: uses browser's time zone instead of preferences
date = new Date(date);
switch (mw.user.options.get('date')) {
case 'dmy' : return date.toLocaleTimeString() + ', ' + date.getDate() + ' ' + mw.language.months.genitive[date.getMonth()] + ' ' + date.getFullYear();
case 'mdy' : return date.toLocaleTimeString() + ', ' + mw.language.months.genitive[date.getMonth()] + ' ' + date.getFullYear() + ', ' + date.getDate();
case 'ymd' : return date.toLocaleTimeString() + ', ' + date.getFullYear() + ' ' + mw.language.months.genitive[date.getMonth()] + ' ' + date.getDate();
case 'default' : return date.toLocaleFormat();
case 'ISO 8601': return date.toISOString();
}
}
var api = new mw.Api();
var linkwrap, linklabel, revsform;
var dm = document.getElementsByClassName('diff-multi')[0]; // XXX: better detection
dm.appendChild(linkwrap = el('span', [
'\xa0[',
el('a', [linklabel = document.createTextNode('show list')], {
"href": 'javascript:void(window.warranty);'
}, {
"click": function (ev) {
if (!revsform)
mw.user.getRights(function (rights) {
haveRevdel = (rights.indexOf("deleterevision") !== -1);
haveBlock = (rights.indexOf("block") !== -1);
var lower = Number(mw.util.getParamValue('oldid'));
var hiher = Number(mw.util.getParamValue('diff'));
if (hiher < lower) {
var t = lower;
lower = hiher;
hiher = t;
}
var revstab;
revsform = el('form', [
el('input', null, { type: "submit", value: "View difference" }),
' ',
haveRevdel && el('button', ["Change visibility"], { type: "submit", name: "action", value: "revisiondelete" }),
revstab = el('table', null, {
"class": "wikitable", // XXX
"style": "text-align: left; margin: 0.5em auto;"
}),
el('input', null, { type: "submit", value: "View difference" }),
' ',
haveRevdel && el('button', ["Change visibility"], { type: "submit", name: "action", value: "revisiondelete" }),
], { action: mw.config.get('wgScript'), style: "display: none; margin: 0.5em auto;" });
revstab.appendChild(el('tr', [
el('th', ['#']),
el('th', ['←']),
el('th', ['→']),
el('th', ['Timestamp']),
el('th', ['Author']),
el('th', ['Summary'])
]));
linkwrap.parentNode.appendChild(revsform);
var k = 0;
function grabHistory(cont) {
var query = {
action: 'query',
pageids: mw.config.get('wgArticleId'),
prop: 'revisions',
rvprop: 'ids|parsedcomment|user|timestamp|tags|size|flags',
rvstartid: hiher,
rvendid: lower,
rvdir: 'older',
rvlimit: 'max',
'continue': ""
};
if (cont) {
for (var key in cont) {
query[key] = cont[key];
}
}
api.get(query, {
success: function (result) {
var wgPageName = mw.config.get('wgPageName');
if (result.error) {
mw.util.jsMessage('<b>API error</b>: ' + result.error.info + ' [code: <code>' + result.error.code + '</code>]');
return;
}
var revs = result.query.pages[mw.config.get('wgArticleId')].revisions;
for (var j = 0; j < revs.length; ++j) {
var rev = revs[j];
var sumcell;
var row = el('tr', [
el('td', [k++]),
el('td', [el('input', null, { type: "radio", value: rev.revid, name: "oldid" })]),
el('td', [el('input', null, { type: "radio", value: rev.revid, name: "diff" })]),
el('td', [
haveRevdel && el('input', null, { type: "checkbox", name: "ids[" + rev.revid + "]", value: "1" }), ' ',
el('a', [fmtDate(rev.timestamp)], {
href: mw.util.getUrl(mw.config.get('wgPageName'), { "oldid": rev.revid })
}), el('br'), el('small', [
el('a', ['diff to prev'], { href: mw.util.getUrl(mw.config.get('wgPageName'), { "oldid": rev.revid, "diff": "prev" }) }),
' \u2022 ',
el('a', ['next'], { href: mw.util.getUrl(mw.config.get('wgPageName'), { "oldid": rev.revid, "diff": "next" }) }),
' \u2022 ',
el('a', ['edit'], { href: mw.util.getUrl(mw.config.get('wgPageName'), { "oldid": rev.revid, "action": "edit" }) }),
])
]),
el('td', [
el('a', [rev.user], { href: mw.util.getUrl('User:' + rev.user) }), el('br'),
el('small', [
el('a', ['talk'], { href: mw.util.getUrl('User talk:' + rev.user) }),
' \u2022 ',
el('a', ['contribs'], { href: mw.util.getUrl('Special:Contributions/' + rev.user) }),
haveBlock && ' \u2022 ',
haveBlock && el('a', ['block'], { href: mw.util.getUrl('Special:Block/' + rev.user) }),
])
]),
sumcell = el('td')
]);
sumcell.innerHTML = rev.parsedcomment;
revstab.appendChild(row);
}
if (result.continue)
grabHistory(result['continue']);
},
error: function () {
mw.util.jsMessage('<b>Request error</b>. Details sent to console.');
console.error(arguments);
}
});
}
grabHistory();
});
if (revsform.style.display === 'none') {
linklabel.data = 'hide list';
revsform.style.display = '';
} else {
linklabel.data = 'show list';
revsform.style.display = 'none';
}
}
}), ']'
]));
});
})();