OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // require: array_data_model.js | 5 // require: array_data_model.js |
6 // require: list_selection_model.js | 6 // require: list_selection_model.js |
7 // require: list_selection_controller.js | 7 // require: list_selection_controller.js |
8 // require: list_item.js | 8 // require: list_item.js |
9 | 9 |
10 /** | 10 /** |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
153 this.itemConstructor_ = func; | 153 this.itemConstructor_ = func; |
154 this.cachedItems_ = {}; | 154 this.cachedItems_ = {}; |
155 this.redraw(); | 155 this.redraw(); |
156 } | 156 } |
157 }, | 157 }, |
158 | 158 |
159 dataModel_: null, | 159 dataModel_: null, |
160 | 160 |
161 /** | 161 /** |
162 * The data model driving the list. | 162 * The data model driving the list. |
163 * @type {ArrayDataModel} | 163 * @type {ListDataModel} |
164 */ | 164 */ |
165 set dataModel(dataModel) { | 165 set dataModel(dataModel) { |
166 if (this.dataModel_ != dataModel) { | 166 if (this.dataModel_ != dataModel) { |
167 if (!this.boundHandleDataModelPermuted_) { | 167 if (!this.boundHandleDataModelSplice_) { |
168 this.boundHandleDataModelPermuted_ = | 168 this.boundHandleDataModelSplice_ = |
169 this.handleDataModelPermuted_.bind(this); | 169 this.handleDataModelSplice_.bind(this); |
170 this.boundHandleDataModelChange_ = | 170 this.boundHandleDataModelChange_ = |
171 this.handleDataModelChange_.bind(this); | 171 this.handleDataModelChange_.bind(this); |
| 172 this.boundHandleSorted_ = |
| 173 this.handleSorted_.bind(this); |
172 } | 174 } |
173 | 175 |
174 if (this.dataModel_) { | 176 if (this.dataModel_) { |
175 this.dataModel_.removeEventListener( | 177 this.dataModel_.removeEventListener('splice', |
176 'permuted', | 178 this.boundHandleDataModelSplice_); |
177 this.boundHandleDataModelPermuted_); | |
178 this.dataModel_.removeEventListener('change', | 179 this.dataModel_.removeEventListener('change', |
179 this.boundHandleDataModelChange_); | 180 this.boundHandleDataModelChange_); |
| 181 this.dataModel_.removeEventListener('sorted', |
| 182 this.boundHandleSorted_); |
180 } | 183 } |
181 | 184 |
182 this.dataModel_ = dataModel; | 185 this.dataModel_ = dataModel; |
183 | 186 |
184 this.cachedItems_ = {}; | 187 this.cachedItems_ = {}; |
185 this.selectionModel.clear(); | 188 this.selectionModel.clear(); |
186 if (dataModel) | 189 if (dataModel) |
187 this.selectionModel.adjustLength(dataModel.length); | 190 this.selectionModel.adjust(0, 0, dataModel.length); |
188 | 191 |
189 if (this.dataModel_) { | 192 if (this.dataModel_) { |
190 this.dataModel_.addEventListener( | 193 this.dataModel_.addEventListener('splice', |
191 'permuted', | 194 this.boundHandleDataModelSplice_); |
192 this.boundHandleDataModelPermuted_); | |
193 this.dataModel_.addEventListener('change', | 195 this.dataModel_.addEventListener('change', |
194 this.boundHandleDataModelChange_); | 196 this.boundHandleDataModelChange_); |
| 197 this.dataModel_.addEventListener('sorted', |
| 198 this.boundHandleSorted_); |
195 } | 199 } |
196 | 200 |
197 this.redraw(); | 201 this.redraw(); |
198 } | 202 } |
199 }, | 203 }, |
200 | 204 |
201 get dataModel() { | 205 get dataModel() { |
202 return this.dataModel_; | 206 return this.dataModel_; |
203 }, | 207 }, |
204 | 208 |
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
543 // the bottom of the list is not "sticky.") So, we set a timeout to | 547 // the bottom of the list is not "sticky.") So, we set a timeout to |
544 // rescroll the list after this all gets sorted out. This is perhaps | 548 // rescroll the list after this all gets sorted out. This is perhaps |
545 // not the most elegant solution, but no others seem obvious. | 549 // not the most elegant solution, but no others seem obvious. |
546 var self = this; | 550 var self = this; |
547 window.setTimeout(function() { | 551 window.setTimeout(function() { |
548 self.scrollIndexIntoView(pe.newValue); | 552 self.scrollIndexIntoView(pe.newValue); |
549 }); | 553 }); |
550 } | 554 } |
551 }, | 555 }, |
552 | 556 |
| 557 handleDataModelSplice_: function(e) { |
| 558 this.selectionModel.adjust(e.index, e.removed.length, e.added.length); |
| 559 // Remove the cache of everything above index. |
| 560 for (var index in this.cachedItems_) { |
| 561 if (index >= e.index) |
| 562 delete this.cachedItems_[index]; |
| 563 } |
| 564 this.redraw(); |
| 565 }, |
| 566 |
| 567 handleDataModelChange_: function(e) { |
| 568 if (e.index >= this.firstIndex_ && e.index < this.lastIndex_) { |
| 569 this.cachedItems_ = null; |
| 570 this.redraw(); |
| 571 } |
| 572 }, |
| 573 |
553 /** | 574 /** |
554 * This handles data model 'permuted' event. | 575 * This handles data model 'sorted' event. |
555 * this event is dispatched as a part of sort or splice. | 576 * After sorting we need to |
556 * We need to | |
557 * - adjust the cache. | |
558 * - adjust selection. | 577 * - adjust selection. |
559 * - redraw. | 578 * - delete the cache. |
| 579 * - redraw all the items. |
560 * - scroll the list to show selection. | 580 * - scroll the list to show selection. |
561 * It is important that the cache adjustment happens before selection model | 581 * @param {Event} e The 'sorted' event. |
562 * adjustments. | |
563 * @param {Event} e The 'permuted' event. | |
564 */ | 582 */ |
565 handleDataModelPermuted_: function(e) { | 583 handleSorted_: function(e) { |
566 var newCachedItems = {}; | 584 var sm = this.selectionModel; |
567 for (var index in this.cachedItems_) { | 585 sm.adjustToReordering(e.sortPermutation); |
568 if (e.permutation[index] != -1) | |
569 newCachedItems[e.permutation[index]] = this.cachedItems_[index]; | |
570 else | |
571 delete this.cachedItems_[index]; | |
572 } | |
573 this.cachedItems_ = newCachedItems; | |
574 | 586 |
575 var sm = this.selectionModel; | 587 this.cachedItems_ = null; |
576 sm.adjustToReordering(e.permutation); | |
577 | |
578 this.redraw(); | 588 this.redraw(); |
579 | |
580 if (sm.leadIndex != -1) | 589 if (sm.leadIndex != -1) |
581 this.scrollIndexIntoView(sm.leadIndex); | 590 this.scrollIndexIntoView(sm.leadIndex); |
582 }, | 591 }, |
583 | 592 |
584 handleDataModelChange_: function(e) { | |
585 if (e.index >= this.firstIndex_ && e.index < this.lastIndex_) { | |
586 if (this.cachedItems_[index]) | |
587 delete this.cachedItems_[index]; | |
588 this.redraw(); | |
589 } | |
590 }, | |
591 | |
592 /** | 593 /** |
593 * @param {number} index The index of the item. | 594 * @param {number} index The index of the item. |
594 * @return {number} The top position of the item inside the list, not taking | 595 * @return {number} The top position of the item inside the list, not taking |
595 * into account lead item. May vary in the case of multiple columns. | 596 * into account lead item. May vary in the case of multiple columns. |
596 */ | 597 */ |
597 getItemTop: function(index) { | 598 getItemTop: function(index) { |
598 return index * this.getItemHeight_(); | 599 return index * this.getItemHeight_(); |
599 }, | 600 }, |
600 | 601 |
601 /** | 602 /** |
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
923 var list = this; | 924 var list = this; |
924 window.setTimeout(function() { | 925 window.setTimeout(function() { |
925 if (listItem.parentNode == list) { | 926 if (listItem.parentNode == list) { |
926 list.measured_ = measureItem(list, listItem); | 927 list.measured_ = measureItem(list, listItem); |
927 } | 928 } |
928 }); | 929 }); |
929 } | 930 } |
930 }, | 931 }, |
931 | 932 |
932 /** | 933 /** |
933 * Invalidates list by removing cached items. | |
934 */ | |
935 invalidate: function() { | |
936 this.cachedItems_ = {}; | |
937 }, | |
938 | |
939 /** | |
940 * Redraws a single item. | 934 * Redraws a single item. |
941 * @param {number} index The row index to redraw. | 935 * @param {number} index The row index to redraw. |
942 */ | 936 */ |
943 redrawItem: function(index) { | 937 redrawItem: function(index) { |
944 if (index >= this.firstIndex_ && index < this.lastIndex_) { | 938 if (index >= this.firstIndex_ && index < this.lastIndex_) { |
945 delete this.cachedItems_[index]; | 939 delete this.cachedItems_[index]; |
946 this.redraw(); | 940 this.redraw(); |
947 } | 941 } |
948 }, | 942 }, |
949 | 943 |
(...skipping 13 matching lines...) Expand all Loading... |
963 * because list items can contain controls that can be focused, and for some | 957 * because list items can contain controls that can be focused, and for some |
964 * purposes (e.g., styling), the list can still be conceptually focused at | 958 * purposes (e.g., styling), the list can still be conceptually focused at |
965 * that point even though it doesn't actually have the page focus. | 959 * that point even though it doesn't actually have the page focus. |
966 */ | 960 */ |
967 cr.defineProperty(List, 'hasElementFocus', cr.PropertyKind.BOOL_ATTR); | 961 cr.defineProperty(List, 'hasElementFocus', cr.PropertyKind.BOOL_ATTR); |
968 | 962 |
969 return { | 963 return { |
970 List: List | 964 List: List |
971 } | 965 } |
972 }); | 966 }); |
OLD | NEW |