context_menu.js
249 lines
| 6.9 KiB
| application/javascript
|
JavascriptLexer
|
r14029 | /* Redmine - project management software | ||
|
r14856 | Copyright (C) 2006-2016 Jean-Philippe Lang */ | ||
|
r14029 | |||
|
r9885 | var contextMenuObserving; | ||
function contextMenuRightClick(event) { | ||||
var target = $(event.target); | ||||
if (target.is('a')) {return;} | ||||
var tr = target.parents('tr').first(); | ||||
if (!tr.hasClass('hascontextmenu')) {return;} | ||||
event.preventDefault(); | ||||
if (!contextMenuIsSelected(tr)) { | ||||
contextMenuUnselectAll(); | ||||
contextMenuAddSelection(tr); | ||||
contextMenuSetLastSelected(tr); | ||||
|
r8769 | } | ||
|
r9885 | contextMenuShow(event); | ||
} | ||||
|
r8770 | |||
|
r9885 | function contextMenuClick(event) { | ||
var target = $(event.target); | ||||
var lastSelected; | ||||
|
r1116 | |||
|
r9885 | if (target.is('a') && target.hasClass('submenu')) { | ||
event.preventDefault(); | ||||
return; | ||||
} | ||||
contextMenuHide(); | ||||
if (target.is('a') || target.is('img')) { return; } | ||||
|
r10609 | if (event.which == 1 || (navigator.appVersion.match(/\bMSIE\b/))) { | ||
|
r9885 | var tr = target.parents('tr').first(); | ||
if (tr.length && tr.hasClass('hascontextmenu')) { | ||||
// a row was clicked, check if the click was on checkbox | ||||
if (target.is('input')) { | ||||
// a checkbox may be clicked | ||||
|
r13045 | if (target.prop('checked')) { | ||
|
r9885 | tr.addClass('context-menu-selection'); | ||
|
r1116 | } else { | ||
|
r9885 | tr.removeClass('context-menu-selection'); | ||
} | ||||
} else { | ||||
if (event.ctrlKey || event.metaKey) { | ||||
contextMenuToggleSelection(tr); | ||||
} else if (event.shiftKey) { | ||||
lastSelected = contextMenuLastSelected(); | ||||
if (lastSelected.length) { | ||||
var toggling = false; | ||||
$('.hascontextmenu').each(function(){ | ||||
if (toggling || $(this).is(tr)) { | ||||
contextMenuAddSelection($(this)); | ||||
|
r1116 | } | ||
|
r9885 | if ($(this).is(tr) || $(this).is(lastSelected)) { | ||
toggling = !toggling; | ||||
} | ||||
}); | ||||
|
r1116 | } else { | ||
|
r9885 | contextMenuAddSelection(tr); | ||
|
r1116 | } | ||
|
r3430 | } else { | ||
|
r9885 | contextMenuUnselectAll(); | ||
contextMenuAddSelection(tr); | ||||
|
r1116 | } | ||
|
r9885 | contextMenuSetLastSelected(tr); | ||
|
r1116 | } | ||
} else { | ||||
|
r9885 | // click is outside the rows | ||
if (target.is('a') && (target.hasClass('disabled') || target.hasClass('submenu'))) { | ||||
event.preventDefault(); | ||||
|
r14929 | } else if (target.is('.toggle-selection') || target.is('.ui-dialog *') || $('#ajax-modal').is(':visible')) { | ||
|
r14347 | // nop | ||
|
r9885 | } else { | ||
contextMenuUnselectAll(); | ||||
} | ||||
|
r1116 | } | ||
|
r9885 | } | ||
} | ||||
|
r8770 | |||
|
r9885 | function contextMenuCreate() { | ||
if ($('#context-menu').length < 1) { | ||||
var menu = document.createElement("div"); | ||||
menu.setAttribute("id", "context-menu"); | ||||
menu.setAttribute("style", "display:none;"); | ||||
document.getElementById("content").appendChild(menu); | ||||
} | ||||
} | ||||
function contextMenuShow(event) { | ||||
var mouse_x = event.pageX; | ||||
|
r14967 | var mouse_y = event.pageY; | ||
var mouse_y_c = event.clientY; | ||||
|
r9885 | 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; | ||||
|
r15554 | var url; | ||
|
r9885 | |||
$('#context-menu').css('left', (render_x + 'px')); | ||||
$('#context-menu').css('top', (render_y + 'px')); | ||||
$('#context-menu').html(''); | ||||
|
r15554 | url = $(event.target).parents('form').first().data('cm-url'); | ||
|
r9885 | $.ajax({ | ||
|
r15554 | url: url, | ||
|
r9885 | data: $(event.target).parents('form').first().serialize(), | ||
success: function(data, textStatus, jqXHR) { | ||||
$('#context-menu').html(data); | ||||
menu_width = $('#context-menu').width(); | ||||
menu_height = $('#context-menu').height(); | ||||
max_width = mouse_x + 2*menu_width; | ||||
|
r14967 | max_height = mouse_y_c + menu_height; | ||
|
r9885 | |||
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').addClass('reverse-x'); | ||||
} else { | ||||
$('#context-menu').removeClass('reverse-x'); | ||||
} | ||||
|
r14967 | |||
|
r9885 | if (max_height > window_height) { | ||
render_y -= menu_height; | ||||
$('#context-menu').addClass('reverse-y'); | ||||
|
r14967 | // adding class for submenu | ||
if (mouse_y_c < 325) { | ||||
$('#context-menu .folder').addClass('down'); | ||||
} | ||||
|
r9885 | } else { | ||
|
r14967 | // adding class for submenu | ||
if (window_height - mouse_y_c < 345) { | ||||
$('#context-menu .folder').addClass('up'); | ||||
} | ||||
$('#context-menu').removeClass('reverse-y'); | ||||
|
r9885 | } | ||
|
r14967 | |||
|
r9885 | if (render_x <= 0) render_x = 1; | ||
if (render_y <= 0) render_y = 1; | ||||
$('#context-menu').css('left', (render_x + 'px')); | ||||
$('#context-menu').css('top', (render_y + 'px')); | ||||
$('#context-menu').show(); | ||||
//if (window.parseStylesheets) { window.parseStylesheets(); } // IE | ||||
|
r1116 | } | ||
|
r9885 | }); | ||
} | ||||
|
r8770 | |||
|
r9885 | function contextMenuSetLastSelected(tr) { | ||
$('.cm-last').removeClass('cm-last'); | ||||
tr.addClass('cm-last'); | ||||
} | ||||
|
r8770 | |||
|
r9885 | function contextMenuLastSelected() { | ||
return $('.cm-last').first(); | ||||
} | ||||
|
r8770 | |||
|
r9885 | function contextMenuUnselectAll() { | ||
|
r14347 | $('input[type=checkbox].toggle-selection').prop('checked', false); | ||
|
r9885 | $('.hascontextmenu').each(function(){ | ||
contextMenuRemoveSelection($(this)); | ||||
}); | ||||
$('.cm-last').removeClass('cm-last'); | ||||
} | ||||
function contextMenuHide() { | ||||
$('#context-menu').hide(); | ||||
} | ||||
function contextMenuToggleSelection(tr) { | ||||
if (contextMenuIsSelected(tr)) { | ||||
contextMenuRemoveSelection(tr); | ||||
} else { | ||||
contextMenuAddSelection(tr); | ||||
} | ||||
} | ||||
function contextMenuAddSelection(tr) { | ||||
tr.addClass('context-menu-selection'); | ||||
contextMenuCheckSelectionBox(tr, true); | ||||
contextMenuClearDocumentSelection(); | ||||
} | ||||
function contextMenuRemoveSelection(tr) { | ||||
tr.removeClass('context-menu-selection'); | ||||
contextMenuCheckSelectionBox(tr, false); | ||||
} | ||||
function contextMenuIsSelected(tr) { | ||||
return tr.hasClass('context-menu-selection'); | ||||
} | ||||
function contextMenuCheckSelectionBox(tr, checked) { | ||||
|
r13045 | tr.find('input[type=checkbox]').prop('checked', checked); | ||
|
r9885 | } | ||
function contextMenuClearDocumentSelection() { | ||||
// TODO | ||||
if (document.selection) { | ||||
|
r11520 | document.selection.empty(); // IE | ||
|
r9885 | } else { | ||
window.getSelection().removeAllRanges(); | ||||
} | ||||
} | ||||
|
r15554 | function contextMenuInit() { | ||
|
r9885 | contextMenuCreate(); | ||
contextMenuUnselectAll(); | ||||
if (!contextMenuObserving) { | ||||
$(document).click(contextMenuClick); | ||||
$(document).contextmenu(contextMenuRightClick); | ||||
contextMenuObserving = true; | ||||
|
r1116 | } | ||
} | ||||
|
r859 | |||
|
r1116 | function toggleIssuesSelection(el) { | ||
|
r14347 | var checked = $(this).prop('checked'); | ||
var boxes = $(this).parents('table').find('input[name=ids\\[\\]]'); | ||||
boxes.prop('checked', checked).parents('tr').toggleClass('context-menu-selection', checked); | ||||
|
r859 | } | ||
|
r1308 | |||
function window_size() { | ||||
|
r8769 | 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}; | ||||
|
r1308 | } | ||
|
r14347 | |||
$(document).ready(function(){ | ||||
|
r15554 | contextMenuInit(); | ||
|
r14347 | $('input[type=checkbox].toggle-selection').on('change', toggleIssuesSelection); | ||
}); | ||||