diff --git a/app/assets/javascripts/filtered_search/dropdown_utils.js.es6 b/app/assets/javascripts/filtered_search/dropdown_utils.js.es6 index 07d257ad8d9..1bfcbd011b0 100644 --- a/app/assets/javascripts/filtered_search/dropdown_utils.js.es6 +++ b/app/assets/javascripts/filtered_search/dropdown_utils.js.es6 @@ -76,13 +76,25 @@ static getSearchInput(filteredSearchInput) { const selectionStart = filteredSearchInput.selectionStart; const inputValue = filteredSearchInput.value; - const rightPos = inputValue.slice(selectionStart).search(/\s/); + const { right } = gl.DropdownUtils.getInputSelectionPosition(filteredSearchInput); - if (rightPos < 0) { + if (right < 0) { return inputValue; } - return inputValue.slice(0, rightPos + selectionStart + 1).trim(); + return inputValue.slice(0, right + selectionStart + 1).trim(); + } + + static getInputSelectionPosition(input) { + const inputValue = input.value; + const selectionStart = input.selectionStart; + const left = inputValue.slice(0, selectionStart + 1).search(/\S+$/); + const right = inputValue.slice(selectionStart).search(/\s/); + + return { + left, + right, + }; } } diff --git a/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6 b/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6 index 4577aa2c94e..95c8761638c 100644 --- a/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6 +++ b/app/assets/javascripts/filtered_search/filtered_search_dropdown_manager.js.es6 @@ -57,29 +57,23 @@ static addWordToInput(tokenName, tokenValue = '') { const input = document.querySelector('.filtered-search'); + const inputValue = input.value; const word = `${tokenName}:${tokenValue}`; - const inputValue = gl.DropdownUtils.getSearchInput(input).trim(); - const { lastToken, searchToken } = gl.FilteredSearchTokenizer.processTokens(inputValue); - const lastSearchToken = searchToken.split(' ').last(); - const lastInputCharacter = input.value[input.value.length - 1]; - const lastInputTrimmedCharacter = input.value.trim()[input.value.trim().length - 1]; + // Get the string to replace + const selectionStart = input.selectionStart; + const { left } = gl.DropdownUtils.getInputSelectionPosition(input); + let { right } = gl.DropdownUtils.getInputSelectionPosition(input); - // Remove the typed tokenName - if (word.indexOf(lastSearchToken) === 0 && searchToken !== '') { - // Remove spaces after the colon - if (lastInputCharacter === ' ' && lastInputTrimmedCharacter === ':') { - input.value = input.value.trim(); - } - - input.value = input.value.slice(0, -1 * lastSearchToken.length); - } else if (lastInputCharacter !== ' ' || (lastToken && lastToken.value[lastToken.value.length - 1] === ' ')) { - // Remove the existing tokenValue - const lastTokenString = `${lastToken.key}:${lastToken.symbol}${lastToken.value}`; - input.value = input.value.slice(0, -1 * lastTokenString.length); + if (right < 0) { + right = inputValue.length; } - input.value += word; + if (left !== -1) { + input.value = `${inputValue.substr(0, left)}${word}${inputValue.substr(right + selectionStart)}`; + } else { + input.value += word; + } } updateCurrentDropdownOffset() { @@ -93,7 +87,8 @@ const filterIconPadding = 27; const offset = gl.text - .getTextWidth(gl.DropdownUtils.getSearchInput(this.filteredSearchInput).trim(), this.font) + filterIconPadding; + .getTextWidth(gl.DropdownUtils.getSearchInput(this.filteredSearchInput).trim(), this.font) + + filterIconPadding; this.mapping[key].reference.setOffset(offset); } diff --git a/app/assets/javascripts/filtered_search/filtered_search_manager.js.es6 b/app/assets/javascripts/filtered_search/filtered_search_manager.js.es6 index 12b8cb4b4b1..b0cabf9d378 100644 --- a/app/assets/javascripts/filtered_search/filtered_search_manager.js.es6 +++ b/app/assets/javascripts/filtered_search/filtered_search_manager.js.es6 @@ -193,7 +193,8 @@ } showOnClick() { - const currentDropdownRef = this.dropdownManager.mapping[this.dropdownManager.currentDropdown].reference; + const dropdown = this.dropdownManager.mapping[this.dropdownManager.currentDropdown]; + const currentDropdownRef = dropdown.reference; this.setDropdownWrapper(); currentDropdownRef.dispatchInputEvent();