Index: chrome/browser/resources/shared/js/cr/ui/list_selection_model.js |
=================================================================== |
--- chrome/browser/resources/shared/js/cr/ui/list_selection_model.js (revision 177292) |
+++ chrome/browser/resources/shared/js/cr/ui/list_selection_model.js (working copy) |
@@ -1,347 +0,0 @@ |
-// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-cr.define('cr.ui', function() { |
- /** @const */ var Event = cr.Event; |
- /** @const */ var EventTarget = cr.EventTarget; |
- |
- /** |
- * Creates a new selection model that is to be used with lists. |
- * |
- * @param {number=} opt_length The number items in the selection. |
- * |
- * @constructor |
- * @extends {!cr.EventTarget} |
- */ |
- function ListSelectionModel(opt_length) { |
- this.length_ = opt_length || 0; |
- // Even though selectedIndexes_ is really a map we use an array here to get |
- // iteration in the order of the indexes. |
- this.selectedIndexes_ = []; |
- |
- // True if any item could be lead or anchor. False if only selected ones. |
- this.independentLeadItem_ = !cr.isMac && !cr.isChromeOS; |
- } |
- |
- ListSelectionModel.prototype = { |
- __proto__: EventTarget.prototype, |
- |
- /** |
- * The number of items in the model. |
- * @type {number} |
- */ |
- get length() { |
- return this.length_; |
- }, |
- |
- /** |
- * The selected indexes. |
- * Setter also changes lead and anchor indexes if value list is nonempty. |
- * @type {!Array} |
- */ |
- get selectedIndexes() { |
- return Object.keys(this.selectedIndexes_).map(Number); |
- }, |
- set selectedIndexes(selectedIndexes) { |
- this.beginChange(); |
- var unselected = {}; |
- for (var index in this.selectedIndexes_) { |
- unselected[index] = true; |
- } |
- |
- for (var i = 0; i < selectedIndexes.length; i++) { |
- var index = selectedIndexes[i]; |
- if (index in this.selectedIndexes_) { |
- delete unselected[index]; |
- } else { |
- this.selectedIndexes_[index] = true; |
- this.changedIndexes_[index] = true; |
- } |
- } |
- |
- for (var index in unselected) { |
- delete this.selectedIndexes_[index]; |
- this.changedIndexes_[index] = false; |
- } |
- |
- if (selectedIndexes.length) { |
- this.leadIndex = this.anchorIndex = selectedIndexes[0]; |
- } else { |
- this.leadIndex = this.anchorIndex = -1; |
- } |
- this.endChange(); |
- }, |
- |
- /** |
- * Convenience getter which returns the first selected index. |
- * Setter also changes lead and anchor indexes if value is nonnegative. |
- * @type {number} |
- */ |
- get selectedIndex() { |
- for (var i in this.selectedIndexes_) { |
- return Number(i); |
- } |
- return -1; |
- }, |
- set selectedIndex(selectedIndex) { |
- this.selectedIndexes = selectedIndex != -1 ? [selectedIndex] : []; |
- }, |
- |
- /** |
- * Returns the last selected index or -1 if no item selected. |
- * @type {number} |
- */ |
- get lastSelectedIndex() { |
- var result = -1; |
- for (var i in this.selectedIndexes_) { |
- result = Math.max(result, Number(i)); |
- } |
- return result; |
- }, |
- |
- /** |
- * Selects a range of indexes, starting with {@code start} and ends with |
- * {@code end}. |
- * @param {number} start The first index to select. |
- * @param {number} end The last index to select. |
- */ |
- selectRange: function(start, end) { |
- // Swap if starts comes after end. |
- if (start > end) { |
- var tmp = start; |
- start = end; |
- end = tmp; |
- } |
- |
- this.beginChange(); |
- |
- for (var index = start; index != end; index++) { |
- this.setIndexSelected(index, true); |
- } |
- this.setIndexSelected(end, true); |
- |
- this.endChange(); |
- }, |
- |
- /** |
- * Selects all indexes. |
- */ |
- selectAll: function() { |
- this.selectRange(0, this.length - 1); |
- }, |
- |
- /** |
- * Clears the selection |
- */ |
- clear: function() { |
- this.beginChange(); |
- this.length_ = 0; |
- this.anchorIndex = this.leadIndex = -1; |
- this.unselectAll(); |
- this.endChange(); |
- }, |
- |
- /** |
- * Unselects all selected items. |
- */ |
- unselectAll: function() { |
- this.beginChange(); |
- for (var i in this.selectedIndexes_) { |
- this.setIndexSelected(i, false); |
- } |
- this.endChange(); |
- }, |
- |
- /** |
- * Sets the selected state for an index. |
- * @param {number} index The index to set the selected state for. |
- * @param {boolean} b Whether to select the index or not. |
- */ |
- setIndexSelected: function(index, b) { |
- var oldSelected = index in this.selectedIndexes_; |
- if (oldSelected == b) |
- return; |
- |
- if (b) |
- this.selectedIndexes_[index] = true; |
- else |
- delete this.selectedIndexes_[index]; |
- |
- this.beginChange(); |
- |
- this.changedIndexes_[index] = b; |
- |
- // End change dispatches an event which in turn may update the view. |
- this.endChange(); |
- }, |
- |
- /** |
- * Whether a given index is selected or not. |
- * @param {number} index The index to check. |
- * @return {boolean} Whether an index is selected. |
- */ |
- getIndexSelected: function(index) { |
- return index in this.selectedIndexes_; |
- }, |
- |
- /** |
- * This is used to begin batching changes. Call {@code endChange} when you |
- * are done making changes. |
- */ |
- beginChange: function() { |
- if (!this.changeCount_) { |
- this.changeCount_ = 0; |
- this.changedIndexes_ = {}; |
- this.oldLeadIndex_ = this.leadIndex_; |
- this.oldAnchorIndex_ = this.anchorIndex_; |
- } |
- this.changeCount_++; |
- }, |
- |
- /** |
- * Call this after changes are done and it will dispatch a change event if |
- * any changes were actually done. |
- */ |
- endChange: function() { |
- this.changeCount_--; |
- if (!this.changeCount_) { |
- // Calls delayed |dispatchPropertyChange|s, only when |leadIndex| or |
- // |anchorIndex| has been actually changed in the batch. |
- this.leadIndex_ = this.adjustIndex_(this.leadIndex_); |
- if (this.leadIndex_ != this.oldLeadIndex_) { |
- cr.dispatchPropertyChange(this, 'leadIndex', |
- this.leadIndex_, this.oldLeadIndex_); |
- } |
- this.oldLeadIndex_ = null; |
- |
- this.anchorIndex_ = this.adjustIndex_(this.anchorIndex_); |
- if (this.anchorIndex_ != this.oldAnchorIndex_) { |
- cr.dispatchPropertyChange(this, 'anchorIndex', |
- this.anchorIndex_, this.oldAnchorIndex_); |
- } |
- this.oldAnchorIndex_ = null; |
- |
- var indexes = Object.keys(this.changedIndexes_); |
- if (indexes.length) { |
- var e = new Event('change'); |
- e.changes = indexes.map(function(index) { |
- return { |
- index: Number(index), |
- selected: this.changedIndexes_[index] |
- }; |
- }, this); |
- this.dispatchEvent(e); |
- } |
- this.changedIndexes_ = {}; |
- } |
- }, |
- |
- leadIndex_: -1, |
- oldLeadIndex_: null, |
- |
- /** |
- * The leadIndex is used with multiple selection and it is the index that |
- * the user is moving using the arrow keys. |
- * @type {number} |
- */ |
- get leadIndex() { |
- return this.leadIndex_; |
- }, |
- set leadIndex(leadIndex) { |
- var oldValue = this.leadIndex_; |
- var newValue = this.adjustIndex_(leadIndex); |
- this.leadIndex_ = newValue; |
- // Delays the call of dispatchPropertyChange if batch is running. |
- if (!this.changeCount_ && newValue != oldValue) |
- cr.dispatchPropertyChange(this, 'leadIndex', newValue, oldValue); |
- }, |
- |
- anchorIndex_: -1, |
- oldAnchorIndex_: null, |
- |
- /** |
- * The anchorIndex is used with multiple selection. |
- * @type {number} |
- */ |
- get anchorIndex() { |
- return this.anchorIndex_; |
- }, |
- set anchorIndex(anchorIndex) { |
- var oldValue = this.anchorIndex_; |
- var newValue = this.adjustIndex_(anchorIndex); |
- this.anchorIndex_ = newValue; |
- // Delays the call of dispatchPropertyChange if batch is running. |
- if (!this.changeCount_ && newValue != oldValue) |
- cr.dispatchPropertyChange(this, 'anchorIndex', newValue, oldValue); |
- }, |
- |
- /** |
- * Helper method that adjustes a value before assiging it to leadIndex or |
- * anchorIndex. |
- * @param {number} index New value for leadIndex or anchorIndex. |
- * @return {number} Corrected value. |
- */ |
- adjustIndex_: function(index) { |
- index = Math.max(-1, Math.min(this.length_ - 1, index)); |
- // On Mac and ChromeOS lead and anchor items are forced to be among |
- // selected items. This rule is not enforces until end of batch update. |
- if (!this.changeCount_ && !this.independentLeadItem_ && |
- !this.getIndexSelected(index)) { |
- index = this.lastSelectedIndex; |
- } |
- return index; |
- }, |
- |
- /** |
- * Whether the selection model supports multiple selected items. |
- * @type {boolean} |
- */ |
- get multiple() { |
- return true; |
- }, |
- |
- /** |
- * Adjusts the selection after reordering of items in the table. |
- * @param {!Array.<number>} permutation The reordering permutation. |
- */ |
- adjustToReordering: function(permutation) { |
- this.beginChange(); |
- var oldLeadIndex = this.leadIndex; |
- var oldAnchorIndex = this.anchorIndex; |
- var oldSelectedItemsCount = this.selectedIndexes.length; |
- |
- this.selectedIndexes = this.selectedIndexes.map(function(oldIndex) { |
- return permutation[oldIndex]; |
- }).filter(function(index) { |
- return index != -1; |
- }); |
- |
- // Will be adjusted in endChange. |
- if (oldLeadIndex != -1) |
- this.leadIndex = permutation[oldLeadIndex]; |
- if (oldAnchorIndex != -1) |
- this.anchorIndex = permutation[oldAnchorIndex]; |
- |
- if (oldSelectedItemsCount && !this.selectedIndexes.length) { |
- // All selected items are deleted. We move selection to next item of |
- // last selected item. |
- this.selectedIndexes = [oldLeadIndex]; |
- } |
- |
- this.endChange(); |
- }, |
- |
- /** |
- * Adjusts selection model length. |
- * @param {number} length New selection model length. |
- */ |
- adjustLength: function(length) { |
- this.length_ = length; |
- } |
- }; |
- |
- return { |
- ListSelectionModel: ListSelectionModel |
- }; |
-}); |