User:Ned Scott/monobook.js

From Wikipedia, the free encyclopedia

If a message on your talk page led you here, please be wary of who left it. The code below could contain malicious content capable of compromising your account; if your account appears to be compromised, it will be blocked. If you are unsure whether the code is safe, you can ask at the appropriate village pump.
Note: After saving, you have to bypass your browser's cache to see the changes. In Internet Explorer and Firefox, hold down the Ctrl key and click the Refresh or Reload button. Opera users have to clear their caches through Tools→Preferences, see the instructions for Opera. Konqueror and Safari users can just click the Reload button.
// ******************************************************START Vandal report tab
function inc (file) {
  var lt = String.fromCharCode(60);
  var gt = String.fromCharCode(62);
  document.writeln(lt+'script type="text/javascript" src="/w/index.php?title='+file+'&action=raw&ctype=text/javascript&dontcountme=s"'+gt+lt+'/script'+gt);
}
 
inc("User:Lightdarkness/aiv.js");
// ******************************************************END Vandal report tab
 
 
 
// ******************************************************START un-watch list
if (wgCanonicalSpecialPageName && wgCanonicalSpecialPageName=='Watchlist' && wgAction=='view') 
addOnloadHook(function () {
var frm = document.getElementsByTagName('form')[0]
frm.parentNode.insertBefore(document.createTextNode(' | '), frm)
var lnk = document.createElement('a')
lnk.appendChild(document.createTextNode('Unwatch…'))
lnk.href = 'javascript:importScript("User:Alex_Smotrov/wlunwatch.js")'
frm.parentNode.insertBefore(lnk, frm)
})
// ******************************************************END un-watch list
 
// ******************************************************START Quick Preview
importScript('User:Alex_Smotrov/qpreview.js');
// ******************************************************END Quick Preview
 
// ******************************************************Start History view
if (wgAction == 'history') //add a link to call histComb.js
addOnloadHook(function(){
var pagehis = document.getElementById('pagehistory');
if (!pagehis) return;
var lnk = document.createElement('a');
lnk.style.marginLeft = '10px';
lnk.href = '#';
lnk.appendChild(document.createTextNode('Improve…'));
lnk.onclick=function(){this.parentNode.removeChild(this);importScript('User:Alex_Smotrov/histcomb.js')}
pagehis.parentNode.insertBefore(lnk, pagehis);
})
// ******************************************************END History view
 
// ******************************************************START Logs link
// adds a 'logs for this page' link to the toolbox bar
// if the page is a user's page, talk page or subpage, the link will go to logs for the user instead
// if the page is a special page, then no link is displayed
 
addOnloadHook(function () {
 
// if this is a user, show the logs for the user rather than the page
if ( wgCanonicalNamespace == "User" || wgCanonicalNamespace == "User_talk" ) {
  url = wgServer + "/w/index.php?title=Special:Log&user=" + wgTitle.split("/")[0];
} else if ( wgCanonicalNamespace == "Special" ) {
  // don't display link for special pages
  return;
} else {
  url = wgServer + "/w/index.php?title=Special:Log&page=" + wgPageName;
}
 
addPortletLink("p-tb", url, "Logs", "pt-logs");
 
});
// ******************************************************END Logs link
 
// ******************************************************START Extra Buttons
 
XEBOrder='C,D,D1,FS,';
rmEditButtons=[0,1,2,3,4,5,6,7,8,9,10,13,14,15,16,17,18,19];
myButtons=[];
importScript('User:MarkS/extraeditbuttons.js'); //[[User:MarkS/extraeditbuttons.js]]
// ******************************************************END Extra Buttons
 
 
// ******************************************************START User:Alex Smotrov/logpage.js
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: '[show table]',
ShowList: '[show list]'
}
 
 
 
var type, user, ul, lis, logTable, logLink, tbody, isTable = false
var thisYear = (new Date()).getFullYear()
 
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 $4'
if (!window.logBlDivider) logBlDivider = '<br>'
logPageCSS = '.logcomment div {overflow:auto} .logtime {width:15px}' + (window.logPageCSS?logPageCSS:'')
addCSS2(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
var columns = 5
tbody = '<tr>'
+'<th><img src=' + imcomm + 'thumb/a/af/Relogio07_15.svg/15px-Relogio07_15.svg.png></th>'
+'<th width=10px class=unsortable>&nbsp;</th>'
+'<th><img src=' + imcomm + '/3/3c/A_help_text.gif></th>'
if (user){ //no need for user column
   columns--
   tbody = '<caption style="text-align:left; padding-left:20%"><img src='+imuser+'>: '
    +user.replace(/\+/,' ')+'</caption>'+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++){
   try {
     parseRow(lis[i].innerHTML)
   } catch(e) { //put without parsing
     tbody += '<td colspan='+columns+'>' + lis[i].innerHTML + '</td>'
     jsMsg('<b>logPage:</b> ' +  e.lineNumber + ': ' + e.name + ': ' + e.message + ' ; please <a href="http://en.wikipedia.org/wiki/user_talk:Alex_Smotrov">report</a>')
   }
}
//insert table
logTable = document.createElement('div')
logTable.innerHTML = '<table class=wikitable width=100% id=logTable>' +  tbody + '</table>'
ul.parentNode.insertBefore(logTable, ul)
ts_makeSortable(document.getElementById('logTable'))
}
 
 
 
function parseRow(row){
 
var icon='', when, what, who, comment='', ma, word, lastLink=''
var r1, r2, opt = '', extra='', until='', trstyle=''
var whatTooltip = '' // not used
//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 characters 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':
   extra = ' <small>(version)</small>'
 
case 'uploaded':
   what = getShortLink() + extra
   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':
   extra = ' <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],'')
   }
   if (ma=comment.match(/\[(edit=[a-z]+)?:?(move=[a-z]+)?\]/)){ //edit/move protection
     if (ma[0].indexOf('sysop') != -1) //is sysop protection at all
        putIcon('thumb/5/59/Padlock.svg/20px-Padlock.svg.png') //yellow
     else
       putIcon('thumb/f/fa/Padlock-silver-medium.svg/20px-Padlock-silver-medium.svg.png') //gray
    if (ma[1]) opt += (ma[1].indexOf('sysop')!=-1)  ? 'sysop' : 'user'
    opt += '&nbsp;::&nbsp;'
    if (ma[2]) opt += (ma[2].indexOf('sysop')!=-1) ? 'sysop' : 'user'
   }else if (ma=comment.match(/\[(create=[a-z]+)?\]/)){ //create protection
     if (ma[0].indexOf('sysop') != -1){
        putIcon('thumb/4/4f/Padlock-purple.svg/20px-Padlock-purple.svg.png') 
        opt = 'sysop'
     }else{
        putIcon('thumb/7/70/Padlock-pink.svg/20px-Padlock-pink.svg.png')
        opt = 'user'
     }
   }
   comment = opt + extra + ' ' + until + '<br>' + comment.replace(ma[0],'')
   break
 
 
case 'unprotected':
   what = getLink()
   putIcon('thumb/5/5e/Padlock-lightolive.svg/15px-Padlock-lightolive.svg.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 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/a/a9/Wikiactividade_bot_bronze.png/16px-Wikiactividade_bot_bronze.png')
   what = 'bot: ' + getShortLink()
   break
 
  case 'removed bot status from':
   putIcon('thumb/1/16/Wikiactividade_bot_prata.png/16px-Wikiactividade_bot_prata.png')
   what = '<s>bot: ' + getShortLink() + '</s>'
   break
 
  //user rights
  case 'Для участника':
 
  case 'changed rights for':
   what = row.match(/<\/a> (.*) \u200E/i)[1] //devs, why use  \u200E ?
   what = what.replace(/\([^\)]+\)/g,'()')
   ma = what.match(/from (.*) to (.*)/) 
   if (!ma) {
     what = getShortLink() + ': ' + what
     putIcon('thumb/b/b3/Kgpg_key3.png/15px-Kgpg_key3.png')
     break
   }
   r1 = ma[1]; r2 = ma[2] 
   if (r1 == r2)
     putIcon('thumb/8/80/Keyring.png/12px-Keyring.png')
   else if (r1.length < r2.length){ //added flags
     if ((r1 == '()' && r2 == 'rollbacker') || (r1 + ', rollbacker' == r2))
       putIcon('thumb/4/40/Wrench.svg/10px-Wrench.svg.png') 
     else
       putIcon('thumb/5/53/Kgpg_key1.png/15px-Kgpg_key1.png') //visible vertical key
   }else{ //removed flags
     if ((r1 == 'rollbacker' && r2 == '()') || (r1 == 'rollbacker, '+r2) || (r1 == r2+', rollbacker'))
       putIcon('thumb/4/40/Wrench.svg/6px-Wrench.svg.png')
     else
       putIcon('thumb/8/82/Kgpg_key2.png/15px-Kgpg_key2.png') //grey and yellow keys
   }
   //   putIcon('thumb/4/43/Crystal_Clear_app_password.png/17px-Crystal_Clear_app_password.png') //clear keys
   what = '<br />' + r1 + ' → ' + r2
   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:
   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).replace(thisYear,'') + '</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 addCSS2(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)
// ******************************************************END User:Alex Smotrov/logpage.js
 
// ******************************************************START User:Splarka/watchimages.js
/* Semi-automatic image watcher, version [0.0.3a]
Originally from: http://en.wikipedia.org/wiki/User:Splarka/watchimages.js
 
Operation:
* Checks which images are being used on a page
* Sorts out those from commons, builds a list of those local or missing
* Passes this list to Special:Watchlist/raw (but does not save, being a test script).
* When saved, returns to the original page.
 
Notes: 
* The logic of which images to watch is easily changed (see below)
* This avoids ajax editing (which is a pain). Possibly the API actions will be enabled later.
 
To do after more testing:
* Abort if no matching images are found.
* Check page more specifically for a content type (page has ID? etc).
* Auto-submit if so desired.
*/
 
if(wgNamespaceNumber != -1) addOnloadHook(watchAllImagesButton)
function watchAllImagesButton() {
  addPortletLink('p-tb','javascript:watchAllImages()','Watch images','t-wai','Add all images on this page to your watchlist.');
}
 
function watchAllImages() {
  var wai = document.getElementById('t-wai');
  if(wai) {
    wai.getElementsByTagName('a')[0].style.display = 'none';
    var prog = document.createElement('img');
    prog.setAttribute('id','wai-prog');
    prog.setAttribute('src',stylepath + '/common/images/spinner.gif');
    wai.appendChild(document.createTextNode('Working...'));
    wai.appendChild(prog);
  }
  var url = wgServer + wgScriptPath +'/api.php?action=query&format=json&callback=watchAllImagesCB&generator=images&prop=imageinfo&iiprop=&iilimit=1&titles=' + encodeURIComponent(wgPageName)
  var scriptElem = document.createElement('script');
  scriptElem.setAttribute('src',url);
  scriptElem.setAttribute('type','text/javascript');
  document.getElementsByTagName('head')[0].appendChild(scriptElem);
}
 
function watchAllImagesCB(obj) {
  document.getElementById('wai-prog').style.display = 'none';
  var towatch = '';
  if(!obj['query'] || !obj['query']['pages']) return
  var images = obj['query']['pages'];
  for(var i in images) {
    // Logic variables to determine which images to watch
    // islocal = image is local, rather than shared (from commons).
    // haspage = has a description page, all local and some shared images have this.
    // hasmedia = the image exists, either locally or shared.
 
    var islocal = (images[i]['imagerepository'] == 'local')
    var haspage = i > 0
    var hasmedia = (images[i]['imagerepository'] != '')
 
    //(!hasmedia || islocal) => all local images, as well as all missing (deleted or soon to be uploaded) images
    if(!hasmedia || islocal) {
      towatch += images[i]['title'] += '\n';
    }
  }
  var url = wgServer + wgArticlePath.replace(/\$1/,'Special:Watchlist/raw') + '?fromtitle=' + encodeURIComponent(wgPageName) + '&towatch=' + encodeURIComponent(towatch);
  document.location.href = url;
}
 
if(queryString('towatch') && wgCanonicalSpecialPageName == 'Watchlist') addOnloadHook(addToWatchlist)
function addToWatchlist() {
  var txt = document.getElementById('titles');
  var towatch = decodeURIComponent(queryString('towatch'));
  if(!txt) return
  if(queryString('fromtitle')) {
    var forms = document.forms;
    for(var i=0;i<forms.length;i++) {
      if(forms[i].action.indexOf('Watchlist') != -1) {
        forms[i].action += '&pleasereturnto=' + queryString('fromtitle');
      }
    }
  }
  txt.value += towatch;
  alert('Note: the following images will be added to your watchlist upon save:\n' + towatch);
}
 
if(queryString('pleasereturnto') && wgCanonicalSpecialPageName == 'Watchlist') addOnloadHook(addToWatchlistDone)
function addToWatchlistDone() {
  var url = wgServer + wgArticlePath.replace(/\$1/,decodeURIComponent(queryString('pleasereturnto')));
  document.location.href = url;
}
 
function queryString(p) {
  var re = RegExp('[&?]' + p + '=([^&]*)');
  var matches;
  if (matches = re.exec(document.location)) {
    try { 
      return decodeURI(matches[1]);
    } catch (e) {
    }
  }
  return null;
}
// ******************************************************END User:Splarka/watchimages.js