| 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 {ListDataModel} | 163 * @type {ArrayDataModel} |
| 164 */ | 164 */ |
| 165 set dataModel(dataModel) { | 165 set dataModel(dataModel) { |
| 166 if (this.dataModel_ != dataModel) { | 166 if (this.dataModel_ != dataModel) { |
| 167 if (!this.boundHandleDataModelSplice_) { | 167 if (!this.boundHandleDataModelPermuted_) { |
| 168 this.boundHandleDataModelSplice_ = | 168 this.boundHandleDataModelPermuted_ = |
| 169 this.handleDataModelSplice_.bind(this); | 169 this.handleDataModelPermuted_.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); | |
| 174 } | 172 } |
| 175 | 173 |
| 176 if (this.dataModel_) { | 174 if (this.dataModel_) { |
| 177 this.dataModel_.removeEventListener('splice', | 175 this.dataModel_.removeEventListener( |
| 178 this.boundHandleDataModelSplice_); | 176 'permuted', |
| 177 this.boundHandleDataModelPermuted_); |
| 179 this.dataModel_.removeEventListener('change', | 178 this.dataModel_.removeEventListener('change', |
| 180 this.boundHandleDataModelChange_); | 179 this.boundHandleDataModelChange_); |
| 181 this.dataModel_.removeEventListener('sorted', | |
| 182 this.boundHandleSorted_); | |
| 183 } | 180 } |
| 184 | 181 |
| 185 this.dataModel_ = dataModel; | 182 this.dataModel_ = dataModel; |
| 186 | 183 |
| 187 this.cachedItems_ = {}; | 184 this.cachedItems_ = {}; |
| 188 this.selectionModel.clear(); | 185 this.selectionModel.clear(); |
| 189 if (dataModel) | 186 if (dataModel) |
| 190 this.selectionModel.adjust(0, 0, dataModel.length); | 187 this.selectionModel.adjustLength(dataModel.length); |
| 191 | 188 |
| 192 if (this.dataModel_) { | 189 if (this.dataModel_) { |
| 193 this.dataModel_.addEventListener('splice', | 190 this.dataModel_.addEventListener( |
| 194 this.boundHandleDataModelSplice_); | 191 'permuted', |
| 192 this.boundHandleDataModelPermuted_); |
| 195 this.dataModel_.addEventListener('change', | 193 this.dataModel_.addEventListener('change', |
| 196 this.boundHandleDataModelChange_); | 194 this.boundHandleDataModelChange_); |
| 197 this.dataModel_.addEventListener('sorted', | |
| 198 this.boundHandleSorted_); | |
| 199 } | 195 } |
| 200 | 196 |
| 201 this.redraw(); | 197 this.redraw(); |
| 202 } | 198 } |
| 203 }, | 199 }, |
| 204 | 200 |
| 205 get dataModel() { | 201 get dataModel() { |
| 206 return this.dataModel_; | 202 return this.dataModel_; |
| 207 }, | 203 }, |
| 208 | 204 |
| (...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 547 // the bottom of the list is not "sticky.") So, we set a timeout to | 543 // the bottom of the list is not "sticky.") So, we set a timeout to |
| 548 // rescroll the list after this all gets sorted out. This is perhaps | 544 // rescroll the list after this all gets sorted out. This is perhaps |
| 549 // not the most elegant solution, but no others seem obvious. | 545 // not the most elegant solution, but no others seem obvious. |
| 550 var self = this; | 546 var self = this; |
| 551 window.setTimeout(function() { | 547 window.setTimeout(function() { |
| 552 self.scrollIndexIntoView(pe.newValue); | 548 self.scrollIndexIntoView(pe.newValue); |
| 553 }); | 549 }); |
| 554 } | 550 } |
| 555 }, | 551 }, |
| 556 | 552 |
| 557 handleDataModelSplice_: function(e) { | 553 /** |
| 558 this.selectionModel.adjust(e.index, e.removed.length, e.added.length); | 554 * This handles data model 'permuted' event. |
| 559 // Remove the cache of everything above index. | 555 * this event is dispatched as a part of sort or splice. |
| 556 * We need to |
| 557 * - adjust the cache. |
| 558 * - adjust selection. |
| 559 * - redraw. |
| 560 * - scroll the list to show selection. |
| 561 * It is important that the cache adjustment happens before selection model |
| 562 * adjustments. |
| 563 * @param {Event} e The 'permuted' event. |
| 564 */ |
| 565 handleDataModelPermuted_: function(e) { |
| 566 var newCachedItems = {}; |
| 560 for (var index in this.cachedItems_) { | 567 for (var index in this.cachedItems_) { |
| 561 if (index >= e.index) | 568 if (e.permutation[index] != -1) |
| 569 newCachedItems[e.permutation[index]] = this.cachedItems_[index]; |
| 570 else |
| 562 delete this.cachedItems_[index]; | 571 delete this.cachedItems_[index]; |
| 563 } | 572 } |
| 573 this.cachedItems_ = newCachedItems; |
| 574 |
| 575 var sm = this.selectionModel; |
| 576 sm.adjustToReordering(e.permutation); |
| 577 |
| 564 this.redraw(); | 578 this.redraw(); |
| 579 |
| 580 if (sm.leadIndex != -1) |
| 581 this.scrollIndexIntoView(sm.leadIndex); |
| 565 }, | 582 }, |
| 566 | 583 |
| 567 handleDataModelChange_: function(e) { | 584 handleDataModelChange_: function(e) { |
| 568 if (e.index >= this.firstIndex_ && e.index < this.lastIndex_) { | 585 if (e.index >= this.firstIndex_ && e.index < this.lastIndex_) { |
| 569 this.cachedItems_ = null; | 586 if (this.cachedItems_[index]) |
| 587 delete this.cachedItems_[index]; |
| 570 this.redraw(); | 588 this.redraw(); |
| 571 } | 589 } |
| 572 }, | 590 }, |
| 573 | 591 |
| 574 /** | 592 /** |
| 575 * This handles data model 'sorted' event. | |
| 576 * After sorting we need to | |
| 577 * - adjust selection. | |
| 578 * - delete the cache. | |
| 579 * - redraw all the items. | |
| 580 * - scroll the list to show selection. | |
| 581 * @param {Event} e The 'sorted' event. | |
| 582 */ | |
| 583 handleSorted_: function(e) { | |
| 584 var sm = this.selectionModel; | |
| 585 sm.adjustToReordering(e.sortPermutation); | |
| 586 | |
| 587 this.cachedItems_ = null; | |
| 588 this.redraw(); | |
| 589 if (sm.leadIndex != -1) | |
| 590 this.scrollIndexIntoView(sm.leadIndex); | |
| 591 }, | |
| 592 | |
| 593 /** | |
| 594 * @param {number} index The index of the item. | 593 * @param {number} index The index of the item. |
| 595 * @return {number} The top position of the item inside the list, not taking | 594 * @return {number} The top position of the item inside the list, not taking |
| 596 * into account lead item. May vary in the case of multiple columns. | 595 * into account lead item. May vary in the case of multiple columns. |
| 597 */ | 596 */ |
| 598 getItemTop: function(index) { | 597 getItemTop: function(index) { |
| 599 return index * this.getItemHeight_(); | 598 return index * this.getItemHeight_(); |
| 600 }, | 599 }, |
| 601 | 600 |
| 602 /** | 601 /** |
| 603 * @param {number} index The index of the item. | 602 * @param {number} index The index of the item. |
| (...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 957 * because list items can contain controls that can be focused, and for some | 956 * because list items can contain controls that can be focused, and for some |
| 958 * purposes (e.g., styling), the list can still be conceptually focused at | 957 * purposes (e.g., styling), the list can still be conceptually focused at |
| 959 * that point even though it doesn't actually have the page focus. | 958 * that point even though it doesn't actually have the page focus. |
| 960 */ | 959 */ |
| 961 cr.defineProperty(List, 'hasElementFocus', cr.PropertyKind.BOOL_ATTR); | 960 cr.defineProperty(List, 'hasElementFocus', cr.PropertyKind.BOOL_ATTR); |
| 962 | 961 |
| 963 return { | 962 return { |
| 964 List: List | 963 List: List |
| 965 } | 964 } |
| 966 }); | 965 }); |
| OLD | NEW |