Участник:Afinogenoff/logpage.js
Перейти к навигации
Перейти к поиску
Замечание: Чтобы после сохранения вступили в силу изменения стилей, перезагрузите файл //traditio.wiki/w/load.php?debug=false&lang=ru&modules=site&only=styles&skin=vector&*, если используете скин Vector, или //traditio.wiki/w/load.php?debug=false&lang=ru&modules=site&only=styles&skin=common&*, если используете скин Common.
Чтобы вступили в силу изменения скриптов, перезагрузите файл //traditio.wiki/w/load.php?debug=false&lang=ru&modules=site&only=scripts&skin=vector&*, если используете скин Vector, или //traditio.wiki/w/load.php?debug=false&lang=ru&modules=site&only=scripts&skin=common&*, если используете скин Common.
Гаджеты и импортируемые скрипты загружаются отдельными файлами.
//To do: add "moved over redirect" case
var logPage = new function(){
var imcomm = 'http://upload.wikimedia.org/wikipedia/commons/'
var imuser = '/skins-1.5/monobook/user.gif'
var m = {
//Mediawiki messages: considered default for IP blocks
mwAnonOnly: 'anon. only', //considered default for IP blocks
mwNoReg: 'account creation blocked', //considered default
//Mediawiki messages: considered unusual for user blocks
mwNoAuto: 'autoblock disabled',
mwNoEmail: 'e-mail blocked',
//output messages
NotAnonOnly: ' <span title="Registered users also blocked">'
+ '<img src='+imcomm+'thumb/c/cc/Nuvola_apps_kdmconfig.png/15px-Nuvola_apps_kdmconfig.png>'
+ '</span>',
YesReg: '<span title="Registration is ok"><img src='+imuser+'></span>',
NoAuto: '<s>autoblock</s>',
NoEmail: '<img src='+imcomm+'thumb/3/3e/Email_delete.png/12px-Email_delete.png>',
NewUserLog: 'account creation log',
ShowTable: '[Смотреть таблицу]',
ShowList: '[Смотреть список]'
}
var type, user, ul, lis, logTable, logLink, tbody, isTable = false
this.onLoad = function(){
//get page structure
var content = document.getElementById('content')
ul = content.getElementsByTagName('ul')[0]
if (!ul) return //log is empty
//create switching link
logLink = document.createElement('a')
logLink.href = 'javascript:logPage.switchTable()'
logLink.style.marginLeft = '10px'; logLink.style.fontSize = '85%'
//attach switching link
var pp = ul
while ((pp=pp.previousSibling) && pp.nodeName!='P');
pp.appendChild(logLink)
//create table
lis = ul.getElementsByTagName('li')
if (window.logMaxRows && lis.length > logMaxRows) isTable = true //surpress creation if too many rows
logPage.switchTable()
}
this.switchTable = function(){
if (isTable){
ul.style.display = 'block'
if (logTable) logTable.style.display = 'none'
logLink.innerHTML = m.ShowTable
}else{
if (!logTable) createTable()
ul.style.display = 'none'
logTable.style.display = 'block'
logLink.innerHTML = m.ShowList
}
isTable = !isTable
}
function createTable(){
if (!window.logDateIn) logDateIn = /(\d\d:\d\d), (\d\d?) (\S\S\S)\S* (\d\d\d\d)/
if (!window.logDateOut) logDateOut = '$1 $2 $3'
if (!window.logBlDivider) logBlDivider = '<br>'
logPageCSS = '.logcomment div {overflow:auto} .logtime {width:15px}' + (window.logPageCSS?logPageCSS:'')
addCSS(logPageCSS)
if (type = document.URL.match(/&type=([^&]+)/)) type = type[1] //"move", "block", etc. or just empty
if (user = document.URL.match(/&user=([^&]+)/)) user = document.getElementById('user').value
tbody = '<tr>'
+'<th><img src=' + imcomm + 'thumb/a/af/Relogio07_15.svg/15px-Relogio07_15.svg.png></th>'
+'<th width=10px> </th>'
+'<th><img src=' + imcomm + '/3/3c/A_help_text.gif></th>'
if (user) //no need for user column
tbody = '<tr><td colspan=4 style="padding-left:20%"><img src='+imuser+'>: '+user.replace(/\+/,' ')+'</td></tr>'+tbody
else
tbody += '<th><img src=' + imuser + '></th>'
tbody += '<th><img src=' + imcomm + '8/80/Icons-mini-comment_blue.gif></th></tr>'
//parse entries
for (var i=0; i<lis.length; i++){
tbody +='<tr>'
parseRow(lis[i].innerHTML)
tbody +='</tr>'
}
//insert table
logTable = document.createElement('div')
logTable.innerHTML = '<table class=wikitable width=100% id=logTable>' + tbody + '</table>'
ul.parentNode.insertBefore(logTable, ul)
//sortables_init() //unfortunately sorting shows some error
}
function parseRow(row){
var icon='', when, what, who, comment='', ma, word, lastLink='', optional='', until='', trstyle=''
var whatTooltip = '' // !!! do we still need this
//extract date, user and userlinks (talk | cotrib | block)
ma = row.match(/([^<]+)(<a.+?>) (\(<a.+?<\/a>\)) /i) //date, user and user links
when = ma[1]
who = ma[2]
row = row.substring(ma[0].length) //get the rest
if (!window.logNoUserLinks) //add talk/contib links
who += ' ' + ma[3].replace(/>(.)(.*?)</g, '>$1<').replace(/> </,'> <') //shorten into (t | c | b)
//possibly get a link at the end
if (ma = row.match(/\((<a[^<]+<\/a>)\) ?$/i)){
lastLink = ma[1]
row = row.substring(0, row.length - ma[0].length)
}
//possibly get a comment at the end
if (ma = row.match(/<span class="?comment"?>\((.*)\)<\/span> ?$/i)){
comment = ma[1]
row = row.substring(0, row.length - ma[0].length)
}
//get the «action» word
//ma = row.match(/^[a-zA-Z]+/) //everything before link or quotes
ma = row.match(/^[^"<«#]+/) //everything before link or quotes
if (ma) word = ma[0].replace(/\s+$/, '') //trim spaces at the end
what = row //just in case and for default in switch
//workaround: some weird characted at the end of this string
if (row.length < 20) word = 'New user account'
switch (word){
case 'marked':
what = row.match(/<a.+<\/a>/i)[0]
putIcon('thumb/7/73/U2713.svg/10px-U2713.svg.png')
break
case 'deleted':
what = row.match(/<a[^<]+<\/a>/i)[0]
putIcon('thumb/0/0b/Cancel.png/10px-Cancel.png')
break
case 'restored':
what = row.match(/<a[^<]+<\/a>/i)[0]
putIcon('thumb/a/a7/Add.png/10px-Add.png')
if (type == 'delete') trstyle = ' style="background-color:#EEFFEE"'
break
case 'uploaded a new version of':
optional = ' <small>(version)</small>'
case 'uploaded':
what = getShortLink() + optional
putIcon('thumb/c/cc/Icons-mini-image.gif/15px-Icons-mini-image.gif')
break
case 'New user account':
putIcon(imuser)
what = putUser(who)
who = ''
break
case 'created new account':
case 'created account for':
putIcon(imuser)
ma = row.match(/(<a.+?>) (.+)/i)
what = ma[1] + ma[2].replace(/>(.)(.*?)</g, '>$1<')
if (type == 'newusers') trstyle = ' style="background-color:#FFEEEE"'
break
case 'changed protection level for':
optional = ' <i>('+word.split(' ')[0] + ')</i>'
case 'protected':
what = getLink()
if (ma = comment.match(/\(\S+ (.+? \(UTC\))\)$/)){ //expiration date
until = '<small> / ' + ma[1] + '</small>'
//period = getPeriod(when, until)
comment = comment.replace(ma[0],'')
}
ma = comment.match(/\[(edit=[a-z]+)?:?(move=[a-z]+)?\]/) //protect options
if (ma[0].indexOf('sysop') != -1) //is sysop protection at all
putIcon('thumb/5/59/Padlock.svg/20px-Padlock.svg.png')
else
putIcon('thumb/f/fa/Padlock-silver-medium.svg/20px-Padlock-silver-medium.svg.png') //gray
var opt = ma[1] ? ( (ma[1].indexOf('sysop')!=-1) ? 'sysop' : 'anon') : ''
opt += ' / '
opt += ma[2] ? ( (ma[2].indexOf('sysop')!=-1) ? 'sysop' : 'anon') : ''
comment = opt + optional + ' ' + until + '<br>' + comment.replace(ma[0],'')
break
case 'unprotected':
what = getLink()
putIcon('thumb/d/df/Close_me_please.png/15px-Close_me_please.png')
if (type == 'protect') trstyle = ' style="background-color:#EEFFEE"'
break
case 'blocked':
putIcon('thumb/4/4f/Blocked_user.svg/18px-Blocked_user.svg.png')
var opt = '', length
//get user and user links
ma = row.match(/.*(<a.+?>) \((<a.+?>)\)(.+)$/i)
if (!ma) { what = row.substring(word.length + 1); break }
var blockedLink = ma[1]
var talkContribLinks = ma[2]
var blockedUser = blockedLink.match(/>(.+?)<\/a>/i)[1]
row = ma[3]
//get options
var options = row.match(/\(.*\)/)[0]
//get period
ma = row.match(/<span .*>(.+)<\/span>/i)
if (ma) length = ma[1]
else length = row.match (/\d+ \S+/)[0] //custom length without span, then it always starts with a number
what = blockedLink+' <small>('+talkContribLinks.replace(/>(.)(.*?)</g, '>$1<')+')</small>'
if (options.indexOf(m.mwNoReg) == -1) opt += m.YesReg //registration is allowed
if (blockedUser.match(/^\d\d?\d?\.\d\d?\d?\.\d\d?\d?\.\d\d?\d?/)) {//IP block
//what += ' style="background-color:white"'
if (blockedUser.match(/\/\d\d?$/)) what = '<b>'+what+'</b>' //range block
if (options.indexOf(m.mwAnonOnly) == -1) opt += m.NotAnonOnly //registered users blocked too
}else{ //user block
what += ' <small>(<a title="' + m.NewUserLog + '" href="/w/index.php?title=Special:Log&type=newusers&user=' +encodeURIComponent(blockedUser) + '">?</a>)</small>'
if (options.indexOf(m.mwNoAuto) != -1)
opt += ' <span title="' + m.mwNoAuto + '">'+ m.NoAuto + '</span>'
if (options.indexOf(m.mwNoEmail) != -1)
opt += ' <span title="' + m.mwNoEmail + '">' + m.NoEmail + '</span>'
}
opt = '<small title="'+options+'">'+opt+'</small>'
what += logBlDivider + length + ' ' + opt
//' <span style="white-space:nowrap" title="' + options + '">' + '</span>'
//reason = reason.replace(/<span class="comment">\(/,'').replace(/\)<\/span>/,'') //remove ()
break
case 'unblocked':
putIcon('thumb/2/23/Nuvola_apps_edu_languages.svg/20px-Nuvola_apps_edu_languages.svg.png')
if (type == 'block') trstyle = ' style="background-color:#EEFFEE"'
if (ma = row.match(/(<a.+?>) (\(<a.+?<\/a>\))/i)) //date, user and user links; otherwise it's "unlocked #7773"
what = ma[1] + ' <small>' + ma[2].replace(/>(.)(.*?)</g, '>$1<') + '</small>' //shorten into (t | c | b)
break
case 'moved':
ma = row.match(/<a[^<]+<\/a>/ig)
what = ma[0] + '<br>' + ma[1]
icon = '→'
break
// !!! over redirect
//bot status
case 'granted bot status to':
putIcon('thumb/5/53/Kgpg_key1.png/15px-Kgpg_key1.png')
what = 'bot: ' + getShortLink()
break
case 'removed bot status from':
putIcon('thumb/5/53/Kgpg_key1.png/15px-Kgpg_key1.png')
what = '<s>bot: ' + getShortLink() + '</s>'
break
//user rights
case 'Для участника':
case 'changed rights for':
putIcon('thumb/5/53/Kgpg_key1.png/15px-Kgpg_key1.png')
//ma = row.match(/<a[^<]+<\/a> .*(\(.*)$/i)
what = row.match(/<\/a> (.*)$/)[1]
what = getShortLink() + ': ' + what
break
case 'renamed':
putIcon('thumb/e/ee/Crystal_Clear_app_kdmconfig.png/15px-Crystal_Clear_app_kdmconfig.png')
what = row
break
default:
//console.log('!'+word+'!')
icon = '?'
}
if (lastLink) icon = lastLink.replace(/>[^<]+</,'>'+icon+'<') //use icon as undo/protect/etc. link
tbody += '<tr' + trstyle + '>'
+ '<td class=logtime title="'+when+'">' + when.replace(logDateIn, logDateOut) + '</td>'
+'<td class=logicon>'+icon+'</td>'
+'<td class=logcontent title="' + whatTooltip + '"><div>'+what+'</div></td>'
+(user ? '' : '<td class=loguser>'+who+'</td>')
+'<td class=logcomment><div>'+comment + '</div></td></tr>'
function putIcon(src){
if (src.substring(0,1) != '/') src = imcomm + src
icon = '<img src=' + src + '>'
}
function getProtect(txt){
if (!txt) return ' '
else if (txt.indexOf('sysop') != -1) return 'sysop'
else return 'anon'
}
function getLink(){ //get first link from the row
return row.match(/<a[^<]+<\/a>/i)[0]
}
function shortLink(htm){ //returns a link without namespace in the text
return htm.replace(/>.+?:(.+?)</, '>$1<')
}
function getShortLink(){ //combination of above
return row.match(/<a[^<]+<\/a>/i)[0].replace(/>.+?:(.+?)</, '>$1<')
}
function putUser (u){
return u // !!!
}
} //parseRow
function shortDate(when){
var ma = when.match(/(\d\d:\d\d), (\d\d?) (\S ...)/)
var when2 = when
if (ma) when2 = ma[1]+'<br/>'+ma[2].replace(/ /,' ')
return '<td class=logtime title="'+when+'"><small>'+when2+'</small></td>'
}
}//obj
function addCSS(text){ //could use createStyleSheet for IE as well
var s = document.createElement('style')
s.setAttribute('type', 'text/css')
if (s.styleSheet) s.styleSheet.cssText = text //IE
else s.appendChild(document.createTextNode(text))
document.getElementsByTagName('head')[0].appendChild(s)
return s
}
if (wgCanonicalNamespace == 'Special' && wgCanonicalSpecialPageName == 'Log')
addOnloadHook (logPage.onLoad)