mirror of
https://github.com/atom/atom.git
synced 2026-01-29 08:48:17 -05:00
153 lines
3.9 KiB
CoffeeScript
153 lines
3.9 KiB
CoffeeScript
$ = require 'jquery'
|
|
{ View } = require 'space-pen'
|
|
Editor = require 'editor'
|
|
fuzzyFilter = require 'fuzzy-filter'
|
|
|
|
module.exports =
|
|
class SelectList extends View
|
|
@content: ->
|
|
@div class: @viewClass(), =>
|
|
@subview 'miniEditor', new Editor(mini: true)
|
|
@div class: 'error', outlet: 'error'
|
|
@div class: 'loading', outlet: 'loading'
|
|
@ol outlet: 'list'
|
|
|
|
@viewClass: -> 'select-list'
|
|
|
|
maxItems: Infinity
|
|
scheduleTimeout: null
|
|
inputThrottle: 50
|
|
cancelling: false
|
|
|
|
initialize: ->
|
|
requireStylesheet 'select-list.css'
|
|
|
|
@miniEditor.getBuffer().on 'changed', => @schedulePopulateList()
|
|
@miniEditor.on 'focusout', => @cancel() unless @cancelling
|
|
@on 'core:move-up', => @selectPreviousItem()
|
|
@on 'core:move-down', => @selectNextItem()
|
|
@on 'core:move-to-top', =>
|
|
@selectItem(@list.find('li:first'))
|
|
@list.scrollToTop()
|
|
@on 'core:move-to-bottom', =>
|
|
@selectItem(@list.find('li:last'))
|
|
@list.scrollToBottom()
|
|
@on 'core:confirm', => @confirmSelection()
|
|
@on 'core:cancel', => @cancel()
|
|
|
|
@list.on 'mousedown', 'li', (e) =>
|
|
@selectItem($(e.target).closest('li'))
|
|
e.preventDefault()
|
|
|
|
@list.on 'mouseup', 'li', (e) =>
|
|
@confirmSelection() if $(e.target).closest('li').hasClass('selected')
|
|
e.preventDefault()
|
|
|
|
schedulePopulateList: ->
|
|
clearTimeout(@scheduleTimeout)
|
|
@scheduleTimeout = setTimeout((=> @populateList()), @inputThrottle)
|
|
|
|
setArray: (@array) ->
|
|
@populateList()
|
|
@setLoading()
|
|
|
|
setError: (message) ->
|
|
if not message or message.length == ""
|
|
@error.text("").hide()
|
|
@removeClass("error")
|
|
else
|
|
@setLoading()
|
|
@error.text(message).show()
|
|
@addClass("error")
|
|
|
|
setLoading: (message) ->
|
|
if not message or message.length == ""
|
|
@loading.text("").hide()
|
|
else
|
|
@setError()
|
|
@loading.text(message).show()
|
|
|
|
populateList: ->
|
|
return unless @array?
|
|
|
|
filterQuery = @miniEditor.getText()
|
|
if filterQuery.length
|
|
filteredArray = fuzzyFilter(@array, filterQuery, key: @filterKey)
|
|
else
|
|
filteredArray = @array
|
|
|
|
@list.empty()
|
|
if filteredArray.length
|
|
@setError(null)
|
|
|
|
for i in [0...Math.min(filteredArray.length, @maxItems)]
|
|
element = filteredArray[i]
|
|
item = @itemForElement(element)
|
|
item.data('select-list-element', element)
|
|
@list.append(item)
|
|
|
|
@selectItem(@list.find('li:first'))
|
|
else
|
|
@setError("No matches found")
|
|
|
|
selectPreviousItem: ->
|
|
item = @getSelectedItem().prev()
|
|
item = @list.find('li:last') unless item.length
|
|
@selectItem(item)
|
|
|
|
selectNextItem: ->
|
|
item = @getSelectedItem().next()
|
|
item = @list.find('li:first') unless item.length
|
|
@selectItem(item)
|
|
|
|
selectItem: (item) ->
|
|
return unless item.length
|
|
@list.find('.selected').removeClass('selected')
|
|
item.addClass 'selected'
|
|
@scrollToItem(item)
|
|
|
|
scrollToItem: (item) ->
|
|
scrollTop = @list.scrollTop()
|
|
desiredTop = item.position().top + scrollTop
|
|
desiredBottom = desiredTop + item.outerHeight()
|
|
|
|
if desiredTop < scrollTop
|
|
@list.scrollTop(desiredTop)
|
|
else if desiredBottom > @list.scrollBottom()
|
|
@list.scrollBottom(desiredBottom)
|
|
|
|
getSelectedItem: ->
|
|
@list.find('li.selected')
|
|
|
|
getSelectedElement: ->
|
|
@getSelectedItem().data('select-list-element')
|
|
|
|
confirmSelection: ->
|
|
element = @getSelectedElement()
|
|
if element?
|
|
@confirmed(element)
|
|
else
|
|
@cancel()
|
|
|
|
attach: ->
|
|
@storeFocusedElement()
|
|
|
|
storeFocusedElement: ->
|
|
@previouslyFocusedElement = $(':focus')
|
|
|
|
restoreFocus: ->
|
|
@previouslyFocusedElement?.focus()
|
|
|
|
cancelled: ->
|
|
@miniEditor.setText('')
|
|
|
|
cancel: ->
|
|
@list.empty()
|
|
@cancelling = true
|
|
miniEditorFocused = @miniEditor.isFocused
|
|
@cancelled()
|
|
@detach()
|
|
@restoreFocus() if miniEditorFocused
|
|
@cancelling = false
|
|
clearTimeout(@scheduleTimeout)
|