diff options
Diffstat (limited to 'app/assets/javascripts/filtered_search/filtered_search_manager.js')
-rw-r--r-- | app/assets/javascripts/filtered_search/filtered_search_manager.js | 43 |
1 files changed, 38 insertions, 5 deletions
diff --git a/app/assets/javascripts/filtered_search/filtered_search_manager.js b/app/assets/javascripts/filtered_search/filtered_search_manager.js index 7ea7313f648..724f80f8866 100644 --- a/app/assets/javascripts/filtered_search/filtered_search_manager.js +++ b/app/assets/javascripts/filtered_search/filtered_search_manager.js @@ -14,7 +14,13 @@ import FilteredSearchTokenizer from './filtered_search_tokenizer'; import FilteredSearchDropdownManager from './filtered_search_dropdown_manager'; import FilteredSearchVisualTokens from './filtered_search_visual_tokens'; import DropdownUtils from './dropdown_utils'; -import { BACKSPACE_KEY_CODE } from '~/lib/utils/keycodes'; +import { + ENTER_KEY_CODE, + BACKSPACE_KEY_CODE, + DELETE_KEY_CODE, + UP_KEY_CODE, + DOWN_KEY_CODE, +} from '~/lib/utils/keycodes'; import { __ } from '~/locale'; export default class FilteredSearchManager { @@ -176,6 +182,8 @@ export default class FilteredSearchManager { this.checkForEnterWrapper = this.checkForEnter.bind(this); this.onClearSearchWrapper = this.onClearSearch.bind(this); this.checkForBackspaceWrapper = this.checkForBackspace.call(this); + this.checkForMetaBackspaceWrapper = this.checkForMetaBackspace.bind(this); + this.checkForAltOrCtrlBackspaceWrapper = this.checkForAltOrCtrlBackspace.bind(this); this.removeSelectedTokenKeydownWrapper = this.removeSelectedTokenKeydown.bind(this); this.unselectEditTokensWrapper = this.unselectEditTokens.bind(this); this.editTokenWrapper = this.editToken.bind(this); @@ -192,6 +200,9 @@ export default class FilteredSearchManager { this.filteredSearchInput.addEventListener('keyup', this.handleInputVisualTokenWrapper); this.filteredSearchInput.addEventListener('keydown', this.checkForEnterWrapper); this.filteredSearchInput.addEventListener('keyup', this.checkForBackspaceWrapper); + // e.metaKey only works with keydown, not keyup + this.filteredSearchInput.addEventListener('keydown', this.checkForMetaBackspaceWrapper); + this.filteredSearchInput.addEventListener('keydown', this.checkForAltOrCtrlBackspaceWrapper); this.filteredSearchInput.addEventListener('click', this.tokenChange); this.filteredSearchInput.addEventListener('keyup', this.tokenChange); this.filteredSearchInput.addEventListener('focus', this.addInputContainerFocusWrapper); @@ -213,6 +224,8 @@ export default class FilteredSearchManager { this.filteredSearchInput.removeEventListener('input', this.handleInputPlaceholderWrapper); this.filteredSearchInput.removeEventListener('keyup', this.handleInputVisualTokenWrapper); this.filteredSearchInput.removeEventListener('keydown', this.checkForEnterWrapper); + this.filteredSearchInput.removeEventListener('keydown', this.checkForMetaBackspaceWrapper); + this.filteredSearchInput.removeEventListener('keydown', this.checkForAltOrCtrlBackspaceWrapper); this.filteredSearchInput.removeEventListener('keyup', this.checkForBackspaceWrapper); this.filteredSearchInput.removeEventListener('click', this.tokenChange); this.filteredSearchInput.removeEventListener('keyup', this.tokenChange); @@ -235,7 +248,11 @@ export default class FilteredSearchManager { return e => { // 8 = Backspace Key // 46 = Delete Key - if (e.keyCode === 8 || e.keyCode === 46) { + // Handled by respective backspace-combination check functions + if (e.altKey || e.ctrlKey || e.metaKey) { + return; + } + if (e.keyCode === BACKSPACE_KEY_CODE || e.keyCode === DELETE_KEY_CODE) { const { lastVisualToken } = FilteredSearchVisualTokens.getLastVisualTokenBeforeInput(); const { tokenName, tokenValue } = DropdownUtils.getVisualTokenValues(lastVisualToken); const canEdit = tokenName && this.canEdit && this.canEdit(tokenName, tokenValue); @@ -258,15 +275,31 @@ export default class FilteredSearchManager { }; } + checkForAltOrCtrlBackspace(e) { + if ((e.altKey || e.ctrlKey) && e.keyCode === BACKSPACE_KEY_CODE) { + // Default to native OS behavior if input value present + if (this.filteredSearchInput.value === '') { + FilteredSearchVisualTokens.removeLastTokenPartial(); + } + } + } + + checkForMetaBackspace(e) { + const onlyMeta = e.metaKey && !e.altKey && !e.ctrlKey && !e.shiftKey; + if (onlyMeta && e.keyCode === BACKSPACE_KEY_CODE) { + this.clearSearch(); + } + } + checkForEnter(e) { - if (e.keyCode === 38 || e.keyCode === 40) { + if (e.keyCode === UP_KEY_CODE || e.keyCode === DOWN_KEY_CODE) { const { selectionStart } = this.filteredSearchInput; e.preventDefault(); this.filteredSearchInput.setSelectionRange(selectionStart, selectionStart); } - if (e.keyCode === 13) { + if (e.keyCode === ENTER_KEY_CODE) { const dropdown = this.dropdownManager.mapping[this.dropdownManager.currentDropdown]; const dropdownEl = dropdown.element; const activeElements = dropdownEl.querySelectorAll('.droplab-item-active'); @@ -375,7 +408,7 @@ export default class FilteredSearchManager { removeSelectedTokenKeydown(e) { // 8 = Backspace Key // 46 = Delete Key - if (e.keyCode === 8 || e.keyCode === 46) { + if (e.keyCode === BACKSPACE_KEY_CODE || e.keyCode === DELETE_KEY_CODE) { this.removeSelectedToken(); } } |