Участник:Js/apl.js

Материал из Википедии — свободной энциклопедии
/* small library for MW API requests */

var wgServerTime


var apl = new function(){


mw.loader.using('mediawiki.util').done(function () {
	//initialization
	mw.util.addCSS('span.sort {display:none}')
});



//-------------------API

var queryType =
{rc:'list=recentchanges'
,uc:'list=usercontribs'
,ap:'list=allpages'
,rv:'prop=revisions'
,le:'list=logevents'
}

// Usage: var myQ = new simpleQuery('rc', {limit:20}, myFunc)
// then myQ.call(); ... if (myQ.isMore) myQ.call(50)
this.simpleQuery = function(tp, params, cbfunc){
 var shortName = tp // 'rc'
 var longName = queryType[shortName].split('=')[1] // 'recentcontribs'
 var url = mw.config.get('wgScriptPath')+'/api.php?action=query&format=json&rawcontinue=&' + queryType[shortName]
 var request = {}, callback = cbfunc, next

 for (var k in params) addParam(k, params[k])
 this.isMore = false

 function addParam(key, val){
   if (!/titles|pageids|revids|redirects|indexpageids|requestid/.test(key))
     key = shortName + key
  request[key] = val
 }
 this.call = function(params){
    if (typeof params == 'number') request[shortName+'limit'] = params
    else if (typeof params == 'object') for (var k in params) addParam(k, params[k])
	$.getJSON(url, $.extend({}, request, next), recv)
 }
 this.isMore = function() {
 	return next
 }

 var recv = function(data, textStatus, jqXHR){
   updateServerTime(jqXHR)
   //save continue values
   if (next = data['query-continue']) next = next[longName]
   if (!data.query) return dispMsg('Server returned empty data')
   callback(data.query[longName], data)
 }

}



this.queryAPI = function(req, callback){
 $.getJSON( 
   mw.config.get('wgScriptPath')+'/api.php?action=query&rawcontinue=&format=json', 
   req, 
   function(resp, status, xhr){
     updateServerTime(xhr)
     callback(resp)
   }  
 )
}



this.updateServerTime = updateServerTime = function(xhr){
  if (xhr) wgServerTime = new Date( xhr.getResponseHeader('Date') )
} 



this.parseTimestamp = parseTS



this.getChild = function(obj, path){ //example:  getSomeChild( data , 'query.pages..somekey' )
 path = path.split('.')
 for( var i=0; i<path.length; i++ ){
   var key = path[i]
   if( key == '' ) for (key in obj) break //get any child
   if( obj ) obj = obj[key]
 }
 return obj
}





//---------------------------- HTML OUTPUT


this.toggleCSS = (function (){ //example:  toggleCSS( 'p{display:none}', true )
 var sheet = {}
 return function(css, isOn){
   mw.loader.using('mediawiki.util').done(function () {
   	if (!sheet[css]) sheet[css] = mw.util.addCSS(css)
   	sheet[css].disabled = ! isOn
   });
 }
})()



this.spinner = function (el){
 if (el)
   $(el).append('<img class=spinner style="margin-left:1em" src="'
   + stylepath +'/common/images/spinner.gif" alt="..." title="..." />')
 else 
   $('img.spinner').remove()
}



this.checkbox = function (name, id, val, txt){
 return '<input type=checkbox name='+name+' id='+id + ' value="'+val+'">'
   + '<label for='+id+'>' + txt + '</label>'
}



this.icon = function(src, size, attr){ //returns <img ...> from Commons
 if( size ) src = 'thumb/'+src+'/'+size+'px-'+src.split('/')[2]  //+'.png' //for svg: not needed?
 return '<img src="http://upload.wikimedia.org/wikipedia/commons/'
 + src + '" ' + (attr||'')+'>'
}


this.output = function (val, type){
 switch ( type ){
   case 'title': return this.outputPage(val, simplifyTitle(val) )
   case 'user':  return this.outputPage('Special:Contributions/'+val, val)
   case 'touched':
   case 'timestamp': return inHours( wgServerTime - parseTS(val) )
   case 'hours': return inHours(val)
   //case 'size': case 'oldlen': case 'newlen':
   default:
    return val
 }
}



this.outputPage = function (page, name){
 name = name || page
 if (name.length > 40) name = name.substr(0, 37) + '…'
 var tip = ''
 if (page != name) tip = ' title="'+page.replace(/"/g,'&quot;') + '"'
 page = encodeURI(page.replace(/ /g,'_')).replace(/\?/g,'%3F')
 // could use encodeURIComponent(page).replace(/%2F/g,'/')  ?
 return '<a href="' + mw.config.get('wgArticlePath').replace('$1', '') + page + '"'
  + tip + '>'+name+'</a>'
}


this.outputLink = function (link, name){
 return '<a href="' + mw.config.get('wgScript') + '?' + link + '">'+name+'</a>'
}


this.outputCell = function (val, key, attr){
 var a1 = '', a2 = '', clss = key
 attr = attr || ''
 if( typeof val == 'object' ){
   if( key == 'title' && typeof val.redirect == 'string' ) clss += ' redirect'
   val = val[key]
 }
 if ( key == 'timestamp'){ //handle timestamp
   attr += ' title="' + val + '"'
   a1 = '<span class=sort>' + val + '</span><span class=hours>'
   a2 = '</span>'
 }
 return '<td class="' + clss + '"' + attr + '>' + a1 + this.output( val, key ) + a2
}



this.makeAPITimestamp = function(d){ //date -> 2008-01-26T06:34:19Z
 return d.getUTCFullYear() + '-'
 + pad0(d.getUTCMonth()+1) + '-'
 + pad0(d.getUTCDate()) + 'T'
 + pad0(d.getUTCHours()) + ':'
 + pad0(d.getUTCMinutes()) + ':'
 + pad0(d.getUTCSeconds()) + 'Z'
}



//----------- AUX Functions 

function pad0(v, len){ // 6 -> '06'
 len = len || 2
 v = v.toString()
 while (v.length < len) v = '0'+v
 return v
}

function diffSize(n){
 return '<span class='
 + 'mw-plusminus-'+ (n>0 ? 'pos' : (n<0?'neg':'null'))
 + (n < - 500 ? ' style="font-weight:bold"' : '')
 + '>' + n.toString() + '</span>'
}

function inHours(ms){ //milliseconds -> "2:30" or 5,06 or 21
 var mm = Math.floor(ms/60000)
 if( !mm ) return '<small>'+Math.floor(ms/1000)+'s</small>'
 var hh = Math.floor(mm/60); mm = mm % 60
 var dd = Math.floor(hh/24); hh = hh % 24
 if (dd) return dd + (dd<10?'<small>,'+pad0(hh)+'</small>':'')
 else return '<small>'+hh + ':' + pad0(mm)+'</small>'
}



//20081226220605  or  2008-01-26T06:34:19Z   -> date
function parseTS(ts){
 var m = ts.replace(/\D/g,'').match(/(\d\d\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)/)
 return new Date ( Date.UTC(m[1], m[2]-1, m[3], m[4], m[5], m[6]) )
}


function simplifyTitle(ttl){
  for (var tt in simplerTitles)
    if ( ttl.substring (0, tt.length) == tt )
      ttl = simplerTitles[ tt ] + ttl.substring(tt.length)
  return ttl   
}

//---------- Per Project

// enwiki
var simplerTitles =
{'Wikipedia:' :'WP:'
,'Wikipedia talk:':'WT:'
}


// ruwiki
var simplerTitles =
{'Википедия:Проект:Инкубатор/Статьи/': '::'
,'Обсуждение Википедии:': 'ОВ:'
,'Википедия:':'ВП:'
}



}//library