function Richwales_markUsers() {
var users = []
var userLinks = []
var userBlocked = {}
var userToolTips = {}
var userSysops = {}
var userSysopsPlus = {}
var userArbs = {}
var userUnconfirmed = {}
var userEdits = {}
var userStyle = {}
if (!window.mbTempStyle)
mbTempStyle = 'opacity: 0.7; text-decoration: line-through'
if (!window.mbIndefStyle)
mbIndefStyle = 'opacity: 0.4; font-style: italic; text-decoration: line-through'
if (!window.mbTipBoxStyle)
mbTipBoxStyle = 'font-size:smaller; background:#FFFFF0; ' +
'border:1px solid #FEA; padding:0 0.3em; color:#AAA'
if (!window.mbTooltip) {
i18n = {
// 'dsb': '(blokěrowany wót $2 za traśe wót $1: $3)',
'en': '(blocked by $2 with an expiry time of $1: $3)',
// 'eo': '(forbarita de $2 por daŭro de $1: $3)',
// 'hsb': '(zablokowany wot $2 za traće wot $1: $3)',
// 'ja': '($2によるブロック。期限:$1 理由:$3)',
// 'pt': '(bloqueado por $2 até $1: $3)',
// 'ru': '(блокировка $2 на срок $1: $3)',
// 'sv': '(har blockerats av $2 till $1: $3)',
// 'uk': '(блокування $2 на термін $1: $3)'
}
mbTooltip = /* i18n[mw.config.get('wgUserLanguage')] || */ i18n.en
}
appendCSS('.user-blocked-temp {' + mbTempStyle + '}\n' +
'.user-blocked-indef {' + mbIndefStyle + '}\n' +
'.user-blocked-tipbox {' + mbTipBoxStyle + '}\n' +
'.user-not-blocked { }\n' +
'.user-is-unconfirmed { background-color: #ddd }\n' +
'.user-is-new { background-color: #fdd }\n' +
'.user-is-sysop { background-color: #cff }\n' +
'.user-is-sysop-plus { background-color: #cfc }\n' +
'.user-may-be-arb { background-color: #fddd77 }\n' +
'.user-is-ordinary { }\n');
function apiRequest(params, callback) {
var aj = sajax_init_object()
aj.onreadystatechange = function() {
if (aj.readyState != 4 || aj.status != 200) return
callback(eval('(' + aj.responseText + ')'))
}
aj.open('GET', mw.config.get('wgServer') + mw.config.get('wgScriptPath') + '/api.php?format=json&' + params, false)
aj.send('')
}
function target(link) {
var hr = link.href;
if (!hr || hr == '') hr = link.baseURI;
if (hr.match(/&action=edit/) && !hr.match(/&action=edit&redlink=1/)) return '';
hr = hr.replace(/^.*\/(wiki\/|w\/index\.php\?title=)/, '');
hr = hr.replace(/[?&].*$/, '');
hr = hr.replace(/_/g, ' ');
hr = decodeURIComponent(hr);
if (hr.match(/#/)) hr = '';
if (hr.match(/\//) && !hr.match(/Special:Contributions\//)) hr = '';
return hr;
}
function checkLinks(namespaces) {
var content = document.getElementById('content') ||
document.getElementById('mw_content') ||
document.body
var links = content.getElementsByTagName('a')
var ns = namespaces.query.namespaces
var ca
for (var i = 0; i < namespaces.query.specialpagealiases.length; i++) {
if (namespaces.query.specialpagealiases[i].realname == 'Contributions')
ca = namespaces.query.specialpagealiases[i].aliases
}
if (!namespaces.fromcookie) {
document.cookie = 'mbNamespaces='
+ escape([ns[-1]['*'], ns[2]['*'], ns[3]['*'], ca.join('|')].join(':'))
+ '; expires=' + (new Date((new Date).getTime() + Math.exp(20))).toGMTString()
}
// User: User_talk: Special:Contributions/ in canonical form, as they are in hrefs
var isUser = new RegExp('^((' + ns[2]['*'] + '|' + ns[3]['*'] + '):|' + ns[-1]['*'] +
':(' + ca.join('|').replace(/_/g, ' ') + ')\\/)([^\\/#]*)$')
var j = 0
for (i = 0; i < links.length; i++) {
var li = links[i]
var tli = target(li)
if (!tli || tli == '') continue
if (tli.match(isUser)) {
users[j] = tli.replace(isUser, '$4')
userLinks[j++] = li
li.style.opacity = window.mbLoadingOpacity || 0.65 // a way to mark that the data is loading
}
}
if (j == 0) return // nobody to mark
// performing sort and duplicate cleanup, otherwise we risk of some users being marked twice
var usersTemp = users.join('|').split('|')
usersTemp.sort()
var u = []
u[0] = usersTemp[0]
if (usersTemp[1]) {
j = 1
for (i = 1; i < usersTemp.length; i++) {
if (usersTemp[i] != usersTemp[i-1])
u[j++] = usersTemp[i]
}
}
usersTemp = null
for (i = 0; i < links.length; i++)
links[i].style.opacity = '';
// do API requests to find blocked and special users, in batches of no more than about 1000 characters each
var query = ''
for (i = 0; i < u.length; i++) {
query += (query ? '|' : '') + encodeURIComponent(u[i])
if (query.length > 1000) {
apiRequest('action=query&list=users&usprop=groups|editcount&ususers=' + query, findSysops)
apiRequest('action=query&list=blocks&bkprop=user|expiry|by|reason&bkusers=' + query, findBlocked)
query = ''
}
}
// take care of API request for any final, leftover batch of users
if (query) {
apiRequest('action=query&list=users&usprop=groups|editcount&ususers=' + query, findSysops)
apiRequest('action=query&list=blocks&bkprop=user|expiry|by|reason&bkusers=' + query, findBlocked)
}
// mark everyone according to results of API requests
doUserMarking()
}
function findBlocked(ulist) {
if (!ulist || !ulist.query)
return;
var ul = ulist.query.blocks;
if (!ul) return;
for (var i = 0; i < ul.length; i++) {
var u = ul[i]
if (u.expiry) {
var name = u.user
userToolTips[name] = ' ' + mbTooltip.replace('$1', u.expiry.replace(/(.*)T(.*)Z/, '$1 $2 UTC'))
.replace('$2', u.by)
.replace('$3', u.reason)
userBlocked[name] = (u.expiry.substr(0,2) == 'in') ? 'indef' : 'temp'
// alert ('findBlocked: user ' + name + ': blocked (' + userBlocked[name] + ')')
}
}
}
function findSysops(ulist) {
if (!ulist || !ulist.query)
return;
var ul = ulist.query.users;
if (!ul) return;
var name;
for (var i = 0; i < ul.length; i++) {
name = ul[i].name;
var usergroups = [];
var gl = ul[i].groups;
if (gl) {
for (var gi = 0; gi < gl.length; gi++)
usergroups[gl[gi]] = 1;
if (usergroups['sysop'])
userSysops[name] = 1;
if (usergroups['checkuser'] && usergroups['oversight'])
userArbs[name] = 1;
if (usergroups['checkuser'] || usergroups['oversight'] ||
usergroups['steward'] || usergroups['bureaucrat'])
userSysopsPlus[name] = 1;
if (! usergroups['autoconfirmed'] && ! usergroups['confirmed'])
userUnconfirmed[name] = 1;
}
userEdits[name] = ul[i].editcount;
// var alertString = 'findSysops: user ' + name + ': ' + userEdits[name] + ' edits'
// if (userSysops[name]) alertString += '; sysop'
// if (userArbs[name]) alertString += '; arb?'
// if (userSysopsPlus[name]) alertString += '; func'
// if (userUnconfirmed[name]) alertString += '; unconfirmed'
// alert (alertString)
}
}
function doUserMarking() {
var span
for (var i = 0; i < users.length; i++) {
var name = users[i]
if (userStyle[name]) {
userLinks[i].className += userStyle[name]
continue
}
var us = ''
if (userBlocked[name]) {
us += ' user-blocked-' + userBlocked[name]
if (window.mbTipBox) {
span = document.createElement('span')
span.title = name + userToolTips[name]
span.className = 'user-blocked-tipbox'
span.innerHTML = '#'
userLinks[i].parentNode.insertBefore(span, ul)
}
else userLinks[i].title += tips[name]
}
else us += ' user-not-blocked'
if (userArbs[name])
us += ' user-may-be-arb'
else if (userSysopsPlus[name])
us += ' user-is-sysop-plus'
else if (userSysops[name])
us += ' user-is-sysop'
else if (userUnconfirmed[name])
us += ' user-is-unconfirmed'
else if (userEdits[name] < 100)
us += ' user-is-new'
else
us += ' user-is-ordinary'
// alert ('doUserMarking: user ' + name + ': ' + us);
userLinks[i].className += us
userStyle[name] = us
}
}
if (ca = document.getElementById('ca-showblocks'))
ca.parentNode.removeChild(ca)
var cookie = document.cookie.match(/mbNamespaces=(.*?);/)
if (cookie) {
cookie = unescape(cookie[1]).split(':')
checkLinks({
'query': {
'namespaces': { '-1': { '*': cookie[0] }, '2': { '*': cookie[1] }, '3': { '*': cookie[2] } },
'specialpagealiases': [{'realname': 'Contributions', 'aliases': cookie[3].split('|')}]
},
'fromcookie': 1
})
} else {
apiRequest('action=query&meta=siteinfo&siprop=namespaces|specialpagealiases', checkLinks)
}
}
// alert ('hooking Richwales_markUsers')
$(Richwales_markUsers);