User:Js/mwmenu.js

//Universal menu. Use "VV" link in right top corner. Alpha version.

var isIE = navigator.userAgent.indexOf('MSIE') != -1

var mnu = function(createFunction, divId){

var menuObj = this, menuDiv, isMenuVisible

function hide{ menuDiv.style.display='none' isMenuVisible=false } function show(e){ if (!menuDiv) create menuDiv.style.display='block' dom.positionMenu(menuDiv, e) isMenuVisible=true } function create{ addMenuSheet menuDiv = document.createElement('div') menuDiv.id = divId || '' menuDiv.className = 'amenu' menuDiv.addEventListener('mouseup', onMouseUp) document.body.appendChild(menuDiv) createFunction(menuObj) }

var arrow = document.createElement('div') arrow.appendChild(document.createTextNode('>')) arrow.className = 'arrow'

function addLI (toMenu, clss, html, tooltip){ toMenu = toMenu || menuDiv var ul = toMenu.getElementsByTagName('ul')[0] if (!ul){ ul = document.createElement('ul') toMenu.appendChild(ul) }  var li = document.createElement('li') if (clss) li.className = clss if (html) li.innerHTML = html if (tooltip) li.title = tooltip ul.appendChild(li) return li }

//methods this.run = function(e){if (isMenuVisible) hide; else show(e)}

this.addLink = function (toMenu, link, name, tip){ return li = addLI(toMenu, 'link', ''+name+'', tip) }

this.addSub = function (toMenu, name, tip){ var li = addLI(toMenu, 'submenu close', '', tip) li.appendChild(arrow.cloneNode(true)) span = document.createElement('span') span.className = 'header' span.appendChild(document.createTextNode(name)) li.appendChild(span) li.appendChild(document.createElement('ul')) //li.style.cursor = 'pointer' return li }

this.addScript = function (toMenu, expr, name, tip){ var li = addLI(toMenu, 'script', ' '+name+' ', tip) li.script = expr return li }

this.addInsert = function(toMenu, name, tagOpen, tagClose, Sample){ tagOpen = tagOpen || '' tagClose = tagClose || '' Sample = Sample || '' name = name || tagOpen + tagClose var li = addLI(toMenu, 'script', name, tagOpen + tagClose) li.script = 'insertTags("'+tagOpen+'","'+tagClose+'","'+Sample+'")' }

function onMouseUp (e){ e = e || window.event var isMiddle = ((isIE && e.button == 4) || (!isIE && e.button == 1)) var targ = e.srcElement || e.target //if (targ.nodeName == 'LI') { hide; return } if (targ.parentNode.nodeName == 'LI') targ = targ.parentNode if (targ.nodeName != 'LI') { hide; return } var type = targ.className.split(' ')[0] switch(type){ case 'submenu': if (isMiddle) return var lis = targ.parentNode.getElementsByTagName('li') for (var i=0; i<lis.length; i++) 		//close neibourghs if (isSub(lis[i]) && lis[i]!=targ) closeSub(lis[i]) if (isSubOpen(targ)) closeSub(targ) else openSub(targ) return case 'link': break case 'script': runScript(targ.script) break default: jsMsg('Error: unknown menu item type: ' + type) } hide }

function isSub(li){ return li.className.indexOf('submenu') != -1 } function isSubOpen(sub){ return sub.className.indexOf('open') != -1 } function closeSub(sub){ sub.className = sub.className.replace(/open|close/, 'close') var arrow = sub.getElementsByTagName('div')[0] if (arrow) arrow.firstChild.data = '>' } function openSub(sub){ sub.className = sub.className.replace(/open|close/, 'open') var arrow = sub.getElementsByTagName('div')[0] if (arrow) arrow.firstChild.data = 'v' }

function runScript(expr) { var runExpr = function{return eval(expr)} var isDefined = function(func){ try {eval(func); return true} catch(e){ return false} } if (expr.indexOf('#') == -1) return runExpr //otherwise this is an external script var url = expr.split('#')[0] expr = expr.split('#')[1] if (isDefined(expr.split('(')[0])) return runExpr //in case it was already loaded //check various url prefixes if (url.indexOf('css:') == 0)  return jsMsg('CSS importing is not implemented yet') else if (url.indexOf('local:') == 0) //for debugging   url = 'http://localhost/' + url.substring(6) + '.js?' + Math.random else if (url.indexOf('en:') == 0)   url = 'http://en.wikipedia.org/w/index.php?action=raw&ctype=text/javascript&title=' + url.substring(3) else if (url.indexOf('http://') != 0) //this project script   url = mw.config.get('wgScript') + '?action=raw&ctype=text/javascript&title=' + url   //log ('Script: ' +  url + ' # ' + expr) //load external script file var s = document.createElement('script') s.type = 'text/javascript'  s.src = url  if (isIE) s.onreadystatechange = function{      if (this.readyState == 'loaded' || this.readyState == 'complete') runExpr   } else s.onload = runExpr document.getElementsByTagName('head')[0].appendChild(s) }

function addMenuSheet{ if (window.menuSheet) return window.menuSheet = dom.appendCSS('\ .amenu {overflow-y:auto; height:auto; background:#E5F0E5; z-index:100;\ border:2px #E0E0E0 outset; width:150px; position:absolute; top:10px; left:10px}\ .amenu ul {margin:0;}\ .amenu li * { cursor:pointer}\ .amenu li { cursor:default}\ .amenu li {list-style-type:none; list-style-image:none; margin:0; border-top:1px solid green}\ .amenu .arrow {float:left; margin-right:5px}\ .open {border:none}\ .amenu .open li {padding-left:10px; }\ .open ul {background:#F0F7F0; border-left:2px solid #C0D0C0}\ .open .open ul {background:#F5FFF5}\ .open .header {font-weight:bold}\ .open .close .header {font-weight:normal}\ .close ul, .open .close ul {display:none}\ .open ul {display:block}\ ') }

} //amenu

var dom = new function {

this.getMousePos = function(ev){ var posx = 0;	var posy = 0 if (ev.pageX) return [ev.pageX, ev.pageY] else if (ev.clientX) return [ev.clientX + document.body.scrollLeft + document.documentElement.scrollLeft, ev.clientY + document.body.scrollTop + document.documentElement.scrollTop] else return null }

this.getWidth = function(el){ return Math.max(el.scrollWidth, el.offsetWidth) }

this.getHeight = function(el){ return Math.max(el.scrollHeight, el.offsetHeight) }

this.windowWidth = function{ if (self.innerWidth) // all except Explorer return self.innerWidth else if (document.documentElement && document.documentElement.clientWidth)// Explorer 6 Strict Mode return document.documentElement.clientWidth else if (document.body) // other Explorers return document.body.clientWidth else return 0 }

this.offsetTop = function(el){ var off = 0 do {off += el.offsetTop} while (el=el.offsetParent) return off } this.offsetLeft = function(el){ var off = 0 do { off += el.offsetLeft} while (el=el.offsetParent) return off }

this.positionMenu = function(box, ev){ ev = ev || window.event var targ = ev.srcElement || ev.target //var coords = dom.getMousePos(e) //var posx = coords[0], posy = coords[1] var posx = dom.offsetLeft(targ), posy = dom.offsetTop(targ) box.style.top = posy + dom.getHeight(targ) + 'px' posx -= dom.getWidth(box)/2 if (posx + dom.getWidth(box) > dom.windowWidth) posx = dom.windowWidth - dom.getWidth(box) - 20 else if (posx < 0) posx = 10 box.style.left = posx + 'px' }

this.appendCSS = function(text){ //could use createStyleSheet for IE as well var s = document.createElement('style') s.setAttribute('type', 'text/css') if (s.styleSheet) s.styleSheet.cssText = text //IE else s.appendChild(document.createTextNode(text)) document.getElementsByTagName('head')[0].appendChild(s) return s.sheet || s //Safari needs sheets, IE the other way } }

function createMWMenu(mn){

var isEdit = (mw.config.get('wgAction') =='edit' || mw.config.get('wgAction') == 'submit')

if (mw.config.get('wgNamespaceNumber') >=0) {

var page = mn.addSub('', 'Page links') mn.addLink(page,'/wiki/'+mw.config.get('wgPageName')+'?action=purge', '¤purge', 'Clear page cache') mn.addLink(page,'/wiki/Special:Prefixindex/' + mw.config.get('wgPageName') + '/', ' /subpages', 'Subpages')

//calc tollserver vars(e.g. dbname=enwiki_p) var wikilang = mw.config.get('wgServer').split('.')[0].substring(7) var wikifam = mw.config.get('wgServer').split('.')[1] var dbname = (wikifam == 'wikipedia')? 'wiki' : wikifam dbname = wikilang + dbname + '_p' mn.addLink(page,   'http://tools.wikimedia.de/~interiot/cgi-bin/contribution_tree?dbname='+dbname    +'&article='+mw.config.get('wgPageName')+'&user='+mw.config.get('wgUserName'), 'my contribs °', 'My edits to this page') mn.addLink(page,   'http://tools.wikimedia.de/~daniel/WikiSense/Contributors.php?wikilang='    +wikilang+'&wikifam=.'+wikifam+'.org&grouped=on&order=-edit_count&page='    +encodeURIComponent(mw.config.get('wgPageName')), 'all authors °', 'Contibutors sorted by the number of edits') if (mw.config.get('wgNamespaceNumber') == 10) //templateTiger mn.addLink(page,      'http://tools.wikimedia.de/~kolossos/templatetiger/tt-table4.php?lang='+wikilang     +'&template='+mw.config.get('wgTitle'), 'template usage °', 'Template usage in  mainspace, with parameters') //stats.grok.se //var i = mw.config.get('wgServer').indexOf('wikipedia.org') //this would work with secure as well ? //var wikilang = mw.config.get('wgServer').substring(6,i-1).match(/[a-z]+$/)[0] // 'en' if (wikifam == 'wikipedia'){ var mm = ((new Date).getMonth + 1).toString if (mm.length == 1) mm = '0' + mm   mn.addLink(page, 'http://stats.grok.se/' + wikilang      + '/' + (new Date).getFullYear + mm      + '/' + encodeURIComponent(mw.config.get('wgPageName')).replace(/%2F/g, '/'),     'traffic stats °', 'Number of visits on stats.grok.se') }

if (mw.config.get('wgNamespaceNumber') == 2 || mw.config.get('wgNamespaceNumber') == 3){ var user = mn.addSub(page, 'This user') mn.addLink(user,   'http://tools.wikimedia.de/~interiot/cgi-bin/count_edits?dbname='    +dbname+ '&user=' + mw.config.get('wgTitle'), 'editcount by Interiot °', 'Interiot\'s user editcounter') } }

var utils = mn.addSub('', 'Page utils')

if (mw.config.get('wgNamespaceNumber') == -1 || mw.config.get('wgAction') == 'history') mn.addScript(utils, 'en:User:Splarka/lifilter.js#filterLiForm', 'LI Filter') if (mw.config.get('wgCanonicalNamespace')=='Special' && mw.config.get('wgCanonicalSpecialPageName')=='Log') mn.addScript(utils, 'en:User:Alex_Smotrov/logpage.js#logPage.onLoad', 'Log: show as table', 'Show log list as a table') if (mw.config.get('wgAction')=='history') mn.addScript(utils, 'en:User:Alex_Smotrov/histcomb.js#histComb.onLoad', 'History: combine edits', 'Combine edits by same user, shorten links')

myBookmarks = ['MediaWiki:Common.css', 'MediaWiki:Common.js', ['user:'+mw.config.get('wgUserName')+'?action=edit', 'edit me'], [mw.config.get('wgServer')+'/w/api.php', 'api.php'], [mw.config.get('wgServer')+'/w/query.php', 'query.php'] ] if (window.myBookmarks){ var bk = mn.addSub('', 'Bookmarks'), url, title for (var i=0; i<myBookmarks.length; i++){ switch (typeof myBookmarks[i]){ case 'object': url = myBookmarks[i][0];  name = myBookmarks[i][1]; break case 'string': name = url = myBookmarks[i]; break default: continue //for }    if (url.indexOf('http://') != 0) url = mw.config.get('wgArticlePath').replace('$1', url) mn.addLink(bk, url, name) } }

}

function addMWMenuLink{

var link = document.createElement('span') link.appendChild(document.createTextNode('vv')) link.style.cssText = 'cursor:pointer; color:#797; font-weight:bold; font-size:15px; right:0px; top:0px; padding:2px; z-index:100; position:absolute' document.body.appendChild(link) mm = new mnu(createMWMenu) link.addEventListener('click', mm.run) }

$(addMWMenuLink)