User:Bradv/sprint.js

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 = ''; 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=''+title+''; 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);