]> git.r.bdr.sh - rbdr/dotfiles/blob - atom/packages/ex-mode/node_modules/atom-space-pen-views/lib/select-list-view.js
Merge remote-tracking branch 'origin/master'
[rbdr/dotfiles] / atom / packages / ex-mode / node_modules / atom-space-pen-views / lib / select-list-view.js
1 (function() {
2 var $, SelectListView, TextEditorView, View, fuzzyFilter, _ref,
3 __hasProp = {}.hasOwnProperty,
4 __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; };
5
6 _ref = require('space-pen'), $ = _ref.$, View = _ref.View;
7
8 TextEditorView = require('./text-editor-view');
9
10 fuzzyFilter = null;
11
12 atom.themes.requireStylesheet(require.resolve('../stylesheets/select-list.less'));
13
14 module.exports = SelectListView = (function(_super) {
15 __extends(SelectListView, _super);
16
17 function SelectListView() {
18 return SelectListView.__super__.constructor.apply(this, arguments);
19 }
20
21 SelectListView.content = function() {
22 return this.div({
23 "class": 'select-list'
24 }, (function(_this) {
25 return function() {
26 _this.subview('filterEditorView', new TextEditorView({
27 mini: true
28 }));
29 _this.div({
30 "class": 'error-message',
31 outlet: 'error'
32 });
33 _this.div({
34 "class": 'loading',
35 outlet: 'loadingArea'
36 }, function() {
37 _this.span({
38 "class": 'loading-message',
39 outlet: 'loading'
40 });
41 return _this.span({
42 "class": 'badge',
43 outlet: 'loadingBadge'
44 });
45 });
46 return _this.ol({
47 "class": 'list-group',
48 outlet: 'list'
49 });
50 };
51 })(this));
52 };
53
54 SelectListView.prototype.maxItems = Infinity;
55
56 SelectListView.prototype.scheduleTimeout = null;
57
58 SelectListView.prototype.inputThrottle = 50;
59
60 SelectListView.prototype.cancelling = false;
61
62
63 /*
64 Section: Construction
65 */
66
67 SelectListView.prototype.initialize = function() {
68 this.filterEditorView.getModel().getBuffer().onDidChange((function(_this) {
69 return function() {
70 return _this.schedulePopulateList();
71 };
72 })(this));
73 this.filterEditorView.on('blur', (function(_this) {
74 return function(e) {
75 if (!_this.cancelling) {
76 return _this.cancel();
77 }
78 };
79 })(this));
80 atom.commands.add(this.element, {
81 'core:move-up': (function(_this) {
82 return function(event) {
83 _this.selectPreviousItemView();
84 return event.stopPropagation();
85 };
86 })(this),
87 'core:move-down': (function(_this) {
88 return function(event) {
89 _this.selectNextItemView();
90 return event.stopPropagation();
91 };
92 })(this),
93 'core:move-to-top': (function(_this) {
94 return function(event) {
95 _this.selectItemView(_this.list.find('li:first'));
96 _this.list.scrollToTop();
97 return event.stopPropagation();
98 };
99 })(this),
100 'core:move-to-bottom': (function(_this) {
101 return function(event) {
102 _this.selectItemView(_this.list.find('li:last'));
103 _this.list.scrollToBottom();
104 return event.stopPropagation();
105 };
106 })(this),
107 'core:confirm': (function(_this) {
108 return function(event) {
109 _this.confirmSelection();
110 return event.stopPropagation();
111 };
112 })(this),
113 'core:cancel': (function(_this) {
114 return function(event) {
115 _this.cancel();
116 return event.stopPropagation();
117 };
118 })(this)
119 });
120 this.list.on('mousedown', (function(_this) {
121 return function(_arg) {
122 var target;
123 target = _arg.target;
124 if (target === _this.list[0]) {
125 return false;
126 }
127 };
128 })(this));
129 this.list.on('mousedown', 'li', (function(_this) {
130 return function(e) {
131 _this.selectItemView($(e.target).closest('li'));
132 e.preventDefault();
133 return false;
134 };
135 })(this));
136 return this.list.on('mouseup', 'li', (function(_this) {
137 return function(e) {
138 if ($(e.target).closest('li').hasClass('selected')) {
139 _this.confirmSelection();
140 }
141 e.preventDefault();
142 return false;
143 };
144 })(this));
145 };
146
147
148 /*
149 Section: Methods that must be overridden
150 */
151
152 SelectListView.prototype.viewForItem = function(item) {
153 throw new Error("Subclass must implement a viewForItem(item) method");
154 };
155
156 SelectListView.prototype.confirmed = function(item) {
157 throw new Error("Subclass must implement a confirmed(item) method");
158 };
159
160
161 /*
162 Section: Managing the list of items
163 */
164
165 SelectListView.prototype.setItems = function(items) {
166 this.items = items != null ? items : [];
167 this.populateList();
168 return this.setLoading();
169 };
170
171 SelectListView.prototype.getSelectedItem = function() {
172 return this.getSelectedItemView().data('select-list-item');
173 };
174
175 SelectListView.prototype.getFilterKey = function() {};
176
177 SelectListView.prototype.getFilterQuery = function() {
178 return this.filterEditorView.getText();
179 };
180
181 SelectListView.prototype.setMaxItems = function(maxItems) {
182 this.maxItems = maxItems;
183 };
184
185 SelectListView.prototype.populateList = function() {
186 var filterQuery, filteredItems, i, item, itemView, _i, _ref1;
187 if (this.items == null) {
188 return;
189 }
190 filterQuery = this.getFilterQuery();
191 if (filterQuery.length) {
192 if (fuzzyFilter == null) {
193 fuzzyFilter = require('fuzzaldrin').filter;
194 }
195 filteredItems = fuzzyFilter(this.items, filterQuery, {
196 key: this.getFilterKey()
197 });
198 } else {
199 filteredItems = this.items;
200 }
201 this.list.empty();
202 if (filteredItems.length) {
203 this.setError(null);
204 for (i = _i = 0, _ref1 = Math.min(filteredItems.length, this.maxItems); 0 <= _ref1 ? _i < _ref1 : _i > _ref1; i = 0 <= _ref1 ? ++_i : --_i) {
205 item = filteredItems[i];
206 itemView = $(this.viewForItem(item));
207 itemView.data('select-list-item', item);
208 this.list.append(itemView);
209 }
210 return this.selectItemView(this.list.find('li:first'));
211 } else {
212 return this.setError(this.getEmptyMessage(this.items.length, filteredItems.length));
213 }
214 };
215
216
217 /*
218 Section: Messages to the user
219 */
220
221 SelectListView.prototype.setError = function(message) {
222 if (message == null) {
223 message = '';
224 }
225 if (message.length === 0) {
226 return this.error.text('').hide();
227 } else {
228 this.setLoading();
229 return this.error.text(message).show();
230 }
231 };
232
233 SelectListView.prototype.setLoading = function(message) {
234 if (message == null) {
235 message = '';
236 }
237 if (message.length === 0) {
238 this.loading.text("");
239 this.loadingBadge.text("");
240 return this.loadingArea.hide();
241 } else {
242 this.setError();
243 this.loading.text(message);
244 return this.loadingArea.show();
245 }
246 };
247
248 SelectListView.prototype.getEmptyMessage = function(itemCount, filteredItemCount) {
249 return 'No matches found';
250 };
251
252
253 /*
254 Section: View Actions
255 */
256
257 SelectListView.prototype.cancel = function() {
258 var filterEditorViewFocused;
259 this.list.empty();
260 this.cancelling = true;
261 filterEditorViewFocused = this.filterEditorView.hasFocus();
262 if (typeof this.cancelled === "function") {
263 this.cancelled();
264 }
265 this.filterEditorView.setText('');
266 if (filterEditorViewFocused) {
267 this.restoreFocus();
268 }
269 this.cancelling = false;
270 return clearTimeout(this.scheduleTimeout);
271 };
272
273 SelectListView.prototype.focusFilterEditor = function() {
274 return this.filterEditorView.focus();
275 };
276
277 SelectListView.prototype.storeFocusedElement = function() {
278 return this.previouslyFocusedElement = $(document.activeElement);
279 };
280
281
282 /*
283 Section: Private
284 */
285
286 SelectListView.prototype.selectPreviousItemView = function() {
287 var view;
288 view = this.getSelectedItemView().prev();
289 if (!view.length) {
290 view = this.list.find('li:last');
291 }
292 return this.selectItemView(view);
293 };
294
295 SelectListView.prototype.selectNextItemView = function() {
296 var view;
297 view = this.getSelectedItemView().next();
298 if (!view.length) {
299 view = this.list.find('li:first');
300 }
301 return this.selectItemView(view);
302 };
303
304 SelectListView.prototype.selectItemView = function(view) {
305 if (!view.length) {
306 return;
307 }
308 this.list.find('.selected').removeClass('selected');
309 view.addClass('selected');
310 return this.scrollToItemView(view);
311 };
312
313 SelectListView.prototype.scrollToItemView = function(view) {
314 var desiredBottom, desiredTop, scrollTop;
315 scrollTop = this.list.scrollTop();
316 desiredTop = view.position().top + scrollTop;
317 desiredBottom = desiredTop + view.outerHeight();
318 if (desiredTop < scrollTop) {
319 return this.list.scrollTop(desiredTop);
320 } else if (desiredBottom > this.list.scrollBottom()) {
321 return this.list.scrollBottom(desiredBottom);
322 }
323 };
324
325 SelectListView.prototype.restoreFocus = function() {
326 var _ref1;
327 return (_ref1 = this.previouslyFocusedElement) != null ? _ref1.focus() : void 0;
328 };
329
330 SelectListView.prototype.getSelectedItemView = function() {
331 return this.list.find('li.selected');
332 };
333
334 SelectListView.prototype.confirmSelection = function() {
335 var item;
336 item = this.getSelectedItem();
337 if (item != null) {
338 return this.confirmed(item);
339 } else {
340 return this.cancel();
341 }
342 };
343
344 SelectListView.prototype.schedulePopulateList = function() {
345 var populateCallback;
346 clearTimeout(this.scheduleTimeout);
347 populateCallback = (function(_this) {
348 return function() {
349 if (_this.isOnDom()) {
350 return _this.populateList();
351 }
352 };
353 })(this);
354 return this.scheduleTimeout = setTimeout(populateCallback, this.inputThrottle);
355 };
356
357 return SelectListView;
358
359 })(View);
360
361 }).call(this);