Jump to content

User:Js/mwmenu.js

From Wikipedia, the free encyclopedia
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
//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', '<a href="'+link+'">'+name+'</a>', 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', '<span>'+name+'</span>', 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)