v50 Steam/Premium information for editors
- v50 information can now be added to pages in the main namespace. v0.47 information can still be found in the DF2014 namespace. See here for more details on the new versioning policy.
- Use this page to report any issues related to the migration.
This notice may be cached—the current version can be found here.
Difference between revisions of "User:Lethosor/rater 0.1.js"
Jump to navigation
Jump to search
(New rating script (which does little to no actual work)) |
m (Lethosor moved page User:Lethosor/rater.js to User:Lethosor/rater 0.1.js: Updating) |
||
(18 intermediate revisions by the same user not shown) | |||
Line 5: | Line 5: | ||
*/ | */ | ||
+ | //Like python: 'a{0}b'.format('c') == 'acb' | ||
+ | String.prototype.format=function(){s=this;for(i=0;i<arguments.length;i++){s=s.replace(RegExp('\\{'+i+'\\}','g'), arguments[i])};return s}; | ||
+ | String.prototype.capitalize=function(){return this.slice(0,1).toUpperCase()+this.slice(1)}; | ||
addOnloadHook(function(){jQuery(function($){ | addOnloadHook(function(){jQuery(function($){ | ||
SCOPE = this | SCOPE = this | ||
var rater = {} | var rater = {} | ||
+ | rater.event=$({});//for event bindings | ||
+ | //Temporary! (importScript doesn't seem to work here) | ||
+ | $.getScript(wgScript+'?title=User:Lethosor/raterwarn.js&action=raw'); | ||
+ | |||
function PD(e){//preventDefault | function PD(e){//preventDefault | ||
− | if(e && 'preventDefault' | + | if(e && e['preventDefault'] && 'call' in e.preventDefault) |
e.preventDefault() | e.preventDefault() | ||
} | } | ||
− | + | function is_func(x){return !!(x&&x['call'])} | |
rater.page = { | rater.page = { | ||
− | name: wgPageName, | + | name: wgPageName.replace(/_/g,' '), |
− | url: wgScript+'?title='+wgPageName | + | ns:wgCanonicalNamespace||'Main', |
+ | url: wgScript+'?title='+wgPageName, | ||
+ | exists:!$('#left-navigation').find('li[class*=selected]').find('a[href*=redlink]').length, | ||
+ | load_time:$('body').html().match(/<!--.*-->/g).slice(-1)[0].match(/\d+\.\d+/)[0] | ||
} | } | ||
− | + | ||
+ | rater.is_valid_page = function(page){ | ||
+ | if(!rater.page.exists) return false; | ||
+ | if(!page) page=wgPageName; | ||
+ | if('Masterwork DF2012 v0.31 40d 23a'.split(' ').indexOf(rater.page.ns)+1) return true | ||
+ | if($('#norate').length) return false | ||
+ | return false | ||
+ | }; | ||
+ | |||
+ | rater.error_invalid_page=function(){ | ||
+ | if('Special File Image Unused'.indexOf(rater.page.ns)+1|| | ||
+ | rater.page.ns.toLowerCase().indexOf('talk')+1){ | ||
+ | rater.box.clear().append('<span class="error">I\'m afraid I can\'t let you do that,'+ | ||
+ | ' Urist.</span><p>This page isn\'t an article, and doesn\'t have some of the necessary'+ | ||
+ | ' properties to be rated. <a href="#rater-cancel">Close this window</a></p>') | ||
+ | } | ||
+ | else if(!rater.page.exists){ | ||
+ | rater.box.clear().append('<p class="error">This page doesn\'t exist!</p>') | ||
+ | } | ||
+ | else{ | ||
+ | rater.box.clear().append('<span class="error">Invalid page</span>') | ||
+ | .append("<p>This page is in an invalid namespace. You can "+ | ||
+ | "<a href='#rater-force'>view this page's rating anyway</a> or "+ | ||
+ | "<a href='#rater-cancel'>close this window</a>.</p>") | ||
+ | } | ||
+ | }; | ||
+ | |||
// Set up UI | // Set up UI | ||
rater.overlay = $('<div>').css({width:'100%', height:'100%', top:0, left:0, | rater.overlay = $('<div>').css({width:'100%', height:'100%', top:0, left:0, | ||
Line 23: | Line 59: | ||
.hide().appendTo('body'); | .hide().appendTo('body'); | ||
rater.box = $('<div>').css({width:'80%', height:'80%', top:'10%', left:'10%', | rater.box = $('<div>').css({width:'80%', height:'80%', top:'10%', left:'10%', | ||
− | position:'fixed', 'background-color':'white', 'z-index':10000, padding:'1em'}) | + | position:'fixed', 'background-color':'white', 'z-index':10000, padding:'1em',overflow:'auto'}) |
.hide().appendTo('body'); | .hide().appendTo('body'); | ||
rater.cancel_link = $('<a>').text('Cancel').attr('href','#rater-cancel').css({color:'red', | rater.cancel_link = $('<a>').text('Cancel').attr('href','#rater-cancel').css({color:'red', | ||
'float':'right'}).appendTo(rater.box); | 'float':'right'}).appendTo(rater.box); | ||
+ | |||
+ | rater.popup={}; | ||
+ | rater.popup.overlay = $('<div>').css({width:'100%', height:'100%', top:0, left:0, | ||
+ | position:'fixed', 'background-color':'rgba(128,128,128,0.5)', 'z-index':10001}) | ||
+ | .hide().appendTo('body'); | ||
+ | rater.popup.box = $('<div>').css({width:'40%', height:'60%', top:'20%', left:'30%', | ||
+ | position:'fixed', 'background-color':'white', 'z-index':10002, padding:'1em', | ||
+ | overflow:'auto'}) | ||
+ | .hide().appendTo('body'); | ||
+ | rater.popup.close_link = $('<a>').text('Close').attr('href','#rater-popup-hide').css({color:'red', | ||
+ | 'float':'right'}).appendTo(rater.popup.box); | ||
rater.box.clear = function(){ | rater.box.clear = function(){ | ||
rater.box.html('') | rater.box.html('') | ||
rater.box.append(rater.cancel_link) | rater.box.append(rater.cancel_link) | ||
− | .append($('<h2>').text('Rating '+ | + | .append($('<h2>').text('Rating '+rater.page.name)); |
+ | rater.event.trigger('box-clear'); | ||
+ | return rater.box; | ||
+ | }; | ||
+ | rater.popup_show=function(e){//note _ - avoid $ clash | ||
+ | PD(e); | ||
+ | rater.popup.box.stop(1,1).fadeIn(500); | ||
+ | rater.popup.overlay.stop(1,1).fadeIn(500); | ||
}; | }; | ||
+ | rater.popup_hide = function(e){ | ||
+ | PD(e); | ||
+ | rater.popup.overlay.stop(1,1).fadeOut(500); | ||
+ | rater.popup.box.stop(1,1).fadeOut(500); | ||
+ | }; | ||
+ | $('body').on('click','a[href=#rater-popup-hide]',rater.popup_hide); | ||
rater.box.clear(); | rater.box.clear(); | ||
+ | rater.popup.clear=function(){ | ||
+ | rater.popup.box.html('').append(rater.popup.close_link); | ||
+ | }; | ||
+ | rater.popup.clear(); | ||
+ | |||
rater.cancel = function(e){ | rater.cancel = function(e){ | ||
− | PD(e) | + | PD(e);rater.show_link.removeClass('selected'); |
+ | $('body').css({overflow:'auto'}); | ||
rater.overlay.stop(1,1).fadeOut(500); | rater.overlay.stop(1,1).fadeOut(500); | ||
rater.box.stop(1,1).fadeOut(500); | rater.box.stop(1,1).fadeOut(500); | ||
Line 45: | Line 111: | ||
$("<a href='#rater-invoke'>").text('Rate') | $("<a href='#rater-invoke'>").text('Rate') | ||
)); | )); | ||
+ | $("#left-navigation #p-namespaces ul:nth(0)").append('<li><span><a></a></span></li>') | ||
$("#left-navigation #p-namespaces ul:nth(0)").append(rater.show_link) | $("#left-navigation #p-namespaces ul:nth(0)").append(rater.show_link) | ||
− | + | ||
− | rater.invoke = function(e){ | + | rater.invoke = function(e, force){ |
− | PD(e); | + | PD(e);$('body').css({overflow:'hidden'}); |
rater.overlay.stop(1,1).fadeIn(500); | rater.overlay.stop(1,1).fadeIn(500); | ||
rater.box.stop(1,1).fadeIn(500); | rater.box.stop(1,1).fadeIn(500); | ||
− | rater.box.clear() | + | if(!rater.is_valid_page(wgPageName) && !force) |
− | rater.box.append('<p>Performing automatic tests, please wait...</p>'); | + | return rater.error_invalid_page(); |
+ | rater.box.clear();rater.show_link.addClass('selected'); | ||
+ | rater.box.append('<p>Performing automatic tests (<span class="rater-tests-left"></span> remaining), please wait...</p>'); | ||
rater.begin_tests(); | rater.begin_tests(); | ||
}; | }; | ||
$('body').on('click', 'a[href=#rater-invoke]', rater.invoke) | $('body').on('click', 'a[href=#rater-invoke]', rater.invoke) | ||
+ | $('body').on('click', 'a[href=#rater-force]', function(e){rater.invoke(e,1)}); | ||
/* | /* | ||
Line 67: | Line 137: | ||
tests.list={}; //list of all tests | tests.list={}; //list of all tests | ||
tests.results={}; //shortcut: data[x]==lists[x].data | tests.results={}; //shortcut: data[x]==lists[x].data | ||
+ | tests.random=Math.floor(Math.random()*1e10); | ||
tests.num_waiting = 0; | tests.num_waiting = 0; | ||
Line 72: | Line 143: | ||
tests.add = function(name, data_url, processor){ | tests.add = function(name, data_url, processor){ | ||
//Note: jQuery caches Ajax requests by default, no need to here | //Note: jQuery caches Ajax requests by default, no need to here | ||
− | tests.list[name] = {data_url:data_url, processor:processor}; | + | tests.list[name] = {data_url:data_url, processor:processor}; |
− | // | + | //Prevents caching for the first rating (reset on page load) |
+ | data_url+=((data_url.indexOf('?')+1)?'&':'?')+'_='+tests.random; | ||
$.get(data_url, function(data){ | $.get(data_url, function(data){ | ||
tests.process(name, data); | tests.process(name, data); | ||
Line 83: | Line 155: | ||
tests.list[name].result = tests.results[name] = result | tests.list[name].result = tests.results[name] = result | ||
tests.num_waiting-- | tests.num_waiting-- | ||
+ | $(".rater-tests-left").text(tests.num_waiting) | ||
if(tests.num_waiting <= 0){ | if(tests.num_waiting <= 0){ | ||
− | setTimeout(tests.all_complete, 1); // | + | setTimeout(tests.all_complete, 1); //async |
} | } | ||
}; | }; | ||
Line 97: | Line 170: | ||
tests.all_callbacks.push(func); | tests.all_callbacks.push(func); | ||
}; | }; | ||
+ | |||
+ | rater.help={view:$('<div>').css({height:'100%'})}; | ||
+ | rater.help.init=function(){ | ||
+ | $.get(wgScript+'/DF:Quality',function(d){ | ||
+ | d=$(d); | ||
+ | rater.help.data=[]; | ||
+ | for(var i=0;i<=5;i++){ | ||
+ | rater.help.data[i]=d.find('h3:nth({0})'.format(i)).nextUntil('h3'); | ||
+ | rater.help.data[i].splice(0,0,d.find('h3:nth({0})'.format(i))[0]); // prepend header | ||
+ | }; | ||
+ | rater.help.update(); | ||
+ | }); | ||
+ | }; | ||
+ | rater.help.update=function(n){ | ||
+ | if(!rater.help.data)return; | ||
+ | if(!(n+1)){ | ||
+ | try{ | ||
+ | n=rater.ratings[rater.select.current].id; | ||
+ | } catch(e){return} | ||
+ | } | ||
+ | rater.help.view.text('').append(rater.help.data[n]); | ||
+ | rater.help.view.find('.editsection').hide(); | ||
+ | //rater.box.scrollTop(rater.box.height()); | ||
+ | }; | ||
+ | |||
rater.begin_tests = function(){ | rater.begin_tests = function(){ | ||
render_url=rater.page.url+'&action=render' | render_url=rater.page.url+'&action=render' | ||
+ | raw_url=rater.page.url+'&action=raw' | ||
+ | rater.help.init() | ||
tests.add('redlinks', render_url, function(data){ | tests.add('redlinks', render_url, function(data){ | ||
all_links = data.match(/<a .*<\/a>/g); | all_links = data.match(/<a .*<\/a>/g); | ||
Line 109: | Line 209: | ||
return total_redlinks | return total_redlinks | ||
}); | }); | ||
− | tests.add('editors', rater.page.url+'&action=history&limit= | + | tests.add('editors', rater.page.url+'&action=history&limit=100', function(data){ |
all_editors = data.match(/<li>.*<\/li>/g) | all_editors = data.match(/<li>.*<\/li>/g) | ||
if(!all_editors) return 0; //no editors | if(!all_editors) return 0; //no editors | ||
Line 115: | Line 215: | ||
$.each(all_editors, function(i,li){ | $.each(all_editors, function(i,li){ | ||
ed = $(li).find('.mw-userlink:nth(0)').text() | ed = $(li).find('.mw-userlink:nth(0)').text() | ||
− | if(ed in editors) editors[ed]=0; | + | if(!(ed in editors)) editors[ed]=0; |
editors[ed]++ | editors[ed]++ | ||
}); | }); | ||
Line 123: | Line 223: | ||
num++ | num++ | ||
} | } | ||
− | return | + | editors.total=num;editors.total_edits=all_editors.length; |
+ | return editors; | ||
+ | }); | ||
+ | tests.add('linkshere', wgScript+'/Special:WhatLinksHere/'+wgPageName, function(data){ | ||
+ | return $(data).find('#mw-whatlinkshere-list').length; | ||
}); | }); | ||
− | tests.add(' | + | tests.add('links', render_url, function(data){ |
− | return | + | return $(data).find('a[href*="'+wgScript+'"]').length; |
}); | }); | ||
− | tests.add(' | + | tests.add('length', raw_url, function(data){ |
− | + | rater.raw_text=data; | |
+ | var a={ | ||
+ | 'full':data.length, | ||
+ | 'nospace':data.replace(/\s/g,'').length, | ||
+ | 'notemplate':data.replace(/{{[^}]*?}}/g,'').length, | ||
+ | 'raw':data.replace(/\s/g,'').replace(/{{[^}]*?}}/g,'').length | ||
+ | }; | ||
+ | a.average=Math.round(.1 * a.full + .2*a.nospace + .3*a.notemplate + .4*a.raw) | ||
+ | return a | ||
+ | }); | ||
+ | tests.add('html_length', render_url, function(data){ | ||
+ | var a={'html':data.length,'text':$(data).text().length}; | ||
+ | return a; | ||
+ | }); | ||
+ | tests.add('verify',raw_url,function(data){ | ||
+ | var m=data.match(/{{verify/g);return +(m&&m.length); | ||
+ | }); | ||
+ | tests.add('current_rating',raw_url,function(data){ | ||
+ | m=data.match(/{{quality[^}]*?}}/i); | ||
+ | return (m&&m.length&&m[0].slice(2,-2).split('|')[1])||'' | ||
}); | }); | ||
tests.add_callback(function(){ | tests.add_callback(function(){ | ||
Line 143: | Line 266: | ||
if(!base) base=0; | if(!base) base=0; | ||
return v*weight+base; | return v*weight+base; | ||
+ | }; | ||
+ | rater.metadata = { | ||
+ | 'redlinks':{name:'Redlinks'}, | ||
+ | 'links': {name:'Outbound links'}, | ||
+ | 'linkshere': {name:'Incoming links'}, | ||
+ | 'editors': {name:'Editor count',str:function(o){return o.total}, | ||
+ | int:function(o){return o.total;}, | ||
+ | info:function(o,view){ | ||
+ | tbl=$("<table>").css({width:'100%'}).append('<tr><th colspan="2">User</th><th>Edits</th></tr>').addClass('wikitable sortable').appendTo(view) | ||
+ | for(i in o){ | ||
+ | if(i in {}||!i.indexOf('total')) continue; | ||
+ | tbl.append('<tr><td colspan="2"><a href="{2}/User:{0}">{0}</a>:</td><td>{1}</td></tr>'.format(i,o[i],wgScript)) | ||
+ | } | ||
+ | tbl.append('<tr style="font-weight:bold"><td>Total:</td><td>{0}</td><td>{1}</td></tr>' | ||
+ | .format(o.total,o.total_edits)) | ||
+ | }, | ||
+ | }, | ||
+ | 'length': {str:function(obj){ | ||
+ | return "Weighted: {0} ({1} characters, {2} without templates)" | ||
+ | .format(obj.average,obj.full,obj.notemplate);}, | ||
+ | name:'Source length'}, | ||
+ | html_length:{name:'Text length', | ||
+ | str:function(o){return '{0} (HTML: {1})'.format(o.text,o.html)}, | ||
+ | int:function(o){return o.text}}, | ||
+ | verify:{name:'{{Verify}} tags',score:function(o){ | ||
+ | if(o<1) return 0; if(o==1) return -10; return o*-20}}, | ||
+ | current_rating:{name:'Current rating', int:function(){return 0;}} | ||
+ | }; | ||
+ | |||
+ | rater.ratings={ | ||
+ | tattered:{id:1,color:{b:'#333',bg:'#ccc',c:'#333'},s:'x'}, | ||
+ | fine:{id:2,color:{b:'#db8',bg:'#ffe0cc',c:'#ca7a02'},s:'+'}, | ||
+ | superior:{id:3,color:{b:'#b8f',bg:'#e4ccff',c:'#80c'},s:'*'}, | ||
+ | exceptional:{id:4,color:{b:'#9df',bg:'#cce4ff',c:'#08c'},s:'\u2261'}, | ||
+ | masterwork:{id:5,color:{b:'#bd8',bg:'#e2fdce',c:'#72a329'},s:'\u263c'} | ||
}; | }; | ||
rater.display_test_results=function(){ | rater.display_test_results=function(){ | ||
+ | var md=rater.metadata; | ||
rater.box.clear(); | rater.box.clear(); | ||
data=tests.results; | data=tests.results; | ||
− | for(i in data){ | + | for(var i in data){ |
− | if(i | + | name=md[i].name; |
− | rater.box.append($("<p>"+ | + | str=is_func(md[i].str)?md[i].str(data[i]):data[i]; |
+ | app='' | ||
+ | if(is_func(md[i].info)){ | ||
+ | app=$('<a href="#">[Info]</a>').data({f:md[i].info,d:data[i]}) | ||
+ | .click(function(e){d=$(this).data() | ||
+ | rater.popup.clear(); rater.popup_show(e); | ||
+ | d.f(d.d,rater.popup.box.append($("<div>"))) | ||
+ | }).css('padding-left','1em'); | ||
+ | } | ||
+ | rater.box.append($("<p>"+name+": "+str+"</p>").append(app)); | ||
} | } | ||
rater.score = 0 | rater.score = 0 | ||
− | +rater.score_bool(data. | + | +rater.score_bool(!data.links,-25) //orphaned |
− | +rater.score_bool(data. | + | +rater.score_bool(!data.linkshere,-30) //dead end |
− | +rater.score_int(data.redlinks,-5) | + | +rater.score_int(data.links,0.5) |
− | +rater.score_int(data.editors, | + | +rater.score_int(data.linkshere,0.75) |
+ | +rater.score_int(data.redlinks,-5,10) | ||
+ | +rater.score_int(data.editors.total,20,-15) | ||
+ | |||
; | ; | ||
rater.box.append($("<p>").text("Score: "+rater.score)) | rater.box.append($("<p>").text("Score: "+rater.score)) | ||
+ | rater.select.init($("<div>").appendTo(rater.box)); | ||
+ | }; | ||
+ | rater.select={}; | ||
+ | rater.select.view=$("<div>").css({padding:'.2em'}); | ||
+ | rater.select.init=function(){ | ||
+ | rater.select.current=rater.tests.results.current_rating.toLowerCase()||'tattered'; | ||
+ | rater.select.view.appendTo(rater.box); | ||
+ | rater.select.draw(); | ||
+ | }; | ||
+ | rater.select.draw=function(){var c,selected,a,view=rater.select.view; | ||
+ | view.text('\nDesired rating: '); | ||
+ | list=$('<span>').css({'font-size':'.8em'}).appendTo(rater.select.view) | ||
+ | for(i in rater.ratings){if(i in {}) continue; | ||
+ | c=rater.ratings[i]; | ||
+ | a=$('<span>').appendTo(list).data('rating',i).attr({tabindex:0}).css({cursor:'pointer'}); //not real link | ||
+ | a.append($('<span>').text(c.s+i.toUpperCase()+c.s) | ||
+ | .css({'text-decoration':'none','color':c.color.c})); | ||
+ | if(i==rater.select.current){ | ||
+ | selected=rater.ratings[i]; | ||
+ | a.find('span').css({'border-color':c.color.b,'background-color':c.color.bg,'border-width':1,'border-style':'solid','border-radius':2,padding:'.2em'}) | ||
+ | } | ||
+ | a.on('click focus',rater.select.click); | ||
+ | list.append(' '); | ||
+ | } | ||
+ | if(rater.is_valid_page()){ | ||
+ | rater.submit_link=$('<a>').attr({href:'#rater-submit'}).text("Submit").appendTo(view); | ||
+ | view.append(' '); | ||
+ | } | ||
+ | rater.reset_link=$('<a>').attr({href:'#rater-reset'}).text("Reset").appendTo(view); | ||
+ | rater.help.view.appendTo(view); | ||
+ | rater.help.update(selected.id); | ||
+ | //rater.box.scrollTop(rater.box.height()); | ||
+ | }; | ||
+ | |||
+ | rater.select.click=function(e){if(e.type=='click')PD(e); | ||
+ | rater.select.current=$(this).data('rating'); | ||
+ | rater.select.draw(); | ||
+ | }; | ||
+ | |||
+ | rater.select.reset=function(e){PD(e);rater.select.init();}; | ||
+ | |||
+ | $('body').on('click','a[href=#rater-reset]',rater.select.reset); | ||
+ | $('body').on('click','a[href=#rater-submit]',function(e){PD(e); | ||
+ | rater.submit_rating(); | ||
+ | }); | ||
+ | |||
+ | rater.submit_rating=function(){ | ||
+ | rater.box.clear();stat=$('<pre>').appendTo(rater.box); | ||
+ | function w(s){stat.append(s);} | ||
+ | var r=rater.select.current; | ||
+ | if(r in {}||!(r in rater.ratings)) return; | ||
+ | var rating=rater.select.current.capitalize(); | ||
+ | if(!rater.raw_text) return; | ||
+ | //get token | ||
+ | w('Retrieving token... '); | ||
+ | $.get(wgScriptPath+'/api.php?format=json&action=query&prop=info&indexpageids=1&intoken=edit&titles='+wgPageName,function(d){ | ||
+ | var token=d.query.pages[d.query.pageids[0]].edittoken; | ||
+ | w('Ok ({0})\nReplacing quality template... '.format(token.slice(0,-2))); | ||
+ | console.log(token); | ||
+ | var text=rater.raw_text.replace(/{{quality[^}]*?}}/gi,''); | ||
+ | text='{{Quality|'+rating+'|~~\u007e~~}}'+text | ||
+ | //console.log(text) | ||
+ | w('Ok\nEditing page... ') | ||
+ | var e=encodeURIComponent; | ||
+ | var page=rater.page.name; | ||
+ | $.post(wgScriptPath+'/api.php', {action:'edit',title:rater.page.name,text:text, | ||
+ | token:token,minor:1,summary:'Rated article "{0}" using the rating script.'.format(rating)},function(d){ | ||
+ | //console.log(d,'DONE') | ||
+ | w('Finished!\nReloading...'); | ||
+ | $('body').load(rater.page.url + ' body',function(d){ | ||
+ | window.location.reload(); //maybe load w/ ajax? | ||
+ | }); | ||
+ | }); | ||
+ | }); | ||
+ | }; | ||
+ | |||
+ | //check for a provided hash... | ||
+ | if(window.location.hash.length){ | ||
+ | rater.auto_link=$('<a>').attr('href',window.location.hash).appendTo('body'); | ||
+ | setTimeout(function(){rater.auto_link.click()},100);//after this returns, anon for scope | ||
}; | }; | ||
Latest revision as of 23:10, 27 April 2013
/*
Rating Script (DF Wiki)
Improved version -- now uses jQuery, extra options (existence not guaranteed)
*/
//Like python: 'a{0}b'.format('c') == 'acb'
String.prototype.format=function(){s=this;for(i=0;i<arguments.length;i++){s=s.replace(RegExp('\\{'+i+'\\}','g'), arguments[i])};return s};
String.prototype.capitalize=function(){return this.slice(0,1).toUpperCase()+this.slice(1)};
addOnloadHook(function(){jQuery(function($){
SCOPE = this
var rater = {}
rater.event=$({});//for event bindings
//Temporary! (importScript doesn't seem to work here)
$.getScript(wgScript+'?title=User:Lethosor/raterwarn.js&action=raw');
function PD(e){//preventDefault
if(e && e['preventDefault'] && 'call' in e.preventDefault)
e.preventDefault()
}
function is_func(x){return !!(x&&x['call'])}
rater.page = {
name: wgPageName.replace(/_/g,' '),
ns:wgCanonicalNamespace||'Main',
url: wgScript+'?title='+wgPageName,
exists:!$('#left-navigation').find('li[class*=selected]').find('a[href*=redlink]').length,
load_time:$('body').html().match(/<!--.*-->/g).slice(-1)[0].match(/\d+\.\d+/)[0]
}
rater.is_valid_page = function(page){
if(!rater.page.exists) return false;
if(!page) page=wgPageName;
if('Masterwork DF2012 v0.31 40d 23a'.split(' ').indexOf(rater.page.ns)+1) return true
if($('#norate').length) return false
return false
};
rater.error_invalid_page=function(){
if('Special File Image Unused'.indexOf(rater.page.ns)+1||
rater.page.ns.toLowerCase().indexOf('talk')+1){
rater.box.clear().append('<span class="error">I\'m afraid I can\'t let you do that,'+
' Urist.</span><p>This page isn\'t an article, and doesn\'t have some of the necessary'+
' properties to be rated. <a href="#rater-cancel">Close this window</a></p>')
}
else if(!rater.page.exists){
rater.box.clear().append('<p class="error">This page doesn\'t exist!</p>')
}
else{
rater.box.clear().append('<span class="error">Invalid page</span>')
.append("<p>This page is in an invalid namespace. You can "+
"<a href='#rater-force'>view this page's rating anyway</a> or "+
"<a href='#rater-cancel'>close this window</a>.</p>")
}
};
// Set up UI
rater.overlay = $('<div>').css({width:'100%', height:'100%', top:0, left:0,
position:'fixed', 'background-color':'rgba(128,128,128,0.5)', 'z-index':9999})
.hide().appendTo('body');
rater.box = $('<div>').css({width:'80%', height:'80%', top:'10%', left:'10%',
position:'fixed', 'background-color':'white', 'z-index':10000, padding:'1em',overflow:'auto'})
.hide().appendTo('body');
rater.cancel_link = $('<a>').text('Cancel').attr('href','#rater-cancel').css({color:'red',
'float':'right'}).appendTo(rater.box);
rater.popup={};
rater.popup.overlay = $('<div>').css({width:'100%', height:'100%', top:0, left:0,
position:'fixed', 'background-color':'rgba(128,128,128,0.5)', 'z-index':10001})
.hide().appendTo('body');
rater.popup.box = $('<div>').css({width:'40%', height:'60%', top:'20%', left:'30%',
position:'fixed', 'background-color':'white', 'z-index':10002, padding:'1em',
overflow:'auto'})
.hide().appendTo('body');
rater.popup.close_link = $('<a>').text('Close').attr('href','#rater-popup-hide').css({color:'red',
'float':'right'}).appendTo(rater.popup.box);
rater.box.clear = function(){
rater.box.html('')
rater.box.append(rater.cancel_link)
.append($('<h2>').text('Rating '+rater.page.name));
rater.event.trigger('box-clear');
return rater.box;
};
rater.popup_show=function(e){//note _ - avoid $ clash
PD(e);
rater.popup.box.stop(1,1).fadeIn(500);
rater.popup.overlay.stop(1,1).fadeIn(500);
};
rater.popup_hide = function(e){
PD(e);
rater.popup.overlay.stop(1,1).fadeOut(500);
rater.popup.box.stop(1,1).fadeOut(500);
};
$('body').on('click','a[href=#rater-popup-hide]',rater.popup_hide);
rater.box.clear();
rater.popup.clear=function(){
rater.popup.box.html('').append(rater.popup.close_link);
};
rater.popup.clear();
rater.cancel = function(e){
PD(e);rater.show_link.removeClass('selected');
$('body').css({overflow:'auto'});
rater.overlay.stop(1,1).fadeOut(500);
rater.box.stop(1,1).fadeOut(500);
};
$('body').on('click','a[href=#rater-cancel]',rater.cancel);
// Set up link
rater.show_link = $("<li>").append($('<span>').append(
$("<a href='#rater-invoke'>").text('Rate')
));
$("#left-navigation #p-namespaces ul:nth(0)").append('<li><span><a></a></span></li>')
$("#left-navigation #p-namespaces ul:nth(0)").append(rater.show_link)
rater.invoke = function(e, force){
PD(e);$('body').css({overflow:'hidden'});
rater.overlay.stop(1,1).fadeIn(500);
rater.box.stop(1,1).fadeIn(500);
if(!rater.is_valid_page(wgPageName) && !force)
return rater.error_invalid_page();
rater.box.clear();rater.show_link.addClass('selected');
rater.box.append('<p>Performing automatic tests (<span class="rater-tests-left"></span> remaining), please wait...</p>');
rater.begin_tests();
};
$('body').on('click', 'a[href=#rater-invoke]', rater.invoke)
$('body').on('click', 'a[href=#rater-force]', function(e){rater.invoke(e,1)});
/*
Tests
Usage: Specify a URL to get data from and `processor` function to extract the
needed data
*/
var tests={};
tests.list={}; //list of all tests
tests.results={}; //shortcut: data[x]==lists[x].data
tests.random=Math.floor(Math.random()*1e10);
tests.num_waiting = 0;
tests.add = function(name, data_url, processor){
//Note: jQuery caches Ajax requests by default, no need to here
tests.list[name] = {data_url:data_url, processor:processor};
//Prevents caching for the first rating (reset on page load)
data_url+=((data_url.indexOf('?')+1)?'&':'?')+'_='+tests.random;
$.get(data_url, function(data){
tests.process(name, data);
});
tests.num_waiting++
};
tests.process = function(name,raw_data){
result = tests.list[name].processor(raw_data);
tests.list[name].result = tests.results[name] = result
tests.num_waiting--
$(".rater-tests-left").text(tests.num_waiting)
if(tests.num_waiting <= 0){
setTimeout(tests.all_complete, 1); //async
}
};
tests.all_callbacks=[]; //when all tests are done
tests.all_complete = function(){
for(i=0; i<tests.all_callbacks.length; i++){
tests.all_callbacks[i]();
}
};
tests.add_callback=function(func){
tests.all_callbacks.push(func);
};
rater.help={view:$('<div>').css({height:'100%'})};
rater.help.init=function(){
$.get(wgScript+'/DF:Quality',function(d){
d=$(d);
rater.help.data=[];
for(var i=0;i<=5;i++){
rater.help.data[i]=d.find('h3:nth({0})'.format(i)).nextUntil('h3');
rater.help.data[i].splice(0,0,d.find('h3:nth({0})'.format(i))[0]); // prepend header
};
rater.help.update();
});
};
rater.help.update=function(n){
if(!rater.help.data)return;
if(!(n+1)){
try{
n=rater.ratings[rater.select.current].id;
} catch(e){return}
}
rater.help.view.text('').append(rater.help.data[n]);
rater.help.view.find('.editsection').hide();
//rater.box.scrollTop(rater.box.height());
};
rater.begin_tests = function(){
render_url=rater.page.url+'&action=render'
raw_url=rater.page.url+'&action=raw'
rater.help.init()
tests.add('redlinks', render_url, function(data){
all_links = data.match(/<a .*<\/a>/g);
if(!all_links) return 0; //no links
total_redlinks=0;
$.each(all_links, function(i,link){
if(link.match(/href=.*redlink=1/)) total_redlinks++;
});
return total_redlinks
});
tests.add('editors', rater.page.url+'&action=history&limit=100', function(data){
all_editors = data.match(/<li>.*<\/li>/g)
if(!all_editors) return 0; //no editors
editors={};
$.each(all_editors, function(i,li){
ed = $(li).find('.mw-userlink:nth(0)').text()
if(!(ed in editors)) editors[ed]=0;
editors[ed]++
});
num=0;
for(i in editors){
if(i in {}) continue;
num++
}
editors.total=num;editors.total_edits=all_editors.length;
return editors;
});
tests.add('linkshere', wgScript+'/Special:WhatLinksHere/'+wgPageName, function(data){
return $(data).find('#mw-whatlinkshere-list').length;
});
tests.add('links', render_url, function(data){
return $(data).find('a[href*="'+wgScript+'"]').length;
});
tests.add('length', raw_url, function(data){
rater.raw_text=data;
var a={
'full':data.length,
'nospace':data.replace(/\s/g,'').length,
'notemplate':data.replace(/{{[^}]*?}}/g,'').length,
'raw':data.replace(/\s/g,'').replace(/{{[^}]*?}}/g,'').length
};
a.average=Math.round(.1 * a.full + .2*a.nospace + .3*a.notemplate + .4*a.raw)
return a
});
tests.add('html_length', render_url, function(data){
var a={'html':data.length,'text':$(data).text().length};
return a;
});
tests.add('verify',raw_url,function(data){
var m=data.match(/{{verify/g);return +(m&&m.length);
});
tests.add('current_rating',raw_url,function(data){
m=data.match(/{{quality[^}]*?}}/i);
return (m&&m.length&&m[0].slice(2,-2).split('|')[1])||''
});
tests.add_callback(function(){
rater.display_test_results();
});
};
rater.score_bool=function(v,y,n){
if(isNaN(Number(n))) n=-y;
return Number(v?y:n);
};
rater.score_int=function(v,weight,base){
if(!base) base=0;
return v*weight+base;
};
rater.metadata = {
'redlinks':{name:'Redlinks'},
'links': {name:'Outbound links'},
'linkshere': {name:'Incoming links'},
'editors': {name:'Editor count',str:function(o){return o.total},
int:function(o){return o.total;},
info:function(o,view){
tbl=$("<table>").css({width:'100%'}).append('<tr><th colspan="2">User</th><th>Edits</th></tr>').addClass('wikitable sortable').appendTo(view)
for(i in o){
if(i in {}||!i.indexOf('total')) continue;
tbl.append('<tr><td colspan="2"><a href="{2}/User:{0}">{0}</a>:</td><td>{1}</td></tr>'.format(i,o[i],wgScript))
}
tbl.append('<tr style="font-weight:bold"><td>Total:</td><td>{0}</td><td>{1}</td></tr>'
.format(o.total,o.total_edits))
},
},
'length': {str:function(obj){
return "Weighted: {0} ({1} characters, {2} without templates)"
.format(obj.average,obj.full,obj.notemplate);},
name:'Source length'},
html_length:{name:'Text length',
str:function(o){return '{0} (HTML: {1})'.format(o.text,o.html)},
int:function(o){return o.text}},
verify:{name:'{{Verify}} tags',score:function(o){
if(o<1) return 0; if(o==1) return -10; return o*-20}},
current_rating:{name:'Current rating', int:function(){return 0;}}
};
rater.ratings={
tattered:{id:1,color:{b:'#333',bg:'#ccc',c:'#333'},s:'x'},
fine:{id:2,color:{b:'#db8',bg:'#ffe0cc',c:'#ca7a02'},s:'+'},
superior:{id:3,color:{b:'#b8f',bg:'#e4ccff',c:'#80c'},s:'*'},
exceptional:{id:4,color:{b:'#9df',bg:'#cce4ff',c:'#08c'},s:'\u2261'},
masterwork:{id:5,color:{b:'#bd8',bg:'#e2fdce',c:'#72a329'},s:'\u263c'}
};
rater.display_test_results=function(){
var md=rater.metadata;
rater.box.clear();
data=tests.results;
for(var i in data){
name=md[i].name;
str=is_func(md[i].str)?md[i].str(data[i]):data[i];
app=''
if(is_func(md[i].info)){
app=$('<a href="#">[Info]</a>').data({f:md[i].info,d:data[i]})
.click(function(e){d=$(this).data()
rater.popup.clear(); rater.popup_show(e);
d.f(d.d,rater.popup.box.append($("<div>")))
}).css('padding-left','1em');
}
rater.box.append($("<p>"+name+": "+str+"</p>").append(app));
}
rater.score = 0
+rater.score_bool(!data.links,-25) //orphaned
+rater.score_bool(!data.linkshere,-30) //dead end
+rater.score_int(data.links,0.5)
+rater.score_int(data.linkshere,0.75)
+rater.score_int(data.redlinks,-5,10)
+rater.score_int(data.editors.total,20,-15)
;
rater.box.append($("<p>").text("Score: "+rater.score))
rater.select.init($("<div>").appendTo(rater.box));
};
rater.select={};
rater.select.view=$("<div>").css({padding:'.2em'});
rater.select.init=function(){
rater.select.current=rater.tests.results.current_rating.toLowerCase()||'tattered';
rater.select.view.appendTo(rater.box);
rater.select.draw();
};
rater.select.draw=function(){var c,selected,a,view=rater.select.view;
view.text('\nDesired rating: ');
list=$('<span>').css({'font-size':'.8em'}).appendTo(rater.select.view)
for(i in rater.ratings){if(i in {}) continue;
c=rater.ratings[i];
a=$('<span>').appendTo(list).data('rating',i).attr({tabindex:0}).css({cursor:'pointer'}); //not real link
a.append($('<span>').text(c.s+i.toUpperCase()+c.s)
.css({'text-decoration':'none','color':c.color.c}));
if(i==rater.select.current){
selected=rater.ratings[i];
a.find('span').css({'border-color':c.color.b,'background-color':c.color.bg,'border-width':1,'border-style':'solid','border-radius':2,padding:'.2em'})
}
a.on('click focus',rater.select.click);
list.append(' ');
}
if(rater.is_valid_page()){
rater.submit_link=$('<a>').attr({href:'#rater-submit'}).text("Submit").appendTo(view);
view.append(' ');
}
rater.reset_link=$('<a>').attr({href:'#rater-reset'}).text("Reset").appendTo(view);
rater.help.view.appendTo(view);
rater.help.update(selected.id);
//rater.box.scrollTop(rater.box.height());
};
rater.select.click=function(e){if(e.type=='click')PD(e);
rater.select.current=$(this).data('rating');
rater.select.draw();
};
rater.select.reset=function(e){PD(e);rater.select.init();};
$('body').on('click','a[href=#rater-reset]',rater.select.reset);
$('body').on('click','a[href=#rater-submit]',function(e){PD(e);
rater.submit_rating();
});
rater.submit_rating=function(){
rater.box.clear();stat=$('<pre>').appendTo(rater.box);
function w(s){stat.append(s);}
var r=rater.select.current;
if(r in {}||!(r in rater.ratings)) return;
var rating=rater.select.current.capitalize();
if(!rater.raw_text) return;
//get token
w('Retrieving token... ');
$.get(wgScriptPath+'/api.php?format=json&action=query&prop=info&indexpageids=1&intoken=edit&titles='+wgPageName,function(d){
var token=d.query.pages[d.query.pageids[0]].edittoken;
w('Ok ({0})\nReplacing quality template... '.format(token.slice(0,-2)));
console.log(token);
var text=rater.raw_text.replace(/{{quality[^}]*?}}/gi,'');
text='{{Quality|'+rating+'|~~\u007e~~}}'+text
//console.log(text)
w('Ok\nEditing page... ')
var e=encodeURIComponent;
var page=rater.page.name;
$.post(wgScriptPath+'/api.php', {action:'edit',title:rater.page.name,text:text,
token:token,minor:1,summary:'Rated article "{0}" using the rating script.'.format(rating)},function(d){
//console.log(d,'DONE')
w('Finished!\nReloading...');
$('body').load(rater.page.url + ' body',function(d){
window.location.reload(); //maybe load w/ ajax?
});
});
});
};
//check for a provided hash...
if(window.location.hash.length){
rater.auto_link=$('<a>').attr('href',window.location.hash).appendTo('body');
setTimeout(function(){rater.auto_link.click()},100);//after this returns, anon for scope
};
//export
rater.tests = tests;
window.rater=rater
return rater;
});});