Position autocomplete menu above cursor if there isn't room below

This commit is contained in:
Corey Johnson & Nathan Sobo
2012-04-20 17:18:07 -06:00
parent 11c465b7fd
commit f652b4e357
6 changed files with 42 additions and 20 deletions

View File

@@ -1,4 +1,4 @@
{runSpecSuite} = require 'jasmine-helper'
document.title = "Benchmark Suite"
runSpecSuite("benchmark-suite", false)
runSpecSuite("benchmark-suite", false)

View File

@@ -15,9 +15,6 @@ describe "Autocomplete", ->
autocomplete = new Autocomplete(editor)
miniEditor = autocomplete.miniEditor
afterEach ->
autocomplete.remove()
describe "@activate(rootView)", ->
it "activates autocomplete on all existing and future editors (but not on autocomplete's own mini editor)", ->
rootView = new RootView(pathToOpen: require.resolve('fixtures/sample.js'))
@@ -370,14 +367,31 @@ describe "Autocomplete", ->
describe ".attach()", ->
beforeEach ->
editor.setCursorBufferPosition [1, 1]
editor.attachToDom()
autocomplete.attach()
setEditorHeightInLines(editor, 8)
editor.setCursorBufferPosition [1, 1]
it "adds the autocomplete view to the editor", ->
expect(editor.find('.autocomplete')).toExist()
expect(autocomplete.position().top).toBeGreaterThan 0
expect(autocomplete.position().left).toBeGreaterThan 0
describe "when the autocomplete view fits below the cursor", ->
it "adds the autocomplete view to the editor below the cursor", ->
cursorPixelPosition = editor.pixelPositionForScreenPosition(editor.getCursorScreenPosition())
autocomplete.attach()
expect(editor.find('.autocomplete')).toExist()
expect(autocomplete.position().top).toBe cursorPixelPosition.top + editor.lineHeight
expect(autocomplete.position().left).toBe cursorPixelPosition.left
describe "when the autocomplete view does not fit below the cursor", ->
it "adds the autocomplete view to the editor above the cursor", ->
editor.setCursorScreenPosition([6, 0])
editor.insertText('t ')
editor.setCursorScreenPosition([6, 0])
cursorPixelPosition = editor.pixelPositionForScreenPosition(editor.getCursorScreenPosition())
autocomplete.attach()
expect(autocomplete.parent()).toExist()
autocompleteBottom = autocomplete.position().top + autocomplete.outerHeight()
expect(autocompleteBottom).toBe cursorPixelPosition.top
expect(autocomplete.position().left).toBe cursorPixelPosition.left
describe ".detach()", ->
it "clears the mini-editor and unbinds autocomplete event handlers for move-up and move-down", ->

View File

@@ -620,7 +620,7 @@ describe "Editor", ->
expect(editor.scroller.scrollTop()).toBe(0)
it "reduces scroll margins when there isn't enough height to maintain them and scroll smoothly", ->
setEditorHeightInChars(editor, 5)
setEditorHeightInLines(editor, 5)
_.times 3, ->
editor.moveCursorDown()
@@ -719,7 +719,7 @@ describe "Editor", ->
it "only attempts to scroll when a cursor is visible", ->
setEditorWidthInChars(editor, 20)
setEditorHeightInChars(editor, 10)
setEditorHeightInLines(editor, 10)
editor.setCursorBufferPosition([11,0])
editor.addCursorAtBufferPosition([6,50])
editor.addCursorAtBufferPosition([0,0])
@@ -734,7 +734,7 @@ describe "Editor", ->
it "only attempts to scroll once when multiple cursors are visible", ->
setEditorWidthInChars(editor, 20)
setEditorHeightInChars(editor, 10)
setEditorHeightInLines(editor, 10)
editor.setCursorBufferPosition([11,0])
editor.addCursorAtBufferPosition([0,0])
editor.addCursorAtBufferPosition([6,0])
@@ -1068,7 +1068,7 @@ describe "Editor", ->
describe "multiple cursors", ->
it "places multiple cursor with meta-click", ->
editor.attachToDom()
setEditorHeightInChars(editor, 5)
setEditorHeightInLines(editor, 5)
editor.lines.trigger mousedownEvent(editor: editor, point: [3, 0])
editor.scroller.scrollTop(editor.lineHeight * 6)

View File

@@ -110,7 +110,7 @@ window.tokensText = (tokens) ->
window.setEditorWidthInChars = (editor, widthInChars, charWidth=editor.charWidth) ->
editor.width(charWidth * widthInChars + editor.lines.position().left)
window.setEditorHeightInChars = (editor, heightInChars, charHeight=editor.lineHeight) ->
window.setEditorHeightInLines = (editor, heightInChars, charHeight=editor.lineHeight) ->
editor.height(charHeight * heightInChars + editor.lines.position().top)
$.fn.resultOfTrigger = (type) ->

View File

@@ -100,12 +100,12 @@ class Autocomplete extends View
@originalSelectionBufferRange = @editor.getSelection().getBufferRange()
@allMatches = @findMatchesForCurrentSelection()
cursorScreenPosition = @editor.getCursorScreenPosition()
{left, top} = @editor.pixelPositionForScreenPosition(cursorScreenPosition)
@css {left: left, top: top + @editor.lineHeight}
originalCursorPosition = @editor.getCursorScreenPosition()
@filterMatches()
@editor.lines.append(this)
@setPosition(originalCursorPosition)
@miniEditor.focus()
detach: ->
@@ -114,6 +114,15 @@ class Autocomplete extends View
super
@miniEditor.buffer.setText('')
setPosition: (originalCursorPosition) ->
{ left, top } = @editor.pixelPositionForScreenPosition(originalCursorPosition)
potentialTop = top + @editor.lineHeight
potentialBottom = potentialTop + @outerHeight()
if potentialBottom > @editor.scroller.scrollBottom()
@css(left: left, bottom: @editor.lines.height() - top, top: 'inherit')
else
@css(left: left, top: potentialTop, bottom: 'inherit')
selectPreviousMatch: ->
previousIndex = @currentMatchIndex - 1
previousIndex = @filteredMatches.length - 1 if previousIndex < 0

View File

@@ -5,8 +5,7 @@
background-color: #444;
border: 2px solid #222;
color: #eee;
-webkit-box-shadow: 0 0 5px 5px #222;
margin: 5px;
-webkit-box-shadow: 0 0 3px 3px rgba(0, 0, 0, .5);
}
.autocomplete ol {