Chris@1464: var contextMenuObserving; Chris@1464: var contextMenuUrl; Chris@1464: Chris@1464: function contextMenuRightClick(event) { Chris@1464: var target = $(event.target); Chris@1464: if (target.is('a')) {return;} Chris@1464: var tr = target.parents('tr').first(); Chris@1464: if (!tr.hasClass('hascontextmenu')) {return;} Chris@1464: event.preventDefault(); Chris@1464: if (!contextMenuIsSelected(tr)) { Chris@1464: contextMenuUnselectAll(); Chris@1464: contextMenuAddSelection(tr); Chris@1464: contextMenuSetLastSelected(tr); Chris@1464: } Chris@1464: contextMenuShow(event); Chris@1464: } Chris@1464: Chris@1464: function contextMenuClick(event) { Chris@1464: var target = $(event.target); Chris@1464: var lastSelected; Chris@1464: Chris@1464: if (target.is('a') && target.hasClass('submenu')) { Chris@1464: event.preventDefault(); Chris@1464: return; Chris@1464: } Chris@1464: contextMenuHide(); Chris@1464: if (target.is('a') || target.is('img')) { return; } Chris@1464: if (event.which == 1 || (navigator.appVersion.match(/\bMSIE\b/))) { Chris@1464: var tr = target.parents('tr').first(); Chris@1464: if (tr.length && tr.hasClass('hascontextmenu')) { Chris@1464: // a row was clicked, check if the click was on checkbox Chris@1464: if (target.is('input')) { Chris@1464: // a checkbox may be clicked Chris@1464: if (target.attr('checked')) { Chris@1464: tr.addClass('context-menu-selection'); Chris@1464: } else { Chris@1464: tr.removeClass('context-menu-selection'); Chris@1464: } Chris@1464: } else { Chris@1464: if (event.ctrlKey || event.metaKey) { Chris@1464: contextMenuToggleSelection(tr); Chris@1464: } else if (event.shiftKey) { Chris@1464: lastSelected = contextMenuLastSelected(); Chris@1464: if (lastSelected.length) { Chris@1464: var toggling = false; Chris@1464: $('.hascontextmenu').each(function(){ Chris@1464: if (toggling || $(this).is(tr)) { Chris@1464: contextMenuAddSelection($(this)); Chris@1464: } Chris@1464: if ($(this).is(tr) || $(this).is(lastSelected)) { Chris@1464: toggling = !toggling; Chris@1464: } Chris@1464: }); Chris@1464: } else { Chris@1464: contextMenuAddSelection(tr); Chris@1464: } Chris@1464: } else { Chris@1464: contextMenuUnselectAll(); Chris@1464: contextMenuAddSelection(tr); Chris@1464: } Chris@1464: contextMenuSetLastSelected(tr); Chris@1464: } Chris@1464: } else { Chris@1464: // click is outside the rows Chris@1464: if (target.is('a') && (target.hasClass('disabled') || target.hasClass('submenu'))) { Chris@1464: event.preventDefault(); Chris@1464: } else { Chris@1464: contextMenuUnselectAll(); Chris@1464: } Chris@1464: } Chris@1464: } Chris@1464: } Chris@1464: Chris@1464: function contextMenuCreate() { Chris@1464: if ($('#context-menu').length < 1) { Chris@1464: var menu = document.createElement("div"); Chris@1464: menu.setAttribute("id", "context-menu"); Chris@1464: menu.setAttribute("style", "display:none;"); Chris@1464: document.getElementById("content").appendChild(menu); Chris@1464: } Chris@1464: } Chris@1464: Chris@1464: function contextMenuShow(event) { Chris@1464: var mouse_x = event.pageX; Chris@1464: var mouse_y = event.pageY; Chris@1464: var render_x = mouse_x; Chris@1464: var render_y = mouse_y; Chris@1464: var dims; Chris@1464: var menu_width; Chris@1464: var menu_height; Chris@1464: var window_width; Chris@1464: var window_height; Chris@1464: var max_width; Chris@1464: var max_height; Chris@1464: Chris@1464: $('#context-menu').css('left', (render_x + 'px')); Chris@1464: $('#context-menu').css('top', (render_y + 'px')); Chris@1464: $('#context-menu').html(''); Chris@1464: Chris@1464: $.ajax({ Chris@1464: url: contextMenuUrl, Chris@1464: data: $(event.target).parents('form').first().serialize(), Chris@1464: success: function(data, textStatus, jqXHR) { Chris@1464: $('#context-menu').html(data); Chris@1464: menu_width = $('#context-menu').width(); Chris@1464: menu_height = $('#context-menu').height(); Chris@1464: max_width = mouse_x + 2*menu_width; Chris@1464: max_height = mouse_y + menu_height; Chris@1464: Chris@1464: var ws = window_size(); Chris@1464: window_width = ws.width; Chris@1464: window_height = ws.height; Chris@1464: Chris@1464: /* display the menu above and/or to the left of the click if needed */ Chris@1464: if (max_width > window_width) { Chris@1464: render_x -= menu_width; Chris@1464: $('#context-menu').addClass('reverse-x'); Chris@1464: } else { Chris@1464: $('#context-menu').removeClass('reverse-x'); Chris@1464: } Chris@1464: if (max_height > window_height) { Chris@1464: render_y -= menu_height; Chris@1464: $('#context-menu').addClass('reverse-y'); Chris@1464: } else { Chris@1464: $('#context-menu').removeClass('reverse-y'); Chris@1464: } Chris@1464: if (render_x <= 0) render_x = 1; Chris@1464: if (render_y <= 0) render_y = 1; Chris@1464: $('#context-menu').css('left', (render_x + 'px')); Chris@1464: $('#context-menu').css('top', (render_y + 'px')); Chris@1464: $('#context-menu').show(); Chris@1464: Chris@1464: //if (window.parseStylesheets) { window.parseStylesheets(); } // IE Chris@1464: Chris@1464: } Chris@1464: }); Chris@1464: } Chris@1464: Chris@1464: function contextMenuSetLastSelected(tr) { Chris@1464: $('.cm-last').removeClass('cm-last'); Chris@1464: tr.addClass('cm-last'); Chris@1464: } Chris@1464: Chris@1464: function contextMenuLastSelected() { Chris@1464: return $('.cm-last').first(); Chris@1464: } Chris@1464: Chris@1464: function contextMenuUnselectAll() { Chris@1464: $('.hascontextmenu').each(function(){ Chris@1464: contextMenuRemoveSelection($(this)); Chris@1464: }); Chris@1464: $('.cm-last').removeClass('cm-last'); Chris@1464: } Chris@1464: Chris@1464: function contextMenuHide() { Chris@1464: $('#context-menu').hide(); Chris@1464: } Chris@1464: Chris@1464: function contextMenuToggleSelection(tr) { Chris@1464: if (contextMenuIsSelected(tr)) { Chris@1464: contextMenuRemoveSelection(tr); Chris@1464: } else { Chris@1464: contextMenuAddSelection(tr); Chris@1464: } Chris@1464: } Chris@1464: Chris@1464: function contextMenuAddSelection(tr) { Chris@1464: tr.addClass('context-menu-selection'); Chris@1464: contextMenuCheckSelectionBox(tr, true); Chris@1464: contextMenuClearDocumentSelection(); Chris@1464: } Chris@1464: Chris@1464: function contextMenuRemoveSelection(tr) { Chris@1464: tr.removeClass('context-menu-selection'); Chris@1464: contextMenuCheckSelectionBox(tr, false); Chris@1464: } Chris@1464: Chris@1464: function contextMenuIsSelected(tr) { Chris@1464: return tr.hasClass('context-menu-selection'); Chris@1464: } Chris@1464: Chris@1464: function contextMenuCheckSelectionBox(tr, checked) { Chris@1464: tr.find('input[type=checkbox]').attr('checked', checked); Chris@1464: } Chris@1464: Chris@1464: function contextMenuClearDocumentSelection() { Chris@1464: // TODO Chris@1464: if (document.selection) { Chris@1464: document.selection.empty(); // IE Chris@1464: } else { Chris@1464: window.getSelection().removeAllRanges(); Chris@1464: } Chris@1464: } Chris@1464: Chris@1464: function contextMenuInit(url) { Chris@1464: contextMenuUrl = url; Chris@1464: contextMenuCreate(); Chris@1464: contextMenuUnselectAll(); Chris@1464: Chris@1464: if (!contextMenuObserving) { Chris@1464: $(document).click(contextMenuClick); Chris@1464: $(document).contextmenu(contextMenuRightClick); Chris@1464: contextMenuObserving = true; Chris@1464: } Chris@1464: } Chris@1464: Chris@1464: function toggleIssuesSelection(el) { Chris@1464: var boxes = $(el).parents('form').find('input[type=checkbox]'); Chris@1464: var all_checked = true; Chris@1464: boxes.each(function(){ if (!$(this).attr('checked')) { all_checked = false; } }); Chris@1464: boxes.each(function(){ Chris@1464: if (all_checked) { Chris@1464: $(this).removeAttr('checked'); Chris@1464: $(this).parents('tr').removeClass('context-menu-selection'); Chris@1464: } else if (!$(this).attr('checked')) { Chris@1464: $(this).attr('checked', true); Chris@1464: $(this).parents('tr').addClass('context-menu-selection'); Chris@1464: } Chris@1464: }); Chris@1464: } Chris@1464: Chris@1464: function window_size() { Chris@1464: var w; Chris@1464: var h; Chris@1464: if (window.innerWidth) { Chris@1464: w = window.innerWidth; Chris@1464: h = window.innerHeight; Chris@1464: } else if (document.documentElement) { Chris@1464: w = document.documentElement.clientWidth; Chris@1464: h = document.documentElement.clientHeight; Chris@1464: } else { Chris@1464: w = document.body.clientWidth; Chris@1464: h = document.body.clientHeight; Chris@1464: } Chris@1464: return {width: w, height: h}; Chris@1464: }