Участник: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&nbsp;$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>&nbsp;</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(/> </,'>&nbsp;<')  //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 += '&nbsp;/&nbsp;'
   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 += '&nbsp;<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 '&nbsp;'
  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(/ /,'&nbsp;')
 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)