diff --git a/spec/app/autocomplete-spec.coffee b/spec/app/autocomplete-spec.coffee index cdeaa19f2..ec281470b 100644 --- a/spec/app/autocomplete-spec.coffee +++ b/spec/app/autocomplete-spec.coffee @@ -166,7 +166,7 @@ describe "Autocomplete", -> expect(editor.find('.autocomplete')).not.toExist() describe 'move-up event', -> - it 'replaces selection with previous match', -> + it "highlights the previous match and replaces the selection with it", -> editor.buffer.insert([10,0] ,"extra:t:extra") editor.setCursorBufferPosition([10,6]) autocomplete.attach() @@ -183,8 +183,25 @@ describe "Autocomplete", -> expect(autocomplete.find('li:eq(7)')).not.toHaveClass('selected') expect(autocomplete.find('li:eq(6)')).toHaveClass('selected') + it "scrolls to the selected match if it is out of view", -> + editor.buffer.insert([10,0] ,"t") + editor.setCursorBufferPosition([10, 0]) + editor.attachToDom() + autocomplete.attach() + + matchesList = autocomplete.matchesList + matchesList.height(100) + expect(matchesList.height()).toBeLessThan matchesList[0].scrollHeight + + matchCount = matchesList.find('li').length + miniEditor.trigger 'move-up' + expect(matchesList.scrollBottom()).toBe matchesList[0].scrollHeight + + miniEditor.trigger 'move-up' for i in [1...matchCount] + expect(matchesList.scrollTop()).toBe 0 + describe 'move-down event', -> - it 'replaces selection with next match', -> + it "highlights the next match and replaces the selection with it", -> editor.buffer.insert([10,0] ,"extra:s:extra") editor.setCursorBufferPosition([10,7]) autocomplete.attach() @@ -199,6 +216,23 @@ describe "Autocomplete", -> expect(autocomplete.find('li:eq(0)')).toHaveClass('selected') expect(autocomplete.find('li:eq(1)')).not.toHaveClass('selected') + it "scrolls to the selected match if it is out of view", -> + editor.buffer.insert([10,0] ,"t") + editor.setCursorBufferPosition([10, 0]) + editor.attachToDom() + autocomplete.attach() + + matchesList = autocomplete.matchesList + matchesList.height(100) + expect(matchesList.height()).toBeLessThan matchesList[0].scrollHeight + + matchCount = matchesList.find('li').length + miniEditor.trigger 'move-down' for i in [1...matchCount] + expect(matchesList.scrollBottom()).toBe matchesList[0].scrollHeight + + miniEditor.trigger 'move-down' + expect(matchesList.scrollTop()).toBe 0 + describe "when the mini-editor receives keyboard input", -> describe "when text is removed from the mini-editor", -> it "reloads the match list based on the mini-editor's text", -> diff --git a/src/app/autocomplete.coffee b/src/app/autocomplete.coffee index db2a5eaca..4866cc2f2 100644 --- a/src/app/autocomplete.coffee +++ b/src/app/autocomplete.coffee @@ -114,7 +114,17 @@ class Autocomplete extends View selectMatchAtIndex: (index) -> @currentMatchIndex = index @matchesList.find("li").removeClass "selected" - @matchesList.find("li:eq(#{index})").addClass "selected" + + liToSelect = @matchesList.find("li:eq(#{index})") + liToSelect.addClass "selected" + + topOfLiToSelect = liToSelect.position().top + @matchesList.scrollTop() + bottomOfLiToSelect = topOfLiToSelect + liToSelect.outerHeight() + if topOfLiToSelect < @matchesList.scrollTop() + @matchesList.scrollTop(topOfLiToSelect) + else if bottomOfLiToSelect > @matchesList.scrollBottom() + @matchesList.scrollBottom(bottomOfLiToSelect) + @replaceSelectedTextWithMatch @selectedMatch() selectedMatch: -> diff --git a/static/autocomplete.css b/static/autocomplete.css index 0b10f95bc..462945a37 100644 --- a/static/autocomplete.css +++ b/static/autocomplete.css @@ -10,6 +10,7 @@ } .autocomplete ol { + position: relative; overflow-y: scroll; max-height: 200px; }