1 | import { SELECTION_CHANGE, SELECTION_ITEMS_CHANGE, SelectionMode } from './Selection.types';
|
2 | import { EventGroup } from '../EventGroup';
|
3 |
|
4 |
|
5 |
|
6 | var Selection = (function () {
|
7 | |
8 |
|
9 |
|
10 |
|
11 |
|
12 | function Selection() {
|
13 | var options = [];
|
14 | for (var _i = 0
|
15 | ; _i < arguments.length
|
16 | ; _i++
|
17 | ) {
|
18 | options[_i] = arguments[_i];
|
19 | }
|
20 | var _a = options[0] || {}, onSelectionChanged = _a.onSelectionChanged, onItemsChanged = _a.onItemsChanged, getKey = _a.getKey, _b = _a.canSelectItem, canSelectItem = _b === void 0 ? function () { return true; } : _b, items = _a.items, _c = _a.selectionMode, selectionMode = _c === void 0 ? SelectionMode.multiple : _c;
|
21 | this.mode = selectionMode;
|
22 | this._getKey = getKey || defaultGetKey;
|
23 | this._changeEventSuppressionCount = 0;
|
24 | this._exemptedCount = 0;
|
25 | this._anchoredIndex = 0;
|
26 | this._unselectableCount = 0;
|
27 | this._onSelectionChanged = onSelectionChanged;
|
28 | this._onItemsChanged = onItemsChanged;
|
29 | this._canSelectItem = canSelectItem;
|
30 | this._keyToIndexMap = {};
|
31 | this._isModal = false;
|
32 | this.setItems(items || [], true);
|
33 | this.count = this.getSelectedCount();
|
34 | }
|
35 | Selection.prototype.canSelectItem = function (item, index) {
|
36 | if (typeof index === 'number' && index < 0) {
|
37 | return false;
|
38 | }
|
39 | return this._canSelectItem(item, index);
|
40 | };
|
41 | Selection.prototype.getKey = function (item, index) {
|
42 | var key = this._getKey(item, index);
|
43 | return typeof key === 'number' || key ? "" + key : '';
|
44 | };
|
45 | Selection.prototype.setChangeEvents = function (isEnabled, suppressChange) {
|
46 | this._changeEventSuppressionCount += isEnabled ? -1 : 1;
|
47 | if (this._changeEventSuppressionCount === 0 && this._hasChanged) {
|
48 | this._hasChanged = false;
|
49 | if (!suppressChange) {
|
50 | this._change();
|
51 | }
|
52 | }
|
53 | };
|
54 | Selection.prototype.isModal = function () {
|
55 | return this._isModal;
|
56 | };
|
57 | Selection.prototype.setModal = function (isModal) {
|
58 | if (this._isModal !== isModal) {
|
59 | this.setChangeEvents(false);
|
60 | this._isModal = isModal;
|
61 | if (!isModal) {
|
62 | this.setAllSelected(false);
|
63 | }
|
64 | this._change();
|
65 | this.setChangeEvents(true);
|
66 | }
|
67 | };
|
68 | |
69 |
|
70 |
|
71 |
|
72 |
|
73 |
|
74 | Selection.prototype.setItems = function (items, shouldClear) {
|
75 | if (shouldClear === void 0) { shouldClear = true; }
|
76 | var newKeyToIndexMap = {};
|
77 | var newUnselectableIndices = {};
|
78 | var hasSelectionChanged = false;
|
79 | this.setChangeEvents(false);
|
80 |
|
81 | this._unselectableCount = 0;
|
82 | var haveItemsChanged = false;
|
83 |
|
84 | for (var i = 0; i < items.length; i++) {
|
85 | var item = items[i];
|
86 | if (item) {
|
87 | var key = this.getKey(item, i);
|
88 | if (key) {
|
89 | if (!haveItemsChanged && (!(key in this._keyToIndexMap) || this._keyToIndexMap[key] !== i)) {
|
90 | haveItemsChanged = true;
|
91 | }
|
92 | newKeyToIndexMap[key] = i;
|
93 | }
|
94 | }
|
95 | newUnselectableIndices[i] = item && !this.canSelectItem(item);
|
96 | if (newUnselectableIndices[i]) {
|
97 | this._unselectableCount++;
|
98 | }
|
99 | }
|
100 | if (shouldClear || items.length === 0) {
|
101 | this._setAllSelected(false, true);
|
102 | }
|
103 |
|
104 | var newExemptedIndicies = {};
|
105 | var newExemptedCount = 0;
|
106 | for (var indexProperty in this._exemptedIndices) {
|
107 | if (this._exemptedIndices.hasOwnProperty(indexProperty)) {
|
108 | var index = Number(indexProperty);
|
109 | var item = this._items[index];
|
110 | var exemptKey = item ? this.getKey(item, Number(index)) : undefined;
|
111 | var newIndex = exemptKey ? newKeyToIndexMap[exemptKey] : index;
|
112 | if (newIndex === undefined) {
|
113 |
|
114 | hasSelectionChanged = true;
|
115 | }
|
116 | else {
|
117 |
|
118 | newExemptedIndicies[newIndex] = true;
|
119 | newExemptedCount++;
|
120 | hasSelectionChanged = hasSelectionChanged || newIndex !== index;
|
121 | }
|
122 | }
|
123 | }
|
124 | if (this._items && this._exemptedCount === 0 && items.length !== this._items.length && this._isAllSelected) {
|
125 |
|
126 | hasSelectionChanged = true;
|
127 | }
|
128 | if (!haveItemsChanged) {
|
129 | for (var _i = 0, _a = Object.keys(this._keyToIndexMap); _i < _a.length; _i++) {
|
130 | var key = _a[_i];
|
131 | if (!(key in newKeyToIndexMap)) {
|
132 | haveItemsChanged = true;
|
133 | break;
|
134 | }
|
135 | }
|
136 | }
|
137 | this._exemptedIndices = newExemptedIndicies;
|
138 | this._exemptedCount = newExemptedCount;
|
139 | this._keyToIndexMap = newKeyToIndexMap;
|
140 | this._unselectableIndices = newUnselectableIndices;
|
141 | this._items = items;
|
142 | this._selectedItems = null;
|
143 | if (hasSelectionChanged) {
|
144 | this._updateCount();
|
145 | }
|
146 | if (haveItemsChanged) {
|
147 | EventGroup.raise(this, SELECTION_ITEMS_CHANGE);
|
148 | if (this._onItemsChanged) {
|
149 | this._onItemsChanged();
|
150 | }
|
151 | }
|
152 | if (hasSelectionChanged) {
|
153 | this._change();
|
154 | }
|
155 | this.setChangeEvents(true);
|
156 | };
|
157 | Selection.prototype.getItems = function () {
|
158 | return this._items;
|
159 | };
|
160 | Selection.prototype.getSelection = function () {
|
161 | if (!this._selectedItems) {
|
162 | this._selectedItems = [];
|
163 | var items = this._items;
|
164 | if (items) {
|
165 | for (var i = 0; i < items.length; i++) {
|
166 | if (this.isIndexSelected(i)) {
|
167 | this._selectedItems.push(items[i]);
|
168 | }
|
169 | }
|
170 | }
|
171 | }
|
172 | return this._selectedItems;
|
173 | };
|
174 | Selection.prototype.getSelectedCount = function () {
|
175 | return this._isAllSelected
|
176 | ? this._items.length - this._exemptedCount - this._unselectableCount
|
177 | : this._exemptedCount;
|
178 | };
|
179 | Selection.prototype.getSelectedIndices = function () {
|
180 | if (!this._selectedIndices) {
|
181 | this._selectedIndices = [];
|
182 | var items = this._items;
|
183 | if (items) {
|
184 | for (var i = 0; i < items.length; i++) {
|
185 | if (this.isIndexSelected(i)) {
|
186 | this._selectedIndices.push(i);
|
187 | }
|
188 | }
|
189 | }
|
190 | }
|
191 | return this._selectedIndices;
|
192 | };
|
193 | Selection.prototype.getItemIndex = function (key) {
|
194 | var index = this._keyToIndexMap[key];
|
195 | return (index !== null && index !== void 0 ? index : -1);
|
196 | };
|
197 | Selection.prototype.isRangeSelected = function (fromIndex, count) {
|
198 | if (count === 0) {
|
199 | return false;
|
200 | }
|
201 | var endIndex = fromIndex + count;
|
202 | for (var i = fromIndex; i < endIndex; i++) {
|
203 | if (!this.isIndexSelected(i)) {
|
204 | return false;
|
205 | }
|
206 | }
|
207 | return true;
|
208 | };
|
209 | Selection.prototype.isAllSelected = function () {
|
210 | var selectableCount = this._items.length - this._unselectableCount;
|
211 |
|
212 | if (this.mode === SelectionMode.single) {
|
213 | selectableCount = Math.min(selectableCount, 1);
|
214 | }
|
215 | return ((this.count > 0 && this._isAllSelected && this._exemptedCount === 0) ||
|
216 | (!this._isAllSelected && this._exemptedCount === selectableCount && selectableCount > 0));
|
217 | };
|
218 | Selection.prototype.isKeySelected = function (key) {
|
219 | var index = this._keyToIndexMap[key];
|
220 | return this.isIndexSelected(index);
|
221 | };
|
222 | Selection.prototype.isIndexSelected = function (index) {
|
223 | return !!((this.count > 0 && this._isAllSelected && !this._exemptedIndices[index] && !this._unselectableIndices[index]) ||
|
224 | (!this._isAllSelected && this._exemptedIndices[index]));
|
225 | };
|
226 | Selection.prototype.setAllSelected = function (isAllSelected) {
|
227 | if (isAllSelected && this.mode !== SelectionMode.multiple) {
|
228 | return;
|
229 | }
|
230 | var selectableCount = this._items ? this._items.length - this._unselectableCount : 0;
|
231 | this.setChangeEvents(false);
|
232 | if (selectableCount > 0 && (this._exemptedCount > 0 || isAllSelected !== this._isAllSelected)) {
|
233 | this._exemptedIndices = {};
|
234 | if (isAllSelected !== this._isAllSelected || this._exemptedCount > 0) {
|
235 | this._exemptedCount = 0;
|
236 | this._isAllSelected = isAllSelected;
|
237 | this._change();
|
238 | }
|
239 | this._updateCount();
|
240 | }
|
241 | this.setChangeEvents(true);
|
242 | };
|
243 | Selection.prototype.setKeySelected = function (key, isSelected, shouldAnchor) {
|
244 | var index = this._keyToIndexMap[key];
|
245 | if (index >= 0) {
|
246 | this.setIndexSelected(index, isSelected, shouldAnchor);
|
247 | }
|
248 | };
|
249 | Selection.prototype.setIndexSelected = function (index, isSelected, shouldAnchor) {
|
250 | if (this.mode === SelectionMode.none) {
|
251 | return;
|
252 | }
|
253 |
|
254 | index = Math.min(Math.max(0, index), this._items.length - 1);
|
255 |
|
256 | if (index < 0 || index >= this._items.length) {
|
257 | return;
|
258 | }
|
259 | this.setChangeEvents(false);
|
260 | var isExempt = this._exemptedIndices[index];
|
261 | var canSelect = !this._unselectableIndices[index];
|
262 | if (canSelect) {
|
263 | if (isSelected && this.mode === SelectionMode.single) {
|
264 |
|
265 | this._setAllSelected(false, true);
|
266 | }
|
267 |
|
268 | if (isExempt && ((isSelected && this._isAllSelected) || (!isSelected && !this._isAllSelected))) {
|
269 | delete this._exemptedIndices[index];
|
270 | this._exemptedCount--;
|
271 | }
|
272 |
|
273 | if (!isExempt && ((isSelected && !this._isAllSelected) || (!isSelected && this._isAllSelected))) {
|
274 | this._exemptedIndices[index] = true;
|
275 | this._exemptedCount++;
|
276 | }
|
277 | if (shouldAnchor) {
|
278 | this._anchoredIndex = index;
|
279 | }
|
280 | }
|
281 | this._updateCount();
|
282 | this.setChangeEvents(true);
|
283 | };
|
284 | Selection.prototype.setRangeSelected = function (fromIndex, count, isSelected, shouldAnchor) {
|
285 | if (this.mode === SelectionMode.none) {
|
286 | return;
|
287 | }
|
288 |
|
289 | fromIndex = Math.min(Math.max(0, fromIndex), this._items.length - 1);
|
290 |
|
291 | count = Math.min(Math.max(0, count), this._items.length - fromIndex);
|
292 |
|
293 | if (fromIndex < 0 || fromIndex >= this._items.length || count === 0) {
|
294 | return;
|
295 | }
|
296 | this.setChangeEvents(false);
|
297 | var anchorIndex = this._anchoredIndex || 0;
|
298 | var startIndex = fromIndex;
|
299 | var endIndex = fromIndex + count - 1;
|
300 | var newAnchorIndex = anchorIndex >= endIndex ? startIndex : endIndex;
|
301 | for (; startIndex <= endIndex; startIndex++) {
|
302 | this.setIndexSelected(startIndex, isSelected, shouldAnchor ? startIndex === newAnchorIndex : false);
|
303 | }
|
304 | this.setChangeEvents(true);
|
305 | };
|
306 | Selection.prototype.selectToKey = function (key, clearSelection) {
|
307 | this.selectToIndex(this._keyToIndexMap[key], clearSelection);
|
308 | };
|
309 | Selection.prototype.selectToRange = function (fromIndex, count, clearSelection) {
|
310 | if (this.mode === SelectionMode.none) {
|
311 | return;
|
312 | }
|
313 | if (this.mode === SelectionMode.single) {
|
314 | if (count === 1) {
|
315 | this.setIndexSelected(fromIndex, true, true);
|
316 | }
|
317 | return;
|
318 | }
|
319 | var anchorIndex = this._anchoredIndex || 0;
|
320 | var startIndex = Math.min(fromIndex, anchorIndex);
|
321 | var endIndex = Math.max(fromIndex + count - 1, anchorIndex);
|
322 | this.setChangeEvents(false);
|
323 | if (clearSelection) {
|
324 | this._setAllSelected(false, true);
|
325 | }
|
326 | for (; startIndex <= endIndex; startIndex++) {
|
327 | this.setIndexSelected(startIndex, true, false);
|
328 | }
|
329 | this.setChangeEvents(true);
|
330 | };
|
331 | Selection.prototype.selectToIndex = function (index, clearSelection) {
|
332 | if (this.mode === SelectionMode.none) {
|
333 | return;
|
334 | }
|
335 | if (this.mode === SelectionMode.single) {
|
336 | this.setIndexSelected(index, true, true);
|
337 | return;
|
338 | }
|
339 | var anchorIndex = this._anchoredIndex || 0;
|
340 | var startIndex = Math.min(index, anchorIndex);
|
341 | var endIndex = Math.max(index, anchorIndex);
|
342 | this.setChangeEvents(false);
|
343 | if (clearSelection) {
|
344 | this._setAllSelected(false, true);
|
345 | }
|
346 | for (; startIndex <= endIndex; startIndex++) {
|
347 | this.setIndexSelected(startIndex, true, false);
|
348 | }
|
349 | this.setChangeEvents(true);
|
350 | };
|
351 | Selection.prototype.toggleAllSelected = function () {
|
352 | this.setAllSelected(!this.isAllSelected());
|
353 | };
|
354 | Selection.prototype.toggleKeySelected = function (key) {
|
355 | this.setKeySelected(key, !this.isKeySelected(key), true);
|
356 | };
|
357 | Selection.prototype.toggleIndexSelected = function (index) {
|
358 | this.setIndexSelected(index, !this.isIndexSelected(index), true);
|
359 | };
|
360 | Selection.prototype.toggleRangeSelected = function (fromIndex, count) {
|
361 | if (this.mode === SelectionMode.none) {
|
362 | return;
|
363 | }
|
364 | var isRangeSelected = this.isRangeSelected(fromIndex, count);
|
365 | var endIndex = fromIndex + count;
|
366 | if (this.mode === SelectionMode.single && count > 1) {
|
367 | return;
|
368 | }
|
369 | this.setChangeEvents(false);
|
370 | for (var i = fromIndex; i < endIndex; i++) {
|
371 | this.setIndexSelected(i, !isRangeSelected, false);
|
372 | }
|
373 | this.setChangeEvents(true);
|
374 | };
|
375 | Selection.prototype._updateCount = function (preserveModalState) {
|
376 | if (preserveModalState === void 0) { preserveModalState = false; }
|
377 | var count = this.getSelectedCount();
|
378 | if (count !== this.count) {
|
379 | this.count = count;
|
380 | this._change();
|
381 | }
|
382 | if (!this.count && !preserveModalState) {
|
383 | this.setModal(false);
|
384 | }
|
385 | };
|
386 | Selection.prototype._setAllSelected = function (isAllSelected, preserveModalState) {
|
387 | if (preserveModalState === void 0) { preserveModalState = false; }
|
388 | if (isAllSelected && this.mode !== SelectionMode.multiple) {
|
389 | return;
|
390 | }
|
391 | var selectableCount = this._items ? this._items.length - this._unselectableCount : 0;
|
392 | this.setChangeEvents(false);
|
393 | if (selectableCount > 0 && (this._exemptedCount > 0 || isAllSelected !== this._isAllSelected)) {
|
394 | this._exemptedIndices = {};
|
395 | if (isAllSelected !== this._isAllSelected || this._exemptedCount > 0) {
|
396 | this._exemptedCount = 0;
|
397 | this._isAllSelected = isAllSelected;
|
398 | this._change();
|
399 | }
|
400 | this._updateCount(preserveModalState);
|
401 | }
|
402 | this.setChangeEvents(true);
|
403 | };
|
404 | Selection.prototype._change = function () {
|
405 | if (this._changeEventSuppressionCount === 0) {
|
406 | this._selectedItems = null;
|
407 | this._selectedIndices = undefined;
|
408 | EventGroup.raise(this, SELECTION_CHANGE);
|
409 | if (this._onSelectionChanged) {
|
410 | this._onSelectionChanged();
|
411 | }
|
412 | }
|
413 | else {
|
414 | this._hasChanged = true;
|
415 | }
|
416 | };
|
417 | return Selection;
|
418 | }());
|
419 | export { Selection };
|
420 | function defaultGetKey(item, index) {
|
421 |
|
422 | var _a = (item || {}).key, key = _a === void 0 ? "" + index : _a;
|
423 | return key;
|
424 | }
|
425 |
|
\ | No newline at end of file |