Mercurial > hg > soundsoftware-site
diff public/javascripts/context_menu.js @ 0:513646585e45
* Import Redmine trunk SVN rev 3859
author | Chris Cannam |
---|---|
date | Fri, 23 Jul 2010 15:52:44 +0100 |
parents | |
children | af80e5618e9b |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/public/javascripts/context_menu.js Fri Jul 23 15:52:44 2010 +0100 @@ -0,0 +1,237 @@ +/* redMine - project management software + Copyright (C) 2006-2008 Jean-Philippe Lang */ + +var observingContextMenuClick; + +ContextMenu = Class.create(); +ContextMenu.prototype = { + initialize: function (url) { + this.url = url; + this.createMenu(); + + if (!observingContextMenuClick) { + Event.observe(document, 'click', this.Click.bindAsEventListener(this)); + Event.observe(document, (window.opera ? 'click' : 'contextmenu'), this.RightClick.bindAsEventListener(this)); + observingContextMenuClick = true; + } + + this.unselectAll(); + this.lastSelected = null; + }, + + RightClick: function(e) { + this.hideMenu(); + // do not show the context menu on links + if (Event.element(e).tagName == 'A') { return; } + // right-click simulated by Alt+Click with Opera + if (window.opera && !e.altKey) { return; } + var tr = Event.findElement(e, 'tr'); + if (tr == document || tr == undefined || !tr.hasClassName('hascontextmenu')) { return; } + Event.stop(e); + if (!this.isSelected(tr)) { + this.unselectAll(); + this.addSelection(tr); + this.lastSelected = tr; + } + this.showMenu(e); + }, + + Click: function(e) { + this.hideMenu(); + if (Event.element(e).tagName == 'A') { return; } + if (window.opera && e.altKey) { return; } + if (Event.isLeftClick(e) || (navigator.appVersion.match(/\bMSIE\b/))) { + var tr = Event.findElement(e, 'tr'); + if (tr!=null && tr!=document && tr.hasClassName('hascontextmenu')) { + // a row was clicked, check if the click was on checkbox + var box = Event.findElement(e, 'input'); + if (box!=document && box!=undefined) { + // a checkbox may be clicked + if (box.checked) { + tr.addClassName('context-menu-selection'); + } else { + tr.removeClassName('context-menu-selection'); + } + } else { + if (e.ctrlKey) { + this.toggleSelection(tr); + } else if (e.shiftKey) { + if (this.lastSelected != null) { + var toggling = false; + var rows = $$('.hascontextmenu'); + for (i=0; i<rows.length; i++) { + if (toggling || rows[i]==tr) { + this.addSelection(rows[i]); + } + if (rows[i]==tr || rows[i]==this.lastSelected) { + toggling = !toggling; + } + } + } else { + this.addSelection(tr); + } + } else { + this.unselectAll(); + this.addSelection(tr); + } + this.lastSelected = tr; + } + } else { + // click is outside the rows + var t = Event.findElement(e, 'a'); + if (t == document || t == undefined) { + this.unselectAll(); + } else { + if (Element.hasClassName(t, 'disabled') || Element.hasClassName(t, 'submenu')) { + Event.stop(e); + } + } + } + } + else{ + this.RightClick(e); + } + }, + + createMenu: function() { + if (!$('context-menu')) { + var menu = document.createElement("div"); + menu.setAttribute("id", "context-menu"); + menu.setAttribute("style", "display:none;"); + document.getElementById("content").appendChild(menu); + } + }, + + showMenu: function(e) { + var mouse_x = Event.pointerX(e); + var mouse_y = Event.pointerY(e); + var render_x = mouse_x; + var render_y = mouse_y; + var dims; + var menu_width; + var menu_height; + var window_width; + var window_height; + var max_width; + var max_height; + + $('context-menu').style['left'] = (render_x + 'px'); + $('context-menu').style['top'] = (render_y + 'px'); + Element.update('context-menu', ''); + + new Ajax.Updater({success:'context-menu'}, this.url, + {asynchronous:true, + evalScripts:true, + parameters:Form.serialize(Event.findElement(e, 'form')), + onComplete:function(request){ + dims = $('context-menu').getDimensions(); + menu_width = dims.width; + menu_height = dims.height; + max_width = mouse_x + 2*menu_width; + max_height = mouse_y + menu_height; + + var ws = window_size(); + window_width = ws.width; + window_height = ws.height; + + /* display the menu above and/or to the left of the click if needed */ + if (max_width > window_width) { + render_x -= menu_width; + $('context-menu').addClassName('reverse-x'); + } else { + $('context-menu').removeClassName('reverse-x'); + } + if (max_height > window_height) { + render_y -= menu_height; + $('context-menu').addClassName('reverse-y'); + } else { + $('context-menu').removeClassName('reverse-y'); + } + if (render_x <= 0) render_x = 1; + if (render_y <= 0) render_y = 1; + $('context-menu').style['left'] = (render_x + 'px'); + $('context-menu').style['top'] = (render_y + 'px'); + + Effect.Appear('context-menu', {duration: 0.20}); + if (window.parseStylesheets) { window.parseStylesheets(); } // IE + }}) + }, + + hideMenu: function() { + Element.hide('context-menu'); + }, + + addSelection: function(tr) { + tr.addClassName('context-menu-selection'); + this.checkSelectionBox(tr, true); + this.clearDocumentSelection(); + }, + + toggleSelection: function(tr) { + if (this.isSelected(tr)) { + this.removeSelection(tr); + } else { + this.addSelection(tr); + } + }, + + removeSelection: function(tr) { + tr.removeClassName('context-menu-selection'); + this.checkSelectionBox(tr, false); + }, + + unselectAll: function() { + var rows = $$('.hascontextmenu'); + for (i=0; i<rows.length; i++) { + this.removeSelection(rows[i]); + } + }, + + checkSelectionBox: function(tr, checked) { + var inputs = Element.getElementsBySelector(tr, 'input'); + if (inputs.length > 0) { inputs[0].checked = checked; } + }, + + isSelected: function(tr) { + return Element.hasClassName(tr, 'context-menu-selection'); + }, + + clearDocumentSelection: function() { + if (document.selection) { + document.selection.clear(); // IE + } else { + window.getSelection().removeAllRanges(); + } + } +} + +function toggleIssuesSelection(el) { + var boxes = el.getElementsBySelector('input[type=checkbox]'); + var all_checked = true; + for (i = 0; i < boxes.length; i++) { if (boxes[i].checked == false) { all_checked = false; } } + for (i = 0; i < boxes.length; i++) { + if (all_checked) { + boxes[i].checked = false; + boxes[i].up('tr').removeClassName('context-menu-selection'); + } else if (boxes[i].checked == false) { + boxes[i].checked = true; + boxes[i].up('tr').addClassName('context-menu-selection'); + } + } +} + +function window_size() { + var w; + var h; + if (window.innerWidth) { + w = window.innerWidth; + h = window.innerHeight; + } else if (document.documentElement) { + w = document.documentElement.clientWidth; + h = document.documentElement.clientHeight; + } else { + w = document.body.clientWidth; + h = document.body.clientHeight; + } + return {width: w, height: h}; +}