diff --git a/etc/RT_Config.pm.in b/etc/RT_Config.pm.in index a39f37c34f4..fcb4798964f 100644 --- a/etc/RT_Config.pm.in +++ b/etc/RT_Config.pm.in @@ -2286,6 +2286,14 @@ Set this to 0 to disable URL shortener. Set($EnableURLShortener, 1); +=item C<$KeyBoardShortcuts> + +Set this to 0 to disable keyboard shortcuts. + +=cut + +Set($KeyBoardShortcuts, 1); + =back diff --git a/lib/RT/Config.pm b/lib/RT/Config.pm index d4845ad00b0..864872d8b50 100644 --- a/lib/RT/Config.pm +++ b/lib/RT/Config.pm @@ -437,6 +437,15 @@ our %META; Description => 'Enable URL shortener', #loc }, }, + KeyBoardShortcuts => { + Section => 'General', #loc + Overridable => 1, + SortOrder => 13, + Widget => '/Widgets/Form/Boolean', + WidgetArguments => { + Description => 'Enable keyboards shortcuts', #loc + }, + }, # User overridable options for RT at a glance HomePageRefreshInterval => { diff --git a/share/html/Elements/JavascriptConfig b/share/html/Elements/JavascriptConfig index eb4e1baffc5..f55d0b38b19 100644 --- a/share/html/Elements/JavascriptConfig +++ b/share/html/Elements/JavascriptConfig @@ -49,7 +49,7 @@ my $Config = {}; $Config->{$_} = RT->Config->Get( $_, $session{CurrentUser} ) for qw(rtname WebPath MessageBoxRichText MessageBoxRichTextHeight - MaxAttachmentSize WebDefaultStylesheet QuoteSelectedText ); + MaxAttachmentSize WebDefaultStylesheet QuoteSelectedText KeyBoardShortcuts ); # JS-only config value. Setting default here, can be reset with # the Data callback below. diff --git a/share/static/js/keyboard-shortcuts.js b/share/static/js/keyboard-shortcuts.js index 8ae117ed92c..3db024a36e1 100644 --- a/share/static/js/keyboard-shortcuts.js +++ b/share/static/js/keyboard-shortcuts.js @@ -1,4 +1,5 @@ jQuery(function() { + if (RT.Config.KeyBoardShortcuts) { var goBack = function() { window.history.back(); }; @@ -68,110 +69,115 @@ jQuery(function() { Mousetrap.bind('g h', goHome); Mousetrap.bind('/', simpleSearch); Mousetrap.bind('?', openHelp); + } }); jQuery(function() { - // Only load these shortcuts if there is a ticket list on the page - var hasTicketList = jQuery('table.ticket-list').length; - if (!hasTicketList) return; - - var currentRow; - - var nextTicket = function() { - var nextRow; - var searchResultsTable = jQuery('.ticket-list.collection-as-table'); - if (!currentRow || !(nextRow = currentRow.next('tbody.list-item')).length) { - nextRow = searchResultsTable.find('tbody.list-item').first(); - } - setNewRow(nextRow); - }; - - var setNewRow = function(newRow) { - if (currentRow) currentRow.removeClass('selected-row'); - currentRow = newRow; - currentRow.addClass('selected-row'); - scrollToJQueryObject(currentRow); - }; - - var prevTicket = function() { - var prevRow, searchResultsTable = jQuery('.ticket-list.collection-as-table'); - if (!currentRow || !(prevRow = currentRow.prev('tbody.list-item')).length) { - prevRow = searchResultsTable.find('tbody.list-item').last(); - } - setNewRow(prevRow); - }; - - var generateTicketLink = function(ticketId) { - if (!ticketId) return ''; - return RT.Config.WebHomePath + '/Ticket/Display.html?id=' + ticketId; - }; - - var generateUpdateLink = function(ticketId, action) { - if (!ticketId) return ''; - return RT.Config.WebHomePath + '/Ticket/Update.html?Action=' + action + '&id=' + ticketId; - }; - - var navigateToCurrentTicket = function() { - if (!currentRow) return; - - var ticketId = currentRow.closest('tbody').data('recordId'); - var ticketLink = generateTicketLink(ticketId); - if (!ticketLink) return; - - window.location.href = ticketLink; - }; - - var toggleTicketCheckbox = function() { - if (!currentRow) return; - var ticketCheckBox = currentRow.find('input[type=checkbox]'); - if (!ticketCheckBox.length) return; - ticketCheckBox.prop("checked", !ticketCheckBox.prop("checked")); - }; - - var replyToTicket = function() { - if (!currentRow) return; - - var ticketId = currentRow.closest('tbody').data('recordId'); - var replyLink = generateUpdateLink(ticketId, 'Respond'); - if (!replyLink) return; - - window.location.href = replyLink; - }; - - var commentOnTicket = function() { - if (!currentRow) return; - - var ticketId = currentRow.closest('tbody').data('recordId'); - var commentLink = generateUpdateLink(ticketId, 'Comment'); - if (!commentLink) return; - - window.location.href = commentLink; - }; - - Mousetrap.bind('j', nextTicket); - Mousetrap.bind('k', prevTicket); - Mousetrap.bind(['enter','o'], navigateToCurrentTicket); - Mousetrap.bind('r', replyToTicket); - Mousetrap.bind('c', commentOnTicket); - Mousetrap.bind('x', toggleTicketCheckbox); + if (RT.Config.KeyBoardShortcuts) { + // Only load these shortcuts if there is a ticket list on the page + var hasTicketList = jQuery('table.ticket-list').length; + if (!hasTicketList) return; + + var currentRow; + + var nextTicket = function() { + var nextRow; + var searchResultsTable = jQuery('.ticket-list.collection-as-table'); + if (!currentRow || !(nextRow = currentRow.next('tbody.list-item')).length) { + nextRow = searchResultsTable.find('tbody.list-item').first(); + } + setNewRow(nextRow); + }; + + var setNewRow = function(newRow) { + if (currentRow) currentRow.removeClass('selected-row'); + currentRow = newRow; + currentRow.addClass('selected-row'); + scrollToJQueryObject(currentRow); + }; + + var prevTicket = function() { + var prevRow, searchResultsTable = jQuery('.ticket-list.collection-as-table'); + if (!currentRow || !(prevRow = currentRow.prev('tbody.list-item')).length) { + prevRow = searchResultsTable.find('tbody.list-item').last(); + } + setNewRow(prevRow); + }; + + var generateTicketLink = function(ticketId) { + if (!ticketId) return ''; + return RT.Config.WebHomePath + '/Ticket/Display.html?id=' + ticketId; + }; + + var generateUpdateLink = function(ticketId, action) { + if (!ticketId) return ''; + return RT.Config.WebHomePath + '/Ticket/Update.html?Action=' + action + '&id=' + ticketId; + }; + + var navigateToCurrentTicket = function() { + if (!currentRow) return; + + var ticketId = currentRow.closest('tbody').data('recordId'); + var ticketLink = generateTicketLink(ticketId); + if (!ticketLink) return; + + window.location.href = ticketLink; + }; + + var toggleTicketCheckbox = function() { + if (!currentRow) return; + var ticketCheckBox = currentRow.find('input[type=checkbox]'); + if (!ticketCheckBox.length) return; + ticketCheckBox.prop("checked", !ticketCheckBox.prop("checked")); + }; + + var replyToTicket = function() { + if (!currentRow) return; + + var ticketId = currentRow.closest('tbody').data('recordId'); + var replyLink = generateUpdateLink(ticketId, 'Respond'); + if (!replyLink) return; + + window.location.href = replyLink; + }; + + var commentOnTicket = function() { + if (!currentRow) return; + + var ticketId = currentRow.closest('tbody').data('recordId'); + var commentLink = generateUpdateLink(ticketId, 'Comment'); + if (!commentLink) return; + + window.location.href = commentLink; + }; + + Mousetrap.bind('j', nextTicket); + Mousetrap.bind('k', prevTicket); + Mousetrap.bind(['enter','o'], navigateToCurrentTicket); + Mousetrap.bind('r', replyToTicket); + Mousetrap.bind('c', commentOnTicket); + Mousetrap.bind('x', toggleTicketCheckbox); + } }); jQuery(function() { - // Only load these shortcuts if reply or comment action is on page - var ticket_reply = jQuery('a#page-actions-reply'); - var ticket_comment = jQuery('a#page-actions-comment'); - if (!ticket_reply.length && !ticket_comment.length) return; - - var replyToTicket = function() { - if (!ticket_reply.length) return; - window.location.href = ticket_reply.attr('href'); - }; - - var commentOnTicket = function() { - if (!ticket_comment.length) return; - window.location.href = ticket_comment.attr('href'); - }; - - Mousetrap.bind('r', replyToTicket); - Mousetrap.bind('c', commentOnTicket); + if (RT.Config.KeyBoardShortcuts) { + // Only load these shortcuts if reply or comment action is on page + var ticket_reply = jQuery('a#page-actions-reply'); + var ticket_comment = jQuery('a#page-actions-comment'); + if (!ticket_reply.length && !ticket_comment.length) return; + + var replyToTicket = function() { + if (!ticket_reply.length) return; + window.location.href = ticket_reply.attr('href'); + }; + + var commentOnTicket = function() { + if (!ticket_comment.length) return; + window.location.href = ticket_comment.attr('href'); + }; + + Mousetrap.bind('r', replyToTicket); + Mousetrap.bind('c', commentOnTicket); + } });