sprint = {
enabled: false,
paused: false,
portlets: [
{ id: 'wl', enabled: true, items: 10, refresh: 5 },
{ id: 'np', enabled: true, items: 10, refresh: 5 },
{ id: 'onp', enabled: true, items: 10, refresh: 5 },
{ id: 'rc', enabled: true, items: 10, refresh: 5 }
],
ajax: [],
ajaxPreview: null
};
sprint.modules = [
{ id: 'wl',
type: 'query',
title: 'Watchlist',
url: "/w/api.php?format=xml&action=query&list=watchlist&wllimit=",
tag: 'item',
titlelink:'/wiki/Special:Watchlist'},
{ id: 'np',
type: 'query',
title: 'New Pages',
url: "/w/api.php?action=query&format=xml&list=recentchanges&rcshow=!bot|!redirect&rctype=new&rcnamespace=0&rcprop=title|timestamp|ids|patrolled&rclimit=",
tag: 'rc',
titlelink:'/wiki/Special:NewPages'},
{ id: 'onp',
type: 'query',
title: 'Oldest Unpatrolled',
url: "/w/api.php?action=query&format=xml&list=recentchanges&rcshow=!bot|!redirect|!patrolled&rctype=new&rcnamespace=0&rcprop=title|timestamp|ids|patrolled&rcdir=newer&rclimit=",
tag: 'rc',
titlelink:'/w/index.php?title=Special:NewPages&dir=prev&hidepatrolled=1' },
{ id: 'rc',
type: 'query',
title: 'Recent Changes',
url: "/w/api.php?format=xml&action=query&list=recentchanges&rclimit=",
tag: 'rc',
titlelink:'/w/index.php?title=Special:RecentChanges&limit=50&hideliu=1' }
];
m_zIndex=101;
sprint.loadCookies=function() {
sprint.enabled = (sprint.readCookie('sprint_enabled')=='true');
var cookie = sprint.readCookie('sprint_portlets');
if (cookie) {
sprint.portlets = [];
var arrPortlets = cookie.split('||');
for (var i=0; i<arrPortlets.length; i++) {
sprint.portlets[i]={};
var s = arrPortlets[i].split('|');
sprint.portlets[i].id = s[0];
sprint.portlets[i].enabled = (s[1]=='true');
sprint.portlets[i].items = s[2];
sprint.portlets[i].refresh = s[3];
}
}
for (var i=0; i<sprint.portlets.length; i++) {
var p = sprint.portlets[i];
for (var j=0; j<sprint.modules.length; j++) {
var m = sprint.modules[j];
if (p.id==m.id) {
p.module = m;
}
}
}
};
sprint.saveCookies=function() {
var cend = "; expires=Tue, 31-Dec-2030 23:59:59 GMT; path=/";
document.cookie = 'sprint_enabled=' + sprint.enabled.toString() + cend;
var arr = [];
for (var i=0; i<sprint.portlets.length; i++) {
var p = sprint.portlets[i];
arr[i] = p.id + '|' + p.enabled.toString() + '|' + p.items + '|' + p.refresh;
}
document.cookie = 'sprint_portlets='+arr.join('||')+cend;
};
sprint.pause = function () {
sprint.paused=true;
p = document.getElementById('sprint_ovl');
if (p) {
p.style.display='';
}
};
sprint.refresh = function () {
if(sprint.paused) {
sprint.paused=false;
p = document.getElementById('sprint_ovl');
if (p) {
p.style.display='none';
}
sprint.loadCookies();
sprint.drawSprint();
}
};
sprint.init = function () {
sprint.loadCookies();
mw.util.addPortletLink ('p-personal', '#', 'My Sidebar', 'toggleSprint');
document.getElementById('toggleSprint').setAttribute('onclick', 'sprint.toggleSprint();return false;');
sprint.drawSprint();
window.onblur = sprint.pause;
window.onfocus = sprint.refresh;
importStylesheetURI('/skins-1.5/common/diff.css');
};
sprint.drawSprint=function() {
sb = document.getElementById('sprint');
if (sprint.enabled) {
if (sb) {
sb.style.display='';
} else {
//Create the main sprint bar
sb = document.createElement('div');
sb.id='sprint';
sb.className='portlet';
sb.style.width='12em';
sb.style.top='0px';
sb.style.right='0px';
sb.style.bottom='0px';
sb.style.zIndex=90;
sb.style.margin='0';//'.1em';
sb.style.padding='.5em';
sb.style.position='absolute';
sb.style.borderLeft='1px solid #bbbbbb;';
sb.style.backgroundColor=document.defaultView.getComputedStyle(document.body, null).backgroundColor;
sb.style.position='fixed';
//Find the container where the sprint bar goes.
//This differs between monobook and modern skins.
container = document.getElementById('content');
if (!container) {
container = document.getElementById('mw_content');
}
container.appendChild(sb);
//Create the overlay for when it is paused (out of focus)
ovl = document.createElement('div');
ovl.id='sprint_ovl';
ovl.style.position='absolute';
ovl.style.top='0px';
ovl.style.right='0px';
ovl.style.width='100%';
ovl.style.height='100%';
ovl.style.borderLeft='1px solid #bbbbbb;';
ovl.style.backgroundColor=document.defaultView.getComputedStyle(document.body, null).backgroundColor;
ovl.zIndex=100;
ovl.style.display='none';
p = document.createElement('p');
p.style.position='absolute';
p.style.top='5em';
p.style.width='100%';
p.style.fontSize='1em';
p.style.lineHeight='2em';
p.style.textAlign='center';
p.style.color='#bbbbbb';
p.appendChild(document.createTextNode('Updates paused'));
p.appendChild(document.createElement('br'));
p.appendChild(document.createTextNode('Click to resume'));
ovl.appendChild(p);
sb.appendChild(ovl);
}
//Set the spacer between the main body and the Sprint sidebar
var spacer = (sb.offsetWidth)+'px';
topbar = document.evaluate('//div[@id="p-personal"]//div[@class="pBody"]',
document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
if (topbar.singleNodeValue) {
topbar.singleNodeValue.style.marginRight=spacer;
}
sb.parentNode.style.marginRight=spacer;
//Draw the portlets
for (var i=0; i<sprint.portlets.length; i++) {
sprint.drawPortlet(i);
}
} else { //Hide the sprint bar, if it has already been drawn
topbar = document.evaluate('//div[@id="p-personal"]//div[@class="pBody"]',
document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
if (topbar.singleNodeValue) {
topbar.singleNodeValue.style.marginRight='';
}
if (sb) {
sb.parentNode.style.marginRight='';
sb.style.display='none';
}
}
};
//Draw each of the portlets. Called by drawSprint()
sprint.drawPortlet=function(index) {
if (!sprint.enabled || sprint.paused) return false;
var ptl = sprint.portlets[index];
sprint.makePortlet(ptl.module.title, ptl.module.titlelink, 'p-sb'+index, ptl.enabled, 'sprint.toggle('+index+')');
if (ptl.enabled) {
if (!sprint.ajax) {
sprint.ajax = [];
}
sprint.ajax[index] = sajax_init_object();
if (sprint.ajax[index]) {
sprint.ajax[index].onreadystatechange = function() {
if(sprint.ajax[index].readyState == 4) {sprint.portletCallback(index);}
};
url = ptl.module.url + ptl.items;
sprint.ajax[index].open("GET", url, true);
sprint.ajax[index].send(null);
} else {
pBody = document.getElementById('p-sb'+index);
while (pBody.firstChild) {
pBody.removeChild(pBody.firstChild);
}
}
}
};
sprint.portletCallback=function(index) {
var url = sprint.portlets[index].module.url;
var tag = sprint.portlets[index].module.tag;
var items;
try {
items = sprint.ajax[index].responseXML.documentElement.getElementsByTagName(tag);
} catch (e) {
setTimeout('sprint.drawPortlet('+index+')', sprint.portlets[index].refresh * 1000);
return;
}
pBody = document.getElementById('p-sb'+index);
while (pBody.firstChild) {
pBody.removeChild(pBody.firstChild);
}
var patrol = (url.indexOf('patrolled')>=0);
for (var i=0; i<items.length; i++) {
var title = items[i].getAttribute('title');
var rcid = items[i].getAttribute('rcid');
var revid = items[i].getAttribute('revid');
var type = items[i].getAttribute('type');
var item_url;
var not_patrolled=false;
if (type=='new') {
if (patrol) not_patrolled = (items[i].getAttribute('patrolled')==null);
item_url = mw.config.get('wgScript') + '?title=' + title.replace(' ', '_', "g").replace('&', '%26', "g") + '&rcid=' + rcid;//+ '&redirect=no'; (this screws up Friendly)
} else {
item_url = mw.config.get('wgScript') + '?title=' + title.replace(' ', '_', "g").replace('&', '%26', "g") + '&oldid=' + revid;
}
var a = document.createElement('a');
a.setAttribute('nopopup', 'true'); //TODO: Test interaction with popups
a.href=item_url;
a.title=title;
a.appendChild(document.createTextNode(title));
var p = sprint.createLine(pBody);
p.appendChild(a);
p.appendChild(document.createTextNode(' ['));
pre = document.createElement('a');
pre.setAttribute('nopopup', 'true');
pre.setAttribute('href', '#');
pre.setAttribute('onclick', 'sprint.showPreview("'+title+'", "'+item_url+'&diff=prev&action=render");return false;');
pre.appendChild(document.createTextNode('preview'));
p.appendChild(pre);
p.appendChild(document.createTextNode(']'));
if (not_patrolled) {
p.style.fontWeight='bold';
p.appendChild(document.createTextNode(' ['));
ap = document.createElement('a');
ap.setAttribute('nopopup', 'true');
ap.setAttribute('href', '#');
ap.setAttribute('onclick', 'sprint.patrol("'+item_url+'&action=markpatrolled");return false;');
ap.appendChild(document.createTextNode('patrol'));
p.appendChild(ap);
p.appendChild(document.createTextNode(']'));
}
}
setTimeout('sprint.drawPortlet('+index+')', sprint.portlets[index].refresh * 1000);
};
sprint.showPreview=function(title, url) {
var aj = sajax_init_object();
if (aj) {
var wnd = document.createElement('div');
wnd.id='sprint_previewWindow';
wnd.style.position='fixed';
wnd.style.padding='10px';
wnd.style.zIndex=++m_zIndex;
wnd.style.backgroundColor='white';
wnd.style.border='2px solid #aaaaaa';
wnd.style.width='60em';
wnd.style.height='30em';
wnd.style.minWidth='20em';
wnd.style.minHeight='10em';
//This is where we place the preview window - TODO: Check for modern skin
var obj = document.getElementById('column-one');
obj.appendChild(wnd);
wnd.style.left=parseInt(window.innerWidth-wnd.clientWidth)/2 + 'px';
wnd.style.top=parseInt(window.innerHeight-wnd.clientHeight)/2 + 'px';
var hdr = document.createElement('div');
hdr.style.position='relative';
hdr.style.width='100%';
hdr.style.height='2em';
hdr.style.borderBottom='1px solid #aaaaaa';
hdr.style.cursor='move';
wnd.appendChild(hdr);
var closeButton = document.createElement('a');
closeButton.href='#';
closeButton.style.position='absolute';
closeButton.style.top='10px';
closeButton.style.right='10px';
closeButton.onclick = function () {wnd.parentNode.removeChild(wnd); return false;};
closeButton.innerHTML = '<img src="http://upload.wikimedia.org/wikipedia/commons/thumb/5/52/Nuvola_apps_error.png/18px-Nuvola_apps_error.png"/>';
wnd.appendChild(closeButton);
var content = document.createElement('div');
content.id='sprint_previewContent';
content.style.position='relative';
content.style.clear='both';
content.style.overflow='scroll';
content.style.height=parseInt(wnd.clientHeight - hdr.offsetHeight - parseInt(wnd.style.padding)*2)+'px';
content.style.lineHeight='1.5em';
wnd.appendChild(content);
wnd.onmousedown=function(event) {
if (wnd.style.zIndex < m_zIndex) {
wnd.style.zIndex=++m_zIndex;
}
}
hdr.onmousedown=function(event) {
wnd.initialX = parseInt( event.clientX - wnd.offsetLeft );
wnd.initialY = parseInt( event.clientY - wnd.offsetTop );
window.onmouseup=function(event) {
window.onmousemove=null;
window.onmouseup=null;
wnd.style.opacity='';
content.style.display='';
}
window.onmousemove=function(event) {
if (!content.style.display) {
wnd.style.opacity='.8';
content.style.display='none';
}
wnd.style.left=event.clientX-wnd.initialX+'px';
wnd.style.top=event.clientY-wnd.initialY+'px';
}
}
var resize = document.createElement('div');
resize.id='sprint_previewResize';
resize.style.position='absolute';
resize.style.bottom='0px';
resize.style.right='0px';
resize.style.height='20px';
resize.style.width='20px';
resize.style.cursor='se-resize';
wnd.appendChild(resize);
resize.onmousedown=function(event) {
wnd.initialWidth = parseInt( event.clientX - wnd.offsetWidth );
wnd.initialHeight = parseInt( event.clientY - wnd.offsetHeight );
window.onmouseup=function(event) {
window.onmousemove=null;
window.onmouseup=null;
wnd.style.opacity='';
content.style.height=parseInt(wnd.clientHeight - hdr.offsetHeight - parseInt(wnd.style.padding)*2)+'px';
content.style.display='';
}
window.onmousemove=function(event) {
if (!content.style.display) {
wnd.style.opacity='.8';
content.style.display='none';
}
wnd.style.width=event.clientX-wnd.initialWidth-parseInt(wnd.style.padding)*2+'px';
wnd.style.height=event.clientY-wnd.initialHeight-parseInt(wnd.style.padding)*2+'px';
}
}
hdr.innerHTML='<a href="/wiki/'+title+'" style="font-size:1.5em;">'+title+'</a>';
content.innerHTML='Loading...';
aj.onreadystatechange = function() {
if(aj.readyState == 4 && aj.status == 200) {
var htm;
htm = aj.responseText;
content.innerHTML = htm;
content.id = 'bodyContent'; //TODO: Find a better way to make the page format correctly
}
}
aj.open("GET", url, true);
aj.send(null);
}
};
sprint.patrol=function(url) {
var myAjax = sajax_init_object();
myAjax.open("GET", url, true);
myAjax.send(null);
};
sprint.makePortlet=function(title, titleLink, id, enabled, toggleFunction) {
var sb = document.getElementById('sprint');
var a;
var hdr = document.getElementById('hdr' + id);
if (hdr) {
while (hdr.firstChild) {
hdr.removeChild(hdr.firstChild);
}
} else {
hdr = document.createElement('h5');
hdr.id = 'hdr' + id;
sb.appendChild(hdr);
}
if (titleLink) {
var a = document.createElement('a');
a.setAttribute('nopopup', 'true');
a.id = 'lnk' + id;
a.setAttribute('href', titleLink);
a.appendChild(document.createTextNode(title));
hdr.appendChild(a);
} else {
hdr.appendChild(document.createTextNode(title));
}
hdr.appendChild(document.createTextNode(' ['));
a = document.createElement('a');
a.setAttribute('nopopup', 'true');
a.id = 'show' + id;
a.setAttribute('href', '#');
a.setAttribute('onclick', toggleFunction+';return false;');
if (enabled) {
a.appendChild(document.createTextNode('hide'));
} else {
a.appendChild(document.createTextNode('show'));
}
hdr.appendChild(a);
hdr.appendChild(document.createTextNode(']'));
hdr.appendChild(document.createElement('br'));
var p = document.getElementById(id);
if (!p) {
p = document.createElement('div');
p.setAttribute('class', 'pBody');
p.setAttribute('id', id);
sb.appendChild(p);//, document.getElementById('sprint_ovl'));
}
if (enabled) {
p.style.display='';
} else {
p.style.display='none';
}
};
sprint.createLine=function(pBody) {
var p = document.createElement('p');
p.style.lineHeight='1em';
p.style.fontSize='95%';
p.style.margin='0px';
p.style.padding='.1em';
pBody.appendChild(p);
return p;
};
sprint.toggleSprint=function() {
sprint.enabled = !sprint.enabled;
sprint.saveCookies();
sprint.drawSprint();
};
sprint.toggle=function(index) {
sprint.portlets[index].enabled = !sprint.portlets[index].enabled;
sprint.saveCookies();
sprint.drawPortlet(index);
};
sprint.readCookie=function(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(';');
for(var i=0;i < ca.length;i++) {
var c = ca[i];
while (c.charAt(0)==' ') { c = c.substring(1,c.length); }
if (c.indexOf(nameEQ) === 0) { return c.substring(nameEQ.length,c.length); }
}
return '';
};
$(sprint.init);