atom-space-pen-views
Version:
Atom SpacePen views that used to live in core.
362 lines (312 loc) • 10.6 kB
JavaScript
(function() {
var $, SelectListView, TextEditorView, View, fuzzyFilter, _ref,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
_ref = require('space-pen'), $ = _ref.$, View = _ref.View;
TextEditorView = require('./text-editor-view');
fuzzyFilter = null;
atom.themes.requireStylesheet(require.resolve('../stylesheets/select-list.less'));
module.exports = SelectListView = (function(_super) {
__extends(SelectListView, _super);
function SelectListView() {
return SelectListView.__super__.constructor.apply(this, arguments);
}
SelectListView.content = function() {
return this.div({
"class": 'select-list'
}, (function(_this) {
return function() {
_this.subview('filterEditorView', new TextEditorView({
mini: true
}));
_this.div({
"class": 'error-message',
outlet: 'error'
});
_this.div({
"class": 'loading',
outlet: 'loadingArea'
}, function() {
_this.span({
"class": 'loading-message',
outlet: 'loading'
});
return _this.span({
"class": 'badge',
outlet: 'loadingBadge'
});
});
return _this.ol({
"class": 'list-group',
outlet: 'list'
});
};
})(this));
};
SelectListView.prototype.maxItems = Infinity;
SelectListView.prototype.scheduleTimeout = null;
SelectListView.prototype.inputThrottle = 50;
SelectListView.prototype.cancelling = false;
/*
Section: Construction
*/
SelectListView.prototype.initialize = function() {
this.filterEditorView.getModel().getBuffer().onDidChange((function(_this) {
return function() {
return _this.schedulePopulateList();
};
})(this));
this.filterEditorView.on('blur', (function(_this) {
return function(e) {
if (!(_this.cancelling || !document.hasFocus())) {
return _this.cancel();
}
};
})(this));
atom.commands.add(this.element, {
'core:move-up': (function(_this) {
return function(event) {
_this.selectPreviousItemView();
return event.stopPropagation();
};
})(this),
'core:move-down': (function(_this) {
return function(event) {
_this.selectNextItemView();
return event.stopPropagation();
};
})(this),
'core:move-to-top': (function(_this) {
return function(event) {
_this.selectItemView(_this.list.find('li:first'));
_this.list.scrollToTop();
return event.stopPropagation();
};
})(this),
'core:move-to-bottom': (function(_this) {
return function(event) {
_this.selectItemView(_this.list.find('li:last'));
_this.list.scrollToBottom();
return event.stopPropagation();
};
})(this),
'core:confirm': (function(_this) {
return function(event) {
_this.confirmSelection();
return event.stopPropagation();
};
})(this),
'core:cancel': (function(_this) {
return function(event) {
_this.cancel();
return event.stopPropagation();
};
})(this)
});
this.list.on('mousedown', (function(_this) {
return function(_arg) {
var target;
target = _arg.target;
if (target === _this.list[0]) {
return false;
}
};
})(this));
this.list.on('mousedown', 'li', (function(_this) {
return function(e) {
_this.selectItemView($(e.target).closest('li'));
e.preventDefault();
return false;
};
})(this));
return this.list.on('mouseup', 'li', (function(_this) {
return function(e) {
if ($(e.target).closest('li').hasClass('selected')) {
_this.confirmSelection();
}
e.preventDefault();
return false;
};
})(this));
};
/*
Section: Methods that must be overridden
*/
SelectListView.prototype.viewForItem = function(item) {
throw new Error("Subclass must implement a viewForItem(item) method");
};
SelectListView.prototype.confirmed = function(item) {
throw new Error("Subclass must implement a confirmed(item) method");
};
/*
Section: Managing the list of items
*/
SelectListView.prototype.setItems = function(items) {
this.items = items != null ? items : [];
this.populateList();
return this.setLoading();
};
SelectListView.prototype.getSelectedItem = function() {
return this.getSelectedItemView().data('select-list-item');
};
SelectListView.prototype.getFilterKey = function() {};
SelectListView.prototype.getFilterQuery = function() {
return this.filterEditorView.getText();
};
SelectListView.prototype.setMaxItems = function(maxItems) {
this.maxItems = maxItems;
};
SelectListView.prototype.populateList = function() {
var filterQuery, filteredItems, i, item, itemView, _i, _ref1;
if (this.items == null) {
return;
}
filterQuery = this.getFilterQuery();
if (filterQuery.length) {
if (fuzzyFilter == null) {
fuzzyFilter = require('fuzzaldrin').filter;
}
filteredItems = fuzzyFilter(this.items, filterQuery, {
key: this.getFilterKey()
});
} else {
filteredItems = this.items;
}
this.list.empty();
if (filteredItems.length) {
this.setError(null);
for (i = _i = 0, _ref1 = Math.min(filteredItems.length, this.maxItems); 0 <= _ref1 ? _i < _ref1 : _i > _ref1; i = 0 <= _ref1 ? ++_i : --_i) {
item = filteredItems[i];
itemView = $(this.viewForItem(item));
itemView.data('select-list-item', item);
this.list.append(itemView);
}
return this.selectItemView(this.list.find('li:first'));
} else {
return this.setError(this.getEmptyMessage(this.items.length, filteredItems.length));
}
};
/*
Section: Messages to the user
*/
SelectListView.prototype.setError = function(message) {
if (message == null) {
message = '';
}
if (message.length === 0) {
return this.error.text('').hide();
} else {
this.setLoading();
return this.error.text(message).show();
}
};
SelectListView.prototype.setLoading = function(message) {
if (message == null) {
message = '';
}
if (message.length === 0) {
this.loading.text("");
this.loadingBadge.text("");
return this.loadingArea.hide();
} else {
this.setError();
this.loading.text(message);
return this.loadingArea.show();
}
};
SelectListView.prototype.getEmptyMessage = function(itemCount, filteredItemCount) {
return 'No matches found';
};
/*
Section: View Actions
*/
SelectListView.prototype.cancel = function() {
var filterEditorViewFocused;
this.list.empty();
this.cancelling = true;
filterEditorViewFocused = this.filterEditorView.hasFocus();
if (typeof this.cancelled === "function") {
this.cancelled();
}
this.filterEditorView.setText('');
if (filterEditorViewFocused) {
this.restoreFocus();
}
this.cancelling = false;
return clearTimeout(this.scheduleTimeout);
};
SelectListView.prototype.focusFilterEditor = function() {
return this.filterEditorView.focus();
};
SelectListView.prototype.storeFocusedElement = function() {
return this.previouslyFocusedElement = $(document.activeElement);
};
/*
Section: Private
*/
SelectListView.prototype.selectPreviousItemView = function() {
var view;
view = this.getSelectedItemView().prev();
if (!view.length) {
view = this.list.find('li:last');
}
return this.selectItemView(view);
};
SelectListView.prototype.selectNextItemView = function() {
var view;
view = this.getSelectedItemView().next();
if (!view.length) {
view = this.list.find('li:first');
}
return this.selectItemView(view);
};
SelectListView.prototype.selectItemView = function(view) {
if (!view.length) {
return;
}
this.list.find('.selected').removeClass('selected');
view.addClass('selected');
return this.scrollToItemView(view);
};
SelectListView.prototype.scrollToItemView = function(view) {
var desiredBottom, desiredTop, scrollTop;
scrollTop = this.list.scrollTop();
desiredTop = view.position().top + scrollTop;
desiredBottom = desiredTop + view.outerHeight();
if (desiredTop < scrollTop) {
return this.list.scrollTop(desiredTop);
} else if (desiredBottom > this.list.scrollBottom()) {
return this.list.scrollBottom(desiredBottom);
}
};
SelectListView.prototype.restoreFocus = function() {
var _ref1;
return (_ref1 = this.previouslyFocusedElement) != null ? _ref1.focus() : void 0;
};
SelectListView.prototype.getSelectedItemView = function() {
return this.list.find('li.selected');
};
SelectListView.prototype.confirmSelection = function() {
var item;
item = this.getSelectedItem();
if (item != null) {
return this.confirmed(item);
} else {
return this.cancel();
}
};
SelectListView.prototype.schedulePopulateList = function() {
var populateCallback;
clearTimeout(this.scheduleTimeout);
populateCallback = (function(_this) {
return function() {
if (_this.isOnDom()) {
return _this.populateList();
}
};
})(this);
return this.scheduleTimeout = setTimeout(populateCallback, this.inputThrottle);
};
return SelectListView;
})(View);
}).call(this);