User:Bradv/Menubar-dev.js

menubook = { settings: { enabled:    true, menulimit:  32, load: function { for (var name in menubook.settings) { if (typeof menubook.settings[name] != 'function') { var val = menubook.utils.readCookie('menubook_' + name); if (val) { switch (typeof menubook.settings[name]) { case 'boolean': menubook.settings[name] = (val == 'true'); break; case 'number': menubook.settings[name] = parseInt(val); break; default: menubook.settings[name] = val.toString; }                   }                }            }        },        save: function  { var cend = "; expires=Tue, 31-Dec-2030 23:59:59 GMT; path=/"; for (var name in menubook.settings) { if (typeof menubook.settings[name] != 'function') { document.cookie = 'menubook_' + name + '=' + menubook.settings[name].toString + cend; }           }                    }           },        styles: { stylesheet: null, setMenubarRules: function (visible) { var rules = [ /*ul { line-height: 1.5em; list-style-type: square; margin: .3em 0 0 1.5em; padding: 0; list-style-image: url(bullet.gif); } ol { line-height: 1.5em; margin: .3em 0 0 3.2em; padding: 0; list-style-image: none; } li { margin-bottom: .1em; } 'body {margin-top:2.5em;background-position:0 2.5em;}', '#p-cactions, #p-personal, #p-logo {margin-top:2em;}', '#menubar {position:fixed;top:0px;left:0px;width:100%;padding:0 1em;margin:0;line-height:2em;max-height:2em;font-size:1.2em;background-color:#f0f0f0;border-bottom:1px solid darkblue;z-index:10;white-space:nowrap;}', '#menubar ul {float:left;position:relative;display:inline;line-height:2em;list-style:none;margin:0;padding:0;}', '#menubar ul ul {position:absolute;display:block;line-height:1.8em;border:1px solid darkblue;background-color:#f0f0f0;overflow:auto;min-width:15em;min-height:1em;padding:0;margin:0;}', '#menubar li {position:relative;display:inline;list-style:none;margin:0;padding:0;}', '#menubar a.menuHeader {display:block;padding:0 .5em;margin:0;text-transform:none;text-decoration:none;font-weight:bold;color:darkblue;}', '#menubar a.menuItem {display:block;padding:0 1.5em;margin:0;text-transform:none;text-decoration:none;line-height:1.8em;height:1.8em;color:darkblue}', '#menubar a.menuHeader:hover, #menubar a.menuItem:hover, #menubar a.highlight {color:#f0f0f0;background-color:darkblue}', '#menubar li.break {border-bottom:1px solid darkblue;}', '#menubar li span.arrow {position:absolute;right:0.3em;}']; for (i=0; i<rules.length; i++) { menubook.styles.setRule(rules[i], visible); }       },            setRule: function (rule, visible) { if (!menubook.styles.stylesheet) { var nod = document.createElement('style'); nod.type = 'text/css'; nod.rel = 'stylesheet'; nod.media = 'screen'; nod.title = 'menubar'; document.getElementsByTagName('head')[0].appendChild(nod); for (var i=0; i<document.styleSheets.length; i++) { if (document.styleSheets[i].title == 'menubar') { menubook.styles.stylesheet = document.styleSheets[i]; break; }               }            }            var found=false; for (var i=0; i<menubook.styles.stylesheet.cssRules.length; i++) { var r = menubook.styles.stylesheet.cssRules[i]; if (r.selectorText==rule.substring(0,rule.indexOf('{'))) { found=true; break; }           }            if (!found && visible) menubook.styles.stylesheet.insertRule(rule, i); else if (found && !visible) menubook.styles.stylesheet.deleteRule(i); },       addRule: function (rule) {menubook.styles.setRule(rule, true)} },   utils: { 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 null; },       getSingleNode: function (context, expression) { var result = document.evaluate(expression, context, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null); return result.singleNodeValue; },       isAncestor: function (node, ofNode) { while(node.parentNode) { if (node.parentNode == ofNode) { return true; }               node = node.parentNode; }           return false; }   },    Menubar: new function  { this.divMenubar = null; this.element = null; this.menus = []; this.topzindex = 10; this.show = function { menubook.styles.setMenubarRules(true); if (!this.divMenubar) { this.divMenubar = document.createElement('div'); this.divMenubar.id = 'menubar'; this.divMenubar.object = this; this.divMenubar.addEventListener('mousedown', function (event) {                   if (this.style.zIndex < this.object.topzindex) {                        this.style.zIndex += this.object.topzindex;                    }                }, false); document.body.appendChild(this.divMenubar); this.element = document.createElement('ul'); this.divMenubar.appendChild(this.element); } else { this.divMenubar.style.display=''; }       }        this.hide = function  { menubook.styles.setMenubarRules(false); if (this.divMenubar) this.divMenubar.style.display='none'; }       this.addMenu = function (id, title, populateCallback, populateArgs) { var mi = new menubook.MenuItem(this, true); mi.anchor.textContent = title; var menu = mi.addChildMenu(populateCallback, populateArgs); this.menus[id] = mi; return mi; }   },    MenuItem: function (parentMenu, header) { //extends IMenuItem this.parentMenu = parentMenu; this.element = document.createElement('li'); this.element.object = this; this.anchor = document.createElement('a'); this.anchor.className = header ? 'menuHeader' : 'menuItem'; this.anchor.href = '#'; //this.anchor.onclick = function {return false}; this.anchor.object = this; this.element.appendChild(this.anchor); this.childMenu = null; this.parentMenu.element.appendChild(this.element);

this.insertBreak = function { this.element.className+=' break'; }               this.addChildMenu = function (populateCallback, populateArgs) { this.childMenu = new menubook.Menu(this, populateCallback, populateArgs) return this.childMenu; }       if (header) { this.anchor.addEventListener('click', function (event) {               if (this.object && this.object.childMenu) {                    if (!this.object.childMenu.visible) {                        this.object.childMenu.show;                        this.object.anchor.className += ' highlight';                    } else {                        this.object.childMenu.hide;                        this.object.anchor.className = this.object.anchor.className.replace('highlight', '');                    }                }            }, false); }   },    Menu: function (parentItem, populateCallback, populateArgs) { this.parentItem = parentItem; this.element = document.createElement('ul'); this.element.style.display = 'none'; this.element.object = this; this.parentItem.element.appendChild(this.element); this.menuItems = []; this.populateCallback = populateCallback; this.populateArgs = populateArgs; this.__defineGetter__("visible", function { return this.element.style.display!='none'; }); this.__defineGetter__("name", function { return this.parentItem.anchor.textContent; });

this.show = function { this.element.style.display=''; if (populateCallback) populateCallback(this, populateArgs); }       this.hide = function  { this.element.style.display='none'; }       this.addMenuItem = function  { var mi = new menubook.MenuItem(this); this.menuItems.push(mi); return mi; }       this.clear = function  { while (this.menuItems.length) { var mi = this.menuItems.pop; mi.element.parentNode.removeChild(mi); }       }    },        init: function  { menubook.settings.load; if (menubook.settings.enabled) { for (var i=0; i<menubook.initHooks.length; i++) menubook.initHooks[i]; menubook.init.done = true; } else { for (var i=0; i<menubook.hideHooks.length; i++) menubook.hideHooks[i]; }   },    initHooks: [ function {menubook.styles.setMenubarRules;} ],   addInitHook: function(f) {if (menubook.init.done) f; else menubook.initHooks.push(f);}, load: function (reload) { if (reload) menubook.init; if (menubook.settings.enabled) { for (var i=0; i<menubook.loadHooks.length; i++) menubook.loadHooks[i]; menubook.load.done = true; }   },    loadHooks: [ function {menubook.Menubar.show;} ],   addLoadHook: function(f) {if (menubook.load.done) f; else menubook.loadHooks.push(f);}, hideHooks: [ function {menubook.Menubar.hide;}, function { addOnloadHook(function {                mw.util.addPortletLink('p-personal', '#', 'Enable Menubook', 'enableMenubook', null, null, document.getElementById("pt-logout"));                with (document.getElementById('enableMenubook')) {                    style.fontWeight = 'bold';                    onclick = function  {                        menubook.settings.enabled = true;                        menubook.settings.save;                        this.parentNode.removeChild(this);                        menubook.load;                    }                }            }); }   ],    addHideHook: function(f) {menubook.hideHooks.push(f);} } menubook.init; $(menubook.load);

//CLOCK menubook.addLoadHook(function loadClock {   menubook.settings.clock=false;    //menubook.settings.load;    if (menubook.settings.clock) {        menubook.styles.addRule('#menubar_clock {position:fixed;right:0em;top:0em;padding:0 .5em;display:block;font-size:larger;font-weight:bolder}');        var el = document.createElement('a');        el.id='menubar_clock';        el.href = mw.config.get('wgServer') + mw.config.get('wgScriptPath') + '/index.php?title=' + encodeURIComponent(mw.config.get('wgPageName')) + '&action=purge';        menubook.Menubar.element.appendChild(el);        function updateClock {            var now = new Date;            var hh = now.getUTCHours;            var mm = now.getUTCMinutes;            var ss = now.getUTCSeconds;            var time = ( hh < 10 ? '0' + hh : hh ) + ':' + ( mm < 10 ? '0' + mm : mm ) + ':' + ( ss < 10 ? '0' + ss : ss );           el.textContent = time;            window.setTimeout(updateClock, 1000);        }        updateClock;    } });

//CONFIG MENU menubook.addLoadHook(function loadConfig {   menubook.Menubar.addMenu('config', '\u25BC', function (menu) { menu.clear; function addCheckbox (name, caption, indentlevel) { with (menu.addMenuItem) { var label = document.createElement('label');

var input = document.createElement('input'); input.type = 'checkbox'; input.value = name; input.checked = menubook.settings[name]; input.style.marginLeft = (indentlevel ? (indentlevel * 0.5) : 0) + 'em'; label.appendChild(input); label.appendChild(document.createTextNode(caption)); anchor.appendChild(label); input.addEventListener('click', function (event) {                   menubook.settings[event.target.value] = event.target.checked ? true : false;                    menubook.settings.save;                    menubook.load(true);                }, false); }           return element; }       addCheckbox('enabled', 'Enable Menubook'); addCheckbox('clock', 'Show clock'); for (var name in menubook.Menubar.menus) { if (name != menu.name) addCheckbox(name, menubook.Menubar.menus[name].anchor.textContent); }   }); });

// CLICK HACK HTMLElement.prototype.click = function { var evt = this.ownerDocument.createEvent('MouseEvents'); evt.initMouseEvent('click', true, true, this.ownerDocument.defaultView, 1, 0, 0, 0, 0, false, false, false, false, 0, null); this.dispatchEvent(evt); }

// OUTERHTML HACK - for debugging purposes only if(!document.documentElement.outerHTML){ Node.prototype.getAttributes = function{ var attStr = ""; if(this && this.attributes.length > 0){ for(a = 0; a < this.attributes.length; a ++){ attStr += " " + this.attributes.item(a).nodeName + "=\"";				attStr += this.attributes.item(a).nodeValue + "\""; }		}		return attStr; }

Node.prototype.getInsideNodes = function{ if(this){ var cNodesStr = "", i = 0; var iEmpty = /^(img|embed|input|br|hr)$/i; var cNodes = this.childNodes; for(i = 0; i < cNodes.length; i ++){ switch(cNodes.item(i).nodeType){ case 1 : cNodesStr += "<" + cNodes.item(i).nodeName.toLowerCase; if(cNodes.item(i).attributes.length > 0){ cNodesStr += cNodes.item(i).getAttributes; }						cNodesStr += (cNodes.item(i).nodeName.match(iEmpty))? "" : ">";						if(cNodes.item(i).childNodes.length > 0){ cNodesStr += cNodes.item(i).getInsideNodes; }						if(cNodes.item(i).nodeName.match(iEmpty)){ cNodesStr += " />"; } else { cNodesStr += ""; }						break; case 3 : cNodesStr += cNodes.item(i).nodeValue; break; case 8 : cNodesStr += ""; break; }			}			return cNodesStr; }	}

HTMLElement.prototype.outerHTML getter = function{ var strOuter = ""; var iEmpty = /^(img|embed|input|br|hr)$/i; switch(this.nodeType){ case 1 : strOuter += "<" + this.nodeName.toLowerCase; strOuter += this.getAttributes; if(this.nodeName.match(iEmpty)){ strOuter += " />"; } else { strOuter += ">" + this.getInsideNodes; strOuter += ""; }				break; case 3 : strOuter += this.nodeValue; break; case 8 : cNodesStr += ""; break; }		return strOuter; }

HTMLElement.prototype.outerHTML setter = function(str){ var iRange = document.createRange;

iRange.setStartBefore(this);

var strFragment = iRange.createContextualFragment(str); var sRangeNode = iRange.startContainer;

iRange.insertNode(strFragment); sRangeNode.removeChild(this); } }