From f6ce427a00650e92f414dc3682e56348d549d7ea Mon Sep 17 00:00:00 2001 From: Jean-Philippe Lang Date: Thu, 3 Apr 2008 16:38:06 +0000 Subject: [PATCH] Display the context menu above and/or to the left of the click if needed (patch by Mike Duchene, closes #960). git-svn-id: http://redmine.rubyforge.org/svn/trunk@1323 e93f8b46-1217-0410-a6f0-8f06a7374b81 --- public/javascripts/context_menu.js | 65 +++++++++++++++++++++++++++-- public/stylesheets/context_menu.css | 10 ++--- 2 files changed, 66 insertions(+), 9 deletions(-) diff --git a/public/javascripts/context_menu.js b/public/javascripts/context_menu.js index e3f128d890..3e2d571fa4 100644 --- a/public/javascripts/context_menu.js +++ b/public/javascripts/context_menu.js @@ -93,14 +93,55 @@ ContextMenu.prototype = { }, showMenu: function(e) { - $('context-menu').style['left'] = (Event.pointerX(e) + 'px'); - $('context-menu').style['top'] = (Event.pointerY(e) + 'px'); - Element.update('context-menu', ''); - new Ajax.Updater({success:'context-menu'}, this.url, + 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 }}) @@ -159,3 +200,19 @@ function toggleIssuesSelection(el) { } } } + +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}; +} diff --git a/public/stylesheets/context_menu.css b/public/stylesheets/context_menu.css index f68b33fe1f..e5a83be0d4 100644 --- a/public/stylesheets/context_menu.css +++ b/public/stylesheets/context_menu.css @@ -22,13 +22,13 @@ padding:1px; z-index:9; } -#context-menu li.folder ul { - position:absolute; - left:168px; /* IE6 */ - top:-2px; -} +#context-menu li.folder ul { position:absolute; left:168px; /* IE6 */ top:-2px; } #context-menu li.folder>ul { left:148px; } +#context-menu.reverse-y li.folder>ul { top:auto; bottom:0; } +#context-menu.reverse-x li.folder ul { left:auto; right:168px; /* IE6 */ } +#context-menu.reverse-x li.folder>ul { right:148px; } + #context-menu a { border:1px solid white; text-decoration:none;