User:Bradv/sidebar.js
Appearance
Code that you insert on this page could contain malicious content capable of compromising your account. If you import a script from another page with "importScript", "mw.loader.load", "iusc", or "lusc", take note that this causes you to dynamically load a remote script, which could be changed by others. Editors are responsible for all edits and actions they perform, including by scripts. User scripts are not centrally supported and may malfunction or become inoperable due to software changes. A guide to help you find broken scripts is available. If you are unsure whether code you are adding to this page is safe, you can ask at the appropriate village pump. This code will be executed when previewing this page. |
Documentation for this user script can be added at User:Bradv/sidebar. |
sidebar_queries = [
{ name: 'wl', url: "/w/api.php?format=xml&action=query&list=watchlist&wllimit=", tag: 'item'},
{ name: 'np', 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'},
{ name: 'onp', 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'},
{ name: 'rc', url: "/w/api.php?format=xml&action=query&list=recentchanges&rclimit=", tag: 'rc'}/*,
{ name: 'un', url: "/w/api.php?action=query&list=logevents&letype=newusers&format=xml&lelimit=", tag: 'item'}*/];
sidebar = {
enabled: false,
scrollwithpage: false,
paused: false,
portlets: [
{ type: 'query', name: 'Watchlist', query:'wl', enabled: true, items: 10, refresh: 5, titlelink:'/wiki/Special:Watchlist' },
{ type: 'query', name: 'New pages', query:'np', enabled: true, items: 10, refresh: 5, titlelink:'/wiki/Special:NewPages' },
{ type: 'query', name: 'Old unpatrolled', query:'onp', enabled: true, items: 10, refresh: 5, titlelink:'/w/index.php?title=Special:NewPages&dir=prev&hidepatrolled=1' },
{ type: 'query', name: 'Recent changes', query:'rc', enabled: true, items: 10, refresh: 5, titlelink:'/w/index.php?title=Special:RecentChanges&limit=50&hideliu=1' },
/*{ type: 'query', name: 'Usernames', query:'un', enabled: true, items: 10, refresh: 5, titlelink:'/w/index.php?title=Special%3ALog&type=newusers&user=&page='},*/
{ type: 'links', name: 'Bookmarks', enabled: true, links: [] }
],
ajax: []
};
sidebar.loadCookies=function() {
sidebar.enabled = (sidebar.readCookie('sidebar_enabled')=='true');
//sidebar.scrollwithpage = (sidebar.readCookie('sidebar_scrollwithpage')=='true');
var cookie = sidebar.readCookie('sidebar_portlets');
if (cookie) {
sidebar.portlets = [];
var arrPortlets = cookie.split('||');
for (var i=0; i<arrPortlets.length; i++) {
sidebar.portlets[i]={};
var s = arrPortlets[i].split('|');
switch (s[0]) {
case 'query':
sidebar.portlets[i].type = 'query';
sidebar.portlets[i].name = s[1];
sidebar.portlets[i].query = s[2];
sidebar.portlets[i].enabled = (s[3]=='true');
sidebar.portlets[i].items = s[4];
sidebar.portlets[i].refresh = s[5];
sidebar.portlets[i].titlelink = s[6];
break;
case 'links':
sidebar.portlets[i].type = 'links';
sidebar.portlets[i].name = s[1];
sidebar.portlets[i].enabled = (s[2]=='true');
sidebar.portlets[i].links = sidebar.readCookie('sidebar_'+s[1]).split('||');
break;
}
}
}
}
sidebar.saveCookies=function() {
var cend = "; expires=Tue, 31-Dec-2030 23:59:59 GMT; path=/";
document.cookie = 'sidebar_enabled=' + sidebar.enabled.toString() + cend;
//document.cookie = 'sidebar_scrollwithpage=' + sidebar.scrollwithpage.toString() + cend;
var arr = [];
for (var i=0; i<sidebar.portlets.length; i++) {
var p = sidebar.portlets[i];
switch (p.type) {
case 'query':
arr[i] = p.type +'|'+ p.name +'|'+ p.query +'|'+ p.enabled.toString() +'|'+ p.items +'|'+ p.refresh +'|'+ p.titlelink;
break;
case 'links':
arr[i] = p.type +'|'+ p.name +'|'+ p.enabled.toString();
var s = '';
if (p.links) {
s = p.links.join('||');
}
document.cookie = 'sidebar_'+p.name+'=' + s + cend;
break;
}
}
document.cookie = 'sidebar_portlets='+arr.join('||')+cend;
}
sidebar.pause = function () {
sidebar.paused=true;
p = document.getElementById('sidebar_ovl');
if (p) {
p.style.display='';
}
};
sidebar.refresh = function () {
if(sidebar.paused) {
sidebar.paused=false;
p = document.getElementById('sidebar_ovl');
if (p) {
p.style.display='none';
}
sidebar.loadCookies();
sidebar.drawSidebar();
}
};
sidebar.init = function () {
sidebar.loadCookies();
addPortletLink ('p-navigation', '#', 'Sidebar', 'toggleSidebar');
document.getElementById('toggleSidebar').setAttribute('onclick', 'sidebar.toggleSidebar();return false;');
sidebar.drawSidebar();
window.onblur = sidebar.pause;
window.onfocus = sidebar.refresh;
};
sidebar.drawSidebar=function() {
sb = document.getElementById('sidebar');
if (sidebar.enabled) {
if (sb) {
sb.style.display='';
} else {
sb = document.createElement('div');
sb.id='sidebar';
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;
//container = document.getElementById('p-personal').parentNode; - this works in place of the next line
container = document.getElementById('content');
if (!container) {
container = document.getElementById('mw_content');
}
container.appendChild(sb);
/* configuration disabled for now
div = document.createElement('div');
div.id='sidebar_configure';
div.style.position='absolute';
div.style.right='1em';
div.style.bottom='1em';
div.style.fontSize='x-small';
a = document.createElement('a');
a.setAttribute('nopopup', 'true');
a.href = "#";
a.setAttribute('onclick', 'sidebar.showConfigure();return false;');
a.appendChild(document.createTextNode('configure sidebar'));
div.appendChild(a)
sb.appendChild(div);
*/
div = document.createElement('div');
div.id='sidebar_ovl';
div.style.position='absolute';
div.style.top='0px';
div.style.right='0px';
div.style.width='100%';
div.style.height='100%';
sb.style.borderLeft='1px solid #bbbbbb;';
sb.style.backgroundColor=document.defaultView.getComputedStyle(document.body, null).backgroundColor;
div.style.opacity='.7';
div.zIndex=100;
div.style.display='none';
sb.appendChild(div);
/* we don't need a header
div = document.createElement('div');
div.id='sidebar_header';
div.style.backgroundColor='#F2F2CE';
div.style.border='1px solid #BFBFA3';
div.style.margin='.1em';
div.style.lineHeight='2em';
div.style.textAlign='center';
div.style.fontWeight='bold';
div.appendChild(document.createTextNode('Sidebar'));
span = document.createElement('span');
span.style.fontWeight='normal';
span.appendChild(document.createTextNode(' ['));
a = document.createElement('a');
a.setAttribute('nopopup', 'true');
a.href = "#";
a.setAttribute('onclick', 'sidebar.toggleSidebar();return false;');
a.appendChild(document.createTextNode('hide'));
span.appendChild(a);
span.appendChild(document.createTextNode(']'));
div.appendChild(span);
sb.appendChild(div);
*/
}
if (sidebar.scrollwithpage) {
sb.style.position='absolute';
} else {
sb.style.position='fixed';
}
var spacer = (sb.offsetWidth)+'px';
/*
mwheader = document.getElementById('mw_header'); //modern skin only
if (mwheader) {
mwheader.style.marginRight=spacer;
mwheader.style.position='static';
}
*/
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;
}
//document.body.style.marginRight=spacer; - this works too
sb.parentNode.style.marginRight=spacer;
for (var i=0; i<sidebar.portlets.length; i++) {
sidebar.drawPortlet(i);
}
} else {
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='';
}
//document.body.style.marginRight=''; - this works too
if (sb) {
sb.parentNode.style.marginRight='';
sb.style.display='none';
}
}
}
sidebar.drawPortlet=function(index) {
if (!sidebar.enabled || sidebar.paused) return false;
var ptl = sidebar.portlets[index];
sidebar.makePortlet(ptl.name, ptl.titlelink, 'p-sb'+index, ptl.enabled, 'sidebar.toggle('+index+')');
if (ptl.enabled) {
if (ptl.type=='query') {
if (!sidebar.ajax) {
sidebar.ajax = [];
}
sidebar.ajax[index] = sajax_init_object();
if (sidebar.ajax[index]) {
var queryIndex = null;
for (var j=0; j<sidebar_queries.length; j++) {
if (sidebar_queries[j].name==ptl.query) {
queryIndex = j;
}
}
sidebar.ajax[index].onreadystatechange = function() {
if(sidebar.ajax[index].readyState == 4) {sidebar.portletCallback(index, queryIndex);}
};
url = sidebar_queries[queryIndex].url + ptl.items;
sidebar.ajax[index].open("GET", url, true);
sidebar.ajax[index].send(null);
} else {
pBody = document.getElementById('p-sb'+index);
while (pBody.firstChild) {
pBody.removeChild(pBody.firstChild);
}
}
} else if (ptl.type=='links') {
pBody = document.getElementById('p-sb'+index);
while (pBody.firstChild) {
pBody.removeChild(pBody.firstChild);
}
for (var i=0; i<ptl.links.length; i++) {
var url = ptl.links[i].split('|')[0];
var title = ptl.links[i].split('|')[1];
if (url && title) {
var p = createLine(pBody);
var a = document.createElement('a');
//a.setAttribute('nopopup', 'true'); //FIXME
a.href = url;
a.title = title;
a.appendChild(document.createTextNode(title));
p.appendChild(a);
p.appendChild(document.createTextNode(' ('));
a = document.createElement('a');
a.setAttribute('nopopup', 'true');
a.setAttribute('href', '#');
a.setAttribute('onclick', 'sidebar.removeBookmark('+index+','+i+');return false;');
a.appendChild(document.createTextNode('x'));
p.appendChild(a);
p.appendChild(document.createTextNode(')'));
}
}
var p = createLine(pBody);
p.style.lineHeight="100%";
p.style.fontSize = 'x-small';
p.style.margin = '0px';
p.style.textAlign = 'right';
var a = document.createElement('a');
a.setAttribute('nopopup', 'true');
a.href = '#';
a.setAttribute('onclick', 'sidebar.addBookmark('+index+');return false;');
a.appendChild(document.createTextNode('add'));
p.appendChild(a);
}
}
}
sidebar.portletCallback=function(index, queryIndex) {
pBody = document.getElementById('p-sb'+index);
while (pBody.firstChild) {
pBody.removeChild(pBody.firstChild);
}
var url = sidebar_queries[queryIndex].url;
var tag = sidebar_queries[queryIndex].tag;
var patrol = (url.indexOf('patrolled')>=0);
var items;
try {
items = sidebar.ajax[index].responseXML.documentElement.getElementsByTagName(tag);
} catch (e) {
//var p = createLine(pBody);
//p.appendChild(document.createTextNode('update failed2'));
return;
}
for (var i=0; i<items.length; i++) {
var title = items[i].getAttribute('title');//.replace(/&/, "%26", "g");
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 (rcid) {
// if (patrol) not_patrolled = (items[i].getAttribute('patrolled')==null);
// item_url = mw.config.get('wgScript') + '?title=' + escape(title.replace(' ', '_', "g")) + '&rcid=' + rcid;//+ '&redirect=no'; (this screws up Friendly)
// } else {
// //item_url = mw.config.get('wgArticlePath').replace("$1", escape(title.replace(' ', '_', "g")));
// item_url = mw.config.get('wgScript') + '?title=' + escape(title.replace(' ', '_', "g")) + '&oldid=' + revid;
// }
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'); //FIXME
a.href=item_url;
a.title=title;
a.appendChild(document.createTextNode(title));
var p = createLine(pBody);
p.appendChild(a);
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', 'sidebar.patrol("'+item_url+'&action=markpatrolled");return false;');
ap.appendChild(document.createTextNode('p'));
p.appendChild(ap);
p.appendChild(document.createTextNode(']'));
}
}
setTimeout('sidebar.drawPortlet('+index+')', sidebar.portlets[index].refresh * 1000);
}
sidebar.patrol=function(url) {
myAjax = sajax_init_object();
myAjax.open("GET", url, true);
myAjax.send(null);
}
sidebar.addBookmark=function(portletIndex) {
var url = window.location.pathname+window.location.search+window.location.hash;
for (var i=0; i<sidebar.portlets[portletIndex].links.length; i++)
{
if (sidebar.portlets[portletIndex].links[i].split('|')[0] == url)
{
return;
}
}
sidebar.portlets[portletIndex].links.push(url + '|' + mw.config.get('wgTitle'));
sidebar.saveCookies();
sidebar.drawPortlet(portletIndex);
}
sidebar.removeBookmark=function(portletIndex, index) {
sidebar.portlets[portletIndex].links.splice(index, 1);
sidebar.saveCookies();
sidebar.drawPortlet(portletIndex);
}
sidebar.makePortlet=function(title, titleLink, id, enabled, toggleFunction) {
var sb = document.getElementById('sidebar');
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);
}
if (enabled) {
p.style.display='';
} else {
p.style.display='none';
}
}
function createLine(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;
}
sidebar.toggleSidebar=function() {
sidebar.enabled = !sidebar.enabled;
sidebar.saveCookies();
sidebar.drawSidebar();
}
sidebar.toggle=function(index) {
sidebar.portlets[index].enabled = !sidebar.portlets[index].enabled;
sidebar.saveCookies();
sidebar.drawPortlet(index);
}
sidebar.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 '';
}
sidebar.showConfigure=function() {
var sb = document.getElementById('sidebar');
var ovl = document.createElement('div');
ovl.id='sbc_ovl';
ovl.style.position='fixed';
ovl.style.left=0;
ovl.style.top=0;
ovl.style.width='100%';
ovl.style.height='100%';
ovl.style.zIndex=99;
ovl.style.backgroundColor='gray';
ovl.style.opacity='.2';
ovl.setAttribute('onclick', 'sidebar.hideConfigure();return false;');
sb.parentNode.appendChild(ovl);
var wnd = document.createElement('div');
wnd.id='sbc_wnd';
wnd.style.position='fixed';
wnd.style.left='50%';
wnd.style.top=ovl.clientHeight/2+'px';
wnd.style.width='60em';
wnd.style.height='40em';
wnd.style.marginLeft='-30em';
wnd.style.marginTop='-20em';
wnd.style.padding='.5em';
wnd.style.zIndex=100;
wnd.style.backgroundColor='#FFFFF5';
wnd.style.border='1px solid #BFBFA3';
wnd.style.opacity='1';
sb.parentNode.appendChild(wnd);
div = document.createElement('div');
div.id='sbc_hdr';
div.style.backgroundColor='#F2F2CE';
div.style.border='1px solid #BFBFA3';
div.style.margin='.1em';
div.style.lineHeight='2em';
div.style.textAlign='center';
div.style.fontWeight='bold';
div.appendChild(document.createTextNode('Sidebar Configuration'));
span = document.createElement('span');
span.style.fontWeight='normal';
span.appendChild(document.createTextNode(' ['));
a = document.createElement('a');
a.setAttribute('nopopup', 'true');
a.href = "#";
a.setAttribute('onclick', 'sidebar.hideConfigure();return false;');
a.appendChild(document.createTextNode('hide'));
span.appendChild(a);
span.appendChild(document.createTextNode(']'));
div.appendChild(span);
wnd.appendChild(div);
}
sidebar.hideConfigure=function() {
var div = document.getElementById('sbc_ovl');
div.parentNode.removeChild(div);
div = document.getElementById('sbc_wnd');
div.parentNode.removeChild(div);
}
addOnloadHook(sidebar.init);