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 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 var p = sprint.portlets[i]; for (var j=0; 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 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.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 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);';